<commit_before>/*global define*/
define([
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        '../Core/Rectangle',
        '../Core/WebMercatorTilingScheme',
        './ImageryProvider'
    ], function(
        Credit,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        Rectangle,
        WebMercatorTilingScheme,
        ImageryProvider) {
    "use strict";

    var trailingQMarkRegex = /\?$/;
    var defaultCredit = new Credit("OGC, http://portal.opengeospatial.org/files/?artifact_id=35326");

    /**
     * Provides tiled imagery Served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers
     *
     * @alias WMTSImageryProvider
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {String} [options.url] The WMTS server url.
     * @param {String} [options.format='image/png'] The type mime for images on the server.
     * @param {String} [options.layer] The layer name for WMTS requests
     * @param {String} [options.style] The style name for WMTS requests
     * @param {String} [options.tms] The TileMatrixSetId
     * @param {TilingScheme} [options.tilingScheme] The tilingScheme corresponding to TMS definition
     * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL.
     * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
     * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
     * @param {Number} [options.maximumLevel=18] The maximum level-of-detail supported by the imagery provider.
     * @param {Credit|String} [options.credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
     *
     * @see ArcGisMapServerImageryProvider
     * @see BingMapsImageryProvider
     * @see SingleTileImageryProvider
     * @see TileMapServiceImageryProvider
     * @see WebMapServiceImageryProvider
     *
     * @see {@link http://wiki.openstreetmap.org/wiki/Main_Page|OpenStreetMap Wiki}
     *
     * @example
     * // IGN French Geoportal tile provider
     * var frenchMaps= new Cesium.WMTSImageryProvider({
     *                 url : 'http://wxs.ign.fr/YOUR_KEY/geoportail/wmts',
     *                 layer : 'GEOGRAPHICALGRIDSYSTEMS.MAPS',
     *                 style : 'normal',
     *                 format : 'image/jpeg',
     *                 tms : 'PM',
     *                 credit : new Cesium.Credit("IGN",
     *                                            "http://wxs.ign.fr/static/logos/IGN/IGN.gif",
     *                                            "http://www.ign.fr/")
     *             }) ;
     */
    var WMTSImageryProvider = function WMTSImageryProvider(options) {
        options = defaultValue(options, {});

        if (!defined(options.url)) {
            throw new DeveloperError('options.url is required.');
        }
        if (!defined(options.layer)) {
            throw new DeveloperError('options.layer is required.');
        }
        if (!defined(options.style)) {
            throw new DeveloperError('options.style is required.');
        }
        if (!defined(options.tms)) {
            throw new DeveloperError('options.tms is required.');
        }

        this._url = options.url;
        if (!trailingQMarkRegex.test(this._url)) {
            this._url = this._url + '?';
        }

        this._layer = options.layer;
        this._style = options.style;
        this._tms = options.tms;
        this._format = defaultValue(options.format, 'image/jpg');
        this._proxy = options.proxy;
        this._tileDiscardPolicy = options.tileDiscardPolicy;

        this._tilingScheme = defaultValue(options.tilingScheme,new WebMercatorTilingScheme()) ;
        this._tileWidth = 256;
        this._tileHeight = 256;

        this._minimumLevel = defaultValue(options.minimumLevel, 0);
        this._maximumLevel = defaultValue(options.maximumLevel, 18);

        this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle);

        // Check the number of tiles at the minimum level.  If it's more than four,
        // throw an exception, because starting at the higher minimum
        // level will cause too many tiles to be downloaded and rendered.
        var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel);
console.log(swTile) ;
        var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel);
console.log(neTile) ;
        var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
console.log(tileCount) ;
        if (tileCount > 4) {
            throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.');
        }

        this._errorEvent = new Event();

        this._ready = true;

        var credit = defaultValue(options.credit, defaultCredit);
        if (typeof credit === 'string') {
            credit = new Credit(credit);
        }
        this._credit = credit;
    };

    function buildImageUrl(imageryProvider, col, row, level) {
        var url = imageryProvider._url +
                  "service=WMTS&VERSION=1.0.0&request=GetTile" +
                  "&TILEMATRIX="+ level +
                  "&LAYER="+ imageryProvider._layer +
                  "&STYLE="+ imageryProvider._style +
                  "&TILEROW="+ row +
                  '&TILECOL=' + col +
                  '&TILEMATRIXSET=' + imageryProvider._tms +
                  "&FORMAT=" + imageryProvider._format ;

        var proxy = imageryProvider._proxy;
        if (defined(proxy)) {
            url = proxy.getURL(url);
        }

        return url;
    }

    defineProperties(WMTSImageryProvider.prototype, {
        /**
         * Gets the URL of the service hosting the imagery.
         * @memberof WMTSImageryProvider.prototype
         * @type {String}
         */
        url : {
            get : function() {
                return this._url;
            }
        },

        /**
         * Gets the proxy used by this provider.
         * @memberof WMTSImageryProvider.prototype
         * @type {Proxy}
         */
        proxy : {
            get : function() {
                return this._proxy;
            }
        },

        /**
         * Gets the width of each tile, in pixels. This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        tileWidth : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileWidth;
            }
        },

        /**
         * Gets the height of each tile, in pixels.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        tileHeight: {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileHeight;
            }
        },

        /**
         * Gets the maximum level-of-detail that can be requested.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        maximumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._maximumLevel;
            }
        },

        /**
         * Gets the minimum level-of-detail that can be requested.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        minimumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._minimumLevel;
            }
        },

        /**
         * Gets the tiling scheme used by this provider.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {TilingScheme}
         */
        tilingScheme : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tilingScheme;
            }
        },

        /**
         * Gets the rectangle, in radians, of the imagery provided by this instance.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Rectangle}
         */
        rectangle : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('rectangle must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._rectangle;
            }
        },

        /**
         * Gets the tile discard policy.  If not undefined, the discard policy is responsible
         * for filtering out "missing" tiles via its shouldDiscardImage function.  If this function
         * returns undefined, no tiles are filtered.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {TileDiscardPolicy}
         */
        tileDiscardPolicy : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileDiscardPolicy;
            }
        },

        /**
         * Gets an event that is raised when the imagery provider encounters an asynchronous error.  By subscribing
         * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
         * are passed an instance of {@link TileProviderError}.
         * @memberof WMTSImageryProvider.prototype
         * @type {Event}
         */
        errorEvent : {
            get : function() {
                return this._errorEvent;
            }
        },

        /**
         * Gets a value indicating whether or not the provider is ready for use.
         * @memberof WMTSImageryProvider.prototype
         * @type {Boolean}
         */
        ready : {
            get : function() {
                return this._ready;
            }
        },

        /**
         * Gets the credit to display when this imagery provider is active.  Typically this is used to credit
         * the source of the imagery.  This function should not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Credit}
         */
        credit : {
            get : function() {
                return this._credit;
            }
        },

        /**
         * Gets a value indicating whether or not the images provided by this imagery provider
         * include an alpha channel.  If this property is false, an alpha channel, if present, will
         * be ignored.  If this property is true, any images without an alpha channel will be treated
         * as if their alpha is 1.0 everywhere.  When this property is false, memory usage
         * and texture upload time are reduced.
         * @memberof WMTSImageryProvider.prototype
         * @type {Boolean}
         */
        hasAlphaChannel : {
            get : function() {
                return true;
            }
        }
    });

    /**
     * Gets the credits to be displayed when a given tile is displayed.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level;
     * @returns {Credit[]} The credits to be displayed when the tile is displayed.
     *
     * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready.
     */
    WMTSImageryProvider.prototype.getTileCredits = function(x, y, level) {
        return undefined;
    };

    /**
     * Requests the image for a given tile.  This function should
     * not be called before {@link WMTSImageryProvider#ready} returns true.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @returns {Promise} A promise for the image that will resolve when the image is available, or
     *          undefined if there are too many active requests to the server, and the request
     *          should be retried later.  The resolved image may be either an
     *          Image or a Canvas DOM object.
     *
     * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready.
     */
    WMTSImageryProvider.prototype.requestImage = function(x, y, level) {
        //>>includeStart('debug', pragmas.debug);
        if (!this._ready) {
            throw new DeveloperError('requestImage must not be called before the imagery provider is ready.');
        }
        //>>includeEnd('debug');

        var url = buildImageUrl(this, x, y, level);
        return ImageryProvider.loadImage(this, url);
    };

    return WMTSImageryProvider;
});
<commit_msg>JSHint errors fix<commit_after>/*global define*/
define([
        '../Core/Credit',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/DeveloperError',
        '../Core/Event',
        '../Core/Rectangle',
        '../Core/WebMercatorTilingScheme',
        './ImageryProvider'
    ], function(
        Credit,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Event,
        Rectangle,
        WebMercatorTilingScheme,
        ImageryProvider) {
    "use strict";

    var trailingQMarkRegex = /\?$/;
    var defaultCredit = new Credit("OGC, http://portal.opengeospatial.org/files/?artifact_id=35326");

    /**
     * Provides tiled imagery Served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers
     *
     * @alias WMTSImageryProvider
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {String} [options.url] The WMTS server url.
     * @param {String} [options.format='image/png'] The type mime for images on the server.
     * @param {String} [options.layer] The layer name for WMTS requests
     * @param {String} [options.style] The style name for WMTS requests
     * @param {String} [options.tms] The TileMatrixSetId
     * @param {TilingScheme} [options.tilingScheme] The tilingScheme corresponding to TMS definition
     * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL.
     * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
     * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
     * @param {Number} [options.maximumLevel=18] The maximum level-of-detail supported by the imagery provider.
     * @param {Credit|String} [options.credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
     *
     * @see ArcGisMapServerImageryProvider
     * @see BingMapsImageryProvider
     * @see SingleTileImageryProvider
     * @see TileMapServiceImageryProvider
     * @see WebMapServiceImageryProvider
     *
     * @see {@link http://wiki.openstreetmap.org/wiki/Main_Page|OpenStreetMap Wiki}
     *
     * @example
     * // IGN French Geoportal tile provider
     * var frenchMaps= new Cesium.WMTSImageryProvider({
     *                 url : 'http://wxs.ign.fr/YOUR_KEY/geoportail/wmts',
     *                 layer : 'GEOGRAPHICALGRIDSYSTEMS.MAPS',
     *                 style : 'normal',
     *                 format : 'image/jpeg',
     *                 tms : 'PM',
     *                 credit : new Cesium.Credit("IGN",
     *                                            "http://wxs.ign.fr/static/logos/IGN/IGN.gif",
     *                                            "http://www.ign.fr/")
     *             }) ;
     */
    var WMTSImageryProvider = function WMTSImageryProvider(options) {
        options = defaultValue(options, {});

        if (!defined(options.url)) {
            throw new DeveloperError('options.url is required.');
        }
        if (!defined(options.layer)) {
            throw new DeveloperError('options.layer is required.');
        }
        if (!defined(options.style)) {
            throw new DeveloperError('options.style is required.');
        }
        if (!defined(options.tms)) {
            throw new DeveloperError('options.tms is required.');
        }

        this._url = options.url;
        if (!trailingQMarkRegex.test(this._url)) {
            this._url = this._url + '?';
        }

        this._layer = options.layer;
        this._style = options.style;
        this._tms = options.tms;
        this._format = defaultValue(options.format, 'image/jpg');
        this._proxy = options.proxy;
        this._tileDiscardPolicy = options.tileDiscardPolicy;

        this._tilingScheme = defaultValue(options.tilingScheme,new WebMercatorTilingScheme()) ;
        this._tileWidth = 256;
        this._tileHeight = 256;

        this._minimumLevel = defaultValue(options.minimumLevel, 0);
        this._maximumLevel = defaultValue(options.maximumLevel, 18);

        this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle);

        // Check the number of tiles at the minimum level.  If it's more than four,
        // throw an exception, because starting at the higher minimum
        // level will cause too many tiles to be downloaded and rendered.
        var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel);
        var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel);
        var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
        if (tileCount > 4) {
            throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.');
        }

        this._errorEvent = new Event();

        this._ready = true;

        var credit = defaultValue(options.credit, defaultCredit);
        if (typeof credit === 'string') {
            credit = new Credit(credit);
        }
        this._credit = credit;
    };

    function buildImageUrl(imageryProvider, col, row, level) {
        var url = imageryProvider._url +
                  "service=WMTS&VERSION=1.0.0&request=GetTile" +
                  "&TILEMATRIX="+ level +
                  "&LAYER="+ imageryProvider._layer +
                  "&STYLE="+ imageryProvider._style +
                  "&TILEROW="+ row +
                  '&TILECOL=' + col +
                  '&TILEMATRIXSET=' + imageryProvider._tms +
                  "&FORMAT=" + imageryProvider._format ;

        var proxy = imageryProvider._proxy;
        if (defined(proxy)) {
            url = proxy.getURL(url);
        }

        return url;
    }

    defineProperties(WMTSImageryProvider.prototype, {
        /**
         * Gets the URL of the service hosting the imagery.
         * @memberof WMTSImageryProvider.prototype
         * @type {String}
         */
        url : {
            get : function() {
                return this._url;
            }
        },

        /**
         * Gets the proxy used by this provider.
         * @memberof WMTSImageryProvider.prototype
         * @type {Proxy}
         */
        proxy : {
            get : function() {
                return this._proxy;
            }
        },

        /**
         * Gets the width of each tile, in pixels. This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        tileWidth : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileWidth;
            }
        },

        /**
         * Gets the height of each tile, in pixels.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        tileHeight: {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileHeight;
            }
        },

        /**
         * Gets the maximum level-of-detail that can be requested.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        maximumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._maximumLevel;
            }
        },

        /**
         * Gets the minimum level-of-detail that can be requested.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Number}
         */
        minimumLevel : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._minimumLevel;
            }
        },

        /**
         * Gets the tiling scheme used by this provider.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {TilingScheme}
         */
        tilingScheme : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tilingScheme;
            }
        },

        /**
         * Gets the rectangle, in radians, of the imagery provided by this instance.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Rectangle}
         */
        rectangle : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('rectangle must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._rectangle;
            }
        },

        /**
         * Gets the tile discard policy.  If not undefined, the discard policy is responsible
         * for filtering out "missing" tiles via its shouldDiscardImage function.  If this function
         * returns undefined, no tiles are filtered.  This function should
         * not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {TileDiscardPolicy}
         */
        tileDiscardPolicy : {
            get : function() {
                //>>includeStart('debug', pragmas.debug);
                if (!this._ready) {
                    throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
                }
                //>>includeEnd('debug');

                return this._tileDiscardPolicy;
            }
        },

        /**
         * Gets an event that is raised when the imagery provider encounters an asynchronous error.  By subscribing
         * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
         * are passed an instance of {@link TileProviderError}.
         * @memberof WMTSImageryProvider.prototype
         * @type {Event}
         */
        errorEvent : {
            get : function() {
                return this._errorEvent;
            }
        },

        /**
         * Gets a value indicating whether or not the provider is ready for use.
         * @memberof WMTSImageryProvider.prototype
         * @type {Boolean}
         */
        ready : {
            get : function() {
                return this._ready;
            }
        },

        /**
         * Gets the credit to display when this imagery provider is active.  Typically this is used to credit
         * the source of the imagery.  This function should not be called before {@link WMTSImageryProvider#ready} returns true.
         * @memberof WMTSImageryProvider.prototype
         * @type {Credit}
         */
        credit : {
            get : function() {
                return this._credit;
            }
        },

        /**
         * Gets a value indicating whether or not the images provided by this imagery provider
         * include an alpha channel.  If this property is false, an alpha channel, if present, will
         * be ignored.  If this property is true, any images without an alpha channel will be treated
         * as if their alpha is 1.0 everywhere.  When this property is false, memory usage
         * and texture upload time are reduced.
         * @memberof WMTSImageryProvider.prototype
         * @type {Boolean}
         */
        hasAlphaChannel : {
            get : function() {
                return true;
            }
        }
    });

    /**
     * Gets the credits to be displayed when a given tile is displayed.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level;
     * @returns {Credit[]} The credits to be displayed when the tile is displayed.
     *
     * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready.
     */
    WMTSImageryProvider.prototype.getTileCredits = function(x, y, level) {
        return undefined;
    };

    /**
     * Requests the image for a given tile.  This function should
     * not be called before {@link WMTSImageryProvider#ready} returns true.
     *
     * @param {Number} x The tile X coordinate.
     * @param {Number} y The tile Y coordinate.
     * @param {Number} level The tile level.
     * @returns {Promise} A promise for the image that will resolve when the image is available, or
     *          undefined if there are too many active requests to the server, and the request
     *          should be retried later.  The resolved image may be either an
     *          Image or a Canvas DOM object.
     *
     * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready.
     */
    WMTSImageryProvider.prototype.requestImage = function(x, y, level) {
        //>>includeStart('debug', pragmas.debug);
        if (!this._ready) {
            throw new DeveloperError('requestImage must not be called before the imagery provider is ready.');
        }
        //>>includeEnd('debug');

        var url = buildImageUrl(this, x, y, level);
        return ImageryProvider.loadImage(this, url);
    };

    return WMTSImageryProvider;
});
<|endoftext|>


<commit_before>'use strict';

var I = require('immutable');
var DS = require('./delaney');
var Partition = require('../common/partition');

var _fold = function _fold(partition, a, b, matchP, spreadFn) {
  var p = partition;
  var q = I.List().push(I.List([a, b]));

  while (!q.isEmpty()) {
    var _tmp = q.first();
    var x = _tmp.get(0);
    var y = _tmp.get(1);

    q = q.rest();

    if (!matchP(x, y))
      return;
    else if (p.get(x) == p.get(y))
      continue;
    else {
      p = p.union(x, y);
      q = q.concat(I.List(spreadFn(x, y)).map(I.List));
    }
  }

  return p;
};

var _typeMap = function _typeMap(ds) {
  var base = I.Map(ds.elements().map(function(D) {
    return [D, I.List()];
  }));
  var idcs = DS.indices(ds);

  return base.withMutations(function(map) {
    idcs.zip(idcs.rest()).forEach(function(p) {
      var i = p[0];
      var j = p[1];

      DS.orbitReps2(ds, i, j).forEach(function(D) {
        var m = DS.m(ds, i, j, D);
        DS.orbit2(ds, i, j, D).forEach(function(E) {
          map.set(E, map.get(E).push(m));
        });
      });
    });
  });
};

var isMinimal = function isMinimal(ds) {
  var D0 = ds.elements().first();
  var tm = _typeMap(ds);

  var match = function(D, E) { return tm.get(D).equals(tm.get(E)); };
  var spread = function(D, E) {
    return ds.indices().map(function(i) {
      return [ds.s(i, D), ds.s(i, E)];
    });
  };

  return ds.elements().rest().every(function(D) {
    return _fold(Partition(), D0, D, match, spread) === undefined;
  });
};

var typePartition = function typePartition(ds) {
  var D0 = ds.elements().first();
  var tm = _typeMap(ds);

  var match = function(D, E) { return tm.get(D).equals(tm.get(E)); };
  var spread = function(D, E) {
    return ds.indices().map(function(i) {
      return [ds.s(i, D), ds.s(i, E)];
    });
  };

  return ds.elements().rest().reduce(
    function(p, D) {
      return _fold(p, D0, D, match, spread) || p;
    },
    Partition()
  );
};

var traversal = function traversal(ds, indices, seeds) {
  var todo = I.OrderedMap(I.List(indices).zip(I.Repeat(I.List())))
    .set(root, I.List(seeds));
  var seen = I.Set();
  var result = I.List();

  while (true) {
    var e = todo.entrySeq()
      .filter(function(e) { return !e[1].isEmpty(); })
      .first();
    if (e == null)
      break;

    var i = e[0];
    var a = e[1];
    var D = a.first();
    todo = todo.set(i, a.rest());

    if (!seen.contains(I.List([D, i]))) {
      var Di = (i == root) ? D : ds.s(i, D);

      indices.forEach(function(i) {
        if (!seen.contains(I.List([Di, i])))
          todo = todo.update(i, function(a) {
            return i < 2 ? a.unshift(Di) : a.push(Di);
          });
      });

      seen = seen
        .add(I.List([Di,root]))
        .add(I.List([D,i]))
        .add(I.List([Di,i]));

      result = result.push([D, i, Di]);
    }
  }

  return result;
};

var Traversal = function Traversal(ds, indices, seeds) {
  var todo = I.OrderedMap(I.List(indices).zip(I.Repeat(I.List())))
    .set(root, I.List(seeds));
  var seen = I.Set();

  return {
    next: function() {
      while (true) {
        var e = todo.entrySeq()
          .filter(function(e) { return !e[1].isEmpty(); })
          .first();
        if (e == null)
          return null;

        var i = e[0];
        var a = e[1];
        var D = a.first();
        todo = todo.set(i, a.rest());

        if (!seen.contains(I.List([D, i]))) {
          var Di = (i == root) ? D : ds.s(i, D);

          indices.forEach(function(i) {
            if (!seen.contains(I.List([Di, i])))
              todo = todo.update(i, function(a) {
                return i < 2 ? a.unshift(Di) : a.push(Di);
              });
          });

          seen = seen
            .add(I.List([Di,root]))
            .add(I.List([D,i]))
            .add(I.List([Di,i]));

          return [D, i, Di];
        }
      }
    }
  };
};

var root = traversal.root = null;

var orbitReps = function orbitReps(ds, indices, seeds) {
  return traversal(ds, indices, seeds || ds.elements())
    .filter(function(e) { return e[1] == root; })
    .map(function(e) { return e[2]; });
};

var isConnected = function isConnected(ds) {
  return orbitReps(ds, ds.indices()).size < 2;
};

var orbit = function orbit(ds, indices, seed) {
  var seen = I.Set().asMutable();
  var result = I.List().asMutable();

  traversal(ds, indices, [seed]).forEach(function(e) {
    var D = e[2];
    if (D && !seen.contains(D)) {
      seen.add(D);
      result.push(D);
    }
  });

  return result.asImmutable();
};

var partialOrientation = function partialOrientation(ds) {
  var ori = I.Map().asMutable();

  traversal(ds, ds.indices(), ds.elements()).forEach(function(e) {
    var Di = e[0];
    var i = e[1];
    var D = e[2];

    if (D && !ori.get(D))
      ori.set(D, i == root ? 1 : -ori.get(Di));
  });

  return ori.asImmutable();
};

var isLoopless = function isLoopless(ds) {
  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      return D != ds.s(i, D);
    });
  });
};

var isOriented = function isOriented(ds) {
  var ori = partialOrientation(ds);

  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      return ori.get(D) != ori.get(ds.s(i, D));
    });
  });
};

var isWeaklyOriented = function isWeaklyOriented(ds) {
  var ori = partialOrientation(ds);

  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      var Di = ds.s(i, D);
      return D == Di || ori.get(D) != ori.get(Di);
    });
  });
};

var _branchings = function _branchings(ds, D) {
  var idcs = DS.indices(ds);
  return idcs.zip(idcs.rest()).map(function(p) { return ds.v(p[0], p[1], D); });
};

var invariant = function invariant(ds) {
  var idcs = DS.indices(ds);
  var imap = I.Map(idcs.zip(I.Range()));
  var best = null;

  ds.elements().forEach(function(D0) {
    var trav    = Traversal(ds, idcs, [D0]);
    var emap    = I.Map();
    var n       = 1;
    var current = I.List();
    var keep    = true;

    while (keep) {
      var next = trav.next();
      if (next == null)
        break;
      if (next[2] == null)
        continue;

      var Di = next[0];
      var i  = next[1];
      var D  = next[2];

      var E  = emap.get(D) || n;
      var chunk = I.List((i == root) ? [-1, E] : [imap.get(i), emap.get(Di), E]);

      if (E == n) {
        emap = emap.set(D, n);
        chunk = chunk.concat(_branchings(ds, D));
        ++n;
      }

      for (var k = 0; best && keep && k < chunk.size; ++k) {
        var d = chunk.get(k) - best.get(current.size + k);
        if (d > 0)
          keep = false;
        else if (d < 0)
          best = null;
      }

      current = current.concat(chunk);
    }

    if (best == null)
      best = current;
  });

  return best;
};

module.exports = {
  isMinimal         : isMinimal,
  typePartition     : typePartition,
  traversal         : traversal,
  orbitReps         : orbitReps,
  isConnected       : isConnected,
  orbit             : orbit,
  partialOrientation: partialOrientation,
  isLoopless        : isLoopless,
  isOriented        : isOriented,
  isWeaklyOriented  : isWeaklyOriented,
  invariant         : invariant
};

if (require.main == module) {
  var test = function test(ds) {
    console.log('ds = '+ds);
    console.log();

    console.log('    symbol is '+(isConnected(ds) ? '' : 'not ')+'connected.');
    console.log('    symbol is '+(isMinimal(ds) ? '' : 'not ')+'minimal.');
    console.log('    symbol is '+(isLoopless(ds) ? '' : 'not ')+'loopless.');
    console.log('    symbol is '+(isOriented(ds) ? '' : 'not ')+'oriented.');
    console.log('    symbol is '+(isWeaklyOriented(ds) ? '' : 'not ')
                +'weakly oriented.');
    console.log('    type partition: '+typePartition(ds));
    var trav = traversal(ds, ds.indices(), ds.elements());
    console.log('    traversal: ' + trav);
    console.log('    invariant: ' + invariant(ds));
    console.log();

    console.log('    0,1 orbit reps: '+orbitReps(ds, [0, 1]));
    console.log('    1,2 orbit reps: '+orbitReps(ds, [1, 2]));
    console.log('    0,2 orbit reps: '+orbitReps(ds, [0, 2]));
    console.log();

    console.log('    0,1 orbit of 1: '+orbit(ds, [0, 1], 1));
    console.log('    1,2 orbit of 1: '+orbit(ds, [1, 2], 1));
    console.log('    0,2 orbit of 1: '+orbit(ds, [0, 2], 1));
    console.log();

    console.log('    partial orientation: '+partialOrientation(ds));
    console.log();
    console.log();
  };

  test(DS.parse(
    '<1.1:24:' +
      '2 4 6 8 10 12 14 16 18 20 22 24,' +
      '16 3 5 7 9 11 13 15 24 19 21 23,' +
      '10 9 20 19 14 13 22 21 24 23 18 17:' +
      '8 4,3 3 3 3>'));

  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(DS.parse('<1.1:2 3:2,1 2,1 2,2:6,3 2,6>'));
  test(DS.parse('<1.1:6:4 6 5,5 4 6,4 6 5:3,6>'));
}
<commit_msg>speed up Traversal()<commit_after>'use strict';

var I = require('immutable');
var DS = require('./delaney');
var Partition = require('../common/partition');

var _fold = function _fold(partition, a, b, matchP, spreadFn) {
  var p = partition;
  var q = I.List().push(I.List([a, b]));

  while (!q.isEmpty()) {
    var _tmp = q.first();
    var x = _tmp.get(0);
    var y = _tmp.get(1);

    q = q.rest();

    if (!matchP(x, y))
      return;
    else if (p.get(x) == p.get(y))
      continue;
    else {
      p = p.union(x, y);
      q = q.concat(I.List(spreadFn(x, y)).map(I.List));
    }
  }

  return p;
};

var _typeMap = function _typeMap(ds) {
  var base = I.Map(ds.elements().map(function(D) {
    return [D, I.List()];
  }));
  var idcs = DS.indices(ds);

  return base.withMutations(function(map) {
    idcs.zip(idcs.rest()).forEach(function(p) {
      var i = p[0];
      var j = p[1];

      DS.orbitReps2(ds, i, j).forEach(function(D) {
        var m = DS.m(ds, i, j, D);
        DS.orbit2(ds, i, j, D).forEach(function(E) {
          map.set(E, map.get(E).push(m));
        });
      });
    });
  });
};

var isMinimal = function isMinimal(ds) {
  var D0 = ds.elements().first();
  var tm = _typeMap(ds);

  var match = function(D, E) { return tm.get(D).equals(tm.get(E)); };
  var spread = function(D, E) {
    return ds.indices().map(function(i) {
      return [ds.s(i, D), ds.s(i, E)];
    });
  };

  return ds.elements().rest().every(function(D) {
    return _fold(Partition(), D0, D, match, spread) === undefined;
  });
};

var typePartition = function typePartition(ds) {
  var D0 = ds.elements().first();
  var tm = _typeMap(ds);

  var match = function(D, E) { return tm.get(D).equals(tm.get(E)); };
  var spread = function(D, E) {
    return ds.indices().map(function(i) {
      return [ds.s(i, D), ds.s(i, E)];
    });
  };

  return ds.elements().rest().reduce(
    function(p, D) {
      return _fold(p, D0, D, match, spread) || p;
    },
    Partition()
  );
};

var traversal = function traversal(ds, indices, seeds) {
  var todo = I.OrderedMap(I.List(indices).zip(I.Repeat(I.List())))
    .set(root, I.List(seeds));
  var seen = I.Set();
  var result = I.List();

  while (true) {
    var e = todo.entrySeq()
      .filter(function(e) { return !e[1].isEmpty(); })
      .first();
    if (e == null)
      break;

    var i = e[0];
    var a = e[1];
    var D = a.first();
    todo = todo.set(i, a.rest());

    if (!seen.contains(I.List([D, i]))) {
      var Di = (i == root) ? D : ds.s(i, D);

      indices.forEach(function(i) {
        if (!seen.contains(I.List([Di, i])))
          todo = todo.update(i, function(a) {
            return i < 2 ? a.unshift(Di) : a.push(Di);
          });
      });

      seen = seen
        .add(I.List([Di,root]))
        .add(I.List([D,i]))
        .add(I.List([Di,i]));

      result = result.push([D, i, Di]);
    }
  }

  return result;
};

var Traversal = function Traversal(ds, indices, seeds) {
  var seedsLeft = seeds.slice();
  var todo = {};
  var seen = {};
  indices.forEach(function(i) { seen[i] = {}; todo[i] = [] });
  seen[root] = {};

  return {
    next: function() {
      while (true) {
        var i = null, D = null;
        for (var k = 0; k < indices.size; ++k)
          if (todo[indices.get(k)].length > 0) {
            i = indices.get(k);
            D = todo[i].shift();
            break;
          }

        if (D == null && seedsLeft.length > 0)
          D = seedsLeft.shift();

        if (D == null)
          return null;

        if (!seen[i][D]) {
          var Di = (i == root) ? D : ds.s(i, D);

          indices.forEach(function(i) {
            if (!seen[i][Di]) {
              if (i < 2)
                todo[i].unshift(Di);
              else
                todo[i].push(Di);
            }
          });

          seen[root][Di] = true;
          seen[i][D]     = true;
          seen[i][Di]    = true;

          return [D, i, Di];
        }
      }
    }
  };
};

var root = traversal.root = null;

var orbitReps = function orbitReps(ds, indices, seeds) {
  return traversal(ds, indices, seeds || ds.elements())
    .filter(function(e) { return e[1] == root; })
    .map(function(e) { return e[2]; });
};

var isConnected = function isConnected(ds) {
  return orbitReps(ds, ds.indices()).size < 2;
};

var orbit = function orbit(ds, indices, seed) {
  var seen = I.Set().asMutable();
  var result = I.List().asMutable();

  traversal(ds, indices, [seed]).forEach(function(e) {
    var D = e[2];
    if (D && !seen.contains(D)) {
      seen.add(D);
      result.push(D);
    }
  });

  return result.asImmutable();
};

var partialOrientation = function partialOrientation(ds) {
  var ori = I.Map().asMutable();

  traversal(ds, ds.indices(), ds.elements()).forEach(function(e) {
    var Di = e[0];
    var i = e[1];
    var D = e[2];

    if (D && !ori.get(D))
      ori.set(D, i == root ? 1 : -ori.get(Di));
  });

  return ori.asImmutable();
};

var isLoopless = function isLoopless(ds) {
  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      return D != ds.s(i, D);
    });
  });
};

var isOriented = function isOriented(ds) {
  var ori = partialOrientation(ds);

  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      return ori.get(D) != ori.get(ds.s(i, D));
    });
  });
};

var isWeaklyOriented = function isWeaklyOriented(ds) {
  var ori = partialOrientation(ds);

  return ds.elements().every(function(D) {
    return ds.indices().every(function(i) {
      var Di = ds.s(i, D);
      return D == Di || ori.get(D) != ori.get(Di);
    });
  });
};

var _branchings = function _branchings(ds, D) {
  var idcs = DS.indices(ds);
  return idcs.zip(idcs.rest()).map(function(p) { return ds.v(p[0], p[1], D); });
};

var invariant = function invariant(ds) {
  var idcs = DS.indices(ds);
  var imap = I.Map(idcs.zip(I.Range()));
  var best = null;

  ds.elements().forEach(function(D0) {
    var trav    = Traversal(ds, idcs, [D0]);
    var emap    = I.Map();
    var n       = 1;
    var current = I.List();
    var keep    = true;

    while (keep) {
      var next = trav.next();
      if (next == null)
        break;
      if (next[2] == null)
        continue;

      var Di = next[0];
      var i  = next[1];
      var D  = next[2];

      var E  = emap.get(D) || n;
      var chunk = I.List((i == root) ? [-1, E] : [imap.get(i), emap.get(Di), E]);

      if (E == n) {
        emap = emap.set(D, n);
        chunk = chunk.concat(_branchings(ds, D));
        ++n;
      }

      for (var k = 0; best && keep && k < chunk.size; ++k) {
        var d = chunk.get(k) - best.get(current.size + k);
        if (d > 0)
          keep = false;
        else if (d < 0)
          best = null;
      }

      current = current.concat(chunk);
    }

    if (best == null)
      best = current;
  });

  return best;
};

module.exports = {
  isMinimal         : isMinimal,
  typePartition     : typePartition,
  traversal         : traversal,
  orbitReps         : orbitReps,
  isConnected       : isConnected,
  orbit             : orbit,
  partialOrientation: partialOrientation,
  isLoopless        : isLoopless,
  isOriented        : isOriented,
  isWeaklyOriented  : isWeaklyOriented,
  invariant         : invariant
};

if (require.main == module) {
  var test = function test(ds) {
    console.log('ds = '+ds);
    console.log();

    console.log('    symbol is '+(isConnected(ds) ? '' : 'not ')+'connected.');
    console.log('    symbol is '+(isMinimal(ds) ? '' : 'not ')+'minimal.');
    console.log('    symbol is '+(isLoopless(ds) ? '' : 'not ')+'loopless.');
    console.log('    symbol is '+(isOriented(ds) ? '' : 'not ')+'oriented.');
    console.log('    symbol is '+(isWeaklyOriented(ds) ? '' : 'not ')
                +'weakly oriented.');
    console.log('    type partition: '+typePartition(ds));
    var trav = traversal(ds, ds.indices(), ds.elements());
    console.log('    traversal: ' + trav);
    console.log('    invariant: ' + invariant(ds));
    console.log();

    console.log('    0,1 orbit reps: '+orbitReps(ds, [0, 1]));
    console.log('    1,2 orbit reps: '+orbitReps(ds, [1, 2]));
    console.log('    0,2 orbit reps: '+orbitReps(ds, [0, 2]));
    console.log();

    console.log('    0,1 orbit of 1: '+orbit(ds, [0, 1], 1));
    console.log('    1,2 orbit of 1: '+orbit(ds, [1, 2], 1));
    console.log('    0,2 orbit of 1: '+orbit(ds, [0, 2], 1));
    console.log();

    console.log('    partial orientation: '+partialOrientation(ds));
    console.log();
    console.log();
  };

  test(DS.parse(
    '<1.1:24:' +
      '2 4 6 8 10 12 14 16 18 20 22 24,' +
      '16 3 5 7 9 11 13 15 24 19 21 23,' +
      '10 9 20 19 14 13 22 21 24 23 18 17:' +
      '8 4,3 3 3 3>'));

  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(DS.parse('<1.1:2 3:2,1 2,1 2,2:6,3 2,6>'));
  test(DS.parse('<1.1:6:4 6 5,5 4 6,4 6 5:3,6>'));
}
<|endoftext|>


<commit_before>(function($){
	// This function adds noise to the background-image attribute of a given element
	$.fn.noisy = function(options) {
		options = $.extend({}, $.fn.noisy.defaults, options);
		var uri, localStorageSupported, cachedUri = false;

		try {
			localStorageSupported = true;
			cachedUri = localStorage.getItem(window.JSON.stringify(options));
		} catch(e) {
			localStorageSupported = false;
		}

		// Use localStorage cache if these options have been used before
		if (cachedUri) {
			uri = cachedUri;
		}
		else {
			var canvas = document.createElement('canvas');

			// Use fallback image if canvas isn't supported
			if (!canvas.getContext) {
				uri = options.fallback;
			}
			else {
				canvas.width = canvas.height = options.size;

				var ctx = canvas.getContext('2d'),
				    imgData = ctx.createImageData(canvas.width, canvas.height),
				    numPixels = Math.round( options.intensity * Math.pow(options.size, 2) ),
				    maxAlpha = 255 * options.opacity;

				// Add color to random pixels in the canvas
				while (numPixels--) { // Read about the double bitwise NOT trick here: goo.gl/6DPpt
					var x = ~~(Math.random()*canvas.width),
					    y = ~~(Math.random()*canvas.height),
					    index = (x + y * imgData.width) * 4;

					var colorChannel = numPixels % 255; // This will look random enough
					imgData.data[index  ] = colorChannel;                                               // red
					imgData.data[index+1] = options.monochrome ? colorChannel : ~~(Math.random()*255);  // green
					imgData.data[index+2] = options.monochrome ? colorChannel : ~~(Math.random()*255);  // blue
					imgData.data[index+3] = ~~(Math.random()*maxAlpha);                                 // alpha
				}

				ctx.putImageData(imgData, 0, 0);
				uri = canvas.toDataURL('image/png');

				// In IE < 9 Data URI's are only displayed if they are < 32KB
				// Though IE < 9 doesn't officially support the canvas element,
				//   certain scripts like excanvas.js will enable it and if the URI is > 32KB it won't be displayed
				if (uri.indexOf('data:image/png') != 0 || // toDataURL doesn't return anything in Android 2.2
				    $.browser.msie &&
				    $.browser.version.substr(0,1) < 9 &&
				    uri.length > 32768) {
					uri = options.fallback;
				}
			}

			if (window.JSON && localStorageSupported) {
				localStorage.setItem(window.JSON.stringify(options), uri);
			}
		}

		return this.each(function() {
	 		$(this).css('background-image', "url('" + uri + "')," + $(this).css('background-image'));
		});
	};
	$.fn.noisy.defaults = {
		// How many percent of the image that is filled with noise,
		//   represented by a number between 0 and 1 inclusive
		intensity:          0.9,

		// The width and height of the image in pixels
		size:               200,

		// The maximum noise particle opacity,
		//   represented by a number between 0 and 1 inclusive
		opacity:            0.08,

		// A string linking to the image used if there's no canvas support
		fallback:           '',

		// Specifies wheter the particles are grayscale or colorful
		monochrome:         false
	};
})(jQuery);
<commit_msg>Removed IE<9 support<commit_after>(function($){
	// This function adds noise to the background-image attribute of a given element
	$.fn.noisy = function(options) {
		options = $.extend({}, $.fn.noisy.defaults, options);
		var uri, localStorageSupported, cachedUri = false;

		try {
			localStorageSupported = true;
			cachedUri = localStorage.getItem(window.JSON.stringify(options));
		} catch(e) {
			localStorageSupported = false;
		}

		// Use localStorage cache if these options have been used before
		if (cachedUri) {
			uri = cachedUri;
		}
		else {
			var canvas = document.createElement('canvas');

			// Use fallback image if canvas isn't supported
			if (!canvas.getContext) {
				uri = options.fallback;
			}
			else {
				canvas.width = canvas.height = options.size;

				var ctx = canvas.getContext('2d'),
				    imgData = ctx.createImageData(canvas.width, canvas.height),
				    numPixels = Math.round( options.intensity * Math.pow(options.size, 2) ),
				    maxAlpha = 255 * options.opacity;

				// Add color to random pixels in the canvas
				while (numPixels--) { // Read about the double bitwise NOT trick here: goo.gl/6DPpt
					var x = ~~(Math.random()*canvas.width),
					    y = ~~(Math.random()*canvas.height),
					    index = (x + y * imgData.width) * 4;

					var colorChannel = numPixels % 255; // This will look random enough
					imgData.data[index  ] = colorChannel;                                               // red
					imgData.data[index+1] = options.monochrome ? colorChannel : ~~(Math.random()*255);  // green
					imgData.data[index+2] = options.monochrome ? colorChannel : ~~(Math.random()*255);  // blue
					imgData.data[index+3] = ~~(Math.random()*maxAlpha);                                 // alpha
				}

				ctx.putImageData(imgData, 0, 0);
				uri = canvas.toDataURL('image/png');

				// toDataURL doesn't return anything in Android 2.2
				if (uri.indexOf('data:image/png') != 0) {
					uri = options.fallback;
				}
			}

			if (window.JSON && localStorageSupported) {
				localStorage.setItem(window.JSON.stringify(options), uri);
			}
		}

		return this.each(function() {
	 		$(this).css('background-image', "url('" + uri + "')," + $(this).css('background-image'));
		});
	};
	$.fn.noisy.defaults = {
		// How many percent of the image that is filled with noise,
		//   represented by a number between 0 and 1 inclusive
		intensity:          0.9,

		// The width and height of the image in pixels
		size:               200,

		// The maximum noise particle opacity,
		//   represented by a number between 0 and 1 inclusive
		opacity:            0.08,

		// A string linking to the image used if there's no canvas support
		fallback:           '',

		// Specifies wheter the particles are grayscale or colorful
		monochrome:         false
	};
})(jQuery);
<|endoftext|>


<commit_before>const { writeFileSync } = require("fs");
const { sync: makeDirectory } = require("mkdirp");
const { transform } = require("./babel");
const banner = require("./banner");
const { prettify } = require("./prettify");
const sources = require("./sources");

function build() {
  makeDirectory("lib");

  Object.keys(sources).forEach(file => {
    const dest = `lib/${file}.flow`;
    const code = transform(sources[file], { flow: true });
    const prettified = prettify(code).replace(/\/\* @flow \*\/\n/, "");
    const bannered = `${banner.flow}${prettified}`;

    writeFileSync(dest, bannered);
  });
}

module.exports = build;
<commit_msg>Don't transpile flow modules<commit_after>const { writeFileSync } = require("fs");
const { sync: makeDirectory } = require("mkdirp");
const banner = require("./banner");
const { prettify } = require("./prettify");
const sources = require("./sources");

function build() {
  makeDirectory("lib");

  Object.keys(sources).forEach(file => {
    const dest = `lib/${file}.flow`;
    const code = prettify(sources[file]).replace(/\/\* @flow \*\/\n/, "");
    const bannered = `${banner.flow}${code}`;

    writeFileSync(dest, bannered);
  });
}

module.exports = build;
<|endoftext|>


<commit_before>/**
 * NestedModel editor
 *
 * Creates a child form. For editing nested Backbone models
 *
 * Special options:
 *   schema.model:   Embedded model constructor
 */
Form.editors.NestedModel = Form.editors.Object.extend({
  initialize: function(options) {
    Form.editors.Base.prototype.initialize.call(this, options);

    if (!this.form) throw new Error('Missing required option "form"');
    if (!options.schema.model) throw new Error('Missing required "schema.model" option for NestedModel editor');

    //Get the constructor for creating the nested form; i.e. the same constructor as used by the parent form
    var NestedForm = this.form.NestedForm;

    var data = this.value || {},
        key = this.key,
        nestedModel = this.schema.model;

    //Wrap the data in a model if it isn't already a model instance
    var modelInstance = (data.constructor === nestedModel) ? data : new nestedModel(data);

    this.nestedForm = new NestedForm({
      model: modelInstance,
      idPrefix: this.id + '_',
      fieldTemplate: 'nestedField'
    });
  },

  render: function() {

    this._observeFormEvents();

    //Render form
    this.$el.html(this.nestedForm.render().el);

    if (this.hasFocus) this.trigger('blur', this);

    return this;
  },

  /**
   * Update the embedded model, checking for nested validation errors and pass them up
   * Then update the main model if all OK
   *
   * @return {Error|null} Validation error or null
   */
  commit: function() {
    var error = this.nestedForm.commit();
    if (error) {
      this.$el.addClass('error');
      return error;
    }

    return Form.editors.Object.prototype.commit.call(this);
  }

});
<commit_msg>Remove NestedModel.render() - its now inherited from Object.render()<commit_after>/**
 * NestedModel editor
 *
 * Creates a child form. For editing nested Backbone models
 *
 * Special options:
 *   schema.model:   Embedded model constructor
 */
Form.editors.NestedModel = Form.editors.Object.extend({
  initialize: function(options) {
    Form.editors.Base.prototype.initialize.call(this, options);

    if (!this.form) throw new Error('Missing required option "form"');
    if (!options.schema.model) throw new Error('Missing required "schema.model" option for NestedModel editor');

    //Get the constructor for creating the nested form; i.e. the same constructor as used by the parent form
    var NestedForm = this.form.NestedForm;

    var data = this.value || {},
        key = this.key,
        nestedModel = this.schema.model;

    //Wrap the data in a model if it isn't already a model instance
    var modelInstance = (data.constructor === nestedModel) ? data : new nestedModel(data);

    this.nestedForm = new NestedForm({
      model: modelInstance,
      idPrefix: this.id + '_',
      fieldTemplate: 'nestedField'
    });
  },

  /**
   * Update the embedded model, checking for nested validation errors and pass them up
   * Then update the main model if all OK
   *
   * @return {Error|null} Validation error or null
   */
  commit: function() {
    var error = this.nestedForm.commit();
    if (error) {
      this.$el.addClass('error');
      return error;
    }

    return Form.editors.Object.prototype.commit.call(this);
  }

});
<|endoftext|>


<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * Tests for Enumeration
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( function( require ) {
  'use strict';

  // modules
  const Enumeration = require( 'PHET_CORE/Enumeration' );

  QUnit.module( 'Enumeration' );

  QUnit.test( 'Basic enumeration', function( assert ) {
    const CardinalDirection = new Enumeration( [ 'NORTH', 'SOUTH', 'EAST', 'WEST' ] );

    assert.equal( CardinalDirection.NORTH, 'NORTH', 'Equality for NORTH' );
    assert.equal( CardinalDirection.SOUTH, 'SOUTH', 'Equality for SOUTH' );
    assert.equal( CardinalDirection.EAST, 'EAST', 'Equality for EAST' );
    assert.equal( CardinalDirection.WEST, 'WEST', 'Equality for WEST' );

    assert.equal( CardinalDirection.includes( CardinalDirection.NORTH ), true, 'NORTH is in the enumeration' );
    assert.equal( CardinalDirection.includes( 'NORTH' ), false, 'Strings shouln\'t match' );
    assert.equal( CardinalDirection.includes( 'YORKSHIRE_TERRIER_WITH_THE_CANDLE_STICK_IN_THE_BALLROOM' ), false,
      'Not in the enumeration' );
    assert.equal( CardinalDirection.includes( { name: 'NORTH' } ), false, 'Should not be able to synthesize Enumeration values' );

    window.assert && assert.throws( function() {
      CardinalDirection.SOMETHING_AFTER_THE_FREEZE = 5;
    }, 'Should not be able to set things after initialization' );
  } );

  QUnit.test( 'Before freeze test', function( assert ) {
    const E = new Enumeration( [ 'A', 'B' ], E => {
      E.opposite = e => {
        window.assert && window.assert( E.includes( e ) );
        return e === E.A ? E.B : E.A;
      };
    } );

    assert.equal( E.A, 'A', 'Equality for A' );
    assert.equal( E.B, 'B', 'Equality for B' );
    assert.equal( E.opposite( E.A ), E.B, 'Custom function check 1' );
    assert.equal( E.opposite( E.B ), E.A, 'Custom function check 2' );

    window.assert && assert.throws( function() {
      E.SOMETHING_AFTER_THE_FREEZE = 5;
    }, 'Should not be able to set things after initialization' );
  } );
} );
<commit_msg>Add test for toString, see https://github.com/phetsims/phet-core/issues/42<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * Tests for Enumeration
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
define( function( require ) {
  'use strict';

  // modules
  const Enumeration = require( 'PHET_CORE/Enumeration' );

  QUnit.module( 'Enumeration' );

  QUnit.test( 'Basic enumeration', function( assert ) {
    const CardinalDirection = new Enumeration( [ 'NORTH', 'SOUTH', 'EAST', 'WEST' ] );

    assert.equal( CardinalDirection.NORTH, 'NORTH', 'Equality for NORTH' );
    assert.equal( CardinalDirection.SOUTH, 'SOUTH', 'Equality for SOUTH' );
    assert.equal( CardinalDirection.EAST, 'EAST', 'Equality for EAST' );
    assert.equal( CardinalDirection.WEST, 'WEST', 'Equality for WEST' );

    assert.equal( CardinalDirection.includes( CardinalDirection.NORTH ), true, 'NORTH is in the enumeration' );
    assert.equal( CardinalDirection.includes( 'NORTH' ), false, 'Strings shouln\'t match' );
    assert.equal( CardinalDirection.includes( 'YORKSHIRE_TERRIER_WITH_THE_CANDLE_STICK_IN_THE_BALLROOM' ), false,
      'Not in the enumeration' );
    assert.equal( CardinalDirection.includes( { name: 'NORTH' } ), false, 'Should not be able to synthesize Enumeration values' );

    // Test toString
    var object = {};
    object[ CardinalDirection.NORTH ] = 'exit';
    assert.equal( object.NORTH, 'exit', 'toString should work seamlessly' );

    window.assert && assert.throws( function() {
      CardinalDirection.SOMETHING_AFTER_THE_FREEZE = 5;
    }, 'Should not be able to set things after initialization' );
  } );

  QUnit.test( 'Before freeze test', function( assert ) {
    const E = new Enumeration( [ 'A', 'B' ], E => {
      E.opposite = e => {
        window.assert && window.assert( E.includes( e ) );
        return e === E.A ? E.B : E.A;
      };
    } );

    assert.equal( E.A, 'A', 'Equality for A' );
    assert.equal( E.B, 'B', 'Equality for B' );
    assert.equal( E.opposite( E.A ), E.B, 'Custom function check 1' );
    assert.equal( E.opposite( E.B ), E.A, 'Custom function check 2' );

    window.assert && assert.throws( function() {
      E.SOMETHING_AFTER_THE_FREEZE = 5;
    }, 'Should not be able to set things after initialization' );
  } );
} );
<|endoftext|>


<commit_before>/**
 * Extension Enabler for the Game Triton Neptunes Prime 2.
 *
 * This file is a simple content script for a google chrome extension
 * which is is responsible to execute Triton extensions
 * inside the execution context of the game page http://triton.ironhelmet.com/game/...
 *
 * The following extensions are already implemented:
 *
 * - assign the space bar as hot key for the ruler
 *
 * @author fxdapokalypse
 */
(function () {
    "use strict";

    /**
     * List of shorthand objects
     */
    var array = [];
    var slice = Array.prototype.slice;
    var root = this;
    var TPEnabler = root.TPEnabler = {};

    /**
     * A main routine which executes a specified javascript function
     * in the execution context of the surrounding web page.
     *
     * @param callback The specified js function which should executed inside the surrounding web page.
     */
    TPEnabler.main = function (callback) {
        $("body").append($("<script />", {
            type: 'text/javascript',
            html: TPEnabler.createExecutionInstructions(callback)
        }));

        $("body").append($("<script />", {
            type: 'text/javascript',
            src: "https://www.dropbox.com/static/api/2/dropins.js",
            id: "dropboxjs",
            'data-app-key': "1kc1ely28g2dlsi"
        }));
    };

    /**
     * Creates a execution string for a specified js instruction.
     *
     * @param {string|function} statement   The js instruction as string or as function object..
     * @param {boolean} returnAsURLString   The flag which determines statement should be returned as javascript url.
     * @returns {string}                    The javascript statement as string.
     */
    TPEnabler.createExecutionInstructions = function (statement, returnAsURLString) {
        if (typeof statement === 'function') {
            statement = "(" + statement.toString() + ").call();";
        }

        if (returnAsURLString && !statement.match(/^javascript:/)) {
            statement = "javascript:" + statement;
        }

        return statement;
    };

    /**
     * Executes a javascript statement inside the execution context
     * of the surrounding page. Please Consider this function must
     * used inside the TPEnabler.main callback function.
     *
     * @param {string|function} statement The statement which should be executed.
     */
    TPEnabler.execute = function (statement) {
        var instructions = TPEnabler.createExecutionInstructions(statement, true);
        window.location.href = instructions;
    };

}).call(this);

TPEnabler.main(function () {
    // Please avoid comments inside the instruction function
    TPEnabler.execute(function () {
        Mousetrap.bind(['space'], function () {
            Crux.crux.trigger('start_ruler');
        });

        Mousetrap.bind(['p'], function () {
            var imageURL = $('canvas').get(0).toDataURL("image/jpeg");
            var fileName = "intel" + (new Date()).toLocaleString().replace(/[\s\.:]/g, '_') + ".jpg";
            Dropbox.save({
                files: [{
                    url: imageURL,
                    filename : fileName
                }],
                success: function () {},
                progress: function (progress) {},
                cancel: function () {},
                error: function (errorMessage) {}
            });
        });
    });
});

<commit_msg>Assigns the space bar as hot key which resets the ruler.<commit_after>/**
 * Extension Enabler for the Game Triton Neptunes Prime 2.
 *
 * This file is a simple content script for a google chrome extension
 * which is is responsible to execute Triton extensions
 * inside the execution context of the game page http://triton.ironhelmet.com/game/...
 *
 * The following extensions are already implemented:
 *
 * - assign the space bar as hot key for the reset of the ruler
 *
 * @author fxdapokalypse
 */
(function () {
    "use strict";

    /**
     * List of shorthand objects
     */
    var array = [];
    var slice = Array.prototype.slice;
    var root = this;
    var TPEnabler = root.TPEnabler = {};

    /**
     * A main routine which executes a specified javascript function
     * in the execution context of the surrounding web page.
     *
     * @param callback The specified js function which should executed inside the surrounding web page.
     */
    TPEnabler.main = function (callback) {
        $("body").append($("<script />", {
            type: 'text/javascript',
            html: TPEnabler.createExecutionInstructions(callback)
        }));

        $("body").append($("<script />", {
            type: 'text/javascript',
            src: "https://www.dropbox.com/static/api/2/dropins.js",
            id: "dropboxjs",
            'data-app-key': "1kc1ely28g2dlsi"
        }));
    };

    /**
     * Creates a execution string for a specified js instruction.
     *
     * @param {string|function} statement   The js instruction as string or as function object..
     * @param {boolean} returnAsURLString   The flag which determines statement should be returned as javascript url.
     * @returns {string}                    The javascript statement as string.
     */
    TPEnabler.createExecutionInstructions = function (statement, returnAsURLString) {
        if (typeof statement === 'function') {
            statement = "(" + statement.toString() + ").call();";
        }

        if (returnAsURLString && !statement.match(/^javascript:/)) {
            statement = "javascript:" + statement;
        }

        return statement;
    };

    /**
     * Executes a javascript statement inside the execution context
     * of the surrounding page. Please Consider this function must
     * used inside the TPEnabler.main callback function.
     *
     * @param {string|function} statement The statement which should be executed.
     */
    TPEnabler.execute = function (statement) {
        var instructions = TPEnabler.createExecutionInstructions(statement, true);
        window.location.href = instructions;
    };

}).call(this);

TPEnabler.main(function () {
    // Please avoid comments inside the instruction function
    TPEnabler.execute(function () {
        Mousetrap.bind(['space'], function () {
            Crux.crux.trigger('start_ruler');
            Crux.crux.trigger('start_ruler');
        });

        Mousetrap.bind(['p'], function () {
            var imageURL = $('canvas').get(0).toDataURL("image/jpeg");
            var fileName = "intel" + (new Date()).toLocaleString().replace(/[\s\.:]/g, '_') + ".jpg";
            Dropbox.save({
                files: [{
                    url: imageURL,
                    filename : fileName
                }],
                success: function () {},
                progress: function (progress) {},
                cancel: function () {},
                error: function (errorMessage) {}
            });
        });
    });
});

<|endoftext|>


<commit_before>(function () {
  var QuadraticDrawing = {

    height : null,
    width : null,
    rendered : false,

    render : function (node) {
      var
        canvas = bonzo.create('<canvas></canvas>')[0],
        offset = bonzo(node).offset();

      this.height = offset.height;
      this.width = offset.width;

      bonzo(canvas)
        .attr('height', offset.height)
        .attr('width', offset.width)
        .css({
          position : 'absolute',
          top : '0px',
          left : '0px'
        });

      node.appendChild(canvas);
      bonzo(node).css({
        position : 'relative'
      });

      this.context = canvas.getContext('2d');
      this.rendered = true;
    },

    draw : function (data, options, node) {

      if (!this.rendered) this.render(node);
      options = options || {};

      console.log(options.min, options.max);

      var
        context = this.context,
        height = this.height,
        width = this.width,
        half = Math.round(height / 2) - .5,
        min = options.min + 1,
        max = options.max;

      context.clearRect(0, 0, width, height);
      if (min || max) {
        context.save();
        context.strokeStyle = '#B6D9FF';
        context.fillOpacity = .5;
        context.fillStyle = 'rgba(182, 217, 255, .4)';
        context.beginPath();

        // Left
        if (min === 1) {
          context.moveTo(0, height);
          context.lineTo(0, 0);
        } else {
          context.moveTo(min, height);
          context.quadraticCurveTo(min, half, Math.max(min - half, min / 2), half);
          context.lineTo(Math.min(half, min / 2), half);
          context.quadraticCurveTo(0, half, 0, 0);
        }

        // Top
        context.lineTo(width, 0);

        // Right
        if (max >= width - 1) {
          context.lineTo(max, height);
        } else {
          context.quadraticCurveTo(width, half, Math.max(width - half, width - (width - max) / 2), half);
          context.lineTo(Math.min(max + half, width - (width - max) / 2), half);
          context.quadraticCurveTo(max, half, max, height);
        }

        context.stroke();
        context.closePath();
        context.fill();
        context.restore();
      }
    },
    adapter : {
      trigger : function (child, name, options) {
        if (name === 'select') {
          this.select(child, options);
        }
      },
      select : function (child, options) {
        var
          x = options.x || {},
          min = x.min,
          max = x.max,
          api = child.api;

        child.draw(null, {
          min : min,
          max : max
        });
      }
    }
  };
  humblevis.QuadraticDrawing = QuadraticDrawing;
})();
<commit_msg>Remove logging.<commit_after>(function () {
  var QuadraticDrawing = {

    height : null,
    width : null,
    rendered : false,

    render : function (node) {
      var
        canvas = bonzo.create('<canvas></canvas>')[0],
        offset = bonzo(node).offset();

      this.height = offset.height;
      this.width = offset.width;

      bonzo(canvas)
        .attr('height', offset.height)
        .attr('width', offset.width)
        .css({
          position : 'absolute',
          top : '0px',
          left : '0px'
        });

      node.appendChild(canvas);
      bonzo(node).css({
        position : 'relative'
      });

      this.context = canvas.getContext('2d');
      this.rendered = true;
    },

    draw : function (data, options, node) {

      if (!this.rendered) this.render(node);
      options = options || {};

      var
        context = this.context,
        height = this.height,
        width = this.width,
        half = Math.round(height / 2) - .5,
        min = options.min + 1,
        max = options.max;

      context.clearRect(0, 0, width, height);
      if (min || max) {
        context.save();
        context.strokeStyle = '#B6D9FF';
        context.fillOpacity = .5;
        context.fillStyle = 'rgba(182, 217, 255, .4)';
        context.beginPath();

        // Left
        if (min === 1) {
          context.moveTo(0, height);
          context.lineTo(0, 0);
        } else {
          context.moveTo(min, height);
          context.quadraticCurveTo(min, half, Math.max(min - half, min / 2), half);
          context.lineTo(Math.min(half, min / 2), half);
          context.quadraticCurveTo(0, half, 0, 0);
        }

        // Top
        context.lineTo(width, 0);

        // Right
        if (max >= width - 1) {
          context.lineTo(max, height);
        } else {
          context.quadraticCurveTo(width, half, Math.max(width - half, width - (width - max) / 2), half);
          context.lineTo(Math.min(max + half, width - (width - max) / 2), half);
          context.quadraticCurveTo(max, half, max, height);
        }

        context.stroke();
        context.closePath();
        context.fill();
        context.restore();
      }
    },
    adapter : {
      trigger : function (child, name, options) {
        if (name === 'select') {
          this.select(child, options);
        }
      },
      select : function (child, options) {
        var
          x = options.x || {},
          min = x.min,
          max = x.max,
          api = child.api;

        child.draw(null, {
          min : min,
          max : max
        });
      }
    }
  };
  humblevis.QuadraticDrawing = QuadraticDrawing;
})();
<|endoftext|>


<commit_before>// Expanding Textareas
// https://github.com/bgrins/ExpandingTextareas

(function(factory) {
    // Add jQuery via AMD registration or browser globals
    if (typeof define === 'function' && define.amd) {
        define([ 'jquery' ], factory);
    }
    else {
        factory(jQuery);
    }
}(function ($) {

    var Expanding = function($textarea, opts) {
        Expanding._registry.push(this);

        this.$textarea = $textarea;
        this.$textCopy = $("");
        this.$clone = $("

").prepend(this.$textCopy);

        this._resetStyles();
        this._setCloneStyles();
        this._setTextareaStyles();

        $textarea
            .wrap($("
"))
            .after(this.$clone)
            .bind("input.expanding propertychange.expanding keyup.expanding change.expanding",
                $.proxy(this.update, this));

        this.update();
        if (opts.update) $textarea.bind("update.expanding", opts.update);
    };

    Expanding._registry = [];

    Expanding.getExpandingInstance = function(textarea) {
        var $textareas = $.map(Expanding._registry, function(instance) {
                return instance.$textarea[0];
            }),
            index = $.inArray(textarea, $textareas);
        return index > -1 ? Expanding._registry[index] : null;
    };

    Expanding.prototype = {

        update: function() {
            this.$textCopy.text(this.$textarea.val().replace(/\r\n/g, "\n"));
            this.$textarea.trigger("update.expanding");
        },

        destroy: function() {
            this.$clone.remove();
            this.$textarea
                .unwrap()
                .attr('style', this._oldTextareaStyles || '');
            var index = $.inArray(this, Expanding._registry);
            if (index > -1) Expanding._registry.splice(index, 1);
        },

        _resetStyles: function() {
            // Store the original styles in case of destroying.
            this._oldTextareaStyles = this.$textarea.attr('style');

            this.$textarea.add(this.$clone).css({
                margin: 0,
                webkitBoxSizing: "border-box",
                mozBoxSizing: "border-box",
                boxSizing: "border-box",
                width: "100%"
            });
        },

        _setCloneStyles: function() {
            var css = {
                display: 'block',
                border: '0 solid',
                visibility: 'hidden',
                minHeight: this.$textarea.outerHeight()
            };
            if(this.$textarea.attr("wrap") === "off") css.overflowX = "scroll";
            else css.whiteSpace = "pre-wrap";

            this.$clone.css(css);
            this._copyTextareaStylesToClone();
        },

        _copyTextareaStylesToClone: function() {
            var _this = this,
                properties = [
                    'lineHeight', 'textDecoration', 'letterSpacing',
                    'fontSize', 'fontFamily', 'fontStyle',
                    'fontWeight', 'textTransform', 'textAlign',
                    'direction', 'wordSpacing', 'fontSizeAdjust',
                    'wordWrap', 'word-break',
                    'borderTopStyle', 'borderBottomStyle',
                    'borderLeftWidth', 'borderRightWidth',
                    'borderTopWidth','borderBottomWidth',
                    'paddingLeft', 'paddingRight',
                    'paddingTop','paddingBottom'];

            $.each(properties, function(i, property) {
                var val = _this.$textarea.css(property);

                // Prevent overriding percentage css values.
                if(_this.$clone.css(property) !== val) {
                    _this.$clone.css(property, val);
                }
            });
        },

        _setTextareaStyles: function() {
            this.$textarea.css({
                position: "absolute",
                top: 0,
                left: 0,
                height: "100%",
                resize: "none"
            });
        }
    };

    $.expanding = $.extend({
        autoInitialize: true,
        initialSelector: "textarea.expanding",
        opts: {
            update: function() { }
        }
    }, $.expanding || {});

    $.fn.expanding = function(o) {

        if (o === "destroy") {
            this.each(function() {
                var instance = Expanding.getExpandingInstance(this);
                if (instance) instance.destroy();
            });
            return this;
        }

        if (o === 'isExpanding') {
            var instances = this.map(function() {
                return !!Expanding.getExpandingInstance(this);
            });
            return $.inArray(true, instances) > -1;
        }

        var opts = $.extend({ }, $.expanding.opts, o);

        this.filter("textarea").each(function() {
            if(!Expanding.getExpandingInstance(this)) {
                new Expanding($(this), opts);
            }
        });
        return this;
    };

    $(function () {
        if ($.expanding.autoInitialize) {
            $($.expanding.initialSelector).expanding();
        }
    });

}));<commit_msg>Remove onpropertychange event binding. Only bind to keyup if oninput is not fully supported<commit_after>// Expanding Textareas
// https://github.com/bgrins/ExpandingTextareas

(function(factory) {
    // Add jQuery via AMD registration or browser globals
    if (typeof define === 'function' && define.amd) {
        define([ 'jquery' ], factory);
    }
    else {
        factory(jQuery);
    }
}(function ($) {

    var Expanding = function($textarea, opts) {
        Expanding._registry.push(this);

        this.$textarea = $textarea;
        this.$textCopy = $("");
        this.$clone = $("

").prepend(this.$textCopy);

        this._resetStyles();
        this._setCloneStyles();
        this._setTextareaStyles();

        $textarea
            .wrap($("
"))
            .after(this.$clone);

        this.attach();
        this.update();
        if (opts.update) $textarea.bind("update.expanding", opts.update);
    };

    Expanding._registry = [];

    Expanding.getExpandingInstance = function(textarea) {
        var $textareas = $.map(Expanding._registry, function(instance) {
                return instance.$textarea[0];
            }),
            index = $.inArray(textarea, $textareas);
        return index > -1 ? Expanding._registry[index] : null;
    };

    // Returns the version of Internet Explorer or -1
    // (indicating the use of another browser).
    // From: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA
    var ieVersion = (function() {
        var v = -1;
        if (navigator.appName === "Microsoft Internet Explorer") {
            var ua = navigator.userAgent;
            var re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
            if (re.exec(ua) !== null) v = parseFloat(RegExp.$1);
        }
        return v;
    })();

    // Check for oninput support
    // IE9 supports oninput, but not when deleting text, so keyup is used.
    // onpropertychange _is_ supported by IE8/9, but may not be fired unless
    // attached with `attachEvent`
    // (see: http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire),
    // and so is avoided altogether.
     var inputSupported = (function () {
        var supported;
        return function() {
            if (!supported) {
                if ("oninput" in document.body && ieVersion !== 9)
                    supported = true;
            }
            return supported;
        };
    })();

    Expanding.prototype = {

        attach: function() {
            var events = 'input.expanding change.expanding',
                _this = this;
            if(!inputSupported()) events += ' keyup.expanding';
            this.$textarea.bind(events, function() { _this.update() });
        },

        update: function() {
            this.$textCopy.text(this.$textarea.val().replace(/\r\n/g, "\n"));
            this.$textarea.trigger("update.expanding");
        },

        destroy: function() {
            this.$clone.remove();
            this.$textarea
                .unwrap()
                .attr('style', this._oldTextareaStyles || '');
            var index = $.inArray(this, Expanding._registry);
            if (index > -1) Expanding._registry.splice(index, 1);
        },

        _resetStyles: function() {
            // Store the original styles in case of destroying.
            this._oldTextareaStyles = this.$textarea.attr('style');

            this.$textarea.add(this.$clone).css({
                margin: 0,
                webkitBoxSizing: "border-box",
                mozBoxSizing: "border-box",
                boxSizing: "border-box",
                width: "100%"
            });
        },

        _setCloneStyles: function() {
            var css = {
                display: 'block',
                border: '0 solid',
                visibility: 'hidden',
                minHeight: this.$textarea.outerHeight()
            };
            if(this.$textarea.attr("wrap") === "off") css.overflowX = "scroll";
            else css.whiteSpace = "pre-wrap";

            this.$clone.css(css);
            this._copyTextareaStylesToClone();
        },

        _copyTextareaStylesToClone: function() {
            var _this = this,
                properties = [
                    'lineHeight', 'textDecoration', 'letterSpacing',
                    'fontSize', 'fontFamily', 'fontStyle',
                    'fontWeight', 'textTransform', 'textAlign',
                    'direction', 'wordSpacing', 'fontSizeAdjust',
                    'wordWrap', 'word-break',
                    'borderTopStyle', 'borderBottomStyle',
                    'borderLeftWidth', 'borderRightWidth',
                    'borderTopWidth','borderBottomWidth',
                    'paddingLeft', 'paddingRight',
                    'paddingTop','paddingBottom'];

            $.each(properties, function(i, property) {
                var val = _this.$textarea.css(property);

                // Prevent overriding percentage css values.
                if(_this.$clone.css(property) !== val) {
                    _this.$clone.css(property, val);
                }
            });
        },

        _setTextareaStyles: function() {
            this.$textarea.css({
                position: "absolute",
                top: 0,
                left: 0,
                height: "100%",
                resize: "none"
            });
        }
    };

    $.expanding = $.extend({
        autoInitialize: true,
        initialSelector: "textarea.expanding",
        opts: {
            update: function() { }
        }
    }, $.expanding || {});

    $.fn.expanding = function(o) {

        if (o === "destroy") {
            this.each(function() {
                var instance = Expanding.getExpandingInstance(this);
                if (instance) instance.destroy();
            });
            return this;
        }

        if (o === 'isExpanding') {
            var instances = this.map(function() {
                return !!Expanding.getExpandingInstance(this);
            });
            return $.inArray(true, instances) > -1;
        }

        var opts = $.extend({ }, $.expanding.opts, o);

        this.filter("textarea").each(function() {
            if(!Expanding.getExpandingInstance(this)) {
                new Expanding($(this), opts);
            }
        });
        return this;
    };

    $(function () {
        if ($.expanding.autoInitialize) {
            $($.expanding.initialSelector).expanding();
        }
    });

}));<|endoftext|>


<commit_before>/* LANGUAGE
================================================== */
if(typeof VMM != 'undefined') {
	VMM.Language = {
		lang: "fo",
		api: {
			wikipedia: "fo"
		},
		date: {
			month: ["januar", "februar", "mars", "aprÌl", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember"],
			month_abbr: ["jan.", "febr.", "mars", "aprÌl", "mai", "juni", "juli", "aug.", "sept.", "okt.", "nov.", "des."],
			day: ["sunnudagur","m·nadagur", "t˝sdagur", "mikudagur", "hÛsdagur", "frÌggjadagur", "leygardagur"],
			day_abbr: ["sun.","m·n.", "t˝s.", "mik.", "hÛs.", "frÌ.", "ley."]
		},
		dateformats: {
			year: "yyyy",
			month_short: "mmm",
			month: "mmmm yyyy",
			full_short: "d'.' mmm",
			full: "d'.' mmmm yyyy",
			time_no_seconds_short: "HH:MM",
			time_no_seconds_small_date: "HH:MM'
'd'.' mmmm yyyy''",
			full_long: "d'.' mmmm yyyy 'klokkan' HH:MM",
			full_long_small_date: "HH:MM'
'd'.' mmm yyyy''"
		},
		messages: {
			loading_timeline: "Lesur inn tÌarr·s... ",
			return_to_title: "Aftur til byrjan",
			expand_timeline: "VÌka tÌarr·s",
			contract_timeline: "Minka tÌarr·s",
			wikipedia: "Fr· Wikipedia, tann frÊlsa alfr¯in",
			loading_content: "Lesur inn tilfar",
			loading: "Lesur inn"
		}
	}
}<commit_msg>Fixes<commit_after>/* LANGUAGE
================================================== */
if(typeof VMM != 'undefined') {
	VMM.Language = {
		lang: "fo",
		api: {
			wikipedia: "fo"
		},
		date: {
			month: ["januar", "februar", "mars", "aprÌl", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember"],
			month_abbr: ["jan.", "febr.", "mars", "aprÌl", "mai", "juni", "juli", "aug.", "sept.", "okt.", "nov.", "des."],
			day: ["sunnudagur","m·nadagur", "t˝sdagur", "mikudagur", "hÛsdagur", "frÌggjadagur", "leygardagur"],
			day_abbr: ["sun.","m·n.", "t˝s.", "mik.", "hÛs.", "frÌ.", "ley."]
		},
		dateformats: {
			year: "yyyy",
			month_short: "mmm",
			month: "mmmm yyyy",
			full_short: "d'.' mmm",
			full: "d'.' mmmm yyyy",
			time_no_seconds_short: "HH:MM",
			time_no_seconds_small_date: "HH:MM'
'd'.' mmmm yyyy''",
			full_long: "d'.' mmmm yyyy 'klokkan' HH:MM",
			full_long_small_date: "HH:MM'
'd'.' mmm yyyy''"
		},
		messages: {
			loading_timeline: "Lesur inn tíðarrás...",
			return_to_title: "Víðka tíðarrás...",
			expand_timeline: "Minka tíðarrás...",
			contract_timeline: "Minka tíðarrás",
			wikipedia: "Fr· Wikipedia",
			loading_content: "Lesur inn tilfar",
			loading: "Lesur inn"
		}
	}
}<|endoftext|>