<commit_before>/**
 * Dense - Device pixel ratio aware images
 *
 * @link    https://github.com/gocom/dense
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

;(function (factory)
{
	if (typeof define === 'function' && define.amd)
	{
		define(['jquery'], factory);
	}
	else
	{
		factory(jQuery);
	}
}(function ($)
{
    /**
     * An array of checked image URLs.
     */

    var pathStack = [],

    /**
     * Methods.
     */

    methods = {},

    /**
     * Regular expression to check whether the URL has a protocol.
     *
     * Is used to check whether the image URL is external.
     */

    regexProtocol = /^https?:\/\//,

    /**
     * Regular expression that split extensions from the file.
     *
     * Is used to inject the DPR suffix to the name.
     */

    regexSuffix = /\.\w+$/,

    /**
     * Device pixel ratio.
     */

    devicePixelRatio,

    /**
     * An array of accepted content-types.
     *
     * Basically contains an array of raster image formats.
     */

    acceptedTypes =
    [
        'image/jpg',
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/bmp'
    ],

    /**
     * Skipped image file extensions.
     *
     * Vectors don't need automatic pixel ratio support.
     */

    skipExtensions =
    [
        'svg'
    ];

    /**
     * Renders a pixel-ratio-aware image.
     *
     * Dense defaults to the init method if no
     * method is specified.
     *
     * The method should be used to select the images that
     * should display retina-size images on high pixel ratio
     * devices.
     *
     * The correct image variation is selected based on the
     * device's pixel ratio. If the image element defines
     * data-{ratio}x (e.g. data-1x, data-2x, data-3x) attributes,
     * the most appropriate of those is selected.
     *
     * If no data-ratio attributes are defined, the retina image is
     * constructed from the specified src attribute.
     * The searched high pixel ratio images follow
     * a {imageName}_{ratio}x.{ext} naming convention.
     * For an image found in /path/to/images/image.jpg, the 2x retina
     * image would be looked from /path/to/images/image_2x.jpg.
     *
     * When image is constructed from the src, the image existance is
     * verified using HTTP HEAD request. The check makes sure no
     * HTTP error code is returned, and that the received content-type
     * is either image/jpg, image/png,
     * image/gif or image/bmp. Vector image
     * formats, like svg, are skipped.
     *
     * This method can also be used to load image in semi-lazy fashion.
     * If the selector targets a element that isn't an image, an
     * image is appended to that location. The image is constructed
     * using the specified data-{ratio}x attributes like
     * with normal images.
     *
     * @param    {Object}  [options={}]                  Options
     * @param    {Boolean} [options.ping=true]           A prefix added to the generated links
     * @param    {String}  [options.dimensions=preserve] What to do with the width and height attributes. Either update, remove or preserve
     * @return   {Object}  this
     * @method   init
     * @memberof jQuery.fn.dense
     * @fires    jQuery.fn.dense#dense-retina-loaded
     * @example
     * $('img.retina').dense({
     *  'ping'      : false,
     *  'dimension' : true
     * });
     */

    methods.init = function (options)
    {
        options = $.extend({
            ping       : true,
            dimensions : 'preserve'
        }, options);

        return this.not('.dense-active').each(function ()
        {
            var $this = $(this),
                target,
                image = methods.getImageAttribute.call(this),
                originalImage = $this.attr('src'),
                ping = false,
                ext;

            if (image)
            {
                if ($this.not('img'))
                {
                    target = $this.siblings('img.dense-active').eq(0);

                    if (!target.length)
                    {
                        target = $('');
                        $this.append(target);
                    }

                    $this = target;
                }
            }
            else
            {
                if (!originalImage || devicePixelRatio == 1)
                {
                    return;
                }

                ext = image.split('.').pop().split(/[\?\#]/).shift();

                if ($.inArray(ext, skipExtensions))
                {
                    return;
                }

                image = originalImage.replace(regexSuffix, function (extension)
                {
                    return '_' + devicePixelRatio + 'x' + extension;
                });

                ping = options.ping && $.inArray(image, pathStack) === -1 && (regexProtocol.test(image) === false || image.indexOf('://' + document.domain) !== -1);
            }

            if (ping)
            {
                $.ajax({
                    url  : image,
                    type : 'HEAD'
                })
                    .done(function (data, textStatus, jqXHR)
                    {
                       var type = jqXHR.getResponseHeader('Content-type').split(';').shift();

                       if (jqXHR.status === 200 && (type === null || $.inArray(type, acceptedTypes) !== -1))
                       {
                           pathStack.push(image);

                           $this
                               .attr('src', image)
                               .data('dense-original', originalImage);

                            if (options.dimensions === 'update')
                            {
                                methods.updateDimensions.call($this.get(0));
                            }

                            $this.trigger('dense-retina-loaded');
                       }
                    });
            }
            else
            {
                $this
                    .attr('src', image)
                    .data('dense-original', originalImage);

                if (options.dimensions === 'update')
                {
                    methods.updateDimensions.call($this.get(0));
                }

                $this.trigger('dense-retina-loaded');
            }

            if (options.dimensions === 'remove')
            {
                $this.removeAttr('width').removeAttr('height');
            }
        }).addClass('dense-active');
    };

    /**
     * Sets an image's width and height attributes to its native values.
     *
     * Updates an img element's dimensions to the source image's
     * real values.
     *
     * This method is asynchronous, so you can not directly return
     * its values. Instead use load event.
     *
     * @return   {Object} this
     * @method   updateDimensions
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('img').dense('updateDimensions');
     */

    methods.updateDimensions = function ()
    {
        return this.each(function ()
        {
            var img, $this = $(this), src = $this.attr('src');

            if (src)
            {
                img = new Image();
                img.src = src;

                $(img).on('load.dense', function ()
                {
                    $this.attr('width', img.width).attr('height', img.height);
                });
            }
        });
    };

    /**
     * Gets device pixel ratio rounded up to the closest integer.
     *
     * @return   {Integer} The pixel ratio
     * @method   devicePixelRatio
     * @memberof jQuery.fn.dense
     * @example
     * var ratio = $(window).dense('devicePixelRatio');
     * alert(ratio);
     */

    methods.devicePixelRatio = function ()
    {
        var pixelRatio = 1;

        if ($.type(window.devicePixelRatio) !== 'undefined')
        {
            pixelRatio = window.devicePixelRatio;
        }
        else if ($.type(window.matchMedia) !== 'undefined')
        {
            $.each([1.3, 1.5, 2, 3, 4, 5, 6], function (key, ratio)
            {
                var mediaQuery = [
                    '(-webkit-min-device-pixel-ratio: '+ratio+')',
                    '(min--moz-device-pixel-ratio: '+ratio+')',
                    '(-o-min-device-pixel-ratio: '+ratio+')',
                    '(min-resolution: '+ratio+'dppx)'
                ].join(',');

                if (!window.matchMedia(mediaQuery).matches)
                {
                    pixelRatio = ratio;
                    return false;
                }
            });
        }

        return Math.ceil(pixelRatio);
    };

    /**
     * Gets an appropriate URL for the pixel ratio from the data attribute list.
     *
     * Selects the most appropriate data-{ratio}x attribute from
     * the given element's attributes.
     *
     * If the devices pixel ratio is greater than the largest specified image,
     * the largest one of the available is used.
     *
     * @return   {String|Boolean} The attribute value
     * @method   getImageAttribute
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('
').dense('getImageAttribute');
     * $('body').css('background-image', 'url(' + image + ')');
     */

    methods.getImageAttribute = function ()
    {
        var $this = $(this).eq(0), image = false, url;

        for (var i = 1; i <= devicePixelRatio; i++)
        {
            url = $this.attr('data-' + i + 'x');

            if (url)
            {
                image = url;
            }
        }

        return image;
    };

    devicePixelRatio = methods.devicePixelRatio();

    /**
     * Dense offers few methods and options that can be used to both customize the
     * plugin's functionality and return resulting values. All interaction is done through
     * the $.fn.dense() method, that accepts a called method and its options
     * object as its arguments. Both arguments are optional, and either one can be omitted.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    dense
     * @memberof jQuery.fn
     */

    $.fn.dense = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };

    /**
     * Initialize automatically when document is ready.
     *
     * Dense is initialized automatically if the body element
     * has a dense-retina class.
     */

    $(document).ready(function ()
    {
        $('body.dense-retina img').dense();
    });

    /**
     * Is invoked when an retina image has finished loading.
     *
     * This event does not take into account dimension updates
     * which are run asynchronously after the retina image has
     * been loaded.
     *
     * @event    jQuery.fn.dense#dense-retina-loaded
     * @type     {Object}
     */
}));<commit_msg>Updated class naming.<commit_after>/**
 * Dense - Device pixel ratio aware images
 *
 * @link    https://github.com/gocom/dense
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

;(function (factory)
{
	if (typeof define === 'function' && define.amd)
	{
		define(['jquery'], factory);
	}
	else
	{
		factory(jQuery);
	}
}(function ($)
{
    /**
     * An array of checked image URLs.
     */

    var pathStack = [],

    /**
     * Methods.
     */

    methods = {},

    /**
     * Regular expression to check whether the URL has a protocol.
     *
     * Is used to check whether the image URL is external.
     */

    regexProtocol = /^https?:\/\//,

    /**
     * Regular expression that split extensions from the file.
     *
     * Is used to inject the DPR suffix to the name.
     */

    regexSuffix = /\.\w+$/,

    /**
     * Device pixel ratio.
     */

    devicePixelRatio,

    /**
     * An array of accepted content-types.
     *
     * Basically contains an array of raster image formats.
     */

    acceptedTypes =
    [
        'image/jpg',
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/bmp'
    ],

    /**
     * Skipped image file extensions.
     *
     * Vectors don't need automatic pixel ratio support.
     */

    skipExtensions =
    [
        'svg'
    ];

    /**
     * Renders a pixel-ratio-aware image.
     *
     * Dense defaults to the init method if no
     * method is specified.
     *
     * The method should be used to select the images that
     * should display retina-size images on high pixel ratio
     * devices.
     *
     * The correct image variation is selected based on the
     * device's pixel ratio. If the image element defines
     * data-{ratio}x (e.g. data-1x, data-2x, data-3x) attributes,
     * the most appropriate of those is selected.
     *
     * If no data-ratio attributes are defined, the retina image is
     * constructed from the specified src attribute.
     * The searched high pixel ratio images follow
     * a {imageName}_{ratio}x.{ext} naming convention.
     * For an image found in /path/to/images/image.jpg, the 2x retina
     * image would be looked from /path/to/images/image_2x.jpg.
     *
     * When image is constructed from the src, the image existance is
     * verified using HTTP HEAD request. The check makes sure no
     * HTTP error code is returned, and that the received content-type
     * is either image/jpg, image/png,
     * image/gif or image/bmp. Vector image
     * formats, like svg, are skipped.
     *
     * This method can also be used to load image in semi-lazy fashion.
     * If the selector targets a element that isn't an image, an
     * image is appended to that location. The image is constructed
     * using the specified data-{ratio}x attributes like
     * with normal images.
     *
     * @param    {Object}  [options={}]                  Options
     * @param    {Boolean} [options.ping=true]           A prefix added to the generated links
     * @param    {String}  [options.dimensions=preserve] What to do with the width and height attributes. Either update, remove or preserve
     * @return   {Object}  this
     * @method   init
     * @memberof jQuery.fn.dense
     * @fires    jQuery.fn.dense#dense-retina-loaded
     * @example
     * $('img.retina').dense({
     *  'ping'      : false,
     *  'dimension' : true
     * });
     */

    methods.init = function (options)
    {
        options = $.extend({
            ping       : true,
            dimensions : 'preserve'
        }, options);

        this.not('.dense').addClass('dense dense-loading').each(function ()
        {
            var $this = $(this),
                target,
                image = methods.getImageAttribute.call(this),
                originalImage = $this.attr('src'),
                ping = false,
                ext;

            if (image)
            {
                if ($this.not('img'))
                {
                    target = $this.siblings('img.dense').eq(0);

                    if (!target.length)
                    {
                        target = $('');
                        $this.append(target);
                    }

                    $this = target;
                }
            }
            else
            {
                if (!originalImage || devicePixelRatio == 1)
                {
                    return;
                }

                ext = image.split('.').pop().split(/[\?\#]/).shift();

                if ($.inArray(ext, skipExtensions))
                {
                    return;
                }

                image = originalImage.replace(regexSuffix, function (extension)
                {
                    return '_' + devicePixelRatio + 'x' + extension;
                });

                ping = options.ping && $.inArray(image, pathStack) === -1 && (regexProtocol.test(image) === false || image.indexOf('://' + document.domain) !== -1);
            }

            if (ping)
            {
                $.ajax({
                    url  : image,
                    type : 'HEAD'
                })
                    .done(function (data, textStatus, jqXHR)
                    {
                       var type = jqXHR.getResponseHeader('Content-type').split(';').shift();

                       if (jqXHR.status === 200 && (type === null || $.inArray(type, acceptedTypes) !== -1))
                       {
                           pathStack.push(image);

                           $this
                               .attr('src', image)
                               .data('dense-original', originalImage);

                            if (options.dimensions === 'update')
                            {
                                methods.updateDimensions.call($this.get(0));
                            }

                            $this.removeClass('dense-loading').addClass('dense-ready').trigger('dense-retina-loaded');
                       }
                    });
            }
            else
            {
                $this
                    .attr('src', image)
                    .data('dense-original', originalImage);

                if (options.dimensions === 'update')
                {
                    methods.updateDimensions.call($this.get(0));
                }

                $this.removeClass('dense-loading').addClass('dense-ready').trigger('dense-retina-loaded');
            }

            if (options.dimensions === 'remove')
            {
                $this.removeAttr('width').removeAttr('height');
            }
        });

        return this;
    };

    /**
     * Sets an image's width and height attributes to its native values.
     *
     * Updates an img element's dimensions to the source image's
     * real values.
     *
     * This method is asynchronous, so you can not directly return
     * its values. Instead use load event.
     *
     * @return   {Object} this
     * @method   updateDimensions
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('img').dense('updateDimensions');
     */

    methods.updateDimensions = function ()
    {
        return this.each(function ()
        {
            var img, $this = $(this), src = $this.attr('src');

            if (src)
            {
                img = new Image();
                img.src = src;

                $(img).on('load.dense', function ()
                {
                    $this.attr('width', img.width).attr('height', img.height);
                });
            }
        });
    };

    /**
     * Gets device pixel ratio rounded up to the closest integer.
     *
     * @return   {Integer} The pixel ratio
     * @method   devicePixelRatio
     * @memberof jQuery.fn.dense
     * @example
     * var ratio = $(window).dense('devicePixelRatio');
     * alert(ratio);
     */

    methods.devicePixelRatio = function ()
    {
        var pixelRatio = 1;

        if ($.type(window.devicePixelRatio) !== 'undefined')
        {
            pixelRatio = window.devicePixelRatio;
        }
        else if ($.type(window.matchMedia) !== 'undefined')
        {
            $.each([1.3, 1.5, 2, 3, 4, 5, 6], function (key, ratio)
            {
                var mediaQuery = [
                    '(-webkit-min-device-pixel-ratio: '+ratio+')',
                    '(min--moz-device-pixel-ratio: '+ratio+')',
                    '(-o-min-device-pixel-ratio: '+ratio+')',
                    '(min-resolution: '+ratio+'dppx)'
                ].join(',');

                if (!window.matchMedia(mediaQuery).matches)
                {
                    pixelRatio = ratio;
                    return false;
                }
            });
        }

        return Math.ceil(pixelRatio);
    };

    /**
     * Gets an appropriate URL for the pixel ratio from the data attribute list.
     *
     * Selects the most appropriate data-{ratio}x attribute from
     * the given element's attributes.
     *
     * If the devices pixel ratio is greater than the largest specified image,
     * the largest one of the available is used.
     *
     * @return   {String|Boolean} The attribute value
     * @method   getImageAttribute
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('
').dense('getImageAttribute');
     * $('body').css('background-image', 'url(' + image + ')');
     */

    methods.getImageAttribute = function ()
    {
        var $this = $(this).eq(0), image = false, url;

        for (var i = 1; i <= devicePixelRatio; i++)
        {
            url = $this.attr('data-' + i + 'x');

            if (url)
            {
                image = url;
            }
        }

        return image;
    };

    devicePixelRatio = methods.devicePixelRatio();

    /**
     * Dense offers few methods and options that can be used to both customize the
     * plugin's functionality and return resulting values. All interaction is done through
     * the $.fn.dense() method, that accepts a called method and its options
     * object as its arguments. Both arguments are optional, and either one can be omitted.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    dense
     * @memberof jQuery.fn
     */

    $.fn.dense = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };

    /**
     * Initialize automatically when document is ready.
     *
     * Dense is initialized automatically if the body element
     * has a dense-retina class.
     */

    $(document).ready(function ()
    {
        $('body.dense-retina img').dense();
    });

    /**
     * Is invoked when an retina image has finished loading.
     *
     * This event does not take into account dimension updates
     * which are run asynchronously after the retina image has
     * been loaded.
     *
     * @event    jQuery.fn.dense#dense-retina-loaded
     * @type     {Object}
     */
}));<|endoftext|>


<commit_before>/**
 * Dense - Device pixel ratio aware images
 *
 * @link    https://github.com/gocom/dense
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

;(function (factory)
{
	if (typeof define === 'function' && define.amd)
	{
		define(['jquery'], factory);
	}
	else
	{
		factory(jQuery);
	}
}(function ($)
{
    /**
     * Default options.
     */

    var defaults =
    {
        ping       : true,
        dimensions : 'preserve'
    },

    /**
     * An array of checked image URLs.
     */

    pathStack = [],

    /**
     * Methods.
     */

    methods = {},

    /**
     * Regular expression to check whether the URL has a protocol.
     *
     * Is used to check whether the image URL is external.
     */

    regexProtocol = /^https?:\/\//,

    /**
     * Regular expression that split extensions from the file.
     *
     * Is used to inject the DPR suffix to the name.
     */

    regexSuffix = /\.\w+$/,

    /**
     * Device pixel ratio.
     */

    devicePixelRatio,

    /**
     * An array of accepted content-types.
     *
     * Basically contains an array of raster image formats.
     */

    acceptedTypes =
    [
        'image/jpg',
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/bmp'
    ],

    /**
     * Skipped image file extensions.
     *
     * Vectors don't need automatic pixel ratio support.
     */

    skipExtensions =
    [
        'svg'
    ];

    /**
     * Renders a pixel-ratio-aware image.
     *
     * Dense defaults to the init method if no
     * method is specified.
     *
     * The method should be used to select the images that
     * should display retina-size images on high pixel ratio
     * devices.
     *
     * The correct image variation is selected based on the
     * device's pixel ratio. If the image element defines
     * data-{ratio}x (e.g. data-1x, data-2x, data-3x) attributes,
     * the most appropriate of those is selected.
     *
     * If no data-ratio attributes are defined, the retina image is
     * constructed from the specified src attribute.
     * The searched high pixel ratio images follow
     * a {imageName}_{ratio}x.{ext} naming convention.
     * For an image found in /path/to/images/image.jpg, the 2x retina
     * image would be looked from /path/to/images/image_2x.jpg.
     *
     * When image is constructed from the src, the image existance is
     * verified using HTTP HEAD request. The check makes sure no
     * HTTP error code is returned, and that the received content-type
     * is either image/jpg, image/png,
     * image/gif or image/bmp. Vector image
     * formats, like svg, are skipped.
     *
     * This method can also be used to load image in semi-lazy fashion.
     * If the selector targets a element that isn't an image, an
     * image is appended to that location. The image is constructed
     * using the specified data-{ratio}x attributes like with normal
     * images.
     *
     * @param    {Object}  [options={}]                  Options
     * @param    {Boolean} [options.ping=true]           A prefix added to the generated links
     * @param    {String}  [options.dimensions=preserve] Whether to do with the 'width' and 'height'. Either "update", "remove" or "preserve"
     * @return   {Object}  this
     * @method   init
     * @memberof jQuery.fn.dense
     * @example
     * $('img.retina').dense({
     *  'ping'      : false,
     *  'dimension' : true
     * });
     */

    methods.init = function (options)
    {
        $.extend(defaults, options);

        return this.not('.jquery-dense-active').each(function ()
        {
            var $this = $(this),
                target,
                image = methods.getImageAttribute.call(this),
                originalImage = $this.attr('src'),
                ping = false,
                ext;

            if (image)
            {
                if ($this.not('img'))
                {
                    target = $this.siblings('img.jquery-dense-active').eq(0);

                    if (!target.length)
                    {
                        target = $('');
                        $this.append(target);
                    }

                    $this = target;
                }
            }
            else
            {
                if (!originalImage || devicePixelRatio == 1)
                {
                    return;
                }

                ext = image.split('.').pop().split(/[\?\#]/).shift();

                if ($.inArray(ext, skipExtensions))
                {
                    return;
                }

                image = originalImage.replace(regexSuffix, function (extension)
                {
                    return '_' + devicePixelRatio + 'x' + extension;
                });

                ping = options.ping && $.inArray(image, pathStack) === -1 && (regexProtocol.test(image) === false || image.indexOf('://' + document.domain) !== -1);
            }

            if (ping)
            {
                $.ajax({
                    url  : image,
                    type : 'HEAD'
                })
                    .done(function (data, textStatus, jqXHR)
                    {
                       var type = jqXHR.getResponseHeader('Content-type').split(';').shift();

                       if (jqXHR.status === 200 && (type === null || $.inArray(type, acceptedTypes) !== -1))
                       {
                           pathStack.push(image);

                           $this
                               .attr('src', image)
                               .data('jquery-dense-original', originalImage);

                            if (options.dimensions === 'update')
                            {
                                methods.updateDimensions.call($this.get(0));
                            }
                       }
                    });
            }
            else
            {
                $this
                    .attr('src', image)
                    .data('jquery-dense-original', originalImage);

                if (options.dimensions === 'update')
                {
                    methods.updateDimensions.call($this.get(0));
                }
            }

            if (options.dimensions === 'remove')
            {
                $this.removeAttr('width').removeAttr('height');
            }
        }).addClass('jquery-dense-active');
    };

    /**
     * Sets an image's width and height attributes to its native values.
     *
     * Updates an img element's dimensions to the source image's
     * real values.
     *
     * This method is asynchronous, so you can not directly return
     * its values. Instead use load event.
     *
     * @return   {Object} this
     * @method   updateDimensions
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('img').dense('updateDimensions');
     */

    methods.updateDimensions = function ()
    {
        return this.each(function ()
        {
            var img, $this = $(this), src = $this.attr('src');

            if (src)
            {
                img = new Image();
                img.src = src;

                $(img).on('load.dense', function ()
                {
                    $this.attr('width', img.width).attr('height', img.height);
                });
            }
        });
    };

    /**
     * Gets device pixel ratio rounded up to the closest integer.
     *
     * @return   {Integer} The pixel ratio
     * @method   devicePixelRatio
     * @memberof jQuery.fn.dense
     * @example
     * var ratio = $(window).dense('devicePixelRatio');
     * alert(ratio);
     */

    methods.devicePixelRatio = function ()
    {
        var pixelRatio = 1;

        if ($.type(window.devicePixelRatio) !== 'undefined')
        {
            pixelRatio = window.devicePixelRatio;
        }
        else if ($.type(window.matchMedia) !== 'undefined')
        {
            $.each([1.3, 1.5, 2, 3, 4, 5, 6], function (key, ratio)
            {
                var mediaQuery = [
                    '(-webkit-min-device-pixel-ratio: '+ratio+')',
                    '(min--moz-device-pixel-ratio: '+ratio+')',
                    '(-o-min-device-pixel-ratio: '+ratio+')',
                    '(min-resolution: '+ratio+'dppx)'
                ].join(',');

                if (!window.matchMedia(mediaQuery).matches)
                {
                    pixelRatio = ratio;
                    return false;
                }
            });
        }

        return Math.ceil(pixelRatio);
    };

    /**
     * Gets an appropriate URL for the pixel ratio from the data attribute list.
     *
     * Selects the most appropriate 'data-{ratio}x' attribute from
     * the given element's attributes.
     *
     * If the devices pixel ratio is greater than the largest specified image,
     * the largest one of the available is used.
     *
     * @return   {String|Boolean} The attribute value
     * @method   getImageAttribute
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('
').dense('getImageAttribute');
     * $('body').css('background-image', 'url(' + image + ')');
     */

    methods.getImageAttribute = function ()
    {
        var $this = $(this).eq(0), image = false, url;

        for (var i = 1; i <= devicePixelRatio; i++)
        {
            url = $(this).attr('data-' + i + 'x');

            if (url)
            {
                image = url;
            }
        }

        return image;
    };

    devicePixelRatio = methods.devicePixelRatio();

    /**
     * Dense offers few methods and options that can be used to both customize the
     * plugin's functionality and return resulting values. All interaction is done through
     * the $.fn.dense() method, that accepts a called method and its options
     * object as its arguments. Both arguments are optional, and either one can be omitted.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    dense
     * @memberof jQuery.fn
     */

    $.fn.dense = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };

    /**
     * Initialize automatically when document is ready.
     *
     * Dense is initialized automatically if the body element
     * has a 'dense-retina' class.
     */

    $(document).ready(function ()
    {
        $('body.dense-retina img').dense();
    });
}));<commit_msg>Updated the documentation.<commit_after>/**
 * Dense - Device pixel ratio aware images
 *
 * @link    https://github.com/gocom/dense
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

;(function (factory)
{
	if (typeof define === 'function' && define.amd)
	{
		define(['jquery'], factory);
	}
	else
	{
		factory(jQuery);
	}
}(function ($)
{
    /**
     * Default options.
     */

    var defaults =
    {
        ping       : true,
        dimensions : 'preserve'
    },

    /**
     * An array of checked image URLs.
     */

    pathStack = [],

    /**
     * Methods.
     */

    methods = {},

    /**
     * Regular expression to check whether the URL has a protocol.
     *
     * Is used to check whether the image URL is external.
     */

    regexProtocol = /^https?:\/\//,

    /**
     * Regular expression that split extensions from the file.
     *
     * Is used to inject the DPR suffix to the name.
     */

    regexSuffix = /\.\w+$/,

    /**
     * Device pixel ratio.
     */

    devicePixelRatio,

    /**
     * An array of accepted content-types.
     *
     * Basically contains an array of raster image formats.
     */

    acceptedTypes =
    [
        'image/jpg',
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/bmp'
    ],

    /**
     * Skipped image file extensions.
     *
     * Vectors don't need automatic pixel ratio support.
     */

    skipExtensions =
    [
        'svg'
    ];

    /**
     * Renders a pixel-ratio-aware image.
     *
     * Dense defaults to the init method if no
     * method is specified.
     *
     * The method should be used to select the images that
     * should display retina-size images on high pixel ratio
     * devices.
     *
     * The correct image variation is selected based on the
     * device's pixel ratio. If the image element defines
     * data-{ratio}x (e.g. data-1x, data-2x, data-3x) attributes,
     * the most appropriate of those is selected.
     *
     * If no data-ratio attributes are defined, the retina image is
     * constructed from the specified src attribute.
     * The searched high pixel ratio images follow
     * a {imageName}_{ratio}x.{ext} naming convention.
     * For an image found in /path/to/images/image.jpg, the 2x retina
     * image would be looked from /path/to/images/image_2x.jpg.
     *
     * When image is constructed from the src, the image existance is
     * verified using HTTP HEAD request. The check makes sure no
     * HTTP error code is returned, and that the received content-type
     * is either image/jpg, image/png,
     * image/gif or image/bmp. Vector image
     * formats, like svg, are skipped.
     *
     * This method can also be used to load image in semi-lazy fashion.
     * If the selector targets a element that isn't an image, an
     * image is appended to that location. The image is constructed
     * using the specified data-{ratio}x attributes like
     * with normal images.
     *
     * @param    {Object}  [options={}]                  Options
     * @param    {Boolean} [options.ping=true]           A prefix added to the generated links
     * @param    {String}  [options.dimensions=preserve] What to do with the width and height attributes. Either update, remove or preserve
     * @return   {Object}  this
     * @method   init
     * @memberof jQuery.fn.dense
     * @example
     * $('img.retina').dense({
     *  'ping'      : false,
     *  'dimension' : true
     * });
     */

    methods.init = function (options)
    {
        $.extend(defaults, options);

        return this.not('.jquery-dense-active').each(function ()
        {
            var $this = $(this),
                target,
                image = methods.getImageAttribute.call(this),
                originalImage = $this.attr('src'),
                ping = false,
                ext;

            if (image)
            {
                if ($this.not('img'))
                {
                    target = $this.siblings('img.jquery-dense-active').eq(0);

                    if (!target.length)
                    {
                        target = $('');
                        $this.append(target);
                    }

                    $this = target;
                }
            }
            else
            {
                if (!originalImage || devicePixelRatio == 1)
                {
                    return;
                }

                ext = image.split('.').pop().split(/[\?\#]/).shift();

                if ($.inArray(ext, skipExtensions))
                {
                    return;
                }

                image = originalImage.replace(regexSuffix, function (extension)
                {
                    return '_' + devicePixelRatio + 'x' + extension;
                });

                ping = options.ping && $.inArray(image, pathStack) === -1 && (regexProtocol.test(image) === false || image.indexOf('://' + document.domain) !== -1);
            }

            if (ping)
            {
                $.ajax({
                    url  : image,
                    type : 'HEAD'
                })
                    .done(function (data, textStatus, jqXHR)
                    {
                       var type = jqXHR.getResponseHeader('Content-type').split(';').shift();

                       if (jqXHR.status === 200 && (type === null || $.inArray(type, acceptedTypes) !== -1))
                       {
                           pathStack.push(image);

                           $this
                               .attr('src', image)
                               .data('jquery-dense-original', originalImage);

                            if (options.dimensions === 'update')
                            {
                                methods.updateDimensions.call($this.get(0));
                            }
                       }
                    });
            }
            else
            {
                $this
                    .attr('src', image)
                    .data('jquery-dense-original', originalImage);

                if (options.dimensions === 'update')
                {
                    methods.updateDimensions.call($this.get(0));
                }
            }

            if (options.dimensions === 'remove')
            {
                $this.removeAttr('width').removeAttr('height');
            }
        }).addClass('jquery-dense-active');
    };

    /**
     * Sets an image's width and height attributes to its native values.
     *
     * Updates an img element's dimensions to the source image's
     * real values.
     *
     * This method is asynchronous, so you can not directly return
     * its values. Instead use load event.
     *
     * @return   {Object} this
     * @method   updateDimensions
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('img').dense('updateDimensions');
     */

    methods.updateDimensions = function ()
    {
        return this.each(function ()
        {
            var img, $this = $(this), src = $this.attr('src');

            if (src)
            {
                img = new Image();
                img.src = src;

                $(img).on('load.dense', function ()
                {
                    $this.attr('width', img.width).attr('height', img.height);
                });
            }
        });
    };

    /**
     * Gets device pixel ratio rounded up to the closest integer.
     *
     * @return   {Integer} The pixel ratio
     * @method   devicePixelRatio
     * @memberof jQuery.fn.dense
     * @example
     * var ratio = $(window).dense('devicePixelRatio');
     * alert(ratio);
     */

    methods.devicePixelRatio = function ()
    {
        var pixelRatio = 1;

        if ($.type(window.devicePixelRatio) !== 'undefined')
        {
            pixelRatio = window.devicePixelRatio;
        }
        else if ($.type(window.matchMedia) !== 'undefined')
        {
            $.each([1.3, 1.5, 2, 3, 4, 5, 6], function (key, ratio)
            {
                var mediaQuery = [
                    '(-webkit-min-device-pixel-ratio: '+ratio+')',
                    '(min--moz-device-pixel-ratio: '+ratio+')',
                    '(-o-min-device-pixel-ratio: '+ratio+')',
                    '(min-resolution: '+ratio+'dppx)'
                ].join(',');

                if (!window.matchMedia(mediaQuery).matches)
                {
                    pixelRatio = ratio;
                    return false;
                }
            });
        }

        return Math.ceil(pixelRatio);
    };

    /**
     * Gets an appropriate URL for the pixel ratio from the data attribute list.
     *
     * Selects the most appropriate data-{ratio}x attribute from
     * the given element's attributes.
     *
     * If the devices pixel ratio is greater than the largest specified image,
     * the largest one of the available is used.
     *
     * @return   {String|Boolean} The attribute value
     * @method   getImageAttribute
     * @memberof jQuery.fn.dense
     * @example
     * var image = $('
').dense('getImageAttribute');
     * $('body').css('background-image', 'url(' + image + ')');
     */

    methods.getImageAttribute = function ()
    {
        var $this = $(this).eq(0), image = false, url;

        for (var i = 1; i <= devicePixelRatio; i++)
        {
            url = $(this).attr('data-' + i + 'x');

            if (url)
            {
                image = url;
            }
        }

        return image;
    };

    devicePixelRatio = methods.devicePixelRatio();

    /**
     * Dense offers few methods and options that can be used to both customize the
     * plugin's functionality and return resulting values. All interaction is done through
     * the $.fn.dense() method, that accepts a called method and its options
     * object as its arguments. Both arguments are optional, and either one can be omitted.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    dense
     * @memberof jQuery.fn
     */

    $.fn.dense = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };

    /**
     * Initialize automatically when document is ready.
     *
     * Dense is initialized automatically if the body element
     * has a dense-retina class.
     */

    $(document).ready(function ()
    {
        $('body.dense-retina img').dense();
    });
}));<|endoftext|>


<commit_before>var request = require('request');
var api     = require('./api');

function Client(options) {

  var fieldsToValidate = !options.accessToken ?
    ['domain', 'clientID', 'clientSecret'] :
    ['domain'];

  fieldsToValidate.forEach(function (k) {
    if(!options[k]){
      throw new Error(k + ' is required');
    }
  });

  this.apiUrl =   'https://' + options.domain + '/api';
  this.tokenUrl = 'https://' + options.domain + '/oauth/token';
  this.options = options;
}

Client.prototype._getAccessToken = function(done){
  var body = {
    'client_id':     this.options.clientID,
    'client_secret': this.options.clientSecret,
    'grant_type':    'client_credentials'
  };

  request.post({
    url: this.tokenUrl,
    form: body
  }, function (err, resp, body) {

    if (err) return done(err);
    if (resp.statusCode === 404) return done(new Error('unknown client'));
    if (resp.statusCode.toString().substr(0, 1) !== '2') return done(new Error(body));

    var accessToken = JSON.parse(body)['access_token'];
    done(null, accessToken);
  });
};

Object.keys(api).forEach(function (m) {
  Client.prototype[m] = function (){
    var args = [].slice.call(arguments);
    var callback = args[args.length - 1];

    if (this.options.accessToken) {
      api[m].apply(this, [this.options.accessToken].concat(args));
    }
    else {
      this._getAccessToken(function (err, accessToken) {
        if (err) return callback(err);
        api[m].apply(this, [accessToken].concat(args));
      }.bind(this));
    }
  };
});

module.exports = Client;<commit_msg>add Client.getAccessToken<commit_after>var request = require('request');
var api     = require('./api');

function Client(options) {

  var fieldsToValidate = !options.accessToken ?
    ['domain', 'clientID', 'clientSecret'] :
    ['domain'];

  fieldsToValidate.forEach(function (k) {
    if(!options[k]){
      throw new Error(k + ' is required');
    }
  });

  this.apiUrl =   'https://' + options.domain + '/api';
  this.tokenUrl = 'https://' + options.domain + '/oauth/token';
  this.options = options;
}

Client.getAccessToken = function (options, done) {
  var body = {
    'client_id':     options.clientID,
    'client_secret': options.clientSecret,
    'grant_type':    'client_credentials'
  };

  var tokenUrl = 'https://' + options.domain + '/oauth/token';

  request.post({
    url:  tokenUrl,
    form: body
  }, function (err, resp, body) {

    if (err) return done(err);
    if (resp.statusCode === 404) return done(new Error('unknown client'));
    if (resp.statusCode.toString().substr(0, 1) !== '2') return done(new Error(body));

    var accessToken = JSON.parse(body)['access_token'];
    done(null, accessToken);
  });
};

Client.prototype._getAccessToken = function(done){
  var self = this;

  if (this._currentAccessToken) return done(null, this._currentAccessToken);

  return Client.getAccessToken(this.options, function (err, token) {
    if (err) return done(err);

    self._currentAccessToken = token;

    setTimeout(function () {
      delete self._currentAccessToken;
    }, 1000 * 60 * 3); //~ 3 hours

    done(null, token);
  });
};

Object.keys(api).forEach(function (m) {
  Client.prototype[m] = function (){
    var args = [].slice.call(arguments);
    var callback = args[args.length - 1];

    if (this.options.accessToken) {
      api[m].apply(this, [this.options.accessToken].concat(args));
    }
    else {
      this._getAccessToken(function (err, accessToken) {
        if (err) return callback(err);
        api[m].apply(this, [accessToken].concat(args));
      }.bind(this));
    }
  };
});

module.exports = Client;<|endoftext|>


<commit_before>/**
* Node dependencies
**/
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fork } from 'child_process';

/**
* NPM dependencies
**/
import { CLIEngine } from 'eslint';
import glob from 'glob';

/**
* Local dependencies
**/
import { formatResults } from './formatter';

const cpuCount = os.cpus().length;

function getIgnorePatterns(options) {
  let ignorePath = path.join(options.cwd || process.cwd(), '.eslintignore');
  try {
    const ignore = fs.readFileSync(
      ignorePath, 'utf8'
    ).trim().split('\n');

    if (options.ignorePattern) {
      ignore.push(options.ignorePattern);
    }
    return ignore;
  } catch (e) {
    return [];
  }
}

function hasEslintCache(options) {
  const cacheLocation = (
    options.cacheFile || options.cacheLocation || path.join(
      options.cwd || process.cwd(), '.eslintcache'
    )
  );
  try {
    fs.accessSync(path.resolve(cacheLocation), fs.F_OK);
    return true;
  } catch (e) {
    return false;
  }
}

function getFilesByPatterns(patterns, options) {
  const ignore = getIgnorePatterns(options);
  let files = [];

  patterns.forEach(pattern => {
    let isFile = false;
    let isFolder = false;
    try {
      const stats = fs.lstatSync(pattern);
      isFile = stats.isFile();
      isFolder = stats.isDirectory();
    } catch (e) {
      //no-op
    }

    if (isFile) {
      files.push(pattern);
    } else {
      const path = isFolder ? `${pattern.replace(/\'|\"|\/$/g, '')}/**` :
        pattern.replace(/\'|\"|\/$/g, '');
      const newFiles = glob.sync(
        path, { cwd: options.cwd || process.cwd(), nodir: true, ignore }
      );
      files = files.concat(newFiles);
    }
  });

  return files;
}

function eslintFork(options, files) {
  return new Promise((resolve, reject) => {
    const eslintChild = fork(path.resolve(__dirname, 'linter'));
    eslintChild.on('message', (report) => {
      if (report.errorCount || report.warningCount) {
        console.log(formatResults(report.results));
      }
      resolve(report);
    });
    eslintChild.on('exit', (code) => {
      if (code !== 0) {
        reject('Linting failed');
      }
    });
    eslintChild.send({options, files});
  });
}

export default class Linter {
  constructor (options) {
    this._options = options;
    this._engine = new CLIEngine(options);
  }

  run (files) {
    return new Promise((resolve) => {
      const report = this._engine.executeOnFiles(files);
      if (this._options.fix) {
        this._engine.outputFixes(report);
      }

      if (this._options.quiet) {
        report.results = this._engine.getErrorResults(report.results);
      }
      resolve(report);
    });
  }

  execute(patterns) {
    return new Promise((resolve, reject) => {
      const files = getFilesByPatterns(
        patterns, this._options
      );

      const hasCache = hasEslintCache(this._options);

      if (!hasCache && files.length > 50 && cpuCount >= 2) {
        // too many items, need to spawn process (if machine has multi-core)
        const totalCount = {
          errorCount: 0,
          warningCount: 0
        };
        const chunckedPromises = [];
        const chunkSize = Math.ceil(files.length / cpuCount);
        for (let i = 0; i < files.length; i += chunkSize) {
          const chunkedPaths = files.slice(i, i + chunkSize);
          const chunckedPromise = eslintFork(
            this._options, chunkedPaths
          );
          chunckedPromise.then((report) => {
            totalCount.errorCount += report.errorCount;
            totalCount.warningCount += report.warningCount;
          });
          chunckedPromises.push(chunckedPromise);
        }
        Promise.all(chunckedPromises).then(() => {
          resolve(totalCount);
        });
      } else {
        this.run(files).then((report) => {
          if (report.errorCount || report.warningCount) {
            console.log(formatResults(report.results));
          }
          resolve(report);
        }, reject);
      }
    });
  }
}

process.on('message', ({options, files}) => {
  // make sure to ignore message to other nested processes
  if (files) {
    new Linter(options).run(files).then((report) => {
      process.send(report);
    }, (err) => {
      console.log(err);
      process.exit(1);
    });
  }
});
<commit_msg>should pass<commit_after>/**
* Node dependencies
**/
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fork } from 'child_process';

/**
* NPM dependencies
**/
import { CLIEngine } from 'eslint';
import glob from 'glob';

/**
* Local dependencies
**/
import { formatResults } from './formatter

const cpuCount = os.cpus().length;

function getIgnorePatterns(options) {
  let ignorePath = path.join(options.cwd || process.cwd(), '.eslintignore');
  try {
    const ignore = fs.readFileSync(
      ignorePath, 'utf8'
    ).trim().split('\n');

    if (options.ignorePattern) {
      ignore.push(options.ignorePattern);
    }
    return ignore;
  } catch (e) {
    return [];
  }
}

function hasEslintCache(options) {
  const cacheLocation = (
    options.cacheFile || options.cacheLocation || path.join(
      options.cwd || process.cwd(), '.eslintcache'
    )
  );
  try {
    fs.accessSync(path.resolve(cacheLocation), fs.F_OK);
    return true;
  } catch (e) {
    return false;
  }
}

function getFilesByPatterns(patterns, options) {
  const ignore = getIgnorePatterns(options);
  let files = [];

  patterns.forEach(pattern => {
    let isFile = false;
    let isFolder = false;
    try {
      const stats = fs.lstatSync(pattern);
      isFile = stats.isFile();
      isFolder = stats.isDirectory();
    } catch (e) {
      //no-op
    }

    if (isFile) {
      files.push(pattern);
    } else {
      const path = isFolder ? `${pattern.replace(/\'|\"|\/$/g, '')}/**` :
        pattern.replace(/\'|\"|\/$/g, '');
      const newFiles = glob.sync(
        path, { cwd: options.cwd || process.cwd(), nodir: true, ignore }
      );
      files = files.concat(newFiles);
    }
  });

  return files;
}

function eslintFork(options, files) {
  return new Promise((resolve, reject) => {
    const eslintChild = fork(path.resolve(__dirname, 'linter'));
    eslintChild.on('message', (report) => {
      if (report.errorCount || report.warningCount) {
        console.log(formatResults(report.results));
      }
      resolve(report);
    });
    eslintChild.on('exit', (code) => {
      if (code !== 0) {
        reject('Linting failed');
      }
    });
    eslintChild.send({options, files});
  });
}

export default class Linter {
  constructor (options) {
    this._options = options;
    this._engine = new CLIEngine(options);
  }

  run (files) {
    return new Promise((resolve) => {
      const report = this._engine.executeOnFiles(files);
      if (this._options.fix) {
        this._engine.outputFixes(report);
      }

      if (this._options.quiet) {
        report.results = this._engine.getErrorResults(report.results);
      }
      resolve(report);
    });
  }

  execute(patterns) {
    return new Promise((resolve, reject) => {
      const files = getFilesByPatterns(
        patterns, this._options
      );

      const hasCache = hasEslintCache(this._options);

      if (!hasCache && files.length > 50 && cpuCount >= 2) {
        // too many items, need to spawn process (if machine has multi-core)
        const totalCount = {
          errorCount: 0,
          warningCount: 0
        };
        const chunckedPromises = [];
        const chunkSize = Math.ceil(files.length / cpuCount);
        for (let i = 0; i < files.length; i += chunkSize) {
          const chunkedPaths = files.slice(i, i + chunkSize);
          const chunckedPromise = eslintFork(
            this._options, chunkedPaths
          );
          chunckedPromise.then((report) => {
            totalCount.errorCount += report.errorCount;
            totalCount.warningCount += report.warningCount;
          });
          chunckedPromises.push(chunckedPromise);
        }
        Promise.all(chunckedPromises).then(() => {
          resolve(totalCount);
        });
      } else {
        this.run(files).then((report) => {
          if (report.errorCount || report.warningCount) {
            console.log(formatResults(report.results));
          }
          resolve(report);
        }, reject);
      }
    });
  }
}

process.on('message', ({options, files}) => {
  // make sure to ignore message to other nested processes
  if (files) {
    new Linter(options).run(files).then((report) => {
      process.send(report);
    }, (err) => {
      console.log(err);
      process.exit(1);
    });
  }
});
<|endoftext|>


<commit_before>/*
 * jsonfs
 *
 * Copyright (c) 2014 Jalal Hejazi
 * Licensed under the MIT license.
 */

'use strict';
//global modules
var path = require('path');

//local modules
var util = require('./util');
var msg = {
    connect_success: 'Successfully connected to : ',
    connect_error_db_path:'The DB Path %s does not seem to be valid. Recheck the path and try again',
    loadCollections_initialize:'Initialize the DB before you add collections. Use: db.connect(path-to-db,["collection"])'
};

var db = {
    connect: function(path, collections) {
        if (util.isValidPath(path)) {
            var _db = {};
            _db.path = path;
            this._db = _db;
            console.log(msg.connect_success + path);
            if (collections) {
                this.loadCollections(collections);
            }
        } else {
            console.log(msg.connect_error_db_path,path);
            return false;
        }
        return this;
    },
    loadCollections: function(collections) {
        if (!this._db) {
            console.log(msg.loadCollections_initialize);
            return false;
        }
        if (typeof collections === 'object' && collections.length) {
            for (var i = 0; i < collections.length; i++) {
                var p = path.join(this._db.path, (collections[i].indexOf('.json') >= 0 ? collections[i] : collections[i] + '.json'));
                if (!util.isValidPath(p)) {
                    util.writeToFile(p);
                }
                var _c = collections[i].replace('.json', '');
                this[_c] = new require('./collection')(this, _c);
            }
        } else {
            console.log('Invalid Collections Array.', 'Expected Format : ', '[\'collection1\',\'collection2\',\'collection3\']');
        }
        return this;
    }

};

module.exports = db;
<commit_msg>rename to jsonfs.js<commit_after><|endoftext|>


<commit_before>var Bitloader = require("bit-loader");
var utils = require("belty");
var resolvePath = require("bit-bundler-utils/resolvePath");
var readFile = require("bit-bundler-utils/readFile");
var logger = require("./logger").create("bundler/loader");

function Loader(options) {
  Bitloader.call(this, utils.extend({
    resolve: configureResolve(options),
    fetch: configureFetch(options)
  }, options));
}

Loader.prototype = Object.create(Bitloader.prototype);
Loader.prototype.constructor = Loader;

function configureResolve(options) {
  var resolver = resolvePath.configure({baseUrl: options.baseUrl});

  return function resolveName(meta) {
    function handleError(err) {
      var message = err && err.message;

      if (message && message.indexOf("Cannot find module") === 0 && options.ignoreNotFound) {
        logger.warn("Module not found. Skipping it.", moduleNotFoundError(meta));
      }
      else {
        var error = moduleNotResolvedError(meta, err);
        logger.error(error);
        throw err;
      }

      return {
        id: "@notfound",
        path: ""
      };
    }

    return resolver(meta).then(utils.identity, handleError);
  };
}

function configureFetch(options) {
  return function fetchModule(meta) {
    function handleError(err) {
      var error = moduleNotLoadedError(meta, err);
      logger.error(error);
      throw err;
    }

    return meta.id === "@notfound" && options.ignoreNotFound ?
      Promise.resolve({ source: "" }) :
      readFile(meta).then(utils.identity, handleError);
  };
}

var moduleNotFoundError = buildError.bind(null, "Unable to find module");
var moduleNotLoadedError = buildError.bind(null, "Unable to load module");
var moduleNotResolvedError = buildError.bind(null, "Unable to resolve module");

function buildError(title, meta, err) {
  var error = title + " \"" + meta.name + "\".";
  error += meta.referrer ? " Referrer " + JSON.stringify(meta.referrer.path) : "";
  error += err ? "\n" + err : "";
  return error;
}

module.exports = Loader;
<commit_msg>Cleaned up a lil bit of the error logged by the loader<commit_after>var Bitloader = require("bit-loader");
var utils = require("belty");
var resolvePath = require("bit-bundler-utils/resolvePath");
var readFile = require("bit-bundler-utils/readFile");
var logger = require("./logger").create("bundler/loader");

function Loader(options) {
  Bitloader.call(this, utils.extend({
    resolve: configureResolve(options),
    fetch: configureFetch(options)
  }, options));
}

Loader.prototype = Object.create(Bitloader.prototype);
Loader.prototype.constructor = Loader;

function configureResolve(options) {
  var resolver = resolvePath.configure({baseUrl: options.baseUrl});

  return function resolveName(meta) {
    function handleError(err) {
      var message = err && err.message;

      if (message && message.indexOf("Cannot find module") === 0 && options.ignoreNotFound) {
        logger.warn("Module not found. Skipping it.", moduleNotFoundError(meta));
      }
      else {
        logger.error(moduleNotResolvedError(meta), err);
        throw err;
      }

      return {
        id: "@notfound",
        path: ""
      };
    }

    return resolver(meta).then(utils.identity, handleError);
  };
}

function configureFetch(options) {
  return function fetchModule(meta) {
    function handleError(err) {
      logger.error(moduleNotLoadedError(meta), err);
      throw err;
    }

    return meta.id === "@notfound" && options.ignoreNotFound ?
      Promise.resolve({ source: "" }) :
      readFile(meta).then(utils.identity, handleError);
  };
}

var moduleNotFoundError = buildError.bind(null, "Unable to find module");
var moduleNotLoadedError = buildError.bind(null, "Unable to load module");
var moduleNotResolvedError = buildError.bind(null, "Unable to resolve module");

function buildError(title, meta) {
  return title + " '" + meta.name + "'." + (meta.referrer ? " Referrer " + JSON.stringify(meta.referrer.path) : "");
}

module.exports = Loader;
<|endoftext|>


<commit_before>var util = require('util')
var LogLevel = require('./LogLevel.js')
var moment = require('moment')

module.exports = Logger

//TODO: add util inspect for objects to save the log.isSilly() checks all over the place
function Logger(level, opts) {
	if (!(this instanceof Logger)) return new Logger(level)

	var addTimestamp, name

	if (typeof(level) === 'object') {
		opts = level
		level = opts.level
	}

	if (typeof(opts) === 'object') {
		addTimestamp = opts.addTimestamp
		name = opts.name
	} else {
		addTimestamp = opts
	}

	if (addTimestamp === undefined)
		addTimestamp = true

	if (name)
		this.name = '[' + name + '] '
	else
		this.name = ''

	level = level || LogLevel.INFO
	this.outputs = []
	this.setLevel(level)
	this.addOutput(Logger.consoleLogOutput, addTimestamp)
}

/*
	set the level of reporting for this logger,
	select for LogLevel
*/
Logger.prototype.setLevel = function(level) {

	// convert the level from string to number
	if (typeof level === 'string')
		level = LogLevel[level.toUpperCase()]

	if (level < LogLevel.SILENT || level > LogLevel.SILLY)
		throw new Error('illegal log level ' + level)

	this.level = level
}

/*
	add another output for this logger

	@param [function|object] fn - if function, then of the form function write(args) {}
							if object, then { write: function(args){}, prepare: function(level, label, args) {}}
							see Logger.addLogLevelLabel() for prepare example
	@param [boolean] addTimestamp - if function optional write down timestamp and label
*/
Logger.prototype.addOutput = function(fn, addTimestamp) {

	if (typeof fn === 'function') {
		fn = {
			write: fn
		}

		if (addTimestamp) {
			fn.prepare = Logger.addLogLevelLabelAndTimestamp
		} else {
			fn.prepare = Logger.addLogLevelLabel
		}
	}

	if (typeof fn === 'object' && typeof fn.write === 'function' && typeof fn.prepare === 'function') {
		this.outputs.unshift(fn)
	} else {
		throw new Error('invalid output argument ' + fn)
	}
}

Logger.prototype.clearOutputs = function() {
	this.outputs = []
}

Logger.prototype.isSilly = function() {
	return this.level === LogLevel.SILLY
}

Logger.prototype.isDebug = function() {
	return this.level === LogLevel.DEBUG
}

Logger.prototype.silly = function() {
	var args = new Array(arguments.length)
	for (var i = args.length; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.SILLY) {
		this._write(LogLevel.SILLY, this.name + 'SILLY: ', args)
	}
}

Logger.prototype.debug = function() {
	var args = new Array(arguments.length)
	for (var i = args.length; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.DEBUG) {
		this._write(LogLevel.DEBUG, this.name + 'DEBUG: ', args)
	}
}

Logger.prototype.info = function() {
	var args = new Array(arguments.length)
	for (var i = args.length; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.INFO) {
		this._write(LogLevel.INFO, this.name + 'INFO: ', args)
	}
}

Logger.prototype.warn = function() {
	var args = new Array(arguments.length)
	for (var i = args.length; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.WARN) {
		this._write(LogLevel.WARN, this.name + 'WARN: ', args)
	}
}

Logger.prototype.error = function() {
	var args = new Array(arguments.length)
	for (var i = args.length; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.ERROR) {

		// if its just log.error(e) then print the stack
		if (args.length === 1 && args[0] instanceof Error && args[0].stack) {
			this._write(LogLevel.ERROR, this.name + 'ERROR: ', [args[0].stack])
		} else {
			this._write(LogLevel.ERROR, this.name + 'ERROR: ', args)
		}
	}
}

Logger.prototype._write = function(level, label, args) {

	var outputs = this.outputs

	for (var i = outputs.length - 1; i >= 0; i--) {
		var output = outputs[i]
		var argsClone = [].concat(args)
		output.prepare(level, label, argsClone)
		output.write(argsClone)
	}
}

Logger.addLogLevelLabel = function(level, label, args) {
	args[0] = label + args[0]
}

Logger.addLogLevelLabelAndTimestamp = function(level, label, args) {
	args[0] = moment().utc().format('[[]YYYY-MM-DD HH:mm:ss.SSS[]]') + ' ' + label + args[0]
}

Logger.consoleLogOutput = function(args) {
	console.log.apply(console, args)
}
<commit_msg>interation mistake<commit_after>var util = require('util')
var LogLevel = require('./LogLevel.js')
var moment = require('moment')

module.exports = Logger

//TODO: add util inspect for objects to save the log.isSilly() checks all over the place
function Logger(level, opts) {
	if (!(this instanceof Logger)) return new Logger(level)

	var addTimestamp, name

	if (typeof(level) === 'object') {
		opts = level
		level = opts.level
	}

	if (typeof(opts) === 'object') {
		addTimestamp = opts.addTimestamp
		name = opts.name
	} else {
		addTimestamp = opts
	}

	if (addTimestamp === undefined)
		addTimestamp = true

	if (name)
		this.name = '[' + name + '] '
	else
		this.name = ''

	level = level || LogLevel.INFO
	this.outputs = []
	this.setLevel(level)
	this.addOutput(Logger.consoleLogOutput, addTimestamp)
}

/*
	set the level of reporting for this logger,
	select for LogLevel
*/
Logger.prototype.setLevel = function(level) {

	// convert the level from string to number
	if (typeof level === 'string')
		level = LogLevel[level.toUpperCase()]

	if (level < LogLevel.SILENT || level > LogLevel.SILLY)
		throw new Error('illegal log level ' + level)

	this.level = level
}

/*
	add another output for this logger

	@param [function|object] fn - if function, then of the form function write(args) {}
							if object, then { write: function(args){}, prepare: function(level, label, args) {}}
							see Logger.addLogLevelLabel() for prepare example
	@param [boolean] addTimestamp - if function optional write down timestamp and label
*/
Logger.prototype.addOutput = function(fn, addTimestamp) {

	if (typeof fn === 'function') {
		fn = {
			write: fn
		}

		if (addTimestamp) {
			fn.prepare = Logger.addLogLevelLabelAndTimestamp
		} else {
			fn.prepare = Logger.addLogLevelLabel
		}
	}

	if (typeof fn === 'object' && typeof fn.write === 'function' && typeof fn.prepare === 'function') {
		this.outputs.unshift(fn)
	} else {
		throw new Error('invalid output argument ' + fn)
	}
}

Logger.prototype.clearOutputs = function() {
	this.outputs = []
}

Logger.prototype.isSilly = function() {
	return this.level === LogLevel.SILLY
}

Logger.prototype.isDebug = function() {
	return this.level === LogLevel.DEBUG
}

Logger.prototype.silly = function() {
	var args = new Array(arguments.length)
	for (var i = args.length - 1; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.SILLY) {
		this._write(LogLevel.SILLY, this.name + 'SILLY: ', args)
	}
}

Logger.prototype.debug = function() {
	var args = new Array(arguments.length)
	for (var i = args.length - 1; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.DEBUG) {
		this._write(LogLevel.DEBUG, this.name + 'DEBUG: ', args)
	}
}

Logger.prototype.info = function() {
	var args = new Array(arguments.length)
	for (var i = args.length - 1; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.INFO) {
		this._write(LogLevel.INFO, this.name + 'INFO: ', args)
	}
}

Logger.prototype.warn = function() {
	var args = new Array(arguments.length)
	for (var i = args.length - 1; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.WARN) {
		this._write(LogLevel.WARN, this.name + 'WARN: ', args)
	}
}

Logger.prototype.error = function() {
	var args = new Array(arguments.length)
	for (var i = args.length - 1; i >= 0; i--) {
		args[i] = arguments[i]
	}

	if (this.level >= LogLevel.ERROR) {

		// if its just log.error(e) then print the stack
		if (args.length === 1 && args[0] instanceof Error && args[0].stack) {
			this._write(LogLevel.ERROR, this.name + 'ERROR: ', [args[0].stack])
		} else {
			this._write(LogLevel.ERROR, this.name + 'ERROR: ', args)
		}
	}
}

Logger.prototype._write = function(level, label, args) {

	var outputs = this.outputs

	for (var i = outputs.length - 1; i >= 0; i--) {
		var output = outputs[i]
		var argsClone = [].concat(args)
		output.prepare(level, label, argsClone)
		output.write(argsClone)
	}
}

Logger.addLogLevelLabel = function(level, label, args) {
	args[0] = label + args[0]
}

Logger.addLogLevelLabelAndTimestamp = function(level, label, args) {
	args[0] = moment().utc().format('[[]YYYY-MM-DD HH:mm:ss.SSS[]]') + ' ' + label + args[0]
}

Logger.consoleLogOutput = function(args) {
	console.log.apply(console, args)
}
<|endoftext|>


<commit_before>module.exports = function(source){
  return source;
}
<commit_msg>Updated<commit_after>var consolidate = require('consolidate');
var utils = require('loader-utils');
var extname = require('path').extname;

module.exports = function(content) {
  this.cacheable && this.cacheable();

  var callback = this.async();
  var opt = utils.parseQuery(this.query);

  function exportContent(content) {
    if (opt.raw) {
      callback(null, content);
    } else {
      callback(null, "module.exports = " + JSON.stringify(content));
    }
  }

  if(!opt.engine) {
    opt.engine = extname(this.request).substr(1).toLowerCase();
  }

  if(!consolidate[opt.engine]) {
    throw new Error("Engine '"+ opt.engine +"' isn't available in Consolidate.js");
  }

  opt.filename = this.resourcePath;

  consolidate[opt.engine].render(content, opt, function(err, html) {
    if(err) {
      throw err;
    }
    exportContent(html);
  });
};
<|endoftext|>


<commit_before>import Transformer from './transformer.js';
import Path from './path.js';

export default {

	data: {},
	type: {
		js: 'attach',
		css: 'attach'
	},

	async setup (options) {
		let self = this;

		options = options || {};

		if (options.loads) {
			return Promise.all(options.loads.map(function (load) {
				return self.load(load);
			}));
		}

	},

	async execute (data) {
		let text = '\'use strict\';\n\n' + (data.ast ? data.ast.cooked : data.text);
		let code = new Function('$LOADER', 'window', text);
		data.result = code(this, window);
	},

	async transform (data) {
		const self = this;

		if (data.type === 'es' || data.type=== 'est') {
			data.text = Transformer.template(data.text);
		}

		if (data.type === 'es' || data.type === 'esm') {
			data.ast = Transformer.ast(data);
		}

		if (data.ast && data.ast.imports.length) {
			return Promise.all(data.ast.imports.map(function (imp) {
				return self.load({ url: imp.url, type: data.type });
			}));
		}

	},

	async attach (data) {
		return new Promise(function (resolve, reject) {
			let element = document.createElement(data.tag);

			element.onload = resolve;
			element.onerror = reject;

			for (let name in data.attributes) {
				element.setAttribute(name, data.attributes[name]);
			}

			document.head.appendChild(element);
		});
	},

	async fetch (data) {
		let result = await window.fetch(data.url);

		if (result.status >= 200 && result.status < 300 || result.status == 304) {
			data.text = await result.text();
		} else {
			throw new Error(result.statusText);
		}

	},

	async js (data) {
		if (data.type === 'es' || data.type === 'est' || data.type === 'esm' || data.type === 'fetch') {
			await this.fetch(data);

			if (data.type === 'es' || data.type === 'est' || data.type === 'esm') {
				await this.transform(data);
			}

			await this.execute(data);
		} else if (data.type === 'script') {
			await this.attach({
				tag: 'script',
				attributes: {
					src: data.url,
					type: 'text/javascript'
				}
			});
		} else {
			await this.attach({
				tag: 'script',
				attributes: {
					src: data.url,
					type: 'module'
				}
			});
		}
	},

	async css (data) {
		if (data.type === 'fetch') {
			await this.fetch(data);
		} else {
			await this.attach({
				tag: 'link',
				attributes: {
					href: data.url,
					type: 'text/css',
					rel: 'stylesheet'
				}
			});
		}
	},

	async load (data) {

		if (typeof data === 'string') {
			data = { url: data };
		}

		data.url = Path.resolve(data.url);

		if (data.url in this.data) {
			await this.data[data.url].promise;
			return this.data[data.url].result;
		}

		this.data[data.url] = data;

		data.extension = data.extension || Path.extension(data.url);
		data.type = data.type || this.type[data.extension];

		if (data.extension === 'js') {
			data.promise = this.js(data);
		} else if (data.extension === 'css') {
			data.promise = this.css(data);
		} else {
			data.promise = this.fetch(data);
		}

		await data.promise;

		return data.result;
	}

};

/*
	https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
*/
<commit_msg>removed line break<commit_after>import Transformer from './transformer.js';
import Path from './path.js';

export default {

	data: {},
	type: {
		js: 'attach',
		css: 'attach'
	},

	async setup (options) {
		let self = this;

		options = options || {};

		if (options.loads) {
			return Promise.all(options.loads.map(function (load) {
				return self.load(load);
			}));
		}

	},

	async execute (data) {
		let text = '\'use strict\';\n' + (data.ast ? data.ast.cooked : data.text);
		let code = new Function('$LOADER', 'window', text);
		data.result = code(this, window);
	},

	async transform (data) {
		const self = this;

		if (data.type === 'es' || data.type=== 'est') {
			data.text = Transformer.template(data.text);
		}

		if (data.type === 'es' || data.type === 'esm') {
			data.ast = Transformer.ast(data);
		}

		if (data.ast && data.ast.imports.length) {
			return Promise.all(data.ast.imports.map(function (imp) {
				return self.load({ url: imp.url, type: data.type });
			}));
		}

	},

	async attach (data) {
		return new Promise(function (resolve, reject) {
			let element = document.createElement(data.tag);

			element.onload = resolve;
			element.onerror = reject;

			for (let name in data.attributes) {
				element.setAttribute(name, data.attributes[name]);
			}

			document.head.appendChild(element);
		});
	},

	async fetch (data) {
		let result = await window.fetch(data.url);

		if (result.status >= 200 && result.status < 300 || result.status == 304) {
			data.text = await result.text();
		} else {
			throw new Error(result.statusText);
		}

	},

	async js (data) {
		if (data.type === 'es' || data.type === 'est' || data.type === 'esm' || data.type === 'fetch') {
			await this.fetch(data);

			if (data.type === 'es' || data.type === 'est' || data.type === 'esm') {
				await this.transform(data);
			}

			await this.execute(data);
		} else if (data.type === 'script') {
			await this.attach({
				tag: 'script',
				attributes: {
					src: data.url,
					type: 'text/javascript'
				}
			});
		} else {
			await this.attach({
				tag: 'script',
				attributes: {
					src: data.url,
					type: 'module'
				}
			});
		}
	},

	async css (data) {
		if (data.type === 'fetch') {
			await this.fetch(data);
		} else {
			await this.attach({
				tag: 'link',
				attributes: {
					href: data.url,
					type: 'text/css',
					rel: 'stylesheet'
				}
			});
		}
	},

	async load (data) {

		if (typeof data === 'string') {
			data = { url: data };
		}

		data.url = Path.resolve(data.url);

		if (data.url in this.data) {
			await this.data[data.url].promise;
			return this.data[data.url].result;
		}

		this.data[data.url] = data;

		data.extension = data.extension || Path.extension(data.url);
		data.type = data.type || this.type[data.extension];

		if (data.extension === 'js') {
			data.promise = this.js(data);
		} else if (data.extension === 'css') {
			data.promise = this.css(data);
		} else {
			data.promise = this.fetch(data);
		}

		await data.promise;

		return data.result;
	}

};

/*
	https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
*/
<|endoftext|>


<commit_before>/*
Copyright (c) 2015 Simon Cullen, http://github.com/cullens

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

/**
 * @memberOf $thing
 * @method switchContext
 */
$thing.switchContext = function(
    functString,
    parentOrdinal,
    superOrdinal,
    ordinal,
    superName,
    methodName
) {
    functString = functString || this.$vtable[ordinal][methodName].toString();

    return (
        functString.indexOf('$parent') > -1 ||
        functString.indexOf('$super') > -1
    )
        ? function() {
            var ret,
                $parent = this.$parent,
                $super = this.$super
                ;

            this.$parent = this.$vtable[parentOrdinal] || $parent;
            this.$super = this.$vtable[superOrdinal][superName];

            ret = this.$vtable[ordinal][methodName].apply(this, arguments);

            this.$parent = $parent;
            this.$super = $super;

            return ret;
        }
        : this.$vtable[ordinal][methodName]
        ;
};

/**
 * @memberOf $thing
 * @method switchParentContext
 */
$thing.switchParentContext = function(
    functString,
    parentOrdinal,
    ordinal,
    methodName
) {
    functString = functString || this.$vtable[ordinal][methodName].toString();

    return (
        functString.indexOf('$parent') > -1
    )
        ? function() {
            var ret,
                $parent = this.$parent
                ;

            this.$parent = this.$vtable[parentOrdinal] || this.$parent;

            ret = this.$vtable[ordinal][methodName].apply(this, arguments);

            this.$parent = $parent;

            return ret;
        }
        : this.$vtable[ordinal][methodName]
        ;
};

/**
 * @class Object
 * @memberOf $thing
 */
$thing.Object = function(){};

/**
 * Return object name
 * @memberOf $thing
 * @method Object#getName
 * @returns {string}
 */
$thing.Object.prototype.getName = function(){
    return 'Object';
};

/**
 * @memberOf $thing
 * @method Object.inherit
 * @param {object} obj
 * @param {object} parent
 * @returns {object}
 */
var $inherit = $thing.Object.inherit = function(obj, parent) {
    var i,
        j,
        k,
        v,
        functString,
        signature,
        signatures = {},
        ontology = {},
        inherit = this.prototype
        ;

    function ret() {
        /*jshint validthis:true */
        (this.init !== undefined)
            ? this.init.apply(this, arguments)
            : undefined
            ;
    }

    function replace() {
        return (obj['$' + arguments[1]] !== undefined)
            ? obj['$' + arguments[1]]
            : arguments[0]
            ;
    }

    ret.prototype = new this();
    ret.prototype.constructor = ret;
    ret.prototype.$vtable = (ret.prototype.$vtable !== undefined)
        ? ret.prototype.$vtable.slice()
        : []
        ;

    var ordinal = ret.prototype.$vtable.push(obj) - 1,
        parentOrdinal = ret.prototype.$vtable.push(parent) - 1,
        superOrdinal = ret.prototype.$vtable.push(inherit) - 1
        ;

    ret.inherit = $inherit;

    for (i in obj) {
        switch(i) {
            case '$vtable':
                /* falls through */
            case '$signatures':
                /* falls through */
            case '$ontology':
                /* falls through */
            case '$owner':
                /* falls through */
            case '$parent':
                /* falls through */
            case '$super':
                /* falls through */
                continue;
        }

        v = obj[i];
        k = i.replace(/\$\((.+?)\)/g, replace);
        j = k.substring(k.indexOf('.') + 1);

        if (typeof v !== 'function')
            if (k.charAt(0) === '$')
                ret.prototype[k] = v;
            else
                ontology[k] = v;
        else {
            functString = v.toString();
            signature = functString.match(/function[^(]*\(([^)]*)\)/);

            (typeof inherit[k] !== 'function')
                ? (typeof inherit[j] !== 'function')
                    ? ret.prototype[k] = $thing.switchParentContext.apply(
                        ret.prototype,
                        [   functString,
                            parentOrdinal,
                            ordinal,
                            i
                        ]
                    )
                    : ret.prototype[k] = $thing.switchContext.apply(
                        ret.prototype,
                        [   functString,
                            parentOrdinal,
                            superOrdinal,
                            ordinal,
                            j,
                            i
                        ]
                    )
                : ret.prototype[k] = $thing.switchContext.apply(
                    ret.prototype,
                    [   functString,
                        parentOrdinal,
                        superOrdinal,
                        ordinal,
                        k,
                        i
                    ]
                )
                ;

            if (signature !== null)
                signatures[k] = (signature[1].length)
                    ? signature[1].split(/,\s*/)
                    : []
                    ;
        }
    }

    ret.prototype.$owner = parent || ret.prototype.$owner;

    ret.prototype.$signatures = $thing.merge(
        signatures,
        ret.prototype.$signatures
    );

    ret.prototype.$ontology = $thing.merge(
        ontology,
        ret.prototype.$ontology
    );

    return ret;
};<commit_msg>Changed ret to $obj as it looks better in V8 Stack Traces<commit_after>/*
Copyright (c) 2015 Simon Cullen, http://github.com/cullens

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

/**
 * @memberOf $thing
 * @method switchContext
 */
$thing.switchContext = function(
    functString,
    parentOrdinal,
    superOrdinal,
    ordinal,
    superName,
    methodName
) {
    functString = functString || this.$vtable[ordinal][methodName].toString();

    return (
        functString.indexOf('$parent') > -1 ||
        functString.indexOf('$super') > -1
    )
        ? function() {
            var ret,
                $parent = this.$parent,
                $super = this.$super
                ;

            this.$parent = this.$vtable[parentOrdinal] || $parent;
            this.$super = this.$vtable[superOrdinal][superName];

            ret = this.$vtable[ordinal][methodName].apply(this, arguments);

            this.$parent = $parent;
            this.$super = $super;

            return ret;
        }
        : this.$vtable[ordinal][methodName]
        ;
};

/**
 * @memberOf $thing
 * @method switchParentContext
 */
$thing.switchParentContext = function(
    functString,
    parentOrdinal,
    ordinal,
    methodName
) {
    functString = functString || this.$vtable[ordinal][methodName].toString();

    return (
        functString.indexOf('$parent') > -1
    )
        ? function() {
            var ret,
                $parent = this.$parent
                ;

            this.$parent = this.$vtable[parentOrdinal] || this.$parent;

            ret = this.$vtable[ordinal][methodName].apply(this, arguments);

            this.$parent = $parent;

            return ret;
        }
        : this.$vtable[ordinal][methodName]
        ;
};

/**
 * @class Object
 * @memberOf $thing
 */
$thing.Object = function(){};

/**
 * Return object name
 * @memberOf $thing
 * @method Object#getName
 * @returns {string}
 */
$thing.Object.prototype.getName = function(){
    return 'Object';
};

/**
 * @memberOf $thing
 * @method Object.inherit
 * @param {object} obj
 * @param {object} parent
 * @returns {object}
 */
var $inherit = $thing.Object.inherit = function(obj, parent) {
    var i,
        j,
        k,
        v,
        functString,
        signature,
        signatures = {},
        ontology = {},
        inherit = this.prototype
        ;

    function $obj() {
        /*jshint validthis:true */
        (this.init !== undefined)
            ? this.init.apply(this, arguments)
            : undefined
            ;
    }

    function replace() {
        return (obj['$' + arguments[1]] !== undefined)
            ? obj['$' + arguments[1]]
            : arguments[0]
            ;
    }

    $obj.prototype = new this();
    $obj.prototype.constructor = $obj;
    $obj.prototype.$vtable = ($obj.prototype.$vtable !== undefined)
        ? $obj.prototype.$vtable.slice()
        : []
        ;

    var ordinal = $obj.prototype.$vtable.push(obj) - 1,
        parentOrdinal = $obj.prototype.$vtable.push(parent) - 1,
        superOrdinal = $obj.prototype.$vtable.push(inherit) - 1
        ;

    $obj.inherit = $inherit;

    for (i in obj) {
        switch(i) {
            case '$vtable':
                /* falls through */
            case '$signatures':
                /* falls through */
            case '$ontology':
                /* falls through */
            case '$owner':
                /* falls through */
            case '$parent':
                /* falls through */
            case '$super':
                /* falls through */
                continue;
        }

        v = obj[i];
        k = i.replace(/\$\((.+?)\)/g, replace);
        j = k.substring(k.indexOf('.') + 1);

        if (typeof v !== 'function')
            if (k.charAt(0) === '$')
                $obj.prototype[k] = v;
            else
                ontology[k] = v;
        else {
            functString = v.toString();
            signature = functString.match(/function[^(]*\(([^)]*)\)/);

            (typeof inherit[k] !== 'function')
                ? (typeof inherit[j] !== 'function')
                    ? $obj.prototype[k] = $thing.switchParentContext.apply(
                        $obj.prototype,
                        [   functString,
                            parentOrdinal,
                            ordinal,
                            i
                        ]
                    )
                    : $obj.prototype[k] = $thing.switchContext.apply(
                        $obj.prototype,
                        [   functString,
                            parentOrdinal,
                            superOrdinal,
                            ordinal,
                            j,
                            i
                        ]
                    )
                : $obj.prototype[k] = $thing.switchContext.apply(
                    $obj.prototype,
                    [   functString,
                        parentOrdinal,
                        superOrdinal,
                        ordinal,
                        k,
                        i
                    ]
                )
                ;

            if (signature !== null)
                signatures[k] = (signature[1].length)
                    ? signature[1].split(/,\s*/)
                    : []
                    ;
        }
    }

    $obj.prototype.$owner = parent || $obj.prototype.$owner;

    $obj.prototype.$signatures = $thing.merge(
        signatures,
        $obj.prototype.$signatures
    );

    $obj.prototype.$ontology = $thing.merge(
        ontology,
        $obj.prototype.$ontology
    );

    return $obj;
};<|endoftext|>