diff --git a/bin/pixi.js b/bin/pixi.js index 8e9f630..fbffb23 100644 --- a/bin/pixi.js +++ b/bin/pixi.js @@ -1,7 +1,7 @@ /** * @license - * pixi.js - v3.0.8 - * Compiled 2015-10-14T14:21:20.183Z + * pixi.js - v3.0.9-dev + * Compiled 2015-10-21T22:04:26.470Z * * pixi.js is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license.php @@ -3974,9 +3974,1423 @@ }; },{}],12:[function(require,module,exports){ +var async = require('async'), + urlParser = require('url'), + Resource = require('./Resource'), + EventEmitter = require('eventemitter3'); + +/** + * Manages the state and loading of multiple resources to load. + * + * @class + * @param [baseUrl=''] {string} The base url for all resources loaded by this loader. + * @param [concurrency=10] {number} The number of resources to load concurrently. + */ +function Loader(baseUrl, concurrency) { + EventEmitter.call(this); + + concurrency = concurrency || 10; + + /** + * The base url for all resources loaded by this loader. + * + * @member {string} + */ + this.baseUrl = baseUrl || ''; + + /** + * The progress percent of the loader going through the queue. + * + * @member {number} + */ + this.progress = 0; + + /** + * Loading state of the loader, true if it is currently loading resources. + * + * @member {boolean} + */ + this.loading = false; + + /** + * The percentage of total progress that a single resource represents. + * + * @member {number} + */ + this._progressChunk = 0; + + /** + * The middleware to run before loading each resource. + * + * @member {function[]} + */ + this._beforeMiddleware = []; + + /** + * The middleware to run after loading each resource. + * + * @member {function[]} + */ + this._afterMiddleware = []; + + /** + * The `_loadResource` function bound with this object context. + * + * @private + * @member {function} + */ + this._boundLoadResource = this._loadResource.bind(this); + + /** + * The `_onLoad` function bound with this object context. + * + * @private + * @member {function} + */ + this._boundOnLoad = this._onLoad.bind(this); + + /** + * The resource buffer that fills until `load` is called to start loading resources. + * + * @private + * @member {Resource[]} + */ + this._buffer = []; + + /** + * Used to track load completion. + * + * @private + * @member {number} + */ + this._numToLoad = 0; + + /** + * The resources waiting to be loaded. + * + * @private + * @member {Resource[]} + */ + this._queue = async.queue(this._boundLoadResource, concurrency); + + /** + * All the resources for this loader keyed by name. + * + * @member {object} + */ + this.resources = {}; + + /** + * Emitted once per loaded or errored resource. + * + * @event progress + * @memberof Loader# + */ + + /** + * Emitted once per errored resource. + * + * @event error + * @memberof Loader# + */ + + /** + * Emitted once per loaded resource. + * + * @event load + * @memberof Loader# + */ + + /** + * Emitted when the loader begins to process the queue. + * + * @event start + * @memberof Loader# + */ + + /** + * Emitted when the queued resources all load. + * + * @event complete + * @memberof Loader# + */ +} + +Loader.prototype = Object.create(EventEmitter.prototype); +Loader.prototype.constructor = Loader; +module.exports = Loader; + +/** + * Adds a resource (or multiple resources) to the loader queue. + * + * This function can take a wide variety of different parameters. The only thing that is always + * required the url to load. All the following will work: + * + * ```js + * loader + * // normal param syntax + * .add('key', 'http://...', function () {}) + * .add('http://...', function () {}) + * .add('http://...') + * + * // object syntax + * .add({ + * name: 'key2', + * url: 'http://...' + * }, function () {}) + * .add({ + * url: 'http://...' + * }, function () {}) + * .add({ + * name: 'key3', + * url: 'http://...' + * onComplete: function () {} + * }) + * .add({ + * url: 'https://...', + * onComplete: function () {}, + * crossOrigin: true + * }) + * + * // you can also pass an array of objects or urls or both + * .add([ + * { name: 'key4', url: 'http://...', onComplete: function () {} }, + * { url: 'http://...', onComplete: function () {} }, + * 'http://...' + * ]); + * ``` + * + * @alias enqueue + * @param [name] {string} The name of the resource to load, if not passed the url is used. + * @param url {string} The url for this resource, relative to the baseUrl of this loader. + * @param [options] {object} The options for the load. + * @param [options.crossOrigin] {boolean} Is this request cross-origin? Default is to determine automatically. + * @param [options.loadType=Resource.LOAD_TYPE.XHR] {Resource.XHR_LOAD_TYPE} How should this resource be loaded? + * @param [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] {Resource.XHR_RESPONSE_TYPE} How should the data being + * loaded be interpreted when using XHR? + * @param [callback] {function} Function to call when this specific resource completes loading. + * @return {Loader} + */ +Loader.prototype.add = Loader.prototype.enqueue = function (name, url, options, cb) { + // special case of an array of objects or urls + if (Array.isArray(name)) { + for (var i = 0; i < name.length; ++i) { + this.add(name[i]); + } + + return this; + } + + // if an object is passed instead of params + if (typeof name === 'object') { + cb = url || name.callback || name.onComplete; + options = name; + url = name.url; + name = name.name || name.key || name.url; + } + + // case where no name is passed shift all args over by one. + if (typeof url !== 'string') { + cb = options; + options = url; + url = name; + } + + // now that we shifted make sure we have a proper url. + if (typeof url !== 'string') { + throw new Error('No url passed to add resource to loader.'); + } + + // options are optional so people might pass a function and no options + if (typeof options === 'function') { + cb = options; + options = null; + } + + // check if resource already exists. + if (this.resources[name]) { + throw new Error('Resource with name "' + name + '" already exists.'); + } + + // add base url if this isn't an absolute url + url = this._handleBaseUrl(url); + + // create the store the resource + this.resources[name] = new Resource(name, url, options); + + if (typeof cb === 'function') { + this.resources[name].once('afterMiddleware', cb); + } + + this._numToLoad++; + + // if already loading add it to the worker queue + if (this._queue.started) { + this._queue.push(this.resources[name]); + this._progressChunk = (100 - this.progress) / (this._queue.length() + this._queue.running()); + } + // otherwise buffer it to be added to the queue later + else { + this._buffer.push(this.resources[name]); + this._progressChunk = 100 / this._buffer.length; + } + + return this; +}; + +Loader.prototype._handleBaseUrl = function (url) { + var parsedUrl = urlParser.parse(url); + + // absolute url, just use it as is. + if (parsedUrl.protocol || parsedUrl.pathname.indexOf('//') === 0) { + return url; + } + + // if baseUrl doesn't end in slash and url doesn't start with slash, then add a slash inbetween + if ( + this.baseUrl.length && + this.baseUrl.lastIndexOf('/') !== this.baseUrl.length - 1 && + url.lastIndexOf('/') !== url.length - 1 + ) { + return this.baseUrl + '/' + url; + } + else { + return this.baseUrl + url; + } +}; + + +/** + * Sets up a middleware function that will run *before* the + * resource is loaded. + * + * @alias pre + * @param middleware {function} The middleware function to register. + * @return {Loader} + */ +Loader.prototype.before = Loader.prototype.pre = function (fn) { + this._beforeMiddleware.push(fn); + + return this; +}; + +/** + * Sets up a middleware function that will run *after* the + * resource is loaded. + * + * @alias use + * @param middleware {function} The middleware function to register. + * @return {Loader} + */ +Loader.prototype.after = Loader.prototype.use = function (fn) { + this._afterMiddleware.push(fn); + + return this; +}; + +/** + * Resets the queue of the loader to prepare for a new load. + * + * @return {Loader} + */ +Loader.prototype.reset = function () { + // this.baseUrl = baseUrl || ''; + + this.progress = 0; + + this.loading = false; + + this._progressChunk = 0; + + // this._beforeMiddleware.length = 0; + // this._afterMiddleware.length = 0; + + this._buffer.length = 0; + + this._numToLoad = 0; + + this._queue.kill(); + this._queue.started = false; + + this.resources = {}; +}; + +/** + * Starts loading the queued resources. + * + * @fires start + * @param [callback] {function} Optional callback that will be bound to the `complete` event. + * @return {Loader} + */ +Loader.prototype.load = function (cb) { + // register complete callback if they pass one + if (typeof cb === 'function') { + this.once('complete', cb); + } + + // if the queue has already started we are done here + if (this._queue.started) { + return this; + } + + // notify of start + this.emit('start', this); + + // start the internal queue + for (var i = 0; i < this._buffer.length; ++i) { + this._queue.push(this._buffer[i]); + } + + // empty the buffer + this._buffer.length = 0; + + return this; +}; + +/** + * Loads a single resource. + * + * @fires progress + * @private + */ +Loader.prototype._loadResource = function (resource, dequeue) { + var self = this; + + resource._dequeue = dequeue; + + this._runMiddleware(resource, this._beforeMiddleware, function () { + // resource.on('progress', self.emit.bind(self, 'progress')); + + resource.load(self._boundOnLoad); + }); +}; + +/** + * Called once each resource has loaded. + * + * @fires complete + * @private + */ +Loader.prototype._onComplete = function () { + this.emit('complete', this, this.resources); +}; + +/** + * Called each time a resources is loaded. + * + * @fires progress + * @fires error + * @fires load + * @private + */ +Loader.prototype._onLoad = function (resource) { + this.progress += this._progressChunk; + + this.emit('progress', this, resource); + + // run middleware, this *must* happen before dequeue so sub-assets get added properly + this._runMiddleware(resource, this._afterMiddleware, function () { + resource.emit('afterMiddleware', resource); + + this._numToLoad--; + + // do completion check + if (this._numToLoad === 0) { + this.progress = 100; + this._onComplete(); + } + + if (resource.error) { + this.emit('error', resource.error, this, resource); + } + else { + this.emit('load', this, resource); + } + }); + + + + // remove this resource from the async queue + resource._dequeue(); +}; + +/** + * Run middleware functions on a resource. + * + * @private + */ +Loader.prototype._runMiddleware = function (resource, fns, cb) { + var self = this; + + async.eachSeries(fns, function (fn, next) { + fn.call(self, resource, next); + }, cb.bind(this, resource)); +}; + +Loader.LOAD_TYPE = Resource.LOAD_TYPE; +Loader.XHR_READY_STATE = Resource.XHR_READY_STATE; +Loader.XHR_RESPONSE_TYPE = Resource.XHR_RESPONSE_TYPE; + +},{"./Resource":13,"async":1,"eventemitter3":10,"url":8}],13:[function(require,module,exports){ +var EventEmitter = require('eventemitter3'), + _url = require('url'), + // tests is CORS is supported in XHR, if not we need to use XDR + useXdr = !!(window.XDomainRequest && !('withCredentials' in (new XMLHttpRequest()))), + tempAnchor = null; + +/** + * Manages the state and loading of a single resource represented by + * a single URL. + * + * @class + * @param name {string} The name of the resource to load. + * @param url {string|string[]} The url for this resource, for audio/video loads you can pass an array of sources. + * @param [options] {object} The options for the load. + * @param [options.crossOrigin] {boolean} Is this request cross-origin? Default is to determine automatically. + * @param [options.loadType=Resource.LOAD_TYPE.XHR] {Resource.LOAD_TYPE} How should this resource be loaded? + * @param [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] {Resource.XHR_RESPONSE_TYPE} How should the data being + * loaded be interpreted when using XHR? + */ +function Resource(name, url, options) { + EventEmitter.call(this); + + options = options || {}; + + if (typeof name !== 'string' || typeof url !== 'string') { + throw new Error('Both name and url are required for constructing a resource.'); + } + + /** + * The name of this resource. + * + * @member {string} + * @readonly + */ + this.name = name; + + /** + * The url used to load this resource. + * + * @member {string} + * @readonly + */ + this.url = url; + + /** + * Stores whether or not this url is a data url. + * + * @member {boolean} + * @readonly + */ + this.isDataUrl = this.url.indexOf('data:') === 0; + + /** + * The data that was loaded by the resource. + * + * @member {any} + */ + this.data = null; + + /** + * Is this request cross-origin? If unset, determined automatically. + * + * @member {string} + */ + this.crossOrigin = options.crossOrigin === true ? 'anonymous' : null; + + /** + * The method of loading to use for this resource. + * + * @member {Resource.LOAD_TYPE} + */ + this.loadType = options.loadType || this._determineLoadType(); + + /** + * The type used to load the resource via XHR. If unset, determined automatically. + * + * @member {string} + */ + this.xhrType = options.xhrType; + + /** + * The error that occurred while loading (if any). + * + * @member {Error} + * @readonly + */ + this.error = null; + + /** + * The XHR object that was used to load this resource. This is only set + * when `loadType` is `Resource.LOAD_TYPE.XHR`. + * + * @member {XMLHttpRequest} + */ + this.xhr = null; + + /** + * Describes if this resource was loaded as json. Only valid after the resource + * has completely loaded. + * + * @member {boolean} + */ + this.isJson = false; + + /** + * Describes if this resource was loaded as xml. Only valid after the resource + * has completely loaded. + * + * @member {boolean} + */ + this.isXml = false; + + /** + * Describes if this resource was loaded as an image tag. Only valid after the resource + * has completely loaded. + * + * @member {boolean} + */ + this.isImage = false; + + /** + * Describes if this resource was loaded as an audio tag. Only valid after the resource + * has completely loaded. + * + * @member {boolean} + */ + this.isAudio = false; + + /** + * Describes if this resource was loaded as a video tag. Only valid after the resource + * has completely loaded. + * + * @member {boolean} + */ + this.isVideo = false; + + /** + * The `dequeue` method that will be used a storage place for the async queue dequeue method + * used privately by the loader. + * + * @member {function} + * @private + */ + this._dequeue = null; + + /** + * The `complete` function bound to this resource's context. + * + * @member {function} + * @private + */ + this._boundComplete = this.complete.bind(this); + + /** + * The `_onError` function bound to this resource's context. + * + * @member {function} + * @private + */ + this._boundOnError = this._onError.bind(this); + + /** + * The `_onProgress` function bound to this resource's context. + * + * @member {function} + * @private + */ + this._boundOnProgress = this._onProgress.bind(this); + + // xhr callbacks + this._boundXhrOnError = this._xhrOnError.bind(this); + this._boundXhrOnAbort = this._xhrOnAbort.bind(this); + this._boundXhrOnLoad = this._xhrOnLoad.bind(this); + this._boundXdrOnTimeout = this._xdrOnTimeout.bind(this); + + /** + * Emitted when the resource beings to load. + * + * @event start + * @memberof Resource# + */ + + /** + * Emitted each time progress of this resource load updates. + * Not all resources types and loader systems can support this event + * so sometimes it may not be available. If the resource + * is being loaded on a modern browser, using XHR, and the remote server + * properly sets Content-Length headers, then this will be available. + * + * @event progress + * @memberof Resource# + */ + + /** + * Emitted once this resource has loaded, if there was an error it will + * be in the `error` property. + * + * @event complete + * @memberof Resource# + */ +} + +Resource.prototype = Object.create(EventEmitter.prototype); +Resource.prototype.constructor = Resource; +module.exports = Resource; + +/** + * Marks the resource as complete. + * + * @fires complete + */ +Resource.prototype.complete = function () { + // TODO: Clean this up in a wrapper or something...gross.... + if (this.data && this.data.removeEventListener) { + this.data.removeEventListener('error', this._boundOnError); + this.data.removeEventListener('load', this._boundComplete); + this.data.removeEventListener('progress', this._boundOnProgress); + this.data.removeEventListener('canplaythrough', this._boundComplete); + } + + if (this.xhr) { + if (this.xhr.removeEventListener) { + this.xhr.removeEventListener('error', this._boundXhrOnError); + this.xhr.removeEventListener('abort', this._boundXhrOnAbort); + this.xhr.removeEventListener('progress', this._boundOnProgress); + this.xhr.removeEventListener('load', this._boundXhrOnLoad); + } + else { + this.xhr.onerror = null; + this.xhr.ontimeout = null; + this.xhr.onprogress = null; + this.xhr.onload = null; + } + } + + this.emit('complete', this); +}; + +/** + * Kicks off loading of this resource. + * + * @fires start + * @param [callback] {function} Optional callback to call once the resource is loaded. + */ +Resource.prototype.load = function (cb) { + this.emit('start', this); + + // if a callback is set, listen for complete event + if (cb) { + this.once('complete', cb); + } + + // if unset, determine the value + if (typeof this.crossOrigin !== 'string') { + this.crossOrigin = this._determineCrossOrigin(this.url); + } + + switch(this.loadType) { + case Resource.LOAD_TYPE.IMAGE: + this._loadImage(); + break; + + case Resource.LOAD_TYPE.AUDIO: + this._loadElement('audio'); + break; + + case Resource.LOAD_TYPE.VIDEO: + this._loadElement('video'); + break; + + case Resource.LOAD_TYPE.XHR: + /* falls through */ + default: + if (useXdr && this.crossOrigin) { + this._loadXdr(); + } + else { + this._loadXhr(); + } + break; + } +}; + +/** + * Loads this resources using an Image object. + * + * @private + */ +Resource.prototype._loadImage = function () { + this.data = new Image(); + + if (this.crossOrigin) { + this.data.crossOrigin = this.crossOrigin; + } + + this.data.src = this.url; + + this.isImage = true; + + this.data.addEventListener('error', this._boundOnError, false); + this.data.addEventListener('load', this._boundComplete, false); + this.data.addEventListener('progress', this._boundOnProgress, false); +}; + +/** + * Loads this resources using an HTMLAudioElement or HTMLVideoElement. + * + * @private + */ +Resource.prototype._loadElement = function (type) { + if (type === 'audio' && typeof Audio !== 'undefined') { + this.data = new Audio(); + } + else { + this.data = document.createElement(type); + } + + if (this.data === null) { + this.error = new Error('Unsupported element ' + type); + this.complete(); + return; + } + + // support for CocoonJS Canvas+ runtime, lacks document.createElement('source') + if (navigator.isCocoonJS) { + this.data.src = Array.isArray(this.url) ? this.url[0] : this.url; + } + else { + if (Array.isArray(this.url)) { + for (var i = 0; i < this.url.length; ++i) { + this.data.appendChild(this._createSource(type, this.url[i])); + } + } + else { + this.data.appendChild(this._createSource(type, this.url)); + } + } + + this['is' + type[0].toUpperCase() + type.substring(1)] = true; + + this.data.addEventListener('error', this._boundOnError, false); + this.data.addEventListener('load', this._boundComplete, false); + this.data.addEventListener('progress', this._boundOnProgress, false); + this.data.addEventListener('canplaythrough', this._boundComplete, false); + + this.data.load(); +}; + +/** + * Loads this resources using an XMLHttpRequest. + * + * @private + */ +Resource.prototype._loadXhr = function () { + // if unset, determine the value + if (typeof this.xhrType !== 'string') { + this.xhrType = this._determineXhrType(); + } + + var xhr = this.xhr = new XMLHttpRequest(); + + // set the request type and url + xhr.open('GET', this.url, true); + + // load json as text and parse it ourselves. We do this because some browsers + // *cough* safari *cough* can't deal with it. + if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON || this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { + xhr.responseType = Resource.XHR_RESPONSE_TYPE.TEXT; + } + else { + xhr.responseType = this.xhrType; + } + + xhr.addEventListener('error', this._boundXhrOnError, false); + xhr.addEventListener('abort', this._boundXhrOnAbort, false); + xhr.addEventListener('progress', this._boundOnProgress, false); + xhr.addEventListener('load', this._boundXhrOnLoad, false); + + xhr.send(); +}; + +/** + * Loads this resources using an XDomainRequest. This is here because we need to support IE9 (gross). + * + * @private + */ +Resource.prototype._loadXdr = function () { + // if unset, determine the value + if (typeof this.xhrType !== 'string') { + this.xhrType = this._determineXhrType(); + } + + var xdr = this.xhr = new XDomainRequest(); + + // XDomainRequest has a few quirks. Occasionally it will abort requests + // A way to avoid this is to make sure ALL callbacks are set even if not used + // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9 + xdr.timeout = 5000; + + xdr.onerror = this._boundXhrOnError; + xdr.ontimeout = this._boundXdrOnTimeout; + xdr.onprogress = this._boundOnProgress; + xdr.onload = this._boundXhrOnLoad; + + xdr.open('GET', this.url, true); + + // Note: The xdr.send() call is wrapped in a timeout to prevent an issue with the interface where some requests are lost + // if multiple XDomainRequests are being sent at the same time. + // Some info here: https://github.com/photonstorm/phaser/issues/1248 + setTimeout(function () { + xdr.send(); + }, 0); +}; + +/** + * Creates a source used in loading via an element. + * + * @param type {string} The element type (video or audio). + * @param url {string} The source URL to load from. + * @param [mime] {string} The mime type of the video + * @private + */ +Resource.prototype._createSource = function (type, url, mime) { + if (!mime) { + mime = type + '/' + url.substr(url.lastIndexOf('.') + 1); + } + + var source = document.createElement('source'); + + source.src = url; + source.type = mime; + + return source; +}; + +/** + * Called if a load errors out. + * + * @param event {Event} The error event from the element that emits it. + * @private + */ +Resource.prototype._onError = function (event) { + this.error = new Error('Failed to load element using ' + event.target.nodeName); + this.complete(); +}; + +/** + * Called if a load progress event fires for xhr/xdr. + * + * @fires progress + * @param event {XMLHttpRequestProgressEvent|Event} + * @private + */ +Resource.prototype._onProgress = function (event) { + if (event && event.lengthComputable) { + this.emit('progress', this, event.loaded / event.total); + } +}; + +/** + * Called if an error event fires for xhr/xdr. + * + * @param event {XMLHttpRequestErrorEvent|Event} + * @private + */ +Resource.prototype._xhrOnError = function () { + this.error = new Error( + reqType(this.xhr) + ' Request failed. ' + + 'Status: ' + this.xhr.status + ', text: "' + this.xhr.statusText + '"' + ); + + this.complete(); +}; + +/** + * Called if an abort event fires for xhr. + * + * @param event {XMLHttpRequestAbortEvent} + * @private + */ +Resource.prototype._xhrOnAbort = function () { + this.error = new Error(reqType(this.xhr) + ' Request was aborted by the user.'); + this.complete(); +}; + +/** + * Called if a timeout event fires for xdr. + * + * @param event {Event} + * @private + */ +Resource.prototype._xdrOnTimeout = function () { + this.error = new Error(reqType(this.xhr) + ' Request timed out.'); + this.complete(); +}; + +/** + * Called when data successfully loads from an xhr/xdr request. + * + * @param event {XMLHttpRequestLoadEvent|Event} + * @private + */ +Resource.prototype._xhrOnLoad = function () { + var xhr = this.xhr, + status = xhr.status !== undefined ? xhr.status : 200; //XDR has no `.status`, assume 200. + + // status can be 0 when using the file:// protocol, also check if a response was found + if (status === 200 || status === 204 || (status === 0 && xhr.responseText.length > 0)) { + // if text, just return it + if (this.xhrType === Resource.XHR_RESPONSE_TYPE.TEXT) { + this.data = xhr.responseText; + } + // if json, parse into json object + else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON) { + try { + this.data = JSON.parse(xhr.responseText); + this.isJson = true; + } catch(e) { + this.error = new Error('Error trying to parse loaded json:', e); + } + } + // if xml, parse into an xml document or div element + else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) { + try { + if (window.DOMParser) { + var domparser = new DOMParser(); + this.data = domparser.parseFromString(xhr.responseText, 'text/xml'); + } + else { + var div = document.createElement('div'); + div.innerHTML = xhr.responseText; + this.data = div; + } + this.isXml = true; + } catch (e) { + this.error = new Error('Error trying to parse loaded xml:', e); + } + } + // other types just return the response + else { + this.data = xhr.response || xhr.responseText; + } + } + else { + this.error = new Error('[' + xhr.status + ']' + xhr.statusText + ':' + xhr.responseURL); + } + + this.complete(); +}; + +function reqType(xhr) { + return xhr.toString().replace('object ', ''); +} + +/** + * Sets the `crossOrigin` property for this resource based on if the url + * for this resource is cross-origin. If crossOrigin was manually set, this + * function does nothing. + * + * @private + * @param url {string} The url to test. + * @param [location=window.location] {object} The location object to test against. + * @return {string} The crossOrigin value to use (or empty string for none). + */ +Resource.prototype._determineCrossOrigin = function (url, loc) { + // data: and javascript: urls are considered same-origin + if (url.indexOf('data:') === 0) { + return ''; + } + + // default is window.location + loc = loc || window.location; + + if (!tempAnchor) { + tempAnchor = document.createElement('a'); + } + + // let the browser determine the full href for the url of this resource and then + // parse with the node url lib, we can't use the properties of the anchor element + // because they don't work in IE9 :( + tempAnchor.href = url; + url = _url.parse(tempAnchor.href); + + var samePort = (!url.port && loc.port === '') || (url.port === loc.port); + + // if cross origin + if (url.hostname !== loc.hostname || !samePort || url.protocol !== loc.protocol) { + return 'anonymous'; + } + + return ''; +}; + +/** + * Determines the responseType of an XHR request based on the extension of the + * resource being loaded. + * + * @private + * @return {Resource.XHR_RESPONSE_TYPE} The responseType to use. + */ +Resource.prototype._determineXhrType = function () { + return Resource._xhrTypeMap[this._getExtension()] || Resource.XHR_RESPONSE_TYPE.TEXT; +}; + +Resource.prototype._determineLoadType = function () { + return Resource._loadTypeMap[this._getExtension()] || Resource.LOAD_TYPE.XHR; +}; + +Resource.prototype._getExtension = function () { + var url = this.url, + ext; + + if (this.isDataUrl) { + var slashIndex = url.indexOf('/'); + ext = url.substring(slashIndex + 1, url.indexOf(';', slashIndex)); + } + else { + var queryStart = url.indexOf('?'); + if (queryStart !== -1) { + url = url.substring(0, queryStart); + } + + ext = url.substring(url.lastIndexOf('.') + 1); + } + + return ext; +}; + +/** + * Determines the mime type of an XHR request based on the responseType of + * resource being loaded. + * + * @private + * @return {string} The mime type to use. + */ +Resource.prototype._getMimeFromXhrType = function (type) { + switch(type) { + case Resource.XHR_RESPONSE_TYPE.BUFFER: + return 'application/octet-binary'; + + case Resource.XHR_RESPONSE_TYPE.BLOB: + return 'application/blob'; + + case Resource.XHR_RESPONSE_TYPE.DOCUMENT: + return 'application/xml'; + + case Resource.XHR_RESPONSE_TYPE.JSON: + return 'application/json'; + + case Resource.XHR_RESPONSE_TYPE.DEFAULT: + case Resource.XHR_RESPONSE_TYPE.TEXT: + /* falls through */ + default: + return 'text/plain'; + + } +}; + +/** + * The types of loading a resource can use. + * + * @static + * @constant + * @property {object} LOAD_TYPE + * @property {number} LOAD_TYPE.XHR - Uses XMLHttpRequest to load the resource. + * @property {number} LOAD_TYPE.IMAGE - Uses an `Image` object to load the resource. + * @property {number} LOAD_TYPE.AUDIO - Uses an `Audio` object to load the resource. + * @property {number} LOAD_TYPE.VIDEO - Uses a `Video` object to load the resource. + */ +Resource.LOAD_TYPE = { + XHR: 1, + IMAGE: 2, + AUDIO: 3, + VIDEO: 4 +}; + +/** + * The XHR ready states, used internally. + * + * @static + * @constant + * @property {object} XHR_READY_STATE + * @property {number} XHR_READY_STATE.UNSENT - open()has not been called yet. + * @property {number} XHR_READY_STATE.OPENED - send()has not been called yet. + * @property {number} XHR_READY_STATE.HEADERS_RECEIVED - send() has been called, and headers and status are available. + * @property {number} XHR_READY_STATE.LOADING - Downloading; responseText holds partial data. + * @property {number} XHR_READY_STATE.DONE - The operation is complete. + */ +Resource.XHR_READY_STATE = { + UNSENT: 0, + OPENED: 1, + HEADERS_RECEIVED: 2, + LOADING: 3, + DONE: 4 +}; + +/** + * The XHR ready states, used internally. + * + * @static + * @constant + * @property {object} XHR_RESPONSE_TYPE + * @property {string} XHR_RESPONSE_TYPE.DEFAULT - defaults to text + * @property {string} XHR_RESPONSE_TYPE.BUFFER - ArrayBuffer + * @property {string} XHR_RESPONSE_TYPE.BLOB - Blob + * @property {string} XHR_RESPONSE_TYPE.DOCUMENT - Document + * @property {string} XHR_RESPONSE_TYPE.JSON - Object + * @property {string} XHR_RESPONSE_TYPE.TEXT - String + */ +Resource.XHR_RESPONSE_TYPE = { + DEFAULT: 'text', + BUFFER: 'arraybuffer', + BLOB: 'blob', + DOCUMENT: 'document', + JSON: 'json', + TEXT: 'text' +}; + +Resource._loadTypeMap = { + 'gif': Resource.LOAD_TYPE.IMAGE, + 'png': Resource.LOAD_TYPE.IMAGE, + 'bmp': Resource.LOAD_TYPE.IMAGE, + 'jpg': Resource.LOAD_TYPE.IMAGE, + 'jpeg': Resource.LOAD_TYPE.IMAGE, + 'tif': Resource.LOAD_TYPE.IMAGE, + 'tiff': Resource.LOAD_TYPE.IMAGE, + 'webp': Resource.LOAD_TYPE.IMAGE, + 'tga': Resource.LOAD_TYPE.IMAGE +}; + +Resource._xhrTypeMap = { + // xml + 'xhtml': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'html': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'htm': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'xml': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'tmx': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'tsx': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + 'svg': Resource.XHR_RESPONSE_TYPE.DOCUMENT, + + // images + 'gif': Resource.XHR_RESPONSE_TYPE.BLOB, + 'png': Resource.XHR_RESPONSE_TYPE.BLOB, + 'bmp': Resource.XHR_RESPONSE_TYPE.BLOB, + 'jpg': Resource.XHR_RESPONSE_TYPE.BLOB, + 'jpeg': Resource.XHR_RESPONSE_TYPE.BLOB, + 'tif': Resource.XHR_RESPONSE_TYPE.BLOB, + 'tiff': Resource.XHR_RESPONSE_TYPE.BLOB, + 'webp': Resource.XHR_RESPONSE_TYPE.BLOB, + 'tga': Resource.XHR_RESPONSE_TYPE.BLOB, + + // json + 'json': Resource.XHR_RESPONSE_TYPE.JSON, + + // text + 'text': Resource.XHR_RESPONSE_TYPE.TEXT, + 'txt': Resource.XHR_RESPONSE_TYPE.TEXT +}; + +/** + * Sets the load type to be used for a specific extension. + * + * @static + * @param extname {string} The extension to set the type for, e.g. "png" or "fnt" + * @param loadType {Resource.LOAD_TYPE} The load type to set it to. + */ +Resource.setExtensionLoadType = function (extname, loadType) { + setExtMap(Resource._loadTypeMap, extname, loadType); +}; + +/** + * Sets the load type to be used for a specific extension. + * + * @static + * @param extname {string} The extension to set the type for, e.g. "png" or "fnt" + * @param xhrType {Resource.XHR_RESPONSE_TYPE} The xhr type to set it to. + */ +Resource.setExtensionXhrType = function (extname, xhrType) { + setExtMap(Resource._xhrTypeMap, extname, xhrType); +}; + +function setExtMap(map, extname, val) { + if (extname && extname.indexOf('.') === 0) { + extname = extname.substring(1); + } + + if (!extname) { + return; + } + + map[extname] = val; +} + +},{"eventemitter3":10,"url":8}],14:[function(require,module,exports){ +module.exports = { + + // private property + _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + encodeBinary: function (input) { + var output = ""; + var bytebuffer; + var encodedCharIndexes = new Array(4); + var inx = 0; + var jnx = 0; + var paddingBytes = 0; + + while (inx < input.length) { + // Fill byte buffer array + bytebuffer = new Array(3); + for (jnx = 0; jnx < bytebuffer.length; jnx++) { + if (inx < input.length) { + // throw away high-order byte, as documented at: + // https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data + bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; + } + else { + bytebuffer[jnx] = 0; + } + } + + // Get each encoded character, 6 bits at a time + // index 1: first 6 bits + encodedCharIndexes[0] = bytebuffer[0] >> 2; + // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2) + encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4); + // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3) + encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6); + // index 3: forth 6 bits (6 least significant bits from input byte 3) + encodedCharIndexes[3] = bytebuffer[2] & 0x3f; + + // Determine whether padding happened, and adjust accordingly + paddingBytes = inx - (input.length - 1); + switch (paddingBytes) { + case 2: + // Set last 2 characters to padding char + encodedCharIndexes[3] = 64; + encodedCharIndexes[2] = 64; + break; + + case 1: + // Set last character to padding char + encodedCharIndexes[3] = 64; + break; + + default: + break; // No padding - proceed + } + + // Now we will grab each appropriate character out of our keystring + // based on our index array and append it to the output string + for (jnx = 0; jnx < encodedCharIndexes.length; jnx++) { + output += this._keyStr.charAt(encodedCharIndexes[jnx]); + } + } + return output; + } +}; + +},{}],15:[function(require,module,exports){ +module.exports = require('./Loader'); + +module.exports.Resource = require('./Resource'); + +module.exports.middleware = { + caching: { + memory: require('./middlewares/caching/memory') + }, + parsing: { + blob: require('./middlewares/parsing/blob') + } +}; + +},{"./Loader":12,"./Resource":13,"./middlewares/caching/memory":16,"./middlewares/parsing/blob":17}],16:[function(require,module,exports){ +// a simple in-memory cache for resources +var cache = {}; + +module.exports = function () { + return function (resource, next) { + // if cached, then set data and complete the resource + if (cache[resource.url]) { + resource.data = cache[resource.url]; + resource.complete(); + } + // if not cached, wait for complete and store it in the cache. + else { + resource.once('complete', function () { + cache[this.url] = this.data; + }); + + next(); + } + }; +}; + +},{}],17:[function(require,module,exports){ +var Resource = require('../../Resource'), + b64 = require('../../b64'); + +window.URL = window.URL || window.webkitURL; + +// a middleware for transforming XHR loaded Blobs into more useful objects + +module.exports = function () { + return function (resource, next) { + if (!resource.data) { + return next(); + } + + // if this was an XHR load of a blob + if (resource.xhr && resource.xhrType === Resource.XHR_RESPONSE_TYPE.BLOB) { + // if there is no blob support we probably got a binary string back + if (!window.Blob || typeof resource.data === 'string') { + var type = resource.xhr.getResponseHeader('content-type'); + + // this is an image, convert the binary string into a data url + if (type && type.indexOf('image') === 0) { + resource.data = new Image(); + resource.data.src = 'data:' + type + ';base64,' + b64.encodeBinary(resource.xhr.responseText); + + resource.isImage = true; + + // wait until the image loads and then callback + resource.data.onload = function () { + resource.data.onload = null; + + next(); + }; + } + } + // if content type says this is an image, then we should transform the blob into an Image object + else if (resource.data.type.indexOf('image') === 0) { + var src = URL.createObjectURL(resource.data); + + resource.blob = resource.data; + resource.data = new Image(); + resource.data.src = src; + + resource.isImage = true; + + // cleanup the no longer used blob after the image loads + resource.data.onload = function () { + URL.revokeObjectURL(src); + resource.data.onload = null; + + next(); + }; + } + } + else { + next(); + } + }; +}; + +},{"../../Resource":13,"../../b64":14}],18:[function(require,module,exports){ module.exports={ "name": "pixi.js", - "version": "3.0.8", + "version": "3.0.9-dev", "description": "Pixi.js is a fast lightweight 2D library that works across all devices.", "author": "Mat Groves", "contributors": [ @@ -4048,7 +5462,7 @@ } } -},{}],13:[function(require,module,exports){ +},{}],19:[function(require,module,exports){ /** * Constant values used in pixi * @@ -4271,7 +5685,7 @@ module.exports = CONST; -},{"../../package.json":12}],14:[function(require,module,exports){ +},{"../../package.json":18}],20:[function(require,module,exports){ var math = require('../math'), DisplayObject = require('./DisplayObject'), RenderTexture = require('../textures/RenderTexture'), @@ -4377,13 +5791,43 @@ /** * Adds a child to the container. - * + * + * You can also add multple items like so: myContainer.addChild(thinkOne, thingTwo, thingThree) * @param child {PIXI.DisplayObject} The DisplayObject to add to the container * @return {PIXI.DisplayObject} The child that was added. */ Container.prototype.addChild = function (child) -{ - return this.addChildAt(child, this.children.length); +{ + var argumentsLength = arguments.length; + + // if there is only one argument we can bypass looping through the them + if(argumentsLength > 1) + { + // loop through the arguments property and add all children + // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes + for (var i = 0; i < argumentsLength; i++) + { + this.addChild( arguments[i] ); + } + } + else + { + // if the child has a parent then lets remove it as Pixi objects can only exist in one place + if (child.parent) + { + child.parent.removeChild(child); + } + + child.parent = this; + + this.children.push(child); + + // TODO - lets either do all callbacks or all events.. not both! + this.onChildrenChange(this.children.length-1); + child.emit('added', this); + } + + return child; }; /** @@ -4395,12 +5839,6 @@ */ Container.prototype.addChildAt = function (child, index) { - // prevent adding self as child - if (child === this) - { - return child; - } - if (index >= 0 && index <= this.children.length) { if (child.parent) @@ -4411,8 +5849,9 @@ child.parent = this; this.children.splice(index, 0, child); - this.onChildrenChange(index); + // TODO - lets either do all callbacks or all events.. not both! + this.onChildrenChange(index); child.emit('added', this); return child; @@ -4511,14 +5950,36 @@ */ Container.prototype.removeChild = function (child) { - var index = this.children.indexOf(child); + var argumentsLength = arguments.length; - if (index === -1) + // if there is only one argument we can bypass looping through the them + if(argumentsLength > 1) { - return; + // loop through the arguments property and add all children + // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes + for (var i = 0; i < argumentsLength; i++) + { + this.removeChild( arguments[i] ); + } + } + else + { + var index = this.children.indexOf(child); + + if (index === -1) + { + return; + } + + child.parent = null; + this.children.splice(index, 1); + + // TODO - lets either do all callbacks or all events.. not both! + this.onChildrenChange(index); + child.emit('removed', this); } - return this.removeChildAt(index); + return child; }; /** @@ -4533,8 +5994,9 @@ child.parent = null; this.children.splice(index, 1); - this.onChildrenChange(index); + // TODO - lets either do all callbacks or all events.. not both! + this.onChildrenChange(index); child.emit('removed', this); return child; @@ -4866,7 +6328,7 @@ this.children = null; }; -},{"../math":23,"../textures/RenderTexture":61,"./DisplayObject":15}],15:[function(require,module,exports){ +},{"../math":29,"../textures/RenderTexture":67,"./DisplayObject":21}],21:[function(require,module,exports){ var math = require('../math'), RenderTexture = require('../textures/RenderTexture'), EventEmitter = require('eventemitter3'), @@ -4908,6 +6370,14 @@ */ this.pivot = new math.Point(0, 0); + + /** + * The skew factor for the object in radians. + * + * @member {PIXI.Point} + */ + this.skew = new math.Point(0, 0); + /** * The rotation of the object in radians. * @@ -5133,7 +6603,6 @@ */ DisplayObject.prototype.updateTransform = function () { - // create some matrix refs for easy access var pt = this.parent.worldTransform; var wt = this.worldTransform; @@ -5141,55 +6610,81 @@ // temporary matrix variables var a, b, c, d, tx, ty; - // so if rotation is between 0 then we can simplify the multiplication process... - if (this.rotation % CONST.PI_2) + // looks like we are skewing + if(this.skew.x || this.skew.y) { - // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes - if (this.rotation !== this.rotationCache) - { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } + // I'm assuming that skewing is not going to be very common + // With that in mind, we can do a full setTransform using the temp matrix + _tempMatrix.setTransform(this.position.x + ,this.position.y + ,this.pivot.x + ,this.pivot.y + ,this.scale.x + ,this.scale.y + ,this.rotation + ,this.skew.x + ,this.skew.y ); - // get the matrix values of the displayobject based on its transform properties.. - a = this._cr * this.scale.x; - b = this._sr * this.scale.x; - c = -this._sr * this.scale.y; - d = this._cr * this.scale.y; - tx = this.position.x; - ty = this.position.y; - - // check for pivot.. not often used so geared towards that fact! - if (this.pivot.x || this.pivot.y) - { - tx -= this.pivot.x * a + this.pivot.y * c; - ty -= this.pivot.x * b + this.pivot.y * d; - } - - // concat the parent matrix with the objects transform. - wt.a = a * pt.a + b * pt.c; - wt.b = a * pt.b + b * pt.d; - wt.c = c * pt.a + d * pt.c; - wt.d = c * pt.b + d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; + // now concat the matrix (inlined so that we can avoid using copy) + wt.a = _tempMatrix.a * pt.a + _tempMatrix.b * pt.c; + wt.b = _tempMatrix.a * pt.b + _tempMatrix.b * pt.d; + wt.c = _tempMatrix.c * pt.a + _tempMatrix.d * pt.c; + wt.d = _tempMatrix.c * pt.b + _tempMatrix.d * pt.d; + wt.tx = _tempMatrix.tx * pt.a + _tempMatrix.ty * pt.c + pt.tx; + wt.ty = _tempMatrix.tx * pt.b + _tempMatrix.ty * pt.d + pt.ty; } else { - // lets do the fast version as we know there is no rotation.. - a = this.scale.x; - d = this.scale.y; + // so if rotation is between 0 then we can simplify the multiplication process... + if (this.rotation % CONST.PI_2) + { + // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes + if (this.rotation !== this.rotationCache) + { + this.rotationCache = this.rotation; + this._sr = Math.sin(this.rotation); + this._cr = Math.cos(this.rotation); + } - tx = this.position.x - this.pivot.x * a; - ty = this.position.y - this.pivot.y * d; + // get the matrix values of the displayobject based on its transform properties.. + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + tx = this.position.x; + ty = this.position.y; - wt.a = a * pt.a; - wt.b = a * pt.b; - wt.c = d * pt.c; - wt.d = d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; + // check for pivot.. not often used so geared towards that fact! + if (this.pivot.x || this.pivot.y) + { + tx -= this.pivot.x * a + this.pivot.y * c; + ty -= this.pivot.x * b + this.pivot.y * d; + } + + // concat the parent matrix with the objects transform. + wt.a = a * pt.a + b * pt.c; + wt.b = a * pt.b + b * pt.d; + wt.c = c * pt.a + d * pt.c; + wt.d = c * pt.b + d * pt.d; + wt.tx = tx * pt.a + ty * pt.c + pt.tx; + wt.ty = tx * pt.b + ty * pt.d + pt.ty; + } + else + { + // lets do the fast version as we know there is no rotation.. + a = this.scale.x; + d = this.scale.y; + + tx = this.position.x - this.pivot.x * a; + ty = this.position.y - this.pivot.y * d; + + wt.a = a * pt.a; + wt.b = a * pt.b; + wt.c = d * pt.c; + wt.d = d * pt.d; + wt.tx = tx * pt.a + ty * pt.c + pt.tx; + wt.ty = tx * pt.b + ty * pt.d + pt.ty; + } } // multiply the alphas.. @@ -5354,7 +6849,8 @@ this.position = null; this.scale = null; this.pivot = null; - + this.skew = null; + this.parent = null; this._bounds = null; @@ -5365,7 +6861,7 @@ this.filterArea = null; }; -},{"../const":13,"../math":23,"../textures/RenderTexture":61,"eventemitter3":10}],16:[function(require,module,exports){ +},{"../const":19,"../math":29,"../textures/RenderTexture":67,"eventemitter3":10}],22:[function(require,module,exports){ var Container = require('../display/Container'), Texture = require('../textures/Texture'), CanvasBuffer = require('../renderers/canvas/utils/CanvasBuffer'), @@ -6550,7 +8046,7 @@ this._localBounds = null; }; -},{"../const":13,"../display/Container":14,"../math":23,"../renderers/canvas/utils/CanvasBuffer":35,"../renderers/canvas/utils/CanvasGraphics":36,"../textures/Texture":62,"./GraphicsData":17}],17:[function(require,module,exports){ +},{"../const":19,"../display/Container":20,"../math":29,"../renderers/canvas/utils/CanvasBuffer":41,"../renderers/canvas/utils/CanvasGraphics":42,"../textures/Texture":68,"./GraphicsData":23}],23:[function(require,module,exports){ /** * A GraphicsData object. * @@ -6643,7 +8139,7 @@ this.shape = null; }; -},{}],18:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ var utils = require('../../utils'), math = require('../../math'), CONST = require('../../const'), @@ -6721,7 +8217,7 @@ var shader = renderer.shaderManager.plugins.primitiveShader, webGLData; - if (graphics.dirty) + if (graphics.dirty || !graphics._webGL[gl.id]) { this.updateGraphics(graphics); } @@ -7548,7 +9044,7 @@ return true; }; -},{"../../const":13,"../../math":23,"../../renderers/webgl/WebGLRenderer":39,"../../renderers/webgl/utils/ObjectRenderer":53,"../../utils":67,"./WebGLGraphicsData":19,"earcut":9}],19:[function(require,module,exports){ +},{"../../const":19,"../../math":29,"../../renderers/webgl/WebGLRenderer":45,"../../renderers/webgl/utils/ObjectRenderer":59,"../../utils":73,"./WebGLGraphicsData":25,"earcut":9}],25:[function(require,module,exports){ /** * An object containing WebGL specific properties to be used by the WebGL renderer * @@ -7666,7 +9162,7 @@ this.glIndices = null; }; -},{}],20:[function(require,module,exports){ +},{}],26:[function(require,module,exports){ /** * @file Main export of the PIXI core library * @author Mat Groves @@ -7758,7 +9254,7 @@ } }); -},{"./const":13,"./display/Container":14,"./display/DisplayObject":15,"./graphics/Graphics":16,"./graphics/GraphicsData":17,"./graphics/webgl/GraphicsRenderer":18,"./math":23,"./particles/ParticleContainer":29,"./particles/webgl/ParticleRenderer":31,"./renderers/canvas/CanvasRenderer":34,"./renderers/canvas/utils/CanvasBuffer":35,"./renderers/canvas/utils/CanvasGraphics":36,"./renderers/webgl/WebGLRenderer":39,"./renderers/webgl/filters/AbstractFilter":40,"./renderers/webgl/filters/FXAAFilter":41,"./renderers/webgl/filters/SpriteMaskFilter":42,"./renderers/webgl/managers/ShaderManager":46,"./renderers/webgl/shaders/Shader":51,"./renderers/webgl/utils/ObjectRenderer":53,"./renderers/webgl/utils/RenderTarget":55,"./sprites/Sprite":57,"./sprites/webgl/SpriteRenderer":58,"./text/Text":59,"./textures/BaseTexture":60,"./textures/RenderTexture":61,"./textures/Texture":62,"./textures/TextureUvs":63,"./textures/VideoBaseTexture":64,"./ticker":66,"./utils":67}],21:[function(require,module,exports){ +},{"./const":19,"./display/Container":20,"./display/DisplayObject":21,"./graphics/Graphics":22,"./graphics/GraphicsData":23,"./graphics/webgl/GraphicsRenderer":24,"./math":29,"./particles/ParticleContainer":35,"./particles/webgl/ParticleRenderer":37,"./renderers/canvas/CanvasRenderer":40,"./renderers/canvas/utils/CanvasBuffer":41,"./renderers/canvas/utils/CanvasGraphics":42,"./renderers/webgl/WebGLRenderer":45,"./renderers/webgl/filters/AbstractFilter":46,"./renderers/webgl/filters/FXAAFilter":47,"./renderers/webgl/filters/SpriteMaskFilter":48,"./renderers/webgl/managers/ShaderManager":52,"./renderers/webgl/shaders/Shader":57,"./renderers/webgl/utils/ObjectRenderer":59,"./renderers/webgl/utils/RenderTarget":61,"./sprites/Sprite":63,"./sprites/webgl/SpriteRenderer":64,"./text/Text":65,"./textures/BaseTexture":66,"./textures/RenderTexture":67,"./textures/Texture":68,"./textures/TextureUvs":69,"./textures/VideoBaseTexture":70,"./ticker":72,"./utils":73}],27:[function(require,module,exports){ var Point = require('./Point'); /** @@ -7835,6 +9331,32 @@ this.ty = array[5]; }; + +/** + * sets the matrix properties + * + * @param {number} a + * @param {number} b + * @param {number} c + * @param {number} d + * @param {number} tx + * @param {number} ty + * + * @return {PIXI.Matrix} This matrix. Good for chaining method calls. + */ +Matrix.prototype.set = function (a, b, c, d, tx, ty) +{ + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + + return this +}; + + /** * Creates an array from the current Matrix object. * @@ -8007,6 +9529,48 @@ }; /** + * Sets the matrix based on all the available properties + * + * @param {number} x + * @param {number} y + * @param {number} pivotX + * @param {number} pivotY + * @param {number} scaleX + * @param {number} scaleY + * @param {number} rotation + * @param {number} skewX + * @param {number} skewY + * + * @return {PIXI.Matrix} This matrix. Good for chaining method calls. + */ +Matrix.prototype.setTransform = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) +{ + var a, b, c, d, tx, ty, sr, cr; + + sr = Math.sin(rotation); + cr = Math.cos(rotation); + cy = Math.cos(skewY); + sy = Math.sin(skewY); + nsx = -Math.sin(skewX); + cx = Math.cos(skewX); + + a = cr * scaleX; + b = sr * scaleX; + c = -sr * scaleY; + d = cr * scaleY; + + this.a = cy * a + sy * c; + this.b = cy * b + sy * d; + this.c = nsx * a + cx * c; + this.d = nsx * b + cx * d; + + this.tx = x + ( pivotX * a + pivotY * c ); + this.ty = y + ( pivotX * b + pivotY * d ); + + return this; +}; + +/** * Prepends the given Matrix to this Matrix. * * @param {PIXI.Matrix} matrix @@ -8125,7 +9689,7 @@ */ Matrix.TEMP_MATRIX = new Matrix(); -},{"./Point":22}],22:[function(require,module,exports){ +},{"./Point":28}],28:[function(require,module,exports){ /** * The Point object represents a location in a two-dimensional coordinate system, where x represents * the horizontal axis and y represents the vertical axis. @@ -8195,7 +9759,7 @@ this.y = y || ( (y !== 0) ? this.x : 0 ) ; }; -},{}],23:[function(require,module,exports){ +},{}],29:[function(require,module,exports){ /** * Math classes and utilities mixed into PIXI namespace. * @@ -8217,7 +9781,7 @@ RoundedRectangle: require('./shapes/RoundedRectangle') }; -},{"./Matrix":21,"./Point":22,"./shapes/Circle":24,"./shapes/Ellipse":25,"./shapes/Polygon":26,"./shapes/Rectangle":27,"./shapes/RoundedRectangle":28}],24:[function(require,module,exports){ +},{"./Matrix":27,"./Point":28,"./shapes/Circle":30,"./shapes/Ellipse":31,"./shapes/Polygon":32,"./shapes/Rectangle":33,"./shapes/RoundedRectangle":34}],30:[function(require,module,exports){ var Rectangle = require('./Rectangle'), CONST = require('../../const'); @@ -8305,7 +9869,7 @@ return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); }; -},{"../../const":13,"./Rectangle":27}],25:[function(require,module,exports){ +},{"../../const":19,"./Rectangle":33}],31:[function(require,module,exports){ var Rectangle = require('./Rectangle'), CONST = require('../../const'); @@ -8400,7 +9964,7 @@ return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); }; -},{"../../const":13,"./Rectangle":27}],26:[function(require,module,exports){ +},{"../../const":19,"./Rectangle":33}],32:[function(require,module,exports){ var Point = require('../Point'), CONST = require('../../const'); @@ -8503,7 +10067,7 @@ return inside; }; -},{"../../const":13,"../Point":22}],27:[function(require,module,exports){ +},{"../../const":19,"../Point":28}],33:[function(require,module,exports){ var CONST = require('../../const'); /** @@ -8597,7 +10161,7 @@ return false; }; -},{"../../const":13}],28:[function(require,module,exports){ +},{"../../const":19}],34:[function(require,module,exports){ var CONST = require('../../const'); /** @@ -8689,7 +10253,7 @@ return false; }; -},{"../../const":13}],29:[function(require,module,exports){ +},{"../../const":19}],35:[function(require,module,exports){ var Container = require('../display/Container'), CONST = require('../const'); @@ -9002,7 +10566,7 @@ this._buffers = null; }; -},{"../const":13,"../display/Container":14}],30:[function(require,module,exports){ +},{"../const":19,"../display/Container":20}],36:[function(require,module,exports){ /** * @author Mat Groves @@ -9222,7 +10786,7 @@ this.gl.deleteBuffer(this.staticBuffer); }; -},{}],31:[function(require,module,exports){ +},{}],37:[function(require,module,exports){ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), ParticleShader = require('./ParticleShader'), @@ -9698,7 +11262,7 @@ this.tempMatrix = null; }; -},{"../../math":23,"../../renderers/webgl/WebGLRenderer":39,"../../renderers/webgl/utils/ObjectRenderer":53,"./ParticleBuffer":30,"./ParticleShader":32}],32:[function(require,module,exports){ +},{"../../math":29,"../../renderers/webgl/WebGLRenderer":45,"../../renderers/webgl/utils/ObjectRenderer":59,"./ParticleBuffer":36,"./ParticleShader":38}],38:[function(require,module,exports){ var TextureShader = require('../../renderers/webgl/shaders/TextureShader'); /** @@ -9776,7 +11340,7 @@ module.exports = ParticleShader; -},{"../../renderers/webgl/shaders/TextureShader":52}],33:[function(require,module,exports){ +},{"../../renderers/webgl/shaders/TextureShader":58}],39:[function(require,module,exports){ var utils = require('../utils'), math = require('../math'), CONST = require('../const'), @@ -10037,7 +11601,7 @@ this._backgroundColorString = null; }; -},{"../const":13,"../math":23,"../utils":67,"eventemitter3":10}],34:[function(require,module,exports){ +},{"../const":19,"../math":29,"../utils":73,"eventemitter3":10}],40:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), CanvasMaskManager = require('./utils/CanvasMaskManager'), utils = require('../../utils'), @@ -10301,7 +11865,7 @@ } }; -},{"../../const":13,"../../math":23,"../../utils":67,"../SystemRenderer":33,"./utils/CanvasMaskManager":37}],35:[function(require,module,exports){ +},{"../../const":19,"../../math":29,"../../utils":73,"../SystemRenderer":39,"./utils/CanvasMaskManager":43}],41:[function(require,module,exports){ /** * Creates a Canvas element of the given size. * @@ -10401,7 +11965,7 @@ this.canvas = null; }; -},{}],36:[function(require,module,exports){ +},{}],42:[function(require,module,exports){ var CONST = require('../../../const'); /** @@ -10755,7 +12319,7 @@ }; -},{"../../../const":13}],37:[function(require,module,exports){ +},{"../../../const":19}],43:[function(require,module,exports){ var CanvasGraphics = require('./CanvasGraphics'); /** @@ -10817,7 +12381,7 @@ CanvasMaskManager.prototype.destroy = function () {}; -},{"./CanvasGraphics":36}],38:[function(require,module,exports){ +},{"./CanvasGraphics":42}],44:[function(require,module,exports){ var utils = require('../../../utils'); /** @@ -11069,7 +12633,7 @@ */ CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply : CanvasTinter.tintWithPerPixel; -},{"../../../utils":67}],39:[function(require,module,exports){ +},{"../../../utils":73}],45:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), @@ -11630,7 +13194,7 @@ } }; -},{"../../const":13,"../../utils":67,"../SystemRenderer":33,"./filters/FXAAFilter":41,"./managers/BlendModeManager":43,"./managers/FilterManager":44,"./managers/MaskManager":45,"./managers/ShaderManager":46,"./managers/StencilManager":47,"./utils/ObjectRenderer":53,"./utils/RenderTarget":55}],40:[function(require,module,exports){ +},{"../../const":19,"../../utils":73,"../SystemRenderer":39,"./filters/FXAAFilter":47,"./managers/BlendModeManager":49,"./managers/FilterManager":50,"./managers/MaskManager":51,"./managers/ShaderManager":52,"./managers/StencilManager":53,"./utils/ObjectRenderer":59,"./utils/RenderTarget":61}],46:[function(require,module,exports){ var DefaultShader = require('../shaders/TextureShader'); /** @@ -11742,7 +13306,7 @@ } }; -},{"../shaders/TextureShader":52}],41:[function(require,module,exports){ +},{"../shaders/TextureShader":58}],47:[function(require,module,exports){ var AbstractFilter = require('./AbstractFilter'); // @see https://github.com/substack/brfs/issues/25 @@ -11797,7 +13361,7 @@ filterManager.applyFilter(shader, input, output); }; -},{"./AbstractFilter":40}],42:[function(require,module,exports){ +},{"./AbstractFilter":46}],48:[function(require,module,exports){ var AbstractFilter = require('./AbstractFilter'), math = require('../../../math'); @@ -11894,7 +13458,7 @@ } }); -},{"../../../math":23,"./AbstractFilter":40}],43:[function(require,module,exports){ +},{"../../../math":29,"./AbstractFilter":46}],49:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'); /** @@ -11938,7 +13502,7 @@ return true; }; -},{"./WebGLManager":48}],44:[function(require,module,exports){ +},{"./WebGLManager":54}],50:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), RenderTarget = require('../utils/RenderTarget'), CONST = require('../../../const'), @@ -12390,7 +13954,7 @@ this.texturePool = null; }; -},{"../../../const":13,"../../../math":23,"../utils/Quad":54,"../utils/RenderTarget":55,"./WebGLManager":48}],45:[function(require,module,exports){ +},{"../../../const":19,"../../../math":29,"../utils/Quad":60,"../utils/RenderTarget":61,"./WebGLManager":54}],51:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), AlphaMaskFilter = require('../filters/SpriteMaskFilter'); @@ -12505,7 +14069,7 @@ }; -},{"../filters/SpriteMaskFilter":42,"./WebGLManager":48}],46:[function(require,module,exports){ +},{"../filters/SpriteMaskFilter":48,"./WebGLManager":54}],52:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), TextureShader = require('../shaders/TextureShader'), ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), @@ -12674,7 +14238,7 @@ this.tempAttribState = null; }; -},{"../../../utils":67,"../shaders/ComplexPrimitiveShader":49,"../shaders/PrimitiveShader":50,"../shaders/TextureShader":52,"./WebGLManager":48}],47:[function(require,module,exports){ +},{"../../../utils":73,"../shaders/ComplexPrimitiveShader":55,"../shaders/PrimitiveShader":56,"../shaders/TextureShader":58,"./WebGLManager":54}],53:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), utils = require('../../../utils'); @@ -13020,7 +14584,7 @@ }; -},{"../../../utils":67,"./WebGLManager":48}],48:[function(require,module,exports){ +},{"../../../utils":73,"./WebGLManager":54}],54:[function(require,module,exports){ /** * @class * @memberof PIXI @@ -13061,7 +14625,7 @@ this.renderer = null; }; -},{}],49:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ var Shader = require('./Shader'); /** @@ -13123,7 +14687,7 @@ ComplexPrimitiveShader.prototype.constructor = ComplexPrimitiveShader; module.exports = ComplexPrimitiveShader; -},{"./Shader":51}],50:[function(require,module,exports){ +},{"./Shader":57}],56:[function(require,module,exports){ var Shader = require('./Shader'); /** @@ -13186,7 +14750,7 @@ PrimitiveShader.prototype.constructor = PrimitiveShader; module.exports = PrimitiveShader; -},{"./Shader":51}],51:[function(require,module,exports){ +},{"./Shader":57}],57:[function(require,module,exports){ /*global console */ var utils = require('../../../utils'); @@ -13750,7 +15314,7 @@ return shader; }; -},{"../../../utils":67}],52:[function(require,module,exports){ +},{"../../../utils":73}],58:[function(require,module,exports){ var Shader = require('./Shader'); /** @@ -13861,7 +15425,7 @@ '}' ].join('\n'); -},{"./Shader":51}],53:[function(require,module,exports){ +},{"./Shader":57}],59:[function(require,module,exports){ var WebGLManager = require('../managers/WebGLManager'); /** @@ -13919,7 +15483,7 @@ // render the object }; -},{"../managers/WebGLManager":48}],54:[function(require,module,exports){ +},{"../managers/WebGLManager":54}],60:[function(require,module,exports){ /** * Helper class to create a quad * @@ -14074,7 +15638,7 @@ -},{}],55:[function(require,module,exports){ +},{}],61:[function(require,module,exports){ var math = require('../../../math'), utils = require('../../../utils'), CONST = require('../../../const'), @@ -14396,7 +15960,7 @@ this.texture = null; }; -},{"../../../const":13,"../../../math":23,"../../../utils":67,"./StencilMaskStack":56}],56:[function(require,module,exports){ +},{"../../../const":19,"../../../math":29,"../../../utils":73,"./StencilMaskStack":62}],62:[function(require,module,exports){ /** * Generic Mask Stack data structure * @class @@ -14429,7 +15993,7 @@ StencilMaskStack.prototype.constructor = StencilMaskStack; module.exports = StencilMaskStack; -},{}],57:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ var math = require('../math'), Texture = require('../textures/Texture'), Container = require('../display/Container'), @@ -14671,7 +16235,8 @@ minY, maxY; - + //TODO - I am SURE this can be optimised, but the below is not accurate enough.. + /* if (b === 0 && c === 0) { // scale may be negative! @@ -14694,38 +16259,41 @@ } else { - var x1 = a * w1 + c * h1 + tx; - var y1 = d * h1 + b * w1 + ty; + */ + + var x1 = a * w1 + c * h1 + tx; + var y1 = d * h1 + b * w1 + ty; - var x2 = a * w0 + c * h1 + tx; - var y2 = d * h1 + b * w0 + ty; + var x2 = a * w0 + c * h1 + tx; + var y2 = d * h1 + b * w0 + ty; - var x3 = a * w0 + c * h0 + tx; - var y3 = d * h0 + b * w0 + ty; + var x3 = a * w0 + c * h0 + tx; + var y3 = d * h0 + b * w0 + ty; - var x4 = a * w1 + c * h0 + tx; - var y4 = d * h0 + b * w1 + ty; + var x4 = a * w1 + c * h0 + tx; + var y4 = d * h0 + b * w1 + ty; - minX = x1; - minX = x2 < minX ? x2 : minX; - minX = x3 < minX ? x3 : minX; - minX = x4 < minX ? x4 : minX; + minX = x1; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; - minY = y1; - minY = y2 < minY ? y2 : minY; - minY = y3 < minY ? y3 : minY; - minY = y4 < minY ? y4 : minY; + minY = y1; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; - maxX = x1; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; + maxX = x1; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; - maxY = y1; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - } + maxY = y1; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + + //} // check for children if(this.children.length) @@ -14998,7 +16566,7 @@ return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode)); }; -},{"../const":13,"../display/Container":14,"../math":23,"../renderers/canvas/utils/CanvasTinter":38,"../textures/Texture":62,"../utils":67}],58:[function(require,module,exports){ +},{"../const":19,"../display/Container":20,"../math":29,"../renderers/canvas/utils/CanvasTinter":44,"../textures/Texture":68,"../utils":73}],64:[function(require,module,exports){ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), CONST = require('../../const'); @@ -15468,7 +17036,7 @@ this.shader = null; }; -},{"../../const":13,"../../renderers/webgl/WebGLRenderer":39,"../../renderers/webgl/utils/ObjectRenderer":53}],59:[function(require,module,exports){ +},{"../../const":19,"../../renderers/webgl/WebGLRenderer":45,"../../renderers/webgl/utils/ObjectRenderer":59}],65:[function(require,module,exports){ var Sprite = require('../sprites/Sprite'), Texture = require('../textures/Texture'), math = require('../math'), @@ -16081,7 +17649,7 @@ this._texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); }; -},{"../const":13,"../math":23,"../sprites/Sprite":57,"../textures/Texture":62,"../utils":67}],60:[function(require,module,exports){ +},{"../const":19,"../math":29,"../sprites/Sprite":63,"../textures/Texture":68,"../utils":73}],66:[function(require,module,exports){ var utils = require('../utils'), CONST = require('../const'), EventEmitter = require('eventemitter3'); @@ -16515,7 +18083,7 @@ return baseTexture; }; -},{"../const":13,"../utils":67,"eventemitter3":10}],61:[function(require,module,exports){ +},{"../const":19,"../utils":73,"eventemitter3":10}],67:[function(require,module,exports){ var BaseTexture = require('./BaseTexture'), Texture = require('./Texture'), RenderTarget = require('../renderers/webgl/utils/RenderTarget'), @@ -16994,7 +18562,7 @@ } }; -},{"../const":13,"../math":23,"../renderers/canvas/utils/CanvasBuffer":35,"../renderers/webgl/managers/FilterManager":44,"../renderers/webgl/utils/RenderTarget":55,"./BaseTexture":60,"./Texture":62}],62:[function(require,module,exports){ +},{"../const":19,"../math":29,"../renderers/canvas/utils/CanvasBuffer":41,"../renderers/webgl/managers/FilterManager":50,"../renderers/webgl/utils/RenderTarget":61,"./BaseTexture":66,"./Texture":68}],68:[function(require,module,exports){ var BaseTexture = require('./BaseTexture'), VideoBaseTexture = require('./VideoBaseTexture'), TextureUvs = require('./TextureUvs'), @@ -17420,7 +18988,7 @@ */ Texture.EMPTY = new Texture(new BaseTexture()); -},{"../math":23,"../utils":67,"./BaseTexture":60,"./TextureUvs":63,"./VideoBaseTexture":64,"eventemitter3":10}],63:[function(require,module,exports){ +},{"../math":29,"../utils":73,"./BaseTexture":66,"./TextureUvs":69,"./VideoBaseTexture":70,"eventemitter3":10}],69:[function(require,module,exports){ /** * A standard object to store the Uvs of a texture @@ -17489,7 +19057,7 @@ } }; -},{}],64:[function(require,module,exports){ +},{}],70:[function(require,module,exports){ var BaseTexture = require('./BaseTexture'), utils = require('../utils'); @@ -17726,7 +19294,7 @@ return source; } -},{"../utils":67,"./BaseTexture":60}],65:[function(require,module,exports){ +},{"../utils":73,"./BaseTexture":66}],71:[function(require,module,exports){ var CONST = require('../const'), EventEmitter = require('eventemitter3'), // Internal event used by composed emitter @@ -18081,7 +19649,7 @@ module.exports = Ticker; -},{"../const":13,"eventemitter3":10}],66:[function(require,module,exports){ +},{"../const":19,"eventemitter3":10}],72:[function(require,module,exports){ var Ticker = require('./Ticker'); /** @@ -18137,7 +19705,7 @@ Ticker: Ticker }; -},{"./Ticker":65}],67:[function(require,module,exports){ +},{"./Ticker":71}],73:[function(require,module,exports){ var CONST = require('../const'); /** @@ -18388,7 +19956,7 @@ BaseTextureCache: {} }; -},{"../const":13,"./pluginTarget":68,"async":1,"eventemitter3":10}],68:[function(require,module,exports){ +},{"../const":19,"./pluginTarget":74,"async":1,"eventemitter3":10}],74:[function(require,module,exports){ /** * Mixins functionality to make an object have "plugins". * @@ -18458,7 +20026,7 @@ } }; -},{}],69:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ /*global console */ var core = require('./core'), mesh = require('./mesh'), @@ -18809,7 +20377,7 @@ return core.utils.uid(); }; -},{"./core":20,"./extras":76,"./filters":93,"./mesh":117}],70:[function(require,module,exports){ +},{"./core":26,"./extras":82,"./filters":99,"./mesh":123}],76:[function(require,module,exports){ var core = require('../core'); /** @@ -19197,7 +20765,7 @@ BitmapText.fonts = {}; -},{"../core":20}],71:[function(require,module,exports){ +},{"../core":26}],77:[function(require,module,exports){ var core = require('../core'); /** @@ -19517,7 +21085,7 @@ return new MovieClip(textures); }; -},{"../core":20}],72:[function(require,module,exports){ +},{"../core":26}],78:[function(require,module,exports){ var core = require('../core'), // a sprite use dfor rendering textures.. tempPoint = new core.Point(), @@ -19969,7 +21537,7 @@ return new TilingSprite(core.Texture.fromImage(imageId, crossorigin, scaleMode),width,height); }; -},{"../core":20,"../core/renderers/canvas/utils/CanvasTinter":38}],73:[function(require,module,exports){ +},{"../core":26,"../core/renderers/canvas/utils/CanvasTinter":44}],79:[function(require,module,exports){ var core = require('../core'), DisplayObject = core.DisplayObject, _tempMatrix = new core.Matrix(); @@ -20241,7 +21809,7 @@ this._originalDestroy(); }; -},{"../core":20}],74:[function(require,module,exports){ +},{"../core":26}],80:[function(require,module,exports){ var core = require('../core'); /** @@ -20271,7 +21839,7 @@ return null; }; -},{"../core":20}],75:[function(require,module,exports){ +},{"../core":26}],81:[function(require,module,exports){ var core = require('../core'); /** @@ -20301,7 +21869,7 @@ return point; }; -},{"../core":20}],76:[function(require,module,exports){ +},{"../core":26}],82:[function(require,module,exports){ /** * @file Main export of the PIXI extras library * @author Mat Groves @@ -20322,7 +21890,7 @@ BitmapText: require('./BitmapText') }; -},{"./BitmapText":70,"./MovieClip":71,"./TilingSprite":72,"./cacheAsBitmap":73,"./getChildByName":74,"./getGlobalPosition":75}],77:[function(require,module,exports){ +},{"./BitmapText":76,"./MovieClip":77,"./TilingSprite":78,"./cacheAsBitmap":79,"./getChildByName":80,"./getGlobalPosition":81}],83:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -20379,7 +21947,7 @@ } }); -},{"../../core":20}],78:[function(require,module,exports){ +},{"../../core":26}],84:[function(require,module,exports){ var core = require('../../core'), BlurXFilter = require('../blur/BlurXFilter'), BlurYFilter = require('../blur/BlurYFilter'); @@ -20480,7 +22048,7 @@ } }); -},{"../../core":20,"../blur/BlurXFilter":81,"../blur/BlurYFilter":82}],79:[function(require,module,exports){ +},{"../../core":26,"../blur/BlurXFilter":87,"../blur/BlurYFilter":88}],85:[function(require,module,exports){ var core = require('../../core'); @@ -20622,7 +22190,7 @@ } }); -},{"../../core":20}],80:[function(require,module,exports){ +},{"../../core":26}],86:[function(require,module,exports){ var core = require('../../core'), BlurXFilter = require('./BlurXFilter'), BlurYFilter = require('./BlurYFilter'); @@ -20732,7 +22300,7 @@ } }); -},{"../../core":20,"./BlurXFilter":81,"./BlurYFilter":82}],81:[function(require,module,exports){ +},{"../../core":26,"./BlurXFilter":87,"./BlurYFilter":88}],87:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -20825,7 +22393,7 @@ } }); -},{"../../core":20}],82:[function(require,module,exports){ +},{"../../core":26}],88:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -20911,7 +22479,7 @@ } }); -},{"../../core":20}],83:[function(require,module,exports){ +},{"../../core":26}],89:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -20941,7 +22509,7 @@ SmartBlurFilter.prototype.constructor = SmartBlurFilter; module.exports = SmartBlurFilter; -},{"../../core":20}],84:[function(require,module,exports){ +},{"../../core":26}],90:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21477,7 +23045,7 @@ } }); -},{"../../core":20}],85:[function(require,module,exports){ +},{"../../core":26}],91:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21526,7 +23094,7 @@ } }); -},{"../../core":20}],86:[function(require,module,exports){ +},{"../../core":26}],92:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21617,7 +23185,7 @@ } }); -},{"../../core":20}],87:[function(require,module,exports){ +},{"../../core":26}],93:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21643,7 +23211,7 @@ CrossHatchFilter.prototype.constructor = CrossHatchFilter; module.exports = CrossHatchFilter; -},{"../../core":20}],88:[function(require,module,exports){ +},{"../../core":26}],94:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21727,7 +23295,7 @@ } }); -},{"../../core":20}],89:[function(require,module,exports){ +},{"../../core":26}],95:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21799,7 +23367,7 @@ } }); -},{"../../core":20}],90:[function(require,module,exports){ +},{"../../core":26}],96:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -21890,7 +23458,7 @@ } }); -},{"../../core":20}],91:[function(require,module,exports){ +},{"../../core":26}],97:[function(require,module,exports){ var core = require('../../core'), BlurXFilter = require('../blur/BlurXFilter'), BlurYTintFilter = require('./BlurYTintFilter'); @@ -22083,7 +23651,7 @@ } }); -},{"../../core":20,"../blur/BlurXFilter":81,"./BlurYTintFilter":90}],92:[function(require,module,exports){ +},{"../../core":26,"../blur/BlurXFilter":87,"./BlurYTintFilter":96}],98:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22132,7 +23700,7 @@ } }); -},{"../../core":20}],93:[function(require,module,exports){ +},{"../../core":26}],99:[function(require,module,exports){ /** * @file Main export of the PIXI filters library * @author Mat Groves @@ -22171,7 +23739,7 @@ TwistFilter: require('./twist/TwistFilter') }; -},{"./ascii/AsciiFilter":77,"./bloom/BloomFilter":78,"./blur/BlurDirFilter":79,"./blur/BlurFilter":80,"./blur/BlurXFilter":81,"./blur/BlurYFilter":82,"./blur/SmartBlurFilter":83,"./color/ColorMatrixFilter":84,"./color/ColorStepFilter":85,"./convolution/ConvolutionFilter":86,"./crosshatch/CrossHatchFilter":87,"./displacement/DisplacementFilter":88,"./dot/DotScreenFilter":89,"./dropshadow/DropShadowFilter":91,"./gray/GrayFilter":92,"./invert/InvertFilter":94,"./noise/NoiseFilter":95,"./pixelate/PixelateFilter":96,"./rgb/RGBSplitFilter":97,"./sepia/SepiaFilter":98,"./shockwave/ShockwaveFilter":99,"./tiltshift/TiltShiftFilter":101,"./tiltshift/TiltShiftXFilter":102,"./tiltshift/TiltShiftYFilter":103,"./twist/TwistFilter":104}],94:[function(require,module,exports){ +},{"./ascii/AsciiFilter":83,"./bloom/BloomFilter":84,"./blur/BlurDirFilter":85,"./blur/BlurFilter":86,"./blur/BlurXFilter":87,"./blur/BlurYFilter":88,"./blur/SmartBlurFilter":89,"./color/ColorMatrixFilter":90,"./color/ColorStepFilter":91,"./convolution/ConvolutionFilter":92,"./crosshatch/CrossHatchFilter":93,"./displacement/DisplacementFilter":94,"./dot/DotScreenFilter":95,"./dropshadow/DropShadowFilter":97,"./gray/GrayFilter":98,"./invert/InvertFilter":100,"./noise/NoiseFilter":101,"./pixelate/PixelateFilter":102,"./rgb/RGBSplitFilter":103,"./sepia/SepiaFilter":104,"./shockwave/ShockwaveFilter":105,"./tiltshift/TiltShiftFilter":107,"./tiltshift/TiltShiftXFilter":108,"./tiltshift/TiltShiftYFilter":109,"./twist/TwistFilter":110}],100:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22221,7 +23789,7 @@ } }); -},{"../../core":20}],95:[function(require,module,exports){ +},{"../../core":26}],101:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22276,7 +23844,7 @@ } }); -},{"../../core":20}],96:[function(require,module,exports){ +},{"../../core":26}],102:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22327,7 +23895,7 @@ } }); -},{"../../core":20}],97:[function(require,module,exports){ +},{"../../core":26}],103:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22413,7 +23981,7 @@ } }); -},{"../../core":20}],98:[function(require,module,exports){ +},{"../../core":26}],104:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22463,7 +24031,7 @@ } }); -},{"../../core":20}],99:[function(require,module,exports){ +},{"../../core":26}],105:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22551,7 +24119,7 @@ } }); -},{"../../core":20}],100:[function(require,module,exports){ +},{"../../core":26}],106:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22676,7 +24244,7 @@ } }); -},{"../../core":20}],101:[function(require,module,exports){ +},{"../../core":26}],107:[function(require,module,exports){ var core = require('../../core'), TiltShiftXFilter = require('./TiltShiftXFilter'), TiltShiftYFilter = require('./TiltShiftYFilter'); @@ -22786,7 +24354,7 @@ } }); -},{"../../core":20,"./TiltShiftXFilter":102,"./TiltShiftYFilter":103}],102:[function(require,module,exports){ +},{"../../core":26,"./TiltShiftXFilter":108,"./TiltShiftYFilter":109}],108:[function(require,module,exports){ var TiltShiftAxisFilter = require('./TiltShiftAxisFilter'); /** @@ -22824,7 +24392,7 @@ this.uniforms.delta.value.y = dy / d; }; -},{"./TiltShiftAxisFilter":100}],103:[function(require,module,exports){ +},{"./TiltShiftAxisFilter":106}],109:[function(require,module,exports){ var TiltShiftAxisFilter = require('./TiltShiftAxisFilter'); /** @@ -22862,7 +24430,7 @@ this.uniforms.delta.value.y = dx / d; }; -},{"./TiltShiftAxisFilter":100}],104:[function(require,module,exports){ +},{"./TiltShiftAxisFilter":106}],110:[function(require,module,exports){ var core = require('../../core'); // @see https://github.com/substack/brfs/issues/25 @@ -22947,7 +24515,7 @@ } }); -},{"../../core":20}],105:[function(require,module,exports){ +},{"../../core":26}],111:[function(require,module,exports){ (function (global){ // run the polyfills require('./polyfill'); @@ -22979,7 +24547,7 @@ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./core":20,"./deprecation":69,"./extras":76,"./filters":93,"./interaction":108,"./loaders":111,"./mesh":117,"./polyfill":122}],106:[function(require,module,exports){ +},{"./core":26,"./deprecation":75,"./extras":82,"./filters":99,"./interaction":114,"./loaders":117,"./mesh":123,"./polyfill":128}],112:[function(require,module,exports){ var core = require('../core'); /** @@ -23028,7 +24596,7 @@ return displayObject.toLocal(globalPos ? globalPos : this.global, point); }; -},{"../core":20}],107:[function(require,module,exports){ +},{"../core":26}],113:[function(require,module,exports){ var core = require('../core'), InteractionData = require('./InteractionData'); @@ -23883,7 +25451,7 @@ core.WebGLRenderer.registerPlugin('interaction', InteractionManager); core.CanvasRenderer.registerPlugin('interaction', InteractionManager); -},{"../core":20,"./InteractionData":106,"./interactiveTarget":109}],108:[function(require,module,exports){ +},{"../core":26,"./InteractionData":112,"./interactiveTarget":115}],114:[function(require,module,exports){ /** * @file Main export of the PIXI interactions library * @author Mat Groves @@ -23900,7 +25468,7 @@ interactiveTarget: require('./interactiveTarget') }; -},{"./InteractionData":106,"./InteractionManager":107,"./interactiveTarget":109}],109:[function(require,module,exports){ +},{"./InteractionData":112,"./InteractionManager":113,"./interactiveTarget":115}],115:[function(require,module,exports){ /** * Default property values of interactive objects * used by {@link PIXI.interaction.InteractionManager}. @@ -23949,7 +25517,7 @@ module.exports = interactiveTarget; -},{}],110:[function(require,module,exports){ +},{}],116:[function(require,module,exports){ var Resource = require('resource-loader').Resource, core = require('../core'), extras = require('../extras'), @@ -24069,7 +25637,7 @@ }; }; -},{"../core":20,"../extras":76,"path":2,"resource-loader":129}],111:[function(require,module,exports){ +},{"../core":26,"../extras":82,"path":2,"resource-loader":15}],117:[function(require,module,exports){ /** * @file Main export of the PIXI loaders library * @author Mat Groves @@ -24090,7 +25658,7 @@ Resource: require('resource-loader').Resource }; -},{"./bitmapFontParser":110,"./loader":112,"./spritesheetParser":113,"./textureParser":114,"resource-loader":129}],112:[function(require,module,exports){ +},{"./bitmapFontParser":116,"./loader":118,"./spritesheetParser":119,"./textureParser":120,"resource-loader":15}],118:[function(require,module,exports){ var ResourceLoader = require('resource-loader'), textureParser = require('./textureParser'), spritesheetParser = require('./spritesheetParser'), @@ -24152,7 +25720,7 @@ Resource.setExtensionXhrType('fnt', Resource.XHR_RESPONSE_TYPE.DOCUMENT); -},{"./bitmapFontParser":110,"./spritesheetParser":113,"./textureParser":114,"resource-loader":129}],113:[function(require,module,exports){ +},{"./bitmapFontParser":116,"./spritesheetParser":119,"./textureParser":120,"resource-loader":15}],119:[function(require,module,exports){ var Resource = require('resource-loader').Resource, path = require('path'), core = require('../core'); @@ -24235,7 +25803,7 @@ }; }; -},{"../core":20,"path":2,"resource-loader":129}],114:[function(require,module,exports){ +},{"../core":26,"path":2,"resource-loader":15}],120:[function(require,module,exports){ var core = require('../core'); module.exports = function () @@ -24257,7 +25825,7 @@ }; }; -},{"../core":20}],115:[function(require,module,exports){ +},{"../core":26}],121:[function(require,module,exports){ var core = require('../core'), tempPoint = new core.Point(), tempPolygon = new core.Polygon(); @@ -24726,7 +26294,7 @@ TRIANGLES: 1 }; -},{"../core":20}],116:[function(require,module,exports){ +},{"../core":26}],122:[function(require,module,exports){ var Mesh = require('./Mesh'); var core = require('../core'); @@ -24939,7 +26507,7 @@ this.containerUpdateTransform(); }; -},{"../core":20,"./Mesh":115}],117:[function(require,module,exports){ +},{"../core":26,"./Mesh":121}],123:[function(require,module,exports){ /** * @file Main export of the PIXI extras library * @author Mat Groves @@ -24957,7 +26525,7 @@ MeshShader: require('./webgl/MeshShader') }; -},{"./Mesh":115,"./Rope":116,"./webgl/MeshRenderer":118,"./webgl/MeshShader":119}],118:[function(require,module,exports){ +},{"./Mesh":121,"./Rope":122,"./webgl/MeshRenderer":124,"./webgl/MeshShader":125}],124:[function(require,module,exports){ var core = require('../../core'), Mesh = require('../Mesh'); @@ -25172,7 +26740,7 @@ core.ObjectRenderer.prototype.destroy.call(this); }; -},{"../../core":20,"../Mesh":115}],119:[function(require,module,exports){ +},{"../../core":26,"../Mesh":121}],125:[function(require,module,exports){ var core = require('../../core'); /** @@ -25233,7 +26801,7 @@ core.ShaderManager.registerPlugin('meshShader', MeshShader); -},{"../../core":20}],120:[function(require,module,exports){ +},{"../../core":26}],126:[function(require,module,exports){ // References: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign @@ -25249,7 +26817,7 @@ }; } -},{}],121:[function(require,module,exports){ +},{}],127:[function(require,module,exports){ // References: // https://github.com/sindresorhus/object-assign // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign @@ -25259,12 +26827,12 @@ Object.assign = require('object-assign'); } -},{"object-assign":11}],122:[function(require,module,exports){ +},{"object-assign":11}],128:[function(require,module,exports){ require('./Object.assign'); require('./requestAnimationFrame'); require('./Math.sign'); -},{"./Math.sign":120,"./Object.assign":121,"./requestAnimationFrame":123}],123:[function(require,module,exports){ +},{"./Math.sign":126,"./Object.assign":127,"./requestAnimationFrame":129}],129:[function(require,module,exports){ (function (global){ // References: // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ @@ -25335,2811 +26903,7 @@ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],124:[function(require,module,exports){ -(function (process){ -/*! - * async - * https://github.com/caolan/async - * - * Copyright 2010-2014 Caolan McMahon - * Released under the MIT license - */ -/*jshint onevar: false, indent:4 */ -/*global setImmediate: false, setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root, previous_async; - - root = this; - if (root != null) { - previous_async = root.async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - function only_once(fn) { - var called = false; - return function() { - if (called) throw new Error("Callback was already called."); - called = true; - fn.apply(root, arguments); - } - } - - //// cross-browser compatiblity functions //// - - var _toString = Object.prototype.toString; - - var _isArray = Array.isArray || function (obj) { - return _toString.call(obj) === '[object Array]'; - }; - - var _each = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _each(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _each(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - if (typeof setImmediate === 'function') { - async.nextTick = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); - }; - async.setImmediate = async.nextTick; - } - else { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - async.setImmediate = async.nextTick; - } - } - else { - async.nextTick = process.nextTick; - if (typeof setImmediate !== 'undefined') { - async.setImmediate = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); - }; - } - else { - async.setImmediate = async.nextTick; - } - } - - async.each = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - _each(arr, function (x) { - iterator(x, only_once(done) ); - }); - function done(err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(); - } - } - } - }; - async.forEach = async.each; - - async.eachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - async.forEachSeries = async.eachSeries; - - async.eachLimit = function (arr, limit, iterator, callback) { - var fn = _eachLimit(limit); - fn.apply(null, [arr, iterator, callback]); - }; - async.forEachLimit = async.eachLimit; - - var _eachLimit = function (limit) { - - return function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); - } - var completed = 0; - var started = 0; - var running = 0; - - (function replenish () { - if (completed >= arr.length) { - return callback(); - } - - while (running < limit && started < arr.length) { - started += 1; - running += 1; - iterator(arr[started - 1], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - running -= 1; - if (completed >= arr.length) { - callback(); - } - else { - replenish(); - } - } - }); - } - })(); - }; - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.each].concat(args)); - }; - }; - var doParallelLimit = function(limit, fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [_eachLimit(limit)].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.eachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - if (!callback) { - eachfn(arr, function (x, callback) { - iterator(x.value, function (err) { - callback(err); - }); - }); - } else { - var results = []; - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - async.mapLimit = function (arr, limit, iterator, callback) { - return _mapLimit(limit)(arr, iterator, callback); - }; - - var _mapLimit = function(limit) { - return doParallelLimit(limit, _asyncMap); - }; - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.eachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - var remainingTasks = keys.length - if (!remainingTasks) { - return callback(); - } - - var results = {}; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - remainingTasks-- - _each(listeners.slice(0), function (fn) { - fn(); - }); - }; - - addListener(function () { - if (!remainingTasks) { - var theCallback = callback; - // prevent final callback from calling itself if it errors - callback = function () {}; - - theCallback(null, results); - } - }); - - _each(keys, function (k) { - var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; - var taskCallback = function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - if (err) { - var safeResults = {}; - _each(_keys(results), function(rkey) { - safeResults[rkey] = results[rkey]; - }); - safeResults[k] = args; - callback(err, safeResults); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - results[k] = args; - async.setImmediate(taskComplete); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); - }; - if (ready()) { - task[task.length - 1](taskCallback, results); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; - addListener(listener); - } - }); - }; - - async.retry = function(times, task, callback) { - var DEFAULT_TIMES = 5; - var attempts = []; - // Use defaults if times not passed - if (typeof times === 'function') { - callback = task; - task = times; - times = DEFAULT_TIMES; - } - // Make sure times is a number - times = parseInt(times, 10) || DEFAULT_TIMES; - var wrappedTask = function(wrappedCallback, wrappedResults) { - var retryAttempt = function(task, finalAttempt) { - return function(seriesCallback) { - task(function(err, result){ - seriesCallback(!err || finalAttempt, {err: err, result: result}); - }, wrappedResults); - }; - }; - while (times) { - attempts.push(retryAttempt(task, !(times-=1))); - } - async.series(attempts, function(done, data){ - data = data[data.length - 1]; - (wrappedCallback || callback)(data.err, data.result); - }); - } - // If a callback is passed, run this as a controll flow - return callback ? wrappedTask() : wrappedTask - }; - - async.waterfall = function (tasks, callback) { - callback = callback || function () {}; - if (!_isArray(tasks)) { - var err = new Error('First argument to waterfall must be an array of functions'); - return callback(err); - } - if (!tasks.length) { - return callback(); - } - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback.apply(null, arguments); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.setImmediate(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - var _parallel = function(eachfn, tasks, callback) { - callback = callback || function () {}; - if (_isArray(tasks)) { - eachfn.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - eachfn.each(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.parallel = function (tasks, callback) { - _parallel({ map: async.map, each: async.each }, tasks, callback); - }; - - async.parallelLimit = function(tasks, limit, callback) { - _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (_isArray(tasks)) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.eachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doWhilst = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - var args = Array.prototype.slice.call(arguments, 1); - if (test.apply(null, args)) { - async.doWhilst(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doUntil = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - var args = Array.prototype.slice.call(arguments, 1); - if (!test.apply(null, args)) { - async.doUntil(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.queue = function (worker, concurrency) { - if (concurrency === undefined) { - concurrency = 1; - } - function _insert(q, data, pos, callback) { - if (!q.started){ - q.started = true; - } - if (!_isArray(data)) { - data = [data]; - } - if(data.length == 0) { - // call drain immediately if there are no tasks - return async.setImmediate(function() { - if (q.drain) { - q.drain(); - } - }); - } - _each(data, function(task) { - var item = { - data: task, - callback: typeof callback === 'function' ? callback : null - }; - - if (pos) { - q.tasks.unshift(item); - } else { - q.tasks.push(item); - } - - if (q.saturated && q.tasks.length === q.concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); - } - - var workers = 0; - var q = { - tasks: [], - concurrency: concurrency, - saturated: null, - empty: null, - drain: null, - started: false, - paused: false, - push: function (data, callback) { - _insert(q, data, false, callback); - }, - kill: function () { - q.drain = null; - q.tasks = []; - }, - unshift: function (data, callback) { - _insert(q, data, true, callback); - }, - process: function () { - if (!q.paused && workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if (q.empty && q.tasks.length === 0) { - q.empty(); - } - workers += 1; - var next = function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if (q.drain && q.tasks.length + workers === 0) { - q.drain(); - } - q.process(); - }; - var cb = only_once(next); - worker(task.data, cb); - } - }, - length: function () { - return q.tasks.length; - }, - running: function () { - return workers; - }, - idle: function() { - return q.tasks.length + workers === 0; - }, - pause: function () { - if (q.paused === true) { return; } - q.paused = true; - q.process(); - }, - resume: function () { - if (q.paused === false) { return; } - q.paused = false; - q.process(); - } - }; - return q; - }; - - async.priorityQueue = function (worker, concurrency) { - - function _compareTasks(a, b){ - return a.priority - b.priority; - }; - - function _binarySearch(sequence, item, compare) { - var beg = -1, - end = sequence.length - 1; - while (beg < end) { - var mid = beg + ((end - beg + 1) >>> 1); - if (compare(item, sequence[mid]) >= 0) { - beg = mid; - } else { - end = mid - 1; - } - } - return beg; - } - - function _insert(q, data, priority, callback) { - if (!q.started){ - q.started = true; - } - if (!_isArray(data)) { - data = [data]; - } - if(data.length == 0) { - // call drain immediately if there are no tasks - return async.setImmediate(function() { - if (q.drain) { - q.drain(); - } - }); - } - _each(data, function(task) { - var item = { - data: task, - priority: priority, - callback: typeof callback === 'function' ? callback : null - }; - - q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); - - if (q.saturated && q.tasks.length === q.concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); - } - - // Start with a normal queue - var q = async.queue(worker, concurrency); - - // Override push to accept second parameter representing priority - q.push = function (data, priority, callback) { - _insert(q, data, priority, callback); - }; - - // Remove unshift function - delete q.unshift; - - return q; - }; - - async.cargo = function (worker, payload) { - var working = false, - tasks = []; - - var cargo = { - tasks: tasks, - payload: payload, - saturated: null, - empty: null, - drain: null, - drained: true, - push: function (data, callback) { - if (!_isArray(data)) { - data = [data]; - } - _each(data, function(task) { - tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - cargo.drained = false; - if (cargo.saturated && tasks.length === payload) { - cargo.saturated(); - } - }); - async.setImmediate(cargo.process); - }, - process: function process() { - if (working) return; - if (tasks.length === 0) { - if(cargo.drain && !cargo.drained) cargo.drain(); - cargo.drained = true; - return; - } - - var ts = typeof payload === 'number' - ? tasks.splice(0, payload) - : tasks.splice(0, tasks.length); - - var ds = _map(ts, function (task) { - return task.data; - }); - - if(cargo.empty) cargo.empty(); - working = true; - worker(ds, function () { - working = false; - - var args = arguments; - _each(ts, function (data) { - if (data.callback) { - data.callback.apply(null, args); - } - }); - - process(); - }); - }, - length: function () { - return tasks.length; - }, - running: function () { - return working; - } - }; - return cargo; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _each(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - async.nextTick(function () { - callback.apply(null, memo[key]); - }); - } - else if (key in queues) { - queues[key].push(callback); - } - else { - queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); - } - }])); - } - }; - memoized.memo = memo; - memoized.unmemoized = fn; - return memoized; - }; - - async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - }; - - async.times = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.map(counter, iterator, callback); - }; - - async.timesSeries = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.mapSeries(counter, iterator, callback); - }; - - async.seq = function (/* functions... */) { - var fns = arguments; - return function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - async.reduce(fns, args, function (newargs, fn, cb) { - fn.apply(that, newargs.concat([function () { - var err = arguments[0]; - var nextargs = Array.prototype.slice.call(arguments, 1); - cb(err, nextargs); - }])) - }, - function (err, results) { - callback.apply(that, [err].concat(results)); - }); - }; - }; - - async.compose = function (/* functions... */) { - return async.seq.apply(null, Array.prototype.reverse.call(arguments)); - }; - - var _applyEach = function (eachfn, fns /*args...*/) { - var go = function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - return eachfn(fns, function (fn, cb) { - fn.apply(that, args.concat([cb])); - }, - callback); - }; - if (arguments.length > 2) { - var args = Array.prototype.slice.call(arguments, 2); - return go.apply(this, args); - } - else { - return go; - } - }; - async.applyEach = doParallel(_applyEach); - async.applyEachSeries = doSeries(_applyEach); - - async.forever = function (fn, callback) { - function next(err) { - if (err) { - if (callback) { - return callback(err); - } - throw err; - } - fn(next); - } - next(); - }; - - // Node.js - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - // AMD / RequireJS - else if (typeof define !== 'undefined' && define.amd) { - define([], function () { - return async; - }); - } - // included directly via