// shut down, since our Document is now dead

/** Triggered by the HighlightAgent to highlight a node in the editor */

CSSDocument.prototype.onHighlight = function onHighlight(node) {

keep keep keep replace keep keep keep keep

/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $, FileError, brackets */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chrome) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * -1: Error
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    'use strict';

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp");
    var Dialogs = require("widgets/Dialogs");
    var Strings = require("strings");

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent")
        /* FUTURE
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
        */
    };

    var _liveDocument; // the live HTML document
    var _relatedDocuments; // CSS and JS documents that are used by the live HTML document

    /** Augments the given Brackets document with information that's useful for live development. */
    function _setDocInfo(doc) {
        // FUTURE: some of these things should just be moved into core Document; others should
        // be in a LiveDevelopment-specific object attached to the doc.
        var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
        if (matches) {
            var prefix = "file://";

            // The file.fullPath on Windows starts with a drive letter ("C:").
            // In order to make it a valid file: URL we need to add an
            // additional slash to the prefix.
            if (brackets.platform === "win") {
                prefix += "/";
            }

            doc.extension = matches[3];
            doc.url = encodeURI(prefix + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI(prefix + matches[1] + fileName)};
        }
    }

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            _setDocInfo(doc);
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
        if (_relatedDocuments) {
            _relatedDocuments.forEach(function (liveDoc) {
                liveDoc.close();
            });
            _relatedDocuments = undefined;
        }
    }

    /**
     * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the
     * given file is no longer associated with the HTML document that is live (e.g.
     * if the related file has been deleted on disk).
     */
    function removeRelatedDocument(liveDoc) {
        var index = _relatedDocuments.indexOf(liveDoc);
        if (index !== -1) {
            _relatedDocuments.splice(index, 1);
        }
    }

    /** Create a live version of a Brackets document */
    function _createDocument(doc, editor) {
        var DocClass = _classForDocument(doc);
        if (DocClass) {
            return new DocClass(doc, editor);
        } else {
            return null;
        }
    }

    /** Convert a file: URL to a local full file path */
    function _urlToPath(url) {
        var path;
        if (url.indexOf("file://") === 0) {
            path = url.slice(7);
            if (path && brackets.platform === "win" && path.charAt(0) === "/") {
                path = path.slice(1);
            }
        }
        return path;
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        _liveDocument = _createDocument(doc, editor);

        // Gather related CSS documents.
        // FUTURE: Gather related JS documents as well.
        _relatedDocuments = [];
        agents.css.getStylesheetURLs().forEach(function (url) {
            // FUTURE: when we get truly async file handling, we might need to prevent other
            // stuff from happening while we wait to add these listeners
            DocumentManager.getDocumentForPath(_urlToPath(url))
                .done(function (doc) {
                    _setDocInfo(doc);
                    var liveDoc = _createDocument(doc);
                    if (liveDoc) {
                        _relatedDocuments.push(liveDoc);
                    }
                });
        });
    }

    /** Unload the agents */
    function unloadAgents() {
        var i;
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        }
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in agents) {
            if (agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
            }
        }
        return promises;
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        console.error(error.message);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        var retryCount = 0;

        if (doc && doc.root) {
            // For Sprint 6, we only open live development connections for HTML files
            // FUTURE: Remove this test when we support opening connections for different
            // file types.
            if (doc.extension.indexOf('htm') !== 0) {
                return;
            }

            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (retryCount > 4) {
                    _setStatus(-1);
                    Dialogs.showModalDialog(
                        Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
                        Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                        Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
                    ).done(function (id) {
                        if (id === Dialogs.DIALOG_BTN_OK) {
                            // User has chosen to reload Chrome, quit the running instance
                            _setStatus(0);
                            NativeApp.closeLiveBrowser()
                                .done(function () {
                                    browserStarted = false;
                                    setTimeout(open);
                                })
                                .fail(function (err) {
                                    // Report error?
                                    _setStatus(-1);
                                    browserStarted = false;
                                });
                        }
                    });
                    return;
                }
                retryCount++;

                if (!browserStarted && exports.status !== -1) {
                    NativeApp.openLiveBrowser(
                        doc.root.url
                    )
                        .done(function () {
                            browserStarted = true;
                        })
                        .fail(function (err) {
                            var message;

                            _setStatus(-1);
                            if (err === FileError.NOT_FOUND_ERR) {
                                message = Strings.ERROR_CANT_FIND_CHROME;
                            } else {
                                message = Strings.format(Strings.ERROR_LAUNCHING_BROWSER, err);
                            }

                            Dialogs.showModalDialog(
                                Dialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_LAUNCHING_BROWSER_TITLE,
                                message
                            );
                        });
                }

                if (exports.status !== -1) {
                    setTimeout(function retryConnect() {
                        Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                    }, 500);
                }
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
        _setStatus(0);
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (Inspector.connected()) {
            if (!doc) {
                close();
            } else if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                /* FUTURE: support live connections for docments other than html */
                if (doc.extension.indexOf('htm') === 0) {
                    close();
                    setTimeout(open);
                }
            }
        } else if (exports.config.autoconnect) {
            setTimeout(open);
        }
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.removeRelatedDocument = removeRelatedDocument;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

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

/**
 * ScriptAgent tracks all executed scripts, defines internal breakpoints, and
 * interfaces with the remote debugger.
 */
define(function ScriptAgent(require, exports, module) {
    'use strict';

    var Inspector = require("LiveDevelopment/Inspector/Inspector");
    var DOMAgent = require("LiveDevelopment/Agents/DOMAgent");

    var _load; // the load promise
    var _urlToScript; // url -> script info
    var _idToScript; // id -> script info
    var _insertTrace; // the last recorded trace of a DOM insertion

    /** Add a call stack trace to a node
     * @param {integer} node id
     * @param [{Debugger.CallFrame}] call stack
     */
    function _addTraceToNode(nodeId, trace) {
        var node = DOMAgent.nodeWithId(nodeId);
        node.trace = trace;
    }

    /** Get the script information for a given url
     * @param {string} url
     */
    function scriptWithId(url) {
        return _idToScript[url];
    }

    /** Get the script information for a given url
     * @param {string} url
     */
    function scriptForURL(url) {
        return _urlToScript[url];
    }

    // DOMAgent Event: Document root loaded
    function _onGetDocument(res) {
        Inspector.DOMDebugger.setDOMBreakpoint(res.root.nodeId, "subtree-modified");
        _load.resolve();
    }

    // WebInspector Event: DOM.childNodeInserted
    function _onChildNodeInserted(res) {
        // res = {parentNodeId, previousNodeId, node}
        if (_insertTrace) {
            var node = DOMAgent.nodeWithId(res.node.nodeId);
            node.trace = _insertTrace;
            _insertTrace = undefined;
        }
    }

    // WebInspector Event: Debugger.scriptParsed
    function _onScriptParsed(res) {
        // res = {scriptId, url, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL}
        _idToScript[res.scriptId] = res;
        _urlToScript[res.url] = res;
    }

    // WebInspector Event: Debugger.scriptFailedToParse
    function _onScriptFailedToParse(res) {
        // res = {url, scriptSource, startLine, errorLine, errorMessage}
    }

    // WebInspector Event: Debugger.paused
    function _onPaused(res) {
        // res = {callFrames, reason, data}
        switch (res.reason) {

        // Exception
        case "exception":
            Inspector.Debugger.resume();
            // var callFrame = res.callFrames[0];
            // var script = scriptWithId(callFrame.location.scriptId);
            break;

        // DOMBreakpoint
        case "DOM":
            Inspector.Debugger.resume();
            if (res.data.type === "subtree-modified" && res.data.insertion === true) {
                _insertTrace = res.callFrames;
            }
            break;
        }

    }

    /** Initialize the agent */
    function load() {
        _urlToScript = {};
        _idToScript = {};
        _load = new $.Deferred();
        Inspector.Debugger.enable();
        Inspector.Debugger.setPauseOnExceptions("uncaught");
        Inspector.on("DOMAgent.getDocument", _onGetDocument);
        Inspector.on("Debugger.scriptParsed", _onScriptParsed);
        Inspector.on("Debugger.scriptFailedToParse", _onScriptFailedToParse);
        Inspector.on("Debugger.paused", _onPaused);
        Inspector.on("DOM.childNodeInserted", _onChildNodeInserted);
        return _load;
    }

    /** Clean up */
    function unload() {
        Inspector.off("DOMAgent.getDocument", _onGetDocument);
        Inspector.off("Debugger.scriptParsed", _onScriptParsed);
        Inspector.off("Debugger.scriptFailedToParse", _onScriptFailedToParse);
        Inspector.off("Debugger.paused", _onPaused);
        Inspector.off("DOM.childNodeInserted", _onChildNodeInserted);
    }

    // Export public functions
    exports.scriptWithId = scriptWithId;
    exports.scriptForURL = scriptForURL;
    exports.load = load;
    exports.unload = unload;
});


body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }

#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }

#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

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

/*
 * Adds a "find in files" command to allow the user to find all occurances of a string in all files in
 * the project.
 *
 * The keyboard shortcut is Cmd(Ctrl)-Shift-F.
 *
 * FUTURE:
 *  - Proper UI for both dialog and results
 *  - Refactor dialog class and share with Quick File Open
 *  - Search files in working set that are *not* in the project
 *  - Handle matches that span mulitple lines
 *  - Refactor UI from functionality to enable unit testing
 *  - Cache result of getLine()
 */

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

    var Async               = require("utils/Async"),
        CommandManager      = require("command/CommandManager"),
        Commands            = require("command/Commands"),
        DocumentManager     = require("document/DocumentManager"),
        EditorManager       = require("editor/EditorManager"),
        FileIndexManager    = require("project/FileIndexManager");

    // This dialog class was mostly copied from QuickFileOpen. We should have a common dialog
    // class that everyone can use.

    /**
    * FindInFilesDialog class
    * @constructor
    *
    */
    function FindInFilesDialog() {
        this.closed = false;
        this.result = null; // $.Deferred
    }

    /**
    * Creates a dialog div floating on top of the current code mirror editor
    */
    FindInFilesDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    FindInFilesDialog.prototype._close = function (value) {
        if (this.closed) {
            return;
        }

        this.closed = true;

        this.dialog.parentNode.removeChild(this.dialog);

        this.result.resolve(value);
    };

    /**
    * Shows the search dialog
    * @param {?string} initialString Default text to prepopulate the search field with
    * @returns {$.Promise} that is resolved with the string to search for
    */
    FindInFilesDialog.prototype.showDialog = function (initialString) {
        var dialogHTML = 'Find in Files: <input type="text" id="findInFilesInput" style="width: 10em"> (Use /re/ syntax for regexp search)';
        this.result = new $.Deferred();
        this._createDialogDiv(dialogHTML);
        var searchField = $('input#findInFilesInput');
        var that = this;

        searchField.attr("value", initialString || "");
        searchField.get(0).select();

        searchField.bind("keydown", function (event) {
            if (event.keyCode === 13 || event.keyCode === 27) {  // Enter/Return key or Esc key
                event.stopPropagation();
                event.preventDefault();

                var query = searchField.val();

                if (event.keyCode === 27) {
                    query = null;
                }

                that._close(query);
            }
        })
            .blur(function () {
                that._close(null);
            })
            .focus();

        return this.result.promise();
    };

    function _getSearchMatches(contents, queryExpr) {
        // Quick exit if not found
        if (contents.search(queryExpr) === -1) {
            return null;
        }

        var trimmedContents = contents;
        var startPos = 0;
        var matchStart;
        var matches = [];

        function getLineNum(offset) {
            return contents.substr(0, offset).split("\n").length - 1; // 0 based linenum
        }

        function getLine(lineNum) {
            // Future: cache result
            return contents.split("\n")[lineNum];
        }

        var match;
        while ((match = queryExpr.exec(contents)) !== null) {
            var lineNum = getLineNum(match.index);
            var line = getLine(lineNum);
            var ch = match.index - contents.lastIndexOf("\n", match.index) - 1;  // 0-based index
            var matchLength = match[0].length;

            // Don't store more than 200 chars per line
            line = line.substr(0, Math.min(200, line.length));

            matches.push({
                start: {line: lineNum, ch: ch},
                end: {line: lineNum, ch: ch + matchLength},
                line: line
            });
        }

        return matches;
    }

    function _showSearchResults(searchResults) {
        var $searchResultsDiv = $("#search-results");

        if (searchResults && searchResults.length) {
            var resultTable = $("
")
                                .append("
");

            // Count the total number of matches
            var numMatches = 0;
            searchResults.forEach(function (item) {
                numMatches += item.matches.length;
            });

            // Show result summary in header
            $("#search-result-summary")
                .text(" - " + numMatches + " match" + (numMatches > 1 ? "es" : "") +
                      " in " + searchResults.length + " file" + (searchResults.length > 1 ? "s" : "") +
                     (numMatches > 100 ? " (showing the first 100 matches)" : ""));

            var resultsDisplayed = 0;

            searchResults.forEach(function (item) {
                if (item && resultsDisplayed < 100) {
                    var makeCell = function (content) {
                        return $("").html(content);
                    };

                    var esc = function (str) {
                        str = str.replace(/</g, "<");
                        str = str.replace(/>/g, ">");
                        return str;
                    };

                    var highlightMatch = function (line, start, end) {
                        return esc(line.substr(0, start)) + "" + esc(line.substring(start, end)) + "" + esc(line.substr(end));
                    };

                    // Add row for file name
                    $("
")
                        .append("File: " + item.fullPath + "	")
                        .appendTo(resultTable);

                    // Add row for each match in file
                    item.matches.forEach(function (match) {
                        if (resultsDisplayed < 100) {
                            var row = $("
")
                                .append(makeCell(" "))      // Indent
                                .append(makeCell("line: " + (match.start.line + 1)))
                                .append(makeCell(highlightMatch(match.line, match.start.ch, match.end.ch)))
                                .appendTo(resultTable);

                            row.click(function () {
                                CommandManager.execute(Commands.FILE_OPEN, {fullPath: item.fullPath})
                                    .done(function (doc) {
                                        // Opened document is now the current main editor
                                        EditorManager.getCurrentFullEditor().setSelection(match.start, match.end);
                                    });
                            });
                            resultsDisplayed++;
                        }
                    });

                }
            });

            $("#search-results .table-container")
                .empty()
                .append(resultTable);

            $("#search-results .close")
                .one("click", function () {
                    $searchResultsDiv.hide();
                    EditorManager.resizeEditor();
                });

            $searchResultsDiv.show();
        } else {
            $searchResultsDiv.hide();
        }

        EditorManager.resizeEditor();
    }

    function _getQueryRegExp(query) {
        // If query is a regular expression, use it directly
        var isRE = query.match(/^\/(.*)\/(g|i)*$/);
        if (isRE) {
            // Make sure the 'g' flag is set
            var flags = isRE[2] || "g";
            if (flags.search("g") === -1) {
                flags += "g";
            }
            return new RegExp(isRE[1], flags);
        }

        // Query is a string. Turn it into a case-insensitive regexp

        // Escape regex special chars
        query = query.replace(/(\(|\)|\{|\}|\[|\]|\.|\^|\$|\||\?|\+|\*)/g, "\\$1");
        return new RegExp(query, "gi");
    }

    /**
    * Displays a non-modal embedded dialog above the code mirror editor that allows the user to do
    * a find operation across all files in the project.
    */
    function doFindInFiles() {

        var dialog = new FindInFilesDialog();
        var searchResults = [];

        // Default to searching for the current selection
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText();

        dialog.showDialog(initialString)
            .done(function (query) {
                if (query) {
                    var queryExpr = _getQueryRegExp(query);
                    FileIndexManager.getFileInfoList("all")
                        .done(function (fileListResult) {
                            Async.doInParallel(fileListResult, function (fileInfo) {
                                var result = new $.Deferred();

                                DocumentManager.getDocumentForPath(fileInfo.fullPath)
                                    .done(function (doc) {
                                        var matches = _getSearchMatches(doc.getText(), queryExpr);

                                        if (matches && matches.length) {
                                            searchResults.push({
                                                fullPath: fileInfo.fullPath,
                                                matches: matches
                                            });
                                        }
                                        result.resolve();
                                    })
                                    .fail(function (error) {
                                        // Error reading this file. This is most likely because the file isn't a text file.
                                        // Resolve here so we move on to the next file.
                                        result.resolve();
                                    });

                                return result.promise();
                            })
                                .done(function () {
                                    console.dir(searchResults);
                                    _showSearchResults(searchResults);
                                })
                                .fail(function () {
                                    console.log("find in files failed.");
                                });
                        });
                }
            });
    }

    CommandManager.register(Commands.FIND_IN_FILES, doFindInFiles);
});


* Removes the given CSS/JSDocument from _relatedDocuments. Signals that the

* given file is no longer associated with the HTML document that is live (e.g.

* if the related file has been deleted on disk).

var index = _relatedDocuments.indexOf(liveDoc);

keep keep keep keep keep replace keep keep keep

function _handleRelatedDocumentDeleted(event, liveDoc) {


/* =========================================================
 * bootstrap-modal.js v1.4.0
 * http://twitter.github.com/bootstrap/javascript.html#modal
 * =========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================= */

!function( $ ){

  "use strict"

 /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
  * ======================================================= */

  var transitionEnd

  $(document).ready(function () {

    $.support.transition = (function () {
      var thisBody = document.body || document.documentElement
        , thisStyle = thisBody.style
        , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
      return support
    })()

    // set CSS transition event type
    if ( $.support.transition ) {
      transitionEnd = "TransitionEnd"
      if ( $.browser.webkit ) {
      	transitionEnd = "webkitTransitionEnd"
      } else if ( $.browser.mozilla ) {
      	transitionEnd = "transitionend"
      } else if ( $.browser.opera ) {
      	transitionEnd = "oTransitionEnd"
      }
    }

  })

 /* MODAL PUBLIC CLASS DEFINITION
  * ============================= */

  var Modal = function ( content, options ) {
    this.settings = $.extend({}, $.fn.modal.defaults, options)
    this.$element = $(content)
      .delegate('.close', 'click.modal', $.proxy(this.hide, this))

    if ( this.settings.show ) {
      this.show()
    }

    return this
  }

  Modal.prototype = {

      toggle: function () {
        return this[!this.isShown ? 'show' : 'hide']()
      }

    , show: function () {
        var that = this
        this.isShown = true
        this.$element.trigger('show')

        escape.call(this)
        backdrop.call(this, function () {
          var transition = $.support.transition && that.$element.hasClass('fade')

          that.$element
            .appendTo(document.body)
            .show()

          if (transition) {
            that.$element[0].offsetWidth // force reflow
          }

          that.$element.addClass('in')

          transition ?
            that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) :
            that.$element.trigger('shown')

        })

        return this
      }

    , hide: function (e) {
        e && e.preventDefault()

        if ( !this.isShown ) {
          return this
        }

        var that = this
        this.isShown = false

        escape.call(this)

        this.$element
          .trigger('hide')
          .removeClass('in')

        $.support.transition && this.$element.hasClass('fade') ?
          hideWithTransition.call(this) :
          hideModal.call(this)

        return this
      }

  }

 /* MODAL PRIVATE METHODS
  * ===================== */

  function hideWithTransition() {
    // firefox drops transitionEnd events :{o
    var that = this
      , timeout = setTimeout(function () {
          that.$element.unbind(transitionEnd)
          hideModal.call(that)
        }, 500)

    this.$element.one(transitionEnd, function () {
      clearTimeout(timeout)
      hideModal.call(that)
    })
  }

  function hideModal (that) {
    this.$element
      .hide()
      .trigger('hidden')

    backdrop.call(this)
  }

  function backdrop ( callback ) {
    var that = this
      , animate = this.$element.hasClass('fade') ? 'fade' : ''
    if ( this.isShown && this.settings.backdrop ) {
      var doAnimate = $.support.transition && animate

      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
        .appendTo(document.body)

      if ( this.settings.backdrop != 'static' ) {
        this.$backdrop.click($.proxy(this.hide, this))
      }

      if ( doAnimate ) {
        this.$backdrop[0].offsetWidth // force reflow
      }

      this.$backdrop.addClass('in')

      doAnimate ?
        this.$backdrop.one(transitionEnd, callback) :
        callback()

    } else if ( !this.isShown && this.$backdrop ) {
      this.$backdrop.removeClass('in')

      $.support.transition && this.$element.hasClass('fade')?
        this.$backdrop.one(transitionEnd, $.proxy(removeBackdrop, this)) :
        removeBackdrop.call(this)

    } else if ( callback ) {
       callback()
    }
  }

  function removeBackdrop() {
    this.$backdrop.remove()
    this.$backdrop = null
  }

  function escape() {
    var that = this
    if ( this.isShown && this.settings.keyboard ) {
      $(document).bind('keyup.modal', function ( e ) {
        if ( e.which == 27 ) {
          that.hide()
        }
      })
    } else if ( !this.isShown ) {
      $(document).unbind('keyup.modal')
    }
  }

 /* MODAL PLUGIN DEFINITION
  * ======================= */

  $.fn.modal = function ( options ) {
    var modal = this.data('modal')

    if (!modal) {

      if (typeof options == 'string') {
        options = {
          show: /show|toggle/.test(options)
        }
      }

      return this.each(function () {
        $(this).data('modal', new Modal(this, options))
      })
    }

    if ( options === true ) {
      return modal
    }

    if ( typeof options == 'string' ) {
      modal[options]()
    } else if ( modal ) {
      modal.toggle()
    }

    return this
  }

  $.fn.modal.Modal = Modal

  $.fn.modal.defaults = {
    backdrop: false
  , keyboard: false
  , show: false
  }

 /* MODAL DATA- IMPLEMENTATION
  * ========================== */

  $(document).ready(function () {
    $('body').delegate('[data-controls-modal]', 'click', function (e) {
      e.preventDefault()
      var $this = $(this).data('show', true)
      $('#' + $this.attr('data-controls-modal')).modal( $this.data() )
    })
  })

}( window.jQuery || window.ender );


/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

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

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file.
* Uses FileIndexManger to supply the file list and registers Commands.FILE_QUICK_NAVIGATE with Brackets.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

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

    var FileIndexManager    = require("project/FileIndexManager"),
        DocumentManager     = require("document/DocumentManager"),
        CommandManager      = require("command/CommandManager"),
        EditorManager       = require("editor/EditorManager"),
        Commands            = require("command/Commands"),
        ProjectManager      = require("project/ProjectManager");

    /**
    * QuickNavigateDialog class
    * @constructor
    *
    */
    function QuickNavigateDialog() {
        this.closed = false;
        this.result = null; // $.Deferred
    }

    /**
    * Creates a dialog div floating on top of the current code mirror editor
    */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path) {
        return path.slice(path.lastIndexOf("/") + 1, path.length);
    }

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {
        if (this.closed) {
            return;
        }

        this.closed = true;

        this.dialog.parentNode.removeChild(this.dialog);

        $(".smart_autocomplete_container").remove();

        this.result.resolve(value);
    };

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    * @param {?string} initialString Default text to prepopulate the search field with
    * @returns {$.Promise} a promise that is resolved when the dialgo closes with the string value from the search field
    */
    QuickNavigateDialog.prototype.showDialog = function (initialString) {
        var that = this;
        var fileInfoList;
        this.result = new $.Deferred();

        FileIndexManager.getFileInfoList("all")
            .done(function (filelistResult) {
                fileInfoList = filelistResult;
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                var closed = false;
                var searchField = $('input#quickFileOpenSearch');

                searchField.attr("value", initialString || "");
                searchField.get(0).select();

                // auto suggest list helper function
                function _handleResultsFormatter(path) {
                    var filename = _filenameFromPath(path);
                    var rPath = ProjectManager.makeProjectRelativeIfPossible(path);
                    var boldName = filename.replace(new RegExp($('input#quickFileOpenSearch').val(), "gi"), "$&");
                    return "
" + boldName +
                        "
" + rPath + "
";
                }

                // auto suggest list helper function
                function _handleFilter(term, source) {
                    var filteredList = $.map(source, function (fileInfo) {
                        // match term again filename only (not the path)
                        var path = fileInfo.fullPath;
                        var filename = _filenameFromPath(path);
                        if (filename.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
                            return fileInfo.fullPath;
                        } else {
                            return null;
                        }
                    }).sort(function (a, b) {
                        // sort by filename
                        var filenameA = _filenameFromPath(a).toLowerCase();
                        var filenameB = _filenameFromPath(b).toLowerCase();
                        if (filenameA < filenameB) {
                            return -1;
                        } else if (filenameA > filenameB) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });

                    return filteredList;
                }

                // Create the auto suggest list of filenames
                searchField.smartAutoComplete({
                    source: fileInfoList,
                    maxResults: 10,
                    forceSelect: false,
                    typeAhead: true,
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                searchField.bind({
                    // close the dialog when the user selects an item
                    itemSelect: function (ev, selected_item) {
                        var value = decodeURIComponent($(selected_item).attr("data-fullpath"));
                        that._close(value);
                    },

                    keydown: function (e) {
                        var query = searchField.val();

                        // close the dialog when the ENTER (23) or ESC (27) key is pressed
                        if ((e.keyCode === 13 && query.charAt(0) === ":") || e.keyCode === 27) {
                            e.stopPropagation();
                            e.preventDefault();

                            // clear the query on ESC key
                            if (e.keyCode === 27) {
                                query = null;
                            }

                            that._close(query);
                            EditorManager.focusEditor();
                        }
                    }

                });

                searchField.focus();
            });

        return this.result;
    };

    /**
    * Displays a non-modal embedded dialog above the code mirror edit that allows the user to quickly
    * navigate to different files and parts of the current file.
    * The search field lists files in the project. The user can enter ":" followed by a line
    * number to navigate to a specific line in the current file.
    */
    function doFileSearch() {
        // Default to searching for the current selection
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText();

        var dialog = new QuickNavigateDialog();

        dialog.showDialog(initialString)
            .done(function (query) {
                if (query) {
                    if (query.charAt(0) === ":") {
                        var lineNumber = parseInt(query.slice(1, query.length), 10);
                        if (!isNaN(lineNumber)) {
                            var editor = EditorManager.getCurrentFullEditor();
                            editor.setCursorPos(lineNumber - 1, 0);
                        }
                    } else {
                        CommandManager.execute(Commands.FILE_OPEN, {fullPath: query});
                    }
                }
            });
    }

    CommandManager.register(Commands.FILE_QUICK_NAVIGATE, doFileSearch);
});


/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

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

/**
 * WorkingSetView generates the UI for the list of the files user is editing based on the model provided by EditorManager.
 * The UI allows the user to see what files are open/dirty and allows them to close files and specify the current editor.
 */
define(function (require, exports, module) {
    'use strict';

    // Load dependent modules
    var DocumentManager       = require("document/DocumentManager"),
        CommandManager        = require("command/CommandManager"),
        Commands              = require("command/Commands"),
        EditorManager         = require("editor/EditorManager"),
        FileViewController    = require("project/FileViewController"),
        NativeFileSystem      = require("file/NativeFileSystem").NativeFileSystem,
        ViewUtils             = require("utils/ViewUtils");

    /** Each list item in the working set stores a references to the related document in the list item's data.
     *  Use listItem.data(_FILE_KEY) to get the document reference
     */
    var _FILE_KEY = "file";

    function _hideShowOpenFileHeader() {
        if (DocumentManager.getWorkingSet().length === 0) {
            $("#open-files-header").hide();
            $("#open-files-container").hide();
            $("#open-files-divider").hide();
        } else {
            $("#open-files-header").show();
            $("#open-files-container").show();
            $("#open-files-divider").show();
        }

        ViewUtils.updateChildrenToParentScrollwidth($("#open-files-container"));
    }

    /**
     * Updates the appearance of the list element based on the parameters provided
     * @private
     * @param {!HTMLLIElement} listElement
     * @param {bool} isDirty
     * @param {bool} canClose
     */
    function _updateFileStatusIcon(listElement, isDirty, canClose) {
        var fileStatusIcon = listElement.find(".file-status-icon");
        var showIcon = isDirty || canClose;

        // remove icon if its not needed
        if (!showIcon && fileStatusIcon.length !== 0) {
            fileStatusIcon.remove();
            fileStatusIcon = null;

        // create icon if its needed and doesn't exist
        } else if (showIcon && fileStatusIcon.length === 0) {

            fileStatusIcon = $("

")
                .prependTo(listElement)
                .click(function () {
                    // Clicking the "X" button is equivalent to File > Close; it doesn't merely
                    // remove a file from the working set
                    var file = listElement.data(_FILE_KEY);
                    CommandManager.execute(Commands.FILE_CLOSE, {file: file});
                });
        }

        // Set icon's class
        if (fileStatusIcon) {
            // cast to Boolean needed because toggleClass() distinguishes true/false from truthy/falsy
            fileStatusIcon.toggleClass("dirty", Boolean(isDirty));
            fileStatusIcon.toggleClass("canClose", Boolean(canClose));
        }
    }

    /**
     * Updates the appearance of the list element based on the parameters provided.
     * @private
     * @param {!HTMLLIElement} listElement
     * @param {?Document} selectedDoc
     */
    function _updateListItemSelection(listItem, selectedDoc) {
        var shouldBeSelected = (selectedDoc && $(listItem).data(_FILE_KEY).fullPath === selectedDoc.file.fullPath);

        // cast to Boolean needed because toggleClass() distinguishes true/false from truthy/falsy
        $(listItem).toggleClass("selected", Boolean(shouldBeSelected));
    }

    function isOpenAndDirty(file) {
        var docIfOpen = DocumentManager.getOpenDocumentForPath(file.fullPath);
        return (docIfOpen && docIfOpen.isDirty);
    }

    /**
     * Builds the UI for a new list item and inserts in into the end of the list
     * @private
     * @param {FileEntry} file
     * @return {HTMLLIElement} newListItem
     */
    function _createNewListItem(file) {
        var curDoc = DocumentManager.getCurrentDocument();

        // Create new list item with a link
        var link = $("").text(file.name);
        var newItem = $("

")
            .append(link)
            .data(_FILE_KEY, file);

        $("#open-files-container > ul").append(newItem);

        // working set item might never have been opened; if so, then it's definitely not dirty

        // Update the listItem's apperance
        _updateFileStatusIcon(newItem, isOpenAndDirty(file), false);
        _updateListItemSelection(newItem, curDoc);

        newItem.click(function () {
            FileViewController.openAndSelectDocument(file.fullPath, FileViewController.WORKING_SET_VIEW);
        });

        newItem.hover(
            function () {
                _updateFileStatusIcon($(this), isOpenAndDirty(file), true);
            },
            function () {
                _updateFileStatusIcon($(this), isOpenAndDirty(file), false);
            }
        );
    }

    /**
     * Deletes all the list items in the view and rebuilds them from the working set model
     * @private
     */
    function _rebuildWorkingSet() {
        $("#open-files-container > ul").empty();

        DocumentManager.getWorkingSet().forEach(function (file) {
            _createNewListItem(file);
        });

        _hideShowOpenFileHeader();
    }

    /**
     * @private
     */
    function _updateListSelection() {
        var doc;
        if (FileViewController.getFileSelectionFocus() === FileViewController.WORKING_SET_VIEW) {
            doc = DocumentManager.getCurrentDocument();
        } else {
            doc = null;
        }

        // Iterate through working set list and update the selection on each
        var items = $("#open-files-container > ul").children().each(function () {
            _updateListItemSelection(this, doc);
        });
    }

    /**
     * @private
     */
    function _handleFileAdded(file) {
        _createNewListItem(file);
        _hideShowOpenFileHeader();
    }

    /**
     * @private
     */
    function _handleDocumentSelectionChange() {
        _updateListSelection();
    }

    /**
     * Finds the listItem item assocated with the file. Returns null if not found.
     * @private
     * @param {!FileEntry} file
     * @return {HTMLLIItem}
     */
    function _findListItemFromFile(file) {
        var result = null;

        if (file) {
            var items = $("#open-files-container > ul").children();
            items.each(function () {
                var listItem = $(this);
                if (listItem.data(_FILE_KEY).fullPath === file.fullPath) {
                    result = listItem;
                    return false;
                    // breaks each
                }
            });
        }

        return result;
    }

    /**
     * @private
     * @param {FileEntry} file
     */
    function _handleFileRemoved(file) {
        var listItem = _findListItemFromFile(file);
        if (listItem) {
            listItem.remove();
        }

        _hideShowOpenFileHeader();
    }

    /**
     * @private
     * @param {Document} doc
     */
    function _handleDirtyFlagChanged(doc) {
        var listItem = _findListItemFromFile(doc.file);
        if (listItem) {
            var canClose = $(listItem).find("canClose").length === 1;
            _updateFileStatusIcon(listItem, doc.isDirty, canClose);
        }

    }

    // Initialize: register listeners
    $(DocumentManager).on("workingSetAdd", function (event, addedFile) {
        //console.log("Working set ++ " + addedFile);
        //console.log("  set: " + DocumentManager.getWorkingSet().join());
        _handleFileAdded(addedFile);
    });

    $(DocumentManager).on("workingSetRemove", function (event, removedFile) {
        //console.log("Working set -- " + removedFile);
        //console.log("  set: " + DocumentManager.getWorkingSet().join());
        _handleFileRemoved(removedFile);
    });

    $(DocumentManager).on("dirtyFlagChange", function (event, doc) {
        //console.log("Dirty flag change: " + doc);
        _handleDirtyFlagChanged(doc);
    });

    $(FileViewController).on("documentSelectionFocusChange", function (event, eventTarget) {
        _handleDocumentSelectionChange();
    });

    _hideShowOpenFileHeader();

});


keep keep keep add keep keep keep keep keep


/* Shared LESS for all versions of Brackets (e.g. App, In-Browser, etc.)
 *
 * IMPORTANT: Importing this file should be the first step in creating a
 * version-specific LESS file.
 *
 * ALSO IMPORTANT: All CSS imports should occur first in this file. This is
 * because LESS puts all CSS imports at the top of the file anyway (because
 * this is required by CSS2). So, we don't want to be misleading about the
 * processing order.
 */

/* CSS imports */

// CodeMirror
@import "thirdparty/CodeMirror2/lib/codemirror.css";

/* LESS imports */

// Bootstrap @ v.1.4.0
@import "bootstrap/bootstrap.less";

// Brackets-specific variables, mixins and overrides
@import "brackets_variables.less";
@import "brackets_mixins.less";
@import "brackets_patterns_override.less";

// Brackets-specific default font and color definitions
@import "brackets_fonts.less";
@import "brackets_colors.less";

// Default theme -- all UI styling comes from variables in a theme
// Themes can rely on variables defined above
@import "brackets_theme_default.less";

// Codemirror styling overrides
@import "brackets_codemirror_override.less";

// styling for file tree
@import "jsTreeTheme.less";


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

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

/**
 * JSDocument manages a single JavaScript source document
 *
 * # EDITING
 *
 * Editing the document will cause the script to be reloaded via the
 * ScriptAgent, which updates the implementation of all functions without
 * loosing any state. To support redrawing canvases, jQuery must be loaded
 * and a rerender method must be attached to every canvas that clears and
 * renders the canvas.
 *
 * # HIGHLIGHTING
 *
 * JSDocument supports highlighting nodes from the HighlightAgent. Support
 * for highlighting the nodes that were created / touched by the current
 * line is missing.
 */
define(function JSDocumentModule(require, exports, module) {
    'use strict';

    var Inspector = require("LiveDevelopment/Inspector/Inspector");
    var ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent");
    var HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent");

    /** Constructor
     *
     * @param {Document} the source document
     */
    var JSDocument = function JSDocument(doc, editor) {
        this.doc = doc;
        this.editor = editor;
        this.script = ScriptAgent.scriptForURL(this.doc.url);
        this.onHighlight = this.onHighlight.bind(this);
        this.onChange = this.onChange.bind(this);
        this.onCursorActivity = this.onCursorActivity.bind(this);
        Inspector.on("HighlightAgent.highlight", this.onHighlight);
        $(this.editor).on("change", this.onChange);
        $(this.editor).on("cursorActivity", this.onCursorActivity);
        this.onCursorActivity();
    };

    /** Close the document */
    JSDocument.prototype.close = function close() {
        Inspector.off("HighlightAgent.highlight", this.onHighlight);
        $(this.editor).off("change", this.onChange);
        $(this.editor).off("cursorActivity", this.onCursorActivity);
        this.onHighlight();
    };

    /** Event Handlers *******************************************************/

    /** Triggered on cursor activity by the editor */
    JSDocument.prototype.onCursorActivity = function onCursorActivity(event, editor) {
    };

    /** Triggered on change by the editor */
    JSDocument.prototype.onChange = function onChange(event, editor, change) {
        var src = this.doc.getText();
        Inspector.Debugger.setScriptSource(this.script.scriptId, src, function onSetScriptSource(res) {
            Inspector.Runtime.evaluate("if($)$(\"canvas\").each(function(i,e){if(e.rerender)e.rerender()})");
        }.bind(this));
    };

    /** Triggered by the HighlightAgent to highlight a node in the editor */
    JSDocument.prototype.onHighlight = function onHighlight(node) {
        // clear an existing highlight
        var codeMirror = this.editor._codeMirror;
        var i;
        for (i in this._highlight) {
            codeMirror.setLineClass(this._highlight[i]);
        }
        this._highlight = [];
        if (!node || !node.trace) {
            return;
        }

        // go through the trace and find highlight the lines of this script
        var callFrame, line;
        for (i in node.trace) {
            callFrame = node.trace[i];
            if (callFrame.location && callFrame.location.scriptId === this.script.scriptId) {
                line = callFrame.location.lineNumber;
                codeMirror.setLineClass(line, "highlight");
                this._highlight.push(line);
            }
        }
    };

    // Export the class
    module.exports = JSDocument;
});


/* ===========================================================
 * bootstrap-popover.js v1.4.0
 * http://twitter.github.com/bootstrap/javascript.html#popover
 * ===========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =========================================================== */

!function( $ ) {

 "use strict"

  var Popover = function ( element, options ) {
    this.$element = $(element)
    this.options = options
    this.enabled = true
    this.fixTitle()
  }

  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TWIPSY.js
     ========================================= */

  Popover.prototype = $.extend({}, $.fn.twipsy.Twipsy.prototype, {

    setContent: function () {
      var $tip = this.tip()
      $tip.find('.title')[this.options.html ? 'html' : 'text'](this.getTitle())
      $tip.find('.content > *')[this.options.html ? 'html' : 'text'](this.getContent())
      $tip[0].className = 'popover'
    }

  , hasContent: function () {
      return this.getTitle() || this.getContent()
    }

  , getContent: function () {
      var content
       , $e = this.$element
       , o = this.options

      if (typeof this.options.content == 'string') {
        content = $e.attr(this.options.content)
      } else if (typeof this.options.content == 'function') {
        content = this.options.content.call(this.$element[0])
      }

      return content
    }

  , tip: function() {
      if (!this.$tip) {
        this.$tip = $('
')
          .html(this.options.template)
      }
      return this.$tip
    }

  })

 /* POPOVER PLUGIN DEFINITION
  * ======================= */

  $.fn.popover = function (options) {
    if (typeof options == 'object') options = $.extend({}, $.fn.popover.defaults, options)
    $.fn.twipsy.initWith.call(this, options, Popover, 'popover')
    return this
  }

  $.fn.popover.defaults = $.extend({} , $.fn.twipsy.defaults, {
    placement: 'right'
  , content: 'data-content'
  , template: '

'
  })

  $.fn.twipsy.rejectAttrOptions.push( 'content' )

}( window.jQuery || window.ender );


/*
 * jsTree default theme 1.0
 * Supported features: dots/no-dots, icons/no-icons, focused, loading
 * Supported plugins: ui (hovered, clicked), checkbox, contextmenu, search
 */

.jstree-default li,
.jstree-default ins { background-image:url("d.png"); background-repeat:no-repeat; background-color:transparent; }
.jstree-default li { background-position:-90px 0; background-repeat:repeat-y; }
.jstree-default li.jstree-last { background:transparent; }
.jstree-default .jstree-open > ins { background-position:-72px 0; }
.jstree-default .jstree-closed > ins { background-position:-54px 0; }
.jstree-default .jstree-leaf > ins { background-position:-36px 0; }

.jstree-default .jstree-hovered { background:#e7f4f9; border:1px solid #d8f0fa; padding:0 2px 0 1px; }
.jstree-default .jstree-clicked { background:#beebff; border:1px solid #99defd; padding:0 2px 0 1px; }
.jstree-default a .jstree-icon { background-position:-56px -19px; }
.jstree-default a.jstree-loading .jstree-icon { background:url("throbber.gif") center center no-repeat !important; }

.jstree-default.jstree-focused { background:#ffffee; }

.jstree-default .jstree-no-dots li,
.jstree-default .jstree-no-dots .jstree-leaf > ins { background:transparent; }
.jstree-default .jstree-no-dots .jstree-open > ins { background-position:-18px 0; }
.jstree-default .jstree-no-dots .jstree-closed > ins { background-position:0 0; }

.jstree-default .jstree-no-icons a .jstree-icon { display:none; }

.jstree-default .jstree-search { font-style:italic; }

.jstree-default .jstree-no-icons .jstree-checkbox { display:inline-block; }
.jstree-default .jstree-no-checkboxes .jstree-checkbox { display:none !important; }
.jstree-default .jstree-checked > a > .jstree-checkbox { background-position:-38px -19px; }
.jstree-default .jstree-unchecked > a > .jstree-checkbox { background-position:-2px -19px; }
.jstree-default .jstree-undetermined > a > .jstree-checkbox { background-position:-20px -19px; }
.jstree-default .jstree-checked > a > .jstree-checkbox:hover { background-position:-38px -37px; }
.jstree-default .jstree-unchecked > a > .jstree-checkbox:hover { background-position:-2px -37px; }
.jstree-default .jstree-undetermined > a > .jstree-checkbox:hover { background-position:-20px -37px; }

#vakata-dragged.jstree-default ins { background:transparent !important; }
#vakata-dragged.jstree-default .jstree-ok { background:url("d.png") -2px -53px no-repeat !important; }
#vakata-dragged.jstree-default .jstree-invalid { background:url("d.png") -18px -53px no-repeat !important; }
#jstree-marker.jstree-default { background:url("d.png") -41px -57px no-repeat !important; text-indent:-100px; }

.jstree-default a.jstree-search { color:aqua; }
.jstree-default .jstree-locked a { color:silver; cursor:default; }

#vakata-contextmenu.jstree-default-context,
#vakata-contextmenu.jstree-default-context li ul { background:#f0f0f0; border:1px solid #979797; -moz-box-shadow: 1px 1px 2px #999; -webkit-box-shadow: 1px 1px 2px #999; box-shadow: 1px 1px 2px #999; }
#vakata-contextmenu.jstree-default-context li { }
#vakata-contextmenu.jstree-default-context a { color:black; }
#vakata-contextmenu.jstree-default-context a:hover,
#vakata-contextmenu.jstree-default-context .vakata-hover > a { padding:0 5px; background:#e8eff7; border:1px solid #aecff7; color:black; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; }
#vakata-contextmenu.jstree-default-context li.jstree-contextmenu-disabled a,
#vakata-contextmenu.jstree-default-context li.jstree-contextmenu-disabled a:hover { color:silver; background:transparent; border:0; padding:1px 4px; }
#vakata-contextmenu.jstree-default-context li.vakata-separator { background:white; border-top:1px solid #e0e0e0; margin:0; }
#vakata-contextmenu.jstree-default-context li ul { margin-left:-4px; }

/* IE6 BEGIN */
.jstree-default li,
.jstree-default ins,
#vakata-dragged.jstree-default .jstree-invalid,
#vakata-dragged.jstree-default .jstree-ok,
#jstree-marker.jstree-default { _background-image:url("d.gif"); }
.jstree-default .jstree-open ins { _background-position:-72px 0; }
.jstree-default .jstree-closed ins { _background-position:-54px 0; }
.jstree-default .jstree-leaf ins { _background-position:-36px 0; }
.jstree-default a ins.jstree-icon { _background-position:-56px -19px; }
#vakata-contextmenu.jstree-default-context ins { _display:none; }
#vakata-contextmenu.jstree-default-context li { _zoom:1; }
.jstree-default .jstree-undetermined a .jstree-checkbox { _background-position:-20px -19px; }
.jstree-default .jstree-checked a .jstree-checkbox { _background-position:-38px -19px; }
.jstree-default .jstree-unchecked a .jstree-checkbox { _background-position:-2px -19px; }
/* IE6 END */


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

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

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

    console.log("and a file that foo depends on!");

    exports.bar = function bar() {
        console.log("in bar in secondary!");
        setTimeout(function () { require("main").bar(); }, 300);
    };

});


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 * @author Jonathan Diehl <jdiehl@adobe.com>
 */

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

/**
 * RemoteFunctions define the functions to be executed in the browser. This
 * modules should define a single function that returns an object of all
 * exported functions.
 */
function RemoteFunctions() {
    'use strict';

    var _body = document.getElementsByTagName("body")[0]; // the document body
    var _sourceHighlight; // the highlighted element in the source
    var _highlight = []; // the highlighted elements
    var _dialog; // the active dialog
    var _target; // the active target element of a dialog
    var _editor; // the editor
    var _editText; // the original editor text

    // prevent an event
    function _preventEventWhenMeta(event) {
        if (event.metaKey) {
            event.preventDefault();
            event.stopPropagation();
        }
    }

    // compute the screen offset of an element
    function _screenOffset(element, key) {
        var value = 0;
        while (element) {
            value += element[key];
            element = element.offsetParent;
        }
        return value;
    }

    // hide dialog
    function _hideDialog() {
        if (_dialog) {
            var dialog = _dialog;
            _dialog = undefined;
            _body.removeChild(dialog);
        }
    }

    // show dialog
    function _createDialog(element, drawBackground) {
        _hideDialog();

        // compute the position on screen
        var x = _screenOffset(element, "offsetLeft");
        var y = _screenOffset(element, "offsetTop") + element.offsetHeight;
        var width = element.offsetWidth;

        // create the container
        _dialog = document.createElement("div");
        _dialog.style.setProperty("z-index", 2147483647);
        _dialog.style.setProperty("position", "absolute");
        _dialog.style.setProperty("left", x + "px");
        _dialog.style.setProperty("top", y + "px");
        _dialog.style.setProperty("font-size", "11pt");
        if (drawBackground) {
            _dialog.style.setProperty("background", "#fff");
            _dialog.style.setProperty("border", "1px solid #888");
            _dialog.style.setProperty("-webkit-box-shadow", "2px 2px 6px 0px #ccc");
            _dialog.style.setProperty("border-radius", "6px");
            _dialog.style.setProperty("padding", "6px");
        }

        return _dialog;
    }

    // row background color
    function _backgroundColorForType(type, highlight) {
        switch (type) {
        case "html":
            return highlight ? "#eec" : "#ffe";
        case "css":
            return highlight ? "#cee" : "#eff";
        case "js":
            return highlight ? "#ccf" : "#eef";
        }
    }

    // set an event on a element
    function _trigger(element, name, value, autoRemove) {
        var key = "data-ld-" + name;
        if (value !== undefined && value !== null) {
            element.setAttribute(key, value);
            if (autoRemove) {
                setTimeout(element.removeAttribute.bind(element, key));
            }
        } else {
            element.removeAttribute(key);
        }
    }

    // low level node highlighting
    function _highlightNode(info) {
        if (!(info instanceof Array)) {
            info = [info, "#ecc"];
        }
        var prevColor = info[0].style.getPropertyValue("background-color");
        info[0].style.setProperty("background-color", info[1]);
        return [info[0], prevColor];
    }

    // editor key press
    function _onEditKeyUp(event) {
        switch (event.which) {
        case 13:
            // return
            _editor.blur();
            break;
        case 27:
            // esc
            _trigger(_target, "edit", _editText, true);
            _editor.blur();
            break;
        case 18:
            // nothing
            break;
        default:
            _trigger(_target, "edit", _editor.value);
        }
    }

    // open the editor
    function _showEdit(text) {
        _editText = text;
        var dialog = _createDialog(_target);
        _editor = document.createElement("input");
        _editor.setAttribute("value", text);
        _editor.setAttribute("width", _target.attributes.width);
        _editor.addEventListener("keyup", _onEditKeyUp);
        _editor.addEventListener("blur", _hideDialog);
        dialog.appendChild(_editor);
        _body.appendChild(dialog);
        _editor.focus();
    }

    /** Event Handlers ***********************************************************/

    // remove highlight on release of the meta key
    function _onKeyUp(event) {
        if (!event.metaKey && _sourceHighlight) {
            _trigger(_sourceHighlight[0], "highlight", 0, true);
            _highlightNode(_sourceHighlight);
            _sourceHighlight = undefined;
        }
    }

    // trigger highlight on mouse move
    function _onMouse(event) {
        if (!event.metaKey || event.type !== "mousemove" || !event.toElement) {
            if (_sourceHighlight) {
                _trigger(_sourceHighlight[0], "highlight", 0, true);
                _highlightNode(_sourceHighlight);
                _sourceHighlight = undefined;
            }
            return;
        }
        if (_sourceHighlight) {
            if (_sourceHighlight[0] === event.toElement) {
                return;
            }
            _trigger(_sourceHighlight[0], "highlight");
            _highlightNode(_sourceHighlight);
        }
        _trigger(event.toElement, "highlight", 1);
        _sourceHighlight = _highlightNode(event.toElement);
    }

    // trigger goto on alt-click
    function _onClick(event) {
        _hideDialog();
        if (event.metaKey && event.toElement) {
            event.preventDefault();
            event.stopPropagation();
            _target = event.toElement;
            _trigger(_target, "showgoto", 1, true);
        } else if (event.altKey && event.toElement && event.toElement.childNodes.length === 1) {
            event.preventDefault();
            event.stopPropagation();
            _target = event.toElement;
            _showEdit(_target.childNodes[0].nodeValue);
        }
    }

    // Goto dialog highlighting
    function _onGotoMouse(row, type, event) {
        if (event.type === "mouseover") {
            row.style.setProperty("background", _backgroundColorForType(type, true));
        } else {
            row.style.setProperty("background", _backgroundColorForType(type));
        }
    }

    // Goto dialog click
    function _onGotoClick(url, event) {
        _hideDialog();
        _trigger(_target, "goto", url, true);
    }

    /** Public Commands **********************************************************/

    // show goto
    function showGoto(targets) {
        var dialog = _createDialog(_target, true);
        var i, target, row, file;
        for (i in targets) {
            target = targets[i];
            row = document.createElement("div");
            row.style.setProperty("padding", "6px 12px");
            row.style.setProperty("display", "block");
            row.style.setProperty("border-bottom", "1px solid #ccc");
            row.style.setProperty("cursor", "pointer");
            row.style.setProperty("background", _backgroundColorForType(target.type));
            row.innerHTML = target.name;
            row.addEventListener("click", _onGotoClick.bind(undefined, target.url));
            row.addEventListener("mouseover", _onGotoMouse.bind(undefined, row, target.type));
            row.addEventListener("mouseout", _onGotoMouse.bind(undefined, row, target.type));
            if (target.file) {
                file = document.createElement("i");
                file.style.setProperty("float", "right");
                file.style.setProperty("margin-left", "12px");
                file.innerHTML = " " + target.file;
                row.appendChild(file);
            }
            dialog.appendChild(row);
        }
        _body.appendChild(dialog);
    }

    // remove active highlights
    function hideHighlight() {
        if (_highlight.length === 0) {
            return;
        }
        var i;
        for (i in _highlight) {
            _highlightNode(_highlight[i]);
        }
        _highlight = [];
    }

    // highlight a node
    function highlight(node) {
        _highlight.push(_highlightNode(node));
    }

    // highlight a rule
    function highlightRule(rule) {
        hideHighlight();
        var i, nodes = document.querySelectorAll(rule);
        for (i = 0; i < nodes.length; i++) {
            highlight(nodes[i]);
        }
    }

    // insert a node
    function insertNode(payload, parent, index) {
        var node;
        if (payload.value) {
            node = document.createTextNode(payload.value);
        } else {
            node = document.createElement(payload.nodeName);
        }
        var sibling;
        if (index !== undefined) {
            sibling = parent.childNodes[index];
        }
        if (sibling) {
            parent.insertBefore(node, sibling);
        } else {
            parent.appendChild(node);
        }
        return node;
    }

    // log something (for testing)
    function log() {
        var i;
        for (i in arguments) {
            console.info(arguments[i]);
        }
    }

    // install event listeners

    /* FUTURE
    document.addEventListener("keyup", _onKeyUp);
    document.addEventListener("mousemove", _onMouse);
    document.addEventListener("mouseout", _onMouse);
    document.addEventListener("mousedown", _preventEventWhenMeta, true);
    document.addEventListener("mouseup", _preventEventWhenMeta, true);
    document.addEventListener("click", _onClick, true);
    */

    return {
        "showGoto": showGoto,
        "hideHighlight": hideHighlight,
        "highlight": highlight,
        "highlightRule": highlightRule,
        "insertNode": insertNode,
        "log": log
    };
}


//  When registering a factory function 'this' refers to the GameObjectFactory context.

//  There are several properties available to use:

//  this.scene - a reference to the Scene that owns the GameObjectFactory

//  this.displayList - a reference to the Display List the Scene owns

//  this.updateList - a reference to the Update List the Scene owns

var ArcadeImage = require('./ArcadeImage');
var ArcadeSprite = require('./ArcadeSprite');
var Class = require('../../utils/Class');
var CONST = require('./const');
var PhysicsGroup = require('./PhysicsGroup');
var StaticPhysicsGroup = require('./StaticPhysicsGroup');

var Factory = new Class({

    initialize:

    function Factory (world)
    {
        this.world = world;

        this.scene = world.scene;

        this.sys = world.scene.sys;
    },

    collider: function (object1, object2, collideCallback, processCallback, callbackContext)
    {
        return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext);
    },

    overlap: function (object1, object2, collideCallback, processCallback, callbackContext)
    {
        return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext);
    },

    staticImage: function (x, y, key, frame)
    {
        var image = new ArcadeImage(this.scene, x, y, key, frame);

        this.sys.displayList.add(image);

        this.world.enableBody(image, CONST.STATIC_BODY);

        return image;
    },

    image: function (x, y, key, frame)
    {
        var image = new ArcadeImage(this.scene, x, y, key, frame);

        this.sys.displayList.add(image);

        this.world.enableBody(image, CONST.DYNAMIC_BODY);

        return image;
    },

    staticSprite: function (x, y, key, frame)
    {
        var sprite = new ArcadeSprite(this.scene, x, y, key, frame);

        this.sys.displayList.add(sprite);
        this.sys.updateList.add(sprite);

        this.world.enableBody(sprite, CONST.STATIC_BODY);

        return sprite;
    },

    sprite: function (x, y, key, frame)
    {
        var sprite = new ArcadeSprite(this.scene, x, y, key, frame);

        this.sys.displayList.add(sprite);
        this.sys.updateList.add(sprite);

        this.world.enableBody(sprite, CONST.DYNAMIC_BODY);

        return sprite;
    },

    staticGroup: function (children, config)
    {
        return new StaticPhysicsGroup(this.world, this.world.scene, children, config);
    },

    group: function (children, config)
    {
        return new PhysicsGroup(this.world, this.world.scene, children, config);
    }

});

module.exports = Factory;


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Phaser Source: src/pixi/textures/Texture.js</title>

	<link type="text/css" rel="stylesheet" href="styles/default.css">

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			Phaser API

					Namespaces

							Phaser

							PIXI

					Classes

							Event

							EventTarget

							Animation

							AnimationManager

							AnimationParser

							ArraySet

							ArrayUtils

							AudioSprite

							BitmapData

							BitmapText

							Bullet

							Button

							Cache

							Camera

							Canvas

							Circle

							Color

							Angle

							Animation

							AutoCull

							Bounds

							BringToTop

							Core

							Crop

							Delta

							Destroy

							FixedToCamera

							Health

							InCamera

							InputEnabled

							InWorld

							LifeSpan

							LoadTexture

							Overlap

							PhysicsBody

							Reset

							ScaleMinMax

							Smoothed

							Create

							Creature

							Device

							DeviceButton

							DOM

							Easing

							Back

							Bounce

							Circular

							Cubic

							Elastic

							Exponential

							Linear

							Quadratic

							Quartic

							Quintic

							Sinusoidal

							Ellipse

							Events

							Filter

							FlexGrid

							FlexLayer

							Frame

							FrameData

							Game

							GameObjectCreator

							GameObjectFactory

							Gamepad

							Graphics

							Group

							Hermite

							Image

							ImageCollection

							Input

							InputHandler

							Key

							Keyboard

							KeyCode

							Line

							LinkedList

							Loader

							LoaderParser

							Math

							Matrix

							Mouse

							MSPointer

							Net

							Particle

							Particles

							Arcade

							Emitter

							Path

							PathFollower

							PathPoint

							Physics

							Arcade

							Body

							TilemapCollision

							Ninja

							AABB

							Body

							Circle

							Tile

							P2

							Body

							BodyDebug

							CollisionGroup

							ContactMaterial

							DistanceConstraint

							FixtureList

							GearConstraint

							InversePointProxy

							LockConstraint

							Material

							PointProxy

							PrismaticConstraint

							RevoluteConstraint

							RotationalSpring

							Spring

							Plugin

							PathManager

							PluginManager

							Point

							Pointer

							PointerMode

							Polygon

							QuadTree

							RandomDataGenerator

							Rectangle

							RenderTexture

							RequestAnimationFrame

							RetroFont

							Rope

							RoundedRectangle

							ScaleManager

							Signal

							SignalBinding

							SinglePad

							Sound

							SoundManager

							Sprite

							SpriteBatch

							Stage

							State

							StateManager

							Text

							Tile

							Tilemap

							TilemapLayer

							TilemapParser

							Tileset

							TileSprite

							Time

							Timer

							TimerEvent

							Touch

							Tween

							TweenData

							TweenManager

							Utils

							Debug

							Video

							Weapon

							World

							AbstractFilter

							BaseTexture

							CanvasBuffer

							CanvasGraphics

							CanvasMaskManager

							CanvasPool

							CanvasRenderer

							CanvasTinter

							ComplexPrimitiveShader

							DisplayObjectContainer

							EarCut

							Event

							EventTarget

							FilterTexture

							Graphics

							GraphicsData

							PIXI

							DisplayObject

							PixiFastShader

							PixiShader

							PrimitiveShader

							RenderTexture

							Rope

							Sprite

							SpriteBatch

							Strip

							StripShader

							Texture

							TilingSprite

							WebGLBlendModeManager

							WebGLFastSpriteBatch

							WebGLFilterManager

							WebGLRenderer

					Global

							ANGLE_DOWN

							ANGLE_LEFT

							ANGLE_NORTH_EAST

							ANGLE_NORTH_WEST

							ANGLE_RIGHT

							ANGLE_SOUTH_EAST

							ANGLE_SOUTH_WEST

							ANGLE_UP

							AUTO

							BITMAPDATA

							BITMAPTEXT

							blendModes

							BOTTOM_CENTER

							BOTTOM_LEFT

							BOTTOM_RIGHT

							BUTTON

							CANVAS

							CANVAS_FILTER

							CENTER

							CIRCLE

							CREATURE

							displayList

							DOWN

							ELLIPSE

							emit

							EMITTER

							GAMES

							GRAPHICS

							GROUP

							HEADLESS

							HORIZONTAL

							IMAGE

							LANDSCAPE

							LEFT

							LEFT_BOTTOM

							LEFT_CENTER

							LEFT_TOP

							LINE

							listeners

							MATRIX

							mixin

							NONE

							off

							on

							once

							PENDING_ATLAS

							Phaser.Path#numPoints
return {number} The total number of PathPoints in this Path.

							POINT

							POINTER

							POLYGON

							PORTRAIT

							RECTANGLE

							removeAllListeners

							RENDERTEXTURE

							RETROFONT

							RIGHT

							RIGHT_BOTTOM

							RIGHT_CENTER

							RIGHT_TOP

							ROPE

							ROUNDEDRECTANGLE

							scaleModes

							SPRITE

							SPRITEBATCH

							stopImmediatePropagation

							stopPropagation

							TEXT

							TILEMAP

							TILEMAPLAYER

							TILESPRITE

							TOP_CENTER

							TOP_LEFT

							TOP_RIGHT

							UP

							VERSION

							VERTICAL

							VIDEO

							WEBGL

							WEBGL_FILTER

					Core

Game

Group

World

Loader

Cache

Time

Camera

State Manager

Tween Manager

Sound Manager

Input Manager

Scale Manager

					Game Objects

Factory (game.add)

Creator (game.make)

Sprite

Image

Sound

Video

Particle Emitter

Particle

Text

Tween

BitmapText

Tilemap

BitmapData

RetroFont

Button

Animation

Graphics

RenderTexture

TileSprite

					Geometry

Circle

Ellipse

Line

Matrix

Point

Polygon

Rectangle

Rounded Rectangle

					Physics

Arcade Physics

Body

Weapon

P2 Physics

Body

Spring

CollisionGroup

ContactMaterial

Ninja Physics

Body

					Input

Input Handler

Pointer

Device Button

Mouse

Keyboard

Key

Key Codes

Gamepad

					Community

Phaser Web Site

Phaser Github

Phaser Examples

Phaser Plugins

Forum

Stack Overflow

Tutorials

Newsletter

Twitter

Slack

Donate

Texture Packer

Source: src/pixi/textures/Texture.js

/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * TextureSilentFail is a boolean that defaults to `false`.
 * If `true` then `PIXI.Texture.setFrame` will no longer throw an error if the texture dimensions are incorrect.
 * Instead `Texture.valid` will be set to `false` (#1556)
 *
 * @type {boolean}
 */
PIXI.TextureSilentFail = false;

/**
 * A texture stores the information that represents an image or part of an image. It cannot be added
 * to the display list directly. Instead use it as the texture for a PIXI.Sprite. If no frame is provided then the whole image is used.
 *
 * @class Texture
 * @uses EventTarget
 * @constructor
 * @param baseTexture {BaseTexture} The base texture source to create the texture from
 * @param frame {Rectangle} The rectangle frame of the texture to show
 * @param [crop] {Rectangle} The area of original texture
 * @param [trim] {Rectangle} Trimmed texture rectangle
 */
PIXI.Texture = function(baseTexture, frame, crop, trim)
{
    /**
     * Does this Texture have any frame data assigned to it?
     *
     * @property noFrame
     * @type Boolean
     */
    this.noFrame = false;

    if (!frame)
    {
        this.noFrame = true;
        frame = new PIXI.Rectangle(0,0,1,1);
    }

    if (baseTexture instanceof PIXI.Texture)
    {
        baseTexture = baseTexture.baseTexture;
    }

    /**
     * The base texture that this texture uses.
     *
     * @property baseTexture
     * @type BaseTexture
     */
    this.baseTexture = baseTexture;

    /**
     * The frame specifies the region of the base texture that this texture uses
     *
     * @property frame
     * @type Rectangle
     */
    this.frame = frame;

    /**
     * The texture trim data.
     *
     * @property trim
     * @type Rectangle
     */
    this.trim = trim;

    /**
     * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.
     *
     * @property valid
     * @type Boolean
     */
    this.valid = false;

    /**
     * Is this a tiling texture? As used by the likes of a TilingSprite.
     *
     * @property isTiling
     * @type Boolean
     */
    this.isTiling = false;

    /**
     * This will let a renderer know that a texture has been updated (used mainly for webGL uv updates)
     *
     * @property requiresUpdate
     * @type Boolean
     */
    this.requiresUpdate = false;

    /**
     * This will let a renderer know that a tinted parent has updated its texture.
     *
     * @property requiresReTint
     * @type Boolean
     */
    this.requiresReTint = false;

    /**
     * The WebGL UV data cache.
     *
     * @property _uvs
     * @type Object
     * @private
     */
    this._uvs = null;

    /**
     * The width of the Texture in pixels.
     *
     * @property width
     * @type Number
     */
    this.width = 0;

    /**
     * The height of the Texture in pixels.
     *
     * @property height
     * @type Number
     */
    this.height = 0;

    /**
     * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering,
     * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases)
     *
     * @property crop
     * @type Rectangle
     */
    this.crop = crop || new PIXI.Rectangle(0, 0, 1, 1);

    if (baseTexture.hasLoaded)
    {
        if (this.noFrame) frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height);
        this.setFrame(frame);
    }

};

PIXI.Texture.prototype.constructor = PIXI.Texture;

/**
 * Called when the base texture is loaded
 *
 * @method onBaseTextureLoaded
 * @private
 */
PIXI.Texture.prototype.onBaseTextureLoaded = function()
{
    var baseTexture = this.baseTexture;

    if (this.noFrame)
    {
        this.frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height);
    }

    this.setFrame(this.frame);
};

/**
 * Destroys this texture
 *
 * @method destroy
 * @param destroyBase {Boolean} Whether to destroy the base texture as well
 */
PIXI.Texture.prototype.destroy = function(destroyBase)
{
    if (destroyBase) this.baseTexture.destroy();

    this.valid = false;
};

/**
 * Specifies the region of the baseTexture that this texture will use.
 *
 * @method setFrame
 * @param frame {Rectangle} The frame of the texture to set it to
 */
PIXI.Texture.prototype.setFrame = function(frame)
{
    this.noFrame = false;

    this.frame = frame;
    this.width = frame.width;
    this.height = frame.height;

    this.crop.x = frame.x;
    this.crop.y = frame.y;
    this.crop.width = frame.width;
    this.crop.height = frame.height;

    if (!this.trim && (frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height))
    {
        if (!PIXI.TextureSilentFail)
        {
            throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this);
        }

        this.valid = false;
        return;
    }

    this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded;

    if (this.trim)
    {
        this.width = this.trim.width;
        this.height = this.trim.height;
        this.frame.width = this.trim.width;
        this.frame.height = this.trim.height;
    }

    if (this.valid) this._updateUvs();

};

/**
 * Updates the internal WebGL UV cache.
 *
 * @method _updateUvs
 * @private
 */
PIXI.Texture.prototype._updateUvs = function()
{
    if(!this._uvs)this._uvs = new PIXI.TextureUvs();

    var frame = this.crop;
    var tw = this.baseTexture.width;
    var th = this.baseTexture.height;

    this._uvs.x0 = frame.x / tw;
    this._uvs.y0 = frame.y / th;

    this._uvs.x1 = (frame.x + frame.width) / tw;
    this._uvs.y1 = frame.y / th;

    this._uvs.x2 = (frame.x + frame.width) / tw;
    this._uvs.y2 = (frame.y + frame.height) / th;

    this._uvs.x3 = frame.x / tw;
    this._uvs.y3 = (frame.y + frame.height) / th;
};

/**
 * Helper function that creates a new a Texture based on the given canvas element.
 *
 * @static
 * @method fromCanvas
 * @param canvas {Canvas} The canvas element source of the texture
 * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values
 * @return {Texture}
 */
PIXI.Texture.fromCanvas = function(canvas, scaleMode)
{
    var baseTexture = PIXI.BaseTexture.fromCanvas(canvas, scaleMode);

    return new PIXI.Texture(baseTexture);
};

PIXI.TextureUvs = function()
{
    this.x0 = 0;
    this.y0 = 0;

    this.x1 = 0;
    this.y1 = 0;

    this.x2 = 0;
    this.y2 = 0;

    this.x3 = 0;
    this.y3 = 0;
};

		Phaser Copyright © 2012-2016 Photon Storm Ltd.

		Documentation generated by JSDoc 3.4.0
		on Fri Aug 26 2016 01:16:09 GMT+0100 (BST) using the DocStrap template.