/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */
/* Written by S A Sureshkumar (saskumar@live.com). */
jQuery(function($){
	$.datepicker.regional['ta'] = {
		closeText: 'மூடு',
		prevText: 'முன்னையது',
		nextText: 'அடுத்தது',
		currentText: 'இன்று',
		monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி',
		'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'],
		monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி',
		'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'],
		dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'],
		dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'],
		dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'],
		weekHeader: 'Не',
		dateFormat: 'dd/mm/yy',
		firstDay: 1,
		isRTL: false,
		showMonthAfterYear: false,
		yearSuffix: ''};
	$.datepicker.setDefaults($.datepicker.regional['ta']);
});


keep keep keep keep keep replace replace replace replace keep keep keep keep keep

/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, window */

/**
 * Button that opens a dropdown list when clicked. More akin to a popup menu than a combobox. Compared to a
 * simple <select> element:
 *  - There's no "selected" state
 *  - The button's label is not automatically changed when an item in the list is clicked
 *  - Its width is not the max of all the dropdown items' labels
 *  - The button & dropdown's appearance can be customized far more
 *
 * TODO: merge DropdownEventHandler into this? Are there any other widgets that might want to use it separately?
 */
define(function (require, exports, module) {
    "use strict";

    // Load dependent modules
    var DropdownEventHandler    = require("utils/DropdownEventHandler").DropdownEventHandler,
        PanelManager            = require("view/PanelManager"),
        Menus                   = require("command/Menus"),
        ViewUtils               = require("utils/ViewUtils"),
        _                       = require("thirdparty/lodash");

    /**
     * Creates a single dropdown-button instance. The DOM node is created but not attached to
     * the document anywhere - clients should append this.$button to the appropriate location.
     *
     * DropdownButton dispatches the following events:
     *  - "select" - when an option in the dropdown is clicked. Passed item object and index.
     *
     * @param {!string} label  Label to display on the button
     * @param {!Array.<*>} items  Items in the dropdown list
     * @param {?function(*, number):!string} itemRenderer  Optional function to convert a single item to HTML
     *          (see itemRenderer() docs below). If not provided, items are assumed to be plain text strings.
     */
    function DropdownButton(label, items, itemRenderer) {
        this.items = items;

        this.itemRenderer = itemRenderer || this.itemRenderer;

        this._onClick        = this._onClick.bind(this);
        this.closeDropdown   = this.closeDropdown.bind(this);
        this._onClickOutside = this._onClickOutside.bind(this);

        this.$button = $("<button class='btn btn-dropdown'/>")
            .text(label)
            .on("click", this._onClick);
    }

    /** @type {!Array.<*>} Items in dropdown list - may be changed any time dropdown isn't open */
    DropdownButton.prototype.items = null;

    /** @type {!jQueryObject} The clickable button. Available as soon as the DropdownButton is constructed. */
    DropdownButton.prototype.$button = null;

    /** @type {?jQueryObject} The dropdown element. Only non-null while open. */
    DropdownButton.prototype.$dropdown = null;

    /** @type {?string} Extra CSS class(es) to apply to $dropdown */
    DropdownButton.prototype.dropdownExtraClasses = null;

    /** @private @type {?HTMLElement} Where to restore focus when dropdown closed */
    DropdownButton.prototype._lastFocus = null;

    /** @private @type {?DropdownEventHandler} Helper object for dropdown. Only non-null while open. */
    DropdownButton.prototype._dropdownEventHandler = null;

    /** @private Handle clicking button */
    DropdownButton.prototype._onClick = function (event) {
        if (!this.$button.hasClass("disabled")) {
            this.toggleDropdown();
        }
        // Indicate click was handled (e.g. to shield from MultiRangeInlineEditor._onClick())
        event.stopPropagation();
    };

    /**
     * Update the button label.
     * @param {string} label
     */
    DropdownButton.prototype.setButtonLabel = function (label) {
        if (!this.$button) {
            return;
        }
        $(this.$button).text(label);
    };

    /**
     * Called for each item when rendering the dropdown.
     * @param {*} item from items array
     * @param {number} index in items array
     * @return {!string} Formatted & escaped HTML
     */
    DropdownButton.prototype.itemRenderer = function (item, index) {
        return _.escape(String(item));
    };

    /** Converts the list of item objects into HTML list items in format required by DropdownEventHandler */
    DropdownButton.prototype._renderList = function () {
        var html = "";
        this.items.forEach(function (item, i) {
            if (item === "---") {
                html += "

";
            } else {
                html += "
";
                html += this.itemRenderer(item, i);
                html += "
";
            }
        }.bind(this));
        return html;
    };

    /**
     * Refresh the dropdown list by removing and re-creating all list items.
     * Call this after deleting/adding any item in the dropdown list.
     */
    DropdownButton.prototype.refresh = function () {
        if (!this.$dropdown) {
            return;
        }

        // Remove all list items and then re-create them from this.items.
        $("li", this.$dropdown).remove();
        this.$dropdown.append(this._renderList());

        // Also trigger openDropdown handler so that custom event handlers can be
        // set up for any custom UI in the list.
        $(this).triggerHandler("openDropdown", [this.$dropdown]);
    };

    /**
     * Check/Uncheck the list item of the given index.
     * @param {number} index The index of the list item to be checked or unchecked
     * @param {boolean} checked True if the list item is to be checked, false to get check
     *    mark removed.
     */
    DropdownButton.prototype.setChecked = function (index, checked) {
        if (!this.$dropdown) {
            return;
        }

        var listItems = $("li", this.$dropdown),
            count     = listItems.length;

        if (index > -1 && index < count) {
            $("a", listItems[index]).toggleClass("checked", checked);
        }
    };

    /** Pops open the dropdown if currently closed. Does nothing if items.length == 0 */
    DropdownButton.prototype.showDropdown = function () {
        // Act like a plain old button if no items to show
        if (!this.items.length) {
            return;
        }

        if (this.$dropdown) {
            return;
        }

        Menus.closeAll();

        var $dropdown = $("
")
            .addClass(this.dropdownExtraClasses)  // (no-op if unspecified)
            .append(this._renderList())
            .appendTo($("body"))
            .data("attached-to", this.$button[0]);  // keep ModalBar open while dropdown focused

        // Calculate position of dropdown
        var toggleOffset   = this.$button.offset(),
            posLeft        = toggleOffset.left,
            posTop         = toggleOffset.top + this.$button.outerHeight(),
            elementRect = {
                top:    posTop,
                left:   posLeft,
                height: $dropdown.height(),
                width:  $dropdown.width()
            },
            clip = ViewUtils.getElementClipSize($(window), elementRect);

        if (clip.bottom > 0) {
            // Bottom is clipped, so move entire menu above button
            posTop = Math.max(0, toggleOffset.top - $dropdown.height() - 4);
        }

        if (clip.right > 0) {
            // Right is clipped, so adjust left to fit menu in editor
            posLeft = Math.max(0, posLeft - clip.right);
        }

        $dropdown.css({
            left: posLeft,
            top: posTop,
            minWidth: this.$button.outerWidth()
        });

        // Attach event handlers
        this._dropdownEventHandler = new DropdownEventHandler($dropdown, this._onSelect.bind(this), this._onDropdownClose.bind(this));
        this._dropdownEventHandler.open();

        window.document.body.addEventListener("mousedown", this._onClickOutside, true);
        $(PanelManager).on("editorAreaResize", this.closeDropdown);

        // Manage focus
        this._lastFocus = window.document.activeElement;
        $dropdown.focus();

        this.$dropdown = $dropdown;

        $(this).triggerHandler("openDropdown", [$dropdown]);
    };

    /**
     * @private
     * Clean up event handlers after dropdown closed & dispose old dropdown DOM. Called regardless of how the dropdown
     * was closed.
     */
    DropdownButton.prototype._onDropdownClose = function () {
        window.document.body.removeEventListener("mousedown", this._onClickOutside, true);
        $(PanelManager).off("editorAreaResize", this.closeDropdown);

        // Restore focus to old pos, unless "select" handler changed it
        if (window.document.activeElement === this.$dropdown[0]) {
            this._lastFocus.focus();
        }

        this._dropdownEventHandler = null;
        this.$dropdown = null;  // already remvoed from DOM automatically by PopUpManager
    };

    /** Closes the dropdown if currently open */
    DropdownButton.prototype.closeDropdown = function () {
        if (this._dropdownEventHandler) {
            this._dropdownEventHandler.close();
        }
    };

    /** @private Clicking outside the dropdown closes it */
    DropdownButton.prototype._onClickOutside = function (event) {
        var $container = $(event.target).closest(".dropdownbutton-popup");

        // If click is outside dropdown list or dropdown button, then close dropdown list
        if (!$(event.target).is(this.$button) &&
                ($container.length === 0 || $container[0] !== this.$dropdown[0])) {
            this.closeDropdown();
            event.stopPropagation();
            event.preventDefault();
        }
    };

    /** Opens the dropdown if closed; closes it if open */
    DropdownButton.prototype.toggleDropdown = function () {
        if (this.$dropdown) {
            this.closeDropdown();
        } else {
            this.showDropdown();
        }
    };

    /**
     * @private
     * Callback from DropdownEventHandler when item in dropdown list is selected (via mouse or keyboard)
     * @param {!jQueryObject} $link  The `a` element selected
     */
    DropdownButton.prototype._onSelect = function ($link) {
        var itemIndex = Number($link.data("index"));
        $(this).triggerHandler("select", [this.items[itemIndex], itemIndex]);
    };

    exports.DropdownButton = DropdownButton;
});


<!doctype html>

	<meta charset="utf-8">
	<title>jQuery UI Resizable Test Suite</title>

	<link rel="stylesheet" href="../../../external/qunit.css">
	<link rel="stylesheet" href="../qunit-composite.css">

jQuery UI Resizable Test Suite


If you want to write an option parser, and have it be good, there are
two ways to do it.  The Right Way, and the Wrong Way.

The Wrong Way is to sit down and write an option parser.  We've all done
that.

The Right Way is to write some complex configurable program with so many
options that you go half-insane just trying to manage them all, and put
it off with duct-tape solutions until you see exactly to the core of the
problem, and finally snap and write an awesome option parser.

If you want to write an option parser, don't write an option parser.
Write a package manager, or a source control system, or a service
restarter, or an operating system.  You probably won't end up with a
good one of those, but if you don't give up, and you are relentless and
diligent enough in your procrastination, you may just end up with a very
nice option parser.

## USAGE

    // my-program.js
    var nopt = require("nopt")
      , Stream = require("stream").Stream
      , path = require("path")
      , knownOpts = { "foo" : [String, null]
                    , "bar" : [Stream, Number]
                    , "baz" : path
                    , "bloo" : [ "big", "medium", "small" ]
                    , "flag" : Boolean
                    , "pick" : Boolean
                    , "many" : [String, Array]
                    }
      , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
                     , "b7" : ["--bar", "7"]
                     , "m" : ["--bloo", "medium"]
                     , "p" : ["--pick"]
                     , "f" : ["--flag"]
                     }
                 // everything is optional.
                 // knownOpts and shorthands default to {}
                 // arg list defaults to process.argv
                 // slice defaults to 2
      , parsed = nopt(knownOpts, shortHands, process.argv, 2)
    console.log(parsed)

This would give you support for any of the following:

```bash
$ node my-program.js --foo "blerp" --no-flag
{ "foo" : "blerp", "flag" : false }

$ node my-program.js ---bar 7 --foo "Mr. Hand" --flag
{ bar: 7, foo: "Mr. Hand", flag: true }

$ node my-program.js --foo "blerp" -f -----p
{ foo: "blerp", flag: true, pick: true }

$ node my-program.js -fp --foofoo
{ foo: "Mr. Foo", flag: true, pick: true }

$ node my-program.js --foofoo -- -fp  # -- stops the flag parsing.
{ foo: "Mr. Foo", argv: { remain: ["-fp"] } }

$ node my-program.js --blatzk 1000 -fp # unknown opts are ok.
{ blatzk: 1000, flag: true, pick: true }

$ node my-program.js --blatzk true -fp # but they need a value
{ blatzk: true, flag: true, pick: true }

$ node my-program.js --no-blatzk -fp # unless they start with "no-"
{ blatzk: false, flag: true, pick: true }

$ node my-program.js --baz b/a/z # known paths are resolved.
{ baz: "/Users/isaacs/b/a/z" }

# if Array is one of the types, then it can take many
# values, and will always be an array.  The other types provided
# specify what types are allowed in the list.

$ node my-program.js --many 1 --many null --many foo
{ many: ["1", "null", "foo"] }

$ node my-program.js --many foo
{ many: ["foo"] }
```

Read the tests at the bottom of `lib/nopt.js` for more examples of
what this puppy can do.

## Types

The following types are supported, and defined on `nopt.typeDefs`

* String: A normal string.  No parsing is done.
* path: A file system path.  Gets resolved against cwd if not absolute.
* url: A url.  If it doesn't parse, it isn't accepted.
* Number: Must be numeric.
* Date: Must parse as a date. If it does, and `Date` is one of the options,
  then it will return a Date object, not a string.
* Boolean: Must be either `true` or `false`.  If an option is a boolean,
  then it does not need a value, and its presence will imply `true` as
  the value.  To negate boolean flags, do `--no-whatever` or `--whatever
  false`
* NaN: Means that the option is strictly not allowed.  Any value will
  fail.
* Stream: An object matching the "Stream" class in node.  Valuable
  for use when validating programmatically.  (npm uses this to let you
  supply any WriteStream on the `outfd` and `logfd` config options.)
* Array: If `Array` is specified as one of the types, then the value
  will be parsed as a list of options.  This means that multiple values
  can be specified, and that the value will always be an array.

If a type is an array of values not on this list, then those are
considered valid values.  For instance, in the example above, the
`--bloo` option can only be one of `"big"`, `"medium"`, or `"small"`,
and any other value will be rejected.

When parsing unknown fields, `"true"`, `"false"`, and `"null"` will be
interpreted as their JavaScript equivalents, and numeric values will be
interpreted as a number.

You can also mix types and values, or multiple types, in a list.  For
instance `{ blah: [Number, null] }` would allow a value to be set to
either a Number or null.

To define a new type, add it to `nopt.typeDefs`.  Each item in that
hash is an object with a `type` member and a `validate` method.  The
`type` member is an object that matches what goes in the type list.  The
`validate` method is a function that gets called with `validate(data,
key, val)`.  Validate methods should assign `data[key]` to the valid
value of `val` if it can be handled properly, or return boolean
`false` if it cannot.

You can also call `nopt.clean(data, types, typeDefs)` to clean up a
config object and remove its invalid properties.

## Error Handling

By default, nopt outputs a warning to standard error when invalid
options are found.  You can change this behavior by assigning a method
to `nopt.invalidHandler`.  This method will be called with
the offending `nopt.invalidHandler(key, val, types)`.

If no `nopt.invalidHandler` is assigned, then it will console.error
its whining.  If it is assigned to boolean `false` then the warning is
suppressed.

## Abbreviations

Yes, they are supported.  If you define options like this:

```javascript
{ "foolhardyelephants" : Boolean
, "pileofmonkeys" : Boolean }
```

Then this will work:

```bash
node program.js --foolhar --pil
node program.js --no-f --pileofmon
# etc.
```

## Shorthands

Shorthands are a hash of shorter option names to a snippet of args that
they expand to.

If multiple one-character shorthands are all combined, and the
combination does not unambiguously match any other option or shorthand,
then they will be broken up into their constituent parts.  For example:

```json
{ "s" : ["--loglevel", "silent"]
, "g" : "--global"
, "f" : "--force"
, "p" : "--parseable"
, "l" : "--long"
}
```

```bash
npm ls -sgflp
# just like doing this:
npm ls --loglevel silent --global --force --long --parseable
```

## The Rest of the args

The config object returned by nopt is given a special member called
`argv`, which is an object with the following fields:

* `remain`: The remaining args after all the parsing has occurred.
* `original`: The args as they originally appeared.
* `cooked`: The args after flags and shorthands are expanded.

## Slicing

Node programs are called with more or less the exact argv as it appears
in C land, after the v8 and node-specific options have been plucked off.
As such, `argv[0]` is always `node` and `argv[1]` is always the
JavaScript program being run.

That's usually not very useful to you.  So they're sliced off by
default.  If you want them, then you can pass in `0` as the last
argument, or any other number that you'd like to slice off the start of
the list.


Performance Data

Operation	Time (ms)

                {{#perfData}}

                    {{{testName}}}
                    {{value}}

                {{/perfData}}

            Raw data (copy paste out):
            <textarea rows="1" id="brackets-perf-raw-data" style="margin: 0; width: 50px;">{{delimitedPerfData}}</textarea>

        <button class="dialog-button btn primary" data-button-id="ok">Close</button>


keep keep keep replace replace replace replace keep keep

// Portip: If no options.name or options.title is provided, then we will rely solely on

/**
 * Brackets Themes Copyright (c) 2014 Miguel Castillo.
 *
 * 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, regexp: true, nomen: true, indent: 4, maxerr: 50 */
/*global $, define, require, less */

define(function (require, exports, module) {
    "use strict";

    var _                  = require("thirdparty/lodash"),
        FileSystem         = require("filesystem/FileSystem"),
        FileUtils          = require("file/FileUtils"),
        EditorManager      = require("editor/EditorManager"),
        ExtensionUtils     = require("utils/ExtensionUtils"),
        ThemeSettings      = require("view/ThemeSettings"),
        ThemeView          = require("view/ThemeView"),
        AppInit            = require("utils/AppInit"),
        PreferencesManager = require("preferences/PreferencesManager"),
        prefs              = PreferencesManager.getExtensionPrefs("themes");

    var loadedThemes    = {},
        currentTheme    = null,
        styleNode       = $(ExtensionUtils.addEmbeddedStyleSheet("")),
        defaultTheme    = "thor-light-theme",
        commentRegex    = /\/\*([\s\S]*?)\*\//mg,
        scrollbarsRegex = /((?:[^}|,]*)::-webkit-scrollbar(?:[^{]*)[{](?:[^}]*?)[}])/mgi,
        stylesPath      = FileUtils.getNativeBracketsDirectoryPath() + "/styles/",
        validExtensions = ["css", "less"];

    /**
     * @private
     * Takes all dashes and converts them to white spaces. Then takes all first letters
     * and capitalizes them.
     *
     * @param {string} name is what needs to be procseed to generate a display name
     * @return {string} theme name properly formatted for display
     */
    function toDisplayName(name) {
        var extIndex = name.lastIndexOf('.');
        name = name.substring(0, extIndex !== -1 ? extIndex : undefined).replace(/-/g, ' ');

        return name.split(" ").map(function (part) {
            return part[0].toUpperCase() + part.substring(1);
        }).join(" ");
    }

    /**
     * @constructor
     * Theme contains all the essential bit to load a theme from disk, display a theme in the settings
     * dialog, and to properly add a theme into CodeMirror along with the rest of brackets.
     *
     * @param {File} file for the theme
     * @param {{name: string, title: string}} options to configure different
     *   properties in the theme
     */
    function Theme(file, options) {
        options = options || {};
        var fileName = file.name;

        // The name is used to map the loaded themes to the list in the settings dialog. So we want
        // a unique name if one is not provided.  This is particularly important when loading just
        // files where there is no other way to feed in meta data to provide unique names.  Say, there
        // is a theme1.css and a theme1.less that are entirely different themes...

        this.file        = file;
        this.name        = options.name  || (options.title || fileName).toLocaleLowerCase().replace(/[\W]/g, '-');
        this.displayName = options.title || toDisplayName(fileName);
        this.dark        = options.theme !== undefined && options.theme.dark === true;
    }

    /**
     * @private
     * Extracts the scrollbar text from the css/less content so that it can be treated
     * as a separate styling component that can be anabled/disabled independently from
     * the theme.
     *
     * @param {string} content is the css/less input string to be processed
     * @return {{content: string, scrollbar: Array.<string>}} content is the new css/less content
     *   with the scrollbar rules extracted out and put in scrollbar
     */
    function extractScrollbars(content) {
        var scrollbar = [];

        // Go through and extract out scrollbar customizations so that we can
        // enable/disable via settings.
        content = content
            .replace(scrollbarsRegex, function (match) {
                scrollbar.push(match);
                return "";
            });

        return {
            content: content,
            scrollbar: scrollbar
        };
    }

    /**
     * @private
     * Function will process a string and figure out if it looks like window path with a
     * a drive.  If that's the case, then we lower case everything.
     * --- NOTE: There is a bug in less that only checks for lowercase in order to handle
     * the rootPath configuration...  Hopefully a PR will be coming their way soon.
     *
     * @param {string} path is a string to search for drive letters that need to be converted
     *   to lower case.
     *
     * @return {string} Windows Drive letter in lowercase.
     */
    function fixPath(path) {
        return path.replace(/^([A-Z]+:)?\//, function (match) {
            return match.toLocaleLowerCase();
        });
    }

    /**
     * @private
     * Takes the content of a file and feeds it through the less processor in order
     * to provide support for less files.
     *
     * @param {string} content is the css/less string to be processed
     * @param {Theme} theme is the object the css/less corresponds to
     * @return {$.Promise} promsie with the processed css/less as the resolved value
     */
    function lessifyTheme(content, theme) {
        var deferred = new $.Deferred();
        var parser   = new less.Parser({
            rootpath: fixPath(stylesPath),
            filename: fixPath(theme.file._path)
        });

        parser.parse("#editor-holder {" + content + "\n}", function (err, tree) {
            if (err) {
                deferred.reject(err);
            } else {
                deferred.resolve(tree.toCSS());
            }
        });

        return deferred.promise();
    }

    /**
     * @private
     * Verifies that the file passed in is a valid theme file type.
     *
     * @param {File} file is object to verify if it is a valid theme file type
     * @return {boolean} to confirm if the file is a valid theme file type
     */
    function isFileTypeValid(file) {
        return file.isFile &&
            validExtensions.indexOf(FileUtils.getFileExtension(file.name)) !== -1;
    }

    /**
     * @private
     * Will search all loaded themes for one the matches the file passed in
     *
     * @param {File} file is the search criteria
     * @return {Theme} theme that matches the file
     */
    function getThemeByFile(file) {
        var path = file._path;
        return _.find(loadedThemes, function (item) {
            return item.file._path === path;
        });
    }

    /**
     * Get current theme object that is loaded in the editor.
     *
     * @return {Theme} the current theme instance
     */
    function getCurrentTheme() {
        if (!currentTheme) {
            currentTheme = loadedThemes[prefs.get("theme")] || loadedThemes[defaultTheme];
        }

        return currentTheme;
    }

    /**
     * Gets all available themes
     * @return {Array.<Theme>} collection of all available themes
     */
    function getAllThemes() {
        return _.map(loadedThemes, function (theme) {
            return theme;
        });
    }

    /**
     * @private
     * Process and load the current theme into the editor
     *
     * @return {$.Promise} promise object resolved with the theme object and all
     *    corresponding new css/less and scrollbar information
     */
    function loadCurrentTheme() {
        var theme = getCurrentTheme();

        var pending = theme && FileUtils.readAsText(theme.file)
            .then(function (lessContent) {
                return lessifyTheme(lessContent.replace(commentRegex, ""), theme);
            })
            .then(function (content) {
                var result = extractScrollbars(content);
                theme.scrollbar = result.scrollbar;
                return result.content;
            })
            .then(function (cssContent) {
                $("body").toggleClass("dark", theme.dark);
                styleNode.text(cssContent);
                return theme;
            });

        return $.when(pending);
    }

    /**
     * Refresh current theme in the editor
     *
     * @param {boolean} force Forces a reload the current theme.  It reload the theme file.
     */
    function refresh(force) {
        if (force) {
            currentTheme = null;
        }

        $.when(force && loadCurrentTheme()).done(function () {
            var editor = EditorManager.getActiveEditor();
            if (!editor || !editor._codeMirror) {
                return;
            }

            var cm = editor._codeMirror;
            ThemeView.updateThemes(cm);
        });
    }

    /**
     * Loads a theme from a file.
     *
     * @param {string} fileName is the full path to the file to be opened
     * @param {Object} options is an optional parameter to specify metadata
     *    for the theme.
     * @return {$.Promise} promise object resolved with the theme to be loaded from fileName
     */
    function loadFile(fileName, options) {
        var deferred         = new $.Deferred(),
            file             = FileSystem.getFileForPath(fileName),
            currentThemeName = prefs.get("theme");

        file.exists(function (err, exists) {
            var theme;

            if (exists) {
                theme = new Theme(file, options);
                loadedThemes[theme.name] = theme;
                ThemeSettings._setThemes(loadedThemes);

                // For themes that are loaded after ThemeManager has been loaded,
                // we should check if it's the current theme.  If it is, then we just
                // load it.
                if (currentThemeName === theme.name) {
                    refresh(true);
                }

                deferred.resolve(theme);
            } else if (err || !exists) {
                deferred.reject(err);
            }
        });

        return deferred.promise();
    }

    /**
     * Loads a theme from an extension package.
     *
     * @param {Object} themePackage is a package from the extension manager for the theme to be loaded.
     * @return {$.Promise} promise object resolved with the theme to be loaded from the pacakge
     */
    function loadPackage(themePackage) {
        var fileName = themePackage.path + "/" + themePackage.metadata.theme.file;
        return loadFile(fileName, themePackage.metadata);
    }

    prefs.on("change", "theme", function () {
        // Make sure we don't reprocess a theme that's already loaded
        if (currentTheme && currentTheme.name === prefs.get("theme")) {
            return;
        }

        // Refresh editor with the new theme
        refresh(true);

        // Process the scrollbars for the editor
        ThemeView.updateScrollbars(getCurrentTheme());

        // Expose event for theme changes
        $(exports).trigger("themeChange", getCurrentTheme());
    });

    prefs.on("change", "themeScrollbars", function () {
        refresh();
        ThemeView.updateScrollbars(getCurrentTheme());
    });

    // Monitor file changes.  If the file that has changed is actually the currently loaded
    // theme, then we just reload the theme.  This allows to live edit the theme
    FileSystem.on("change", function (evt, file) {
        if (!file || file.isDirectory) {
            return;
        }

        if (getThemeByFile(file)) {
            refresh(true);
        }
    });

    $(EditorManager).on("activeEditorChange", function () {
        refresh();
    });

    exports.refresh         = refresh;
    exports.loadFile        = loadFile;
    exports.loadPackage     = loadPackage;
    exports.getCurrentTheme = getCurrentTheme;
    exports.getAllThemes    = getAllThemes;

    // Exposed for testing purposes
    exports._toDisplayName     = toDisplayName;
    exports._extractScrollbars = extractScrollbars;
});


/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

define(function (require, exports, module) {

    "use strict";

    // Code that needs to display user strings should call require("strings") to load
    // src/strings.js. This file will dynamically load strings.js for the specified brackets.locale.
    //
    // See the README.md file in this folder for information on how to add a new translation for
    // another language or locale.
    //
    // TODO: dynamically populate the local prefix list below?
    module.exports = {
        root: true,
        "cs": true,
        "da": true,
        "de": true,
        "el": true,
        "en-gb": true,
        "es": true,
        "fa-ir": true,
        "fi": true,
        "fr": true,
        "gl": true,
        "hr": true,
        "hu": true,
        "id": true,
        "it": true,
        "ja": true,
        "ko": true,
        "nb": true,
        "nl": true,
        "pl": true,
        "pt-br": true,
        "pt-pt": true,
        "ro": true,
        "ru": true,
        "sk": true,
        "sr": true,
        "sv": true,
        "tr": true,
        "zh-cn": true,
        "zh-tw": true
    };
});


{{Strings.FILE_FILTER_DIALOG}}

            {{{instruction}}}
            <textarea class="exclusions-editor"></textarea>
            <input type="text" class="exclusions-name" placeholder="{{Strings.FILTER_NAME_PLACEHOLDER}}">

{{Strings.FILTER_COUNTING_FILES}}

        <button class="dialog-button btn" data-button-id="cancel">{{Strings.CANCEL}}</button>
        <button class="dialog-button btn primary" data-button-id="ok">{{Strings.OK}}</button>


/*
 * button_tickets.js
 */
(function( $ ) {

module( "button: tickets" );

test( "#5946 - buttonset should ignore buttons that are not :visible", function() {
	$( "#radio01" ).next().andSelf().hide();
	var set = $( "#radio0" ).buttonset({ items: "input[type=radio]:visible" });
	ok( set.find( "label:eq(0)" ).is( ":not(.ui-button):not(.ui-corner-left)" ) );
	ok( set.find( "label:eq(1)" ).is( ".ui-button.ui-corner-left" ) );
});

test( "#6262 - buttonset not applying ui-corner to invisible elements", function() {
	$( "#radio0" ).hide();
	var set = $( "#radio0" ).buttonset();
	ok( set.find( "label:eq(0)" ).is( ".ui-button.ui-corner-left" ) );
	ok( set.find( "label:eq(1)" ).is( ".ui-button" ) );
	ok( set.find( "label:eq(2)" ).is( ".ui-button.ui-corner-right" ) );
});

test( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard Navigation", function() {
	var check = $( "#check" ).button(),
		label = $( "label[for='check']" );
	ok( !label.is( ".ui-state-focus" ) );
	check.focus();
	ok( label.is( ".ui-state-focus" ) );
});

test( "#7092 - button creation that requires a matching label does not find label in all cases", function() {
	var group = $( "<input type='checkbox' id='t7092a'>" );
	group.find( "input[type=checkbox]" ).button();
	ok( group.find( "label" ).is( ".ui-button" ) );

	group = $( "<input type='checkbox' id='t7092b'>" );
	group.filter( "input[type=checkbox]" ).button();
	ok( group.filter( "label" ).is( ".ui-button" ) );

	group = $( "<input type='checkbox' id='t7092c'>" );
	group.find( "input[type=checkbox]" ).button();
	ok( group.filter( "label" ).is( ".ui-button" ) );

	group = $( "<input type='checkbox' id='t7092d'>" );
	group.find( "input[type=checkbox]" ).button();
	ok( group.find( "label" ).is( ".ui-button" ) );

	group = $( "<input type='checkbox' id='t7092e'>" );
	group.filter( "input[type=checkbox]" ).button();
	ok( group.find( "label" ).is( ".ui-button" ) );
});

test( "#7534 - Button label selector works for ids with \":\"", function() {
	var group = $( "<input type='checkbox' id='check:7534'>Label" );
	group.find( "input" ).button();
	ok( group.find( "label" ).is( ".ui-button" ), "Found an id with a :" );
});

})( jQuery );


this.name        = options.name  || (options.title || fileName).toLocaleLowerCase().replace(/[\W]/g, '-');

this.displayName = options.title || toDisplayName(fileName);

this.dark        = options.theme !== undefined && options.theme.dark === true;

keep keep replace keep keep keep keep keep

this.name        = options.name  || (options.title || fileName.replace(/.[\w]+$/gi, '')).toLocaleLowerCase().replace(/[\W]/g, '-');

/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, beforeEach, it, runs, expect, waitsForDone, beforeFirst, afterLast */

define(function (require, exports, module) {
    "use strict";

    var ThemeManager     = require("view/ThemeManager"),
        FileSystem       = require("filesystem/FileSystem"),
        FileUtils        = require("file/FileUtils"),
        SpecRunnerUtils  = require("spec/SpecRunnerUtils");

    var testFilePath = SpecRunnerUtils.getTestPath("/spec/Theme-test-files");

    function superTrim(text) {
        return text.replace(/\s/g, '');
    }

    describe("ThemeManager", function () {

        describe("toDisplayName", function () {
            it("should format a name with no extension", function () {
                expect(ThemeManager._toDisplayName("this file")).toEqual("This File");
            });

            it("should format a short filename", function () {
                expect(ThemeManager._toDisplayName("this file.css")).toEqual("This File");
            });

            it("should format a longer filename", function () {
                expect(ThemeManager._toDisplayName("this is a simple file.css")).toEqual("This Is A Simple File");
            });

            it("should handle a name with dashes", function () {
                expect(ThemeManager._toDisplayName("this-is a simple-file.css")).toEqual("This Is A Simple File");
            });
        });

        describe("Extract Scrollbar", function () {
            it("should extract scrollbars from a theme with other css", function () {
                var themeFile = FileSystem.getFileForPath(testFilePath + "/scrollbars.css");
                var promise = FileUtils.readAsText(themeFile).done(function (content) {
                    var themeScrollbars = ThemeManager._extractScrollbars(content);
                    expect(themeScrollbars.scrollbar.length).toEqual(4);
                    expect(superTrim(themeScrollbars.content)).toEqual("span{}");
                });

                waitsForDone(promise, "theme with scrollbar and other css", 5000);
            });

            it("should extract scrollbars from a theme with only scrollbars", function () {
                var themeFile = FileSystem.getFileForPath(testFilePath + "/simple-scrollbars.css");
                var promise = FileUtils.readAsText(themeFile).done(function (content) {
                    var themeScrollbars = ThemeManager._extractScrollbars(content);
                    expect(themeScrollbars.scrollbar.length).toEqual(3);
                    expect(superTrim(themeScrollbars.scrollbar.join(""))).toEqual("::-webkit-scrollbar{width:12px;}::-webkit-scrollbar-thumb:window-inactive{background:white;}::-webkit-scrollbar-thumb{background:white;}");
                    expect(superTrim(themeScrollbars.content)).toEqual("");
                });

                waitsForDone(promise, "theme with only scrollbars", 5000);
            });

            it("should be fine with an empty theme", function () {
                var themeFile = FileSystem.getFileForPath(testFilePath + "/empty.css");
                var promise = FileUtils.readAsText(themeFile).done(function (content) {
                    var themeScrollbars = ThemeManager._extractScrollbars(content);
                    expect(themeScrollbars.scrollbar.length).toEqual(0);
                    expect(superTrim(themeScrollbars.content)).toEqual("");
                });

                waitsForDone(promise, "empty theme", 5000);
            });
        });

        describe("Load themes", function () {
            it("should load a theme from a single CSS file", function () {
                var promise = ThemeManager.loadFile(testFilePath + "/scrollbars.css").done(function (theme) {
                    expect(theme.name).toEqual("scrollbars-css");
                    expect(theme.displayName).toEqual("Scrollbars");
                });

                waitsForDone(promise, "theme file", 5000);
            });
        });
    });

});


.hex-rule {
    background: #abcdef;
}

.hex-three-rule {
    background: #abc;
}

.rgb-rule {
    background: rgb(100, 200, 150);
}

.rgba-rule {
    background: rgba(100, 200, 150, 0.5);
}

.hsl-rule {
    background: hsl(180, 50%, 50%);
}

.hsla-rule {
    background: hsla(180, 50%, 50%, 0.5);
}

.invalid-color {
    background: rgb(150;
}

.multiple-colors {
    background: linear-gradient(90deg, #aabbcc, #ddeeff);
}

.uppercase-hex {
    background: #DEFCBA;
}

.missing-percent {
    background: hsla(180, 50, 50, 0.5);
}

.in-shorthand {
    border: 1px solid #0f0f0f;
}

.rgba-leading-period {
    background: rgba(100, 200, 150, .5);
}

.hsla-leading-period {
    background: hsla(180, 50%, 50%, .5);
}


/* Tests borrowed from substack's node-mkdirp
 * https://github.com/substack/node-mkdirp */

var mkpath = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;

test('implicit mode from umask', function (t) {
    t.plan(2);
    var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
    var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
    var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);

    var file = '/tmp/' + [x,y,z].join('/');

    mkpath(file, function (err) {
        if (err) t.fail(err);
        else path.exists(file, function (ex) {
            if (!ex) t.fail('file not created')
            else fs.stat(file, function (err, stat) {
                if (err) t.fail(err)
                else {
                    t.equal(stat.mode & 0777, 0777 & (~process.umask()));
                    t.ok(stat.isDirectory(), 'target not a directory');
                    t.end();
                }
            })
        })
    });
});


#!/usr/bin/env node

//process.env.DEBUG_NOPT = 1

// my-program.js
var nopt = require("../lib/nopt")
  , Stream = require("stream").Stream
  , path = require("path")
  , knownOpts = { "foo" : [String, null]
                , "bar" : [Stream, Number]
                , "baz" : path
                , "bloo" : [ "big", "medium", "small" ]
                , "flag" : Boolean
                , "pick" : Boolean
                }
  , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
                 , "b7" : ["--bar", "7"]
                 , "m" : ["--bloo", "medium"]
                 , "p" : ["--pick"]
                 , "f" : ["--flag", "true"]
                 , "g" : ["--flag"]
                 , "s" : "--flag"
                 }
             // everything is optional.
             // knownOpts and shorthands default to {}
             // arg list defaults to process.argv
             // slice defaults to 2
  , parsed = nopt(knownOpts, shortHands, process.argv, 2)

console.log("parsed =\n"+ require("util").inspect(parsed))


waitsForDone(promise, "theme with scrollbar and other css", 5000);

it("should extract scrollbars from a theme with only scrollbars", function () {

var themeFile = FileSystem.getFileForPath(testFilePath + "/simple-scrollbars.css");

var promise = FileUtils.readAsText(themeFile).done(function (content) {

keep keep keep keep keep replace keep keep keep


span {
}

::-webkit-scrollbar {
    width: 12px;
}

::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
    -webkit-border-radius: 10px;
}

::-webkit-scrollbar-thumb {
    -webkit-border-radius: 10px;
    border-radius: 10px;
    background: grey;
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}

::-webkit-scrollbar-thumb:window-inactive {
    background: white;
}


/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 */

/*
 * The timing function canvas and editing code was adapted from Lea Verou's cubic-bezier project:
 * - https://github.com/LeaVerou/cubic-bezier (cubic-bezier.com)
 *
 * The canvas exceeds the top and bottom of main grid so y-value of points can be
 * dragged outside of the 0-1 range.
 *
 *   . . . . . .
 *   .         .
 *   +---------+
 *   |         |
 *   |         |
 *   |         |
 *   |         |
 *   +---------+ <-- main grid has height of 150
 *   .         .
 *   . . . . . . <-- canvas has height of 300 (extra 75 above/below)
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true,  regexp: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window, Mustache */

define(function (require, exports, module) {
    "use strict";

    // Brackets modules
    var EditorManager       = brackets.getModule("editor/EditorManager"),
        ExtensionUtils      = brackets.getModule("utils/ExtensionUtils"),
        Strings             = brackets.getModule("strings"),

        InlineTimingFunctionEditor = require("InlineTimingFunctionEditor").InlineTimingFunctionEditor,
        TimingFunctionUtils        = require("TimingFunctionUtils"),
        Localized                  = require("text!Localized.css");

    // Functions

    /**
     * Prepare hostEditor for an InlineTimingFunctionEditor at pos if possible.
     * Return editor context if so; otherwise null.
     *
     * @param {Editor} hostEditor
     * @param {{line:Number, ch:Number}} pos
     * @return {timingFunction:{?string}, reason:{?string}, start:{?TextMarker}, end:{?TextMarker}}
     */
    function prepareEditorForProvider(hostEditor, pos) {
        var cursorLine, sel, startPos, endPos, startBookmark, endBookmark, currentMatch,
            cm = hostEditor._codeMirror;

        sel = hostEditor.getSelection();
        if (sel.start.line !== sel.end.line) {
            return {timingFunction: null, reason: null};
        }

        cursorLine = hostEditor.document.getLine(pos.line);

        // code runs several matches complicated patterns, multiple times, so
        // first do a quick, simple check to see make sure we may have a match
        if (!cursorLine.match(/cubic-bezier|linear|ease|step/)) {
            return {timingFunction: null, reason: null};
        }

        currentMatch = TimingFunctionUtils.timingFunctionMatch(cursorLine, false);
        if (!currentMatch) {
            return {timingFunction: null, reason: Strings.ERROR_TIMINGQUICKEDIT_INVALIDSYNTAX};
        }

        // check for subsequent matches, and use first match after pos
        var lineOffset = 0,
            matchLength = ((currentMatch.originalString && currentMatch.originalString.length) || currentMatch[0].length);
        while (pos.ch > (currentMatch.index + matchLength + lineOffset)) {
            var restOfLine = cursorLine.substring(currentMatch.index + matchLength + lineOffset),
                newMatch = TimingFunctionUtils.timingFunctionMatch(restOfLine, false);

            if (newMatch) {
                lineOffset += (currentMatch.index + matchLength);
                currentMatch = $.extend(true, [], newMatch);
            } else {
                break;
            }
        }

        currentMatch.lineOffset = lineOffset;

        startPos = {line: pos.line, ch: lineOffset + currentMatch.index};
        endPos   = {line: pos.line, ch: lineOffset + currentMatch.index + matchLength};

        startBookmark = cm.setBookmark(startPos);
        endBookmark   = cm.setBookmark(endPos);

        // Adjust selection to the match so that the inline editor won't
        // get dismissed while we're updating the timing function.
        hostEditor.setSelection(startPos, endPos);

        return {
            timingFunction: currentMatch,
            start: startBookmark,
            end: endBookmark
        };
    }

    /**
     * Registered as an inline editor provider: creates an InlineTimingFunctionEditor
     * when the cursor is on a timing function value.
     *
     * @param {!Editor} hostEditor
     * @param {!{line:Number, ch:Number}} pos
     * @return {?$.Promise} synchronously resolved with an InlineWidget, or
     *         {string} if timing function with invalid syntax is detected at pos, or
     *         null if there's no timing function at pos.
     */
    function inlineTimingFunctionEditorProvider(hostEditor, pos) {
        var context = prepareEditorForProvider(hostEditor, pos),
            inlineTimingFunctionEditor,
            result;

        if (!context.timingFunction) {
            return context.reason || null;
        } else {
            inlineTimingFunctionEditor = new InlineTimingFunctionEditor(context.timingFunction, context.start, context.end);
            inlineTimingFunctionEditor.load(hostEditor);

            result = new $.Deferred();
            result.resolve(inlineTimingFunctionEditor);
            return result.promise();
        }
    }

    /**
     * Initialization code
     */
    function init() {
        // Load our stylesheet
        ExtensionUtils.loadStyleSheet(module, "main.less");
        ExtensionUtils.addEmbeddedStyleSheet(Mustache.render(Localized, Strings));

        EditorManager.registerInlineEditProvider(inlineTimingFunctionEditorProvider);
    }

    init();

    // for unit tests only
    exports.inlineTimingFunctionEditorProvider = inlineTimingFunctionEditorProvider;
});


waitsForDone(promise, "theme with only scrollbars", 5000);

it("should be fine with an empty theme", function () {

var themeFile = FileSystem.getFileForPath(testFilePath + "/empty.css");


<!DOCTYPE html>

    <meta charset='utf-8'>
    <title>listing directory {directory}</title>

    <input id="search" type="text" placeholder="Search" autocomplete="off" />

{linked-path}

      {files}


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Datepicker - Localize calendar</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

Date: <input type="text" id="datepicker"/>
	<select id="locale">
		<option value="af">Afrikaans</option>
		<option value="sq">Albanian (Gjuha shqipe)</option>
		<option value="ar-DZ">Algerian Arabic</option>
		<option value="ar">Arabic ((لعربي</option>
		<option value="hy">Armenian (Հայերեն)</option>
		<option value="az">Azerbaijani (Azərbaycan dili)</option>
		<option value="eu">Basque (Euskara)</option>
		<option value="bs">Bosnian (Bosanski)</option>
		<option value="bg">Bulgarian (български език)</option>
		<option value="ca">Catalan (Català)</option>
		<option value="zh-HK">Chinese Hong Kong (繁體中文)</option>
		<option value="zh-CN">Chinese Simplified (简体中文)</option>
		<option value="zh-TW">Chinese Traditional (繁體中文)</option>
		<option value="hr">Croatian (Hrvatski jezik)</option>
		<option value="cs">Czech (čeština)</option>
		<option value="da">Danish (Dansk)</option>
		<option value="nl-BE">Dutch (Belgium)</option>
		<option value="nl">Dutch (Nederlands)</option>
		<option value="en-AU">English/Australia</option>
		<option value="en-NZ">English/New Zealand</option>
		<option value="en-GB">English/UK</option>
		<option value="eo">Esperanto</option>
		<option value="et">Estonian (eesti keel)</option>
		<option value="fo">Faroese (føroyskt)</option>
		<option value="fa">Farsi/Persian ((فارسی</option>
		<option value="fi">Finnish (suomi)</option>
		<option value="fr" selected="selected">French (Français)</option>
		<option value="fr-CH">French/Swiss (Français de Suisse)</option>
		<option value="gl">Galician</option>
		<option value="ge">Georgian</option>
		<option value="de">German (Deutsch)</option>
		<option value="el">Greek (Ελληνικά)</option>
		<option value="he">Hebrew ((עברית</option>
		<option value="hi">Hindi (हिंदी)</option>
		<option value="hu">Hungarian (Magyar)</option>
		<option value="is">Icelandic (Õslenska)</option>
		<option value="id">Indonesian (Bahasa Indonesia)</option>
		<option value="it">Italian (Italiano)</option>
		<option value="ja">Japanese (日本語)</option>
		<option value="kk">Kazakhstan (Kazakh)</option>
		<option value="km">Khmer</option>
		<option value="ko">Korean (한국어)</option>
		<option value="lv">Latvian (Latvieöu Valoda)</option>
		<option value="lt">Lithuanian (lietuviu kalba)</option>
		<option value="lb">Luxembourgish</option>
		<option value="mk">Macedonian</option>
		<option value="ml">Malayalam</option>
		<option value="ms">Malaysian (Bahasa Malaysia)</option>
		<option value="no">Norwegian (Norsk)</option>
		<option value="pl">Polish (Polski)</option>
		<option value="pt">Portuguese (Português)</option>
		<option value="pt-BR">Portuguese/Brazilian (Português)</option>
		<option value="rm">Rhaeto-Romanic (Romansh)</option>
		<option value="ro">Romanian (Română)</option>
		<option value="ru">Russian (Русский)</option>
		<option value="sr">Serbian (српски језик)</option>
		<option value="sr-SR">Serbian (srpski jezik)</option>
		<option value="sk">Slovak (Slovencina)</option>
		<option value="sl">Slovenian (Slovenski Jezik)</option>
		<option value="es">Spanish (Español)</option>
		<option value="sv">Swedish (Svenska)</option>
		<option value="ta">Tamil (தமிழ்)</option>
		<option value="th">Thai (ภาษาไทย)</option>
		<option value="tj">Tajikistan</option>
		<option value="tr">Turkish (Türkçe)</option>
		<option value="uk">Ukranian (Українська)</option>
		<option value="vi">Vietnamese (Tiếng Việt)</option>
		<option value="cy-GB">Welsh/UK (Cymraeg)</option>
	</select>

Localize the datepicker calendar language and format (English / Western formatting is the default).  The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.


/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global brackets, require */

var A1 = { propA : 1 },
    A2 = { propA : 2 },
    A3 = A2;

function funB(paramB1, paramB2) {
    'use strict';

    var B1 = { propB : 1 },
        B2 = { propB : 2 };

    function funC(paramC1, paramC2) {
        var C1 = { propC : 1 },
            C2 = { propC : 2 };

        B1.propB = 0;
        C1.propC = 0;
        B1.foo = 0;
        console.log("hello\\\" world!");
    }

    var s = "a string";
    var r = s;
    var t = r;

}

/**
 * @param {string} a
 * @param {number} b
 */
function funD(a, b) {
    "use strict";
    return {x: a, y: b};
}

require(["MyModule"], function (myModule) {
    'use strict';
    var x = myModule.a;
});

funB();
var x = A1;

var arr = [];
arr["my-key"] = 1;
arr["for"] = 10;

function MClass() {
    "use strict";
}
MClass.prototype.calc = function (a4, b4) {
    "use strict";
    return a4 + b4;
};

var ins1 = new MClass();
ins1.calc(10, 10);

var Person = function (name) {
    "use strict";
    this.name = name;
};

Person.prototype.getName = function () {
    "use strict";
    return this.name;
};

var Customer = function (name) {
    "use strict";
    this.name = name;
};

Customer.prototype = new Person();

var myCustomer = new Customer('Dream Inc.');
myCustomer.getName();

Customer.prototype.setAmountDue = function (amountDue) {
    "use strict";
    this.amountDue = amountDue;
};
Customer.prototype.getAmountDue = function () {
    "use strict";
    return this.amountDue;
};

function testInnerFunc() {
    "use strict";
    var t = "test";
    function innerFunc(arg) {
        return {t: function () {return arg; }};
    }
    var t2 = innerFunc("test").t().toLocaleLowerCase();

}

/**
 * @param {boolean} a
 * @param {Date} b
 */

function funTypeAn1(a, b) {
    "use strict";
    return {x: a, y: b};
}

/**
 * @param {function(): number} f
 */
function funFuncArg(f) {
    "use strict";
    return f();
}

function testRef1() {
    "use strict";
    return 100;
}

funFuncArg(testRef1); //also test return type

/**
 * @param {function(string,number): string} f
 */
function funFunc2Arg(f) {
    "use strict";
    var s = "test";
    return f(s, 10);
}

function testRef2(s, n) {
    "use strict";
    return s + n;
}

funFunc2Arg(testRef2);

var funArr = [];
funArr.index1 = testRef1;
funArr.index2 = testRef2;

var _A1 = A1;

var s = "", // string type
    help;   // unknown type

function testNonAscii() {
    "use strict";
    var hope;  // unknown type
    hope["frenchçProp"] = "";

}

require(["MyModule"], function (myModule) {
    'use strict';
    var x = myModule.c;
});

/**
 *  Test record type google annoations.
 *
 *  @param {{index: number, name: string}} t
 */
function testRecordTypeAnnotation(t) {
    'use strict';

}

// More parameter hint testing
function functionHintTesting() {
    "use strict";

    // function with record type argument
    testRecordTypeAnnotation();

    // function with a function argument
    arr.sort();

    // function with array argument
    arr.concat();

    s.lastIndexOf(s, 5);

}

/**
 *  Test Array annotation
 *
 *  @param {Array.<string>} a
 */
function testArrayAnnotation(a) {
    "use strict";

}

testArrayAnnotation();

/**
 *  Test multiple optional args
 *
 * @param {number=} a
 * @param {string=} b
 *
 */
function testOptionalArgs(a, b) {
    "use strict";

}

testOptionalArgs();

/* Add large comment to make this test over 250 lines which will trigger
 *  partial updates to be used.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 * end of large comment
 */


it("should load a theme from a single CSS file", function () {

var promise = ThemeManager.loadFile(testFilePath + "/scrollbars.css").done(function (theme) {

waitsForDone(promise, "theme file", 5000);

keep keep keep replace keep keep keep keep keep


/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, beforeEach, afterEach, it, runs, waits, waitsFor, waitsForDone, waitsForFail, expect, $, jasmine  */

define(function (require, exports, module) {
    "use strict";

    var Async = require("utils/Async"),
        PromiseQueue = Async.PromiseQueue;

    describe("Async", function () {

        describe("Chain", function () {

            function zeroArgThatSucceeds() {
                var d = new $.Deferred();
                setTimeout(function () {
                    d.resolve();
                }, 1);
                return d.promise();
            }

            function zeroArgThatFails() {
                var d = new $.Deferred();
                setTimeout(function () {
                    d.reject();
                }, 1);
                return d.promise();
            }

            function oneArgThatSucceeds(x) {
                var d = new $.Deferred();
                setTimeout(function () {
                    d.resolveWith(null, [x]);
                }, 1);
                return d.promise();
            }

            function twoArgThatSucceeds(x, y) {
                var d = new $.Deferred();
                setTimeout(function () {
                    d.resolveWith(null, [x, y]);
                }, 1);
                return d.promise();
            }

            function twoArgThatFails(x, y) {
                var d = new $.Deferred();
                setTimeout(function () {
                    d.rejectWith(null, [x, y]);
                }, 1);
                return d.promise();
            }

            function syncAddTwoArg(x, y) {
                return x + y;
            }

            function syncException() {
                throw new Error("sync error");
            }

            function createArrayComparator(arrayOne) {
                return function (arrayTwo) {
                    var i, l;
                    expect(arrayOne.length).toBe(arrayTwo.length);
                    l = Math.min(arrayOne.length, arrayTwo.length);
                    for (i = 0; i < l; i++) {
                        expect(arrayOne[i]).toBe(arrayTwo[i]);
                    }
                };
            }

            function expectChainHelper(functions, args, shouldSucceed, responseComparator) {
                var done = false;
                var success = false;
                var response = null;
                runs(function () {
                    var result = Async.chain(
                        functions,
                        args
                    );
                    result.done(function () {
                        done = true;
                        success = true;
                        response = arguments;
                    });
                    result.fail(function () {
                        done = true;
                        success = false;
                        response = arguments;
                    });
                });
                waitsFor(function () {
                    return done;
                }, "The chain should complete", 100);
                runs(function () {
                    expect(success).toBe(shouldSucceed);
                    responseComparator(response);
                });
            }

            describe("Zero-argument deferreds", function () {
                it("[zero-arg] work with a null argument array", function () {
                    expectChainHelper(
                        [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatSucceeds],
                        null,
                        true,
                        createArrayComparator([])
                    );
                });

                it("[zero-arg] call error callback when first deferred fails", function () {
                    expectChainHelper(
                        [zeroArgThatFails, zeroArgThatSucceeds, zeroArgThatSucceeds],
                        [],
                        false,
                        createArrayComparator([])
                    );
                });

                it("[zero-arg] call error callback when middle deferred fails", function () {
                    expectChainHelper(
                        [zeroArgThatSucceeds, zeroArgThatFails, zeroArgThatSucceeds],
                        [],
                        false,
                        createArrayComparator([])
                    );
                });

                it("[zero-arg] call error callback when last deferred fails", function () {
                    expectChainHelper(
                        [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatFails],
                        [],
                        false,
                        createArrayComparator([])
                    );
                });

                it("[zero-arg] call success callback when all deferreds succeed", function () {
                    expectChainHelper(
                        [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatSucceeds],
                        [],
                        true,
                        createArrayComparator([])
                    );
                });

                it("[zero-arg] call success callback immediately if there are no deferreds", function () {
                    expectChainHelper(
                        [],
                        [],
                        true,
                        createArrayComparator([])
                    );
                });
            });

            describe("Nonzero-argument deferreds", function () {
                it("[nonzero-arg] call error callback when first deferred fails", function () {
                    expectChainHelper(
                        [twoArgThatFails, twoArgThatSucceeds, twoArgThatSucceeds],
                        [1, 2],
                        false,
                        createArrayComparator([1, 2])
                    );
                });

                it("[nonzero-arg] call error callback when middle deferred fails", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, twoArgThatFails, twoArgThatSucceeds],
                        [1, 2],
                        false,
                        createArrayComparator([1, 2])
                    );
                });

                it("[nonzero-arg] call error callback when last deferred fails", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, twoArgThatSucceeds, twoArgThatFails],
                        [1, 2],
                        false,
                        createArrayComparator([1, 2])
                    );
                });

                it("[nonzero-arg] call success callback when all deferreds succeed", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, twoArgThatSucceeds, twoArgThatSucceeds],
                        [1, 2],
                        true,
                        createArrayComparator([1, 2])
                    );
                });

                it("[nonzero-arg] call success callback immediately if there are no deferreds", function () {
                    expectChainHelper(
                        [],
                        [1, 2],
                        true,
                        createArrayComparator([1, 2])
                    );
                });
            });

            describe("With Timeout", function () {
                function promiseThatSucceeds(duration) {
                    var d = new $.Deferred();
                    setTimeout(function () {
                        d.resolve();
                    }, duration);
                    return d.promise();
                }

                function promiseThatFails(duration) {
                    var d = new $.Deferred();
                    setTimeout(function () {
                        d.reject();
                    }, duration);
                    return d.promise();
                }

                it("should resolve promise before rejected with timeout", function () {
                    var promiseBase, promiseWrapper;

                    runs(function () {
                        promiseBase    = promiseThatSucceeds(5);
                        promiseWrapper = Async.withTimeout(promiseBase, 10);
                        waitsForDone(promiseWrapper, "promise resolves before timeout");
                    });

                    runs(function () {
                        // base promise resolves wrapper promise
                        expect(promiseBase.state()).toBe("resolved");
                        expect(promiseWrapper.state()).toBe("resolved");
                    });
                });

                it("should reject promise before resolved with timeout", function () {
                    var promiseBase, promiseWrapper;

                    runs(function () {
                        promiseBase    = promiseThatFails(5);
                        promiseWrapper = Async.withTimeout(promiseBase, 10, true);
                        waitsForFail(promiseWrapper, "promise rejected before timeout");
                    });

                    runs(function () {
                        // base promise rejects wrapper promise
                        expect(promiseBase.state()).toBe("rejected");
                        expect(promiseWrapper.state()).toBe("rejected");
                    });
                });

                it("should timeout with reject before promise resolves", function () {
                    var promiseBase, promiseWrapper;

                    runs(function () {
                        promiseBase    = promiseThatSucceeds(10);
                        promiseWrapper = Async.withTimeout(promiseBase, 5);
                        waitsForFail(promiseWrapper, "times out before promise resolves");
                    });

                    runs(function () {
                        expect(promiseWrapper.state()).toBe("rejected");
                        waitsForDone(promiseBase, "promise resolves after timeout");
                    });

                    runs(function () {
                        expect(promiseBase.state()).toBe("resolved");
                    });
                });

                it("should timeout with resolve before promise rejected", function () {
                    var promiseBase, promiseWrapper;

                    runs(function () {
                        promiseBase    = promiseThatFails(10);
                        promiseWrapper = Async.withTimeout(promiseBase, 5, true);
                        waitsForDone(promiseWrapper, "times out before promise is rejected");
                    });

                    runs(function () {
                        expect(promiseWrapper.state()).toBe("resolved");
                        waitsForFail(promiseBase, "promise is rejected after timeout");
                    });

                    runs(function () {
                        expect(promiseBase.state()).toBe("rejected");
                    });
                });
            });

            describe("Async/sync mix", function () {
                it("[async/sync] succeed with sync command at beginning", function () {
                    expectChainHelper(
                        [syncAddTwoArg, oneArgThatSucceeds, oneArgThatSucceeds],
                        [1, 2],
                        true,
                        createArrayComparator([3])
                    );
                });

                it("[async/sync] succeed with sync command at middle", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, syncAddTwoArg, oneArgThatSucceeds],
                        [1, 2],
                        true,
                        createArrayComparator([3])
                    );
                });

                it("[async/sync] succeed with sync command at end", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, twoArgThatSucceeds, syncAddTwoArg],
                        [1, 2],
                        true,
                        createArrayComparator([3])
                    );
                });

                it("[async/sync] call error callback if sync command fails", function () {
                    expectChainHelper(
                        [twoArgThatSucceeds, syncException, twoArgThatSucceeds],
                        [1, 2],
                        false,
                        function (response) {
                            expect(response.length).toBe(1);
                            expect(response[0] instanceof Error).toBe(true);
                        }
                    );
                });

                it("[async/sync] two sync commands in order are executed completely synchronously", function () {
                    var promise = null,
                        flag = true;

                    runs(function () {

                        function negate(b) {
                            return !b;
                        }
                        function setFlag(b) {
                            flag = b;
                            return flag;
                        }

                        promise = Async.chain([negate, setFlag], [flag]);
                        promise.done(function (b) {
                            expect(b).toBe(flag);
                        });

                        // note, we WANT to test this synchronously. This is not a bug
                        // in the unit test. A series of synchronous functions should
                        // execute synchronously.
                        expect(flag).toBe(false);
                    });

                    runs(function () {
                        // With (the current version) of jQuery promises, resolution and
                        // resolution handlers will get called synchronously. However, if we
                        // move to a different promise implementation (e.g. Q) then resolution
                        // handlers will get called asynchronously. So, we check completion
                        // of the promise on a separate pass.
                        waitsForDone(promise, "The chain to complete");
                    });
                });

            });

        });

        describe("promisify", function () {
            var testObj = {
                someVal: 5,
                succeeder: function (input, cb) {
                    cb(null, input, this.someVal);
                },
                failer: function (input, cb) {
                    cb("this is an error");
                }
            };

            it("should resolve its returned promise when the errback is called with null err", function () {
                Async.promisify(testObj, "succeeder", "myInput")
                    .then(function (input, someVal) {
                        expect(input).toBe("myInput");
                        expect(someVal).toBe(testObj.someVal);
                    }, function (err) {
                        expect("should not have called fail callback").toBe(false);
                    });
            });

            it("should reject its returned promise when the errback is called with an err", function () {
                Async.promisify(testObj, "failer", "myInput")
                    .then(function (input, someVal) {
                        expect("should not have called success callback").toBe(false);
                    }, function (err) {
                        expect(err).toBe("this is an error");
                    });
            });
        });

        describe("Async PromiseQueue", function () {
            var queue, calledFns;

            beforeEach(function () {
                queue = new PromiseQueue();
                calledFns = {};
            });

            function makeFn(id, resolveNow, rejectNow) {
                var result = new $.Deferred();
                return {
                    fn: function () {
                        calledFns[id] = true;
                        if (rejectNow) {
                            result.reject();
                        } else if (resolveNow) {
                            result.resolve();
                        }
                        return result.promise();
                    },
                    deferred: result
                };
            }

            it("should immediately execute a function when the queue is empty", function () {
                var fnInfo = makeFn("one");

                queue.add(fnInfo.fn);
                expect(calledFns.one).toBe(true);

                fnInfo.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should wait to execute the second added function", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBeUndefined();

                fnInfo1.deferred.resolve();
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should properly handle the case where the first function completes synchronously", function () {
                var fnInfo1 = makeFn("one", true),
                    fnInfo2 = makeFn("two");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should sequentially execute a second and third function if they're both added while the first is executing", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two"),
                    fnInfo3 = makeFn("three");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                queue.add(fnInfo3.fn);
                expect(calledFns.two).toBeUndefined();
                expect(calledFns.three).toBeUndefined();

                fnInfo1.deferred.resolve();
                expect(calledFns.two).toBe(true);
                expect(calledFns.three).toBeUndefined();

                fnInfo2.deferred.resolve();
                expect(calledFns.three).toBe(true);

                fnInfo3.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should sequentially execute a second and third function if the third is added while the second is executing", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two"),
                    fnInfo3 = makeFn("three");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBeUndefined();

                fnInfo1.deferred.resolve();
                expect(calledFns.two).toBe(true);

                queue.add(fnInfo3.fn);
                expect(calledFns.three).toBeUndefined();

                fnInfo2.deferred.resolve();
                expect(calledFns.three).toBe(true);

                fnInfo3.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should execute a second function when added to the empty queue after the first function has completed", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                fnInfo1.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should execute the second function if the first function is rejected", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBeUndefined();

                fnInfo1.deferred.reject();
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should execute the third function after first and second functions are rejected", function () {
                var fnInfo1 = makeFn("one"),
                    fnInfo2 = makeFn("two"),
                    fnInfo3 = makeFn("three");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                queue.add(fnInfo3.fn);
                expect(calledFns.two).toBeUndefined();
                expect(calledFns.three).toBeUndefined();

                fnInfo1.deferred.reject();
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.reject();
                expect(calledFns.three).toBe(true);

                fnInfo3.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should execute the second function after the already-rejected first function is added to the queue", function () {
                var fnInfo1 = makeFn("one", false, true),
                    fnInfo2 = makeFn("two");

                queue.add(fnInfo1.fn);
                expect(calledFns.one).toBe(true);

                queue.add(fnInfo2.fn);
                expect(calledFns.two).toBe(true);

                fnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);
            });

            it("should be able to run two queues simultaneously without clashing", function () {
                var queue2 = new PromiseQueue(),
                    q1FnInfo1 = makeFn("one"),
                    q1FnInfo2 = makeFn("two"),
                    q2FnInfo3 = makeFn("three"),
                    q2FnInfo4 = makeFn("four");

                //queue one
                queue.add(q1FnInfo1.fn);
                queue.add(q1FnInfo2.fn);
                expect(calledFns.one).toBe(true);
                expect(calledFns.two).toBeUndefined();
                //queue one should have one in _queue,
                //queue two should have zero in _queue
                expect(queue._queue.length).toBe(1);
                expect(queue2._queue.length).toBe(0);

                //queue two
                queue2.add(q2FnInfo3.fn);
                queue2.add(q2FnInfo4.fn);
                expect(calledFns.three).toBe(true);
                expect(calledFns.four).toBeUndefined();
                //queue one and two should have one in _queue
                expect(queue._queue.length).toBe(1);
                expect(queue2._queue.length).toBe(1);

                q1FnInfo1.deferred.resolve();
                expect(calledFns.two).toBe(true);
                expect(queue._queue.length).toBe(0);

                q1FnInfo2.deferred.resolve();
                expect(queue._queue.length).toBe(0);
                expect(queue._curPromise).toBe(null);

                q2FnInfo3.deferred.resolve();
                expect(calledFns.three).toBe(true);
                expect(queue2._queue.length).toBe(0);

                q2FnInfo4.deferred.resolve();
                expect(queue2._queue.length).toBe(0);
                expect(queue2._curPromise).toBe(null);
            });
        });
    });
});


# Authors sorted by whether or not they're me.
Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)
Wayne Larsen <wayne@larsen.st> (http://github.com/wvl)
ritch <skawful@gmail.com>
Marcel Laverdet
Yosef Dinerstein <yosefd@microsoft.com>


#!/usr/bin/env node

var ncp = require('../lib/ncp'),
    args = process.argv.slice(2),
    source, dest;

if (args.length < 2) {
  console.error('Usage: ncp [source] [destination] [--filter=filter] [--limit=concurrency limit]');
  process.exit(1);
}

// parse arguments the hard way
function startsWith(str, prefix) {
  return str.substr(0, prefix.length) == prefix;
}

var options = {};
args.forEach(function (arg) {
  if (startsWith(arg, "--limit=")) {
    options.limit = parseInt(arg.split('=', 2)[1], 10);
  }
  if (startsWith(arg, "--filter=")) {
    options.filter = new RegExp(arg.split('=', 2)[1]);
  }
  if (startsWith(arg, "--stoponerr")) {
    options.stopOnErr = true;
  }
});

ncp.ncp(args[0], args[1], options, function (err) {
  if (Array.isArray(err)) {
    console.error('There were errors during the copy.');
    err.forEach(function (err) {
      console.error(err.stack || err.message);
    });
    process.exit(1);
  }
  else if (err) {
    console.error('An error has occurred.');
    console.error(err.stack || err.message);
    process.exit(1);
  }
});


border-top: 1px solid rgba(var(--color_r), var(--color_g), var(--color_b), 0.3);

div#mod_sysinfo {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    height: 60px;
    border-top: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    font-size: 12px;
    font-family: var(--font_main_light);
    letter-spacing: 1px;
}

div#mod_sysinfo::before {
    content: "";
    border-left: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    position: relative;
    left: -1px;
    top: -31px;
    height: 9px;
}

div#mod_sysinfo::after {
    content: "";
    border-right: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    position: relative;
    right: -1px;
    top: -31px;
    height: 9px;
}

div#mod_sysinfo div {
    height: 100%;
    box-sizing: border-box;
    padding: 10px 5px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-around;
}

div#mod_sysinfo h1 {
    margin: 0px;
    opacity: 0.5;
}

div#mod_sysinfo h2 {
    margin: 0px;
}


# eDEX-UI

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/93b816722c4e4af2bdf401b8187b8a2d)](https://www.codacy.com/app/GitSquared/edex-ui?utm_source=github.com&utm_medium=referral&utm_content=GitSquared/edex-ui&utm_campaign=Badge_Grade)  [![Greenkeeper badge](https://badges.greenkeeper.io/GitSquared/edex-ui.svg)](https://greenkeeper.io/)   [![Build Status](https://travis-ci.org/GitSquared/edex-ui.svg?branch=master)](https://travis-ci.org/GitSquared/edex-ui)

[![Pre-release demo](https://github.com/GitSquared/edex-ui/raw/master/media/demo-preview.gif)](https://squared.codebrew.fr/edex-demo.mp4)

_(click to view full-size)_

eDEX-UI is a sci-fi interactive terminal interface heavily inspired from [DEX-UI](https://github.com/seenaburns/dex-ui) and the [TRON Legacy movie effects](https://web.archive.org/web/20170511000410/http://jtnimoy.com/blogs/projects/14881671), made cross-platform and easy to install with [Electron](https://github.com/electron/electron).

I had no ideas for a name so i took DEX-UI and added a "e" for Electron. Deal with it.

## FAQ
#### What OS can this thing run on?
Currently Windows and any linux distro that can run Chromium.
#### Is this a real terminal?
Yes. By default, eDEX runs bash on linux and Powershell on Windows, but you can change that to any command in the settings.json file.
#### Why is there a keyboard?
As DEX-UI's author said, it's there mostly because it looks cool, but in eDEX it's also a fully-capable tactile keyboard.
#### What's the difference between this and the original DEX-UI?
Seenaburns' DEX-UI was created _"as an experiment or an art piece, not distributable software"_.
My goal with eDEX is to create a similar experience, but easier to install, run, and use.
#### Will using this make me insanely badass?
[Yes.](https://78.media.tumblr.com/35d4ef4447e0112f776b629bffd99188/tumblr_mk4gf8zvyC1s567uwo1_500.gif)

## How to run it from source?
on *nix systems:
- clone the repository
- `npm run install-linux`
- `npm start`

on windows:
- start cmd or powershell **as administrator**
- clone the repository
- `npm run install-windows`
- `npm start`


const fs = require("fs");
const path = require("path");
const UglifyJS = require("uglify-js");
const minifier = require("minifier");
JSON.minify = require("node-json-minify");

minifier.on("error", (err) => {
    console.log(err);
    throw err;
});

let writeMinified = (path, data) => {
    fs.writeFile(path, data, (err) => {
        if (err) {
            console.log(path+" -  ❌");
            console.log("");
            console.log("");
            throw err;
        }
        console.log(path+" -  ✓");
    });
};

let recursiveMinify = (dirPath) => {
    try { var files = fs.readdirSync(dirPath); }
    catch(e) { return; }
    if (files.length > 0) {
        for (let i = 0; i < files.length; i++) {
            let filePath = dirPath + '/' + files[i];
            if (fs.statSync(filePath).isFile()) {
                let tst = filePath.split(".").pop();
                switch (tst) {
                    case "js":
                        // writeMinified(filePath, UglifyJS.minify(fs.readFileSync(filePath, {encoding: "utf-8"})).error);
                        // Commented out, broken for some reason
                        break;
                    case "css":
                        minifier.minify(filePath, {output: filePath});
                        console.log(filePath+" -  ✓");
                        break;
                    case "json":
                        writeMinified(filePath, JSON.minify(fs.readFileSync(filePath, {encoding:"utf-8"})));
                        break;
                }
            } else {
                recursiveMinify(filePath);
            }
        }
    }
};

recursiveMinify(path.join(__dirname, "prebuild-src"));


keep keep keep replace keep keep keep keep

border-left: 1px solid rgba(var(--color_r), var(--color_g), var(--color_b), 0.3);

div#mod_cpuinfo {
    border-top: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    font-family: var(--font_main_light);
    letter-spacing: 1px;
    padding: 7px 0px;
    display: flex;
}

div#mod_cpuinfo::before {
    content: "";
    border-left: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    align-self: flex-start;
    position: relative;
    left: -1px;
    top: -12px;
    height: 9px;
}

div#mod_cpuinfo::after {
    content: "";
    border-right: 1px solid rgba(var(--color_r), var(--color_g), 193, 0.3);
    position: relative;
    right: -1px;
    top: -12px;
    height: 9px;
}

div#mod_cpuinfo > div#mod_cpuinfo_innercontainer {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

div#mod_cpuinfo > div > div {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    margin: 3px 0px;
}

div#mod_cpuinfo h1 {
    font-size: 16px;
    margin: 0px;
}

div#mod_cpuinfo em {
    font-family: var(--font_main);
    font-style: normal;
}

div#mod_cpuinfo span {
    width: 1em;
    position: relative;
    top: 4px;
    right: 3px;
    text-align: center;
    overflow: hidden;
    display: inline-block;
}

div#mod_cpuinfo i {
    font-style: normal;
    font-size: 14px;
    opacity: 0.5;
}

div#mod_cpuinfo canvas {
    width: 76%;
    height: 45px;
    border-top: 1px dashed rgba(var(--color_r), var(--color_g), 193, 0.3);
    border-bottom: 1px dashed rgba(var(--color_r), var(--color_g), 193, 0.3);
    margin: 5px 0px;
}