if (typeof global != "undefined" && typeof document == "undefined") {
  if (!global.TDev)
    global.TDev = { 
      window: { 
        document: { URL: "http://localhost/" },
        isNodeJS: true
      } 
    };
  var TDev      = global.TDev;
  var window    = global.TDev.window;
  var document  = global.TDev.window.document;
}
var TDev;
(function (TDev) {
    TDev.dbg = false;
    TDev.isBeta = false;
    (function (BrowserSoftware) {
        BrowserSoftware[BrowserSoftware["unknown"] = 0] = "unknown";
        BrowserSoftware[BrowserSoftware["ie10"] = 1] = "ie10";
        BrowserSoftware[BrowserSoftware["ie11"] = 2] = "ie11";
        BrowserSoftware[BrowserSoftware["ieOld"] = 3] = "ieOld";
        BrowserSoftware[BrowserSoftware["android2"] = 4] = "android2";
        BrowserSoftware[BrowserSoftware["android4"] = 5] = "android4";
        BrowserSoftware[BrowserSoftware["chrome"] = 6] = "chrome";
        BrowserSoftware[BrowserSoftware["chromeiOS"] = 7] = "chromeiOS";
        BrowserSoftware[BrowserSoftware["firefox"] = 8] = "firefox";
        BrowserSoftware[BrowserSoftware["safari"] = 9] = "safari";
        BrowserSoftware[BrowserSoftware["silkOld"] = 10] = "silkOld";
        BrowserSoftware[BrowserSoftware["silk"] = 11] = "silk";
        BrowserSoftware[BrowserSoftware["opera"] = 12] = "opera";
        BrowserSoftware[BrowserSoftware["nodeJS"] = 13] = "nodeJS";
        BrowserSoftware[BrowserSoftware["maxthon"] = 14] = "maxthon";
        BrowserSoftware[BrowserSoftware["bb10"] = 15] = "bb10";
    })(TDev.BrowserSoftware || (TDev.BrowserSoftware = {}));
    var BrowserSoftware = TDev.BrowserSoftware;
    var Browser;
    (function (Browser) {
        Browser.isNodeJS = false;
        Browser.isHeadless = false;
        Browser.isTouchDevice = false;
        Browser.isMobile = undefined;
        Browser.isCellphone = false;
        Browser.isTablet = false;
        Browser.isDesktop = false;
        Browser.isMobileSafari = false;
        Browser.isMobileSafariOld = false;
        Browser.isGecko = false;
        Browser.isTrident = false;
        Browser.isWebkit = false;
        Browser.isAndroid = false;
        Browser.isMacOSX = false;
        Browser.isWindows = false;
        Browser.isWindows8plus = false;
        Browser.isRaspberryPiDebian = false;
        Browser.isCompiledApp = false;
        Browser.isHosted = false;
        Browser.browser = 0 /* unknown */;
        Browser.browserVersion = 0;
        Browser.browserVersion2 = 0;
        Browser.webkitVersion = 0;
        Browser.isEmbedded = false;
        Browser.canIndexedDB = false;
        Browser.canWebSql = false;
        Browser.canMemoryTable = true;
        Browser.hasHardwareBack = false;
        Browser.localProxy = false;
        Browser.noAnimations = false;
        Browser.noStorage = false;
        Browser.isGenStubs = false;
        Browser.mobileWebkit = false;
        Browser.touchStart = false;
        Browser.webRunner = false;
        Browser.webAppImplicit = false;
        Browser.inCordova = false;
        Browser.inEditor = false;
        Browser.builtinTouchToPan = false;
        Browser.canLogin = true;
        Browser.canWriteLocalStorage;
        Browser.cscript = false;
        Browser.useConsoleLog = false;
        Browser.brokenColumns = false;
        Browser.assumeMouse = false;
        Browser.brokenGradient = false;
        Browser.deviceMotion = false;
        Browser.deviceOrientation = false;
        Browser.deviceHeading = false;
        Browser.audioDataUrls = true;
        Browser.audioWav = false;
        Browser.compilerInlining = false;
        Browser.compilerOkElimination = true;
        Browser.compilerBlockChaining = false;
        Browser.brokenBackButton = false;
        Browser.brokenResize = false;
        Browser.screenshots = false;
        Browser.setInnerHTML = function (el, html) {
            el.innerHTML = html;
        };
        Browser.dragAndDrop = false;
        Browser.videoTracks = true;
        Browser.directionAuto = true;
        Browser.notifyBackToHost = false;
        Browser.logToHost = false;
        Browser.noNetwork = false;
        Browser.lowMemory = false;
        Browser.serialLog = false;
        Browser.loadingDone = false;
        Browser.platformCaps = [];
        Browser.browserShortName = "unknown";
        Browser.startTimestamp = 0;
        function browserName(s) {
            var n = BrowserSoftware[s];
            return !n || s == 0 /* unknown */ ? "unknownBrowser" : n;
        }
        function setBrowserVersion(name) {
            var userAgent = window.navigator.userAgent;
            var idx = userAgent.indexOf(name + "/");
            if (idx >= 0) {
                var verNo = userAgent.slice(idx + name.length + 1);
                Browser.browserVersion = parseInt(verNo);
            }
            var m = userAgent.match(/Version\/(\d+)\./);
            if (m)
                Browser.browserVersion2 = parseInt(m[1]);
        }
        function detect() {
            var url = document ? document.URL : "";
            if (/dbg=[1t]/.test(url) || (window && window.localStorage && window.localStorage["dbg"]))
                TDev.dbg = true;
            if (/nodbg/.test(url))
                TDev.dbg = false;
            if (window.betaFriendlyId || TDev.dbg || /localhost/.test(url) || /consolelog/.test(url))
                TDev.isBeta = true;
            if (/nobeta/.test(url))
                TDev.isBeta = false;
            Browser.useConsoleLog = TDev.isBeta && !!console && !!console.log;
            Browser.startTimestamp = new Date().getTime();
            if (window.touchDevelopExec || window.mcefQuery || window.cordova) {
                Browser.isHosted = true;
                Browser.screenshots = true;
            }
            if (window.isNodeJS) {
                Browser.isNodeJS = true;
                Browser.isHeadless = true;
            }
            if (window.localProxy || Browser.isNodeJS) {
                Browser.localProxy = true;
            }
            if (window.cordova)
                Browser.inCordova = true;
            var userAgent = Browser.isNodeJS ? "NodeJS" : window.navigator.userAgent;
            var addCap = function (c) {
                Browser.platformCaps.push(c);
            };
            if (!Browser.isNodeJS) {
                Browser.webRunner = !!window.webRunner;
                Browser.webAppImplicit = !!window.webAppImplicit;
                Browser.deviceMotion = !!window.DeviceMotionEvent;
                Browser.deviceOrientation = !!window.DeviceOrientationEvent;
                Browser.deviceHeading = Browser.deviceOrientation;
            }
            var flags = (window.runtimeFlags || "").split(/,/);
            if (flags.indexOf("notifyBack") >= 0)
                Browser.notifyBackToHost = true;
            if (flags.indexOf("logToHost") >= 0)
                Browser.logToHost = true;
            if (flags.indexOf("noNetwork") >= 0)
                Browser.noNetwork = true;
            if (/Silk|Kindle/.test(userAgent)) {
                if (/ Android [123]\./.test(userAgent))
                    Browser.browser = 10 /* silkOld */;
                else
                    Browser.browser = 11 /* silk */;
                Browser.isTablet = true;
            }
            else if (/ Trident\/[7-9]/.test(userAgent)) {
                Browser.browser = 2 /* ie11 */;
                Browser.isMobile = / IEMobile\//.test(userAgent);
                if (Browser.isMobile)
                    Browser.isCellphone = true;
                else if (window.navigator.msMaxTouchPoints)
                    Browser.isTablet = true;
                else
                    Browser.isDesktop = true;
                Browser.hasHardwareBack = Browser.isCellphone;
                Browser.isTrident = true;
            }
            else if (/Maxthon\//.test(userAgent)) {
                Browser.browser = 14 /* maxthon */;
            }
            else if (/ Android /.test(userAgent)) {
                if (/ Chrome\//.test(userAgent)) {
                    Browser.browser = 6 /* chrome */;
                    setBrowserVersion("Chrome");
                }
                else if (/ Android [123]\./.test(userAgent))
                    Browser.browser = 4 /* android2 */;
                else
                    Browser.browser = 5 /* android4 */;
                if (/ Mobile /.test(userAgent))
                    Browser.isCellphone = true;
                else
                    Browser.isTablet = true;
                Browser.isAndroid = true;
                Browser.hasHardwareBack = true;
            }
            else if (/ Chrome\//.test(userAgent)) {
                Browser.browser = 6 /* chrome */;
                setBrowserVersion("Chrome");
                Browser.isDesktop = true;
            }
            else if (/ MSIE 1[0-9]/.test(userAgent)) {
                Browser.browser = 1 /* ie10 */;
                Browser.isMobile = / IEMobile\//.test(userAgent);
                if (Browser.isMobile)
                    Browser.isCellphone = true;
                else if (window.navigator.msMaxTouchPoints)
                    Browser.isTablet = true;
                else
                    Browser.isDesktop = true;
                Browser.hasHardwareBack = Browser.isCellphone;
                Browser.isTrident = true;
            }
            else if (/ MSIE [2-9]/.test(userAgent)) {
                Browser.browser = 3 /* ieOld */;
                Browser.isDesktop = true;
                Browser.isTrident = true;
            }
            else if (/BB10/.test(userAgent)) {
                Browser.browser = 15 /* bb10 */;
                Browser.isMobile = true;
                Browser.isCellphone = true;
            }
            else if (/\(iPad/.test(userAgent)) {
                Browser.browser = 9 /* safari */;
                setBrowserVersion("Version");
                Browser.isTablet = true;
                addCap("iPad");
            }
            else if (/\(iPhone/.test(userAgent)) {
                Browser.browser = 9 /* safari */;
                setBrowserVersion("Version");
                Browser.isCellphone = true;
                addCap("iPhone");
            }
            else if (/\(iPod/.test(userAgent)) {
                Browser.browser = 9 /* safari */;
                setBrowserVersion("Version");
                Browser.isCellphone = true;
                addCap("iPod");
            }
            else if (/Safari/.test(userAgent)) {
                Browser.browser = 9 /* safari */;
                setBrowserVersion("Version");
                Browser.isDesktop = true;
            }
            else if (/ Firefox\//.test(userAgent)) {
                Browser.browser = 8 /* firefox */;
                setBrowserVersion("Firefox");
                if (/Mobile/.test(userAgent))
                    Browser.isCellphone = true;
                else if (/Tablet/.test(userAgent))
                    Browser.isTablet = true;
                else
                    Browser.isDesktop = true;
                Browser.isAndroid = /Android/.test(userAgent);
                Browser.isGecko = true;
            }
            else if (/Opera\//.test(userAgent)) {
                Browser.browser = 12 /* opera */;
            }
            else if (/NodeJS/.test(userAgent)) {
                Browser.browser = 13 /* nodeJS */;
                Browser.useConsoleLog = true;
            }
            if (Browser.inCordova)
                addCap("cordova");
            if (Browser.isTrident) {
                Browser.videoTracks = false;
                Browser.directionAuto = false;
            }
            if (/lowMemory/.test(url))
                Browser.lowMemory = true;
            if (/noAnim/.test(url))
                Browser.noAnimations = true;
            Browser.isTouchDevice = Browser.isCellphone || Browser.isTablet;
            if (Browser.isMobile === undefined)
                Browser.isMobile = Browser.isTouchDevice;
            Browser.isWebkit = /WebKit/.test(userAgent);
            if (Browser.isWebkit) {
                var m = userAgent.match(/WebKit\/(\d+)\./);
                if (m)
                    Browser.webkitVersion = parseInt(m[1]);
            }
            Browser.isMacOSX = /Macintosh/.test(userAgent);
            if (/Windows NT/.test(userAgent))
                Browser.isWindows = true;
            if (/Windows NT (6.[2-9]|[789])/.test(userAgent))
                Browser.isWindows8plus = true;
            Browser.mobileWebkit = Browser.isWebkit && Browser.isMobile;
            if (!Browser.isMobile)
                Browser.assumeMouse = true;
            Browser.builtinTouchToPan = true;
            Browser.isMobileSafari = (Browser.browser == 9 /* safari */ && Browser.isMobile);
            if (Browser.isMobileSafari) {
                var m = userAgent.match(/Safari\/([^.]*)/);
                Browser.isMobileSafariOld = (!Browser.browserVersion || Browser.browserVersion < 8) && m && m.length > 1 && parseInt(m[1]) < 7534;
            }
            if (Browser.isMobileSafari && !/Safari/.test(userAgent) && !window.navigator.standalone) {
                Browser.isEmbedded = true;
            }
            if ((Browser.browser == 1 /* ie10 */ || Browser.browser == 2 /* ie11 */) && !window.applicationCache) {
                Browser.isEmbedded = true;
            }
            var w = window;
            if (w.indexedDB || w.mozIndexedDB || w.msIndexedDB) {
                Browser.canIndexedDB = true;
            }
            if (w.openDatabase || Browser.inCordova) {
                Browser.canWebSql = true;
            }
            if (Browser.isMobile && Browser.browser == 9 /* safari */ && /CriOS/.test(userAgent)) {
                Browser.browser = 7 /* chromeiOS */;
                setBrowserVersion("CriOS");
            }
            if (Browser.isWebkit) {
                if (!Browser.isMobileSafari)
                    Browser.brokenColumns = true;
                if (Browser.isAndroid)
                    Browser.brokenGradient = true;
            }
            if (Browser.isDesktop) {
                Browser.deviceMotion = false;
                Browser.deviceOrientation = false;
            }
            if (Browser.isMobileSafari && Browser.webkitVersion >= 537) {
                Browser.brokenBackButton = true;
                Browser.brokenResize = true;
            }
            if (/Linux armv7/.test(userAgent)) {
                Browser.isRaspberryPiDebian = true;
                Browser.noAnimations = true;
                Browser.noStorage = true;
                Browser.lowMemory = true;
            }
            Browser.browserShortName = browserName(Browser.browser);
            if (Browser.isCellphone)
                Browser.browserShortName += ".phone";
            else if (Browser.isTablet)
                Browser.browserShortName += ".tablet";
            else
                Browser.browserShortName += ".desktop";
            if (Browser.inCordova)
                Browser.browserShortName += ".cordova";
            addCap(Browser.browserShortName);
            addCap(browserName(Browser.browser));
            if (Browser.isCellphone)
                addCap("cellphone");
            if (Browser.isTablet)
                addCap("tablet");
            if (Browser.isTouchDevice)
                addCap("touch");
            if (Browser.isMobile)
                addCap("mobile");
            if (Browser.isMacOSX)
                addCap("macOSX");
            if (Browser.assumeMouse)
                addCap("assumeMouse");
            if (Browser.isWindows8plus) {
                addCap("win");
                addCap("win8plus");
            }
            if (Browser.isAndroid)
                addCap("android");
            if (/X11/.test(userAgent))
                addCap("x11");
            if (/Windows NT 5.1/.test(userAgent)) {
                addCap("win");
                addCap("winXP");
            }
            if (/Windows NT 6.0/.test(userAgent)) {
                addCap("win");
                addCap("winVista");
            }
            if (/Windows NT 6.1/.test(userAgent)) {
                addCap("win");
                addCap("win7");
            }
            if (Browser.isMobileSafari || (Browser.isMobile && (Browser.browser == 1 /* ie10 */ || Browser.browser == 2 /* ie11 */))) {
                Browser.audioDataUrls = false;
            }
            if (Browser.mobileWebkit)
                Browser.touchStart = true;
            Browser.canWriteLocalStorage = false;
            if (typeof window == "object" && typeof window.localStorage == "object" && window.localStorage.removeItem)
                try {
                    var s = Browser.startTimestamp + "";
                    window.localStorage["test"] = s;
                    if (window.localStorage["test"] == s) {
                        Browser.canWriteLocalStorage = true;
                        window.localStorage.removeItem("test");
                    }
                }
                catch (e) {
                }
            Browser.dragAndDrop = !Browser.isNodeJS && !Browser.isMobile && document && document.createElement && 'draggable' in document.createElement('span');
        }
        Browser.detect = detect;
        var getServiceUrl = function () { return (window.rootUrl); };
        function unsupportedMessage(what, path) {
            if (what === void 0) { what = "Touch Develop"; }
            if (path === void 0) { path = ""; }
            var message = function (problemHTML, fixHTML) {
                if (fixHTML === void 0) { fixHTML = undefined; }
                return { problemHTML: problemHTML, fixHTML: fixHTML };
            };
            var genericMessage = function (problemHTML, upgradedBrowserName) {
                if (upgradedBrowserName === void 0) { upgradedBrowserName = undefined; }
                return message(problemHTML, upgradedBrowserName ? "<p>Follow these easy steps to run " + what + " on your device:</p>" + "<ol class='light'><li>open <b>" + upgradedBrowserName + "</b></li><li>navigate to <u>" + path + "</u></li></ol>" + "<p>You can copy&amp;paste the link into " + upgradedBrowserName + ".</p>" : undefined);
            };
            if (Browser.isEmbedded)
                return genericMessage("<p>It seems you're running " + what + " inside of another app.</p>", "your regular internet browser");
            var olderAndroidMessage = function (problemHTML) { return message(problemHTML, "<p>Follow these easy steps to run " + what + " on Android:</p>" + "<ol class='light'><li><b>try to install the latest <a href='market://details?id=org.mozilla.firefox&hl=en'>Firefox Browser</a></b> from the Google Play Store</li>" + "<li>open <u>" + path + "</u> in the Chrome Browser</li></ol>" + "<p>You can copy&amp;paste the link into Firefox.</p>"); };
            var chromeAndroidMessage = function (problemHTML) { return message(problemHTML, "<p>Follow these easy steps to run " + what + " on Android:</p>" + "<ol class='light'><li><b>install the latest <a href='market://details?id=com.android.chrome&hl=en'>Chrome Browser</a> or <a href='market://details?id=org.mozilla.firefox&hl=en'>Firefox Browser</a> or <a href='market://details?id=com.opera.browser&hl=en'>Opera Browser</a> </b> from the Google Play Store</li>" + "<li>open <u>" + path + "</u> in the Chrome Browser</li></ol>" + "<p>You can copy&amp;paste the link into the installed browser.</p>"); };
            var upgradeMessage = function (problemHTML) { return message(problemHTML, "<p>Follow these easy steps to run " + what + " on your device:</p>" + "<ol class='light'><li>upgrade your browser to the latest version</li><li>navigate to <u>" + path + "</u></li></ol>" + "<p>You can copy&amp;paste the link into your upgraded browser.</p>"); };
            switch (Browser.browser) {
                case 3 /* ieOld */:
                    return message(what + " does not work with Internet Explorer versions earlier than 10.");
                case 10 /* silkOld */:
                    return message(what + " does not work with the Silk browser in Kindle Fire 1st Gen. Please upgrade to Kindle Fire 2nd Gen or Kindle Fire HD.");
                case 12 /* opera */:
                    return genericMessage(what + " does not work with Opera. Please use Internet Explorer 10+, Chrome or Firefox.", "one of the suggested browsers");
                case 9 /* safari */:
                    if (Browser.isMobileSafariOld)
                        return upgradeMessage("Please upgrade to the latest version of iOS / Safari.");
                    if (Browser.isMacOSX && Browser.browserVersion2 < 6)
                        return genericMessage("Safari 5 and older are not supported. Please upgrade Safari or <a href='http://www.google.com/mac/'>install Chrome</a> or <a href='http://www.mozilla.org/en-US/firefox/new/'>Firefox</a>.", "the upgraded browser");
                    if (Browser.isTouchDevice)
                        break;
                    if (Browser.isMacOSX)
                        break;
                    return genericMessage(what + " is not supported in Safari on a PC. Please use Internet Explorer 10 or better, Chrome or Firefox.", "one of the suggested browsers");
                case 4 /* android2 */:
                    return olderAndroidMessage(what + " might require a newer version of Android.");
                case 5 /* android4 */:
                    return chromeAndroidMessage(what + " is not supported in the stock Android browser.");
                case 8 /* firefox */:
                    if (Browser.browserVersion < 16)
                        return upgradeMessage("You are using an outdated version of Firefox.");
                    if (Browser.isAndroid && Browser.browserVersion < 29)
                        return upgradeMessage("Please upgrade to the latest version of Firefox for Android.");
                    break;
                case 6 /* chrome */:
                    if (Browser.isMobileSafari && Browser.browserVersion < 38)
                        return upgradeMessage("<p>You are using an outdated version of Chrome.</p>");
                    if (Browser.isMobile && Browser.browserVersion < 19)
                        return chromeAndroidMessage("<p>You are using an outdated browser.</p>");
                    if (!Browser.isMobile && Browser.browserVersion < 21)
                        return upgradeMessage("<p>You are using an outdated version of Chrome.</p>");
                    break;
                case 7 /* chromeiOS */:
                    if (window.bbcMicrobit)
                        return message(what + " is not supported in Chrome for iOS. Please use Safari instead.");
                    break;
                case 1 /* ie10 */:
                    break;
                case 15 /* bb10 */:
                    break;
                case 14 /* maxthon */:
                case 0 /* unknown */:
                    return genericMessage(what + " is not supported in the current browser.", "<a href='/app/.browsers#supported'>a supported browser</a>");
            }
            if (!Browser.canWriteLocalStorage) {
                if (Browser.browser == 9 /* safari */)
                    return message("<p>You are running Safari in Private Mode or Private Browsing. " + what + " does not support this mode.</p>", "<p><b>Please disable Private Mode or Private Browsing, and then try again.</b></p>" + "<ul>" + "<li>In iOS 6, open 'Settings', select 'Safari', and turn 'Private Browsing' off.</li>" + "<li>In iOS 7, 8 and 8.1, open 'Safari', tap on the Bookmarks button, then tap on the 'Private' button in the lower left corner of the screen.</li>" + "</ul>");
                else
                    return genericMessage("<p>" + what + " does not seem to allow storing data.</p>", "regular internet browser");
            }
            Browser.canMemoryTable = !window.localStorage["disableMemoryTable"];
            if (!Browser.canWebSql && !Browser.canIndexedDB && !Browser.canMemoryTable) {
                if (Browser.browser == 1 /* ie10 */ || Browser.browser == 2 /* ie11 */)
                    return genericMessage("<p>You are running Internet Explorer in the InPrivate mode. " + what + " does not support this mode, as " + what + " needs to maintain a database of installed scripts, but the InPrivate mode does not allow the use of databases.</p>", "a regular Internet Explorer window");
                else
                    return genericMessage("<p>Your browser does not seem to support databases.</p>", "<a href='/app/.browsers#supported'>a supported browser </a>");
            }
            return null;
        }
        function supportMemoryTable(value) {
            if (value) {
                if (Browser.canWriteLocalStorage)
                    window.localStorage.removeItem('disableMemoryTable');
                Browser.canMemoryTable = true;
            }
            else {
                if (Browser.canWriteLocalStorage)
                    window.localStorage["disableMemoryTable"] = "1";
                Browser.canMemoryTable = false;
            }
        }
        Browser.supportMemoryTable = supportMemoryTable;
        function browsersHtml() {
            var url = window.browsersUrl;
            if (url)
                window.location.href = window.browsersUrl;
        }
        function supportedBrowsers(descriptionHTML, fixHTML) {
            if (fixHTML === void 0) { fixHTML = undefined; }
            var e = document.getElementById("browserMessage");
            if (e) {
                var happy = window.browserSupported;
                e.innerHTML = (happy ? "" : fixHTML ? "<p>There is only a slight problem:</p>" : "<p>There is a problem:</p>") + descriptionHTML;
                if (happy)
                    e.style.color = "green";
                if (fixHTML) {
                    e = document.getElementById("browserAlmost");
                    if (e)
                        e.innerHTML = "<p>You are almost there!</p>";
                    e = document.getElementById("browserFix");
                    if (e)
                        e.innerHTML = fixHTML;
                }
            }
            e = document.getElementById("userAgent");
            if (e)
                e.innerText = "User Agent: " + window.navigator.userAgent;
        }
        function reportBrowser(browser) {
            try {
                if (window.tdlite)
                    return;
                var serviceUrl = getServiceUrl();
                if (!serviceUrl)
                    return;
                if (window.localStorage) {
                    if (window.localStorage["browserReported"])
                        return;
                    try {
                        window.localStorage["browserReported"] = "1";
                    }
                    catch (e) {
                    }
                }
                var now = new Date();
                var userAgent = window.navigator.userAgent;
                var dateStr = now.getFullYear() + "." + (now.getMonth() + 1) + "." + now.getDate();
                var se = {};
                se["browser." + browser] = 1;
                var ticksReq = {
                    dateStr: dateStr,
                    sessionEvents: se,
                    platform: [],
                    jsUrl: window.mainJsName
                };
                var client = new XMLHttpRequest();
                client.open("POST", serviceUrl + "/api/ticks");
                client.send(JSON.stringify(ticksReq));
                if (browser == "unknown") {
                    var msg = "Unsupported-" + browser;
                    var bug = {
                        exceptionConstructor: msg,
                        exceptionMessage: msg,
                        context: "detection",
                        currentUrl: "",
                        scriptId: "",
                        stackTrace: "browserNotSupported",
                        sourceURL: "",
                        line: -1,
                        eventTrace: "",
                        userAgent: userAgent,
                        resolution: "",
                        jsUrl: window.mainJsName,
                        timestamp: now.getTime(),
                        platform: [],
                    };
                    var client = new XMLHttpRequest();
                    client.open("POST", serviceUrl + "/api/bug");
                    client.send(JSON.stringify(bug));
                }
            }
            catch (e) {
            }
        }
        function statusMsg(m) {
            var f = window.statusMsg;
            if (f)
                f(m);
        }
        function check(isIndex, what, path) {
            if (what === void 0) { what = undefined; }
            if (path === void 0) { path = undefined; }
            if (window.isNodeJS) {
                detect();
                return;
            }
            statusMsg("browser detector started");
            var userAgent = window.navigator.userAgent;
            if (/ IEMobile\/[3-9]/.test(userAgent)) {
                statusMsg("IEMobile userAgent: " + userAgent);
                if (isIndex) {
                    reportBrowser("IEMobile");
                    browsersHtml();
                }
                else
                    supportedBrowsers("<p>The " + what + " Web App doesn't work on Windows Phone 7.</p>");
            }
            else if (/ MSIE [6789]/.test(userAgent)) {
                statusMsg("IEx userAgent: " + userAgent);
                if (isIndex) {
                    if (/ MSIE 9/.test(userAgent))
                        reportBrowser("IE9");
                    else
                        reportBrowser("IE8-");
                    browsersHtml();
                }
                else {
                    supportedBrowsers("<p>" + what + " doesn't work with Internet Explorer 9 or earlier.<p/>", '<p>You can upgrade your browser to <a href="http://windows.microsoft.com/en-us/internet-explorer/downloads/ie-10/worldwide-languages">Internet Explorer 10</a> if you are running Windows 7, ' + 'or upgrade your operating system to <a href="http://windows.microsoft.com/en-US/windows/buy">Windows 8</a> which comes with Internet Explorer 10, or try the latest version of Chrome or Firefox.</p>');
                }
            }
            else {
                statusMsg("browser detector processing");
                detect();
                var um = unsupportedMessage(what, path);
                if (!um || /ignoreAgent/.test(document.URL) || Browser.inCordova) {
                    statusMsg("browser detector success: " + Browser.browserShortName);
                    window.browserSupported = true;
                    if (isIndex)
                        reportBrowser(Browser.browserShortName);
                    else
                        supportedBrowsers("<p>Your browser is supported.</p>");
                }
                else {
                    statusMsg("browser detector failed: " + Browser.browserShortName);
                    if (isIndex) {
                        reportBrowser(Browser.browserShortName);
                        browsersHtml();
                    }
                    else {
                        supportedBrowsers(um.problemHTML, um.fixHTML);
                    }
                }
            }
        }
        Browser.check = check;
    })(Browser = TDev.Browser || (TDev.Browser = {}));
})(TDev || (TDev = {}));
'use strict';
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var RTValue = (function () {
            function RTValue() {
                this.on_render_heap = false;
                this.versioncounter = 1;
                this.jsonExportMark = false;
            }
            RTValue.normalize = function (n) {
                return n < 0 ? 0 : n > 1 ? 1 : n;
            };
            RTValue.prototype.post_to_wall = function (s) {
                if (!s.rt.mayPostToWall(s.rt.getCurrentPage()))
                    TDev.Util.userError("cannot post to the wall here");
                var box = TDev.WallBox.CreateOrRecycleLeafBox(s.rt, this);
                if (!box.getContent()) {
                    var e;
                    try {
                        e = this.getViewCore(s, box);
                    }
                    catch (e) {
                        TDev.Util.reportError('getViewCore crash: ' + (typeof this), e, false);
                        e = TDev.div('item item-crash', ':( something went wrong');
                    }
                    if (box instanceof TDev.WallBox)
                        s.rt.addTapEvent(e, this.rtType(), box, this);
                    box.setContent(e);
                    try {
                        this.updateViewCore(s, box);
                    }
                    catch (e) {
                        TDev.Util.reportError('updateViewCore crash: ' + (typeof this), e, false);
                    }
                }
                if (box instanceof TDev.WallBox && box.getDepth() === 1)
                    s.rt.renderBox(box);
            };
            RTValue.prototype.viewIsRefreshable = function () {
                return false;
            };
            RTValue.prototype.refreshViews = function (s) {
            };
            RTValue.prototype.debuggerDisplay = function (clickHandler) {
                return TDev.div("wall-text", this.getShortStringRepresentation()).withClick(clickHandler);
            };
            RTValue.prototype.getViewCore = function (s, b) {
                return TDev.div("wall-text", this.getShortStringRepresentation());
            };
            RTValue.prototype.updateViewCore = function (s, b) {
            };
            RTValue.prototype.getShortStringRepresentation = function () {
                try {
                    if (this.to_string)
                        return this.to_string();
                    else
                        return this.toString();
                }
                catch (e) {
                    TDev.Util.reportError("getShortStringRepresentation", e, false);
                    return "???";
                }
            };
            RTValue.prototype.toString = function () {
                return "[" + this.rtType() + "]";
            };
            RTValue.prototype.isSerializable = function () {
                return false;
            };
            RTValue.prototype.rtType = function () {
                return "RTValue";
            };
            RTValue.mkPicker = function (p, v, n, qn) {
                var fp = p;
                p.set(v);
                fp.userName = n;
                fp.quotedName = qn;
                return fp;
            };
            RTValue.prototype.exportJson = function (ctx) {
                return undefined;
            };
            RTValue.prototype.importJson = function (ctx, json) {
                return undefined;
            };
            RTValue.prototype.jsonExportKey = function (ctx) {
                return undefined;
            };
            RTValue.prototype.toJsonKey = function () {
                throw new Error("cannot use " + this.rtType() + " as a key (it is not a value)");
            };
            RTValue.prototype.keyCompareTo = function (other) {
                throw new Error("cannot use " + this.rtType() + " as a key (it is not a value)");
            };
            RTValue.prototype.isDefaultValue = function () {
                return false;
            };
            RTValue.CompareKeys = function (a, b) {
                if (!a)
                    return (b ? -1 : 0);
                else
                    return (b ? a.keyCompareTo(b) : 1);
            };
            RTValue.copySpecificImpls = function (classPrefix) {
                var rt = TDev.RT;
                var moduleOverrides = rt[classPrefix];
                Object.keys(moduleOverrides).forEach(function (k) {
                    if (/Init$/.test(k)) {
                        var f = moduleOverrides[k];
                        if (f instanceof Function)
                            f();
                    }
                });
                var rx = new RegExp("^" + classPrefix);
                function copyFrom(src) {
                    Object.keys(src).forEach(function (k) {
                        if (rx.test(k)) {
                            var baseName = k.slice(classPrefix.length);
                            var derived = src[k].prototype;
                            if (!derived)
                                return;
                            var base = rt[baseName].prototype;
                            Object.keys(derived).forEach(function (m) {
                                if (m != "constructor" && m != "rtType")
                                    base[m] = derived[m];
                            });
                        }
                    });
                }
                copyFrom(rt);
                copyFrom(moduleOverrides);
            };
            RTValue.setupTypeTable = function () {
                var setClsName = function (name, fn) {
                    fn.prototype.rtType = function () { return name; };
                };
                for (var cls in TDev.RT) {
                    if (!TDev.RT.hasOwnProperty(cls))
                        continue;
                    var fn = TDev.RT[cls];
                    if (fn.prototype && fn.prototype.rtType && !fn.prototype.noMagicRtType) {
                        if (!fn.prototype.hasOwnProperty("rtType"))
                            setClsName(cls, fn);
                    }
                }
            };
            RTValue.initApis = function () {
                RTValue.setupTypeTable();
                if (TDev.Browser.isNodeJS)
                    this.copySpecificImpls("Node");
                else if (TDev.Browser.inCordova)
                    this.copySpecificImpls("Cordova");
            };
            return RTValue;
        })();
        RT.RTValue = RTValue;
        var DisposableHandler = (function () {
            function DisposableHandler(handler) {
                this.handler = handler;
            }
            DisposableHandler.prototype.dispose = function () {
                this.handler();
            };
            return DisposableHandler;
        })();
        RT.DisposableHandler = DisposableHandler;
        var RTDisposableValue = (function (_super) {
            __extends(RTDisposableValue, _super);
            function RTDisposableValue(rt) {
                _super.call(this);
                this.rt = rt;
                this.rt.disposables.push(this);
            }
            RTDisposableValue.prototype.dispose = function () {
                var i = this.rt.disposables.indexOf(this);
                if (i > 0)
                    this.rt.disposables.splice(i, 1);
            };
            return RTDisposableValue;
        })(RTValue);
        RT.RTDisposableValue = RTDisposableValue;
        var DecoratorCollection = (function (_super) {
            __extends(DecoratorCollection, _super);
            function DecoratorCollection() {
                _super.call(this);
            }
            return DecoratorCollection;
        })(RTValue);
        RT.DecoratorCollection = DecoratorCollection;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
'use strict';
var TDev;
(function (TDev) {
    var JsonExportCtx = (function () {
        function JsonExportCtx(stackframe, fullcloudstate) {
            if (fullcloudstate === void 0) { fullcloudstate = false; }
            this.stackframe = stackframe;
            this.fullcloudstate = fullcloudstate;
            this.depth = 0;
        }
        JsonExportCtx.prototype.push = function (node) {
            TDev.Util.assert(!node.jsonExportMark);
            node.jsonExportMark = true;
            this.depth++;
        };
        JsonExportCtx.prototype.pop = function (node) {
            TDev.Util.assert(node.jsonExportMark);
            node.jsonExportMark = false;
            this.depth--;
        };
        JsonExportCtx.prototype.encodeObjectNode = function (node, keys, vals) {
            TDev.Util.assert(keys.length == vals.length);
            var json = {};
            var exportkey = node.jsonExportKey(this);
            if (exportkey)
                json["⌹id"] = exportkey;
            this.encodeValues(vals);
            for (var i = 0; i < vals.length; i++) {
                var val = vals[i];
                if (val !== undefined)
                    json[keys[i]] = val;
            }
            return json;
        };
        JsonExportCtx.prototype.encodeArrayNode = function (node, vals) {
            TDev.Util.assert(!node.jsonExportKey(this));
            this.encodeValues(vals);
            return vals;
        };
        JsonExportCtx.prototype.encodeValues = function (vals) {
            var recursed;
            for (var i = 0; i < vals.length; i++) {
                var v = vals[i];
                if (v && (v instanceof TDev.RT.RTValue)) {
                    var k = v.jsonExportKey(this);
                    if (k !== undefined) {
                        if (v.jsonExportMark || (this.fullcloudstate && this.depth > 0)) {
                            vals[i] = k;
                        }
                        else {
                            v.jsonExportMark = true;
                            if (!recursed)
                                recursed = new Array();
                            recursed.push(v);
                        }
                    }
                }
            }
            for (var i = 0; i < vals.length; i++) {
                var val = vals[i];
                if (val !== undefined && val !== null) {
                    var t = typeof val;
                    if (t == "function")
                        vals[i] = undefined;
                    else if (t !== "boolean" && t !== "string" && t !== "number")
                        vals[i] = val.exportJson(this);
                }
            }
            if (recursed)
                recursed.forEach(function (rv) {
                    TDev.Util.assert(rv.jsonExportMark);
                    rv.jsonExportMark = false;
                });
        };
        return JsonExportCtx;
    })();
    TDev.JsonExportCtx = JsonExportCtx;
    var JsonImportCtx = (function () {
        function JsonImportCtx(s) {
            this.s = s;
            this.mapping = {};
        }
        JsonImportCtx.prototype.map = function (table, id) {
            return id ? (this.mapping[table + id] || id) : id;
        };
        JsonImportCtx.prototype.addmapping = function (table, from, to) {
            this.mapping[table + from] = to;
        };
        JsonImportCtx.prototype.importString = function (source, key) {
            var v = source ? source[key] : undefined;
            return (typeof v == "string") ? v : undefined;
        };
        JsonImportCtx.prototype.importNumber = function (source, key) {
            var v = source ? source[key] : undefined;
            if (typeof v == "string")
                v = Number(v);
            return (typeof v == "number") ? v : undefined;
        };
        JsonImportCtx.prototype.importBoolean = function (source, key) {
            var v = source ? source[key] : undefined;
            return (typeof v == "boolean") ? v : undefined;
        };
        JsonImportCtx.prototype.importDateTime = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.DateTime.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importColor = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.Color.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importJsonObject = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.JsonObject.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importLocation = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.Location_.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importVector3 = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.Vector3.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importUser = function (source, key) {
            var v = source ? source[key] : undefined;
            return TDev.RT.User.mkFromJson(this, v);
        };
        JsonImportCtx.prototype.importStringMap = function (source, target, key) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target)
                target = new TDev.RT.StringMap();
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importNumberMap = function (source, target, key) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target)
                target = new TDev.RT.NumberMap();
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importCollection = function (source, target, key, typeInfo) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target) {
                target = TDev.RT.Collection.fromArray([], typeInfo);
            }
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importJsonBuilder = function (source, target, key) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target)
                target = new TDev.RT.JsonBuilder();
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importLink = function (source, target, key) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target)
                target = new TDev.RT.Link();
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importOAuthResponse = function (source, target, key) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            if (!target)
                target = new TDev.RT.OAuthResponse();
            return target.importJson(this, v);
        };
        JsonImportCtx.prototype.importRecord = function (source, target, key, singleton) {
            var v = source ? source[key] : undefined;
            if (!v)
                return undefined;
            return singleton.importJsonRecord(this, target, v, false);
        };
        return JsonImportCtx;
    })();
    TDev.JsonImportCtx = JsonImportCtx;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Cloud;
    (function (Cloud) {
        Cloud.lite = true;
        Cloud.fullTD = true;
        Cloud.litePermissions = {};
        Cloud._migrate;
        Cloud.useNativeCompilation = false;
        Cloud.config = {
            searchApiKey: "E43690E2B2A39FEB68117546BF778DB8",
            searchUrl: "https://tdsearch.search.windows.net",
            cdnUrl: "https://az31353.vo.msecnd.net",
            primaryCdnUrl: "https://az31353.vo.msecnd.net",
            altCdnUrls: [
                "https://az31353.vo.msecnd.net",
                "https://touchdevelop.blob.core.windows.net",
                "http://cdn.touchdevelop.com",
            ],
            translateCdnUrl: "https://tdtutorialtranslator.blob.core.windows.net",
            translateApiUrl: "https://tdtutorialtranslator.azurewebsites.net/api",
            workspaceUrl: null,
            rootUrl: "https://www.touchdevelop.com",
            shareUrl: "http://tdev.ly",
            hashtag: "#TouchDevelop",
            liteVersion: null,
            helpPath: "/docs",
            specHelpPaths: {},
            topicPath: "/docs/",
            legalButtons: [
                { name: "terms of use", url: "/terms-of-use" },
                { name: "privacy and cookies", url: "/privacy" },
                { name: "support", url: "https://touchdevelop.uservoice.com" }
            ],
            doNothingText: "do nothing",
            hintLevel: "full",
            userVoice: "touchdevelop",
            tutorialsid: "vjsseqks",
            showcaseid: "njigpnyj",
            primaryLocale: "en-US",
            cloudId: "touchdevelop.com",
            scriptRenderers: {
                "blocks": function (id) {
                    var url = TDev.Ticker.mainJsName.replace(/main.js$/, "");
                    var match = url.match(/(https?:\/\/[^\/]+)(.*)/);
                    var origin = match[1];
                    if (/http:\/\/localhost/.test(origin))
                        origin += "/editor/local";
                    return origin + "/blockly/render.html?id=" + encodeURIComponent(id);
                }
            },
            microbitGitTag: "v79"
        };
        function isArtUrl(url) {
            if (!url)
                return false;
            if (/\.\/art\//i.test(url))
                return true;
            for (var i = 0; i < Cloud.config.altCdnUrls.length; ++i) {
                var pubUrl = Cloud.config.altCdnUrls[i] + "/pub/";
                if (url.substr(0, pubUrl.length) == pubUrl)
                    return true;
            }
            return false;
        }
        Cloud.isArtUrl = isArtUrl;
        function stripCdnUrl(url) {
            if (!isArtUrl(url))
                return null;
            return url.replace(/^.*?\/pub\//, "");
        }
        function toCdnUrl(url, thumbContainer) {
            if (thumbContainer === void 0) { thumbContainer = ""; }
            if (!thumbContainer)
                thumbContainer = "pub";
            var tmp = stripCdnUrl(url);
            if (tmp)
                return Cloud.config.primaryCdnUrl + "/" + thumbContainer + "/" + tmp;
            else
                return url;
        }
        Cloud.toCdnUrl = toCdnUrl;
        function getArtId(url) {
            var tmp = stripCdnUrl(url);
            if (/^\w+/.test(tmp))
                return tmp;
            else
                return null;
        }
        Cloud.getArtId = getArtId;
        function artCssImg(id, thumb) {
            if (thumb === void 0) { thumb = false; }
            return TDev.HTML.cssImage(Cloud.artUrl(id, thumb));
        }
        Cloud.artCssImg = artCssImg;
        function artUrl(id, thumb) {
            if (thumb === void 0) { thumb = false; }
            return id ? TDev.HTML.proxyResource(TDev.Util.fmt("{0}/{1}/{2:uri}", Cloud.config.primaryCdnUrl, thumb ? "thumb" : "pub", id)) : undefined;
        }
        Cloud.artUrl = artUrl;
        function setPermissions(perms) {
            if (perms === void 0) { perms = null; }
            if (perms !== null)
                localStorage['litePermissions'] = perms;
            Cloud.litePermissions = {};
            (localStorage['litePermissions'] || "").split(",").forEach(function (t) {
                if (t)
                    Cloud.litePermissions[t] = true;
            });
            if (/http:\/\/localhost/i.test(document.URL))
                Cloud.litePermissions['internal'] = true;
        }
        Cloud.setPermissions = setPermissions;
        function hasPermission(perm) {
            return Cloud.litePermissions.hasOwnProperty(perm) || Cloud.litePermissions.hasOwnProperty("admin");
        }
        Cloud.hasPermission = hasPermission;
        function isRestricted() {
            return !Cloud.fullTD;
        }
        Cloud.isRestricted = isRestricted;
        function getServiceUrl() {
            return Cloud.config.rootUrl;
        }
        Cloud.getServiceUrl = getServiceUrl;
        function mkLegalDiv() {
            var link = function (text, lnk) { return TDev.HTML.mkA(null, getServiceUrl() + lnk, "_blank", text); };
            return TDev.div("wall-dialog-body", TDev.div("smallText", TDev.lf("Publishing is subject to our "), link(TDev.lf("terms of use"), "/terms-of-use"), TDev.lf(". Please read our "), link(TDev.lf("privacy policy"), "/privacy"), "."));
        }
        Cloud.mkLegalDiv = mkLegalDiv;
        Cloud.authenticateAsync = function (activity, redirect, dontRedirect, sensitive) {
            if (redirect === void 0) { redirect = false; }
            if (dontRedirect === void 0) { dontRedirect = false; }
            if (sensitive === void 0) { sensitive = false; }
            if (!sensitive && !Cloud.isAccessTokenExpired())
                return TDev.Promise.as(true);
            function loginAsync() {
                var loginUrl = Cloud.getServiceUrl() + "/oauth/dialog?response_type=token&" + "client_id=webapp" + "&identity_provider=" + encodeURIComponent(Cloud.getIdentityProvider() || "");
                return TDev.RT.Web.oauth_v2_async(loginUrl, "touchdevelop").then(function (or) {
                    if (or.is_error())
                        return false;
                    else {
                        var id = or.others().at('id');
                        var oldid = Cloud.getUserId();
                        if (oldid && id != oldid) {
                            return false;
                        }
                        Cloud.setUserId(or.others().at('id'));
                        Cloud.setAccessToken(encodeURIComponent(or.access_token()));
                        Cloud.setIdentityProvider(or.others().at('identity_provider'));
                        return true;
                    }
                });
            }
            return Cloud.isOnlineWithPingAsync().then(function (isOnline) {
                if (!isOnline)
                    return TDev.Promise.as(false);
                var prevHash = (window.location.hash || "#").replace(/#/, "");
                var login = TDev.Login;
                if (login) {
                    if (!login.show || dontRedirect)
                        login = null;
                    if (!redirect && (!prevHash || /^(hub|list:.*:user:me:)/.test(prevHash)))
                        login = null;
                }
                var r = new TDev.PromiseInv();
                var m = new TDev.ModalDialog();
                if (sensitive)
                    m.addHTML(TDev.lf("<h3>we need you to sign in again</h3>") + "<p class='agree'>" + TDev.lf("Accessing private data requires verification of your sign in credentials.") + "</p>");
                else
                    m.addHTML(TDev.lf("<h3>{0:q} requires sign&nbsp;in</h3>", activity) + (!TDev.TheEditor ? "" : "<p class='agree'>" + TDev.lf("You can run and save your scripts locally, but to access your scripts from all devices, you need to be signed in. After you sign in, we will save and sync your scripts between your devices.") + "</p>"));
                m.fullWhite();
                var ignoreDismiss = false;
                m.add(TDev.div("wall-dialog-buttons", TDev.HTML.mkButton(TDev.lf("maybe later"), function () {
                    m.dismiss();
                }), TDev.HTML.mkButton(TDev.lf("sign in"), function () {
                    ignoreDismiss = true;
                    m.dismiss();
                    if (login)
                        login.show();
                    else
                        loginAsync().done(function (v) { return r.success(v); });
                })));
                m.onDismiss = function () {
                    if (!ignoreDismiss)
                        r.success(false);
                };
                m.show();
                return r;
            });
        };
        function anonMode(activity, restart, redirect) {
            if (restart === void 0) { restart = null; }
            if (redirect === void 0) { redirect = false; }
            if (Cloud.isOffline()) {
                Cloud.showModalOnlineInfo(TDev.lf("{0} requires online access", activity));
                return true;
            }
            if (Cloud.getUserId())
                return false;
            Cloud.authenticateAsync(activity, redirect).done(function (ok) {
                if (ok && restart)
                    restart();
            });
            return true;
        }
        Cloud.anonMode = anonMode;
        function parseAccessToken(h, onStateError, onUserError) {
            var stateMatch = h.match(/.*&state=([^&]*)/);
            var state = stateMatch ? stateMatch[1] : "";
            if (Cloud.oauthStates().indexOf(decodeURIComponent(state)) == -1) {
                onStateError();
                return false;
            }
            var token = h.match(/.*#access_token=([^&]*)/)[1];
            var m = h.match(/.*&identity_provider=([^&]*)/);
            var identityProvider = m ? decodeURIComponent(m[1]) : undefined;
            var id = h.match(/.*&id=([^&]*)/)[1];
            var expires = parseInt((h.match(/.*&expires_in=([^&]*)/) || ["0", "0"])[1]);
            var oldid = Cloud.getUserId();
            if (oldid && id != oldid) {
                onUserError();
                return false;
            }
            if (/.*[#&]dbg=true/.test(h))
                window.localStorage.setItem("dbg", "true");
            else
                window.localStorage.removeItem("dbg");
            Cloud.setUserId(id);
            Cloud.setIdentityProvider(identityProvider || "");
            Cloud.setAccessToken(token);
            return true;
        }
        Cloud.parseAccessToken = parseAccessToken;
        function hasAccessToken() {
            return !!getAccessToken();
        }
        Cloud.hasAccessToken = hasAccessToken;
        function getAccessToken() {
            return window.localStorage.getItem("access_token");
        }
        Cloud.getAccessToken = getAccessToken;
        function isAccessTokenExpired() {
            return !hasAccessToken() || !!window.localStorage.getItem("access_token_expired");
        }
        Cloud.isAccessTokenExpired = isAccessTokenExpired;
        function accessTokenExpired() {
            window.localStorage.setItem("access_token_expired", "1");
        }
        Cloud.accessTokenExpired = accessTokenExpired;
        function setAccessToken(token) {
            window.localStorage.removeItem("access_token_expired");
            if (!token)
                window.localStorage.removeItem("access_token");
            else
                window.localStorage.setItem("access_token", token);
        }
        Cloud.setAccessToken = setAccessToken;
        Cloud.getUserId = function () { return window.localStorage.getItem("userid"); };
        Cloud.currentReleaseId = "";
        function getWorldId() {
            var worldId = window.localStorage.getItem("worldId");
            if (!worldId)
                window.localStorage.setItem("worldId", worldId = "$webclient$-" + TDev.Util.guidGen());
            return worldId;
        }
        Cloud.getWorldId = getWorldId;
        function oauthStates() {
            var a = JSON.parse(window.localStorage.getItem("oauth_states") || "[]");
            if (a.length == 0)
                a = [TDev.Random.normalized().toString()];
            window.localStorage.setItem("oauth_states", JSON.stringify(a));
            return a;
        }
        Cloud.oauthStates = oauthStates;
        function setUserId(id) {
            if (!id)
                window.localStorage.removeItem("userid");
            else
                window.localStorage.setItem("userid", id);
        }
        Cloud.setUserId = setUserId;
        function getIdentityProvider() {
            return window.localStorage.getItem("identity_provider");
        }
        Cloud.getIdentityProvider = getIdentityProvider;
        function setIdentityProvider(id) {
            if (!id)
                window.localStorage.removeItem("identity_provider");
            else
                window.localStorage.setItem("identity_provider", id);
        }
        Cloud.setIdentityProvider = setIdentityProvider;
        function mergeProgress(oldData, data) {
            oldData = JSON.parse(JSON.stringify(oldData));
            Object.keys(data).forEach(function (id) {
                var oldProgress = oldData[id] || {};
                var progress = data[id];
                if (oldProgress.index === undefined || oldProgress.index <= progress.index) {
                    if (progress.guid)
                        oldProgress.guid = progress.guid;
                    oldProgress.index = progress.index;
                    if (progress.completed && (oldProgress.completed === undefined || oldProgress.completed > progress.completed))
                        oldProgress.completed = progress.completed;
                    oldProgress.numSteps = progress.numSteps;
                    oldProgress.lastUsed = progress.lastUsed;
                }
                oldData[id] = oldProgress;
            });
            return oldData;
        }
        function storeProgress(data) {
            var newData = mergeProgress(loadPendingProgress(), data);
            window.localStorage.setItem("progress", JSON.stringify(newData));
            window.localStorage.setItem("total_progress", JSON.stringify(mergeProgress(loadProgress(), data)));
        }
        Cloud.storeProgress = storeProgress;
        function clearPendingProgress(data) {
            var oldData = loadPendingProgress();
            Object.keys(data).forEach(function (id) {
                var oldProgress = oldData[id];
                var progress = data[id];
                var uploaded = oldProgress && (!oldProgress.guid || !progress.guid || oldProgress.guid == progress.guid) && (oldProgress.index === undefined || progress.index === undefined || oldProgress.index <= progress.index) && (oldProgress.completed === undefined || progress.completed === undefined || oldProgress.completed <= progress.completed);
                if (uploaded) {
                    delete oldData[id];
                }
            });
            window.localStorage.setItem("progress", JSON.stringify(oldData));
        }
        function loadProgress() {
            return loadPendingProgress("total_progress");
        }
        Cloud.loadProgress = loadProgress;
        function loadPendingProgress(name) {
            if (name === void 0) { name = "progress"; }
            return JSON.parse(window.localStorage.getItem(name) || "{}");
        }
        function isOffline() {
            return !isOnline();
        }
        Cloud.isOffline = isOffline;
        function isOnline() {
            var b = !TDev.Browser.noNetwork && (TDev.Browser.isNodeJS || window.navigator.onLine) && isTouchDevelopOnline();
            if (TDev.dbg && b && isChaosOffline() && TDev.RT.Math_.random(10) < 4)
                b = false;
            return b;
        }
        Cloud.isOnline = isOnline;
        function isOnlineWithPingAsync() {
            if (!isOnline())
                return TDev.Promise.as(false);
            return pingAsync();
        }
        Cloud.isOnlineWithPingAsync = isOnlineWithPingAsync;
        Cloud.transientOfflineMode = false;
        function isTouchDevelopOnline() {
            return !window.localStorage.getItem('offline_mode') && !Cloud.transientOfflineMode;
        }
        Cloud.isTouchDevelopOnline = isTouchDevelopOnline;
        function setTouchDevelopOnline(value) {
            if (value)
                window.localStorage.removeItem('offline_mode');
            else
                window.localStorage.setItem('offline_mode', "true");
        }
        Cloud.setTouchDevelopOnline = setTouchDevelopOnline;
        function isChaosOffline() {
            return !!window.localStorage.getItem('chaos_offline_mode');
        }
        Cloud.isChaosOffline = isChaosOffline;
        function setChaosOffline(value) {
            if (!value)
                window.localStorage.removeItem('chaos_offline_mode');
            else
                window.localStorage.setItem('chaos_offline_mode', "true");
        }
        Cloud.setChaosOffline = setChaosOffline;
        function offlineErrorAsync() {
            var msg = isTouchDevelopOnline() ? "offline mode is on" : "force offline mode is on";
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var e = new Error(msg);
                e.status = 502;
                onError(e);
            });
        }
        Cloud.offlineErrorAsync = offlineErrorAsync;
        function canPublish() {
            return Cloud.getUserId() != "paema";
        }
        Cloud.canPublish = canPublish;
        function onlineInfo() {
            if (Cloud.isOffline()) {
                var msg = TDev.lf("You appear to be offline. ") + (isTouchDevelopOnline() ? TDev.lf("Please connect to the internet and try again.") : TDev.lf("Please go to the settings in the main hub to disable offline mode."));
                return msg;
            }
            else {
                return TDev.lf("You are online.");
            }
        }
        Cloud.onlineInfo = onlineInfo;
        function showOnlineInfoProgess() {
            TDev.HTML.showProgressNotification(onlineInfo(), true);
        }
        Cloud.showOnlineInfoProgess = showOnlineInfoProgess;
        function showModalOnlineInfo(title) {
            TDev.ModalDialog.info(title, onlineInfo());
        }
        Cloud.showModalOnlineInfo = showModalOnlineInfo;
        var appendAccessToken = function (url) {
            return (url + (/\?/.test(url) ? "&" : "?") + "access_token=" + getAccessToken() + "&world_id=" + encodeURIComponent(Cloud.getWorldId()) + "&release_id=" + encodeURIComponent(Cloud.currentReleaseId) + "&user_platform=" + encodeURIComponent(TDev.Browser.platformCaps.join(",")) + "&anon_token=" + encodeURIComponent(Cloud.config.anonToken || ""));
        };
        function getPublicApiUrl(path) {
            return appendAccessToken(getServiceUrl() + "/api/" + path);
        }
        Cloud.getPublicApiUrl = getPublicApiUrl;
        function getPrivateApiUrl(path) {
            return appendAccessToken(getServiceUrl() + "/api" + (path == null ? "" : "/" + path));
        }
        Cloud.getPrivateApiUrl = getPrivateApiUrl;
        function getScriptTextAsync(id) {
            return TDev.Util.httpGetTextAsync(getPublicApiUrl(encodeURIComponent(id) + "/text?original=true"));
        }
        Cloud.getScriptTextAsync = getScriptTextAsync;
        function getPrivateApiAsync(path) {
            return TDev.Util.httpGetJsonAsync(getPrivateApiUrl(path));
        }
        Cloud.getPrivateApiAsync = getPrivateApiAsync;
        function getPublicApiAsync(path) {
            return TDev.Util.httpGetJsonAsync(getPublicApiUrl(path));
        }
        Cloud.getPublicApiAsync = getPublicApiAsync;
        function postPrivateApiAsync(path, req) {
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl(path), req);
        }
        Cloud.postPrivateApiAsync = postPrivateApiAsync;
        function deletePrivateApiAsync(path) {
            return TDev.Util.httpRequestAsync(Cloud.getPrivateApiUrl(path), "DELETE");
        }
        Cloud.deletePrivateApiAsync = deletePrivateApiAsync;
        function deletePublicationAsync(id) {
            return TDev.Util.httpRequestAsync(Cloud.getPrivateApiUrl(id), "DELETE");
        }
        Cloud.deletePublicationAsync = deletePublicationAsync;
        function getRandomAsync() {
            return TDev.Util.httpGetTextAsync(getPublicApiUrl("random"));
        }
        Cloud.getRandomAsync = getRandomAsync;
        function isVersionNewer(version1, version2) {
            if (typeof version1 === "object" && typeof version2 === "object") {
                if (version1.instanceId == version2.instanceId)
                    return version1.version > version2.version || version1.version == version2.version && version1.time > version2.time;
                else
                    return version1.time > version2.time;
            }
            return false;
        }
        Cloud.isVersionNewer = isVersionNewer;
        function getUserInstalledAsync() {
            return getPrivateApiAsync("me/installed");
        }
        Cloud.getUserInstalledAsync = getUserInstalledAsync;
        function getUserInstalledLongAsync(v, m) {
            return getPrivateApiAsync("me/installedlong" + (v ? "?v=" + v + (m ? "&m=1" : "") : ""));
        }
        Cloud.getUserInstalledLongAsync = getUserInstalledLongAsync;
        function getUserInstalledBodyAsync(guid) {
            return getPrivateApiAsync("me/installed/" + guid);
        }
        Cloud.getUserInstalledBodyAsync = getUserInstalledBodyAsync;
        function postUserInstalledAsync(installedBodies) {
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl("me/installed"), installedBodies);
        }
        Cloud.postUserInstalledAsync = postUserInstalledAsync;
        function postUserInstalledPublishAsync(guid, hidden, scriptVersion, meta) {
            var url = "me/installed/" + guid + "/publish?hidden=" + (hidden ? "true" : "false");
            if (scriptVersion)
                url += "&scriptversion=" + encodeURIComponent(scriptVersion);
            if (!meta)
                meta = {};
            var mergeIds = meta.parentIds;
            if (mergeIds)
                url += "&mergeids=" + encodeURIComponent(mergeIds);
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl(url), meta);
        }
        Cloud.postUserInstalledPublishAsync = postUserInstalledPublishAsync;
        function isFota() {
            return /fota=1/.test(document.URL) || navigator.userAgent.indexOf("Profile/OTA-DFU1.0") > 0;
        }
        Cloud.isFota = isFota;
        function canCompile() {
            return Cloud.isRestricted();
        }
        Cloud.canCompile = canCompile;
        function postUserInstalledCompileAsync(guid, cppSource, meta) {
            if (meta === void 0) { meta = {}; }
            var r = new TDev.PromiseInv();
            var pollUrl = "";
            var poll = function () {
                TDev.Util.httpGetJsonAsync(pollUrl).done(function (json) {
                    TDev.HTML.showProgressNotification(TDev.lf("compilation finished"));
                    json.url = pollUrl;
                    r.success(json);
                }, function (err) { return TDev.Util.setTimeout(1000, poll); });
            };
            TDev.Util.httpPostJsonAsync(getPrivateApiUrl("me/installed/" + guid + "/compile"), {
                config: "ws",
                source: cppSource,
                meta: meta,
                repohash: Cloud.config.microbitGitTag,
            }).done(function (resp) {
                pollUrl = resp.statusurl;
                poll();
            }, function (e) {
                r.success(undefined);
                Cloud.handlePostingError(e, TDev.lf("could not start compilation"));
            });
            return r;
        }
        Cloud.postUserInstalledCompileAsync = postUserInstalledCompileAsync;
        function errorCallback(action) {
            if (action === void 0) { action = TDev.lf("do this"); }
            return function (e) { return handlePostingError(e, action); };
        }
        Cloud.errorCallback = errorCallback;
        function showSigninNotification(isOnline) {
            if (isOnline)
                TDev.HTML.showWarningNotification(TDev.lf("You are not signed in."), {
                    els: [TDev.HTML.mkLinkButton(TDev.lf("sign in"), function () {
                        var login = TDev.Login;
                        if (login && login.show)
                            login.show();
                    })]
                });
            else
                TDev.HTML.showProgressNotification(TDev.lf("You appear to be offline."));
        }
        Cloud.showSigninNotification = showSigninNotification;
        function handlePostingError(e, action, modal) {
            if (modal === void 0) { modal = true; }
            if (e) {
                if (e.status == 502) {
                    if (modal)
                        Cloud.showModalOnlineInfo(TDev.lf("could not {0}", action));
                    else
                        TDev.HTML.showProgressNotification(TDev.lf("could not {0}, are you connected to internet?", action));
                    return;
                }
                else if (e.status == 429) {
                    TDev.ModalDialog.info(TDev.lf("could not {0}", action), TDev.lf("Did you post a lot recently? Please try again later."));
                    return;
                }
                else if (e.status == 403) {
                    Cloud.accessTokenExpired();
                    if (localStorage['everLoggedIn'])
                        Cloud.isOnlineWithPingAsync().done(function (isOnline) { return Cloud.showSigninNotification(isOnline); });
                    else
                        Cloud.authenticateAsync(action).done();
                    return;
                }
                else if (e.status == 419 || e.status == 402) {
                    TDev.ModalDialog.info(TDev.lf("access denied"), TDev.lf("Your account is not authorized to perform this action."));
                    return;
                }
                else if (e.status == 404) {
                    TDev.ModalDialog.info(TDev.lf("publication not found"), TDev.lf("Maybe it has been removed?"));
                    return;
                }
                else if (e.status == 442 && Cloud._migrate) {
                    Cloud._migrate();
                    return;
                }
                else if (e.status == 452) {
                    return Cloud.authenticateAsync(action, true, false, true).then(function () { return null; });
                }
                else if (e.status == 400)
                    throw new Error(TDev.lf("Cloud precondition violated ({0})", e.errorMessage));
            }
            throw e;
        }
        Cloud.handlePostingError = handlePostingError;
        function postApiBatch(bundle) {
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl(null), bundle);
        }
        Cloud.postApiBatch = postApiBatch;
        function postBugReportAsync(bug) {
            return postPrivateApiAsync("bug", bug);
        }
        Cloud.postBugReportAsync = postBugReportAsync;
        function postTicksAsync(ticks) {
            return postPrivateApiAsync("ticks", ticks);
        }
        Cloud.postTicksAsync = postTicksAsync;
        function postNotificationsAsync() {
            return postPrivateApiAsync("me/notifications", {});
        }
        Cloud.postNotificationsAsync = postNotificationsAsync;
        function postNotificationChannelAsync(body) {
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl("me/notificationchannel"), body);
        }
        Cloud.postNotificationChannelAsync = postNotificationChannelAsync;
        function getUserSettingsAsync(priv) {
            if (priv === void 0) { priv = false; }
            return TDev.Util.httpGetJsonAsync(getPrivateApiUrl("me/settings?format=" + (priv ? "sensitive" : "nonsensitive"))).then(function (r) { return r; }, function (e) {
                Cloud.handlePostingError(e, TDev.lf("get settings"));
                return new TDev.PromiseInv();
            });
        }
        Cloud.getUserSettingsAsync = getUserSettingsAsync;
        function postUserSettingsAsync(body) {
            return TDev.Util.httpPostJsonAsync(getPrivateApiUrl("me/settings"), body);
        }
        Cloud.postUserSettingsAsync = postUserSettingsAsync;
        function getAppAsync(id, appPlatform) {
            return TDev.Util.httpGetJsonAsync(getPrivateApiUrl(id + "/" + appPlatform + "app"));
        }
        Cloud.getAppAsync = getAppAsync;
        function postAppAsync(id, appPlatform, data) {
            return TDev.Util.httpPostTextAsync(getPrivateApiUrl(id + "/" + appPlatform + "app"), JSON.stringify(data));
        }
        Cloud.postAppAsync = postAppAsync;
        function postAskBetaAsync(accept) {
            return TDev.Util.httpPostTextAsync(getPrivateApiUrl("/me/askbeta?accept=" + accept), "");
        }
        Cloud.postAskBetaAsync = postAskBetaAsync;
        function postAskSomethingAsync(accept) {
            return TDev.Util.httpPostTextAsync(getPrivateApiUrl("/me/asksomething?accept=" + accept), "");
        }
        Cloud.postAskSomethingAsync = postAskSomethingAsync;
        function pingAsync() {
            if (/http:\/\/localhost/i.test(document.URL))
                return TDev.Promise.as(true);
            var v = TDev.RT.Math_.random(0xffffff).toString();
            var url = getPublicApiUrl("ping?value=" + encodeURIComponent(v));
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var client;
                function ready() {
                    if (client.readyState == 4)
                        onSuccess(client.status == 200 && client.responseText === v);
                }
                client = new XMLHttpRequest();
                client.onreadystatechange = ready;
                client.open("GET", url);
                client.send();
            });
        }
        Cloud.pingAsync = pingAsync;
        function postPendingProgressAsync() {
            if (!Cloud.getUserId() || !hasAccessToken() || isOffline())
                return TDev.Promise.as();
            var data = loadPendingProgress();
            if (Object.keys(data).length == 0)
                return TDev.Promise.as();
            TDev.Util.log('progress: ' + JSON.stringify(data));
            return Cloud.postPrivateApiAsync("me/progress", data).then(function () { return clearPendingProgress(data); }, function () {
            });
        }
        Cloud.postPendingProgressAsync = postPendingProgressAsync;
        function postCommentAsync(id, text) {
            var req = { kind: "comment", text: text, userplatform: TDev.Browser.platformCaps };
            return Cloud.postPrivateApiAsync(id + "/comments", req);
        }
        Cloud.postCommentAsync = postCommentAsync;
    })(Cloud = TDev.Cloud || (TDev.Cloud = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var HTML;
    (function (HTML) {
        function tr(parent, cl) {
            var d = document.createElement('tr');
            d.className = cl;
            parent.appendChild(d);
            return d;
        }
        HTML.tr = tr;
        function td(parent, cl) {
            var d = document.createElement('td');
            d.className = cl;
            parent.appendChild(d);
            return d;
        }
        HTML.td = td;
        function col(parent) {
            var d = document.createElement('col');
            parent.appendChild(d);
            return d;
        }
        HTML.col = col;
        function jsrequireAsync(url) {
            return new TDev.Promise(function (onSuccess, onProgress, onError) {
                if (TDev.Util.children(document.head).some(function (el) { return /script/i.test(el.tagName) && el.getAttribute("src") == url; })) {
                    onSuccess(undefined);
                    return;
                }
                TDev.Util.log('require ' + url);
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.charset = "utf-8";
                script.onload = function () {
                    if (!script.readyState || script.readyState === 'complete') {
                        TDev.Util.log('require success ' + url);
                        onSuccess(undefined);
                    }
                };
                script.onreadystatechange = script.onload;
                script.onerror = function (err) {
                    TDev.Util.log('require error: {0}', err);
                    onSuccess(err);
                };
                script.src = url;
                document.head.appendChild(script);
            });
        }
        HTML.jsrequireAsync = jsrequireAsync;
        function mkOEmbed(url, oe) {
            var d = TDev.div('md-video-link', TDev.div('', HTML.mkImg(oe.thumbnail_url)).withClick(function () { return window.open(url, 'oembed'); }), oe.title, HTML.mkA('', oe.author_url, 'oembed', oe.author_name), HTML.mkA('', oe.provider_url, 'oembed', oe.provider_url));
            return d;
        }
        HTML.mkOEmbed = mkOEmbed;
        function mkVideoIframe(iframeSrc) {
            return TDev.Util.fmt("<div class='md-video-wrapper'><iframe src='{0:url}' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>", iframeSrc);
        }
        HTML.mkVideoIframe = mkVideoIframe;
        function mkLazyVideoPlayer(preview, iframeSrc) {
            var d = TDev.div('md-video-link');
            TDev.Browser.setInnerHTML(d, TDev.SVG.getVideoPlay(preview));
            d.setAttribute("data-playerurl", iframeSrc);
            d.withClick(function () {
                d.innerHTML = mkVideoIframe(iframeSrc);
            });
            return d;
        }
        HTML.mkLazyVideoPlayer = mkLazyVideoPlayer;
        function mkYouTubePlayer(ytid) {
            return mkLazyVideoPlayer(TDev.Util.fmt('https://img.youtube.com/vi/{0:q}/hqdefault.jpg', ytid), TDev.Util.fmt("//www.youtube-nocookie.com/embed/{0:uri}?modestbranding=1&autoplay=1&autohide=1&origin={1:uri}", ytid, TDev.Cloud.config.rootUrl));
        }
        HTML.mkYouTubePlayer = mkYouTubePlayer;
        function mkAudio(url, aacUrl, mp3Url, controls) {
            if (aacUrl === void 0) { aacUrl = null; }
            if (mp3Url === void 0) { mp3Url = null; }
            if (controls === void 0) { controls = false; }
            var audio = document.createElement('audio');
            audio.crossorigin = "anonymous";
            audio.controls = controls;
            setAudioSource(audio, url, aacUrl, mp3Url);
            return audio;
        }
        HTML.mkAudio = mkAudio;
        function audioLoadAsync(audio) {
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                audio.oncanplay = function () {
                    TDev.Util.log('loaded sound oncanplay');
                    audio.oncanplay = null;
                    audio.oncanplaythrough = null;
                    audio.onerror = null;
                    onSuccess(audio);
                };
                audio.oncanplaythrough = function () {
                    TDev.Util.log('loaded sound oncanplaythrough');
                    audio.oncanplay = null;
                    audio.oncanplaythrough = null;
                    audio.onerror = null;
                    onSuccess(audio);
                };
                audio.onerror = function (e) {
                    TDev.Util.log('failed loading sound - ' + audio.readyState);
                    audio.oncanplay = null;
                    audio.oncanplaythrough = null;
                    audio.onerror = null;
                    onSuccess(audio);
                };
                var retry = 20;
                var loadTracker = function () {
                    var readyState = (audio.readyState);
                    if (!audio.oncanplay)
                        return;
                    if (readyState === HTMLMediaElement.HAVE_ENOUGH_DATA) {
                        audio.oncanplay = null;
                        audio.oncanplaythrough = null;
                        audio.onerror = null;
                        onSuccess(audio);
                    }
                    else if (retry-- > 0) {
                        TDev.Util.log('retry loading sound. readState:' + readyState + ', networkState:' + audio.networkState + ', try:' + retry);
                        TDev.Util.setTimeout(250, loadTracker);
                    }
                    else {
                        TDev.Util.log('timeout loading sound');
                        audio.oncanplay = null;
                        audio.oncanplaythrough = null;
                        audio.onerror = null;
                        onSuccess(audio);
                    }
                };
                try {
                    TDev.Util.log('start loading sound');
                    audio.load();
                    TDev.Util.setTimeout(400, loadTracker);
                }
                catch (e) {
                    TDev.Util.log('failed loading sound: ' + e.message);
                    onSuccess(audio);
                }
            });
        }
        HTML.audioLoadAsync = audioLoadAsync;
        function setAudioSource(audio, url, aacUrl, mp3Url) {
            if (aacUrl === void 0) { aacUrl = null; }
            if (mp3Url === void 0) { mp3Url = null; }
            if (!url) {
                audio.setChildren([]);
                return;
            }
            var m = url.match(/^data:audio\/(mpeg|mp3|mp4|wav);base64,/i);
            if (m) {
                TDev.Util.log('audio: src datauri ' + m[1]);
                var src = document.createElement('source');
                src.src = url;
                src.type = 'audio/' + m[1];
                audio.setChildren([src]);
            }
            else {
                var wavSrc = document.createElement('source');
                wavSrc.src = proxyResource(url);
                wavSrc.type = 'audio/wav';
                var mp3Src = document.createElement('source');
                mp3Src.src = proxyResource(mp3Url || url);
                mp3Src.type = 'audio/mp3';
                var aacSrc = document.createElement('source');
                aacSrc.src = proxyResource(aacUrl || url);
                aacSrc.type = 'audio/mp4';
                audio.setChildren([aacSrc, wavSrc, mp3Src]);
            }
        }
        HTML.setAudioSource = setAudioSource;
        function parseWtt(wtt) {
            var r = [];
            if (wtt) {
                try {
                    var rx = /((\d{2}):)?(\d{2}):(\d{2})\.(\d{3}) --> ((\d{2}):)?(\d{2}):(\d{2})\.(\d{3})/gi;
                    var m;
                    while (m = rx.exec(wtt)) {
                        var startTime = parseInt(m[2] || "0") * 3600 + parseInt(m[3]) * 60 + parseInt(m[4]) + parseInt(m[5]) / 1000;
                        var endTime = parseInt(m[7] || "0") * 3600 + parseInt(m[8]) * 60 + parseInt(m[9]) + parseInt(m[10]) / 1000;
                        var message = wtt.substr(m.index + m[0].length).trim();
                        var emptyLine = /^$/m.exec(message);
                        if (emptyLine)
                            message = message.substr(0, emptyLine.index).trim();
                        r.push({ startTime: startTime, endTime: endTime, message: message });
                    }
                }
                catch (e) {
                    TDev.Util.reportError("wtt", e, false);
                    return r;
                }
            }
            return r;
        }
        HTML.parseWtt = parseWtt;
        function pauseVideos(el) {
            if (el) {
                var vids = el.getElementsByTagName("video");
                for (var i = 0; i < vids.length; ++i) {
                    try {
                        vids.item(i).pause();
                    }
                    catch (e) {
                    }
                }
            }
        }
        HTML.pauseVideos = pauseVideos;
        function patchWavToMp4Url(url) {
            if (url) {
                if (/^\.\/art\//i.test(url))
                    return url + '.m4a';
                else if (TDev.Cloud.isArtUrl(url))
                    return TDev.Cloud.toCdnUrl(url, "aac") + ".m4a";
            }
            return url;
        }
        HTML.patchWavToMp4Url = patchWavToMp4Url;
        function mkBr() {
            return document.createElement("br");
        }
        HTML.mkBr = mkBr;
        function mkTextArea(cls) {
            if (cls === void 0) { cls = null; }
            var ta = document.createElement("textarea");
            if (cls != null)
                ta.className = cls;
            TDev.dirAuto(ta);
            ta.onselectstart = function (e) {
                e.stopImmediatePropagation();
                return true;
            };
            return ta;
        }
        HTML.mkTextArea = mkTextArea;
        function wrong(e) {
            TDev.Util.coreAnim("shakeTip", 500, e);
        }
        HTML.wrong = wrong;
        function setupDragAndDrop(r, onFiles) {
            if (!TDev.Browser.dragAndDrop)
                return;
            r.addEventListener('dragover', function (e) {
                if (e.dataTransfer.types[0] == 'Files') {
                    if (e.preventDefault)
                        e.preventDefault();
                    e.dataTransfer.dropEffect = 'copy';
                    return false;
                }
            }, false);
            r.addEventListener('drop', function (e) {
                if (e.dataTransfer.files[0]) {
                    e.stopPropagation();
                    e.preventDefault();
                    onFiles(e.dataTransfer.files);
                }
                return false;
            }, false);
            r.addEventListener('dragend', function (e) {
                return false;
            }, false);
        }
        HTML.setupDragAndDrop = setupDragAndDrop;
        function mkButtonElt(cl) {
            var children = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                children[_i - 1] = arguments[_i];
            }
            var elt = document.createElement("button");
            if (cl != null)
                elt.className = cl;
            elt.appendChildren(children);
            TDev.dirAuto(elt);
            return elt;
        }
        HTML.mkButtonElt = mkButtonElt;
        function mkImg(url, cls, alt, ariaHidden) {
            if (/^\//.test(url))
                url = url.slice(1);
            var m = /^scripticons(96)?\/(.*)\.png/.exec(url);
            if (m) {
                url = "svg:" + m[2] + ",white";
            }
            var img;
            if (/^svg:/.test(url)) {
                img = TDev.SVG.getIconSVG(url.slice(4), ariaHidden ? undefined : alt);
            }
            else {
                var elt = document.createElement("img");
                elt.src = proxyResource(url);
                if (!ariaHidden)
                    elt.alt = alt || "";
                img = elt;
            }
            if (cls)
                img.className += " " + cls;
            if (ariaHidden)
                img.setAttribute("aria-hidden", "true");
            return img;
        }
        HTML.mkImg = mkImg;
        function mkImgButton(img, f) {
            var i = HTML.mkImg(img);
            HTML.setRole(i, "presentation");
            var btn = mkButtonElt("wall-button", i);
            TDev.Util.clickHandler(btn, f);
            return btn;
        }
        HTML.mkImgButton = mkImgButton;
        function mkDisablableButton(content, f) {
            var r = mkButton(content, function () {
                if (!r.getFlag("disabled"))
                    f();
            });
            return r;
        }
        HTML.mkDisablableButton = mkDisablableButton;
        function mkAsyncButton(content, f, cls) {
            if (cls === void 0) { cls = ""; }
            var btn = mkButtonElt("wall-button " + cls, TDev.text(content));
            var running = false;
            TDev.Util.clickHandler(btn, function () {
                if (running)
                    return;
                running = true;
                btn.style.opacity = "0.5";
                btn.setFlag("disabled", true);
                f().done(function () {
                    running = false;
                    btn.style.opacity = null;
                    btn.setFlag("disabled", false);
                });
            });
            return btn;
        }
        HTML.mkAsyncButton = mkAsyncButton;
        function mkButton(content, f, cls) {
            if (cls === void 0) { cls = ""; }
            var btn = mkButtonElt("wall-button " + cls, TDev.text(content));
            TDev.Util.clickHandler(btn, f);
            return btn;
        }
        HTML.mkButton = mkButton;
        function mkAButton(content, href) {
            return HTML.mkA('wall-button', href, '_blank', content);
        }
        HTML.mkAButton = mkAButton;
        function mkLinkButton(content, f, cls) {
            if (cls === void 0) { cls = ""; }
            var btn = mkButtonElt("link-button " + cls, TDev.text(content));
            TDev.Util.clickHandler(btn, f);
            return btn;
        }
        HTML.mkLinkButton = mkLinkButton;
        function mkButtonTick(content, t, f, cls) {
            if (cls === void 0) { cls = ""; }
            var btn = mkButtonElt("wall-button " + cls, TDev.text(content));
            setTickCallback(btn, t, f);
            return btn;
        }
        HTML.mkButtonTick = mkButtonTick;
        function mkButtonOnce(content, f, removeSiblings) {
            if (removeSiblings === void 0) { removeSiblings = false; }
            var btn = mkButtonElt("wall-button", TDev.text(content));
            TDev.Util.clickHandler(btn, function (e) {
                if (removeSiblings)
                    btn.parentNode.removeAllChildren();
                else
                    btn.removeSelf();
                f();
            });
            return btn;
        }
        HTML.mkButtonOnce = mkButtonOnce;
        function setTickCallback(btn, tick, f) {
            if (tick == 0 /* noEvent */) {
                return btn.withClick(f);
            }
            else {
                btn.id = "btn-" + TDev.Ticker.tickName(tick);
                return btn.withClick(function (e) {
                    TDev.Ticker.tick(tick);
                    f(e);
                });
            }
            return btn;
        }
        HTML.setTickCallback = setTickCallback;
        function mkRoundButton(icon, name, tick, f) {
            var btn = HTML.mkButtonElt("topMenu-button " + (name.length > 11 ? "topMenu-button-long-desc" : ""), [
                TDev.div("topMenu-button-frame", HTML.mkImg(icon)),
                TDev.div("topMenu-button-desc", name)
            ]);
            setTickCallback(btn, tick, f);
            return btn;
        }
        HTML.mkRoundButton = mkRoundButton;
        function fileReadAsArrayBufferAsync(f) {
            if (!f)
                return TDev.Promise.as(null);
            else {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var reader = new FileReader();
                    reader.onerror = function (ev) { return onSuccess(null); };
                    reader.onload = function (ev) { return onSuccess(reader.result); };
                    reader.readAsArrayBuffer(f);
                });
            }
        }
        HTML.fileReadAsArrayBufferAsync = fileReadAsArrayBufferAsync;
        function fileReadAsDataURLAsync(f, fileType) {
            if (fileType === void 0) { fileType = ""; }
            if (!f)
                return TDev.Promise.as(null);
            if (fileType)
                return fileReadAsArrayBufferAsync(f).then(function (buf) {
                    if (buf)
                        return "data:" + fileType + ";base64," + btoa(TDev.Util.uint8ArrayToString(new Uint8Array(buf)));
                    else
                        return null;
                });
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var reader = new FileReader();
                reader.onerror = function (ev) { return onSuccess(null); };
                reader.onload = function (ev) { return onSuccess(reader.result); };
                reader.readAsDataURL(f);
            });
        }
        HTML.fileReadAsDataURLAsync = fileReadAsDataURLAsync;
        HTML.documentMimeTypes = {
            "text/css": "css",
            "application/javascript": "js",
            "text/plain": "txt",
            "application/pdf": "pdf",
            "application/x-zip-compressed": "zip",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
            "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
            "application/x-microbit-hex": "hex",
        };
        function mkDocumentInput(maxMb) {
            var input = HTML.mkTextInput("file", TDev.lf("choose a file"));
            input.accept = Object.keys(HTML.documentMimeTypes).join(";");
            return {
                element: input,
                validate: function () {
                    var f = input.files[0];
                    if (!f)
                        return TDev.lf("Oops, you need to select a file...");
                    if (maxMb > 0 && f.size > maxMb * 1024 * 1024)
                        return TDev.lf("Sorry, the file is too big. It must be less than {0}Mb...", maxMb);
                    if (input.accept.indexOf(f.type) < 0)
                        return TDev.lf("Sorry, this document format is not supported...");
                    return null;
                },
                readAsync: function () { return fileReadAsDataURLAsync(input.files[0]); }
            };
        }
        HTML.mkDocumentInput = mkDocumentInput;
        HTML.mkAudioInput = function (allowEmpty, maxMb) {
            var input = HTML.mkTextInput("file", TDev.lf("choose a file"));
            input.accept = "audio/mpeg";
            return {
                element: input,
                validate: function () {
                    var files = input.files;
                    if (files.length == 0)
                        return allowEmpty ? null : 'Oops, you need to select a sound...';
                    var f = files[0];
                    if (maxMb > 0 && f.size > maxMb * 1000000)
                        return TDev.lf("Sorry, the sound is too big. The sound must be less than {0}Mb...", maxMb);
                    if (f.type !== 'audio/mpeg' && f.type !== 'audio/mp3')
                        return TDev.lf("Sorry, you can only upload MP3 sounds...");
                    return null;
                },
                readAsync: function () { return fileReadAsDataURLAsync(input.files[0]); }
            };
        };
        HTML.mkImageChooser = function (onchanged) {
            var file = HTML.mkTextInput("file", TDev.lf("choose a picture"));
            file.accept = "image/jpeg,image/png";
            file.onchange = function () {
                var f = file.files.length > 0 ? file.files[0] : null;
                if (!f)
                    return;
                var reader = new FileReader();
                reader.onload = function (ev) { return onchanged(reader.result); };
                reader.readAsDataURL(f);
            };
            return file;
        };
        function mkFileInput(file, maxMb, fileType) {
            if (fileType === void 0) { fileType = ""; }
            var input;
            fileType = fileType || file.type;
            if (/^image\//.test(fileType)) {
                input = document.createElement("img");
                input.style.maxWidth = '15em';
                input.style.maxHeight = '7em';
                input.src = file;
                fileReadAsDataURLAsync(file, fileType).done(function (url) { return input.src = url; });
            }
            else if (/^audio\//.test(fileType)) {
                input = document.createElement("audio");
                input.crossorigin = "anonymous";
                input.src = file;
                fileReadAsDataURLAsync(file, fileType).done(function (url) { return input.src = url; });
            }
            else {
                input = TDev.div('wall-textbox', TDev.lf("{0} {1}Kb", file.name, Math.ceil(file.size / 1000)));
            }
            input.style.margins = '0.5em';
            return {
                element: input,
                validate: function () { return null; },
                readAsync: function () { return fileReadAsDataURLAsync(file, fileType); }
            };
        }
        HTML.mkFileInput = mkFileInput;
        HTML.mkImageInput = function (allowEmpty, maxMb) {
            var input = HTML.mkTextInput("file", TDev.lf("choose a picture"));
            input.accept = "image/jpeg,image/png";
            return { element: input, validate: function () {
                var files = input.files;
                if (files.length == 0)
                    return allowEmpty ? null : TDev.lf("Oops, you need to select a picture...");
                var f = files[0];
                if (maxMb > 0 && f.size > maxMb * 1000000)
                    return TDev.lf("Sorry, the picture is too big. The picture must be less than {0} Mb...", maxMb);
                if (f.type !== 'image/jpeg' && f.type !== 'image/png')
                    return TDev.lf("Sorry, you can only upload JPEG and PNG pictures...");
                return null;
            }, readAsync: function () {
                var f = input.files[0];
                if (!f)
                    return TDev.Promise.as(null);
                else {
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        var reader = new FileReader();
                        reader.onerror = function (ev) { return onSuccess(null); };
                        reader.onload = function (ev) { return onSuccess(reader.result); };
                        reader.readAsDataURL(f);
                    });
                }
            } };
        };
        function setRole(el, role) {
            if (!el)
                return;
            if (role)
                el.setAttribute("role", role);
            else
                el.removeAttribute("role");
        }
        HTML.setRole = setRole;
        function enableSpeech(el, changed) {
            el.setAttribute('x-webkit-speech', 'x-webkit-speech');
            el.onwebkitspeechchange = function () {
                changed();
            };
            el.onspeechchange = function () {
                changed();
            };
        }
        HTML.enableSpeech = enableSpeech;
        function mkTextInput(type, placeholder, role, label) {
            var txt = document.createElement("input");
            txt.setAttribute("type", type);
            if (placeholder) {
                txt.setAttribute("placeholder", placeholder);
                txt.setAttribute("aria-label", label || placeholder);
            }
            if (role)
                HTML.setRole(txt, role);
            txt.autofocus = false;
            txt.className = "wall-textbox";
            TDev.dirAuto(txt);
            if (TDev.Browser.browser == 9 /* safari */)
                txt.autocapitalize = false;
            txt.onselectstart = function (e) {
                e.stopImmediatePropagation();
                return true;
            };
            return txt;
        }
        HTML.mkTextInput = mkTextInput;
        function mkTextInputWithOk(type, placeholder, onOk) {
            var res = mkTextInput(type, placeholder);
            var okBtn = null;
            TDev.Util.onInputChange(res, function () {
                if (okBtn)
                    return;
                res.style.width = "calc(100% - 6em)";
                okBtn = mkButton(TDev.lf("ok"), function () {
                    var b = okBtn;
                    okBtn = null;
                    res.style.width = "";
                    if (b)
                        b.removeSelf();
                    res.blur();
                }, "input-confirm");
                res.parentNode.insertBefore(okBtn, res.nextSibling);
            });
            res.addEventListener("blur", function () {
                var b = okBtn;
                okBtn = null;
                res.style.width = "";
                if (b)
                    b.removeSelf();
                if (onOk)
                    onOk();
            }, false);
            return res;
        }
        HTML.mkTextInputWithOk = mkTextInputWithOk;
        function mkOption(value, label, selected) {
            if (selected === void 0) { selected = undefined; }
            var children = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                children[_i - 3] = arguments[_i];
            }
            var option = document.createElement("option");
            option.label = label;
            option.value = value;
            if (selected !== undefined)
                option.selected = selected;
            if (label)
                option.appendChildren(label);
            option.appendChildren(children);
            return option;
        }
        HTML.mkOption = mkOption;
        function mkComboBox(options) {
            var combobox = document.createElement("select");
            combobox.autofocus = false;
            combobox.className = "wall-textbox";
            combobox.appendChildren(options);
            return combobox;
        }
        HTML.mkComboBox = mkComboBox;
        function getCheckboxValue(ch) {
            return !!ch.selected;
        }
        HTML.getCheckboxValue = getCheckboxValue;
        function setCheckboxValue(ch, v) {
            ch.theBox.setChildren(v ? [TDev.text("\u2713")] : []);
            ch.selected = v;
        }
        HTML.setCheckboxValue = setCheckboxValue;
        function mkCheckBox(lbl, onchg, v) {
            if (onchg === void 0) { onchg = undefined; }
            return mkTickCheckBox(0 /* noEvent */, lbl, onchg, v);
        }
        HTML.mkCheckBox = mkCheckBox;
        function mkTickCheckBox(t, lbl, onchg, v) {
            if (onchg === void 0) { onchg = undefined; }
            var b = TDev.div("theBox", TDev.text(""));
            var r = TDev.div("checkbox", b, TDev.text(lbl));
            r.theBox = b;
            setTickCallback(r, t, function () {
                var nv = !r.selected;
                setCheckboxValue(r, nv);
                if (!!onchg)
                    onchg(nv);
            });
            if (v !== undefined)
                setCheckboxValue(r, v);
            return r;
        }
        HTML.mkTickCheckBox = mkTickCheckBox;
        function mkCheckBoxLocalStorage(key, msg) {
            var val = !!window.localStorage.getItem(key);
            var check = HTML.mkCheckBox(msg, function (v) { return TDev.Util.localStore(key, v ? "1" : undefined); }, val);
            return check;
        }
        HTML.mkCheckBoxLocalStorage = mkCheckBoxLocalStorage;
        function mkRadioButtons(lbls) {
            var res = {
                current: -1,
                enabled: true,
                buttons: lbls.map(function (l, i) { return setTickCallback(mkButtonElt("radio-button", TDev.div("radio-outer", TDev.div("radio-inner")), TDev.div("radio-label", l.name)), l.tick, function () {
                    if (res.enabled)
                        res.change(i);
                }); }),
                onchange: function (n) {
                },
                change: function (n) {
                    res.current = n;
                    res.buttons.forEach(function (b, i) { return b.setFlag("selected", i == n); });
                    res.onchange(n);
                },
                elt: TDev.div("radio-group")
            };
            res.elt.setChildren(res.buttons);
            return res;
        }
        HTML.mkRadioButtons = mkRadioButtons;
        function mkModalList(children) {
            var kindList = TDev.div("modalList", children);
            TDev.Util.setupDragToScroll(kindList);
            return kindList;
        }
        HTML.mkModalList = mkModalList;
        var progressNotificationAnimation;
        HTML.showProgressNotification = function (msgText, fadeOut, delay, duration) {
            if (fadeOut === void 0) { fadeOut = true; }
            if (delay === void 0) { delay = 1000; }
            if (duration === void 0) { duration = 2000; }
            if (TDev.Browser.isHeadless) {
                TDev.Util.log("progress: " + msgText);
                return;
            }
            var className = "progressNotification";
            var se = TDev.elt("root");
            var oldMsgs = se.getElementsByClassName(className);
            var msg = oldMsgs.length > 0 ? oldMsgs.item(0) : undefined;
            var f = function () {
                progressNotificationAnimation = undefined;
                if (fadeOut) {
                    progressNotificationAnimation = TDev.Animation.fadeOut(msg);
                    progressNotificationAnimation.delay = delay;
                    progressNotificationAnimation.duration = duration;
                    progressNotificationAnimation.completed = function () {
                        progressNotificationAnimation = undefined;
                    };
                    progressNotificationAnimation.begin();
                }
            };
            if (msg) {
                if (!!progressNotificationAnimation) {
                    progressNotificationAnimation.stop();
                }
                msg.style.opacity = "1";
                if (msgText !== undefined) {
                    msg.removeAllChildren();
                    msg.appendChildren(msgText);
                }
                f();
            }
            else if (msgText) {
                msg = TDev.div(className, msgText);
                msg.setAttribute("role", "alert");
                msg.setAttribute("aria-live", "status");
                se.appendChild(msg);
                progressNotificationAnimation = TDev.Animation.fadeIn(msg);
                progressNotificationAnimation.completed = f;
                progressNotificationAnimation.begin();
            }
        };
        function showWarningNotification(msgText, options) {
            if (options === void 0) { options = {}; }
            if (TDev.Browser.isHeadless) {
                TDev.Util.log("warning: " + msgText);
                return;
            }
            var info = TDev.div('info', msgText);
            var msg = TDev.div("warningNotification", info);
            msg.setAttribute("role", "alert");
            msg.setAttribute("aria-label", msgText);
            var a = TDev.Animation.fadeOut(msg);
            a.delay = 6000;
            a.duration = 500;
            a.begin();
            if (options && options.els)
                info.appendChildren(options.els);
            if (options && options.details) {
                msg.appendChild(TDev.div('info link', TDev.lf("learn more...")));
                msg.withClick(function () {
                    TDev.tick(470 /* warningNotificationTap */);
                    TDev.ModalDialog.info(msgText, options.details);
                });
            }
            info.appendChild(HTML.mkLinkButton(TDev.lf("dismiss"), function () {
                a.complete();
            }));
            TDev.elt("root").appendChild(msg);
        }
        HTML.showWarningNotification = showWarningNotification;
        function showPluginNotification(msgText) {
            var msg = TDev.div("pluginNotification", TDev.div('info', msgText));
            msg.setAttribute("role", "alert");
            msg.setAttribute("aria-live", "status");
            TDev.elt("root").appendChild(msg);
            var a = TDev.Animation.fadeOut(msg);
            a.delay = 6000;
            a.duration = 3000;
            a.begin();
        }
        HTML.showPluginNotification = showPluginNotification;
        function showUndoNotification(msgText, undo) {
            var previous = TDev.elt("infoNotification");
            if (previous)
                previous.removeSelf();
            var msg = TDev.divId("infoNotification", "infoNotification", msgText, HTML.mkButtonOnce(TDev.lf("undo"), function () {
                msg.removeSelf();
                undo();
            }));
            TDev.elt("root").appendChild(msg);
            var fi = TDev.Animation.fadeIn(msg, 1000);
            fi.completed = function () {
                var a = TDev.Animation.fadeOut(msg);
                a.delay = 4000;
                a.duration = 1000;
                a.begin();
            };
            fi.begin();
        }
        HTML.showUndoNotification = showUndoNotification;
        function showErrorNotification(msgText) {
            if (TDev.Browser.isHeadless) {
                TDev.Util.log("error: " + msgText);
                return;
            }
            var msg = TDev.div("errorNotification", msgText);
            msg.setAttribute("role", "alert");
            msg.setAttribute("alert-label", msgText);
            TDev.elt("root").appendChild(msg);
            var a = TDev.Animation.fadeOut(msg);
            a.delay = 2000;
            a.duration = 2000;
            a.begin();
        }
        HTML.showErrorNotification = showErrorNotification;
        function showSaveNotification(msgText, time) {
            if (time === void 0) { time = 1000; }
            var msg = TDev.div("saveNotification", msgText);
            TDev.elt("root").appendChild(msg);
            var a = TDev.Animation.fadeOut(msg);
            a.delay = time;
            a.duration = 1000;
            a.begin();
            return msg;
        }
        HTML.showSaveNotification = showSaveNotification;
        ;
        function showWebNotification(aTitle, aOptions, aTimeout) {
            if (aOptions === void 0) { aOptions = {}; }
            if (aTimeout === void 0) { aTimeout = 10000; }
            if (TDev.Cloud.isRestricted())
                return;
            if (!("Notification" in window))
                return;
            if (document.hasFocus())
                return;
            var Notification = window.Notification;
            var doit = function () {
                var n = new Notification(aTitle, aOptions);
                n.onshow = function () {
                    TDev.Util.setTimeout(aTimeout, function () { return n.close(); });
                };
            };
            if (Notification.permission === "granted") {
                doit();
            }
            else {
                Notification.requestPermission(function (permission) {
                    if (permission === "granted")
                        doit();
                });
            }
        }
        HTML.showWebNotification = showWebNotification;
        function mkA(cl, href, target) {
            var children = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                children[_i - 3] = arguments[_i];
            }
            var elt = document.createElement("a");
            elt.href = href;
            elt.target = target;
            if (cl)
                elt.className = cl;
            elt.appendChildren(children);
            return elt;
        }
        HTML.mkA = mkA;
        function li(cls) {
            var elts = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                elts[_i - 1] = arguments[_i];
            }
            var r = document.createElement("li");
            if (cls)
                r.className = cls;
            r.setChildren(elts);
            return r;
        }
        HTML.li = li;
        function span(cls) {
            var elts = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                elts[_i - 1] = arguments[_i];
            }
            var r = document.createElement("span");
            if (cls)
                r.className = cls;
            r.setChildren(elts);
            return r;
        }
        HTML.span = span;
        function label(cls) {
            var elts = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                elts[_i - 1] = arguments[_i];
            }
            var r = document.createElement("label");
            if (cls)
                r.className = cls;
            r.setChildren(elts);
            return r;
        }
        HTML.label = label;
        function browserDownloadText(text, name, contentType) {
            if (contentType === void 0) { contentType = "octet/stream"; }
            var buf = TDev.Util.stringToUint8Array(TDev.Util.toUTF8(text));
            browserDownloadUInt8Array(buf, name, contentType);
        }
        HTML.browserDownloadText = browserDownloadText;
        function browserDownloadUInt8Array(buf, name, contentType) {
            if (contentType === void 0) { contentType = "octet/stream"; }
            try {
                if (typeof saveAs !== "undefined") {
                    var b = new Blob([buf], { type: contentType });
                    saveAs(b, name, true);
                    return;
                }
                if (window.navigator.msSaveOrOpenBlob && !TDev.Browser.isMobile) {
                    var b = new Blob([buf], { type: contentType });
                    var result = window.navigator.msSaveOrOpenBlob(b, name);
                }
                else {
                    var link = window.document.createElement('a');
                    var dataurl = "data:" + contentType + ";base64," + TDev.Util.base64EncodeBytes(buf);
                    if (typeof link.download == "string") {
                        link.href = dataurl;
                        link.download = name;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                    }
                    else {
                        document.location.href = dataurl;
                    }
                }
            }
            catch (e) {
                TDev.Util.reportError("browserdownload", e, false);
                HTML.showProgressNotification(TDev.lf("saving file failed..."));
            }
        }
        HTML.browserDownloadUInt8Array = browserDownloadUInt8Array;
        function browserDownload(dataurl, name) {
            try {
                var getblob = function () {
                    var m = /data:([^;]+);base64,/.exec(dataurl);
                    var buf = TDev.Util.stringToUint8Array(atob(dataurl.slice(m[0].length)));
                    return new Blob([buf], { type: m[1] });
                };
                if (typeof saveAs !== "undefined") {
                    saveAs(getblob(), name, true);
                    return;
                }
                if (window.navigator.msSaveOrOpenBlob) {
                    var result = window.navigator.msSaveOrOpenBlob(getblob(), name);
                }
                else {
                    var link = window.document.createElement('a');
                    link.href = dataurl;
                    if (typeof link.download == "string") {
                        link.download = name;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                    }
                    else {
                        document.location.href = dataurl;
                    }
                }
            }
            catch (e) {
                TDev.Util.reportError("browserdownload", e, false);
                HTML.showProgressNotification(TDev.lf("saving file failed..."));
            }
        }
        HTML.browserDownload = browserDownload;
        function showNotification(msg) {
            TDev.elt("root").appendChild(msg);
            var a = TDev.Animation.fadeOut(msg);
            a.delay = 6000;
            a.duration = 2000;
            a.begin();
        }
        HTML.showNotification = showNotification;
        function showNotificationText(text) {
            var msg = TDev.div("errorNotification", text);
            showNotification(msg);
        }
        HTML.showNotificationText = showNotificationText;
        function showProxyNotification(message, url) {
            var msg = TDev.div("errorNotification", message, mkBr(), span("smallText", "URL: " + url));
            showNotification(msg);
        }
        HTML.showProxyNotification = showProxyNotification;
        function showCorsNotification(url) {
            var msg = TDev.div("errorNotification", TDev.lf("Access Denied: Your web browser and the web site prevent cross-origin resource sharing (CORS)."), mkA("", TDev.Cloud.config.rootUrl + TDev.Cloud.config.topicPath + "CORS", "_blank", TDev.lf("Learn more...")), mkBr(), span("smallText", TDev.lf("URL: {0}", url)));
            showNotification(msg);
        }
        HTML.showCorsNotification = showCorsNotification;
        function mkProgressBar() {
            var r = TDev.div("progressBar", TDev.Util.range(0, 4).map(function (v) { return TDev.div("progressDot progressDot-" + v); }));
            HTML.setRole(r, "progressbar");
            var n = 0;
            function update(k) {
                n += k;
                if (n < 0)
                    n = 0;
                r.style.display = n > 0 ? "block" : "none";
            }
            update(0);
            if (TDev.Browser.noAnimations) {
                r.start = r.stop = r.reset = function () {
                };
            }
            else {
                r.start = function () {
                    update(+1);
                };
                r.stop = function () {
                    update(-1);
                };
                r.reset = function () {
                    update(-n);
                };
            }
            return r;
        }
        HTML.mkProgressBar = mkProgressBar;
        function mkAutoExpandingTextArea(options) {
            if (options === void 0) { options = {}; }
            var ta = HTML.mkTextArea();
            var pre = document.createElement("pre");
            var dismiss;
            var fullScreen;
            var btns;
            if (options.showDismiss || options.editFullScreenAsync) {
                btns = TDev.div('close-round-buttons');
                if (options.showDismiss)
                    btns.appendChild(dismiss = TDev.div('', HTML.mkImg("svg:check,currentColor")).withClick(function () {
                        if (r.onDismiss)
                            r.onDismiss();
                    }));
                if (options.editFullScreenAsync)
                    btns.appendChild(fullScreen = TDev.div('', HTML.mkImg('svg:expand,currentColor')).withClick(function () {
                        options.editFullScreenAsync(ta.value).done(function (value) {
                            ta.value = value;
                            if (r.onDismiss)
                                r.onDismiss();
                        });
                    }));
            }
            var content = span(null, null);
            pre.setChildren([content, mkBr()]);
            var update = function () {
                content.textContent = ta.value;
                r.onUpdate();
            };
            TDev.Util.onInputChange(ta, update);
            var r = {
                div: TDev.div("expandingTextAreaContainer", pre, ta, btns),
                textarea: ta,
                update: update,
                onUpdate: function () {
                },
                dismiss: dismiss,
                onDismiss: function () {
                },
                fullScreen: fullScreen,
            };
            if (options.singleLine) {
                ta.onkeydown = function (ev) {
                    if ((ev.keyCode || ev.which) == 13) {
                        ev.stopPropagation();
                        if (r.onDismiss)
                            r.onDismiss();
                        return true;
                    }
                };
            }
            return r;
        }
        HTML.mkAutoExpandingTextArea = mkAutoExpandingTextArea;
        function fixWp8Links() {
            var elts = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                elts[_i - 0] = arguments[_i];
            }
            elts.forEach(function (elt) {
                var ch = elt.getElementsByTagName("A");
                for (var i = 0; i < ch.length; ++i)
                    (function () {
                        var a = ch[i];
                        var href = a.getAttribute("href");
                        if (/^#/.test(href)) {
                            a.onclick = function () { return false; };
                            a.withClick(function () {
                                TDev.Util.setHash(href);
                                return false;
                            });
                        }
                    })();
            });
        }
        HTML.fixWp8Links = fixWp8Links;
        HTML.localCdn = null;
        function proxyResource(url) {
            if (!url)
                return url;
            url = TDev.Cloud.toCdnUrl(url);
            if (HTML.localCdn && !/http:\/\/localhost/i.test(url) && (TDev.Cloud.isArtUrl(url) || /^(https?:\/\/lexmediaservice3.blob.core.windows.net|https:\/\/tdtutorialtranslator.blob.core.windows.net)/i.test(url))) {
                url = HTML.localCdn + encodeURIComponent(url);
            }
            return url;
        }
        HTML.proxyResource = proxyResource;
        function cssImage(url, opacity) {
            if (opacity === void 0) { opacity = 1; }
            if (!url)
                return "";
            var u = "url(" + proxyResource(url) + ")";
            if (opacity < 1)
                u = TDev.Util.fmt("linear-gradient(to bottom, rgba(255,255,255,{0}) 0%,rgba(255,255,255,{0}) 100%), {1}", (1 - opacity).toFixed(3), u);
            return u;
        }
        HTML.cssImage = cssImage;
        HTML.html5Tags = {
            "dialog": -1,
            "embed": -1,
            "keygen": -1,
            "link": -1,
            "meta": -1,
            "noscript": -1,
            "object": -1,
            "param": -1,
            "script": -1,
            "applet": -1,
            "frame": -1,
            "frameset": -1,
            "noframes": -1,
            "html": -1,
            "body": -1,
            "head": -1,
            "form": -1,
            "style": -1,
            "basefont": -2,
            "font": -2,
            "center": -2,
            "big": -2,
            "dir": -2,
            "acronym": -2,
            "strike": -2,
            "tt": -2,
            "a": 1,
            "ul": 1,
            "h1": 1,
            "h2": 1,
            "h3": 1,
            "h4": 1,
            "h5": 1,
            "h6": 1,
            "ol": 1,
            "li": 1,
            "blockquote": 1,
            "pre": 1,
            "b": 1,
            "button": 1,
            "code": 1,
            "img": 1,
            "strong": 1,
            "span": 1,
            "br": 1,
            "del": 1,
            "div": 1,
            "em": 1,
            "p": 1,
            "i": 1,
            "u": 1,
            "video": 1,
            "source": 1,
            "audio": 1,
            "track": 1,
            "small": 1,
            "hr": 1,
            "iframe": 1,
            "svg": 1,
            "path": 1,
            "circle": 1,
            "g": 1,
            "title": 1,
            "abbr": 2,
            "address": 2,
            "area": 2,
            "article": 2,
            "aside": 2,
            "bdi": 2,
            "bdo": 2,
            "canvas": 2,
            "caption": 2,
            "cite": 2,
            "col": 2,
            "colgroup": 2,
            "datalist": 2,
            "dd": 2,
            "details": 2,
            "dfn": 2,
            "dl": 2,
            "dt": 2,
            "fieldset": 2,
            "figcaption": 2,
            "figure": 2,
            "footer": 2,
            "header": 2,
            "hgroup": 2,
            "input": 2,
            "ins": 2,
            "kbd": 2,
            "label": 2,
            "legend": 2,
            "main": 2,
            "map": 2,
            "mark": 2,
            "menu": 2,
            "menuitem": 2,
            "meter": 2,
            "nav": 2,
            "optgroup": 2,
            "option": 2,
            "output": 2,
            "progress": 2,
            "q": 2,
            "rp": 2,
            "rt": 2,
            "ruby": 2,
            "s": 2,
            "samp": 2,
            "section": 2,
            "select": 2,
            "sub": 2,
            "summary": 2,
            "sup": 2,
            "table": 2,
            "tbody": 2,
            "td": 2,
            "textarea": 2,
            "tfoot": 2,
            "th": 2,
            "thead": 2,
            "time": 2,
            "tr": 2,
            "var": 2,
            "wbr": 2,
        };
        var html5Attributes = {
            "src": 1,
            "srcset": 1,
            "href": 1,
            "xmlns": 1,
            "class": 2,
            "frameborder": 2,
            "allowfullscreen": 2,
            "alt": 2,
            "style": 2,
            "type": 2,
            "target": 2,
            "rel": 2,
            "name": 2,
            "translate": 2,
            "dir": 2,
            "id": 2,
            "width": 2,
            "height": 2,
            "placeholder": 2,
            "title": 2,
            "controls": 2,
            "autoplay": 2,
            "disabled": 2,
            "role": 2,
            "aria-atomic": 2,
            "aria-busy": 2,
            "aria-controls": 2,
            "aria-describedby": 2,
            "aria-disabled": 2,
            "aria-dropeffect": 2,
            "aria-flowto": 2,
            "aria-grabbed": 2,
            "aria-haspopup": 2,
            "aria-hidden": 2,
            "aria-invalid": 2,
            "aria-label": 2,
            "aria-labelledby": 2,
            "aria-live": 2,
            "aria-owns": 2,
            "aria-relevant": 2,
            "viewbox": 2,
            "preserveaspectratio": 2,
            "fill": 2,
            "d": 2,
            "cx": 2,
            "cy": 2,
            "r": 2,
            "stroke": 2,
            "stroke-width": 2,
            "transform": 2,
            "fill-opacity": 2,
            "stroke-miterlimit": 2,
            "stroke-dasharray": 2,
            "sandbox": 2,
        };
        function htmlOops(msg, html, other) {
            if (other)
                msg += ": " + other.slice(0, 100);
            var err = new Error("Critical: HTML sanitization failure, " + msg);
            err.bugAttachments = [html];
            if (other && other.length > 100)
                err.bugAttachments.push(other);
            throw err;
        }
        function validateTag(t, html) {
            if (/^\!--.*--$/.exec(t))
                return;
            var m = /^\/?([a-zA-Z0-9]+)(\s|\/?$)/.exec(t);
            if (!m)
                htmlOops("no tag name", html, t);
            var tn = m[1].toLowerCase();
            if (!HTML.html5Tags.hasOwnProperty(tn))
                htmlOops("unknown tag", html, tn);
            var v = HTML.html5Tags[tn];
            if (v !== 1)
                htmlOops("tag not allowed, " + v, html, tn);
            t = t.slice(m[0].length);
            while (!/^\s*\/?$/.test(t)) {
                m = /^\s*([a-zA-Z0-9-]+)($|\s|="([^"]*)"|='([^']*)'|=([a-zA-Z0-9]+))/.exec(t);
                if (!m)
                    htmlOops("cannot parse html attribute", html, t);
                var an = m[1].toLowerCase();
                var av = m[3] || m[4] || m[5] || "";
                if (/^data-/.test(an)) {
                }
                else if (!html5Attributes.hasOwnProperty(an))
                    htmlOops("unknown attribute", html, t);
                else {
                    var kk = html5Attributes[an];
                    if (kk == 1) {
                        if (!/^(http|\/|\.\/|#|mailto:)/i.test(av))
                            htmlOops("bad URL", html, t);
                    }
                    else if (kk == 2) {
                    }
                    else {
                        htmlOops("forbidden attribute", html, t);
                    }
                }
                t = t.slice(m[0].length);
            }
        }
        function sanitizeHTML(html) {
            if (!TDev.isBeta)
                return html;
            if (!html)
                return html;
            try {
                var reminder = html.replace(/<([^<>]+)>/g, function (allm, t) {
                    validateTag(t, html);
                    return "(tag)";
                });
                if (/[<>]/.test(reminder)) {
                    htmlOops("unexpected tag", html, reminder);
                }
                return html;
            }
            catch (e) {
                TDev.Util.reportError("html", e, false);
                return html;
            }
        }
        HTML.sanitizeHTML = sanitizeHTML;
        function allowedTagName(tn) {
            tn = tn.toLowerCase();
            if (!HTML.html5Tags.hasOwnProperty(tn))
                return false;
            var v = HTML.html5Tags[tn];
            return v === 1 || v === 2;
        }
        HTML.allowedTagName = allowedTagName;
        function allowedAttribute(name, val) {
            if (/^data-/.test(name))
                return true;
            if (!html5Attributes.hasOwnProperty(name))
                return false;
            var v = html5Attributes[val];
            if (v === 1)
                return /^(http|\/|\.\/|#|mailto:)/.test(val);
            else if (v === 2)
                return true;
            else
                return false;
        }
        HTML.allowedAttribute = allowedAttribute;
    })(HTML = TDev.HTML || (TDev.HTML = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var StackFrameBase = (function () {
        function StackFrameBase(rt) {
            this.rt = rt;
            this.returnAddr = null;
            this.entryAddr = null;
            this.previous = null;
            this.isLibProxy = false;
        }
        return StackFrameBase;
    })();
    TDev.StackFrameBase = StackFrameBase;
    var StackBottom = (function (_super) {
        __extends(StackBottom, _super);
        function StackBottom(rt) {
            _super.call(this, rt);
            this.needsPicker = false;
            this.pc = "";
            this.stackDepth = 0;
            this.name = "<entry-point>";
            this.d = this.rt.datas["this"];
            this.libs = this.rt.compiled.libs;
        }
        return StackBottom;
    })(StackFrameBase);
    TDev.StackBottom = StackBottom;
    var LibProxy = (function (_super) {
        __extends(LibProxy, _super);
        function LibProxy(libs, previous, libRefName, libActionName, invoke) {
            _super.call(this, previous.rt);
            this.libRefName = libRefName;
            this.libActionName = libActionName;
            this.invoke = invoke;
            this.isLibProxy = true;
            this.pc = "";
            this.libs = libs;
            this.previous = previous;
            this.prevPC = previous.pc;
            this.d = this.rt.datas[this.libRefName];
            this.name = this.libActionName;
            this.stackDepth = previous.stackDepth;
        }
        return LibProxy;
    })(StackFrameBase);
    TDev.LibProxy = LibProxy;
    var ResumeCtx = (function () {
        function ResumeCtx(stackframe) {
            this.stackframe = stackframe;
            this.used = false;
            this.isBlocking = false;
            this.rt = stackframe.rt;
            stackframe.rendermode = stackframe.rt.rendermode;
        }
        ResumeCtx.prototype.isTaskCtx = function () {
            return false;
        };
        ResumeCtx.prototype.clearProgress = function () {
            if (this.shownProgress) {
                this.shownProgress = false;
                TDev.HTML.showProgressNotification("");
            }
        };
        ResumeCtx.prototype.resumeVal = function (v) {
            if (this.used)
                return;
            this.used = true;
            this.clearProgress();
            this.resumeCore(v);
        };
        ResumeCtx.prototype.resumeCore = function (v) {
            this.rt._resumeVal(v, this);
        };
        ResumeCtx.prototype.resume = function () {
            return this.resumeVal(undefined);
        };
        ResumeCtx.prototype.progress = function (msg) {
            this.shownProgress = true;
            TDev.HTML.showProgressNotification(msg, false);
        };
        return ResumeCtx;
    })();
    TDev.ResumeCtx = ResumeCtx;
    (function (RtState) {
        RtState[RtState["Stopped"] = 0] = "Stopped";
        RtState[RtState["Running"] = 1] = "Running";
        RtState[RtState["Paused"] = 2] = "Paused";
        RtState[RtState["AtAwait"] = 3] = "AtAwait";
        RtState[RtState["BreakpointHit"] = 4] = "BreakpointHit";
    })(TDev.RtState || (TDev.RtState = {}));
    var RtState = TDev.RtState;
    var RuntimeSettings;
    (function (RuntimeSettings) {
        RuntimeSettings.readSetting = function (key) {
            return window.localStorage[key];
        };
        RuntimeSettings.storeSetting = function (key, value) {
            window.localStorage[key] = value;
        };
        function location() {
            return !RuntimeSettings.readSetting("rtnolocation");
        }
        RuntimeSettings.location = location;
        function setLocation(value) {
            RuntimeSettings.storeSetting("rtnolocation", value ? value : undefined);
        }
        RuntimeSettings.setLocation = setLocation;
        function sounds() {
            return !RuntimeSettings.readSetting("rtsnosounds");
        }
        RuntimeSettings.sounds = sounds;
        function setSounds(value) {
            RuntimeSettings.storeSetting("rtsnosounds", value ? value : undefined);
            if (!value)
                TDev.RT.Player.pause();
        }
        RuntimeSettings.setSounds = setSounds;
        RuntimeSettings.askSourceAccess = true;
    })(RuntimeSettings = TDev.RuntimeSettings || (TDev.RuntimeSettings = {}));
    var Runtime = (function () {
        function Runtime(sessions) {
            this.handlingException = false;
            this.datas = {};
            this.testMode = false;
            this.devMode = true;
            this.eventQ = null;
            this.recordTypesRegistered = false;
            this.resumePointOverride = null;
            this.versionNumber = 1;
            this.restartQueued = false;
            this.tutorialState = null;
            this.renderedComments = "";
            this.webState = {};
            this.state = 0 /* Stopped */;
            this.stateMsg = undefined;
            this.eventExecuting = false;
            this.mainLoopRunning = false;
            this.resumeAllowed = false;
            this.runningPluginOn = "";
            this.headlessPluginMode = false;
            this.tutorialObject = "";
            this.pageTransitionStyle = "slide";
            this.currentScriptId = undefined;
            this.currentAuthorId = undefined;
            this.baseScriptId = undefined;
            this.disposables = [];
            this.asyncStack = [];
            this.asyncTasks = [];
            this.runMap = new TDev.RunBitMap();
            this.debuggerLastState = null;
            this.eventCategory = null;
            this.eventVariable = null;
            this.inCloudCall = false;
            this.inQuery = false;
            this.rendermode = false;
            this.lastBreak = 0;
            this.quickLoopDepth = 0;
            this.sessions = sessions || new TDev.Revisions.Sessions();
            this.sessions.rt = this;
        }
        Runtime.prototype.liveMode = function () {
            return this.host.liveMode();
        };
        Runtime.prototype.getWall = function () {
            return this.host.getWall();
        };
        Runtime.prototype.runtimeKind = function () {
            return this.devMode ? "editor" : "website";
        };
        Runtime.prototype.requiresAuth = function () {
            return this.compiled.hasCloudData && this.sessions.getCurrentSession().requiresAuth;
        };
        Runtime.prototype.getUserId = function () {
            if (this.authUserId)
                return this.authUserId;
            if (this.sessions.isNodeClient()) {
                return this.sessions.getCurrentSession().clientUserId;
            }
            return TDev.Cloud.getUserId();
        };
        Runtime.prototype.getScriptGuid = function () {
            return this.host.currentGuid;
        };
        Runtime.prototype.getScriptName = function () {
            return this.compiled.scriptTitle;
        };
        Runtime.prototype.getScriptColor = function () {
            return this.compiled.scriptColor;
        };
        Runtime.prototype.beenHere = function (id) {
            this.runMap.push(id);
        };
        Runtime.prototype.resetRunMap = function () {
            this.runMap.clear();
        };
        Runtime.prototype.initBreakpoints = function (h) {
            this.breakpoints = h;
            this.updateScriptBreakpoints();
        };
        Runtime.prototype.hitBreakpoint = function (id) {
            this.debuggerLastState = this.state;
            this.setState(4 /* BreakpointHit */, "breakpoint");
            this.host.notifyBreakpointHit(id);
        };
        Runtime.prototype.updateScriptBreakpoints = function () {
            var _this = this;
            if (!this.compiled)
                return;
            var binds = this.compiled.breakpointBindings;
            Object.keys(binds).forEach(function (k) {
                var bind = binds[k];
                bind.setter(_this.breakpoints.get(k));
            });
        };
        Runtime.prototype.debuggerContinue = function () {
            if (!this.debuggerStopped())
                return;
            if (this.debuggerLastState !== null)
                this.setState(this.debuggerLastState, "debugger last state");
            if (this.debuggerCC)
                this.mainLoop(this.debuggerCC, "resume debugger");
        };
        Runtime.prototype.debuggerStopped = function () {
            return this.state === 4 /* BreakpointHit */;
        };
        Runtime.prototype.debuggerQueryGlobalValue = function (stableName) {
            TDev.Util.log("Runtime.debuggerQueryGlobalValue: " + stableName);
            if (!this.compiled || !this.current)
                return;
            return this.current.d[stableName];
        };
        Runtime.prototype.debuggerQueryLocalValue = function (actionId, name, stackFrame) {
            TDev.Util.log("Runtime.debuggerQueryLocalValue: " + name);
            if (!this.compiled || !this.current)
                return;
            var actionBindings;
            this.compiled.forEachLib(function (l) {
                if (!actionBindings && l.localNamesBindings)
                    actionBindings = l.localNamesBindings[actionId];
            });
            if (!actionBindings)
                return;
            name = actionBindings[name];
            TDev.Util.log("Runtime.debuggerQueryLocalValue resolved to: " + name);
            var frame = stackFrame ? stackFrame : this.current;
            return frame && frame["$" + name];
        };
        Runtime.prototype.debuggerQueryOutValue = function (ix, stackFrame) {
            TDev.Util.log("Runtime.debuggerQueryOutValue: " + ix);
            if (!this.compiled || !this.current)
                return;
            var frame = stackFrame ? stackFrame : this.current;
            if (ix > 0)
                return frame.results[ix];
            else
                return frame.orig_result || frame.result || (frame.results && frame.results[0]);
        };
        Runtime.prototype.saveAndCloseAllSessionsAsync = function () {
            return this.sessions.clearScriptContext(true);
        };
        Runtime.prototype.permissionsAsync = function () {
            return this.sessions.getLocalSessionAttributeAsync("____source_access", this).then(function (s) { return JSON.parse(s || "{}"); });
        };
        Runtime.prototype.savePermissionsAsync = function (perm) {
            return this.sessions.setLocalSessionAttributeAsync("____source_access", JSON.stringify(perm), this);
        };
        Runtime.offerNotifications = function () {
            return !!Runtime.refreshNotifications || !!localStorage["gcm"];
        };
        Runtime.prototype.getActionResults = function () {
            var r = this.returnedFrom;
            if (!r)
                return null;
            if (r.results)
                return r.results.slice(0);
            else
                return [r.result];
        };
        Runtime.prototype.setNextEvent = function (c, v) {
            this.eventCategory = c;
            this.eventVariable = v;
        };
        Runtime.prototype.resetNextEvent = function () {
            this.eventCategory = null;
            this.eventVariable = null;
        };
        Runtime.prototype.currentTime = function () {
            return TDev.Util.perfNow();
        };
        Runtime.prototype.setHost = function (h) {
            this.host = h;
            this.host.init(this);
        };
        Runtime.prototype.startCloudCall = function (libName, actionName, paramNames, returnNames, args, isQuery) {
            TDev.Util.assert(!this.inCloudCall);
            TDev.Util.assert(!this.inQuery);
            this.inCloudCall = true;
            if (!isQuery) {
                this.sessions.getCurrentSession().user_start_cloud_operation(libName, actionName, paramNames, returnNames, args, 2 /* OFFLINE */);
            }
            else {
                this.inQuery = true;
            }
        };
        Runtime.prototype.endCloudCall = function (libName, actionName, paramNames, returnNames, args, isQuery) {
            TDev.Util.assert(this.inCloudCall);
            this.inCloudCall = false;
            if (isQuery) {
                TDev.Util.assert(this.inQuery);
                this.inQuery = false;
            }
            else {
                this.sessions.getCurrentSession().user_stop_cloud_operation(libName, actionName, paramNames, returnNames, args);
            }
        };
        Runtime.prototype.log = function (s) {
            TDev.Util.log(s);
        };
        Runtime.prototype.mayPostToWall = function (p) {
            return !this.headlessPluginMode && (!p.isAuto() || this.rendermode || p.crashed);
        };
        Runtime.prototype.clearWall = function () {
            var p = this.getCurrentPage();
            if (p.isAuto())
                TDev.Util.userError(TDev.lf("cannot clear wall on pages"));
            p.clear();
            p.render(this.host);
        };
        Runtime.prototype.setWallDirection = function (topDown) {
            var p = this.getCurrentPage();
            if (p.isAuto())
                TDev.Util.userError(TDev.lf("cannot set wall direction on pages"));
            p.setReversed(topDown);
        };
        Runtime.prototype.postHtml = function (e, pc) {
            this.postBoxedHtml(e, pc);
        };
        Runtime.prototype.postText = function (s, pc) {
            this.postHtml(TDev.div("wall-text", s), pc);
        };
        Runtime.prototype.postException = function (e) {
            var p = this.getCurrentPage();
            if (this.rendermode)
                this.abortRender();
            else if (p.isAuto())
                p.clear();
            p.crashed = true;
            this.postBoxedHtml(e, "");
        };
        Runtime.prototype.addTapEvent = function (e, tp, box, v) {
            var _this = this;
            if (this.eventEnabled("tap wall " + tp)) {
                if (!box || !this.getCurrentPage().isAuto()) {
                    e.style.cursor = "pointer";
                    e.withClick(function () {
                        _this.eventQ.add("tap wall " + tp, null, [v]);
                    });
                }
                else {
                    box.withClick(function () {
                        _this.eventQ.add("tap wall " + tp, null, [v]);
                    });
                }
            }
        };
        Runtime.prototype.getPageCount = function () {
            return !this.pageStack ? 0 : this.pageStack.length < 1 ? 1 : this.pageStack.length;
        };
        Runtime.prototype.pushPage = function (auto) {
            if (auto === void 0) { auto = false; }
            var currentPage = this.getCurrentPage();
            currentPage.deactivate();
            var page = new TDev.WallPage(this, auto);
            if (auto && this.pageStack.length == 1 && !this.pageStack[0].isAuto() && this.pageStack[0].lastChildCount < 0 && !(this.pageStack[0].fullScreenElement))
                this.pageStack[0] = page;
            else
                this.pageStack.push(page);
            var wall = this.getWall();
            wall.appendChild(page.getElement());
            if (this.pageTransitionStyle == "slide")
                TDev.Util.coreAnim("showPageRight", 400, page.getElement());
            else if (this.pageTransitionStyle == "fade")
                TDev.Util.coreAnim("fadeIn", 400, page.getElement());
            this.forcePageRefresh();
            this.host.notifyPagePush();
            this.applyPageAttributes();
            return page;
        };
        Runtime.prototype.popPagesIncluding = function (p) {
            while (this.pageStack.indexOf(p) >= 0) {
                if (!this.popPage())
                    return;
            }
        };
        Runtime.prototype.popPage = function (transition) {
            var _this = this;
            if (transition === void 0) { transition = null; }
            if (this.pageStack.length <= 1)
                return false;
            var currentPage = this.pageStack.pop();
            var prevPage = currentPage;
            var currentElement = currentPage.getElement();
            currentPage = this.getCurrentPage();
            currentPage.activate();
            var hideStyle = transition;
            var hideAnim = null;
            if (hideStyle == "slide" || hideStyle == "slide right")
                hideAnim = "hidePageLeft 0.2";
            else if (hideStyle == "slide up")
                hideAnim = "hidePageUp 0.7";
            else if (hideStyle == "slide down")
                hideAnim = "hidePageDown 0.7";
            else if (hideStyle == "fade")
                hideAnim = "fadeOut 0.3";
            else if (hideStyle == "none")
                hideAnim = "fadeOut 0.01";
            if (!hideAnim && this.pageTransitionStyle == "slide")
                hideAnim = "hidePageLeft 0.2";
            if (hideAnim) {
                currentPage.getElement().style.opacity = "0";
                var parts = hideAnim.split(/ /);
                var hideDuration = parseFloat(parts[1]) * 1000;
                hideAnim = parts[0];
                TDev.Util.coreAnim(hideAnim, hideDuration, currentElement, function () {
                    currentElement.removeSelf();
                    currentPage.getElement().style.opacity = null;
                    if (_this.pageTransitionStyle == "slide")
                        TDev.Util.coreAnim("showPageLeft", 300, currentPage.getElement());
                    else if (_this.pageTransitionStyle == "fade")
                        TDev.Util.coreAnim("fadeIn", 400, currentPage.getElement());
                    else {
                    }
                });
            }
            else if (this.pageTransitionStyle == "fade") {
                TDev.Util.coreAnim("fadeOut", 400, currentElement, function () { return currentElement.removeSelf(); });
                TDev.Util.coreAnim("fadeIn", 400, currentPage.getElement());
            }
            else {
                currentElement.removeSelf();
            }
            if (this.eventEnabled("page navigated from"))
                this.eventQ.add("page navigated from", null, [prevPage.rtPage()]);
            if (prevPage.onNavigatedFrom.handlers)
                this.queueLocalEvent(prevPage.onNavigatedFrom);
            this.host.notifyPagePop(prevPage);
            this.applyPageAttributes();
            if (currentPage.isAuto())
                this.forcePageRefresh();
            else
                currentPage.render(this.host);
            return true;
        };
        Runtime.prototype.getPageAt = function (idx) {
            if (idx == 0)
                return this.getCurrentPage();
            else
                return this.pageStack[idx];
        };
        Runtime.prototype.initPageStack = function () {
            var page = new TDev.WallPage(this, false);
            this.pageStack = [page];
            var wall = this.getWall();
            if (wall)
                wall.setChildren([page.getElement()]);
            this.sessions.scriptRestarted();
            this.resetRender();
        };
        Runtime.prototype.refreshPageStackForNewScript = function () {
            this.pageStack.forEach(function (p) { return p.refreshForNewScript(); });
        };
        Runtime.prototype.getCurrentPage = function () {
            if (!this.pageStack)
                return new TDev.WallPage(this, false);
            return this.pageStack.peek();
        };
        Runtime.prototype.onCssPage = function () {
            if (!this.pageStack)
                return false;
            var pg = this.pageStack.peek();
            return pg ? pg.csslayout : false;
        };
        Runtime.prototype.addPageButton = function (pageButton) {
            this.forceNonRender("You may not add a page button here");
            var currentPage = this.getCurrentPage();
            currentPage.buttons.push(pageButton);
            this.host.notifyPageButtonUpdate();
            this.addTapEvent(pageButton.getElement(), "Page Button", null, pageButton);
        };
        Runtime.prototype.clearPageButtons = function () {
            this.forceNonRender("You may not remove a page button here");
            var currentPage = this.getCurrentPage();
            currentPage.buttons = [];
            this.host.notifyPageButtonUpdate();
        };
        Runtime.prototype.getPageButtons = function () {
            return this.getCurrentPage().buttons;
        };
        Runtime.prototype.applyPageAttributes = function (renderwall) {
            if (renderwall === void 0) { renderwall = false; }
            var p = this.getCurrentPage();
            this.host.applyPageAttributes(p);
            if (renderwall && !p.isAuto())
                p.render(this.host);
        };
        Runtime.prototype.postAutoPage = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i - 0] = arguments[_i];
            }
            this.eventQ.add("page", null, args);
        };
        Runtime.prototype.forceNonRender = function (msg) {
            if (msg === void 0) { msg = "You may not perform this operation here"; }
            if (this.rendermode) {
                TDev.Util.userError(msg + ". Only side-effect-free operations are allowed in page display code.");
            }
        };
        Runtime.prototype.mkLibObject = function (libId, objectName) {
            var singl = this.getLibRecordSingleton(libId, objectName);
            var obj = new singl.entryCtor(this);
            obj.on_render_heap = this.rendermode;
            return obj;
        };
        Runtime.prototype.getLibRecordSingleton = function (libId, objectName) {
            var indir = this.current.libs[libId + "$lib"];
            if (indir)
                libId = indir;
            var d = this.datas[libId];
            var getsingl = this.compiled.libScripts[libId].objectSingletons[objectName];
            return getsingl(d);
        };
        Runtime.prototype.logDataWrite = function (renderheap) {
            if (renderheap === void 0) { renderheap = false; }
            if (!renderheap)
                this.forceNonRender("You may not modify global variables here");
            if (this.inQuery)
                this.forceNonRender("You may not change data in a query function");
            this.forcePageRefresh();
        };
        Runtime.prototype.logObjectMutation = function (value) {
            if (value) {
                value.versioncounter++;
                if (!value.on_render_heap) {
                    this.forcePageRefresh();
                    this.forceNonRender();
                }
            }
            else {
                this.forceNonRender();
                this.forcePageRefresh();
            }
        };
        Runtime.prototype.forcePageRefresh = function () {
            if (!TDev.Browser.isNodeJS) {
                if (this.eventQ)
                    this.eventQ.queuePageUpdate();
            }
        };
        Runtime.prototype.yield_when_possible = function () {
            if (this.eventQ)
                this.eventQ.queueYield();
        };
        Runtime.prototype.yield_now = function () {
            var changes = this.sessions.yieldSession();
            if (this.eventQ) {
                this.eventQ.finishYield(changes, this.eventEnabled("cloud data updated"));
            }
        };
        Runtime.prototype.registerTimeDependency = function () {
            if (this.rendermode && this.eventQ)
                this.eventQ.registerTimeDependency();
        };
        Runtime.prototype.canPause = function () {
            return this.pageStack && this.pageStack.length && this.pageStack[this.pageStack.length - 1].isAuto();
        };
        Runtime.prototype.canResume = function () {
            return this.canPause() && this.resumeAllowed;
        };
        Runtime.prototype.liveViewSupported = function () {
            return this.canResume() && this.getCurrentPage().isAuto();
        };
        Runtime.prototype.enter_render = function () {
            this.rendermode = true;
            TDev.LayoutMgr.SetRenderExecutionMode(true);
            var page = this.getCurrentPage();
            page.startrender();
            TDev.LayoutMgr.setCurrentRenderBox(page.getCurrentBox());
            TDev.Util.log("Enter Render Mode");
        };
        Runtime.prototype.leave_render = function () {
            TDev.Util.log("Leave Render Mode");
            this.render();
            TDev.LayoutMgr.SetRenderExecutionMode(false);
            this.rendermode = false;
            if (this.eventQ)
                this.eventQ.finishPageUpdate();
        };
        Runtime.prototype.abortRender = function () {
            TDev.LayoutMgr.SetRenderExecutionMode(false);
            this.rendermode = false;
            this.getCurrentPage().clear();
            this.host.setFullScreenElement(undefined);
        };
        Runtime.prototype.resetRender = function () {
            TDev.LayoutMgr.SetRenderExecutionMode(false);
            this.rendermode = false;
            this.host.setFullScreenElement(undefined);
        };
        Runtime.prototype.markAllocated = function (obj) {
            if (this.rendermode && obj)
                obj.on_render_heap = true;
        };
        Runtime.prototype.getCurrentBoxBase = function (nonRenderOk) {
            if (nonRenderOk === void 0) { nonRenderOk = false; }
            if (this.rendermode) {
                return TDev.LayoutMgr.getCurrentRenderBox();
            }
            else {
                if (!nonRenderOk)
                    TDev.Util.userError(TDev.lf("'box' can only be accessed in page display code"));
                return this.getCurrentPage().getCurrentBox();
            }
        };
        Runtime.prototype.getCurrentBox = function () {
            var box = this.getCurrentBoxBase();
            if (!(box instanceof TDev.WallBox))
                TDev.Util.userError(TDev.lf("'box' cannot be accessed in HTML layout mode"));
            return box;
        };
        Runtime.prototype.getCurrentHtmlBox = function () {
            var box = this.getCurrentBoxBase();
            if (!(box instanceof TDev.HtmlBox))
                TDev.Util.userError(TDev.lf("'html' can only be accessed in HTML layout mode"));
            return box;
        };
        Runtime.prototype.render = function (popCount) {
            if (popCount === void 0) { popCount = 0; }
            TDev.Util.assertCode(popCount >= 0);
            this.getCurrentPage().render(this.host, popCount);
        };
        Runtime.prototype.renderBox = function (box) {
            var p = this.getCurrentPage();
            if ((p.crashed || !p.isAuto()) && box.getDepth() === 1) {
                var popCount = 0;
                var parent = box.parent;
                TDev.Util.assert(parent instanceof TDev.WallBox);
                if (parent.size() > Runtime.maxBoxLength) {
                    parent.shift();
                    popCount++;
                }
                this.render(popCount);
            }
        };
        Runtime.prototype.postBoxedHtml = function (e, pc, reusekey) {
            if (reusekey === void 0) { reusekey = null; }
            if (!this.mayPostToWall(this.getCurrentPage()))
                TDev.Util.userError(TDev.lf("cannot post to the wall here"));
            var box = TDev.WallBox.CreateOrRecycleLeafBox(this, reusekey);
            box.setContent(e);
            this.renderBox(box);
            return box;
        };
        Runtime.prototype.postBoxedTextWithTap = function (s, rtV, pc) {
            if (!this.mayPostToWall(this.getCurrentPage()))
                TDev.Util.userError(TDev.lf("cannot post to the wall here"));
            var box = TDev.WallBox.CreateOrRecycleLeafBox(this, rtV);
            if (!box.getContent()) {
                box.setContent(s);
                this.renderBox(box);
                var type;
                switch (typeof rtV) {
                    case "boolean":
                        type = "Bool";
                        break;
                    case "string":
                        type = "String";
                        break;
                    case "number":
                        type = "Number";
                        break;
                    default:
                        type = rtV.rtType();
                        break;
                }
                if (box instanceof TDev.WallBox)
                    this.addTapEvent(box.getContent(), type, box, rtV);
            }
            return box;
        };
        Runtime.prototype.postBoxedText = function (s, pc) {
            if (!this.mayPostToWall(this.getCurrentPage()))
                TDev.Util.userError(TDev.lf("cannot post to the wall here"));
            var box = TDev.WallBox.CreateOrRecycleLeafBox(this, s);
            if (!box.getContent()) {
                box.setContent(s);
                this.renderBox(box);
            }
            return box;
        };
        Runtime.prototype.postUnboxedText = function (s, pc) {
            if (!this.mayPostToWall(this.getCurrentPage()))
                TDev.Util.userError(TDev.lf("cannot post to the wall here"));
            var box = TDev.WallBox.CreateOrRecycleLeafBox(this, s);
            if (!box.getContent()) {
                box.setContent(TDev.text(s));
                this.renderBox(box);
            }
            return box;
        };
        Runtime.prototype.postEditableText = function (style, s, handler, pc) {
            if (!this.mayPostToWall(this.getCurrentPage()))
                TDev.Util.userError(TDev.lf("cannot post to the wall here"));
            var box = TDev.WallBox.CreateOrRecycleLeafBox(this, style);
            var current = box.getContent();
            if (!current) {
                if (style === "textarea") {
                    box.textarea = true;
                    var elt = TDev.HTML.mkTextArea();
                    elt.id = "i" + box.getId();
                    box.setContent(elt);
                }
                else {
                    box.textarea = false;
                    style = (Runtime.inputboxstylemap[style] || "text");
                    var elt2 = TDev.HTML.mkTextInput(style, TDev.lf("edit"));
                    elt2.id = "i" + box.getId();
                    box.setContent(elt2);
                }
                box.bindEditableText(s, handler, pc);
                this.renderBox(box);
            }
            else {
                box.textarea = (style === "textarea");
                box.bindEditableText(s, handler, pc);
            }
            return box;
        };
        Runtime.prototype.nextHitCount = function (current) {
            if (current >= 200)
                return Math.round(200 + (Math.random() * 50));
            else
                return Math.round(current * (Math.random() + 1) + 2);
        };
        Runtime.prototype.isHeadless = function () {
            return this.host && this.host.isHeadless();
        };
        Runtime.prototype.restartAfterException = function () {
            this.current = null;
            this.asyncStack = [];
            this.setState(3 /* AtAwait */, "restart after exception");
            this.queueRestart();
        };
        Runtime.prototype.stopAsync = function (isPause) {
            var _this = this;
            if (isPause === void 0) { isPause = false; }
            var p = TDev.Promise.as();
            if (!this.isHeadless()) {
                TDev.HistoryMgr.instance.clearModalStack();
            }
            if (this.state != 0 /* Stopped */) {
                this.setState(0 /* Stopped */, "stopAsync");
                if (!isPause) {
                    this.versionNumber++;
                    if (this.eventQ)
                        this.eventQ.clear();
                }
                this.eventExecuting = false;
                this.resumeAllowed = isPause;
                if (this.headlessPluginMode)
                    TDev.ProgressOverlay.hide();
                this.asyncStack = [];
                this.asyncTasks = [];
                this.compiled.stopFn(this);
                if (!isPause && !this.resumeAllowed && !this.handlingException) {
                    var profilingData = this.compiled._getProfilingResults();
                    this.host.attachProfilingInfo(profilingData);
                    var runMap = this.getRunMap();
                    if (runMap)
                        this.host.attachCoverageInfo({
                            compilerversion: this.compiled._compilerVersion,
                            astnodes: runMap.toJSON()
                        }, this.compiled._showCoverage);
                }
                if (!this.resumeAllowed) {
                    this.killDisposables();
                    this.killTempState();
                }
                p = this.host.notifyStopAsync();
                p = p.then(function () { return _this.sessions.stopAsync(); });
            }
            return p;
        };
        Runtime.prototype.stopAndHideAsync = function () {
            var p = this.stopAsync();
            this.host.notifyHideWall();
            return p;
        };
        Runtime.prototype.isStopped = function () {
            return this.state == 0 /* Stopped */;
        };
        Runtime.prototype.queueEvent = function (category, varValue, args, ignore) {
            if (ignore === void 0) { ignore = true; }
            if (this.eventQ == null)
                return;
            this.eventQ.add(category, varValue, args, ignore);
        };
        Runtime.prototype.queueBoardEvent = function (categories, valueStack, args, ignore, matchAll) {
            if (ignore === void 0) { ignore = true; }
            if (matchAll === void 0) { matchAll = false; }
            if (this.eventQ == null)
                return;
            this.eventQ.addBoardEvent(categories, valueStack, args, ignore, matchAll);
        };
        Runtime.prototype.queueLocalEvent = function (e, args, ignore, skipIfInQueue, filter) {
            if (args === void 0) { args = []; }
            if (ignore === void 0) { ignore = true; }
            if (skipIfInQueue === void 0) { skipIfInQueue = false; }
            if (filter === void 0) { filter = undefined; }
            if (this.eventQ == null)
                return;
            this.eventQ.addLocalEvent(e, args, ignore, skipIfInQueue, filter);
        };
        Runtime.prototype.queueAsyncEvent = function (f) {
            this.asyncTasks.push(f);
            this.queueRestart();
        };
        Runtime.prototype.queueRestart = function () {
            var _this = this;
            if (this.restartQueued || this.state != 3 /* AtAwait */)
                return;
            this.restartQueued = true;
            TDev.Util.setTimeout(0, function () {
                _this.restartQueued = false;
                if (_this.state != 3 /* AtAwait */)
                    return;
                var f = _this.pumpEventsCore();
                if (f) {
                    _this.mainLoop(f, "queue restart");
                }
            });
        };
        Runtime.prototype.eventEnabled = function (category) {
            return this.eventQ != null && !!this.eventQ.eventsByCategory[category];
        };
        Runtime.prototype.enterAsync = function (t, s) {
            var _this = this;
            this.current.continueAt = s.returnAddr;
            this.asyncStack.push(this.current);
            s.asyncTask = t;
            s.returnAddr = function (s) {
                var prev = s.rt.returnedFrom;
                t.resume(prev.results || prev.result);
                _this.setState(3 /* AtAwait */, "enterAsync stop");
                return null;
            };
            return this.enter(s);
        };
        Runtime.prototype.isTopScriptFrame = function (s) {
            return s.libs.scriptId === s.libs.topScriptId;
        };
        Runtime.prototype.getTopScriptPc = function () {
            return this.current ? ((!this.rendermode || this.isTopScriptFrame(this.current)) ? this.current.pc : this.last_topscript_pc) : "";
        };
        Runtime.prototype.enter = function (s) {
            this.current = s;
            if (s.previous) {
                if (this.rendermode && s.previous.isLibProxy && this.isTopScriptFrame(s.previous.previous)) {
                    this.last_topscript_pc = s.previous.previous.pc;
                    s.previous.previous.libs;
                }
                s.stackDepth = s.previous.stackDepth + 1;
                if (s.stackDepth > 1000) {
                    TDev.Util.userError("stack overflow");
                }
            }
            return s.entryAddr;
        };
        Runtime.prototype.leave = function () {
            var c = this.current;
            this.current = c.previous;
            if (this.current.isLibProxy)
                this.current = this.current.previous;
            if (c.serverRequest)
                c.serverRequest.response().sendNow();
            this.returnedFrom = c;
            var ret = c.returnAddr;
            c.returnAddr = Runtime.pumpEvents;
            return ret;
        };
        Runtime.toRestArgument = function (v, s) {
            if (typeof v == "undefined" || typeof v == "string" || typeof v == "number" || typeof v == "boolean") {
                return v;
            }
            else if (v.exportJson) {
                try {
                    var ctx = new TDev.JsonExportCtx(s);
                    var v0 = v;
                    ctx.push(v0);
                    v = v.exportJson(ctx);
                    ctx.pop(v0);
                    return v;
                }
                catch (e) {
                    TDev.Util.userError("JSON export failed on " + v.toString());
                }
            }
            else {
                TDev.Util.userError("unsupported value in JSON cloud call: " + v.toString());
            }
        };
        Runtime.prototype.getRuntimeType = function (libname, typename) {
            var type = this.datas[libname];
            var result;
            Object.keys(type).forEach(function (t) {
                if (type[t].name === typename) {
                    result = type[t];
                }
            });
            return result;
        };
        Runtime.stringToBoolean = function (s) {
            if (!s)
                return false;
            if (/^(false|no|0)$/i.test(s))
                return false;
            return true;
        };
        Runtime.fromRestArgument = function (v, tp, s) {
            var singleton = s.d["$" + tp];
            if (singleton !== undefined) {
                return singleton.fromRest(v);
            }
            var a = tp.indexOf("→");
            if (a !== -1) {
                var lib = tp.slice(0, a);
                var tab = tp.slice(a + 1);
                if (lib.indexOf("Collection of") !== -1) {
                    lib = lib.slice(14);
                    var typ = s.rt.getRuntimeType(lib, tab);
                    return TDev.RT.Collection.fromArray(v.map(function (v) { return typ.fromRest(v); }), typ);
                }
                else {
                    return s.rt.getRuntimeType(lib, tab).fromRest(v);
                }
            }
            switch (tp) {
                case "Number":
                    return parseFloat(v);
                case "String":
                    return v + "";
                case "Boolean":
                    return Runtime.stringToBoolean(v);
                case "Json Object":
                    return RT.JsonObject.wrap(v);
                case "Json Builder":
                    if (typeof v == "object")
                        return RT.JsonBuilder.wrap(TDev.Util.jsonClone(v));
                    return undefined;
                default:
                    TDev.RT.App.logEvent(TDev.RT.App.WARNING, "rest", TDev.lf("unsupported type {0}", tp), undefined);
                    return undefined;
            }
        };
        Runtime.prototype.callServiceOffline = function (isQuery, site, service, libName, actionName, paramNames, returnNames, returnTypes, prev, ret) {
            var args = [];
            for (var _i = 10; _i < arguments.length; _i++) {
                args[_i - 10] = arguments[_i];
            }
            var rt = this;
            var action = prev.libs[libName][actionName](prev);
            var next = ret;
            if (this.rendermode && !isQuery) {
                this.forceNonRender("Can not call a cloud function that is not \"read-only\" in display code");
            }
            if (!rt.inCloudCall && !rt.host.isServer) {
                var req = {};
                for (var i = 0; i < args.length; i++) {
                    req[paramNames[i]] = Runtime.toRestArgument(args[i], prev);
                }
                prev.rt.startCloudCall(service, actionName, paramNames, returnNames, req, isQuery);
                next = function (s) {
                    s.rt.endCloudCall(service, actionName, paramNames, returnNames, req, isQuery);
                    return ret;
                };
            }
            return action.invoke.apply(action, [action, next].concat(args));
        };
        Runtime.prototype.queryServiceAsync = function (path, req, site) {
            if (site === void 0) { site = ""; }
            var hdrs = {};
            hdrs["Content-type"] = "application/json;charset=UTF-8";
            if (this.authAccessToken)
                hdrs["Authorization"] = "Bearer " + this.authAccessToken;
            if (!site)
                site = this.compiled.azureSite;
            return TDev.Util.httpRequestAsync(site + "-tdevrpc-/" + path, "POST", JSON.stringify(req), hdrs).then(function (s) { return s ? JSON.parse(s) : {}; });
        };
        Runtime.prototype.callService = function (isQuery, site, service, libName, actionName, paramNames, returnNames, returnTypes, prev, ret) {
            var _this = this;
            var args = [];
            for (var _i = 10; _i < arguments.length; _i++) {
                args[_i - 10] = arguments[_i];
            }
            var rt = this;
            var run = function (s) {
                if (_this.rendermode) {
                    _this.forceNonRender("Can not call a remote cloud function in display code (only \"offline available\" \"read-only\" are allowed)");
                }
                var ctx = _this.getAwaitResumeCtx(function (s) { return s.rt.leave(); });
                var req = {};
                for (var i = 0; i < args.length; i++) {
                    req[paramNames[i]] = Runtime.toRestArgument(args[i], prev);
                }
                _this.queryServiceAsync(encodeURIComponent(service) + "/" + encodeURIComponent(actionName), req, site).done(function (resp) {
                    var results = returnNames.map(function (n) { return resp[n]; });
                    results = results.map(function (v, i) { return Runtime.fromRestArgument(v, returnTypes[i], s); });
                    if (results.length == 1)
                        s.result = results[0];
                    else
                        s.results = results;
                    ctx.resume();
                }, function (err) {
                    TDev.Runtime.theRuntime.handleException(err, s);
                });
            };
            return {
                previous: prev,
                returnAddr: ret,
                d: prev.d,
                rt: this,
                libs: prev.libs,
                entryAddr: run,
                name: actionName
            };
        };
        Runtime.prototype.pickParameters = function (cont) {
            var _this = this;
            var parms = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                parms[_i - 1] = arguments[_i];
            }
            var ch = parms.map(function (p) { return [TDev.div("picker-name", p.userName + ":"), TDev.div("picker-input", p.html)]; });
            var ctx = this.getAwaitResumeCtx(cont);
            ch.push(TDev.div("wall-dialog-buttons", TDev.HTML.mkButton(TDev.lf("ok"), function () {
                var allOk = true;
                var s = _this.current;
                parms.forEach(function (p) {
                    var ok = p.validate();
                    allOk = allOk && ok;
                    p.html.setFlag("invalid", !ok);
                    if (ok) {
                        s[p.quotedName] = p.get();
                    }
                });
                if (allOk)
                    ctx.resume();
            })));
            this.postHtml(TDev.div("picker-form", ch), "");
        };
        Runtime.prototype.displayResult = function (name, val) {
            var _this = this;
            var e = TDev.div("picker-form");
            var pc = this.current.pc;
            var box = new TDev.WallBox(this, this.getCurrentBoxBase(true), pc);
            box.setContent(e);
            this.getCurrentPage().setCurrentBox(box);
            var dual = function (str) {
                _this.postHtml(TDev.div("picker-name", name + ":"), pc);
                _this.postHtml(TDev.div("picker-input", str), pc);
            };
            try {
                switch (typeof val) {
                    case "string":
                        dual(val);
                        break;
                    case "number":
                        dual(val + "");
                        break;
                    case "boolean":
                        dual(val ? "True" : "False");
                        break;
                    case "undefined":
                        dual("[invalid]");
                        break;
                    default:
                        if (val === null)
                            dual("[null]");
                        else {
                            if (val.postResult)
                                val.postResult(this.current);
                            else {
                                this.postText(name + ":", pc);
                                val.post_to_wall(this.current);
                            }
                        }
                        break;
                }
            }
            finally {
                this.getCurrentPage().setCurrentBox(box.parent);
            }
            box.forEachChild(function (c) {
                e.appendChild(c.getContent());
            });
            this.renderBox(box);
        };
        Runtime.prototype.setState = function (s, msg) {
            if (this.state == 0 /* Stopped */ || s == 0 /* Stopped */)
                TDev.Util.log("runtime state: {0} -> {1}, {2}", this.state, s, msg);
            this.state = s;
            this.stateMsg = msg;
        };
        Runtime.prototype.getResumeCtxCore = function (isBlocking, cont) {
            TDev.Util.assert(this.state == 1 /* Running */);
            if (isBlocking)
                this.setState(2 /* Paused */, "getBlockingResumeCtx");
            else
                this.setState(3 /* AtAwait */, "getAwaitResumeCtx");
            this.current.continueAt = cont;
            var r = new ResumeCtx(this.current);
            r.isBlocking = isBlocking;
            r.versionNumber = this.versionNumber;
            return r;
        };
        Runtime.prototype.getBlockingResumeCtx = function (cont) {
            return this.getResumeCtxCore(true, cont);
        };
        Runtime.prototype.getAwaitResumeCtx = function (cont) {
            if (this.rendermode)
                TDev.Util.userError("non-atomic APIs cannot be called in page display code");
            return this.getResumeCtxCore(false, cont);
        };
        Runtime.prototype.getAsyncResumeCtx = function () {
            TDev.Util.assert(this.state == 1 /* Running */);
            if (this.rendermode)
                TDev.Util.userError("'async' cannot be used in page display code");
            var t = new RT.Task();
            var r = new RT.TaskResumeCtx(t, this.current);
            r.versionNumber = this.versionNumber;
            return r;
        };
        Runtime.prototype.mkActionTask = function () {
            var t = new RT.Task();
            return t;
        };
        Runtime.prototype._resumeVal = function (v, r) {
            var _this = this;
            var frame = r.stackframe;
            if (r.versionNumber != this.versionNumber)
                return;
            if (this.state == 2 /* Paused */) {
                if (r.isBlocking) {
                    this._resumeValCore(v, frame);
                    this.mainLoop(frame.continueAt, "_resumeValBlocking");
                }
                else {
                    this.queueAsyncEvent(function () { return _this.continueStackFrame(v, frame); });
                }
            }
            else if (this.state == 3 /* AtAwait */) {
                TDev.Util.assert(!r.isBlocking, "blocking await");
                this._resumeValCore(v, frame);
                this.mainLoop(frame.continueAt, "_resumeValAwait");
            }
            else {
                TDev.Util.oops("wrong resume state: " + this.state);
            }
        };
        Runtime.prototype.continueStackFrame = function (v, frame) {
            this._resumeValCore(v, frame);
            return frame.continueAt;
        };
        Runtime.prototype._resumeValCore = function (v, frame) {
            this.current = frame;
            if (frame.rendermode !== undefined)
                this.rendermode = frame.rendermode;
            frame.pauseValue = v;
        };
        Runtime.prototype.initFrom = function (cs) {
            this.compiled = cs;
            if (cs.authorId)
                this.currentAuthorId = cs.authorId;
            if (cs.scriptId) {
                this.currentScriptId = this.baseScriptId = cs.scriptId;
            }
            cs.initPages();
            EventQueue.init(this);
            this.sessions.scriptStarted(cs.authorId);
        };
        Runtime.prototype.nextAsyncTask = function () {
            if (this.asyncStack.length > 0) {
                if (this.current.asyncTask)
                    this.current.isDetached = true;
                var f = this.asyncStack.pop();
                this.current = f;
                this.setState(1 /* Running */, "async stack");
                return f.continueAt;
            }
            else if (this.asyncTasks.length > 0) {
                var q = this.asyncTasks.shift();
                this.setState(1 /* Running */, "async task");
                return q();
            }
            else {
                return null;
            }
        };
        Runtime.prototype.runInlineJavascript = function (f) {
            f();
        };
        Runtime.prototype.wrap = function (s, f) {
            if (this.isStopped())
                return function () {
                };
            if (!s)
                s = this.current;
            var rt = s.rt;
            TDev.Util.assert(rt == this);
            return function () {
                try {
                    if (rt.isStopped())
                        return undefined;
                    Runtime.theRuntime = rt;
                    rt.current = s;
                    f.apply(this, arguments);
                }
                catch (e) {
                    e.tdStackFrame = s;
                    throw e;
                }
            };
        };
        Runtime.prototype.pumpEventsCore = function () {
            this.yield_now();
            TDev.Util.assert(!this.isStopped(), "pump-stopped");
            var r = this.nextAsyncTask();
            if (r)
                return r;
            if (this.eventQ == null) {
                this.stopAsync().done();
                return null;
            }
            else if (this.eventExecuting) {
                this.setState(3 /* AtAwait */, "event executing");
                return null;
            }
            else {
                var fn = this.eventQ.maybeRunPageRefresh();
                if (!fn)
                    fn = this.eventQ.process();
                if (!fn && this.host.dontWaitForEvents())
                    this.stopAsync(true).done();
                else if (fn)
                    this.setState(1 /* Running */, "got event");
                else {
                    if (this.liveMode())
                        this.stopAsync(true).done();
                    else if (this.headlessPluginMode)
                        this.stopAsync().done();
                    else
                        this.setState(3 /* AtAwait */, "no event");
                }
                return fn;
            }
        };
        Runtime.pumpEvents = function (s) {
            s.rt.eventExecuting = false;
            return s.rt.pumpEventsCore();
        };
        Runtime.prototype.pauseExecution = function () {
            this.queueEvent("pause", null, []);
        };
        Runtime.prototype.resumeExecution = function (once) {
            if (once === void 0) { once = false; }
            this.eventQ.clearPause();
            if (this.state != 0 /* Stopped */ || !this.resumeAllowed)
                return;
            this.refreshPageStackForNewScript();
            this.eventQ.clear();
            if (!this.liveMode())
                this.getWall().setChildrenIfNeeded(this.pageStack.map(function (p) { return p.getElement(); }));
            try {
                this.eventQ.blockEvents = false;
                this.logDataWrite();
                this.eventQ.blockEvents = once;
                var bot = new StackBottom(this);
                bot.entryAddr = Runtime.pumpEvents;
                bot.returnAddr = Runtime.pumpEvents;
                var frame = this.enter(bot);
                this.mainLoop(frame, "resume execution");
            }
            catch (e) {
                this.handleException(e, this.current);
            }
        };
        Runtime.mkStackFrame = function (prev, ret) {
            return {
                previous: prev,
                prevPC: prev.pc,
                d: prev.d,
                rt: prev.rt,
                libs: prev.libs,
                returnAddr: ret,
            };
        };
        Runtime.syntheticFrame = function (f) {
            return function (prev, ret) {
                var s = Runtime.mkStackFrame(prev, ret);
                s.name = "__synthetic";
                s.entryAddr = function (s) {
                    s.rt.forcePageRefresh();
                    f(s);
                    return s.rt.leave();
                };
                return s;
            };
        };
        Runtime.prototype.getActionFrame = function (mk, args, isBlocking) {
            if (isBlocking === void 0) { isBlocking = true; }
            var bot = new StackBottom(this);
            if (args == null) {
                bot.needsPicker = true;
                args = [];
            }
            var fnObj;
            if (isBlocking)
                this.eventExecuting = true;
            if (args.length == 0)
                fnObj = mk(bot, Runtime.pumpEvents);
            else
                fnObj = mk.apply(null, [bot, Runtime.pumpEvents].concat(args));
            this.resetNextEvent();
            return this.enter(fnObj);
        };
        Runtime.prototype.queueEventCallback = function (cb) {
            var ev = new RT.Event_();
            ev.addHandler(new RT.PseudoAction(function (rt, args) {
                cb(rt, args);
            }));
            this.queueLocalEvent(ev);
        };
        Runtime.prototype.getEventFrame = function (mk, args, isBlocking) {
            if (isBlocking === void 0) { isBlocking = true; }
            try {
                if (this.state != 1 /* Running */) {
                    TDev.Util.assert(this.state == 3 /* AtAwait */);
                    this.setState(1 /* Running */, "getEventFrame dispatch");
                }
                return this.getActionFrame(mk, args, isBlocking);
            }
            catch (e) {
                return function () {
                    throw e;
                    return null;
                };
            }
        };
        Runtime.handleUserError = function (err) {
            var rt = Runtime.theRuntime;
            if (rt && rt.state != 0 /* Stopped */ && !rt.handlingException) {
                if (err.isUserError) {
                    rt.handleException(err, rt.current);
                    return true;
                }
            }
            return false;
        };
        Runtime.stopPendingScriptsAsync = function () {
            if (Runtime.theRuntime && Runtime.theRuntime.state != 0 /* Stopped */) {
                return Runtime.theRuntime.stopAsync();
            }
            else {
                return TDev.Promise.as();
            }
        };
        Runtime.prototype.rerunAsync = function () {
            var _this = this;
            return this.stopAsync().then(function () {
                TDev.Util.assert(_this.isStopped(), "rerun-isStopped");
                _this.initPageStack();
                _this.run(_this.startMk, _this.startArgs);
            });
        };
        Runtime.prototype.run = function (mk, args) {
            var _this = this;
            TDev.Util.assert(this.isStopped(), "run-isStopped");
            this.startMk = mk;
            this.startArgs = args;
            this.tutorialState = null;
            Runtime.stopPendingScriptsAsync().done(function () {
                Runtime.theRuntime = _this;
                if (_this.eventQ)
                    _this.eventQ.blockEvents = false;
                _this.resetRunMap();
                _this.killTempState();
                TDev.ProgressOverlay.setMessage("loading...");
                RT.ArtCache.resetProgress();
                _this.initDataAsync().done(function () {
                    try {
                        if (_this.headlessPluginMode) {
                            TDev.ProgressOverlay.setMessage("running...");
                            TDev.ProgressOverlay.unblockKeyboard();
                            TDev.ProgressOverlay.showLog();
                        }
                        else
                            TDev.ProgressOverlay.hide();
                        if (!_this.isStopped())
                            return;
                        _this.host.agreeTermsOfUseAsync().done(function () {
                            try {
                                var entryPt = _this.getActionFrame(mk, args);
                                if (_this.validatorAction) {
                                    var act = _this.current.libs["tutorialLib"][_this.validatorAction];
                                    if (!act) {
                                        TDev.Util.userError(TDev.lf("problem with tutorial: validator function '{0}' not found", _this.validatorAction));
                                    }
                                    var libcall = act(_this.current);
                                    _this.tutorialObject = libcall.libs.topScriptId;
                                    if (/norun/i.test(_this.validatorActionFlags))
                                        entryPt = Runtime.pumpEvents;
                                    entryPt = _this.enter(libcall.invoke(libcall, entryPt, _this.editorObj));
                                }
                                _this.mainLoop(entryPt, "Runtime.run");
                            }
                            catch (e) {
                                _this.handleException(e, _this.current);
                            }
                        });
                    }
                    catch (e) {
                        _this.handleException(e, _this.current);
                    }
                }, function (e) {
                    _this.handleException(e, null);
                });
            });
        };
        Runtime.prototype.resyncData = function () {
            this.datas = {};
        };
        Runtime.prototype.initDataAsync = function () {
            var _this = this;
            this.compiled.startFn(this);
            var loadSession = this.sessions.ensureSessionLoaded().thenalways(function () {
                _this.sessions.yieldSession();
            });
            this.compiled.initGlobals(this.datas, this);
            return TDev.Promise.join([this.compiled.initArtAsync(this.datas), loadSession]);
        };
        Runtime.prototype.addDisposableHandler = function (handler) {
            var binding = new RT.DisposableHandler(handler);
            this.disposables.push(binding);
            return binding;
        };
        Runtime.prototype.killDisposables = function () {
            this.disposables.forEach(function (d) {
                try {
                    d.dispose();
                }
                catch (e) {
                    TDev.Util.reportError('', e, false);
                }
            });
            this.disposables = [];
        };
        Runtime.prototype.killTempState = function () {
            this.renderedComments = "";
            this._libinitDone = false;
            this.sessions.unlink();
            this.compiled.resetData(this.datas);
        };
        Runtime.prototype.resetData = function () {
            if (this.state == 0 /* Stopped */ && this.resumeAllowed) {
                this.resumeAllowed = false;
                this.killTempState();
                this.initPageStack();
                this.host.notifyRunState();
            }
        };
        Runtime.prototype.quietlyHandleError = function (e, s) {
            var _this = this;
            try {
                this.augmentException(e);
            }
            catch (ee) {
            }
            var foundSome = false;
            var isSecondary = !!s;
            if (!s)
                s = e.tdStackFrame;
            for (; s; s = s.previous) {
                if (s.isDetached) {
                    s.asyncTask.setException(e);
                    break;
                }
                if (s.errorHandler)
                    (function () {
                        foundSome = true;
                        var s0 = s;
                        var h = s.errorHandler;
                        s.errorHandler = null;
                        TDev.Util.setTimeout(0, function () {
                            try {
                                var prev = e.tdIsSecondary;
                                e.tdIsSecondary = isSecondary;
                                h(e, s0);
                                e.tdIsSecondary = prev;
                            }
                            catch (exn) {
                                _this.host.exceptionHandler(exn);
                            }
                        });
                    })();
            }
            return foundSome;
        };
        Runtime.prototype.augmentException = function (e) {
            if (typeof e !== "object")
                return;
            var s = this.current;
            if (e.tdStackFrame)
                s = e.tdStackFrame;
            var st = e.stack;
            if (s && st !== undefined && !e.tdStack) {
                e.tdStack = this.getStackTrace(s, true);
                if (!e.tdMeta)
                    e.tdMeta = {};
                if (s)
                    new RT.AppLogger("dummy").setMetaFromContext(e.tdMeta, s);
                var compr = TDev.StackUtil.compress(e.tdStack);
                if (compr) {
                    compr = "StK" + compr;
                    e.tdMeta.compressedStack = compr;
                }
                if (compr) {
                    e.tdMeta.originalStack = st;
                    st = st.replace(/^\s*at a_\S+\$\d[^]*/m, "");
                    st = st.replace(/((compiled|noderuntime).js):\d+:\d+/g, function (t, f) { return f + ":1:1"; });
                    st = st.replace(/^\s*at /m, function (t) { return t + compr + " (td.js:42:42)\n" + t; });
                    try {
                        e.stack = st;
                    }
                    catch (fail) {
                    }
                }
                if (!e.tdMeta.reportId)
                    e.tdMeta.reportId = TDev.Ticker.mkReportId();
            }
        };
        Runtime.prototype.handleException = function (e, s) {
            if (!e.tdStackFrame)
                e.tdStackFrame = s;
            var handled = this.quietlyHandleError(e);
            this.handlingException = true;
            if (!handled) {
                this.compiled.extractAllRunMaps(this);
                this.host.exceptionHandler(e);
            }
            this.stopAsync().done();
        };
        Runtime.prototype.getStackTrace = function (init, strip) {
            if (strip === void 0) { strip = false; }
            var locs = [];
            for (var s = init || this.current; s; s = s.previous) {
                var ns;
                if (strip)
                    ns = {
                        pc: s.pc,
                        prevPC: s.prevPC,
                        name: s.name,
                        d: { libName: (s.d ? s.d.libName : undefined) }
                    };
                else
                    ns = TDev.Util.flatClone(s);
                locs.push(ns);
            }
            locs.forEach(function (l, i) {
                if (l.prevPC && locs[i + 1])
                    locs[i + 1].pc = l.prevPC;
            });
            return locs;
        };
        Runtime.prototype.getRunMap = function () {
            this.runMap.clear();
            if (this.compiled.extractAllRunMaps(this))
                return this.runMap;
            else
                return undefined;
        };
        Runtime.prototype.saveComment = function (cmt) {
            this.renderedComments += cmt;
        };
        Runtime.prototype.wrapFromHandler = function (f) {
            var prevState = this.state;
            var prevCurr = this.current;
            this.current = new StackBottom(this);
            this.setState(1 /* Running */, "runUserAction from handler");
            try {
                f();
                this.setState(prevState, "runUserAction from handler restore");
                this.current = prevCurr;
            }
            catch (e) {
                this.handleException(e, this.current);
            }
        };
        Runtime.prototype.runUserAction = function (f, args) {
            var _this = this;
            args.unshift(function (s) {
                _this.state = 2 /* Paused */;
                return null;
            });
            args.unshift(this.current);
            var fn = this.enter(f.apply(null, args));
            return this.quickLoop(fn);
        };
        Runtime.prototype.runValidUserAction = function (f, args) {
            var r = this.runUserAction(f, args);
            if (r === undefined)
                TDev.Util.userError("user function passed to library returned invalid");
            return r;
        };
        Runtime.prototype.quickLoop = function (fn) {
            if (this.quickLoopDepth > 20) {
                TDev.Util.userError("stack overflow (more than 20 runtime/user code switches)");
            }
            TDev.Util.assert(this.state == 1 /* Running */);
            this.quickLoopDepth++;
            var prevFrom = this.returnedFrom;
            this.returnedFrom = null;
            try {
                while (true) {
                    var newFn = fn(this.current);
                    if (this.state != 1 /* Running */) {
                        if (this.state == 2 /* Paused */) {
                            this.state = 1 /* Running */;
                            break;
                        }
                        if (this.state == 4 /* BreakpointHit */)
                            TDev.Util.userError("breakpoints in library callbacks are not supported");
                        TDev.Util.oops("wrong state in quick Loop " + this.state);
                    }
                    if (!newFn)
                        TDev.Util.oops("no newFn: " + fn);
                    fn = newFn;
                }
            }
            finally {
                this.quickLoopDepth--;
            }
            var res = this.returnedFrom ? this.returnedFrom.result : undefined;
            this.returnedFrom = prevFrom;
            return res;
        };
        Runtime.prototype.mainLoop = function (fn, comment) {
            var _this = this;
            if (!Runtime.continueAfter)
                Runtime.continueAfter = TDev.Util.setTimeout;
            this.handlingException = false;
            if (this.mainLoopRunning) {
                this.setState(1 /* Running */, "resume point override");
                this.resumePointOverride = fn;
                return;
            }
            var prevState = this.state;
            this.setState(1 /* Running */, comment);
            if (prevState == 0 /* Stopped */)
                this.host.notifyRunState();
            if (!this.sessions.readyForExecution()) {
                this.stopAsync().done();
                return;
            }
            var continueLater = false;
            var continueLaterVersion = 0;
            var numCheck = 0;
            this.mainLoopRunning = true;
            try {
                while (true) {
                    var newFn = fn(this.current);
                    if (this.state != 1 /* Running */) {
                        if (this.state == 4 /* BreakpointHit */) {
                            this.debuggerCC = newFn;
                            break;
                        }
                        if (this.state == 0 /* Stopped */) {
                            break;
                        }
                        if (this.debuggerCC) {
                            this.debuggerCC = null;
                            this.host.notifyBreakpointContinue();
                        }
                        if (this.state == 3 /* AtAwait */) {
                            newFn = this.pumpEventsCore();
                            if (!newFn)
                                break;
                            TDev.Util.check(!this.resumePointOverride);
                            this.resumePointOverride = null;
                        }
                        if (this.state != 1 /* Running */) {
                            break;
                        }
                    }
                    if (!newFn)
                        TDev.Util.oops("no newFn: " + fn);
                    if (!!this.resumePointOverride) {
                        fn = this.resumePointOverride;
                        this.resumePointOverride = null;
                    }
                    else {
                        fn = newFn;
                    }
                    if (numCheck++ > 10) {
                        var now = Date.now();
                        if (now - this.lastBreak > (TDev.Browser.isNodeJS ? 1000 : 50)) {
                            continueLater = true;
                            continueLaterVersion = this.versionNumber;
                            break;
                        }
                        numCheck = 0;
                    }
                }
            }
            catch (e) {
                this.handleException(e, this.current);
            }
            this.mainLoopRunning = false;
            if (continueLater && continueLaterVersion == this.versionNumber && this.state != 0 /* Stopped */) {
                this.setState(2 /* Paused */, "continue later");
                var ver = this.versionNumber;
                var curr = this.current;
                Runtime.continueAfter(1, function () {
                    if (ver != _this.versionNumber)
                        return;
                    _this.lastBreak = Date.now();
                    _this.current = curr;
                    _this.mainLoop(fn, "continue later - run");
                });
            }
            TDev.Util.assert(this.state != 1 /* Running */);
        };
        Runtime.prototype.saveDataAsync = function () {
            this.sessions.yieldSession();
            return TDev.Promise.as();
        };
        Runtime.prototype.getRestRequest = function () {
            var frame = this.current;
            while (frame && !frame.serverRequest)
                frame = frame.previous;
            return frame ? frame.serverRequest : undefined;
        };
        Runtime.prototype.getRestArgument = function (name, tp, s) {
            var r = this.getRestRequest().getRestArgument(name, tp, s);
            return r;
        };
        Runtime.prototype.runLibInits = function (ids, cb) {
            var _this = this;
            if (this._libinitDone)
                return;
            var frame = this.current;
            this._libinitDone = true;
            var loop = function (i) {
                if (i >= ids.length)
                    return cb(frame);
                var libcall = _this.compiled.libs[ids[i]]["_libinit"](frame);
                return _this.enter(libcall.invoke(libcall, function () {
                    return loop(i + 1);
                }));
            };
            return loop(0);
        };
        Runtime.shellVersion = 41;
        Runtime.maxBoxLength = 1000;
        Runtime.lockOrientation = function () {
        };
        Runtime.legalNotice = "";
        Runtime.companyCopyright = "Microsoft";
        Runtime.appName = "TouchDevelop";
        Runtime.notificationIcon = "https://www.touchdevelop.com/images/touchdevelop114x114.png";
        Runtime.accelerometerTiltBooster = 1;
        Runtime.inputboxstylemap = { textline: "text", password: "password", number: "number" };
        return Runtime;
    })();
    TDev.Runtime = Runtime;
    var EventHandlerDesc = (function () {
        function EventHandlerDesc(varId, entry) {
            this.varId = varId;
            this.entry = entry;
        }
        return EventHandlerDesc;
    })();
    TDev.EventHandlerDesc = EventHandlerDesc;
    var EventEntry = (function () {
        function EventEntry(binding, args, isLast) {
            this.binding = binding;
            this.args = args;
            this.isLast = isLast;
            this.category = "local";
            this.done = false;
        }
        EventEntry.prototype.isPageEvent = function () {
            return this.binding._event.isPageEvent;
        };
        EventEntry.prototype.dispatch = function (rt, eventsByCategory) {
            if (this.done)
                return null;
            this.done = true;
            var ev = this.binding._event;
            ev.pendinghandlers--;
            this.binding.inQueue = false;
            var f = this.binding._handler;
            if (!f)
                return null;
            if (f instanceof RT.PseudoAction) {
                f.run(rt, this.args);
                return null;
            }
            var res = rt.getEventFrame(f, this.args, ev.isBlocking);
            if (rt.current) {
                rt.current.currentHandler = this.binding;
                if (ev.finalCallback) {
                    var cb = ev.finalCallback;
                    ev.finalCallback = null;
                    rt.current.returnAddr = function (s) {
                        cb(s);
                        return Runtime.pumpEvents(s);
                    };
                }
                if (ev.errorHandler) {
                    rt.current.errorHandler = ev.errorHandler;
                }
            }
            return res;
        };
        EventEntry.prototype.clear = function () {
            var ev = this.binding._event;
            ev.pendinghandlers = 0;
        };
        EventEntry.prototype.isPause = function () {
            return false;
        };
        EventEntry.prototype.isGameLoop = function () {
            return false;
        };
        return EventEntry;
    })();
    TDev.EventEntry = EventEntry;
    var GlobalEventEntry = (function () {
        function GlobalEventEntry(category, varValue, args, idx) {
            if (idx === void 0) { idx = 0; }
            this.category = category;
            this.varValue = varValue;
            this.args = args;
            this.idx = idx;
            TDev.Util.assert(category != "local");
        }
        GlobalEventEntry.prototype.isPageEvent = function () {
            return false;
        };
        GlobalEventEntry.prototype.dispatch = function (rt, eventsByCategory) {
            if (this.evts === undefined)
                this.evts = eventsByCategory[this.category];
            if (this.evts === undefined)
                return null;
            while (this.idx < this.evts.length) {
                var handler = this.evts[this.idx++];
                var match = this.handlerMatch(handler, rt);
                if (match.matches) {
                    rt.setNextEvent(this.category, handler.varId);
                    return rt.getEventFrame(handler.entry, match.args);
                }
            }
            return null;
        };
        GlobalEventEntry.prototype.handlerMatch = function (desc, rt) {
            if (desc.varId == null)
                return { matches: true, args: this.args };
            if (this.category.search(/ in /) >= 0) {
                var set = rt.datas["this"][desc.varId];
                if (!!set) {
                    var idx = set.index_of_obj(this.varValue);
                    if (idx >= 0) {
                        return { matches: true, args: [this.varValue, idx].concat(this.args) };
                    }
                }
            }
            else {
                if (rt.datas["this"][desc.varId] === this.varValue) {
                    return { matches: true, args: this.args };
                }
            }
            return { matches: false, args: [] };
        };
        GlobalEventEntry.prototype.isGameLoop = function () {
            return this.category == "gameloop" && !this.evts;
        };
        GlobalEventEntry.prototype.isPause = function () {
            return this.category == "pause" && !this.evts;
        };
        GlobalEventEntry.prototype.clear = function () {
        };
        return GlobalEventEntry;
    })();
    TDev.GlobalEventEntry = GlobalEventEntry;
    var BoardEventEntry = (function () {
        function BoardEventEntry(categories, valueStack, args, matchAll) {
            this.categories = categories;
            this.valueStack = valueStack;
            this.args = args;
            this.matchAll = matchAll;
            this.category = "board";
        }
        BoardEventEntry.prototype.dispatch = function (rt, eventsByCategory) {
            if (this.categoryHandlers === undefined)
                this.categoryHandlers = this.categories.map(function (c) { return eventsByCategory[c]; });
            var valueIndex = 0;
            while (!this.matchedHandlers && valueIndex < this.valueStack.length) {
                var value = this.valueStack[valueIndex++];
                var categoryIndex = 0;
                while (categoryIndex < this.categories.length) {
                    var category = this.categories[categoryIndex];
                    var handlers = this.categoryHandlers[categoryIndex++];
                    if (!handlers) {
                        continue;
                    }
                    var handlerIndex = 0;
                    while (handlerIndex < handlers.length) {
                        var handler = handlers[handlerIndex++];
                        var match = this.handlerMatch(handler, category, value, rt);
                        if (match.matches) {
                            if (!this.matchedHandlers) {
                                this.matchedHandlers = [];
                            }
                            this.matchedHandlers.push({ category: category, varid: handler.varId, handler: handler.entry, args: match.args });
                        }
                    }
                }
                if (!this.matchAll && !!this.matchedHandlers) {
                    break;
                }
            }
            if (!!this.matchedHandlers && this.matchedHandlers.length > 0) {
                var matchedHandler = this.matchedHandlers.shift();
                rt.setNextEvent(matchedHandler.category, matchedHandler.varid);
                return rt.getEventFrame(matchedHandler.handler, matchedHandler.args);
            }
            return null;
        };
        BoardEventEntry.prototype.handlerMatch = function (desc, category, varValue, rt) {
            if (category.search(/ sprite in /) >= 0) {
                var set = rt.datas["this"][desc.varId];
                if (!!set) {
                    var idx = set.index_of_obj(varValue);
                    if (idx >= 0) {
                        return { matches: true, args: [varValue, idx].concat(this.args) };
                    }
                }
            }
            if (category.search(/touch over /) >= 0) {
                var set = rt.datas["this"][desc.varId];
                if (!!set) {
                    var idx = set.index_of_obj(varValue);
                    if (idx >= 0) {
                        return { matches: true, args: [varValue, idx].concat(this.args) };
                    }
                }
            }
            else if (category.search(/ sprite:/) >= 0) {
                if (rt.datas["this"][desc.varId] == varValue) {
                    return { matches: true, args: [varValue].concat(this.args) };
                }
            }
            else {
                if (rt.datas["this"][desc.varId] === varValue) {
                    return { matches: true, args: this.args };
                }
            }
            return { matches: false, args: [] };
        };
        BoardEventEntry.prototype.isGameLoop = function () {
            return false;
        };
        BoardEventEntry.prototype.isPause = function () {
            return false;
        };
        BoardEventEntry.prototype.isPageEvent = function () {
            return false;
        };
        BoardEventEntry.prototype.clear = function () {
        };
        return BoardEventEntry;
    })();
    TDev.BoardEventEntry = BoardEventEntry;
    var EventQueue = (function () {
        function EventQueue(rt) {
            this.rt = rt;
            this.queue = [];
            this.needPageRefresh = false;
            this.needYield = false;
            this.needCloudstateRefresh = false;
            this.eventsByCategory = null;
            this.hasGameLoop = false;
            this.needsGameLoopTimer = false;
            this.blockEvents = false;
            this.eps = 0;
            this.minimumEps = 0;
            this.maximumEps = 0;
            this.averageEps = 0;
            this.epsHistory = [];
            this.profiling = false;
            this.numPageEvents = 0;
            this.pageIsTimeDependent = false;
            this.refreshtimerpending = false;
        }
        EventQueue.prototype.add = function (category, varValue, args, ignore) {
            if (ignore === void 0) { ignore = true; }
            if (this.blockEvents)
                return;
            TDev.Util.assert(!(varValue instanceof RT.Event_));
            if (this.eventsByCategory[category] !== undefined) {
                var ev = new GlobalEventEntry(category, varValue, args);
                this.queue.push(ev);
                this.rt.queueRestart();
            }
        };
        EventQueue.prototype.addLocalEvent = function (ev, args, ignore, skipIfInQueue, filter) {
            if (ignore === void 0) { ignore = true; }
            if (skipIfInQueue === void 0) { skipIfInQueue = false; }
            if (filter === void 0) { filter = undefined; }
            if (!this.blockEvents && ev.handlers) {
                var anyPushed = false;
                for (var i = 0; i < ev.handlers.length; ++i) {
                    var binding = ev.handlers[i];
                    if (filter && !filter(binding))
                        continue;
                    if (!(skipIfInQueue && binding.inQueue)) {
                        var ee = new EventEntry(binding, args, i == ev.handlers.length - 1);
                        if (ee.isPageEvent())
                            this.numPageEvents++;
                        ev.pendinghandlers++;
                        binding.inQueue = true;
                        this.queue.push(ee);
                        anyPushed = true;
                    }
                }
                if (anyPushed)
                    this.rt.queueRestart();
            }
            ev.runAwaiters(args);
        };
        EventQueue.prototype.addBoardEvent = function (categories, valueStack, args, ignore, matchAll) {
            if (ignore === void 0) { ignore = true; }
            if (matchAll === void 0) { matchAll = false; }
            if (this.blockEvents)
                return;
            this.queue.push(new BoardEventEntry(categories, valueStack, args, matchAll));
            this.rt.queueRestart();
        };
        EventQueue.prototype.clear = function () {
            this.queue.forEach(function (e) { return e.clear(); });
            this.queue = [];
        };
        EventQueue.prototype.clearPause = function () {
            this.queue = this.queue.filter(function (q) { return !q.isPause(); });
        };
        EventQueue.prototype.calculateEpsInfo = function () {
            if (this.epsHistory.length > 2) {
                var myEpsHistory = this.epsHistory.slice(1);
                myEpsHistory.pop();
                var minimum = Number.MAX_VALUE;
                var maximum = 0;
                var cumulative = 0;
                for (var i = 0; i < myEpsHistory.length; ++i) {
                    if (myEpsHistory[i] > maximum)
                        maximum = myEpsHistory[i];
                    if (myEpsHistory[i] < minimum)
                        minimum = myEpsHistory[i];
                    cumulative += myEpsHistory[i];
                }
                if (TDev.dbg) {
                    TDev.Util.log("Gameloop Events per Second statistics: minimum " + minimum + ", maximum " + maximum + ", average " + (cumulative / myEpsHistory.length).toFixed(2) + ". Ran for " + myEpsHistory.length + "s.");
                }
                this.minimumEps = minimum;
                this.maximumEps = maximum;
                this.averageEps = cumulative / myEpsHistory.length;
                this.epsHistory = [];
            }
        };
        EventQueue.prototype.setupGameLoopTimer = function () {
            var _this = this;
            var stopLogEPS = false;
            var logEPS = function () {
                var eps = _this.eps;
                _this.eps = 0;
                if (!stopLogEPS)
                    TDev.Util.setTimeout(1000, logEPS);
                if (eps > 0)
                    _this.epsHistory.push(eps);
            };
            var gameLoop = function () {
                if (_this.rt.isStopped()) {
                    _this.needsGameLoopTimer = true;
                    stopLogEPS = true;
                    return;
                }
                var hasIt = false;
                for (var i = 0; i < _this.queue.length; ++i)
                    if (_this.queue[i].isGameLoop()) {
                        hasIt = true;
                        break;
                    }
                if (!hasIt)
                    _this.add("gameloop", null, []);
                TDev.Util.setTimeout(20, gameLoop);
            };
            this.needsGameLoopTimer = false;
            gameLoop();
            if (this.profiling)
                logEPS();
        };
        EventQueue.prototype.queuePageUpdate = function () {
            this.needPageRefresh = true;
            this.rt.queueRestart();
        };
        EventQueue.prototype.viewIsCurrent = function () {
            return !this.needPageRefresh;
        };
        EventQueue.prototype.registerTimeDependency = function () {
            this.pageIsTimeDependent = true;
        };
        EventQueue.prototype.finishPageUpdate = function () {
            var _this = this;
            this.needPageRefresh = false;
            if (this.pageIsTimeDependent) {
                this.pageIsTimeDependent = false;
                if (!this.refreshtimerpending) {
                    this.refreshtimerpending = true;
                    TDev.Util.setTimeout(100, function () {
                        if (_this.refreshtimerpending) {
                            _this.refreshtimerpending = false;
                            _this.queuePageUpdate();
                        }
                    });
                }
            }
            else
                this.refreshtimerpending = false;
        };
        EventQueue.prototype.queueYield = function () {
            this.needYield = true;
            this.rt.queueRestart();
        };
        EventQueue.prototype.finishYield = function (changes, fireevent) {
            this.needYield = false;
            if (changes) {
                if (fireevent)
                    this.add("cloud data updated", null, []);
                this.queuePageUpdate();
            }
        };
        EventQueue.prototype.maybeRunPageRefresh = function () {
            var _this = this;
            if (this.rt.isHeadless())
                return null;
            if (!this.needPageRefresh && !this.needYield)
                return null;
            if (this.numPageEvents > 0)
                return null;
            var p = this.rt.getCurrentPage();
            if (p.isAuto() && !p.crashed) {
                return function () {
                    var page = _this.rt.getCurrentPage();
                    return _this.rt.getEventFrame(function (p, b) { return page.getFrame(p, b); }, []);
                };
            }
            else {
                this.needPageRefresh = false;
                this.needYield = false;
                return null;
            }
        };
        EventQueue.prototype.process = function () {
            if (this.needsGameLoopTimer)
                this.setupGameLoopTimer();
            while (this.queue.length > 0) {
                var e = this.queue[0];
                if (this.profiling && this.hasGameLoop && e.isGameLoop()) {
                    ++this.eps;
                }
                var fn = e.dispatch(this.rt, this.eventsByCategory);
                if (fn != null)
                    return fn;
                this.queue.shift();
                if (e.isPageEvent())
                    this.numPageEvents--;
                TDev.Util.assert(this.numPageEvents >= 0);
            }
            return null;
        };
        EventQueue.init = function (rt) {
            var s = rt.compiled;
            var q = new EventQueue(rt);
            rt.eventQ = q;
            if (!s.eventsByCategory || !s.eventsByCategory["local"]) {
                s.registerEventHandler("local", null, null);
            }
            q.hasGameLoop = (s.eventsByCategory && s.eventsByCategory["gameloop"] !== undefined);
            q.eps = 0;
            q.needsGameLoopTimer = q.hasGameLoop;
            q.eventsByCategory = s.eventsByCategory;
        };
        return EventQueue;
    })();
    TDev.EventQueue = EventQueue;
    var BreakpointCollection = (function () {
        function BreakpointCollection(cs) {
            this.cs = cs;
        }
        BreakpointCollection.prototype.init = function (bps) {
            var _this = this;
            bps.forEach(function (k, v) { return _this.cs.breakpointBindings[k].setter(true); });
        };
        BreakpointCollection.prototype.set = function (bp, val) {
            this.cs.breakpointBindings[bp].setter(val);
        };
        BreakpointCollection.prototype.get = function (bp) {
            return this.cs.breakpointBindings[bp].getter();
        };
        return BreakpointCollection;
    })();
    TDev.BreakpointCollection = BreakpointCollection;
    var CompilerOptStatistics = (function () {
        function CompilerOptStatistics(inlinedFunctions, inlinedCalls, eliminatedOks, termsReused, constantsPropagated, reachingDefsTime, inlineAnalysisTime, dominatorsTime, usedAnalysisTime, availableExpressionsTime, constantPropagationTime, compileTime, numActions, numStatements) {
            if (inlinedFunctions === void 0) { inlinedFunctions = 0; }
            if (inlinedCalls === void 0) { inlinedCalls = 0; }
            if (eliminatedOks === void 0) { eliminatedOks = 0; }
            if (termsReused === void 0) { termsReused = 0; }
            if (constantsPropagated === void 0) { constantsPropagated = 0; }
            if (reachingDefsTime === void 0) { reachingDefsTime = 0; }
            if (inlineAnalysisTime === void 0) { inlineAnalysisTime = 0; }
            if (dominatorsTime === void 0) { dominatorsTime = 0; }
            if (usedAnalysisTime === void 0) { usedAnalysisTime = 0; }
            if (availableExpressionsTime === void 0) { availableExpressionsTime = 0; }
            if (constantPropagationTime === void 0) { constantPropagationTime = 0; }
            if (compileTime === void 0) { compileTime = 0; }
            if (numActions === void 0) { numActions = 0; }
            if (numStatements === void 0) { numStatements = 0; }
            this.inlinedFunctions = inlinedFunctions;
            this.inlinedCalls = inlinedCalls;
            this.eliminatedOks = eliminatedOks;
            this.termsReused = termsReused;
            this.constantsPropagated = constantsPropagated;
            this.reachingDefsTime = reachingDefsTime;
            this.inlineAnalysisTime = inlineAnalysisTime;
            this.dominatorsTime = dominatorsTime;
            this.usedAnalysisTime = usedAnalysisTime;
            this.availableExpressionsTime = availableExpressionsTime;
            this.constantPropagationTime = constantPropagationTime;
            this.compileTime = compileTime;
            this.numActions = numActions;
            this.numStatements = numStatements;
        }
        return CompilerOptStatistics;
    })();
    TDev.CompilerOptStatistics = CompilerOptStatistics;
    var CompiledScript = (function () {
        function CompiledScript() {
            this.steps = [];
            this.actionsByName = {};
            this.actionsByStableName = {};
            this.pagesByName = {};
            this.eventsByCategory = null;
            this.reflectionInfo = {};
            this.artInitializers = [];
            this.artPromises = [];
            this.missingApis = [];
            this.globals = [];
            this.packageResources = [];
            this.imports = {
                npmModules: {},
                cordovaPlugins: {},
                pipPackages: {}
            };
            this.scriptTitle = "";
            this.scriptColor = "";
            this.showAd = false;
            this.startFn = function (rt) {
            };
            this.stopFn = function (rt) {
            };
            this.setupRestRoutes = function (rt) {
            };
            this.extractRunMap = undefined;
            this._resetGlobals = function (dt) {
            };
            this._initGlobals = function (dt, rt) {
            };
            this._initGlobals2 = function (dt) {
            };
            this._importJson = function (dt, ctx, json) {
            };
            this._exportJson = function (dt, ctx) {
            };
            this._getProfilingResults = function () { return null; };
            this._showCoverage = false;
            this.breakpointBindings = {};
            this.initBreakpoints = null;
            this.localNamesBindings = {};
            this.optStatistics = new CompilerOptStatistics();
            this.libScripts = { "this": this };
            this.breakpoints = new BreakpointCollection(this);
        }
        CompiledScript.prototype.forEachLib = function (f) {
            var _this = this;
            Object.keys(this.libScripts).forEach(function (k) {
                f(_this.libScripts[k]);
            });
        };
        CompiledScript.prototype.extractAllRunMaps = function (rt) {
            var _this = this;
            var defined = true;
            Object.keys(this.libScripts).forEach(function (k) {
                var extractRunMap = _this.libScripts[k].extractRunMap;
                if (extractRunMap)
                    extractRunMap(rt);
                else
                    defined = false;
            });
            return defined;
        };
        CompiledScript.prototype.registerAction = function (name, stName, entry, isAsync) {
            this.actionsByName[name] = entry;
            this.actionsByStableName[stName] = entry;
            if (isAsync && !this.eventsByCategory)
                this.registerEventHandler("async", null, null);
        };
        CompiledScript.prototype.initPages = function () {
            var _this = this;
            var hasPages = Object.keys(this.libScripts).some(function (k) { return Object.keys(_this.libScripts[k].pagesByName).length > 0; });
            if (!hasPages)
                return;
            this.registerEventHandler("page", null, function (prev, ret, libName, pageName) {
                var args = [];
                for (var _i = 4; _i < arguments.length; _i++) {
                    args[_i - 4] = arguments[_i];
                }
                var p = prev.rt.pushPage(true);
                p.libName = libName;
                p.pageName = pageName;
                p.drawArgs = args;
                return p.getFrame(prev, ret);
            });
        };
        CompiledScript.prototype.getCompiledCode = function () {
            return null;
        };
        CompiledScript.prototype.initFromPrecompiled = function (script) {
            var _this = this;
            if (script === void 0) { script = null; }
            if (!script)
                script = TDev.precompiledScript;
            Object.keys(script).forEach(function (name) {
                if (name == "this")
                    return;
                var f = script[name];
                var cs = _this;
                if (typeof f == "string") {
                    cs = _this.libScripts[f];
                }
                else {
                    cs = new CompiledScript();
                    f(cs);
                }
                _this.registerLibRef(name, cs);
            });
            script["this"](this);
        };
        CompiledScript.prototype.registerPage = function (name, stName, entry) {
            this.actionsByName[name] = entry;
            this.actionsByStableName[stName] = entry;
            this.pagesByName[name] = entry;
        };
        CompiledScript.prototype.registerLambda = function (name, stName, entry) {
            this.actionsByName[name] = entry;
            this.actionsByStableName[stName] = entry;
        };
        CompiledScript.prototype.forEachData = function (datas, f) {
            var _this = this;
            var res = [];
            Object.keys(this.libScripts).forEach(function (lr) {
                if (!datas[lr])
                    datas[lr] = {};
                datas[lr]["libName"] = lr;
                res.push(f(datas[lr], _this.libScripts[lr], lr));
            });
            return res;
        };
        CompiledScript.prototype.resetData = function (datas) {
            this.forEachData(datas, function (d, cs) {
                cs._resetGlobals(d);
            });
        };
        CompiledScript.prototype.initGlobals = function (datas, rt) {
            this.forEachData(datas, function (d, cs) {
                cs._initGlobals(d, rt);
                cs._initGlobals2(d);
            });
        };
        CompiledScript.prototype.registerArtResource = function (clsName, id, url) {
            var _this = this;
            this.artInitializers.push(function (data) {
                if (!!data[id])
                    return;
                var f = TDev.RT[clsName].fromArtUrl;
                if (!!f)
                    _this.artPromises.push(f(url).then(function (v) {
                        if (v === undefined) {
                            switch (clsName) {
                                case "Picture":
                                    v = TDev.RT.Picture.fromArtUrl("data:image/jpeg;base64," + "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAW7SURBVHhe7ZxbTBxVGMc/7gssdGG5LSIUC6UKTQu1Rg19EDVqmja2SWNTo1HTxMTESLw90PhkUk29PZgYo6kPTXyqDbGJPhgDKW1tLRWsWhrFyp0F2kUuy7VcnG/2bGcG+sAuifufM+eXbPg+CAT2x3fmfDPnnLji423LpIAhXnxUgKCEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgKGEgOFoIdmuxNuv9ESMt8KxQg5X5lL7oa3669LBKirzuMRXYosjhTyQ76aGnXeJjOjopQG6cnNaZLHFcUKK3Mn05WOllBAfp+c/9IzRVx039BgBRwlJ0Bx89kgpeVIS9bx/cp7eONurxyg4SsjLW/NpW26aHi8tL9Ob53poYn5Rz1FwjJCKLBe9tr1AZERf/xmgC/6gyHBwhBAeqj6oLSGXmNoOBOfp2OVBPUbDEUL2bcq+PVQxH7f54YaqMNILSdWq4q0dhSIj6p6Yo8broyLDQ3ohz9+bQwXpSSIj+vTXIVoEXjwrtRCuDp5ZhUGvDkZqIXvvySKvK9RzMMevjkBXByO1kGcrckRENL2wRN9e/1dkuEgrpNKbaplZfd81RuOgMyszcEKe2uihLx4tpVO7y+mZzV7x2cg5UGb93pOdARFhAyXkUIWXPq8rpSdKPHR/vpuO1RZTfbXRXUfC4yUbREQUmF2gi0N4XfmdgBLyYmWeiAwORlEl5R6Xflc3THPfhIjwgRJinhGFcScliGjtPKlVmJmmvnER4QMlpKV/9X9y63DkQ01tYYaIiOYWl6jpDj8XFSghR1sH6MyA8eZ1BGboyE99IlsbyfFxVJ1nzK7aR6ZpRpvy2gXIXbh5qYmUk5pEf43N0sJSZL9ejTbVbdxTITKiE9du0jsXIpMaS6AqJMzIzAJ1jM5ELIOpyjGqg7nonxSRPYAUsh6qc9NFFIKrzE5IJ2RzlrGcZ1LrzDuVkNhSkpEiIqJRrSG0G1IJ4RlWRrLRt3RPzonIPkglxGd6EMX4g7dEZB8kE2LcLmHUkBVjvFr/YsY/PS8i+yDdRd3uSCXEnWT9c3jaazekEpKSYP1z5qPo9GONGrLAUELAkEoIP/sww42i3ZBKSPCWVYi5a7cLasgCQyoh/qC1EfSlWTt3OyCVEF7uY8a8yNouyFUhU9abiRszjVvxdkEqIdwI+qeMYWvl3V87IN1F3Txs8QkNdpv6SiekbcQ4AIBvpdTkWZ+xoyOhEOvCOiUkxvwRmBFRiCqvdVkQOtIJ4VUm5tvuD/rcIrIH0glhWgaMxXG8gJtXw9sFOCE7tDG/YWchfbirWN+8Ew0rV7vX3Z0pInyghPAmzW92l+s7Zw+UhzbvvHRfrvjq2mnun6BF08OpuiJj8w46UEJe3V5A8XHWvuGFKIRwL9I6PCUy0lfDr3y8iwrUb+lLW91Zc3MXDd91GztuuR/ZX5YtMmyghJwdXL1S/fdAdCe9newc1bdCh3luS+SVFgughLz7c7++SSdM1/gcNZyPbm8Hb9I5/Y9RJbwIm/eOoAO3YYePUtqSnaqf+vbLcJBm13H0wracNDq919i80/j3KNW39IgME7grHb//V7UqOa8NX+uRwfDBlk2mHbg8iyvJwH5oZY+pxzr4pN0vIq364uP0mRwy0gv5bUWV7N+UDV0l0gthVlbJ6zU+keHhCCFcJSeuGWfzPq1VyUOgNx0dIYR5v3WQhkzP3N97uJhcPKUDwzFCprS+5Ihpv3rphhQ6XLX6bJVY4xghzI+943RK60XC1Ff79F4FCUcJYd4+10tXboRuxyRpF3g+ejwTaMmp44Tw6RCvNHfRyHToelKkTYE/2lWsxwhAnnXyf1CTm077yrJEFjoTBeGQAccKQcVxQxY6SggYSggYSggYSggYSggYSggYSggYSggYSggYSggYSggYSggYSggYSggYSggURP8B901+vZyEn/4AAAAASUVORK5CYII=")._value;
                                    break;
                                case "Sound":
                                    var missingUrl = TDev.Cloud.artUrl('pxiraczt');
                                    if (!TDev.Browser.audioWav)
                                        missingUrl = TDev.HTML.patchWavToMp4Url(missingUrl);
                                    v = TDev.RT.Sound.mk(missingUrl);
                                    break;
                                default:
                                    break;
                            }
                        }
                        data[id] = v;
                    }));
            });
        };
        CompiledScript.prototype.registerGlobal = function (id) {
            this.globals.push(id);
        };
        CompiledScript.prototype.initArtAsync = function (datas) {
            return TDev.Promise.join(this.forEachData(datas, function (d, cs) { return cs.initArtCoreAsync(d); }));
        };
        CompiledScript.prototype.initArtCoreAsync = function (data) {
            this.artPromises = [];
            this.artInitializers.forEach(function (f) {
                f(data);
            });
            return TDev.Promise.join(this.artPromises);
        };
        CompiledScript.prototype.registerEventHandler = function (category, varId, entry) {
            if (this.eventsByCategory == null)
                this.eventsByCategory = {};
            var curr = this.eventsByCategory[category];
            if (curr === undefined) {
                curr = [];
                this.eventsByCategory[category] = curr;
            }
            curr.push(new EventHandlerDesc(varId, entry));
            if (!this.eventsByCategory["pause"])
                this.registerEventHandler("pause", null, function (prev, ret) {
                    var frame = {};
                    frame.previous = prev;
                    frame.rt = prev.rt;
                    frame.returnAddr = ret;
                    frame.entryAddr = function (s) {
                        s.rt.stopAsync(true).done();
                        return null;
                    };
                    return frame;
                });
            if (!this.eventsByCategory["async"])
                this.registerEventHandler("async", null, null);
        };
        CompiledScript.prototype.registerStep = function (step, name) {
            step.idx = this.steps.length;
            step.theName = name;
            this.steps.push(step);
        };
        CompiledScript.prototype.registerLibRef = function (libRefName, cs) {
            if (this.libScripts.hasOwnProperty(libRefName))
                TDev.Util.oops("redefinition of libref " + libRefName);
            this.libScripts[libRefName] = cs;
        };
        CompiledScript.prototype.mkLambdaProxy = function (libs, libRefName) {
            return function (s) { return new LibProxy(libs, s, libRefName, "inline function", null); };
        };
        CompiledScript.prototype.mkLibProxyFactory = function (libs, libRefName, actionName) {
            var f = this.libScripts[libRefName].actionsByName[actionName];
            TDev.Util.assert(f);
            return function (s) { return new LibProxy(libs, s, libRefName, actionName, f); };
        };
        CompiledScript.prototype.lookupLibPage = function (libRefName, actionName) {
            var _this = this;
            var f = this.libScripts[libRefName].actionsByName[actionName];
            TDev.Util.assert(f);
            return function (s) { return new LibProxy(_this.libBindings[libRefName], s, libRefName, actionName, f); };
        };
        CompiledScript.prototype.lookupAction = function (libName, actName) {
            return this.libScripts[libName].actionsByStableName[actName];
        };
        CompiledScript.prototype.init = function (code, missingApis, packageResources, safe) {
            this.code = code;
            this.missingApis.pushRange(missingApis);
            this.packageResources.pushRange(packageResources);
            if (safe) {
                var f = eval(code);
                f(this);
            }
        };
        CompiledScript.prototype.reinit = function (code) {
            this.additionalCode = code;
            var f = eval(code);
            f(this);
        };
        CompiledScript.additionalScriptStateFields = ["leaderboard_score", "source_access"];
        return CompiledScript;
    })();
    TDev.CompiledScript = CompiledScript;
    var RT;
    (function (RT) {
        function unwrapJson(o) {
            return o ? o.value() : undefined;
        }
        RT.unwrapJson = unwrapJson;
        function wrapJson(o) {
            return RT.JsonObject.wrap(o);
        }
        RT.wrapJson = wrapJson;
        function queueAction(s, a, args, whenDone, errorHandler) {
            if (whenDone === void 0) { whenDone = null; }
            if (errorHandler === void 0) { errorHandler = null; }
            if (a) {
                var ev = new RT.Event_();
                ev.isBlocking = false;
                ev.finalCallback = whenDone;
                ev.errorHandler = errorHandler;
                ev.addHandler(a);
                s.rt.queueLocalEvent(ev, args);
            }
        }
        RT.queueAction = queueAction;
        function protect(s, f) {
            return s.rt.wrap(s, f);
        }
        RT.protect = protect;
        function userError(msg) {
            TDev.Util.userError(msg);
        }
        RT.userError = userError;
        function logError(err, meta) {
            if (err)
                RT.App.logException(err, meta);
        }
        RT.logError = logError;
        function checkAndLog(err, meta) {
            if (!err)
                return true;
            logError(err, meta);
            return false;
        }
        RT.checkAndLog = checkAndLog;
        function checkAndThrow(e) {
            if (!e)
                return;
            TDev.Util.userError(e + "");
        }
        RT.checkAndThrow = checkAndThrow;
        function checkAndResume(s) {
            return protect(s, function (err) {
                checkAndThrow(err);
                s.localResume();
            });
        }
        RT.checkAndResume = checkAndResume;
        function warn(msg, s) {
            var ed = s.rt.editorObj;
            if (ed)
                ed.annotate_caller("warning", msg, s);
        }
        RT.warn = warn;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Revisions;
    (function (Revisions) {
        function revisionservice_http() {
            return revision_service_url;
        }
        Revisions.revisionservice_http = revisionservice_http;
        var revision_service_url = "https://storage.touchdevelop.com/sessions";
        function parseUrlParameters(url) {
            if (/altrevserv3/.test(url))
                revision_service_url = "http://localhost:843/sessions3";
            else if (/altrevserv2/.test(url))
                revision_service_url = "http://localhost:843/sessions2";
            else if (/altrevserv1/.test(url))
                revision_service_url = "http://localhost:843/sessions1";
            else if (/altrevserv/.test(url))
                revision_service_url = "http://localhost:843/sessions";
            else if (/simrevserv1/.test(url))
                revision_service_url = "http://127.0.0.1:82/sessions1";
            else if (/simrevserv/.test(url))
                revision_service_url = "http://127.0.0.1:82/sessions";
            else if (/revserv=/.test(url)) {
                var myRe = new RegExp("revserv=([^?&#]+)", "i");
                var myArray = myRe.exec(url);
                revision_service_url = "https://" + myArray[1] + "/sessions";
            }
        }
        Revisions.parseUrlParameters = parseUrlParameters;
        function localsessionid(scriptguid) {
            return "L" + scriptguid;
        }
        Revisions.localsessionid = localsessionid;
        function nodesessionid(guid) {
            return "userid" + "0pn" + letterify(guid);
        }
        Revisions.nodesessionid = nodesessionid;
        function justmesessionid(userid, guid) {
            return userid + "0pr" + letterify(guid);
        }
        Revisions.justmesessionid = justmesessionid;
        function everyonesessionid(author, scriptname) {
            return author + "0pu" + scripthash(author, scriptname);
        }
        Revisions.everyonesessionid = everyonesessionid;
        function make_astsessionid(userid) {
            return userid + "0pa" + letterify(TDev.Util.guidGen());
        }
        Revisions.make_astsessionid = make_astsessionid;
        function scripthash(author, title) {
            return letterify(author + title);
        }
        Revisions.scripthash = scripthash;
        function publicpermission(script) {
            return "users:*=W" + (script ? " scripts:" + (script) : "");
        }
        Revisions.publicpermission = publicpermission;
        function broadcastpermission(script) {
            return "users:*=R" + (script ? " scripts:" + (script) : "");
        }
        Revisions.broadcastpermission = broadcastpermission;
        function privatepermission(script) {
            return "users:" + (script ? " scripts:" + (script) : "");
        }
        Revisions.privatepermission = privatepermission;
        function letterify(s) {
            var n = Math.floor(Math.abs(TDev.Util.getStableHashCode(s)));
            var c = "";
            while (n > 0) {
                var d = n % 26;
                n = Math.floor(n / 26);
                c = c + String.fromCharCode(97 + d);
            }
            return c;
        }
        Revisions.letterify = letterify;
        function getRevisionServiceTokenAsync(forcefreshtoken) {
            if (forcefreshtoken === void 0) { forcefreshtoken = false; }
            var token = getRevisionServiceToken(forcefreshtoken);
            if (token)
                return TDev.Promise.wrap(token);
            else
                return refreshRevisionServiceTokenAsync();
        }
        Revisions.getRevisionServiceTokenAsync = getRevisionServiceTokenAsync;
        function getRevisionServiceToken(forcefreshtoken) {
            if (forcefreshtoken === void 0) { forcefreshtoken = false; }
            var expires = parseInt(window.localStorage["rs_token_expires"] || "0");
            if (forcefreshtoken || expires > 0 && Date.now() + 600 > expires) {
                setRevisionServiceToken(undefined);
                return undefined;
            }
            return window.localStorage["rs_access_token"];
        }
        function setRevisionServiceToken(token, expires_in) {
            if (expires_in === void 0) { expires_in = 0; }
            if (!token) {
                TDev.Util.log('revision service access token expired');
                window.localStorage.removeItem("rs_access_token");
                window.localStorage.removeItem("rs_token_expires");
            }
            else {
                TDev.Util.log('received revision service token (expires in ' + (expires_in * 1000).toString() + 'ms)');
                window.localStorage["rs_access_token"] = token;
                if (expires_in > 0)
                    window.localStorage["rs_token_expires"] = Date.now() + expires_in * 1000;
                else
                    window.localStorage.removeItem("rs_token_expires");
            }
        }
        function refreshRevisionServiceTokenAsync() {
            if (TDev.Cloud.isOffline())
                return TDev.Promise.wrapError(TDev.lf("cloud is offline"));
            return TDev.Cloud.authenticateAsync(TDev.lf("cloud data")).then(function (authenticated) {
                if (authenticated) {
                    var userid = TDev.Cloud.getUserId();
                    TDev.Util.log('asking TD server for revision service access token');
                    return TDev.Cloud.postPrivateApiAsync("me/storage/access_token", {}).then(function (json) {
                        var token = json["access_token"];
                        var expires_in = json["expires_in"];
                        setRevisionServiceToken(token, expires_in);
                        return token;
                    }, function (error) {
                        TDev.Util.log('could not get revision service token, web request failed');
                        return TDev.Promise.wrapError("Failed to receive revision service token");
                    });
                }
                else {
                    TDev.Util.log('could not get revision service token, user not signed in');
                    return TDev.Promise.wrapError("User not signed in");
                }
            });
        }
        function getServerInfoAsync(id) {
            return Revisions.getRevisionServiceTokenAsync().then(function (token) {
                if (TDev.Cloud.isOffline())
                    return TDev.Promise.wrapError("Cloud is offline");
                var url = Revisions.revisionservice_http() + "/" + id + "/info?user=" + TDev.Cloud.getUserId() + "&access_token=" + encodeURIComponent(token);
                return TDev.Util.httpRequestAsync(url, "GET", undefined).then(function (response) { return TDev.RT.JsonObject.mk(response, TDev.RT.Time.log); }, function (error) { return undefined; });
            }, function (error) { return undefined; });
        }
        Revisions.getServerInfoAsync = getServerInfoAsync;
        function queryMySessionsOnRevisionServerAsync(rt, filter_based_on_current_script) {
            if (filter_based_on_current_script === void 0) { filter_based_on_current_script = false; }
            var userid = TDev.Cloud.getUserId();
            return getRevisionServiceTokenAsync().then(function (token) {
                if (TDev.Cloud.isOffline())
                    return TDev.Promise.wrapError("Cloud is offline");
                var url = revisionservice_http() + "?user=" + userid + "&access_token=" + encodeURIComponent(token);
                if (filter_based_on_current_script) {
                    url = url + "&guidhash=" + encodeURIComponent(letterify(rt.sessions.getScriptGuid())) + "&scripthash=" + encodeURIComponent(scripthash(rt.sessions.getScriptAuthor(), rt.sessions.getScriptName()));
                }
                return TDev.Util.httpRequestAsync(url, "GET", undefined).then(function (s) {
                    var json = JSON.parse(s);
                    var sessions = new Array();
                    for (var f in json)
                        if (json.hasOwnProperty(f)) {
                            var cs = new TDev.RT.CloudSession();
                            cs._id = f;
                            if (!cs.validate())
                                continue;
                            cs.serverinfo = json[f];
                            cs._title = cs.serverinfo.title;
                            cs._permissions = "";
                            sessions.push(cs);
                        }
                    return sessions;
                });
            });
        }
        Revisions.queryMySessionsOnRevisionServerAsync = queryMySessionsOnRevisionServerAsync;
        function queryCachedSessionsAsync(filter_based_on_current_script, rt) {
            var sessions = [];
            var confirmedsessions = [];
            return TDev.Storage.getTableAsync("Sessions").then(function (table) {
                return table.getValueAsync("%").then(function (val) {
                    var sessionlist = (val || "").split(" ");
                    sessionlist.forEach(function (id) {
                        var cs = new TDev.RT.CloudSession();
                        cs._id = id;
                        if (cs.validate()) {
                            if (filter_based_on_current_script) {
                                var privatehash = letterify(rt.sessions.getScriptGuid());
                                var scripthash = Revisions.scripthash(rt.sessions.getScriptAuthor(), rt.sessions.getScriptName());
                                if (cs.tag === "pr" && cs.guidhash != privatehash)
                                    return;
                                if (cs.tag === "pu" && cs.guidhash != scripthash)
                                    return;
                                if (cs.tag === "pn")
                                    return;
                                if (cs.tag[0] === "c" && cs.guidhash[0] === "s" && cs.guidhash.lastIndexOf(scripthash, 1) !== 1)
                                    return;
                            }
                            sessions.push(cs);
                        }
                    });
                    var keys = sessions.map(function (s, idx, arr) { return s._id + "/S"; });
                    return table.getItemsAsync(keys).then(function (results) {
                        for (var i = 0; i < sessions.length; i++) {
                            var cs = sessions[i];
                            var val = results[keys[i]];
                            if (val) {
                                var json = JSON.parse(val);
                                TDev.Util.assert(cs._id === json.servername);
                                TDev.Util.assert(cs._id === json.localname);
                                cs.localname = cs._id;
                                cs._title = json.description;
                                cs._permissions = json.permissions;
                                cs.membernumber = json.membernumber;
                                cs.enable_sync = json.enable_sync;
                                confirmedsessions.push(cs);
                            }
                            else {
                            }
                        }
                        return confirmedsessions;
                    });
                });
            });
        }
        Revisions.queryCachedSessionsAsync = queryCachedSessionsAsync;
        function deleteSessionAsync(desc, rt) {
            var tasks = [];
            tasks.push(Slot.deleteSessionFileAsync(rt.sessions, desc));
            if (!desc.nodeserver && desc.servername) {
                var pos = desc.servername.indexOf("0");
                if (pos > 3 && pos < desc.servername.length - 4 && desc.servername.substr(0, pos) == TDev.Cloud.getUserId()) {
                    tasks.push(Slot.queueSessionWork(desc.localname, "deleting session on server", function () { return getRevisionServiceTokenAsync().then(function (token) {
                        if (TDev.Cloud.isOffline())
                            return TDev.Promise.wrapError("Cloud is offline");
                        var url = revisionservice_http() + "/" + desc.servername + "?user=" + TDev.Cloud.getUserId() + "&access_token=" + encodeURIComponent(token);
                        var deleteonserver = TDev.Util.httpRequestAsync(url, "DELETE", undefined);
                        return deleteonserver;
                    }); }));
                }
            }
            return TDev.Promise.join(tasks);
        }
        Revisions.deleteSessionAsync = deleteSessionAsync;
        var Slot = (function () {
            function Slot(context, getCurrent, setCurrent) {
                this.context = context;
                this.getCurrent = getCurrent;
                this.setCurrent = setCurrent;
            }
            Slot.prototype.connect = function (desc, loadonly) {
                var _this = this;
                if (loadonly === void 0) { loadonly = false; }
                var cs = this.getCurrent();
                if (cs) {
                    if (cs.servername === desc.servername && cs.localname === desc.localname && (cs.user === desc.user || cs.user === "")) {
                        if (cs.script !== desc.script || cs.readonly !== desc.readonly || cs.user !== desc.user) {
                            cs.script = desc.script;
                            cs.readonly = desc.readonly;
                            cs.user = desc.user;
                            if (cs.loaded && (cs.servername != "")) {
                                cs.disconnect();
                                cs.try_reconnect_in(1000);
                            }
                        }
                        this.context.updateStatus();
                        if (!cs.loadtask.isPending())
                            this.context.afterload();
                        return cs.loadtask;
                    }
                    this.disconnect(false, "unload previous session");
                }
                if (desc.localname) {
                    var openedby = Slot.slots[desc.localname];
                    openedby && openedby.disconnect(false, "opening session in different context");
                }
                cs = this.context.createSession(desc);
                this.setCurrent(cs);
                if (cs.localname)
                    Slot.slots[cs.localname] = this;
                cs.user_set_doorbell(function () { return _this.context.onDoorBell(); });
                var loadtask = this.loadSessionAsync(cs);
                return loadtask;
            };
            Slot.prototype.disconnect = function (deletelocalstorage, msg) {
                var cs = this.getCurrent();
                if (!cs)
                    return TDev.Promise.as();
                cs.user_unlink();
                cs.user_set_doorbell(function () { return undefined; });
                this.setCurrent(undefined);
                if (cs.localname && Slot.slots[cs.localname] === this)
                    Slot.slots[cs.localname] = undefined;
                var p = Slot.queueSessionWork(cs.localname, "unloading session" + (msg ? " (" + msg + ")" : ""), function () {
                    var promise = cs.closeAsync(deletelocalstorage);
                    promise.done();
                    return promise;
                });
                this.context.clearCachedData();
                this.context.updateStatus();
                return p;
            };
            Slot.prototype.loadSessionAsync = function (session) {
                var _this = this;
                TDev.Util.assert(session !== undefined);
                TDev.Util.assert(session.loadtask === undefined);
                var loadtask = Slot.queueSessionWork(session.localname, "loading session", function () { return session.loadAsync(function () { return _this.context.afterload(); }); });
                loadtask.thenalways(function () {
                    _this.context.updateStatus();
                    if (session.loaded) {
                        if (session.servername != "")
                            return session.connect(_this.context.url_ws(), function (needfreshtoken) { return _this.context.tokensource(needfreshtoken); });
                    }
                    else
                        session.log("!! failure while loading session");
                }).done();
                this.context.clearCachedData();
                this.context.updateStatus();
                return loadtask;
            };
            Slot.createSessionFileAsync = function (context, desc) {
                TDev.Util.assert(desc.localname && !Slot.slots[desc.localname]);
                var s = context.createSession(desc);
                return Slot.queueSessionWork(desc.localname, "creating session", function () {
                    return s.loadAsync().then(function () { return s.closeAsync(false); }).then(function () { return s; }, function () { return undefined; });
                });
            };
            Slot.deleteSessionFileAsync = function (context, desc) {
                var openedby = desc.localname && Slot.slots[desc.localname];
                if (openedby)
                    return openedby.disconnect(true);
                var s = context.createSession(desc);
                return Slot.queueSessionWork(desc.localname, "deleting session cache", function () {
                    return s.loadAsync().then(function () { return s.closeAsync(true); });
                });
            };
            Slot.queueSessionWork = function (localname, description, work) {
                var waitfor = Slot.busysessions[localname];
                if (waitfor === undefined)
                    waitfor = TDev.Promise.wrap(undefined);
                else
                    TDev.Util.log("[" + localname + "] queued " + description);
                waitfor = waitfor.then(function () {
                    TDev.Util.log("[" + localname + "] started " + description);
                    return work().then(function (x) {
                        Slot.busysessions[localname] = undefined;
                        TDev.Util.log("[" + localname + "] finished " + description);
                        return x;
                    }, function (e) {
                        Slot.busysessions[localname] = undefined;
                        TDev.Util.log("[" + localname + "] unsuccessfully terminated  " + description);
                    });
                });
                Slot.busysessions[localname] = (!!waitfor._state) ? undefined : waitfor;
                return waitfor;
            };
            Slot.slots = {};
            Slot.busysessions = {};
            return Slot;
        })();
        Revisions.Slot = Slot;
        var Sessions = (function () {
            function Sessions(wsServer) {
                var _this = this;
                if (wsServer === void 0) { wsServer = undefined; }
                this.wsServer = wsServer;
                this.CurrentSession = undefined;
                this.LocalSession = undefined;
                this.currentSessionSlot = new Slot(this, function () { return _this.CurrentSession; }, function (cs) { return _this.CurrentSession = cs; });
                this.localSessionSlot = new Slot(this, function () { return _this.LocalSession; }, function (cs) { return _this.LocalSession = cs; });
                this.doorbelllisteners = [];
                this.registereddatacaches = [];
            }
            Sessions.prototype.url_http = function () {
                return (this.current_nodeserver || revisionservice_http());
            };
            Sessions.prototype.url_ws = function () {
                return this.url_http().replace("http", "ws");
            };
            Sessions.prototype.tokensource = function (forcefreshtoken) {
                if (this.current_nodeserver)
                    return TDev.Promise.as(this._authtoken || "token");
                else
                    return Revisions.getRevisionServiceTokenAsync(forcefreshtoken);
            };
            Sessions.prototype.setAccessToken = function (token) {
                this._authtoken = token;
            };
            Sessions.prototype.isNodeServer = function () {
                return this.wsServer !== undefined;
            };
            Sessions.prototype.isNodeClient = function () {
                return this.current_nodeserver && this.wsServer === undefined;
            };
            Sessions.prototype.hasNodeConnection = function () {
                return this.current_nodeserver && this.CurrentSession !== undefined && this.CurrentSession.hasNodeConnection();
            };
            Sessions.prototype.nodeConnectionPending = function () {
                return false;
            };
            Sessions.prototype.afterload = function () {
                return undefined;
            };
            Sessions.prototype.getUserId = function () {
                return this.current_userid;
            };
            Sessions.prototype.getScriptGuid = function () {
                return this.current_scriptguid;
            };
            Sessions.prototype.getScriptAuthor = function () {
                return this.current_scriptauthor;
            };
            Sessions.prototype.getScriptName = function () {
                return this.current_scriptname;
            };
            Sessions.prototype.getScript = function () {
                return this.current_script;
            };
            Sessions.prototype.getNodeServer = function () {
                return this.current_nodeserver;
            };
            Sessions.prototype.setEditorScriptContext = function (user, guid, title, basescript, author) {
                this.current_userid = user;
                this.current_scriptguid = guid;
                this.current_scriptname = title;
                this.current_scriptauthor = author;
                this.current_script = TDev.RT.CloudSession.makeScriptIdentifier(basescript, author);
            };
            Sessions.prototype.refreshFinalScriptContext = function () {
                var changed;
                var userid = TDev.Cloud.getUserId() || "";
                var scriptguid = this.rt.host ? this.rt.host.currentGuid : this.current_scriptguid;
                var scriptname = this.rt.compiled.scriptTitle;
                var scriptauthor = this.rt.compiled.authorId || "";
                var basescript = this.rt.compiled && this.rt.compiled.baseScriptId || "";
                var script = TDev.RT.CloudSession.makeScriptIdentifier(basescript, scriptauthor);
                var nodeserver = this.rt.compiled.azureSite;
                if ((!nodeserver && this.current_userid !== userid) || this.current_script != script || this.current_scriptguid != scriptguid || this.current_scriptname != scriptname || this.current_nodeserver != nodeserver) {
                    changed = true;
                    this.currentSessionSlot.disconnect(false, "script context changed");
                    this.localSessionSlot.disconnect(false, "script context changed");
                }
                this.current_userid = userid;
                this.current_scriptguid = scriptguid;
                this.current_scriptname = scriptname;
                this.current_scriptauthor = scriptauthor;
                this.current_script = script;
                this.current_nodeserver = nodeserver;
                return changed;
            };
            Sessions.prototype.clearScriptContext = function (includinglocal) {
                var tasks = [];
                tasks.push(this.currentSessionSlot.disconnect(false, "clear script context"));
                if (includinglocal)
                    tasks.push(this.localSessionSlot.disconnect(false, "clear script context"));
                this.current_userid = undefined;
                this.current_scriptguid = undefined;
                this.current_scriptname = undefined;
                this.current_script = undefined;
                this.current_scriptauthor = undefined;
                this.current_nodeserver = undefined;
                return TDev.Promise.join(tasks);
            };
            Sessions.prototype.getCurrentSession = function () {
                TDev.Util.assert(this.CurrentSession !== undefined);
                return this.CurrentSession;
            };
            Sessions.prototype.getLocalSession = function () {
                if (!this.isNodeServer()) {
                    TDev.Util.assert(this.LocalSession !== undefined);
                    return this.LocalSession;
                }
                else {
                    TDev.Util.assert(this.CurrentSession !== undefined);
                    return this.CurrentSession;
                }
            };
            Sessions.prototype.getLastSession = function () {
                return this.CurrentSession;
            };
            Sessions.prototype.getJustMeSessionDescriptor = function () {
                if (!this.current_userid)
                    return undefined;
                return this.getCloudSessionDescriptor(justmesessionid(this.current_userid, this.current_scriptguid), "just-me session for script \"" + this.current_scriptname + "\"", privatepermission());
            };
            Sessions.prototype.getNodeSessionDescriptor = function (user) {
                var desc = this.getCloudSessionDescriptor(nodesessionid(this.current_scriptguid), "node session for script \"" + this.current_scriptname + "\"", publicpermission(this.current_script));
                desc.user = user;
                return desc;
            };
            Sessions.prototype.getEveryoneSessionDescriptor = function () {
                return this.getCloudSessionDescriptor(everyonesessionid(this.current_scriptauthor, this.current_scriptname), "everyone session for script \"" + this.current_scriptname + "\"", publicpermission(this.current_script));
            };
            Sessions.prototype.getLocalSessionDescriptor = function () {
                var desc = {};
                desc.servername = "";
                desc.localname = localsessionid(this.current_scriptguid);
                desc.user = "";
                desc.title = "";
                desc.permissions = "";
                desc.script = this.current_script;
                desc.readonly = false;
                desc.nodeserver = "";
                return desc;
            };
            Sessions.prototype.getCloudSessionDescriptor = function (servername, title, permissions) {
                var isnode = servername.indexOf("0pn") != -1;
                var owner = servername.substr(0, servername.indexOf("0"));
                var desc = {};
                desc.servername = servername;
                desc.user = this.current_userid;
                desc.title = title;
                desc.script = this.current_script;
                desc.permissions = permissions;
                desc.nodeserver = this.current_nodeserver;
                desc.localname = (!isnode && TDev.Browser.isNodeJS) ? undefined : servername;
                desc.readonly = !isnode && (owner !== this.current_userid) && (servername.indexOf("0cr") != -1);
                return desc;
            };
            Sessions.prototype.disconnect = function () {
                this.currentSessionSlot.disconnect(false, "disconnect");
                this.localSessionSlot.disconnect(false, "disconnect");
            };
            Sessions.prototype.unlink = function () {
                if (this.CurrentSession)
                    this.CurrentSession.user_unlink();
                if (this.LocalSession)
                    this.LocalSession.user_unlink();
            };
            Sessions.prototype.scriptRestarted = function () {
                this.refreshFinalScriptContext();
            };
            Sessions.prototype.scriptStarted = function (author) {
                this.refreshFinalScriptContext();
            };
            Sessions.prototype.createSession = function (original) {
                var si = original.nodeserver ? (this.isNodeServer() ? new Revisions.ServerSession(original.nodeserver, original.servername, original.localname, original.user, this.rt, this.wsServer) : new Revisions.NodeSession(original.nodeserver, original.servername, original.localname, original.user)) : new Revisions.ClientSession(original.servername, original.localname, original.user);
                si.permissions = original.permissions;
                si.title = original.title;
                si.script = original.script;
                si.readonly = original.readonly;
                si.user = original.user;
                return si;
            };
            Sessions.prototype.connectCurrent = function (desc) {
                var isnodesession = desc.servername.indexOf("0pn") != -1;
                TDev.Util.assert(isnodesession == !!this.current_nodeserver, "must not mix cloud/node sessions");
                TDev.Util.assert(isnodesession || !!this.current_userid, "must be signed in to connect cloud session");
                TDev.Util.assert(!this.isNodeServer() || isnodesession, "can only use node session on server");
                return this.currentSessionSlot.connect(desc);
            };
            Sessions.prototype.enable_script_session_mgt = function () {
                return TDev.Cloud.getUserId() && !!this.current_userid && !!this.current_scriptguid && !!this.current_scriptauthor;
            };
            Sessions.prototype.ensureSessionLoaded = function () {
                var _this = this;
                var sign_in = (this.current_userid || !this.rt.compiled.hasCloudData || this.current_nodeserver) ? TDev.Promise.as() : TDev.Cloud.authenticateAsync(TDev.lf("cloud data"));
                return sign_in.thenalways(function () {
                    _this.refreshFinalScriptContext();
                    var loadlocal;
                    var loadcurrent;
                    if (_this.rt.compiled.hasLocalData && !_this.isNodeServer()) {
                        loadlocal = _this.localSessionSlot.connect(_this.getLocalSessionDescriptor()).thenalways(function () {
                            if (_this.LocalSession && _this.LocalSession.faulted) {
                                TDev.Util.check(false, "local data corrupted - resetting");
                                _this.localSessionSlot.disconnect(true, "delete due to faulted load");
                                _this.localSessionSlot.connect(_this.getLocalSessionDescriptor());
                            }
                        });
                    }
                    else {
                        _this.localSessionSlot.disconnect(false, "no local data");
                        loadlocal = TDev.Promise.as();
                    }
                    if (_this.rt.compiled.hasCloudData || (_this.rt.compiled.hasLocalData && _this.isNodeServer())) {
                        if (!_this.current_nodeserver && !_this.current_userid)
                            loadcurrent = TDev.Promise.wrapError("cannot run this script without first signing in");
                        else if (!_this.current_scriptguid || !_this.current_scriptname || !_this.current_scriptauthor || !_this.current_script)
                            TDev.Util.oops("cannot determine script info: runtime lacks information");
                        else {
                            var session = _this.current_nodeserver ? _this.getNodeSessionDescriptor("") : (_this.CurrentSession || _this.getJustMeSessionDescriptor());
                            loadcurrent = _this.connectCurrent(session);
                        }
                    }
                    else {
                        _this.currentSessionSlot.disconnect(false, "no cloud session");
                        loadcurrent = TDev.Promise.as();
                    }
                    _this.updateStatus();
                    return TDev.Promise.join([loadlocal, loadcurrent]);
                });
            };
            Sessions.prototype.readyForExecution = function () {
                if (this.refreshFinalScriptContext()) {
                    TDev.Util.check(false, "script info changed between loading and execution");
                    return false;
                }
                if (this.rt.compiled.hasCloudData && !this.current_nodeserver && !this.current_userid) {
                    return false;
                }
                if (this.rt.compiled.hasLocalData && !this.isNodeServer() && !(this.LocalSession && this.LocalSession.loaded)) {
                    TDev.Util.check(false, "failed to load local session");
                    return false;
                }
                if ((this.rt.compiled.hasCloudData || (this.rt.compiled.hasLocalData && this.isNodeServer())) && !(this.CurrentSession && this.CurrentSession.loaded)) {
                    TDev.Util.check(false, "failed to load cloud session");
                    return false;
                }
                if (this.LocalSession && this.LocalSession.faulted) {
                    TDev.Util.check(false, "error loading local session from disk");
                    return false;
                }
                return true;
            };
            Sessions.prototype.stopAsync = function () {
                return TDev.Promise.as();
            };
            Sessions.prototype.receive_operation = function (p) {
                if (!this.current_nodeserver)
                    throw new Error("should not be called for unexported apps");
            };
            Sessions.prototype.resetCurrentSession = function () {
                var session = this.CurrentSession;
                if (!session)
                    return;
                var desc = this.getCloudSessionDescriptor(session.servername, session.title, session.permissions);
                this.currentSessionSlot.disconnect(true, "reset current session");
                return this.currentSessionSlot.connect(desc);
            };
            Sessions.prototype.clearCurrentSession = function () {
                if (!this.CurrentSession)
                    return;
                this.CurrentSession.user_clear_all();
                this.clearCachedData();
            };
            Sessions.prototype.getLocalSessionAttributeAsync = function (key, rt) {
                var _this = this;
                TDev.Util.assert(!this.isNodeServer(), "cannot access attributes on server");
                return this.get_attribute_lval(key, rt).then(function (lval) { return TDev.RT.Conv.fromCloud("string", _this.LocalSession.user_get_value(lval)); });
            };
            Sessions.prototype.setLocalSessionAttributeAsync = function (key, value, rt) {
                var _this = this;
                TDev.Util.assert(!this.isNodeServer(), "cannot access attributes on server");
                var op = TDev.RT.Conv.toCloud("string", value, false);
                return this.get_attribute_lval(key, rt).then(function (lval) { return _this.LocalSession.user_modify_lval(lval, op); });
            };
            Sessions.prototype.get_attribute_lval = function (key, rt) {
                var _this = this;
                var waitfor = this.LocalSession ? TDev.Promise.as() : this.localSessionSlot.connect(this.getLocalSessionDescriptor());
                return waitfor.then(function () { return _this.LocalSession.user_get_lval(Revisions.Parser.MakeProperty(key, "attributes[]", "string"), [], []); });
            };
            Sessions.prototype.queueRestRequest = function (sr) {
                sr._onStop = new TDev.PromiseInv();
                this.rt.dispatchServerRequest(sr, sr._onStop).then(function (res) {
                }, function (err) {
                    TDev.RT.App.log("404 " + sr.method().toUpperCase() + " " + sr.url());
                    var resp = sr.getNodeRequest().tdResponse;
                    resp.writeHead(404, "API Error");
                    resp.end(err.message);
                });
            };
            Sessions.prototype.yieldSession = function () {
                var somechanges = false;
                if (this.CurrentSession) {
                    var changes = this.CurrentSession.user_yield();
                    if (changes) {
                        this.updateStatus();
                        this.clearCachedData();
                        somechanges = true;
                    }
                }
                if (this.LocalSession) {
                    var changes = this.LocalSession.user_yield();
                    if (changes) {
                        this.clearCachedData();
                        somechanges = true;
                    }
                }
                return somechanges;
            };
            Sessions.prototype.updateStatus = function () {
                if (this.isNodeServer())
                    return;
                if (this.CurrentSession) {
                    if (this.rt.host)
                        this.rt.host.updateCloudState(true, this.CurrentSession.getCloudSession().type(), this.CurrentSession.user_get_connectionstatus(false));
                    TDev.RT.CloudData.refreshSessionInfo(this.CurrentSession);
                }
                else {
                    if (this.rt.host)
                        this.rt.host.updateCloudState(false, "", "");
                }
            };
            Sessions.prototype.onDoorBell = function () {
                if (this.isNodeClient() && this.CurrentSession && (this.CurrentSession.marooned || this.CurrentSession.faulted)) {
                    var s = this.CurrentSession;
                    s.log("discard cache because it is " + (s.marooned ? "marooned" : s.faulted ? "faulted" : ""));
                    this.currentSessionSlot.disconnect(true, "reset because " + (s.marooned ? "marooned" : s.faulted ? "faulted" : ""));
                    this.currentSessionSlot.connect(s);
                }
                if (!TDev.Browser.isNodeJS) {
                    this.rt.yield_when_possible();
                }
                this.doorbelllisteners = this.doorbelllisteners.filter(function (listener) { return listener(); });
                this.updateStatus();
            };
            Sessions.prototype.addDoorbellListener = function (listener) {
                this.doorbelllisteners.push(listener);
            };
            Sessions.prototype.clearCachedData = function () {
                for (var l in this.registereddatacaches) {
                    if (this.registereddatacaches.hasOwnProperty(l))
                        this.registereddatacaches[l].clearCachedData();
                }
            };
            Sessions.prototype.registerDataCache = function (key, o) {
                this.registereddatacaches[key] = o;
            };
            Sessions.prototype.unregisterDataCache = function (key) {
                delete this.registereddatacaches[key];
            };
            Sessions.prototype.deleteAllLocalDataAsync = function (scriptguid) {
                var localtask = Slot.deleteSessionFileAsync(this, this.getLocalSessionDescriptor());
                if (this.current_nodeserver) {
                    return TDev.Promise.join([
                        Slot.deleteSessionFileAsync(this, this.getNodeSessionDescriptor("")),
                        localtask
                    ]);
                }
                else {
                    var userid = TDev.Cloud.getUserId();
                    if (!userid || userid !== this.current_userid || scriptguid !== this.current_scriptguid)
                        return localtask;
                    else {
                        var justmesession = this.getJustMeSessionDescriptor();
                        var everyonesession = this.getEveryoneSessionDescriptor();
                        return TDev.Promise.join([
                            Slot.deleteSessionFileAsync(this, justmesession),
                            Slot.deleteSessionFileAsync(this, everyonesession),
                            localtask
                        ]);
                    }
                }
            };
            Sessions.prototype.createCustomSessionAsync = function (title, type) {
                TDev.Util.assert(!!this.current_userid, "must be signed in to create a cloud session");
                TDev.Util.assert(!this.current_nodeserver, "cannot create sessions for cloud library");
                var desc = {};
                var letter = (permit_all_scripts ? "a" : "s");
                var scripth = (permit_all_scripts ? "" : scripthash(this.current_scriptauthor, this.current_scriptname));
                var guid = letterify(TDev.Util.guidGen());
                var id;
                var permit_all_scripts = false;
                if (type === "shareable") {
                    desc.servername = this.current_userid + "0cw" + letter + scripth + guid;
                    desc.permissions = publicpermission(permit_all_scripts ? "" : this.current_script);
                }
                else if (type === "broadcast") {
                    desc.servername = this.current_userid + "0cr" + letter + scripth + guid;
                    desc.permissions = broadcastpermission(permit_all_scripts ? "" : this.current_script);
                }
                else {
                    desc.servername = this.current_userid + "0cp" + letter + scripth + guid;
                    desc.permissions = privatepermission(permit_all_scripts ? "" : this.current_script);
                }
                desc.localname = desc.servername;
                desc.readonly = false;
                desc.user = this.current_userid;
                desc.title = title;
                desc.nodeserver = "";
                desc.script = this.current_script;
                return Slot.createSessionFileAsync(this, desc).then(function (s) { return s.getCloudSession(); });
            };
            return Sessions;
        })();
        Revisions.Sessions = Sessions;
        (function (CloudOperationType) {
            CloudOperationType[CloudOperationType["UNKNOWN"] = 0] = "UNKNOWN";
            CloudOperationType[CloudOperationType["RPC"] = 1] = "RPC";
            CloudOperationType[CloudOperationType["OFFLINE"] = 2] = "OFFLINE";
        })(Revisions.CloudOperationType || (Revisions.CloudOperationType = {}));
        var CloudOperationType = Revisions.CloudOperationType;
    })(Revisions = TDev.Revisions || (TDev.Revisions = {}));
    var WebSocketWrapper = (function () {
        function WebSocketWrapper(server, request, socket) {
            this.server = server;
            this.request = request;
            this.socket = socket;
        }
        WebSocketWrapper.prototype.origin = function () {
            return this.request.headers['origin'];
        };
        WebSocketWrapper.prototype.path = function () {
            return this.request.url;
        };
        WebSocketWrapper.prototype.accept = function () {
            var _this = this;
            this.socket.tdWrapper = this;
            this.server._conns.push(this.socket);
            var remove = function () {
                var conns = _this.server._conns;
                var idx = conns.indexOf(_this.socket);
                if (idx >= 0)
                    conns.splice(idx, 1);
            };
            this.onClose(remove);
            this.onError(remove);
            return this.socket;
        };
        WebSocketWrapper.prototype.reject = function () {
            this.socket.close();
        };
        WebSocketWrapper.prototype.remoteAddress = function () {
            return this.socket.remoteAddress;
        };
        WebSocketWrapper.prototype.onMessage = function (h) {
            this.socket.addEventListener("message", function (msg) { return typeof msg.data == "string" ? h(msg.data, null) : h(null, msg.data); }, false);
        };
        WebSocketWrapper.prototype.onClose = function (h) {
            this.socket.addEventListener("close", function (ev) { return h(ev.code, ev.reason); }, false);
        };
        WebSocketWrapper.prototype.onError = function (h) {
            this.socket.addEventListener("error", h, false);
        };
        WebSocketWrapper.prototype.mkTdWebSocket = function (rt) {
            if (!this.socket)
                this.accept();
            var w = new TDev.RT.WebSocket_(this.socket, rt);
            this.onMessage(function (str, buff) {
                var data = str;
                if (buff)
                    data = TDev.RT.Buffer.fromTypedArray(buff);
                w.receiveMessage(TDev.RT.WebSocketMessage.mk(data));
            });
            this.onError(function (ev) {
                var msg = ev.message || (ev + "");
                TDev.RT.App.logEvent(TDev.RT.App.DEBUG, "ws", "error: " + msg, undefined);
                w.receiveMessage(TDev.RT.WebSocketMessage.mkError(msg));
            });
            this.onClose(function (code, reason) {
                w.gotClose();
            });
            return w;
        };
        return WebSocketWrapper;
    })();
    TDev.WebSocketWrapper = WebSocketWrapper;
    var WebSocketServerWrapper = (function () {
        function WebSocketServerWrapper(WebSocketModule) {
            this.WebSocketModule = WebSocketModule;
            this.handlers = [];
            this._conns = [];
        }
        WebSocketServerWrapper.prototype.isReal = function () {
            return !!this.WebSocketModule;
        };
        WebSocketServerWrapper.prototype.upgradeCallback = function (request, socket, body) {
            var _this = this;
            var ws = this.WebSocketModule;
            if (ws.isWebSocket(request)) {
                var conn = new ws(request, socket, body);
                var r = new WebSocketWrapper(this, request, conn);
                var nextOne = function (idx) {
                    if (!_this.handlers[idx])
                        r.reject();
                    else
                        _this.handlers[idx](r, function () { return nextOne(idx + 1); });
                };
                nextOne(0);
            }
        };
        WebSocketServerWrapper.prototype.closeConnections = function () {
            this._conns.forEach(function (c) { return c.close(); });
            this._conns = [];
        };
        WebSocketServerWrapper.prototype.addHandler = function (h) {
            this.handlers.push(h);
        };
        WebSocketServerWrapper.prototype.connections = function () {
            return this._conns;
        };
        return WebSocketServerWrapper;
    })();
    TDev.WebSocketServerWrapper = WebSocketServerWrapper;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Revisions;
    (function (Revisions) {
        (function (StatusType) {
            StatusType[StatusType["Error"] = 0] = "Error";
            StatusType[StatusType["Warning"] = 1] = "Warning";
            StatusType[StatusType["Ok"] = 2] = "Ok";
        })(Revisions.StatusType || (Revisions.StatusType = {}));
        var StatusType = Revisions.StatusType;
        (function (EncodingMode) {
            EncodingMode[EncodingMode["CLIENT_LAYER_TO_DISK"] = 0] = "CLIENT_LAYER_TO_DISK";
            EncodingMode[EncodingMode["CLIENT_BASE_TO_DISK"] = 1] = "CLIENT_BASE_TO_DISK";
            EncodingMode[EncodingMode["CLIENT_LAYER_TO_SERVER"] = 2] = "CLIENT_LAYER_TO_SERVER";
            EncodingMode[EncodingMode["SERVER_BASE_TO_DISK"] = 3] = "SERVER_BASE_TO_DISK";
            EncodingMode[EncodingMode["SERVER_LAYER_TO_CLIENT"] = 4] = "SERVER_LAYER_TO_CLIENT";
            EncodingMode[EncodingMode["SERVER_UPDATES_TO_CLIENT"] = 5] = "SERVER_UPDATES_TO_CLIENT";
            EncodingMode[EncodingMode["TRACE_LOAD"] = 6] = "TRACE_LOAD";
        })(Revisions.EncodingMode || (Revisions.EncodingMode = {}));
        var EncodingMode = Revisions.EncodingMode;
        var Layer = (function () {
            function Layer(session, name, data, clientround, serverround, grounded) {
                if (grounded === void 0) { grounded = false; }
                this.delcount = 0;
                this.session = session;
                this.name = name;
                this.data = data;
                if (clientround !== undefined)
                    this.clientround = clientround;
                if (serverround !== undefined)
                    this.serverround = serverround;
                this.grounded = grounded;
            }
            Layer.prototype.hasData = function () {
                return ((this.data && this.data.length !== 0) || (this.cloudOperations && this.cloudOperations.length !== 0) || this.grounded || this.clientrounds);
            };
            Layer.prototype.clear = function () {
                var _this = this;
                var changes = false;
                this.data.forEach(function (d) {
                    if (d.removeOperation(_this) !== undefined)
                        changes = true;
                });
                return changes;
                this.grounded = false;
            };
            Layer.prototype.cleanIfNeeded = function (limit) {
                var _this = this;
                if (this.delcount > limit) {
                    this.data = this.data.filter(function (d) { return (d.getOperation(_this.name) !== undefined); });
                    this.delcount = 0;
                }
            };
            Layer.prototype.invalidate_all = function () {
                this.data.forEach(function (d) {
                    if (d instanceof Item)
                        d.invalidate(true);
                    else
                        d.invalidate(false);
                });
            };
            Layer.prototype.CommitCloudOperation = function (op) {
                if (!this.cloudOperations) {
                    this.cloudOperations = [op];
                }
                else {
                    this.cloudOperations.push(op);
                }
            };
            Layer.prototype.mergeCloudOperations = function (layer) {
                if (!layer.cloudOperations)
                    return;
                if (!this.cloudOperations) {
                    this.cloudOperations = [];
                }
                this.cloudOperations = this.cloudOperations.concat(layer.cloudOperations);
            };
            Layer.prototype.removeCloudOperations = function () {
                delete this.cloudOperations;
            };
            return Layer;
        })();
        Revisions.Layer = Layer;
        var Fence = (function () {
            function Fence(continuation, round, exclusive) {
                this.continuation = continuation;
                this.round = round;
                this.exclusive = exclusive;
            }
            return Fence;
        })();
        var Datum = (function () {
            function Datum() {
                this.fromCloudOp = TDev.Runtime.theRuntime && TDev.Runtime.theRuntime.inCloudCall;
                this.ops = {};
            }
            Datum.prototype.invalidate = function (deleted) {
                delete this.cached;
                if (deleted) {
                    this.deleted = true;
                    this.unlink();
                }
            };
            Datum.prototype.get_op = function (layer) {
                return this.ops[layer];
            };
            Datum.prototype.set_op = function (layer, op) {
                this.ops[layer] = op;
            };
            Datum.prototype.del_op = function (layer) {
                delete this.ops[layer];
            };
            Datum.prototype.all_ops = function () {
                return Object.keys(this.ops);
            };
            Datum.prototype.getOperation = function (lname) {
                return this.get_op(lname);
            };
            Datum.prototype.recordOperation = function (l, op) {
                var val = this.get_op(l.name);
                var result = this.collapse(val, op, l.grounded);
                if (result !== undefined) {
                    this.set_op(l.name, result);
                    if (val === undefined)
                        l.data.push(this);
                }
                else {
                    if (val !== undefined) {
                        this.del_op(l.name);
                        l.delcount += 1;
                    }
                }
                return (val !== result);
            };
            Datum.prototype.removeOperation = function (l) {
                var val = this.get_op(l.name);
                if (val !== undefined) {
                    this.del_op(l.name);
                    l.delcount += 1;
                }
                return val;
            };
            Datum.prototype.compute_current = function () {
                var cur = this.getOperation("B");
                if (!this.session.readonly) {
                    var baseround = this.session.get_layer("B").clientround;
                    var localround = this.session.localround;
                    for (var i = baseround + 1; i < localround; i++) {
                        var datalayer = this.session.get_layer("D" + i);
                        cur = (datalayer.grounded) ? this.getOperation("D" + i) : this.collapse(cur, this.getOperation("D" + i), true);
                    }
                    var locallayer = this.session.get_layer("D" + localround);
                    cur = (locallayer && locallayer.grounded) ? this.getOperation("D" + localround) : this.collapse(cur, this.getOperation("D" + localround), true);
                    var tlayer = this.session.get_layer("T");
                    if (tlayer)
                        cur = (tlayer.grounded) ? this.getOperation("T") : this.collapse(cur, this.getOperation("T"), true);
                }
                TDev.Util.check(!TDev.dbg || (this.cached === undefined) || (this.cached !== null && this.cached === cur) || (this.cached === null && cur === undefined));
                this.cached = (cur === undefined) ? null : cur;
                return cur;
            };
            Datum.prototype.has_deleted_dependencies = function () {
                var _this = this;
                var deleted = false;
                this.ukeys.forEach(function (uid) {
                    var item = _this.session.get_item(uid);
                    if (!item || _this.session.user_is_datum_deleted(item))
                        deleted = true;
                });
                TDev.Util.assert(!deleted || this.deleted);
                return deleted;
            };
            Datum.prototype.linkDeps = function () {
                var _this = this;
                this.ukeys.forEach(function (l) {
                    var item = _this.session.get_item(l);
                    if (!(item && item.addDependency(_this)))
                        _this.deleted = true;
                });
            };
            Datum.prototype.collapse = function (first, second, grounded) {
            };
            Datum.prototype.target = function () {
                return "";
            };
            Datum.prototype.unlink = function () {
            };
            return Datum;
        })();
        Revisions.Datum = Datum;
        var Item = (function (_super) {
            __extends(Item, _super);
            function Item() {
                _super.apply(this, arguments);
                this.deps = {};
            }
            Item.prototype.target = function () {
                return this.uid;
            };
            Item.prototype.unlink = function () {
                if (this.backlink) {
                    this.backlink.unlink();
                    delete this.backlink;
                }
            };
            Item.prototype.collapse = function (first, second, grounded) {
                if (first === undefined)
                    return second;
                if (second === undefined)
                    return first;
                if (first === "D") {
                    this.session.assertConsistency(second === "D");
                    return grounded ? undefined : "D";
                }
                TDev.Util.assert(first[0] === "C");
                if (second !== "D")
                    this.session.assertConsistency(false, "collapse uid=" + this.uid + " def=" + (this.backlink && this.backlink.parent && this.backlink.parent.cloudtype) + " second=" + second);
                return undefined;
            };
            Item.prototype.recordCreation = function (l, serveritemcount) {
                if (serveritemcount === undefined)
                    this.recordOperation(l, "C");
                else {
                    this.recordOperation(l, "C" + serveritemcount);
                }
            };
            Item.prototype.recordDeletion = function (l) {
                this.recordOperation(l, "D");
            };
            Item.prototype.recordOperation = function (l, op) {
                if (op === "D")
                    this.removeRedundantOps(l);
                return _super.prototype.recordOperation.call(this, l, op);
            };
            Item.prototype.compareTo = function (other) {
                var a = this.compute_current();
                if (a === "C") {
                    var b = other.compute_current();
                    if (b === "C")
                        return Number(this.uid) - Number(other.uid);
                    else
                        return 1;
                }
                else {
                    var b = other.compute_current();
                    if (b === "C")
                        return -1;
                    else
                        return Number(a.substr(1)) - Number(b.substr(1));
                }
            };
            Item.prototype.addDependency = function (d) {
                this.deps["$" + d.target()] = d;
                return !this.deleted;
            };
            Item.prototype.removeDependency = function (d) {
                delete this.deps["$" + d.target()];
            };
            Item.prototype.invalidate = function (deleted) {
                _super.prototype.invalidate.call(this, deleted);
                for (var p in this.deps)
                    if (this.deps.hasOwnProperty(p) && p[0] === "$")
                        this.deps[p].invalidate(deleted);
                this.session.remove_item_from_index(this);
            };
            Item.prototype.removeRedundantOps = function (layer) {
                for (var p in this.deps)
                    if (this.deps.hasOwnProperty(p) && p[0] === "$") {
                        var datum = this.deps[p];
                        datum.removeOperation(layer);
                        if (datum instanceof Item)
                            datum.removeRedundantOps(layer);
                    }
            };
            return Item;
        })(Datum);
        Revisions.Item = Item;
        var Entry = (function (_super) {
            __extends(Entry, _super);
            function Entry() {
                _super.apply(this, arguments);
            }
            Entry.prototype.target = function () {
                return ClientSession.MakeModTarget(this.definition, this.ukeys, this.lkeys);
            };
            return Entry;
        })(Datum);
        Revisions.Entry = Entry;
        var LVal = (function (_super) {
            __extends(LVal, _super);
            function LVal() {
                _super.apply(this, arguments);
            }
            LVal.prototype.target = function () {
                return ClientSession.MakeModTarget(this.definition, this.ukeys, this.lkeys);
            };
            LVal.prototype.parseDefinition = function () {
                var p = new Parser(this.definition, 0);
                this.name = p.ParseDefinitionString();
                TDev.Util.assert(p.text[p.pos] === ",");
                p.pos += 1;
                this.codomain = p.ParseDefinitionString();
                TDev.Util.assert(p.text[p.pos] === "[");
                this.indexdomain = p.text.slice(p.pos + 1, p.text.length - 1);
            };
            LVal.prototype.collapse = function (first, second, grounded) {
                if (second === undefined)
                    return first;
                else if (first === undefined) {
                    if (this.codomain === "double" || this.codomain === "long") {
                        if (grounded) {
                            if (second.lastIndexOf("A", 0) === 0)
                                second = second.slice(1);
                            return (second === "0") ? undefined : second;
                        }
                        else
                            return second === "A0" ? undefined : second;
                    }
                    else if (this.codomain === "ast") {
                        return second;
                    }
                    else {
                        if (second.lastIndexOf("^?", 0) !== 0)
                            return (grounded && !second) ? undefined : second;
                        var cond = second.substring(2);
                        if (cond === "")
                            return undefined;
                        if (grounded)
                            return (cond.charAt(0) === "^") ? ("^!" + cond) : cond;
                        return second;
                    }
                }
                else if (this.codomain === "double" || this.codomain === "long") {
                    if (second.charAt(0) !== 'A')
                        return (grounded && second === "0") ? undefined : second;
                    var secondval = Number(second.slice(1));
                    var relative = false;
                    var firstval = Number(first);
                    if (isNaN(firstval)) {
                        TDev.Util.assert(first.charAt(0) === 'A');
                        firstval = Number(first.slice(1));
                        relative = true;
                        TDev.Util.assert(!grounded);
                    }
                    var sum = (firstval + secondval);
                    if (sum !== 0 || (!relative && !grounded))
                        return relative ? ("A" + sum) : sum.toString();
                    else
                        return undefined;
                }
                else if (this.codomain === "ast") {
                    return second;
                }
                else {
                    if (second.lastIndexOf("^?", 0) !== 0) {
                        return (grounded && !second) ? undefined : second;
                    }
                    else {
                        if (first.lastIndexOf("^?", 0) !== 0) {
                            if (first === "" || first === "^!") {
                                var cond = second.substring(2);
                                var r = (cond.charAt(0) === "^") ? ("^!" + cond) : cond;
                                return (grounded && !r) ? undefined : r;
                            }
                            else {
                                return first;
                            }
                        }
                        else {
                            if (first.length === 2)
                                return (grounded && !second) ? undefined : second;
                            else
                                return first;
                        }
                    }
                }
                TDev.Util.oops("missing case in LVal.collapse");
            };
            return LVal;
        })(Datum);
        Revisions.LVal = LVal;
        var ClientSession = (function () {
            function ClientSession(servername, localname, user) {
                this.servername = servername;
                this.localname = localname;
                this.user = user;
                this.sendCloudOperations = false;
                this.concatIdToItem = false;
                this.includeKeysInStatus = false;
                this.acceptsUpdates = false;
                this.requiresAuth = true;
                this.trace_save_and_load = false;
                this.trace_incoming_packets = false;
                this.trace_saving = false;
                this.membernumber = -1;
                this.disambiguator = "";
                this.enable_sync = undefined;
                this.serveritemcount = 0;
                this.userdata = {};
                this.localround = 1;
                this.uidcount = 0;
                this.sendinterval = 250;
                this.pendingroundlimit = 5;
                this.scrublimit = 1000;
                this.connectionretrydelay = 20000;
                this.qcount = 0;
                this.last_S_save = TDev.Promise.as();
                this.last_C_save = TDev.Promise.as();
                this.ring_doorbell_when_done = false;
                this.CLstate_needsave = false;
                this.Sstate_needsave = false;
                this.previewround = 0;
                this.percentfull = 0;
                this.presence = [];
                this.dochannelcompression = false;
                this.statuschanges = false;
                this.fences = [];
                this.doorbell = function () {
                };
                this.initialize_data();
                this.loaded = (localname === undefined);
                if (this.user === undefined)
                    this.user = "";
                TDev.Util.assert(!!servername || !!localname);
            }
            ClientSession.prototype.samesession = function (other) {
                return (this.servername === other.servername && this.localname === other.localname);
            };
            ClientSession.prototype.getMemberNumber = function () {
                return this.membernumber;
            };
            ClientSession.prototype.key_sessionlist = function () {
                return "%";
            };
            ClientSession.prototype.key_Sstate = function () {
                return this.localname + "/S";
            };
            ClientSession.prototype.key_Cstate = function () {
                return this.localname + "/C";
            };
            ClientSession.prototype.key_layer = function (layer) {
                return this.localname + "/" + layer;
            };
            ClientSession.prototype.S_toJSONstring = function () {
                return JSON.stringify({
                    servername: this.servername,
                    localname: this.localname,
                    description: this.title,
                    membernumber: this.membernumber,
                    disambiguator: this.disambiguator,
                    enable_sync: this.enable_sync,
                    serveritemcount: this.serveritemcount,
                    permissions: this.permissions,
                    userdata: this.userdata,
                });
            };
            ClientSession.prototype.S_fromJSONstring = function (s) {
                var json = JSON.parse(s);
                TDev.Util.assert(this.servername === json.servername);
                TDev.Util.assert(this.localname === json.localname);
                if (!this.title && json.description)
                    this.title = json.description;
                this.membernumber = json.membernumber;
                this.disambiguator = json.disambiguator;
                if (this.enable_sync === undefined)
                    this.enable_sync = json.enable_sync;
                this.serveritemcount = json.serveritemcount;
                this.permissions = json.permissions;
                this.userdata = json.userdata || {};
            };
            ClientSession.prototype.C_toJSONstring = function () {
                return JSON.stringify({
                    uidcount: this.uidcount,
                    localround: this.localround,
                });
            };
            ClientSession.prototype.C_fromJSONstring = function (s) {
                var json = JSON.parse(s);
                this.uidcount = json.uidcount;
                this.localround = json.localround;
            };
            ClientSession.prototype.user_specify_ast_encoding = function (s) {
                this.astencoding = s;
            };
            ClientSession.prototype.assertConsistency = function (cond, message) {
                if (!cond) {
                    this.faulted = true;
                    this.statuschanges = true;
                    TDev.Util.check(cond, "local cache inconsistent with server");
                }
            };
            ClientSession.prototype.user_get_lval = function (definition, ukeys, lkeys) {
                var t = ClientSession.MakeModTarget(definition, ukeys, lkeys);
                var lval = this.get_lval(t);
                if (!lval) {
                    lval = new LVal();
                    lval.session = this;
                    lval.definition = definition;
                    lval.ukeys = ukeys;
                    lval.lkeys = lkeys;
                    lval.parseDefinition();
                    lval.entry = this.user_get_entry(lval.indexdomain, ukeys, lkeys);
                    lval.linkDeps();
                    this.add_lval(lval);
                    this.add_lval_to_index(lval);
                }
                else {
                    this.assertConsistency(lval.definition === definition);
                    this.assertConsistency(ukeys.length === lval.ukeys.length);
                    for (var i = 0; i < ukeys.length; i++)
                        this.assertConsistency(ukeys[i] === lval.ukeys[i]);
                    this.assertConsistency(lkeys.length === lval.lkeys.length);
                    for (var i = 0; i < lkeys.length; i++)
                        this.assertConsistency(lkeys[i] === lval.lkeys[i]);
                }
                return lval;
            };
            ClientSession.prototype.user_get_entry = function (definition, ukeys, lkeys) {
                var k = ClientSession.MakeModTarget(definition, ukeys, lkeys);
                var entry = this.get_entry(k);
                if (!entry) {
                    entry = new Entry();
                    entry.session = this;
                    entry.definition = definition;
                    entry.ukeys = ukeys;
                    entry.lkeys = lkeys;
                    entry.linkDeps();
                    this.add_entry(entry);
                }
                else {
                    this.assertConsistency(entry.definition === definition);
                    this.assertConsistency(ukeys.length === entry.ukeys.length);
                    for (var i = 0; i < ukeys.length; i++)
                        this.assertConsistency(ukeys[i] === entry.ukeys[i]);
                    this.assertConsistency(lkeys.length === entry.lkeys.length);
                    for (var i = 0; i < lkeys.length; i++)
                        this.assertConsistency(lkeys[i] === entry.lkeys[i]);
                }
                return entry;
            };
            ClientSession.prototype.user_get_entries_in_indexdomain = function (indexdomain) {
                var _this = this;
                var entries = new Array();
                var qcount = this.qcount;
                this.qcount += 1;
                this.get_lvals_for_indexdomain(indexdomain).forEach(function (lval) {
                    if (!_this.user_is_defaultvalue(lval)) {
                        var e = lval.entry;
                        if (e.qcount !== qcount) {
                            e.qcount = qcount;
                            entries.push(lval.entry);
                            e.lvals = new Array();
                        }
                        e.lvals.push(lval);
                    }
                });
                return entries;
            };
            ClientSession.prototype.user_modify_lval = function (lval, op) {
                if (this.readonly)
                    return;
                var deleted = this.user_is_datum_deleted(lval);
                if (!deleted) {
                    lval.invalidate(false);
                    if (op !== undefined) {
                        var transactionlayer = this.get_layer("T") || this.create_layer("T");
                        lval.recordOperation(transactionlayer, op);
                    }
                }
            };
            ClientSession.prototype.user_get_items_in_domain = function (domain) {
                var _this = this;
                var base = this.get_items_in_domain(domain);
                return base.filter(function (i) { return !_this.user_is_datum_deleted(i); });
            };
            ClientSession.prototype.user_get_item = function (uid) {
                var k = this.get_item(uid);
                if (k === undefined) {
                    var pos = uid.indexOf('.');
                    if (pos != -1 && uid.substr(0, pos) === this.membernumber.toString())
                        k = this.get_item(uid.substr(pos + 1));
                }
                return k;
            };
            ClientSession.prototype.user_create_tombstone = function (definition, uid, ukeys, lkeys) {
                var k = new Item();
                k.session = this;
                k.definition = definition;
                k.uid = uid;
                k.ukeys = ukeys;
                k.lkeys = lkeys;
                k.deleted = true;
                return k;
            };
            ClientSession.prototype.user_create_item = function (definition, ukeys, lkeys) {
                var k = new Item();
                k.session = this;
                k.definition = definition;
                TDev.Util.assert(this.loaded || this.faulted);
                this.uidcount += 1;
                k.uid = (this.concatIdToItem ? (this.membernumber + ".") : "") + this.uidcount.toString();
                k.ukeys = ukeys;
                k.lkeys = lkeys;
                this.assertConsistency(!this.get_item(k.uid));
                if (this.readonly) {
                    k.deleted = true;
                    return k;
                }
                k.linkDeps();
                this.add_item(k);
                if (!k.has_deleted_dependencies()) {
                    var transactionlayer = this.get_layer("T") || this.create_layer("T");
                    k.recordCreation(transactionlayer);
                    this.add_item_to_index(k);
                }
                return k;
            };
            ClientSession.prototype.user_delete_item = function (item) {
                if (this.readonly)
                    return;
                var deleted = this.user_is_datum_deleted(item);
                if (!deleted) {
                    var transactionlayer = this.get_layer("T") || this.create_layer("T");
                    item.recordDeletion(transactionlayer);
                    item.invalidate(true);
                }
            };
            ClientSession.prototype.user_clear_all = function () {
                if (this.readonly)
                    return;
                var baselayer = this.get_layer("B");
                baselayer.invalidate_all();
                var baseround = baselayer.clientround;
                var localround = this.localround;
                for (var i = baseround + 1; i <= localround; i++) {
                    var datalayer = this.get_layer("D" + i);
                    datalayer && datalayer.invalidate_all();
                }
                var transactionlayer = this.get_layer("T");
                transactionlayer && transactionlayer.invalidate_all();
                this.delete_layer("T", false);
                var transactionlayer = this.create_layer("T");
                transactionlayer.grounded = true;
            };
            ClientSession.prototype.log = function (msg) {
                TDev.Util.log("{0}", this.logmsg(msg));
            };
            ClientSession.prototype.logmsg = function (msg) {
                return "[" + (this.servername || this.localname) + "] " + msg;
            };
            ClientSession.prototype.user_is_datum_deleted = function (datum) {
                if (datum.has_deleted_dependencies())
                    return true;
                var deleted = false;
                if (datum instanceof Item) {
                    var s = datum.compute_current();
                    deleted = (!s || s[0] !== "C");
                }
                TDev.Util.assert(!TDev.dbg || deleted === !!datum.deleted);
                return deleted;
            };
            ClientSession.prototype.user_is_datum_confirmed = function (datum) {
                var ops = datum.all_ops();
                if (this.servername)
                    return !ops.some(function (s) { return (s[0] === "D" || s[0] === "T"); });
                else
                    return !ops.some(function (s) { return s != "D1"; });
            };
            ClientSession.prototype.user_get_value = function (lval) {
                var s;
                if (!lval.has_deleted_dependencies())
                    s = lval.compute_current();
                return s;
            };
            ClientSession.prototype.user_is_defaultvalue = function (lval) {
                if (lval.has_deleted_dependencies())
                    return true;
                var s = lval.compute_current();
                if (s === undefined)
                    return true;
                if (lval.codomain === "long" || lval.codomain === "double")
                    return (s === "A0" || s === "0");
                else if (lval.codomain === "string")
                    return (s === "" || s === "^" || s === "^?" || s === "^!");
                else
                    return s === "";
            };
            ClientSession.prototype.get_datum = function (target) {
                return this.data[target];
            };
            ClientSession.prototype.get_item = function (uid) {
                return this.data[uid];
            };
            ClientSession.prototype.get_lval = function (target) {
                return this.data[target];
            };
            ClientSession.prototype.get_entry = function (target) {
                return this.data[target];
            };
            ClientSession.prototype.add_item = function (item) {
                this.data[item.uid] = item;
            };
            ClientSession.prototype.add_lval = function (lval) {
                this.data[lval.target()] = lval;
            };
            ClientSession.prototype.add_entry = function (entry) {
                this.data[entry.target()] = entry;
            };
            ClientSession.prototype.get_items_in_domain = function (domain) {
                var obj = this.domains[domain];
                return obj ? TDev.Util.values(obj) : [];
            };
            ClientSession.prototype.add_item_to_index = function (item) {
                var obj = this.domains[item.definition];
                if (!obj)
                    obj = this.domains[item.definition] = {};
                obj[item.target()] = item;
            };
            ClientSession.prototype.remove_item_from_index = function (item) {
                var obj = this.domains[item.definition];
                if (obj)
                    delete obj[item.target()];
            };
            ClientSession.prototype.get_lvals_for_indexdomain = function (indexdomain) {
                var obj = this.properties[indexdomain];
                if (obj)
                    return TDev.Util.values(obj);
                else
                    return [];
            };
            ClientSession.prototype.add_lval_to_index = function (lval) {
                var obj = this.properties[lval.indexdomain];
                if (!obj)
                    obj = this.properties[lval.indexdomain] = {};
                obj[lval.target()] = lval;
            };
            ClientSession.prototype.remove_lval_from_index = function (lval) {
                var obj = this.properties[lval.indexdomain];
                if (obj)
                    delete obj[lval.target()];
            };
            ClientSession.prototype.user_unlink = function () {
                for (var p in this.data) {
                    var o = this.data[p];
                    if (o.backlink) {
                        o.backlink.unlink();
                        o.backlink = undefined;
                    }
                }
            };
            ClientSession.prototype.checkinvariants = function () {
                var _this = this;
                return;
                this.all_layers().forEach(function (l) {
                    l.data.forEach(function (d) {
                        TDev.Util.assert(_this.get_datum(d.target()) === d);
                    });
                });
            };
            ClientSession.prototype.user_dump_stable_data = function (assert) {
                var _this = this;
                var result = new Array();
                assert(this.loaded);
                this.checkinvariants();
                var count1 = 0;
                for (var x in TDev.Util.values(this.data)) {
                    if (x instanceof Datum) {
                        var ops = x.all_ops();
                        if (ops.length !== 0) {
                            assert(ops.length === 1);
                            assert(ops[0] === "B");
                            count1 += 1;
                        }
                    }
                }
                var basedata = this.get_layer("B").data;
                var count2 = 0;
                basedata.forEach(function (d) {
                    var op = d.getOperation("B");
                    var p;
                    if (op !== undefined) {
                        if (d instanceof Item) {
                            if (op[0] === "C")
                                p = Packet.MakeNewPacket(d.definition, d.uid, d.ukeys, d.lkeys, (op.length === 1) ? undefined : Number(op.substr(1)));
                            else {
                                TDev.Util.assert(op === "D");
                                p = Packet.MakeDelPacket(d.uid);
                            }
                        }
                        else if (d instanceof LVal && (op !== undefined)) {
                            p = Packet.MakeModPacket(d.definition, op, d.ukeys, d.lkeys, _this.astencoding);
                        }
                        result.push(p.toString());
                        count2 += 1;
                    }
                });
                assert(count1 === count2);
                return result;
            };
            ClientSession.prototype.initialize_data = function () {
                this.data = {};
                this.domains = {};
                this.properties = {};
                this.layers = {
                    "B": new Layer(this, "B", new Array(), 0, 0, true)
                };
            };
            ClientSession.prototype.create_layer = function (name, clientround, serverround) {
                TDev.Util.assert(!this.layers[name]);
                var l = new Layer(this, name, new Array(), clientround, serverround, false);
                this.layers[name] = l;
                if (clientround === 1 && serverround === undefined && this.servername === "")
                    l.grounded = true;
                return l;
            };
            ClientSession.prototype.get_layer = function (s) {
                return this.layers[s];
            };
            ClientSession.prototype.collapse_layers = function (firstname, secondname, keepsecond) {
                var _this = this;
                var first = this.layers[firstname];
                var second = this.layers[secondname];
                TDev.Util.assert(first && second);
                var changed = false;
                var observable = (firstname === "B" && secondname === "S");
                if (second.grounded) {
                    changed = first.clear();
                    if (observable)
                        first.invalidate_all();
                }
                if ((first.serverround === undefined) || first.serverround < second.serverround) {
                    changed = true;
                    first.serverround = second.serverround;
                }
                if ((first.clientround === undefined) || first.clientround < second.clientround) {
                    changed = true;
                    first.clientround = second.clientround;
                }
                second.data.forEach(function (d) {
                    var secondop = d.getOperation(second.name);
                    if (!keepsecond) {
                        d.removeOperation(second);
                    }
                    if (d.recordOperation(first, secondop)) {
                        changed = true;
                        if (observable) {
                            if (d instanceof Item) {
                                var item = d;
                                d.invalidate(secondop === "D");
                                if (secondop && secondop[0] === "C")
                                    _this.add_item_to_index(item);
                            }
                            else {
                                TDev.Util.assert(d instanceof LVal);
                                d.invalidate(false);
                                if (secondop !== undefined)
                                    _this.add_lval_to_index(d);
                            }
                        }
                    }
                });
                if (second.grounded)
                    first.grounded = true;
                if (!keepsecond) {
                    delete this.layers[second.name];
                }
                return changed;
            };
            ClientSession.prototype.delete_layer = function (s, assertexists) {
                var l = this.layers[s];
                if (assertexists)
                    TDev.Util.assert(l);
                else if (l === undefined)
                    return false;
                var changes = l.clear();
                delete this.layers[s];
                return changes;
            };
            ClientSession.prototype.all_layers = function () {
                return TDev.Util.values(this.layers);
            };
            ClientSession.prototype.logLayers = function () {
                var layers = this.all_layers();
                for (var i = 0; i < layers.length; i++) {
                    var layer = layers[i];
                    this.log(TDev.Util.fmt("Layer {0} (s:{1}/c:{2})", layer.name, layer.serverround, layer.clientround));
                }
            };
            ClientSession.prototype.unsent_changes = function () {
                var locallayer = this.get_layer("D" + this.localround);
                return locallayer && locallayer.hasData();
            };
            ClientSession.prototype.dependency_is_gone = function (d, layer) {
                var _this = this;
                if (d.ukeys.some(function (uid) { return _this.uid_is_gone(uid, layer); })) {
                    d.removeOperation(layer);
                    return true;
                }
                return false;
            };
            ClientSession.prototype.item_is_gone = function (i, layer) {
                var op = i.getOperation(layer.name);
                if (op === undefined)
                    return true;
                if (op === "D") {
                    i.removeOperation(layer);
                    return true;
                }
                return this.dependency_is_gone(i, layer);
            };
            ClientSession.prototype.uid_is_gone = function (uid, layer) {
                var i = this.get_item(uid);
                if (!i)
                    return true;
                return this.item_is_gone(i, layer);
            };
            ClientSession.prototype.forEachValidDatum = function (layer, fn) {
                var _this = this;
                layer.data.forEach(function (d) {
                    var op = d.getOperation(layer.name);
                    if (op === undefined || (layer.grounded && (d instanceof Item && _this.item_is_gone(d, layer) || _this.dependency_is_gone(d, layer))))
                        return;
                    fn(d, op);
                });
            };
            ClientSession.prototype.EncodeLayer = function (layer, mode, socket) {
                var _this = this;
                var includeCloudEffects = (mode != 2 /* CLIENT_LAYER_TO_SERVER */ && mode != 5 /* SERVER_UPDATES_TO_CLIENT */);
                var withClientRounds = (mode == 3 /* SERVER_BASE_TO_DISK */);
                var packets = new Array();
                var comp = socket && socket.channelCompressor;
                if (layer.grounded) {
                    packets.push(Packet.MakeCldStarPacket(comp));
                }
                layer.data.forEach(function (d) {
                    if (mode == 4 /* SERVER_LAYER_TO_CLIENT */) {
                        if (!socket.keyset.contains_and_clr(d.target()))
                            return;
                    }
                    else if (mode == 5 /* SERVER_UPDATES_TO_CLIENT */) {
                        if (!socket.keyset.is_unsent_and_clr(d.target()))
                            return;
                    }
                    var op = d.getOperation(layer.name);
                    if (op !== undefined) {
                        if (layer.grounded && (d instanceof Item && _this.item_is_gone(d, layer) || _this.dependency_is_gone(d, layer))) {
                        }
                        else {
                            if (d.fromCloudOp && !includeCloudEffects)
                                return;
                            var p;
                            if (d instanceof Item) {
                                if (op[0] === "C") {
                                    p = Packet.MakeNewPacket(d.definition, d.uid, d.ukeys, d.lkeys, (op.length == 1) ? undefined : Number(op.substr(1)), comp);
                                }
                                else {
                                    _this.assertConsistency(op === "D" && !layer.grounded);
                                    p = Packet.MakeDelPacket(d.uid);
                                }
                            }
                            else if (d instanceof LVal) {
                                p = Packet.MakeModPacket(d.definition, op, d.ukeys, d.lkeys, _this.astencoding, comp);
                            }
                            p.fromCloudOp = d.fromCloudOp;
                            packets.push(p);
                        }
                    }
                });
                if (this.sendCloudOperations && layer.cloudOperations !== undefined) {
                    layer.cloudOperations.forEach(function (op) {
                        if (op.optype == 1 /* RPC */ && mode == 0 /* CLIENT_LAYER_TO_DISK */)
                            return;
                        var p = Packet.MakeCopPacket(op.libName + "/" + op.actionName, op.args, op.opid, op.uidcountstart, op.uidcountstop);
                        packets.push(p);
                    });
                }
                packets.push(Packet.MakeFramePacket(layer, withClientRounds));
                return packets;
            };
            ClientSession.MakeModTarget = function (definition, ukeys, lkeys) {
                var s = (definition ? Parser.WriteComboString(definition) : "");
                ukeys.forEach(function (uid) {
                    s = s + "|" + uid;
                });
                lkeys.forEach(function (lit) {
                    s = s + "|+" + Parser.WriteComboString(lit);
                });
                return s;
            };
            ClientSession.ParseModTarget = function (s, datum) {
                var c = (new Parser(s, 0)).ParseComboComponents();
                datum.definition = c[0];
                datum.ukeys = new Array();
                datum.lkeys = new Array();
                for (var i = 2; i < c.length; i++) {
                    var s = c[i];
                    if (s.charAt(0) === "+")
                        datum.lkeys.push(s.slice(1));
                    else
                        datum.ukeys.push(s);
                }
            };
            ClientSession.prototype.isFaulted = function () {
                return this.faulted;
            };
            ClientSession.prototype.isMarooned = function () {
                return this.marooned;
            };
            ClientSession.prototype.isClosed = function () {
                return this.closed;
            };
            ClientSession.prototype.stopAsync = function () {
                return TDev.Promise.as();
            };
            ClientSession.prototype.send_layer = function (layer) {
                var _this = this;
                var packets = this.EncodeLayer(layer, 2 /* CLIENT_LAYER_TO_SERVER */, this.ws);
                this.log(TDev.Util.fmt("Sending {0}[{1},{2}]", layer.name, layer.clientround, layer.serverround));
                packets.forEach(function (p) { return p.send(_this.ws); });
            };
            ClientSession.prototype.getCloudSession = function () {
                if (!this.cachedsession) {
                    var cs = new TDev.RT.CloudSession();
                    cs._id = this.servername;
                    cs._permissions = this.permissions;
                    cs._title = this.title;
                    cs.sessionimpl = this;
                    if (cs.validate())
                        this.cachedsession = cs;
                }
                return this.cachedsession;
            };
            ClientSession.prototype.loadAsync = function (after_load_task) {
                var _this = this;
                TDev.Util.assert(this.loadtask === undefined && !this.loaded);
                if (!this.localname || this.closed)
                    return (after_load_task ? after_load_task() : TDev.Promise.as());
                var promise = this.LoadFromDiskAsync();
                promise = promise.then(function (success) {
                    if (!_this.closed) {
                        _this.intervalhandle = setInterval(function () {
                            if (!_this.closed && !_this.faulted)
                                _this.SaveAndSend();
                        }, _this.sendinterval);
                        var h = _this.intervalhandle;
                        if (h.unref)
                            h.unref();
                    }
                }, function (error) {
                    _this.faulted = true;
                    _this.initialize_data();
                    _this.statuschanges = true;
                    _this.log("failed to load stored session, error=" + error);
                });
                if (after_load_task)
                    promise = promise.thenalways(function () { return after_load_task(); });
                promise.thenalways(this.doorbell);
                return this.loadtask = promise;
            };
            ClientSession.prototype.LoadFromDiskAsync = function () {
                var _this = this;
                return TDev.Storage.getTableAsync("Sessions").then(function (table) {
                    _this.table = table;
                    var keys = [_this.key_Sstate(), _this.key_Cstate(), _this.key_layer("B")];
                    return table.getItemsAsync(keys).then(function (results) {
                        var S = results[keys[0]];
                        var C = results[keys[1]];
                        var B = results[keys[2]];
                        if (!S) {
                            _this.Sstate_needsave = true;
                            _this.loaded = true;
                            _this.statuschanges = true;
                            if (_this.trace_save_and_load)
                                _this.trace_load();
                            return _this.table.getValueAsync(_this.key_sessionlist()).then(function (val) {
                                var kvpairs = {};
                                kvpairs[_this.key_sessionlist()] = (val || "") + _this.localname + " ";
                                return _this.table.setItemsAsync(kvpairs);
                            });
                        }
                        else {
                            _this.S_fromJSONstring(S);
                            if (C)
                                _this.C_fromJSONstring(C);
                            var baselayer = _this.get_layer("B");
                            if (B) {
                                var packets = JSON.parse(B);
                                packets.forEach(function (p) { return _this.ProcessLoadedPacket(p, baselayer); });
                            }
                            keys = new Array();
                            for (var i = baselayer.clientround + 1; i <= _this.localround; i++)
                                keys.push(_this.key_layer("D" + i));
                            return _this.table.getItemsAsync(keys).then(function (result) {
                                keys.forEach(function (k) {
                                    var packetsjson = result[k];
                                    if (packetsjson) {
                                        var packets = JSON.parse(packetsjson);
                                        var datalayer = _this.create_layer(k.substr(k.indexOf("/") + 1));
                                        datalayer.clientround = Number(k.substr(k.indexOf("/") + 2));
                                        packets.forEach(function (p) { return _this.ProcessLoadedPacket(p, datalayer); });
                                    }
                                    else if (k !== _this.key_layer("D" + _this.localround)) {
                                        baselayer.clientround = baselayer.clientround + 1;
                                    }
                                });
                                _this.loaded = true;
                                _this.statuschanges = true;
                                if (_this.trace_save_and_load)
                                    _this.trace_load();
                            });
                        }
                    });
                });
            };
            ClientSession.prototype.trace_load = function () {
                this.log(TDev.Util.fmt("\Loaded S:\n{0}\nLoaded C:{1}\nLoaded Data:\n{2}", this.S_toJSONstring(), this.C_toJSONstring(), this.EncodeLayer(this.get_layer("B"), 6 /* TRACE_LOAD */).map(function (p) { return p.toString(); }).join("\n")));
            };
            ClientSession.prototype.deleteLocalStorageAsync = function () {
                var _this = this;
                var keystodelete = [this.key_Sstate(), this.key_Cstate(), this.key_layer("B")];
                var baselayer = this.get_layer("B");
                for (var i = baselayer.clientround + 1; i <= this.localround; i++)
                    keystodelete.push(this.key_layer("D" + i));
                var kvpairs = [];
                keystodelete.forEach(function (k) { return kvpairs[k] = undefined; });
                return this.table.getValueAsync(this.key_sessionlist()).then(function (val) {
                    var regexp = new RegExp(_this.localname + " ", 'g');
                    kvpairs[_this.key_sessionlist()] = (val || "").replace(regexp, "");
                    return _this.table.setItemsAsync(kvpairs);
                });
            };
            ClientSession.prototype.try_reconnect_in = function (msec) {
                var _this = this;
                var curws = this.ws;
                var currentTime = new Date();
                this.nexttry = currentTime.getTime() + msec;
                this.statuschanges = true;
                this.retrypending = curws;
                TDev.Util.setTimeout(msec, function () { return _this.user_retry_now(); });
            };
            ClientSession.prototype.user_retry_now = function () {
                if (this.retrypending === this.ws) {
                    this.retrypending = undefined;
                    this.connect(this.url, this.tokensource);
                }
            };
            ClientSession.prototype.connect = function (url, tokensource) {
                var _this = this;
                this.url = url;
                this.tokensource = tokensource;
                TDev.Util.assert(this.servername !== "");
                if (this.enable_sync === undefined) {
                    this.enable_sync = true;
                }
                if (TDev.Cloud.isOffline()) {
                    this.try_reconnect_in(this.connectionretrydelay);
                    return;
                }
                if (!this.enable_sync || this.marooned || this.closed || this.faulted)
                    return;
                var need_fresh_token = this.encountered_token_expiration;
                this.delete_layer("R", false);
                this.delete_layer("S", false);
                this.receivedstatus = false;
                this.last_serverround_received = undefined;
                this.last_clientround_received = undefined;
                this.last_serverround_sent = undefined;
                this.last_clientround_sent = undefined;
                this.encountered_token_expiration = undefined;
                var gotconnection = false;
                this.tokenpromise = this.tokensource(need_fresh_token);
                var ws = new WebSocket(url);
                this.log("connecting to " + url);
                this.ws = ws;
                this.nexttry = 0;
                if (this.dochannelcompression)
                    this.ws.channelCompressor = new ChannelCompressor();
                this.ws.onmessage = function (e) {
                    if (_this.ws !== ws)
                        return;
                    if (_this.trace_incoming_packets)
                        _this.log("receive: " + e.data.replace(/\n/g, " ").substr(0, 300));
                    _this.ReceivePacket(Packet.ParsePacket(e.data, _this.ws));
                };
                this.ws.onopen = function () {
                    if (_this.ws !== ws)
                        return;
                    _this.log("connected to " + url);
                    gotconnection = true;
                    _this.nexttry = undefined;
                    _this.tokenpromise.then(function (token) {
                        if (_this.ws !== ws)
                            return;
                        _this.SendStatusPacket(token);
                    }, function (err) {
                        _this.log("could not get authentication token");
                        if (_this.ws !== ws)
                            return;
                        _this.errorcategory = "offline";
                        _this.error = "could not get authentication token from server";
                        _this.disconnect();
                        _this.try_reconnect_in(_this.connectionretrydelay);
                    }).then(function () {
                        _this.doorbell();
                    });
                };
                this.ws.onclose = function (c) {
                    var retryspeed = 1;
                    if (_this.ws !== ws)
                        return;
                    _this.log("disconnected, code=" + c.code + ", reason=" + c.reason);
                    if (c.code === 1011 || c.code === 1005 || c.code === 1000) {
                        if (c.reason.indexOf("switched server") !== -1 || c.reason.indexOf("member not found") !== -1 || c.reason.indexOf("session salt mismatch") !== -1) {
                            _this.marooned = true;
                        }
                        else if (c.reason.indexOf("connection reset") !== -1) {
                            _this.errorcategory = "connecting";
                            _this.error = "refreshing base value";
                            _this.rebase = true;
                            retryspeed = 10;
                        }
                        else if (c.reason.indexOf("cannot create session") !== -1) {
                            if (_this.membernumber !== -1) {
                                _this.marooned = true;
                            }
                            else if (_this.servername.lastIndexOf(_this.user, 0) !== 0) {
                                _this.errorcategory = "not found";
                                _this.error = "possible causes: spelling error in session id, the owner has not connected to this session yet, the session has been deleted";
                                retryspeed = 2;
                            }
                            else {
                                _this.errorcategory = "not found";
                                _this.error = "cannot create session on server" + c.reason.substr(21);
                                retryspeed = 1;
                            }
                        }
                        else if (c.reason.indexOf("Cannot reconnect: member still connected on existing socket") !== -1) {
                            _this.errorcategory = "connecting";
                            _this.error = "cleaning up old connection";
                            retryspeed = 7;
                        }
                        else if (c.reason.indexOf("access denied: readonly.") !== -1) {
                            _this.errorcategory = "connecting";
                            _this.error = "reconnecting as readonly";
                            _this.readonly = true;
                            retryspeed = 10;
                        }
                        else if (c.reason.indexOf("access denied: ") !== -1) {
                            _this.error = c.reason.substr(15);
                            if (c.reason.indexOf("old script version") !== -1 || c.reason.indexOf("outdated script, must update first") !== -1) {
                                _this.errorcategory = "need update";
                                retryspeed = 0.01;
                            }
                            else
                                _this.errorcategory = "access denied";
                        }
                        else if (c.reason.indexOf("Token Expired") !== -1) {
                            _this.errorcategory = "connecting";
                            _this.error = c.reason;
                            _this.encountered_token_expiration = true;
                            retryspeed = 10;
                        }
                        else if (c.reason.indexOf("failed to migrate session") !== -1 || c.reason.indexOf("Migrating session to new script version") !== -1) {
                            _this.errorcategory = "transitioning";
                            _this.error = "server is migrating session to newer script version";
                            retryspeed = 10;
                        }
                        else if (c.reason.indexOf("reset") !== -1) {
                            _this.errorcategory = "transitioning";
                            _this.error = c.reason;
                            retryspeed = 10;
                        }
                        else if (c.reason.indexOf("server: ") !== -1) {
                            _this.errorcategory = "transitioning";
                            _this.error = c.reason;
                        }
                        else {
                            _this.errorcategory = "not working";
                            _this.error = "server error: " + c.reason;
                        }
                    }
                    else if (c.code === 1006) {
                        _this.errorcategory = "offline";
                        _this.error = gotconnection ? "lost connection to server" : "could not connect to server";
                        retryspeed = gotconnection ? 10 : 1;
                    }
                    else {
                        _this.errorcategory = "not working";
                        _this.error = "websocket error " + c.code + " clean=" + c.wasClean + " reason=" + c.reason;
                    }
                    _this.try_reconnect_in(_this.connectionretrydelay / retryspeed);
                    _this.presence = [];
                    _this.statuschanges = true;
                    _this.doorbell();
                };
            };
            ClientSession.prototype.disconnect = function () {
                var curws = this.ws;
                if (curws !== undefined) {
                    this.ws = undefined;
                    this.nexttry = undefined;
                    curws.close();
                    this.statuschanges = true;
                }
            };
            ClientSession.prototype.finishPendingOperationsAsync = function () {
                var _this = this;
                if (!this.localname || !this.loadtask)
                    return TDev.Promise.as();
                if (this.closetask)
                    return this.closetask;
                return this.loadtask.then(function () { return TDev.Promise.join([
                    _this.last_C_save.then(function (saveok) {
                        _this.SaveAndSend();
                        return _this.last_C_save;
                    }, function (savefailure) {
                        _this.faulted = true;
                        TDev.Util.oops("session save failed... local storage full?");
                    }),
                    _this.last_S_save.then(function (saveok) {
                        _this.MergeAndSaveSB();
                        return _this.last_S_save;
                    }, function (savefailure) {
                        _this.faulted = true;
                        TDev.Util.oops("session save failed... local storage full?");
                    })
                ]); });
            };
            ClientSession.prototype.closeAsync = function (deletelocalstorage) {
                var _this = this;
                this.closed = true;
                var loadfirst = this.loadtask;
                if (this.intervalhandle)
                    clearInterval(this.intervalhandle);
                this.disconnect();
                this.user_unlink();
                if (!loadfirst) {
                    if (deletelocalstorage)
                        return this.closetask = this.deleteLocalStorageAsync();
                    else
                        return this.closetask = TDev.Promise.as();
                }
                if (!(this.localname && deletelocalstorage)) {
                    return this.closetask = loadfirst.then(function () { return _this.finishPendingOperationsAsync(); });
                }
                else {
                    return this.closetask = loadfirst.then(function () { return TDev.Promise.join([_this.last_C_save, _this.last_S_save]).then(function () {
                        return _this.deleteLocalStorageAsync();
                    }); });
                }
            };
            ClientSession.prototype.MergeAndSaveSB = function () {
                var _this = this;
                TDev.Util.assert(this.loaded);
                if (this.faulted)
                    return false;
                var save = false;
                var visiblechanges = false;
                var statuschanges = false;
                var changes = {};
                var layers_to_delete = new Array();
                var serverlayer = this.get_layer("S");
                if (serverlayer) {
                    var newround = serverlayer.clientround;
                    for (var i = newround + 1; i <= this.localround; i++) {
                        var unconfirmedlayer = this.get_layer("D" + i);
                        if (unconfirmedlayer && unconfirmedlayer.grounded)
                            serverlayer.invalidate_all();
                    }
                    if (!this.readblock) {
                        var oldbaseround = this.get_layer("B").clientround;
                        visiblechanges = this.collapse_layers("B", "S");
                        statuschanges = (newround === this.localround - 1);
                        this.get_layer("B").cleanIfNeeded(this.scrublimit);
                        for (var i = oldbaseround + 1; i <= newround; i++) {
                            var datalayer = "D" + i;
                            this.delete_layer(datalayer, true);
                            if (this.localname) {
                                changes[this.key_layer(datalayer)] = undefined;
                                save = true;
                            }
                        }
                    }
                    else {
                        if (serverlayer.serverround >= this.readblock) {
                            serverlayer.grounded = true;
                            this.collapse_layers("B", "S");
                            var oldbaseround = this.get_layer("B").clientround;
                            var newround = serverlayer.clientround;
                            visiblechanges = true;
                            statuschanges = true;
                            for (var i = oldbaseround + 1; i <= newround; i++) {
                                var datalayer = "D" + i;
                                this.delete_layer(datalayer, true);
                                if (this.localname) {
                                    changes[this.key_layer(datalayer)] = undefined;
                                    save = true;
                                }
                            }
                            this.readblock = undefined;
                        }
                    }
                }
                if (this.localname && !this.faulted) {
                    var packets;
                    var baselayer;
                    if (visiblechanges) {
                        changes[this.key_layer("B")] = JSON.stringify(packets = this.EncodeLayer(baselayer = this.get_layer("B"), 1 /* CLIENT_BASE_TO_DISK */));
                        save = true;
                    }
                    if (this.Sstate_needsave) {
                        save = true;
                        this.Sstate_needsave = false;
                    }
                    if (save) {
                        changes[this.key_Sstate()] = this.S_toJSONstring();
                        var savemsg = "(" + (packets ? ("B[" + baselayer.clientround + "," + baselayer.serverround + "]: " + packets.length + " pkts") : "status only") + ")";
                        if (this.trace_saving)
                            this.log("saving merged data " + savemsg);
                        if (this.trace_save_and_load)
                            this.log(TDev.Util.fmt("\nSaving S:\n{0}\nSaving B:\n{1}", changes[this.key_Sstate()], packets ? packets.map(function (p) { return p.toString(); }).join("\n") : "none"));
                        this.last_S_save = this.table.setItemsAsync(changes).then(function (saveok) {
                            if (_this.trace_saving)
                                _this.log("saved merged data " + savemsg);
                            if (_this.ring_doorbell_when_done) {
                                _this.ring_doorbell_when_done = false;
                                _this.last_S_save = TDev.Promise.as();
                                _this.doorbell();
                            }
                        }, function (savefailure) {
                            _this.log("!! failure while saving data " + savemsg);
                            TDev.Util.oops("save failed... local storage full?");
                        });
                    }
                }
                return visiblechanges || statuschanges;
            };
            ClientSession.prototype.SaveAndSend = function () {
                var _this = this;
                TDev.Util.assert(this.loaded);
                if (this.last_C_save._state === 0 /* Pending */)
                    return this.last_C_save;
                if (this.ShouldSend()) {
                    var oldlayer = this.get_layer("D" + this.localround);
                    if (!oldlayer)
                        oldlayer = this.create_layer("D" + this.localround, this.localround);
                    var baselayer = this.get_layer("B");
                    this.localround += 1;
                    var newlayer = this.create_layer("D" + this.localround, this.localround);
                    TDev.Util.check(baselayer.serverround !== undefined, "undefined serverround on baselayer");
                    var serverround = oldlayer.serverround = baselayer.serverround;
                    var clientround = oldlayer.clientround;
                    if (!this.localname) {
                        this.send_layer(oldlayer);
                        return TDev.Promise.as();
                    }
                    else {
                        var curws = this.ws;
                        return this.SaveToDiskAsync([oldlayer, newlayer]).then(function () {
                            if (_this.ws === curws)
                                _this.send_layer(oldlayer);
                        });
                    }
                    this.CLstate_needsave = false;
                }
                else if (this.localname && this.CLstate_needsave) {
                    var locallayer = this.get_layer("D" + this.localround);
                    if (!locallayer)
                        locallayer = this.create_layer("D" + this.localround, this.localround);
                    var promise = this.SaveToDiskAsync([locallayer]);
                    this.CLstate_needsave = false;
                    return promise;
                }
            };
            ClientSession.prototype.cleanOutstandingLayers = function () {
                var blayer = this.get_layer("B");
                var deleted = [];
                for (var i = blayer.clientround + 1; i <= this.localround; i++) {
                    this.delete_layer("D" + i, true);
                    deleted.push("D" + i);
                }
                this.localround = blayer.clientround + 1;
                return deleted;
            };
            ClientSession.prototype.RemoveFromDiskAsync = function (layers) {
                var _this = this;
                var kvpairs = {};
                kvpairs[this.key_Cstate()] = this.C_toJSONstring();
                kvpairs[this.key_Sstate()] = this.S_toJSONstring();
                layers.forEach(function (l) { return kvpairs[_this.key_layer(l)] = undefined; });
                return this.table.setItemsAsync(kvpairs);
            };
            ClientSession.prototype.SaveToDiskAsync = function (layers) {
                var _this = this;
                if (this.faulted)
                    return TDev.Promise.as();
                var kvpairs = {};
                kvpairs[this.key_Cstate()] = this.C_toJSONstring();
                layers.forEach(function (l) {
                    var p = _this.EncodeLayer(l, 0 /* CLIENT_LAYER_TO_DISK */);
                    kvpairs[_this.key_layer(l.name)] = JSON.stringify(p);
                });
                var currentws = this.ws;
                var savemsg = "(" + layers.map(function (l) { return (l.name + "[" + l.clientround + ", " + l.serverround + "]"); }).join("/") + ")";
                if (this.trace_saving)
                    this.log("saving data " + savemsg);
                this.last_C_save = this.table.setItemsAsync(kvpairs).then(function (saveok) {
                    if (_this.ws === currentws)
                        return TDev.Promise.as(currentws);
                    if (_this.trace_saving)
                        _this.log("saved data " + savemsg);
                }, function (savefailure) {
                    _this.log("!! failure while saving data " + savemsg);
                    TDev.Util.oops("save failed... local storage full?");
                    _this.faulted = true;
                });
                return this.last_C_save;
            };
            ClientSession.prototype.ShouldSend = function () {
                var _this = this;
                if (this.faulted)
                    return false;
                if (this.ws === undefined || this.ws.readyState != WebSocket.OPEN || !this.receivedstatus)
                    return false;
                if (this.readonly || this.ws.bufferedAmount != 0)
                    return false;
                var baselayer = this.get_layer("B");
                if (this.writeblock !== undefined) {
                    if (baselayer.serverround < this.writeblock)
                        return false;
                    this.writeblock = undefined;
                    this.statuschanges = true;
                    var newround = this.localround;
                    for (var i = baselayer.clientround + 1; i < newround; i++) {
                        this.send_layer(this.get_layer("D" + i));
                    }
                }
                if (this.localround - baselayer.clientround > this.pendingroundlimit)
                    return false;
                if (!this.unsent_changes() && !this.fences.some(function (f) { return (_this.localround === f.round); }))
                    return false;
                return true;
            };
            ClientSession.prototype.user_issue_fence = function (continuation, exclusive) {
                this.fences.push(new Fence(continuation, this.loaded ? this.localround : 0, exclusive));
                this.user_yield();
            };
            ClientSession.prototype.user_set_doorbell = function (doorbell) {
                this.doorbell = doorbell;
            };
            ClientSession.prototype.user_enable_sync = function (enable) {
                if (enable !== this.enable_sync) {
                    this.enable_sync = enable;
                    if (enable)
                        this.try_reconnect_in(500);
                    else
                        this.disconnect();
                    this.Sstate_needsave = true;
                    this.statuschanges = true;
                    this.doorbell();
                }
            };
            ClientSession.prototype.user_sync_enabled = function () {
                return (this.enable_sync === undefined || this.enable_sync);
            };
            ClientSession.prototype.user_get_next_connection_attempt = function () {
                return (this.marooned || this.closed || this.faulted) ? undefined : this.nexttry;
            };
            ClientSession.prototype.user_get_missing_rounds = function () {
                if (!this.faulted && this.loaded && !this.marooned && !this.closed && this.ws && this.ws.readyState === WebSocket.OPEN && this.receivedstatus) {
                    var baselayer = this.get_layer("B");
                    if (this.readblock)
                        return this.readblock - (this.get_layer("S") ? this.get_layer("S").serverround : 0);
                    else if (this.writeblock)
                        return this.writeblock - baselayer.serverround;
                    else if (this.localround - 1 > baselayer.clientround)
                        return (this.localround - 1 - baselayer.clientround);
                    else if (this.previewround > baselayer.serverround)
                        return (this.previewround - baselayer.serverround);
                    else
                        return this.NumberWaitingRpcs();
                }
                else
                    return 0;
            };
            ClientSession.prototype.user_is_websocket_open = function () {
                return this.ws && this.ws.readyState === WebSocket.OPEN;
            };
            ClientSession.prototype.user_get_percent_full = function () {
                return (this.receivedserverinfo && this.percentfull) || 0;
            };
            ClientSession.prototype.user_get_presence = function () {
                if (!this.presence && this.membernumber !== -1)
                    return [{ userId: this.user, sessionId: this.membernumber }];
                else
                    return this.presence;
            };
            ClientSession.prototype.user_get_connectionstatus = function (include_details) {
                var status = this.user_get_connectionstatus_full();
                if (include_details)
                    return status.status + " (" + status.description + ")";
                else
                    return status.status;
            };
            ClientSession.prototype.user_get_connectionstatus_full = function () {
                var retrymsg = "";
                if (this.faulted) {
                    return {
                        type: 0 /* Error */,
                        status: TDev.lf("not working"),
                        description: TDev.lf("local cache corrupted or storage full")
                    };
                }
                else if (!this.loaded) {
                    return {
                        type: 2 /* Ok */,
                        status: TDev.lf("loading"),
                        description: TDev.lf("retrieving state from local storage")
                    };
                }
                else if (this.marooned) {
                    return {
                        type: 0 /* Error */,
                        status: TDev.lf("isolated"),
                        description: TDev.lf("cloud session was deleted on server")
                    };
                }
                else if (this.closed) {
                    return {
                        type: 0 /* Error */,
                        status: TDev.lf("closed"),
                        description: ""
                    };
                }
                else if (this.ws === undefined) {
                    if (this.enable_sync === false)
                        return {
                            type: 1 /* Warning */,
                            status: TDev.lf("disabled"),
                            description: TDev.lf("sync was disabled on purpose")
                        };
                    else if (TDev.Cloud.isOffline())
                        return {
                            type: 1 /* Warning */,
                            status: TDev.lf("offline"),
                            description: TDev.lf("touch develop is in offline mode{0}", retrymsg)
                        };
                    else {
                        return {
                            type: 0 /* Error */,
                            status: TDev.lf("offline"),
                            description: retrymsg
                        };
                    }
                }
                else if (this.ws.readyState === WebSocket.CONNECTING) {
                    return {
                        type: 1 /* Warning */,
                        status: TDev.lf("connecting"),
                        description: TDev.lf("trying to contact server")
                    };
                }
                else if (this.ws.readyState === WebSocket.OPEN) {
                    var baselayer = this.get_layer("B");
                    if (!this.receivedstatus)
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connecting"),
                            description: TDev.lf("waiting for server connection")
                        };
                    else if (this.readblock)
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connecting"),
                            description: TDev.lf("receiving server data")
                        };
                    else if (this.writeblock)
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connecting"),
                            description: TDev.lf("checking changes on server")
                        };
                    else if (this.localround - 1 > baselayer.clientround)
                        return {
                            type: 2 /* Ok */,
                            status: "connected",
                            description: this.NumberWaitingRpcs() ? TDev.lf(" waiting for server") : TDev.lf(" sending changes")
                        };
                    else if (this.previewround > baselayer.serverround)
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connected"),
                            description: TDev.lf("receiving changes")
                        };
                    else if (this.unsent_changes() || this.get_layer("T"))
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connected"),
                            description: TDev.lf("local changes pending")
                        };
                    else if (this.NumberWaitingRpcs())
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connected"),
                            description: TDev.lf("waiting for server")
                        };
                    else
                        return {
                            type: 2 /* Ok */,
                            status: TDev.lf("connected"),
                            description: ""
                        };
                }
                else
                    return {
                        type: 0 /* Error */,
                        status: this.errorcategory,
                        description: (this.error) ? this.error + retrymsg : ""
                    };
            };
            ClientSession.prototype.NumberWaitingRpcs = function () {
                return 0;
            };
            ClientSession.prototype.user_set_userdata = function (key, val, equals) {
                if (equals === undefined || !equals(this.userdata[key], val)) {
                    this.userdata[key] = val;
                    this.Sstate_needsave = true;
                }
            };
            ClientSession.prototype.user_get_userdata = function (key) {
                return this.userdata[key];
            };
            ClientSession.prototype.user_push = function () {
                if (!this.loaded)
                    return;
                this.checkinvariants();
                var locallayer = this.get_layer("D" + this.localround);
                if (!locallayer)
                    locallayer = this.create_layer("D" + this.localround, this.localround);
                var transactionlayer = this.get_layer("T");
                if (transactionlayer) {
                    var changed = this.collapse_layers(locallayer.name, "T");
                    locallayer.cleanIfNeeded(this.scrublimit);
                    this.CLstate_needsave = this.CLstate_needsave || changed;
                }
                this.SaveAndSend();
                this.checkinvariants();
            };
            ClientSession.prototype.user_yield = function () {
                if (!this.loaded)
                    return;
                this.checkinvariants();
                var statuschanges = this.statuschanges;
                this.statuschanges = false;
                var locallayer = this.get_layer("D" + this.localround);
                if (!locallayer)
                    locallayer = this.create_layer("D" + this.localround, this.localround);
                var transactionlayer = this.get_layer("T");
                if (transactionlayer) {
                    var changed = this.collapse_layers(locallayer.name, "T");
                    locallayer.cleanIfNeeded(this.scrublimit);
                    this.CLstate_needsave = this.CLstate_needsave || changed;
                }
                if (this.last_S_save._state === 0 /* Pending */) {
                    this.ring_doorbell_when_done = true;
                    return false;
                }
                var datachanges = this.MergeAndSaveSB();
                this.SaveAndSend();
                this.checkinvariants();
                if (this.fences.length > 0) {
                    var round = this.get_layer("B").clientround;
                    this.fences = this.fences.filter(function (f) {
                        if (round < f.round)
                            return true;
                        f.continuation();
                        return false;
                    });
                }
                return datachanges || statuschanges;
            };
            ClientSession.prototype.protocolversion = function () {
                return "3.0";
            };
            ClientSession.prototype.SendStatusPacket = function (token) {
                var baselayer = this.get_layer("B");
                var keystring = "";
                if (this.includeKeysInStatus) {
                    var keys = [];
                    this.forEachValidDatum(baselayer, function (datum) { return keys.push(datum.target()); });
                    keystring = keys.join("?").replace("|", "/");
                }
                var p = Packet.MakeStatusPacket(this.protocolversion() + (this.dochannelcompression ? "C" : "") + (this.readonly ? "R" : ""), this.servername, this.membernumber.toString(), this.user, this.title, this.disambiguator, baselayer.clientround.toString(), this.rebase ? "0" : baselayer.serverround.toString(), token, this.script, this.permissions, keystring);
                this.rebase = false;
                this.assertConsistency(this.receivedstatus === false);
                this.assertConsistency(this.last_serverround_sent === undefined);
                this.assertConsistency(this.last_serverround_received === undefined);
                this.assertConsistency(this.last_clientround_sent === undefined);
                this.assertConsistency(this.last_clientround_received === undefined);
                p.send(this.ws);
            };
            ClientSession.prototype.ReceivePacket = function (p) {
                if (p.code === "sts") {
                    this.ReceiveStatusPacket(p);
                    this.doorbell();
                }
                else if (p.code === "inf") {
                    this.ReceiveInfoPacket(p);
                    this.doorbell();
                }
                else if (p.code === "frm") {
                    this.ReceiveFramePacket(p);
                    this.doorbell();
                }
                else {
                    var receivelayer = this.get_layer("R") || this.create_layer("R");
                    if (p.code === "new") {
                        p.serveritemcount = this.serveritemcount;
                        this.serveritemcount += 1;
                        this.ProcessNewPacket(p, receivelayer, this.ws.channelCompressor);
                    }
                    else if (p.code === "del") {
                        this.ProcessDelPacket(p, receivelayer);
                    }
                    else if (p.code === "cld") {
                        if (this.ws.channelCompressor)
                            p.definition = this.ws.channelCompressor.InBound(p.definition, p.lkeys);
                        if (p.definition === "*")
                            this.ProcessClearRootPacket(p, receivelayer);
                    }
                    else if (p.code === "clp") {
                        if (this.ws.channelCompressor)
                            p.definition = this.ws.channelCompressor.InBound(p.definition, p.lkeys);
                    }
                    else {
                        TDev.Util.assert(p.code === "mod");
                        this.ProcessModPacket(p, receivelayer, this.ws.channelCompressor);
                    }
                }
            };
            ClientSession.prototype.ProcessLoadedPacket = function (p, l) {
                if (typeof p === "string")
                    p = Packet.ParsePacket(p, this.ws, true);
                if (p.code === "new") {
                    var item = this.ProcessNewPacket(p, l);
                    this.add_item_to_index(item);
                }
                else if (p.code === "del") {
                    var item = this.ProcessDelPacket(p, l);
                    if (item)
                        item.invalidate(true);
                }
                else if (p.code === "mod") {
                    var lval = this.ProcessModPacket(p, l);
                    this.add_lval_to_index(lval);
                }
                else if (p.code === "cld" && p.definition === "*") {
                    this.ProcessClearRootPacket(p, l);
                    if (l.name != "B") {
                        var baselayer = this.get_layer("B");
                        baselayer.invalidate_all();
                        var baseround = baselayer.clientround;
                        var localround = this.localround;
                        for (var i = baselayer.clientround + 1; i < l.clientround; i++) {
                            var datalayer = this.get_layer("D" + i);
                            datalayer && datalayer.invalidate_all();
                        }
                    }
                }
                else if (p.code === "cop") {
                    var json = JSON.parse(p.lkeys[0]);
                    var libName = json.path.split("/")[0];
                    var actionName = json.path.split("/")[1];
                    var cop = {
                        libName: libName,
                        actionName: actionName,
                        paramNames: Object.keys(json.params),
                        returnNames: json.returnNames,
                        args: json.params,
                        opid: json.opid === undefined ? undefined : Number(json.opid),
                        uidcountstart: json.uidcountstart === undefined ? undefined : Number(json.uidcountstart),
                        uidcountstop: json.uidcountstop === undefined ? undefined : Number(json.uidcountstop),
                        optype: json.optype || 0 /* UNKNOWN */
                    };
                    l.CommitCloudOperation(cop);
                }
                else {
                    TDev.Util.assert(p.code === "frm");
                    this.ProcessFramePacket(p, l);
                }
            };
            ClientSession.prototype.ReceiveInfoPacket = function (p) {
                this.receivedserverinfo = true;
                this.previewround = Number(p.lkeys[0]);
                this.percentfull = Number(p.lkeys[1]);
                var userIds = p.lkeys[2].split(",");
                var sessionIds = p.lkeys[3].split(",");
                TDev.Util.assert(userIds.length == sessionIds.length);
                this.presence = userIds.map(function (userId, i) { return ({ userId: userId, sessionId: parseInt(sessionIds[i]) }); });
                this.statuschanges = true;
            };
            ClientSession.prototype.ReceiveStatusPacket = function (p) {
                var version = p.lkeys[0];
                var servername = p.lkeys[1];
                var membernumber = Number(p.lkeys[2]);
                var user = p.lkeys[3];
                var description = p.lkeys[4];
                var disambiguator = p.lkeys[5];
                var curserverround = Number(p.lkeys[6]);
                var serverround = Number(p.lkeys[7]);
                var token = p.lkeys[8];
                var script = p.lkeys[9];
                var permissions = p.lkeys[10];
                var clientUserId = p.lkeys[11];
                this.clientUserId = clientUserId;
                if (description)
                    this.title = description;
                this.disambiguator = disambiguator;
                this.permissions = permissions;
                this.statusPacket = p;
                this.previewround = curserverround;
                TDev.Util.assert(version === this.protocolversion());
                TDev.Util.assert(servername === this.servername);
                TDev.Util.assert(this.membernumber === -1 || this.membernumber === membernumber);
                TDev.Util.assert(membernumber > 0);
                this.membernumber = membernumber;
                TDev.Util.assert(user === this.user);
                var baselayer = this.get_layer("B");
                this.assertConsistency(serverround === baselayer.serverround || serverround === 0);
                this.assertConsistency(curserverround >= baselayer.serverround);
                var rebase = (this.receivedstatus);
                this.receivedstatus = true;
                if (rebase) {
                    this.delete_layer("R", false);
                    this.delete_layer("S", false);
                }
                else {
                    this.assertConsistency(this.last_clientround_received === undefined);
                }
                this.last_serverround_received = serverround;
                this.last_clientround_received = 0;
                if (rebase || (serverround < baselayer.serverround))
                    this.readblock = curserverround;
                if (!rebase && (baselayer.clientround < this.localround - 1))
                    this.writeblock = curserverround;
                this.statuschanges = true;
                this.Sstate_needsave = true;
            };
            ClientSession.prototype.ReceiveFramePacket = function (p) {
                var clientround = Number(p.lkeys[0]);
                var serverround = Number(p.lkeys[1]);
                this.assertConsistency(this.receivedstatus);
                this.assertConsistency(serverround > this.last_serverround_received || this.acceptsUpdates);
                this.assertConsistency(clientround >= this.last_clientround_received);
                this.assertConsistency((!this.last_serverround_sent) || serverround > this.last_serverround_sent || this.acceptsUpdates);
                this.assertConsistency((!this.last_clientround_sent) || clientround <= this.last_clientround_sent);
                this.last_clientround_received = clientround;
                this.last_serverround_received = serverround;
                var baselayer = this.get_layer("B");
                this.assertConsistency(serverround >= baselayer.serverround || this.acceptsUpdates);
                this.assertConsistency(clientround >= baselayer.clientround);
                var serverlayer = this.get_layer("S") || this.create_layer("S", clientround, serverround);
                this.assertConsistency(serverround >= serverlayer.serverround || this.acceptsUpdates);
                this.assertConsistency(clientround >= serverlayer.clientround);
                var receivelayer = this.get_layer("R");
                if (receivelayer)
                    this.collapse_layers("S", "R");
                this.get_layer("S").cleanIfNeeded(this.scrublimit);
                serverlayer.serverround = serverround;
                serverlayer.clientround = clientround;
                if (this.fences.some(function (f) { return f.exclusive; })) {
                    this.user_yield();
                }
            };
            ClientSession.prototype.ProcessFramePacket = function (p, layer) {
                layer.clientround = Number(p.lkeys[0]);
                layer.serverround = p.lkeys[1] == "" ? undefined : Number(p.lkeys[1]);
                if (p.lkeys[2]) {
                    var x = layer.clientrounds = {};
                    p.lkeys[2].split(",").forEach(function (s) {
                        var pair = s.split(":");
                        x[Number(pair[0])] = Number(pair[1]);
                    });
                }
            };
            ClientSession.prototype.ProcessNewPacket = function (p, layer, comp) {
                var uid = p.ukeys.shift();
                var ukeys = p.ukeys;
                var lkeys = p.lkeys;
                var fromCloudOp = p.fromCloudOp;
                var definition = comp ? comp.InBound(p.definition, lkeys) : p.definition;
                var entry = this.get_item(uid);
                if (!entry) {
                    entry = new Item();
                    entry.session = this;
                    entry.definition = definition;
                    entry.uid = uid;
                    entry.ukeys = ukeys;
                    entry.lkeys = lkeys;
                    entry.linkDeps();
                    entry.fromCloudOp = fromCloudOp;
                    this.add_item(entry);
                }
                else {
                    this.assertConsistency(entry.uid === uid);
                    this.assertConsistency(entry.definition === definition);
                    this.assertConsistency(ukeys.length === entry.ukeys.length);
                    for (var i = 0; i < ukeys.length; i++)
                        this.assertConsistency(ukeys[i] === entry.ukeys[i]);
                    this.assertConsistency(lkeys.length === entry.lkeys.length);
                    for (var i = 0; i < lkeys.length; i++)
                        this.assertConsistency(lkeys[i] === entry.lkeys[i]);
                }
                this.assertConsistency((uid.indexOf(".") !== -1) || (Number(uid) <= this.uidcount));
                entry.recordCreation(layer, p.serveritemcount);
                return entry;
            };
            ClientSession.prototype.ProcessDelPacket = function (p, layer) {
                var uid = p.ukeys[0];
                var entry = this.get_item(uid);
                if (entry) {
                    this.assertConsistency(entry.uid === uid);
                    entry.recordDeletion(layer);
                }
                return entry;
            };
            ClientSession.prototype.ProcessModPacket = function (p, layer, comp, member) {
                var ukeys = p.ukeys;
                var lkeys = p.lkeys;
                var definition = comp ? comp.InBound(p.definition, lkeys) : p.definition;
                var fromCloudOp = p.fromCloudOp;
                var op = lkeys.pop();
                if (op.lastIndexOf("^#", 0) === 0) {
                    var c = (new Parser(op.substr(2), 0)).ParseComboComponents();
                    op = c.map(function (code) { return comp ? comp.InBound(code, lkeys) : code; });
                    if (this.astencoding)
                        op = this.astencoding.fromstrings(op);
                }
                var target = ClientSession.MakeModTarget(definition, ukeys, lkeys);
                var lval = this.get_lval(target);
                if (!lval) {
                    lval = new LVal();
                    lval.session = this;
                    lval.definition = definition;
                    lval.ukeys = ukeys;
                    lval.lkeys = lkeys;
                    lval.parseDefinition();
                    lval.entry = this.user_get_entry(lval.indexdomain, ukeys, lkeys);
                    lval.linkDeps();
                    lval.fromCloudOp = fromCloudOp;
                    this.add_lval(lval);
                }
                else {
                    this.assertConsistency(lval.definition === definition);
                    this.assertConsistency(ukeys.length === lval.ukeys.length);
                    for (var i = 0; i < ukeys.length; i++)
                        this.assertConsistency(ukeys[i] === lval.ukeys[i]);
                    this.assertConsistency(lkeys.length === lval.lkeys.length);
                    for (var i = 0; i < lkeys.length; i++)
                        this.assertConsistency(lkeys[i] === lval.lkeys[i]);
                }
                if (member !== undefined && lval.codomain.indexOf("^") === 0) {
                    if (op.indexOf(".") !== 0) {
                        op = member + "." + op;
                    }
                }
                lval.recordOperation(layer, op);
                return lval;
            };
            ClientSession.prototype.ProcessClearRootPacket = function (p, layer) {
                TDev.Util.assert(p.code === "cld" && p.definition === "*");
                layer.grounded = true;
            };
            return ClientSession;
        })();
        Revisions.ClientSession = ClientSession;
        var NodeSession = (function (_super) {
            __extends(NodeSession, _super);
            function NodeSession(nodeserver, servername, localname, user) {
                _super.call(this, servername, localname, user);
                this.returnMap = {};
                this.sendCloudOperations = true;
                this.includeKeysInStatus = true;
                this.acceptsUpdates = true;
                this.requiresAuth = false;
                this.recording = null;
                TDev.Util.assert(!!nodeserver);
                this.nodeserver = nodeserver;
            }
            NodeSession.prototype.hasNodeConnection = function () {
                return this.ws !== undefined && this.ws.readyState === WebSocket.OPEN;
            };
            NodeSession.prototype.stopAsync = function () {
                this.disconnect();
                return TDev.Promise.as();
            };
            NodeSession.prototype.ReceivePacket = function (p) {
                if (p.code === 'rpc') {
                    this.ReceiveOperation(p);
                    this.doorbell();
                }
                else {
                    return _super.prototype.ReceivePacket.call(this, p);
                }
            };
            NodeSession.prototype.user_start_cloud_operation = function (libName, actionName, paramNames, returnNames, args, optype) {
                TDev.Util.assert(this.recording == null);
                TDev.Util.assert(this.recordinground == null);
                TDev.Util.assert(optype == 2 /* OFFLINE */);
                this.log("start recording operation: " + actionName);
                var script = TDev.Runtime.theRuntime.compiled.libScripts[libName];
                this.recording = {
                    libName: libName,
                    actionName: actionName,
                    paramNames: paramNames,
                    returnNames: returnNames,
                    uidcountstart: this.uidcount,
                    args: args,
                    optype: optype
                };
                this.recordinground = this.localround;
            };
            NodeSession.prototype.user_stop_cloud_operation = function (libName, actionName, paramNames, returnNames, args) {
                TDev.Util.assert(this.recording.libName == libName);
                TDev.Util.assert(this.recording.actionName == actionName);
                TDev.Util.assert(this.recording.paramNames == paramNames);
                TDev.Util.assert(this.recording.returnNames == returnNames);
                TDev.Util.assert(this.recording.args == args);
                TDev.Util.assert(this.recordinground == this.localround);
                this.log("done recording operation: " + actionName);
                var tlayer = this.get_layer("T") || this.create_layer("T");
                this.recording.uidcountstop = this.uidcount;
                tlayer.CommitCloudOperation(this.recording);
                this.recording = null;
                this.recordinground = null;
            };
            NodeSession.prototype.user_rpc_cloud_operation = function (libName, actionName, paramNames, returnNames, args) {
                this.log("record rpc operation: " + actionName);
                var promise = new TDev.PromiseInv();
                var script = TDev.Runtime.theRuntime.compiled.libScripts[libName];
                var tlayer = this.get_layer("T") || this.create_layer("T");
                this.uidcount += 1;
                var opid = this.uidcount;
                this.returnMap[opid] = promise;
                var cop = {
                    libName: libName,
                    actionName: actionName,
                    paramNames: paramNames,
                    returnNames: returnNames,
                    args: args,
                    opid: opid,
                    optype: 1 /* RPC */
                };
                tlayer.CommitCloudOperation(cop);
                this.user_yield();
                return promise;
            };
            NodeSession.prototype.NumberWaitingRpcs = function () {
                return Object.keys(this.returnMap).length;
            };
            NodeSession.prototype.ReceiveOperation = function (p) {
                var _this = this;
                var json = JSON.parse(p.lkeys[0]);
                var opid = Number(json.opid);
                var res = json.params;
                var path = json.path;
                if (path === "err") {
                    this.RemoveFromDiskAsync(this.cleanOutstandingLayers()).thenalways(function () {
                        if (opid === -1 || _this.returnMap[opid] === undefined) {
                            TDev.Runtime.theRuntime.handleException(res, null);
                        }
                        else {
                            _this.returnMap[opid].error(res);
                        }
                    }).done();
                }
                else {
                    if (this.returnMap[opid] !== undefined) {
                        this.returnMap[opid].success(res);
                        delete this.returnMap[opid];
                    }
                }
            };
            NodeSession.prototype.unsent_changes = function () {
                var locallayer = this.get_layer("D" + this.localround);
                if (locallayer && ((locallayer.data.length != 0 || locallayer.grounded) || locallayer.cloudOperations && locallayer.cloudOperations.length > 0))
                    return true;
                return false;
            };
            NodeSession.prototype.collapse_layers = function (firstname, secondname, keepsecond) {
                var l1 = this.get_layer(firstname);
                var l2 = this.get_layer(secondname);
                if (!l1.grounded) {
                    l1.mergeCloudOperations(l2);
                }
                return _super.prototype.collapse_layers.call(this, firstname, secondname, keepsecond);
            };
            return NodeSession;
        })(ClientSession);
        Revisions.NodeSession = NodeSession;
        var ServerSession = (function (_super) {
            __extends(ServerSession, _super);
            function ServerSession(nodeserver, servername, localname, user, rt, wsServer) {
                _super.call(this, nodeserver, servername, localname, user);
                this.rt = rt;
                this.wsServer = wsServer;
                this.sendCloudOperations = false;
                this.concatIdToItem = true;
                this.includeKeysInStatus = false;
                this.requiresAuth = false;
                this.current_membernumber = 0;
                this.membernumber = 0;
                this.disambiguators = {};
                this.schema = {};
                this.full_keys = {};
                this.types = {};
                this.transactionFailed = false;
                this.transactionRunning = false;
            }
            ServerSession.prototype.log = function (msg) {
                TDev.Util.log(msg);
            };
            ServerSession.prototype.user_create_item = function (definition, ukeys, lkeys) {
                var k = new Item();
                k.session = this;
                k.definition = definition;
                TDev.Util.assert(this.loaded || this.faulted);
                if (this.uidcountstart === undefined || this.uidcountstart > this.uidcountstop) {
                    this.uidcount++;
                    var uid = "0." + this.uidcount;
                }
                else {
                    this.uidcountstart++;
                    var uid = this.membernumber + "." + this.uidcountstart;
                }
                k.uid = uid;
                k.ukeys = ukeys;
                k.lkeys = lkeys;
                TDev.Util.assert(!this.get_item(k.uid));
                if (this.readonly) {
                    k.deleted = true;
                    return k;
                }
                k.linkDeps();
                this.add_item(k);
                if (!k.has_deleted_dependencies()) {
                    var transactionlayer = this.get_layer("T") || this.create_layer("T");
                    k.recordCreation(transactionlayer);
                    this.add_item_to_index(k);
                }
                return k;
            };
            ServerSession.prototype.create_layer = function (name, clientround, serverround) {
                if (serverround === undefined) {
                    serverround = clientround;
                }
                return _super.prototype.create_layer.call(this, name, clientround, serverround);
            };
            ServerSession.prototype.get_unsaved_layer = function () {
                var locallayer = this.get_layer("D" + this.localround);
                if (!locallayer)
                    locallayer = this.create_layer("D" + this.localround, this.localround, this.localround);
                return locallayer;
            };
            ServerSession.prototype.collapse_layers = function (first, second, keep_second) {
                var l1 = this.get_layer(first);
                var l2 = this.get_layer(second);
                if (l2.clientrounds !== undefined) {
                    if (l1.clientrounds === undefined) {
                        l1.clientrounds = {};
                    }
                    Object.keys(l2.clientrounds).forEach(function (c) {
                        if (l1.clientrounds[c] !== undefined && l2.clientrounds[c] !== undefined)
                            TDev.Util.assert(l1.clientrounds[c] <= l2.clientrounds[c]);
                        l1.clientrounds[c] = l2.clientrounds[c];
                    });
                }
                return _super.prototype.collapse_layers.call(this, first, second, keep_second);
            };
            ServerSession.prototype.user_start_transaction = function (membernumber, clientRound) {
                var tlayer = this.get_layer("T") || this.create_layer("T");
                if (clientRound !== undefined) {
                    tlayer.clientrounds = {};
                    tlayer.clientrounds[membernumber] = clientRound;
                }
                this.checkinvariants();
                return tlayer;
            };
            ServerSession.prototype.user_end_transaction = function () {
                var tlayer = this.get_layer("T") || this.create_layer("T");
                var unsavedlayer = this.get_unsaved_layer();
                this.collapse_layers(unsavedlayer.name, "T");
                unsavedlayer.cleanIfNeeded(this.scrublimit);
                this.Sstate_needsave = true;
            };
            ServerSession.prototype.user_rollback_transaction = function () {
                var tlayer = this.get_layer("T");
                TDev.Util.assert(tlayer !== undefined, "transaction layer has to be created by user_start_transaction before calling user_rollback_transaction");
                this.delete_layer("T", true);
            };
            ServerSession.prototype.user_yield = function () {
                if (this.transactionRunning)
                    return false;
                return _super.prototype.user_yield.call(this);
            };
            ServerSession.prototype.user_push = function () {
                if (this.transactionRunning)
                    return;
                return _super.prototype.user_push.call(this);
            };
            ServerSession.prototype.MergeAndSaveSB = function () {
                return false;
            };
            ServerSession.prototype.sendLayerToClient = function (layer, socket) {
                var _this = this;
                var packets = this.EncodeLayer(layer, 4 /* SERVER_LAYER_TO_CLIENT */, socket);
                var clientround = (layer.clientrounds && layer.clientrounds[socket.membernumber]) || socket.lastclientroundsent;
                var serverround = layer.serverround;
                this.updateForClient(packets, clientround, socket.membernumber);
                packets.forEach(function (p) { return _this.sendPacketToClient(_this, p, socket); });
                TDev.Util.assert(clientround >= socket.lastclientroundsent);
                TDev.Util.assert(serverround > socket.lastserverroundsent);
                socket.lastclientroundsent = clientround;
                socket.lastserverroundsent = serverround;
            };
            ServerSession.prototype.sendUpdatesToClient = function (socket) {
                var _this = this;
                if (socket.keyset.has_unsent_keys()) {
                    var layer = this.get_layer("B");
                    var packets = this.EncodeLayer(layer, 5 /* SERVER_UPDATES_TO_CLIENT */, socket);
                    if (packets.length > 2) {
                        var clientround = (layer.clientrounds && layer.clientrounds[socket.membernumber]) || socket.lastclientroundsent;
                        TDev.Util.assert(clientround >= socket.lastclientroundsent);
                        this.updateForClient(packets, clientround, socket.membernumber);
                        packets.slice(1).forEach(function (p) { return (p.code !== "cld") ? _this.sendPacketToClient(_this, p, socket) : undefined; });
                    }
                }
            };
            ServerSession.prototype.sendPacketToClient = function (session, p, socket) {
                var s = p.toString();
                session.log(socket.membernumber.toString() + "< " + s);
                socket.send(s);
            };
            ServerSession.prototype.updateForClient = function (packets, clientround, membernumber) {
                var _this = this;
                if (packets.length > 0) {
                    packets[packets.length - 1].lkeys[0] = String(clientround);
                }
                for (var i = 0; i < packets.length - 1; i++) {
                    var packet = packets[i];
                    packet.ukeys = packet.ukeys.map(function (uid) { return _this.filteruid(uid, membernumber); });
                    if (packet.code == "mod" && packet.definition.indexOf("^") !== -1) {
                        var l = packet.lkeys.length - 1;
                        var k = packet.lkeys[l];
                        packet.lkeys[l] = this.filteruid(k, membernumber);
                    }
                }
                return packets;
            };
            ServerSession.prototype.filteruid = function (uid, member) {
                var r = /^\d+/.exec(uid);
                var m = r ? r[0] : undefined;
                if (m === String(member)) {
                    return uid.slice(uid.indexOf(".") + 1);
                }
                else {
                    return uid;
                }
            };
            ServerSession.prototype.update_keysets = function (layer) {
                var _this = this;
                this.forEachValidDatum(layer, function (d, op) {
                    if (d instanceof Item) {
                        if (op[0] === "C") {
                            var def = /^\w+/.exec(d.definition)[0];
                            d.uid;
                            if (_this.types[def].replication === "full") {
                                _this.add_item_to_keysets(d);
                            }
                        }
                        else {
                            TDev.Util.assert(op === "D");
                            TDev.Util.assert(!layer.grounded);
                        }
                    }
                    else if (d instanceof LVal) {
                    }
                });
                this.add_closure_to_keysets();
            };
            ServerSession.prototype.add_item_to_keysets = function (item) {
                this.sockets().forEach(function (s) { return s.keyset.add(item.uid); });
            };
            ServerSession.prototype.add_closure_to_keysets = function () {
                var _this = this;
                this.sockets().forEach(function (s) { return _this.add_closure_to_keyset(s.keyset); });
            };
            ServerSession.prototype.add_closure_to_keyset = function (keyset) {
                var added = true;
                while (added) {
                    added = this.add_closure_to_keyset_it(keyset);
                }
            };
            ServerSession.prototype.add_closure_to_keyset_it = function (keyset) {
                var _this = this;
                keyset.track();
                var blayer = this.get_layer("B");
                this.forEachValidDatum(blayer, function (datum) {
                    if (datum instanceof Item) {
                        var item = datum;
                        if (_this.all_keys_in_keyset(item.ukeys, keyset)) {
                            keyset.add(item.uid);
                        }
                        return;
                    }
                    if (datum instanceof LVal) {
                        var lval = datum;
                        if (/^\w+\[.*\]/.exec(lval.indexdomain)) {
                            if (keyset.contains(lval.lkeys[0])) {
                                _this.add_lval_to_keyset(lval, keyset);
                            }
                            return;
                        }
                        if (/\w+\(.*\)/.exec(lval.indexdomain)) {
                            if (keyset.contains(lval.ukeys[0])) {
                                _this.add_lval_to_keyset(lval, keyset);
                            }
                        }
                        return;
                    }
                    if (datum instanceof Entry) {
                        var entry = datum;
                        if (_this.get_replication_type(entry) === "partial") {
                            if (keyset.contains(entry.lkeys[0])) {
                                if (entry.definition.charAt(entry.definition.length - 1) === "]") {
                                    var types = entry.definition.slice(entry.definition.indexOf("["), entry.definition.lastIndexOf("]")).split(",");
                                    for (var i = 0; i < types.length; i++) {
                                        if (types[i].indexOf("(") !== -1) {
                                            keyset.add(entry.ukeys[i]);
                                        }
                                    }
                                }
                            }
                        }
                        return;
                    }
                    TDev.Util.assert(false);
                });
                return keyset.track();
            };
            ServerSession.prototype.add_lval_to_keyset = function (lval, keyset) {
                var key = lval.target();
                keyset.add(key);
                var datum = this.data[key];
                if (datum instanceof Item) {
                    var item = datum;
                    if (this.all_keys_in_keyset(item.ukeys, keyset)) {
                        keyset.add(item.uid);
                    }
                }
            };
            ServerSession.prototype.all_keys_in_keyset = function (keys, keyset) {
                var _this = this;
                return keys.reduce(function (included, uid) {
                    var item = _this.get_item(uid);
                    return included && (item === undefined || keyset.contains(uid));
                }, true);
            };
            ServerSession.prototype.initializeKeyset = function (socket, keys) {
                var _this = this;
                if (keys.length !== 1 || keys[0] !== "") {
                    keys.forEach(function (k) { return socket.keyset.keys[k] = true; });
                }
                if (socket.clientUserId !== undefined) {
                    socket.keyset.add(socket.clientUserId);
                }
                var blayer = this.get_layer("B");
                this.forEachValidDatum(blayer, function (datum) {
                    if (datum instanceof Item) {
                        var item = datum;
                        if (_this.get_replication_type(item) === "full") {
                            socket.keyset.add(item.uid);
                        }
                    }
                });
                this.add_closure_to_keyset(socket.keyset);
            };
            ServerSession.prototype.addKeysFromLayer = function (layer, keyset) {
                this.forEachValidDatum(layer, function (d) { return keyset.add(d.target()); });
            };
            ServerSession.prototype.setupKeyset = function (socket) {
                socket.keyset = new Keyset(this);
            };
            ServerSession.prototype.getMetaData = function () {
                var _this = this;
                if (this.rt === undefined)
                    return;
                var datas = this.rt.datas;
                Object.keys(datas).forEach(function (d) {
                    var lib = datas[d];
                    Object.keys(lib).forEach(function (n) {
                        if (/^\$\w+/.exec(n)) {
                            var name = n.slice(1);
                            _this.types[name] = { replication: (lib[n] ? lib[n].replication : undefined) };
                        }
                    });
                });
            };
            ServerSession.prototype.get_replication_type = function (datum) {
                var def = /^\w+/.exec(datum.definition);
                if (!def)
                    return undefined;
                var repl = this.types[def[0]];
                if (!repl)
                    return undefined;
                return repl.replication;
            };
            ServerSession.prototype.isOriginAllowed = function (origin) {
                return true;
            };
            ServerSession.prototype.connect = function (url, tokensource) {
                this.url = url;
                if (this.closed || this.faulted)
                    return;
                this.hasPartialData = this.rt.compiled.hasPartialData;
                this.hasLocalData = this.rt.compiled.hasLocalData;
                if (this.rt.compiled.hostCloudData)
                    this.setupWebSockets();
                this.getMetaData();
            };
            ServerSession.prototype.sockets = function () {
                return this.wsServer.connections().filter(function (c) { return c.isTdWebSocket; });
            };
            ServerSession.prototype.setupWebSockets = function () {
                var _this = this;
                this.log('setting up websockets server');
                this.wsServer.addHandler(function (request, next) {
                    if (request.path() != "/") {
                        next();
                        return;
                    }
                    if (!_this.isOriginAllowed(request.origin())) {
                        request.reject();
                        _this.log(TDev.Util.fmt("WebSocket connection from {0} rejected", request.origin()));
                        return;
                    }
                    _this.log(TDev.Util.fmt("WS request from {0}", request.origin()));
                    var socket = request.accept();
                    socket.isTdWebSocket = true;
                    _this.log(TDev.Util.fmt("accepted socket {0}", request.remoteAddress()));
                    var buffer = [];
                    var receivedStatus = false;
                    _this.setupKeyset(socket);
                    request.onMessage(function (str, buff) {
                        if (buff) {
                            _this.log('ERROR: Received Binary Message of ' + buff.length + ' bytes');
                        }
                        else {
                            _this.log((socket.membernumber || "?") + "> " + str);
                            var p = Packet.ParsePacket(str, socket);
                            if (p.code === "sts") {
                                _this.handleStatusPacket(p, socket);
                                receivedStatus = true;
                                return;
                            }
                            TDev.Util.assert(receivedStatus);
                            if (p.code === "frm") {
                                _this.queuePackets(buffer, p, socket, request, socket.membernumber);
                                buffer = [];
                            }
                            else {
                                buffer.push(p);
                            }
                        }
                    });
                    request.onClose(function (reasonCode, description) {
                        receivedStatus = false;
                        _this.log(' Peer ' + request.remoteAddress() + ' disconnected.');
                    });
                });
            };
            ServerSession.prototype.handleStatusPacket = function (p, socket) {
                var version = p.lkeys[0];
                var servername = p.lkeys[1];
                var membernumber = Number(p.lkeys[2]);
                var user = p.lkeys[3];
                var description = p.lkeys[4];
                var disambiguator = p.lkeys[5];
                var last_clientround = Number(p.lkeys[6]);
                var last_serverround = Number(p.lkeys[7]);
                var token = p.lkeys[8];
                var script = p.lkeys[9];
                var permissions = p.lkeys[10];
                var keysoruser = p.lkeys[11];
                var keys = keysoruser.replace("/", "|").replace(/(^\d+(?!\.))|(\|\d+(?!\.))|(\?\d+(?!\.))/g, function (d) {
                    if (d.indexOf("|") === 0) {
                        return ("|" + p.lkeys[2] + "." + d.slice(1));
                    }
                    else if (d.indexOf("?") === 0) {
                        return ("?" + p.lkeys[2] + "." + d.slice(1));
                    }
                    else {
                        return (p.lkeys[2] + "." + d);
                    }
                }).split("?");
                var rt = TDev.Runtime.theRuntime;
                if (rt.authValidator) {
                    var clientUserId = "";
                    rt.wrapFromHandler(function () {
                        clientUserId = rt.runUserAction(rt.authValidator, [token]);
                        if (clientUserId && !/:/.test(clientUserId))
                            TDev.Util.userError("user id returned from validator has to have a namespace (eg., fb:123456)");
                    });
                    if (!clientUserId) {
                        this.log("invalid authorization attempt");
                    }
                    else {
                        this.log("authorized as " + clientUserId);
                        socket.keyset.add(clientUserId);
                    }
                    p.lkeys[11] = clientUserId;
                    socket.clientUserId = clientUserId;
                }
                if (servername !== Revisions.nodesessionid(this.rt.host.currentGuid)) {
                    return socket.close(1000, "switched script");
                }
                var baselayer = this.get_layer("B");
                var startFrom = 0;
                if (membernumber === -1) {
                    TDev.Util.assert(disambiguator === "");
                    membernumber = ++this.current_membernumber;
                    disambiguator = (+new Date()).toString(36);
                    p.lkeys[5] = disambiguator;
                    p.lkeys[2] = (membernumber).toString();
                    this.disambiguators[membernumber] = disambiguator;
                }
                else {
                    if (membernumber > this.current_membernumber || this.disambiguators[membernumber] !== disambiguator) {
                        return socket.close(1000, "switched server");
                    }
                    if (last_serverround <= baselayer.serverround && this.get_layer("D" + (last_serverround + 1).toString()) && baselayer.clientrounds && baselayer.clientrounds[membernumber] >= last_clientround) {
                        startFrom = last_serverround;
                    }
                }
                p.lkeys[6] = String(baselayer.serverround);
                p.lkeys[7] = String(startFrom);
                socket.membernumber = membernumber;
                this.sendPacketToClient(this, p, socket);
                this.initializeKeyset(socket, keys);
                this.CLstate_needsave = true;
                if (baselayer.serverround === 0) {
                    this.log("Sending Nothing");
                    socket.lastclientroundsent = 0;
                    socket.lastserverroundsent = 0;
                    return;
                }
                if (startFrom === 0) {
                    this.log("Sending Base (" + baselayer.serverround + ")");
                    socket.lastclientroundsent = 0;
                    socket.lastserverroundsent = 0;
                    this.sendLayerToClient(baselayer, socket);
                }
                else {
                    this.log("Sending " + (baselayer.serverround - startFrom).toString() + " Deltas");
                    socket.lastclientroundsent = last_clientround;
                    socket.lastserverroundsent = startFrom;
                    for (var i = startFrom + 1; i <= baselayer.serverround; i++) {
                        var dlayer = this.get_layer("D" + i);
                        this.sendLayerToClient(dlayer, socket);
                    }
                    this.log("Sending Updates");
                    this.sendUpdatesToClient(socket);
                }
            };
            ServerSession.prototype.queuePackets = function (packets, frame, socket, request, membernumber) {
                var _this = this;
                var clientRound = Number(frame.lkeys[0]);
                this.rt.queueAsync(function (rt, args) {
                    _this.user_start_transaction(membernumber, clientRound);
                    _this.transactionRunning = true;
                    _this.membernumber = membernumber;
                });
                packets.forEach(function (p) {
                    if (p.code === "cop") {
                        if (_this.transactionFailed)
                            return;
                        var json = JSON.parse(p.lkeys[0]);
                        var path = json.path;
                        var params = json.params;
                        var opid = json.opid;
                        var optype = json.optype;
                        var uidcountstart = (isNaN(Number(json.uidcountstart))) ? undefined : Number(json.uidcountstart);
                        var uidcountstop = (isNaN(Number(json.uidcountstop))) ? undefined : Number(json.uidcountstoptart);
                        var promise = _this.queueOperation(path, params, request.origin, socket.membernumber, socket, uidcountstart, uidcountstop);
                        promise.then(function (res) {
                            var tlayer = _this.get_layer("T") || _this.create_layer("T");
                            tlayer.CommitCloudOperation({
                                libName: path.split("/")[0],
                                actionName: path.split("/")[1],
                                paramNames: Object.keys(params),
                                returnNames: [],
                                args: [],
                                optype: optype,
                                opid: opid,
                                res: res,
                                socket: socket
                            });
                        }, function (err) {
                            _this.sendError(opid, err, socket);
                        });
                    }
                    else {
                        _this.rt.queueAsync(function (rt, args) {
                            var tlayer = _this.get_layer("T") || _this.create_layer("T");
                            var key = _this.handleCloudPacket(p, tlayer, request, socket);
                        });
                    }
                });
                this.rt.queueAsync(function (rt, args) {
                    _this.membernumber = 0;
                    if (_this.transactionFailed) {
                        _this.user_rollback_transaction();
                        _this.transactionFailed = false;
                    }
                    else {
                        _this.addKeysFromLayer(_this.get_layer("T"), socket.keyset);
                        _this.user_end_transaction();
                        _this.log("finished handling cloud request");
                        _this.SaveAndSend();
                    }
                    _this.transactionRunning = false;
                });
            };
            ServerSession.prototype.queueOperation = function (path, params, host, membernumber, socket, uidcountstart, uidcountstop) {
                var _this = this;
                var promiseInv = new TDev.PromiseInv();
                var req = {
                    method: "WS",
                    headers: { host: host.replace(/^[a-z]+:\/\//, "") },
                    url: "/api/" + path,
                    body: params,
                    connection: socket,
                    tdQueryString: {},
                };
                var sReq = TDev.RT.ServerRequest.mk(req, promiseInv);
                if (socket.clientUserId)
                    sReq._user = TDev.RT.User.mk(socket.clientUserId);
                sReq.setJsonBody(params);
                sReq._api_path = path;
                this.currentOp = promiseInv;
                promiseInv.thenalways(function () {
                    if (_this.currentOp === promiseInv) {
                        _this.currentOp = undefined;
                    }
                });
                this.rt.queueAsync(function (rt, args) {
                    _this.membernumber = membernumber;
                    _this.uidcountstart = uidcountstart;
                    _this.uidcountstop = uidcountstop;
                });
                var promise = this.rt.dispatchServerRequest(sReq, promiseInv);
                this.rt.queueAsync(function (rt, args) {
                    _this.membernumber = 0;
                    _this.uidcountstart = undefined;
                    _this.uidcountstop = undefined;
                });
                return promise;
            };
            ServerSession.prototype.abortCurrentTransaction = function (bug) {
                if (this.currentOp != undefined) {
                    this.currentOp.error(bug);
                    this.transactionFailed = true;
                    this.log("rolled back transaction because of error");
                }
                this.log(bug.exceptionMessage);
            };
            ServerSession.prototype.handleCloudPacket = function (p, layer, request, socket) {
                TDev.Util.assert(layer !== undefined);
                this.completeIds(p, layer, socket.membernumber);
                if (p.code === "new") {
                    this.log("Handling new effect");
                    p.serveritemcount = this.serveritemcount;
                    this.serveritemcount += 1;
                    var entry = this.ProcessNewPacket(p, layer);
                    return entry.uid;
                }
                else if (p.code === "del") {
                    this.log("Handling del effect");
                    this.ProcessDelPacket(p, layer);
                }
                else if (p.code === "cld") {
                    this.log("Handling cld effect");
                    if (p.definition === "*")
                        this.ProcessClearRootPacket(p, layer);
                }
                else if (p.code === "clp") {
                    this.log("Handling clp effect");
                }
                else {
                    TDev.Util.assert(p.code === "mod");
                    this.log("Handling mod effect");
                    var lval = this.ProcessModPacket(p, layer, undefined, socket.membernumber);
                    return lval.target();
                }
                return undefined;
            };
            ServerSession.prototype.completeIds = function (p, layer, membernumber) {
                p.ukeys.forEach(function (uid) {
                    var uid = p.ukeys[0];
                    if (uid.indexOf(".") === -1) {
                        p.ukeys[0] = String(membernumber) + "." + uid;
                    }
                });
            };
            ServerSession.prototype.sendResults = function (layer) {
                var _this = this;
                if (layer.cloudOperations !== undefined) {
                    layer.cloudOperations.forEach(function (cop) {
                        if (cop.opid !== undefined) {
                            TDev.Util.assert(cop.socket !== undefined);
                            TDev.Util.assert(cop.res !== undefined);
                            _this.sendResult(cop.opid, cop.res, cop.socket);
                        }
                    });
                }
            };
            ServerSession.prototype.sendResult = function (opid, res, socket) {
                var p = Packet.MakeRpcPacket("", res, opid);
                socket.send(p.toString());
            };
            ServerSession.prototype.sendError = function (opid, err, socket) {
                var p = Packet.MakeRpcPacket("err", err, opid);
                socket.send(p.toString());
            };
            ServerSession.prototype.SaveAndSend = function (serverround) {
                var _this = this;
                TDev.Util.assert(this.loaded);
                var promise = TDev.Promise.as();
                if (serverround !== undefined && this.localround > serverround) {
                    return this.last_C_save;
                }
                if (this.last_C_save._state === 0 /* Pending */) {
                    return this.last_C_save.then(function () { return _this.SaveAndSend(serverround); });
                }
                var ulayer = this.get_layer("D" + this.localround);
                if (ulayer && ulayer.hasData()) {
                    var oldlayer = this.get_unsaved_layer();
                    var baselayer = this.get_layer("B");
                    this.localround += 1;
                    var newlayer = this.create_layer("D" + this.localround, this.localround, this.localround);
                    this.collapse_layers("B", oldlayer.name, true);
                    this.last_C_save = this.SaveToDiskAsync().then(function () {
                        _this.update_keysets(oldlayer);
                        _this.log("Broadcasting Layer " + oldlayer.name);
                        _this.sockets().forEach(function (s) {
                            if (s.lastserverroundsent < oldlayer.serverround) {
                                TDev.Util.assert(s.lastserverroundsent == oldlayer.serverround - 1);
                                _this.sendLayerToClient(oldlayer, s);
                            }
                            else
                                TDev.Util.assert(s.lastserverroundsent == oldlayer.serverround);
                        });
                        _this.log("Sending Updates");
                        _this.sockets().forEach(function (s) { return _this.sendUpdatesToClient(s); });
                        _this.sendResults(oldlayer);
                        oldlayer.removeCloudOperations();
                    });
                    promise = this.last_C_save;
                    this.CLstate_needsave = false;
                }
                else if (this.CLstate_needsave) {
                    promise = this.SaveToDiskAsync();
                    this.CLstate_needsave = false;
                    return promise;
                }
                return promise;
            };
            ServerSession.prototype.S_toJSONstring = function () {
                return JSON.stringify({
                    uidcount: this.uidcount,
                    localround: this.localround,
                    disambiguators: this.disambiguators,
                    current_membernumber: this.current_membernumber
                });
            };
            ServerSession.prototype.S_fromJSONstring = function (s) {
                var json = JSON.parse(s);
                this.uidcount = json.uidcount;
                this.disambiguators = json.disambiguators || {};
                this.localround = json.localround;
                this.current_membernumber = json.current_membernumber;
            };
            ServerSession.prototype.SaveToDiskAsync = function () {
                var _this = this;
                var baselayer = this.get_layer("B");
                var kvpairs = {};
                kvpairs[this.key_Sstate()] = this.S_toJSONstring();
                var packets = this.EncodeLayer(baselayer, 3 /* SERVER_BASE_TO_DISK */);
                kvpairs[this.key_layer("B")] = JSON.stringify(packets);
                this.log("saving state...");
                if (this.trace_save_and_load)
                    this.log(TDev.Util.fmt("\nSaved Metadata:\n{0}\nSaved Data:\n{1}", kvpairs[this.key_Sstate()], packets.map(function (p) { return p.toString(); }).join("\n")));
                this.last_C_save = this.table.setItemsAsync(kvpairs).then(function (saveok) {
                    _this.log("saved state.");
                    return TDev.Promise.as();
                }, function (savefailure) {
                    _this.log("!! failure while saving data ");
                    TDev.Util.oops("save failed... local storage full?");
                    _this.faulted = true;
                    throw savefailure;
                });
                return this.last_C_save;
            };
            ServerSession.prototype.LoadFromDiskAsync = function () {
                var _this = this;
                return TDev.Storage.getTableAsync("Sessions").then(function (table) {
                    _this.table = table;
                    var keys = [_this.key_Sstate(), _this.key_layer("B")];
                    return table.getItemsAsync(keys).then(function (results) {
                        var S = results[keys[0]];
                        var B = results[keys[1]];
                        var baselayer = _this.get_layer("B");
                        if (!S) {
                            _this.Sstate_needsave = true;
                        }
                        else {
                            _this.S_fromJSONstring(S);
                            if (B) {
                                var packets = JSON.parse(B);
                                packets.forEach(function (p) { return _this.ProcessLoadedPacket(p, baselayer); });
                            }
                        }
                        if (baselayer.serverround < _this.localround - 1) {
                            _this.log("Corrupted files - lost " + (_this.localround - baselayer.serverround - 1) + " rounds. ");
                            _this.localround = baselayer.serverround + 1;
                        }
                        _this.loaded = true;
                        _this.statuschanges = true;
                        if (_this.trace_save_and_load)
                            _this.log(TDev.Util.fmt("\Loaded Metadata:\n{0}\nLoaded Data:\n{1}", _this.S_toJSONstring(), _this.EncodeLayer(_this.get_layer("B"), 6 /* TRACE_LOAD */).map(function (p) { return p.toString(); }).join("\n")));
                    });
                });
            };
            ServerSession.prototype.user_sync_enabled = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_enable_sync = function (b) {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_issue_fence = function (continuation, exclusive) {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_get_connectionstatus = function (include_details) {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_get_next_connection_attempt = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_get_missing_rounds = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_is_websocket_open = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_retry_now = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.user_get_percent_full = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.isFaulted = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.isClosed = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.isMarooned = function () {
                throw new Error("Should not be called on the server");
            };
            ServerSession.prototype.getCloudSession = function () {
                throw new Error("Should not be called on the server");
            };
            return ServerSession;
        })(NodeSession);
        Revisions.ServerSession = ServerSession;
        var Keyset = (function () {
            function Keyset(session) {
                this.session = session;
                this.keys = {};
                this.delta = {};
            }
            Keyset.prototype.add = function (key) {
                TDev.Util.assert(key !== undefined);
                if (this.keys[key])
                    return;
                this.added = true;
                this.delta[key] = true;
                this.keys[key] = true;
            };
            Keyset.prototype.remove = function (key) {
                delete this.keys[key];
                delete this.delta[key];
            };
            Keyset.prototype.contains = function (key) {
                return this.keys[key] !== undefined;
            };
            Keyset.prototype.contains_and_clr = function (key) {
                var contains = this.contains(key);
                if (contains) {
                    if (this.delta[key] !== undefined) {
                        this.session.log("sending " + key);
                    }
                    delete this.delta[key];
                }
                else {
                    this.session.log(TDev.Util.fmt("Does not contain: {0}", key));
                }
                return contains;
            };
            Keyset.prototype.is_unsent_and_clr = function (key) {
                var is_unsent = this.delta[key] !== undefined;
                if (is_unsent) {
                    this.session.log("send update for " + key);
                    delete this.delta[key];
                }
                return is_unsent;
            };
            Keyset.prototype.has_unsent_keys = function () {
                return Object.keys(this.delta).length > 0;
            };
            Keyset.prototype.key_sent = function (key) {
                delete this.delta[key];
            };
            Keyset.prototype.unsent_keys = function () {
                return this.delta;
            };
            Keyset.prototype.reset_delta = function () {
                this.delta = {};
            };
            Keyset.prototype.track = function () {
                var res = this.added;
                this.added = false;
                return res;
            };
            return Keyset;
        })();
        Revisions.Keyset = Keyset;
        var Packet = (function () {
            function Packet() {
            }
            Packet.MakeStatusPacket = function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i - 0] = arguments[_i];
                }
                var p = new Packet();
                p.code = "sts";
                p.ukeys = [];
                p.lkeys = args;
                return p;
            };
            Packet.MakeNewPacket = function (definition, uid, ukeys, lkeys, serveritemcount, comp) {
                var addedliterals = [];
                var p = new Packet();
                p.code = "new";
                p.ukeys = [uid].concat(ukeys);
                if (comp) {
                    p.lkeys = lkeys.slice(0);
                    p.definition = comp.OutBound(definition, p.lkeys);
                }
                else {
                    p.lkeys = lkeys;
                    p.definition = definition;
                }
                p.serveritemcount = serveritemcount;
                return p;
            };
            Packet.MakeDelPacket = function (uid) {
                var p = new Packet();
                p.code = "del";
                p.ukeys = [uid];
                p.lkeys = [];
                return p;
            };
            Packet.MakeCldStarPacket = function (comp) {
                var p = new Packet();
                p.code = "cld";
                p.ukeys = [];
                p.lkeys = [];
                p.definition = comp ? comp.OutBound("*", p.lkeys) : "*";
                return p;
            };
            Packet.MakeModPacket = function (definition, op, ukeys, lkeys, scheme, comp) {
                var p = new Packet();
                p.code = "mod";
                var addedliterals = [];
                if (typeof (op) !== "string") {
                    TDev.Util.assert(Array.isArray(op));
                    if (scheme)
                        op = scheme.tostrings(op);
                    op = "^#" + op.map(function (s) { return Parser.WriteComboString(comp ? comp.OutBound(s, addedliterals) : s); }).join("|");
                }
                addedliterals.reverse();
                addedliterals.push(op);
                p.definition = comp ? comp.OutBound(definition, addedliterals) : definition;
                p.ukeys = ukeys;
                p.lkeys = lkeys.concat(addedliterals);
                return p;
            };
            Packet.MakeFramePacket = function (layer, withClientRounds) {
                var p = new Packet();
                p.code = "frm";
                p.ukeys = [];
                p.lkeys = [layer.clientround.toString()];
                p.lkeys.push(layer.serverround === undefined ? "" : layer.serverround.toString());
                if (withClientRounds && layer.clientrounds)
                    p.lkeys.push(Object.keys(layer.clientrounds).map(function (c) { return c + ":" + layer.clientrounds[c].toString(); }).join(","));
                return p;
            };
            Packet.MakeCopPacket = function (path, params, opid, uidcountstart, uidcountstop) {
                var json = {
                    path: path,
                    params: params,
                    opid: opid,
                    uidcountstart: uidcountstart,
                    uidcountstop: uidcountstop
                };
                var p = new Packet();
                p.code = "cop";
                p.ukeys = [];
                p.lkeys = [JSON.stringify(json)];
                return p;
            };
            Packet.MakeRpcPacket = function (path, params, opid) {
                var json = {
                    path: path,
                    params: params,
                    opid: opid
                };
                var p = new Packet();
                p.code = "rpc";
                p.ukeys = [];
                p.lkeys = [JSON.stringify(json)];
                return p;
            };
            Packet.ParsePacket = function (from, ws, fromDisk) {
                var p = new Packet();
                var code = from.slice(0, 3);
                var c = (new Parser(from, 0)).ParseComboComponents();
                var i = 0;
                p.code = c[i++];
                p.definition = c[i++];
                if (fromDisk) {
                    p.fromCloudOp = Boolean(c[i++]);
                }
                p.ukeys = new Array();
                p.lkeys = new Array();
                for (; i < c.length; i++) {
                    var s = c[i];
                    var first = s.charAt(0);
                    if (first === "+")
                        p.lkeys.push(s.slice(1));
                    else if (first === "-")
                        p.serveritemcount = Number(s.slice(1));
                    else
                        p.ukeys.push(s);
                }
                return p;
            };
            Packet.prototype.toString = function () {
                var s = this.code + "|" + (this.definition ? Parser.WriteComboString(this.definition) : "");
                this.ukeys.forEach(function (uid) {
                    s = s + "|" + uid;
                });
                this.lkeys.forEach(function (lit) {
                    s = s + "|+" + Parser.WriteComboString(lit);
                });
                if (this.serveritemcount !== undefined)
                    s = s + "|-" + this.serveritemcount;
                return s;
            };
            Packet.prototype.send = function (ws) {
                TDev.Util.check(this.code !== "frm" || this.lkeys[1] !== undefined, "undefined serverround sent frame");
                ws.send(this.toString());
            };
            return Packet;
        })();
        Revisions.Packet = Packet;
        var ChannelCompressor = (function () {
            function ChannelCompressor() {
                this.map = {};
                this.hash = {};
                this.localcount = 0;
            }
            ChannelCompressor.prototype.InBound = function (code, lkeys) {
                TDev.Util.assert(code.length > 0);
                var n;
                var s;
                if (code[0] === '+') {
                    n = Number(code.substr(1));
                    TDev.Util.assert(n !== undefined);
                    s = lkeys.pop();
                    this.map[n] = s;
                    this.hash[s] = n;
                }
                else {
                    n = Number(code);
                    TDev.Util.assert(n !== undefined);
                    s = this.map[n];
                    TDev.Util.assert(s !== undefined);
                }
                return s;
            };
            ChannelCompressor.prototype.OutBound = function (s, lkeys) {
                var code;
                var key = this.hash[s];
                if (key !== undefined) {
                    code = key.toString();
                }
                else {
                    code = "+" + (--this.localcount).toString();
                    this.map[this.localcount] = s;
                    this.hash[s] = this.localcount;
                    lkeys.push(s);
                }
                return code;
            };
            return ChannelCompressor;
        })();
        Revisions.ChannelCompressor = ChannelCompressor;
        var Parser = (function () {
            function Parser(text, pos) {
                this.DefinitionEscapeChar = '$';
                this.DefinitionMetaCharacters = "([,])";
                this.ComboEscapeChar = '@';
                this.ComboMetaCharacters = "|";
                this.text = text;
                this.pos = pos;
            }
            Parser.MakeDomain = function (name, type, components) {
                var s = Parser.WriteDefinitionString(name);
                if (type !== Parser.DOMAIN_BUILTIN) {
                    s += (type === Parser.DOMAIN_DYNAMIC ? "(" : "[");
                    s += components.join(",");
                    s += (type === Parser.DOMAIN_DYNAMIC ? ")" : "]");
                }
                return s;
            };
            Parser.MakeProperty = function (name, domain, codomain) {
                return Parser.WriteDefinitionString(name) + "," + codomain + "[" + domain + "]";
            };
            Parser.MakeKeyString = function (ukeys, lkeys) {
                var s = "";
                ukeys.forEach(function (uid) {
                    s = s + "|" + uid;
                });
                lkeys.forEach(function (lit) {
                    s = s + "|+" + Parser.WriteComboString(lit);
                });
                return s;
            };
            Parser.prototype.ParseKeyString = function (ukeys, lkeys) {
                var c = this.ParseComboComponents();
                for (var i = 0; i < c.length; i++) {
                    var s = c[i];
                    if (s.charAt(0) === "+")
                        lkeys.push(s.slice(1));
                    else
                        ukeys.push(s);
                }
            };
            Parser.prototype.ParseComboComponents = function () {
                var result = new Array();
                while (this.pos < this.text.length) {
                    result.push(this.ParseComboString());
                    this.pos++;
                }
                return result;
            };
            Parser.WriteDefinitionString = function (s) {
                var regexp = /[\$\(\[.\]\)]/g;
                return s.replace(regexp, '$$$&');
            };
            Parser.WriteComboString = function (s) {
                var regexp = /[@\|]/g;
                return s.replace(regexp, '@$&');
            };
            Parser.prototype.ParseDefinitionString = function () {
                return this.ParseString(this.DefinitionEscapeChar, this.DefinitionMetaCharacters);
            };
            Parser.prototype.ParseComboString = function () {
                return this.ParseString(this.ComboEscapeChar, this.ComboMetaCharacters);
            };
            Parser.prototype.ParseString = function (escapechar, metachars) {
                var result = "";
                while (this.pos < this.text.length) {
                    var c = this.text.charAt(this.pos);
                    this.pos += 1;
                    if (c === escapechar) {
                        result = result + (this.text.charAt(this.pos) || escapechar);
                        this.pos += 1;
                    }
                    else if (metachars.indexOf(c) != -1) {
                        this.pos -= 1;
                        return result;
                    }
                    else {
                        result = result + c;
                    }
                }
                return result;
            };
            Parser.DOMAIN_BUILTIN = 0;
            Parser.DOMAIN_STATIC = 1;
            Parser.DOMAIN_DYNAMIC = 2;
            return Parser;
        })();
        Revisions.Parser = Parser;
    })(Revisions = TDev.Revisions || (TDev.Revisions = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Revisions;
    (function (Revisions) {
        var SessionTests = (function () {
            function SessionTests(rt) {
                this.rt = rt;
            }
            SessionTests.prototype.runtest = function (which) {
                if (typeof this[which] === "function") {
                    this.print("running test \"" + which + "\"");
                    this[which]();
                }
                else
                    this.print("no such test: \"" + which + "\"");
            };
            SessionTests.prototype.print = function (s) {
                this.rt.postBoxedText(s, "");
            };
            SessionTests.prototype.fail = function (msg) {
                this.print("FAILED: " + msg);
            };
            SessionTests.prototype.assert = function (cond) {
                if (!cond)
                    this.print("FAILED");
            };
            SessionTests.prototype.randomsuffix = function () {
                var d = new Date();
                var ms = d.getMilliseconds();
                return String.fromCharCode("a".charCodeAt(0) + ms % 26) + String.fromCharCode("a".charCodeAt(0) + Math.floor(ms / 26) % 26);
            };
            SessionTests.prototype.refreshtoken = function () {
                var _this = this;
                Revisions.getRevisionServiceTokenAsync().then(function (token) {
                    _this.print("success:");
                    _this.print("token=" + token);
                }, function (e) {
                    _this.fail("error: " + e);
                });
            };
            SessionTests.prototype.list = function () {
                var _this = this;
                var user = TDev.Cloud.getUserId();
                this.print("issuing get request for sessions by user " + user + "...");
                Revisions.queryMySessionsOnRevisionServerAsync(this.rt).then(function (s) {
                    _this.print("success:");
                    s.forEach(function (si) {
                        _this.print("");
                        _this.print("id=" + si._id);
                        _this.print("d=" + si._title);
                    });
                }, function (e) {
                    _this.fail("error: " + e);
                });
            };
            SessionTests.prototype.deletetests = function () {
                var _this = this;
                var user = TDev.Cloud.getUserId();
                this.print("issuing get request for sessions by user " + user + "...");
                Revisions.queryMySessionsOnRevisionServerAsync(this.rt).then(function (s) {
                    _this.print("success:");
                    s.forEach(function (si) {
                        if (si._title.indexOf("test session for") == 0) {
                            _this.print("deleting " + si._id);
                            Revisions.deleteSessionAsync(_this.rt.sessions.getCloudSessionDescriptor(s._id, s._title, s._permissions), _this.rt).then(function (ack) {
                                _this.print("successfully deleted " + si._id);
                            }, function (err) {
                                _this.fail("error deleting " + si._id + ": " + err);
                            }).done();
                        }
                    });
                }, function (e) {
                    _this.fail("error: " + e);
                });
            };
            SessionTests.prototype.connect1 = function () {
                var _this = this;
                this.print("connecting...");
                var sfx = this.randomsuffix();
                var testname = "connectone" + sfx;
                var s = new TDev.Revisions.ClientSession(TDev.Cloud.getUserId() + "0" + testname, "a" + sfx, TDev.Cloud.getUserId());
                s.connect(this.rt.sessions.url_ws(), Revisions.getRevisionServiceTokenAsync);
                this.print("create elt...");
                var dcustomer = "customer()";
                var alice = s.user_create_item(dcustomer, [], []);
                var items = s.user_get_items_in_domain(dcustomer);
                this.assert(items.length == 1);
                this.assert(items[0] === alice);
                this.print("issuing fence 1...");
                s.user_issue_fence(function () {
                    _this.print("fence 1 completed.");
                    var items = s.user_get_items_in_domain(dcustomer);
                    _this.assert(items.length == 1);
                    _this.assert(items[0] === alice);
                    _this.print("delete elt...");
                    s.user_delete_item(alice);
                    var items = s.user_get_items_in_domain(dcustomer);
                    _this.assert(items.length == 0);
                    _this.print("issuing fence 2...");
                    s.user_issue_fence(function () {
                        _this.print("fence 2 completed.");
                        var items = s.user_get_items_in_domain(dcustomer);
                        _this.assert(items.length == 0);
                        _this.print("DATA:");
                        var lines = s.user_dump_stable_data(function (b) { return _this.assert(b); });
                        lines.forEach(function (l) { return _this.print(l); });
                        _this.print("test completed.");
                    }, true);
                }, true);
            };
            SessionTests.prototype.connect2 = function () {
                var _this = this;
                this.print("connecting...");
                var testname = TDev.Cloud.getUserId() + "0" + "connecttwo" + this.randomsuffix();
                var s = new TDev.Revisions.ClientSession(testname, testname, TDev.Cloud.getUserId());
                s.connect(this.rt.sessions.url_ws(), Revisions.getRevisionServiceTokenAsync);
                var st = s.user_get_value(s.user_get_lval("mystring,string[void[]]", [], []));
                var db = s.user_get_value(s.user_get_lval("mydouble,double[void[]]", [], []));
                this.assert(st === "");
                this.assert(db === 0.0);
                this.print("writing data...");
                s.user_modify_lval(s.user_get_lval("mystring,string[void[]]", [], []), "");
                s.user_modify_lval(s.user_get_lval("mydouble,double[void[]]", [], []), 3.14);
                var st = s.user_get_value(s.user_get_lval("mystring,string[void[]]", [], []));
                var db = s.user_get_value(s.user_get_lval("mydouble,double[void[]]", [], []));
                this.assert(st === "");
                this.assert(db === 3.14);
                this.print("yielding...");
                s.user_yield();
                s.user_modify_lval(s.user_get_lval("mystring,string[void[]]", [], []), "new");
                s.user_modify_lval(s.user_get_lval("mydouble,double[void[]]", [], []), "A-3");
                var st = s.user_get_value(s.user_get_lval("mystring,string[void[]]", [], []));
                var db = s.user_get_value(s.user_get_lval("mydouble,double[void[]]", [], []));
                this.assert(st === "new");
                this.assert(db - 0.14 < 0.000000001);
                this.print("issuing fence 1...");
                s.user_issue_fence(function () {
                    _this.print("fence 1 completed.");
                    var st = s.user_get_value(s.user_get_lval("mystring,string[void[]]", [], []));
                    var db = s.user_get_value(s.user_get_lval("mydouble,double[void[]]", [], []));
                    _this.assert(st === "new");
                    _this.assert(db - 0.14 < 0.000000001);
                    _this.print("DATA:");
                    var lines = s.user_dump_stable_data(function (b) { return _this.assert(b); });
                    lines.forEach(function (l) { return _this.print(l); });
                    _this.print("test completed.");
                }, true);
            };
            SessionTests.prototype.serverpersistence1 = function () {
                var _this = this;
                this.print("connecting first session...");
                var sfx = this.randomsuffix();
                var testname = TDev.Cloud.getUserId() + "0serverpersistenceone" + sfx;
                var s = new TDev.Revisions.ClientSession(testname, "a", TDev.Cloud.getUserId());
                s.connect(this.rt.sessions.url_ws(), Revisions.getRevisionServiceTokenAsync);
                this.print("data...");
                var alice = s.user_create_item("customer()", [], []);
                var bob = s.user_create_item("customer()", [], []);
                var charlie = s.user_create_item("customer()", [], []);
                var delta = s.user_create_item("customer()", [], []);
                s.user_modify_lval(s.user_get_lval("name,string[customertable[customer()]]", [alice.uid], []), "Alice");
                s.user_modify_lval(s.user_get_lval("name,string[customertable[customer()]]", [bob.uid], []), "Bob");
                s.user_modify_lval(s.user_get_lval("name,string[customertable[customer()]]", [charlie.uid], []), "Charlie");
                s.user_modify_lval(s.user_get_lval("name,string[customertable[customer()]]", [delta.uid], []), "");
                var is = s.user_get_items_in_domain("customer()").map(function (e) { return e.target(); }).sort();
                var ref = [alice.uid, bob.uid, charlie.uid, delta.uid].sort();
                this.assert(is.length == ref.length);
                for (var i = 0; i < is.length; i++)
                    this.assert(is[i] === ref[i]);
                var ks = s.user_get_entries_in_indexdomain("customertable[customer()]").map(function (e) { return e.target(); }).sort();
                var ref = [s.user_get_entry("customertable[customer()]", [alice.uid], []), s.user_get_entry("customertable[customer()]", [bob.uid], []), s.user_get_entry("customertable[customer()]", [charlie.uid], [])].map(function (e) { return e.target(); }).sort();
                this.assert(ks.length == ref.length);
                for (var i = 0; i < ks.length; i++)
                    this.assert(ks[i] === ref[i]);
                this.print("saving...");
                s.user_issue_fence(function () {
                    _this.print("save completed.");
                    _this.print("connecting second session...");
                    s = new TDev.Revisions.ClientSession(testname, "b", TDev.Cloud.getUserId());
                    s.connect(_this.rt.sessions.url_ws(), Revisions.getRevisionServiceTokenAsync);
                    _this.print("loading...");
                    s.user_issue_fence(function () {
                        _this.print("load completed.");
                        _this.print("checking data...");
                        var is = s.user_get_items_in_domain("customer()");
                        _this.assert(is.length == 4);
                        var es = s.user_get_entries_in_indexdomain("customertable[customer()]");
                        _this.assert(es.length == 3);
                        _this.print("DATA:");
                        var lines = s.user_dump_stable_data(function (b) { return _this.assert(b); });
                        var ref = ["new|customer()|1.1", "new|customer()|1.2", "new|customer()|1.3", "new|customer()|1.4", "mod|name,string[customertable[customer()]]|1.1|+Alice", "mod|name,string[customertable[customer()]]|1.2|+Bob", "mod|name,string[customertable[customer()]]|1.3|+Charlie"];
                        _this.assert(lines.length == ref.length);
                        for (var i = 0; i < lines.length; i++) {
                            _this.assert(lines[i] === ref[i]);
                            _this.print(lines[i]);
                        }
                        _this.print("test completed.");
                    }, true);
                }, true);
            };
            return SessionTests;
        })();
        Revisions.SessionTests = SessionTests;
    })(Revisions = TDev.Revisions || (TDev.Revisions = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var SVG;
    (function (SVG) {
        var actionIcon = "M 90,129L 240,129L 240,149L 90,149L 90,129 Z M 140,169L 240,169L 240,189L 140,189L 140,169 Z M 140,209L 240,209L 240,229L 140,229L 140,209 Z M 190,249L 370,249L 370,269L 190,269L 190,249 Z M 90,289L 370,289L 370,309L 90,309L 90,289 Z M 140,329L 370,329L 370,349L 140,349L 140,329 Z M 140,369L 370,369L 370,389L 140,389L 140,369 Z M ";
        var codeSigns = {
            "\u2339": svgBoilerPlate('0 0 380 380', "<path fill='#000000' d=' M 263.5,153.201L 263.5,181.142L 263.5,181.799L 71.5,181.799L 71.5,181.142L 71.5,153.201L 71.5,152.543L 263.5,152.543L 263.5,153.201 Z M 2.79943e-005,0L 335,0L 335,335L 2.79943e-005,335L 2.79943e-005,0 Z M 24.4999,24.5L 24.4999,310.5L 310.5,310.5L 310.5,24.5L 24.4999,24.5 Z M 167.5,66.6287C 180.203,66.6287 190.5,76.926 190.5,89.6286C 190.5,102.331 180.203,112.629 167.5,112.629C 154.797,112.629 144.5,102.331 144.5,89.6286C 144.5,76.926 154.797,66.6287 167.5,66.6287 Z M 167.5,267.714C 154.797,267.714 144.5,257.416 144.5,244.714C 144.5,232.011 154.797,221.714 167.5,221.714C 180.203,221.714 190.5,232.011 190.5,244.714C 190.5,257.416 180.203,267.714 167.5,267.714 Z '/>"),
            "\u25f3": svgBoilerPlate('0 0 380 380', "<path fill='#000000' d=' M 179.812,155.187L 310.5,155.187L 310.5,24.4998L 179.812,24.4998L 179.812,155.187 Z M 155.172,179.812L 155.172,155.187L 155.188,155.187L 155.188,24.4999L 24.4999,24.4999L 24.4999,310.5L 310.5,310.5L 310.5,179.812L 155.172,179.812 Z M -2.2889e-005,0L 335,0L 335,335L -2.2889e-005,335L -2.2889e-005,0 Z '/>"),
        };
        var scriptIcons = {};
        function loadScriptIcons(icons) {
            scriptIcons = icons;
        }
        SVG.loadScriptIcons = loadScriptIcons;
        var icons = {
            findrefs: "M 100,240L 176,240L 91,155L 117,130L 202,215L 202,138L 232,168L 232,270L 130,270L 100,240 Z M 278,138L 278,215L 363,130L 388,155L 303,240L 380,240L 350,270L 248,270L 248,168L 278,138 Z M 240,279C 260,279 277,296 277,317C 277,337 260,354 240,354C 219,354 203,337 203,317C 203,296 219,279 240,279 Z ",
            back: "M 272,137L 213,137L 112,238L 213,340L 272,340L 196,264L 365,264L 365,213L 196,213L 272,137 Z ",
            select: "M 248,139L 313,120L 313,119L 313,119L 341,119L 341,354L 313,354L 313,354L 313,353L 248,334L 313,315L 313,158L 248,139 Z M 297,175L 297,202L 127,202L 127,175L 297,175 Z M 297,221L 297,249L 127,249L 127,221L 297,221 Z M 297,266L 297,294L 127,294L 127,266L 297,266 Z ",
            add: "M 219,119L 260,119L 260,220L 361,220L 361,261L 260,261L 260,363L 219,363L 219,261L 117,261L 117,220L 219,220L 219,119 Z ",
            color: "M 219,360C 190,355 163,341 145,322C 137,314 135,311 130,302C 115,272 113,230 125,198C 134,174 152,150 171,134C 181,127 198,118 209,115C 223,112 240,112 251,116C 262,119 268,123 275,131C 284,140 287,151 286,165C 285,169 282,180 279,190C 270,215 270,219 269,234C 268,246 268,247 267,247C 262,247 254,251 250,255C 245,259 240,266 237,278C 234,287 231,289 221,292C 216,293 213,293 213,293C 212,293 212,290 211,287C 207,273 192,265 179,269C 161,274 154,294 164,309C 169,318 182,323 192,320C 194,319 198,318 200,316L 204,314L 209,316C 213,318 232,323 237,323C 240,323 240,324 245,330C 253,341 269,343 280,336C 286,333 291,325 292,319C 292,315 293,314 298,310C 305,304 310,295 310,290C 310,286 311,286 314,284C 316,283 319,281 320,280C 322,279 322,279 324,282C 326,283 328,287 329,290C 332,295 332,297 332,307C 332,316 332,318 329,324C 322,338 302,351 272,358C 259,361 231,362 219,360 Z M 176,239C 182,236 188,230 190,224C 194,216 191,203 185,196C 172,183 150,187 142,203C 139,208 139,219 141,224C 147,238 163,245 176,239 Z M 239,193C 249,188 254,180 254,169C 254,161 252,155 246,150C 241,145 236,143 229,143C 215,143 203,152 202,166C 199,186 221,201 239,193 Z M 239,314C 232,312 218,309 214,307C 210,306 211,305 221,302C 238,299 242,295 248,276C 251,267 257,260 264,259C 269,258 270,258 272,262C 278,278 281,281 292,284C 295,285 298,287 299,288C 303,293 289,306 274,312C 267,314 249,315 239,314 Z M 294,277C 290,275 284,269 282,265C 280,260 281,254 285,249C 289,243 310,222 336,197C 366,169 374,163 385,163C 397,163 396,174 383,194C 365,221 330,260 314,271C 304,278 300,280 294,277 Z ",
            script: "M 145,329L 145,314L 176,314L 176,345L 145,345M 197,329L 197,314L 381,314L 381,345L 197,345M 145,278L 145,263L 279,263L 279,293L 145,293M 145,227L 145,212L 176,212L 176,242L 145,242M 197,227L 197,212L 381,212L 381,242L 197,242M 145,176L 145,160L 176,160L 176,191L 145,191M 197,176L 197,160L 381,160L 381,191L 197,191M 145,124L 145,108L 279,108L 279,140L 145,140",
            cursorright: "M 145,372L 204,372L 323,239L 204,105L 145,105L 264,239L 145,372",
            cursorleft: "M 323,105L 264,105L 145,238L 264,372L 323,372L 204,238L 323,105",
            actionlocation: actionIcon + "322,214L 373,162L 259,162L 259,128L 373,128L 322,77L 362,77L 430,145L 362,214L 322,214 Z ",
            actionevent: actionIcon + "333,70L 398,70L 342,128L 392,128L 289,231L 330,149L 283,149L 333,70 Z ",
            play: "M 353,238L 171,139L 171,338L 353,238 Z ",
            touchdevelop: "M 325.771,240.507L 256.702,292.393L 256.702,188.608L 325.771,240.507 Z M 275.211,115.775C 343.573,113.37 400.414,167.062 402.864,234.975C 404.979,302.949 351.353,360.095 283.378,362.207C 240.754,363.628 202.621,343.247 179.365,311.196L 191.855,302.111C 212.239,330.188 245.485,348.056 282.862,346.829C 342.441,344.974 389.341,295.087 387.486,235.491C 385.322,175.842 335.761,129.107 275.822,131.267L 275.727,131.267C 245.163,132.189 218.147,145.678 198.99,166.69L 187.512,156.267C 209.335,132.35 240.382,116.857 275.211,115.775 Z M 143.005,154.602C 176.572,154.602 204.154,181.844 204.154,215.751C 204.154,249.658 176.572,276.806 143.005,276.806C 109.437,276.806 81.2436,249.741 81.2436,215.751C 81.2436,181.766 109.437,154.602 143.005,154.602 Z M 143.005,165.141C 115.101,165.141 91.7829,187.608 91.7829,215.751C 91.7829,239.424 108.257,258.99 130.081,264.628L 120.282,229.356L 118.637,223.613L 167.182,223.613L 165.306,229.472L 154.771,264.908C 177.02,259.672 193.615,239.881 193.615,215.751C 193.615,187.525 170.908,165.141 143.005,165.141 Z M 143.005,266.266L 144.495,266.245L 154.577,232.793L 131.032,232.793L 140.295,266.196L 143.005,266.266 Z M 114.907,279.177L 169.437,279.177L 169.437,284.792L 114.907,289.084L 114.907,279.177 Z M 169.437,288.762L 169.437,296.364L 114.907,300.656L 114.907,293.055L 169.437,288.762 Z M 169.437,300.334L 169.437,306.936L 115.568,311.229L 114.907,304.627L 169.437,300.334 Z M 116.894,314.873L 125.818,314.212L 160.514,311.229L 169.115,310.564L 168.776,311.568L 167.471,314.873L 165.145,319.83C 164.162,321.475 162.84,323.462 160.852,325.123C 158.869,326.767 156.221,328.415 153.251,329.738C 150.284,331.06 146.975,331.725 144.327,332.064C 141.36,332.386 139.034,332.064 136.725,331.725C 134.419,331.06 131.771,330.399 129.788,329.077C 127.801,328.093 125.818,326.767 124.169,325.445C 122.508,324.123 121.186,322.474 119.86,320.491C 118.538,318.826 117.555,317.182 116.894,314.873 Z ",
            undo: "M 256,133C 228,133 202,143 183,163C 174,172 166,183 161,194L 121,148L 121,260L 220,260L 186,221C 189,208 195,195 205,185C 219,172 237,164 256,164C 275,164 293,172 306,185C 320,199 327,217 327,236C 327,255 320,273 306,287C 300,293 300,303 306,309C 310,312 314,314 318,314C 322,314 326,312 329,309C 348,290 359,264 359,236C 359,208 348,182 329,163C 309,143 283,133 256,133 Z ",
            cut: "M 328,324C 325,330 322,333 318,333C 315,333 311,331 308,327L 289,301L 289,299L 276,282L 273,277C 277,272 283,267 291,267C 299,267 307,272 316,281C 331,297 332,315 328,324 Z M 173,326C 165,335 157,334 153,324C 149,315 149,297 165,281C 174,272 182,267 189,267C 197,267 204,273 208,277L 196,293L 192,299L 192,300L 173,326 Z M 333,265C 320,251 305,243 291,243C 277,243 266,251 258,258L 256,254L 262,246L 292,227L 336,156L 336,109L 241,235L 146,109L 146,156L 189,227L 219,246L 225,255L 223,258C 215,251 204,243 189,243C 175,243 161,251 148,265C 124,289 124,317 131,334C 137,348 152,357 165,357C 171,357 192,342 193,341L 204,325L 241,275L 278,326L 290,342C 290,343 310,357 316,357C 330,357 343,348 349,334C 356,317 357,289 333,265 Z ",
            search: "M 277,139C 310,139 338,166 338,200C 338,233 310,261 277,261C 243,261 216,233 216,200C 216,166 243,139 277,139 Z M 156,354L 233,277C 246,284 261,288 277,288C 325,288 365,248 365,200C 365,151 325,112 277,112C 228,112 189,151 189,200C 189,218 194,235 204,249L 127,325C 123,329 122,334 122,339C 122,345 123,350 127,354C 135,362 148,362 156,354 Z ",
            history: "M 343,215L 378,181L 343,146L 257,146L 257,112L 223,112L 223,146L 154,146L 154,215L 223,215L 223,232L 136,232L 102,267L 136,301L 223,301L 223,388L 257,388L 257,301L 326,301L 326,232L 257,232L 257,215L 343,215 Z ",
            edit: "M 135,344L 141,303L 175,337L 135,344 Z M 195,331L 147,283L 269,160L 318,209L 195,331 Z M 328,198L 281,150L 290,141L 294,137C 306,125 327,127 340,139C 352,152 353,173 341,185C 340,186 340,186 339,188L 328,198 Z ",
            backspace: "M 242,198L 267,224L 293,198L 308,213L 282,238L 308,264L 293,279L 267,253L 242,279L 227,264L 253,238L 227,213L 242,198 Z M 75,238L 173,161L 349,161L 349,316L 173,316L 75,238 Z M 105,238L 182,300L 333,300L 333,177L 182,177L 105,238 Z ",
            hammer: "M 251,118C 256,115 268,109 283,109C 298,109 316,116 328,123C 340,130 346,137 349,141C 352,145 352,145 350,147C 348,150 343,154 344,160C 345,166 352,174 357,175C 362,176 367,171 370,169C 373,167 375,170 377,172C 378,174 380,177 380,179C 380,181 379,183 373,189C 367,195 356,206 351,212C 345,217 345,217 343,217C 342,217 339,217 337,216C 334,215 332,212 332,209C 331,207 332,204 333,202C 334,200 336,198 337,196C 338,194 338,192 336,190C 334,187 330,185 327,183C 323,181 320,181 318,182C 315,183 312,185 298,198C 284,211 259,234 246,247C 234,259 234,260 234,261C 235,263 235,264 232,268C 229,272 223,278 209,291C 195,305 174,326 163,337C 152,348 152,348 150,348C 149,348 146,348 142,344C 138,341 133,335 130,331C 128,327 128,326 142,312C 156,298 185,270 199,256C 214,242 214,242 215,242C 216,243 218,243 220,244C 221,244 221,244 234,232C 247,220 272,195 284,183C 297,170 297,170 298,166C 300,163 303,156 302,149C 302,142 297,134 291,130C 285,125 276,124 269,124C 262,123 255,123 252,122C 248,122 246,122 251,118 Z ",
            circleplus: "M 236.481,4.8425C 365.798,4.8425 470.63,109.674 470.63,238.991C 470.63,368.307 365.798,473.139 236.481,473.139C 107.165,473.139 2.33301,368.307 2.33301,238.991C 2.33301,109.674 107.165,4.8425 236.481,4.8425 Z M 236.481,26.9594C 119.379,26.9594 24.4499,121.889 24.4499,238.991C 24.4499,356.092 119.38,451.022 236.481,451.022C 353.583,451.022 448.513,356.092 448.513,238.991C 448.513,121.889 353.583,26.9594 236.481,26.9594 Z M 255.648,137.451L 255.648,219.824L 338.02,219.824L 338.02,258.157L 255.648,258.157L 255.648,340.53L 217.315,340.53L 217.315,258.157L 134.942,258.157L 134.942,219.824L 217.315,219.824L 217.315,137.451L 255.648,137.451 Z ",
            cancel: "M 172.862,139.945L 240.453,207.537L 308.045,139.945L 339.499,171.399L 271.907,238.991L 339.499,306.582L 308.045,338.036L 240.453,270.445L 172.862,338.036L 141.408,306.582L 208.999,238.991L 141.408,171.399L 172.862,139.945 Z ",
            stop: "M 153,153L 326,153L 326,326L 153,326L 153,326 Z ",
            gameboard: "M 154.865,98.1082L 154.865,154.865L 211.622,154.865L 211.622,98.1089L 154.865,98.1082 Z M 98.1082,90.0002L 381.892,90.0002L 390,90.0002L 390,390L 381.892,390L 98.1082,390L 90.0001,390L 90.0001,90.0001L 98.1082,90.0002 Z M 98.1081,325.136L 154.865,325.136L 154.865,268.379L 98.108,268.379L 98.1081,325.136 Z M 98.108,211.622L 154.865,211.622L 154.865,154.866L 98.1081,154.865L 98.108,211.622 Z M 381.892,154.865L 325.135,154.865L 325.135,98.1089L 268.378,98.109L 268.378,154.866L 325.135,154.866L 325.135,211.622L 381.892,211.622L 381.892,154.865 Z M 381.892,268.379L 325.135,268.379L 325.135,325.136L 381.892,325.136L 381.892,268.379 Z M 325.135,268.379L 325.135,211.622L 268.378,211.622L 268.378,268.379L 325.135,268.379 Z M 325.135,381.892L 325.135,325.136L 268.378,325.136L 268.378,381.892L 325.135,381.892 Z M 211.622,381.892L 211.622,325.136L 154.865,325.136L 154.865,381.892L 211.622,381.892 Z M 211.622,154.865L 211.622,211.622L 268.378,211.622L 268.378,154.866L 211.622,154.865 Z M 268.378,268.379L 211.622,268.379L 211.622,325.136L 268.378,325.136L 268.378,268.379 Z M 154.865,268.379L 211.622,268.379L 211.622,211.622L 154.865,211.622L 154.865,268.379 Z ",
            follower: "M 240.779,79.9986C 226.097,79.9986 214.194,91.9003 214.194,106.582C 214.194,121.258 226.097,133.16 240.779,133.16C 255.455,133.16 267.357,121.258 267.357,106.582C 267.357,91.9003 255.455,79.9986 240.779,79.9986 Z M 213.625,146.396C 204.769,146.396 195.965,149.489 189.708,154.791C 183.446,160.1 179.802,167.559 179.802,175.059L 179.802,175.818C 179.784,176.15 179.784,176.476 179.802,176.808L 179.802,288.21C 179.749,293.4 185.117,298.181 191.107,298.258C 197.202,298.335 202.802,293.5 202.743,288.21L 202.743,192.312L 210.1,192.312L 210.1,285.515L 210.137,285.515L 210.137,385.659C 210.041,392.01 215.729,397.883 222.081,397.983C 225.321,398.03 228.562,396.721 230.855,394.427C 233.143,392.136 234.458,388.901 234.404,385.659L 234.404,285.515L 246.538,285.515L 246.538,385.659C 246.443,392.01 252.13,397.883 258.482,397.983C 261.722,398.03 264.963,396.721 267.257,394.427C 269.544,392.136 270.859,388.901 270.806,385.659L 270.806,285.515L 270.847,285.515L 270.847,192.312L 278.163,192.312L 278.163,289.614C 278.082,294.827 283.49,299.638 289.504,299.698C 295.6,299.757 301.187,294.905 301.104,289.614L 301.104,178.247C 301.116,177.958 301.116,177.666 301.104,177.377L 301.104,175.059C 301.104,167.559 297.461,160.1 291.204,154.791C 284.942,149.489 276.137,146.396 267.279,146.396",
            nicehammer: "M 260.037,115.075C 264.533,111.92 274.714,105.811 288.337,105.666C 301.96,105.52 319.025,111.338 330.176,117.64C 341.326,123.943 346.562,130.73 349.18,134.172C 351.798,137.614 351.798,137.711 349.956,139.796C 348.114,141.88 344.429,145.953 345.496,151.48C 346.562,157.006 352.38,163.988 357.276,164.909C 362.173,165.83 366.148,160.691 368.96,159.091C 371.772,157.491 373.421,159.43 374.923,161.612C 376.426,163.794 377.784,166.218 378.123,168.108C 378.462,169.999 377.784,171.357 372.439,177.102C 367.094,182.846 357.083,192.979 351.956,198.118C 346.829,203.257 346.587,203.402 345.241,203.499C 343.896,203.596 341.448,203.645 339.29,202.433C 337.133,201.221 335.266,198.748 334.612,196.421C 333.957,194.094 334.515,191.912 335.727,189.961C 336.939,188.01 338.805,186.289 339.593,184.519C 340.381,182.749 340.09,180.931 338.236,178.726C 336.381,176.52 332.964,173.926 329.873,172.544C 326.782,171.163 324.019,170.993 321.413,171.829C 318.807,172.666 316.359,174.508 301.52,188.886C 286.681,203.265 259.451,230.18 245.902,244.041C 232.352,257.902 232.484,258.71 232.743,259.951C 233.003,261.191 233.391,262.863 230.837,266.31C 228.284,269.757 222.789,274.978 206.547,291.429C 190.305,307.88 163.316,335.561 149.773,349.402C 136.23,363.242 136.133,363.242 134.792,363.242C 133.45,363.242 130.865,363.242 127.168,360.337C 123.471,357.433 118.664,351.623 116.26,348.331C 113.856,345.038 113.856,344.262 130.465,327.068C 147.073,309.873 180.29,276.26 196.996,259.518C 213.702,242.776 213.896,242.906 214.962,243.197C 216.029,243.487 217.968,243.94 219.164,244.198C 220.36,244.457 220.812,244.522 234.532,230.753C 248.252,216.985 275.239,189.383 288.782,175.405C 302.324,161.426 302.421,161.071 303.762,157.855C 305.103,154.639 307.689,148.563 306.913,142.034C 306.138,135.505 302.001,128.524 296.215,124.646C 290.43,120.767 282.996,119.992 276.338,119.507C 269.68,119.022 263.798,118.828 260.263,118.63C 256.728,118.432 255.54,118.23 260.037,115.075 Z ",
            resume: "M 379.088,238.991L 200.911,336.845L 200.911,141.136L 379.088,238.991 Z M 150.921,141.091L 181.27,141.091L 181.27,336.89L 150.921,336.89L 150.921,141.091 Z ",
            pausesq: "M 256.877,141.174L 295.645,141.174L 295.645,336.807L 256.877,336.807L 256.877,141.174 Z M 185.261,141.174L 224.029,141.174L 224.029,336.807L 185.261,336.807L 185.261,141.174 Z ",
            experiment: "M 364.4,192.137L 364.363,192.112L 225.122,99.8953L 232.252,89.1295L 291.226,128.169L 336.644,128.169L 246.104,68.215L 253.232,57.4525L 392.51,149.694C 404.23,157.456 407.439,173.25 399.676,184.97C 391.914,196.69 376.121,199.899 364.4,192.137 Z M 200.75,294.907C 206.525,294.907 211.207,299.589 211.207,305.364C 211.207,311.139 206.525,315.82 200.75,315.82C 194.975,315.82 190.293,311.139 190.293,305.364C 190.293,299.589 194.975,294.907 200.75,294.907 Z M 223.827,267.863C 229.602,267.863 234.284,272.545 234.284,278.32C 234.284,284.095 229.602,288.777 223.827,288.777C 218.052,288.777 213.37,284.095 213.37,278.32C 213.37,272.545 218.052,267.863 223.827,267.863 Z M 217.343,195.686C 223.118,195.686 227.8,200.368 227.8,206.143C 227.8,211.918 223.118,216.6 217.343,216.6C 211.568,216.6 206.886,211.918 206.886,206.143C 206.886,200.368 211.568,195.686 217.343,195.686 Z M 95.4793,378.08L 190.255,258.966L 190.255,138.415L 204.394,138.415L 204.394,267.793L 159.43,325.71L 275.622,325.71L 230.659,267.792L 230.659,138.415L 244.797,138.415L 244.797,258.966L 339.573,378.08L 95.4793,378.08 Z M 183.646,337.876C 177.87,337.876 173.189,342.558 173.189,348.333C 173.189,354.108 177.87,358.79 183.646,358.79C 189.421,358.79 194.102,354.108 194.102,348.333C 194.102,342.558 189.421,337.876 183.646,337.876 Z M 238.19,328.321C 232.415,328.321 227.733,333.002 227.733,338.777C 227.733,344.553 232.415,349.234 238.19,349.234C 243.965,349.234 248.647,344.553 248.647,338.777C 248.647,333.002 243.965,328.321 238.19,328.321 Z ",
            stackpoint: "M 288.576,32.0641L 464.928,240.48L 288.576,464.928L 288.576,320.64C 235.136,320.64 181.696,320.64 133.6,293.839C 85.5041,267.039 42.752,213.438 29.392,162.67C 16.032,111.902 32.064,63.9671 48.0961,16.032C 74.8161,69.472 101.536,122.912 141.616,149.632C 181.696,176.352 235.136,176.352 288.576,176.352L 288.576,32.0641 Z",
            breakpoint: "M 240.48,64.1281C 143.084,64.1281 64.128,143.084 64.128,240.48C 64.128,337.877 143.084,416.832 240.48,416.832C 337.877,416.832 416.832,337.877 416.832,240.48C 416.832,143.084 337.877,64.1281 240.48,64.1281 Z",
            currentpoint: "M 288.576, 32.0641L 464.928, 240.48L 288.576, 464.928L 288.576, 320.64L 64.128, 320.64L 64.128, 176.352L 288.576, 176.352L 288.576, 32.0641 Z",
            stepin: "M 288.576,272.544L 384.768,272.544L 384.768,368.736L 288.576,368.736L 288.576,272.544 Z M 208.416,256.512L 272.544,320.64L 208.416,384.768L 144.288,384.768L 176.352,352.704C 133.6,352.704 90.848,352.704 69.472,312.624C 48.096,272.544 48.096,192.384 77.488,152.304C 106.88,112.224 165.664,112.224 224.448,112.224L 224.448,176.352C 187.04,176.352 149.632,176.352 130.928,195.056C 112.224,213.76 112.224,251.168 122.912,269.872C 133.6,288.576 154.976,288.576 176.352,288.576L 144.288,256.512L 208.416,256.512 Z",
            stepover: "M 224,160L 320,160L 320,256L 224,256L 224,160 Z M 288,288L 352,352L 288,416L 224,416L 256,384C 202.667,384 149.333,384 122.667,330.667C 96,277.333 96,170.667 122.667,117.333C 149.333,64 202.667,64 256,64L 256,128C 224,128 192,128 176,160C 160,192 160,256 176,288C 192,320 224,320 256,320L 224,288L 288,288 Z",
            stepout: "M 272.544,288.576L 368.736,288.576L 368.736,384.768L 272.544,384.768L 272.544,288.576 Z M 296.926,224.448L 361.054,160.32L 296.926,96.192L 232.798,96.192L 264.862,128.256C 200.734,128.256 136.606,128.256 104.542,168.336C 72.478,208.416 72.478,288.576 101.87,328.656C 131.262,368.736 190.046,368.736 248.83,368.736L 248.83,304.608C 211.422,304.608 174.014,304.608 155.31,285.904C 136.606,267.2 136.606,229.792 157.982,211.088C 179.358,192.384 222.11,192.384 264.862,192.384L 232.798,224.448L 296.926,224.448 Z",
            bug: "M 292.799,197.661C 299.238,200.966 301.197,209.996 297.176,217.83C 295.167,221.744 292.045,224.618 288.62,226.103C 290.629,232.763 291.696,240.224 291.803,248.223C 297.67,249.987 304.994,252.703 309.852,254.9C 315.641,257.519 317.928,259.4 320.115,265.05C 322.302,270.701 324.39,280.121 325.146,292.748C 325.902,305.375 325.326,321.209 323.033,323.428C 320.74,325.646 316.73,314.249 314.514,303.137C 312.299,292.025 311.878,281.197 311.642,275.628C 311.406,270.06 311.355,269.751 309.385,268.48C 307.415,267.209 303.526,264.976 299.269,263.357C 296.524,262.313 293.626,261.524 291.2,261.006C 289.985,272.614 286.958,284.971 282.073,297.402C 283.702,298.245 285.222,299.07 286.539,299.83C 291.843,302.893 293.856,304.916 295.416,310.544C 296.976,316.172 298.081,325.406 297.604,337.59C 297.126,349.774 295.066,364.908 292.655,366.818C 290.244,368.728 287.483,357.413 286.417,346.543C 285.35,335.673 285.978,325.247 286.282,319.883C 286.586,314.519 286.566,314.218 284.797,312.811C 283.32,311.636 280.623,309.691 277.486,307.941C 276.823,309.327 276.136,310.713 275.426,312.096C 270.586,321.523 265.021,330.133 258.986,337.767C 260.824,339.452 262.539,341.108 263.918,342.54C 267.756,346.525 268.998,348.784 268.944,354.059C 268.89,359.334 267.54,367.625 264.079,378.081C 260.617,388.536 255.044,401.156 252.475,402.211C 249.905,403.266 250.338,392.755 252.13,383.054C 253.923,373.352 257.075,364.46 258.68,359.881C 260.286,355.301 260.344,355.035 259.161,353.371C 257.977,351.708 255.552,348.648 252.632,345.966C 252.515,345.858 252.397,345.751 252.278,345.645C 230.233,369.66 203.612,381.193 183.106,373.604L 239.423,257.632L 177.902,371.186C 158.057,359.941 151.05,330.794 157.811,297.747C 157.357,297.637 156.901,297.533 156.444,297.438C 152.473,296.61 148.483,296.418 146.395,296.426C 144.306,296.434 144.12,296.641 141.27,300.707C 138.42,304.772 132.907,312.695 125.911,319.97C 118.915,327.245 110.436,333.872 109.78,331.107C 109.124,328.341 116.292,316.183 122.92,307.071C 129.548,297.959 135.636,291.893 139.989,288.703C 144.342,285.513 146.961,285.198 152.562,286.012C 154.806,286.339 157.529,286.846 160.333,287.449C 163.024,278.004 166.804,268.366 171.693,258.842C 172.45,257.367 173.225,255.912 174.017,254.478C 170.422,252.71 166.829,251.497 164.827,250.928C 162.603,250.296 162.341,250.46 158.063,253.911C 153.785,257.362 145.492,264.101 135.819,269.696C 126.146,275.291 115.094,279.742 115.244,276.599C 115.394,273.456 126.747,262.72 136.591,255.057C 146.435,247.395 154.771,242.808 160.38,240.749C 165.989,238.689 168.871,239.157 174.58,241.74C 176.221,242.483 178.097,243.401 180.059,244.415C 187.485,233.022 195.966,223.249 204.893,215.474C 202.919,213.6 200.195,211.32 197.31,209.409C 193.426,206.836 189.251,204.934 187.02,204.054C 184.789,203.174 184.501,203.316 179.731,206.44C 174.961,209.564 165.709,215.671 155.15,220.455C 144.59,225.24 132.725,228.702 133.202,225.472C 133.679,222.243 146.499,212.323 157.447,205.422C 168.395,198.521 177.471,194.64 183.473,193.089C 189.474,191.538 192.401,192.317 198.03,195.568C 203.089,198.491 210.331,203.411 215.377,207.398C 220.512,203.941 225.713,201.157 230.873,199.111C 230.904,196.199 231.633,193.135 233.128,190.224C 237.47,181.765 246.627,177.801 253.58,181.37C 258.671,183.984 261.168,189.911 260.437,196.218C 261.218,196.418 261.993,196.644 262.759,196.896C 271.644,169.666 279.848,143.046 281.456,122.34C 283.248,99.2486 276.837,83.5108 271.788,73.9875C 266.739,64.4644 263.051,61.1559 263.828,58.6207C 264.604,56.0857 269.845,54.3239 275.163,57.0064C 280.481,59.6888 285.876,66.8152 288.889,82.9933C 291.903,99.1714 292.534,124.401 287.268,146.464C 282.807,165.148 274.117,181.562 264.779,197.627C 265.844,198.05 266.893,198.525 267.923,199.053C 269.165,199.691 270.36,200.397 271.507,201.166C 279.203,190.277 287.4,179.795 298.365,171.556C 311.758,161.494 329.278,154.778 341.378,152.35C 353.477,149.922 360.155,151.782 363.759,154.849C 367.362,157.916 367.89,162.191 366.408,163.47C 364.926,164.75 361.434,163.035 353.226,162.105C 345.018,161.176 332.094,161.032 316.844,168.885C 303.547,175.733 288.482,188.661 273.19,202.368C 273.822,202.846 274.437,203.346 275.037,203.865C 279.377,197.427 286.935,194.65 292.799,197.661 Z ",
            twobugs: " M 217.767,207.218C 222.158,209.472 223.494,215.63 220.751,220.973C 219.381,223.642 217.252,225.602 214.917,226.614C 216.287,231.156 217.014,236.245 217.088,241.7C 219.876,242.538 223.148,243.692 225.996,244.821C 228.874,241.683 233.516,237.555 237.748,234.26C 244.462,229.035 250.146,225.907 253.971,224.502C 257.796,223.098 259.762,223.417 263.655,225.179L 267.392,227.003C 272.456,219.233 278.24,212.568 284.327,207.266C 282.981,205.989 281.123,204.433 279.156,203.13C 276.507,201.376 273.66,200.078 272.139,199.478C 270.617,198.878 270.421,198.975 267.168,201.105C 263.915,203.236 257.605,207.401 250.404,210.663C 243.204,213.926 235.112,216.287 235.437,214.085C 235.763,211.883 244.505,205.118 251.971,200.412C 259.437,195.705 265.627,193.059 269.719,192.001C 273.812,190.943 275.808,191.474 279.647,193.692C 283.097,195.685 288.036,199.04 291.477,201.759C 294.979,199.402 298.526,197.503 302.044,196.107C 302.065,194.121 302.563,192.032 303.582,190.047C 306.543,184.278 312.788,181.575 317.53,184.009C 321.001,185.791 322.704,189.833 322.205,194.135L 323.789,194.597C 329.848,176.027 335.443,157.874 336.539,143.753C 337.762,128.006 333.39,117.274 329.946,110.779C 326.503,104.285 323.988,102.029 324.518,100.3C 325.047,98.5709 328.621,97.3695 332.248,99.1988C 335.874,101.028 339.554,105.888 341.609,116.921C 343.664,127.953 344.094,145.159 340.503,160.204C 337.461,172.947 331.535,184.14 325.166,195.096L 327.311,196.068C 328.158,196.503 328.972,196.984 329.755,197.509C 335.003,190.083 340.593,182.935 348.071,177.317C 357.204,170.454 369.152,165.875 377.403,164.219C 385.655,162.563 390.209,163.831 392.666,165.923C 395.124,168.015 395.484,170.93 394.473,171.802C 393.462,172.675 391.081,171.505 385.483,170.871C 379.886,170.238 371.072,170.139 360.673,175.495C 351.605,180.165 341.331,188.981 330.903,198.328L 332.162,199.35C 335.122,194.959 340.276,193.066 344.275,195.119C 348.666,197.373 350.002,203.531 347.26,208.873C 345.89,211.542 343.76,213.502 341.425,214.515C 342.795,219.056 343.523,224.145 343.596,229.6C 347.597,230.803 352.592,232.655 355.904,234.153C 359.852,235.939 361.412,237.222 362.903,241.075C 364.395,244.929 365.818,251.352 366.334,259.963C 366.849,268.575 366.457,279.373 364.893,280.886C 363.329,282.399 360.595,274.627 359.084,267.048C 357.573,259.47 357.286,252.086 357.125,248.289C 356.964,244.491 356.929,244.28 355.586,243.414C 354.242,242.547 351.59,241.025 348.687,239.92C 346.815,239.208 344.839,238.67 343.185,238.317C 342.356,246.233 340.292,254.66 336.96,263.138L 340.006,264.793C 343.623,266.882 344.996,268.261 346.06,272.1C 347.123,275.938 347.877,282.235 347.552,290.544C 347.226,298.853 345.821,309.174 344.177,310.476C 342.533,311.778 340.65,304.063 339.922,296.65C 339.195,289.237 339.623,282.126 339.831,278.468C 340.038,274.811 340.024,274.605 338.818,273.646C 337.811,272.845 335.972,271.518 333.832,270.324L 332.427,273.158C 329.127,279.587 325.332,285.458 321.216,290.664C 322.47,291.814 323.639,292.943 324.58,293.92C 327.197,296.637 328.044,298.178 328.007,301.775C 327.97,305.372 327.05,311.027 324.689,318.157C 322.329,325.287 318.528,333.893 316.776,334.612C 315.023,335.331 315.318,328.164 316.541,321.548C 317.763,314.932 319.913,308.868 321.008,305.745C 322.102,302.622 322.142,302.44 321.335,301.306C 320.528,300.172 318.874,298.085 316.883,296.256L 316.642,296.037C 301.608,312.414 283.454,320.279 269.469,315.104L 307.875,236.016L 265.921,313.455C 252.387,305.786 247.609,285.909 252.22,263.373L 251.287,263.162C 248.579,262.597 245.858,262.466 244.434,262.472C 243.01,262.477 242.883,262.619 240.939,265.391C 240.523,265.984 240.025,266.698 239.45,267.501C 239.603,268.945 239.73,270.466 239.826,272.063C 240.341,280.674 239.948,291.472 238.385,292.985C 236.821,294.498 234.086,286.726 232.576,279.148C 232.414,278.34 232.267,277.533 232.132,276.734C 231.592,277.334 231.036,277.934 230.465,278.528C 226.488,282.664 221.807,286.493 220.101,286.559C 220.855,290.418 221.309,295.86 221.043,302.644C 220.718,310.953 219.312,321.273 217.668,322.575C 216.024,323.878 214.142,316.162 213.414,308.749C 212.687,301.336 213.115,294.226 213.322,290.568C 213.53,286.91 213.516,286.705 212.31,285.745C 211.303,284.944 209.463,283.617 207.324,282.424L 205.919,285.258C 202.619,291.687 198.824,297.558 194.708,302.764C 195.961,303.913 197.131,305.042 198.072,306.019C 200.688,308.737 201.535,310.277 201.499,313.875C 201.462,317.472 200.542,323.126 198.181,330.256C 195.82,337.387 192.02,345.993 190.267,346.712C 188.515,347.431 188.81,340.263 190.033,333.648C 191.255,327.032 193.405,320.968 194.499,317.845C 195.594,314.722 195.634,314.54 194.827,313.406C 194.02,312.271 192.366,310.185 190.375,308.355L 190.133,308.136C 175.1,324.513 156.946,332.379 142.961,327.203L 181.367,248.116L 139.412,325.554C 125.879,317.886 121.1,298.009 125.711,275.472L 124.779,275.261C 122.071,274.697 119.35,274.566 117.926,274.571C 116.502,274.577 116.374,274.718 114.431,277.491C 112.487,280.263 108.728,285.666 103.957,290.627C 99.1859,295.589 93.4034,300.108 92.9563,298.222C 92.5091,296.336 97.3974,288.045 101.917,281.831C 106.437,275.617 110.589,271.48 113.558,269.305C 116.526,267.129 118.312,266.915 122.131,267.47C 123.662,267.692 125.519,268.038 127.431,268.45C 129.266,262.009 131.844,255.436 135.178,248.941L 136.763,245.965C 134.312,244.759 131.861,243.932 130.496,243.544C 128.979,243.113 128.8,243.225 125.883,245.578C 122.966,247.932 117.31,252.527 110.714,256.343C 104.117,260.158 96.5803,263.194 96.6827,261.051C 96.7851,258.907 104.527,251.585 111.24,246.36C 117.953,241.135 123.638,238.007 127.463,236.602C 131.288,235.198 133.254,235.517 137.147,237.278L 140.883,239.102C 145.947,231.333 151.731,224.668 157.819,219.366C 156.473,218.088 154.615,216.533 152.648,215.23C 149.999,213.475 147.152,212.178 145.63,211.578C 144.109,210.978 143.913,211.074 140.66,213.205C 137.407,215.336 131.097,219.5 123.896,222.763C 116.695,226.026 108.604,228.387 108.929,226.184C 109.254,223.982 117.997,217.217 125.463,212.511C 132.929,207.805 139.118,205.158 143.211,204.1C 147.304,203.043 149.3,203.574 153.139,205.791C 156.589,207.784 161.528,211.14 164.968,213.858C 168.471,211.501 172.018,209.602 175.536,208.207C 175.557,206.221 176.055,204.132 177.074,202.147C 180.035,196.378 186.28,193.675 191.021,196.109C 194.493,197.891 196.196,201.933 195.697,206.234L 197.281,206.697C 203.34,188.127 208.935,169.974 210.031,155.853C 211.254,140.106 206.882,129.373 203.438,122.879C 199.995,116.384 197.48,114.128 198.01,112.399C 198.539,110.671 202.113,109.469 205.739,111.298C 209.366,113.128 213.045,117.988 215.1,129.02C 217.155,140.053 217.586,157.258 213.995,172.304C 210.953,185.046 205.026,196.239 198.658,207.195L 200.802,208.168C 201.649,208.603 202.464,209.084 203.246,209.609C 208.495,202.183 214.085,195.035 221.563,189.416C 230.696,182.554 242.644,177.974 250.895,176.319C 259.146,174.663 263.701,175.931 266.158,178.023C 268.615,180.114 268.976,183.029 267.965,183.902C 266.954,184.775 264.572,183.605 258.975,182.971C 253.377,182.337 244.564,182.239 234.164,187.595C 225.097,192.265 214.823,201.081 204.394,210.428L 205.654,211.449C 208.614,207.059 213.768,205.165 217.767,207.218 Z M 236.395,253.175C 236.976,254.676 237.547,256.568 238.057,258.827C 238.774,258.2 239.446,257.66 240.066,257.205C 243.035,255.03 244.82,254.815 248.64,255.37C 250.17,255.593 252.027,255.939 253.939,256.35C 255.774,249.909 258.352,243.336 261.686,236.841L 263.271,233.865C 260.82,232.66 258.37,231.832 257.004,231.444C 255.487,231.014 255.308,231.125 252.391,233.479C 249.474,235.832 243.818,240.428 237.222,244.243C 235.307,245.351 233.312,246.393 231.448,247.262C 233.949,248.636 235.194,250.072 236.395,253.175 Z M 230.617,260.388C 230.456,256.591 230.421,256.38 229.078,255.513C 227.734,254.647 225.082,253.124 222.179,252.02C 220.307,251.308 218.331,250.77 216.676,250.417C 215.848,258.333 213.783,266.76 210.452,275.237L 213.498,276.893C 217.114,278.982 218.488,280.361 219.551,284.199C 219.592,284.345 219.632,284.494 219.671,284.647C 220.669,281.477 224.674,274.889 228.426,269.732C 229.279,268.559 230.118,267.46 230.94,266.435C 230.765,263.992 230.681,261.904 230.617,260.388 Z ",
            bandage: "M 248.07,189.861L 289.582,231.373L 343.085,177.87C 350.508,170.447 350.508,158.412 343.085,150.989L 328.454,136.358C 321.031,128.935 308.996,128.935 301.574,136.358L 248.07,189.861 Z M 289.582,231.373L 232.836,288.12L 240.453,295.737L 297.2,238.991L 289.582,231.373 Z M 232.836,288.12L 191.324,246.608L 137.821,300.111C 130.398,307.534 130.398,319.569 137.821,326.992L 152.452,341.623C 159.875,349.046 171.91,349.046 179.333,341.623L 232.836,288.12 Z M 191.324,246.608L 248.07,189.861L 240.453,182.244L 183.707,238.991L 191.324,246.608 Z M 253.315,251.852C 255.495,249.672 255.495,246.138 253.315,243.958C 251.135,241.778 247.601,241.778 245.421,243.958C 243.241,246.138 243.241,249.672 245.421,251.852C 247.601,254.032 251.135,254.032 253.315,251.852 Z M 235.271,269.896C 237.451,267.717 237.451,264.182 235.271,262.002C 233.091,259.822 229.556,259.822 227.376,262.002C 225.196,264.182 225.196,267.717 227.376,269.896C 229.556,272.077 233.091,272.077 235.271,269.896 Z M 271.359,233.809C 273.539,231.629 273.539,228.094 271.359,225.914C 269.179,223.734 265.644,223.734 263.464,225.914C 261.284,228.094 261.284,231.629 263.464,233.809C 265.644,235.989 269.179,235.989 271.359,233.809 Z M 235.486,234.023C 237.666,231.843 237.666,228.309 235.486,226.129C 233.306,223.949 229.771,223.949 227.591,226.129C 225.411,228.309 225.411,231.843 227.591,234.023C 229.771,236.203 233.306,236.203 235.486,234.023 Z M 217.442,252.067C 219.622,249.887 219.622,246.353 217.442,244.173C 215.262,241.993 211.727,241.993 209.547,244.173C 207.367,246.353 207.367,249.887 209.547,252.067C 211.727,254.247 215.262,254.247 217.442,252.067 Z M 253.53,215.979C 255.71,213.799 255.71,210.265 253.53,208.085C 251.35,205.905 247.815,205.905 245.635,208.085C 243.455,210.265 243.455,213.799 245.635,215.979C 247.815,218.159 251.35,218.159 253.53,215.979 Z M 334.194,126.317L 353.126,145.25C 363.568,155.692 363.568,172.622 353.126,183.064L 297.2,238.991L 353.126,294.917C 363.568,305.359 363.568,322.289 353.126,332.732L 334.194,351.664C 323.752,362.106 306.822,362.106 296.38,351.664L 240.453,295.737L 184.527,351.664C 174.084,362.106 157.154,362.106 146.712,351.664L 127.78,332.732C 117.338,322.289 117.338,305.359 127.78,294.917L 183.707,238.991L 127.78,183.064C 117.338,172.622 117.338,155.692 127.78,145.25L 146.712,126.318C 157.154,115.875 174.084,115.875 184.527,126.318L 240.453,182.244L 296.38,126.318C 306.822,115.875 323.752,115.875 334.194,126.317 Z ",
            eye: "M 349.943,192.816C 353.79,209.607 345.604,223.355 341.548,218.002C 321.074,196.481 291.853,180.14 240.803,180.14C 195.394,180.14 141.395,202.522 131.663,234.793C 130.839,232.063 128.494,234.793 131.663,224.233C 143.803,188.948 198.826,159.234 265.989,159.234C 316.361,159.234 346.03,167.63 349.943,192.816 Z M 224.012,243.188L 209.43,227.165C 207.876,231.401 207.385,236.692 207.385,242.433C 207.385,256.342 215.617,268.375 224.012,268.375C 240.803,268.375 257.594,259.979 257.594,243.188C 257.594,229.278 238.086,217.246 224.176,217.246C 221.994,217.246 220.084,217.524 218.413,218.045L 224.012,243.188 Z M 299.735,250.828C 299.735,283.284 268.787,309.596 240.967,309.596C 213.147,309.596 182.199,283.284 182.199,250.828C 182.199,232.076 192.529,215.376 206.618,204.616C 170.27,212.023 141.014,230.95 133.526,255.781C 143.258,288.052 189.753,310.352 240.803,310.352C 291.853,310.352 338.348,288.052 348.08,255.781C 340.622,231.053 311.576,212.179 275.436,204.708C 289.464,215.471 299.735,232.13 299.735,250.828 Z M 280.633,283.423C 284.181,279.111 287.039,274.209 289.039,268.888L 264.787,254.886C 263.82,260.607 260.841,265.644 256.604,269.245L 256.745,269.632L 256.389,269.426C 252.205,272.899 246.83,274.987 240.967,274.987L 240.826,274.987L 250.404,301.301C 256.041,300.254 261.354,298.286 266.182,295.558C 271.719,292.43 276.618,288.304 280.633,283.423 Z M 349.741,247.386C 349.875,248.771 349.943,250.17 349.943,251.584C 349.943,254.442 349.664,257.243 349.125,259.979C 342.32,294.497 294.038,318.747 240.803,318.747C 187.568,318.747 139.286,294.497 132.481,259.979C 131.941,257.243 131.663,254.442 131.663,251.584C 131.663,250.17 131.731,248.771 131.865,247.386C 135.425,210.652 185.435,184.421 240.803,184.421C 296.171,184.421 346.181,210.652 349.741,247.386 Z M 240.803,335.538L 240.803,327.142L 240.803,335.538 Z M 240.803,142.443L 240.803,150.839L 240.803,142.443 Z",
            timer: "M 346.944,236.425C 346.944,290.093 298.523,333.6 238.792,333.6C 179.062,333.6 130.64,290.093 130.64,236.425C 130.64,186.531 172.492,145.419 226.373,139.884L 226.373,136.022C 211.128,132.468 200.029,121.559 200.029,108.653C 200.029,92.8638 216.641,80.064 237.132,80.064C 257.623,80.064 274.235,92.8638 274.235,108.653C 274.235,121.528 263.19,132.415 248.003,135.996L 248.003,139.598C 266.312,140.985 283.322,146.471 297.894,155.03L 313.116,139.487L 313.581,139.835C 313.62,139.783 313.662,139.734 313.708,139.686C 315.542,137.779 322.03,140.116 328.199,144.906C 334.129,149.51 337.605,154.704 336.238,156.794L 337.022,157.382L 321.223,173.514C 337.265,190.466 346.944,212.43 346.944,236.425 Z M 248.003,132.297C 260.554,128.861 269.541,119.629 269.541,108.78C 269.541,95.0001 255.043,83.8294 237.16,83.8294C 219.277,83.8294 204.779,95.0001 204.779,108.78C 204.779,119.645 213.793,128.889 226.373,132.312L 226.373,122.218L 220.168,122.218L 220.168,102.783L 254.235,102.783L 254.235,122.218L 248.003,122.218L 248.003,132.297 Z M 238.792,148.968C 185.035,148.968 141.456,188.124 141.456,236.425C 141.456,284.727 185.035,323.883 238.792,323.883C 292.549,323.883 336.128,284.727 336.128,236.425C 336.128,188.124 292.549,148.968 238.792,148.968 Z M 291.264,180.523L 256.618,235C 256.697,235.615 256.738,236.24 256.738,236.874C 256.738,245.765 248.716,252.972 238.821,252.972C 228.926,252.972 220.904,245.765 220.904,236.874C 220.904,228.4 228.191,221.455 237.442,220.822L 291.264,180.523 Z M 187.778,207.084C 186.399,208.951 185.144,210.899 184.022,212.917L 159.076,199.977C 160.24,197.982 161.494,196.036 162.833,194.143L 187.778,207.084 Z M 211.527,188.204C 209.281,189.212 207.113,190.34 205.034,191.579L 190.632,169.166C 192.738,167.963 194.904,166.836 197.125,165.791L 211.527,188.204 Z M 159.076,274.963L 184.022,262.022C 185.143,264.041 186.399,265.988 187.778,267.856L 162.833,280.796C 161.494,278.904 160.24,276.958 159.076,274.963 Z M 190.632,305.774L 205.034,283.36C 207.113,284.6 209.28,285.728 211.527,286.736L 197.125,309.149C 194.904,308.103 192.738,306.977 190.632,305.774 Z M 314.872,280.796L 289.927,267.856C 291.306,265.988 292.562,264.041 293.684,262.022L 318.629,274.963C 317.465,276.958 316.211,278.904 314.872,280.796 Z M 280.581,309.149L 266.179,286.736C 268.425,285.728 270.593,284.6 272.671,283.36L 287.074,305.774C 284.967,306.977 282.801,308.103 280.581,309.149 Z M 293.684,212.917C 292.562,210.899 291.306,208.951 289.927,207.083L 314.872,194.143C 316.211,196.036 317.465,197.982 318.629,199.977L 293.684,212.917 Z M 272.671,191.579C 270.593,190.34 268.425,189.212 266.179,188.204L 280.581,165.79C 282.801,166.836 284.967,167.963 287.074,169.166L 272.671,191.579 Z M 328.788,240.84L 299.989,240.84C 300.064,239.725 300.102,238.601 300.102,237.47C 300.102,236.338 300.064,235.215 299.989,234.1L 328.788,234.1L 328.865,237.47L 328.788,240.84 Z M 148.917,234.1L 177.716,234.1C 177.641,235.214 177.603,236.338 177.603,237.47C 177.603,238.601 177.641,239.725 177.716,240.839L 148.917,240.839L 148.841,237.47L 148.917,234.1 Z M 235.102,318.277L 235.102,292.401C 236.343,292.468 237.593,292.503 238.853,292.503C 240.112,292.503 241.363,292.468 242.603,292.401L 242.603,318.277L 238.853,318.346L 235.102,318.277 Z M 235.102,182.538L 235.102,156.662L 238.853,156.593L 242.603,156.662L 242.603,182.538C 241.363,182.471 240.112,182.437 238.853,182.437C 237.593,182.437 236.343,182.471 235.102,182.538 Z",
            chip: "M 136.738,226.451L 170.519,226.451L 170.519,195.786L 136.738,195.786L 136.738,170.707L 170.519,170.707L 170.519,135.695C 170.519,130.129 175.032,125.617 180.598,125.617L 300.309,125.617C 305.875,125.617 310.387,130.129 310.387,135.695L 310.387,170.707L 344.168,170.707L 344.168,195.786L 310.387,195.786L 310.387,226.451L 344.168,226.451L 344.168,251.53L 310.387,251.53L 310.387,282.184L 344.168,282.184L 344.168,307.263L 310.387,307.263L 310.387,342.286C 310.387,347.852 305.875,352.364 300.309,352.364L 180.598,352.364C 175.032,352.364 170.519,347.852 170.519,342.286L 170.519,307.263L 136.738,307.263L 136.738,282.184L 170.519,282.184L 170.519,251.53L 136.738,251.53L 136.738,226.451 Z ",
            "delete": " M 248,316C 231,316 215,311 202,302L 314,190C 323,203 328,219 328,236C 328,280 292,316 248,316 Z M 248,155C 264,155 280,160 293,169L 181,281C 172,268 167,252 167,236C 167,191 203,155 248,155 Z M 248,125C 187,125 137,174 137,236C 137,297 187,346 248,346C 309,346 358,297 358,236C 358,174 309,125 248,125 Z ",
            clock2: "M 240,83.3306C 326,83.3306 396,153 396,238C 396,324 326,394 240,394C 154,394 84.7931,324 84.7931,238C 84.7931,153 154,83.3306 240,83.3306 Z M 240,117C 173,117 119,172 119,238C 119,305 173,360 240,360C 307,360 361,305 361,238C 361,172 307,117 240,117 Z M 226,134L 257,134L 257,222L 344,222L 344,254L 257,254L 226,254L 226,222L 226,134 Z ",
            brokenheart: "M 330.477,132.197C 356.937,138.77 391.78,171.336 377.523,214.52C 363.524,256.922 300.573,315.649 236.736,374.673L 236.661,377.192L 236.462,377.511L 236.458,377.474C 236.027,377.024 235.597,376.574 235.166,376.125C 234.604,376.645 234.041,377.165 233.478,377.686L 234.248,375.165C 173.755,311.965 113.848,249.002 102.394,205.56C 90.7992,161.586 128.204,131.166 155.016,126.221C 181.828,121.275 198.047,141.805 213.619,155.886L 213.62,155.898L 216.057,174.84L 207.556,193.875L 234.339,205.886L 223.103,240.42L 244.574,264.845L 225.139,285.432L 246.366,312.2L 228.578,323.124L 237.755,340.49L 236.989,366.187L 244.202,342.568L 239.924,323.398L 259.961,317.546L 246.537,286.132L 270.708,271.392L 256.431,242.173L 276.367,211.819L 253.695,193.176L 266.91,177.053L 269.626,158.078C 286.004,144.978 304.064,125.636 330.477,132.197 Z ",
            wholeheart: "M 298.517,129.106C 306.097,129.106 313.441,130.486 320.548,133.247C 327.655,136.007 333.928,140.168 339.366,145.73C 344.805,151.292 349.162,158.296 352.437,166.742C 355.712,175.188 357.35,185.159 357.35,196.653C 357.35,209.467 355.3,221.404 351.201,232.466C 347.102,243.529 341.715,253.932 335.04,263.675C 328.366,273.419 320.837,282.545 312.452,291.053C 304.068,299.56 295.581,307.687 286.991,315.433C 278.401,323.178 270.099,330.594 262.086,337.681C 254.072,344.767 247.182,351.709 241.414,358.507L 239.683,358.507C 233.915,351.709 227.066,344.767 219.135,337.681C 211.204,330.594 202.943,323.178 194.353,315.433C 185.763,307.687 177.276,299.56 168.892,291.053C 160.507,282.545 152.978,273.419 146.304,263.675C 139.629,253.932 134.243,243.529 130.143,232.466C 126.044,221.404 123.994,209.467 123.994,196.653C 123.994,185.159 125.632,175.188 128.907,166.742C 132.183,158.296 136.539,151.292 141.978,145.73C 147.416,140.168 153.689,136.007 160.796,133.247C 167.903,130.486 175.247,129.106 182.827,129.106C 190.12,129.106 196.681,130.064 202.511,131.98C 208.34,133.896 213.593,136.491 218.27,139.767C 222.946,143.042 227.045,146.76 230.568,150.922C 234.09,155.083 237.129,159.326 239.683,163.652L 241.414,163.652C 244.009,159.326 247.099,155.083 250.684,150.922C 254.268,146.76 258.398,143.042 263.074,139.767C 267.751,136.491 273.004,133.896 278.833,131.98C 284.663,130.064 291.224,129.106 298.517,129.106 Z ",
            plug: "M 359.701,173.023C 369.366,173.023 377.202,180.858 377.202,190.524C 377.202,200.19 369.366,208.025 359.701,208.025L 286.266,208.025L 286.266,269.956L 359.701,269.956C 369.366,269.956 377.202,277.791 377.202,287.457C 377.202,297.123 369.366,304.958 359.701,304.958L 286.266,304.958L 286.266,341.604L 208.803,341.604L 208.803,341.45C 181.438,341.366 159.277,317.007 159.277,286.97L 159.277,286.88L 159.277,279.85L 159.277,272.47L 107.202,272.47L 107.202,205.511L 159.277,205.511L 159.277,190.702L 159.418,190.701C 159.495,160.685 181.702,136.377 209.085,136.377L 209.203,136.377L 286.266,136.377L 286.266,173.023L 359.701,173.023 Z ",
            diamond: "M 196.624,189.138L 162.308,129.7L 230.941,129.7L 196.624,189.138 Z M 283.757,189.138L 249.441,129.7L 318.074,129.7L 283.757,189.138 Z M 327.492,129.7L 361.809,189.138L 293.176,189.138L 327.492,129.7 Z M 240.51,129.7L 274.826,189.138L 206.193,189.138L 240.51,129.7 Z M 153.415,129.7L 187.731,189.138L 119.098,189.138L 153.415,129.7 Z M 240.453,392.787L 119.062,199.376L 191.65,199.376L 240.453,392.787L 206.066,199.376L 274.841,199.377L 240.453,392.787L 289.257,199.377L 361.844,199.376L 240.453,392.787 Z ",
            cloudupload: "M 307.457,322.847L 263.012,278.402L 263.012,377.169L 233.382,377.169L 233.382,278.402L 188.937,322.847L 188.937,288.279L 248.197,229.019L 307.457,288.279L 307.457,322.847 Z M 134.171,193.154L 134.264,193.154L 152.596,193.154C 155.211,174.969 170.855,160.995 189.763,160.995C 196.549,160.995 202.914,162.795 208.407,165.943C 220.476,139.797 246.926,121.653 277.612,121.653C 318.303,121.653 351.542,153.555 353.684,193.71C 374.206,197.034 389.875,214.834 389.875,236.294C 389.875,260.12 370.561,279.434 346.735,279.434L 312.878,279.434L 298.847,265.403L 342.068,265.403L 342.068,265.08C 357.647,264.738 370.171,252.001 370.171,236.34C 370.171,220.679 357.647,207.942 342.068,207.6L 342.068,207.593L 341.424,207.593L 337.448,207.593C 337.984,204.35 338.263,201.021 338.263,197.626C 338.263,164.096 311.081,136.915 277.552,136.915C 246.798,136.915 221.385,159.782 217.388,189.441C 212.187,181.43 203.163,176.132 192.901,176.132C 176.789,176.132 163.728,189.193 163.728,205.305L 163.816,207.593L 135.032,207.593C 119.156,207.593 106.286,220.464 106.286,236.34C 106.286,252.216 119.156,265.087 135.032,265.087L 135.032,265.403L 197.548,265.403L 183.516,279.434L 134.171,279.434C 110.345,279.434 91.031,260.119 91.031,236.294C 91.031,212.468 110.346,193.154 134.171,193.154 Z ",
            emptyplay: "M 368.719,238.991L 178.28,343.579L 178.28,134.402L 368.719,238.991 Z M 333.017,238.991L 195.594,163.519L 195.594,314.463L 333.017,238.991 Z ",
            braces: "M 162.632,350.534C 136.692,350.21 123.722,337.172 123.722,311.421L 123.722,273.524C 123.722,256.527 116.804,247.61 102.97,246.773L 102.97,231.209C 116.804,230.371 123.722,221.278 123.722,203.931L 123.722,167.087C 123.722,140.985 136.692,127.772 162.632,127.447L 162.632,143.012C 148.798,143.363 141.88,151.78 141.88,168.263L 141.88,205.674C 141.88,223.535 135.476,234.505 122.668,238.585L 122.668,239.112C 135.476,242.922 141.88,253.785 141.88,271.7L 141.88,308.503C 141.88,317.906 143.427,324.627 146.521,328.667C 149.615,332.707 154.985,334.808 162.632,334.97L 162.632,350.534 Z M 377.937,246.773C 364.102,247.61 357.184,256.527 357.184,273.524L 357.184,311.421C 357.184,337.172 344.214,350.21 318.274,350.534L 318.274,334.97C 325.786,334.808 331.122,332.686 334.284,328.606C 337.445,324.526 339.026,317.825 339.026,308.503L 339.026,271.7C 339.026,253.785 345.43,242.922 358.238,239.112L 358.238,238.585C 345.43,234.505 339.026,223.535 339.026,205.674L 339.026,168.263C 339.026,151.78 332.109,143.363 318.274,143.012L 318.274,127.447C 344.214,127.772 357.184,140.985 357.184,167.087L 357.184,203.931C 357.184,221.278 364.102,230.371 377.937,231.209L 377.937,246.773 Z M 179.21,177.142L 194.321,177.142L 301.697,177.142L 301.697,207.604L 194.321,207.604L 194.321,285.313L 255.16,285.313L 255.16,300.839L 179.21,300.839L 179.21,292.62L 179.21,285.313L 179.209,207.604L 179.21,177.142 Z M 201.558,213.199L 268.948,213.199L 268.948,243.661L 201.558,243.661L 201.558,213.199 Z M 201.229,249.256L 293.972,249.256L 293.972,279.718L 201.229,279.718L 201.229,249.256 Z ",
            wand: "M 341.424,128.115L 351.527,138.218L 323.055,166.69L 312.952,156.587L 341.424,128.115 Z M 351.123,249.865L 341.02,259.968L 312.548,231.496L 322.651,221.393L 351.123,249.865 Z M 257.44,156.183L 247.337,166.286L 218.865,137.814L 228.968,127.711L 257.44,156.183 Z M 372.71,189.221L 372.71,203.509L 332.444,203.509L 332.444,189.221L 372.71,189.221 Z M 291.446,147.61L 277.158,147.61L 277.158,107.344L 291.446,107.344L 291.446,147.61 Z M 281.85,158.275L 320.558,196.984L 146.905,370.637L 108.196,331.929L 281.85,158.275 Z M 234.93,216.045L 119.152,331.823L 147.01,359.681L 262.789,243.903L 234.93,216.045 Z ",
            commandline: "M 108.874,328.138L 372.032,328.138L 372.032,149.843L 108.874,149.843L 108.874,328.138 Z M 188.674,271.59L 141.412,304.72L 141.412,286.282L 175.317,265.526L 175.317,265.206L 141.412,242.848L 141.412,224.262L 188.674,258.969L 188.674,271.59 Z M 200.548,287.425L 241.265,287.425L 241.265,302.664L 200.548,302.664L 200.548,287.425 Z ",
            split: "M 168.96,188.271L 130.92,226.311L 215.453,226.311L 215.453,251.67L 130.92,251.67L 168.96,289.71L 139.373,289.71L 88.6535,238.99L 139.373,188.271L 168.96,188.271 Z M 311.946,289.71L 349.986,251.671L 265.453,251.671L 265.453,226.311L 349.986,226.311L 311.946,188.271L 341.533,188.271L 392.253,238.991L 341.533,289.71L 311.946,289.71 Z M 226.511,75.2216L 254.395,75.2216L 254.395,402.76L 226.511,402.76L 226.511,75.2216 Z ",
            "package": "M 142.374,266.405L 233.787,266.405L 233.787,350.836L 142.374,350.836L 142.374,266.405 Z M 247.119,266.405L 338.532,266.405L 338.532,350.836L 247.119,350.836L 247.119,266.405 Z M 350.276,186.1L 350.276,254.025L 247.119,254.025L 247.119,191.217C 245.407,191.325 243.69,191.427 241.973,191.529C 241.966,191.6 241.959,191.67 241.952,191.74L 233.788,191.24L 233.788,254.025L 130.63,254.025L 130.63,186.1L 197.792,186.1C 191.84,184.338 186.527,181.957 182.152,178.668C 168.397,168.327 163.909,149.012 172.104,135.939C 180.298,122.867 201.175,116.039 215.515,120.428C 229.855,124.818 237.66,140.427 240.977,154.182C 241.177,155.013 241.361,155.837 241.53,156.655C 241.677,155.953 241.837,155.246 242.008,154.535C 245.28,140.966 252.979,125.569 267.125,121.238C 281.272,116.908 301.865,123.644 309.949,136.539C 318.033,149.434 313.606,168.488 300.037,178.689C 295.655,181.983 290.32,184.354 284.34,186.1L 350.276,186.1 Z M 232.489,181.725C 233.312,173.359 234.135,164.993 231.803,155.323C 229.472,145.654 223.986,134.682 213.905,131.596C 203.824,128.51 189.149,133.31 183.388,142.499C 177.628,151.689 180.782,165.267 190.452,172.536C 200.121,179.805 216.305,180.765 232.489,181.725 Z M 250.381,181.706C 266.346,180.758 282.311,179.811 291.85,172.641C 301.388,165.47 304.5,152.075 298.818,143.01C 293.135,133.945 278.658,129.21 268.714,132.254C 258.769,135.298 253.357,146.122 251.057,155.661C 248.757,165.199 249.569,173.452 250.381,181.706 Z ",
            smiliesad: "M 197.203,320.447C 191.802,320.447 187.205,318.673 183.41,315.127C 179.615,311.58 177.717,307.325 177.717,302.362C 177.717,297.341 179.615,293.028 183.41,289.423C 187.205,285.818 191.802,284.015 197.203,284.015C 202.691,284.015 207.355,285.818 211.193,289.423C 215.032,293.028 216.951,297.341 216.951,302.362C 216.951,307.325 215.032,311.58 211.193,315.127C 207.355,318.673 202.691,320.447 197.203,320.447 Z M 197.203,211.151C 191.802,211.151 187.205,209.378 183.41,205.831C 179.615,202.284 177.717,198.03 177.717,193.067C 177.717,188.046 179.615,183.733 183.41,180.127C 187.205,176.522 191.802,174.72 197.203,174.72C 202.691,174.72 207.355,176.522 211.193,180.127C 215.032,183.733 216.951,188.046 216.951,193.067C 216.951,198.03 215.032,202.284 211.193,205.831C 207.355,209.378 202.691,211.151 197.203,211.151 Z M 320.642,362.484L 292.618,362.484C 264.593,330.168 250.581,290.321 250.581,242.942C 250.581,195.388 264.593,154.898 292.618,121.473L 320.642,121.473C 292.618,156.153 278.605,196.555 278.605,242.679C 278.605,288.394 292.618,328.329 320.642,362.484 Z ",
            signalalt: "M 125.019,266.274L 169.669,266.274L 169.669,324.752L 125.019,324.752L 125.019,266.274 Z M 183.23,228.487L 227.88,228.487L 227.88,324.752L 183.23,324.752L 183.23,228.487 Z M 241.441,192.022L 286.091,192.022L 286.091,324.752L 241.441,324.752L 241.441,192.022 Z M 299.32,155.063L 343.97,155.063L 343.97,324.752L 299.32,324.752L 299.32,155.063 Z M 305.697,162.256L 305.697,317.208L 337.594,317.208L 337.594,162.256L 305.697,162.256 Z M 247.817,200.291L 247.817,317.208L 279.714,317.208L 279.714,200.291L 247.817,200.291 Z M 189.317,235.184L 189.317,317.208L 221.214,317.208L 221.214,235.184L 189.317,235.184 Z M 131.065,274.708L 131.065,317.208L 162.962,317.208L 162.962,274.708L 131.065,274.708 Z ",
            signal: "M 125.011,266.081L 169.661,266.081L 169.661,324.559L 125.011,324.559L 125.011,266.081 Z M 183.222,228.294L 227.872,228.294L 227.872,324.559L 183.222,324.559L 183.222,228.294 Z M 241.432,191.83L 286.082,191.83L 286.082,324.559L 241.432,324.559L 241.432,191.83 Z M 299.312,154.87L 343.962,154.87L 343.962,324.559L 299.312,324.559L 299.312,154.87 Z ",
            lock: "M 151.624,205.982L 167.789,205.982C 171.332,160.444 202.513,124.832 240.453,124.832C 278.394,124.832 309.574,160.444 313.118,205.982L 329.282,205.982L 329.282,353.149L 151.624,353.149L 151.624,205.982 Z M 240.453,149.899C 216.112,149.899 196.02,177.033 193.033,205.982L 287.874,205.982C 284.886,177.033 264.794,149.899 240.453,149.899 Z M 240.453,244.36C 231.985,244.36 225.12,251.225 225.12,259.693C 225.12,265.145 227.965,269.932 232.251,272.651L 227.403,315.19L 253.503,315.19L 248.655,272.651C 252.941,269.932 255.786,265.145 255.786,259.693C 255.786,251.225 248.921,244.36 240.453,244.36 Z ",
            emptycircle: "M 240.453,101.462C 316.408,101.462 377.982,163.036 377.982,238.991C 377.982,314.946 316.408,376.519 240.453,376.519C 164.498,376.519 102.924,314.946 102.924,238.991C 102.924,163.036 164.498,101.462 240.453,101.462 Z M 240.453,135.773C 183.447,135.773 137.235,181.985 137.235,238.991C 137.235,295.996 183.447,342.209 240.453,342.209C 297.459,342.209 343.671,295.996 343.671,238.991C 343.671,181.985 297.459,135.773 240.453,135.773 Z ",
            group: "M 146.602,137.257C 155.992,137.257 163.608,144.873 163.608,154.267C 163.608,163.658 155.992,171.273 146.602,171.273C 137.208,171.273 129.591,163.658 129.591,154.267C 129.591,144.873 137.208,137.257 146.602,137.257 Z M 129.227,179.743L 163.558,179.743C 169.226,179.743 174.86,181.722 178.867,185.115C 182.87,188.511 185.201,193.284 185.201,198.083L 185.201,199.566L 185.201,200.123L 185.201,271.383C 185.255,274.768 181.679,277.873 177.779,277.835C 173.931,277.797 170.47,274.719 170.523,271.383L 170.523,209.123L 165.841,209.123L 165.841,268.76L 165.815,268.76L 165.815,332.839C 165.849,334.913 165.007,336.983 163.544,338.449C 162.076,339.916 160.002,340.754 157.93,340.724C 153.865,340.66 150.226,336.902 150.287,332.839L 150.287,268.76L 142.523,268.76L 142.523,332.839C 142.557,334.913 141.715,336.983 140.252,338.449C 138.785,339.916 136.711,340.754 134.638,340.724C 130.573,340.66 126.934,336.902 126.995,332.839L 126.995,268.76L 126.972,268.76L 126.972,209.123L 122.264,209.123L 122.264,270.484C 122.302,273.869 118.719,276.963 114.818,276.914C 110.986,276.864 107.551,273.805 107.585,270.484L 107.585,199.202L 107.585,198.569L 107.585,198.083C 107.585,193.284 109.916,188.511 113.923,185.115C 117.927,181.722 123.56,179.743 129.227,179.743 Z M 240.662,137.257C 250.052,137.257 257.668,144.873 257.668,154.267C 257.668,163.658 250.052,171.273 240.662,171.273C 231.267,171.273 223.651,163.658 223.651,154.267C 223.651,144.873 231.267,137.257 240.662,137.257 Z M 223.287,179.743L 257.618,179.743C 263.286,179.743 268.92,181.722 272.927,185.115C 276.93,188.511 279.261,193.284 279.261,198.083L 279.261,199.566L 279.261,200.123L 279.261,271.383C 279.315,274.768 275.739,277.873 271.839,277.835C 267.991,277.797 264.53,274.719 264.583,271.383L 264.583,209.123L 259.901,209.123L 259.901,268.76L 259.875,268.76L 259.875,332.839C 259.909,334.912 259.067,336.983 257.604,338.449C 256.136,339.916 254.062,340.754 251.989,340.724C 247.925,340.66 244.286,336.902 244.347,332.839L 244.347,268.76L 236.583,268.76L 236.583,332.839C 236.617,334.912 235.775,336.983 234.312,338.449C 232.844,339.916 230.77,340.754 228.697,340.724C 224.633,340.66 220.994,336.902 221.055,332.839L 221.055,268.76L 221.032,268.76L 221.032,209.123L 216.324,209.123L 216.324,270.484C 216.362,273.869 212.778,276.963 208.878,276.914C 205.046,276.864 201.611,273.805 201.645,270.484L 201.645,199.202L 201.645,198.569L 201.645,198.083C 201.645,193.284 203.976,188.511 207.983,185.115C 211.987,181.722 217.62,179.743 223.287,179.743 Z M 334.722,137.258C 344.112,137.258 351.728,144.873 351.728,154.267C 351.728,163.658 344.112,171.273 334.722,171.273C 325.327,171.273 317.711,163.658 317.711,154.267C 317.711,144.873 325.327,137.258 334.722,137.258 Z M 317.347,179.743L 351.678,179.743C 357.346,179.743 362.98,181.722 366.987,185.115C 370.99,188.511 373.321,193.284 373.321,198.083L 373.321,199.566L 373.321,200.123L 373.321,271.383C 373.375,274.768 369.799,277.873 365.899,277.835C 362.051,277.797 358.59,274.719 358.642,271.383L 358.642,209.123L 353.961,209.123L 353.961,268.76L 353.935,268.76L 353.935,332.839C 353.969,334.913 353.127,336.983 351.664,338.449C 350.196,339.916 348.122,340.754 346.049,340.724C 341.985,340.66 338.345,336.902 338.407,332.839L 338.407,268.76L 330.643,268.76L 330.643,332.839C 330.677,334.913 329.835,336.983 328.372,338.449C 326.904,339.916 324.83,340.754 322.757,340.724C 318.693,340.66 315.054,336.902 315.115,332.839L 315.115,268.76L 315.091,268.76L 315.091,209.123L 310.384,209.123L 310.384,270.484C 310.421,273.869 306.838,276.963 302.938,276.914C 299.105,276.864 295.671,273.805 295.705,270.484L 295.705,199.202L 295.705,198.569L 295.705,198.083C 295.705,193.284 298.036,188.511 302.043,185.115C 306.046,181.722 311.68,179.743 317.347,179.743 Z ",
            im: "M 393.488,206.958L 393.488,321.247L 357.423,321.247L 357.423,369.234L 328.898,321.247L 196.081,321.247L 196.081,206.958L 393.488,206.958 Z M 87.4178,146.461L 292.537,146.461L 292.537,193.312L 182.971,193.312L 182.971,265.214L 154.531,265.214L 124.892,315.075L 124.892,265.214L 87.4178,265.214L 87.4178,146.461 Z ",
            arrowdownl: "M 183.668,152.318L 141.826,194.16L 141.826,337.618L 285.284,337.618L 327.126,295.776L 219.532,295.776L 339.08,176.228L 303.216,140.364L 183.668,259.911L 183.668,152.318 Z ",
            blockeditor: "M 291.345,115.775C 359.131,119.293 411.588,177.379 408.425,245.148C 404.906,312.946 346.532,365.37 278.767,362.207C 247.808,360.803 220,347.803 199.579,327.738L 209.998,317.088C 227.904,334.688 252.181,346.11 279.378,347.353L 279.473,347.353C 339.239,350.124 390.47,304.138 393.55,244.421C 396.342,184.655 350.368,133.746 290.639,130.649C 259.036,129.1 230.084,141.134 209.387,161.831L 198.853,151.297C 222.42,127.73 255.551,114.036 291.345,115.775 Z M 330.947,239.837L 261.91,291.7L 261.91,187.962L 330.947,239.837 Z M 94.3721,159.556L 179.659,159.556C 185.931,159.556 191.498,162.764 195.239,167.509C 198.981,172.233 201.128,178.543 201.128,185.365L 201.128,292.732C 201.128,299.554 198.981,305.748 195.239,310.493C 191.498,315.217 185.931,318.446 179.659,318.446L 146.623,318.446C 144.797,318.446 142.493,316.815 141.861,315.539C 141.234,314.284 141.345,313.169 141.345,313.169L 141.345,312.558L 141.461,311.926L 145.169,298.104L 145.074,298.104C 145.846,294.991 145.768,291.811 144.748,289.54C 142.927,285.571 140.024,283.085 137.331,282.714L 137.121,282.714L 136.815,282.619L 135.096,282.413C 135.165,282.457 133.721,282.809 132.475,283.651L 132.359,283.651L 132.264,283.746C 130.249,284.956 128.345,287.475 127.313,291.088C 126.925,292.443 126.925,294.264 127.313,295.618L 127.313,295.924L 130.926,312.042L 131.137,312.653L 131.137,313.169L 131.021,313.896C 130.976,314.428 130.765,315.799 129.588,316.993C 128.395,318.186 127.119,318.38 126.586,318.446L 125.765,318.446L 94.0665,318.446C 87.7896,318.446 82.2272,315.217 78.4859,310.493C 74.7239,305.748 72.5972,299.554 72.5972,292.732L 72.5972,263.309L 72.5972,262.583L 72.5972,260.518L 72.4816,254.629L 72.4816,248.645L 72.4816,246.581L 72.5972,245.664L 72.8078,244.821L 73.324,243.599L 73.7246,242.967L 74.4513,242.241L 75.6943,241.534L 77.5485,241.113L 78.4859,241.113L 79.4026,241.534L 93.5503,247.097L 93.6453,247.097C 95.3425,247.807 99.567,247.13 100.777,245.664C 101.826,244.194 102.164,244.21 102.536,243.599C 102.953,242.889 103.535,241.613 103.663,238.627L 103.663,238.532C 103.969,233.193 103.486,233.032 102.115,229.968C 100.872,227.226 98.7452,225.545 96.6474,224.69C 94.5496,223.852 92.584,224.306 92.6129,224.29L 92.4229,224.385L 92.0967,224.5L 85.5969,227.692L 82.1942,229.241C 81.2279,229.691 81.0007,229.984 79.8238,230.368L 79.0021,230.579L 78.2753,230.579L 75.6943,229.968L 74.4513,228.82L 73.9352,228.114L 73.6296,227.597L 73.324,226.565L 73.2084,225.838L 73.2084,224.806L 73.1134,221.919L 72.9978,213.45L 72.9028,201.156L 72.9028,186.092C 72.5642,171.684 81.8555,159.556 94.3721,159.556 Z M 94.3721,169.458C 88.438,169.458 82.5328,175.785 82.8053,185.881L 82.8053,201.156L 82.921,213.334L 83.0159,217.885L 87.6616,215.725L 88.0828,215.609C 91.9687,213.528 96.2427,213.85 100.356,215.514C 104.617,217.224 108.714,220.643 111.101,225.838L 111.196,225.933C 112.472,228.807 113.925,232.565 113.587,239.048C 113.376,243.372 112.294,246.486 111.006,248.645C 109.68,250.838 107.954,252.841 108.825,251.532L 108.615,251.743L 108.52,251.858C 103.791,257.615 96.1643,258.841 89.937,256.293L 89.842,256.293L 82.4048,253.291L 82.4048,254.534L 82.4997,260.423L 82.4997,262.372L 82.4997,263.309L 82.4997,292.732C 82.4997,297.473 84.0153,301.619 86.2287,304.394C 88.4214,307.185 91.0974,308.523 94.0665,308.523L 120.086,308.523L 117.716,298.315L 117.716,298.104C 116.828,294.892 116.795,291.605 117.716,288.392C 119.294,282.858 122.539,278.167 127.007,275.392L 127.313,275.277C 129.811,273.65 132.198,272.506 135.056,272.506L 138.669,272.906L 139.185,273.022L 139.185,273.117C 146.057,274.277 151.008,279.456 153.734,285.295L 153.734,285.41C 155.992,290.378 155.959,295.701 154.766,300.475L 154.766,300.57L 154.671,300.57L 152.606,308.523L 179.659,308.523C 182.624,308.523 185.304,307.185 187.496,304.394C 189.689,301.619 191.205,297.473 191.205,292.732L 191.205,185.365C 191.205,180.624 189.689,176.478 187.496,173.703C 185.304,170.912 182.624,169.458 179.659,169.458L 94.3721,169.458 Z ",
            bitcompile: "M 185.748,120.291L 226.777,161.32L 226.777,88.4853L 254.129,88.4853L 254.13,161.32L 295.159,120.291L 295.159,152.202L 240.453,206.908L 185.748,152.202L 185.748,120.291 Z M 283.951,302.191C 283.951,293.063 291.357,285.652 300.492,285.652C 309.638,285.652 317.027,293.063 317.027,302.191C 317.027,311.322 309.638,318.739 300.492,318.739C 291.357,318.739 283.951,311.322 283.951,302.191 Z M 162.457,302.194C 162.457,293.065 169.87,285.652 179.005,285.652C 188.134,285.652 195.542,293.065 195.542,302.194C 195.542,311.325 188.134,318.741 179.005,318.741C 169.87,318.741 162.457,311.325 162.457,302.194 Z M 179.001,220.264L 301.555,220.466C 347.222,220.466 383.84,257.019 383.84,302.198C 383.84,347.377 347.083,384.132 301.903,384.132L 179.001,384.132C 133.824,384.132 97.0666,347.377 97.0666,302.198C 97.0666,257.019 133.824,220.264 179.001,220.264 Z M 129.837,302.198C 129.837,329.303 151.896,351.362 179.001,351.362L 301.903,351.362C 329.01,351.362 351.062,329.303 351.062,302.198C 351.062,275.086 329.01,253.034 301.903,253.034L 179.001,253.034C 151.896,253.034 129.837,275.086 129.837,302.198 Z ",
            bitload: "M 295.158,156.941L 254.13,115.912L 254.13,188.747L 226.777,188.747L 226.777,115.912L 185.748,156.941L 185.748,125.029L 240.453,70.3241L 295.158,125.029L 295.158,156.941 Z M 283.951,300.514C 283.951,291.385 291.357,283.974 300.492,283.974C 309.639,283.974 317.027,291.385 317.027,300.514C 317.027,309.645 309.639,317.061 300.492,317.061C 291.357,317.061 283.951,309.645 283.951,300.514 Z M 162.457,300.516C 162.457,291.387 169.87,283.974 179.005,283.974C 188.134,283.974 195.542,291.387 195.542,300.516C 195.542,309.647 188.134,317.064 179.005,317.064C 169.87,317.064 162.457,309.647 162.457,300.516 Z M 179.001,218.586L 301.555,218.788C 347.222,218.788 383.84,255.341 383.84,300.52C 383.84,345.699 347.083,382.454 301.903,382.454L 179.001,382.454C 133.824,382.454 97.0667,345.699 97.0667,300.52C 97.0667,255.341 133.824,218.586 179.001,218.586 Z M 129.837,300.52C 129.837,327.625 151.896,349.684 179.001,349.684L 301.903,349.684C 329.01,349.684 351.062,327.625 351.062,300.52C 351.062,273.409 329.01,251.357 301.903,251.357L 179.001,251.357C 151.896,251.357 129.837,273.409 129.837,300.52 Z ",
        };
        var gelIcons = {
            alert: "M42,34v-6c-0.2-4.6-3.6-8.4-8-9.3V16h-4v2.7c-4.4,0.9-7.8,4.7-8,9.3v6l-6,8h32L42,34z M28,44 l8,0 l0,4 l-8,0 z",
            create: "M48,36H36v12h-8V36H16v-8h12V16h8v12h12V36z",
            edit: "M17.1,39.5v7.4h7.4l0.9-0.8l-7.5-7.5L17.1,39.5z M19.8,36.7L40.5,16l7.4,7.4L27.3,44.1L19.8,36.7z",
            duplicate: "M45.4,19.1h-5.8L32.5,12H14v29h12.9v7.7h25.9V26.5L45.4,19.1z M26.9,24.1h-5.5v2.8h5.5v0.9h-5.5v2.8h5.5v0.9h-5.5v2.8h5.5V39H17V15h14.9l4.1,4.1h-9.1V24.1z M50,45.9H29.7v-24h15.1l5.2,5.2C50,27.1,50,45.9,50,45.9z M34.3,31.1h11.1v2.8H34.3V31.1z M34.3,34.8h11.1v2.8H34.3V34.8z M34.3,38.5h11.1v2.8H34.3V38.5z",
            import: "M31.2,39l2,2H15V15h26v21.9l3,3V33h5v16H33v-5h7.5L22,25.3l3.6-3.7L39,34.9V17H17v22H31.2z",
            info: "M32,16c-8.8,0-16,7.2-16,16s7.2,16,16,16s16-7.2,16-16S40.8,16,32,16z M34,41h-4V29h4V41z M34,27h-4v-4h4V27z",
            left: "M19,32l26,16v-7.2L30.4,32L45,23.2V16L19,32z",
            love: "M45.4,20.6c-3.5-3.5-9-3.5-12.5,0c-0.3,0.3-0.6,0.7-0.9,1.1c-0.3-0.4-0.6-0.7-0.9-1.1c-3.5-3.5-9-3.5-12.5,0c-3.5,3.5-3.5,9,0,12.5L32,46.5l13.4-13.4C48.9,29.6,48.9,24,45.4,20.6z",
            pairnew: "M38.1,26.5c-1.1,0-2,0.9-2,2s0.9,2,2,2s2-0.9,2-2S39.2,26.5,38.1,26.5z M23.1,26.4c-1.1,0-2.1,0.9-2.1,2s0.9,2.1,2.1,2.1c1.1,0,2-0.9,2-2.1C25.1,27.3,24.2,26.4,23.1,26.4z M48.4,28.5c0-5.5-4.5-10.1-10.1-10.1H23.1c-5.5,0-10.1,4.5-10.1,10.1c0,5.5,4.5,10.1,10.1,10.1h15.2C43.9,38.6,48.4,34,48.4,28.5z M38.3,34.5H23.1c-3.4,0-6.1-2.7-6.1-6.1s2.7-6.1,6.1-6.1h15.2c3.4,0,6.1,2.7,6.1,6.1C44.4,31.8,41.7,34.5,38.3,34.5z M52,38.8v-5.3h-3.5v5.3h-5.3v3.5h5.3v5.2H52v-5.2h5.2v-3.5H52z",
            play: "M21,48l26-16L21,16V48z",
            print: "M40,32H24V16h13l3,3V32z M42,28v4v2h-2H24h-2v-2v-4h-6v12.1l5.9,5.9H22v-5h20v5h0.1l5.9-5.9V28H42z M24,48h16v-5H24V48z",
            publish: "M32.2,28.8L21.3,39.7l2.6,2.7l6.3-6.3v11.3h4.1V36.1l6.3,6.3l2.6-2.7L32.2,28.8z M26.2,32.3l1.3-1.3c-0.2-0.1-0.3-0.2-0.4-0.3c0.1-0.1,0.3-0.2,0.4-0.4c0.3-0.3,0.3-0.4-0.1-0.6c-0.4-0.4-0.7-0.7-1.1-1.2c-0.1-0.1,0-0.2-0.1-0.3c-0.1-0.4-0.1-0.8-0.2-1.2c-0.2-0.5-0.4-1.1-0.6-1.6c-0.1-0.4-0.2-0.7-0.2-1.1c0.1-0.7,0.4-0.9,1-0.4c0.5,0.5,1.1,1.1,1.6,1.6c0.4,0.4,0.8,0.7,1.3,1c0.3,0.3,0.6,0.2,0.9,0c0.1-0.1,0.3-0.2,0.4-0.3c0.4-0.3,0.8-0.5,1.3-0.7c0.5-0.2,1.1,0.2,1.1,0.7c0,0.1,0,0.3,0,0.4l0.7,0.7l4.8,4.9l1.2-1c2-1.9,3.2-4.6,3.2-7.5c0-5.7-4.7-10.4-10.4-10.4S21.9,18,21.9,23.7C21.8,27.3,23.5,30.4,26.2,32.3z M29.9,16.2c0.4-0.2,0.7,0,1,0.3c0.7,0.5,1.3,1.3,1.9,1.9c0.4,0.5,1,0.9,1.6,1.1c0.2,0.1,0.4,0.2,0.6,0.3c0.4,0.3,0.8,0.5,0.9,1.1c0.1,0.4,0.3,0.4,0.5,0.4c0.4-0.2,1-0.4,1.4-0.5c0.5-0.2,1.1-0.2,1.6-0.1c0.2,0.1,0.4,0.1,0.6,0.2c0.4,1,0.6,2,0.6,3.1c0,1.4-0.4,2.8-1,3.9c-0.7,0.2-1.3-0.1-1.5-0.9c-0.1-0.4-0.2-1-0.1-1.5c0.1-0.6,0.4-1.2,0.5-1.8c0.1-0.4,0.3-0.9,0.4-1.3c0.1-0.3-0.1-0.4-0.4-0.5s-0.5-0.1-0.9-0.1c-0.3,0-0.4,0-0.7-0.1c-0.4-0.1-0.7-0.1-1,0.2c-0.4,0.3-0.7,0.6-1.1,0.9c-0.6,0.4-1.3,0.8-2.2,0.9c-0.8,0.1-1.5-0.1-1.9-0.9c-0.3-0.5-0.4-1.2-0.6-1.7c-0.3-0.8-0.4-1.5-0.7-2.3c-0.1-0.4-0.3-0.8-0.3-1.3C29.4,16.8,29.5,16.3,29.9,16.2z",
            right: "M45,32L19,16v7.2L33.6,32L19,40.8V48L45,32z",
            save: "M42.5,15H16v31.6h30.9V19.4L42.5,15z M31.4,17.8h3.9V25h-3.9V17.8z M37.5,43.8H25.2v-9.4h12.4L37.5,43.8L37.5,43.8z M44.1,43.8h-4V32H22.7v11.9h-3.9v-26h6.1v9.7h12.9v-9.7h4.1l2.2,2.2C44.1,20.1,44.1,43.8,44.1,43.8z",
            search: "M48,44.5l-8.2-8.2c3.4-5.1,2.9-12-1.6-16.5C35.7,17.3,32.3,16,29,16s-6.7,1.3-9.2,3.8c-5.1,5.1-5.1,13.3,0,18.4c2.5,2.5,5.9,3.8,9.2,3.8c2.5,0,5-0.7,7.2-2.2l8.3,8.2L48,44.5z M22.6,35.3c-1.7-1.7-2.6-4-2.6-6.4c0-2.4,0.9-4.7,2.6-6.4c1.7-1.6,4-2.5,6.4-2.5s4.7,0.9,6.4,2.6c3.5,3.5,3.5,9.2,0,12.7c-1.7,1.7-4,2.6-6.4,2.6S24.3,37,22.6,35.3z",
            share: "M21.2,37.8c1.6,0,3-0.7,4-1.8l9,4.8c-0.1,0.4-0.2,0.8-0.2,1.3c0,3,2.5,5.5,5.5,5.5s5.5-2.4,5.5-5.5c0-3-2.5-5.5-5.5-5.5c-1.6,0-3,0.7-4,1.8L26,33.2v-2.7l9.7-5.5c1,1,2.3,1.5,3.8,1.5c3,0,5.5-2.5,5.5-5.5s-2.5-5.5-5.5-5.5S34,17.9,34,21c0,0.6,0.1,1.1,0.2,1.6L25 28.4c-1-0.9-2.3-1.5-3.8-1.5c-3,0-5.5,2.4-5.5,5.5C15.8,35.3,18.2,37.8,21.2,37.8z",
            trash: "M40,47.5l-1,0.9l-1-0.9V26h-5v21.5l-1.1,0.9L31,47.5V26h-5v21.5l-1,0.9l-1-0.9V26h-4.2l0.4,25h23.6l0.4-25H40V47.5z M28,16.5c0-0.2,0-0.4,1-0.4l0,0L28.6,16h7.6c0.2,0,0.8,0.3,0.8,0.5V17h2v-0.5c0-1.6-1.2-2.5-2.8-2.5h-7.6l0.4-0.4l0,0c-2,0-3,1.3-3,2.9V17h2V16.5z M45.5,21c0-1-1.1-2-2.9-2h-22c-1.1,0-2.7,0.8-2.7,2.2V25h28v-4H45.5z",
            uninstall: "M35.5,32L48,19.6L44.4,16L32,28.5L19.6,16L16,19.6L28.5,32L15.9,44.5l3.6,3.6L32,35.5L44.5,48l3.6-3.5L35.5,32z",
            upload: "M43.1,31.9L32.3,21.2L21.6,31.9l2.4,2.5l6-6.2V42h-9v-5h-2v6h2.1h2.1h7.1h3.9H34V28.2l6.4,6.2L43.1,31.9zM42,37v5h-7v1h2h4.4H44v-2.5V37H42z",
        };
        var iconMapping = {
            document: "fa-file-o",
            copy: "fa-files-o",
            paste: "fa-clipboard",
            recyclelib: "fa-recycle",
            settings: "fa-cogs",
            setting: "fa-cogs",
            chapback: "fa-fast-backward",
            save: "gel-save",
            email: "fa-envelope-o",
            cycle: "fa-refresh",
            folder: "fa-folder-open",
            video: "fa-video-camera",
            rewind: "fa-backward",
            sharethis: "gel-share",
            subtract: "fa-minus",
            heart: "gel-love",
            award: "fa-trophy",
            person: "fa-user",
            art: "fa-paint-brush",
            videoptr: "fa-video-camera",
            bbc: "play",
            edit: "gel-edit",
            upload: "gel-publish",
            play: "gel-play",
            clone: "gel-duplicate",
            search: "gel-search",
            print: "gel-print",
            info: "gel-info",
            cursorleft: "gel-left",
            cursorright: "gel-right",
        };
        var fontAwesomeIconsByDaveGandy = {
            "cutlery": "M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z",
            "rocket": "M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z",
            "code-fork": "M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z",
            "indent": "M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z",
            "history": "M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z",
            "file-image-o": "M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z",
            "trash": "M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z",
            "binoculars": "M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z",
            "globe": "M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z",
            "film": "M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z",
            "headphones": "M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z",
            "file-text-o": "M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z",
            "calculator": "M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z",
            "check-square-o": "M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z",
            "gift": "M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z",
            "paint-brush": "M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z",
            "list-ol": "M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z",
            "gamepad": "M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z",
            "user": "M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z",
            "file-o": "M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z ",
            "bolt": "M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z",
            "book": "M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z",
            "table": "M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z",
            "list-ul": "M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z",
            "th-list": "M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z",
            "subscript": "M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z",
            "list-alt": "M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z",
            "facebook": "M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z",
            "twitter": "M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z",
            "upload": "M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z",
            "files-o": "M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z",
            "recycle": "M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z",
            "clipboard": "M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z",
            "download": "M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z",
            "camera": "M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z",
            "cog": "M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z",
            "cogs": "M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z",
            "floppy-o": "M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z",
            "refresh": "M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z",
            "envelope-o": "M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z",
            "video-camera": "M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z",
            "folder-open": "M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z",
            "forward": "M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z",
            "backward": "M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z",
            "question": "M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z",
            "share-alt": "M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z",
            "pause": "M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z",
            "star": "M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z",
            "minus": "M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z",
            "check": "M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z",
            "heart-o": "M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z",
            "trophy": "M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z",
            "bell": "M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z",
            "wrench": "M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z",
            "fast-backward": "M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z",
            "flag": "M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z",
            "cloud": "M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z ",
            "laptop": "M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z",
            "expand": "M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z",
            "list": "M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z",
            "share": "M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z",
            "youtube": "M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z",
            "instagram": "M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z",
            "vine": "M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z",
            "print": "M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z",
            "vimeo": "M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z",
            "code": "M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z",
            "puzzle-piece": "M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z",
            "bars": "M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z",
            "external-link": "M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z",
            "ban": "M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z",
        };
        function svgBoilerPlate(viewPort, svg, iconName, altText) {
            if (iconName === void 0) { iconName = ""; }
            if (altText === void 0) { altText = ""; }
            return "<svg class='svg svg-icon-" + iconName + "' viewBox='" + viewPort + "'" + " preserveAspectRatio='xMinYMin' xmlns='http://www.w3.org/2000/svg'>" + (altText ? "<title>" + altText.replace(/[<>]/g, "") + "</title>" : "") + svg + "</svg>";
        }
        SVG.svgBoilerPlate = svgBoilerPlate;
        var loginButton = svgBoilerPlate('0 0 480 100', '<path fill="#F1511B" d="M 304.013,30.6004L 287.456,30.5787L 287.456,14.0221L 304.012,14.0221L 304.013,30.6004 Z "/>' + '<path fill="#7FCB28" d="M 322.293,30.5783L 305.731,30.5848L 305.736,14.0221L 322.293,14.0221L 322.293,30.5783 Z "/>' + '<path fill="#00ADEE" d="M 304.012,48.8651L 287.456,48.8651L 287.456,32.309L 303.997,32.3036L 304.012,48.8651 Z "/>' + '<path fill="#FABC09" d="M 322.293,48.8651L 305.736,48.8651L 305.747,32.3192L 322.293,32.309L 322.293,48.8651 Z "/>' + '<path fill="#DF4A32" d="M 374.073,59.2197L 401.083,59.2197C 401.73,59.2197 402.255,59.7444 402.255,60.3916L 402.255,87.4013C 402.255,88.0485 401.73,88.5732 401.083,88.5732L 393.197,88.5732L 388.656,88.5732L 374.073,88.5732C 373.426,88.5732 372.901,88.0485 372.901,87.4013L 372.901,60.3916C 372.901,59.7444 373.426,59.2197 374.073,59.2197 Z M 386.737,63.2903L 388.618,63.2903L 390.501,62.1863L 384.402,62.1863C 383.593,62.1863 382.725,62.2811 381.8,62.4701C 380.865,62.6892 379.964,63.1573 379.097,63.874C 377.835,65.099 377.204,66.4629 377.204,67.9665C 377.204,69.2112 377.649,70.3014 378.54,71.2373C 379.391,72.243 380.629,72.7558 382.252,72.7757C 382.559,72.7757 382.886,72.7558 383.232,72.7159L 383.046,73.2413C 382.97,73.4215 382.931,73.647 382.931,73.9171C 382.931,74.3678 383.032,74.7534 383.232,75.0737C 383.404,75.4043 383.6,75.7147 383.82,76.005C 383.109,76.025 382.215,76.1142 381.138,76.2734C 380.051,76.4622 379.013,76.8399 378.025,77.4066C 377.146,77.9331 376.538,78.5444 376.202,79.2404C 375.857,79.9362 375.684,80.5672 375.684,81.1339C 375.684,82.2968 376.215,83.2957 377.279,84.1308C 378.332,85.0252 379.927,85.4825 382.063,85.5025C 384.615,85.4626 386.568,84.8502 387.922,83.6651C 389.226,82.5198 389.879,81.2053 389.879,79.7217C 389.86,78.676 389.623,77.8295 389.166,77.1822C 388.681,76.5448 388.117,75.9625 387.474,75.4345L 386.44,74.5832C 386.29,74.4337 386.137,74.2596 385.978,74.0603C 385.792,73.8512 385.699,73.5874 385.699,73.2686C 385.699,72.94 385.79,72.6512 385.971,72.4022C 386.126,72.1631 386.294,71.9492 386.475,71.7599L 387.375,70.9384C 387.629,70.6694 387.87,70.3758 388.097,70.057C 388.561,69.3997 388.802,68.5236 388.82,67.428C 388.82,66.8304 388.753,66.3076 388.619,65.8595C 388.456,65.4114 388.269,65.0231 388.059,64.6945C 387.838,64.3459 387.613,64.0521 387.383,63.8131C 387.144,63.5841 386.928,63.4098 386.737,63.2903 Z M 387.915,80.9187C 387.915,81.8748 387.546,82.6566 386.808,83.2644C 386.051,83.882 384.953,84.2006 383.516,84.2207C 381.914,84.2006 380.651,83.8421 379.729,83.145C 378.758,82.4475 378.272,81.5611 378.272,80.4855C 378.272,79.9376 378.384,79.4696 378.607,79.0811C 378.802,78.7125 379.039,78.4036 379.321,78.1548C 379.612,77.9159 379.899,77.7314 380.18,77.6021L 380.836,77.333C 381.496,77.1337 382.142,76.9894 382.773,76.8999C 383.414,76.8401 383.812,76.8201 383.968,76.8401L 384.652,76.87C 385.789,77.6668 386.624,78.339 387.158,78.8871C 387.663,79.4644 387.915,80.1418 387.915,80.9187 Z M 383.663,71.9419C 383.027,71.9419 382.462,71.7476 381.968,71.3582C 381.474,70.9691 381.07,70.4952 380.758,69.9363C 380.112,68.739 379.79,67.5862 379.79,66.4785C 379.77,65.6406 379.991,64.8822 380.453,64.2035C 381,63.555 381.688,63.2207 382.514,63.2007C 383.139,63.2207 383.692,63.4054 384.173,63.7545C 384.644,64.1237 385.023,64.6027 385.312,65.1914C 385.927,66.4188 386.234,67.6362 386.234,68.8436C 386.234,69.1232 386.212,69.4674 386.168,69.8763C 386.094,70.2856 385.928,70.6846 385.67,71.0736C 385.135,71.6227 384.466,71.9121 383.663,71.9419 Z M 400.017,71.7155L 396.809,71.7155L 396.809,68.4458L 394.931,68.4458L 394.931,71.7155L 391.703,71.7155L 391.703,73.5403L 391.723,73.5403L 391.723,73.6096L 394.931,73.6096L 394.931,76.8175L 396.809,76.8175L 396.809,73.6096L 400.095,73.6096L 400.095,71.7318L 400.017,71.7318L 400.017,71.7155 Z "/>' + '<path fill="#3F008F" d="M 447.118,85.0025L 442.792,84.4735L 443.273,80.6767L 447.599,81.205L 447.118,85.0025 Z M 451.446,61.9735L 447.311,78.657L 444.089,78.2252L 444.042,61.0608L 451.446,61.9735 Z M 436.542,82.1673C 434.069,84.0011 431.003,85.0745 427.368,85.3876L 422.716,85.3876C 419.055,85.0745 415.993,84.0011 413.561,82.1673C 410.581,79.9555 409.09,77.0707 409.09,73.5128C 409.09,70.0033 410.581,67.1659 413.561,64.9548C 416.494,62.6954 420.34,61.5899 425.051,61.5899C 429.715,61.5899 433.561,62.6954 436.542,64.9548C 439.474,67.1659 440.965,70.0033 440.965,73.5128C 440.965,77.0707 439.474,79.9555 436.542,82.1673 Z M 434.33,70.5798L 434.907,69.7628L 430.965,69.7146L 426.782,69.7146L 426.975,70.5798L 429.474,70.9648C 429.426,71.4932 428.129,72.6952 425.677,74.5702C 423.802,72.2144 422.407,70.3401 421.494,68.9941L 424.426,68.7048L 424.523,68.0311C 423.225,67.936 421.59,67.936 419.619,67.9836C 416.782,67.936 415.244,67.936 415.099,68.0311L 415.099,68.8488L 417.888,69.2332C 418.369,69.6182 419.379,70.7245 420.917,72.5995C 422.407,74.4269 423.177,75.4843 423.273,75.7729L 423.321,77.0232L 423.321,77.6472C 423.321,78.657 423.273,79.2343 423.177,79.3293C 423.033,79.4747 422.6,79.5704 421.878,79.6187L 420.484,79.6662L 420.34,80.5321L 424.667,80.4838L 429.522,80.4838L 429.571,79.5704L 426.59,79.5222L 426.398,77.6961L 426.446,76.9742L 426.542,75.7729C 426.686,75.3396 427.551,74.4745 429.234,73.1284C 430.821,71.83 431.734,71.1563 432.071,71.0613L 434.33,70.5798 Z "/>' + '<path fill="#000000" d="M 448.753,81.205L 448.417,81.205L 448.417,80.9653L 449.33,80.9653L 449.33,81.205L 448.994,81.205L 448.994,82.1184L 448.753,82.1184L 448.753,81.205 Z M 449.811,81.3015L 449.811,82.1184L 449.571,82.1184L 449.571,80.9653L 449.859,80.9653L 450.196,81.5418L 450.532,80.9653L 450.772,80.9653L 450.772,82.1184L 450.532,82.1184L 450.532,81.3015L 450.196,81.8787L 450.147,81.8787L 449.811,81.3015 Z "/>' + '<path fill="#3B5998" d="M 362.345,88.5734L 354.865,88.5734L 354.865,77.2061L 358.68,77.2061L 359.251,72.7761L 354.865,72.7761L 354.865,69.9477C 354.865,68.6651 355.221,67.791 357.06,67.791L 359.406,67.7899L 359.406,63.8277C 359,63.7738 357.608,63.6532 355.988,63.6532C 352.605,63.6532 350.29,65.7177 350.29,69.5091L 350.29,72.7761L 346.465,72.7761L 346.465,77.2061L 350.29,77.2061L 350.29,88.5734L 336.231,88.5734C 335.336,88.5734 334.611,87.848 334.611,86.9534L 334.611,60.8398C 334.611,59.9449 335.336,59.2197 336.231,59.2197L 362.345,59.2197C 363.239,59.2197 363.965,59.9449 363.965,60.8398L 363.965,86.9534C 363.965,87.848 363.239,88.5734 362.345,88.5734 Z "/>' + '<path fill="#686868" d="M 345.055,34.0982L 350.422,20.9961L 355.338,20.9961L 355.338,41.8745L 351.737,41.8745L 351.737,28.6072L 351.897,24.8576L 351.822,24.8576C 351.685,25.4729 351.535,26.1565 351.394,26.507L 345.163,41.8745L 342.802,41.8745L 336.525,26.6446L 336.046,24.8576L 335.972,24.8576L 336.068,26.1946L 336.118,29.0398L 336.118,41.8745L 332.742,41.8745L 332.742,20.9961L 337.86,20.9961L 343.095,34.128C 343.554,35.2844 343.847,36.1942 344.022,36.8356L 344.077,36.8356L 345.055,34.0982 Z M 358.728,41.8747L 358.728,26.9128L 362.247,26.9128L 362.247,41.8747L 358.728,41.8747 Z M 360.524,20.5542C 361.133,20.5542 361.648,20.7572 362.054,21.1582C 362.46,21.5597 362.666,22.0478 362.666,22.61C 362.666,23.183 362.454,23.667 362.037,24.0493C 361.622,24.4293 361.113,24.6219 360.524,24.6219C 359.935,24.6219 359.427,24.4293 359.017,24.049C 358.605,23.667 358.396,23.183 358.396,22.61C 358.396,22.0279 358.607,21.5336 359.024,21.1421C 359.439,20.7522 359.944,20.5542 360.524,20.5542 Z M 374.707,26.7628C 375.387,26.9041 375.935,27.0894 376.336,27.3139L 376.383,27.3408L 376.383,30.7383L 376.235,30.631C 375.169,29.8574 374.042,29.4655 372.885,29.4655C 371.533,29.4655 370.422,29.9241 369.584,30.8282C 368.743,31.7343 368.317,32.9631 368.317,34.4804C 368.317,35.9881 368.726,37.1847 369.533,38.0378C 370.338,38.89 371.446,39.3221 372.827,39.3221C 373.324,39.3221 373.891,39.2119 374.513,38.9948C 375.137,38.7781 375.716,38.4765 376.235,38.0986L 376.383,37.9909L 376.383,41.2148L 376.337,41.2417C 375.192,41.9013 373.764,42.2356 372.091,42.2356C 370.659,42.2356 369.364,41.9207 368.243,41.3005C 367.122,40.679 366.236,39.7833 365.61,38.6372C 364.985,37.4933 364.668,36.1969 364.668,34.7828C 364.668,33.1691 364.994,31.7227 365.638,30.4834C 366.283,29.2413 367.233,28.2648 368.46,27.5811C 369.685,26.8979 371.125,26.552 372.741,26.552C 373.369,26.552 374.03,26.6228 374.707,26.7628 Z M 386.304,26.6528C 386.891,26.6528 387.355,26.7232 387.682,26.8624L 387.739,26.8864L 387.739,30.4347L 387.591,30.3278C 387.428,30.2105 387.152,30.0987 386.771,29.9959C 386.385,29.8927 386.03,29.8405 385.712,29.8405C 384.777,29.8405 384.011,30.2449 383.436,31.0429C 382.854,31.85 382.559,32.9189 382.559,34.2207L 382.559,41.8745L 379.04,41.8745L 379.04,26.9126L 382.559,26.9126L 382.559,29.5033L 382.596,29.5033C 382.926,28.6622 383.355,27.9881 383.95,27.4967C 384.628,26.937 385.42,26.6528 386.304,26.6528 Z M 398.661,38.0724C 399.328,37.2372 399.666,35.99 399.666,34.3647C 399.666,32.76 399.307,31.5278 398.599,30.7029C 397.894,29.8813 396.911,29.4657 395.676,29.4657C 394.402,29.4657 393.392,29.9008 392.673,30.7597C 391.951,31.6231 391.584,32.8652 391.584,34.4513C 391.584,35.9896 391.951,37.1999 392.673,38.0488C 393.391,38.8936 394.411,39.322 395.704,39.322C 397.005,39.322 398,38.9019 398.661,38.0724 Z M 395.863,26.5518C 398.187,26.5518 400.031,27.2433 401.341,28.6077C 402.651,29.9708 403.315,31.8688 403.315,34.2491C 403.315,36.6588 402.607,38.6127 401.211,40.057C 399.815,41.5026 397.893,42.2355 395.502,42.2355C 393.207,42.2355 391.352,41.539 389.989,40.1664C 388.626,38.7933 387.935,36.9094 387.935,34.5669C 387.935,32.1 388.642,30.1262 390.039,28.7009C 391.436,27.2748 393.396,26.5518 395.863,26.5518 Z M 411.121,33.0948C 412.514,33.6559 413.512,34.2914 414.087,34.9833C 414.666,35.6802 414.96,36.5453 414.96,37.5538C 414.96,38.9529 414.414,40.096 413.337,40.9529C 412.267,41.8039 410.801,42.2356 408.979,42.2356C 408.39,42.2356 407.711,42.1573 406.962,42.0023C 406.213,41.8478 405.577,41.6514 405.073,41.4189L 405.019,41.3937L 405.019,37.9631L 405.167,38.0696C 405.772,38.5046 406.443,38.8448 407.161,39.081C 407.879,39.3175 408.534,39.4373 409.11,39.4373C 410.658,39.4373 411.411,38.9488 411.411,37.9428C 411.411,37.5894 411.337,37.304 411.19,37.0947C 411.04,36.8813 410.773,36.6617 410.397,36.4438L 408.596,35.6048C 407.631,35.1897 406.902,34.782 406.431,34.3933C 405.955,34.0014 405.597,33.5332 405.366,33.0016C 405.136,32.4734 405.019,31.8494 405.019,31.1471C 405.019,29.7957 405.56,28.679 406.626,27.8276C 407.688,26.9812 409.076,26.5519 410.754,26.5519C 411.267,26.5519 411.858,26.6128 412.51,26.7334C 413.164,26.8548 413.701,27.0048 414.11,27.1796L 414.166,27.2036L 414.166,30.4573L 414.02,30.3583C 413.578,30.0571 413.047,29.8109 412.444,29.6274C 411.84,29.4435 411.233,29.3498 410.639,29.3498C 409.999,29.3498 409.489,29.494 409.123,29.7778C 408.759,30.06 408.582,30.4088 408.582,30.8439C 408.582,31.3348 408.725,31.7222 409.008,31.9965C 409.3,32.2795 410.011,32.649 411.121,33.0948 Z M 427.222,38.0724C 427.888,37.2371 428.226,35.99 428.226,34.3646C 428.226,32.7599 427.868,31.5277 427.16,30.7029C 426.455,29.8812 425.471,29.4657 424.236,29.4657C 422.963,29.4657 421.952,29.9007 421.234,30.7596C 420.511,31.623 420.145,32.8651 420.145,34.4512C 420.145,35.9895 420.511,37.1998 421.234,38.0487C 421.952,38.8935 422.972,39.3219 424.265,39.3219C 425.566,39.3219 426.561,38.9018 427.222,38.0724 Z M 424.423,26.5518C 426.747,26.5518 428.591,27.2433 429.902,28.6076C 431.212,29.9707 431.876,31.8687 431.876,34.249C 431.876,36.6587 431.168,38.6126 429.771,40.0569C 428.375,41.5025 426.454,42.2354 424.063,42.2354C 421.768,42.2354 419.913,41.5389 418.55,40.1663C 417.186,38.7932 416.495,36.9093 416.495,34.5668C 416.495,32.0999 417.203,30.1261 418.599,28.7008C 419.997,27.2747 421.956,26.5518 424.423,26.5518 Z M 450.642,29.7826L 447.077,29.7826L 447.077,36.8463C 447.077,37.7525 447.24,38.3993 447.56,38.7692C 447.877,39.1359 448.387,39.3215 449.077,39.3215L 449.78,39.2022L 450.497,38.8894L 450.642,38.7928L 450.642,41.691L 450.595,41.7179C 450.383,41.8393 450.023,41.9533 449.493,42.0672C 448.974,42.1787 448.464,42.2354 447.98,42.2354C 445.036,42.2354 443.544,40.6312 443.544,37.467L 443.544,29.7826L 438.263,29.7826L 438.263,41.8745L 434.7,41.8745L 434.7,29.7826L 432.218,29.7826L 432.218,26.9122L 434.7,26.9122L 434.7,24.841C 434.7,23.8007 434.929,22.8606 435.383,22.0469C 435.837,21.2319 436.485,20.5909 437.31,20.1414C 438.133,19.6939 439.078,19.4669 440.118,19.4669C 440.943,19.4669 441.608,19.5559 442.097,19.7321L 442.159,19.754L 442.159,22.7773L 442.028,22.7189C 441.503,22.4848 440.981,22.3659 440.478,22.3659C 439.779,22.3659 439.23,22.5905 438.846,23.0338C 438.459,23.4808 438.263,24.152 438.263,25.0287L 438.263,26.9122L 443.544,26.9122L 443.544,23.5314L 443.609,23.5111L 446.957,22.4865L 447.077,22.4496L 447.077,26.9122L 450.642,26.9122L 450.642,29.7826 Z "/>' + '<path fill="#686868" d="M 295.763,86.9415C 293.441,86.9415 291.587,86.2508 290.201,84.8695C 288.815,83.4882 288.122,81.6565 288.122,79.3746C 288.122,76.891 288.844,74.9517 290.289,73.5563C 291.734,72.161 293.681,71.4635 296.131,71.4635C 298.484,71.4635 300.317,72.1418 301.63,73.4982C 302.944,74.8547 303.6,76.7375 303.6,79.1466C 303.6,81.503 302.892,83.3913 301.477,84.8114C 300.062,86.2314 298.157,86.9415 295.763,86.9415 Z M 295.935,74.1424C 294.627,74.1424 293.593,74.5982 292.833,75.5097C 292.074,76.4213 291.694,77.6786 291.694,79.2816C 291.694,80.8257 292.078,82.0418 292.847,82.9301C 293.616,83.8185 294.646,84.2627 295.935,84.2627C 297.25,84.2627 298.261,83.8262 298.968,82.9534C 299.675,82.0806 300.028,80.8381 300.028,79.2258C 300.028,77.6042 299.675,76.3515 298.968,75.4679C 298.261,74.5843 297.25,74.1424 295.935,74.1424 Z M 315.506,75.0354C 315.091,74.6385 314.494,74.4401 313.716,74.4401C 312.699,74.4401 311.85,74.8927 311.169,75.7981C 310.489,76.7035 310.148,77.9344 310.148,79.4908L 310.148,86.6438L 306.874,86.6438L 306.874,71.7612L 310.148,71.7612L 310.148,74.7749L 310.209,74.7749C 310.544,73.7332 311.059,72.9208 311.755,72.3379C 312.451,71.7549 313.227,71.4635 314.083,71.4635C 314.706,71.4635 315.181,71.5581 315.506,71.7472L 315.506,75.0354 Z "/>' + '<path fill="#686868" d="M 28.7274,69.3415L 28.7274,61.271C 29.4541,61.9977 30.3205,62.6527 31.3267,63.2362C 32.3329,63.8197 33.4002,64.3105 34.5287,64.7088C 35.6572,65.1071 36.7839,65.4163 37.9089,65.6364C 39.0339,65.8565 40.0715,65.9666 41.0218,65.9666C 44.3338,65.9666 46.8021,65.39 48.4267,64.2372C 50.0513,63.0842 50.8636,61.4142 50.8636,59.2272C 50.8636,58.1162 50.5928,57.1537 50.0513,56.3396C 49.5098,55.5256 48.7534,54.7814 47.7821,54.1071C 46.8109,53.4328 45.6702,52.7865 44.36,52.1681L 40.1414,50.2343C 38.5343,49.3888 37.0355,48.5312 35.645,47.6612C 34.2545,46.7913 33.0456,45.8288 32.0185,44.7737C 30.9913,43.7185 30.186,42.529 29.6026,41.2048C 29.0191,39.8807 28.7274,38.3278 28.7274,36.5459C 28.7274,34.3519 29.2252,32.446 30.221,30.8285C 31.2167,29.2109 32.5321,27.8745 34.1671,26.8194C 35.8022,25.7644 37.6608,24.9818 39.7431,24.4717C 41.8253,23.9616 43.9495,23.7065 46.1156,23.7065C 51.0488,23.7065 54.6438,24.2655 56.9007,25.3835L 56.9007,33.0977C 54.2036,30.8617 50.7343,29.7437 46.493,29.7437C 45.3191,29.7437 44.1522,29.859 42.9922,30.0896C 41.8323,30.3202 40.7929,30.7027 39.8741,31.2373C 38.9553,31.7718 38.2093,32.4566 37.6364,33.2915C 37.0634,34.1266 36.7769,35.1345 36.7769,36.3153C 36.7769,37.3565 36.997,38.2578 37.4372,39.0195C 37.8774,39.7811 38.522,40.4764 39.371,41.1052C 40.22,41.7341 41.2576,42.3473 42.4839,42.9447L 46.734,44.8889C 48.39,45.7344 49.9517,46.6253 51.4191,47.5616C 52.8865,48.498 54.1774,49.5304 55.2919,50.6588C 56.4064,51.7873 57.2885,53.0415 57.9384,54.4215C 58.5882,55.8016 58.9131,57.372 58.9131,59.1328C 58.9131,61.5016 58.431,63.5 57.4667,65.1281C 56.5025,66.7561 55.2028,68.0802 53.5677,69.1004C 51.9327,70.1206 50.0531,70.8595 47.9289,71.3172C 45.8047,71.7749 43.5582,72.0037 41.1895,72.0037C 40.3999,72.0037 39.4304,71.9425 38.281,71.8203C 37.1315,71.698 35.9542,71.5216 34.7488,71.291C 33.5435,71.0604 32.4028,70.7809 31.3267,70.4525C 30.2507,70.1241 29.3842,69.7538 28.7274,69.3415 Z M 69.5934,30.4146C 68.3147,30.4146 67.2212,30.0077 66.3128,29.1936C 65.4044,28.3795 64.9502,27.3437 64.9502,26.0859C 64.9502,24.8352 65.4044,23.7906 66.3128,22.9521C 67.2212,22.1136 68.3147,21.6944 69.5934,21.6944C 70.921,21.6944 72.0442,22.1136 72.9631,22.9521C 73.8819,23.7906 74.3414,24.8352 74.3414,26.0859C 74.3414,27.2738 73.8819,28.2922 72.9631,29.1412C 72.0442,29.9902 70.921,30.4146 69.5934,30.4146 Z M 73.6706,71.3331L 66.2918,71.3331L 66.2918,37.7934L 73.5497,37.8614L 73.6706,71.3331 Z M 113.918,68.8385C 113.918,81.2343 107.829,87.4321 95.6495,87.4321C 91.3523,87.4321 87.6035,86.6809 84.4032,85.1787L 84.4032,78.041C 88.0297,80.2769 91.471,81.395 94.7272,81.395C 102.602,81.395 106.539,77.3807 106.539,69.3521L 106.539,65.5999L 106.414,65.5999C 103.926,69.8692 100.188,72.0039 95.1988,72.0039C 91.1601,72.0039 87.904,70.5225 85.4304,67.5598C 82.9568,64.5972 81.7201,60.6213 81.7201,55.6323C 81.7201,49.9724 83.0494,45.4725 85.7082,42.1326C 88.3669,38.7926 92.0161,37.1226 96.6557,37.1226C 101.044,37.1226 104.296,38.9288 106.414,42.5414L 106.539,42.5414L 106.539,37.7933L 113.918,37.7933L 113.918,68.8385 Z M 106.613,55.9572L 106.613,51.6389C 106.613,49.2982 105.856,47.2998 104.344,45.6438C 102.831,43.9877 100.943,43.1597 98.6786,43.1597C 95.8906,43.1597 93.7088,44.2148 92.1331,46.325C 90.5574,48.4352 89.7696,51.3875 89.7696,55.1816C 89.7696,58.4517 90.526,61.0668 92.0388,63.0267C 93.5515,64.9867 95.5552,65.9667 98.0497,65.9667C 100.586,65.9667 102.647,65.0304 104.234,63.1577C 105.82,61.2851 106.613,58.8849 106.613,55.9572 Z M 153.495,71.333L 146.116,71.333L 146.116,52.5193C 146.116,46.2795 143.884,43.1597 139.419,43.1597C 137.085,43.1597 135.158,44.0244 133.638,45.7538C 132.119,47.4832 131.359,49.6615 131.359,52.2887L 131.359,71.333L 123.98,71.333L 123.98,37.7933L 131.359,37.7933L 131.359,43.4846L 131.485,43.4846C 133.986,39.2432 137.595,37.1225 142.312,37.1225C 145.945,37.1225 148.717,38.3034 150.628,40.6652C 152.54,43.0269 153.495,46.4368 153.495,50.8948L 153.495,71.333 Z M 184.299,30.4146C 183.02,30.4146 181.927,30.0075 181.019,29.1935C 180.11,28.3794 179.656,27.3436 179.656,26.0858C 179.656,24.8351 180.11,23.7904 181.019,22.952C 181.927,22.1135 183.02,21.6942 184.299,21.6942C 185.627,21.6942 186.75,22.1135 187.669,22.952C 188.588,23.7904 189.047,24.8351 189.047,26.0858C 189.047,27.2737 188.588,28.2921 187.669,29.1411C 186.75,29.9901 185.627,30.4146 184.299,30.4146 Z M 188.376,71.333L 180.998,71.333L 180.998,37.7932L 188.344,37.8003L 188.376,71.333 Z M 227.953,71.3329L 220.574,71.3329L 220.574,52.5193C 220.574,46.2795 218.342,43.1596 213.877,43.1596C 211.543,43.1596 209.616,44.0243 208.097,45.7537C 206.577,47.4831 205.817,49.6614 205.817,52.2887L 205.817,71.3329L 198.438,71.3329L 198.438,37.7932L 205.817,37.7932L 205.817,43.4845L 205.943,43.4845C 208.444,39.2431 212.053,37.1224 216.77,37.1224C 220.403,37.1224 223.175,38.3033 225.087,40.6651C 226.998,43.0269 227.953,46.4367 227.953,50.8947L 227.953,71.3329 Z "/>' + '', 'login');
        var tdLogoHoriz = svgBoilerPlate('-20 -15 455 58', '<path fill="#5ACC13" d="M 144.047,34.0633C 152.854,34.0633 160.032,26.8941 160.032,18.0977C 160.032,9.30162 152.854,2.13243 144.047,2.13243C 135.24,2.13243 128.062,9.30162 128.062,18.0977C 128.062,26.8941 135.24,34.0633 144.047,34.0633 Z M 144.047,32.1437C 136.25,32.1437 129.984,25.8845 129.984,18.0977C 129.984,10.3109 136.251,3.96493 144.047,3.96493C 151.844,3.96493 158.11,10.3109 158.11,18.0977C 158.11,25.8845 151.844,32.1437 144.047,32.1437 Z M 142.113,22.7178C 142.452,22.7178 142.74,22.6112 142.977,22.3938C 143.213,22.1789 143.329,21.9187 143.329,21.617C 143.329,21.3135 143.213,21.0512 142.977,20.8303C 142.74,20.6126 142.452,20.5035 142.113,20.5035C 141.778,20.5035 141.496,20.6126 141.264,20.8303C 141.029,21.0512 140.914,21.3135 140.914,21.617C 140.914,21.9187 141.029,22.1789 141.264,22.3938C 141.496,22.6112 141.778,22.7178 142.113,22.7178 Z M 142.113,16.0708C 142.452,16.0708 142.74,15.9646 142.977,15.7489C 143.213,15.5312 143.329,15.2751 143.329,14.9734C 143.329,14.6666 143.213,14.4033 142.977,14.1858C 142.74,13.965 142.452,13.8566 142.113,13.8566C 141.778,13.8566 141.496,13.965 141.264,14.1858C 141.029,14.4033 140.914,14.6666 140.914,14.9734C 140.914,15.2751 141.029,15.5312 141.264,15.7489C 141.496,15.9646 141.778,16.0708 142.113,16.0708 Z M 145.957,25.2742C 147.724,23.309 148.61,20.8861 148.61,18.0047C 148.61,15.1131 147.727,12.6509 145.966,10.6178L 144.319,10.6178C 146.044,12.7258 146.908,15.1849 146.908,17.9883C 146.908,20.7687 146.047,23.1975 144.328,25.2742L 145.957,25.2742 Z M 15.8976,34.0625C 24.7052,34.0625 31.8824,26.8933 31.8824,18.0969C 31.8824,9.30157 24.7052,2.13238 15.8976,2.13238C 7.09033,2.13238 -7.77965e-006,9.30157 -7.77965e-006,18.0969C -7.77965e-006,26.8933 7.09033,34.0625 15.8976,34.0625 Z M 15.8976,32.2297C 8.10089,32.2297 1.83402,25.8838 1.83402,18.0969C 1.83402,10.3111 8.10089,4.05116 15.8976,4.05116C 23.6944,4.05116 30.0487,10.3111 30.0487,18.0969C 30.0487,25.8838 23.6944,32.2297 15.8976,32.2297 Z M 16.3347,20.453C 19.3352,20.453 21.7501,18.0391 21.7501,15.0444C 21.7501,12.0464 19.3352,9.63488 16.3347,9.63488C 13.3359,9.63488 10.8311,12.0464 10.8311,15.0444C 10.8311,18.0391 13.3359,20.453 16.3347,20.453 Z M 16.3347,19.0567C 16.1515,19.0567 15.9708,19.0449 15.7936,19.0221L 14.7623,15.2186L 17.9069,15.2186L 16.7929,19.0318C 16.6427,19.0483 16.4898,19.0567 16.3347,19.0567 Z M 20.352,15.0444C 20.352,16.7246 19.3582,18.1402 17.9135,18.744L 19.0423,14.8692C 19.0524,14.8114 19.0524,14.7529 19.0423,14.695C 19.0251,14.6313 18.9958,14.5714 18.9551,14.5209L 18.8681,14.4328L 18.7799,14.3457L 18.6927,14.3457L 18.6055,14.2586L 18.5183,14.2586L 14.1511,14.2586L 14.0629,14.2586C 14.0001,14.2759 13.9401,14.3063 13.8885,14.3457C 13.8166,14.3882 13.7556,14.4491 13.7141,14.5209C 13.6736,14.5725 13.6432,14.6323 13.6269,14.695L 13.6269,14.7821L 13.6269,14.8692L 14.7566,18.7495C 13.2804,18.1489 12.2288,16.7297 12.2288,15.0444C 12.2288,12.7988 14.0891,11.0309 16.3347,11.0309C 18.5832,11.0309 20.352,12.7988 20.352,15.0444 Z M 13.6513,21.9858L 18.9561,21.5727L 18.9624,21.034L 13.6645,21.026L 13.6513,21.9858 Z M 13.6513,22.3766L 13.6513,23.1086L 18.9512,22.6864L 18.9562,21.9474L 13.6513,22.3766 Z M 13.6706,23.4914L 13.7344,24.1272L 18.9513,23.7252L 18.9562,23.0752L 13.6706,23.4914 Z M 13.838,24.4958L 13.838,24.516L 13.8462,24.5151L 13.838,24.4958 Z M 13.8462,24.5151C 13.9245,24.6987 14.004,24.8784 14.1125,25.0484C 14.2241,25.2215 14.3692,25.3835 14.5262,25.5232C 14.6824,25.6629 14.8527,25.7855 15.0595,25.8889C 15.2643,25.9952 15.5046,26.0841 15.7366,26.1378C 15.9707,26.1906 16.1999,26.2067 16.4747,26.1764C 16.7485,26.146 17.0635,26.0649 17.3516,25.9444C 17.6425,25.8249 17.908,25.6629 18.1037,25.4949C 18.2994,25.3278 18.4281,25.1518 18.5265,24.9846C 18.6269,24.8146 18.6967,24.6526 18.7525,24.516L 18.8672,24.1938L 18.8833,24.1018L 18.045,24.1555L 14.6905,24.4289L 13.8462,24.5151 Z M 58.7067,34.0625C 67.5139,34.0625 74.6922,26.8933 74.6922,18.0969C 74.6922,9.30154 67.5139,2.13235 58.7067,2.13235C 49.9001,2.13235 42.7218,9.30154 42.7218,18.0969C 42.7218,26.8933 49.9001,34.0625 58.7067,34.0625 Z M 58.7063,32.2299C 50.9106,32.2299 44.6434,25.8839 44.6434,18.0971C 44.6434,10.3113 50.9106,4.05133 58.7063,4.05133C 66.503,4.05133 72.7698,10.3113 72.7698,18.0971C 72.7698,25.8839 66.503,32.2299 58.7063,32.2299 Z M 51.8838,25.6428L 54.5955,25.2188L 52.3063,22.9356L 51.8838,25.6428 Z M 55.9113,24.8147L 64.1227,16.6148L 60.8909,13.386L 52.6795,21.587L 55.9113,24.8147 Z M 64.8214,15.9162L 65.52,15.2187C 65.6506,15.089 65.6278,15.0956 65.6831,15.0404C 66.5185,14.2061 66.4252,12.8181 65.5898,11.9838C 64.7565,11.1515 63.3626,11.0148 62.5304,11.8491L 62.288,12.0778L 61.6768,12.6885L 64.8214,15.9162 Z M 101.238,34.0624C 110.045,34.0624 117.223,26.8932 117.223,18.0968C 117.223,9.30075 110.045,2.13233 101.238,2.13233C 92.4305,2.13233 85.3402,9.30075 85.3402,18.0968C 85.3402,26.8932 92.4305,34.0624 101.238,34.0624 Z M 101.238,32.23C 93.4411,32.23 87.1742,25.8837 87.1742,18.0969C 87.1742,10.3101 93.4411,4.05118 101.238,4.05118C 109.035,4.05118 115.389,10.3101 115.389,18.0969C 115.389,25.8837 109.035,32.23 101.238,32.23 Z M 107.567,18.1122L 98.0294,10.9521L 98.0294,25.2702L 107.567,18.1122 Z "/>' + '<path fill="#000000" d="M 201.679,28.4272C 200.753,28.851 199.884,29.0629 199.072,29.0629C 196.153,29.0629 194.694,27.3434 194.694,23.9042L 194.694,10.8501L 191.208,10.8501L 191.208,9.30013L 194.694,9.30013L 194.694,4.09301L 195.664,3.77817C 196,3.68936 196.323,3.59248 196.634,3.48754L 196.634,9.30013L 201.679,9.30013L 201.679,10.8501L 196.634,10.8501L 196.634,23.6923C 196.634,25.0365 196.843,26.0093 197.259,26.6107C 197.675,27.2122 198.383,27.5129 199.381,27.5129C 200.092,27.5129 200.858,27.2788 201.679,26.8105L 201.679,28.4272 Z M 213.331,29.0629C 210.458,29.0629 208.185,28.1406 206.514,26.2959C 204.842,24.4512 204.007,22.0535 204.007,19.1029C 204.007,15.91 204.881,13.4134 206.629,11.6131C 208.377,9.81281 210.68,8.91267 213.538,8.91267C 216.347,8.91267 218.565,9.80676 220.192,11.5949C 221.818,13.3831 222.632,15.8595 222.632,19.0241C 222.632,22.0152 221.802,24.4361 220.143,26.2868C 218.484,28.1376 216.213,29.0629 213.331,29.0629 Z M 213.459,10.4627C 211.171,10.4627 209.347,11.2276 207.987,12.7575C 206.627,14.2873 205.947,16.4145 205.947,19.1392C 205.947,21.662 206.611,23.6883 207.939,25.2182C 209.266,26.748 211.082,27.5129 213.386,27.5129C 215.726,27.5129 217.529,26.7601 218.794,25.2545C 220.059,23.7489 220.692,21.66 220.692,18.9878C 220.692,16.2389 220.062,14.1309 218.803,12.6636C 217.544,11.1963 215.763,10.4627 213.459,10.4627 Z M 240.093,28.6754L 240.093,25.085L 240.02,25.085C 238.666,27.7369 236.583,29.0629 233.769,29.0629C 229.19,29.0629 226.9,26.193 226.9,20.4531L 226.9,9.30017L 228.84,9.30017L 228.84,20.0413C 228.84,22.657 229.266,24.5562 230.117,25.7389C 230.967,26.9216 232.306,27.5129 234.133,27.5129C 235.908,27.5129 237.344,26.8519 238.444,25.53C 239.543,24.208 240.093,22.4471 240.093,20.2472L 240.093,9.30017L 242.033,9.30017L 242.033,28.6754L 240.093,28.6754 Z M 260.967,27.7733C 259.496,28.633 257.74,29.0629 255.699,29.0629C 252.999,29.0629 250.822,28.1658 249.169,26.3716C 247.516,24.5774 246.689,22.2291 246.689,19.3269C 246.689,16.2753 247.619,13.7767 249.478,11.8311C 251.338,9.88546 253.728,8.91266 256.651,8.91266C 258.158,8.91266 259.623,9.20732 261.046,9.79665L 261.046,11.7523C 259.636,10.8926 258.09,10.4627 256.408,10.4627C 254.096,10.4627 252.222,11.275 250.785,12.8997C 249.348,14.5244 248.629,16.6285 248.629,19.2118C 248.629,21.7104 249.287,23.7186 250.603,25.2363C 251.919,26.754 253.654,27.5129 255.808,27.5129C 257.784,27.5129 259.504,26.9942 260.967,25.9569L 260.967,27.7733 Z M 278.507,28.6754L 278.507,17.0866C 278.507,14.7979 278.097,13.1217 277.276,12.0581C 276.456,10.9945 275.177,10.4627 273.439,10.4627C 271.802,10.4627 270.362,11.1105 269.119,12.4063C 267.876,13.702 267.255,15.5588 267.255,17.9767L 267.255,28.6754L 265.314,28.6754L 265.314,2.67029e-005L 267.255,2.67029e-005L 267.255,12.8483L 267.333,12.8483C 268.861,10.2245 271.084,8.91265 274.003,8.91265C 276.1,8.91265 277.699,9.58473 278.798,10.9289C 279.898,12.2731 280.447,14.2005 280.447,16.7112L 280.447,28.6754L 278.507,28.6754 Z M 303.341,28.6754L 299.072,28.6754L 299.072,25.309L 299,25.309C 297.597,27.8116 295.439,29.0629 292.525,29.0629C 290.16,29.0629 288.267,28.2011 286.847,26.4776C 285.426,24.754 284.716,22.4087 284.716,19.4419C 284.716,16.2571 285.501,13.706 287.071,11.7887C 288.641,9.87132 290.734,8.91265 293.349,8.91265C 295.94,8.91265 297.823,9.95609 299,12.043L 299.072,12.043L 299.072,2.28882e-005L 303.341,2.28882e-005L 303.341,28.6754 Z M 299.133,19.8052L 299.133,17.2925C 299.133,15.9281 298.698,14.7717 297.827,13.8231C 296.955,12.8745 295.847,12.4002 294.501,12.4002C 292.909,12.4002 291.656,13.0057 290.742,14.2166C 289.829,15.4276 289.372,17.1088 289.372,19.2603C 289.372,21.2099 289.81,22.7498 290.688,23.8801C 291.565,25.0103 292.743,25.5754 294.222,25.5754C 295.681,25.5754 296.865,25.0284 297.772,23.9345C 298.679,22.8407 299.133,21.4642 299.133,19.8052 Z M 326.234,20.1503L 312.653,20.1503C 312.706,21.886 313.274,23.2241 314.357,24.1646C 315.44,25.1051 316.93,25.5754 318.825,25.5754C 320.951,25.5754 322.904,24.9295 324.682,23.6379L 324.682,27.3252C 322.855,28.4837 320.442,29.0629 317.443,29.0629C 314.496,29.0629 312.185,28.189 310.51,26.4412C 308.835,24.6934 307.997,22.2332 307.997,19.0604C 307.997,16.0654 308.919,13.6253 310.762,11.7402C 312.605,9.85517 314.894,8.91264 317.631,8.91264C 320.367,8.91264 322.485,9.75728 323.985,11.4466C 325.484,13.1359 326.234,15.4801 326.234,18.4792L 326.234,20.1503 Z M 321.578,17.0503C 321.566,15.581 321.196,14.4386 320.468,13.6233C 319.741,12.8079 318.736,12.4002 317.455,12.4002C 316.198,12.4002 315.134,12.8291 314.263,13.6868C 313.392,14.5446 312.855,15.6657 312.653,17.0503L 321.578,17.0503 Z M 346.799,9.30015L 339.148,28.6754L 334.298,28.6754L 327.01,9.30015L 331.788,9.30015L 336.256,22.8507C 336.595,23.8478 336.806,24.7176 336.887,25.4603L 336.947,25.4603C 337.064,24.5279 337.246,23.6823 337.493,22.9234L 342.179,9.30015L 346.799,9.30015 Z M 366.589,20.1503L 353.008,20.1503C 353.06,21.886 353.628,23.2241 354.711,24.1646C 355.795,25.1051 357.284,25.5754 359.18,25.5754C 361.306,25.5754 363.258,24.9295 365.036,23.6379L 365.036,27.3252C 363.209,28.4837 360.796,29.0629 357.797,29.0629C 354.851,29.0629 352.54,28.189 350.864,26.4412C 349.189,24.6934 348.351,22.2331 348.351,19.0604C 348.351,16.0653 349.273,13.6253 351.116,11.7402C 352.959,9.85516 355.249,8.91264 357.985,8.91264C 360.722,8.91264 362.84,9.75727 364.339,11.4466C 365.839,13.1358 366.589,15.48 366.589,18.4792L 366.589,20.1503 Z M 361.932,17.0503C 361.92,15.581 361.55,14.4386 360.823,13.6233C 360.095,12.8079 359.091,12.4002 357.809,12.4002C 356.552,12.4002 355.488,12.8291 354.617,13.6868C 353.746,14.5446 353.21,15.6657 353.008,17.0503L 361.932,17.0503 Z M 374.349,28.6754L 370.081,28.6754L 370.081,0L 374.349,0L 374.349,28.6754 Z M 388.967,29.0629C 385.939,29.0629 383.522,28.1638 381.715,26.3655C 379.909,24.5672 379.005,22.1827 379.005,19.2118C 379.005,15.9786 379.947,13.4537 381.831,11.6373C 383.714,9.82084 386.252,8.91263 389.446,8.91263C 392.513,8.91263 394.903,9.79562 396.615,11.5616C 398.327,13.3276 399.182,15.7787 399.182,18.9151C 399.182,21.9829 398.26,24.4411 396.415,26.2898C 394.57,28.1386 392.087,29.0629 388.967,29.0629 Z M 389.191,12.4002C 387.485,12.4002 386.137,12.9935 385.147,14.1803C 384.157,15.367 383.662,17.0038 383.662,19.0907C 383.662,21.1009 384.163,22.6842 385.165,23.8407C 386.168,24.9971 387.509,25.5754 389.191,25.5754C 390.905,25.5754 392.222,25.0072 393.144,23.871C 394.065,22.7347 394.526,21.117 394.526,19.018C 394.526,16.9069 394.065,15.2762 393.144,14.1258C 392.222,12.9754 390.905,12.4002 389.191,12.4002 Z M 407.798,25.7449L 407.719,25.7449L 407.719,37.588L 403.451,37.588L 403.451,9.30013L 407.719,9.30013L 407.719,12.7574L 407.798,12.7574C 409.326,10.1942 411.561,8.91262 414.503,8.91262C 417.009,8.91262 418.963,9.77341 420.363,11.495C 421.764,13.2166 422.464,15.5285 422.464,18.4307C 422.464,21.6478 421.674,24.2241 420.093,26.1597C 418.513,28.0952 416.355,29.0629 413.618,29.0629C 411.1,29.0629 409.16,27.9569 407.798,25.7449 Z M 407.683,18.1704L 407.683,20.5499C 407.683,21.9506 408.138,23.1383 409.05,24.1131C 409.961,25.088 411.12,25.5754 412.527,25.5754C 414.172,25.5754 415.463,24.9477 416.401,23.6923C 417.339,22.437 417.808,20.6851 417.808,18.4368C 417.808,16.5477 417.371,15.0693 416.498,14.0017C 415.625,12.934 414.441,12.4002 412.945,12.4002C 411.365,12.4002 410.093,12.9501 409.129,14.0501C 408.165,15.1501 407.683,16.5235 407.683,18.1704 Z "/>');
        var horizontalMarker = svgBoilerPlate('0 0 100 30', "<path fill='#E72A59' d='M 0.583332,10.9896L 71.726,10.9896C 73.4524,5.17697 78.8353,0.937502 85.2083,0.937502C 92.9748,0.937502 99.2708,7.2335 99.2708,15C 99.2708,22.7665 92.9748,29.0625 85.2083,29.0625C 78.8353,29.0625 73.4524,24.823 71.726,19.0104L 0.583332,19.0104L 0.583332,10.9896 Z'/>" + "<path fill='#FFFFFF' d='M 85.2083,5.52735C 90.4399,5.52735 94.681,9.76839 94.681,15C 94.681,20.2316 90.4399,24.4727 85.2083,24.4727C 79.9767,24.4727 75.7158,20.2316 75.7357,15C 75.7552,9.85417 79.9767,5.52735 85.2083,5.52735 Z '/>");
        var verticalMarker = svgBoilerPlate('0 0 30 100', "<path fill='#E72A59' d='M 19.0104,0.583336L 19.0104,71.726C 24.823,73.4524 29.0625,78.8353 29.0625,85.2083C 29.0625,92.9748 22.7665,99.2708 15,99.2708C 7.23349,99.2708 0.937499,92.9748 0.937499,85.2083C 0.937499,78.8353 5.17696,73.4524 10.9896,71.726L 10.9896,0.583336L 19.0104,0.583336 Z'/>" + "<path fill='#FFFFFF' d='M 24.4727,85.2083C 24.4727,90.4399 20.2316,94.681 15,94.681C 9.7684,94.681 5.52735,90.4399 5.52735,85.2083C 5.52735,79.9767 9.76844,75.7158 15,75.7357C 20.1458,75.7552 24.4727,79.9767 24.4727,85.2083 Z'/>");
        var tdLogo = svgBoilerPlate('0 0 2200 480', '<path fill="#0095FF" d="M 396.586,234.249L 284.566,318.402L 284.566,150.077L 396.586,234.249 Z M 314.585,31.9531C 425.459,28.0533 517.645,115.134 521.618,225.278C 525.049,335.522 438.076,428.204 327.832,431.628C 258.702,433.933 196.856,400.879 159.138,348.896L 179.394,334.162C 212.455,379.699 266.374,408.679 326.994,406.689C 423.623,403.68 499.688,322.771 496.679,226.115C 493.168,129.373 412.788,53.5758 315.576,57.0802L 315.422,57.0802C 265.851,58.5744 222.036,80.4518 190.966,114.531L 172.352,97.6253C 207.744,58.8358 258.099,33.7086 314.585,31.9531 Z M 100.167,94.925C 154.609,94.925 199.342,139.108 199.342,194.1C 199.342,249.091 154.609,293.121 100.167,293.121C 45.7246,293.121 -5.03592e-005,249.225 -5.03592e-005,194.1C -5.03592e-005,138.981 45.7246,94.925 100.167,94.925 Z M 100.167,112.018C 54.911,112.018 17.0931,148.456 17.0931,194.1C 17.0931,232.494 43.8115,264.227 79.2072,273.371L 63.3136,216.165L 60.6467,206.851L 139.378,206.851L 136.336,216.352L 119.25,273.825C 155.335,265.333 182.248,233.235 182.248,194.1C 182.248,148.322 145.422,112.018 100.167,112.018 Z M 100.167,276.028L 102.584,275.993L 118.935,221.74L 80.7484,221.74L 95.7724,275.913L 100.167,276.028 Z M 54.5961,296.967L 143.037,296.967L 143.037,306.073L 54.5961,313.035L 54.5961,296.967 Z M 143.037,312.512L 143.037,324.841L 54.5961,331.803L 54.5961,319.474L 143.037,312.512 Z M 143.037,331.28L 143.037,341.988L 55.6682,348.95L 54.5962,338.242L 143.037,331.28 Z M 57.8191,354.86L 72.2924,353.788L 128.564,348.95L 142.514,347.871L 141.965,349.499L 139.847,354.86L 136.075,362.9C 134.48,365.567 132.336,368.79 129.113,371.484C 125.897,374.151 121.602,376.824 116.784,378.968C 111.973,381.112 106.606,382.191 102.311,382.741C 97.4999,383.263 93.7275,382.741 89.9818,382.191C 86.2429,381.112 81.9479,380.04 78.7316,377.896C 75.5086,376.301 72.2924,374.151 69.6188,372.006C 66.9252,369.862 64.781,367.189 62.6302,363.972C 60.486,361.272 58.8912,358.605 57.8191,354.86 Z "/>' + '<path class="hidden-portrait" fill="#7e7e7e" d="M 751.846,162.195L 732.672,162.195L 732.672,89.8798C 732.672,83.9597 733.055,76.7088 733.821,68.1279L 733.521,68.1279C 732.423,73.017 731.441,76.5259 730.575,78.6546L 698.32,162.195L 685.986,162.195L 653.656,79.2782C 652.74,76.8335 651.783,73.1168 650.785,68.1279L 650.485,68.1279C 650.951,72.6013 651.184,79.9018 651.184,90.0294L 651.184,162.195L 632.011,162.195L 632.011,50.4419L 660.147,50.4419L 688.233,124.877C 690.38,130.582 691.778,134.839 692.428,137.649L 692.802,137.649C 694.633,131.779 696.123,127.414 697.271,124.553L 725.882,50.4419L 751.846,50.4419L 751.846,162.195 Z M 780.48,64.814C 777.435,64.814 774.83,63.8453 772.666,61.9079C 770.502,59.9706 769.42,57.5052 769.42,54.5116C 769.42,51.5348 770.502,49.0488 772.666,47.0532C 774.83,45.0575 777.435,44.0597 780.48,44.0597C 783.643,44.0597 786.318,45.0575 788.507,47.0532C 790.695,49.0488 791.79,51.5348 791.79,54.5116C 791.79,57.3388 790.695,59.7625 788.507,61.7832C 786.318,63.8036 783.643,64.814 780.48,64.814 Z M 790.192,162.198L 772.616,162.198L 772.616,82.3751L 790.192,82.3751L 790.192,162.198 Z M 868.485,158.407C 862.093,161.999 854.529,163.795 845.791,163.795C 833.94,163.795 824.374,160.116 817.093,152.757C 809.811,145.398 806.17,135.865 806.17,124.157C 806.17,111.087 810.077,100.589 817.891,92.6648C 825.706,84.7408 836.154,80.7786 849.236,80.7786C 856.509,80.7786 862.926,82.0591 868.485,84.6201L 868.485,101.533C 863.025,97.2756 857.2,95.147 851.008,95.147C 843.502,95.147 837.348,97.7079 832.546,102.83C 827.745,107.952 825.344,114.654 825.344,122.935C 825.344,131.117 827.607,137.578 832.135,142.317C 836.662,147.057 842.737,149.427 850.359,149.427C 856.767,149.427 862.809,147.298 868.485,143.041L 868.485,158.407 Z M 929.202,99.9362C 926.971,97.8075 923.768,96.7432 919.59,96.7432C 914.131,96.7432 909.575,99.1714 905.921,104.027C 902.268,108.883 900.441,115.485 900.441,123.833L 900.441,162.198L 882.865,162.198L 882.865,82.3751L 900.441,82.3751L 900.441,98.5393L 900.766,98.5393C 902.563,92.9518 905.331,88.5946 909.067,85.4682C 912.803,82.3418 916.969,80.7786 921.562,80.7786C 924.908,80.7786 927.454,81.2856 929.202,82.3002L 929.202,99.9362 Z M 975.014,163.795C 962.548,163.795 952.595,160.09 945.155,152.682C 937.716,145.273 933.996,135.449 933.996,123.209C 933.996,109.889 937.874,99.4871 945.63,92.0038C 953.386,84.5203 963.838,80.7784 976.987,80.7784C 989.619,80.7784 999.46,84.4163 1006.51,91.6918C 1013.56,98.9675 1017.08,109.066 1017.08,121.987C 1017.08,134.626 1013.28,144.753 1005.68,152.37C 998.087,159.986 987.863,163.795 975.014,163.795 Z M 975.938,95.1467C 968.914,95.1467 963.364,97.5914 959.286,102.48C 955.208,107.37 953.169,114.113 953.169,122.71C 953.169,130.992 955.233,137.515 959.361,142.28C 963.489,147.044 969.014,149.427 975.938,149.427C 982.995,149.427 988.421,147.086 992.216,142.404C 996.011,137.723 997.908,131.059 997.908,122.411C 997.908,113.714 996.011,106.996 992.216,102.256C 988.421,97.5167 982.995,95.1467 975.938,95.1467 Z M 1026.67,159.18L 1026.67,141.444C 1033.36,146.766 1040.74,149.427 1048.81,149.427C 1059.62,149.427 1065.02,146.574 1065.02,140.87C 1065.02,139.058 1064.55,137.519 1063.63,136.256C 1062.71,134.992 1061.46,133.869 1059.89,132.888C 1058.31,131.907 1056.46,131.03 1054.32,130.256L 1047.17,127.625C 1043.92,126.344 1041,124.98 1038.39,123.534C 1035.79,122.087 1033.62,120.449 1031.89,118.62C 1030.16,116.791 1028.85,114.712 1027.98,112.384C 1027.11,110.055 1026.67,107.345 1026.67,104.252C 1026.67,100.427 1027.58,97.055 1029.42,94.1364C 1031.25,91.218 1033.71,88.765 1036.79,86.7776C 1039.88,84.7904 1043.38,83.2937 1047.3,82.2876C 1051.22,81.2815 1055.28,80.7784 1059.47,80.7784C 1066.9,80.7784 1073.54,81.9842 1079.4,84.3953L 1079.4,101.533C 1073.92,97.2754 1067.63,95.1467 1060.52,95.1467C 1058.29,95.1467 1056.28,95.3545 1054.48,95.7704C 1052.68,96.1862 1051.15,96.7597 1049.87,97.4915C 1048.6,98.2231 1047.61,99.1046 1046.9,100.136C 1046.2,101.167 1045.84,102.306 1045.84,103.553C 1045.84,105.249 1046.2,106.692 1046.93,107.881C 1047.65,109.07 1048.73,110.118 1050.15,111.024C 1051.57,111.93 1053.27,112.758 1055.25,113.506L 1062.12,115.951C 1065.52,117.331 1068.57,118.745 1071.28,120.191C 1074,121.638 1076.31,123.28 1078.22,125.118C 1080.14,126.955 1081.61,129.071 1082.64,131.466C 1083.67,133.861 1084.19,136.713 1084.19,140.022C 1084.19,144.047 1083.24,147.556 1081.34,150.549C 1079.45,153.542 1076.92,156.02 1073.75,157.983C 1070.59,159.945 1066.94,161.404 1062.79,162.36C 1058.65,163.317 1054.28,163.795 1049.69,163.795C 1040.83,163.795 1033.16,162.257 1026.67,159.18 Z M 1133.2,163.795C 1120.73,163.795 1110.78,160.09 1103.34,152.682C 1095.9,145.273 1092.18,135.449 1092.18,123.209C 1092.18,109.889 1096.06,99.4871 1103.81,92.0036C 1111.57,84.52 1122.02,80.7784 1135.17,80.7784C 1147.8,80.7784 1157.64,84.416 1164.69,91.6918C 1171.74,98.9673 1175.27,109.066 1175.27,121.987C 1175.27,134.626 1171.47,144.753 1163.87,152.37C 1156.27,159.986 1146.05,163.795 1133.2,163.795 Z M 1134.12,95.1465C 1127.1,95.1465 1121.55,97.5912 1117.47,102.48C 1113.39,107.37 1111.35,114.113 1111.35,122.71C 1111.35,130.992 1113.42,137.515 1117.55,142.28C 1121.67,147.044 1127.2,149.427 1134.12,149.427C 1141.18,149.427 1146.61,147.086 1150.4,142.404C 1154.19,137.723 1156.09,131.059 1156.09,122.411C 1156.09,113.714 1154.19,106.996 1150.4,102.256C 1146.61,97.5164 1141.18,95.1465 1134.12,95.1465 Z M 1231.99,58.4276C 1229.44,57.3633 1226.54,56.8311 1223.28,56.8311C 1214.12,56.8311 1209.54,61.7621 1209.54,71.6234L 1209.54,82.3746L 1228.79,82.3746L 1228.79,96.743L 1209.62,96.743L 1209.62,162.198L 1192.04,162.198L 1192.04,96.743L 1177.66,96.743L 1177.66,82.3746L 1192.04,82.3746L 1192.04,69.5032C 1192.04,61.1382 1194.83,54.5403 1200.39,49.7094C 1205.96,44.8783 1212.92,42.4628 1221.28,42.4628C 1225.79,42.4628 1229.36,42.9367 1231.99,43.8847L 1231.99,58.4276 Z M 1282.32,161.051C 1278.82,162.88 1274.23,163.795 1268.54,163.795C 1253.23,163.795 1245.57,156.403 1245.57,141.619L 1245.57,96.743L 1232.79,96.743L 1232.79,82.3746L 1245.57,82.3746L 1245.57,63.641L 1263.15,58.4276L 1263.15,82.3746L 1282.32,82.3746L 1282.32,96.743L 1263.15,96.743L 1263.15,136.355C 1263.15,141.045 1264.01,144.396 1265.73,146.408C 1267.45,148.42 1270.32,149.426 1274.33,149.426C 1277.41,149.426 1280.07,148.362 1282.32,146.233L 1282.32,161.051 Z M 746.992,250.992L 699.508,250.992L 699.508,393.442L 671.018,393.442L 671.018,250.992L 623.535,250.992L 623.535,227.249L 746.992,227.249L 746.992,250.992 Z M 796.071,395.816C 777.548,395.816 762.758,390.307 751.704,379.289C 740.649,368.272 735.121,353.662 735.121,335.459C 735.121,315.651 740.884,300.182 752.408,289.053C 763.933,277.924 779.464,272.359 799.002,272.359C 817.773,272.359 832.395,277.769 842.869,288.589C 853.343,299.409 858.579,314.427 858.579,333.642C 858.579,352.437 852.935,367.499 841.645,378.826C 830.355,390.152 815.164,395.816 796.071,395.816 Z M 797.444,293.727C 787.007,293.727 778.76,297.362 772.7,304.633C 766.641,311.904 763.612,321.933 763.612,334.718C 763.612,347.034 766.678,356.734 772.812,363.82C 778.945,370.905 787.156,374.448 797.444,374.448C 807.93,374.448 815.992,370.967 821.631,364.005C 827.27,357.044 830.089,347.133 830.089,334.272C 830.089,321.339 827.27,311.348 821.631,304.299C 815.992,297.251 807.93,293.727 797.444,293.727 Z M 986.786,393.442L 960.67,393.442L 960.67,374.226L 960.225,374.226C 952.459,388.619 940.415,395.816 924.092,395.816C 896.245,395.816 882.322,379.023 882.322,345.438L 882.322,274.733L 908.438,274.733L 908.438,342.582C 908.438,363.826 916.698,374.448 933.218,374.448C 941.206,374.448 947.779,371.524 952.935,365.675C 958.092,359.826 960.67,352.165 960.67,342.693L 960.67,274.733L 986.786,274.733L 986.786,393.442 Z M 1107.87,387.803C 1098.37,393.145 1087.13,395.816 1074.15,395.816C 1056.54,395.816 1042.33,390.344 1031.51,379.4C 1020.69,368.457 1015.28,354.28 1015.28,336.869C 1015.28,317.431 1021.08,301.82 1032.69,290.035C 1044.3,278.251 1059.83,272.358 1079.27,272.358C 1090.08,272.358 1099.61,274.263 1107.87,278.071L 1107.87,303.223C 1099.76,296.892 1091.1,293.726 1081.9,293.726C 1070.75,293.726 1061.6,297.535 1054.47,305.152C 1047.33,312.769 1043.77,322.736 1043.77,335.051C 1043.77,347.219 1047.13,356.827 1053.86,363.875C 1060.58,370.924 1069.61,374.448 1080.94,374.448C 1090.46,374.448 1099.44,371.282 1107.87,364.951L 1107.87,387.803 Z M 1238.45,393.441L 1212.33,393.441L 1212.33,328.819C 1212.33,305.424 1204.4,293.726 1188.52,293.726C 1180.53,293.726 1173.8,297.114 1168.32,303.891C 1162.84,310.667 1160.1,319.323 1160.1,329.857L 1160.1,393.441L 1133.99,393.441L 1133.99,217.752L 1160.1,217.752L 1160.1,294.876L 1160.55,294.876C 1169.5,279.864 1182.31,272.358 1198.98,272.358C 1225.29,272.358 1238.45,288.421 1238.45,320.547L 1238.45,393.441 Z M 1340.54,393.441L 1340.54,227.248L 1388.58,227.248C 1449.94,227.248 1480.62,254.255 1480.62,308.268C 1480.62,333.913 1472.1,354.521 1455.08,370.089C 1438.05,385.657 1415.23,393.441 1386.62,393.441L 1340.54,393.441 Z M 1369.03,250.99L 1369.03,369.699L 1390.96,369.699C 1410.27,369.699 1425.3,364.401 1436.03,353.803C 1446.76,343.206 1452.13,328.238 1452.13,308.898C 1452.13,270.293 1432.08,250.99 1391.99,250.99L 1369.03,250.99 Z M 1611.2,341.209L 1528.1,341.209C 1528.42,351.843 1531.9,360.042 1538.53,365.804C 1545.15,371.566 1554.27,374.448 1565.87,374.448C 1578.88,374.448 1590.82,370.491 1601.7,362.577L 1601.7,385.169C 1590.52,392.266 1575.76,395.815 1557.41,395.815C 1539.38,395.815 1525.24,390.461 1514.99,379.752C 1504.74,369.044 1499.61,353.97 1499.61,334.531C 1499.61,316.182 1505.25,301.232 1516.53,289.682C 1527.81,278.133 1541.82,272.358 1558.56,272.358C 1575.3,272.358 1588.26,277.533 1597.44,287.883C 1606.61,298.233 1611.2,312.596 1611.2,330.97L 1611.2,341.209 Z M 1582.71,322.216C 1582.63,313.214 1580.37,306.215 1575.92,301.219C 1571.47,296.224 1565.32,293.726 1557.48,293.726C 1549.79,293.726 1543.28,296.353 1537.95,301.609C 1532.62,306.864 1529.34,313.733 1528.1,322.216L 1582.71,322.216 Z M 1737.03,274.732L 1690.22,393.441L 1660.54,393.441L 1615.95,274.732L 1645.18,274.732L 1672.52,357.754C 1674.6,363.863 1675.88,369.192 1676.38,373.743L 1676.75,373.743C 1677.47,368.03 1678.58,362.849 1680.09,358.199L 1708.76,274.732L 1737.03,274.732 Z M 1858.12,341.209L 1775.02,341.209C 1775.34,351.843 1778.81,360.042 1785.44,365.804C 1792.07,371.566 1801.18,374.447 1812.78,374.447C 1825.79,374.447 1837.74,370.49 1848.62,362.576L 1848.62,385.168C 1837.44,392.266 1822.68,395.815 1804.33,395.815C 1786.3,395.815 1772.16,390.461 1761.91,379.752C 1751.65,369.044 1746.53,353.97 1746.53,334.531C 1746.53,316.181 1752.17,301.231 1763.44,289.682C 1774.72,278.132 1788.73,272.357 1805.48,272.357C 1822.22,272.357 1835.18,277.533 1844.35,287.882C 1853.53,298.233 1858.12,312.595 1858.12,330.97L 1858.12,341.209 Z M 1829.63,322.216C 1829.55,313.214 1827.29,306.215 1822.84,301.219C 1818.38,296.223 1812.24,293.725 1804.4,293.725C 1796.71,293.725 1790.2,296.353 1784.87,301.608C 1779.54,306.864 1776.26,313.733 1775.02,322.216L 1829.63,322.216 Z M 1905.6,393.441L 1879.48,393.441L 1879.48,217.751L 1905.6,217.751L 1905.6,393.441 Z M 1995.04,395.815C 1976.52,395.815 1961.73,390.306 1950.67,379.288C 1939.62,368.271 1934.09,353.661 1934.09,335.458C 1934.09,315.649 1939.85,300.18 1951.38,289.051C 1962.9,277.922 1978.43,272.357 1997.97,272.357C 2016.74,272.357 2031.36,277.767 2041.84,288.587C 2052.31,299.407 2057.55,314.425 2057.55,333.641C 2057.55,352.436 2051.9,367.498 2040.61,378.825C 2029.32,390.151 2014.13,395.815 1995.04,395.815 Z M 1996.41,293.725C 1985.98,293.725 1977.73,297.36 1971.67,304.631C 1965.61,311.902 1962.58,321.931 1962.58,334.717C 1962.58,347.033 1965.65,356.733 1971.78,363.819C 1977.91,370.904 1986.12,374.447 1996.41,374.447C 2006.9,374.447 2014.96,370.966 2020.6,364.004C 2026.24,357.043 2029.06,347.132 2029.06,334.271C 2029.06,321.337 2026.24,311.346 2020.6,304.297C 2014.96,297.249 2006.9,293.725 1996.41,293.725 Z M 2110.26,375.486L 2109.78,375.486L 2109.78,448.047L 2083.66,448.047L 2083.66,274.731L 2109.78,274.731L 2109.78,295.913L 2110.26,295.913C 2119.61,280.209 2133.29,272.357 2151.29,272.357C 2166.63,272.357 2178.58,277.631 2187.15,288.179C 2195.72,298.726 2200,312.891 2200,330.673C 2200,350.384 2195.17,366.168 2185.5,378.027C 2175.83,389.885 2162.62,395.815 2145.88,395.815C 2130.47,395.815 2118.6,389.039 2110.26,375.486 Z M 2109.56,329.078L 2109.56,343.657C 2109.56,352.238 2112.35,359.516 2117.92,365.488C 2123.5,371.461 2130.59,374.447 2139.2,374.447C 2149.26,374.447 2157.17,370.601 2162.9,362.91C 2168.64,355.219 2171.51,344.485 2171.51,330.71C 2171.51,319.136 2168.84,310.078 2163.5,303.537C 2158.16,296.995 2150.91,293.725 2141.76,293.725C 2132.09,293.725 2124.3,297.094 2118.41,303.833C 2112.51,310.573 2109.56,318.987 2109.56,329.078 Z "/>');
        var videoPlay = svgBoilerPlate('0 0 320 180', '<g transform="translate(0,-872.36218)"><path d="m193.35,76.144a35.355,35.355,0,1,1,-70.711,0,35.355,35.355,0,1,1,70.711,0z" fill-opacity="0.41269842000000001" transform="matrix(1.4083841,0,0,1.4083841,-58.307492,855.21509)" stroke="#FFF" stroke-miterlimit="10" stroke-dasharray="none" stroke-width="6.85040394999999960" fill="#000"/><path fill="#FFF" d="m151.19,939.89-0.21124,46.293,36.567-22.321z"/></g>', "videoplay", "Play video icon");
        var cloudpath = "<path style='fill:none;stroke:fgcolor;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:desiredopacity;stroke-dasharray:none;marker-start:none' d='M 53.728638,839.48313 C 44.890866,821.0777 75.842011,799.132 90.002668,814.85472 m 95.479832,42.85851 c -1.38106,-5.8005 4.40628,-18.7826 16.84904,-18.7826 13.54573,0 21.94059,7.3948 22.09708,21.2685 0.12491,11.0738 -9.9144,15.1917 -18.78252,15.1917 -113.282692,0 -116.668932,-0.117 -192.520858,0 -19.4386752,0.03 -13.81264047,-42.1213 18.48727,-28.1053 M 171.91337,824.7065 c -4.93156,-14.64758 -17.61648,-26.12905 -40.14249,-26.46505 -23.58689,-0.35183 -48.384356,11.52296 -51.525738,39.03198 m 118.210358,2.1465 c -2.39812,-10.1263 -12.21999,-14.27103 -22.09021,-14.82478 -25.14358,-1.41071 -32.89057,15.94078 -28.71083,28.10798 m -117.127762,6.9436 c -2.458337,-17.837 10.678185,-24.8171 21.948736,-24.6319'/>";
        var peoplepath = "<path style='fill:fgcolor;fill-opacity:desiredopacity;fill-rule:nonzero;stroke:none' d='m 166.22645,843.32735 c 2.92046,0 5.28806,3.01049 5.28806,6.72401 0,3.71352 -2.3676,6.72401 -5.28806,6.72401 -2.92065,0 -5.28825,-3.01049 -5.28825,-6.72401 0,-3.71352 2.3676,-6.72401 5.28825,-6.72401 z m 11.17157,32.21923 -22.41337,0 c 0,-5.97691 0,-11.95381 1.49422,-14.94226 1.49423,-2.98845 4.48268,-2.98845 6.91658,-2.98845 2.4341,0 4.31346,0 6.19301,0 2.60312,0 5.20644,0 6.50791,2.98845 1.30165,2.98845 1.30165,8.96535 1.30165,14.94226 z M 87.781795,843.05114 c 2.920462,0 5.288062,3.01049 5.288062,6.72401 0,3.71352 -2.3676,6.72401 -5.288062,6.72401 -2.92065,0 -5.288249,-3.01049 -5.288249,-6.72401 0,-3.71352 2.367599,-6.72401 5.288249,-6.72401 z m 11.171572,32.21923 -22.413373,0 c 0,-5.97691 0,-11.95381 1.494225,-14.94226 1.494225,-2.98845 4.482674,-2.98845 6.91658,-2.98845 2.434092,0 4.313454,0 6.193002,0 2.603126,0 5.20644,0 6.50791,2.98845 1.301656,2.98845 1.301656,8.96535 1.301656,14.94226 z m 20.869203,-32.21924 c 2.92046,0 5.28806,3.01049 5.28806,6.72401 0,3.71352 -2.3676,6.72401 -5.28806,6.72401 -2.92065,0 -5.28825,-3.01049 -5.28825,-6.72401 0,-3.71352 2.3676,-6.72401 5.28825,-6.72401 z m 11.17157,32.21923 -22.41337,0 c 0,-5.97691 0,-11.95381 1.49422,-14.94226 1.49423,-2.98845 4.48268,-2.98845 6.91658,-2.98845 2.4341,0 4.31346,0 6.19301,0 2.60312,0 5.20644,0 6.50791,2.98845 1.30165,2.98845 1.30165,8.96535 1.30165,14.94226 z M 66.249157,842.77492 c 2.920462,0 5.288062,3.01049 5.288062,6.72401 0,3.71352 -2.3676,6.72401 -5.288062,6.72401 -2.92065,0 -5.288249,-3.01049 -5.288249,-6.72401 0,-3.71352 2.367599,-6.72401 5.288249,-6.72401 z m 11.171572,32.21923 -22.413373,0 c 0,-5.97691 0,-11.95381 1.494225,-14.94226 1.494225,-2.98845 4.482674,-2.98845 6.91658,-2.98845 2.434092,0 4.313454,0 6.193002,0 2.603126,0 5.20644,0 6.50791,2.98845 1.301656,2.98845 1.301656,8.96535 1.301656,14.94226 z'/>";
        var broadcastpath = "<path style='fill:fgcolor;fill-opacity:desiredopacity;fill-rule:nonzero;stroke:none' d='m 158.25,47.375 c -2.92046,0 -5.28125,3.00523 -5.28125,6.71875 0,3.71352 2.36079,6.75 5.28125,6.75 2.92065,0 5.28125,-3.03648 5.28125,-6.75 0,-3.71352 -2.3606,-6.71875 -5.28125,-6.71875 z m -45.5625,0.28125 c -2.92046,0 -5.3125,3.00523 -5.3125,6.71875 0,3.71352 2.39204,6.71875 5.3125,6.71875 2.92065,0 5.28125,-3.00523 5.28125,-6.71875 0,-3.71352 -2.3606,-6.71875 -5.28125,-6.71875 z m 24.03125,0 c -2.92046,0 -5.28125,3.00523 -5.28125,6.71875 0,3.71352 2.36079,6.71875 5.28125,6.71875 2.92065,0 5.28125,-3.00523 5.28125,-6.71875 0,-3.71352 -2.3606,-6.71875 -5.28125,-6.71875 z m -74.4375,0.28125 c -2.92046,0 -5.3125,3.00523 -5.3125,6.71875 0,3.71352 2.39204,6.71875 5.3125,6.71875 2.92065,0 5.28125,-3.00523 5.28125,-6.71875 0,-3.71352 -2.3606,-6.71875 -5.28125,-6.71875 z m 34.932585,-5.692657 -10.799454,9.091808 -11.274272,0 0.276214,10.50813 3.443568,-0.276213 2.762136,9.509162 3.875,0 -1.933496,-8.847876 13.650304,10.65534 z M 154.875,61.6875 c -2.60312,0 -5.19853,-0.0197 -6.5,2.96875 -0.4408,1.012029 -0.71345,2.387341 -0.90625,3.96875 -0.22102,-1.459898 -0.52452,-2.736531 -1,-3.6875 -1.49423,-2.98845 -4.5036,-3 -6.9375,-3 l -6.1875,0 c -2.60312,0 -5.19853,0.01155 -6.5,3 -1.30165,2.98845 -1.3125,8.96059 -1.3125,14.9375 l 22.4375,0 c 0,-0.0947 1e-5,-0.186562 0,-0.28125 l 21.53125,0 c 0,-5.97691 -0.006,-11.94905 -1.5,-14.9375 -1.49422,-2.98845 -4.50359,-2.96875 -6.9375,-2.96875 z m -45.5625,0.25 c -2.60312,0 -5.19853,0.01155 -6.5,3 -1.30165,2.98845 -1.3125,8.96059 -1.3125,14.9375 l 22.40625,0 c 0,-5.97691 -0.006,-11.94905 -1.5,-14.9375 -1.49423,-2.98845 -4.47235,-3 -6.90625,-3 z m -50.40625,0.28125 c -2.60312,0 -5.19853,0.01155 -6.5,3 -1.30165,2.98845 -1.3125,8.96059 -1.3125,14.9375 l 22.40625,0 c 0,-5.97691 0.02547,-11.94905 -1.46875,-14.9375 -1.49423,-2.98845 -4.5036,-3 -6.9375,-3 z' transform='translate(-0.0892384, 795.39085)'/>";
        var codekingdomsLogo = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" width="107" height="107.00001" viewBox="0 0 107 107.00001" id="svg4207" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="Microbit CK Logo.svg"><defs id="defs4209" /><sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8" inkscape:cx="11.591697" inkscape:cy="15.87942" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" units="px" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1680" inkscape:window-height="1001" inkscape:window-x="0" inkscape:window-y="23" inkscape:window-maximized="1" /><metadata id="metadata4212"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-154.28575,-805.36218)"><rect style="opacity:1;fill:#333333;fill-opacity:1;stroke:none;stroke-width:0.07577424;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect11957" width="107" height="107.00001" x="154.28575" y="805.36218" /><path id="path12604" d="m 167.13201,841.77337 c -1.09811,-1.17115 -2.4386,-1.31504 -3.58068,-0.38517 -1.17442,0.95712 -1.33105,2.37283 -0.40153,3.63846 0.88264,1.18679 2.51601,1.3543 3.70096,0.403 0.94441,-0.75837 1.39754,-2.56616 0.28125,-3.65629 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#f48023;fill-opacity:1;fill-rule:evenodd" /><path id="path12606" d="m 195.32515,827.53564 c -1.12791,-1.23947 -2.4782,-1.42079 -3.63883,-0.48983 -1.22347,0.9822 -1.37501,2.38192 -0.40117,3.70206 0.73075,1.07667 2.47422,1.33902 3.64757,0.379 1.10392,-0.903 1.28634,-2.46333 0.39243,-3.59123 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#f48023;fill-opacity:1;fill-rule:evenodd" /><path id="path12608" d="m 183.0551,829.91611 c 0.99746,1.22384 2.68969,1.43169 3.94151,0.48437 1.21948,-0.9237 1.49237,-2.59558 0.62936,-3.85903 -1.10211,-1.45642 -2.70132,-1.75474 -4.04072,-0.75437 -1.41207,1.05487 -1.61447,2.62901 -0.53015,4.12903 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#f48023;fill-opacity:1;fill-rule:evenodd" /><path id="path12610" d="m 167.42926,837.87472 c 0.94478,1.29253 2.74166,1.52873 4.01311,0.52726 1.27218,-1.00218 1.48474,-2.81214 0.4713,-4.01819 -1.18461,-1.32995 -2.68316,-1.53163 -3.96696,-0.53344 -1.32668,1.03126 -1.52654,2.58469 -0.51745,4.02437 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#f48023;fill-opacity:1;fill-rule:evenodd" /><path id="path12612" d="m 179.04562,827.68135 c -1.49566,-1.52327 -3.32561,-1.73402 -4.84378,-0.5556 -1.47712,1.14681 -2.04907,3.1628 -0.79506,4.93099 0.80704,1.19841 2.18496,1.77763 3.64028,1.46803 1.35321,-0.28779 2.3056,-1.09339 2.70931,-2.43024 0.37646,-1.24493 0.24346,-2.42481 -0.71075,-3.41318 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#f48023;fill-opacity:1;fill-rule:evenodd" /><path id="path12614" d="m 181.91736,845.16983 c -0.2013,-0.12973 -0.40987,-0.25 -0.60248,-0.39135 -2.67261,-1.96295 -5.34196,-3.93025 -8.01676,-5.88993 -0.16243,-0.11919 -0.34157,-0.41897 -0.53706,-0.2511 -0.27145,0.23402 0.0839,0.42151 0.19804,0.58649 1.83212,2.64609 3.68061,5.28128 5.52038,7.92192 0.1319,0.18933 0.32268,0.35031 0.35174,0.61483 -0.3194,0.0665 -0.5694,-0.11592 -0.83285,-0.20966 -2.91244,-1.03888 -5.81981,-2.09085 -8.73189,-3.12938 -0.17115,-0.0611 -0.38409,-0.29361 -0.55487,-0.002 -0.15153,0.25799 -0.1388,0.49782 0.14135,0.68605 0.13917,0.0934 0.25473,0.22202 0.38264,0.33322 2.37755,2.06397 4.75693,4.12539 7.13049,6.19371 0.29071,0.25328 0.57594,0.52145 0.82123,0.8176 1.1577,1.39898 2.36956,2.76127 3.42298,4.23585 0.64426,0.90154 1.42443,1.09448 2.41172,1.06179 2.50184,-0.0833 4.72641,-0.96731 6.74896,-2.36957 3.17226,-2.19987 5.54146,-5.01748 6.59923,-8.81619 0.23693,-0.85176 0.25365,-1.59776 -0.26562,-2.39536 -0.75073,-1.1519 -1.35175,-2.40082 -2.05343,-3.58688 -0.32012,-0.54033 -0.44877,-1.09885 -0.48874,-1.71622 -0.12209,-1.88482 -0.29215,-3.76564 -0.41606,-5.65011 -0.0225,-0.3423 -0.15625,-0.41242 -0.45676,-0.49201 -0.39063,-0.10356 -0.45495,0.1152 -0.54325,0.37246 -0.30632,0.89099 -0.60938,1.78309 -0.92043,2.67227 -0.43895,1.25363 -0.88409,2.50582 -1.36919,3.87829 -1.18679,-2.51238 -2.31396,-4.89102 -3.42989,-7.27477 -0.13772,-0.2936 -0.26309,-0.45348 -0.64426,-0.37645 -0.41316,0.0833 -0.32668,0.33576 -0.31505,0.59121 0.1439,3.04835 0.28998,6.09597 0.42733,9.14432 0.007,0.17151 0.13409,0.37972 -0.0999,0.5407 -0.14208,-0.16678 -0.28452,-0.32776 -0.41897,-0.49491 -1.98875,-2.47094 -3.99312,-4.92918 -5.94845,-7.42665 -0.37173,-0.47529 -0.61845,-0.37645 -1.06249,-0.1726 -0.57704,0.26526 -0.24093,0.58648 -0.13118,0.87718 1.26019,3.34487 2.53272,6.68537 3.80162,10.02731 -0.04,0.0298 -0.0793,0.06 -0.1181,0.0902 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#ffce3c;fill-opacity:1;fill-rule:evenodd" /><path id="path12616" d="m 200.39423,846.01541 c -0.84885,-0.28853 -1.70641,-0.12065 -2.56216,-0.0476 -0.28452,0.0244 -0.30159,0.23982 -0.34919,0.46511 -1.31942,6.26385 -8.51278,12.69703 -15.10476,12.36418 -0.29942,-0.0148 -0.44877,0.0829 -0.50618,0.36701 -0.27581,1.37174 -0.52726,2.74494 -0.29506,4.15228 0.0723,0.86665 0.10247,1.73912 0.22348,2.59885 0.75618,5.37612 3.38592,9.45937 8.37033,11.82385 3.47786,1.65008 7.18608,2.02399 10.97863,1.65262 1.24891,-0.12208 2.48185,-0.38264 3.63448,-0.93459 0.3928,-0.18824 0.58539,-0.4237 0.5923,-0.88046 0.0134,-0.91825 0.0556,-1.83941 0.14606,-2.75293 0.0683,-0.68604 -0.11264,-0.78452 -0.77762,-0.60683 -5.01601,1.34195 -9.4539,-1.55197 -10.10726,-6.55201 -0.55704,-4.26237 1.96804,-7.86051 6.12759,-8.63959 1.70132,-0.31868 3.42625,-0.23438 5.12212,0.10756 0.54616,0.1101 0.62428,-0.0284 0.6232,-0.54106 -0.006,-2.5429 -0.16098,-5.07926 -0.33613,-7.61343 -0.0814,-1.17878 -0.25508,-2.35139 -0.53052,-3.5091 -0.12973,-0.54688 -0.4168,-0.79652 -0.94187,-0.93278 -1.41499,-0.36775 -2.85503,-0.48438 -4.30744,-0.52108 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#33c5f3;fill-opacity:1;fill-rule:evenodd" /><path id="path12618" d="m 217.44994,846.74471 c -1.87102,0.0938 -3.90847,0.0167 -5.93282,0.27688 -0.37427,0.0484 -0.55815,0.14645 -0.54361,0.57123 0.0469,1.37937 0.0163,2.76237 0.0891,4.14029 0.35901,6.7951 0.7322,13.58947 1.12246,20.38275 0.12537,2.17371 0.21658,4.35251 0.55633,6.5095 0.0755,0.48001 0.27181,0.67842 0.79761,0.70131 3.17298,0.13771 6.34379,0.0683 9.51606,-0.0109 0.72165,-0.0181 0.94113,-0.23475 0.8899,-0.97531 -0.1886,-2.7322 -0.15371,-5.46987 -0.13228,-8.20716 0.006,-0.58686 0.36338,-0.5756 0.72531,-0.66608 0.37681,-0.0941 0.66897,-0.11919 0.85392,0.36229 0.35466,0.92333 0.80088,1.81069 1.18242,2.72459 1.00582,2.40916 1.87974,4.86593 2.63447,7.36559 0.0738,0.24492 0.0622,0.56832 0.51418,0.55306 3.12065,-0.10574 6.24422,-0.15335 9.31001,-0.8612 0.58249,-0.13445 0.74347,-0.31323 0.53743,-0.97057 -1.6301,-5.20861 -3.88084,-10.14868 -6.39212,-14.97721 -0.2649,-0.50945 -0.23582,-0.84048 0.11846,-1.28307 3.38447,-4.22569 5.66719,-9.02912 7.35979,-14.13927 0.129,-0.3899 0.16278,-0.55922 -0.35575,-0.65626 -3.0102,-0.56286 -6.05599,-0.68313 -9.1018,-0.84047 -0.5189,-0.0269 -0.74129,0.12354 -0.899,0.63517 -1.38191,4.48514 -3.22312,8.7962 -5.03782,13.11673 -0.0719,0.17115 -0.0876,0.39099 -0.30996,0.45276 -0.58139,0.16098 -1.19222,-0.26272 -1.23437,-0.87319 -0.2947,-4.2533 -0.48911,-8.50986 -0.4019,-12.77442 0.01,-0.45495 -0.0985,-0.57304 -0.54724,-0.56651 -1.71912,0.0244 -3.43898,0.01 -5.31871,0.01 z" inkscape:connector-curvature="0" style="clip-rule:evenodd;fill:#ffce3c;fill-opacity:1;fill-rule:evenodd" /></g></svg>';
        var pythonLogo = '<svg viewBox="0 0 90 90" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="78" height="77.593796" id="svg2169" sodipodi:version="0.32" inkscape:version="0.48.5 r10040" version="1.0" sodipodi:docname="python-logo1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs2171"> <linearGradient id="linearGradient11301" inkscape:collect="always"> <stop id="stop11303" offset="0" style="stop-color:#ffe052;stop-opacity:1" /> <stop id="stop11305" offset="1" style="stop-color:#ffc331;stop-opacity:1" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" y2="168.1012" x2="147.77737" y1="111.92053" x1="89.136749" id="linearGradient11307" xlink:href="#linearGradient11301" inkscape:collect="always" /> <linearGradient id="linearGradient9515" inkscape:collect="always"> <stop id="stop9517" offset="0" style="stop-color:#387eb8;stop-opacity:1" /> <stop id="stop9519" offset="1" style="stop-color:#366994;stop-opacity:1" /> </linearGradient> <linearGradient gradientUnits="userSpaceOnUse" y2="131.85291" x2="110.14919" y1="77.070274" x1="55.549179" id="linearGradient9521" xlink:href="#linearGradient9515" inkscape:collect="always" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="9.3947058" inkscape:cy="72.439766" inkscape:document-units="px" inkscape:current-layer="layer1" width="131.10236px" height="184.25197px" inkscape:window-width="872" inkscape:window-height="624" inkscape:window-x="82" inkscape:window-y="82" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showborder="true" inkscape:showpageshadow="false" inkscape:window-maximized="0" /> <metadata id="metadata2174"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Calque 1" inkscape:groupmode="layer" id="layer1" transform="translate(-489.57146,-267.85101)"> <g id="g1894" transform="matrix(0.70638641,0,0,0.70638641,457.82822,220.192)"> <path style="color:#000000;fill:url(#linearGradient9521);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" d="M 99.75,67.46875 C 71.718268,67.468752 73.46875,79.625 73.46875,79.625 L 73.5,92.21875 l 26.75,0 0,3.78125 -37.375,0 c 0,0 -17.9375,-2.034276 -17.9375,26.25 -2e-6,28.28427 15.65625,27.28125 15.65625,27.28125 l 9.34375,0 0,-13.125 c 0,0 -0.503652,-15.65625 15.40625,-15.65625 15.9099,0 26.53125,0 26.53125,0 0,0 14.90625,0.24096 14.90625,-14.40625 0,-14.647206 0,-24.21875 0,-24.21875 0,-2e-6 2.26318,-14.65625 -27.03125,-14.65625 z M 85,75.9375 c 2.661429,-2e-6 4.8125,2.151071 4.8125,4.8125 2e-6,2.661429 -2.151071,4.8125 -4.8125,4.8125 -2.661429,2e-6 -4.8125,-2.151071 -4.8125,-4.8125 -2e-6,-2.661429 2.151071,-4.8125 4.8125,-4.8125 z" id="path8615" inkscape:connector-curvature="0" /> <path id="path8620" d="m 100.5461,177.31485 c 28.03174,0 26.28125,-12.15625 26.28125,-12.15625 l -0.0312,-12.59375 -26.75,0 0,-3.78125 37.375,0 c 0,0 17.9375,2.03427 17.9375,-26.25001 10e-6,-28.284267 -15.65625,-27.281247 -15.65625,-27.281247 l -9.34375,0 0,13.124997 c 0,0 0.50366,15.65625 -15.40625,15.65625 -15.909902,0 -26.531252,0 -26.531252,0 0,0 -14.90625,-0.24096 -14.90625,14.40626 0,14.6472 0,24.21875 0,24.21875 0,0 -2.26318,14.65625 27.031252,14.65625 z m 14.75,-8.46875 c -2.66143,0 -4.8125,-2.15107 -4.8125,-4.8125 0,-2.66143 2.15107,-4.8125 4.8125,-4.8125 2.66143,0 4.8125,2.15107 4.8125,4.8125 1e-5,2.66143 -2.15107,4.8125 -4.8125,4.8125 z" style="color:#000000;fill:url(#linearGradient11307);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" inkscape:connector-curvature="0" /> </g> </g> </svg>';
        function getIconSVG(name, alt) {
            var title = alt || name.split(',')[0];
            var d = TDev.div(null);
            d.innerHTML = getIconSVGCore(name);
            var svg = d.firstChild;
            TDev.HTML.setRole(svg, "img");
            svg.setAttribute("aria-label", title);
            var tt = document.createElementNS("http://www.w3.org/2000/svg", 'title');
            tt.textContent = title;
            svg.insertBefore(tt, svg.firstElementChild);
            return svg;
        }
        SVG.getIconSVG = getIconSVG;
        function getIconNames() {
            return Object.keys(icons).concat(Object.keys(gelIcons).map(function (i) { return "gel-" + i; })).concat(Object.keys(fontAwesomeIconsByDaveGandy).map(function (i) { return "fa-" + i; }));
        }
        SVG.getIconNames = getIconNames;
        function getAllIcons() {
            var r = "";
            getIconNames().forEach(function (i) {
                var s = getIconSVGCore(i + ",currentColor");
                s = s.replace(/^<svg /, "<svg style='width:100%;height:100%' ");
                s = "<div style='margin:1em;display:inline-block;width:3em;height:3em;'>" + s + "<div style='font-size:0.6em;text-align:center'>" + i + "</div></div>";
                r += s;
            });
            return r;
        }
        SVG.getAllIcons = getAllIcons;
        function getIconSVGUrl(name) {
            return "data:image/svg+xml," + escape(getIconSVGCore(name));
        }
        SVG.getIconSVGUrl = getIconSVGUrl;
        function getVideoPlay(bg, alt) {
            if (alt === void 0) { alt = ""; }
            return TDev.Util.fmt("<img src='{0:url}' alt='{1:q}' />", bg, alt || "") + videoPlay;
        }
        SVG.getVideoPlay = getVideoPlay;
        function getIconSVGCore(name) {
            var toks = name.split(/,/);
            var h = 480;
            name = toks[0];
            var fill = toks[1];
            var viewDiff = 0;
            var opacity = 1;
            toks.forEach(function (s) {
                if (/clip=/.test(s)) {
                    viewDiff = s.slice(5) * 1;
                }
                if (/opacity=/.test(s)) {
                    opacity = s.slice(8) * 1;
                }
                if (/h=/.test(s)) {
                    h = s.slice(2) * 1;
                }
            });
            var lname = name.toLowerCase();
            if (lname == "codekingdoms")
                return codekingdomsLogo;
            if (lname == "python")
                return pythonLogo;
            if (iconMapping.hasOwnProperty(lname))
                lname = iconMapping[lname];
            var ic = icons[lname];
            var fa = false;
            var gel = false;
            if (!ic) {
                ic = fontAwesomeIconsByDaveGandy[lname.replace(/^fa-/, "")];
                if (ic)
                    fa = true;
            }
            if (!ic && /^gel-/.test(lname)) {
                ic = gelIcons[lname.replace(/^gel-/, "")];
                if (ic) {
                    gel = true;
                }
            }
            if (!ic) {
                TDev.Util.log("SCRIPTICON: " + name);
                ic = icons["cancel"];
            }
            var viewPort = viewDiff + " " + viewDiff + " " + (480 - 2 * viewDiff) + " " + (h - 2 * viewDiff);
            var style = "";
            if (opacity != 1)
                style = " style='fill-opacity:" + opacity + "' ";
            if (fa)
                style += " transform='scale(0.13,-0.13) translate(1000,-2500)' ";
            if (gel)
                style += " transform='scale(7.5,7.5)' ";
            var svg = svgBoilerPlate(viewPort, "<path fill='" + fill + "' " + style + " d='" + ic + "' />", name);
            return svg;
        }
        SVG.getIconSVGCore = getIconSVGCore;
        function drawSVG(ctx, name) {
            var path = icons[name.toLowerCase()] || (scriptIcons ? scriptIcons[name.toLowerCase()] : null);
            if (path == null)
                return;
            path = path.replace(/,/g, " ");
            path = path.replace(/([0-9])([A-Z])/g, (function (str, n, l) { return n + " " + l; }));
            var words = path.split(/ +/);
            var implicitCmd = "";
            var w = function (n) { return parseFloat(words[n]); };
            for (var i = 0; i < words.length;) {
                var cmd = words[i];
                if (/^[A-Za-z]$/.test(cmd))
                    i++;
                else
                    cmd = implicitCmd;
                switch (cmd) {
                    case "M":
                        ctx.moveTo(w(i + 0), w(i + 1));
                        i += 2;
                        implicitCmd = "L";
                        break;
                    case "C":
                        ctx.bezierCurveTo(w(i + 0), w(i + 1), w(i + 2), w(i + 3), w(i + 4), w(i + 5));
                        i += 6;
                        implicitCmd = "C";
                        break;
                    case "L":
                        ctx.lineTo(w(i + 0), w(i + 1));
                        i += 2;
                        implicitCmd = "L";
                        break;
                    case "Z":
                        ctx.closePath();
                        break;
                    default:
                        i++;
                        break;
                }
            }
            ctx.fill();
        }
        SVG.drawSVG = drawSVG;
        function svgToElement(svg) {
            var d = TDev.div(null);
            d.innerHTML = svg;
            return d.firstChild;
        }
        SVG.svgToElement = svgToElement;
        function codeSignHtml(name) {
            return codeSigns[name];
        }
        SVG.codeSignHtml = codeSignHtml;
        function getHorizLogo() {
            return svgToElement(tdLogoHoriz);
        }
        SVG.getHorizLogo = getHorizLogo;
        function getTopLogo() {
            return svgToElement(tdLogo);
        }
        SVG.getTopLogo = getTopLogo;
        function getLoginButton() {
            return svgToElement(loginButton);
        }
        SVG.getLoginButton = getLoginButton;
        function getHorizontalCursorMarker() {
            return svgToElement(horizontalMarker);
        }
        SVG.getHorizontalCursorMarker = getHorizontalCursorMarker;
        function getVerticalCursorMarker() {
            return svgToElement(verticalMarker);
        }
        SVG.getVerticalCursorMarker = getVerticalCursorMarker;
        function getCloudSymbol(color, type, connected, height_in_em) {
            var opacity = connected ? "1" : "0.3";
            var extrapath = (type == "public" ? peoplepath : (type == "broadcast" ? broadcastpath : ""));
            var svg = svgToElement(svgBoilerPlate('0 795 227 82', cloudpath.replace(/fgcolor/, color).replace(/desiredopacity/, opacity) + (extrapath ? extrapath.replace(/fgcolor/, color).replace(/desiredopacity/, opacity) : "")));
            if (height_in_em) {
                svg.style.height = height_in_em.toString() + "em";
                svg.style.width = (height_in_em * 2.77).toString() + "em";
            }
            return svg;
        }
        SVG.getCloudSymbol = getCloudSymbol;
        function justName(s) {
            return s ? s.replace(/^svg:/, "").replace(/,.*/, "") : null;
        }
        SVG.justName = justName;
    })(SVG = TDev.SVG || (TDev.SVG = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var CallNode = (function () {
        function CallNode(id, action) {
            this.id = id;
            this.action = action;
        }
        return CallNode;
    })();
    TDev.CallNode = CallNode;
    var PackedStackTrace = (function () {
        function PackedStackTrace() {
            this.pack = [];
            this.path = [];
        }
        PackedStackTrace.buildFrom = function (st) {
            var ret = new PackedStackTrace();
            var pack = [];
            var actions = [];
            st.forEach(function (sf) {
                var ix = pack.indexOf(sf.pc);
                if (ix === -1) {
                    ix = pack.push(sf.pc) - 1;
                    actions.push(sf.name);
                }
                ret.path.push(ix);
            });
            pack.forEach(function (x, i) { return ret.pack.push(new CallNode(x, actions[i])); });
            return ret;
        };
        PackedStackTrace.toFakeStackTrace = function (st) {
            if (!st)
                return [];
            var fakePack = st.pack.map(function (cnode) {
                return { pc: cnode.id, name: cnode.action };
            });
            return st.path.map(function (ix) { return fakePack[ix]; });
        };
        return PackedStackTrace;
    })();
    TDev.PackedStackTrace = PackedStackTrace;
    var RunBitMap = (function () {
        function RunBitMap() {
            this.empty = true;
            this.data = {};
        }
        RunBitMap.prototype.push = function (id) {
            this.data[id] = true;
            this.empty = false;
        };
        RunBitMap.prototype.contains = function (id) {
            return !!this.data[id];
        };
        RunBitMap.prototype.toJSON = function () {
            return Object.keys(this.data);
        };
        RunBitMap.prototype.isEmpty = function () {
            return this.empty;
        };
        RunBitMap.prototype.clear = function () {
            this.empty = true;
            this.data = {};
        };
        RunBitMap.fromJSON = function (json) {
            if (json == null)
                return null;
            if (json instanceof Array) {
                var ret = new RunBitMap();
                json.forEach(function (e) {
                    if (e != undefined) {
                        ret.push(e);
                    }
                });
                return ret;
            }
            return undefined;
        };
        return RunBitMap;
    })();
    TDev.RunBitMap = RunBitMap;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    TDev.debuggerExceptions = false;
    TDev.forceLocalStorage = false;
    TDev.withTracing = false;
    TDev.asyncEnabled = true;
    TDev.isWebWorker = false;
    TDev.noHub = false;
    TDev.hubHash = "hub";
    function enumToString(enumType, theEnum) {
        var ret = enumType[theEnum];
        if (!ret)
            throw new Error("Cannot convert enum to string: " + theEnum);
        return ret;
    }
    TDev.enumToString = enumToString;
    function nullify(v) {
        return (v == null) ? null : v;
    }
    TDev.nullify = nullify;
    function coalesce(v) {
        return function (f) {
            if (f && (v != null))
                return coalesce(f(v));
            else if (!f)
                return v;
            else
                return coalesce(null);
        };
    }
    TDev.coalesce = coalesce;
    function tweetify(text) {
        if (!text)
            return text;
        if (text.length > 140)
            return text.substr(0, 140) + '...';
        return text;
    }
    TDev.tweetify = tweetify;
    function elt(name) {
        return document.getElementById(name);
    }
    TDev.elt = elt;
    function span(cl, kw) {
        return createElement("span", cl, kw);
    }
    TDev.span = span;
    function show(v) {
        if (v instanceof TDev.Promise)
            v.done(show);
        else
            console.log(v);
    }
    TDev.show = show;
    function createElement(tag, cl, kw) {
        if (cl === void 0) { cl = null; }
        if (kw === void 0) { kw = null; }
        var elt = document.createElement(tag);
        if (cl)
            elt.className = cl;
        if (typeof kw === "string")
            elt.appendChild(document.createTextNode(kw));
        else
            elt.appendChildren(kw);
        return elt;
    }
    TDev.createElement = createElement;
    function text(s) {
        return document.createTextNode(s);
    }
    TDev.text = text;
    function lzmaDecompressAsync(buf) {
        var lzma = window.LZMA;
        if (!lzma)
            return TDev.Promise.as(undefined);
        return new TDev.Promise(function (onSuccess, onError, onProgress) {
            try {
                lzma.decompress(buf, function (res, error) {
                    onSuccess(error ? undefined : res);
                });
            }
            catch (e) {
                onSuccess(undefined);
            }
        });
    }
    TDev.lzmaDecompressAsync = lzmaDecompressAsync;
    function lzmaCompressAsync(text) {
        var lzma = window.LZMA;
        if (!lzma)
            return TDev.Promise.as(undefined);
        return new TDev.Promise(function (onSuccess, onError, onProgress) {
            try {
                lzma.compress(text, 7, function (res, error) {
                    onSuccess(error ? undefined : new Uint8Array(res));
                });
            }
            catch (e) {
                onSuccess(undefined);
            }
        });
    }
    TDev.lzmaCompressAsync = lzmaCompressAsync;
    function img(cl, src, alt) {
        var elt = document.createElement("img");
        if (cl)
            elt.className = cl;
        elt.src = src;
        elt.alt = alt;
        return elt;
    }
    TDev.img = img;
    function spanDirAuto(txt) {
        return dirAuto(span('', txt));
    }
    TDev.spanDirAuto = spanDirAuto;
    function dirAuto(el) {
        if (el) {
            if (TDev.Browser.directionAuto)
                el.setAttribute('dir', 'auto');
            else {
                var t = el.innerText;
                var dir = /^[\s\.;:(+0-9]*[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/i.test(t) ? "rtl" : "ltr";
                el.setAttribute('dir', dir);
            }
        }
        return el;
    }
    TDev.dirAuto = dirAuto;
    function div(cl) {
        var children = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            children[_i - 1] = arguments[_i];
        }
        var tag = "div";
        if (cl == "wall-dialog-header" || cl == "modalSearchHeader")
            tag = "h1";
        var elt = document.createElement(tag);
        if (cl)
            elt.className = cl;
        elt.tabIndex = -1;
        elt.appendChildren(children.filter(function (e) { return e != undefined; }));
        if (cl == "sdLoadingMore")
            elt.setAttribute("aria-live", "polite");
        return elt;
    }
    TDev.div = div;
    function divId(id, cls) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        var d = div(cls, args);
        d.id = id;
        return d;
    }
    TDev.divId = divId;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Debug;
    (function (Debug) {
        function whenSet(f) {
            f();
        }
        Debug.whenSet = whenSet;
    })(Debug = TDev.Debug || (TDev.Debug = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var HttpLog;
    (function (HttpLog) {
        HttpLog.enabled = false;
        var theLog = [];
        var startTime = 0;
        function log(req) {
            req.timestamp = Date.now();
            if (/^[\{\[]/.test(req.contentText)) {
                req.contentJson = JSON.parse(req.contentText);
                delete req.contentText;
            }
            req.method = req.method.toUpperCase();
            if (Util.startsWith(req.url, TDev.Cloud.getServiceUrl())) {
                req.url = req.url.slice(TDev.Cloud.getServiceUrl().length).replace(/.access_token=.*/, "");
            }
            if (!startTime)
                startTime = req.timestamp;
            req.relativeTime = req.timestamp - startTime;
            theLog.push(Util.jsonClone(req));
        }
        HttpLog.log = log;
        function show() {
            theLog.forEach(function (e) { return console.log(e); });
            return theLog;
        }
        HttpLog.show = show;
    })(HttpLog = TDev.HttpLog || (TDev.HttpLog = {}));
    var Util;
    (function (Util) {
        Util.eventLogging = false;
        Util.mouseLogging = false;
        function splitKeyValues(text, sep, valSep) {
            if (sep === void 0) { sep = ','; }
            if (valSep === void 0) { valSep = '='; }
            var result = {};
            if (text)
                text.split(sep).forEach(function (x) {
                    var arr = x.split(valSep);
                    if (arr[1])
                        result[arr[0]] = arr[1];
                });
            return result;
        }
        Util.splitKeyValues = splitKeyValues;
        function hasCJKChars(s) {
            var b = /[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf\u3400-\u4dbf\u3130-\u318F\uAC00-\uD7AF]/.test(s);
            return b;
        }
        Util.hasCJKChars = hasCJKChars;
        function wordLength(s) {
            var max = 0;
            s.split(/(\s+|-)/).forEach(function (w) { return max = Math.max(w.length, max); });
            return max;
        }
        Util.wordLength = wordLength;
        function isoTime(time) {
            var d = new Date(time * 1000);
            return Util.fmt("{0}-{1:f02.0}-{2:f02.0} {3:f02.0}:{4:f02.0}:{5:f02.0}", d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
        }
        Util.isoTime = isoTime;
        function timeSince(time) {
            var now = Util.now();
            time *= 1000;
            var diff = (now - time) / 1000;
            if (isNaN(diff))
                return "";
            if (diff < -30) {
                diff = -diff;
                if (diff < 60)
                    return lf("in a few seconds");
                if (diff < 2 * 60)
                    return lf("in a minute");
                if (diff < 60 * 60)
                    return lf("in {0} minute{0:s}", Math.floor(diff / 60));
                if (diff < 2 * 60 * 60)
                    return lf("in an hour");
                if (diff < 60 * 60 * 24)
                    return lf("in {0} hour{0:s}", Math.floor(diff / 60 / 60));
                if (diff < 60 * 60 * 24 * 30)
                    return lf("in {0} day{0:s}", Math.floor(diff / 60 / 60 / 24));
                if (diff < 60 * 60 * 24 * 365)
                    return lf("in {0} month{0:s}", Math.floor(diff / 60 / 60 / 24 / 30));
                return lf("in {0} year{0:s}", Math.floor(diff / 60 / 60 / 24 / 365));
            }
            else {
                if (diff < 0)
                    return lf("now");
                if (diff < 10)
                    return lf("a few seconds ago");
                if (diff < 60)
                    return lf("{0} second{0:s} ago", Math.floor(diff));
                if (diff < 2 * 60)
                    return lf("a minute ago");
                if (diff < 60 * 60)
                    return lf("{0} minute{0:s} ago", Math.floor(diff / 60));
                if (diff < 2 * 60 * 60)
                    return lf("an hour ago");
                if (diff < 60 * 60 * 24)
                    return lf("{0} hour{0:s} ago", Math.floor(diff / 60 / 60));
                if (diff < 60 * 60 * 24 * 30)
                    return lf("{0} day{0:s} ago", Math.floor(diff / 60 / 60 / 24));
                if (diff < 60 * 60 * 24 * 365)
                    return lf("{0} month{0:s} ago", Math.floor(diff / 60 / 60 / 24 / 30));
                return lf("{0} year{0:s} ago", Math.floor(diff / 60 / 60 / 24 / 365));
            }
        }
        Util.timeSince = timeSince;
        function toAbsoluteUrl(url) {
            if (/^http(s)?:/i.test(url))
                return url;
            var a = document.createElement('a');
            a.href = url;
            return a.href;
        }
        Util.toAbsoluteUrl = toAbsoluteUrl;
        function trimAfter(s, searchString) {
            if (!s)
                return s;
            var index = s.indexOf(searchString, 0);
            if (index > -1)
                return s.substr(0, index + searchString.length);
            else
                return s;
        }
        Util.trimAfter = trimAfter;
        function translatedFirstSentence(desc) {
            desc = desc.replace(/{hints:[^}]+}/g, "");
            desc = desc.replace(/\n/g, " ");
            desc = desc.replace(/^\s+/, "");
            desc = desc.replace(/\s+$/, "");
            var d2 = lf_static(desc, !!Util.translationToken);
            var trimmed = firstSentence(d2);
            if (d2 == desc)
                return lf_static(trimmed, false);
            else
                return trimmed;
        }
        Util.translatedFirstSentence = translatedFirstSentence;
        function firstSentence(s) {
            return Util.trimAfter(s, ".");
        }
        Util.firstSentence = firstSentence;
        function httpGetJsonAsync(filename, contentTypeOrHeaders) {
            return httpGetTextAsync(filename, contentTypeOrHeaders).then(function (s) { return JSON.parse(s); });
        }
        Util.httpGetJsonAsync = httpGetJsonAsync;
        function forEachResponseHeader(client, action) {
            var headers = client.getAllResponseHeaders();
            if (headers) {
                headers = headers.replace(/^\s*/, '');
                headers.split('\r\n').forEach(function (line) {
                    var i = line.indexOf(': ');
                    if (i > 0)
                        action(line.substr(0, i), line.substr(i + 2));
                });
            }
        }
        Util.forEachResponseHeader = forEachResponseHeader;
        function decodeErrorMessage(errorMessage) {
            if (errorMessage)
                errorMessage = decodeURIComponent(errorMessage.replace(/[+]/g, " "));
            return errorMessage;
        }
        Util.decodeErrorMessage = decodeErrorMessage;
        function networkError(client, meth, filename) {
            var e = new Error(Util.fmt("cannot {0} '{1}'; status={2}", meth, filename, client.status));
            e.status = client.status;
            try {
                e.errorMessage = decodeErrorMessage(client.getResponseHeader("ErrorMessage"));
            }
            catch (e) {
            }
            if (e.errorMessage == undefined) {
                e.errorMessage = client.responseText;
            }
            if (client.status == 404 || client.status == 403 || client.status == 409 || client.status == 400) {
            }
            else {
                e.isNetworkError = 1;
            }
            return e;
        }
        function httpGetTextAsync(filename, contentTypeOrHeaders) {
            return Util.httpRequestAsync(toAbsoluteUrl(filename), "get", undefined, contentTypeOrHeaders);
        }
        Util.httpGetTextAsync = httpGetTextAsync;
        function httpPostRealJsonAsync(url, body) {
            return Util.httpRequestAsync(url, "POST", JSON.stringify(body), "application/json;charset=UTF-8").then(function (s) { return s ? JSON.parse(s) : {}; });
        }
        Util.httpPostRealJsonAsync = httpPostRealJsonAsync;
        function parseJsonWithHack(s) {
            if (!s)
                return {};
            try {
                return JSON.parse(s);
            }
            catch (e) {
                return JSON.parse(s.replace(/":NaN,"/g, '":0,"'));
            }
        }
        Util.parseJsonWithHack = parseJsonWithHack;
        function httpPostJsonAsync(url, body) {
            return Util.httpRequestAsync(url, "POST", JSON.stringify(body), TDev.Cloud.lite ? "application/json;charset=UTF-8" : "text/plain;charset=UTF-8").then(function (s) { return s ? parseJsonWithHack(s) : {}; });
        }
        Util.httpPostJsonAsync = httpPostJsonAsync;
        function httpPostTextAsync(url, body) {
            return Util.httpRequestAsync(url, "POST", body);
        }
        Util.httpPostTextAsync = httpPostTextAsync;
        function httpDeleteAsync(url) {
            return Util.httpRequestAsync(url, "DELETE");
        }
        Util.httpDeleteAsync = httpDeleteAsync;
        function authenticationOverride(client, url, headers) {
            if (!TDev.Cloud.lite)
                return url;
            var pref = TDev.Cloud.getServiceUrl() + "/api";
            if (!(url.slice(0, pref.length) == pref && /^[\/\?]/.test(url.slice(pref.length))))
                return url;
            client.withCredentials = true;
            var m = /([^\?]+)\?(.*)/.exec(url);
            var qs = "";
            if (m) {
                m[2].split(/&/).forEach(function (kv) {
                    var k = kv;
                    var v = "true";
                    var mm = /([^=]+)=(.*)/.exec(kv);
                    if (mm) {
                        k = mm[1];
                        v = decodeURIComponent(mm[2]);
                    }
                    k = decodeURIComponent(k);
                    switch (k) {
                        case "user_platform":
                            if (TDev.Cloud.isRestricted())
                                break;
                        case "world_id":
                        case "release_id":
                        case "access_token":
                            if (v)
                                headers["x-td-" + k.replace(/_/g, "-")] = v;
                            break;
                        case "anon_token":
                            if (v)
                                headers["authorization"] = v;
                            break;
                        default:
                            if (qs)
                                qs += "&";
                            else
                                qs += "?";
                            qs += kv;
                            break;
                    }
                });
                url = m[1] + qs;
            }
            return url;
        }
        Util.httpRequestAsync = function (url, method, body, contentTypeOrHeaders) {
            if (method === void 0) { method = "GET"; }
            if (body === void 0) { body = undefined; }
            if (contentTypeOrHeaders === void 0) { contentTypeOrHeaders = null; }
            if (TDev.Cloud.isOffline())
                return TDev.Cloud.offlineErrorAsync();
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var client;
                var resolved = false;
                function innerSuccess() {
                    onSuccess(client.responseText);
                }
                function innerError() {
                    onError(networkError(client, method, url));
                }
                function ready() {
                    if (resolved)
                        return;
                    if (client.readyState == 4) {
                        resolved = true;
                        if (client.status == 200)
                            innerSuccess();
                        else
                            innerError();
                    }
                }
                var headers = contentTypeOrHeaders || {};
                if (typeof headers == "string")
                    headers = { "Content-Type": headers };
                if (HttpLog.enabled)
                    HttpLog.log({
                        url: url,
                        method: method,
                        contentText: body,
                        headers: Object.keys(headers).map(function (k) {
                            return { name: k, value: headers[k] };
                        })
                    });
                client = new XMLHttpRequest();
                if (TDev.Cloud.lite)
                    url = authenticationOverride(client, url, headers);
                client.onreadystatechange = ready;
                client.open(method, url);
                Object.keys(headers).forEach(function (k) {
                    client.setRequestHeader(k, headers[k]);
                });
                if (body === undefined)
                    client.send();
                else
                    client.send(body);
            });
        };
        function betaCheck(cond, msg) {
            if (msg === void 0) { msg = ""; }
            if (TDev.isBeta)
                check(cond, msg);
        }
        Util.betaCheck = betaCheck;
        function check(cond, msg) {
            if (msg === void 0) { msg = ""; }
            try {
                if (!cond)
                    throw Error("check failed: " + msg);
            }
            catch (e) {
                try {
                    reportError("check", e, false);
                }
                catch (e) {
                }
            }
            return cond;
        }
        Util.check = check;
        function assert(cond, msg) {
            if (msg === void 0) { msg = ""; }
            if (!cond)
                throw Error("assertion failed: " + msg);
        }
        Util.assert = assert;
        function assertCode(cond) {
            if (!cond) {
                var e = Error("assertion failed");
                e.includeSource = true;
                throw e;
            }
        }
        Util.assertCode = assertCode;
        function die() {
            throw Error("OOPS");
        }
        Util.die = die;
        function oops(msg, attachments) {
            if (attachments === void 0) { attachments = null; }
            var err = new Error("OOPS: " + msg);
            if (attachments)
                err.bugAttachments = attachments;
            throw err;
        }
        Util.oops = oops;
        function abstract() {
            oops("this method should have been overriden");
            return undefined;
        }
        Util.abstract = abstract;
        function initHtmlExtensions() {
            if (window.performance && window.performance.now)
                Util.perfNow = function () { return window.performance.now(); };
            else
                Util.perfNow = function () { return Date.now(); };
            TDev.Promise.errorHandler = Util.reportError;
            TDev.Promise.checkHandler = function (msg) { return Util.check(false, msg); };
            var pelt = Element.prototype;
            pelt.removeAllChildren = function () {
                while (this.hasChildNodes()) {
                    this.removeChild(this.firstChild);
                }
            };
            pelt.removeSelf = function () {
                if (!!this.parentNode)
                    this.parentNode.removeChild(this);
            };
            pelt.setFlag = function (name, v) {
                this.setAttribute("data-" + name, v ? "yes" : "no");
            };
            pelt.getFlag = function (name) {
                var s = this.getAttribute("data-" + name);
                if (!s || s == "no")
                    return false;
                else
                    return true;
            };
            pelt.appendChildren = function (children) {
                var th = this;
                if (!children)
                    return;
                if (Array.isArray(children))
                    for (var i = 0; i < children.length; ++i)
                        th.appendChildren(children[i]);
                else if (typeof children === "string")
                    th.appendChild(TDev.text(children));
                else
                    th.appendChild(children);
            };
            pelt.setChildren = function (children) {
                this.removeAllChildren();
                this.appendChildren(children);
            };
            pelt.setChildrenIfNeeded = function (children) {
                if (Array.isArray(children) && children.length == this.childNodes.length) {
                    var ok = true;
                    for (var i = 0; i < children.length; ++i) {
                        if (this.childNodes[i] !== children[i]) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok)
                        return;
                }
                this.removeAllChildren();
                this.appendChildren(children);
            };
            pelt.setPosition = function (x, y, w, h) {
                var accentBox = this;
                accentBox.style.left = x + "px";
                accentBox.style.top = y + "px";
                if (w)
                    accentBox.style.width = w + "px";
                if (h)
                    accentBox.style.height = h + "px";
            };
            pelt.offsetPosition = function () {
                return {
                    top: this.offsetTop,
                    bot: this.offsetTop + this.offsetHeight,
                    left: this.offsetLeft,
                    right: this.offsetLeft + this.offsetWidth,
                    width: this.offsetWidth,
                    height: this.offsetHeight
                };
            };
            setupTimeoutZero();
            Error.stackTraceLimit = 64;
            TDev.Browser.setInnerHTML = function (el, html) {
                el.innerHTML = TDev.HTML.sanitizeHTML(html);
            };
        }
        Util.initHtmlExtensions = initHtmlExtensions;
        var zeroTimeoutFunctions;
        var zeroTimeoutName = "tdev-zero-timeout-message";
        function setZeroTimeout(cb) {
            zeroTimeoutFunctions.push(function () {
                if (Util.eventLogging)
                    Util.log("executing zero timeout " + cb.toString());
                try {
                    cb();
                }
                catch (err) {
                    Util.reportError("zero-timeout-" + cb.toString(), err);
                }
            });
            window.postMessage(zeroTimeoutName, "*");
        }
        function setupTimeoutZero() {
            zeroTimeoutFunctions = [];
            window.addEventListener("message", function (ev) {
                if (ev.source == window && ev.data == zeroTimeoutName) {
                    ev.stopPropagation();
                    while (zeroTimeoutFunctions.length > 0) {
                        var f = zeroTimeoutFunctions.shift();
                        f();
                    }
                }
            }, true);
        }
        function initGenericExtensions() {
            var arr = Array.prototype;
            arr.peek = function () {
                return this.length === 0 ? undefined : this[this.length - 1];
            };
            arr.collect = function (fn) {
                var res = [];
                for (var i = 0; i < this.length; ++i) {
                    var tmp = fn(this[i]);
                    for (var j = 0; j < tmp.length; ++j) {
                        res.push(tmp[j]);
                    }
                }
                return res;
            };
            arr.pushRange = function (other) {
                for (var i = 0; i < other.length; ++i)
                    this.push(other[i]);
            };
            arr.max = function () {
                return Math.max.apply(null, this);
            };
            arr.min = function () {
                return Math.min.apply(null, this);
            };
            arr.spliceArr = function (f, t, a) {
                return Array.prototype.splice.apply(this, [f, t].concat(a));
            };
            arr.stableSortObjs = function (cmp) {
                for (var i = 0; i < this.length; ++i)
                    this[i].__stableSortIdx = i;
                this.sort(function (a, b) {
                    var r = cmp(a, b);
                    if (r == 0)
                        return a.__stableSortIdx - b.__stableSortIdx;
                    else
                        return r;
                });
                for (var i = 0; i < this.length; ++i)
                    delete this[i].__stableSortIdx;
            };
            arr.stableSorted = function (cmp) {
                var idx = new Array(this.length);
                for (var i = 0; i < idx.length; ++i)
                    idx[i] = i;
                var t = this;
                idx.sort(function (a, b) {
                    var r = cmp(t[a], t[b]);
                    if (r == 0)
                        return a - b;
                    else
                        return r;
                });
                for (var i = 0; i < idx.length; ++i)
                    idx[i] = t[idx[i]];
                return idx;
            };
            arr.stableSort = function (cmp) {
                var idx = this.stableSorted(cmp);
                for (var i = 0; i < this.length; ++i)
                    this[i] = idx[i];
            };
            arr.clear = function () {
                return this.splice(0, this.length);
            };
            var str = String.prototype;
            str.startsWith = function (str) {
                this.slice(0, str.length) == str;
            };
            str.endsWith = function (str) {
                this.slice(-str.length) == str;
            };
            str.count = function () {
                return this.length;
            };
            str.at = function (idx) {
                return this.charAt(idx);
            };
        }
        Util.initGenericExtensions = initGenericExtensions;
        function intersectArraysVA(arrays) {
            if (!arrays.length)
                return [];
            arrays.sort(function (a, b) { return a.length - b.length; });
            var res = [];
            arrays[0].forEach(function (e) {
                for (var i = 1; i < arrays.length; ++i)
                    if (arrays[i].indexOf(e) < 0)
                        return;
                res.push(e);
            });
            return res;
        }
        Util.intersectArraysVA = intersectArraysVA;
        function concatArraysVA(arrays) {
            var res = [];
            for (var i = 0; i < arrays.length; ++i) {
                var a = arrays[i];
                for (var j = 0; j < a.length; ++j)
                    res.push(a[j]);
            }
            return res;
        }
        Util.concatArraysVA = concatArraysVA;
        function concatArrays() {
            var arrays = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                arrays[_i - 0] = arguments[_i];
            }
            return concatArraysVA(arrays);
        }
        Util.concatArrays = concatArrays;
        function startsWith(s, pref) {
            if (!pref)
                return true;
            if (!s || s.length < pref.length)
                return false;
            return s.slice(0, pref.length) == pref;
        }
        Util.startsWith = startsWith;
        function stableSum(v) {
            var sum = 0.0;
            var c = 0.0;
            for (var i = 0; i < v.length; i++) {
                var y = v[i] - c;
                var t = sum + y;
                c = (t - sum) - y;
                sum = t;
            }
            return sum;
        }
        Util.stableSum = stableSum;
        function initCscript() {
            TDev.Browser.cscript = true;
            var arr = Array.prototype;
            arr.map = function (f) {
                var res = [];
                for (var i = 0; i < this.length; ++i) {
                    var tmp = f(this[i], i);
                    res.push(tmp);
                }
                return res;
            };
            arr.forEach = function (f) {
                for (var i = 0; i < this.length; ++i) {
                    f(this[i], i);
                }
            };
            arr.filter = function (f) {
                var res = [];
                for (var i = 0; i < this.length; ++i) {
                    if (f(this[i], i))
                        res.push(this[i]);
                }
                return res;
            };
            var obj = Object.prototype;
            obj.create = function (o) {
                function F() {
                }
                F.prototype = o;
                return new F();
            };
            Object.keys = function (o) {
                var res = [];
                for (var k in o) {
                    if (o.hasOwnProperty(k))
                        res.push(k);
                }
                return res;
            };
        }
        Util.initCscript = initCscript;
        function values(o) {
            return Object.keys(o).map(function (k) { return o[k]; });
        }
        Util.values = values;
        function userError(msg, pc, statusCode) {
            if (pc === void 0) { pc = ""; }
            var e = new Error(msg);
            e.isUserError = true;
            if (statusCode)
                e.statusCode = statusCode;
            try {
                throw e;
            }
            catch (err) {
                Util.log('error: {0}, {1}, {2}', msg, pc, statusCode);
                Util.log(err.stack + "");
                throw e;
            }
        }
        Util.userError = userError;
        function syntaxError(msg, declName) {
            var e = new Error(msg);
            e.syntaxErrorDeclName = declName;
            e.isUserError = true;
            throw e;
        }
        Util.syntaxError = syntaxError;
        function indexCheck(i, length) {
            i = Math.floor(i);
            if (i < 0 || i >= length)
                Util.userError("index " + i + " out of bounds (collection size: " + length + ")");
            return i;
        }
        Util.indexCheck = indexCheck;
        function isOOB(i, length) {
            i = Math.floor(i);
            return (i < 0 || i >= length);
        }
        Util.isOOB = isOOB;
        function notImplementedYet(s, apiName) {
            if (s.rt.devMode)
                Util.userError(apiName + " not implemented yet");
            return undefined;
        }
        Util.notImplementedYet = notImplementedYet;
        function notSupported(s, apiName) {
            if (s.rt.devMode)
                Util.userError(apiName + " is not supported in this version of Touch Develop");
            return undefined;
        }
        Util.notSupported = notSupported;
        function guidGen() {
            function f() {
                return (TDev.Random.uint32() | 0x10000).toString(16).slice(-4);
            }
            return f() + f() + "-" + f() + "-4" + f().slice(-3) + "-" + f() + "-" + f() + f() + f();
        }
        Util.guidGen = guidGen;
        function guidToAlpha(guid) {
            var nohyphens = guid.replace(/-/g, 'z');
            var nonumbers = nohyphens.replace(/[0-9]/g, function (s) {
                var digit = s.charCodeAt(0) - ("0".charCodeAt(0)) + ("m".charCodeAt(0));
                return String.fromCharCode(digit);
            });
            return nonumbers;
        }
        Util.guidToAlpha = guidToAlpha;
        Util.colors = [
            "#FF00FF",
            "#800080",
            "#A52A2A",
            "#E25822",
            "#FF0038",
            "#008080",
            "#00008B",
            "#004B49",
        ];
        function svgGravatar(id) {
            if (!id)
                id = "none";
            var advance = function (hash, v) { return ((hash << 16) + (hash << 6) + v - hash) << 0; };
            var hash = 0;
            for (var i = 0; i < id.length; ++i) {
                hash = advance(hash, id.charCodeAt(i));
            }
            var n = hash & 0xffff;
            var idx = n % (Util.colors.length - 1);
            var c = Util.colors[idx];
            var d = "";
            var numPixels = 0;
            while (numPixels < 6) {
                for (var x = 0; x < 3; ++x) {
                    for (var y = 0; y < 5; ++y) {
                        hash = advance(hash, id.charCodeAt(i++ % id.length));
                        n = hash & 0xffff;
                        if (n > 30000) {
                        }
                        else {
                            d += Util.fmt(" M {0} {1} l 46 0 0 46 -46 0 Z", 50 * x + 2, 50 * y + 2);
                            if (x != 2)
                                d += Util.fmt(" M {0} {1} l 46 0 0 46 -46 0 Z", 50 * (4 - x) + 2, 50 * y + 2);
                            numPixels++;
                        }
                    }
                }
                numPixels++;
            }
            var svg = Util.fmt("<path fill='{0}' d='{1}' />", c, d);
            return TDev.SVG.svgBoilerPlate('0 0 250 250', svg);
        }
        Util.svgGravatar = svgGravatar;
        function base64Encode(_input) {
            function _base64(_x) {
                return ((_x <= 0x19) ? (_x + 0x41) : ((_x <= 0x33) ? (_x + 0x47) : ((_x <= 0x3D) ? (_x - 0x4) : ((_x == 0x3E) ? 0x2B : 0x2F))));
            }
            ;
            var result = new Array();
            var _q = 0x0;
            var _r = 0x0;
            for (var _i = 0; _i < _input.length; _i++) {
                var _x = _input.charCodeAt(_i);
                if ((_x > 0xFF)) {
                    return undefined;
                }
                else if ((_q == 0x0)) {
                    result.push(String.fromCharCode(_base64((_x >> 0x2))));
                    _q = 0x1;
                    _r = ((_x & 0x3) << 0x4);
                }
                else if ((_q == 0x1)) {
                    result.push(String.fromCharCode(_base64((_r | (_x >> 0x4)))));
                    _q = 0x2;
                    _r = ((_x & 0xF) << 0x2);
                }
                else if ((_q == 0x2)) {
                    result.push(String.fromCharCode(_base64((_r | (_x >> 0x6))), _base64((_x & 0x3F))));
                    _q = 0x0;
                    _r = 0x0;
                }
            }
            if ((_q == 0x1)) {
                result.push(String.fromCharCode(_base64(_r), 0x3D, 0x3D));
            }
            else if ((_q == 0x2)) {
                result.push(String.fromCharCode(_base64(_r), 0x3D));
            }
            return result.join('');
        }
        Util.base64Encode = base64Encode;
        function base64EncodeBytes(_input) {
            function _base64(_x) {
                return ((_x <= 0x19) ? (_x + 0x41) : ((_x <= 0x33) ? (_x + 0x47) : ((_x <= 0x3D) ? (_x - 0x4) : ((_x == 0x3E) ? 0x2B : 0x2F))));
            }
            ;
            var result = new Array();
            var _q = 0x0;
            var _r = 0x0;
            for (var _i = 0; _i < _input.length; _i++) {
                var _x = _input[_i];
                if ((_x > 0xFF)) {
                    return undefined;
                }
                else if ((_q == 0x0)) {
                    result.push(String.fromCharCode(_base64((_x >> 0x2))));
                    _q = 0x1;
                    _r = ((_x & 0x3) << 0x4);
                }
                else if ((_q == 0x1)) {
                    result.push(String.fromCharCode(_base64((_r | (_x >> 0x4)))));
                    _q = 0x2;
                    _r = ((_x & 0xF) << 0x2);
                }
                else if ((_q == 0x2)) {
                    result.push(String.fromCharCode(_base64((_r | (_x >> 0x6))), _base64((_x & 0x3F))));
                    _q = 0x0;
                    _r = 0x0;
                }
            }
            if ((_q == 0x1)) {
                result.push(String.fromCharCode(_base64(_r), 0x3D, 0x3D));
            }
            else if ((_q == 0x2)) {
                result.push(String.fromCharCode(_base64(_r), 0x3D));
            }
            return result.join('');
        }
        Util.base64EncodeBytes = base64EncodeBytes;
        function stringToUint8Array(input) {
            var len = input.length;
            var res = new Uint8Array(len);
            for (var i = 0; i < len; ++i)
                res[i] = input.charCodeAt(i) & 0xff;
            return res;
        }
        Util.stringToUint8Array = stringToUint8Array;
        function uint8ArrayToString(input) {
            var len = input.length;
            var res = "";
            for (var i = 0; i < len; ++i)
                res += String.fromCharCode(input[i]);
            return res;
        }
        Util.uint8ArrayToString = uint8ArrayToString;
        function base64Decode(_input) {
            function _D(_x) {
                return ((_x == 0x2F) ? 0x3F : ((_x == 0x2B) ? 0x3E : ((_x <= 0x39) ? (_x + 0x4) : ((_x <= 0x5A) ? (_x - 0x41) : (_x - 0x47)))));
            }
            ;
            function _Bits(m, n, c) {
                var mask = 0;
                for (var i = 0; i <= (m - n); i++) {
                    mask = (mask << 1) + 1;
                }
                return (c >> n) & mask;
            }
            ;
            var result = new Array();
            var _q0 = true;
            var _q1 = false;
            var _q2 = false;
            var _q3 = false;
            var _q4 = false;
            var _q5 = false;
            var _r = 0x0;
            var rx = new RegExp("^([A-Za-z0-9+/=])$");
            for (var _i = 0; _i < _input.length; _i++) {
                var _x = _input.charCodeAt(_i);
                if ((!String.fromCharCode(_x).match(rx) || ((_x == 0x3D) && (_q0 || _q1)) || ((_x == 0x3D) && !(_r == 0x0)) || (!(_x == 0x3D) && _q4) || _q5)) {
                    return undefined;
                }
                else if (_q0) {
                    _r = (_D(_x) << 0x2);
                    _q0 = false;
                    _q1 = true;
                    _q2 = false;
                    _q3 = false;
                    _q4 = false;
                    _q5 = false;
                }
                else if (_q1) {
                    result.push(String.fromCharCode((_r | _Bits(0x5, 0x4, _D(_x)))));
                    _r = ((_D(_x) & 0xF) << 0x4);
                    _q0 = false;
                    _q1 = false;
                    _q2 = true;
                    _q3 = false;
                    _q4 = false;
                    _q5 = false;
                }
                else if (_q2) {
                    if ((_x == 0x3D)) {
                        _r = 0x0;
                        _q0 = false;
                        _q1 = false;
                        _q2 = false;
                        _q3 = false;
                        _q4 = true;
                        _q5 = false;
                    }
                    else {
                        result.push(String.fromCharCode((_r | _Bits(0x5, 0x2, _D(_x)))));
                        _r = ((_D(_x) & 0x3) << 0x6);
                        _q0 = false;
                        _q1 = false;
                        _q2 = false;
                        _q3 = true;
                        _q4 = false;
                        _q5 = false;
                    }
                }
                else if (_q3) {
                    if ((_x == 0x3D)) {
                        _r = 0x0;
                        _q0 = false;
                        _q1 = false;
                        _q2 = false;
                        _q3 = false;
                        _q4 = false;
                        _q5 = true;
                    }
                    else {
                        result.push(String.fromCharCode((_r | _D(_x))));
                        _r = 0x0;
                        _q0 = true;
                        _q1 = false;
                        _q2 = false;
                        _q3 = false;
                        _q4 = false;
                        _q5 = false;
                    }
                }
                else if (_q4) {
                    _r = 0x0;
                    _q0 = false;
                    _q1 = false;
                    _q2 = false;
                    _q3 = false;
                    _q4 = false;
                    _q5 = true;
                }
            }
            if (!(_q0 || _q5)) {
                return undefined;
            }
            return result.join('');
        }
        Util.base64Decode = base64Decode;
        function splitDataUrl(url) {
            if (!!url) {
                var match = /^data:([^;]+);base64,/.exec(url);
                if (!!match)
                    return {
                        contentType: match[1],
                        content: url.substr(match[0].length)
                    };
            }
            return null;
        }
        Util.splitDataUrl = splitDataUrl;
        function base64EncodeToBase64(url, mimeType) {
            var prefix = 'data:' + mimeType + ';base64,';
            if (!!url && TDev.RT.String_.starts_with(url, prefix))
                return url.substr(prefix.length);
            return undefined;
        }
        Util.base64EncodeToBase64 = base64EncodeToBase64;
        function decodeDataURL(url, mimeType) {
            if (mimeType === void 0) { mimeType = null; }
            if (!mimeType) {
                var m = url.match(/^data:([^;]+);base64,/);
                if (!m)
                    return undefined;
                mimeType = m[1];
            }
            var prefix = 'data:' + mimeType + ';base64,';
            var binaryEncoded = url.substr(prefix.length);
            var binary = atob(binaryEncoded);
            var arrayBuffer = new ArrayBuffer(binary.length);
            var array = new Uint8Array(arrayBuffer);
            for (var i = 0; i < binary.length; i++)
                array[i] = binary.charCodeAt(i) & 0xff;
            return array;
        }
        Util.decodeDataURL = decodeDataURL;
        function hex1(a) {
            var h = a & 0xF;
            h = (h <= 9 ? h + 48 : h + 55);
            return h;
        }
        ;
        function hex2(a0, a1) {
            var h = (a1 >> (4 * a0)) & 0xF;
            h = (h <= 9 ? h + 48 : h + 55);
            return h;
        }
        ;
        var entities = undefined;
        var entitiesRx = undefined;
        function htmlUnescape(_w) {
            if (!_w)
                return _w;
            if (!entities) {
                entities = {};
                entities['nbsp'] = ' ';
                entities['iexcl'] = '¡';
                entities['cent'] = '¢';
                entities['pound'] = '£';
                entities['curren'] = '¤';
                entities['yen'] = '¥';
                entities['brvbar'] = '¦';
                entities['sect'] = '§';
                entities['uml'] = '¨';
                entities['copy'] = '©';
                entities['ordf'] = 'ª';
                entities['laquo'] = '«';
                entities['not'] = '¬';
                entities['shy'] = '­';
                entities['reg'] = '®';
                entities['macr'] = '¯';
                entities['deg'] = '°';
                entities['plusmn'] = '±';
                entities['sup2'] = '²';
                entities['sup3'] = '³';
                entities['acute'] = '´';
                entities['micro'] = 'µ';
                entities['para'] = '¶';
                entities['middot'] = '·';
                entities['cedil'] = '¸';
                entities['sup1'] = '¹';
                entities['ordm'] = 'º';
                entities['raquo'] = '»';
                entities['frac14'] = '¼';
                entities['frac12'] = '½';
                entities['frac34'] = '¾';
                entities['iquest'] = '¿';
                entities['times'] = '×';
                entities['divide'] = '÷';
                entities['Agrave'] = 'À';
                entities['Aacute'] = 'Á';
                entities['Acirc'] = 'Â';
                entities['Atilde'] = 'Ã';
                entities['Auml'] = 'Ä';
                entities['Aring'] = 'Å';
                entities['AElig'] = 'Æ';
                entities['Ccedil'] = 'Ç';
                entities['Egrave'] = 'È';
                entities['Eacute'] = 'É';
                entities['Ecirc'] = 'Ê';
                entities['Euml'] = 'Ë';
                entities['Igrave'] = 'Ì';
                entities['Iacute'] = 'Í';
                entities['Icirc'] = 'Î';
                entities['Iuml'] = 'Ï';
                entities['ETH'] = 'Ð';
                entities['Ntilde'] = 'Ñ';
                entities['Ograve'] = 'Ò';
                entities['Oacute'] = 'Ó';
                entities['Ocirc'] = 'Ô';
                entities['Otilde'] = 'Õ';
                entities['Ouml'] = 'Ö';
                entities['Oslash'] = 'Ø';
                entities['Ugrave'] = 'Ù';
                entities['Uacute'] = 'Ú';
                entities['Ucirc'] = 'Û';
                entities['Uuml'] = 'Ü';
                entities['Yacute'] = 'Ý';
                entities['THORN'] = 'Þ';
                entities['szlig'] = 'ß';
                entities['agrave'] = 'à';
                entities['aacute'] = 'á';
                entities['acirc'] = 'â';
                entities['atilde'] = 'ã';
                entities['auml'] = 'ä';
                entities['aring'] = 'å';
                entities['aelig'] = 'æ';
                entities['ccedil'] = 'ç';
                entities['egrave'] = 'è';
                entities['eacute'] = 'é';
                entities['ecirc'] = 'ê';
                entities['euml'] = 'ë';
                entities['igrave'] = 'ì';
                entities['iacute'] = 'í';
                entities['icirc'] = 'î';
                entities['iuml'] = 'ï';
                entities['eth'] = 'ð';
                entities['ntilde'] = 'ñ';
                entities['ograve'] = 'ò';
                entities['oacute'] = 'ó';
                entities['ocirc'] = 'ô';
                entities['otilde'] = 'õ';
                entities['ouml'] = 'ö';
                entities['oslash'] = 'ø';
                entities['ugrave'] = 'ù';
                entities['uacute'] = 'ú';
                entities['ucirc'] = 'û';
                entities['uuml'] = 'ü';
                entities['yacute'] = 'ý';
                entities['thorn'] = 'þ';
                entities['yuml'] = 'ÿ';
                entitiesRx = new RegExp('&(' + Object.keys(entities).join('|') + ');', 'gim');
            }
            _w = _w.replace(entitiesRx, function (m, args) {
                return entities[args];
            });
            function _IsDecDig(_x) {
                return ((0x30 <= _x) && (_x <= 0x39));
            }
            ;
            function _F(_x, _y) {
                return ((0xA * _x) + (_y - 0x30));
            }
            ;
            function _D1(_x) {
                return ((_x % 0xA) + 0x30);
            }
            ;
            function _D2(_x) {
                return (((_x / 0xA) % 0xA) + 0x30);
            }
            ;
            function _D3(_x) {
                return (((_x / 0x64) % 0xA) + 0x30);
            }
            ;
            function _D4(_x) {
                return (((_x / 0x3E8) % 0xA) + 0x30);
            }
            ;
            function _D5(_x) {
                return (((_x / 0x2710) % 0xA) + 0x30);
            }
            ;
            function _IsHexDig(_x) {
                return (((0x30 <= _x) && (_x <= 0x39)) || ((0x41 <= _x) && (_x <= 0x46)));
            }
            ;
            function _Fx(_x, _y) {
                return ((_x << 0x4) | (_IsDecDig(_y) ? (_y - 0x30) : (_y - 0x37)));
            }
            ;
            function _H1(_x) {
                return (_IsDec((_x & 0xF)) ? ((_x & 0xF) + 0x30) : ((_x & 0xF) + 0x37));
            }
            ;
            function _IsDec(_x) {
                return ((0x0 <= _x) && (_x <= 0x9));
            }
            ;
            function _H2(_x) {
                return (_IsDec(((_x >> 0x4) & 0xF)) ? (((_x >> 0x4) & 0xF) + 0x30) : (((_x >> 0x4) & 0xF) + 0x37));
            }
            ;
            function _H3(_x) {
                return (_IsDec(((_x >> 0x8) & 0xF)) ? (((_x >> 0x8) & 0xF) + 0x30) : (((_x >> 0x8) & 0xF) + 0x37));
            }
            ;
            function _H4(_x) {
                return (_IsDec(((_x >> 0xC) & 0xF)) ? (((_x >> 0xC) & 0xF) + 0x30) : (((_x >> 0xC) & 0xF) + 0x37));
            }
            ;
            var result = new Array();
            var _q = 0x0;
            var _d = 0x0;
            for (var _i = 0; _i < _w.length; _i++) {
                var _c = _w.charCodeAt(_i);
                if (((_q == 0x0) && (_c == 0x26))) {
                    _q = 0x26;
                }
                else if ((_q == 0x0)) {
                    result.push(String.fromCharCode(_c));
                }
                else if (((_q == 0x26) && (_c == 0x23))) {
                    _q = 0x23;
                }
                else if (((_q == 0x26) && (_c == 0x61))) {
                    _q = 0x61;
                }
                else if (((_q == 0x26) && (_c == 0x71))) {
                    _q = 0x71;
                }
                else if (((_q == 0x26) && (_c == 0x6C))) {
                    _q = 0x6C;
                }
                else if (((_q == 0x26) && (_c == 0x67))) {
                    _q = 0x67;
                }
                else if (((_q == 0x26) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26));
                }
                else if ((_q == 0x26)) {
                    result.push(String.fromCharCode(0x26, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x23) && (_c == 0x58))) {
                    _q = 0x58;
                }
                else if (((_q == 0x23) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23));
                    _q = 0x26;
                }
                else if (((_q == 0x23) && _IsDecDig(_c))) {
                    _q = 0x1;
                    _d = (_c - 0x30);
                }
                else if ((_q == 0x23)) {
                    result.push(String.fromCharCode(0x26, 0x23, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x1) && _IsDecDig(_c))) {
                    _q = 0x2;
                    _d = _F(_d, _c);
                }
                else if (((_q == 0x1) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x1) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, _D1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x1)) {
                    result.push(String.fromCharCode(0x26, 0x23, _D1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x2) && _IsDecDig(_c))) {
                    _q = 0x3;
                    _d = _F(_d, _c);
                }
                else if (((_q == 0x2) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x2) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, _D2(_d), _D1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x2)) {
                    result.push(String.fromCharCode(0x26, 0x23, _D2(_d), _D1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x3) && _IsDecDig(_c))) {
                    _q = 0x4;
                    _d = _F(_d, _c);
                }
                else if (((_q == 0x3) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x3) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, _D3(_d), _D2(_d), _D1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x3)) {
                    result.push(String.fromCharCode(0x26, 0x23, _D3(_d), _D2(_d), _D1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x4) && _IsDecDig(_c) && (_F(_d, _c) <= 0xFFFF))) {
                    _q = 0x5;
                    _d = _F(_d, _c);
                }
                else if (((_q == 0x4) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x4) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, _D4(_d), _D3(_d), _D2(_d), _D1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x4)) {
                    result.push(String.fromCharCode(0x26, 0x23, _D4(_d), _D3(_d), _D2(_d), _D1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x5) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x5) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, _D5(_d), _D4(_d), _D3(_d), _D2(_d), _D1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x5)) {
                    result.push(String.fromCharCode(0x26, 0x23, _D5(_d), _D4(_d), _D3(_d), _D2(_d), _D1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x58) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58));
                    _q = 0x26;
                }
                else if (((_q == 0x58) && _IsHexDig(_c))) {
                    _q = 0x6;
                    _d = _Fx(0x0, _c);
                }
                else if ((_q == 0x58)) {
                    _q = 0x0;
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _c));
                    _d = 0x0;
                }
                else if (((_q == 0x6) && _IsHexDig(_c))) {
                    _q = 0x7;
                    _d = _Fx(_d, _c);
                }
                else if (((_q == 0x6) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x6) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x6)) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x7) && _IsHexDig(_c))) {
                    _q = 0x8;
                    _d = _Fx(_d, _c);
                }
                else if (((_q == 0x7) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x7) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H2(_d), _H1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x7)) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H2(_d), _H1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x8) && _IsHexDig(_c))) {
                    _q = 0x9;
                    _d = _Fx(_d, _c);
                }
                else if (((_q == 0x8) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x8) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H3(_d), _H2(_d), _H1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x8)) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H3(_d), _H2(_d), _H1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x9) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(_d));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x9) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H4(_d), _H3(_d), _H2(_d), _H1(_d)));
                    _q = 0x26;
                    _d = 0x0;
                }
                else if ((_q == 0x9)) {
                    result.push(String.fromCharCode(0x26, 0x23, 0x58, _H4(_d), _H3(_d), _H2(_d), _H1(_d), _c));
                    _q = 0x0;
                    _d = 0x0;
                }
                else if (((_q == 0x6C) && (_c == 0x74))) {
                    _q = 0x4C;
                }
                else if (((_q == 0x6C) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x6C));
                    _q = 0x26;
                }
                else if ((_q == 0x6C)) {
                    result.push(String.fromCharCode(0x26, 0x6C, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x4C) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(0x3C));
                    _q = 0x0;
                }
                else if (((_q == 0x4C) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x6C, 0x74));
                    _q = 0x26;
                }
                else if ((_q == 0x4C)) {
                    result.push(String.fromCharCode(0x26, 0x6C, 0x74, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x67) && (_c == 0x74))) {
                    _q = 0x47;
                }
                else if (((_q == 0x67) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x67));
                    _q = 0x26;
                }
                else if ((_q == 0x67)) {
                    result.push(String.fromCharCode(0x26, 0x67, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x47) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(0x3E));
                    _q = 0x0;
                }
                else if (((_q == 0x47) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x67, 0x74));
                    _q = 0x26;
                }
                else if ((_q == 0x47)) {
                    result.push(String.fromCharCode(0x26, 0x67, 0x74, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x71) && (_c == 0x75))) {
                    _q = 0x75;
                }
                else if (((_q == 0x71) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x71));
                    _q = 0x26;
                }
                else if ((_q == 0x71)) {
                    result.push(String.fromCharCode(0x26, 0x71, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x75) && (_c == 0x6F))) {
                    _q = 0x6F;
                }
                else if (((_q == 0x75) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75));
                    _q = 0x26;
                }
                else if ((_q == 0x75)) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x6F) && (_c == 0x74))) {
                    _q = 0x74;
                }
                else if (((_q == 0x6F) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F));
                    _q = 0x26;
                }
                else if ((_q == 0x6F)) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x74) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(0x22));
                    _q = 0x0;
                }
                else if (((_q == 0x74) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F, 0x74));
                    _q = 0x26;
                }
                else if ((_q == 0x74)) {
                    result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F, 0x74, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x61) && (_c == 0x6D))) {
                    _q = 0x6D;
                }
                else if (((_q == 0x61) && (_c == 0x70))) {
                    _q = 0x50;
                }
                else if (((_q == 0x61) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61));
                    _q = 0x26;
                }
                else if ((_q == 0x61)) {
                    result.push(String.fromCharCode(0x26, 0x61, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x6D) && (_c == 0x70))) {
                    _q = 0x70;
                }
                else if (((_q == 0x6D) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x6D));
                    _q = 0x26;
                }
                else if ((_q == 0x6D)) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x6D, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x70) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(0x26));
                    _q = 0x0;
                }
                else if (((_q == 0x70) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x6D, 0x70));
                    _q = 0x26;
                }
                else if ((_q == 0x70)) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x6D, 0x70, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x50) && (_c == 0x6F))) {
                    _q = 0x4F;
                }
                else if (((_q == 0x50) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70));
                    _q = 0x26;
                }
                else if ((_q == 0x50)) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x4F) && (_c == 0x73))) {
                    _q = 0x53;
                }
                else if (((_q == 0x4F) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F));
                    _q = 0x26;
                }
                else if ((_q == 0x4F)) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F, _c));
                    _q = 0x0;
                }
                else if (((_q == 0x53) && (_c == 0x3B))) {
                    result.push(String.fromCharCode(0x27));
                    _q = 0x0;
                }
                else if (((_q == 0x53) && (_c == 0x26))) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F, 0x73));
                    _q = 0x26;
                }
                else if ((_q == 0x53)) {
                    result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F, 0x73, _c));
                    _q = 0x0;
                }
                else if (true) {
                    _q = 0x0;
                    _d = 0x0;
                }
            }
            if ((_q == 0x0)) {
            }
            else if ((_q == 0x26)) {
                result.push(String.fromCharCode(0x26));
            }
            else if ((_q == 0x23)) {
                result.push(String.fromCharCode(0x26, 0x23));
            }
            else if ((_q == 0x58)) {
                result.push(String.fromCharCode(0x26, 0x23, 0x58));
            }
            else if ((_q == 0x1)) {
                result.push(String.fromCharCode(0x26, 0x23, _D1(_d)));
            }
            else if ((_q == 0x2)) {
                result.push(String.fromCharCode(0x26, 0x23, _D2(_d), _D1(_d)));
            }
            else if ((_q == 0x3)) {
                result.push(String.fromCharCode(0x26, 0x23, _D3(_d), _D2(_d), _D1(_d)));
            }
            else if ((_q == 0x4)) {
                result.push(String.fromCharCode(0x26, 0x23, _D4(_d), _D3(_d), _D2(_d), _D1(_d)));
            }
            else if ((_q == 0x5)) {
                result.push(String.fromCharCode(0x26, 0x23, _D5(_d), _D4(_d), _D3(_d), _D2(_d), _D1(_d)));
            }
            else if ((_q == 0x6)) {
                result.push(String.fromCharCode(0x26, 0x23, 0x58, _H1(_d)));
            }
            else if ((_q == 0x7)) {
                result.push(String.fromCharCode(0x26, 0x23, 0x58, _H2(_d), _H1(_d)));
            }
            else if ((_q == 0x8)) {
                result.push(String.fromCharCode(0x26, 0x23, 0x58, _H3(_d), _H2(_d), _H1(_d)));
            }
            else if ((_q == 0x9)) {
                result.push(String.fromCharCode(0x26, 0x23, 0x58, _H4(_d), _H3(_d), _H2(_d), _H1(_d)));
            }
            else if ((_q == 0x6C)) {
                result.push(String.fromCharCode(0x26, 0x6C));
            }
            else if ((_q == 0x4C)) {
                result.push(String.fromCharCode(0x26, 0x6C, 0x74));
            }
            else if ((_q == 0x67)) {
                result.push(String.fromCharCode(0x26, 0x67));
            }
            else if ((_q == 0x47)) {
                result.push(String.fromCharCode(0x26, 0x67, 0x74));
            }
            else if ((_q == 0x71)) {
                result.push(String.fromCharCode(0x26, 0x71));
            }
            else if ((_q == 0x75)) {
                result.push(String.fromCharCode(0x26, 0x71, 0x75));
            }
            else if ((_q == 0x6F)) {
                result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F));
            }
            else if ((_q == 0x74)) {
                result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F, 0x74));
            }
            else if ((_q == 0x61)) {
                result.push(String.fromCharCode(0x26, 0x61));
            }
            else if ((_q == 0x6D)) {
                result.push(String.fromCharCode(0x26, 0x61, 0x6D));
            }
            else if ((_q == 0x70)) {
                result.push(String.fromCharCode(0x26, 0x61, 0x6D, 0x70));
            }
            else if ((_q == 0x50)) {
                result.push(String.fromCharCode(0x26, 0x61, 0x70));
            }
            else if ((_q == 0x4F)) {
                result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F));
            }
            else if ((_q == 0x53)) {
                result.push(String.fromCharCode(0x26, 0x61, 0x70, 0x6F, 0x73));
            }
            else if (true) {
            }
            return result.join('');
        }
        Util.htmlUnescape = htmlUnescape;
        function htmlEscape(_input) {
            if (!_input)
                return _input;
            var result = new Array();
            var _HS = false;
            var _r = 0x0;
            for (var _i = 0; _i < _input.length; _i++) {
                var _x = _input.charCodeAt(_i);
                if (!_HS) {
                    if (String.fromCharCode(_x).match(/^([\x20\x21\x23-\x25\x28-\x3B\x3D\x3F-\x7E\xA1-\xAC\xAE-\u036F])$/)) {
                        result.push(String.fromCharCode(_x));
                    }
                    else {
                        if ((_x == 0x22)) {
                            result.push(String.fromCharCode(0x26, 0x71, 0x75, 0x6F, 0x74, 0x3B));
                        }
                        else {
                            if ((_x == 0x26)) {
                                result.push(String.fromCharCode(0x26, 0x61, 0x6D, 0x70, 0x3B));
                            }
                            else {
                                if ((_x == 0x3C)) {
                                    result.push(String.fromCharCode(0x26, 0x6C, 0x74, 0x3B));
                                }
                                else {
                                    if ((_x == 0x3E)) {
                                        result.push(String.fromCharCode(0x26, 0x67, 0x74, 0x3B));
                                    }
                                    else {
                                        if ((_x < 0x10)) {
                                            result.push(String.fromCharCode(0x26, 0x23, 0x58, hex2(0x0, _x), 0x3B));
                                        }
                                        else {
                                            if ((_x < 0x100)) {
                                                result.push(String.fromCharCode(0x26, 0x23, 0x58, hex2(0x1, _x), hex2(0x0, _x), 0x3B));
                                            }
                                            else {
                                                if ((_x < 0x1000)) {
                                                    result.push(String.fromCharCode(0x26, 0x23, 0x58, hex2(0x2, _x), hex2(0x1, _x), hex2(0x0, _x), 0x3B));
                                                }
                                                else {
                                                    if (((0xD800 <= _x) && (_x <= 0xDBFF))) {
                                                        if ((((_x >> 0x6) & 0xF) == 0xF)) {
                                                            result.push(String.fromCharCode(0x26, 0x23, 0x58, 0x31, 0x30, hex2(0x0, (_x >> 0x2))));
                                                            _HS = true;
                                                            _r = (_x & 0x3);
                                                        }
                                                        else {
                                                            result.push(String.fromCharCode(0x26, 0x23, 0x58, hex2(0x0, ((_x >> 0x6) + 0x1)), hex2(0x0, (_x >> 0x2))));
                                                            _HS = true;
                                                            _r = (_x & 0x3);
                                                        }
                                                    }
                                                    else {
                                                        if ((((0xDC00 <= _x) && (_x <= 0xDFFF)) || (_x == 0xFFFF) || (_x == 0xFFFE))) {
                                                            return undefined;
                                                        }
                                                        else {
                                                            result.push(String.fromCharCode(0x26, 0x23, 0x58, hex2(0x3, _x), hex2(0x2, _x), hex2(0x1, _x), hex2(0x0, _x), 0x3B));
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else if (true) {
                    if (((0xDC00 <= _x) && (_x <= 0xDFFF))) {
                        result.push(String.fromCharCode(hex1(((_r << 0x2) | ((_x >> 0x8) & 0x3))), hex2(0x1, _x), hex2(0x0, _x), 0x3B));
                        _HS = false;
                        _r = 0x0;
                    }
                    else {
                        return undefined;
                    }
                }
            }
            if (_HS) {
                return undefined;
            }
            return result.join('');
        }
        Util.htmlEscape = htmlEscape;
        function formatText(s) {
            return htmlEscape(s).replace(/&#XA;/g, "<br/>\n").replace(/ /g, "&#x2005;");
        }
        Util.formatText = formatText;
        function selectOnFocusTextArea(elt) {
            elt.onfocus = function () {
                elt.select();
            };
            elt.onmouseup = function () { return false; };
        }
        Util.selectOnFocusTextArea = selectOnFocusTextArea;
        function selectOnFocus(elt) {
            elt.onfocus = function () {
                elt.select();
            };
            elt.onmouseup = function () { return false; };
        }
        Util.selectOnFocus = selectOnFocus;
        function setKeyboardFocusTextArea(elt, selectAll) {
            if (selectAll === void 0) { selectAll = false; }
            elt.focus();
            try {
                elt.setSelectionRange(selectAll ? 0 : elt.value.length, elt.value.length);
            }
            catch (e) {
            }
        }
        Util.setKeyboardFocusTextArea = setKeyboardFocusTextArea;
        function setKeyboardFocus(elt, selectAll) {
            if (selectAll === void 0) { selectAll = false; }
            elt.focus();
            if (elt.type === "text" || elt.type === "number")
                try {
                    elt.setSelectionRange(selectAll ? 0 : elt.value.length, elt.value.length);
                }
                catch (e) {
                }
        }
        Util.setKeyboardFocus = setKeyboardFocus;
        function hideKeyboard() {
            var active = document.activeElement;
            if (active && active.blur) {
                if (TDev.Browser.isAndroid) {
                    active.readonly = "readonly";
                    active.disabled = "true";
                    Util.setTimeout(10, function () {
                        active.blur();
                        active.removeAttribute("readonly");
                        active.removeAttribute("disabled");
                    });
                }
                else {
                    active.blur();
                }
            }
        }
        Util.hideKeyboard = hideKeyboard;
        function offsetIn(elt, par) {
            var x = 0;
            var y = 0;
            while (!!elt) {
                if (elt == par)
                    break;
                x += elt.offsetLeft + elt.clientLeft - elt.scrollLeft;
                y += elt.offsetTop + elt.clientTop - elt.scrollTop;
                elt = elt.offsetParent;
            }
            return { x: x, y: y };
        }
        Util.offsetIn = offsetIn;
        function children() {
            var elts = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                elts[_i - 0] = arguments[_i];
            }
            var res = [];
            elts.forEach(function (elt) {
                var cn = elt.children;
                for (var i = 0; i < cn.length; ++i)
                    res.push(cn[i]);
            });
            return res;
        }
        Util.children = children;
        function childNodes() {
            var elts = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                elts[_i - 0] = arguments[_i];
            }
            var res = [];
            elts.forEach(function (elt) {
                var cn = elt.childNodes;
                for (var i = 0; i < cn.length; ++i)
                    res.push(cn[i]);
            });
            return res;
        }
        Util.childNodes = childNodes;
        var transformPropertyName = "";
        var perspectivePropertyName = "";
        function setTransform(e, t, origin, perspective) {
            if (origin === void 0) { origin = undefined; }
            if (perspective === void 0) { perspective = undefined; }
            var style = e.style;
            if (!transformPropertyName) {
                if (style["transform"] !== undefined)
                    transformPropertyName = "transform";
                else
                    ["Webkit", "ms", "Moz", "O"].forEach(function (pref) {
                        var tt = pref + "Transform";
                        if (!transformPropertyName && style[tt] !== undefined) {
                            transformPropertyName = tt;
                            perspectivePropertyName = pref + "Perspective";
                        }
                    });
                if (!transformPropertyName) {
                    transformPropertyName = "transform";
                    perspectivePropertyName = "perspective";
                }
            }
            if (origin !== undefined)
                style[transformPropertyName + "Origin"] = origin;
            if (perspective !== undefined)
                style[perspectivePropertyName] = perspective;
            style[transformPropertyName] = t;
        }
        Util.setTransform = setTransform;
        function id(e) {
            return e;
        }
        Util.id = id;
        function doNothing() {
            var pars = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                pars[_i - 0] = arguments[_i];
            }
        }
        Util.doNothing = doNothing;
        ;
        var logMsgs = [];
        Util.logSz = 200;
        var logIdx = -1;
        function timeSeries(f, len) {
            if (len === void 0) { len = 10; }
            var times = [];
            var avg = function (v) {
                var sum = 0;
                v.forEach(function (x) { return sum += x; });
                return Math.round(sum / v.length * 100) / 100;
            };
            var report = function (m) {
                if (m === void 0) { m = ""; }
                times.sort(function (a, b) { return a - b; });
                var t = times.slice(0, Math.round(0.7 * times.length));
                var sum = 0;
                t.forEach(function (v) { return sum += v; });
                var sum2 = 0;
                times.forEach(function (v) { return sum2 += v; });
                Util.log("iter {0}; {2}ms (with drop {1}; otherwise {3}ms) [{5}] {4}", times.length, times.length - t.length, avg(t), avg(times), m, times.map(function (v) { return Math.round(v); }).join(", "));
            };
            var tot = 0;
            for (var i = 0; i < len; ++i) {
                var st = Util.perfNow();
                f();
                var tm = Util.perfNow() - st;
                tot += tm;
                times.push(tm);
                if (tot > 1000) {
                    report();
                    tot = 0;
                }
            }
            report("done");
        }
        Util.timeSeries = timeSeries;
        function time(msg, f, dontDoIt) {
            if (dontDoIt === void 0) { dontDoIt = false; }
            if (dontDoIt)
                f();
            else {
                var ts = TDev.RT.Perf.start(msg);
                f();
                TDev.RT.Perf.stop(ts);
            }
        }
        Util.time = time;
        function now() {
            return Date.now();
        }
        Util.now = now;
        Util.startupTime = now();
        Util.perfNow;
        Util.externalLog = null;
        Util.remoteLogEndpoint = "";
        var remoteLogConnection = null;
        var remoteLogConnecting = false;
        function handleRemoteLog(m) {
            if (!Util.remoteLogEndpoint)
                return;
            if (!remoteLogConnecting) {
                remoteLogConnecting = true;
                var conn = new WebSocket(Util.remoteLogEndpoint);
                conn.onopen = function () {
                    console.log("Remote log connection opened");
                    remoteLogConnection = conn;
                    getLogMsgs().forEach(function (m) { return conn.send(m.elapsed + ": " + m.msg); });
                };
                conn.onclose = function () {
                    console.log("Remote log connection closed");
                    remoteLogConnection = null;
                };
                conn.onerror = function () {
                    console.log("Remote log connection error");
                    remoteLogConnection = null;
                };
            }
            if (remoteLogConnection)
                remoteLogConnection.send(m);
        }
        function log(f) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            var msg = fmt_va(f, args);
            var n = now();
            var diff = (now() - Util.startupTime) / 1000;
            var m = fmt_va("{0:f04.3}: {1}", [diff, msg]);
            var lm = {
                timestamp: n,
                level: /^log:/.test(f) ? 6 : /^crash/i.test(f) ? 3 : 7,
                category: "tdlog",
                msg: msg
            };
            if (logIdx >= 0) {
                logMsgs[logIdx++] = lm;
                if (logIdx >= Util.logSz)
                    logIdx = 0;
            }
            else {
                logMsgs.push(lm);
                if (logMsgs.length >= Util.logSz)
                    logIdx = 0;
            }
            if (!/^(DBG|TICK): /.test(f))
                TDev.Ticker.tick(454 /* dbgLogEvent */, msg.slice(0, 200));
            if (TDev.Browser.cscript) {
            }
            else if (TDev.Browser.useConsoleLog) {
                if (TDev.isWebWorker)
                    console.log("WORK-TD-LOG: " + m);
                else
                    console.log("TD-LOG: " + m);
            }
            if (TDev.Browser.logToHost)
                Util.externalNotify("LOG: " + m);
            handleRemoteLog(m);
            if (Util.externalLog)
                Util.externalLog(m);
            if (!TDev.Browser.loadingDone && /debugMsg/.test(document.URL)) {
                var e = TDev.elt("statusMsg");
                if (e)
                    TDev.Browser.setInnerHTML(e, Util.formatText(m) + "</br>" + e.innerHTML);
            }
        }
        Util.log = log;
        Util.dbglog = log;
        function elapsed(start, end) {
            return ("00000000" + (end - start)).slice(-7).replace(/(\d\d\d)$/, function (k) { return "." + k; });
        }
        Util.elapsed = elapsed;
        function getLogMsgs() {
            var i = logIdx;
            var res = [];
            var wrapped = false;
            if (i < 0)
                i = 0;
            var n = now();
            while (i < logMsgs.length) {
                var c = Util.clone(logMsgs[i]);
                c.elapsed = Util.elapsed(c.timestamp, n);
                res.push(c);
                if (++i == logMsgs.length && !wrapped) {
                    wrapped = true;
                    i = 0;
                }
                if (wrapped && i >= logIdx)
                    break;
            }
            return res;
        }
        Util.getLogMsgs = getLogMsgs;
        function externalNotify(msg) {
            var w = window;
            if (w && w.external && "notify" in w.external)
                w.external.notify(msg);
        }
        Util.externalNotify = externalNotify;
        function showLog(ld) {
            Util.log("show log");
            var res = getLogMsgs().map(function (m) { return "<div class='logMsg'>" + Util.formatText(m.msg) + "</div>\n"; });
            res.reverse();
            TDev.Browser.setInnerHTML(ld, res.join(""));
        }
        Util.showLog = showLog;
        function jsonEq(a, b) {
            switch (typeof a) {
                case "string":
                case "number":
                case "boolean":
                    return a === b;
            }
            if (a === b)
                return true;
            if (a === null || a === undefined || b === null || b === undefined)
                return false;
            if (Array.isArray(a)) {
                if (Array.isArray(b)) {
                    if (a.length != b.length)
                        return false;
                    for (var i = 0; i < a.length; ++i)
                        if (!jsonEq(a[i], b[i]))
                            return false;
                    return true;
                }
                else
                    return false;
            }
            for (var p in b)
                if (b.hasOwnProperty(p) && !a.hasOwnProperty(p))
                    return false;
            for (var p in a) {
                if (a.hasOwnProperty(p)) {
                    if (!b.hasOwnProperty(p))
                        return false;
                    if (!jsonEq(a[p], b[p]))
                        return false;
                }
            }
            return true;
        }
        Util.jsonEq = jsonEq;
        function range(from, length) {
            var res = [];
            for (var i = 0; i < length; ++i)
                res.push(i + from);
            return res;
        }
        Util.range = range;
        function iterHtml(e, f) {
            if (!(e instanceof HTMLElement))
                return;
            if (f(e))
                return;
            for (var i = 0; i < e.childNodes.length; ++i) {
                var node = e.childNodes[i];
                iterHtml(node, f);
            }
        }
        Util.iterHtml = iterHtml;
        function highlightWords(e, terms, keepCache) {
            if (keepCache === void 0) { keepCache = false; }
            if (e instanceof Text) {
                var d = e.data;
                var lc = d.toLowerCase();
                var res = [];
                var prev = 0;
                for (var i = 0; i < lc.length; ++i) {
                    for (var j = 0; j < terms.length; ++j) {
                        if (terms[j].length == 0)
                            continue;
                        if (lc.slice(i, i + terms[j].length) == terms[j]) {
                            var t0 = document.createTextNode(d.slice(prev, i));
                            var t1 = TDev.span("highlight", d.slice(i, i + terms[j].length));
                            res.push(t0);
                            res.push(t1);
                            i += terms[j].length;
                            prev = i;
                            i--;
                            break;
                        }
                    }
                }
                if (prev == 0)
                    return;
                res.push(document.createTextNode(d.slice(prev, d.length)));
                var par = e.parentNode;
                if (keepCache && !par.originalCache)
                    par.originalCache = par.innerHTML;
                e.parentNode.replaceChild(TDev.span(null, res), e);
            }
            else if (e instanceof HTMLElement) {
                var ee = e;
                if (keepCache && ee.originalCache)
                    ee.innerHTML = ee.originalCache;
                for (var i = 0; i < e.childNodes.length; ++i) {
                    var node = e.childNodes[i];
                    highlightWords(node, terms);
                }
            }
        }
        Util.highlightWords = highlightWords;
        function animationProperty() {
            if (TDev.Browser.isWebkit)
                return "webkitAnimation";
            if (TDev.Browser.isGecko)
                return "MozAnimation";
            return "animation";
        }
        Util.animationProperty = animationProperty;
        function cancelAnim(elt) {
            elt.style[animationProperty()] = "";
        }
        Util.cancelAnim = cancelAnim;
        function coreAnim(name, duration, elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            var remove = function () {
                elt.removeSelf();
            };
            if (TDev.Browser.noAnimations) {
                if (/^fadeOut/.test(name)) {
                    elt.style.opacity = "0";
                    if (!andThen)
                        andThen = remove;
                }
                if (andThen)
                    Util.setTimeout(300, function () { return andThen(); });
                return;
            }
            var evtName = TDev.Browser.isWebkit ? "webkitAnimationEnd" : "animationend";
            var propName = animationProperty();
            var oldOpacity = elt.style.opacity;
            var callbackExecuted = false;
            var f = Util.catchErrors("animationEnd " + name, function () {
                if (callbackExecuted)
                    return;
                callbackExecuted = true;
                window.clearTimeout(id);
                elt.removeEventListener(evtName, f);
                elt.style[propName] = "";
                elt.style.opacity = oldOpacity;
                if (andThen)
                    andThen();
            });
            var id = Util.setTimeout(duration + 300, f);
            elt.addEventListener(evtName, f);
            if (/^fadeOut/.test(name)) {
                elt.style.opacity = "0";
                if (!andThen)
                    andThen = remove;
            }
            elt.style[propName] = name + " " + duration + "ms";
            return elt;
        }
        Util.coreAnim = coreAnim;
        function delayButton(b, time, blink) {
            if (time === void 0) { time = 3000; }
            if (blink === void 0) { blink = false; }
            b.style.opacity = "0";
            b.style.visibility = "hidden";
            Util.setTimeout(time, function () {
                b.style.visibility = "";
                Util.fadeIn(b, function () {
                    b.style.opacity = '1';
                    if (blink)
                        Util.setTimeout(2000, function () { return Util.coreAnim("blinkLocation", 4000, b); });
                });
            });
            return b;
        }
        Util.delayButton = delayButton;
        function animAsync(name, duration, elt) {
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                coreAnim(name, duration, elt, function () { return onSuccess(null); });
            });
        }
        Util.animAsync = animAsync;
        var easeOut = " cubic-bezier(0.1, 0.9, 0.2, 1)";
        function showPopup(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("showPopup" + easeOut, 300, elt, andThen);
        }
        Util.showPopup = showPopup;
        function hidePopup(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("fadeOut", 100, elt, andThen);
        }
        Util.hidePopup = hidePopup;
        function fadeIn(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("fadeIn", 150, elt, andThen);
        }
        Util.fadeIn = fadeIn;
        function fadeOut(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("fadeOut", 150, elt, andThen);
        }
        Util.fadeOut = fadeOut;
        function showLeftPanel(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("showLeftPanel" + easeOut, 250, elt, andThen);
        }
        Util.showLeftPanel = showLeftPanel;
        function showRightPanel(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("showRightPanel" + easeOut, 250, elt, andThen);
        }
        Util.showRightPanel = showRightPanel;
        function showBottomPanel(elt, andThen) {
            if (andThen === void 0) { andThen = undefined; }
            return coreAnim("showBottomPanel" + easeOut, 150, elt, andThen);
        }
        Util.showBottomPanel = showBottomPanel;
        function stopEvent() {
            var e = this;
            e.stopPropagation();
            e.preventDefault();
            return false;
        }
        function geckoKeyName(code) {
            switch (code) {
                case 0x0D: return "Enter";
                case 0x21: return "PageUp";
                case 0x22: return "PageDown";
                case 0x23: return "End";
                case 0x24: return "Home";
                case 0x25: return "Left";
                case 0x26: return "Up";
                case 0x27: return "Right";
                case 0x28: return "Down";
                case 0x2D: return "Insert";
                case 0x2E: return "Del";
                case 0x08: return "Backspace";
                case 0x11: return "Control";
                default: return null;
            }
        }
        function normalizeKeyEvent(e) {
            var keyName = e.key;
            if (e.keyIdentifier)
                keyName = e.keyIdentifier;
            switch (e.keyCode) {
                case 27:
                    keyName = "Esc";
                    break;
                case 9:
                    keyName = "Tab";
                    break;
                case 32:
                    keyName = "Space";
                    break;
                default:
                    if (TDev.Browser.isGecko && geckoKeyName(e.keyCode)) {
                        keyName = geckoKeyName(e.keyCode);
                    }
                    else {
                        var s = String.fromCharCode(e.keyCode);
                        if (/^[A-Z0-9]$/.test(s))
                            keyName = s;
                    }
                    break;
            }
            switch (keyName) {
                case "U+007F":
                    if (!e.charCode)
                        keyName = "Del";
                    break;
                case "U+0008":
                    keyName = "Backspace";
                    break;
                case "U+0020":
                    keyName = "Space";
                    break;
                case "Insert":
                    keyName = "Ins";
                    break;
                case "PageDown":
                    keyName = "PgDn";
                    break;
                case "PageUp":
                    keyName = "PgUp";
                    break;
            }
            if (e.altKey)
                keyName = "Alt-" + keyName;
            if (e.ctrlKey)
                keyName = "Ctrl-" + keyName;
            if (e.shiftKey)
                keyName = "Shift-" + keyName;
            e.keyName = keyName;
            var srcElt = e.srcElement;
            if (!srcElt)
                srcElt = e.originalTarget;
            try {
                var srcType = !srcElt ? "" : srcElt.type;
                e.fromTextBox = e.fromTextBox || srcType == "text" || srcType == "textarea" || srcElt.className == "wall-textbox";
                e.fromTextArea = e.fromTextArea || srcType == "textarea";
            }
            catch (e) {
            }
            if (srcElt && e.fromTextBox)
                TDev.LayoutMgr.instance.FlagTypingActivity(srcElt.getAttribute("id"));
            e.stopIt = stopEvent;
        }
        Util.normalizeKeyEvent = normalizeKeyEvent;
        function keyEventString(e, additionalChars) {
            if (additionalChars === void 0) { additionalChars = ""; }
            if (!e.fromTextBox) {
                var s = String.fromCharCode(e.charCode);
                if (/^[A-Za-z0-9]$/.test(s) || additionalChars.indexOf(s) >= 0)
                    return s;
            }
            return "";
        }
        Util.keyEventString = keyEventString;
        function onInputChange(e, f) {
            var current = e.value;
            e.addEventListener("input", function () {
                if (e.value != current) {
                    current = e.value;
                    f(current);
                }
            });
        }
        Util.onInputChange = onInputChange;
        function boundTo(low, x, high) {
            if (x < low)
                x = low;
            if (x > high)
                x = high;
            return x;
        }
        Util.boundTo = boundTo;
        function between(low, x, high) {
            return boundTo(low, x, high);
        }
        Util.between = between;
        function intBetween(low, x, high) {
            return Math.round(boundTo(low, x, high));
        }
        Util.intBetween = intBetween;
        function fmt_va(f, args) {
            if (args.length == 0)
                return f;
            return f.replace(/\{([0-9]+)(\:[^\}]+)?\}/g, function (s, n, spec) {
                var v = args[parseInt(n)];
                var r = "";
                var fmtMatch = /^:f(\d*)\.(\d+)/.exec(spec);
                if (fmtMatch) {
                    var precision = parseInt(fmtMatch[2]);
                    var len = parseInt(fmtMatch[1]) || 0;
                    var fillChar = /^0/.test(fmtMatch[1]) ? "0" : " ";
                    var num = v.toFixed(precision);
                    if (len > 0 && precision > 0)
                        len += precision + 1;
                    if (len > 0) {
                        while (num.length < len) {
                            num = fillChar + num;
                        }
                    }
                    r = num;
                }
                else if (spec == ":x") {
                    r = "0x" + v.toString(16);
                }
                else if (v === undefined)
                    r = "(undef)";
                else if (v === null)
                    r = "(null)";
                else if (v.toString)
                    r = v.toString();
                else
                    r = v + "";
                if (spec == ":a") {
                    if (/^\s*[euioah]/.test(r.toLowerCase()))
                        r = "an " + r;
                    else if (/^\s*[bcdfgjklmnpqrstvwxz]/.test(r.toLowerCase()))
                        r = "a " + r;
                }
                else if (spec == ":s") {
                    if (v == 1)
                        r = "";
                    else
                        r = "s";
                }
                else if (spec == ":q") {
                    r = Util.htmlEscape(r);
                }
                else if (spec == ":jq") {
                    r = Util.jsStringQuote(r);
                }
                else if (spec == ":uri") {
                    r = encodeURIComponent(r).replace(/'/g, "%27").replace(/"/g, "%22");
                }
                else if (spec == ":url") {
                    r = encodeURI(r).replace(/'/g, "%27").replace(/"/g, "%22");
                }
                else if (spec == ":%") {
                    r = (v * 100).toFixed(1).toString() + '%';
                }
                return r;
            });
        }
        Util.fmt_va = fmt_va;
        function fmt(f) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            return fmt_va(f, args);
        }
        Util.fmt = fmt;
        function ensureVisible(node, parent, margin) {
            if (parent === void 0) { parent = undefined; }
            if (margin === void 0) { margin = undefined; }
            if (!parent) {
                parent = node.parentNode;
                if (!parent)
                    return;
                while (!parent.scrollEnabled) {
                    parent = parent.parentNode;
                    if (!parent)
                        return;
                }
            }
            if (!margin)
                margin = 5;
            if (margin < 1)
                margin = parent.clientHeight * margin;
            var pos = offsetIn(node, parent);
            var y0 = pos.y;
            var y1 = pos.y + node.offsetHeight;
            var target = parent.scrollTop;
            if (target < y1 - parent.clientHeight + margin)
                target = y1 - parent.clientHeight + margin;
            if (target > y0 - margin)
                target = y0 - margin;
            parent.scrollTop = target;
            if (TDev.Browser.isMobileSafari)
                Util.setTimeout(500, function () {
                    parent.scrollTop = target;
                });
        }
        Util.ensureVisible = ensureVisible;
        function flatClone(obj) {
            var r = {};
            Object.keys(obj).forEach(function (k) {
                r[k] = obj[k];
            });
            return r;
        }
        Util.flatClone = flatClone;
        function sendErrorReport(bug, willReload) {
            if (willReload === void 0) { willReload = false; }
            try {
                var bb = Util.flatClone(bug);
                bb.eventTrace = "";
                Util.log(TDev.Ticker.bugReportToString(bb));
            }
            catch (e) {
                debugger;
            }
            TDev.Cloud.postBugReportAsync(bug).done(function () {
            }, function (e) { return undefined; });
        }
        Util.sendErrorReport = sendErrorReport;
        var recentBugReports = {};
        function sendPendingBugReports() {
            var b = window.localStorage["storedBug"];
            if (b) {
                window.localStorage.removeItem("storedBug");
                try {
                    sendErrorReport(JSON.parse(b));
                }
                catch (e) {
                    debugger;
                }
            }
        }
        Util.sendPendingBugReports = sendPendingBugReports;
        Util.navigatingAway = false;
        function navigateInWindow(url) {
            window.location.href = url;
            Util.navigatingAway = true;
        }
        Util.navigateInWindow = navigateInWindow;
        function navigateNewWindow(url) {
            TDev.RT.Web.browseAsync(url).done();
        }
        Util.navigateNewWindow = navigateNewWindow;
        function isError(err, f) {
            return err && (f(err) || (typeof err == "object" && Object.keys(err).some(function (k) { return err[k] && f(err[k]); })));
        }
        Util.isError = isError;
        function getErrorInfo(err) {
            var res = undefined;
            if (err) {
                if (err.constructor && err.code != undefined)
                    res = err.constructor.name + " code " + err.code + ": " + err.message;
                else if (err.name)
                    res = err.name;
                else if (typeof err == "object")
                    Object.keys(err).forEach(function (k) {
                        if (res == undefined)
                            res = getErrorInfo(err[k]);
                    });
                if (err.databaseOrigin)
                    res += "; origin: " + err.databaseOrigin;
            }
            return res;
        }
        Util.getErrorInfo = getErrorInfo;
        function reportError(ctx, err, fatal) {
            if (fatal === void 0) { fatal = true; }
            if (TDev.Runtime.handleUserError(err))
                return;
            var bug = TDev.Ticker.mkBugReport(err, ctx);
            var willReload = fatal;
            var lastBugReload = window.localStorage["lastBugReload"];
            if (lastBugReload && now() - lastBugReload < 30 * 1000)
                willReload = false;
            if (now() - Util.startupTime < 30 * 1000)
                willReload = false;
            if (TDev.dbg)
                willReload = false;
            if (isError(err, function (e) { return e.isNetworkError; })) {
                willReload = false;
                if (err && err.status === 424)
                    TDev.HTML.showProgressNotification(lf("we're having problems, try again later..."));
                else {
                    TDev.HTML.showProgressNotification(lf("we're having network problems..."));
                    return;
                }
            }
            var hashBug = TDev.Ticker.bugReportForHash(bug);
            var lastTime = recentBugReports[hashBug];
            if (lastTime && now() - lastTime < 5 * 60 * 1000) {
            }
            else {
                sendErrorReport(bug, willReload);
                if (Object.keys(recentBugReports).length > 30)
                    recentBugReports = {};
                recentBugReports[hashBug] = now();
            }
            if (isError(err, function (e) { return e.isDatabaseError; })) {
                if (false) {
                    var m = TDev.ModalDialog.info("", "");
                }
                if (!willReload) {
                    Util.navigateInWindow(window.errorUrl + "#storage," + encodeURIComponent(getErrorInfo(err)));
                    return;
                }
            }
            if (willReload && !TDev.Storage.showTemporaryWarning()) {
                try {
                    TDev.ProgressOverlay.show(lf("Whoops! Something went wrong."));
                    TDev.ProgressOverlay.setProgress("");
                    TDev.ProgressOverlay.setAddInfo([
                        TDev.div(null, lf("We're reloading the page.")),
                        TDev.div("item-subtle", lf("Technical information: {0}", bug.exceptionMessage || "None"))
                    ]);
                }
                catch (e) {
                    debugger;
                }
                Util.setTimeout(3000, function () {
                    window.location.reload();
                });
                return;
            }
            try {
                if (fatal || TDev.dbg) {
                    var msgText = Util.formatText(TDev.dbg ? bug.exceptionMessage : "Something went wrong; please reload the webpage.");
                    var dmsg = TDev.div("errorNotification");
                    TDev.Browser.setInnerHTML(dmsg, msgText);
                    TDev.elt("root").appendChild(dmsg);
                    Util.setTimeout(5000, function () {
                        dmsg.removeSelf();
                    });
                }
            }
            catch (e) {
                debugger;
            }
        }
        Util.reportError = reportError;
        function catchErrors(ctx, f) {
            return function () {
                if (Util.eventLogging)
                    Util.log("catching errors in " + ctx);
                try {
                    return f.apply(this, arguments);
                }
                catch (e) {
                    if (TDev.Browser.isHeadless)
                        TDev.Promise.errorHandler(ctx, e);
                    else
                        reportError(ctx, e);
                    return undefined;
                }
            };
        }
        Util.catchErrors = catchErrors;
        function setTimeout(ms, cb) {
            if (ms == 0 && zeroTimeoutFunctions) {
                setZeroTimeout(cb);
                return -1;
            }
            else {
                return window.setTimeout(function () {
                    if (Util.eventLogging)
                        Util.log("executing timeout " + ms + " / " + cb.toString());
                    try {
                        cb();
                    }
                    catch (err) {
                        Util.reportError("timeout-" + ms + "-" + cb.toString(), err);
                    }
                }, ms);
            }
        }
        Util.setTimeout = setTimeout;
        var FNV1_prime_32 = 16777619;
        var FNV1_basis_32 = 2166136261 | 0;
        function toUTF16LE(str) {
            var res = "";
            if (!str)
                return res;
            for (var i = 0; i < str.length; ++i) {
                var code = str.charCodeAt(i);
                res += String.fromCharCode(code & 0xff);
                res += String.fromCharCode((code >> 8) & 0xff);
            }
            return res;
        }
        Util.toUTF16LE = toUTF16LE;
        function fromUTF8Bytes(binstr) {
            if (!binstr)
                return "";
            var escaped = "";
            for (var i = 0; i < binstr.length; ++i) {
                var k = binstr[i] & 0xff;
                if (k == 37 || k > 0x7f) {
                    escaped += "%" + k.toString(16);
                }
                else {
                    escaped += String.fromCharCode(k);
                }
            }
            return decodeURIComponent(escaped);
        }
        Util.fromUTF8Bytes = fromUTF8Bytes;
        function fromUTF8(binstr) {
            if (!binstr)
                return "";
            var escaped = "";
            for (var i = 0; i < binstr.length; ++i) {
                var k = binstr.charCodeAt(i) & 0xff;
                if (k == 37 || k > 0x7f) {
                    escaped += "%" + k.toString(16);
                }
                else {
                    escaped += binstr.charAt(i);
                }
            }
            return decodeURIComponent(escaped);
        }
        Util.fromUTF8 = fromUTF8;
        function toUTF8(str) {
            var res = "";
            if (!str)
                return res;
            for (var i = 0; i < str.length; ++i) {
                var code = str.charCodeAt(i);
                if (code <= 0x7f)
                    res += str.charAt(i);
                else if (code <= 0x7ff) {
                    res += String.fromCharCode(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
                }
                else {
                    if (0xd800 <= code && code <= 0xdbff) {
                        var next = str.charCodeAt(++i);
                        if (!isNaN(next))
                            code = 0x10000 + ((code - 0xd800) << 10) + (next - 0xdc00);
                    }
                    if (code <= 0xffff)
                        res += String.fromCharCode(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
                    else
                        res += String.fromCharCode(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 0x3f), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
                }
            }
            return res;
        }
        Util.toUTF8 = toUTF8;
        function intMult(a, b) {
            return (((a & 0xffff) * (b >>> 16) + (b & 0xffff) * (a >>> 16)) << 16) + ((a & 0xffff) * (b & 0xffff));
        }
        Util.intMult = intMult;
        function getStableHashCodeBytes(bytes) {
            var hc = FNV1_basis_32;
            if (bytes) {
                for (var i = 0; i < bytes.length; ++i)
                    hc = intMult(hc, FNV1_prime_32) ^ bytes.charCodeAt(i);
            }
            return hc;
        }
        Util.getStableHashCodeBytes = getStableHashCodeBytes;
        function getStableHashCode(str) {
            return getStableHashCodeBytes(toUTF16LE(str));
        }
        Util.getStableHashCode = getStableHashCode;
        function isntNull(o) {
            return o !== null && o !== undefined;
        }
        Util.isntNull = isntNull;
        function capitalizeFirst(s) {
            return s.slice(0, 1).toUpperCase() + s.slice(1);
        }
        Util.capitalizeFirst = capitalizeFirst;
        function tagify(name) {
            return name.replace(/([^a-zA-Z0-9])([a-z])/g, function (m, a, b) { return a + b.toUpperCase(); }).replace(/[^a-zA-Z0-9]/g, "");
        }
        Util.tagify = tagify;
        function toHashTag(name) {
            return "#" + tagify(name);
        }
        Util.toHashTag = toHashTag;
        function getHashTags(s) {
            var r = [];
            s.replace(/#(\w+)/g, function (m, h) {
                r.push(h);
                return "";
            });
            return r;
        }
        Util.getHashTags = getHashTags;
        function jsStringQuote(s) {
            return s.replace(/[^A-Z0-9a-z .!?_\-$]/g, function (c) {
                var h = c.charCodeAt(0).toString(16);
                return "\\u" + "0000".substr(0, 4 - h.length) + h;
            });
        }
        Util.jsStringQuote = jsStringQuote;
        function jsStringLiteral(s) {
            return "\"" + jsStringQuote(s) + "\"";
        }
        Util.jsStringLiteral = jsStringLiteral;
        function canvasToBlob(canvas, blobName) {
            if (blobName === void 0) { blobName = null; }
            if (canvas.mozGetAsFile) {
                var blob = canvas.mozGetAsFile(blobName || 'img.png', 'image/png');
                return blob;
            }
            if (canvas.msToBlob)
                return canvas.msToBlob();
            var dataUrl = canvas.toDataURL('image/png');
            var bytes = decodeDataURL(dataUrl, 'image/png');
            try {
                var blob = new Blob([bytes], { type: 'image/png' });
                return blob;
            }
            catch (e) {
                return null;
            }
        }
        Util.canvasToBlob = canvasToBlob;
        function stringCompare(an, bn) {
            if (an == bn)
                return 0;
            if (an < bn)
                return -1;
            return 1;
        }
        Util.stringCompare = stringCompare;
        function nameCompare(a, b) {
            return stringCompare(a.getName(), b.getName());
        }
        Util.nameCompare = nameCompare;
        function jsonClone(obj) {
            return JSON.parse(JSON.stringify(obj));
        }
        Util.jsonClone = jsonClone;
        function jsonCopyFrom(trg, src) {
            var v = jsonClone(src);
            Object.keys(src).forEach(function (k) {
                trg[k] = v[k];
            });
        }
        Util.jsonCopyFrom = jsonCopyFrom;
        function clone(obj) {
            var r = new obj.constructor;
            for (var k in obj) {
                if (obj.hasOwnProperty(k))
                    r[k] = obj[k];
            }
            return r;
        }
        Util.clone = clone;
        function chopArray(arr, chunkSize) {
            var res = [];
            for (var i = 0; i < arr.length; i += chunkSize)
                res.push(arr.slice(i, i + chunkSize));
            return res;
        }
        Util.chopArray = chopArray;
        function unique(arr, f) {
            var v = [];
            var r = {};
            arr.forEach(function (e) {
                var k = f(e);
                if (!r.hasOwnProperty(k)) {
                    r[k] = null;
                    v.push(e);
                }
            });
            return v;
        }
        Util.unique = unique;
        function groupBy(arr, f) {
            var r = {};
            arr.forEach(function (e) {
                var k = f(e);
                if (!r.hasOwnProperty(k))
                    r[k] = [];
                r[k].push(e);
            });
            return r;
        }
        Util.groupBy = groupBy;
        function toDictionary(arr, f) {
            var r = {};
            arr.forEach(function (e) {
                r[f(e)] = e;
            });
            return r;
        }
        Util.toDictionary = toDictionary;
        function toArray(a) {
            var r = [];
            for (var i = 0; i < a.length; ++i)
                r.push(a[i]);
            return r;
        }
        Util.toArray = toArray;
        function indexOfMatching(arr, f) {
            for (var i = 0; i < arr.length; ++i)
                if (f(arr[i]))
                    return i;
            return -1;
        }
        Util.indexOfMatching = indexOfMatching;
        function memoize(f) {
            var cache = {};
            return function (s) {
                if (cache.hasOwnProperty(s))
                    return cache[s];
                return (cache[s] = f(s));
            };
        }
        Util.memoize = memoize;
        function memoizeHashed(h, f) {
            var cache = {};
            return function (e) {
                var s = h(e);
                if (cache.hasOwnProperty(s))
                    return cache[s];
                return (cache[s] = f(e));
            };
        }
        Util.memoizeHashed = memoizeHashed;
        function even(arr) {
            var r = [];
            for (var i = 0; i < arr.length; i += 2)
                r.push(arr[i]);
            return r;
        }
        Util.even = even;
        function odd(arr) {
            var r = [];
            for (var i = 1; i < arr.length; i += 2)
                r.push(arr[i]);
            return r;
        }
        Util.odd = odd;
        function repeatString(s, n) {
            return Array(n + 1).join(s);
        }
        Util.repeatString = repeatString;
        function numberToStringNoE(v) {
            var s = v.toString();
            var m = /^([+\-])?(\d)(\.(\d*))?[eE]([+\-])?(\d+)$/.exec(s);
            if (!m)
                return s;
            var sign = m[1] || "";
            var pref = m[2];
            var suff = m[4] || "";
            var esign = m[5];
            var exp = parseInt(m[6]);
            if (esign == "-") {
                return sign + "0." + repeatString("0", exp - 1) + pref + suff;
            }
            else {
                var add = exp - suff.length;
                if (add < 0) {
                    return sign + pref + suff.slice(0, exp) + "." + suff.slice(add);
                }
                else {
                    return sign + pref + suff + repeatString("0", add);
                }
            }
        }
        Util.numberToStringNoE = numberToStringNoE;
        function msSubtract(a, b) {
            var r = {};
            Object.keys(a).forEach(function (k) {
                var d = 0;
                if (b.hasOwnProperty(k))
                    d = b[k];
                var n = a[k] - d;
                if (n > 0)
                    r[k] = n;
            });
            return r;
        }
        Util.msSubtract = msSubtract;
        function msAdd(a, b) {
            var r = {};
            Object.keys(a).forEach(function (k) {
                var d = 0;
                if (b.hasOwnProperty(k))
                    d = b[k];
                r[k] = a[k] + d;
            });
            Object.keys(b).forEach(function (k) {
                if (!a.hasOwnProperty(k))
                    r[k] = b[k];
            });
            return r;
        }
        Util.msAdd = msAdd;
        function setAdd(a, b) {
            var r = {};
            Object.keys(a).forEach(function (v) { return r[v] = true; });
            Object.keys(b).forEach(function (v) { return r[v] = true; });
            return r;
        }
        Util.setAdd = setAdd;
        function setAddTo(a, b) {
            Object.keys(b).forEach(function (v) { return a[v] = true; });
        }
        Util.setAddTo = setAddTo;
        function setIntersect(a, b) {
            var r = {};
            Object.keys(a).forEach(function (v) {
                if (b.hasOwnProperty(v))
                    r[v] = true;
            });
            return r;
        }
        Util.setIntersect = setIntersect;
        Util.onSetHash;
        Util.onGoBack;
        function setHash(s, replace) {
            if (replace === void 0) { replace = false; }
            Util.log("navigate " + s);
            s = s.replace(/^#/, "");
            Util.setTimeout(1, function () { return Util.onSetHash(s, replace); });
        }
        Util.setHash = setHash;
        function goBack() {
            Util.onGoBack();
        }
        Util.goBack = goBack;
        function toFileName(name, defaultName) {
            name = name || "";
            var filename = name.replace(/[^\w]+/g, " ").trim().replace(/ /g, "-") || defaultName;
            if (!/^\w/.test(filename))
                filename = "_" + filename;
            return filename;
        }
        Util.toFileName = toFileName;
        function mkAbsoluteUrl(relativeUrl) {
            return TDev.Ticker.mainJsName.replace(/main.js$/, "") + relativeUrl;
        }
        Util.mkAbsoluteUrl = mkAbsoluteUrl;
        function localStore(key, data) {
            if (!data)
                window.localStorage.removeItem(key);
            else
                window.localStorage.setItem(key, data);
        }
        Util.localStore = localStore;
        Util.translationDebug = false;
        Util.translations = {};
        function enableTranslationTracking(local) {
            if (local === void 0) { local = false; }
            translationTracker = {};
            if (local) {
                translationScheduled = true;
                Util.localTranslationTracking = true;
            }
        }
        Util.enableTranslationTracking = enableTranslationTracking;
        function dumpTranslationFreqs() {
            var lst = Object.keys(translationTracker);
            lst.sort(function (a, b) { return translationTracker[b] - translationTracker[a]; });
            var words = 0;
            var str = "";
            lst.forEach(function (e) {
                words += e.split(/\s+/).filter(function (s) { return !!s; }).length;
                str += JSON.stringify(e).slice(1).replace(/"$/, "") + "\n";
            });
            str = "# words: " + words + ", texts: " + lst.length + "\n" + str;
            return str;
        }
        Util.dumpTranslationFreqs = dumpTranslationFreqs;
        var translationTracker;
        var lastTranslationUpload = 0;
        var translationScheduled = false;
        var translationSending = false;
        Util.translationToken = "";
        Util.localTranslationTracking = false;
        function scheduleTranslations() {
            translationScheduled = true;
            Util.setTimeout(10000, function () {
                translationScheduled = false;
                translationSending = true;
                var toSend = translationTracker;
                translationTracker = {};
                Util.httpPostRealJsonAsync("https://touchdeveloptranslator.azurewebsites.net/api/Svc/submit", {
                    freqs: toSend,
                    lang: getTranslationLanguage(),
                    token: Util.translationToken,
                }).done(function (resp) {
                    translationSending = false;
                    if (Object.keys(translationTracker).length > 0 && !translationScheduled)
                        scheduleTranslations();
                }, function (err) {
                });
            });
        }
        function _localize(msg, account) {
            if (translationTracker && account) {
                translationTracker[msg] = (translationTracker[msg] || 0) + 1;
                if (!translationScheduled && !translationSending)
                    scheduleTranslations();
            }
            if (Util.translations.hasOwnProperty(msg))
                return Util.translations[msg];
            return msg;
        }
        Util._localize = _localize;
        Util._languageData;
        var translationLang = null;
        function seeTranslatedText(value) {
            if (value !== undefined) {
                if (!value)
                    window.localStorage.setItem("skipTranslatedText", "1");
                else
                    window.localStorage.removeItem("skipTranslatedText");
                return !value;
            }
            else {
                return !window.localStorage.getItem("skipTranslatedText");
            }
        }
        Util.seeTranslatedText = seeTranslatedText;
        function getTranslationLanguage() {
            return translationLang;
        }
        Util.getTranslationLanguage = getTranslationLanguage;
        Util.sForPlural = true;
        function loadUserLanguageSetting() {
            var ln = getUserLanguageSetting();
            if (ln) {
                setTranslationLanguage(ln);
                return true;
            }
            else
                return false;
        }
        Util.loadUserLanguageSetting = loadUserLanguageSetting;
        function getUserLanguageSetting() {
            return window.localStorage.getItem("userLocale") || "";
        }
        Util.getUserLanguageSetting = getUserLanguageSetting;
        function setUserLanguageSetting(culture, reloadIfNeeded) {
            if (reloadIfNeeded === void 0) { reloadIfNeeded = false; }
            var locale = culture || "";
            var currentLocale = getUserLanguageSetting();
            if (currentLocale != locale) {
                window.localStorage.setItem("userLocale", locale);
                seeTranslatedText(true);
                if (reloadIfNeeded && !TDev.Storage.temporary)
                    Util.setTimeout(500, function () { return window.location.reload(); });
            }
        }
        Util.setUserLanguageSetting = setUserLanguageSetting;
        function setTranslationLanguage(ln) {
            var m = /^([a-z]{2,})(-([a-z]{2,}))$/i.exec(ln);
            if (m) {
                ln = m[1].toLowerCase();
                if (m[2])
                    ln += '-' + m[3].toUpperCase();
            }
            var ln2 = ln.slice(0, 2);
            if (ln2 == "zh") {
                if (ln == "zh-TW" || ln == "zh-HK")
                    ln = "zh-CHT";
                else
                    ln = "zh-CHS";
            }
            if (TDev.Cloud.config.primaryLocale.slice(0, 2) == ln) {
                ln = TDev.Cloud.config.primaryLocale;
            }
            Util.sForPlural = ln2 == "en" || ln2 == "es" || ln2 == "pt" || ln2 == "de" || ln2 == "fr";
            Util.translations = {};
            translationLang = ln2;
            if (Util._languageData) {
                if (Util._languageData(ln))
                    translationLang = ln;
                else
                    Util._languageData(ln2);
            }
        }
        Util.setTranslationLanguage = setTranslationLanguage;
        function setTranslationTable(tr) {
            Util.translations = tr;
        }
        Util.setTranslationTable = setTranslationTable;
        function _setLanguageArray(keys, trans) {
            Util.translations = {};
            trans.forEach(function (t, i) {
                if (t)
                    Util.translations[keys[i]] = t;
            });
        }
        Util._setLanguageArray = _setLanguageArray;
    })(Util = TDev.Util || (TDev.Util = {}));
    var numStatic = 1;
    function lf_static(format, account) {
        if (Util.translationDebug)
            return Util._localize(format, account).toUpperCase();
        else
            return Util._localize(format, account);
    }
    TDev.lf_static = lf_static;
    function lf_va(format, args) {
        var lfmt = Util._localize(format, true);
        if (!Util.sForPlural && lfmt != format && /\d:s\}/.test(lfmt)) {
            lfmt = lfmt.replace(/\{\d+:s\}/g, "");
        }
        if (Util.translationDebug)
            return Util.fmt_va(lfmt, args).toUpperCase();
        else
            return Util.fmt_va(lfmt, args);
    }
    TDev.lf_va = lf_va;
    function lf(format) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return lf_va(format, args);
    }
    TDev.lf = lf;
    var Lock = (function () {
        function Lock() {
            this.waiting = [];
            this.acquired = false;
        }
        Lock.prototype.acquire = function (f) {
            if (this.acquired) {
                this.waiting.push(f);
            }
            else {
                this.acquired = true;
                f();
            }
        };
        Lock.prototype.release = function () {
            Util.assert(this.acquired);
            if (this.waiting.length > 0) {
                var f = this.waiting.shift();
                f();
            }
            else {
                this.acquired = false;
            }
        };
        return Lock;
    })();
    TDev.Lock = Lock;
    var RefreshTimer = (function () {
        function RefreshTimer(interval, callback) {
            this.interval = interval;
            this.callback = callback;
            this.tick = 0;
        }
        RefreshTimer.prototype.restart = function () {
            var _this = this;
            this.tick++;
            var tick0 = this.tick;
            Util.setTimeout(this.interval, function () {
                if (tick0 == _this.tick) {
                    _this.callback();
                }
            });
        };
        return RefreshTimer;
    })();
    TDev.RefreshTimer = RefreshTimer;
    var KeyboardAutoUpdate = (function () {
        function KeyboardAutoUpdate(read, update) {
            this.read = read;
            this.update = update;
            this.version = 0;
            this.lastValue = null;
            this.updateValue = null;
            this.delay = TDev.Browser.isDesktop ? 300 : TDev.Browser.isCellphone ? 800 : 500;
        }
        KeyboardAutoUpdate.createInput = function (placeholder, update) {
            var up = KeyboardAutoUpdate.mkInput(TDev.HTML.mkTextInput("text", placeholder), update);
            up.attach();
            return up;
        };
        KeyboardAutoUpdate.mkInput = function (textbox, update) {
            var kb = new KeyboardAutoUpdate(function () { return textbox.value; }, update);
            kb.element = textbox;
            return kb;
        };
        KeyboardAutoUpdate.mkTextArea = function (textbox, update) {
            var kb = new KeyboardAutoUpdate(function () { return textbox.value; }, update);
            kb.element = textbox;
            return kb;
        };
        KeyboardAutoUpdate.prototype.attach = function () {
            var _this = this;
            Util.onInputChange(this.element, function () { return _this.keypress(); });
        };
        KeyboardAutoUpdate.prototype.keypress = function () {
            var _this = this;
            var searchValue = this.read();
            if (searchValue == this.lastValue)
                return;
            var v = ++this.version;
            this.lastValue = searchValue;
            if (!this.update)
                return;
            if (this.delay <= 0) {
                this.update(searchValue);
            }
            else {
                Util.setTimeout(this.delay, function () {
                    if (v == _this.version && _this.update && searchValue == _this.read()) {
                        _this.update(searchValue);
                    }
                });
            }
        };
        KeyboardAutoUpdate.prototype.resultsCurrent = function (s) {
            return this.read() == s;
        };
        return KeyboardAutoUpdate;
    })();
    TDev.KeyboardAutoUpdate = KeyboardAutoUpdate;
    var CsvParser = (function () {
        function CsvParser() {
            this.m_pos = 0;
            this.m_line = 1;
            this.m_col = 1;
            this.space = ' '.charCodeAt(0);
            this.comma = ','.charCodeAt(0);
            this.semiColumn = ';'.charCodeAt(0);
            this.doubleQuote = '"'.charCodeAt(0);
            this.cr = '\r'.charCodeAt(0);
            this.lf = '\n'.charCodeAt(0);
            this.tab = '\t'.charCodeAt(0);
            this.dot = '.'.charCodeAt(0);
            this.backwack = '\\'.charCodeAt(0);
        }
        CsvParser.prototype.parse = function (text, separator) {
            if (!text)
                return null;
            this.m_text = text;
            this.m_errors = [];
            this.file = { headers: [], records: [] };
            this.m_pos = 0;
            this.m_line = 1;
            this.m_col = 1;
            this.m_separator = (separator) ? separator.charCodeAt(0) : 0;
            try {
                if (!this.parseHeader())
                    return null;
                if (this.atEnd())
                    return this.file;
                this.parseRecords();
                return this.file;
            }
            catch (e) {
                return null;
            }
        };
        CsvParser.prototype.atEnd = function () {
            return this.m_text.length == this.m_pos;
        };
        CsvParser.prototype.peek = function () {
            if (this.atEnd())
                return -1;
            return this.m_text.charCodeAt(this.m_pos);
        };
        CsvParser.prototype.read = function () {
            if (this.atEnd()) {
                this.fail("end of file.");
                throw new Error();
            }
            if (this.m_text.charCodeAt(this.m_pos) === this.lf) {
                this.m_line++;
                this.m_col = 1;
            }
            return this.m_text.charCodeAt(this.m_pos++);
        };
        CsvParser.prototype.expected = function (expectedToken) {
            this.fail("expecting: " + expectedToken);
        };
        CsvParser.prototype.fail = function (message) {
            this.m_errors.push({ line: this.m_line, column: this.m_col, message: message });
        };
        CsvParser.prototype.parseHeader = function () {
            var firstName = this.parseField();
            if (firstName == null)
                return false;
            this.file.headers.push(firstName);
            this.inferSeparator();
            while (this.peek() === this.m_separator) {
                if (!this.parseSeparator())
                    return false;
                var nextName = this.parseField();
                if (nextName == null)
                    return false;
                this.file.headers.push(nextName);
            }
            return this.parseCRLF();
        };
        CsvParser.prototype.inferSeparator = function () {
            if (this.m_separator == 0 && !this.atEnd()) {
                var c = this.peek();
                if (c == this.comma || c == this.semiColumn || c == this.tab)
                    this.m_separator = c;
            }
        };
        CsvParser.prototype.parseSeparator = function () {
            var c = this.read();
            if (c != this.m_separator) {
                this.expected(String.fromCharCode(this.m_separator));
                return false;
            }
            this.eatWhitespace();
            return true;
        };
        CsvParser.prototype.eatWhitespace = function () {
            while (!this.atEnd() && this.peek() == this.space)
                this.read();
        };
        CsvParser.prototype.parseCRLF = function () {
            this.eatWhitespace();
            this.eatCR();
            return this.parseLF();
        };
        CsvParser.prototype.parseLF = function () {
            var c = this.read();
            if (c != this.lf) {
                this.expected("<LF>");
                return false;
            }
            return true;
        };
        CsvParser.prototype.eatCR = function () {
            if (!this.atEnd() && this.peek() == this.cr)
                this.read();
        };
        CsvParser.prototype.parseRecords = function () {
            if (!this.parseRecord())
                return false;
            while (!this.atEnd()) {
                if (!this.parseCRLF())
                    return false;
                if (this.atEnd())
                    break;
                if (!this.parseRecord())
                    return false;
            }
            return true;
        };
        CsvParser.prototype.parseRecord = function () {
            var record = [];
            var firstField = this.parseField();
            if (firstField == null)
                return false;
            record.push(firstField);
            this.inferSeparator();
            while (!this.atEnd() && this.peek() === this.m_separator) {
                if (!this.parseSeparator())
                    return false;
                var nextField = this.parseField();
                if (nextField == null)
                    return false;
                record.push(nextField);
            }
            this.file.records.push(record);
            return true;
        };
        CsvParser.prototype.parseField = function () {
            if (this.peek() == this.doubleQuote)
                return this.parseEscaped();
            return this.parseNonescaped();
        };
        CsvParser.prototype.parseNonescaped = function () {
            var data = [];
            while (!this.atEnd() && !this.isSeparatorOrCRLF(this.peek())) {
                data.push(String.fromCharCode(this.read()));
            }
            return data.join('');
        };
        CsvParser.prototype.isSeparatorOrCRLF = function (val) {
            return val === this.m_separator || val === this.cr || val === this.lf;
        };
        CsvParser.isTextData = function (val) {
            return val == 0x20 || val == 0x21 || (val >= 0x23 && val <= 0x2b) || (val >= 0x2D && val <= 0x7e);
        };
        CsvParser.isEscaped = function (val) {
            return CsvParser.isTextData(val) || val == 0x2c || val == 0xD || val == 0xa;
        };
        CsvParser.prototype.parseEscaped = function () {
            var data = [];
            if (!this.parseDoubleQuote())
                return null;
            while (!this.atEnd()) {
                var c = this.read();
                if (c == this.doubleQuote) {
                    if (this.peek() == this.doubleQuote)
                        data.push(String.fromCharCode(this.read()));
                    else
                        break;
                }
                else if (c == this.backwack) {
                    if (this.peek() == this.doubleQuote)
                        data.push(String.fromCharCode(this.read()));
                }
                else
                    data.push(String.fromCharCode(c));
            }
            return data.join('');
        };
        CsvParser.prototype.parseDoubleQuote = function () {
            this.eatWhitespace();
            var c = this.read();
            if (c != this.doubleQuote) {
                this.expected("<DoubleQuote>");
                return false;
            }
            return true;
        };
        return CsvParser;
    })();
    TDev.CsvParser = CsvParser;
    var Set = (function () {
        function Set() {
            this._list = [];
        }
        Set.prototype.add = function (e) {
            if (!this.contains(e))
                this._list.push(e);
        };
        Set.prototype.contains = function (e) {
            return this._list.indexOf(e) >= 0;
        };
        Set.prototype.elts = function () {
            return this._list;
        };
        Set.prototype.length = function () {
            return this._list.length;
        };
        return Set;
    })();
    TDev.Set = Set;
    var Lcs = (function () {
        function Lcs(equal, l1, l2) {
            this.equal = equal;
            this.l1 = l1;
            this.l2 = l2;
            this.table = [];
            for (var i = -1; i < l1.length; ++i)
                this.table[i] = [];
        }
        Lcs.prototype.lcs_m = function (i, j) {
            if (this.table[i][j] !== undefined) {
                return this.table[i][j];
            }
            else {
                var r = this.lcs_i(i, j);
                this.table[i][j] = r;
                return r;
            }
        };
        Lcs.prototype.lcs_i = function (i, j) {
            var c1 = this.l1[i];
            var c2 = this.l2[j];
            if (i == -1 || j == -1) {
                return [];
            }
            else if (this.equal(c1, c2)) {
                return this.lcs_m(i - 1, j - 1).concat([c1]);
            }
            else {
                var lcs1 = i > 0 ? this.lcs_m(i - 1, j) : [];
                var lcs2 = j > 0 ? this.lcs_m(i, j - 1) : [];
                return lcs1.length > lcs2.length ? lcs1 : lcs2;
            }
        };
        Lcs.prototype.lcs = function () {
            return this.lcs_i(this.l1.length - 1, this.l2.length - 1);
        };
        return Lcs;
    })();
    TDev.Lcs = Lcs;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Random;
    (function (Random) {
        var sha256_k = new Uint32Array([
            0x428a2f98,
            0x71374491,
            0xb5c0fbcf,
            0xe9b5dba5,
            0x3956c25b,
            0x59f111f1,
            0x923f82a4,
            0xab1c5ed5,
            0xd807aa98,
            0x12835b01,
            0x243185be,
            0x550c7dc3,
            0x72be5d74,
            0x80deb1fe,
            0x9bdc06a7,
            0xc19bf174,
            0xe49b69c1,
            0xefbe4786,
            0x0fc19dc6,
            0x240ca1cc,
            0x2de92c6f,
            0x4a7484aa,
            0x5cb0a9dc,
            0x76f988da,
            0x983e5152,
            0xa831c66d,
            0xb00327c8,
            0xbf597fc7,
            0xc6e00bf3,
            0xd5a79147,
            0x06ca6351,
            0x14292967,
            0x27b70a85,
            0x2e1b2138,
            0x4d2c6dfc,
            0x53380d13,
            0x650a7354,
            0x766a0abb,
            0x81c2c92e,
            0x92722c85,
            0xa2bfe8a1,
            0xa81a664b,
            0xc24b8b70,
            0xc76c51a3,
            0xd192e819,
            0xd6990624,
            0xf40e3585,
            0x106aa070,
            0x19a4c116,
            0x1e376c08,
            0x2748774c,
            0x34b0bcb5,
            0x391c0cb3,
            0x4ed8aa4a,
            0x5b9cca4f,
            0x682e6ff3,
            0x748f82ee,
            0x78a5636f,
            0x84c87814,
            0x8cc70208,
            0x90befffa,
            0xa4506ceb,
            0xbef9a3f7,
            0xc67178f2
        ]);
        function rotr(v, b) {
            return (v >>> b) | (v << (32 - b));
        }
        function sha256round(hs, w) {
            TDev.Util.assert(hs.length == 8);
            TDev.Util.assert(w.length == 64);
            for (var i = 16; i < 64; ++i) {
                var s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
                var s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
                w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;
            }
            var a = hs[0];
            var b = hs[1];
            var c = hs[2];
            var d = hs[3];
            var e = hs[4];
            var f = hs[5];
            var g = hs[6];
            var h = hs[7];
            for (var i = 0; i < 64; ++i) {
                var s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
                var ch = (e & f) ^ (~e & g);
                var temp1 = (h + s1 + ch + sha256_k[i] + w[i]) | 0;
                var s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
                var maj = (a & b) ^ (a & c) ^ (b & c);
                var temp2 = (s0 + maj) | 0;
                h = g;
                g = f;
                f = e;
                e = (d + temp1) | 0;
                d = c;
                c = b;
                b = a;
                a = (temp1 + temp2) | 0;
            }
            hs[0] += a;
            hs[1] += b;
            hs[2] += c;
            hs[3] += d;
            hs[4] += e;
            hs[5] += f;
            hs[6] += g;
            hs[7] += h;
        }
        function sha256buffer(buf) {
            var h = new Uint32Array(8);
            h[0] = 0x6a09e667;
            h[1] = 0xbb67ae85;
            h[2] = 0x3c6ef372;
            h[3] = 0xa54ff53a;
            h[4] = 0x510e527f;
            h[5] = 0x9b05688c;
            h[6] = 0x1f83d9ab;
            h[7] = 0x5be0cd19;
            var work = new Uint32Array(64);
            var chunkLen = 16 * 4;
            function addBuf(buf) {
                var end = buf.length - (chunkLen - 1);
                for (var i = 0; i < end; i += chunkLen) {
                    for (var j = 0; j < 16; j++) {
                        var off = (j << 2) + i;
                        work[j] = (buf[off] << 24) | (buf[off + 1] << 16) | (buf[off + 2] << 8) | buf[off + 3];
                    }
                    sha256round(h, work);
                }
            }
            addBuf(buf);
            var padSize = 64 - (buf.length + 9) % 64;
            if (padSize == 64)
                padSize = 0;
            var endPos = buf.length - (buf.length % chunkLen);
            var padBuf = new Uint8Array((buf.length - endPos) + 1 + padSize + 8);
            var dst = 0;
            while (endPos < buf.length)
                padBuf[dst++] = buf[endPos++];
            padBuf[dst++] = 0x80;
            while (padSize-- > 0)
                padBuf[dst++] = 0x00;
            var len = buf.length * 8;
            dst = padBuf.length;
            while (len > 0) {
                padBuf[--dst] = len & 0xff;
                len >>= 8;
            }
            addBuf(padBuf);
            var res = "";
            for (var i = 0; i < h.length; ++i)
                res += ("000000000" + h[i].toString(16)).slice(-8);
            return res.toLowerCase();
        }
        Random.sha256buffer = sha256buffer;
        function sha256string(s) {
            return sha256buffer(TDev.Util.stringToUint8Array(TDev.Util.toUTF8(s)));
        }
        Random.sha256string = sha256string;
        var RC4 = (function () {
            function RC4() {
                this.rc4_i = 0;
                this.rc4_j = 0;
                this.rc4_buf = new Uint8Array(256);
                for (var i = 0; i < 256; ++i)
                    this.rc4_buf[i] = i;
            }
            RC4.prototype.getBytes = function (arr) {
                var rc4_i = this.rc4_i;
                var rc4_j = this.rc4_j;
                var rc4_buf = this.rc4_buf;
                for (var i = 0; i < arr.length; ++i) {
                    rc4_i = (rc4_i + 1) & 0xff;
                    rc4_j = (rc4_j + rc4_buf[rc4_i]) & 0xff;
                    var tmp = rc4_buf[rc4_i];
                    var tmp2 = rc4_buf[rc4_j];
                    rc4_buf[rc4_i] = tmp2;
                    rc4_buf[rc4_j] = tmp;
                    arr[i] = rc4_buf[(tmp + tmp2) & 0xff];
                }
                this.rc4_i = rc4_i;
                this.rc4_j = rc4_j;
            };
            RC4.prototype.addEntropy = function (key) {
                var rc4_buf = this.rc4_buf;
                var j = 0;
                for (var i = 0; i < 256; ++i) {
                    j = (j + rc4_buf[i] + key[i % key.length]) & 0xff;
                    var tmp = rc4_buf[i];
                    rc4_buf[i] = rc4_buf[j];
                    rc4_buf[j] = tmp;
                }
                bytes(new Uint8Array(4096));
            };
            RC4.prototype.uniqueId = function (len) {
                if (len === void 0) { len = 24; }
                var buf = new Uint8Array(len);
                this.getBytes(buf);
                var r = "";
                for (var i = 0; i < buf.length; ++i)
                    r += RC4.idChars.charAt(buf[i] & 63);
                return r.replace(/^[0-9]/, "x");
            };
            RC4.idChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678942";
            return RC4;
        })();
        Random.RC4 = RC4;
        var rc4;
        var saveScheduled = false;
        var u32_8;
        var u32_32;
        Random.strongEntropySource = null;
        function addEntropy(key) {
            rc4.addEntropy(key);
        }
        function scheduleSave() {
            if (saveScheduled || Random.strongEntropySource)
                return;
            saveScheduled = true;
            TDev.Util.setTimeout(1000, function () {
                saveScheduled = false;
                saveState();
            });
        }
        function setup() {
            if (rc4)
                return;
            rc4 = new RC4();
            u32_8 = new Uint8Array(4);
            u32_32 = new Uint32Array(u32_8.buffer);
            var key = new Uint8Array(64);
            for (var i = 0; i < key.length; ++i)
                key[i] = (Math.random() * 0x100) & 0xff;
            addEntropy(key);
            var needsMoreEntropy = true;
            var wc = window.crypto;
            try {
                if (wc && wc.getRandomValues) {
                    wc.getRandomValues(key);
                    addEntropy(key);
                    needsMoreEntropy = false;
                }
            }
            catch (exn) {
            }
            if (needsMoreEntropy) {
                if (Random.strongEntropySource) {
                    Random.strongEntropySource(key);
                    addEntropy(key);
                }
                else {
                    addEntropy64(window.localStorage["entropy"]);
                    if (!window.localStorage["gotCloudEntropy"])
                        TDev.Util.setTimeout(1000, function () {
                            if (!window.localStorage["gotCloudEntropy"])
                                TDev.Cloud.getRandomAsync().done(addCloudEntropy, function (err) {
                                });
                        });
                }
            }
            scheduleSave();
        }
        function bytes(arr) {
            setup();
            bytes_internal(arr);
            scheduleSave();
        }
        Random.bytes = bytes;
        function bytes_internal(arr) {
            rc4.getBytes(arr);
        }
        function uint32() {
            setup();
            bytes_internal(u32_8);
            scheduleSave();
            return u32_32[0];
        }
        Random.uint32 = uint32;
        var m32 = 1 / 0x100000000;
        var m64 = 1 / 0x10000000000000000;
        function normalized() {
            return uint32() * m32 + uint32() * m64;
        }
        Random.normalized = normalized;
        function saveState() {
            setup();
            if (Random.strongEntropySource)
                return;
            var state = new Uint8Array(8 * 4);
            bytes_internal(state);
            window.localStorage["entropy"] = TDev.Util.base64EncodeBytes(state);
        }
        function addCloudEntropy(buf) {
            if (buf) {
                addEntropy64(buf);
                saveState();
                window.localStorage["gotCloudEntropy"] = "yes";
            }
        }
        Random.addCloudEntropy = addCloudEntropy;
        function addEntropy64(buf) {
            if (!buf)
                return;
            var strbuf = TDev.Util.base64Decode(buf);
            if (!strbuf)
                return;
            setup();
            addEntropy(TDev.Util.stringToUint8Array(strbuf));
            scheduleSave();
        }
        function uniqueId(len) {
            if (len === void 0) { len = 24; }
            setup();
            var r = rc4.uniqueId(len);
            scheduleSave();
            return r;
        }
        Random.uniqueId = uniqueId;
        function permute(arr) {
            for (var i = 0; i < arr.length; ++i) {
                var j = uint32() % arr.length;
                var tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
        }
        Random.permute = permute;
        function pick(arr) {
            if (arr.length == 0)
                return null;
            return arr[uint32() % arr.length];
        }
        Random.pick = pick;
    })(Random = TDev.Random || (TDev.Random = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    (function (PromiseState) {
        PromiseState[PromiseState["Pending"] = 0] = "Pending";
        PromiseState[PromiseState["Success"] = 1] = "Success";
        PromiseState[PromiseState["Error"] = 2] = "Error";
    })(TDev.PromiseState || (TDev.PromiseState = {}));
    var PromiseState = TDev.PromiseState;
    var Promise = (function () {
        function Promise(init, _onNotify) {
            if (_onNotify === void 0) { _onNotify = undefined; }
            this._onNotify = _onNotify;
            this._listeners = [];
            this._state = 0 /* Pending */;
            if (!!init) {
                var promise = this;
                try {
                    init(function (v) {
                        if (promise._state != 0 /* Pending */) {
                            Promise.checkHandler("trying to resolve promise more than once");
                            return;
                        }
                        promise._value = v;
                        promise._state = 1 /* Success */;
                        promise._notifyListeners();
                    }, function (v) {
                        if (promise._state == 2 /* Error */) {
                            Promise.checkHandler("trying to resolve (error) promise more than once");
                            return;
                        }
                        promise._value = v || new Error("An error occured");
                        promise._state = 2 /* Error */;
                        promise._notifyListeners();
                    }, undefined);
                }
                catch (err) {
                    Promise.errorHandler("promiseCtor", err);
                }
            }
        }
        Promise.prototype._notify = function (l) {
            if (this._value instanceof Promise) {
                var p = this._value;
                if (!!p._state)
                    p._notify(l);
                else
                    p._listeners.push(l);
            }
            else
                l._onNotify(this);
        };
        Promise.prototype.isPending = function () {
            return this._state == 0 /* Pending */;
        };
        Promise.prototype._notifyListeners = function () {
            var _this = this;
            this._listeners.forEach(function (p) { return _this._notify(p); });
        };
        Promise.propagate = function (s, v, onSuccess, onError) {
            if (s === 1 /* Success */ && v instanceof Promise) {
                var q = v;
                if (!!q._state) {
                    v = q._value;
                    if (q._state == 2 /* Error */)
                        s = 2 /* Error */;
                }
                else {
                    q._listeners.push(new Promise(undefined, function () {
                        Promise.propagate(q._state, q._value, onSuccess, onError);
                    }));
                    return;
                }
            }
            if (s === 2 /* Error */)
                onError(v);
            else
                onSuccess(v);
        };
        Promise.prototype.then = function (onSuccess, onError, onProgress) {
            if (onError === void 0) { onError = undefined; }
            if (onProgress === void 0) { onProgress = undefined; }
            var onSuccess3;
            var onError3;
            var r = new Promise(function (onSuccess2, onError2, onProgress2) {
                onSuccess3 = onSuccess2;
                onError3 = onError2;
            }, function (p) {
                var v = p._value;
                var s = p._state;
                if (s === 2 /* Error */) {
                    if (!!onError)
                        try {
                            v = onError(v);
                            s = 1 /* Success */;
                        }
                        catch (e) {
                            v = e;
                            s = 2 /* Error */;
                        }
                }
                else {
                    if (!!onSuccess)
                        try {
                            v = onSuccess(v);
                            s = 1 /* Success */;
                        }
                        catch (e) {
                            v = e;
                            s = 2 /* Error */;
                        }
                }
                Promise.propagate(s, v, onSuccess3, onError3);
            });
            if (!!this._state)
                this._notify(r);
            else
                this._listeners.push(r);
            return r;
        };
        Promise.prototype.done = function (onSuccess, onError, onProgress) {
            if (onSuccess === void 0) { onSuccess = undefined; }
            if (onError === void 0) { onError = undefined; }
            if (onProgress === void 0) { onProgress = undefined; }
            this.then(onSuccess, onError, onProgress).then(undefined, function (e) {
                Promise.errorHandler("promiseDone", e);
            });
        };
        Promise.prototype.thenalways = function (onSuccessOrError, onProgress) {
            if (onProgress === void 0) { onProgress = undefined; }
            return this.then(onSuccessOrError, onSuccessOrError, onProgress);
        };
        Promise.is = function (v) {
            return v instanceof Promise;
        };
        Promise.as = function (v) {
            if (v === void 0) { v = undefined; }
            return v instanceof Promise ? v : Promise.wrap(v);
        };
        Promise.wrap = function (v) {
            if (v === void 0) { v = undefined; }
            return new Promise(function (onSuccess, onError, onProgress) {
                onSuccess(v);
            });
        };
        Promise.wrapError = function (v) {
            if (v === void 0) { v = undefined; }
            return new Promise(function (onSuccess, onError, onProgress) {
                onError(v);
            });
        };
        Promise.delay = function (ms, f) {
            if (f === void 0) { f = null; }
            return new Promise(function (onSuccess, onError, onProgress) {
                window.setTimeout(function () { return f ? f().then(function (v) { return onSuccess(v); }, function (e) { return onError(e); }, function (v) { return onProgress(v); }) : onSuccess(undefined); }, ms);
            });
        };
        Promise.join = function (values) {
            return new Promise(function (onSuccess, onError, onProgress) {
                var keys = Object.keys(values);
                var errors = Array.isArray(values) ? new Array(values.length) : {};
                var results = Array.isArray(values) ? new Array(values.length) : {};
                if (keys.length == 0) {
                    onSuccess(results);
                    return;
                }
                var missing = keys.length;
                var next = function () {
                    if (--missing == 0)
                        if (Object.keys(errors).length == 0)
                            onSuccess(results);
                        else
                            onError(errors);
                };
                keys.forEach(function (key) {
                    Promise.as(values[key]).then(function (v) {
                        results[key] = v;
                        next();
                    }, function (v) {
                        errors[key] = v;
                        next();
                    });
                });
            });
        };
        Promise.thenEach = function (values, onSuccess, onError, onProgress) {
            if (onSuccess === void 0) { onSuccess = undefined; }
            if (onError === void 0) { onError = undefined; }
            if (onProgress === void 0) { onProgress = undefined; }
            var result = Array.isArray(values) ? new Array(values.length) : {};
            Object.keys(values).forEach(function (key) {
                result[key] = Promise.as(values[key]).then(onSuccess, onError, onProgress);
            });
            return Promise.join(result);
        };
        Promise.sequentialMap = function (values, f) {
            return new Promise(function (onSuccess, onError, onProgress) {
                var keys = Object.keys(values);
                var results = Array.isArray(values) ? new Array(values.length) : {};
                function next(i) {
                    if (i >= keys.length) {
                        onSuccess(results);
                    }
                    else {
                        var key = keys[i];
                        try {
                            Promise.as(values[key]).done(function (x) {
                                Promise.as(f(x, key, results)).done(function (v) {
                                    results[key] = v;
                                    next(i + 1);
                                }, onError);
                            });
                        }
                        catch (e) {
                            onError(e);
                        }
                    }
                }
                next(0);
            });
        };
        Promise.errorHandler = function (ctx, err) {
            throw err;
        };
        Promise.checkHandler = function (msg) {
            Promise.errorHandler("promise-check", new Error(msg));
        };
        return Promise;
    })();
    TDev.Promise = Promise;
    var PromiseInv = (function (_super) {
        __extends(PromiseInv, _super);
        function PromiseInv() {
            var _this = this;
            _super.call(this, function (onSuccess, onError) {
                _this.success = onSuccess;
                _this.error = onError;
            });
        }
        PromiseInv.as = function (v) {
            if (v === void 0) { v = undefined; }
            var r = new PromiseInv();
            r.success(v);
            return r;
        };
        return PromiseInv;
    })(Promise);
    TDev.PromiseInv = PromiseInv;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Animation = (function () {
        function Animation(update) {
            var _this = this;
            this.update = update;
            this.running = false;
            this.beginValue = 0;
            this.delay = 0;
            this.endValue = 1;
            this.duration = 1000;
            this.frameLength = 30;
            this.beginTime = 0;
            this.quadratic = true;
            this.stepFn = function () {
                _this.step();
            };
        }
        Animation.prototype.begin = function () {
            var _this = this;
            var run = function () {
                _this.beginTime = new Date().getTime();
                _this.step();
            };
            this.running = true;
            if (this.delay > 0)
                window.setTimeout(run, this.delay);
            else
                run();
        };
        Animation.prototype.complete = function () {
            if (this.running) {
                this.running = false;
                this.update(this.endValue);
                if (!!this.completed)
                    this.completed();
            }
        };
        Animation.prototype.stop = function () {
            this.running = false;
        };
        Animation.prototype.step = function () {
            try {
                if (!this.running)
                    return;
                var now = new Date().getTime();
                if (now > this.beginTime + this.duration || TDev.Browser.noAnimations) {
                    this.complete();
                    return;
                }
                var phase = 1 - (now - this.beginTime) / this.duration;
                if (this.quadratic)
                    phase = (this.beginValue - this.endValue) * phase * phase + this.endValue;
                else
                    phase = (this.beginValue - this.endValue) * phase + this.endValue;
                this.update(phase);
                window.setTimeout(this.stepFn, this.frameLength);
            }
            catch (err) {
                TDev.Util.reportError("animation", err);
            }
        };
        Animation.fadeIn = function (elt, duration) {
            if (duration === void 0) { duration = 300; }
            var a = new Animation(function (v) {
                elt.style.opacity = v + "";
            });
            a.duration = duration;
            return a;
        };
        Animation.fadeOut = function (elt, duration) {
            if (duration === void 0) { duration = 300; }
            var a = new Animation(function (v) {
                if (v == 0)
                    elt.removeSelf();
                else
                    elt.style.opacity = v + "";
            });
            a.beginValue = 1;
            a.endValue = 0;
            a.duration = duration;
            return a;
        };
        return Animation;
    })();
    TDev.Animation = Animation;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var ClickHandler = (function () {
        function ClickHandler(helt, f) {
            this.helt = helt;
            this.f = f;
            this.begX = 0;
            this.begY = 0;
            this.cleared = false;
            this.version = 0;
            this.mouseCaptureOverlay = document.body;
            this.setup();
        }
        ClickHandler.prototype.clickBegin = function (pos) {
            this.helt.setFlag("active", true);
            this.begX = pos.pageX;
            this.begY = pos.pageY;
            this.cleared = false;
            this.setupVersion();
        };
        ClickHandler.prototype.setupVersion = function () {
            var _this = this;
            var v = ++this.version;
            Util.setTimeout(300, function () {
                if (!_this.cleared && v == _this.version)
                    _this.clear();
            });
        };
        ClickHandler.prototype.onMove = function (e) {
            if (Math.abs(e.pageX - this.begX) > 10 || Math.abs(e.pageY - this.begY) > 10)
                this.clear();
        };
        ClickHandler.prototype.getPos = function (e) {
            if (!e.getPointerList)
                return { pageX: e.clientX, pageY: e.clientY };
            var pt = e.getPointerList()[0];
            return {
                pageX: pt.clientX,
                pageY: pt.clientY
            };
        };
        ClickHandler.prototype.skipIt = function (e) {
            var targ = e.target;
            if (e.target != e.currentTarget && (targ.nodeName == "INPUT" || targ.nodeName == "TEXTAREA"))
                return true;
            return false;
        };
        ClickHandler.prototype.isCanceled = function (e) {
            if (this.skipIt(e))
                return true;
            if (e.utilClickCancel)
                return true;
            e.utilClickCancel = true;
            return false;
        };
        ClickHandler.prototype.getPosition = function (element) {
            var xPosition = 0;
            var yPosition = 0;
            while (element) {
                xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
                yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
                element = element.offsetParent;
            }
            return { x: xPosition, y: yPosition };
        };
        ClickHandler.prototype.handleEvent = function (e) {
            try {
                var ep = e;
                if (Util.mouseLogging) {
                    Util.log("executing click handler " + e.type + " on " + this.helt.id);
                    Util.log("pageX:{0} pageY:{1} offsetX:{2} offsetY:{3} clientX:{4} clientY:{5}", ep.pageX, ep.pageY, ep.offsetX, ep.offsetY, ep.clientX, ep.clientY);
                }
                if (ep.touches && ep.touches[0]) {
                    ep = ep.touches[0];
                }
                else if (ep.touches && ep.touches.item(0)) {
                    ep = ep.touches.item(0);
                }
                else if (ep.changedTouches && ep.changedTouches.item(0)) {
                    ep = ep.changedTouches.item(0);
                }
                if (Util.mouseLogging) {
                    Util.log("after touch adjustment");
                    var pos = this.getPosition(this.helt);
                    Util.log("pageX:{0} pageY:{1} offsetX:{2} offsetY:{3} clientX:{4} clientY:{5} eltX:{6} eltY:{7}", ep.pageX, ep.pageY, ep.offsetX, ep.offsetY, ep.clientX, ep.clientY, pos.x, pos.y);
                }
                switch (e.type) {
                    case "pointerdown":
                        if (this.isCanceled(e))
                            break;
                        this.prepareMouseOverlay();
                        this.clickBegin(this.getPos(e));
                        this.mouseCaptureOverlay.addEventListener("pointermove", this, false);
                        this.mouseCaptureOverlay.addEventListener("pointerup", this, false);
                        break;
                    case "MSPointerDown":
                        if (this.isCanceled(e))
                            break;
                        this.prepareMouseOverlay();
                        this.clickBegin(this.getPos(e));
                        this.mouseCaptureOverlay.addEventListener("MSPointerMove", this, false);
                        this.mouseCaptureOverlay.addEventListener("MSPointerUp", this, false);
                        break;
                    case "pointermove":
                    case "MSPointerMove":
                        if (!this.cleared)
                            this.onMove(this.getPos(e));
                        break;
                    case "pointerup":
                    case "MSPointerUp":
                        if (!this.cleared)
                            this.fireClick(e);
                        break;
                    case "touchstart":
                        if (this.isCanceled(e))
                            break;
                        this.helt.addEventListener("touchend", this, false);
                        document.body.addEventListener("touchmove", this, false);
                        document.body.addEventListener("touchend", this, false);
                        this.clickBegin(ep);
                        break;
                    case "touchmove":
                        if (!this.cleared)
                            this.onMove(ep);
                        break;
                    case "touchend":
                        if (!this.cleared)
                            this.fireClick(ep);
                        break;
                    case "mousedown":
                        if (this.isCanceled(e))
                            break;
                        if (e.button != 0)
                            break;
                        this.helt.hideFocus = true;
                        this.helt.addEventListener("mouseup", this, false);
                        document.addEventListener("mouseup", this, false);
                        document.body.addEventListener("mousemove", this, false);
                        this.clickBegin(e);
                        break;
                    case "mousemove":
                        if (!this.cleared)
                            this.onMove(e);
                        break;
                    case "mouseup":
                        if (!this.cleared)
                            this.fireClick(e);
                        break;
                    case "keypress":
                        var ke = e;
                        if (ke.target == this.helt && (ke.which == 13 || ke.which == 32)) {
                            this.f(e);
                        }
                        break;
                }
            }
            catch (err) {
                Util.reportError("clickHandler", err);
            }
        };
        ClickHandler.prototype.fireClick = function (e) {
            this.clear();
            var canc = e.clickCancelled;
            e.clickCancelled = true;
            if (!canc) {
                e.pgX = this.begX;
                e.pgY = this.begY;
                this.f(e);
            }
        };
        ClickHandler.prototype.clear = function () {
            this.hideMouseOverlay();
            this.cleared = true;
            this.hideMouseOverlay();
            this.helt.removeEventListener("touchend", this, false);
            this.helt.removeEventListener("mouseup", this, false);
            this.helt.setFlag("active", false);
            document.body.removeEventListener("touchmove", this, false);
            document.removeEventListener("mouseup", this, false);
            document.body.removeEventListener("mouseup", this, false);
            document.body.removeEventListener("mousemove", this, false);
            document.body.removeEventListener("touchend", this, false);
            this.mouseCaptureOverlay.removeEventListener("MSPointerMove", this, false);
            this.mouseCaptureOverlay.removeEventListener("MSPointerUp", this, false);
            this.mouseCaptureOverlay.removeEventListener("pointermove", this, false);
            this.mouseCaptureOverlay.removeEventListener("pointerup", this, false);
        };
        ClickHandler.prototype.prepareMouseOverlay = function () {
        };
        ClickHandler.prototype.hideMouseOverlay = function () {
        };
        ClickHandler.prototype.setup = function () {
            if (window.navigator.pointerEnabled)
                this.helt.addEventListener("pointerdown", this, false);
            else if (window.navigator.msPointerEnabled)
                this.helt.addEventListener("MSPointerDown", this, false);
            else if (TDev.Browser.touchStart)
                this.helt.addEventListener("touchstart", this, false);
            else
                this.helt.addEventListener("mousedown", this, false);
            this.helt.addEventListener("keypress", this, true);
        };
        ClickHandler.prototype.unhook = function () {
            this.helt.removeEventListener("MSPointerDown", this, false);
            this.helt.removeEventListener("touchstart", this, false);
            this.helt.removeEventListener("mousedown", this, false);
            this.helt.removeEventListener("keypress", this, true);
        };
        return ClickHandler;
    })();
    TDev.ClickHandler = ClickHandler;
    var Util;
    (function (Util) {
        function clickHandler(e, cb, allowSelect) {
            if (e) {
                e.setAttribute("role", "button");
                e.tabIndex = 0;
            }
            function newCb(e) {
                try {
                    return cb(e);
                }
                catch (err) {
                    Util.reportError("clickHandler " + cb.toString(), err);
                }
            }
            var oldH = e.clickHandler;
            if (oldH)
                oldH.unhook();
            var handler = new ClickHandler(e, newCb);
            e.clickHandler = handler;
            if (!allowSelect)
                e.onselectstart = function () {
                    return false;
                };
            else
                e.onselectstart = function (e) {
                    e.stopImmediatePropagation();
                    return true;
                };
        }
        Util.clickHandler = clickHandler;
        try {
            if (typeof HTMLElement != "undefined")
                HTMLElement.prototype.withClick = function (cb, allowSelect) {
                    Util.clickHandler(this, cb, allowSelect);
                    return this;
                };
        }
        catch (e) {
        }
    })(Util = TDev.Util || (TDev.Util = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var DragHandler = (function (_super) {
        __extends(DragHandler, _super);
        function DragHandler(helt, cb) {
            _super.call(this, helt, null);
            this.helt = helt;
            this.cb = cb;
            this.offX = 0;
            this.offY = 0;
            this.lockX = false;
            this.lockY = false;
            this.isTap = true;
            this.lastX = 0;
            this.lastY = 0;
            this.beginTime = 0;
            this.moveElt = true;
            this.isIeTouch = false;
            this.helt.style.msTouchAction = "none";
            this.helt.style.touchAction = "none";
        }
        DragHandler.prototype.setupVersion = function () {
        };
        DragHandler.prototype.clickBegin = function (pos) {
            _super.prototype.clickBegin.call(this, pos);
            this.offX = this.helt.offsetLeft - this.begX;
            this.offY = this.helt.offsetTop - this.begY;
            this.beginTime = TDev.Util.now();
            this.isTap = true;
            this.lastX = this.begX;
            this.lastY = this.begY;
            this.cb("drag", 0, 0, this.begX, this.begY);
        };
        DragHandler.prototype.onMove = function (pos) {
            this.lastX = pos.pageX;
            this.lastY = pos.pageY;
            if (this.lockX)
                this.lastX = this.begX;
            if (this.lockY)
                this.lastY = this.begY;
            if (this.moveElt) {
                this.helt.style.left = this.offX + this.lastX + "px";
                this.helt.style.top = this.offY + this.lastY + "px";
            }
            var dx = this.lastX - this.begX;
            var dy = this.lastY - this.begY;
            if (Math.abs(dx) > 10 || Math.abs(dy) > 10)
                this.isTap = false;
            this.cb("move", dx, dy, undefined, undefined);
        };
        DragHandler.prototype.fireClick = function (pos) {
            if (TDev.Util.now() - this.beginTime > 300)
                this.isTap = false;
            this.clear();
            this.cb("release", this.lastX - this.begX, this.lastY - this.begY, this.isTap, undefined);
        };
        DragHandler.prototype.prepareMouseOverlay = function () {
            if (this.isIeTouch)
                this.mouseCaptureOverlay = this.helt;
            else
                this.mouseCaptureOverlay = document.body;
        };
        DragHandler.prototype.hideMouseOverlay = function () {
        };
        DragHandler.prototype.handleEvent = function (e) {
            try {
                if (this.skipIt(e))
                    return;
                e.stopPropagation();
                e.preventDefault();
                this.isIeTouch = e.pointerType == 2;
                if (e.preventMouseEvent) {
                    e.preventMouseEvent();
                }
                if (e.preventManipulation) {
                    e.preventManipulation();
                }
                _super.prototype.handleEvent.call(this, e);
            }
            catch (err) {
                TDev.Util.reportError("dragHandler", err);
            }
        };
        return DragHandler;
    })(TDev.ClickHandler);
    TDev.DragHandler = DragHandler;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var DragToScrollHandler = (function () {
        function DragToScrollHandler(helt) {
            this.helt = helt;
            this.posX = 0;
            this.posY = 0;
            this.theHistory = [];
            this.vertical = true;
            this.horizontal = false;
            this.seenTouchEvent = false;
            this.captureingMouse = false;
        }
        DragToScrollHandler.prototype.unhook = function () {
            var t = this;
            if (TDev.Browser.touchStart) {
                this.helt.removeEventListener("touchstart", t, false);
                this.helt.removeEventListener("touchmove", t, false);
                this.helt.removeEventListener("touchend", t, false);
            }
            else {
                this.helt.removeEventListener("mousedown", t, false);
                this.helt.removeEventListener("mouseup", t, false);
                this.helt.removeEventListener("mouseout", t, false);
                this.helt.removeEventListener("mouseleave", t, false);
                this.helt.removeEventListener("mousemove", t, false);
            }
        };
        DragToScrollHandler.prototype.init = function () {
            this.helt.dragToScroll = this;
            var t = this;
            if (TDev.Browser.touchStart) {
                this.helt.addEventListener("touchstart", t, false);
                this.helt.addEventListener("touchmove", t, false);
                this.helt.addEventListener("touchend", t, false);
            }
            else {
                this.helt.addEventListener("mousedown", t, false);
                this.helt.addEventListener("mouseup", t, false);
                this.helt.addEventListener("mouseout", t, false);
                this.helt.addEventListener("mouseleave", t, false);
                this.helt.addEventListener("mousemove", t, false);
            }
        };
        DragToScrollHandler.prototype.record = function (pos) {
            var n = new Date().getTime();
            this.theHistory.push({ x: pos.pageX, y: pos.pageY, t: n });
        };
        DragToScrollHandler.prototype.stopInertialAnimation = function () {
            if (!this.inertialAnimation)
                return;
            this.inertialAnimation.complete();
            this.inertialAnimation = null;
        };
        DragToScrollHandler.prototype.begin = function (pos) {
            this.posX = this.helt.scrollLeft + pos.pageX;
            this.posY = this.helt.scrollTop + pos.pageY;
            this.stopInertialAnimation();
            this.theHistory = [];
            this.record(pos);
        };
        DragToScrollHandler.prototype.scrollTo = function (x, y) {
            if (this.horizontal) {
                this.helt.scrollLeft = x;
            }
            if (this.vertical) {
                this.helt.scrollTop = y;
            }
        };
        DragToScrollHandler.prototype.move = function (pos) {
            this.scrollTo(this.posX - pos.pageX, this.posY - pos.pageY);
            this.record(pos);
        };
        DragToScrollHandler.prototype.log = function () {
            var n = new Date().getTime();
            var k = this.theHistory.slice(this.theHistory.length - 5).map(function (h) { return h.x + "," + h.y + "," + (h.t - n); }).join(" : ");
            Util.log(k);
        };
        DragToScrollHandler.prototype.end = function (pos) {
            var _this = this;
            if (!!pos)
                this.record(pos);
            if (this.theHistory.length == 0)
                return;
            var last = this.theHistory[this.theHistory.length - 1];
            var beg = last.t - 200;
            var first = last;
            for (var i = 0; i < this.theHistory.length; ++i) {
                if (this.theHistory[i].t >= beg) {
                    first = this.theHistory[i];
                    break;
                }
            }
            var dt = last.t - first.t;
            if (dt > 0) {
                var m = 150;
                var dx = (last.x - first.x) / dt * m;
                var dy = (last.y - first.y) / dt * m;
                var speed = Math.abs(dx) + Math.abs(dy);
                if (speed < 50)
                    return;
                this.inertialAnimation = new TDev.Animation(function (p) {
                    _this.scrollTo(_this.posX - (last.x + dx * p), _this.posY - (last.y + dy * p));
                });
                this.inertialAnimation.duration = 700;
                this.inertialAnimation.begin();
            }
        };
        DragToScrollHandler.prototype.handleEvent = function (e) {
            try {
                var now = new Date().getTime();
                switch (e.type) {
                    case "mousedown":
                        if (!this.seenTouchEvent && e.button == 0) {
                            this.captureingMouse = true;
                            this.begin(e);
                        }
                        break;
                    case "mousemove":
                        if (this.captureingMouse) {
                            this.move(e);
                        }
                        break;
                    case "mouseleave":
                        this.end(e);
                        this.captureingMouse = false;
                        break;
                    case "mouseout":
                        if (this.captureingMouse) {
                            var me = e;
                            if (!!me.relatedTarget) {
                                var elts = this.helt.getElementsByTagName(me.relatedTarget.nodeName);
                                for (var i = 0; i < elts.length; ++i)
                                    if (elts[i] == me.relatedTarget)
                                        return;
                            }
                            this.end(e);
                            this.captureingMouse = false;
                        }
                        break;
                    case "mouseup":
                        this.end(e);
                        this.captureingMouse = false;
                        break;
                    case "touchstart":
                        this.seenTouchEvent = true;
                        this.begin(e.touches[0]);
                        break;
                    case "touchmove":
                        e.preventDefault();
                        this.move(e.touches[0]);
                        break;
                    case "touchend":
                        this.end(e.touches[0]);
                        break;
                }
            }
            catch (err) {
                Util.reportError("dragToScroll", err);
            }
        };
        return DragToScrollHandler;
    })();
    TDev.DragToScrollHandler = DragToScrollHandler;
    var Util;
    (function (Util) {
        function setupDragToScroll(e) {
            e.scrollEnabled = true;
            if (TDev.Browser.isMobileSafari) {
                e.style.boxSizing = "border-box";
                e.style.overflowY = "scroll";
                e.className += " iOSScroll";
            }
            else if (TDev.Browser.builtinTouchToPan) {
                e.style.boxSizing = "border-box";
                e.style.overflowY = "auto";
            }
            else {
                e.style.overflowY = "hidden";
                var d = new DragToScrollHandler(e);
                d.init();
            }
        }
        Util.setupDragToScroll = setupDragToScroll;
        function resetDragToScroll(e) {
            e.scrollEnabled = false;
            if (TDev.Browser.builtinTouchToPan || TDev.Browser.isMobileSafari) {
                e.style.boxSizing = "";
                e.style.overflowX = "";
                e.style.overflowY = "";
                if (TDev.Browser.isMobileSafari)
                    e.className = e.className.replace(/iOSScroll/g, "");
            }
            else {
                var d = e.dragToScroll;
                if (d)
                    d.unhook();
            }
        }
        Util.resetDragToScroll = resetDragToScroll;
        function setupHDragToScroll(e) {
            e.scrollEnabled = true;
            if (TDev.Browser.isMobileSafari) {
                e.style.boxSizing = "border-box";
                e.style.overflowY = "auto";
                e.className += " iOSScroll";
            }
            else if (TDev.Browser.builtinTouchToPan) {
                e.style.boxSizing = "border-box";
                e.style.overflowX = "auto";
                if (TDev.Browser.isTrident)
                    e.style.msScrollTranslation = 'vertical-to-horizontal';
            }
            else {
                e.style.overflowX = "hidden";
                var d = new DragToScrollHandler(e);
                d.horizontal = true;
                d.vertical = false;
                d.init();
            }
        }
        Util.setupHDragToScroll = setupHDragToScroll;
    })(Util = TDev.Util || (TDev.Util = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var TouchHandler = (function (_super) {
        __extends(TouchHandler, _super);
        function TouchHandler(helt, cb) {
            _super.call(this, helt, null);
            this.helt = helt;
            this.cb = cb;
            this.offX = 0;
            this.offY = 0;
            this.lockX = false;
            this.lockY = false;
            this.lastX = 0;
            this.lastY = 0;
            this.isIeTouch = false;
            this.helt.style.touchAction = "none";
            this.helt.style.msTouchAction = "none";
        }
        TouchHandler.prototype.setupVersion = function () {
        };
        TouchHandler.prototype.getRelativePos = function (pos) {
            if (TDev.Util.mouseLogging) {
                TDev.Util.log("touch handler ");
                var apos = this.getPosition(this.helt);
                TDev.Util.log("pageX:{0} pageY:{1} offsetX:{2} offsetY:{3} clientX:{4} clientY:{5} eltX:{6} eltY:{7}", pos.pageX, pos.pageY, pos.offsetX, pos.offsetY, pos.clientX, pos.clientY, apos.x, apos.y);
            }
            var x, y;
            if (pos.pageX) {
                x = pos.pageX;
                y = pos.pageY;
            }
            else {
                x = pos.clientX;
                y = pos.clientY;
            }
            var absPos = this.getPosition(this.helt);
            pos.offX = x - absPos.x;
            pos.offY = y - absPos.y;
            return pos;
        };
        TouchHandler.prototype.clickBegin = function (pos) {
            _super.prototype.clickBegin.call(this, pos);
            this.getRelativePos(pos);
            if (TDev.Util.mouseLogging) {
                TDev.Util.log("touchBegin: {0},{1}", pos.offX, pos.offY);
            }
            this.offX = this.helt.offsetLeft - this.begX;
            this.offY = this.helt.offsetTop - this.begY;
            this.cb("down", pos.offX, pos.offY);
        };
        TouchHandler.prototype.onMove = function (pos) {
            this.getRelativePos(pos);
            if (TDev.Util.mouseLogging) {
                TDev.Util.log("onMove: {0},{1}", pos.offX, pos.offY);
            }
            this.cb("move", pos.offX, pos.offY);
        };
        TouchHandler.prototype.fireClick = function (pos) {
            this.getRelativePos(pos);
            if (TDev.Util.mouseLogging) {
                TDev.Util.log("touchEnd: {0},{1}", pos.offX, pos.offY);
            }
            this.clear();
            this.cb("up", pos.offX, pos.offY);
        };
        TouchHandler.prototype.prepareMouseOverlay = function () {
            if (this.isIeTouch)
                this.mouseCaptureOverlay = this.helt;
            else
                this.mouseCaptureOverlay = document.body;
        };
        TouchHandler.prototype.hideMouseOverlay = function () {
        };
        TouchHandler.prototype.handleEvent = function (e) {
            try {
                e.stopPropagation();
                e.preventDefault();
                this.isIeTouch = e.pointerType == 2;
                if (e.preventMouseEvent) {
                    e.preventMouseEvent();
                }
                if (e.preventManipulation) {
                    e.preventManipulation();
                }
                _super.prototype.handleEvent.call(this, e);
            }
            catch (err) {
                TDev.Util.reportError("dragHandler", err);
            }
        };
        return TouchHandler;
    })(TDev.ClickHandler);
    TDev.TouchHandler = TouchHandler;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var HashtableEntry = (function () {
        function HashtableEntry(key, next) {
            this.key = key;
            this.next = next;
        }
        return HashtableEntry;
    })();
    TDev.HashtableEntry = HashtableEntry;
    var Hashtable = (function () {
        function Hashtable(getHashCode, equals, initialSize) {
            if (initialSize === void 0) { initialSize = 13; }
            this.getHashCode = getHashCode;
            this.equals = equals;
            this.initialSize = initialSize;
            this.entryCount = 0;
        }
        Hashtable.prototype.count = function () {
            return this.entryCount;
        };
        Hashtable.prototype.deleteKey = function (k) {
            if (!this.entries)
                return null;
            var h = (this.getHashCode(k) & 0x7fffffff) % this.entries.length;
            var e0 = this.entries[h];
            if (!e0)
                return null;
            if (this.equals(k, e0.key)) {
                this.entries[h] = e0.next;
                e0.next = null;
                this.entryCount--;
                return e0;
            }
            var e = e0;
            while (e && e.next && !this.equals(k, e.next.key))
                e = e.next;
            if (!e.next)
                return null;
            var found = e.next;
            e.next = found.next;
            found.next = null;
            this.entryCount--;
            return found;
        };
        Hashtable.prototype.remove = function (k) {
            return this.deleteKey(k);
        };
        Hashtable.prototype.lookup = function (k, addNew) {
            if (addNew === void 0) { addNew = false; }
            if (!this.entries) {
                if (!addNew)
                    return null;
                this.entries = [];
                for (var i = 0; i < this.initialSize; ++i)
                    this.entries[i] = null;
            }
            var h = (this.getHashCode(k) & 0x7fffffff) % this.entries.length;
            var e0 = this.entries[h];
            var e = e0;
            while (e && !this.equals(k, e.key))
                e = e.next;
            if (!e && addNew) {
                e = new HashtableEntry(k, e0);
                this.entryCount++;
                this.entries[h] = e;
                if (this.entryCount > this.entries.length + this.entries.length) {
                    this.rehash();
                }
            }
            return e;
        };
        Hashtable.prototype.sizeAtLeast = function (n) {
            for (var i = 0; i < Hashtable.primeSizes.length; ++i)
                if (Hashtable.primeSizes[i] > n)
                    return Hashtable.primeSizes[i];
            return 0;
        };
        Hashtable.prototype.rehash = function () {
            var size = this.sizeAtLeast(this.entries.length);
            if (size == 0)
                return;
            var oldEntries = this.entries;
            this.entries = [];
            for (var i = 0; i < size; ++i)
                this.entries[i] = null;
            for (var i = 0; i < oldEntries.length; ++i) {
                var next;
                for (var e = oldEntries[i]; e; e = next) {
                    next = e.next;
                    var h = (this.getHashCode(e.key) & 0x7fffffff) % this.entries.length;
                    e.next = this.entries[h];
                    this.entries[h] = e;
                }
            }
        };
        Hashtable.prototype.forEachEntry = function (f) {
            if (!this.entries)
                return;
            for (var i = 0; i < this.entries.length; ++i)
                for (var e = this.entries[i]; e; e = e.next)
                    f(e);
        };
        Hashtable.prototype.forEach = function (f) {
            this.forEachEntry(function (e) { return f(e.key, e.value); });
        };
        Hashtable.prototype.mapEntries = function (f) {
            var res = [];
            if (this.entries) {
                for (var i = 0; i < this.entries.length; ++i)
                    for (var e = this.entries[i]; e; e = e.next)
                        res.push(f(e));
            }
            return res;
        };
        Hashtable.prototype.keys = function () {
            return this.mapEntries(function (e) { return e.key; });
        };
        Hashtable.prototype.pairs = function () {
            return this.mapEntries(function (e) {
                return { key: e.key, value: e.value };
            });
        };
        Hashtable.prototype.filteredValues = function (filter) {
            var res = [];
            if (this.entries) {
                for (var i = 0; i < this.entries.length; ++i)
                    for (var e = this.entries[i]; e; e = e.next) {
                        var val = e.value;
                        if (filter(val))
                            res.push(val);
                    }
            }
            return res;
        };
        Hashtable.prototype.countFiltered = function (filter) {
            var count = 0;
            if (this.entries) {
                for (var i = 0; i < this.entries.length; ++i)
                    for (var e = this.entries[i]; e; e = e.next) {
                        var val = e.value;
                        if (filter(val))
                            count = count + 1;
                    }
            }
            return count;
        };
        Hashtable.prototype.set = function (k, v) {
            var e = this.lookup(k, true);
            e.value = v;
        };
        Hashtable.prototype.get = function (k) {
            var e = this.lookup(k);
            if (!e)
                return undefined;
            return e.value;
        };
        Hashtable.prototype.clear = function () {
            this.entries = null;
            this.entryCount = 0;
        };
        Hashtable.stringHash = function (s) {
            var res = 5381;
            for (var i = 0; i < s.length; ++i)
                res = (((res + (res << 5)) | 0) + s.charCodeAt(i)) | 0;
            return res;
        };
        Hashtable.stringEq = function (a, b) {
            return a == b;
        };
        Hashtable.forStrings = function () {
            return new Hashtable(Hashtable.stringHash, Hashtable.stringEq);
        };
        Hashtable.jsonHash = function (v) {
            return Hashtable.stringHash(JSON.stringify(v));
        };
        Hashtable.jsonEq = function (a, b) {
            return (a == b) || JSON.stringify(a) == JSON.stringify(b);
        };
        Hashtable.forJson = function () {
            return new Hashtable(Hashtable.jsonHash, Hashtable.jsonEq);
        };
        Hashtable.primeSizes = [13, 29, 59, 127, 257, 521, 1049, 2099, 4201, 8419, 16843, 33703, 67409, 134837, 269683, 539389, 1078787, 2157587, 4315183, 8630387, 17260781, 34521589, 69043189, 138086407, 276172823, 552345671, 1104691373, 2209382761];
        return Hashtable;
    })();
    TDev.Hashtable = Hashtable;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    (function (Ticks) {
        Ticks[Ticks["noEvent"] = 0] = "noEvent";
        Ticks[Ticks["mainInit"] = 1] = "mainInit";
        Ticks[Ticks["mainHashChange"] = 2] = "mainHashChange";
        Ticks[Ticks["mainKeyEvent"] = 3] = "mainKeyEvent";
        Ticks[Ticks["mainShortcutKeyEvent"] = 4] = "mainShortcutKeyEvent";
        Ticks[Ticks["mainResetWorld"] = 5] = "mainResetWorld";
        Ticks[Ticks["artSoundPreviewPlay"] = 6] = "artSoundPreviewPlay";
        Ticks[Ticks["docsEdit"] = 7] = "docsEdit";
        Ticks[Ticks["exportAzure"] = 8] = "exportAzure";
        Ticks[Ticks["exportCordova"] = 9] = "exportCordova";
        Ticks[Ticks["exportHTML5"] = 10] = "exportHTML5";
        Ticks[Ticks["scriptPropsIconArt"] = 11] = "scriptPropsIconArt";
        Ticks[Ticks["scriptPropsSplashArt"] = 12] = "scriptPropsSplashArt";
        Ticks[Ticks["hourOfCodeDoneStep"] = 13] = "hourOfCodeDoneStep";
        Ticks[Ticks["hourOfCodeKeepCoding"] = 14] = "hourOfCodeKeepCoding";
        Ticks[Ticks["hourOfCodeConfirm"] = 15] = "hourOfCodeConfirm";
        Ticks[Ticks["hourOfCodeDone"] = 16] = "hourOfCodeDone";
        Ticks[Ticks["hourOfCodeMore"] = 17] = "hourOfCodeMore";
        Ticks[Ticks["hourOfCodeFinal"] = 18] = "hourOfCodeFinal";
        Ticks[Ticks["tutorialStart"] = 19] = "tutorialStart";
        Ticks[Ticks["tutorialEnd"] = 20] = "tutorialEnd";
        Ticks[Ticks["tutorialTranslateSplash"] = 21] = "tutorialTranslateSplash";
        Ticks[Ticks["tutorialTranslateStep"] = 22] = "tutorialTranslateStep";
        Ticks[Ticks["tutorialTranslateScript"] = 23] = "tutorialTranslateScript";
        Ticks[Ticks["tutorialKeepEditing"] = 24] = "tutorialKeepEditing";
        Ticks[Ticks["tutorialMoreTutorials"] = 25] = "tutorialMoreTutorials";
        Ticks[Ticks["tutorialNextStep"] = 26] = "tutorialNextStep";
        Ticks[Ticks["dodStart"] = 27] = "dodStart";
        Ticks[Ticks["dodDrop"] = 28] = "dodDrop";
        Ticks[Ticks["dodWrongTarget"] = 29] = "dodWrongTarget";
        Ticks[Ticks["cordovaBuild"] = 30] = "cordovaBuild";
        Ticks[Ticks["translateDocTopic"] = 31] = "translateDocTopic";
        Ticks[Ticks["legalNoticeSignIn"] = 32] = "legalNoticeSignIn";
        Ticks[Ticks["legalNoticeAgree"] = 33] = "legalNoticeAgree";
        Ticks[Ticks["calcAddMissingArgs"] = 34] = "calcAddMissingArgs";
        Ticks[Ticks["calcBackspace"] = 35] = "calcBackspace";
        Ticks[Ticks["calcCopy"] = 36] = "calcCopy";
        Ticks[Ticks["calcCut"] = 37] = "calcCut";
        Ticks[Ticks["calcDedicatedOp"] = 38] = "calcDedicatedOp";
        Ticks[Ticks["calcEdit"] = 39] = "calcEdit";
        Ticks[Ticks["calcEditString"] = 40] = "calcEditString";
        Ticks[Ticks["calcExtract"] = 41] = "calcExtract";
        Ticks[Ticks["calcPromoteToParameter"] = 42] = "calcPromoteToParameter";
        Ticks[Ticks["calcGoToDef"] = 43] = "calcGoToDef";
        Ticks[Ticks["calcFindRefs"] = 44] = "calcFindRefs";
        Ticks[Ticks["calcAddDataVar"] = 45] = "calcAddDataVar";
        Ticks[Ticks["calcUnselect"] = 46] = "calcUnselect";
        Ticks[Ticks["calcExtend"] = 47] = "calcExtend";
        Ticks[Ticks["calcReplaceInScript"] = 48] = "calcReplaceInScript";
        Ticks[Ticks["calcReplaceInSelection"] = 49] = "calcReplaceInSelection";
        Ticks[Ticks["calcReplaceInAction"] = 50] = "calcReplaceInAction";
        Ticks[Ticks["calcInsertAssignment"] = 51] = "calcInsertAssignment";
        Ticks[Ticks["calcInsertString"] = 52] = "calcInsertString";
        Ticks[Ticks["calcIntelliButton"] = 53] = "calcIntelliButton";
        Ticks[Ticks["calcIntelliButton0"] = 54] = "calcIntelliButton0";
        Ticks[Ticks["calcIntelliButton1"] = 55] = "calcIntelliButton1";
        Ticks[Ticks["calcIntelliButton2"] = 56] = "calcIntelliButton2";
        Ticks[Ticks["calcIntelliButton3"] = 57] = "calcIntelliButton3";
        Ticks[Ticks["calcIntelliButton4"] = 58] = "calcIntelliButton4";
        Ticks[Ticks["calcIntelliButton5plus"] = 59] = "calcIntelliButton5plus";
        Ticks[Ticks["calcIntelliLiteral"] = 60] = "calcIntelliLiteral";
        Ticks[Ticks["calcIntelliLocal"] = 61] = "calcIntelliLocal";
        Ticks[Ticks["calcIntelliProperty"] = 62] = "calcIntelliProperty";
        Ticks[Ticks["calcIntelliPropertyPrimary"] = 63] = "calcIntelliPropertyPrimary";
        Ticks[Ticks["calcIntelliSingleton"] = 64] = "calcIntelliSingleton";
        Ticks[Ticks["calcIntelliLibrary"] = 65] = "calcIntelliLibrary";
        Ticks[Ticks["calcIntelliResource"] = 66] = "calcIntelliResource";
        Ticks[Ticks["calcKeyboardSearch"] = 67] = "calcKeyboardSearch";
        Ticks[Ticks["calcMoveCursorLeft"] = 68] = "calcMoveCursorLeft";
        Ticks[Ticks["calcMoveCursorRight"] = 69] = "calcMoveCursorRight";
        Ticks[Ticks["calcNewLine"] = 70] = "calcNewLine";
        Ticks[Ticks["calcNextIntelliTopPage"] = 71] = "calcNextIntelliTopPage";
        Ticks[Ticks["calcNextIntelliPageSearch"] = 72] = "calcNextIntelliPageSearch";
        Ticks[Ticks["calcNextIntelliPage"] = 73] = "calcNextIntelliPage";
        Ticks[Ticks["calcNextIntelliPage0"] = 74] = "calcNextIntelliPage0";
        Ticks[Ticks["calcNextIntelliPage1"] = 75] = "calcNextIntelliPage1";
        Ticks[Ticks["calcNextIntelliPage2"] = 76] = "calcNextIntelliPage2";
        Ticks[Ticks["calcNextIntelliPage3"] = 77] = "calcNextIntelliPage3";
        Ticks[Ticks["calcNextIntelliPage4"] = 78] = "calcNextIntelliPage4";
        Ticks[Ticks["calcNextIntelliPage5plus"] = 79] = "calcNextIntelliPage5plus";
        Ticks[Ticks["calcAsync"] = 80] = "calcAsync";
        Ticks[Ticks["calcAwait"] = 81] = "calcAwait";
        Ticks[Ticks["calcNot"] = 82] = "calcNot";
        Ticks[Ticks["calcNumber"] = 83] = "calcNumber";
        Ticks[Ticks["calcPaste"] = 84] = "calcPaste";
        Ticks[Ticks["calcPickColor"] = 85] = "calcPickColor";
        Ticks[Ticks["calcPickNumber"] = 86] = "calcPickNumber";
        Ticks[Ticks["calcDemoteIntoLocal"] = 87] = "calcDemoteIntoLocal";
        Ticks[Ticks["calcPromoteIntoGlobal"] = 88] = "calcPromoteIntoGlobal";
        Ticks[Ticks["calcPromoteIntoField"] = 89] = "calcPromoteIntoField";
        Ticks[Ticks["calcRenameLocal"] = 90] = "calcRenameLocal";
        Ticks[Ticks["calcRenameProperty"] = 91] = "calcRenameProperty";
        Ticks[Ticks["calcSearchBack"] = 92] = "calcSearchBack";
        Ticks[Ticks["calcSearchRun"] = 93] = "calcSearchRun";
        Ticks[Ticks["calcSearchCompile"] = 94] = "calcSearchCompile";
        Ticks[Ticks["calcSimplify"] = 95] = "calcSimplify";
        Ticks[Ticks["calcStrip"] = 96] = "calcStrip";
        Ticks[Ticks["calcSpecialKey"] = 97] = "calcSpecialKey";
        Ticks[Ticks["calcStartSearch"] = 98] = "calcStartSearch";
        Ticks[Ticks["calcStoreInVar"] = 99] = "calcStoreInVar";
        Ticks[Ticks["calcSwapBoolean"] = 100] = "calcSwapBoolean";
        Ticks[Ticks["calcSwapAsync"] = 101] = "calcSwapAsync";
        Ticks[Ticks["calcIntelliAsync"] = 102] = "calcIntelliAsync";
        Ticks[Ticks["calcSwitchToNormal"] = 103] = "calcSwitchToNormal";
        Ticks[Ticks["calcSwitchToNumber"] = 104] = "calcSwitchToNumber";
        Ticks[Ticks["calcTrueFalse"] = 105] = "calcTrueFalse";
        Ticks[Ticks["calcUndo"] = 106] = "calcUndo";
        Ticks[Ticks["calcGoToBoxProperty"] = 107] = "calcGoToBoxProperty";
        Ticks[Ticks["calcAddBoxProperty"] = 108] = "calcAddBoxProperty";
        Ticks[Ticks["calcInsertStringParamterValue"] = 109] = "calcInsertStringParamterValue";
        Ticks[Ticks["calcHelp"] = 110] = "calcHelp";
        Ticks[Ticks["calcHelpOverlay"] = 111] = "calcHelpOverlay";
        Ticks[Ticks["calcElseIf"] = 112] = "calcElseIf";
        Ticks[Ticks["calcUnElseIf"] = 113] = "calcUnElseIf";
        Ticks[Ticks["calcBindGlobal"] = 114] = "calcBindGlobal";
        Ticks[Ticks["calcFixItAtomic"] = 115] = "calcFixItAtomic";
        Ticks[Ticks["calcEditArt"] = 116] = "calcEditArt";
        Ticks[Ticks["calcAddOptionalParameter"] = 117] = "calcAddOptionalParameter";
        Ticks[Ticks["calcChangeOptionalParameter"] = 118] = "calcChangeOptionalParameter";
        Ticks[Ticks["codeAddAbove"] = 119] = "codeAddAbove";
        Ticks[Ticks["codeAddBelow"] = 120] = "codeAddBelow";
        Ticks[Ticks["codeShow"] = 121] = "codeShow";
        Ticks[Ticks["codeContinue"] = 122] = "codeContinue";
        Ticks[Ticks["codeReturn"] = 123] = "codeReturn";
        Ticks[Ticks["codeBreak"] = 124] = "codeBreak";
        Ticks[Ticks["codeBoxed"] = 125] = "codeBoxed";
        Ticks[Ticks["codeCopy"] = 126] = "codeCopy";
        Ticks[Ticks["codeCopySelection"] = 127] = "codeCopySelection";
        Ticks[Ticks["codeDeleteSelection"] = 128] = "codeDeleteSelection";
        Ticks[Ticks["codeCut"] = 129] = "codeCut";
        Ticks[Ticks["codeCutSelection"] = 130] = "codeCutSelection";
        Ticks[Ticks["codeCycleSidePane"] = 131] = "codeCycleSidePane";
        Ticks[Ticks["codeCycleSidePaneFull"] = 132] = "codeCycleSidePaneFull";
        Ticks[Ticks["codeExtractAction"] = 133] = "codeExtractAction";
        Ticks[Ticks["codeFocusSidePane"] = 134] = "codeFocusSidePane";
        Ticks[Ticks["codeFocusSidePaneFull"] = 135] = "codeFocusSidePaneFull";
        Ticks[Ticks["codeFor"] = 136] = "codeFor";
        Ticks[Ticks["codeForEach"] = 137] = "codeForEach";
        Ticks[Ticks["codeHub"] = 138] = "codeHub";
        Ticks[Ticks["codeIf"] = 139] = "codeIf";
        Ticks[Ticks["codeMoveLeft"] = 140] = "codeMoveLeft";
        Ticks[Ticks["codeNewVar"] = 141] = "codeNewVar";
        Ticks[Ticks["codePaste"] = 142] = "codePaste";
        Ticks[Ticks["codeRun"] = 143] = "codeRun";
        Ticks[Ticks["codeResume"] = 144] = "codeResume";
        Ticks[Ticks["codeStartSelection"] = 145] = "codeStartSelection";
        Ticks[Ticks["codeSurround"] = 146] = "codeSurround";
        Ticks[Ticks["codeUndo"] = 147] = "codeUndo";
        Ticks[Ticks["codeSplit"] = 148] = "codeSplit";
        Ticks[Ticks["codeWhile"] = 149] = "codeWhile";
        Ticks[Ticks["codeUninstallScript"] = 150] = "codeUninstallScript";
        Ticks[Ticks["codeBackFromSearch"] = 151] = "codeBackFromSearch";
        Ticks[Ticks["actionPropPrivate"] = 152] = "actionPropPrivate";
        Ticks[Ticks["actionPropTest"] = 153] = "actionPropTest";
        Ticks[Ticks["actionPropAtomic"] = 154] = "actionPropAtomic";
        Ticks[Ticks["siteMenuCreateCode"] = 155] = "siteMenuCreateCode";
        Ticks[Ticks["siteMenuImportCode"] = 156] = "siteMenuImportCode";
        Ticks[Ticks["siteMenuGroups"] = 157] = "siteMenuGroups";
        Ticks[Ticks["siteMenuTutorials"] = 158] = "siteMenuTutorials";
        Ticks[Ticks["siteMenuProjects"] = 159] = "siteMenuProjects";
        Ticks[Ticks["siteMenuHome"] = 160] = "siteMenuHome";
        Ticks[Ticks["siteMenuHelp"] = 161] = "siteMenuHelp";
        Ticks[Ticks["siteMenuGettingStarted"] = 162] = "siteMenuGettingStarted";
        Ticks[Ticks["siteMenuMyScripts"] = 163] = "siteMenuMyScripts";
        Ticks[Ticks["siteMenuSignIn"] = 164] = "siteMenuSignIn";
        Ticks[Ticks["siteMenuProfile"] = 165] = "siteMenuProfile";
        Ticks[Ticks["siteMenuChannels"] = 166] = "siteMenuChannels";
        Ticks[Ticks["btnPaste"] = 167] = "btnPaste";
        Ticks[Ticks["btnCopy"] = 168] = "btnCopy";
        Ticks[Ticks["btnCut"] = 169] = "btnCut";
        Ticks[Ticks["btnSelect"] = 170] = "btnSelect";
        Ticks[Ticks["btnTryFix"] = 171] = "btnTryFix";
        Ticks[Ticks["btnUndoFix"] = 172] = "btnUndoFix";
        Ticks[Ticks["btnAddUp"] = 173] = "btnAddUp";
        Ticks[Ticks["btnAddDown"] = 174] = "btnAddDown";
        Ticks[Ticks["btnMoveLeft"] = 175] = "btnMoveLeft";
        Ticks[Ticks["btnBreakpoint"] = 176] = "btnBreakpoint";
        Ticks[Ticks["btnChangeKind"] = 177] = "btnChangeKind";
        Ticks[Ticks["calcBtnBackspace"] = 178] = "calcBtnBackspace";
        Ticks[Ticks["calcBtnUndo"] = 179] = "calcBtnUndo";
        Ticks[Ticks["calcBtnNumberKeypad"] = 180] = "calcBtnNumberKeypad";
        Ticks[Ticks["calcBtnMiscKeypad"] = 181] = "calcBtnMiscKeypad";
        Ticks[Ticks["calcBtnNormalKeypad"] = 182] = "calcBtnNormalKeypad";
        Ticks[Ticks["calcBtnApiSearch"] = 183] = "calcBtnApiSearch";
        Ticks[Ticks["editBtnSideSearch"] = 184] = "editBtnSideSearch";
        Ticks[Ticks["chooseCancel"] = 185] = "chooseCancel";
        Ticks[Ticks["editTapBelow"] = 186] = "editTapBelow";
        Ticks[Ticks["coverageShown"] = 187] = "coverageShown";
        Ticks[Ticks["coverageOpenInEditor"] = 188] = "coverageOpenInEditor";
        Ticks[Ticks["coverageBucketSurveyActionEdit"] = 189] = "coverageBucketSurveyActionEdit";
        Ticks[Ticks["coverageBucketSurveyStatementEdit"] = 190] = "coverageBucketSurveyStatementEdit";
        Ticks[Ticks["coverageBucketSurveyDebugger"] = 191] = "coverageBucketSurveyDebugger";
        Ticks[Ticks["coverageBucketSurveyBreakpoint"] = 192] = "coverageBucketSurveyBreakpoint";
        Ticks[Ticks["coverageBucketSurveyExceededSuccessfully"] = 193] = "coverageBucketSurveyExceededSuccessfully";
        Ticks[Ticks["profileShown"] = 194] = "profileShown";
        Ticks[Ticks["profileOpenInEditor"] = 195] = "profileOpenInEditor";
        Ticks[Ticks["debuggerExit"] = 196] = "debuggerExit";
        Ticks[Ticks["debuggerContinue"] = 197] = "debuggerContinue";
        Ticks[Ticks["debuggerStepIn"] = 198] = "debuggerStepIn";
        Ticks[Ticks["debuggerStepOver"] = 199] = "debuggerStepOver";
        Ticks[Ticks["debuggerStepOut"] = 200] = "debuggerStepOut";
        Ticks[Ticks["debuggerToggleBreakpoint"] = 201] = "debuggerToggleBreakpoint";
        Ticks[Ticks["debuggerViewInit"] = 202] = "debuggerViewInit";
        Ticks[Ticks["debuggerPauseWall"] = 203] = "debuggerPauseWall";
        Ticks[Ticks["debuggerShowValues"] = 204] = "debuggerShowValues";
        Ticks[Ticks["debuggerShowStack"] = 205] = "debuggerShowStack";
        Ticks[Ticks["debuggerGotoWall"] = 206] = "debuggerGotoWall";
        Ticks[Ticks["debuggerGotoCurrent"] = 207] = "debuggerGotoCurrent";
        Ticks[Ticks["debuggerAppLog"] = 208] = "debuggerAppLog";
        Ticks[Ticks["debuggerHelp"] = 209] = "debuggerHelp";
        Ticks[Ticks["debuggerValueClicked"] = 210] = "debuggerValueClicked";
        Ticks[Ticks["debuggerKeyboardEvent"] = 211] = "debuggerKeyboardEvent";
        Ticks[Ticks["editorTutorialClose"] = 212] = "editorTutorialClose";
        Ticks[Ticks["editorTutorialNext"] = 213] = "editorTutorialNext";
        Ticks[Ticks["editorTutorialPrevious"] = 214] = "editorTutorialPrevious";
        Ticks[Ticks["externalSave"] = 215] = "externalSave";
        Ticks[Ticks["externalLoad"] = 216] = "externalLoad";
        Ticks[Ticks["externalCompile"] = 217] = "externalCompile";
        Ticks[Ticks["externalRun"] = 218] = "externalRun";
        Ticks[Ticks["sideAddAction"] = 219] = "sideAddAction";
        Ticks[Ticks["sideAddActionTest"] = 220] = "sideAddActionTest";
        Ticks[Ticks["sideAddActionTypeDef"] = 221] = "sideAddActionTypeDef";
        Ticks[Ticks["sideAddEvent"] = 222] = "sideAddEvent";
        Ticks[Ticks["sideAddLibrary"] = 223] = "sideAddLibrary";
        Ticks[Ticks["sideAddPage"] = 224] = "sideAddPage";
        Ticks[Ticks["sideAddRecord"] = 225] = "sideAddRecord";
        Ticks[Ticks["sideAddObject"] = 226] = "sideAddObject";
        Ticks[Ticks["sideAddTable"] = 227] = "sideAddTable";
        Ticks[Ticks["sideAddIndex"] = 228] = "sideAddIndex";
        Ticks[Ticks["sideAddDecorator"] = 229] = "sideAddDecorator";
        Ticks[Ticks["sideAddResource"] = 230] = "sideAddResource";
        Ticks[Ticks["sideAddVariable"] = 231] = "sideAddVariable";
        Ticks[Ticks["sideAddAnything"] = 232] = "sideAddAnything";
        Ticks[Ticks["sideHelp"] = 233] = "sideHelp";
        Ticks[Ticks["sideBraces"] = 234] = "sideBraces";
        Ticks[Ticks["sideDebug"] = 235] = "sideDebug";
        Ticks[Ticks["sideLogs"] = 236] = "sideLogs";
        Ticks[Ticks["sideErrors"] = 237] = "sideErrors";
        Ticks[Ticks["sideDeployWebSite"] = 238] = "sideDeployWebSite";
        Ticks[Ticks["sidePlugins"] = 239] = "sidePlugins";
        Ticks[Ticks["sideButtonPlugin"] = 240] = "sideButtonPlugin";
        Ticks[Ticks["sidePreview"] = 241] = "sidePreview";
        Ticks[Ticks["sideHistory"] = 242] = "sideHistory";
        Ticks[Ticks["sideHistoryGoTo"] = 243] = "sideHistoryGoTo";
        Ticks[Ticks["sidePaste"] = 244] = "sidePaste";
        Ticks[Ticks["sideScript"] = 245] = "sideScript";
        Ticks[Ticks["sideScriptGoToDecl"] = 246] = "sideScriptGoToDecl";
        Ticks[Ticks["sideSearch"] = 247] = "sideSearch";
        Ticks[Ticks["sideSearchGoToDecl"] = 248] = "sideSearchGoToDecl";
        Ticks[Ticks["sideSearchGoToStmt"] = 249] = "sideSearchGoToStmt";
        Ticks[Ticks["sidePublish"] = 250] = "sidePublish";
        Ticks[Ticks["sideShare"] = 251] = "sideShare";
        Ticks[Ticks["sideDisconnect"] = 252] = "sideDisconnect";
        Ticks[Ticks["sideRun"] = 253] = "sideRun";
        Ticks[Ticks["sideCut"] = 254] = "sideCut";
        Ticks[Ticks["sideCopy"] = 255] = "sideCopy";
        Ticks[Ticks["sideDelete"] = 256] = "sideDelete";
        Ticks[Ticks["sideFindRefs"] = 257] = "sideFindRefs";
        Ticks[Ticks["sideActionHeaderInit"] = 258] = "sideActionHeaderInit";
        Ticks[Ticks["sideCommentInit"] = 259] = "sideCommentInit";
        Ticks[Ticks["sideParameterInit"] = 260] = "sideParameterInit";
        Ticks[Ticks["sideResetSidePane"] = 261] = "sideResetSidePane";
        Ticks[Ticks["sideInlineActionInit"] = 262] = "sideInlineActionInit";
        Ticks[Ticks["sideExport"] = 263] = "sideExport";
        Ticks[Ticks["sideAllTests"] = 264] = "sideAllTests";
        Ticks[Ticks["sideTestOne"] = 265] = "sideTestOne";
        Ticks[Ticks["sideEditLibrary"] = 266] = "sideEditLibrary";
        Ticks[Ticks["sideEditString"] = 267] = "sideEditString";
        Ticks[Ticks["sideUpdate"] = 268] = "sideUpdate";
        Ticks[Ticks["sideUpdateOne"] = 269] = "sideUpdateOne";
        Ticks[Ticks["sideActionAddInput"] = 270] = "sideActionAddInput";
        Ticks[Ticks["sideActionAddOutput"] = 271] = "sideActionAddOutput";
        Ticks[Ticks["sideTutorialCancel"] = 272] = "sideTutorialCancel";
        Ticks[Ticks["sideTutorialRedisplay"] = 273] = "sideTutorialRedisplay";
        Ticks[Ticks["sideMoreOptions"] = 274] = "sideMoreOptions";
        Ticks[Ticks["appsCreateAzureWebsite"] = 275] = "appsCreateAzureWebsite";
        Ticks[Ticks["appsDeployWebsite"] = 276] = "appsDeployWebsite";
        Ticks[Ticks["pluginStop"] = 277] = "pluginStop";
        Ticks[Ticks["pluginRunOperation"] = 278] = "pluginRunOperation";
        Ticks[Ticks["pluginAddMore"] = 279] = "pluginAddMore";
        Ticks[Ticks["pluginRunAnnotationOperation"] = 280] = "pluginRunAnnotationOperation";
        Ticks[Ticks["searchApiSynthesis"] = 281] = "searchApiSynthesis";
        Ticks[Ticks["searchApiSearchArt"] = 282] = "searchApiSearchArt";
        Ticks[Ticks["searchApiSearchLib"] = 283] = "searchApiSearchLib";
        Ticks[Ticks["searchApiSearchAuto"] = 284] = "searchApiSearchAuto";
        Ticks[Ticks["searchApiInsertArt"] = 285] = "searchApiInsertArt";
        Ticks[Ticks["searchApiUploadArt"] = 286] = "searchApiUploadArt";
        Ticks[Ticks["searchApiInsertLib"] = 287] = "searchApiInsertLib";
        Ticks[Ticks["wallBack"] = 288] = "wallBack";
        Ticks[Ticks["wallJS"] = 289] = "wallJS";
        Ticks[Ticks["wallEdit"] = 290] = "wallEdit";
        Ticks[Ticks["wallReplay"] = 291] = "wallReplay";
        Ticks[Ticks["wallScreenshot"] = 292] = "wallScreenshot";
        Ticks[Ticks["wallLogs"] = 293] = "wallLogs";
        Ticks[Ticks["wallSerial"] = 294] = "wallSerial";
        Ticks[Ticks["wallStop"] = 295] = "wallStop";
        Ticks[Ticks["wallStopForce"] = 296] = "wallStopForce";
        Ticks[Ticks["wallPause"] = 297] = "wallPause";
        Ticks[Ticks["wallResume"] = 298] = "wallResume";
        Ticks[Ticks["wallRun"] = 299] = "wallRun";
        Ticks[Ticks["wallTraces"] = 300] = "wallTraces";
        Ticks[Ticks["wallAddHeart"] = 301] = "wallAddHeart";
        Ticks[Ticks["wallRemoveHeart"] = 302] = "wallRemoveHeart";
        Ticks[Ticks["commentAttach"] = 303] = "commentAttach";
        Ticks[Ticks["commentBugTracking"] = 304] = "commentBugTracking";
        Ticks[Ticks["coreRun"] = 305] = "coreRun";
        Ticks[Ticks["coreNativeCompile"] = 306] = "coreNativeCompile";
        Ticks[Ticks["coreResume"] = 307] = "coreResume";
        Ticks[Ticks["coreRerun"] = 308] = "coreRerun";
        Ticks[Ticks["corePublishHidden"] = 309] = "corePublishHidden";
        Ticks[Ticks["corePublishPublic"] = 310] = "corePublishPublic";
        Ticks[Ticks["runtimePlayAgain"] = 311] = "runtimePlayAgain";
        Ticks[Ticks["runtimeBack"] = 312] = "runtimeBack";
        Ticks[Ticks["appUpdateAvailable"] = 313] = "appUpdateAvailable";
        Ticks[Ticks["appNoUpdate"] = 314] = "appNoUpdate";
        Ticks[Ticks["appQuickUpdate"] = 315] = "appQuickUpdate";
        Ticks[Ticks["appUpdate"] = 316] = "appUpdate";
        Ticks[Ticks["editorUpdateScript"] = 317] = "editorUpdateScript";
        Ticks[Ticks["editorUpdateLibrary"] = 318] = "editorUpdateLibrary";
        Ticks[Ticks["editorRunWithProfiling"] = 319] = "editorRunWithProfiling";
        Ticks[Ticks["editorRunWithCoverage"] = 320] = "editorRunWithCoverage";
        Ticks[Ticks["editorRunAsMinion"] = 321] = "editorRunAsMinion";
        Ticks[Ticks["viewActionInit"] = 322] = "viewActionInit";
        Ticks[Ticks["viewLibraryRefInit"] = 323] = "viewLibraryRefInit";
        Ticks[Ticks["viewRecordInit"] = 324] = "viewRecordInit";
        Ticks[Ticks["viewScriptInit"] = 325] = "viewScriptInit";
        Ticks[Ticks["viewVariableInit"] = 326] = "viewVariableInit";
        Ticks[Ticks["hubCreateScript"] = 327] = "hubCreateScript";
        Ticks[Ticks["hubCreateGame"] = 328] = "hubCreateGame";
        Ticks[Ticks["hubCreateGroup"] = 329] = "hubCreateGroup";
        Ticks[Ticks["hubCreateList"] = 330] = "hubCreateList";
        Ticks[Ticks["hubJoinGroup"] = 331] = "hubJoinGroup";
        Ticks[Ticks["hubUploadPicture"] = 332] = "hubUploadPicture";
        Ticks[Ticks["hubUploadSound"] = 333] = "hubUploadSound";
        Ticks[Ticks["hubGameTutorial"] = 334] = "hubGameTutorial";
        Ticks[Ticks["hubWinStore"] = 335] = "hubWinStore";
        Ticks[Ticks["hubDocs"] = 336] = "hubDocs";
        Ticks[Ticks["hubFirstTutorial"] = 337] = "hubFirstTutorial";
        Ticks[Ticks["hubDocsTutorial"] = 338] = "hubDocsTutorial";
        Ticks[Ticks["hubBasicEditorVideo"] = 339] = "hubBasicEditorVideo";
        Ticks[Ticks["hubBasicEditorVideoVoice"] = 340] = "hubBasicEditorVideoVoice";
        Ticks[Ticks["hubBasicEditorVideoSubtitles"] = 341] = "hubBasicEditorVideoSubtitles";
        Ticks[Ticks["hubBeginnersGettingStarted"] = 342] = "hubBeginnersGettingStarted";
        Ticks[Ticks["hubCCGA"] = 343] = "hubCCGA";
        Ticks[Ticks["hubChatSearch"] = 344] = "hubChatSearch";
        Ticks[Ticks["hubChooseSkill"] = 345] = "hubChooseSkill";
        Ticks[Ticks["hubDevBootCamp"] = 346] = "hubDevBootCamp";
        Ticks[Ticks["hubDocsApi"] = 347] = "hubDocsApi";
        Ticks[Ticks["hubDocsWhatsNew"] = 348] = "hubDocsWhatsNew";
        Ticks[Ticks["hubAdvancedEditorVideo"] = 349] = "hubAdvancedEditorVideo";
        Ticks[Ticks["hubSeeMoreMyScripts"] = 350] = "hubSeeMoreMyScripts";
        Ticks[Ticks["hubSeeMoreNewScripts"] = 351] = "hubSeeMoreNewScripts";
        Ticks[Ticks["hubSeeMoreArt"] = 352] = "hubSeeMoreArt";
        Ticks[Ticks["hubSeeMoreUsers"] = 353] = "hubSeeMoreUsers";
        Ticks[Ticks["hubSeeMoreCloudOther"] = 354] = "hubSeeMoreCloudOther";
        Ticks[Ticks["hubSeeMoreShowcase"] = 355] = "hubSeeMoreShowcase";
        Ticks[Ticks["hubSeeMoreTutorials"] = 356] = "hubSeeMoreTutorials";
        Ticks[Ticks["hubSeeMoreTopScripts"] = 357] = "hubSeeMoreTopScripts";
        Ticks[Ticks["hubSeeMoreDocs"] = 358] = "hubSeeMoreDocs";
        Ticks[Ticks["hubSeeMoreCloud"] = 359] = "hubSeeMoreCloud";
        Ticks[Ticks["hubSeeMoreGroups"] = 360] = "hubSeeMoreGroups";
        Ticks[Ticks["hubSeeMoreLists"] = 361] = "hubSeeMoreLists";
        Ticks[Ticks["hubMyScriptsShowcase"] = 362] = "hubMyScriptsShowcase";
        Ticks[Ticks["hubMyScriptsTemplate"] = 363] = "hubMyScriptsTemplate";
        Ticks[Ticks["hubNotifications"] = 364] = "hubNotifications";
        Ticks[Ticks["hubUpdates"] = 365] = "hubUpdates";
        Ticks[Ticks["hubDoUpdates"] = 366] = "hubDoUpdates";
        Ticks[Ticks["hubTests"] = 367] = "hubTests";
        Ticks[Ticks["hubShowcaseMgmt"] = 368] = "hubShowcaseMgmt";
        Ticks[Ticks["hubBenchmarks"] = 369] = "hubBenchmarks";
        Ticks[Ticks["hubForum"] = 370] = "hubForum";
        Ticks[Ticks["hubFacebook"] = 371] = "hubFacebook";
        Ticks[Ticks["hubTwitter"] = 372] = "hubTwitter";
        Ticks[Ticks["hubYouTube"] = 373] = "hubYouTube";
        Ticks[Ticks["hubSettings"] = 374] = "hubSettings";
        Ticks[Ticks["hubAbout"] = 375] = "hubAbout";
        Ticks[Ticks["hubHelp"] = 376] = "hubHelp";
        Ticks[Ticks["hubWrongTime"] = 377] = "hubWrongTime";
        Ticks[Ticks["hubTag"] = 378] = "hubTag";
        Ticks[Ticks["hubTagFromList"] = 379] = "hubTagFromList";
        Ticks[Ticks["hubFeedback"] = 380] = "hubFeedback";
        Ticks[Ticks["hubChooseWallpaper"] = 381] = "hubChooseWallpaper";
        Ticks[Ticks["changeSkillScriptProperties"] = 382] = "changeSkillScriptProperties";
        Ticks[Ticks["changeSkillActionProperties"] = 383] = "changeSkillActionProperties";
        Ticks[Ticks["changeSkillScriptExplorer"] = 384] = "changeSkillScriptExplorer";
        Ticks[Ticks["editorSkillBlock"] = 385] = "editorSkillBlock";
        Ticks[Ticks["editorSkillClassic"] = 386] = "editorSkillClassic";
        Ticks[Ticks["editorSkillCurly"] = 387] = "editorSkillCurly";
        Ticks[Ticks["groupCodeReset"] = 388] = "groupCodeReset";
        Ticks[Ticks["groupCodeNew"] = 389] = "groupCodeNew";
        Ticks[Ticks["groupCodeGet"] = 390] = "groupCodeGet";
        Ticks[Ticks["groupDelete"] = 391] = "groupDelete";
        Ticks[Ticks["groupLeave"] = 392] = "groupLeave";
        Ticks[Ticks["groupJoin"] = 393] = "groupJoin";
        Ticks[Ticks["groupAllowAnyoneToJoin"] = 394] = "groupAllowAnyoneToJoin";
        Ticks[Ticks["groupRequireInvitationCodeToJoin"] = 395] = "groupRequireInvitationCodeToJoin";
        Ticks[Ticks["groupChangePicture"] = 396] = "groupChangePicture";
        Ticks[Ticks["publishShareGroup"] = 397] = "publishShareGroup";
        Ticks[Ticks["browseEditInstall"] = 398] = "browseEditInstall";
        Ticks[Ticks["browseRunInstall"] = 399] = "browseRunInstall";
        Ticks[Ticks["browseRun"] = 400] = "browseRun";
        Ticks[Ticks["browseEdit"] = 401] = "browseEdit";
        Ticks[Ticks["browsePin"] = 402] = "browsePin";
        Ticks[Ticks["browseHeart"] = 403] = "browseHeart";
        Ticks[Ticks["browseUnHeart"] = 404] = "browseUnHeart";
        Ticks[Ticks["browseModerate"] = 405] = "browseModerate";
        Ticks[Ticks["browsePublish"] = 406] = "browsePublish";
        Ticks[Ticks["browseUninstall"] = 407] = "browseUninstall";
        Ticks[Ticks["browsePush"] = 408] = "browsePush";
        Ticks[Ticks["browseDiffBase"] = 409] = "browseDiffBase";
        Ticks[Ticks["browseConvertToTutorial"] = 410] = "browseConvertToTutorial";
        Ticks[Ticks["browseConvertToLesson"] = 411] = "browseConvertToLesson";
        Ticks[Ticks["browseAddScriptToList"] = 412] = "browseAddScriptToList";
        Ticks[Ticks["browseUpdate"] = 413] = "browseUpdate";
        Ticks[Ticks["browseSendPullRequest"] = 414] = "browseSendPullRequest";
        Ticks[Ticks["browseClone"] = 415] = "browseClone";
        Ticks[Ticks["browseSave"] = 416] = "browseSave";
        Ticks[Ticks["browseCreateCode"] = 417] = "browseCreateCode";
        Ticks[Ticks["browseImportCode"] = 418] = "browseImportCode";
        Ticks[Ticks["browsePublicationNotes"] = 419] = "browsePublicationNotes";
        Ticks[Ticks["browseListPointers"] = 420] = "browseListPointers";
        Ticks[Ticks["browseListBugs"] = 421] = "browseListBugs";
        Ticks[Ticks["browseListReleases"] = 422] = "browseListReleases";
        Ticks[Ticks["browseShare"] = 423] = "browseShare";
        Ticks[Ticks["browseListMyScripts"] = 424] = "browseListMyScripts";
        Ticks[Ticks["browseListNew"] = 425] = "browseListNew";
        Ticks[Ticks["browseListTop"] = 426] = "browseListTop";
        Ticks[Ticks["browseListShowcase"] = 427] = "browseListShowcase";
        Ticks[Ticks["browseListForum"] = 428] = "browseListForum";
        Ticks[Ticks["browseListDocs"] = 429] = "browseListDocs";
        Ticks[Ticks["browseListHelp"] = 430] = "browseListHelp";
        Ticks[Ticks["browseListGroups"] = 431] = "browseListGroups";
        Ticks[Ticks["browseListArt"] = 432] = "browseListArt";
        Ticks[Ticks["browseListMyArt"] = 433] = "browseListMyArt";
        Ticks[Ticks["browseListTags"] = 434] = "browseListTags";
        Ticks[Ticks["browseListSearch"] = 435] = "browseListSearch";
        Ticks[Ticks["browseListUsers"] = 436] = "browseListUsers";
        Ticks[Ticks["browseListLists"] = 437] = "browseListLists";
        Ticks[Ticks["browseFollowTopic"] = 438] = "browseFollowTopic";
        Ticks[Ticks["introSlideGetStarted"] = 439] = "introSlideGetStarted";
        Ticks[Ticks["introSlideLimitations"] = 440] = "introSlideLimitations";
        Ticks[Ticks["introSlideCreateApps"] = 441] = "introSlideCreateApps";
        Ticks[Ticks["introSlidePopCorn"] = 442] = "introSlidePopCorn";
        Ticks[Ticks["introSlideLogIn"] = 443] = "introSlideLogIn";
        Ticks[Ticks["introSlideDismiss"] = 444] = "introSlideDismiss";
        Ticks[Ticks["recordAddKey"] = 445] = "recordAddKey";
        Ticks[Ticks["recordAddValue"] = 446] = "recordAddValue";
        Ticks[Ticks["recordAddAction"] = 447] = "recordAddAction";
        Ticks[Ticks["recordPersTemporary"] = 448] = "recordPersTemporary";
        Ticks[Ticks["recordPersLocal"] = 449] = "recordPersLocal";
        Ticks[Ticks["recordPersCloud"] = 450] = "recordPersCloud";
        Ticks[Ticks["recordPersPartial"] = 451] = "recordPersPartial";
        Ticks[Ticks["recordExported"] = 452] = "recordExported";
        Ticks[Ticks["dbgEvent"] = 453] = "dbgEvent";
        Ticks[Ticks["dbgLogEvent"] = 454] = "dbgLogEvent";
        Ticks[Ticks["learnPlayVideo"] = 455] = "learnPlayVideo";
        Ticks[Ticks["learnBrowseDoc"] = 456] = "learnBrowseDoc";
        Ticks[Ticks["offlineLoginSync"] = 457] = "offlineLoginSync";
        Ticks[Ticks["offlineLoginSyncNoToken"] = 458] = "offlineLoginSyncNoToken";
        Ticks[Ticks["offlineLoginGettingStarted"] = 459] = "offlineLoginGettingStarted";
        Ticks[Ticks["offlineEnsureLogin"] = 460] = "offlineEnsureLogin";
        Ticks[Ticks["offlineEnsureLoginOk"] = 461] = "offlineEnsureLoginOk";
        Ticks[Ticks["translateNagDisplay"] = 462] = "translateNagDisplay";
        Ticks[Ticks["translateNagOk"] = 463] = "translateNagOk";
        Ticks[Ticks["benchmarksNagDisplay"] = 464] = "benchmarksNagDisplay";
        Ticks[Ticks["benchmarksNagDismiss"] = 465] = "benchmarksNagDismiss";
        Ticks[Ticks["benchmarksNagRunOne"] = 466] = "benchmarksNagRunOne";
        Ticks[Ticks["benchmarksNagRunSuite"] = 467] = "benchmarksNagRunSuite";
        Ticks[Ticks["songAlbumPlay"] = 468] = "songAlbumPlay";
        Ticks[Ticks["songPlay"] = 469] = "songPlay";
        Ticks[Ticks["warningNotificationTap"] = 470] = "warningNotificationTap";
        Ticks[Ticks["crashDialogEdit"] = 471] = "crashDialogEdit";
        Ticks[Ticks["crashDialogDebug"] = 472] = "crashDialogDebug";
        Ticks[Ticks["toLibNewLib"] = 473] = "toLibNewLib";
        Ticks[Ticks["toLibExistingLib"] = 474] = "toLibExistingLib";
        Ticks[Ticks["toLibOKtoMove"] = 475] = "toLibOKtoMove";
        Ticks[Ticks["toLibAdvanceSelectedToPending"] = 476] = "toLibAdvanceSelectedToPending";
        Ticks[Ticks["toLibMakeTheMove"] = 477] = "toLibMakeTheMove";
        Ticks[Ticks["toLibDiscardPending"] = 478] = "toLibDiscardPending";
        Ticks[Ticks["toLibExitToEditor"] = 479] = "toLibExitToEditor";
        Ticks[Ticks["collabFirstLoad"] = 480] = "collabFirstLoad";
        Ticks[Ticks["collabResume"] = 481] = "collabResume";
        Ticks[Ticks["collabRecordAst"] = 482] = "collabRecordAst";
        Ticks[Ticks["collabRealMerge"] = 483] = "collabRealMerge";
        Ticks[Ticks["collabPostChatMessage"] = 484] = "collabPostChatMessage";
        Ticks[Ticks["collabStartCollaboration"] = 485] = "collabStartCollaboration";
        Ticks[Ticks["collabStopCollaboration"] = 486] = "collabStopCollaboration";
        Ticks[Ticks["codeCompile"] = 487] = "codeCompile";
    })(TDev.Ticks || (TDev.Ticks = {}));
    var Ticks = TDev.Ticks;
    var Ticker;
    (function (Ticker) {
        var logMsgs = [];
        var logSz = 200;
        var logIdx = -1;
        var thresholdTime = -1;
        var dateStr = "";
        var sessionEvents = {};
        var disabled = false;
        var delay = 10;
        var chunkId = 1;
        var maxDelay = 300;
        var initialized = false;
        Ticker.mainJsName = "unknown";
        Ticker.fillEditorInfoBugReport;
        Ticker.fillEditorInfoTicksReport;
        function setDate() {
            var now = new Date();
            dateStr = TDev.Util.fmt("{0}.{1}.{2}", now.getFullYear(), now.getMonth() + 1, now.getDate());
            if (delay > maxDelay)
                delay = maxDelay;
            thresholdTime = now.getTime() + delay * 1000;
        }
        function disable() {
            disabled = true;
        }
        Ticker.disable = disable;
        function init() {
            if (/ckns_policy=..0/.test(document.cookie)) {
                disable();
                return;
            }
            var d = window.localStorage["ticksDelay"] * 1;
            if (d)
                delay = d;
            setDate();
            var archived = window.localStorage["archivedEvents"];
            if (archived) {
                var prevEvents;
                try {
                    prevEvents = JSON.parse(archived);
                }
                catch (e) {
                    TDev.Util.log("bogus JSON in archivedEvents: " + archived);
                    TDev.Util.check(false, "malformed JSON in archived events");
                    delete window.localStorage["archivedEvents"];
                }
                if (prevEvents) {
                    prevEvents.forEach(function (e) {
                        chunkId = Math.max(e.chunkId, chunkId);
                    });
                    chunkId++;
                    var last = prevEvents.peek();
                    if (!!last && last.dateStr == dateStr) {
                        sessionEvents = last.sessionEvents;
                        prevEvents.pop();
                        window.localStorage["archivedEvents"] = JSON.stringify(prevEvents);
                    }
                    sendOutEvents(prevEvents);
                }
            }
            usageTick();
            initialized = true;
        }
        Ticker.init = init;
        function saveCurrent(sendCurrent) {
            if (sendCurrent === void 0) { sendCurrent = false; }
            var prevEvents = [];
            var archived = window.localStorage["archivedEvents"];
            if (archived)
                prevEvents = JSON.parse(archived);
            prevEvents.push({
                sessionEvents: sessionEvents,
                dateStr: dateStr,
                chunkId: chunkId++
            });
            prevEvents = prevEvents.filter(function (e) { return !!e.dateStr; });
            if (prevEvents.length > 30)
                prevEvents = prevEvents.slice(prevEvents.length - 30);
            var newVal = JSON.stringify(prevEvents);
            if (newVal.length > 50000)
                newVal = "[]";
            window.localStorage["archivedEvents"] = newVal;
            if (sendCurrent && TDev.Cloud.hasAccessToken() && TDev.Cloud.isOnline())
                sendOutEvents(prevEvents);
        }
        Ticker.saveCurrent = saveCurrent;
        function checkDate() {
            if (TDev.Util.now() > thresholdTime) {
                setDate();
                saveCurrent(true);
                TDev.RT.Perf.saveCurrentAsync(true).done();
                if (delay < maxDelay) {
                    delay *= 1.1;
                    window.localStorage["ticksDelay"] = delay + "";
                }
                sessionEvents = {};
            }
        }
        function sendOutEvents(events) {
            if (events.length == 0)
                return;
            var currId = events[0].chunkId;
            var req = {
                dateStr: events[0].dateStr,
                sessionEvents: events[0].sessionEvents,
                platform: TDev.Browser.platformCaps,
                worldId: "",
                jsUrl: Ticker.mainJsName
            };
            if (Ticker.fillEditorInfoTicksReport)
                Ticker.fillEditorInfoTicksReport(req);
            function sendNextEvents() {
                var events = window.localStorage["archivedEvents"];
                if (events) {
                    var newEvents = JSON.parse(events);
                    window.localStorage["archivedEvents"] = JSON.stringify(newEvents.filter(function (t) { return t.chunkId != currId; }));
                    sendOutEvents(newEvents);
                }
            }
            if (Object.keys(req.sessionEvents).length == 0)
                sendNextEvents();
            else
                TDev.Cloud.postTicksAsync(req).done(function () { return sendNextEvents(); }, function (e) {
                });
        }
        function tickName(t) {
            return TDev.enumToString(Ticks, t);
        }
        Ticker.tickName = tickName;
        function tickN(t, v) {
            tick(t + TDev.Util.boundTo(0, v, 5));
        }
        Ticker.tickN = tickN;
        function dbg(f) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            var msg = TDev.Util.fmt_va(f, args);
            tick(453 /* dbgEvent */, msg);
        }
        Ticker.dbg = dbg;
        function localStorageState() {
            if (!window || !window.localStorage)
                return "";
            var l = window.localStorage;
            var r = "";
            for (var i = 0; i < l.length; ++i) {
                r += l.key(i) + " -> " + l[l.key(i)].length + ",  ";
            }
            return r;
        }
        Ticker.localStorageState = localStorageState;
        function mkReportId() {
            return "BuG" + (20000000000000 - Date.now()) + TDev.Random.uniqueId(12);
        }
        Ticker.mkReportId = mkReportId;
        function mkBugReport(err, ctx) {
            if (ctx === void 0) { ctx = ""; }
            var r = {
                exceptionConstructor: "(unknown)",
                exceptionMessage: "(unknown)",
                context: ctx,
                currentUrl: "",
                worldId: "",
                kind: "",
                scriptId: "",
                stackTrace: "",
                sourceURL: "",
                line: -1,
                eventTrace: "",
                userAgent: "",
                resolution: "",
                jsUrl: Ticker.mainJsName,
                timestamp: TDev.Util.now(),
                platform: [],
                attachments: [],
                tdVersion: TDev.Cloud.config.tdVersion || "",
                reportId: mkReportId(),
            };
            if (Ticker.fillEditorInfoBugReport)
                Ticker.fillEditorInfoBugReport(r);
            if (Array.isArray(err.bugAttachments))
                r.attachments.pushRange(err.bugAttachments);
            var meta = err.tdMeta;
            if (meta) {
                if (meta.reportId)
                    r.reportId = meta.reportId;
            }
            try {
                var isDatabaseError = TDev.Util.isError(err, function (e) { return e.isDatabaseError; });
                var isNetworkError = TDev.Util.isError(err, function (e) { return e.isNetworkError; });
                r.kind = isDatabaseError ? "databaseError" : isNetworkError ? "networkError" : "";
                if (!err)
                    r.exceptionMessage = "(null)";
                else if (err.message) {
                    r.exceptionMessage = err.message + "";
                    if (err.stack)
                        r.stackTrace = err.stack + "";
                    else if (err.sourceURL)
                        r.stackTrace = "@" + err.sourceURL + ":" + err.line;
                }
                else if (Array.isArray(err)) {
                    r.exceptionMessage = err.join("\n");
                }
                else {
                    r.exceptionMessage = err + "";
                }
                if (err && err.name && err.name != "Error")
                    r.exceptionConstructor = err.name;
                else
                    r.exceptionConstructor = r.exceptionMessage.substr(0, 40);
                if (isDatabaseError)
                    r.exceptionConstructor = "DB " + r.exceptionConstructor;
                if (/autotest-/.test(ctx))
                    r.exceptionConstructor = "TEST " + r.exceptionConstructor;
                if (/^bitvm/.test(ctx))
                    r.exceptionConstructor = "BITVM " + r.exceptionConstructor;
                if (r.exceptionMessage && /\[object /.test(r.exceptionMessage)) {
                    var msg = r.exceptionMessage;
                    var errorInfo = TDev.Util.getErrorInfo(err);
                    if (errorInfo)
                        msg += " " + errorInfo;
                    else
                        Object.keys(err).forEach(function (k) {
                            if (msg.length < 2000) {
                                msg += " " + k + ": '" + err[k] + "'";
                            }
                        });
                    r.exceptionMessage = msg;
                }
                if (/QUOTA/.test(r.exceptionMessage))
                    r.exceptionMessage += "  " + localStorageState();
                if (ctx != "custom")
                    Ticker.dbg("CRASH REPORT " + r.exceptionMessage);
                if (err.sourceURL)
                    r.sourceURL = err.sourceURL;
                if (err.line)
                    r.line = err.line;
            }
            catch (e) {
                debugger;
            }
            try {
                r.logMessages = TDev.Util.getLogMsgs();
                r.logMessages.reverse();
                var maxSize = 100000;
                var maxIter = 20;
                while (JSON.stringify(r.logMessages).length > maxSize) {
                    r.logMessages = r.logMessages.slice(0, Math.floor(r.logMessages.length / 2));
                    if (maxIter-- < 0) {
                        r.logMessages = [];
                        break;
                    }
                }
                r.eventTrace = "";
            }
            catch (e) {
                debugger;
            }
            if (ctx != "custom" && window.tdAppInsights)
                try {
                    window.tdAppInsights.trackException(err, r);
                }
                catch (e) {
                }
            return r;
        }
        Ticker.mkBugReport = mkBugReport;
        function bugReportToString(b, short) {
            if (short === void 0) { short = false; }
            var e = function (s) { return s.replace(/\r?\n/, " "); };
            var r = "Error: " + e(b.exceptionMessage) + "\n" + "URL: " + e(b.currentUrl) + " (script: " + e(b.scriptId) + ", context: " + e(b.context) + ")\n" + "JS-URL: " + e(b.jsUrl) + "\n" + "Platform: " + e(TDev.Browser.platformCaps.join(", ")) + "\n" + "UserAgent: " + e(b.userAgent) + " (resolution: " + e(b.resolution) + ")\n" + "Date: " + new Date(b.timestamp).toString() + "\n";
            if (!short)
                r += "\n" + "RecentEvents:\n" + b.eventTrace + "\n\n" + "StackTrace:\n" + b.stackTrace + "\n\n";
            return r;
        }
        Ticker.bugReportToString = bugReportToString;
        function bugReportForHash(b) {
            return b.exceptionMessage + " " + b.stackTrace;
        }
        Ticker.bugReportForHash = bugReportForHash;
        function rawTick(tn) {
            TDev.Util.log("TICK: " + tn);
            if (!initialized || disabled)
                return;
            checkDate();
            tn = tn.replace(/[^a-zA-Z_]/g, "_");
            if (shouldStoreTick(tn))
                if (sessionEvents[tn])
                    sessionEvents[tn]++;
                else
                    sessionEvents[tn] = 1;
        }
        Ticker.rawTick = rawTick;
        function shouldStoreTick(tn) {
            if (!tn)
                return false;
            if (TDev.Cloud.config.tickFilter)
                return !!TDev.Cloud.config.tickFilter[tn.replace(/\|.*/, "")];
            else
                return true;
        }
        function tickBase(t, sep, arg) {
            if (t == 0 /* noEvent */ || !t)
                return;
            var tn = tickName(t);
            if (arg)
                tn += sep + arg;
            if (t == 454 /* dbgLogEvent */) {
                t = 453 /* dbgEvent */;
            }
            else if (t == 453 /* dbgEvent */)
                TDev.Util.log("DBG: " + tn);
            else
                TDev.Util.log("TICK: " + tn);
            if (!initialized || disabled)
                return;
            checkDate();
            var m = { timestamp: TDev.Util.now(), event: t, arg: arg };
            if (logIdx >= 0) {
                logMsgs[logIdx++] = m;
                if (logIdx >= logSz)
                    logIdx = 0;
            }
            else {
                logMsgs.push(m);
                if (logMsgs.length >= logSz)
                    logIdx = 0;
            }
            if (t != 453 /* dbgEvent */)
                poke();
            if (t != 453 /* dbgEvent */ && shouldStoreTick(tn)) {
                if (sessionEvents[tn])
                    sessionEvents[tn]++;
                else
                    sessionEvents[tn] = 1;
                if (window.tdAppInsights)
                    try {
                        window.tdAppInsights.trackEvent(tn);
                    }
                    catch (e) {
                    }
            }
        }
        function tickArg(t, arg) {
            return tickBase(t, "$", arg);
        }
        Ticker.tickArg = tickArg;
        function tick(t, arg) {
            return tickBase(t, "|", arg);
        }
        Ticker.tick = tick;
        function getRecentEvents() {
            if (logIdx >= 0)
                return logMsgs.slice(logIdx).concat(logMsgs.slice(0, logIdx));
            else
                return logMsgs.slice(0);
        }
        Ticker.getRecentEvents = getRecentEvents;
        function usageTick() {
            var id = getCurrentEditorId();
            if (id && !document.hidden && lastPoke) {
                if (TDev.Browser.isCellphone)
                    id += "_mobile";
                rawTick("editor_" + id);
                lastPoke = 0;
            }
            TDev.Util.setTimeout(TDev.RT.Math_.random_range(3000, 17000), usageTick);
        }
        var currentEditorId;
        var lastPoke;
        function poke() {
            lastPoke = TDev.Util.now();
        }
        Ticker.poke = poke;
        function setCurrentEditorId(id) {
            TDev.Util.log("set editor: " + id);
            currentEditorId = id;
        }
        Ticker.setCurrentEditorId = setCurrentEditorId;
        function getCurrentEditorId() {
            return currentEditorId;
        }
        Ticker.getCurrentEditorId = getCurrentEditorId;
    })(Ticker = TDev.Ticker || (TDev.Ticker = {}));
    function tick(t, arg) {
        Ticker.tick(t, arg);
    }
    TDev.tick = tick;
    function tickArg(t, arg) {
        Ticker.tickArg(t, arg);
    }
    TDev.tickArg = tickArg;
    function tickN(t, v) {
        Ticker.tickN(t, v);
    }
    TDev.tickN = tickN;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    TDev.snapView = false;
    var SizeMgr;
    (function (SizeMgr) {
        SizeMgr.topFontSize = 24;
        SizeMgr.windowHeight = 800;
        SizeMgr.windowWidth = 1300;
        SizeMgr.wallWindowWidth = 1300;
        SizeMgr.editorWindowWidth = 1300;
        SizeMgr.portraitMode = false;
        SizeMgr.phoneMode = false;
        SizeMgr.devicePixelRatio = 1;
        SizeMgr.hubFontSize = 30;
        SizeMgr.lastOrientationLockTime = 0;
        SizeMgr.splitScreen = false;
        SizeMgr.splitScreenRequested = false;
        var phoneSimulationW = -1;
        var phoneSimulationH = -1;
        var previousHeight = 0;
        var previousWidth = 0;
        var savedPortraitWidth = 320;
        var savedPortraitHeight = 460;
        function setupPhoneSimulation() {
            if (phoneSimulationW >= 0)
                return;
            var m = /phone=([\d\.]+)(x([\d\.]+))?/.exec(window.document.URL);
            if (m) {
                phoneSimulationW = parseFloat(m[1]);
                var h = m[3];
                if (!h)
                    h = m[1];
                phoneSimulationH = parseFloat(h);
            }
            else {
                phoneSimulationW = 0;
                phoneSimulationH = 0;
            }
        }
        function earlyInit() {
            SizeMgr.phoneMode = TDev.Browser.isCellphone || /phone=([\d\.]+)/.test(window.document.URL);
        }
        SizeMgr.earlyInit = earlyInit;
        function canSplitScreen() {
            return !SizeMgr.phoneMode && !SizeMgr.portraitMode && SizeMgr.windowWidth * 1.2 > SizeMgr.windowHeight;
        }
        SizeMgr.canSplitScreen = canSplitScreen;
        function setSplitScreen(isSplit) {
            SizeMgr.splitScreenRequested = isSplit;
            var newSplit = SizeMgr.splitScreenRequested && canSplitScreen();
            if (newSplit != SizeMgr.splitScreen) {
                SizeMgr.splitScreen = newSplit;
                applySizes(true);
            }
        }
        SizeMgr.setSplitScreen = setSplitScreen;
        function applySizes(force) {
            if (force === void 0) { force = false; }
            setupPhoneSimulation();
            var h = window.innerHeight;
            var w = window.innerWidth;
            if (TDev.Browser.isTrident && TDev.Browser.isCellphone) {
                if (w < h) {
                    SizeMgr.devicePixelRatio = window.screen.width / w;
                }
                else {
                    SizeMgr.devicePixelRatio = window.screen.height / w;
                }
            }
            TDev.Ticker.dbg("resize(prev w={0} h={1}, curr w={2} h={3})", previousWidth, previousHeight, w, h);
            if (!force && previousHeight > 0) {
                if (TDev.Browser.isTouchDevice && Math.abs(w - previousWidth) < 30 && Math.abs(previousHeight - h) > 1) {
                    if (TDev.Util.now() - SizeMgr.lastOrientationLockTime > 600) {
                        return;
                    }
                }
            }
            if (TDev.Browser.brokenResize) {
                if (w < h) {
                    if (h <= 300) {
                        w = savedPortraitWidth;
                        h = savedPortraitHeight;
                        TDev.Ticker.dbg("brokenResize, fixing up to {0}x{1}", w, h);
                    }
                    else {
                        savedPortraitWidth = w;
                        savedPortraitHeight = h;
                    }
                }
            }
            if (TDev.Browser.browser == 9 /* safari */ && TDev.Browser.isCellphone) {
                if (350 < h && h <= 416)
                    h = 417;
            }
            if (TDev.Browser.mobileWebkit) {
                TDev.Util.setTimeout(100, function () {
                    window.scrollTo(0, 1);
                });
            }
            var origW = w;
            var origH = h;
            var applySim = function (w, simW) { return simW <= 0 ? w : simW <= 2 ? simW * w : simW; };
            w = applySim(w, phoneSimulationW);
            h = applySim(h, phoneSimulationH);
            if (!force && h == previousHeight && w == previousWidth)
                return;
            previousHeight = h;
            previousWidth = w;
            var portraitThreshold = TDev.Browser.isDesktop ? 0.9 : 1.2;
            SizeMgr.portraitMode = w * portraitThreshold < h;
            if (TDev.Browser.isCellphone)
                SizeMgr.phoneMode = true;
            if (phoneSimulationW > 0) {
                SizeMgr.phoneMode = true;
            }
            SizeMgr.splitScreen = SizeMgr.splitScreenRequested && canSplitScreen();
            if (SizeMgr.phoneMode || SizeMgr.splitScreen)
                SizeMgr.portraitMode = true;
            TDev.Util.log("view:" + (SizeMgr.portraitMode ? " portrait" : " landscape") + (SizeMgr.phoneMode ? " phone" : "") + (SizeMgr.splitScreen ? " split" : "") + " size:" + w + "x" + h);
            var statusBarSize = 0;
            SizeMgr.windowHeight = h;
            SizeMgr.windowWidth = w;
            if (SizeMgr.splitScreen) {
                SizeMgr.editorWindowWidth = SizeMgr.windowWidth / 1.618;
                SizeMgr.wallWindowWidth = SizeMgr.windowWidth - SizeMgr.editorWindowWidth;
            }
            else {
                SizeMgr.editorWindowWidth = SizeMgr.windowWidth;
                SizeMgr.wallWindowWidth = SizeMgr.windowWidth;
            }
            SizeMgr.topFontSize = Math.floor(Math.min(h / 25, SizeMgr.editorWindowWidth / (SizeMgr.phoneMode ? 25 : SizeMgr.portraitMode ? 36 : 55)));
            if (SizeMgr.splitScreen)
                SizeMgr.wallWindowWidth -= 0.15 * SizeMgr.topFontSize;
            var zoom = window.localStorage["zoomFactor"];
            if (zoom && parseFloat(zoom)) {
                SizeMgr.topFontSize = Math.round(SizeMgr.topFontSize * TDev.Util.between(0.3, parseFloat(zoom), 2));
            }
            TDev.elt("root").style.height = h + "px";
            if (phoneSimulationW > 0)
                TDev.elt("root").style.width = w + "px";
            if (!TDev.Browser.isMobile)
                SizeMgr.topFontSize = 16;
            TDev.elt("root").style.fontSize = SizeMgr.topFontSize + "px";
            var rootClass = SizeMgr.portraitMode ? "portrait" : "landscape";
            if (SizeMgr.phoneMode)
                rootClass += " phone";
            if (SizeMgr.splitScreen)
                rootClass += " split";
            if (TDev.Browser.assumeMouse)
                rootClass += " assume-mouse";
            if (TDev.Browser.assumeMouse && TDev.Browser.browser != 1 /* ie10 */ && TDev.Browser.browser != 2 /* ie11 */)
                rootClass += " assume-notouch";
            if (SizeMgr.topFontSize <= 12)
                rootClass += " tinyFont";
            if (SizeMgr.topFontSize <= 18)
                rootClass += " smallFont";
            rootClass += " rootClass";
            if (TDev.Browser.brokenColumns)
                rootClass += " brokenColumns";
            TDev.elt("root").className = rootClass;
            var rootStyle = TDev.elt("root").style;
            if (phoneSimulationW > 0) {
                rootStyle.left = (origW - w) / 2 + "px";
                rootStyle.top = (origH - h) / 2 + "px";
                rootStyle.background = "#fff";
                document.body.style.background = "#666";
            }
            if (TDev.currentScreen)
                TDev.currentScreen.applySizes();
        }
        SizeMgr.applySizes = applySizes;
        function getColumnWidth() {
            return this.portraitMode ? (window.innerWidth - (2 * this.topFontSize)) : (18.5 * this.topFontSize);
        }
        SizeMgr.getColumnWidth = getColumnWidth;
    })(SizeMgr = TDev.SizeMgr || (TDev.SizeMgr = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    TDev.currentScreen = null;
    TDev.allScreens = [];
    var HistoryMgr = (function () {
        function HistoryMgr() {
            var _this = this;
            this.numReloads = 0;
            this.urlStack = [];
            this.numPush = 1;
            this.lastSetHash = "";
            this.replaceNext = false;
            Screen.pushModalHash = function (s, f) { return _this.pushModalHash(s, f); };
            Screen.popModalHash = function (s) { return _this.popModalHash(s); };
            HistoryMgr.instance = this;
            TDev.Util.onSetHash = function (s, r) { return _this.setHashHandler(s, r); };
            TDev.Util.onGoBack = function () { return _this.back(); };
        }
        HistoryMgr.prototype.currentHash = function () {
            return this.lastSetHash;
        };
        HistoryMgr.urlHash = function (url) {
            var i = url.indexOf('#');
            if (i > 0 && i < url.length - 1)
                return url.slice(i);
            else
                return "#" + TDev.hubHash;
        };
        HistoryMgr.windowHash = function () {
            var h = window.location.href;
            return HistoryMgr.urlHash(h);
        };
        HistoryMgr.prototype.pushState = function (h) {
            try {
                TDev.Util.log("pushState: " + h);
                h = window.location.href.replace(/#.*/, "") + (h || "");
                window.history.pushState(++this.numPush, null, h);
            }
            catch (e) {
            }
        };
        HistoryMgr.prototype.setHash = function (h, t) {
            TDev.Util.log("sethash: " + h + " - " + t);
            TDev.Ticker.dbg("History.setHash|" + h);
            var repl = this.replaceNext;
            this.replaceNext = false;
            if (repl) {
                TDev.Ticker.dbg("History.setHash is a replace");
            }
            this.numReloads++;
            if (!/^#/.test(h))
                h = "#" + h;
            if (h == "#" + TDev.hubHash)
                h = "#";
            this.clearModalSuffix();
            Screen.arrivedAtHash(h);
            if (this.urlStack.length == 0 || this.urlStack.peek().url != h) {
                this.urlStack.push({ url: h, onPop: function () {
                } });
                this.pushState(h);
            }
            else {
                TDev.Ticker.dbg("setHash.. ignoring same hash");
            }
            if (t !== null) {
                if (t)
                    document.title = t + " - " + TDev.Runtime.appName;
                else
                    document.title = TDev.Runtime.appName;
            }
        };
        HistoryMgr.prototype.pushModalHash = function (s, f) {
            var hash = '#modal-' + s;
            if (this.urlStack.length > 0 && this.urlStack.peek().url == hash) {
                this.urlStack.pop();
            }
            this.urlStack.push({ url: hash, onPop: f });
            this.pushState(this.topHash());
            Screen.arrivedAtHash(hash);
        };
        HistoryMgr.prototype.popModalHash = function (s) {
            TDev.Ticker.dbg("popModal " + s);
            var hash = '#modal-' + s;
            var index = -1;
            for (var i = 0; i < this.urlStack.length; i++) {
                if (this.urlStack[i].url == hash) {
                    index = i;
                    this.urlStack[i].onPop = null;
                    break;
                }
            }
            if (index < 0)
                return;
            this.popBack(this.urlStack.length - index);
        };
        HistoryMgr.prototype.popBack = function (toPop) {
            if (toPop === void 0) { toPop = 1; }
            TDev.Ticker.dbg("historyMgr: popBack " + toPop);
            var popped = this.urlStack.splice(this.urlStack.length - toPop, toPop);
            var seenNonModal = false;
            for (var i = popped.length - 1; i >= 0; i--) {
                var entry = popped[i];
                if (!/#modal-/.test(entry.url))
                    seenNonModal = true;
                if (entry.onPop) {
                    var f = entry.onPop;
                    entry.onPop = null;
                    f();
                }
            }
            var last = this.urlStack.peek();
            Screen.arrivedAtHash(last ? last.url : "#");
            if (seenNonModal)
                this.dispatch(this.topHash());
            else
                this.hashReloaded();
        };
        HistoryMgr.prototype.hashReloaded = function () {
            this.pushState(this.topHash());
        };
        HistoryMgr.prototype.topHash = function () {
            for (var i = this.urlStack.length - 1; i >= 0; i--) {
                var t = this.urlStack[i];
                if (t && !/^#modal-/.test(t.url))
                    return t.url;
            }
            return "#";
        };
        HistoryMgr.prototype.dispatch = function (h) {
            TDev.Util.log("dispatch: " + h);
            TDev.ModalDialog.dismissCurrent();
            this.pushState(h);
            this.reload(h);
        };
        HistoryMgr.prototype.initialHash = function () {
            this.setHashHandler(HistoryMgr.windowHash(), true);
            if (this.lastSetHash == "" && !this.replaceNext) {
                this.pushState(null);
                this.replaceNext = true;
                this.showStartScreen();
            }
        };
        HistoryMgr.prototype.showStartScreen = function () {
        };
        HistoryMgr.prototype.reload = function (hash) {
        };
        HistoryMgr.prototype.confirmLoadHash = function () {
            TDev.Ticker.dbg("History.confirmLoadHash");
            this.replaceNext = false;
        };
        HistoryMgr.prototype.clearModalSuffix = function () {
            for (var i = 0; i < this.urlStack.length; i++) {
                if (/^#modal-/.test(this.urlStack[i].url)) {
                    var removed = this.urlStack.splice(i, this.urlStack.length - i);
                    return removed.length;
                }
            }
            return 0;
        };
        HistoryMgr.prototype.clearModalStack = function () {
            var n = this.clearModalSuffix();
        };
        HistoryMgr.prototype.commandHandler = function (h) {
        };
        HistoryMgr.prototype.popState = function (event) {
            var _this = this;
            TDev.Ticker.dbg("popState: " + event.state);
            if (this.urlStack.length == 1) {
                window.history.back();
                return;
            }
            var h = HistoryMgr.windowHash();
            if (/^#cmd:/.test(h)) {
                var nh = this.topHash();
                this.whenSafe(function () {
                    _this.pushState(nh);
                    _this.commandHandler(h);
                });
            }
            else {
                this.back();
            }
        };
        HistoryMgr.prototype.back = function () {
            var _this = this;
            this.whenSafe(function () { return _this.popBack(); });
        };
        HistoryMgr.prototype.whenSafe = function (f) {
            var _this = this;
            if (TDev.ProgressOverlay.isActive())
                TDev.Util.setTimeout(500, function () { return _this.whenSafe(f); });
            else
                f();
        };
        HistoryMgr.prototype.setHashHandler = function (h, replace) {
            var _this = this;
            this.whenSafe(function () {
                if (!h)
                    h = "#";
                if (!/^#/.test(h))
                    h = "#" + h;
                if (replace) {
                    for (var i = _this.urlStack.length - 1; i >= 0; --i) {
                        if (_this.urlStack[i].url == h) {
                            if (i == _this.urlStack.length - 1) {
                                TDev.Util.log("replaced hash already current, skipping " + h);
                                return;
                            }
                            else {
                                TDev.Util.log("found hash to replace in stack, popping " + h);
                                _this.popBack(_this.urlStack.length - 1 - i);
                                return;
                            }
                        }
                    }
                }
                _this.dispatch(h);
            });
        };
        HistoryMgr.prototype.scriptOrHub = function (h) {
            var id = h.filter(function (s) { return /^id=/.test(s); })[0];
            if (id) {
                var scr = id.replace(/^id=/, "script:");
                if (h[0] == "list")
                    TDev.Util.setHash(h[0] + ":" + h[1] + ":" + scr, true);
                else
                    TDev.Util.setHash(scr, true);
            }
            else {
                TDev.Util.setHash(TDev.hubHash, true);
            }
        };
        HistoryMgr.prototype.hashChange = function () {
            TDev.Util.log("hashChange: " + HistoryMgr.windowHash());
        };
        return HistoryMgr;
    })();
    TDev.HistoryMgr = HistoryMgr;
    var Screen = (function () {
        function Screen() {
            this.paneState = 0;
        }
        Screen.prototype.init = function () {
        };
        Screen.prototype.hide = function () {
        };
        Screen.prototype.screenId = function () {
            return "";
        };
        Screen.prototype.loadHash = function (h) {
        };
        Screen.prototype.keyDown = function (e) {
            return false;
        };
        Screen.prototype.applySizes = function () {
        };
        Screen.prototype.syncDone = function () {
        };
        Screen.prototype.hashReloaded = function () {
        };
        Screen.prototype.autoHide = function () {
            return TDev.SizeMgr.portraitMode;
        };
        Screen.prototype.sidePaneVisible = function () {
            return !this.autoHide() || this.sidePane().style.display == "block";
        };
        Screen.prototype.sidePaneVisibleNow = function () {
            return !this.autoHide() || this.paneState > 0;
        };
        Screen.prototype.updateSidePane = function () {
            var pane = this.sidePane();
            if (!this.autoHide()) {
                pane.style.display = "block";
                pane.style.opacity = "1";
            }
            else if (this.autoHide() && this.paneState < 0) {
                pane.style.display = "none";
            }
            TDev.elt("root").setFlag("pane-hidden", pane.style.display == "none");
        };
        Screen.prototype.showSidePane = function () {
            var _this = this;
            if (!this.autoHide() || this.paneState > 0)
                return;
            Screen.pushModalHash("side", function () { return _this.hideSidePane(); });
            TDev.elt("root").setFlag("pane-hidden", false);
            this.paneState = 1;
            var pane = this.sidePane();
            pane.style.display = "block";
            pane.style.opacity = "1";
            TDev.Util.showRightPanel(pane);
        };
        Screen.prototype.sidePane = function () {
            return null;
        };
        Screen.prototype.hideSidePane = function () {
            var _this = this;
            var pane = this.sidePane();
            if (!this.autoHide()) {
                pane.style.display = "block";
                pane.style.opacity = "1";
                return;
            }
            if (this.paneState < 0)
                return;
            Screen.popModalHash("side");
            TDev.elt("root").setFlag("pane-hidden", true);
            this.paneState = -1;
            TDev.Util.hidePopup(pane, function () {
                if (_this.paneState < 0 && _this.autoHide())
                    pane.style.display = "none";
            });
        };
        Screen.prototype.hashCommandHandler = function (h) {
        };
        Screen.pushModalHash = function (s, removeCb) {
        };
        Screen.popModalHash = function (s) {
        };
        Screen.arrivedAtHash = function (s) {
        };
        return Screen;
    })();
    TDev.Screen = Screen;
    var KeyboardMgr = (function () {
        function KeyboardMgr() {
            this.handlers = {};
        }
        KeyboardMgr.prototype.register = function (key, cb) {
            if (/^-/.test(key))
                return;
            this.handlers[key] = cb;
        };
        KeyboardMgr.prototype.saveState = function () {
            return TDev.Util.flatClone(this.handlers);
        };
        KeyboardMgr.prototype.loadState = function (s) {
            if (!TDev.Util.check(!!s))
                return;
            this.handlers = s;
        };
        KeyboardMgr.prototype.triggerKey = function (name) {
            var h = this.handlers[name];
            if (h && h.isBtnShortcut)
                h();
        };
        KeyboardMgr.triggerClick = function (e) {
            var h = e.clickHandler;
            if (!!h) {
                var active = document.activeElement;
                if (!!active && !!active.blur)
                    active.blur();
                e.setFlag("active", true);
                TDev.Util.setTimeout(150, function () {
                    e.setFlag("active", false);
                });
                h.fireClick({});
            }
        };
        KeyboardMgr.elementVisible = function (e) {
            while (e) {
                if (e.id == "root")
                    return true;
                if (window.getComputedStyle(e).display == "none")
                    return false;
                e = e.parentNode;
            }
            return false;
        };
        KeyboardMgr.prototype.btnShortcut = function (e, key) {
            var _this = this;
            if (!key)
                return;
            var handle = function () {
                if (KeyboardMgr.elementVisible(e)) {
                    KeyboardMgr.triggerClick(e);
                    return true;
                }
                return false;
            };
            handle.isBtnShortcut = true;
            if (!/^ /.test(key))
                key.split(", ").forEach(function (k) { return _this.register(k, handle); });
            e.title = key.replace(/(^| )-/g, "");
        };
        KeyboardMgr.prototype.keyUp = function (e) {
            TDev.Util.normalizeKeyEvent(e);
            if (/-(Control|Alt)$/.test(e.keyName))
                return true;
            var h = this.handlers["*keyup*"];
            if (h) {
                TDev.Ticker.dbg("keyUp.run");
                if (h(e))
                    return true;
            }
        };
        KeyboardMgr.prototype.processKey = function (e) {
            TDev.Util.normalizeKeyEvent(e);
            if (/-(Control|Alt)$/.test(e.keyName))
                return true;
            if (TDev.Browser.isGecko) {
                var isRepeated = e.type == "keypress" && this.previousStoppedEvent && this.previousStoppedEvent.type == "keydown";
                this.previousStoppedEvent = null;
                if (isRepeated)
                    return e.stopIt();
            }
            if (this.keyHandler(e)) {
                if (TDev.Browser.isGecko)
                    this.previousStoppedEvent = e;
                return e.stopIt();
            }
        };
        KeyboardMgr.prototype.attach = function (inp) {
            var _this = this;
            inp.onkeydown = TDev.Util.catchErrors("textboxKey", function (e) {
                e.fromTextBox = true;
                return _this.processKey(e);
            });
        };
        KeyboardMgr.prototype.keyHandler = function (e) {
            if (TDev.ProgressOverlay.isKeyboardBlocked())
                return true;
            if (e.keyName == "Ctrl-Control")
                return false;
            if (/^(Del|Ctrl-[CXVA]|Shift-(Left|Right)|(Ctrl|Shift)-(Ins|Del))$/.test(e.keyName) && e.fromTextBox)
                return false;
            if (TDev.dbg && e.keyName)
                TDev.tick(3 /* mainKeyEvent */);
            h = this.handlers["*keydown*"];
            if (h) {
                if (TDev.dbg && e.keyName)
                    TDev.Ticker.dbg("keyHandler.preCatchAll." + e.keyName);
                if (h(e))
                    return true;
            }
            var h = this.handlers[e.keyName];
            if (h) {
                if (TDev.dbg && e.keyName)
                    TDev.Ticker.dbg("keyHandler.byName." + e.keyName);
                if (h(e))
                    return true;
            }
            h = this.handlers["***"];
            if (h) {
                if (TDev.dbg && e.keyName)
                    TDev.Ticker.dbg("keyHandler.catchAll." + e.keyName);
                if (h(e))
                    return true;
            }
            if (TDev.currentScreen) {
                if (TDev.dbg && e.keyName)
                    TDev.Ticker.dbg("keyHandler.currentScreen." + e.keyName);
                if (TDev.currentScreen.keyDown(e))
                    return true;
            }
            if (e.keyCode == 8 && !e.fromTextBox)
                return true;
            return false;
        };
        KeyboardMgr.instance = new KeyboardMgr();
        return KeyboardMgr;
    })();
    TDev.KeyboardMgr = KeyboardMgr;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var LayoutMgr = (function () {
        function LayoutMgr() {
            this.onBoxSelected = function () {
            };
            this.onRendered = function () {
            };
            this.numBoxes = 0;
            this.scrollspeculation = true;
            this.currentAstNodeId = "";
            this.selectedBox = null;
            this.boxMenu = null;
            this.scrollTop = undefined;
            this.scrollLeft = undefined;
            this.sideview = false;
            this.scrollbarWidth = undefined;
            this.scrollbarHeight = undefined;
        }
        LayoutMgr.prototype.updateEditMode = function (rt) {
            this.editMode = rt.liveViewSupported() && (rt.isStopped() || rt.liveMode());
            if (this.editMode) {
            }
            else {
                if (this.currentAstNodeId) {
                    this.clearRelatedBoxes();
                }
                if (this.selectedBox !== null) {
                    this.unselectBox();
                }
                this.adjustForNormalView();
            }
            if (!!this.rootBox)
                this.updateRootElement();
        };
        LayoutMgr.RenderExecutionMode = function () {
            return LayoutMgr.renderexecutionmode;
        };
        LayoutMgr.SetRenderExecutionMode = function (val) {
            LayoutMgr.renderexecutionmode = val;
        };
        LayoutMgr.QueueReLayout = function () {
            var check = function () {
                if (LayoutMgr.needrelayout) {
                    if (!LayoutMgr.renderexecutionmode && LayoutMgr.instance.rootBox) {
                        LayoutMgr.instance.CoreLayout();
                        LayoutMgr.needrelayout = false;
                    }
                    else
                        TDev.Util.setTimeout(100, check);
                }
            };
            if (!LayoutMgr.needrelayout) {
                LayoutMgr.needrelayout = true;
                TDev.Util.setTimeout(50, check);
            }
        };
        LayoutMgr.prototype.adjustForSideView = function () {
            if (!this.sideview) {
                this.rootElement.style.overflow = "auto";
                this.rootElement.style.msContentZooming = "zoom";
                if (this.rootBox instanceof WallBox)
                    this.rootBox.setRenderedSideView(true);
                this.updateRootElement();
                this.sideview = true;
            }
        };
        LayoutMgr.prototype.adjustForNormalView = function () {
            if (this.sideview) {
                var rootelt = this.rootElement;
                rootelt.style.overflow = "";
                rootelt.style.msContentZooming = "";
                rootelt.scrollTop = 0;
                rootelt.scrollLeft = 0;
                rootelt.msContentZoomFactor = 1;
                if (this.rootBox instanceof WallBox)
                    this.rootBox.setRenderedSideView(false);
                this.updateRootElement();
                this.sideview = false;
            }
        };
        LayoutMgr.prototype.FlagTypingActivity = function (id) {
            this.lastbox_edited = id;
        };
        LayoutMgr.prototype.ClearTypingActivity = function (id) {
            if (this.lastbox_edited === id)
                this.lastbox_edited = undefined;
        };
        LayoutMgr.prototype.CheckTypingActivity = function (id) {
            return this.lastbox_edited === id;
        };
        LayoutMgr.createOrRecycleContainerBoxDelayed = function (rt, cur) {
            var pc = rt.getTopScriptPc();
            LayoutMgr.lazyInitCurrentRanderBox = function () {
                LayoutMgr.lazyInitCurrentRanderBox = function () {
                };
                var tag = LayoutMgr.htmlTagName || "div";
                LayoutMgr.htmlTagName = undefined;
                var w = WallBox.CreateOrRecycleContainerBox(rt, cur, pc, tag);
                LayoutMgr.currentbox = w;
            };
            LayoutMgr.currentbox = null;
        };
        LayoutMgr.setHtmlTagName = function (name) {
            if (LayoutMgr.currentbox)
                TDev.Util.userError(TDev.lf("you cannot set the HTML tag name here"));
            LayoutMgr.htmlTagName = name;
        };
        LayoutMgr.getCurrentRenderBox = function () {
            LayoutMgr.lazyInitCurrentRanderBox();
            return LayoutMgr.currentbox;
        };
        LayoutMgr.setCurrentRenderBox = function (box) {
            LayoutMgr.lazyInitCurrentRanderBox();
            LayoutMgr.currentbox = box;
        };
        LayoutMgr.prototype.findFirstBoxByNodeId = function (astNodeId) {
            if (!this.pcTable)
                return null;
            var box = this.pcTable[astNodeId];
            return box === undefined ? null : box;
        };
        LayoutMgr.prototype.findAllBoxesByNodeId = function (astNodeId) {
            var boxes = [];
            if (this.boxes)
                this.boxes.forEach(function (box) {
                    if (box.getAstNodeId() === astNodeId)
                        boxes.push(box);
                });
            return boxes;
        };
        LayoutMgr.prototype.findAllBoxesByPropertyNodeId = function (astNodeId) {
            var boxes = [];
            if (this.boxes)
                this.boxes.forEach(function (box) {
                    var pcTable = box.pcTable;
                    for (var propName in pcTable) {
                        if (pcTable[propName] === astNodeId) {
                            boxes.push(box);
                            break;
                        }
                    }
                });
            return boxes;
        };
        LayoutMgr.prototype.getSelectedBox = function () {
            return this.selectedBox;
        };
        LayoutMgr.prototype.setCurrentId = function (astNodeId) {
            this.currentAstNodeId = astNodeId;
        };
        LayoutMgr.prototype.getCurrentId = function () {
            return this.currentAstNodeId;
        };
        LayoutMgr.prototype.selectBox = function (box) {
            if (this.selectedBox !== null) {
                var parent = box;
                while (parent !== null) {
                    if (parent === this.selectedBox)
                        return false;
                    parent = parent.parent;
                }
                this.unselectBox();
            }
            if (this.currentAstNodeId)
                this.clearRelatedBoxes();
            if (!box || box.depth <= 0 || (box.isSingleChild && box.isLeaf() && box.depth > 1))
                return false;
            this.selectedBox = box;
            this.highlightSelectedBox();
            if (this.onBoxSelected)
                this.onBoxSelected();
            return true;
        };
        LayoutMgr.prototype.showBoxMenu = function (cb) {
            var editButton = TDev.HTML.mkRoundButton("svg:edit,currentColor", TDev.lf("edit"), 290 /* wallEdit */, function () {
                if (cb)
                    cb();
            });
            this.boxMenu = TDev.div("wall-selected", [editButton]);
            this.refreshBoxMenu();
        };
        LayoutMgr.prototype.refreshBoxMenu = function () {
            if (this.boxMenu !== null) {
                this.updateBoxMenuPosition();
                this.rootElement.appendChild(this.boxMenu);
                this.checkBoxMenuPosition();
            }
        };
        LayoutMgr.prototype.hideBoxMenu = function () {
            if (this.boxMenu !== null) {
                TDev.Animation.fadeOut(this.boxMenu).begin();
                this.boxMenu = null;
            }
        };
        LayoutMgr.prototype.updateBoxMenuPosition = function () {
            if (this.selectedBox === null || this.boxMenu === null)
                return;
            var box = this.selectedBox;
            var offset = TDev.Util.offsetIn(box.element, this.rootElement);
            var renderedScale = 1;
            var viewWidth = this.rootElement.clientWidth, viewHeight = this.rootElement.clientHeight;
            var boxWidth = box.getRenderedWidth() * renderedScale, boxHeight = box.getRenderedHeight() * renderedScale;
            var viewLeft = offset.x * renderedScale, viewTop = offset.y * renderedScale;
            var margin = TDev.SizeMgr.topFontSize * 0.2;
            if (viewLeft + boxWidth / 2 < viewWidth / 2) {
                this.boxMenu.style.right = "auto";
                this.boxMenu.style.left = (viewLeft + boxWidth + margin) + "px";
            }
            else {
                this.boxMenu.style.left = "auto";
                this.boxMenu.style.right = (viewWidth - (viewLeft - margin)) + "px";
            }
            if (viewTop + boxHeight / 2 < viewHeight / 2) {
                this.boxMenu.style.bottom = "auto";
                this.boxMenu.style.top = viewTop + "px";
            }
            else {
                this.boxMenu.style.top = "auto";
                this.boxMenu.style.bottom = (viewHeight - (viewTop + boxHeight)) + "px";
            }
        };
        LayoutMgr.prototype.checkBoxMenuPosition = function () {
            if (this.boxMenu === null)
                return;
            var box = this.selectedBox;
            var offset = TDev.Util.offsetIn(this.boxMenu, this.rootElement);
            var renderedScale = 1;
            var viewWidth = this.rootElement.clientWidth, viewHeight = this.rootElement.clientHeight;
            var menuWidth = this.boxMenu.clientWidth * renderedScale, menuHeight = this.boxMenu.clientHeight * renderedScale;
            var viewLeft = offset.x * renderedScale - this.rootElement.scrollLeft, viewTop = offset.y * renderedScale - this.rootElement.scrollTop;
            var viewRight = viewLeft + menuWidth, viewBottom = viewTop + menuHeight;
            if (viewLeft < 0) {
                this.boxMenu.style.left = "0px";
                this.boxMenu.style.right = "auto";
            }
            else if (viewRight > viewWidth) {
                this.boxMenu.style.right = "0px";
                this.boxMenu.style.left = "auto";
            }
            if (viewTop < 0) {
                this.boxMenu.style.top = "0px";
                this.boxMenu.style.bottom = "auto";
            }
            else if (viewBottom > viewHeight) {
                this.boxMenu.style.bottom = "0px";
                this.boxMenu.style.top = "auto";
            }
        };
        LayoutMgr.prototype.unselectBox = function () {
            if (this.selectedBox !== null) {
                this.findAllBoxesByNodeId(this.selectedBox.getAstNodeId()).forEach(function (box) {
                    box.clearHighlight();
                });
                this.selectedBox = null;
                this.hideBoxMenu();
            }
        };
        LayoutMgr.prototype.highlightSelectedBox = function () {
            var _this = this;
            if (this.selectedBox !== null) {
                this.selectedBox.setHighlight();
                this.scrollToShow(this.selectedBox);
                this.findAllBoxesByNodeId(this.selectedBox.getAstNodeId()).forEach(function (box) {
                    if (_this.selectedBox !== box)
                        box.setHighlight(false);
                });
            }
        };
        LayoutMgr.prototype.highlightRelatedBoxes = function () {
            if (this.selectedBox !== null)
                this.unselectBox();
            if (this.currentAstNodeId) {
                var firstBox = this.findFirstBoxByNodeId(this.currentAstNodeId);
                if (firstBox !== null) {
                    firstBox.setHighlight();
                    this.selectedBox = firstBox;
                }
                this.findAllBoxesByPropertyNodeId(this.currentAstNodeId).forEach(function (box) {
                    if (firstBox !== box)
                        box.setHighlight(false);
                });
            }
        };
        LayoutMgr.prototype.clearRelatedBoxes = function () {
            if (this.currentAstNodeId) {
                this.findAllBoxesByPropertyNodeId(this.currentAstNodeId).forEach(function (box) {
                    box.clearHighlight();
                });
            }
            this.currentAstNodeId = "";
        };
        LayoutMgr.prototype.createZoomingUI = function () {
            var _this = this;
            var scaleSpan = TDev.span(null, "");
            var scaleSliderCursor = TDev.div("cursor");
            var scaleSlider = TDev.div("slider", [scaleSliderCursor]);
            this.updateslider = function (zoom, adjustscroll) {
                var oldScale = _this.scale;
                _this.scale = Math.max(_this.minimumScale, Math.min(zoom, _this.maximumScale));
                scaleSliderCursor.style.top = "0";
                scaleSliderCursor.style.left = (scaleSlider.clientWidth - scaleSliderCursor.clientWidth) * _this.fromZoomToSliderValue(_this.scale) + "px";
                scaleSpan.setChildren([Math.round(_this.scale * 100).toString() + "%"]);
                if (adjustscroll) {
                    _this.updateScaling(_this.scale);
                    if (_this.scrollTop !== undefined) {
                        _this.scrollTop = _this.scrollTop * _this.scale / oldScale + _this.rootElement.offsetHeight / 2 * (_this.scale / oldScale - 1);
                        _this.scrollLeft = _this.scrollLeft * _this.scale / oldScale + _this.rootElement.offsetWidth / 2 * (_this.scale / oldScale - 1);
                        _this.recoverScroll();
                    }
                }
            };
            new TDev.DragHandler(scaleSliderCursor, function (e, dx, dy) {
                var pos = TDev.Util.offsetIn(scaleSliderCursor, scaleSlider);
                var max = scaleSlider.clientWidth - scaleSliderCursor.clientWidth;
                _this.updateslider(_this.fromSliderValueToZoom(pos.x / max), true);
            });
            var zoomOutButton = TDev.HTML.mkButtonElt("wall-zoom-out", "-");
            zoomOutButton.withClick(function () {
                _this.updateslider(_this.scale * 0.9, true);
            });
            var zoomInButton = TDev.HTML.mkButtonElt("wall-zoom-in", "+");
            zoomInButton.withClick(function () {
                _this.updateslider(_this.scale * 1.1, true);
            });
            var ui = TDev.div("wall-zoom", scaleSpan, zoomOutButton, scaleSlider, zoomInButton);
            return ui;
        };
        LayoutMgr.prototype.fromSliderValueToZoom = function (value) {
            return this.minimumScale * Math.exp(Math.log(this.maximumScale / this.minimumScale) * value);
        };
        LayoutMgr.prototype.fromZoomToSliderValue = function (zoom) {
            return this.minimumScale >= this.maximumScale ? 1 : Math.log(zoom / this.minimumScale) / Math.log(this.maximumScale / this.minimumScale);
        };
        LayoutMgr.prototype.getRootElement = function () {
            return this.rootElement;
        };
        LayoutMgr.prototype.getRootBox = function () {
            return this.rootBox;
        };
        LayoutMgr.prototype.updateRootElement = function () {
            this.rootElement.setAttribute("livemode", this.editMode ? "true" : "false");
        };
        LayoutMgr.prototype.calcDefaultScaling = function () {
            if (this.sideview) {
                if (this.scale === undefined || isNaN(this.scale)) {
                    var horizontalScale = this.rootElement.offsetWidth / this.rootBox.element.offsetWidth;
                    var verticalScale = this.rootElement.offsetHeight / this.rootBox.element.offsetHeight;
                    this.minimumScale = Math.min(horizontalScale, verticalScale) * 0.5;
                    this.maximumScale = this.minimumScale * 100;
                    var defaultScale = Math.max(horizontalScale, verticalScale);
                    this.scale = defaultScale;
                    this.updateScaling(this.scale);
                }
            }
            else {
                this.updateScaling(1);
            }
        };
        LayoutMgr.prototype.updateScaling = function (scale) {
            if (this.sideview && this.rootElement.msContentZoomFactor) {
                TDev.Util.setTransform(this.rootBox.element, "scale(" + this.minimumScale * 10 + ", " + this.minimumScale * 10 + ")", "0% 0%");
                this.rootElement.msContentZoomFactor = scale / (this.minimumScale * 10);
                this.rootElement.style.msContentZoomLimit = "10% 1000%";
            }
            else {
                TDev.Util.setTransform(this.rootBox.element, "scale(" + scale + ", " + scale + ")", "0% 0%");
            }
        };
        LayoutMgr.prototype.FindScrollbarSizes = function (elt) {
            if (this.scrollbarWidth === undefined) {
                var saved = elt.style.overflow || "";
                this.scrollbarWidth = elt.clientWidth;
                this.scrollbarHeight = elt.clientHeight;
                elt.style.overflow = "scroll";
                this.scrollbarWidth -= elt.clientWidth;
                this.scrollbarHeight -= elt.clientHeight;
                elt.style.overflow = saved;
            }
        };
        LayoutMgr.prototype.recoverScroll = function () {
            if (this.sideview) {
                if (this.scrollTop !== undefined) {
                    this.rootElement.scrollTop = this.scrollTop;
                    this.rootElement.scrollLeft = this.scrollLeft;
                }
            }
        };
        LayoutMgr.prototype.onScroll = function () {
            this.scrollTop = this.rootElement.scrollTop;
            this.scrollLeft = this.rootElement.scrollLeft;
            var zoomfactor = this.rootElement.msContentZoomFactor;
            if (zoomfactor)
                this.updateslider(zoomfactor * this.minimumScale * 10, false);
        };
        LayoutMgr.prototype.scrollToShow = function (box) {
        };
        LayoutMgr.prototype.render = function (box, e) {
            if (box === null || (box.parent !== null && box.parent !== undefined)) {
                return;
            }
            this.rootElement = e;
            this.rootBox = box;
            box.isRoot = true;
            var el = box.element;
            if (this.rootElement.firstChild != el || !this.rootBox.structuring_done) {
                this.CreateOrFixElementStructure();
            }
            this.CoreLayout();
        };
        LayoutMgr.prototype.isOnScreen = function (node) {
            var top = document.documentElement;
            while (node) {
                if (node === top)
                    return true;
                if (node.style.display === "none")
                    return false;
                node = node.parentNode;
            }
            return false;
        };
        LayoutMgr.prototype.CoreLayout = function () {
            var _this = this;
            if (this.rootBox instanceof HtmlBox) {
                this.rootBox.doLayout();
                return;
            }
            if (!this.isOnScreen(this.rootElement))
                return;
            TDev.Util.time("CoreLayout", function () {
                _this.FindScrollbarSizes(_this.rootElement);
                if (_this.sideview && _this.scale !== undefined && _this.scale != 1)
                    _this.updateScaling(_this.scale);
                _this.rootBox.doLayout();
                if (_this.rootBox instanceof WallBox && !_this.rootBox.speculationwascorrect(_this.scrollspeculation)) {
                    _this.scrollspeculation = !_this.scrollspeculation;
                    _this.rootBox.doLayout();
                }
                _this.calcDefaultScaling();
                if (_this.sideview) {
                    _this.recoverScroll();
                    _this.updateslider(_this.scale, true);
                }
                if (_this.onRendered)
                    _this.onRendered();
            }, false);
        };
        LayoutMgr.prototype.CreateOrFixElementStructure = function () {
            this.boxes = [];
            this.pcTable = {};
            var e = this.rootElement;
            var el = this.rootBox.element;
            while (e.hasChildNodes()) {
                var b = e.firstChild;
                if (b == el)
                    break;
                e.removeChild(b);
            }
            while (e.hasChildNodes()) {
                var b = e.lastChild;
                if (b == el)
                    break;
                e.removeChild(b);
            }
            this.passS(this.rootBox);
            this.rootBox.structuring_done = true;
        };
        LayoutMgr.prototype.passS = function (box) {
            if (box.doLiveNavigation()) {
                this.boxes.push(box);
                this.recordmapping(box);
            }
            box.visitS();
            for (var i = 0; i < box.children.length; i++)
                this.passS(box.children[i]);
        };
        LayoutMgr.prototype.recordmapping = function (box) {
            if (this.pcTable[box.getAstNodeId()] === undefined)
                this.pcTable[box.getAstNodeId()] = box;
            for (var propName in box.pcTable)
                if (this.pcTable[box.pcTable[propName]] === undefined)
                    this.pcTable[box.pcTable[propName]] = box;
        };
        LayoutMgr.instance = new LayoutMgr();
        LayoutMgr.renderexecutionmode = false;
        LayoutMgr.needrelayout = false;
        LayoutMgr.lazyInitCurrentRanderBox = function () {
        };
        return LayoutMgr;
    })();
    TDev.LayoutMgr = LayoutMgr;
    var WallPage = (function () {
        function WallPage(rt, auto) {
            this.topDown = false;
            this.crashed = false;
            this.id = TDev.Random.uniqueId();
            this.csslayout = false;
            this.lastChildCount = -1;
            this.title = "";
            this.subtitle = "";
            this.chromeVisible = true;
            this.backButtonVisible = true;
            this.fgColor = "#000000";
            this.bgColor = "#ffffff";
            this.renderCount = 0;
            this.onNavigatedFrom = new TDev.RT.Event_();
            this.runtime = rt;
            this.element = TDev.div("wall-page");
            this.buttons = [];
            this.auto = auto;
            this.onNavigatedFrom.isPageEvent = true;
            this.clear();
        }
        WallPage.prototype.activate = function () {
            this.getElement().style.display = "block";
        };
        WallPage.prototype.deactivate = function () {
            this.getElement().style.display = "none";
        };
        WallPage.prototype.getElement = function () {
            return this.element;
        };
        WallPage.prototype.isAuto = function () {
            return this.auto;
        };
        WallPage.prototype.isReversed = function () {
            return this.topDown;
        };
        WallPage.prototype.setReversed = function (reversed) {
            if (this.topDown != reversed) {
                this.lastChildCount = -1;
                this.topDown = reversed;
            }
        };
        WallPage.prototype.rtPage = function () {
            if (!this._rtPage)
                this._rtPage = TDev.RT.Page.mk(this);
            return this._rtPage;
        };
        WallPage.applySizeUpdate = function (e) {
            var walkHtml = function (e) {
                if (!e)
                    return;
                if (e.updateSizes)
                    e.updateSizes();
                TDev.Util.childNodes(e).forEach(walkHtml);
            };
            walkHtml(e);
        };
        WallPage.prototype.getFrame = function (prev, ret) {
            var _this = this;
            var rt = prev.rt;
            if (!this.isAuto()) {
                var frame = {};
                frame.previous = prev;
                frame.rt = prev.rt;
                frame.returnAddr = ret;
                frame.entryAddr = function (s) {
                    return s.rt.leave();
                };
                return frame;
            }
            if (!this.drawFn) {
                var f = prev.rt.compiled.lookupLibPage(this.libName, this.pageName);
                this.drawFn = function (prev, ret) {
                    var newFrame = f(prev);
                    return newFrame.invoke.apply(null, [newFrame, ret].concat(_this.drawArgs));
                };
            }
            return this.drawFn(prev, ret);
        };
        WallPage.prototype.refreshForNewScript = function () {
            this.drawFn = null;
        };
        WallPage.prototype.getCurrentBox = function () {
            return this.currentBox;
        };
        WallPage.prototype.setCurrentBox = function (box) {
            this.currentBox = box;
        };
        WallPage.prototype.setFullScreenElement = function (host, elt) {
            this.fullScreenElement = elt;
            host.setFullScreenElement(elt);
        };
        WallPage.prototype.clear = function () {
            this.rootBox = WallBox.CreateOrRecycleRoot(this.runtime, null);
            this.setCurrentBox(this.rootBox);
            this.lastChildCount = -1;
        };
        WallPage.prototype.startrender = function () {
            this.renderCount++;
            this.rootBox = WallBox.CreateOrRecycleRoot(this.runtime, this.rootBox);
            this.setCurrentBox(this.rootBox);
            this.lastChildCount = -1;
        };
        WallPage.prototype.render = function (host, popCount) {
            if (popCount === void 0) { popCount = 0; }
            TDev.Util.assertCode(popCount >= 0);
            var rootElt = this.getElement();
            var getElt = function (b) {
                return TDev.div("legacy-wall-box", b.getContent());
            };
            rootElt.style.background = "none";
            rootElt.style.color = this.fgColor;
            if (this.isAuto()) {
                rootElt.className = "wall-page " + (this.csslayout ? " html-page" : "box-page");
                this.setFullScreenElement(host, null);
                LayoutMgr.instance.render(this.rootBox, rootElt);
            }
            else {
                TDev.Util.assert(this.rootBox instanceof WallBox);
                var i = 0;
                var sz = this.rootBox.size();
                var newElts = [];
                if (sz > 0) {
                    var last = this.rootBox.get(sz - 1);
                    if (last.fullScreen) {
                        this.setFullScreenElement(host, TDev.div("wall-fullscreen", last.getContent()));
                        this.lastChildCount = -1;
                        return;
                    }
                }
                this.setFullScreenElement(host, null);
                rootElt.className = "wall-page classic-page";
                if (this.lastChildCount < 0) {
                    var children = [];
                    for (i = 0; i < sz; ++i)
                        children.push(this.rootBox.get(this.isReversed() ? i : sz - i - 1));
                    rootElt.setChildren(children.map(getElt));
                    newElts = [rootElt];
                }
                else {
                    for (i = this.lastChildCount - popCount; i < sz; ++i) {
                        var ch = getElt(this.rootBox.get(i));
                        newElts.push(ch);
                        if (this.isReversed()) {
                            rootElt.appendChild(ch);
                        }
                        else {
                            var first = rootElt.firstChild;
                            if (!first)
                                rootElt.appendChild(ch);
                            else
                                rootElt.insertBefore(ch, first);
                        }
                    }
                    for (var i = 0; i < popCount; ++i) {
                        if (this.isReversed()) {
                            var firstChild = rootElt.firstChild;
                            if (firstChild)
                                rootElt.removeChild(firstChild);
                        }
                        else {
                            var lastChild = rootElt.lastChild;
                            if (lastChild)
                                rootElt.removeChild(lastChild);
                        }
                    }
                }
                this.lastChildCount = sz;
                newElts.forEach(WallPage.applySizeUpdate);
            }
        };
        return WallPage;
    })();
    TDev.WallPage = WallPage;
    var BoxAttributes = (function () {
        function BoxAttributes() {
            this.tappedEvent = this.mkEv();
            this.textEditingEvent = this.mkEv();
        }
        BoxAttributes.prototype.applyToStyle = function (b) {
            TDev.Util.oops("must override");
        };
        BoxAttributes.prototype.mkEv = function () {
            var r = new TDev.RT.Event_();
            r.isPageEvent = true;
            return r;
        };
        return BoxAttributes;
    })();
    TDev.BoxAttributes = BoxAttributes;
    var HtmlAttributes = (function (_super) {
        __extends(HtmlAttributes, _super);
        function HtmlAttributes() {
            _super.apply(this, arguments);
        }
        HtmlAttributes.prototype.applyToStyle = function (b) {
            TDev.Util.assert(b instanceof HtmlBox);
            var bb = b;
            if (bb.element.nodeType == Node.ELEMENT_NODE) {
                bb.setRenderedClassnames(this.classnames);
                bb.setRenderedStyles(this.styles);
                bb.setRenderedAttributes(this.attributes);
            }
        };
        return HtmlAttributes;
    })(BoxAttributes);
    TDev.HtmlAttributes = HtmlAttributes;
    var LayoutAttributes = (function (_super) {
        __extends(LayoutAttributes, _super);
        function LayoutAttributes(isroot) {
            _super.call(this);
            this.flow = WallBox.FLOW_VERTICAL;
            this.fontSize = 0;
            this.fontFamily = "";
            this.background = "transparent";
            this.width = [0, Infinity];
            this.height = [0, Infinity];
            this.margin = [0, 0, 0, 0];
            this.padding = [0, 0, 0, 0];
            this.stretchwidth = -1;
            this.stretchheight = -1;
            this.stretchmargin = [0, 0, 0, 0];
            this.borderwidth = [0, 0, 0, 0];
            this.arrangement = [undefined, WallBox.ARRANGE_BASELINE];
            this.scroll = [isroot, isroot];
            this.legacystretch = [false, false];
            this.legacybaseline = true;
            this.wrap = undefined;
            this.wraplimit = 15;
            this.textEditedEvent = this.mkEv();
        }
        LayoutAttributes.prototype.applyToStyle = function (b) {
            b.setRenderedPositionMode("absolute");
            b.setRenderedTextAlign(this.textalign);
            b.setRenderedBackgroundColor(this.background);
            b.setRenderedBackgroundImages(this.backgroundImages);
            b.setRenderedColor(this.foreground);
            b.setRenderedFontWeight(this.fontWeight);
            b.setRenderedFontFamily(this.fontFamily);
            b.setRenderedFontSize(this.fontSize);
            b.setRenderedWrap(this.wrap, this.wraplimit);
            b.setRenderedBorder(this.border, this.borderwidth);
        };
        return LayoutAttributes;
    })(BoxAttributes);
    TDev.LayoutAttributes = LayoutAttributes;
    var BoxBase = (function () {
        function BoxBase(rt, parent, nodeId) {
            this.obsolete = false;
            this.recycled = false;
            this.reuseindex = 0;
            this.fresh = true;
            this.structuring_done = false;
            this.isSingleChild = false;
            this.delayedlayout = false;
            this.inputversions = new Array();
            this.runtime = rt;
            this.id = LayoutMgr.instance.numBoxes++;
            this.astNodeId = nodeId;
            this.isRoot = false;
            this.parent = parent;
            if (this.parent) {
                this.parent.children.push(this);
                this.depth = this.parent.depth + 1;
            }
            else {
                this.depth = 0;
            }
            this.children = [];
            this.pcTable = { "": this.astNodeId };
        }
        BoxBase.prototype.getContent = function () {
            return undefined;
        };
        BoxBase.prototype.setContent = function (e) {
        };
        BoxBase.prototype.RefreshOnScreen = function () {
        };
        BoxBase.prototype.SwapImageContent = function (newcontent) {
        };
        BoxBase.prototype.hookContent = function () {
        };
        BoxBase.prototype.mayReplaceWith = function (tagname) {
            return false;
        };
        BoxBase.prototype.isLeaf = function () {
            return false;
        };
        BoxBase.prototype.doLiveNavigation = function () {
            return true;
        };
        BoxBase.prototype.getRenderedWidth = function () {
            return 0;
        };
        BoxBase.prototype.getRenderedHeight = function () {
            return 0;
        };
        BoxBase.prototype.setHighlight = function (strong) {
            if (strong === void 0) { strong = true; }
        };
        BoxBase.prototype.clearHighlight = function () {
        };
        BoxBase.prototype.Obsolete = function () {
            this.obsolete = true;
            this.children.forEach(function (c) { return c.Obsolete(); });
        };
        BoxBase.prototype.getAstNodeId = function () {
            return this.astNodeId;
        };
        BoxBase.prototype.onFunctionCall = function (f, pc) {
            var functionNames = f.toString().match(/function ([^\(]+)/);
            if (functionNames !== null) {
                var functionName = functionNames[1];
                this.onCall(functionName, pc);
            }
        };
        BoxBase.prototype.onCall = function (fName, pc) {
            if (!pc)
                return;
            this.pcTable[fName] = pc;
        };
        BoxBase.prototype.tapped = function () {
            var done = false;
            if (LayoutMgr.instance.editMode) {
                if (LayoutMgr.instance.selectBox(this))
                    done = true;
            }
            else {
                if (this.obsolete || (this.runtime.eventQ && !this.runtime.eventQ.viewIsCurrent()))
                    return;
                if (this.attributes.tappedEvent.handlers) {
                    done = true;
                    this.setRenderedTappable(true, true);
                    this.runtime.queueLocalEvent(this.attributes.tappedEvent);
                    this.runtime.forcePageRefresh();
                }
                else if (this.contenttapapplies()) {
                    this.contenttaphandler();
                    done = true;
                }
            }
            if (LayoutMgr.instance.editMode || this instanceof WallBox)
                if (!done && this.parent)
                    this.parent.tapped();
        };
        BoxBase.prototype.withClick = function (h) {
            this.contenttaphandler = h;
        };
        BoxBase.prototype.contenttapapplies = function () {
            return this.contenttaphandler && !this.attributes.tappedEvent.handlers && !(this.isSingleChild && this.parent.attributes.tappedEvent.handlers);
        };
        BoxBase.prototype.setRenderedTappable = function (tappable, tapped) {
        };
        BoxBase.prototype.bindEditableText = function (s, handler, pc) {
            this.addTextEditHandler(handler);
            this.setInputText(s);
            this.onCall("binding", pc);
        };
        BoxBase.prototype.addTextEditHandler = function (handler) {
            if (handler instanceof TDev.RT.Ref) {
                this.attributes.textEditingEvent.addHandler(new TDev.RT.PseudoAction(function (rt, args) {
                    handler._set(args[0], rt.current);
                    rt.forcePageRefresh();
                }));
            }
            else
                this.attributes.textEditingEvent.addHandler(handler);
        };
        BoxBase.prototype.getEditableContent = function () {
            TDev.Util.oops("virtual");
            return undefined;
        };
        BoxBase.prototype.setEditableContent = function (s) {
            TDev.Util.oops("virtual");
        };
        BoxBase.prototype.invalidateCachedLayout = function (triggerdelayedrelayout) {
        };
        BoxBase.prototype.onInputTextChange = function () {
            if (LayoutMgr.instance.editMode)
                return;
            var text = this.getEditableContent();
            if (this.obsolete)
                return;
            if (this.inputversions.length === 3)
                this.inputversions.pop();
            if (this.inputversions[this.inputversions.length - 1] === text) {
                if (WallBox.debuginput)
                    TDev.Util.log("&&&" + this.id + "                 flag \"" + this.inputversions + "\"");
                LayoutMgr.instance.FlagTypingActivity("i" + this.id);
                return;
            }
            this.inputversions.push(text);
            if (WallBox.debuginput)
                TDev.Util.log("&&&" + this.id + "                 push \"" + this.inputversions + "\"");
            var parent = this.parent;
            if (this.attributes.textEditingEvent.handlers) {
                this.invalidateCachedLayout(false);
                if (this.inputversions.length >= 2) {
                    this.runtime.queueLocalEvent(this.lastqueuededit = this.attributes.textEditingEvent, [this.inputversions[1]]);
                    this.runtime.forcePageRefresh();
                }
            }
            else {
                this.invalidateCachedLayout(true);
            }
        };
        BoxBase.prototype.setInputText = function (text) {
            var cur = this.getEditableContent();
            var requeue = false;
            if (text === this.inputversions[1]) {
                this.inputversions.shift();
                if (WallBox.debuginput)
                    TDev.Util.log("&&&" + this.id + "                 prune \"" + this.inputversions + "\"");
                if (text !== cur) {
                    this.inputversions[1] = cur;
                    requeue = true;
                }
            }
            else if (this.inputversions.length === 1 && text != cur && LayoutMgr.instance.CheckTypingActivity("i" + this.id)) {
                this.inputversions = [text, cur];
                LayoutMgr.instance.ClearTypingActivity("i" + this.id);
                if (WallBox.debuginput)
                    TDev.Util.log("&&&" + this.id + "                 skip \"" + this.inputversions + "\"");
                requeue = true;
            }
            else {
                this.inputversions = [text];
                this.lastqueuededit = undefined;
                if (WallBox.debuginput)
                    TDev.Util.log("&&&" + this.id + "                 set \"" + this.inputversions + "\"");
            }
            if (this.inputversions.length == 1) {
                if (text !== cur) {
                    this.setEditableContent(text);
                    this.invalidateCachedLayout(false);
                }
                LayoutMgr.instance.ClearTypingActivity("i" + this.id);
            }
            else if (this.inputversions.length == 2 && requeue) {
                if (this.attributes.textEditingEvent.handlers) {
                    if (WallBox.debuginput)
                        TDev.Util.log("&&&" + this.id + "                 requeue \"" + this.inputversions + "\"");
                    this.runtime.queueLocalEvent(this.lastqueuededit = this.attributes.textEditingEvent, [this.inputversions[1]]);
                }
            }
        };
        BoxBase.CreateOrRecycleRoot = function (rt, p) {
            var cssmode = rt.onCssPage();
            if (LayoutMgr.RenderExecutionMode() && p && (cssmode == p instanceof HtmlBox)) {
                return p.recycle(rt, null, "", rt.onCssPage());
            }
            else {
                return cssmode ? (new HtmlBox(rt, null, "", "div")) : (new WallBox(rt, null, ""));
            }
        };
        BoxBase.CreateOrRecycleContainerBox = function (rt, cur, pc, tagName) {
            var candidate = null;
            if (LayoutMgr.RenderExecutionMode() && cur.recycled && cur.reuseindex < cur.prevchildren.length) {
                candidate = cur.prevchildren[cur.reuseindex];
                cur.reuseindex = cur.reuseindex + 1;
                if (candidate.mayReplaceWith(tagName))
                    return candidate.recycle(rt, cur, pc, rt.onCssPage());
            }
            var box = rt.onCssPage() ? new HtmlBox(rt, cur, pc, tagName) : new WallBox(rt, cur, pc);
            box.replaces = candidate;
            return box;
        };
        BoxBase.CreateOrRecycleLeafBox = function (rt, val) {
            var cur = rt.getCurrentBoxBase(true);
            var candidate = null;
            var pc = rt.getTopScriptPc();
            if (LayoutMgr.RenderExecutionMode() && cur.recycled && cur.reuseindex < cur.prevchildren.length) {
                candidate = cur.prevchildren[cur.reuseindex];
                cur.reuseindex = cur.reuseindex + 1;
                if (val !== null && candidate.content && candidate.reusekey === val && (!candidate.reuseversion || (candidate.reuseversion === val.versioncounter))) {
                    return candidate.recycle(rt, cur, pc, rt.onCssPage());
                }
            }
            var cssmode = rt.onCssPage();
            var box = rt.onCssPage() ? new HtmlBox(rt, cur, pc) : new WallBox(rt, cur, pc);
            box.reusekey = val;
            box.reuseversion = val && val.versioncounter;
            box.replaces = candidate;
            return box;
        };
        BoxBase.prototype.recycle = function (rt, parent, nodeId, cssmode) {
            TDev.Util.assert(!!cssmode === (this instanceof HtmlBox), "mixed up boxes");
            this.runtime = rt;
            this.parent = parent;
            this.astNodeId = nodeId;
            if (this.parent) {
                this.parent.children.push(this);
                TDev.Util.assert(this.depth === this.parent.depth + 1);
            }
            else {
                TDev.Util.assert(this.depth === 0);
            }
            this.recycled = true;
            this.structuring_done = false;
            this.prevchildren = this.children;
            this.reuseindex = 0;
            this.children = [];
            this.attributes = cssmode ? new HtmlAttributes() : new LayoutAttributes(this.depth == 0);
            this.pcTable = { "": this.astNodeId };
            return this;
        };
        BoxBase.prototype.doLayout = function () {
        };
        BoxBase.prototype.visitS = function () {
            if (this.recycled) {
                for (var i = this.children.length; i < this.prevchildren.length; i++) {
                    var b = this.prevchildren[i];
                    b.Obsolete();
                    this.element.removeChild(b.element);
                }
            }
            var p = this.parent;
            if (this.fresh || (p && !p.recycled)) {
                if (p) {
                    if (this.replaces) {
                        this.replaces.Obsolete();
                        p.element.replaceChild(this.element, this.replaces.element);
                        this.replaces = null;
                    }
                    else {
                        p.element.appendChild(this.element);
                    }
                }
                else {
                    TDev.Util.assert(this.isRoot);
                    LayoutMgr.instance.rootElement.appendChild(this.element);
                    LayoutMgr.instance.rootElement.onscroll = function (e) {
                        LayoutMgr.instance.onScroll();
                    };
                }
                if (this.fresh) {
                    this.hookContent();
                    this.fresh = false;
                }
            }
        };
        BoxBase.prototype.visitI = function () {
            this.attributes.applyToStyle(this);
        };
        BoxBase.debuginput = false;
        return BoxBase;
    })();
    TDev.BoxBase = BoxBase;
    var HtmlBox = (function (_super) {
        __extends(HtmlBox, _super);
        function HtmlBox(rt, parent, nodeId, tagName) {
            _super.call(this, rt, parent, nodeId);
            if (parent)
                TDev.Util.assert(parent instanceof HtmlBox);
            this.attributes = new HtmlAttributes();
            if (tagName !== undefined) {
                this.tagName = tagName;
                if (tagName && !TDev.HTML.allowedTagName(tagName))
                    TDev.Util.userError(TDev.lf("tag name {0} is not allowed", tagName));
                this.element = document.createElement(tagName);
                this.element.id = this.id.toString();
                this.attributes.applyToStyle(this);
            }
        }
        HtmlBox.prototype.isLeaf = function () {
            return !this.tagName;
        };
        HtmlBox.prototype.mayReplaceWith = function (tagName) {
            return (this.tagName === tagName);
        };
        HtmlBox.prototype.doLiveNavigation = function () {
            return !!this.tagName;
        };
        HtmlBox.prototype.setContent = function (e) {
            TDev.Util.check(this.isLeaf());
            TDev.Util.check(e != null);
            this.element = e;
            this.attributes.applyToStyle(this);
        };
        HtmlBox.prototype.getContent = function () {
            return this.element;
        };
        HtmlBox.prototype.RefreshOnScreen = function () {
        };
        HtmlBox.prototype.invalidateCachedLayout = function (triggerdelayedrelayout) {
        };
        HtmlBox.prototype.withClick = function (h) {
        };
        HtmlBox.prototype.getRenderedWidth = function () {
            return this.element.clientWidth;
        };
        HtmlBox.prototype.getRenderedHeight = function () {
            return this.element.clientHeight;
        };
        HtmlBox.prototype.getEditableContent = function () {
            return this.element.value;
        };
        HtmlBox.prototype.setEditableContent = function (text) {
            this.element.value = text;
        };
        HtmlBox.prototype.hookContent = function () {
            var _this = this;
            var tag = this.element && this.element.tagName;
            if (tag) {
                this.element.withClick(function () {
                    _this.tapped();
                });
                if (/input|textarea/i.test(tag))
                    this.element.oninput = function (e) {
                        _this.onInputTextChange();
                    };
            }
        };
        HtmlBox.prototype.SwapImageContent = function (newcontent) {
            var p = this.element.parentNode;
            if (p)
                p.replaceChild(newcontent, this.element);
            this.element = newcontent;
        };
        HtmlBox.prototype.setHighlight = function (strong) {
            if (strong === void 0) { strong = true; }
            if (this.element && this.element.style) {
                this.element.style.border = strong ? "5px dotted #C00" : "5px dotted #rgba(204, 0, 0, 0.6)";
                if (!strong)
                    this.element.style.background = "rgba(204, 0, 0, 0.4)";
            }
        };
        HtmlBox.prototype.clearHighlight = function () {
            this.element.style.cssText = this.rendered_styles;
        };
        HtmlBox.prototype.doLayout = function () {
            this.passA();
        };
        HtmlBox.prototype.passA = function () {
            this.visitI();
            for (var i = 0; i < this.children.length; i++) {
                this.children[i].passA();
            }
        };
        HtmlBox.prototype.addClassName = function (s, pc) {
            if (pc === void 0) { pc = ""; }
            if (!this.attributes.classnames)
                this.attributes.classnames = [];
            this.attributes.classnames.push(s);
            this.onCall("class name", pc);
        };
        HtmlBox.prototype.setAttribute = function (name, value, pc) {
            if (pc === void 0) { pc = ""; }
            if (!this.attributes.attributes)
                this.attributes.attributes = {};
            this.attributes.attributes[name] = value;
            this.onCall("attr:" + name, pc);
        };
        HtmlBox.prototype.setStyle = function (property, value, pc) {
            if (pc === void 0) { pc = ""; }
            if (!this.attributes.styles)
                this.attributes.styles = {};
            this.attributes.styles[property] = value;
            this.onCall("style:" + property, pc);
        };
        HtmlBox.prototype.setRenderedClassnames = function (names) {
            var cmp = (names && names.length > 0) ? names.join(' ') : '';
            if (cmp !== this.rendered_classnames) {
                if (cmp)
                    this.element.className = cmp;
                else
                    this.element.removeAttribute("class");
                this.rendered_classnames = cmp;
            }
        };
        HtmlBox.prototype.setRenderedStyles = function (styles) {
            var s = styles ? Object.keys(styles).map(function (k) { return k + ": " + styles[k]; }).join("; ") : "";
            if (s !== this.rendered_styles) {
                this.element.style.cssText = s;
                this.rendered_styles = s;
            }
        };
        HtmlBox.prototype.setRenderedAttributes = function (attributes) {
            var _this = this;
            var s = JSON.stringify(attributes);
            if (s !== this.rendered_attributes) {
                var prev = JSON.parse(this.rendered_attributes || "{}");
                Object.keys(attributes).forEach(function (k) {
                    _this.element.setAttribute(k, attributes[k]);
                    delete prev[k];
                });
                Object.keys(prev).forEach(function (k) { return _this.element.removeAttribute(k); });
                this.rendered_attributes = s;
            }
        };
        return HtmlBox;
    })(BoxBase);
    TDev.HtmlBox = HtmlBox;
    var WallBox = (function (_super) {
        __extends(WallBox, _super);
        function WallBox(rt, parent, nodeId) {
            var _this = this;
            _super.call(this, rt, parent, nodeId);
            this.cached_width = -1;
            this.cached_height = -1;
            this.cached_baseline = -1;
            this.cached_aspectratio = 0;
            if (parent)
                TDev.Util.assert(parent instanceof WallBox);
            this.attributes = new LayoutAttributes(this.depth == 0);
            this.contentType = WallBox.CONTENT_NONE;
            this.content = null;
            this.element = document.createElement("div");
            this.element.id = this.id.toString();
            this.element.withClick(function () {
                _this.tapped();
            });
            this.attributes.applyToStyle(this);
        }
        WallBox.prototype.mayReplaceWith = function (tagname) {
            return (tagname === "div" && this.content === null && this.contentType === WallBox.CONTENT_NONE);
        };
        WallBox.prototype.isLeaf = function () {
            return this.contentType != WallBox.CONTENT_NONE;
        };
        WallBox.prototype.RefreshOnScreen = function () {
            if (this.contentType == WallBox.CONTENT_NONE)
                return;
            TDev.Util.assert(this.contentType == WallBox.CONTENT_IMAGE);
            this.cached_height = -1;
            this.cached_width = -1;
            LayoutMgr.QueueReLayout();
        };
        WallBox.prototype.SwapImageContent = function (newcontent) {
            TDev.Util.assert(this.contentType == WallBox.CONTENT_IMAGE);
            this.element.removeAllChildren();
            this.element.appendChild(newcontent);
            this.content = newcontent;
            this.cached_height = -1;
            this.cached_width = -1;
            LayoutMgr.QueueReLayout();
        };
        WallBox.prototype.hookContent = function () {
            var _this = this;
            if (this.content && this.content !== this.element) {
                var e = this.element;
                if (this.contentType === WallBox.CONTENT_TEXT) {
                }
                else if (this.contentType === WallBox.CONTENT_INPUT) {
                    this.content.oninput = function (e) {
                        _this.onInputTextChange();
                    };
                    this.content.onchange = function (e) {
                        _this.onInputTextChangeDone();
                    };
                    this.content.onclick = function (e) {
                        if (LayoutMgr.instance.editMode) {
                            _this.tapped();
                        }
                        else {
                            if (_this.attributes.tappedEvent.handlers) {
                                _this.runtime.queueLocalEvent(_this.attributes.tappedEvent);
                            }
                        }
                    };
                }
                if (this.auxcontent)
                    e.appendChild(this.auxcontent);
                e.appendChild(this.content);
            }
        };
        WallBox.prototype.setHighlight = function (strong) {
            if (strong === void 0) { strong = true; }
            this.element.style.zIndex = strong ? "2" : "1";
            this.element.setAttribute("sel", strong ? "strong" : "weak");
        };
        WallBox.prototype.clearHighlight = function () {
            this.element.setAttribute("sel", "");
            this.element.style.zIndex = "auto";
        };
        WallBox.prototype.visitI = function () {
            if (!this.isRoot) {
                if (this.getFontFamily() === "")
                    this.setFontFamily(this.parent.getFontFamily());
                if (this.getFontSize() <= 0)
                    this.setFontSize(this.parent.getFontSize());
            }
            else {
                var width = this.runtime.host.fullWallWidth();
                var height = this.runtime.host.userWallHeight();
                this.setRenderedWidth(width);
                this.setRenderedHeight(height);
                if (this.getFontFamily() === "")
                    this.setFontFamily('"Segoe UI", "Segoe WP", "Helvetica Neue", Sans-Serif');
                if (this.getFontSize() <= 0)
                    this.setFontSize(TDev.SizeMgr.topFontSize);
            }
            var parent = this.parent;
            if (parent && parent.children.length === 1)
                this.isSingleChild = true;
            if (this.contentType == WallBox.CONTENT_TEXT) {
                var parentattributes = (parent.attributes);
                this.attributes.textalign = parentattributes.textalign;
                this.attributes.wrap = parentattributes.wrap;
                this.attributes.wraplimit = parentattributes.wraplimit;
            }
            if (this.contentType == WallBox.CONTENT_INPUT) {
                var parentattributes = (parent.attributes);
                this.attributes.textalign = WallBox.ARRANGE_LEFT;
                this.attributes.wrap = this.textarea ? (parentattributes.wrap === undefined ? true : parentattributes.wrap) : false;
                this.attributes.wraplimit = parentattributes.wraplimit;
            }
            if (this.contentType == WallBox.CONTENT_IMAGE) {
                var parentattributes = (parent.attributes);
                this.attributes.textalign = parentattributes.textalign;
                this.attributes.width = parentattributes.width;
                this.attributes.height = parentattributes.height;
                if (parentattributes.stretchwidth !== -1)
                    this.attributes.stretchwidth = parentattributes.stretchwidth;
                if (parentattributes.stretchheight !== -1)
                    this.attributes.stretchheight = parentattributes.stretchheight;
                this.attributes.wrap = parentattributes.wrap;
                this.attributes.wraplimit = parentattributes.wraplimit;
            }
            var numchildren = this.children.length;
            var harr = this.attributes.arrangement[WallBox.H];
            if (harr !== undefined) {
                if (this.attributes.flow !== WallBox.FLOW_HORIZONTAL) {
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        child.attributes.stretchmargin[WallBox.L] = (harr == WallBox.ARRANGE_RIGHT || harr == WallBox.ARRANGE_CENTER || harr == WallBox.ARRANGE_SPREAD) ? 1 : 0;
                        child.attributes.stretchmargin[WallBox.R] = (harr == WallBox.ARRANGE_LEFT || harr == WallBox.ARRANGE_CENTER || harr == WallBox.ARRANGE_SPREAD) ? 1 : 0;
                    }
                }
                else {
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        child.attributes.stretchmargin[WallBox.L] = (harr == WallBox.ARRANGE_SPREAD || (i == 0 ? (harr == WallBox.ARRANGE_RIGHT || harr == WallBox.ARRANGE_CENTER) : (harr == WallBox.ARRANGE_JUSTIFY))) ? 1 : 0;
                        child.attributes.stretchmargin[WallBox.R] = (harr == WallBox.ARRANGE_SPREAD || (i == (numchildren - 1) ? (harr == WallBox.ARRANGE_LEFT || harr == WallBox.ARRANGE_CENTER) : (harr == WallBox.ARRANGE_JUSTIFY || harr == WallBox.ARRANGE_CENTER))) ? 1 : 0;
                    }
                }
            }
            var varr = this.attributes.arrangement[WallBox.V];
            if (varr !== WallBox.ARRANGE_BASELINE) {
                if (this.attributes.flow !== WallBox.FLOW_VERTICAL) {
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        child.attributes.stretchmargin[WallBox.T] = (varr == WallBox.ARRANGE_BOTTOM || varr == WallBox.ARRANGE_CENTER || varr == WallBox.ARRANGE_SPREAD) ? 1 : 0;
                        child.attributes.stretchmargin[WallBox.B] = (varr == WallBox.ARRANGE_TOP || varr == WallBox.ARRANGE_CENTER || varr == WallBox.ARRANGE_SPREAD) ? 1 : 0;
                    }
                }
                else {
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        child.attributes.stretchmargin[WallBox.T] = (varr == WallBox.ARRANGE_SPREAD || (i == 0 ? (varr == WallBox.ARRANGE_BOTTOM || varr == WallBox.ARRANGE_CENTER) : (varr == WallBox.ARRANGE_JUSTIFY))) ? 1 : 0;
                        child.attributes.stretchmargin[WallBox.B] = (varr == WallBox.ARRANGE_SPREAD || (i == (numchildren - 1) ? (varr == WallBox.ARRANGE_TOP || varr == WallBox.ARRANGE_CENTER) : (varr == WallBox.ARRANGE_JUSTIFY))) ? 1 : 0;
                    }
                }
            }
            if (!this.attributes.legacybaseline && (this.attributes.flow !== WallBox.FLOW_HORIZONTAL || varr !== WallBox.ARRANGE_BASELINE || numchildren < 2))
                for (var i = 0; i < numchildren; i++) {
                    var child = this.children[i];
                    child.attributes.legacybaseline = false;
                }
            _super.prototype.visitI.call(this);
            this.setRenderedTappable((this.attributes.tappedEvent.handlers || this.contenttapapplies()) ? true : false, false);
        };
        WallBox.prototype.speculationwascorrect = function (scroll) {
            return scroll === this.D_scr;
        };
        WallBox.prototype.bound = function (min, val, max) {
            if (min > val)
                return min;
            if (max < val)
                return max;
            return val;
        };
        WallBox.prototype.tryPreserveAspectRatio = function () {
            return /img|canvas|video|audio|boardContainer|viewPicture/i.test(this.content.tagName) || /boardContainer|viewPicture/i.test(this.content.className);
        };
        WallBox.prototype.fillh = function (f) {
            if (f <= 0)
                return false;
            if (Math.abs(1 - f) < 0.0001 || this.isRoot)
                return true;
            var a = this.attributes.arrangement[WallBox.H];
            return (a === WallBox.ARRANGE_LEFT || a === WallBox.ARRANGE_CENTER || a === WallBox.ARRANGE_SPREAD || a === WallBox.ARRANGE_RIGHT);
        };
        WallBox.prototype.fillv = function (f) {
            if (f <= 0)
                return false;
            if (f == 1 || this.isRoot)
                return true;
            var a = this.attributes.arrangement[WallBox.V];
            return (a === WallBox.ARRANGE_TOP || a === WallBox.ARRANGE_BOTTOM || a === WallBox.ARRANGE_CENTER || a === WallBox.ARRANGE_SPREAD);
        };
        WallBox.prototype.doLayout = function () {
            this.passA();
            this.passBC();
            this.passD();
        };
        WallBox.prototype.passA = function () {
            this.visitI();
            for (var i = 0; i < this.children.length; i++) {
                this.children[i].passA();
            }
            this.visitA();
        };
        WallBox.prototype.passBC = function () {
            this.visitB();
            for (var i = 0; i < this.children.length; i++)
                this.children[i].passBC();
            this.visitC();
        };
        WallBox.prototype.passD = function () {
            this.visitD();
            for (var i = 0; i < this.children.length; i++)
                this.children[i].passD();
            if (this.layoutcompletehandler)
                this.layoutcompletehandler(this.getRenderedWidth(), this.getRenderedHeight());
        };
        WallBox.prototype.visitA = function () {
            var numchildren = this.children.length;
            if (numchildren === 0) {
                if (this.contentType != WallBox.CONTENT_NONE && this.cached_width === -1) {
                    this.setRenderedWidth(-1);
                    this.setRenderedHeight(-1);
                    if ((this.contentType === WallBox.CONTENT_TEXT || this.contentType === WallBox.CONTENT_INPUT)) {
                        if (this.contentType === WallBox.CONTENT_INPUT) {
                            var text = this.textarea ? this.content.value : this.content.value;
                            text = text + " abc";
                            this.auxcontent.textContent = text;
                        }
                        this.setRenderedWrap(false, this.attributes.wraplimit);
                        var newwidth = (this.contentType === WallBox.CONTENT_INPUT) ? this.auxcontent.scrollWidth + (this.textarea ? (LayoutMgr.instance.scrollbarWidth + 50) : 50) : this.element.scrollWidth;
                        this.setRenderedWrap(this.attributes.wrap, this.attributes.wraplimit);
                        this.cached_width = newwidth;
                        this.cached_aspectratio = 0;
                        if (this.attributes.legacybaseline && this.cached_baseline === -1) {
                            if (!this.baselineprobe) {
                                this.baselineprobe = TDev.span(null, "s");
                                this.baselineprobe.style.fontSize = "0";
                                var c = TDev.div(null, TDev.span(null, "L"), this.baselineprobe);
                                c.style.visibility = "hidden";
                                c.style.position = "absolute";
                                this.element.appendChild(c);
                            }
                            var yPosition = 0;
                            this.cached_baseline = this.baselineprobe.offsetTop - this.baselineprobe.scrollTop + this.baselineprobe.clientTop;
                            this.element.removeChild(this.baselineprobe.parentElement);
                            this.baselineprobe = null;
                        }
                    }
                    else {
                        var targetelt = (this.content.className === "viewPicture") ? this.content.firstChild : this.content;
                        var ha = targetelt ? Number(targetelt.getAttribute("height")) : 0;
                        var wa = targetelt ? Number(targetelt.getAttribute("width")) : 0;
                        if (targetelt && (targetelt.tagName == "IMG" || targetelt.tagName == "VIDEO" || targetelt.tagName == "AUDIO")) {
                            ha = ha || targetelt.height;
                            wa = wa || targetelt.width;
                        }
                        this.cached_width = wa || this.element.scrollWidth;
                        this.cached_aspectratio = (this.tryPreserveAspectRatio() && this.cached_width) ? ((ha || this.element.scrollHeight) / this.cached_width) : 0;
                        if ((this.cached_width == 0) && targetelt && (targetelt.tagName == "VIDEO" || targetelt.tagName == "AUDIO")) {
                            this.cached_width = 300;
                        }
                        if ((this.cached_width == 0) && targetelt && (targetelt.tagName == "IMG")) {
                            this.cached_width = 100;
                        }
                    }
                }
                if (this.contentType === WallBox.CONTENT_IMAGE) {
                    if (this.cached_aspectratio > 0) {
                        var scmin = this.attributes.height[WallBox.MIN] / this.cached_aspectratio;
                        var scmax = this.attributes.height[WallBox.MAX] / this.cached_aspectratio;
                        if ((this.attributes.width[WallBox.MIN] <= scmax) && (this.attributes.width[WallBox.MAX] >= scmin))
                            this.A_sc = this.bound(scmin, this.cached_width, scmax);
                        else
                            this.A_sc = this.cached_width;
                    }
                    else {
                        this.A_sc = this.cached_width;
                    }
                    this.A_asc = this.A_sc;
                    var flex = (this.attributes.stretchwidth == 1 || !this.tryPreserveAspectRatio() || (this.attributes.stretchwidth == -1 && this.content && this.content.tagName == "IMG")) ? 1 : 0;
                    this.A_mc = flex ? 0 : this.A_asc;
                    this.A_fcc = flex;
                }
                else if (this.contentType === WallBox.CONTENT_TEXT) {
                    var statedwidth = this.cached_width;
                    var safetywidth = statedwidth + 1;
                    this.A_sc = safetywidth;
                    this.A_asc = (this.attributes.wrap) ? Math.min(this.A_sc, this.attributes.wraplimit * TDev.SizeMgr.topFontSize) : this.A_sc;
                    this.A_mc = this.A_asc;
                    this.A_fcc = 1;
                }
                else if (this.contentType === WallBox.CONTENT_INPUT) {
                    this.A_sc = this.cached_width;
                    this.A_asc = (this.attributes.wrap) ? Math.min(this.A_sc, this.attributes.wraplimit * TDev.SizeMgr.topFontSize) : this.A_sc;
                    this.A_mc = this.A_asc;
                    this.A_fcc = 1;
                }
                else {
                    this.A_sc = 0;
                    this.A_mc = 0;
                    this.A_asc = 0;
                    this.A_fcc = 0;
                }
            }
            else {
                if (this.attributes.flow === WallBox.FLOW_HORIZONTAL) {
                    var lm_s = this.attributes.padding[WallBox.L];
                    var lm_f = 0;
                    this.A_mc = lm_s;
                    this.A_sc = lm_s;
                    this.A_scc = 0;
                    this.A_asc = lm_s;
                    this.A_fcc = 0;
                    this.A_fcs = 0;
                    this.A_fp = 0;
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        var ws = Math.max(0, child.A_sl - lm_s) + child.A_sr;
                        lm_s = child.A_sr;
                        if (i == numchildren - 1)
                            ws += Math.max(0, this.attributes.padding[WallBox.R] - lm_s);
                        this.A_mc += child.A_m + ws;
                        this.A_sc += child.A_s + ws;
                        this.A_scc += child.A_s;
                        this.A_asc += child.A_as + ws;
                        this.A_fcc += child.A_f;
                        this.A_fcs += Math.max(0, child.A_fl - lm_f) + child.A_fr;
                        this.A_fp = this.A_fp || child.A_fp;
                        lm_f = child.A_fr;
                    }
                }
                else if (this.attributes.flow === WallBox.FLOW_VERTICAL || this.attributes.flow === WallBox.FLOW_OVERLAY) {
                    this.A_mc = 0;
                    this.A_sc = 0;
                    this.A_asc = 0;
                    this.A_fcc = 0;
                    this.A_fp = 0;
                    for (var i = 0; i < this.children.length; i++) {
                        var child = this.children[i];
                        var ws = Math.max(child.A_sl, this.attributes.padding[WallBox.L]) + Math.max(child.A_sr, this.attributes.padding[WallBox.R]);
                        this.A_mc = Math.max(this.A_mc, child.A_m + ws);
                        this.A_asc = Math.max(this.A_asc, child.A_as + ws);
                        this.A_sc = Math.max(this.A_sc, child.A_s + ws);
                        this.A_fcc = Math.max(this.A_fcc, child.A_f);
                        this.A_fp = this.A_fp || child.A_fp;
                    }
                }
            }
            var min = this.attributes.width[WallBox.MIN];
            var max = this.attributes.width[WallBox.MAX];
            var borderwidth = this.attributes.borderwidth[WallBox.L] + this.attributes.borderwidth[WallBox.R];
            this.A_scr = (this.attributes.scroll[WallBox.V] && (!this.isRoot || LayoutMgr.instance.scrollspeculation)) ? LayoutMgr.instance.scrollbarWidth : 0;
            this.A_m = this.bound(min, (this.attributes.scroll[WallBox.H] ? Math.min(this.A_mc, TDev.SizeMgr.topFontSize * 6) : this.A_mc) + this.A_scr, max) + borderwidth;
            this.A_as = this.bound(min, (this.attributes.scroll[WallBox.H] ? Math.min(this.A_mc, TDev.SizeMgr.topFontSize * 10) : this.A_asc) + this.A_scr, max) + borderwidth;
            this.A_s = this.bound(min, this.A_sc + this.A_scr, max) + borderwidth;
            this.A_sl = this.attributes.margin[WallBox.L];
            this.A_sr = this.attributes.margin[WallBox.R];
            this.A_f = (this.attributes.stretchwidth == -1) ? ((this.A_fp || (numchildren == 0)) ? (this.fillh(this.A_fcc) ? 1 : this.A_fcc) : 0) : this.attributes.stretchwidth;
            this.A_fp = (this.attributes.stretchwidth == -1) ? ((numchildren > 0) && (max > min) && this.A_fp) : (this.attributes.legacystretch[WallBox.H] ? 0 : this.attributes.stretchwidth);
            this.A_fl = this.attributes.stretchmargin[WallBox.L];
            this.A_fr = this.attributes.stretchmargin[WallBox.R];
        };
        WallBox.prototype.visitB = function () {
            if (this.isRoot) {
                this.B_x = 0;
                this.B_s = this.runtime.host.fullWallWidth();
            }
            var borderwidth = (this.attributes.borderwidth[WallBox.L] + this.attributes.borderwidth[WallBox.R]);
            var allowance = this.B_s - this.A_scr - borderwidth;
            var numchildren = this.children.length;
            var overflow = false;
            if (numchildren == 0) {
                this.B_scr = false;
            }
            else {
                overflow = allowance < this.A_mc;
                this.B_scr = (overflow && this.attributes.scroll[WallBox.H]);
                if (this.attributes.flow === WallBox.FLOW_VERTICAL || this.attributes.flow === WallBox.FLOW_OVERLAY) {
                    var pl = this.attributes.padding[WallBox.L];
                    var pr = this.attributes.padding[WallBox.R];
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        var ws = Math.max(Math.max(pl, child.A_sl) + Math.max(pr, child.A_sr));
                        if (allowance > child.A_s + ws) {
                            var extra_c = 0;
                            if (child.A_f) {
                                var proportion = (child.A_f < 1 && this.fillh(child.A_f)) ? child.A_f : 1;
                                extra_c = Math.max(0, Math.min(proportion * allowance - ws, child.attributes.width[WallBox.MAX]) - child.A_s);
                            }
                            child.B_s = child.A_s + extra_c;
                            var extra_s = (child.A_fl + child.A_fr) ? ((allowance - child.B_s - ws) / (child.A_fl + child.A_fr)) : 0;
                            child.B_x = Math.max(pl, child.A_sl) + extra_s * child.A_fl;
                        }
                        else if (allowance > child.A_as + ws) {
                            child.B_x = Math.max(pl, child.A_sl);
                            child.B_s = allowance - ws;
                        }
                        else if (this.B_scr) {
                            child.B_x = Math.max(pl, child.A_sl);
                            child.B_s = child.A_as;
                        }
                        else {
                            child.B_x = Math.max(pl, child.A_sl);
                            child.B_s = Math.max(child.A_m, allowance - ws);
                        }
                    }
                }
                else if (this.attributes.flow === WallBox.FLOW_HORIZONTAL) {
                    if (allowance >= this.A_sc) {
                        var apply_fractional_stretches = this.fillh(this.A_fcc);
                        var space_for_content = allowance - (this.A_sc - this.A_scc);
                        var remainder = space_for_content;
                        var wsum = this.A_fcc;
                        var csum = this.A_scc;
                        if (remainder === 0 || wsum === 0)
                            this.children.forEach(function (c) { return remainder -= (c.B_s = c.A_s); });
                        else {
                            var limit = function (c) {
                                if (!apply_fractional_stretches || c.A_f >= 1)
                                    return c.attributes.width[WallBox.MAX];
                                else
                                    return Math.max(c.A_s, Math.min(c.attributes.width[WallBox.MAX], space_for_content * c.A_f));
                            };
                            var sortedlist = this.children.slice(0).sort(function (wb1, wb2) { return limit(wb1) - limit(wb2); });
                            for (var i = 0; i < sortedlist.length; i++) {
                                var c = sortedlist[i];
                                c.B_s = (c.A_f == 0) ? c.A_s : ((!apply_fractional_stretches || c.A_f >= 1) ? Math.min(c.attributes.width[WallBox.MAX], c.A_s + ((remainder - csum) / wsum) * c.A_f) : Math.max(c.A_s, Math.min(c.attributes.width[WallBox.MAX], space_for_content * c.A_f)));
                                remainder -= c.B_s;
                                csum -= c.A_s;
                                wsum -= c.A_f;
                            }
                        }
                        var extra_s = this.A_fcs ? (remainder / this.A_fcs) : 0;
                        var ls = this.attributes.padding[WallBox.L];
                        var lf = 0;
                        var x = ls;
                        for (var i = 0; i < numchildren; i++) {
                            var child = this.children[i];
                            x = x + Math.max(0, child.A_sl - ls) + Math.max(0, extra_s * child.A_fl - lf);
                            child.B_x = x;
                            ls = child.A_sr;
                            lf = extra_s * child.A_fr;
                            x = x + child.B_s + ls + lf;
                        }
                    }
                    else {
                        if (allowance > this.A_asc) {
                            this.distribute(allowance - this.A_asc, function (child) { return child.A_s - child.A_as; }, function (child, give) {
                                child.B_s = child.A_as + give;
                            });
                        }
                        else if (this.B_scr) {
                            for (var i = 0; i < numchildren; i++) {
                                var child = this.children[i];
                                child.B_s = child.A_as;
                            }
                        }
                        else {
                            overflow = true;
                            this.distribute(this.A_asc - allowance, function (child) { return child.A_as - child.A_m; }, function (child, take) {
                                child.B_s = child.A_as - take;
                            });
                        }
                        var x = 0;
                        var lastmargin = this.attributes.padding[WallBox.L];
                        for (var i = 0; i < numchildren; i++) {
                            var child = this.children[i];
                            x = x + Math.max(lastmargin, child.A_sl);
                            child.B_x = x;
                            x = x + child.B_s;
                            lastmargin = child.A_sr;
                        }
                    }
                }
            }
            if (!this.delayedlayout)
                this.setRenderedWidth(this.B_s - borderwidth);
            this.setRenderedHorizontalOverflow(this.B_scr ? "scroll" : (overflow ? "hidden" : ""));
            this.setRenderedX(this.B_x);
        };
        WallBox.prototype.distribute = function (amount, limit, apply) {
            if (amount === 0) {
                for (var i = 0; i < this.children.length; i++)
                    apply(this.children[i], 0);
            }
            else {
                var takers = this.children.length;
                var sortedlist = this.children.slice(0).sort(function (wb1, wb2) { return limit(wb1) - limit(wb2); });
                for (var i = 0; i < this.children.length; i++) {
                    var child = sortedlist[i];
                    var take = Math.min(limit(child), amount / takers);
                    amount -= take;
                    apply(child, take);
                    takers--;
                }
            }
        };
        WallBox.prototype.visitC = function () {
            var numchildren = this.children.length;
            if (numchildren === 0) {
                if (this.contentType != WallBox.CONTENT_NONE && this.cached_height === -1) {
                    if (this.contentType == WallBox.CONTENT_IMAGE) {
                        var targetelt = (this.content.className === "viewPicture") ? this.content.firstChild : this.content;
                        this.cached_height = targetelt ? Number(targetelt.getAttribute("height")) : 0;
                        if (!this.cached_height && this.content && this.content.tagName == "IMG") {
                            this.cached_height = targetelt.height;
                        }
                        if (!this.cached_height) {
                            this.setRenderedHeight(-1);
                            this.cached_height = this.element.clientHeight;
                        }
                    }
                    else if (this.contentType == WallBox.CONTENT_INPUT) {
                        this.setRenderedHeight(-1);
                        this.cached_height = this.auxcontent.scrollHeight + (this.textarea ? 5 : 0);
                    }
                    else {
                        this.setRenderedHeight(-1);
                        this.cached_height = this.element.clientHeight;
                    }
                }
                if (this.contentType === WallBox.CONTENT_IMAGE) {
                    if (this.cached_aspectratio > 0)
                        this.C_sc = ((this.delayedlayout ? this.cached_width : this.getRenderedWidth()) * this.cached_aspectratio);
                    else
                        this.C_sc = this.cached_height;
                    this.C_mc = this.attributes.stretchheight == 1 ? 0 : this.C_sc;
                    this.C_bc = 0;
                    this.C_fcc = this.attributes.stretchheight == 1 ? 1 : 0;
                }
                else if (this.contentType === WallBox.CONTENT_TEXT) {
                    this.C_sc = this.cached_height + 1;
                    this.C_mc = this.C_sc;
                    this.C_bc = this.cached_baseline;
                    this.C_fcc = 0;
                }
                else if (this.contentType === WallBox.CONTENT_INPUT) {
                    this.C_sc = this.cached_height + (this.textarea ? 1 : 6);
                    this.C_mc = this.C_sc;
                    this.C_bc = this.cached_baseline;
                    this.C_fcc = 0;
                }
                else {
                    this.C_sc = 0;
                    this.C_mc = 0;
                    this.C_bc = 0;
                    this.C_fcc = 0;
                }
                this.C_zc = 1;
            }
            else {
                this.C_bc = 0;
                var dobaseline = (this.attributes.arrangement[WallBox.V] === WallBox.ARRANGE_BASELINE);
                if (this.attributes.flow === WallBox.FLOW_VERTICAL) {
                    var firstchild = this.children[0];
                    if (dobaseline && firstchild.C_b) {
                        this.C_bc = firstchild.C_b + Math.max(this.attributes.padding[WallBox.T], firstchild.C_st);
                    }
                    var bm_s = this.attributes.padding[WallBox.T];
                    var bm_f = 0;
                    this.C_sc = bm_s;
                    this.C_scc = 0;
                    this.C_mc = bm_s;
                    this.C_fcc = 0;
                    this.C_fcs = 0;
                    this.C_fp = 0;
                    this.C_zc = 1;
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        var ws = Math.max(0, child.C_st - bm_s) + child.C_sb;
                        bm_s = child.C_sb;
                        if (i == numchildren - 1)
                            ws += Math.max(0, this.attributes.padding[WallBox.B] - bm_s);
                        this.C_sc += child.C_s + ws;
                        this.C_scc += child.C_s;
                        this.C_mc += child.C_m + ws;
                        this.C_fcc += child.C_f;
                        this.C_fcs += Math.max(0, child.C_ft - bm_f) + child.C_fb;
                        this.C_fp = this.C_fp || child.C_fp;
                        bm_f = child.C_fb;
                        this.C_zc = Math.max(this.C_zc, 1 + child.C_zc);
                    }
                }
                else if (this.attributes.flow === WallBox.FLOW_HORIZONTAL || this.attributes.flow === WallBox.FLOW_OVERLAY) {
                    if (dobaseline)
                        for (var i = 0; i < this.children.length; i++) {
                            var child = this.children[i];
                            if (child.C_b)
                                this.C_bc = Math.max(this.C_bc, child.C_b + Math.max(this.attributes.padding[WallBox.T], child.C_st));
                        }
                    this.C_sc = 0;
                    this.C_mc = 0;
                    this.C_fcc = 0;
                    this.C_fp = 0;
                    this.C_zc = 1;
                    for (var i = 0; i < this.children.length; i++) {
                        var child = this.children[i];
                        var wst = Math.max(this.attributes.padding[WallBox.T], child.C_st);
                        var bsa = child.C_b ? Math.max(0, this.C_bc - (child.C_b + wst)) : 0;
                        var ws = wst + bsa + Math.max(this.attributes.padding[WallBox.B], child.C_sb);
                        this.C_sc = Math.max(this.C_sc, child.C_s + ws);
                        this.C_mc = Math.max(this.C_mc, child.C_m + ws);
                        this.C_fcc = Math.max(this.C_fcc, child.C_f);
                        this.C_fp = this.C_fp || child.C_fp;
                        if (this.attributes.flow === WallBox.FLOW_OVERLAY)
                            this.C_zc = this.C_zc + child.C_zc;
                        else
                            this.C_zc = Math.max(this.C_zc, 1 + child.C_zc);
                    }
                }
            }
            var min = this.attributes.height[WallBox.MIN];
            var max = this.attributes.height[WallBox.MAX];
            var borderwidth = this.attributes.borderwidth[WallBox.T] + this.attributes.borderwidth[WallBox.B];
            this.C_scr = this.B_scr ? LayoutMgr.instance.scrollbarHeight : 0;
            this.C_m = this.bound(min, (this.attributes.scroll[WallBox.V] ? Math.min(this.C_mc, TDev.SizeMgr.topFontSize * 6) : this.C_mc) + this.C_scr, max) + borderwidth;
            this.C_s = this.bound(min, this.C_sc + this.C_scr, max) + borderwidth;
            this.C_st = this.attributes.margin[WallBox.T];
            this.C_sb = this.attributes.margin[WallBox.B];
            this.C_f = (this.attributes.stretchheight == -1) ? ((this.C_fp || (numchildren == 0)) ? (this.fillv(this.C_fcc) ? 1 : this.C_fcc) : 0) : this.attributes.stretchheight;
            this.C_fp = (this.attributes.stretchheight == -1) ? ((numchildren > 0) && (max > min) && this.C_fp) : (this.attributes.legacystretch[WallBox.V] ? 0 : this.attributes.stretchheight);
            this.C_ft = this.attributes.stretchmargin[WallBox.T];
            this.C_fb = this.attributes.stretchmargin[WallBox.B];
            this.C_b = (this.attributes.legacybaseline && this.C_bc) ? (this.C_bc + this.attributes.borderwidth[WallBox.T]) : 0;
        };
        WallBox.prototype.visitD = function () {
            if (this.isRoot) {
                this.D_y = 0;
                this.D_s = this.runtime.host.userWallHeight();
                this.D_z = 1;
                this.D_b = this.C_b;
            }
            var overflow = false;
            var borderwidth = (this.attributes.borderwidth[WallBox.T] + this.attributes.borderwidth[WallBox.B]);
            var allowance = this.D_s - this.C_scr - borderwidth;
            var baseline = this.attributes.legacybaseline ? ((this.attributes.arrangement[WallBox.V] === WallBox.ARRANGE_BASELINE) ? Math.max(this.C_bc, this.D_b - this.attributes.borderwidth[WallBox.T]) : 0) : this.C_bc;
            var numchildren = this.children.length;
            if (numchildren === 0) {
                this.D_scr = false;
            }
            else {
                overflow = allowance < this.C_mc + this.C_scr;
                this.D_scr = (overflow && this.attributes.scroll[WallBox.V]);
                var nextz = this.D_z + 1;
                if (this.attributes.flow === WallBox.FLOW_HORIZONTAL || this.attributes.flow === WallBox.FLOW_OVERLAY) {
                    var pt = this.attributes.padding[WallBox.T];
                    var pb = this.attributes.padding[WallBox.B];
                    for (var i = 0; i < numchildren; i++) {
                        var child = this.children[i];
                        var wst = Math.max(pt, child.C_st, child.C_b ? Math.max(0, baseline - child.C_b) : 0);
                        var ws = wst + Math.max(pb, child.C_sb);
                        if (allowance > child.C_s + ws) {
                            var extra_c = 0;
                            if (child.C_f) {
                                var proportion = (child.C_f < 1 && this.fillv(child.C_f)) ? child.C_f : 1;
                                extra_c = Math.max(0, Math.min(allowance * proportion - ws, child.attributes.height[WallBox.MAX]) - child.C_s);
                            }
                            child.D_s = child.C_s + extra_c;
                            var extra_s = (child.C_ft + child.C_fb) ? ((allowance - child.D_s - ws) / (child.C_ft + child.C_fb)) : 0;
                            child.D_y = wst + extra_s * child.C_ft;
                        }
                        else if (this.D_scr) {
                            child.D_y = wst;
                            child.D_s = child.C_s;
                        }
                        else {
                            child.D_y = wst;
                            child.D_s = Math.max(child.C_m, allowance - ws);
                        }
                        child.D_b = Math.max(0, baseline - child.D_y);
                        child.D_z = nextz;
                        if (this.attributes.flow === WallBox.FLOW_OVERLAY)
                            nextz = nextz + child.C_zc;
                    }
                }
                else if (this.attributes.flow === WallBox.FLOW_VERTICAL) {
                    var firstchild = this.children[0];
                    var bsa = firstchild.C_b ? Math.max(0, baseline - firstchild.C_b) : 0;
                    var pt = Math.max(this.attributes.padding[WallBox.T], bsa);
                    if (allowance >= this.C_sc) {
                        var apply_fractional_stretches = this.fillv(this.C_fcc);
                        var space_for_content = allowance - (this.C_sc - this.C_scc);
                        var remainder = space_for_content;
                        var wsum = this.C_fcc;
                        var csum = this.C_scc;
                        if (remainder === 0 || wsum === 0)
                            this.children.forEach(function (c) { return remainder -= (c.D_s = c.C_s); });
                        else {
                            var limit = function (c) {
                                if (!apply_fractional_stretches || c.C_f >= 1)
                                    return c.attributes.height[WallBox.MAX];
                                else
                                    return Math.max(c.C_s, Math.min(c.attributes.height[WallBox.MAX], space_for_content * c.C_f));
                            };
                            var sortedlist = this.children.slice(0).sort(function (wb1, wb2) { return limit(wb1) - limit(wb2); });
                            for (var i = 0; i < sortedlist.length; i++) {
                                var c = sortedlist[i];
                                c.D_s = (c.C_f == 0) ? c.C_s : ((!apply_fractional_stretches || c.C_f >= 1) ? Math.min(c.attributes.height[WallBox.MAX], c.C_s + ((remainder - csum) / wsum) * c.C_f) : Math.max(c.C_s, Math.min(c.attributes.height[WallBox.MAX], space_for_content * c.C_f)));
                                remainder -= c.D_s;
                                csum -= c.C_s;
                                wsum -= c.C_f;
                            }
                        }
                        var extra_s = this.C_fcs ? (remainder / this.C_fcs) : 0;
                        var y = pt;
                        var ls = pt;
                        var lf = 0;
                        for (var i = 0; i < numchildren; i++) {
                            var child = this.children[i];
                            y = y + Math.max(0, child.C_st - ls) + Math.max(0, extra_s * child.C_ft - lf);
                            child.D_y = y;
                            ls = child.C_sb;
                            lf = extra_s * child.C_fb;
                            y = y + child.D_s + ls + lf;
                            child.D_z = nextz;
                            child.D_b = Math.max(0, baseline - child.D_y);
                        }
                    }
                    else {
                        if (this.D_scr) {
                            for (var i = 0; i < numchildren; i++) {
                                var child = this.children[i];
                                child.D_s = child.C_s;
                            }
                        }
                        else if (allowance > this.C_mc) {
                            this.distribute(allowance - this.C_mc, function (child) { return child.C_s - child.C_m; }, function (child, give) {
                                child.D_s = child.C_m + give;
                            });
                        }
                        else {
                            overflow = allowance < this.C_mc;
                            for (var i = 0; i < numchildren; i++) {
                                var child = this.children[i];
                                child.D_s = child.C_m;
                            }
                        }
                        var y = 0;
                        var lastmargin = pt;
                        for (var i = 0; i < numchildren; i++) {
                            var child = this.children[i];
                            y = y + Math.max(lastmargin, child.C_st);
                            child.D_y = y;
                            child.D_b = Math.max(0, baseline - child.D_y);
                            y = y + child.D_s;
                            lastmargin = child.C_sb;
                            child.D_z = nextz;
                            child.D_b = Math.max(0, baseline - child.D_y);
                        }
                    }
                }
            }
            if (!this.delayedlayout)
                this.setRenderedHeight(this.D_s - borderwidth);
            this.setRenderedVerticalOverflow(this.D_scr ? "scroll" : (overflow ? "hidden" : ""));
            this.setRenderedY(this.D_y);
            this.setRenderedZIndex(this.D_z);
        };
        WallBox.prototype.getEditableContent = function () {
            TDev.Util.assert(this.contentType == WallBox.CONTENT_INPUT);
            return this.textarea ? this.content.value : this.content.value;
        };
        WallBox.prototype.setEditableContent = function (text) {
            TDev.Util.assert(this.contentType == WallBox.CONTENT_INPUT);
            if (this.textarea)
                this.content.value = text;
            else
                this.content.value = text;
        };
        WallBox.prototype.invalidateCachedLayout = function (triggerdelayedrelayout) {
            var _this = this;
            this.cached_width = -1;
            this.cached_height = -1;
            if (triggerdelayedrelayout)
                TDev.Util.setTimeout(100, function () {
                    if (_this.cached_width === -1)
                        LayoutMgr.QueueReLayout();
                });
        };
        WallBox.prototype.onInputTextChangeDone = function () {
            if (this.obsolete)
                return;
            if (LayoutMgr.instance.editMode) {
            }
            else {
                this.cached_width = -1;
                this.cached_height = -1;
                var parent = this.parent;
                var text = this.textarea ? this.content.value : this.content.value;
                if (parent && parent.attributes.textEditedEvent.handlers) {
                    this.runtime.queueLocalEvent(parent.attributes.textEditedEvent, [text]);
                }
                this.runtime.forcePageRefresh();
            }
        };
        WallBox.prototype.size = function () {
            return this.children.length;
        };
        WallBox.prototype.get = function (index) {
            return this.children[index];
        };
        WallBox.prototype.shift = function () {
            if (this.children.length > 0)
                this.children.shift();
        };
        WallBox.prototype.forEachChild = function (f) {
            this.children.forEach(f);
        };
        WallBox.prototype.getDepth = function () {
            return this.depth;
        };
        WallBox.prototype.getId = function () {
            return this.id;
        };
        WallBox.prototype.getElement = function () {
            return this.element;
        };
        WallBox.prototype.getFlow = function () {
            return this.attributes.flow;
        };
        WallBox.prototype.getAlign = function () {
            return this.attributes.textalign;
        };
        WallBox.prototype.getBackground = function () {
            return this.attributes.background;
        };
        WallBox.prototype.getForeground = function () {
            return this.attributes.foreground;
        };
        WallBox.prototype.getFontSize = function () {
            return this.attributes.fontSize;
        };
        WallBox.prototype.getFontWeight = function () {
            return this.attributes.fontWeight;
        };
        WallBox.prototype.getFontFamily = function () {
            return this.attributes.fontFamily;
        };
        WallBox.prototype.getRenderedWidth = function () {
            return this.rendered_width;
        };
        WallBox.prototype.getRenderedHeight = function () {
            return this.rendered_height;
        };
        WallBox.prototype.getContent = function () {
            return this.content;
        };
        WallBox.prototype.setFlow = function (flow, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.flow = flow;
            this.onCall("flow", pc);
        };
        WallBox.prototype.setBackground = function (background, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.background = background;
            this.onCall("background", pc);
        };
        WallBox.prototype.addBackgroundImage = function (img, pc) {
            if (pc === void 0) { pc = ""; }
            if (!this.attributes.backgroundImages)
                this.attributes.backgroundImages = [];
            this.attributes.backgroundImages.splice(0, 0, img);
            this.onCall("background image", pc);
        };
        WallBox.prototype.setForeground = function (foreground, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.foreground = foreground;
            this.onCall("foreground", pc);
        };
        WallBox.prototype.setFontSize = function (fontSize, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.fontSize = fontSize;
            this.onCall("font size", pc);
        };
        WallBox.prototype.setFontWeight = function (fontWeight, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.fontWeight = fontWeight;
            this.onCall("font weight", pc);
        };
        WallBox.prototype.setFontFamily = function (fontFamily, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.fontFamily = fontFamily;
            this.onCall("font family", pc);
        };
        WallBox.prototype.setScrolling = function (h, v, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.scroll = [h, v];
            this.onCall("scrolling", pc);
        };
        WallBox.prototype.setEmBorder = function (color, width, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.border = color;
            var bw = TDev.SizeMgr.topFontSize * width;
            this.attributes.borderwidth = [bw, bw, bw, bw];
            this.onCall("border", pc);
        };
        WallBox.prototype.setBorderWidth = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.borderwidth = [top, right, bottom, left];
            this.onCall("border widths", pc);
        };
        WallBox.prototype.setAllMargins = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.margin = [top, right, bottom, left];
            this.onCall("margins", pc);
        };
        WallBox.prototype.setPadding = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.padding = [top, right, bottom, left];
            this.onCall("margins", pc);
        };
        WallBox.prototype.setWrap = function (wrap, width, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.wrap = wrap;
            this.attributes.wraplimit = Math.max(width, 1);
            this.onCall("text wrap", pc);
        };
        WallBox.prototype.setWidth = function (width, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.width = [width, width];
            this.onCall("width", pc);
        };
        WallBox.prototype.setWidthRange = function (minWidth, maxWidth, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.width[WallBox.MIN] = minWidth;
            this.attributes.width[WallBox.MAX] = maxWidth;
            this.onCall("width range", pc);
        };
        WallBox.prototype.setHorizontalStretch = function (n, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.stretchwidth = n;
            this.onCall("horizontal stretch", pc);
        };
        WallBox.prototype.setVerticalStretch = function (n, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.stretchheight = n;
            this.onCall("vertical stretch", pc);
        };
        WallBox.prototype.setHorizontalAlignment = function (left, right, pc) {
            if (pc === void 0) { pc = ""; }
            left = Math.max(0, Math.min(1, left));
            right = Math.max(0, Math.min(1, right));
            if (left < 1)
                this.attributes.stretchmargin[WallBox.L] = (1 - left);
            if (right < 1)
                this.attributes.stretchmargin[WallBox.R] = (1 - left);
            if (left > 0 && right > 0)
                this.attributes.stretchwidth = 1;
            if (right == 0 && left != 0)
                this.attributes.textalign = WallBox.ARRANGE_LEFT;
            else if (right != 0 && left == 0)
                this.attributes.textalign = WallBox.ARRANGE_RIGHT;
            else if (right == 0 && left == 0)
                this.attributes.textalign = WallBox.ARRANGE_CENTER;
            else
                this.attributes.textalign = WallBox.ARRANGE_JUSTIFY;
            this.attributes.legacystretch[WallBox.H] = true;
            this.onCall("horizontal alignment", pc);
        };
        WallBox.prototype.setVerticalAlignment = function (top, bottom, pc) {
            if (pc === void 0) { pc = ""; }
            top = Math.max(0, Math.min(1, top));
            bottom = Math.max(0, Math.min(1, bottom));
            if (top < 1)
                this.attributes.stretchmargin[WallBox.T] = (1 - top);
            if (bottom < 1)
                this.attributes.stretchmargin[WallBox.B] = (1 - bottom);
            if (top > 0 && bottom > 0)
                this.attributes.stretchheight = 1;
            this.attributes.legacybaseline = false;
            this.attributes.legacystretch[WallBox.V] = true;
            this.onCall("vertical alignment", pc);
        };
        WallBox.prototype.setHorizontalArrangement = function (what, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.arrangement[WallBox.H] = what;
            this.attributes.textalign = what;
            this.onCall("horizontal arrangement", pc);
        };
        WallBox.prototype.setVerticalArrangement = function (what, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.arrangement[WallBox.V] = what;
            if (what != WallBox.ARRANGE_BASELINE)
                this.attributes.legacybaseline = false;
            this.onCall("vertical arrangement", pc);
        };
        WallBox.prototype.setHeight = function (height, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.height = [height, height];
            this.onCall("height", pc);
        };
        WallBox.prototype.setHeightRange = function (minHeight, maxHeight, pc) {
            if (pc === void 0) { pc = ""; }
            this.attributes.height[WallBox.MIN] = minHeight;
            this.attributes.height[WallBox.MAX] = maxHeight;
            this.onCall("height range", pc);
        };
        WallBox.prototype.setEmFontSize = function (fontSize, pc) {
            if (pc === void 0) { pc = ""; }
            this.setFontSize(TDev.SizeMgr.topFontSize * fontSize, pc);
        };
        WallBox.prototype.setEmBorderWidth = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.setBorderWidth(TDev.SizeMgr.topFontSize * top, TDev.SizeMgr.topFontSize * right, TDev.SizeMgr.topFontSize * bottom, TDev.SizeMgr.topFontSize * left, pc);
        };
        WallBox.prototype.setAllEmMargins = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.setAllMargins(TDev.SizeMgr.topFontSize * top, TDev.SizeMgr.topFontSize * right, TDev.SizeMgr.topFontSize * bottom, TDev.SizeMgr.topFontSize * left, pc);
        };
        WallBox.prototype.setEmPadding = function (top, right, bottom, left, pc) {
            if (pc === void 0) { pc = ""; }
            this.setPadding(TDev.SizeMgr.topFontSize * top, TDev.SizeMgr.topFontSize * right, TDev.SizeMgr.topFontSize * bottom, TDev.SizeMgr.topFontSize * left, pc);
        };
        WallBox.prototype.setEmWidth = function (width, pc) {
            if (pc === void 0) { pc = ""; }
            this.setWidth(TDev.SizeMgr.topFontSize * width, pc);
        };
        WallBox.prototype.setEmWidthRange = function (minWidth, maxWidth, pc) {
            if (pc === void 0) { pc = ""; }
            this.setWidthRange(TDev.SizeMgr.topFontSize * minWidth, TDev.SizeMgr.topFontSize * maxWidth, pc);
        };
        WallBox.prototype.setEmHeight = function (height, pc) {
            if (pc === void 0) { pc = ""; }
            this.setHeight(TDev.SizeMgr.topFontSize * height, pc);
        };
        WallBox.prototype.setEmHeightRange = function (minHeight, maxHeight, pc) {
            if (pc === void 0) { pc = ""; }
            this.setHeightRange(TDev.SizeMgr.topFontSize * minHeight, TDev.SizeMgr.topFontSize * maxHeight, pc);
        };
        WallBox.prototype.setContent = function (e) {
            TDev.Util.check(e != null);
            if (e instanceof HTMLTextAreaElement || e instanceof HTMLInputElement) {
                this.contentType = WallBox.CONTENT_INPUT;
                this.content = e;
                this.auxcontent = TDev.span("wall-text", "");
                this.auxcontent.style.visibility = "hidden";
                this.auxcontent.style.position = "absolute";
                this.auxcontent.style.left = "0px";
                this.auxcontent.style.top = "0px";
                this.auxcontent.style.padding = "1px";
                this.auxcontent.style.color = "red";
                this.auxcontent.style.zIndex = "-1";
            }
            else if (e instanceof HTMLElement) {
                this.contentType = WallBox.CONTENT_IMAGE;
                this.content = e;
            }
            else {
                this.contentType = WallBox.CONTENT_TEXT;
                var str = (e || "").toString();
                this.content = TDev.span("wall-text", str);
            }
        };
        WallBox.prototype.setRenderedX = function (x) {
            if (x !== this.rendered_x) {
                if (typeof (this.rendered_x) === "invalid" && !this.isRoot) {
                    this.element.style.position = "absolute";
                }
                this.element.style.left = x + "px";
                this.rendered_x = x;
            }
        };
        WallBox.prototype.setRenderedY = function (y) {
            if (y !== this.rendered_y) {
                this.element.style.top = y + "px";
                this.rendered_y = y;
            }
        };
        WallBox.prototype.setRenderedWidth = function (width) {
            if (width !== this.rendered_width) {
                this.element.style.width = (width >= 0) ? (width + "px") : "";
                if (this.contentType != WallBox.CONTENT_NONE && this.contentType != WallBox.CONTENT_TEXT) {
                    var extra = (this.contentType == WallBox.CONTENT_INPUT && !this.textarea) ? 6 : 0;
                    var targetelt = (this.content.className === "viewPicture") ? this.content.firstChild : this.content;
                    if (targetelt)
                        targetelt.style.width = (width > 0) ? ((width - extra) + "px") : "";
                    if (this.contentType === WallBox.CONTENT_INPUT && this.textarea)
                        this.auxcontent.style.width = (width >= 0) ? ((width - 10) + "px") : "";
                }
                this.rendered_width = width;
                this.cached_height = -1;
            }
        };
        WallBox.prototype.setRenderedHeight = function (height) {
            if (height !== this.rendered_height) {
                this.element.style.height = (height > 0) ? (height + "px") : "";
                if (this.contentType != WallBox.CONTENT_NONE && this.contentType != WallBox.CONTENT_TEXT) {
                    var extra = (this.contentType == WallBox.CONTENT_INPUT && !this.textarea) ? 6 : 0;
                    var targetelt = (this.content.className === "viewPicture") ? this.content.firstChild : this.content;
                    if (targetelt)
                        targetelt.style.height = (height > 0) ? ((height - extra) + "px") : "";
                    if (this.contentType == WallBox.CONTENT_INPUT && this.textarea && height >= this.cached_height) {
                        this.content.style.overflow = "hidden";
                    }
                }
                this.rendered_height = height;
            }
        };
        WallBox.prototype.setRenderedFontFamily = function (family) {
            if (family !== this.rendered_fontfamily) {
                this.element.style.fontFamily = (family === "Default" ? '"Segoe UI", "Segoe WP", "Helvetica Neue", Sans-Serif' : family);
                this.rendered_fontfamily = family;
                this.cached_height = -1;
                this.cached_baseline = -1;
                this.cached_width = -1;
            }
        };
        WallBox.prototype.setRenderedFontWeight = function (fw) {
            var fontweight = fw || "inherit";
            if (fontweight !== this.rendered_fontweight) {
                this.element.style.fontWeight = fontweight;
                this.rendered_fontweight = fontweight;
                this.cached_height = -1;
                this.cached_baseline = -1;
                this.cached_width = -1;
            }
        };
        WallBox.prototype.setRenderedFontSize = function (size) {
            if (size !== this.rendered_fontsize) {
                this.element.style.fontSize = (size > 0) ? (size + "px") : "inherit";
                this.rendered_fontsize = size;
                this.cached_height = -1;
                this.cached_baseline = -1;
                this.cached_width = -1;
            }
        };
        WallBox.prototype.setRenderedColor = function (clr) {
            var color = clr || "inherit";
            if (color !== this.rendered_foregroundcolor) {
                this.element.style.color = color;
                this.rendered_foregroundcolor = color;
            }
        };
        WallBox.prototype.setRenderedBackgroundColor = function (color) {
            if (color !== this.rendered_backgroundcolor) {
                this.element.style.backgroundColor = color;
                this.rendered_backgroundcolor = color;
            }
        };
        WallBox.prototype.setRenderedBackgroundImages = function (images) {
            var css = images ? images.map(function (img) { return TDev.HTML.cssImage(img.url) + ' ' + (img.position || 'center') + ' / ' + (img.size || 'cover') + ' ' + (img.repeat || 'no-repeat') + ' ' + (img.attachment || 'scroll'); }).join(', ') : '';
            if (css !== this.rendered_background) {
                this.element.style.background = css;
                this.rendered_background = css;
            }
        };
        WallBox.prototype.setRenderedTappable = function (tappable, tapped) {
            var x = "wall-box" + (tappable ? " tappable " : "") + (tapped ? " tapped" : "");
            if (x !== this.rendered_tappable) {
                this.element.className = x;
                this.rendered_tappable = x;
            }
        };
        WallBox.prototype.setRenderedPositionMode = function (positionmode) {
            if (positionmode !== this.rendered_positionmode) {
                this.element.style.position = positionmode;
                this.rendered_positionmode = positionmode;
            }
        };
        WallBox.prototype.min1pixel = function (x) {
            return ((x > 0 && x < 1) ? "1" : x.toString()) + "px";
        };
        WallBox.prototype.setRenderedBorder = function (clr, width) {
            var color = clr || "black";
            if (color !== this.rendered_border) {
                this.element.style.borderColor = color;
                this.rendered_border = color;
            }
            if (!this.rendered_borderwidth || width[0] !== this.rendered_borderwidth[0] || width[1] !== this.rendered_borderwidth[1] || width[2] !== this.rendered_borderwidth[2] || width[3] !== this.rendered_borderwidth[3]) {
                var visible = (width[0] || width[1] || width[2] || width[3]);
                this.element.style.borderStyle = visible ? "solid" : "none";
                this.element.style.borderTopWidth = visible ? this.min1pixel(width[WallBox.T]) : "";
                this.element.style.borderRightWidth = visible ? this.min1pixel(width[WallBox.R]) : "";
                this.element.style.borderBottomWidth = visible ? this.min1pixel(width[WallBox.B]) : "";
                this.element.style.borderLeftWidth = visible ? this.min1pixel(width[WallBox.L]) : "";
                this.rendered_borderwidth = width.slice(0);
            }
        };
        WallBox.prototype.setRenderedTextAlign = function (alignment) {
            if (alignment !== this.rendered_textalign) {
                switch (alignment) {
                    case WallBox.ARRANGE_RIGHT:
                        this.element.style.textAlign = "right";
                        break;
                    case WallBox.ARRANGE_CENTER:
                        this.element.style.textAlign = "center";
                        break;
                    case WallBox.ARRANGE_JUSTIFY:
                        this.element.style.textAlign = "justify";
                        break;
                    default:
                        this.element.style.textAlign = "left";
                        break;
                }
                this.cached_height = -1;
                this.cached_width = -1;
                this.rendered_textalign = alignment;
            }
        };
        WallBox.prototype.setRenderedHorizontalOverflow = function (mode) {
            if (mode != this.rendered_hmode) {
                this.element.style.overflowX = (this.rendered_sideview || (mode == "scroll" && (this.contentType == WallBox.CONTENT_INPUT))) ? "" : mode;
                this.rendered_hmode = mode;
            }
        };
        WallBox.prototype.setRenderedVerticalOverflow = function (mode) {
            if (mode != this.rendered_vmode) {
                this.element.style.overflowY = (this.rendered_sideview || (mode == "scroll" && (this.contentType == WallBox.CONTENT_INPUT))) ? "" : mode;
                this.rendered_vmode = mode;
            }
        };
        WallBox.prototype.setRenderedSideView = function (sideview) {
            if (this.rendered_sideview != sideview) {
                this.element.style.overflowX = (sideview || (this.rendered_hmode == "scroll" && (this.contentType == WallBox.CONTENT_INPUT))) ? "" : this.rendered_hmode;
                this.element.style.overflowY = (sideview || (this.rendered_vmode == "scroll" && (this.contentType == WallBox.CONTENT_INPUT))) ? "" : this.rendered_vmode;
                this.rendered_sideview = sideview;
            }
        };
        WallBox.prototype.setRenderedWrap = function (wrap, wraplimit) {
            wrap = wrap || false;
            if (wrap != this.rendered_wrap || wraplimit != this.rendered_wraplimit) {
                this.element.style.whiteSpace = wrap ? (this.element.style.textAlign === "justify" ? "pre-line" : "pre-wrap") : "pre";
                this.element.style.wordWrap = wrap ? "break-word" : "";
                this.rendered_wrap = wrap;
                this.rendered_wraplimit = wraplimit;
                this.cached_height = -1;
                this.cached_width = -1;
            }
        };
        WallBox.prototype.setRenderedZIndex = function (zi) {
            if (zi != this.rendered_zindex) {
                this.element.style.zIndex = zi ? zi.toString() : "";
                this.rendered_zindex = zi;
            }
        };
        WallBox.FLOW_HORIZONTAL = 0;
        WallBox.FLOW_VERTICAL = 1;
        WallBox.FLOW_OVERLAY = 2;
        WallBox.STRETCH_AUTO = -1;
        WallBox.ARRANGE_LEFT = 1;
        WallBox.ARRANGE_RIGHT = 2;
        WallBox.ARRANGE_CENTER = 3;
        WallBox.ARRANGE_JUSTIFY = 4;
        WallBox.ARRANGE_BASELINE = 5;
        WallBox.ARRANGE_TOP = 6;
        WallBox.ARRANGE_BOTTOM = 7;
        WallBox.ARRANGE_SPREAD = 8;
        WallBox.MIN = 0;
        WallBox.MAX = 1;
        WallBox.T = 0;
        WallBox.R = 1;
        WallBox.B = 2;
        WallBox.L = 3;
        WallBox.H = 0;
        WallBox.V = 1;
        WallBox.CONTENT_NONE = -1;
        WallBox.CONTENT_TEXT = 0;
        WallBox.CONTENT_IMAGE = 1;
        WallBox.CONTENT_INPUT = 2;
        return WallBox;
    })(BoxBase);
    TDev.WallBox = WallBox;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var ModalDialog = (function () {
        function ModalDialog(header) {
            if (header === void 0) { header = ""; }
            this.overlay = TDev.div("modalOverlay");
            this.dialog = TDev.div("modalDialog");
            this.savedKeyState = null;
            this.id = TDev.Random.uniqueId();
            this.opacity = 0.85;
            this.onDismiss = null;
            this.visible = false;
            this.canDismiss = true;
            this.dialog.setAttribute("role", "dialog");
            this.floating = TDev.div("modalDialogInner", this.dialog);
            this.outerDialog = TDev.div("modalDialogOuter", TDev.div("modalDialogMid", this.floating));
            if (header)
                this.add(TDev.div("wall-dialog-header", header));
            this.fullWhite();
        }
        ModalDialog.prototype.setAlert = function () {
            this.dialog.setAttribute("role", "alertdialog");
            this.applyAria();
        };
        ModalDialog.prototype.applyAria = function () {
            var _this = this;
            var foundtitle = false;
            var founddesc = false;
            TDev.Util.children(this.dialog).forEach(function (el) {
                if (!foundtitle && el.classList.contains('wall-dialog-header')) {
                    foundtitle = true;
                    if (!el.id)
                        el.id = TDev.Util.guidGen();
                    _this.dialog.setAttribute("aria-labelledby", el.id);
                }
                if (!founddesc && el.classList.contains('wall-dialog-body')) {
                    founddesc = true;
                    if (!el.id)
                        el.id = TDev.Util.guidGen();
                    _this.dialog.setAttribute("aria-describedby", el.id);
                }
            });
        };
        ModalDialog.dismissCurrent = function () {
            if (ModalDialog.currentIsVisible()) {
                ModalDialog.current.canDismiss = true;
                ModalDialog.current.dismiss();
            }
        };
        ModalDialog.currentIsVisible = function () {
            return ModalDialog.current && ModalDialog.current.visible;
        };
        ModalDialog.prototype.show = function () {
            this.showBare();
        };
        ModalDialog.prototype.addLog = function () {
            if (!this.logView) {
                this.logView = new TDev.RT.AppLogView();
                this.logView.charts(false);
                this.logView.search(false);
                this.logView.reversed(true);
                this.logView.attachLogEvents();
                this.logView.element.style.fontSize = "0.7em";
                this.add(this.logView.element);
                this.setScroll();
                this.stretchWide();
            }
        };
        ModalDialog.prototype.addFirst = function (v) {
            if (this.dialog.firstChild)
                this.dialog.insertBefore(v, this.dialog.firstChild);
            else
                this.add(v);
        };
        ModalDialog.prototype.empty = function () {
            this.dialog.setChildren([]);
        };
        ModalDialog.prototype.addBody = function (v) {
            this.add(TDev.div("wall-dialog-body", v));
        };
        ModalDialog.prototype.add = function (v) {
            if (v && Array.isArray(v))
                this.dialog.appendChildren(v);
            else
                this.dialog.appendChildren([v]);
            this.applyAria();
        };
        ModalDialog.prototype.addClass = function (c) {
            this.dialog.className += " " + c;
        };
        ModalDialog.prototype.addHTML = function (html) {
            var b = TDev.div("wall-dialog-body");
            TDev.Browser.setInnerHTML(b, html);
            this.add(b);
            return b;
        };
        ModalDialog.prototype.addOuter = function (v) {
            this.outerDialog.appendChildren([v]);
        };
        ModalDialog.prototype.stretchDown = function (e, keep) {
            if (keep === void 0) { keep = 0; }
            this.outerDialog.className += " modalDialogOuterLong";
            this.listheight = TDev.SizeMgr.windowHeight - e.offsetTop - (3 + keep) * TDev.SizeMgr.topFontSize;
            e.style.height = this.listheight + "px";
        };
        ModalDialog.prototype.adjustlistsize = function () {
            if (!this.list || !this.buttondiv)
                return;
            var howmuchover = this.dialog.scrollHeight - this.dialog.clientHeight;
            if (howmuchover > 0) {
                this.listheight = Math.max(10 * TDev.SizeMgr.topFontSize, this.listheight - howmuchover);
                this.list.style.height = this.listheight + "px";
            }
        };
        ModalDialog.prototype.stretchWide = function () {
            this.floating.style.width = 'calc(100% - 1em)';
            this.dialog.style.width = '100%';
        };
        ModalDialog.prototype.showBare = function (what) {
            var _this = this;
            if (what === void 0) { what = null; }
            TDev.Ticker.dbg("ModalDialog.showBare0");
            if (ModalDialog.current && ModalDialog.current != this && !ModalDialog.current.canDismiss)
                return;
            this.overlay.style.opacity = this.opacity.toString();
            this.overlay.withClick(function () {
                _this.dismiss();
            });
            this.outerDialog.withClick(function () {
                _this.dismiss();
            });
            this.floating.withClick(function () {
            });
            var root = TDev.elt("root");
            TDev.Util.children(root).forEach(function (ch) { return ch.setAttribute("aria-hidden", "true"); });
            root.appendChildren([this.overlay, what || this.outerDialog]);
            var btnsDiv;
            TDev.Util.children(this.dialog).forEach(function (e) {
                if (e.className == "wall-dialog-buttons")
                    btnsDiv = e;
                if (e.withClick && !e.clickHandler && !e.onselectstart)
                    e.tabIndex = -1;
            });
            if (!what) {
                TDev.Util.showPopup(this.floating);
            }
            else {
                this.outerDialog = what;
                TDev.Util.showPopup(what);
            }
            if (ModalDialog.current && ModalDialog.current != this) {
                ModalDialog.dismissCurrent();
            }
            if (this.canDismiss)
                TDev.Screen.pushModalHash("dialog-" + this.id, function () { return _this.dismiss(); });
            this.savedKeyState = TDev.KeyboardMgr.instance.saveState();
            TDev.KeyboardMgr.instance.register("Esc", function () {
                _this.dismiss();
                return true;
            });
            this.visible = true;
            ModalDialog.current = this;
            if (btnsDiv) {
                var btns = TDev.Util.children(btnsDiv).filter(function (e) { return e.clickHandler; });
                if (btns.length == 1)
                    TDev.KeyboardMgr.instance.btnShortcut(btns[0], "Enter");
            }
            TDev.elt("root").setFlag("modal-visible", true);
            this.dialog.removeAttribute("aria-labelledby");
            var h1 = this.dialog.getElementsByTagName("h1")[0];
            if (h1) {
                h1.id = TDev.Util.guidGen();
                this.dialog.setAttribute("aria-labelledby", h1.id);
            }
            var trap = TDev.div('focustrap');
            trap.tabIndex = 0;
            trap.setAttribute("aria-hidden", "true");
            trap.onfocus = function () { return _this.focusFirstAsync().done(); };
            this.dialog.appendChild(trap);
            this.focusFirstAsync().done();
            TDev.Ticker.dbg("ModalDialog.showBare1");
        };
        ModalDialog.prototype.focusFirstAsync = function () {
            var _this = this;
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                setTimeout(function () {
                    try {
                        var focus = _this.dialog.getElementsByTagName("input")[0] || _this.dialog.getElementsByTagName("button")[0];
                        if (focus)
                            focus.focus();
                    }
                    catch (e) {
                    }
                    onSuccess(undefined);
                }, 10);
            });
        };
        ModalDialog.prototype.dismiss = function () {
            var _this = this;
            if (!this.canDismiss) {
                TDev.Ticker.dbg("ModalDialog.dismiss - cannot");
                return;
            }
            TDev.Ticker.dbg("ModalDialog.dismiss0");
            TDev.Screen.popModalHash("dialog-" + this.id);
            if (this.logView)
                this.logView.removeLogEvents();
            this.visible = false;
            TDev.elt("root").setFlag("modal-visible", false);
            TDev.KeyboardMgr.instance.loadState(this.savedKeyState);
            TDev.Util.hidePopup(this.outerDialog, function () {
                TDev.Ticker.dbg("ModalDialog.dismiss1");
                _this.outerDialog.removeSelf();
                TDev.Util.children(TDev.elt("root")).forEach(function (ch) { return ch.removeAttribute("aria-hidden"); });
            });
            TDev.Util.fadeOut(this.overlay);
            var f = this.onDismiss;
            this.onDismiss = null;
            if (f)
                f(this);
        };
        ModalDialog.ask = function (msg, confirmation, act, critical, header) {
            if (critical === void 0) { critical = false; }
            if (header === void 0) { header = null; }
            var m = new ModalDialog();
            if (header == null)
                header = confirmation + "?";
            m.add([
                TDev.div("wall-dialog-header", header),
                TDev.div("wall-dialog-body", msg),
                TDev.div("wall-dialog-buttons", TDev.HTML.mkButton(TDev.lf("cancel"), function () { return m.dismiss(); }), TDev.HTML.mkButton(confirmation, function () {
                    act();
                    m.dismiss();
                }))
            ]);
            m.setAlert();
            if (critical)
                m.critical();
            m.show();
            return m;
        };
        ModalDialog.askAsync = function (msg, confirmation, critical, header) {
            if (critical === void 0) { critical = false; }
            if (header === void 0) { header = null; }
            var ret = new TDev.PromiseInv();
            var m = ModalDialog.ask(msg, confirmation, function () {
                ret.success(null);
            }, critical, header);
            return ret;
        };
        ModalDialog.askMany = function (header, msg, options) {
            var m = new ModalDialog();
            m.add([
                TDev.div("wall-dialog-header", header),
                TDev.div("wall-dialog-body", msg),
                TDev.div("wall-dialog-buttons", Object.keys(options).map(function (k) { return TDev.HTML.mkButton(k, function () {
                    m.dismiss();
                    options[k]();
                }); }))
            ]);
            m.setAlert();
            m.show();
            return m;
        };
        ModalDialog.askManyWithAdditionalElts = function (header, helpLink, msg, subHeader, subMsg, options) {
            var elts = [];
            for (var _i = 6; _i < arguments.length; _i++) {
                elts[_i - 6] = arguments[_i];
            }
            var m = new ModalDialog();
            m.add([
                TDev.div("wall-dialog-header", header, helpLink),
                TDev.div("wall-dialog-body", msg),
                TDev.div("wall-dialog-header", subHeader),
                TDev.div("wall-dialog-body", subMsg),
                TDev.div("wall-dialog-buttons", Object.keys(options).map(function (k) { return TDev.HTML.mkButton(k, function () {
                    m.dismiss();
                    options[k]();
                }); })),
                elts
            ]);
            m.show();
            return m;
        };
        ModalDialog.buttons = function (header, msg, subheader, submsg) {
            var buttons = [];
            for (var _i = 4; _i < arguments.length; _i++) {
                buttons[_i - 4] = arguments[_i];
            }
            var m = new ModalDialog();
            m.add([
                TDev.div("wall-dialog-header", header),
                TDev.div("wall-dialog-body", msg),
                subheader && TDev.div("wall-dialog-header", subheader),
                submsg && TDev.div("wall-dialog-body", submsg),
                TDev.div("wall-dialog-buttons", buttons)
            ]);
            m.setAlert();
            m.show();
            return m;
        };
        ModalDialog.info = function (title, msg, btn) {
            if (btn === void 0) { btn = "ok"; }
            var m = new ModalDialog();
            m.add([
                TDev.div("wall-dialog-header", title),
                TDev.div("wall-dialog-body", msg)
            ]);
            if (btn)
                m.addOk(btn);
            m.setAlert();
            m.show();
            return m;
        };
        ModalDialog.infoAsync = function (title, msg, btn) {
            if (btn === void 0) { btn = "ok"; }
            var r = new TDev.PromiseInv();
            var m = ModalDialog.info(title, msg, btn);
            m.onDismiss = function () { return r.success(null); };
            return r;
        };
        ModalDialog.prototype.addButtons = function (btns) {
            this.add(TDev.div("wall-dialog-buttons", Object.keys(btns).map(function (b) { return TDev.HTML.mkButton(b, btns[b]); })));
        };
        ModalDialog.prototype.addOk = function (btn, f, cls, btns) {
            var _this = this;
            if (btn === void 0) { btn = TDev.lf("ok"); }
            if (f === void 0) { f = null; }
            if (cls === void 0) { cls = ""; }
            if (btns === void 0) { btns = []; }
            var b = TDev.HTML.mkButton(btn, function () {
                if (f)
                    f();
                else
                    _this.dismiss();
            });
            if (cls)
                b.className += " " + cls;
            this.add(TDev.div("wall-dialog-buttons", [b, btns]));
            return b;
        };
        ModalDialog.showAsync = function (msg, options) {
            if (options === void 0) { options = {}; }
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var m = new ModalDialog();
                var ok = false;
                if (options.title)
                    m.add(TDev.div('wall-dialog-header', options.title));
                if (msg)
                    m.add(TDev.div('wall-dialog-body', msg));
                m.addOk(TDev.lf("ok"), function () {
                    ok = true;
                    m.dismiss();
                }, "", options.cancel ? TDev.HTML.mkButton(TDev.lf("cancel"), function () { return m.dismiss(); }) : undefined);
                m.onDismiss = function () { return onSuccess(ok); };
                m.setAlert();
                m.show();
            });
        };
        ModalDialog.showText = function (s, title, msg, done) {
            if (title === void 0) { title = null; }
            if (msg === void 0) { msg = null; }
            if (done === void 0) { done = null; }
            var m = new ModalDialog();
            if (title != null)
                m.add(TDev.div('wall-dialog-header', title));
            if (msg != null)
                m.add(TDev.div('wall-dialog-body', msg));
            var elt = TDev.HTML.mkTextArea("scriptText");
            elt.value = s;
            m.dialog.appendChild(elt);
            m.textArea = elt;
            m.onDismiss = done;
            m.setAlert();
            m.show();
            m.stretchDown(elt);
            m.stretchWide();
            try {
                elt.setSelectionRange(0, s.length);
            }
            catch (e) {
            }
            return m;
        };
        ModalDialog.showTable = function (headers, values, ondblclick) {
            var m = new ModalDialog();
            var table = document.createElement("table");
            table.className = "traces";
            var hdrRow = document.createElement("tr");
            for (var i = 0; i < headers.length; i++) {
                var hdr = document.createElement("th");
                hdr.textContent = headers[i];
                hdrRow.appendChild(hdr);
            }
            table.appendChild(hdrRow);
            for (var i = 0; i < values.length; i++) {
                var row = document.createElement("tr");
                row.classList.add("hover");
                var rowValues = values[i];
                for (var j = 0; j < rowValues.length; j++) {
                    var v = document.createElement("td");
                    v.textContent = rowValues[j];
                    v.ondblclick = function (ev) {
                        var target = ev.target || ev.srcElement;
                        return ondblclick(m, target.parentElement.sectionRowIndex - 1);
                    };
                    row.appendChild(v);
                }
                table.appendChild(row);
            }
            m.dialog.appendChild(table);
            m.stretchDown(table);
            m.setAlert();
            m.show();
            return m;
        };
        ModalDialog.editText = function (lbl, text, updateAsync) {
            var m = new ModalDialog();
            var btns = TDev.div("wall-dialog-buttons", TDev.HTML.mkButton(TDev.lf("update"), function () {
                btns.removeSelf();
                updateAsync(inp.value).done(function () { return m.dismiss(); });
            }), TDev.HTML.mkButton(TDev.lf("cancel"), function () { return m.dismiss(); }));
            var inp = TDev.HTML.mkTextInput("text", "");
            inp.value = text;
            m.add(TDev.div("wall-dialog-header", lbl));
            m.add(TDev.div(null, inp));
            m.add(btns);
            m.setAlert();
            m.show();
            return m;
        };
        ModalDialog.prototype.noChrome = function () {
            this.outerDialog.className += " modalNoChrome";
        };
        ModalDialog.prototype.fullScreen = function (iMeanIt) {
            if (iMeanIt === void 0) { iMeanIt = false; }
            this.outerDialog.className += " modalNoChrome " + (iMeanIt ? "reallyFullScreen" : "modalFullScreen");
            this.outerDialog.setChildren(this.dialog);
        };
        ModalDialog.prototype.fullBlack = function () {
            this.outerDialog.classList.add("modalFullBlack");
            this.outerDialog.classList.remove("modalFullWhite");
            this.outerDialog.classList.remove("modalFullYellow");
        };
        ModalDialog.prototype.fullWhite = function () {
            this.outerDialog.classList.remove("modalFullBlack");
            this.outerDialog.classList.add("modalFullWhite");
            this.outerDialog.classList.remove("modalFullYellow");
        };
        ModalDialog.prototype.fullYellow = function () {
            this.outerDialog.classList.remove("modalFullBlack");
            this.outerDialog.classList.remove("modalFullWhite");
            this.outerDialog.classList.add("modalFullYellow");
        };
        ModalDialog.prototype.critical = function () {
            this.outerDialog.classList.remove("modalFullBlack");
            this.outerDialog.classList.remove("modalFullWhite");
            this.outerDialog.classList.remove("modalFullYellow");
            this.floating.classList.add('bg-critical');
            this.setAlert();
        };
        ModalDialog.prototype.setScroll = function () {
            this.dialog.style.maxHeight = (TDev.SizeMgr.windowHeight * 0.85) / TDev.SizeMgr.topFontSize + "em";
            TDev.Util.setupDragToScroll(this.dialog);
        };
        ModalDialog.prototype.showorhidelist = function (show) {
            var d = show ? "" : "none";
            if (this.searchbox)
                this.searchbox.style.display = d;
            if (this.list)
                this.list.style.display = d;
        };
        ModalDialog.prototype.choose = function (boxes, options) {
            var _this = this;
            if (options === void 0) { options = {}; }
            var progressBar = TDev.HTML.mkProgressBar();
            var list = this.list = TDev.HTML.mkModalList([]);
            var search = TDev.HTML.mkTextInput("text", TDev.lf("choose..."));
            search.id = "chooseSearch";
            search.setAttribute("role", "search");
            search.placeholder = options.searchHint || (options.queryAsync ? TDev.lf("Type to search online...") : TDev.lf("Type to search..."));
            var autoKeyboard = TDev.KeyboardAutoUpdate.mkInput(search, TDev.Util.catchErrors("chooseSearch", function () { return refresh(true); }));
            autoKeyboard.attach();
            var limitedMode = !!options.mkSeeMore;
            if (limitedMode && boxes.every(function (b) { return !b.initiallyHidden; }))
                limitedMode = false;
            var needKbd = false;
            function selectedItem() {
                return TDev.Util.children(list).filter(function (el) { return el == document.activeElement; })[0];
            }
            function refresh(onlineOK, focus) {
                var allTerms = search.value;
                var terms = allTerms.split(/\s+/).map(function (s) { return s.toLowerCase(); }).filter(function (s) { return s != ""; });
                var res = [];
                var ids = {};
                if (terms.length > 0)
                    limitedMode = false;
                var skipCnt = 0;
                boxes.forEach(function (b) {
                    var miss = false;
                    if (limitedMode && b.initiallyHidden) {
                        skipCnt++;
                        return;
                    }
                    var cont = b.textContent.toLowerCase();
                    terms.forEach(function (term) {
                        if (!miss && cont.indexOf(term) < 0)
                            miss = true;
                    });
                    if (!miss) {
                        ids[cont] = 1;
                        res.push(b);
                        TDev.Util.highlightWords(b, terms, true);
                    }
                });
                if (limitedMode) {
                    var b = options.mkSeeMore(needKbd ? TDev.lf("you can also search") : TDev.lf("more option{0:s}", skipCnt));
                    TDev.HTML.setTickCallback(b, 274 /* sideMoreOptions */, function () {
                        limitedMode = false;
                        refresh(options.initialEmptyQuery);
                    });
                    res.push(b);
                }
                list.setChildren(res);
                if (onlineOK && !!options.queryAsync && TDev.Cloud.isOnline()) {
                    progressBar.start();
                    options.queryAsync(allTerms).then(function (bxs) {
                        progressBar.stop();
                        if (!autoKeyboard.resultsCurrent(allTerms)) {
                            return;
                        }
                        if (!!bxs) {
                            bxs.forEach(function (bx) {
                                var bkey = bx.textContent.toLowerCase();
                                if (!ids[bkey]) {
                                    ids[bkey] = 1;
                                    list.appendChild(bx);
                                    TDev.Util.highlightWords(bx, terms, true);
                                }
                            });
                        }
                    }).done();
                }
                if (focus && !!list.firstElementChild) {
                    var fe = list.firstElementChild;
                    TDev.Util.setTimeout(10, function () { return fe.focus(); });
                }
                if (options.afterRefresh)
                    options.afterRefresh();
            }
            if (!options.noBackground)
                this.outerDialog.className += " modalChooser";
            if (options.header) {
                this.add(TDev.div("modalSearchHeader", options.header));
            }
            if (options.includeSearch !== undefined)
                needKbd = !!options.includeSearch;
            else
                needKbd = (!!options.queryAsync || boxes.length > 5);
            if (needKbd)
                this.add(this.searchbox = TDev.div("modalSearch", [progressBar, search]));
            this.add(list);
            this.buttondiv = TDev.div('wall-dialog-buttons modalChooseBtns');
            if (options.custombuttons !== undefined)
                this.buttondiv.appendChildren(options.custombuttons);
            else
                this.buttondiv.appendChild(TDev.HTML.mkButtonTick(TDev.lf("cancel"), 185 /* chooseCancel */, function () { return _this.dismiss(); }));
            this.add(this.buttondiv);
            this.show();
            function keyDown() {
                var selected = selectedItem();
                if (!selected && list.firstElementChild) {
                    list.firstElementChild.focus();
                }
                else if (selected && selected.nextElementSibling) {
                    selected.nextElementSibling.focus();
                    selected.nextElementSibling.scrollIntoView(false);
                }
                return true;
            }
            function keyUp() {
                var selected = selectedItem();
                if (!selected && list.lastElementChild) {
                    list.lastElementChild.focus();
                }
                else if (selected && selected.previousElementSibling) {
                    selected.previousElementSibling.focus();
                    selected.previousElementSibling.scrollIntoView(false);
                }
                return true;
            }
            TDev.KeyboardMgr.instance.register("Down", keyDown);
            TDev.KeyboardMgr.instance.register("Up", keyUp);
            TDev.KeyboardMgr.instance.register("Enter", function (e) {
                var selected = selectedItem();
                if (selected && selected.clickHandler) {
                    selected.clickHandler.fireClick(e);
                }
                else if (list.firstElementChild) {
                    list.firstElementChild.focus();
                }
                return true;
            });
            TDev.KeyboardMgr.instance.register("***", function (e) {
                if (e.fromTextBox)
                    return false;
                var s = TDev.Util.keyEventString(e);
                if (s) {
                    search.value += s;
                    TDev.Util.setKeyboardFocus(search);
                    return true;
                }
                return false;
            });
            if (!options.dontStretchDown)
                this.stretchDown(list, 2.8);
            if (options.adjustListSize)
                this.adjustlistsize();
            var needFocus = true;
            if (options.initialQuery !== undefined) {
                options.initialEmptyQuery = true;
                search.value = options.initialQuery;
                if (needKbd) {
                    TDev.Util.setKeyboardFocus(search, true);
                    needFocus = false;
                }
            }
            refresh(options.initialEmptyQuery, needFocus);
        };
        return ModalDialog;
    })();
    TDev.ModalDialog = ModalDialog;
    var ProgressOverlay;
    (function (ProgressOverlay) {
        var overlay;
        var msgDiv;
        var addInfo;
        var progress;
        var visible = 0;
        var unblockedKeyboard = false;
        var logView;
        ProgressOverlay.lock = TDev.PromiseInv.as();
        function lockAndShow(msg, f, splashUrl) {
            if (msg === void 0) { msg = TDev.lf("working hard"); }
            ProgressOverlay.lock.done(function () { return show(msg, f, splashUrl); });
        }
        ProgressOverlay.lockAndShow = lockAndShow;
        function lockAndShowAsync(msg) {
            var r = new TDev.PromiseInv();
            lockAndShow(msg, function () { return r.success(null); });
            return r;
        }
        ProgressOverlay.lockAndShowAsync = lockAndShowAsync;
        function bumpShow() {
            TDev.Util.assert(isActive());
            visible++;
        }
        ProgressOverlay.bumpShow = bumpShow;
        function show(msg, f, splashUrl) {
            if (msg === void 0) { msg = TDev.lf("working hard"); }
            visible++;
            TDev.Ticker.dbg("ProgressOverlay.show " + visible + " " + msg);
            if (visible > 1) {
                setMessage(msg);
                return;
            }
            if (!overlay) {
                overlay = TDev.div("modalOverlay", TDev.div("modalMessage", msgDiv = TDev.div("modalMessageHeader"), addInfo = TDev.div("modalMessagePleaseWait"), progress = TDev.div("modalMessagePleaseWait")));
                overlay.withClick(function () {
                });
                overlay.style.backgroundColor = "white";
                overlay.style.opacity = "0.95";
                overlay.style.backgroundSize = "cover";
                overlay.style.backgroundRepeat = "no-repeat";
            }
            ProgressOverlay.lock = new TDev.PromiseInv();
            setMessage(msg);
            setSplashArtId(splashUrl);
            addInfo.setChildren([TDev.lf("please wait...")]);
            closeLog();
            overlay.removeSelf();
            TDev.elt("root").appendChildren([overlay]);
            if (f)
                TDev.Util.setTimeout(TDev.Browser.isWebkit ? 100 : 1, f);
        }
        ProgressOverlay.show = show;
        function setAddInfo(info) {
            addInfo.setChildren(info);
        }
        ProgressOverlay.setAddInfo = setAddInfo;
        function hide() {
            if (visible == 0) {
                return;
            }
            visible--;
            TDev.Ticker.dbg("ProgressOverlay.hide " + visible);
            if (visible == 0) {
                ProgressOverlay.lock.success(null);
                progress.setChildren([]);
                overlay.removeSelf();
                unblockedKeyboard = false;
                closeLog();
            }
        }
        ProgressOverlay.hide = hide;
        function closeLog() {
            if (logView) {
                logView.element.removeSelf();
                logView.removeLogEvents();
                logView = undefined;
            }
        }
        function setProgress(msg) {
            if (progress)
                progress.setChildren(msg);
        }
        ProgressOverlay.setProgress = setProgress;
        function setMessage(msg) {
            if (msgDiv)
                msgDiv.setChildren(msg);
        }
        ProgressOverlay.setMessage = setMessage;
        function setSplashArtId(url) {
            if (overlay)
                overlay.style.backgroundImage = TDev.HTML.cssImage(url, 0.3);
        }
        ProgressOverlay.setSplashArtId = setSplashArtId;
        function unblockKeyboard() {
            unblockedKeyboard = true;
        }
        ProgressOverlay.unblockKeyboard = unblockKeyboard;
        function isKeyboardBlocked() {
            return isActive() && !unblockedKeyboard;
        }
        ProgressOverlay.isKeyboardBlocked = isKeyboardBlocked;
        function showLog() {
            if (!logView) {
                logView = new TDev.RT.AppLogView();
                logView.charts(false);
                logView.search(false);
                logView.reversed(true);
                logView.attachLogEvents();
                logView.element.style.fontSize = "0.7em";
                progress.parentElement.appendChild(logView.element);
            }
        }
        ProgressOverlay.showLog = showLog;
        function isActive() {
            return visible > 0;
        }
        ProgressOverlay.isActive = isActive;
    })(ProgressOverlay = TDev.ProgressOverlay || (TDev.ProgressOverlay = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Storage;
    (function (Storage) {
        function fatalError(e, op) {
            if (op === void 0) { op = undefined; }
            TDev.Util.navigateInWindow(window.errorUrl + "#storageinit," + encodeURIComponent(op));
        }
        function versionError(e) {
            TDev.Util.navigateInWindow(window.errorUrl + "#storageversion");
        }
        function tagError(e, origin, willRetry) {
            if (willRetry === void 0) { willRetry = false; }
            e.isDatabaseError = true;
            e.databaseOrigin = origin;
            TDev.Util.log("database error" + (willRetry ? " (will retry)" : " (no retry)") + ": " + TDev.Util.getErrorInfo(e));
            return e;
        }
        Storage.temporary = false;
        var temporaryRequestedSignin = false;
        function showTemporaryWarning() {
            if (Storage.temporary) {
                if (TDev.Cloud.isAccessTokenExpired())
                    TDev.HTML.showWarningNotification(TDev.lf("Web site data not available, sign in to back up your scripts!"), { details: TDev.lf("Your browser does not allow Touch Develop to store data. This usually happens if run in Private Mode (Safari), in InPrivate mode (Internet Explorer) or your security settings prevent data storage. Sign in or change your browser settings to avoid loosing your work. All the changes not saved to the cloud will be lost when leaving this page.") });
                else if (TDev.Cloud.isOffline())
                    TDev.HTML.showWarningNotification(TDev.lf("Web site data not available, connect to internet to back up your scripts!"), { details: TDev.lf("Your browser does not allow Touch Develop to store data. This usually happens if run in Private Mode (Safari), in InPrivate mode (Internet Explorer) or your security settings prevent data storage. Sign in or change your browser settings to avoid loosing your work. All the changes not saved to the cloud will be lost when leaving this page.") });
                return true;
            }
            else {
                return false;
            }
        }
        Storage.showTemporaryWarning = showTemporaryWarning;
        var memoryStorage = {};
        var MemoryTable = (function () {
            function MemoryTable(tableName) {
                this.tableName = tableName;
                Storage.temporary = true;
            }
            MemoryTable.prototype.getValueAsync = function (key) {
                var v = memoryStorage[this.tableName + "-" + key];
                if (typeof v !== "string")
                    v = undefined;
                return TDev.Promise.as(v);
            };
            MemoryTable.prototype.getItemsAsync = function (keys) {
                var _this = this;
                var items = {};
                keys.forEach(function (k) {
                    var v = memoryStorage[_this.tableName + "-" + k];
                    if (typeof v !== "string")
                        v = undefined;
                    items[k] = v;
                });
                return TDev.Promise.as(items);
            };
            MemoryTable.prototype.getKeysAsync = function () {
                var prefix = this.tableName + "-";
                var results = [];
                Object.keys(memoryStorage).forEach(function (k) {
                    if (k.length > prefix.length && k.slice(0, prefix.length) === prefix)
                        results.push(k.slice(prefix.length));
                });
                return TDev.Promise.as(results);
            };
            MemoryTable.prototype.setItemsAsync = function (items) {
                var _this = this;
                Object.keys(items).forEach(function (k) {
                    var v = items[k];
                    if (typeof v === "string")
                        memoryStorage[_this.tableName + "-" + k] = v;
                    else
                        delete memoryStorage[_this.tableName + "-" + k];
                });
                return TDev.Promise.as();
            };
            return MemoryTable;
        })();
        function createMemoryTable(tableName) {
            return new MemoryTable(tableName);
        }
        Storage.createMemoryTable = createMemoryTable;
        Storage.tableNames = ["Editor", "Index", "Scripts", "ScriptCache", "Traces", "ApiCache", "ArtCache", "Sessions"];
        var indexedDBDeleting = false;
        var indexedDBPromise;
        var indexedDB;
        var IndexedDBTable = (function () {
            function IndexedDBTable(tableName) {
                this.tableName = tableName;
            }
            IndexedDBTable.prototype.getValueAsync = function (key) {
                return this.getItemsAsync([key]).then(function (items) { return items[key]; });
            };
            IndexedDBTable.prototype.getItemsAsync = function (keys) {
                var _this = this;
                if (keys.length == 0)
                    return TDev.Promise.as({});
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        var trans = indexedDB.transaction([_this.tableName], 'readonly');
                        var store = trans.objectStore(_this.tableName);
                        var requests = keys.map(function (k) { return store.get(k); });
                        var items = {};
                        var missing = keys.length;
                        requests.forEach(function (r, i) {
                            r.onsuccess = function (e) {
                                var result = e.target.result;
                                items[keys[i]] = result === undefined ? undefined : result.value;
                                if (--missing == 0)
                                    onSuccess(items);
                            };
                            r.onerror = function (e) {
                                if (missing >= 0) {
                                    missing = -1;
                                    onError(tagError(e, "IndexedDBTable.getItemsAsync/0", false));
                                }
                                ;
                            };
                        });
                    }
                    catch (e) {
                        onError(tagError(e, "IndexedDBTable.getItemsAsync/1", false));
                    }
                });
            };
            IndexedDBTable.prototype.getKeysAsync = function () {
                var _this = this;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        var trans = indexedDB.transaction([_this.tableName], 'readonly');
                        var store = trans.objectStore(_this.tableName);
                        var request = store.openCursor();
                        var results = [];
                        request.onsuccess = function (e) {
                            var cursor = (e.target.result);
                            if (!!cursor) {
                                results.push(cursor.key);
                                cursor["continue"]();
                            }
                            else
                                onSuccess(results);
                        };
                        request.onerror = onError;
                    }
                    catch (e) {
                        onError(tagError(e, "IndexedDBTable.getKeysAsync", false));
                    }
                });
            };
            IndexedDBTable.prototype.setItemsAsync = function (items) {
                var _this = this;
                var list = [];
                Object.keys(items).forEach(function (k) {
                    list.push({ key: k, value: items[k] });
                });
                if (list.length == 0)
                    return TDev.Promise.as();
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        var requests = list.map(function (kvp) {
                            var trans = indexedDB.transaction([_this.tableName], 'readwrite');
                            var store = trans.objectStore(_this.tableName);
                            if (typeof kvp.value === "string")
                                return store.put(kvp);
                            else
                                return store["delete"](kvp.key);
                        });
                        var missing = requests.length;
                        requests.forEach(function (r, i) {
                            r.onsuccess = function (e) {
                                if (--missing == 0)
                                    onSuccess(undefined);
                            };
                            r.onerror = function (e) {
                                if (missing >= 0) {
                                    missing = -1;
                                    onError(tagError(e, "IndexedDBTable.setItemsAsync/0", false));
                                }
                                ;
                            };
                        });
                    }
                    catch (e) {
                        onError(tagError(e, "IndexedDBTable.setItemsAsync/1", false));
                    }
                });
            };
            return IndexedDBTable;
        })();
        function indexedDBupgrade(indexedDB) {
            try {
                var names = indexedDB.objectStoreNames;
                var exisiting = {};
                for (var i = 0; i < names.length; i++) {
                    if (Storage.tableNames.indexOf(names[i]) < 0)
                        indexedDB.deleteObjectStore(names[i]);
                    else
                        exisiting[names[i]] = true;
                }
                Storage.tableNames.forEach(function (tableName) {
                    if (!exisiting[tableName])
                        indexedDB.createObjectStore(tableName, { keyPath: "key" });
                });
            }
            catch (e) {
                TDev.Util.reportError("indexedDBupgrade", e, true);
            }
        }
        var webSqlDeleting = false;
        var webSqlPromise;
        var webSql;
        var WebSqlTable = (function () {
            function WebSqlTable(tableName) {
                this.tableName = tableName;
            }
            WebSqlTable.prototype.getValueAsync = function (key) {
                return this.getItemsAsync([key]).then(function (items) { return items[key]; });
            };
            WebSqlTable.prototype.internalGetItemsAsync = function (items, keys, start, retries) {
                var _this = this;
                if (retries === void 0) { retries = 3; }
                if (start >= keys.length)
                    return TDev.Promise.as(items);
                var end = start + 256;
                if (end > keys.length)
                    end = keys.length;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var propagated = false;
                    var errorHandler = function (e, origin) {
                        if (!propagated) {
                            propagated = true;
                            tagError(e, "WebSqlTable.internalGetItemsAsync/" + origin, retries > 0);
                            if (retries > 0)
                                delayCreateWebSqlAsync().then(function () { return _this.internalGetItemsAsync(items, keys, start, retries - 3); }).done(onSuccess, onError);
                            else
                                onError(e);
                        }
                    };
                    try {
                        webSql.transaction(function (tx) {
                            var query = "SELECT * FROM TABLE" + _this.tableName + " WHERE ";
                            var values = [];
                            for (var i = start; i < end; i++) {
                                if (i > start)
                                    query += " OR ";
                                query += "id=?";
                                values.push(keys[i]);
                            }
                            try {
                                tx.executeSql(query, values, function (tx, results) {
                                    var len = results.rows.length;
                                    for (var i = 0; i < len; i++) {
                                        var item = results.rows.item(i);
                                        items[item.id] = item.text;
                                    }
                                });
                            }
                            catch (e) {
                                errorHandler(e, 0);
                            }
                        }, function (e) { return errorHandler(e, 1); }, function () {
                            if (!propagated) {
                                propagated = true;
                                onSuccess(items);
                            }
                        });
                    }
                    catch (e) {
                        errorHandler(e, 2);
                    }
                }).then(function () { return _this.internalGetItemsAsync(items, keys, end); });
            };
            WebSqlTable.prototype.getItemsAsync = function (keys) {
                return this.internalGetItemsAsync({}, keys, 0);
            };
            WebSqlTable.prototype.getKeysAsync = function (retries) {
                var _this = this;
                if (retries === void 0) { retries = 3; }
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var keys = [];
                    var propagated = false;
                    var errorHandler = function (e, origin) {
                        if (!propagated) {
                            propagated = true;
                            tagError(e, "WebSqlTable.getKeysAsync/" + origin, retries > 0);
                            if (retries > 0)
                                delayCreateWebSqlAsync().then(function () { return _this.getKeysAsync(retries - 1); }).done(onSuccess, onError);
                            else
                                onError(e);
                        }
                    };
                    try {
                        webSql.transaction(function (tx) {
                            try {
                                tx.executeSql("SELECT id FROM TABLE" + _this.tableName, [], function (tx, results) {
                                    var len = results.rows.length;
                                    for (var i = 0; i < len; i++) {
                                        var item = results.rows.item(i);
                                        keys.push(item.id);
                                    }
                                });
                            }
                            catch (e) {
                                errorHandler(e, 0);
                            }
                        }, function (e) { return errorHandler(e, 1); }, function () {
                            if (!propagated) {
                                propagated = true;
                                onSuccess(keys);
                            }
                        });
                    }
                    catch (e) {
                        errorHandler(e, 2);
                    }
                });
            };
            WebSqlTable.prototype.setItemsAsync = function (items, retries) {
                var _this = this;
                if (retries === void 0) { retries = 3; }
                var list = [];
                Object.keys(items).forEach(function (k) {
                    list.push({ key: k, value: items[k] });
                });
                if (list.length == 0)
                    return TDev.Promise.as();
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var propagated = false;
                    var errorHandler = function (e, origin) {
                        if (!propagated) {
                            propagated = true;
                            tagError(e, "WebSqlTable.setItemsAsync/" + origin, retries > 0);
                            if (retries > 0)
                                delayCreateWebSqlAsync().then(function () { return _this.setItemsAsync(items, retries - 1); }).done(onSuccess, onError);
                            else
                                onError(e);
                        }
                    };
                    try {
                        webSql.transaction(function (tx) {
                            list.forEach(function (kvp) {
                                try {
                                    if (typeof kvp.value === "string")
                                        tx.executeSql("INSERT OR REPLACE INTO TABLE" + _this.tableName + " (id, text) VALUES (?, ?)", [kvp.key, kvp.value]);
                                    else
                                        tx.executeSql("DELETE FROM TABLE" + _this.tableName + " WHERE id=?", [kvp.key]);
                                }
                                catch (e) {
                                    errorHandler(e, 0);
                                }
                            });
                        }, function (e) { return errorHandler(e, 1); }, function () {
                            if (!propagated) {
                                propagated = true;
                                onSuccess(undefined);
                            }
                        });
                    }
                    catch (e) {
                        errorHandler(e, 2);
                    }
                });
            };
            return WebSqlTable;
        })();
        function webSqlInit(webSql, onSuccess, onError, retries) {
            if (retries === void 0) { retries = 3; }
            var propagated = false;
            var errorHandler = function (e, origin) {
                if (!propagated) {
                    propagated = true;
                    tagError(e, "WebSqlTable.webSqlInit/" + origin, retries > 0);
                    if (retries > 0)
                        delayCreateWebSqlAsync(retries - 1).done(onSuccess, onError);
                    else
                        onError(e);
                }
            };
            try {
                webSql.transaction(function (tx) {
                    Storage.tableNames.forEach(function (tableName) {
                        try {
                            tx.executeSql("CREATE TABLE IF NOT EXISTS TABLE" + tableName + " (id unique, text)");
                        }
                        catch (e) {
                            errorHandler(e, 0);
                        }
                    });
                }, function (e) { return errorHandler(e, 1); }, function () {
                    if (!propagated) {
                        propagated = true;
                        onSuccess(webSql);
                    }
                });
            }
            catch (e) {
                errorHandler(e, 2);
            }
        }
        function getWebSqlAsync(retries) {
            if (retries === void 0) { retries = 3; }
            if (webSql)
                return TDev.Promise.as(webSql);
            if (!webSqlPromise) {
                if (webSqlDeleting)
                    return TDev.Promise.delay(1000, function () { return getWebSqlAsync(retries); });
                webSqlPromise = internalGetWebSqlAsync(retries);
            }
            return webSqlPromise;
        }
        function internalGetWebSqlAsync(retries) {
            if (retries === void 0) { retries = 3; }
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                var propagated = false;
                var errorHandler = function (e, origin) {
                    if (!propagated) {
                        propagated = true;
                        tagError(e, "WebSqlTable.internalGetWebSqlAsync/" + origin, retries > 0);
                        if (retries > 0)
                            TDev.Promise.delay(2000, function () { return internalGetWebSqlAsync(retries - 1); }).done(onSuccess, onError);
                        else {
                            TDev.Util.log("error during openDatabase " + TDev.Util.getErrorInfo(e));
                            if (TDev.Browser.canMemoryTable)
                                onSuccess(undefined);
                            else
                                fatalError(e, "during openDatabase: " + TDev.Util.getErrorInfo(e));
                        }
                    }
                };
                try {
                    webSqlInit(window.openDatabase("TDev", "1.0", "TouchDevelop database", 5 * 1024 * 1024), function (webSqlInitialized) {
                        webSql = webSqlInitialized;
                        onSuccess(webSql);
                    }, function (e) { return errorHandler(e, 0); }, retries);
                }
                catch (e) {
                    errorHandler(e, 1);
                }
            });
        }
        function delayCreateWebSqlAsync(retries) {
            if (retries === void 0) { retries = 3; }
            webSql = undefined;
            webSqlPromise = undefined;
            return TDev.Promise.delay(2000, function () { return getWebSqlAsync(retries); });
        }
        function getIndexedDBFactory() {
            var w = window;
            return w.indexedDB || w.mozIndexedDB || w.msIndexedDB;
        }
        function getIndexedDBAsync() {
            if (Storage.temporary)
                return TDev.Promise.as(undefined);
            if (indexedDB)
                return TDev.Promise.as(indexedDB);
            if (!indexedDBPromise) {
                if (indexedDBDeleting)
                    return TDev.Promise.delay(1000, function () { return getIndexedDBAsync(); });
                indexedDBPromise = new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var version = 26;
                    try {
                        var request = getIndexedDBFactory().open("TDev", version);
                        request.onupgradeneeded = function (e) {
                            indexedDBupgrade(request.result);
                        };
                        request.onsuccess = function (e) {
                            indexedDB = request.result;
                            onSuccess(indexedDB);
                        };
                        request.onblocked = function (e) {
                            fatalError(e, "blocked during open " + TDev.Util.getErrorInfo(request.error));
                        };
                        request.onerror = function (e) {
                            if (request.error && request.error.name == "VersionError")
                                versionError(e);
                            else {
                                TDev.Util.log("error during openDatabase " + TDev.Util.getErrorInfo(request.error));
                                if (TDev.Browser.canMemoryTable)
                                    onSuccess(undefined);
                                else
                                    fatalError(e, "error during openDatabase " + TDev.Util.getErrorInfo(request.error));
                            }
                        };
                    }
                    catch (e) {
                        TDev.Util.log("error during openDatabase " + TDev.Util.getErrorInfo(request.error));
                        if (TDev.Browser.canMemoryTable)
                            onSuccess(undefined);
                        else
                            fatalError(e, "during openDatabase " + TDev.Util.getErrorInfo(e));
                    }
                });
            }
            return indexedDBPromise;
        }
        Storage.getTableAsync = function (tableName) {
            if (!Storage.temporary && TDev.Browser.webAppImplicit) {
                TDev.Util.log('implicit web app: disable database storage');
                Storage.temporary = true;
                TDev.Browser.canMemoryTable = true;
            }
            if (!Storage.temporary) {
                if (TDev.Browser.canWebSql)
                    return getWebSqlAsync().then(function (myWebSql) {
                        if (!myWebSql) {
                            TDev.Util.log('webSql openDatabase failed');
                            Storage.temporary = true;
                            return Storage.getTableAsync(tableName);
                        }
                        else {
                            TDev.Browser.supportMemoryTable(false);
                            return TDev.Promise.as(new WebSqlTable(tableName));
                        }
                    });
                if (TDev.Browser.canIndexedDB) {
                    return getIndexedDBAsync().then(function (database) {
                        if (!database) {
                            TDev.Util.log('indexedDB openDatabase failed');
                            Storage.temporary = true;
                            return Storage.getTableAsync(tableName);
                        }
                        else {
                            TDev.Browser.supportMemoryTable(false);
                            return TDev.Promise.as(new IndexedDBTable(tableName));
                        }
                    });
                }
            }
            if (TDev.Browser.canMemoryTable) {
                TDev.Util.log('storage: opening in-memory table ' + tableName);
                return TDev.Promise.as(new MemoryTable(tableName));
            }
            else
                throw tagError(new Error("no database available"), "getTableAsync", false);
        };
        function webSqlClearAsync(retries) {
            if (retries === void 0) { retries = 3; }
            return getWebSqlAsync().then(function (myWebSql) {
                webSql = undefined;
                webSqlPromise = undefined;
                webSqlDeleting = true;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var propagated = false;
                    var errorHandler = function (e, origin) {
                        webSql = undefined;
                        if (!propagated) {
                            propagated = true;
                            webSqlDeleting = false;
                            tagError(e, origin, retries > 0);
                            if (retries > 0)
                                delayCreateWebSqlAsync().then(function () { return webSqlClearAsync(retries - 1); }).done(onSuccess, onError);
                            else
                                fatalError(e, "during drop " + TDev.Util.getErrorInfo(e));
                        }
                    };
                    try {
                        myWebSql.transaction(function (tx) {
                            Storage.tableNames.forEach(function (tableName) {
                                try {
                                    tx.executeSql("DROP TABLE TABLE" + tableName);
                                }
                                catch (e) {
                                    errorHandler(e, "0");
                                }
                            });
                        }, function (e) { return errorHandler(e, 1); }, function () {
                            webSql = undefined;
                            if (!propagated) {
                                propagated = true;
                                webSqlDeleting = false;
                                onSuccess(undefined);
                            }
                        });
                    }
                    catch (e) {
                        errorHandler(e, 2);
                    }
                });
            });
        }
        function indexedDBClearAsync() {
            if (indexedDB) {
                try {
                    indexedDB.close();
                }
                catch (e) {
                }
                indexedDB = null;
            }
            indexedDBPromise = undefined;
            indexedDBDeleting = true;
            return new TDev.Promise(function (onSuccess, onError, onProgress) {
                try {
                    var request = getIndexedDBFactory().deleteDatabase("TDev");
                    request.onsuccess = function (e) {
                        if (!indexedDBDeleting)
                            return;
                        indexedDBDeleting = false;
                        onSuccess(undefined);
                    };
                    request.onblocked = request.onerror = function (e) {
                        if (!indexedDBDeleting)
                            return;
                        indexedDBDeleting = false;
                        onError(e);
                    };
                }
                catch (e) {
                    indexedDBDeleting = false;
                    onError(e);
                }
            });
        }
        Storage.clearPreAsync = function () { return TDev.Promise.as(); };
        function clearAsync() {
            var p = Storage.clearPreAsync();
            if (TDev.Browser.canWebSql)
                p = p.then(function () {
                    TDev.Util.log("clearing WebSql");
                    return getWebSqlAsync();
                }).then(function (wsql) {
                    if (!wsql)
                        return TDev.Promise.as(undefined);
                    return webSqlClearAsync().then(function () { return getWebSqlAsync(); }, function () {
                    });
                });
            if (TDev.Browser.canIndexedDB)
                p = p.then(function () {
                    TDev.Util.log("clearing IndexedDB");
                    return indexedDBClearAsync();
                }).then(function (_) { return _; }, function (_) {
                });
            p = p.then(function () {
                TDev.Util.log("clearing localStorage");
                var oauth_states = window.localStorage["oauth_states"];
                window.localStorage.clear();
                if (oauth_states)
                    window.localStorage["oauth_states"] = oauth_states;
                TDev.Browser.supportMemoryTable(true);
            });
            return p;
        }
        Storage.clearAsync = clearAsync;
        function logContentsAsync(details) {
            var formatBytes = function (n) { return n < 1024 ? (n + " B") : n < 1024 * 1024 ? (Math.floor(n / 1024) + " KB") : (Math.floor(n / 1024 / 1024) + " MB"); };
            return TDev.Promise.sequentialMap(Storage.tableNames, function (tableName) { return Storage.getTableAsync(tableName).then(function (table) { return table.getKeysAsync().then(function (keys) { return TDev.Promise.sequentialMap(keys, function (key) { return table.getValueAsync(key).then(function (value) {
                if (details) {
                    var escapedKey = (key + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
                    TDev.Util.log("DB table " + tableName + '["' + escapedKey + '"].length=' + formatBytes(value.length));
                }
                return keys.length + value.length;
            }); }).then(function (lengths) {
                var sum = lengths.reduce(function (a, b) { return a + b; }, 0);
                TDev.Util.log("DB table " + tableName + " size: " + formatBytes(sum));
                return sum;
            }); }); }); }).then(function (lengths) {
                var sum = lengths.reduce(function (a, b) { return a + b; }, 0);
                TDev.Util.log("DB total size: " + formatBytes(sum));
            });
        }
        Storage.logContentsAsync = logContentsAsync;
    })(Storage = TDev.Storage || (TDev.Storage = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Perf;
        (function (Perf) {
            Perf.timeReporting = false;
            function unit() {
                var ret = -1;
                if (TDev.Browser.isNodeJS)
                    return ret;
                try {
                    ret = parseFloat(localStorage["perfunit"] || -1);
                }
                catch (e) {
                    TDev.Util.log("perf: Failed to read from localStorage");
                }
                return ret;
            }
            Perf.unit = unit;
            function setUnit(value) {
                TDev.Util.log('perf: unit = ' + value.toFixed(0) + ' ms');
                try {
                    localStorage["perfunit"] = value;
                }
                catch (e) {
                    TDev.Util.log("perf: Failed to write to localStorage");
                }
            }
            Perf.setUnit = setUnit;
            function start(id, report) {
                if (report === void 0) { report = false; }
                return { id: id, time: TDev.Util.perfNow(), lastPause: -1, report: report };
            }
            Perf.start = start;
            function startPaused(id, report) {
                if (report === void 0) { report = false; }
                var now = TDev.Util.perfNow();
                return { id: id, time: now, lastPause: now, report: report };
            }
            Perf.startPaused = startPaused;
            var perfEvents = [];
            var compilerVersion;
            var releaseId;
            function init(compversion, release) {
                compilerVersion = compversion;
                releaseId = release;
                if (TDev.Cloud.hasAccessToken() && TDev.Cloud.isOnline())
                    sendPerfEvents();
            }
            Perf.init = init;
            function saveCurrentAsync(sendToCloud) {
                if (sendToCloud === void 0) { sendToCloud = false; }
                var prevEvents = [];
                var archived = window.localStorage["archivedPerfData"];
                if (archived != undefined && archived.length > 0)
                    prevEvents = JSON.parse(archived);
                prevEvents = prevEvents.concat(perfEvents);
                perfEvents = [];
                if (prevEvents.length > 500)
                    prevEvents = prevEvents.slice(prevEvents.length - 500);
                var newVal = JSON.stringify(prevEvents);
                if (newVal.length > 50000)
                    newVal = "[]";
                window.localStorage["archivedPerfData"] = newVal;
                if (sendToCloud && TDev.Cloud.hasAccessToken() && TDev.Cloud.isOnline())
                    return sendPerfEvents();
                else
                    return TDev.Promise.as(undefined);
            }
            Perf.saveCurrentAsync = saveCurrentAsync;
            function sendPerfEvents() {
                var rp = new TDev.PromiseInv();
                var events;
                var archived = window.localStorage["archivedPerfData"];
                if (archived == undefined || archived.length == 0)
                    return TDev.Promise.as(undefined);
                events = JSON.parse(archived);
                if (events == undefined || events.length == 0)
                    return TDev.Promise.as(undefined);
                events.forEach(function (e) {
                    e.userplatform = TDev.Browser.platformCaps;
                });
                TDev.Cloud.postPrivateApiAsync("benchmarks", events).done(function (json) {
                    window.localStorage["archivedPerfData"] = [];
                    rp.success(undefined);
                    TDev.Util.log("perf: Perf data successfully submitted.");
                }, function (e) {
                    TDev.Util.log("perf: Failed to send events.");
                    rp.error(undefined);
                });
                return rp;
            }
            function pushCustomData(data) {
                if (TDev.Util.check(!isNaN(data.duration) && data.duration > 0 && data.duration < 1e6, "invalid duration " + JSON.stringify(data)))
                    perfEvents.push(data);
            }
            Perf.pushCustomData = pushCustomData;
            function purgeSavedEvents() {
                perfEvents = [];
            }
            Perf.purgeSavedEvents = purgeSavedEvents;
            function stop(ts) {
                var end = TDev.Util.perfNow();
                var durr = 0;
                if (ts.lastPause == -1)
                    durr = end - ts.time;
                else {
                    durr = ts.lastPause - ts.time;
                }
                durr = Math.round(durr * 100) / 100;
                var u = unit();
                if (ts.report) {
                    if (u > 0 && compilerVersion != undefined && releaseId != undefined) {
                        var data = {
                            unitduration: u,
                            duration: durr,
                            id: ts.id,
                            compilerversion: compilerVersion,
                            releaseid: releaseId,
                            userplatform: null
                        };
                        if (TDev.Util.check(!isNaN(data.duration) && data.duration > 0 && data.duration < 1e6, "invalid duration"))
                            perfEvents.push(data);
                    }
                }
                if (Perf.timeReporting) {
                    if (u > 0)
                        TDev.Util.log(TDev.Util.fmt('perf: {0} - {1} - {2}ms', ts.id, (durr / u).toFixed(2), durr.toFixed(0)));
                    else
                        TDev.Util.log(TDev.Util.fmt('perf: {0} - {1}ms', ts.id, durr.toFixed(0)));
                }
                return durr;
            }
            Perf.stop = stop;
            function ellapsed(ts) {
                var end = TDev.Util.perfNow();
                var durr = 0;
                if (ts.lastPause == -1)
                    durr = end - ts.time;
                else {
                    durr = ts.lastPause - ts.time;
                }
                return durr;
            }
            Perf.ellapsed = ellapsed;
            function pause(ts) {
                if (ts.lastPause == -1)
                    ts.lastPause = TDev.Util.perfNow();
            }
            Perf.pause = pause;
            function resume(ts) {
                if (ts.lastPause != -1) {
                    ts.time = TDev.Util.perfNow() - (ts.lastPause - ts.time);
                    ts.lastPause = -1;
                }
            }
            Perf.resume = resume;
        })(Perf = RT.Perf || (RT.Perf = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var AppLogger = (function (_super) {
            __extends(AppLogger, _super);
            function AppLogger(category) {
                _super.call(this);
                this.category = category;
                this.minLevel = App.DEBUG;
                this.category = this.category || "";
                this.created = TDev.Util.perfNow();
            }
            AppLogger.prototype.debug = function (message, s) {
                this.log("debug", message, undefined, s);
            };
            AppLogger.prototype.info = function (message, s) {
                this.log("info", message, undefined, s);
            };
            AppLogger.prototype.warning = function (message, s) {
                this.log("warning", message, undefined, s);
            };
            AppLogger.prototype.error = function (message, s) {
                this.log("error", message, undefined, s);
            };
            AppLogger.prototype.stringToLevel = function (level) {
                switch (level.trim().toLowerCase()) {
                    case 'debug': return App.DEBUG;
                    case 'warning': return App.WARNING;
                    case 'error': return App.ERROR;
                    default: return App.INFO;
                }
            };
            AppLogger.prototype.log = function (level, message, meta, s) {
                var ilevel = this.stringToLevel(level);
                if (ilevel > this.minLevel)
                    return;
                App.logEvent(ilevel, this.category, message, this.augmentMeta(meta ? meta.value() : undefined, s));
            };
            AppLogger.prototype.set_verbosity = function (level, s) {
                this.minLevel = this.stringToLevel(level);
            };
            AppLogger.prototype.verbosity = function (s) {
                if (this.minLevel == App.DEBUG)
                    return "debug";
                if (this.minLevel == App.WARNING)
                    return "warning";
                if (this.minLevel == App.ERROR)
                    return "error";
                return "info";
            };
            AppLogger.findContext = function (s) {
                while (s && !s.loggerContext) {
                    s = s.previous;
                    if (s && s.isDetached) {
                        s = null;
                        break;
                    }
                }
                if (s)
                    return s.loggerContext;
                return null;
            };
            AppLogger.prototype.contextInfo = function (s) {
                var c = AppLogger.findContext(s);
                if (!c) {
                    return null;
                }
                else {
                    var tm = TDev.Util.perfNow() - c.created;
                    if (c.root.pauseOffset)
                        tm -= c.root.pauseOffset;
                    var r = { contextId: c.id, contextDuration: Math.round(tm), contextUser: "" };
                    for (var p = c; p; p = p.prev)
                        if (!r.contextUser)
                            r.contextUser = p.userid || "";
                    return r;
                }
            };
            AppLogger.prototype.setMetaFromContext = function (v, s) {
                var i = this.contextInfo(s);
                if (i) {
                    v.contextId = i.contextId;
                    v.contextDuration = i.contextDuration;
                    v.contextUser = i.contextUser;
                }
            };
            AppLogger.prototype.augmentMeta = function (meta, s) {
                var v = meta ? meta.value() : null;
                if (!AppLogger.findContext(s))
                    return v || {};
                if (v)
                    v = TDev.Util.jsonClone(v);
                else
                    v = {};
                this.setMetaFromContext(v, s);
                return v;
            };
            AppLogger.prototype.set_context_user = function (userid, s) {
                var c = AppLogger.findContext(s);
                if (!c)
                    TDev.Util.userError("No current context");
                if (c)
                    c.userid = userid;
            };
            AppLogger.prototype.context_user = function (s) {
                var i = this.contextInfo(s);
                if (!i || !i.contextUser)
                    return "";
                return i.contextUser;
            };
            AppLogger.prototype.context_id = function (s) {
                var i = this.contextInfo(s);
                if (!i)
                    return "";
                return i.contextId;
            };
            AppLogger.prototype.context_pause = function (s) {
                var c = AppLogger.findContext(s);
                if (c) {
                    c.root.pauseStart = TDev.Util.perfNow();
                }
            };
            AppLogger.prototype.context_resume = function (s) {
                var c = AppLogger.findContext(s);
                if (c) {
                    c = c.root;
                    if (c.pauseStart) {
                        c.pauseOffset = TDev.Util.perfNow() - c.pauseStart;
                        c.pauseStart = 0;
                    }
                }
            };
            AppLogger.prototype.logger_duration = function (s) {
                return TDev.Util.perfNow() - this.created;
            };
            AppLogger.prototype.context_duration = function (s) {
                var i = this.contextInfo(s);
                if (i)
                    return i.contextDuration;
                return TDev.Util.perfNow() - this.created;
            };
            AppLogger.prototype.tick = function (id, s) {
                if (!id)
                    return;
                App.logTick(this.category, id, this.augmentMeta(null, s));
            };
            AppLogger.prototype.custom_tick = function (id, meta, s) {
                if (!id)
                    return;
                App.logTick(this.category, id, this.augmentMeta(meta, s));
            };
            AppLogger.prototype.measure = function (id, value, s) {
                if (!id)
                    return;
                App.logMeasure(this.category, id, value, this.augmentMeta(null, s));
            };
            AppLogger.prototype.new_context = function (s) {
                var prev = AppLogger.findContext(s);
                var ctx = {
                    id: prev ? prev.id + "." + ++prev.numCh : TDev.Random.uniqueId(8),
                    prev: prev,
                    created: TDev.Util.perfNow(),
                    numCh: 0,
                };
                if (prev)
                    ctx.root = prev.root;
                else
                    ctx.root = ctx;
                s.loggerContext = ctx;
            };
            AppLogger.prototype.start = function (task) {
                var name = this.category;
                if (name)
                    name += ".";
                name += task;
                var logger = new AppLogger(name);
                logger.parent = this;
                return logger;
            };
            AppLogger.prototype.end = function () {
                if (this.parent) {
                    App.logMeasure(this.category, "LoggerStop", TDev.Util.perfNow() - this.created, null);
                    this.parent = undefined;
                }
            };
            return AppLogger;
        })(RT.RTValue);
        RT.AppLogger = AppLogger;
        var AppLogView = (function () {
            function AppLogView() {
                var _this = this;
                this._reversed = false;
                this.maxItems = TDev.Browser.isMobile ? 200 : 2000;
                this.refreshRate = TDev.Browser.isMobile ? 500 : 100;
                this.pendingChartUpdate = false;
                this.series = {};
                AppLogView.current = this;
                this.searchBox = TDev.HTML.mkTextInput("text", TDev.lf("Filter..."), "search");
                this.searchBox.classList.add("logSearchInput");
                TDev.Util.onInputChange(this.searchBox, function (v) { return _this.update(); });
                this.chartsEl = TDev.div('');
                this.chartsEl.style.display = 'none';
                this.logsEl = TDev.div('');
                this.element = TDev.div('', this.searchBox, TDev.div('logView', this.chartsEl, this.logsEl));
                TDev.Util.setupDragToScroll(this.element);
                this.element.withClick(function () {
                }, true);
                this.update();
            }
            AppLogView.prototype.setFilter = function (filter) {
                this.searchBox.value = filter || "";
                this.update();
            };
            AppLogView.prototype.showAsync = function () {
                var _this = this;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var m = new TDev.ModalDialog();
                    m.onDismiss = function () { return onSuccess(undefined); };
                    m.add(_this.element);
                    m.setScroll();
                    m.fullScreen();
                    m.show();
                });
            };
            AppLogView.prototype.attachLogEvents = function () {
                var _this = this;
                if (!this.transport) {
                    var start = TDev.Util.now();
                    this.transport = {
                        log: function (level, category, msg, meta) {
                            var lm = App.createLogMessage(level, category, msg, meta);
                            lm.elapsed = TDev.Util.elapsed(start, TDev.Util.now());
                            _this.append([lm]);
                        }
                    };
                    App.addTransport(this.transport);
                }
            };
            AppLogView.prototype.removeLogEvents = function () {
                if (this.transport) {
                    App.removeTransport(this.transport);
                    this.transport = undefined;
                }
            };
            AppLogView.prototype.charts = function (visible) {
                this.chartsEl.style.display = visible ? "block" : "none";
            };
            AppLogView.prototype.search = function (visible) {
                this.searchBox.style.display = visible ? "block" : "none";
            };
            AppLogView.prototype.reversed = function (r) {
                this._reversed = r;
                this.update();
            };
            AppLogView.prototype.update = function () {
                var _this = this;
                var els = TDev.Util.childNodes(this.logsEl);
                var terms = this.searchBox.value.toLowerCase();
                if (!terms)
                    els.forEach(function (el) { return el.style.display = 'block'; });
                else
                    els.forEach(function (el) {
                        if (el.innerText.toLowerCase().indexOf(terms) > -1) {
                            el.style.display = 'block';
                        }
                        else
                            el.style.display = 'none';
                    });
                if (this.chartsEl.style.display == 'block' && !this.pendingChartUpdate) {
                    this.pendingChartUpdate = true;
                    TDev.Util.setTimeout(this.refreshRate, function () {
                        _this.generateLogCharts();
                        _this.pendingChartUpdate = false;
                    });
                }
            };
            AppLogView.prototype.append = function (msgs) {
                function levelToClass(level) {
                    if (level <= RT.App.ERROR)
                        return "error";
                    else if (level <= RT.App.WARNING)
                        return "warning";
                    else if (level <= RT.App.INFO)
                        return "info";
                    else if (level <= RT.App.DEBUG)
                        return "debug";
                    else
                        return "noisy";
                }
                var res = [];
                msgs.filter(function (msg) { return !!msg; }).forEach(function (lvl, index) {
                    var msg = lvl.msg;
                    var txt = TDev.Util.htmlEscape(msg).replace(/https?:\/\/[^\s\r\n"'`]+/ig, function (m) { return "<a href=\"" + m + "\" target='_blank' rel='nofollow'>" + m + "</a>"; }).replace(/\b(StK[A-Za-z0-9]{8,500})/g, function (m) { return " <a href='#cmd:search:" + m + "'>" + m + "</a>"; });
                    if (lvl.meta && lvl.meta.contextId) {
                        var searchTerm = TDev.Util.htmlEscape(lvl.meta.contextId.replace(/\..*/, ""));
                        txt += " <span class='logMeta'>[<a href='#cmd:logfilter:" + searchTerm + "'>" + TDev.Util.htmlEscape(lvl.meta.contextId) + "</a>: " + Math.round(lvl.meta.contextDuration) + "ms]</span>";
                    }
                    var crash = undefined;
                    if (lvl.meta && lvl.meta && lvl.meta.kind === 'crash')
                        crash = lvl.meta;
                    res.push("<div class='logMsg' data-level='" + levelToClass(lvl.level) + "' data-timestamp='" + lvl.timestamp + "'" + (crash ? " data-crash='" + TDev.Util.htmlEscape(JSON.stringify(crash)) + "'" : "") + ">" + (lvl.elapsed ? (lvl.elapsed + '&gt; ') : '') + (lvl.category ? (TDev.Util.htmlEscape(lvl.category) + ': ') : '') + txt + "</div>");
                });
                var temp = TDev.div('');
                TDev.Browser.setInnerHTML(temp, res.join(""));
                var nodes = TDev.Util.childNodes(temp);
                if (this.onMessages)
                    this.onMessages(nodes);
                var todrop = this.logsEl.childElementCount + nodes.length - this.maxItems;
                while (todrop-- > 0 && this.logsEl.firstElementChild)
                    this.logsEl.removeChild(this._reversed ? this.logsEl.lastElementChild : this.logsEl.firstElementChild);
                var n = Math.min(nodes.length, this.maxItems);
                if (this._reversed) {
                    for (var i = n - 1; i >= 0; --i)
                        this.logsEl.insertBefore(nodes[i], this.logsEl.firstElementChild);
                }
                else {
                    for (var i = 0; i < n; ++i)
                        this.logsEl.appendChild(nodes[i]);
                }
                this.update();
            };
            AppLogView.prototype.prependHTML = function (e) {
                this.logsEl.insertBefore(e, this.logsEl.firstElementChild);
            };
            AppLogView.prototype.generateLogCharts = function () {
                var _this = this;
                var els = TDev.Util.childNodes(this.logsEl).filter(function (el) { return el.style.display == 'block'; });
                Object.keys(this.series).forEach(function (key) { return _this.series[key].points = []; });
                var timestart = 0;
                els.forEach(function (elt, index) {
                    var msg = elt.innerText;
                    if (!msg)
                        return;
                    var timestamp = parseFloat(elt.getAttribute("data-timestamp"));
                    if (index == 0)
                        timestart = timestamp;
                    var f;
                    msg.replace(/\b([a-z]\w*)\b\s*[:=]\s*(-?\d+(\.\d+)?(e\d+)?)\s*$/ig, function (mtch, key, v) {
                        var value = parseFloat(v);
                        if (!_this.series[key])
                            _this.series[key] = { points: [] };
                        var x = (timestamp - timestart) / 1000.0;
                        _this.series[key].points.push(new RT.Charts.Point(x, value));
                        return mtch;
                    });
                });
                Object.keys(this.series).forEach(function (key) {
                    var serie = _this.series[key];
                    var points = serie.points;
                    if (points.length < 5) {
                        if (serie.d)
                            serie.d.removeSelf();
                        delete _this.series[key];
                    }
                    else {
                        if (!serie.canvas) {
                            serie.canvas = document.createElement("canvas");
                            serie.canvas.width = TDev.SizeMgr.windowWidth * 0.8;
                            serie.canvas.height = serie.canvas.width / 7;
                            serie.canvas.style.display = 'block';
                            serie.canvas.style.cursor = 'pointer';
                            serie.canvas.style.marginTop = "0.5em";
                            serie.canvas.style.width = "100%";
                            serie.canvas.withClick(function () {
                                var rows = serie.points.map(function (p) { return p.x + "\t" + p.y; });
                                rows.unshift("t\t" + key);
                                var csv = rows.join('\n');
                                RT.ShareManager.copyToClipboardAsync(csv).done(function () { return TDev.HTML.showProgressNotification(TDev.lf("time serie copied to clipboard")); });
                            });
                            serie.d = TDev.div('logMsg', TDev.spanDirAuto(key), serie.canvas);
                            _this.chartsEl.appendChild(serie.d);
                        }
                        var chart = new RT.Charts.CanvasChart();
                        chart.backgroundColor = "#000";
                        chart.gridColor = "#ccc";
                        chart.lineColor = "#0c0";
                        chart.axesColor = "#000";
                        chart.graphLineWidth = 3;
                        chart.gridCols = 11;
                        chart.gridRows = 5;
                        chart.drawChart(serie.canvas, points);
                    }
                });
            };
            return AppLogView;
        })();
        RT.AppLogView = AppLogView;
        var AppEnv = (function () {
            function AppEnv() {
                this.temporarySettings = {};
            }
            AppEnv.prototype.temporary_setting = function (key) {
                return this.temporarySettings[key];
            };
            AppEnv.prototype.set_temporary_setting = function (key, value) {
                this.temporarySettings[key] = value;
            };
            AppEnv.prototype.user_agent = function () {
                return navigator.userAgent;
            };
            AppEnv.prototype.has_shell = function () {
                return !!TDev.Browser.localProxy;
            };
            AppEnv.prototype.has_host = function () {
                return TDev.Browser.isHosted;
            };
            AppEnv.prototype.runtime_kind = function (s) {
                return s.rt.runtimeKind();
            };
            AppEnv.prototype.form_factor = function () {
                if (TDev.Browser.isCellphone)
                    return "phone";
                if (TDev.Browser.isTablet)
                    return "tablet";
                return "desktop";
            };
            AppEnv.prototype.operating_system = function () {
                if (TDev.Browser.isAndroid)
                    return "android";
                if (TDev.Browser.isTrident && TDev.Browser.isCellphone)
                    return "wp";
                if (TDev.Browser.isMobileSafari)
                    return "ios";
                if (TDev.Browser.isMacOSX)
                    return "osx";
                var c = TDev.Browser.platformCaps;
                for (var i = 0; i < c.length; ++i)
                    switch (c[i]) {
                        case "win": return "windows";
                        case "x11": return "linux";
                    }
                return "unknown";
            };
            AppEnv.prototype.backend_url = function (s) {
                return s.rt.compiled.azureSite;
            };
            AppEnv.prototype.initial_url = function () {
                return TDev.Runtime.initialUrl;
            };
            return AppEnv;
        })();
        RT.AppEnv = AppEnv;
        var App;
        (function (App) {
            function createInfoMessage(s) {
                return createLogMessage(App.INFO, "", s, undefined);
            }
            App.createInfoMessage = createInfoMessage;
            function createLogMessage(level, category, s, meta) {
                var m = {
                    timestamp: TDev.Util.now(),
                    level: level,
                    category: category,
                    msg: s,
                    meta: meta
                };
                return m;
            }
            App.createLogMessage = createLogMessage;
            var Logger = (function () {
                function Logger() {
                    this.logIdx = -1;
                    this.logMsgs = [];
                    this.logSz = TDev.Browser.isNodeJS ? 2000 : 300;
                }
                Logger.prototype.addMsg = function (level, category, s, meta) {
                    var m = createLogMessage(level, category, s, meta);
                    if (this.logIdx >= 0) {
                        this.logMsgs[this.logIdx++] = m;
                        if (this.logIdx >= this.logSz)
                            this.logIdx = 0;
                    }
                    else {
                        this.logMsgs.push(m);
                        if (this.logMsgs.length >= this.logSz)
                            this.logIdx = 0;
                    }
                };
                Logger.prototype.getMsgs = function () {
                    var i = this.logIdx;
                    var res = [];
                    var wrapped = false;
                    if (i < 0)
                        i = 0;
                    var n = Date.now();
                    while (i < this.logMsgs.length) {
                        var m = this.logMsgs[i];
                        var diff = ("00000000" + (n - m.timestamp)).slice(-7).replace(/(\d\d\d)$/, function (k) { return "." + k; });
                        res.push({
                            level: m.level,
                            category: m.category,
                            msg: m.msg,
                            elapsed: diff,
                            meta: m.meta,
                            timestamp: m.timestamp
                        });
                        if (++i == this.logMsgs.length && !wrapped) {
                            wrapped = true;
                            i = 0;
                        }
                        if (wrapped && i >= this.logIdx)
                            break;
                    }
                    res.reverse();
                    return res;
                };
                return Logger;
            })();
            var logger;
            App.transports = [];
            function clearLogs() {
                logger = null;
                App.transports = [];
            }
            App.clearLogs = clearLogs;
            function startLogger() {
                logger = new Logger();
                App.transports = [];
            }
            App.startLogger = startLogger;
            function rt_start(rt) {
                if (rt.liveMode())
                    logger = null;
                else if (!logger)
                    logger = new Logger();
                App.transports = [];
            }
            App.rt_start = rt_start;
            function rt_stop(rt) {
            }
            App.rt_stop = rt_stop;
            function create_logger(category) {
                return new AppLogger(category);
            }
            App.create_logger = create_logger;
            function addTransport(transport) {
                if (transport) {
                    removeTransport(transport);
                    App.transports.push(transport);
                }
            }
            App.addTransport = addTransport;
            function removeTransport(transport) {
                if (transport) {
                    var i = App.transports.indexOf(transport);
                    if (i > -1)
                        App.transports.splice(i, 1);
                }
            }
            App.removeTransport = removeTransport;
            App.ERROR = 3;
            App.WARNING = 4;
            App.INFO = 6;
            App.DEBUG = 7;
            function log(message) {
                logEvent(App.INFO, "", message, undefined);
            }
            App.log = log;
            function transportFailed(t, tp, err) {
                if (t.id)
                    tp = " (" + t.id + ")";
                TDev.Util.log(tp + ": transport failed. " + (err.stack || err.message || err));
            }
            App.transportFailed = transportFailed;
            App.runTransports = function (id, run) {
                App.transports.forEach(function (transport) {
                    try {
                        run(transport);
                    }
                    catch (err) {
                        transportFailed(transport, id, err);
                    }
                });
            };
            function logException(err, meta) {
                if (err.tdSkipReporting) {
                    logEvent(App.DEBUG, "skipped-crash", err.message || err + "", null);
                    return;
                }
                if (err.tdIsSecondary) {
                    logEvent(App.DEBUG, "secondary-crash", err.message || err + "", null);
                    return;
                }
                try {
                    if (TDev.Runtime.theRuntime)
                        TDev.Runtime.theRuntime.augmentException(err);
                }
                catch (e) {
                }
                if (err.tdMeta) {
                    if (meta)
                        Object.keys(meta).forEach(function (k) {
                            err.tdMeta[k] = meta[k];
                        });
                    meta = err.tdMeta;
                }
                App.runTransports("logException", function (t) { return t.logException && t.logException(err, meta); });
                var msg = err.stack;
                if (!msg) {
                    msg = err.message || (err + "");
                    if (err.tdMeta && err.tdMeta.compressedStack)
                        msg += " at " + err.tdMeta.compressedStack;
                }
                logEvent(App.ERROR, "crash", msg, meta);
            }
            App.logException = logException;
            function logEvent(level, category, message, meta) {
                level = Math.max(0, Math.floor(level));
                category = category || "";
                message = message || "";
                App.runTransports("logEvent", function (t) { return t.log && t.log(level, category, message, meta); });
                if (logger) {
                    logger.addMsg(level, category, message, meta);
                    TDev.Util.log((category || "log") + ": " + message);
                }
            }
            App.logEvent = logEvent;
            function logTick(category, id, meta) {
                App.runTransports("logTick", function (t) { return t.logTick && t.logTick(category, id, meta); });
                if (!meta || !meta.skipLog)
                    App.logEvent(App.INFO, category, id, meta);
            }
            App.logTick = logTick;
            function logMeasure(category, id, value, meta) {
                var lmeta = TDev.Util.jsonClone(meta) || {};
                lmeta.measureId = id;
                lmeta.measureValue = value;
                App.runTransports("logMeasure", function (t) { return t.logMeasure && t.logMeasure(category, id, value, meta); });
                if (!meta || !meta.skipLog)
                    App.logEvent(App.INFO, category, id + ": " + value, lmeta);
            }
            App.logMeasure = logMeasure;
            function logs() {
                if (logger)
                    return logger.getMsgs();
                else
                    return [];
            }
            App.logs = logs;
            function current_handler(s) {
                return s.currentHandler;
            }
            App.current_handler = current_handler;
            function stop(r) {
                if (TDev.Browser.isCompiledApp)
                    App.restart("", r);
                else
                    r.rt.stopAsync().done();
            }
            App.stop = stop;
            function script_id(s) {
                return s.rt.currentScriptId || undefined;
            }
            App.script_id = script_id;
            function restart(message, r) {
                var rt = r.rt;
                if (TDev.Cloud.isRestricted()) {
                    rt.stopAsync().then(function () { return rt.rerunAsync(); }).done();
                    return;
                }
                var score = RT.Bazaar.cachedScore(rt);
                var scriptId = rt.currentScriptId;
                rt.stopAsync().done(function () {
                    var m = new TDev.ModalDialog();
                    m.add(TDev.div('wall-dialog-huge wall-dialog-text-center', message || TDev.lf("try again!")));
                    if (score > 0)
                        m.add(TDev.div('wall-dialog-large wall-dialog-text-center', TDev.lf("your best score: {0}", score)));
                    m.add(TDev.div('wall-dialog-body wall-dialog-extra-space wall-dialog-text-center', TDev.HTML.mkButton(TDev.lf("play again"), function () {
                        TDev.tick(311 /* runtimePlayAgain */);
                        m.dismiss();
                        rt.rerunAsync().done();
                    }, 'wall-dialog-button-huge'), TDev.Browser.notifyBackToHost ? TDev.HTML.mkButton(TDev.lf("back"), function () {
                        TDev.tick(312 /* runtimeBack */);
                        m.dismiss();
                        TDev.Util.externalNotify("exit");
                    }) : null));
                    if (scriptId && score > 0) {
                        RT.Bazaar.loadLeaderboardItemsAsync(scriptId).done(function (els) {
                            if (els && els.length > 0) {
                                m.add(TDev.div('wall-dialog-body wall-dialog-extra-space ', els));
                                m.setScroll();
                            }
                        }, function (e) {
                        });
                    }
                    m.fullWhite();
                    m.show();
                });
            }
            App.restart = restart;
            function fail_if_not(condition) {
                if (!condition)
                    TDev.Util.userError(TDev.lf("assertion violation"));
            }
            App.fail_if_not = fail_if_not;
            function server_setting(key, optional, s) {
                if (!optional)
                    TDev.Util.userError(TDev.lf("only supported on exported node.js apps"), s.pc);
                return undefined;
            }
            App.server_setting = server_setting;
            function javascript(calling_convention, script) {
            }
            App.javascript = javascript;
            function javascript_async(calling_convention, script, r) {
                r.resume();
            }
            App.javascript_async = javascript_async;
            function import_(manager, module, version) {
            }
            App.import_ = import_;
            function thumb(script) {
            }
            App.thumb = thumb;
            function server_request(s) {
                return s.rt.getRestRequest();
            }
            App.server_request = server_request;
            function server_response(s) {
                var r = s.rt.getRestRequest();
                if (r)
                    return r.response();
                return undefined;
            }
            App.server_response = server_response;
            function editor(s) {
                return s.rt.editorObj;
            }
            App.editor = editor;
            var _env = new AppEnv();
            function env() {
                return _env;
            }
            App.env = env;
            function reflect(what, s) {
                var ri = s.rt.compiled.reflectionInfo;
                if (ri.hasOwnProperty(what))
                    return RT.JsonObject.wrap(ri[what]);
                return undefined;
            }
            App.reflect = reflect;
            function run_command(cmd, data, r) {
                var proxyAsync = r.rt.host.localProxyAsync;
                if (!proxyAsync) {
                    r.resumeVal(RT.JsonObject.wrap({ error: 'notsupported', reason: TDev.lf("This command requires a local proxy.") }));
                    return;
                }
                r.rt.host.askSourceAccessAsync(TDev.lf("execute shell commands or manipulate files."), TDev.lf("the shell and/or the file system. This script may be harmful for your computer. Do not allow this if you do not trust the source of this script."), false, true).then(function (allow) {
                    if (!allow)
                        return TDev.Promise.as(RT.JsonObject.wrap({ error: 'denied', reason: TDev.lf("The user denied access to shell execution.") }));
                    else
                        return proxyAsync(cmd, data ? data.value() : undefined);
                }).done(function (res) { return r.resumeVal(RT.JsonObject.wrap(res)); }, function (e) { return r.resumeVal(RT.JsonObject.wrap({ error: 'proxyerror', message: e.message, stack: e.stack })); });
            }
            App.run_command = run_command;
            function show_logs(filter, r) {
                r.resume();
                showAppLogAsync(undefined, filter).done(function () {
                }, function (e) {
                });
            }
            App.show_logs = show_logs;
            function showAppLogAsync(msgs, filter, onMessages) {
                var view = new AppLogView();
                view.onMessages = onMessages;
                view.charts(true);
                view.append(App.logs());
                view.setFilter(filter);
                if (msgs)
                    view.append(msgs);
                view.attachLogEvents();
                return view.showAsync().then(function () { return view.removeLogEvents(); }, function () { return view.removeLogEvents(); });
            }
            App.showAppLogAsync = showAppLogAsync;
            function showLog(msgs, onMessages) {
                var view = new AppLogView();
                view.onMessages = onMessages;
                view.append(msgs);
                view.showAsync().done(function () {
                }, function (e) {
                });
            }
            App.showLog = showLog;
            function consume_rendered_comments(s) {
                var r = s.rt.renderedComments;
                s.rt.renderedComments = "";
                return r;
            }
            App.consume_rendered_comments = consume_rendered_comments;
            function hostExecAsync(message) {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    if (message == "td_access_token") {
                        if (!TDev.Cloud.hasPermission("post-raw"))
                            onSuccess(undefined);
                        TDev.Runtime.theRuntime.host.askSourceAccessAsync(TDev.lf("your private access token"), TDev.lf("your Touch Develop access token. The script will be able to upload web content as you."), false, true).done(function (allow) {
                            if (!allow)
                                onSuccess(undefined);
                            else
                                onSuccess(TDev.Cloud.getServiceUrl() + "/?access_token=" + TDev.Cloud.getAccessToken());
                        });
                        return;
                    }
                    var mcefQuery = window.mcefQuery;
                    if (mcefQuery) {
                        mcefQuery({
                            request: message,
                            persistent: false,
                            onSuccess: function (response) {
                                onSuccess(response);
                            },
                            onFailure: function (error_code, error_message) {
                                App.logEvent(App.DEBUG, "app", "mcefQuery failed", undefined);
                                onSuccess(JSON.stringify({ error: error_code, message: error_message }));
                            }
                        });
                        return;
                    }
                    var cordova = window.cordova;
                    if (cordova && cordova.exec) {
                        try {
                            var payload = JSON.parse(message);
                            cordova.exec(function (result) {
                                onSuccess(JSON.stringify(result));
                            }, function (error) {
                                onSuccess(JSON.stringify({ error: error }));
                            }, payload.service, payload.action, payload.arguments);
                        }
                        catch (e) {
                            App.logEvent(App.DEBUG, "app", "window.cordova.exec failed", undefined);
                            onSuccess(undefined);
                        }
                        return;
                    }
                    var exec = window.touchDevelopExec;
                    if (exec) {
                        try {
                            exec(message, function (result) {
                                onSuccess(result);
                            });
                        }
                        catch (e) {
                            App.logEvent(App.DEBUG, "app", "touchDevelopExec failed", undefined);
                            onSuccess(undefined);
                        }
                        return;
                    }
                    App.log("no host found");
                    onSuccess(undefined);
                });
            }
            App.hostExecAsync = hostExecAsync;
            function hostSubscribeAsync(rt, message, handler) {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var ev = new RT.Event_();
                    var binding = ev.addHandler(handler);
                    var mcefQuery = window.mcefQuery;
                    if (mcefQuery) {
                        try {
                            mcefQuery({
                                request: message,
                                persistent: true,
                                onSuccess: function (response) {
                                    rt.queueLocalEvent(ev, [response], false, false);
                                },
                                onFailure: function (error_code, error_message) {
                                    App.logEvent(App.DEBUG, "app", "mcefQuery failed: " + error_code, undefined);
                                }
                            });
                        }
                        catch (e) {
                            onSuccess(undefined);
                            return;
                        }
                        onSuccess(binding);
                        return;
                    }
                    var cordova = window.cordova;
                    if (cordova && cordova.exec) {
                        try {
                            var payload = JSON.parse(message);
                            cordova.exec(function (result) {
                                rt.queueLocalEvent(ev, [JSON.stringify(result)], false, false);
                            }, function (error) {
                                App.logEvent(App.DEBUG, "app", "cordova.exec failed: " + error, undefined);
                            }, payload.service, payload.action, payload.arguments);
                        }
                        catch (e) {
                            App.logEvent(App.DEBUG, "app", "cordova.exec failed: " + e, undefined);
                            onSuccess(undefined);
                            return;
                        }
                        onSuccess(binding);
                        return;
                    }
                    var exec = window.touchDevelopExec;
                    if (exec) {
                        try {
                            exec(message, function (result) {
                                rt.queueLocalEvent(ev, [JSON.stringify(result)], false, false);
                            });
                        }
                        catch (e) {
                            App.logEvent(App.DEBUG, "app", "touchDevelopExec failed", undefined);
                            onSuccess(undefined);
                            return;
                        }
                        onSuccess(binding);
                        return;
                    }
                    App.log("no host found");
                    onSuccess(undefined);
                });
            }
            App.hostSubscribeAsync = hostSubscribeAsync;
            function host_exec(message, r) {
                return hostExecAsync(message).done(function (resp) { return r.resumeVal(resp); });
            }
            App.host_exec = host_exec;
            function host_subscribe(message, handler, r) {
                return hostSubscribeAsync(r.rt, message, handler).done(function (resp) { return r.resumeVal(resp); });
            }
            App.host_subscribe = host_subscribe;
            function allow_other_events(s) {
                s.rt.eventExecuting = false;
            }
            App.allow_other_events = allow_other_events;
        })(App = RT.App || (RT.App = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ActionBase = (function (_super) {
            __extends(ActionBase, _super);
            function ActionBase() {
                _super.apply(this, arguments);
            }
            return ActionBase;
        })(RT.RTValue);
        RT.ActionBase = ActionBase;
        var PseudoAction = (function (_super) {
            __extends(PseudoAction, _super);
            function PseudoAction(run) {
                _super.call(this);
                this.run = run;
            }
            return PseudoAction;
        })(ActionBase);
        RT.PseudoAction = PseudoAction;
        var Event_ = (function (_super) {
            __extends(Event_, _super);
            function Event_() {
                _super.call(this);
                this.isPageEvent = false;
                this.handlers = undefined;
                this.pendinghandlers = 0;
                this.isBlocking = true;
            }
            Event_.prototype.addHandler = function (f) {
                var binding = new EventBinding(this, f);
                if (!this.handlers)
                    this.handlers = [];
                this.handlers.push(binding);
                return binding;
            };
            Event_.prototype.removeHandler = function (binding) {
                if (this.handlers) {
                    var idx = this.handlers.indexOf(binding);
                    if (idx > -1) {
                        this.handlers.splice(idx, 1);
                        if (this.handlers.length == 0)
                            this.handlers = undefined;
                    }
                }
            };
            Event_.prototype.clearHandlers = function () {
                this.handlers = undefined;
            };
            Event_.prototype.runAwaiters = function (args) {
                if (this.awaiters) {
                    var lst = this.awaiters;
                    this.awaiters = null;
                    TDev.Util.setTimeout(0, function () { return lst.forEach(function (a) { return a(args); }); });
                }
            };
            Event_.prototype.addAwaiter = function (f) {
                if (!this.awaiters)
                    this.awaiters = [];
                this.awaiters.push(f);
            };
            return Event_;
        })(RT.RTValue);
        RT.Event_ = Event_;
        var EventBinding = (function (_super) {
            __extends(EventBinding, _super);
            function EventBinding(_event, _handler) {
                _super.call(this);
                this._event = _event;
                this._handler = _handler;
                this.inQueue = false;
                this.data = undefined;
            }
            EventBinding.prototype.delete_ = function () {
                if (this._event && this._handler) {
                    this._event.removeHandler(this);
                    this._handler = undefined;
                }
            };
            return EventBinding;
        })(RT.RTValue);
        RT.EventBinding = EventBinding;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Bazaar;
        (function (Bazaar) {
            function user_of(id, r) {
                RT.User.getJsonAsync(id).done(function (user) { return r.resumeVal((user && user.kind == "user") ? RT.User.mk(id) : undefined); }, function (e) { return r.resumeVal(undefined); });
            }
            Bazaar.user_of = user_of;
            function userIdAsync(rt) {
                if (!rt.requiresAuth())
                    return TDev.Promise.as(rt.getUserId());
                return TDev.Cloud.authenticateAsync(TDev.lf("user identification")).then(function () { return TDev.Cloud.getUserId(); });
            }
            Bazaar.userIdAsync = userIdAsync;
            function current_user(r) {
                userIdAsync(r.rt).done(function (userId) { return r.resumeVal(userId ? RT.User.mk(userId) : undefined); });
            }
            Bazaar.current_user = current_user;
            function cachedScore(rt, score) {
                var currentScore = rt.datas["this"]["leaderboard_score"] || 0;
                if (score && score > currentScore) {
                    rt.datas["this"]["leaderboard_score"] = score;
                    currentScore = score;
                }
                return currentScore;
            }
            Bazaar.cachedScore = cachedScore;
            function leaderboard_score(r) {
                var rt = r.rt;
                var currentScore = cachedScore(rt);
                var localScore = function () { return r.resumeVal(currentScore); };
                if (!rt.currentScriptId || !TDev.Cloud.isOnline()) {
                    localScore();
                }
                else {
                    TDev.Cloud.authenticateAsync(TDev.lf("leaderboard")).done(function (authenticated) {
                        if (authenticated) {
                            var url = TDev.Cloud.getPrivateApiUrl('me/leaderboardscored/' + rt.currentScriptId);
                            var request = RT.WebRequest.mk(url, undefined);
                            request.sendAsync().done(function (response) {
                                var curr = 0;
                                var json = response.content_as_json();
                                if (json)
                                    curr = json.number('score');
                                r.resumeVal(cachedScore(rt, Math.max(currentScore, curr || 0)));
                            });
                        }
                        else {
                            localScore();
                        }
                    });
                }
            }
            Bazaar.leaderboard_score = leaderboard_score;
            function postScoreToOfficeMix(score, scriptId) {
                if (TDev.Browser.webRunner || TDev.Browser.webAppImplicit) {
                    var msg = RT.JsonObject.wrap({
                        kind: "leaderboardScore__Send",
                        data: { score: score, scriptId: scriptId }
                    });
                    RT.Web.post_message_to_parent(TDev.Cloud.config.rootUrl, msg, null);
                    RT.Web.post_message_to_parent("http://localhost:15669", msg, null);
                }
            }
            Bazaar.postScoreToOfficeMix = postScoreToOfficeMix;
            function post_leaderboard_score(score, r) {
                var rt = r.rt;
                var currentScore = cachedScore(rt, score);
                if (!rt.currentScriptId || !TDev.Cloud.isOnline()) {
                    r.resume();
                }
                else {
                    Bazaar.postScoreToOfficeMix(score, rt.currentScriptId);
                    TDev.Cloud.authenticateAsync(TDev.lf("leaderboard")).done(function (authenticated) {
                        if (authenticated) {
                            var url = TDev.Cloud.getPrivateApiUrl(rt.currentScriptId + '/leaderboardscores');
                            var request = RT.WebRequest.mk(url, undefined);
                            request.set_method('post');
                            request.set_content_as_json(RT.JsonObject.mk(JSON.stringify({ kind: "leaderboardscore", score: score || 0, userplatform: TDev.Browser.platformCaps }), TDev.Util.log));
                            request.sendAsync().done(function (response) {
                                var json = response.content_as_json();
                                if (json)
                                    cachedScore(rt, json.number('score'));
                                r.resume();
                            });
                        }
                    }, function (e) {
                        r.resume();
                    });
                }
            }
            Bazaar.post_leaderboard_score = post_leaderboard_score;
            function loadLeaderboardItemsAsync(striptId) {
                if (!striptId || !TDev.Cloud.isOnline())
                    return TDev.Promise.as([]);
                return TDev.Cloud.getPublicApiAsync(striptId + '/leaderboardscores?count=250').then(function (leaderboards) {
                    return leaderboards.items.map(function (item) {
                        var userid = item.userid;
                        var username = item.username;
                        var userscore = item.score.toString();
                        var time = TDev.Util.timeSince(item.time);
                        var imgDiv = TDev.div('leaderboard-img');
                        if (item.userhaspicture)
                            imgDiv.style.backgroundImage = TDev.HTML.cssImage(TDev.Cloud.getPublicApiUrl(userid + "/picture?type=normal"));
                        else
                            imgDiv.innerHTML = TDev.Util.svgGravatar(userid);
                        var scoreDiv = TDev.div('item leaderboard-item', [
                            imgDiv,
                            TDev.div('leaderboards-score', userscore),
                            TDev.div('leaderboard-center', [
                                TDev.div('item-title', username),
                                TDev.div('item-subtle', time)
                            ])
                        ]);
                        return scoreDiv;
                    });
                }, function (e) {
                    return [];
                });
            }
            Bazaar.loadLeaderboardItemsAsync = loadLeaderboardItemsAsync;
            function post_leaderboard_to_wall(r) {
                var rt = r.rt;
                if (!rt.currentScriptId) {
                    var curr = cachedScore(rt).toString();
                    var imgDiv = TDev.div('leaderboard-img');
                    imgDiv.innerHTML = TDev.Util.svgGravatar('me');
                    var leaderboardDiv = TDev.div('item leaderboard-item', [
                        imgDiv,
                        TDev.div('leaderboards-score', curr),
                        TDev.div('leaderboard-center', [
                            TDev.div('item-title', TDev.lf("Me")),
                            TDev.div('item-subtle', TDev.lf("Publish your script to get a leaderboard available for all your users.")),
                        ])
                    ]);
                    r.rt.postBoxedHtml(leaderboardDiv, r.rt.current.pc);
                    r.resume();
                }
                else if (!TDev.Cloud.isOnline()) {
                    var curr = cachedScore(rt).toString();
                    var imgDiv = TDev.div('leaderboard-img');
                    imgDiv.innerHTML = TDev.Util.svgGravatar('me');
                    var leaderboardDiv = TDev.div('item leaderboard-item', [
                        imgDiv,
                        TDev.div('leaderboards-score', curr),
                        TDev.div('leaderboard-center', [
                            TDev.div('item-title', TDev.lf("Me")),
                            TDev.div('item-subtle', TDev.lf("Please connect to internet to load the leaderboards.")),
                        ])
                    ]);
                    r.rt.postBoxedHtml(leaderboardDiv, r.rt.current.pc);
                    r.resume();
                }
                else {
                    r.progress(TDev.lf("Loading leaderboards..."));
                    var leaderboardDiv = TDev.div('');
                    loadLeaderboardItemsAsync(rt.currentScriptId).done(function (els) {
                        leaderboardDiv.setChildren(els);
                        rt.postBoxedHtml(leaderboardDiv, r.rt.current.pc);
                        r.resume();
                    }, function (e) {
                        rt.postBoxedText(TDev.lf("Oops, could not get the leaderboards. Please check your internet connection."), r.rt.current.pc);
                        r.resume();
                    });
                }
            }
            Bazaar.post_leaderboard_to_wall = post_leaderboard_to_wall;
            function merge3(O, A, B) {
                var t1 = TDev.AST.Parser.parseScript(O);
                var t2 = TDev.AST.Parser.parseScript(A);
                var t3 = TDev.AST.Parser.parseScript(B);
                TDev.AST.TypeChecker.tcApp(t1);
                TDev.AST.TypeChecker.tcApp(t2);
                TDev.AST.TypeChecker.tcApp(t3);
                TDev.TheEditor.initIds(t1);
                TDev.TheEditor.initIds(t2);
                TDev.TheEditor.initIds(t3);
                var merged = TDev.AST.Merge.merge3(t1, t2, t3);
                return merged.serialize();
            }
            Bazaar.merge3 = merge3;
            function open() {
            }
            Bazaar.open = open;
            function open_review() {
            }
            Bazaar.open_review = open_review;
            function open_leaderboard(r) {
                post_leaderboard_to_wall(r);
            }
            Bazaar.open_leaderboard = open_leaderboard;
            function script_id(which, s) {
                if (which == "top")
                    return s.libs.topScriptId;
                if (which == "current")
                    return s.libs.scriptId;
                return undefined;
            }
            Bazaar.script_id = script_id;
            function pick_script(mode, message, r) {
                r.rt.host.pickScriptAsync(mode, message).done(function (id) {
                    r.resumeVal(id);
                });
            }
            Bazaar.pick_script = pick_script;
            function save_ast(id, script, r) {
                r.rt.host.saveAstAsync(id, script.value()).done(function (id) {
                    r.resume();
                });
            }
            Bazaar.save_ast = save_ast;
            function ast_of(id, r) {
                r.rt.host.astOfAsync(id).done(function (j) {
                    if (!j)
                        r.resumeVal(undefined);
                    else
                        r.resumeVal(RT.JsonObject.wrap(j));
                });
            }
            Bazaar.ast_of = ast_of;
            Bazaar.storeidAsync = function () {
                var host = window.touchDevelopHost;
                if (host) {
                    TDev.Util.log("using touchdevelop host");
                    var id = host.storeid() || "";
                    TDev.Util.log("storeid: " + id);
                    return TDev.Promise.as(id);
                }
                return TDev.Promise.as("");
            };
        })(Bazaar = RT.Bazaar || (RT.Bazaar = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Board = (function (_super) {
            __extends(Board, _super);
            function Board() {
                _super.call(this);
                this.scaleFactor = 1.0;
                this.sprites = [];
                this.backgroundColor = null;
                this.backgroundPicture = null;
                this.backgroundCamera = null;
                this._boundaryDistance = NaN;
                this._everyFrameTimer = undefined;
                this._gravity = new RT.Vector2(0, 0);
                this._worldFriction = 0;
                this._debugMode = false;
                this._lastUpdateMS = 0;
                this._lastTimeDelta = 0;
                this._startTime = 0;
                this._touched = false;
                this._touchStart = RT.Vector3.mk(0, 0, 0);
                this._touchCurrent = RT.Vector3.mk(0, 0, 0);
                this._touchEnd = RT.Vector3.mk(0, 0, 0);
                this._touchVelocity = RT.Vector3.mk(0, 0, 0);
                this._minSegments = [];
                this._walls = [];
                this._obstacles = [];
                this._springs = [];
                this._backgroundScene = undefined;
                this.swipeThreshold = 10;
                this.dragThreshold = 5;
                this.onTap = new RT.Event_();
                this.onTouchDown = new RT.Event_();
                this.onTouchUp = new RT.Event_();
                this.onSwipe = new RT.Event_();
                this._touchPrevious = RT.Vector3.mk(0, 0, 0);
                this._touchDirection = RT.Vector3.mk(0, 0, 0);
                this.tick = 0;
                this._everyFrameOnSprite = false;
            }
            Board.mk = function (rt, landscape, w, h, full) {
                var b = new Board();
                b._landscape = landscape;
                b._width = w;
                b._height = h;
                b._full = full;
                b._startTime = rt.currentTime();
                b.backgroundColor = RT.Colors.transparent();
                b.init(rt);
                return b;
            };
            Board.prototype.init = function (rt) {
                var _this = this;
                this._runtime = rt;
                this.canvas = document.createElement("canvas");
                this.canvas.className = "boardCanvas";
                this.updateScaleFactor();
                this.container = TDev.div("boardContainer", this.canvas);
                this.ctx = this.canvas.getContext("2d");
                this.container.setChildren([this.canvas]);
                this.container.updateSizes = function () {
                    _this.updateScaleFactor();
                    _this.redrawBoardAndContents();
                };
                var handler = new TDev.TouchHandler(this.canvas, function (e, x, y) {
                    _this.touchHandler(e, x, y);
                });
            };
            Board.prototype.updateScaleFactor = function () {
                TDev.Util.assert(!!this._runtime);
                if (!this._runtime)
                    return;
                var s0;
                var s1;
                if (this._full) {
                    s0 = this._runtime.host.fullWallWidth() / this._width;
                    s1 = this._runtime.host.fullWallHeight() / this._height;
                }
                else {
                    var w = this._runtime.host.wallWidth;
                    if (this.container && this.container.offsetWidth)
                        w = this.container.offsetWidth;
                    s0 = w / this._width;
                    s1 = this._runtime.host.wallHeight / this._height;
                }
                if (s0 > s1)
                    s0 = s1;
                var ww = this._width * s0;
                var hh = this._height * s0;
                this.scaleFactor = s0;
                this.canvas.width = ww * TDev.SizeMgr.devicePixelRatio;
                this.canvas.height = hh * TDev.SizeMgr.devicePixelRatio;
                this.canvas.style.width = ww + "px";
                this.canvas.style.height = hh + "px";
                if (this._full) {
                    var topMargin = (this._runtime.host.fullWallHeight() - hh) / 2;
                    this.canvas.style.marginTop = topMargin + "px";
                }
            };
            Board.prototype.touchHandler = function (e, x, y) {
                TDev.Util.assert(!!this._runtime);
                if (!this._runtime)
                    return;
                x = Math.round(x / this.scaleFactor);
                y = Math.round(y / this.scaleFactor);
                switch (e) {
                    case "down":
                        this._touched = true;
                        this._touchPrevious = this._touchCurrent = this._touchLast = this._touchStart = RT.Vector3.mk(x, y, 0);
                        this._touchedSpriteStack = this.findTouchedSprites(x, y);
                        this._prevTouchTime = this._runtime.currentTime();
                        this._touchDeltaTime = 0;
                        this._touchDirection = RT.Vector3.mk(0, 0, 0);
                        this.queueTouchDown(this._touchedSpriteStack, [x, y]);
                        this._runtime.queueBoardEvent(["touch down: "], [this], [x, y]);
                        if (!!this._touchedSpriteStack) {
                            this._runtime.queueBoardEvent(["touch over "], this._touchedSpriteStack, [x, y], true, true);
                        }
                        break;
                    case "move":
                        this._touchCurrent = RT.Vector3.mk(x, y, 0);
                        var now = this._runtime.currentTime();
                        var deltaMove = this._touchCurrent.subtract(this._touchPrevious);
                        var deltaTime = now - this._prevTouchTime;
                        if (deltaTime > 50 || deltaMove.length() > 20) {
                            this._touchDirection = deltaMove;
                            this._touchDeltaTime = deltaTime;
                        }
                        if (!!this._touchedSpriteStack) {
                            var dist = this._touchCurrent.subtract(this._touchLast);
                            if (dist.length() > this.dragThreshold) {
                                this._touchLast = this._touchCurrent;
                                this.queueDrag(this._touchedSpriteStack, [x, y, dist._x, dist._y]);
                                this._runtime.queueBoardEvent(["drag sprite in ", "drag sprite: "], this._touchedSpriteStack, [x, y, dist._x, dist._y]);
                            }
                        }
                        var currentStack = this.findTouchedSprites(x, y);
                        if (!!currentStack) {
                            this._runtime.queueBoardEvent(["touch over "], currentStack, [x, y], true, true);
                        }
                        break;
                    case "up":
                        var currentPoint = RT.Vector3.mk(x, y, 0);
                        this._touchEnd = this._touchCurrent = currentPoint;
                        this._touched = false;
                        if (this._touchDeltaTime > 0) {
                            this._touchVelocity = this._touchDirection.scale(1000 / this._touchDeltaTime);
                        }
                        else {
                            this._touchVelocity = RT.Vector3.mk(0, 0, 0);
                        }
                        var dist = this._touchEnd.subtract(this._touchStart);
                        var stack = this._touchedSpriteStack;
                        if (!stack) {
                            stack = [];
                        }
                        stack.push(this);
                        if (dist.length() > this.swipeThreshold) {
                            this.queueSwipe(this._touchedSpriteStack, [this._touchStart._x, this._touchStart._y, dist._x, dist._y]);
                            this._runtime.queueBoardEvent(["swipe sprite in ", "swipe sprite: ", "swipe board: "], stack, [this._touchStart._x, this._touchStart._y, dist._x, dist._y]);
                        }
                        else {
                            this.queueTap(this._touchedSpriteStack, [x, y]);
                            this._runtime.queueBoardEvent(["tap sprite in ", "tap sprite: ", "tap board: "], stack, [x, y]);
                        }
                        this.queueTouchUp(this._touchedSpriteStack, [x, y]);
                        this._runtime.queueBoardEvent(["touch up: "], [this], [x, y]);
                        break;
                }
            };
            Board.prototype.queueDrag = function (stack, args) {
                if (!stack)
                    return false;
                for (var i = 0; i < stack.length; i++) {
                    var sprite = stack[i];
                    if (sprite instanceof Board)
                        continue;
                    if (sprite.onDrag.handlers) {
                        this._runtime.queueLocalEvent(sprite.onDrag, args);
                        return true;
                    }
                }
                return false;
            };
            Board.prototype.queueTouchDown = function (stack, args) {
                if (stack && stack.length > 0) {
                    for (var i = 0; i < stack.length; i++) {
                        var sprite = stack[i];
                        if (sprite instanceof Board)
                            continue;
                        if (sprite.onTouchDown.handlers) {
                            this._runtime.queueLocalEvent(sprite.onTouchDown, args);
                            return true;
                        }
                    }
                }
                else {
                    if (this.onTouchDown.handlers) {
                        this._runtime.queueLocalEvent(this.onTouchDown, args);
                        return true;
                    }
                }
                return false;
            };
            Board.prototype.queueTouchUp = function (stack, args) {
                if (stack && stack.length > 0) {
                    for (var i = 0; i < stack.length; i++) {
                        var sprite = stack[i];
                        if (sprite instanceof Board)
                            continue;
                        if (sprite.onTouchUp.handlers) {
                            this._runtime.queueLocalEvent(sprite.onTouchUp, args);
                            return true;
                        }
                    }
                }
                else {
                    if (this.onTouchUp.handlers) {
                        this._runtime.queueLocalEvent(this.onTouchUp, args);
                        return true;
                    }
                }
                return false;
            };
            Board.prototype.queueTap = function (stack, args) {
                if (stack && stack.length > 0) {
                    for (var i = 0; i < stack.length; i++) {
                        var sprite = stack[i];
                        if (sprite instanceof Board)
                            continue;
                        if (sprite.onTap.handlers) {
                            this._runtime.queueLocalEvent(sprite.onTap, args);
                            return true;
                        }
                    }
                }
                if (this.onTap.handlers) {
                    this._runtime.queueLocalEvent(this.onTap, args);
                    return true;
                }
                return false;
            };
            Board.prototype.queueSwipe = function (stack, args) {
                if (stack && stack.length > 0) {
                    for (var i = 0; i < stack.length; i++) {
                        var sprite = stack[i];
                        if (sprite instanceof Board)
                            continue;
                        if (sprite.onSwipe.handlers) {
                            this._runtime.queueLocalEvent(sprite.onSwipe, args);
                            return true;
                        }
                    }
                }
                else {
                    if (this.onSwipe.handlers) {
                        this._runtime.queueLocalEvent(this.onSwipe, args);
                        return true;
                    }
                }
                return false;
            };
            Board.prototype.findTouchedSprites = function (x, y) {
                var candidates = this.orderedSprites().filter(function (sp) { return !sp._hidden && sp.contains(x, y); }).reverse();
                if (candidates.length == 0)
                    return undefined;
                return candidates;
            };
            Board.prototype.applyBackground = function () {
                this.ctx.save();
                this.ctx.clearRect(0, 0, this._width, this._height);
                if (!!this.backgroundCamera) {
                }
                else if (!!this.backgroundPicture && this.backgroundPicture.hasCanvas()) {
                    this.ctx.drawImage(this.backgroundPicture.getCanvas(), 0, 0, this.backgroundPicture.widthSync(), this.backgroundPicture.heightSync(), 0, 0, this._width, this._height);
                }
                else if (!!this.backgroundColor) {
                    this.ctx.fillStyle = this.backgroundColor.toHtml();
                    this.ctx.fillRect(0, 0, this._width, this._height);
                }
                if (this._backgroundScene)
                    this._backgroundScene.render(this._width, this._height, this.ctx);
                this.ctx.restore();
            };
            Board.prototype.height = function () {
                return this._height;
            };
            Board.prototype.count = function () {
                return this.sprites.length;
            };
            Board.prototype.get_enumerator = function () {
                return this.sprites.slice(0);
            };
            Board.prototype.width = function () {
                return this._width;
            };
            Board.prototype.touched = function () {
                return this._touched;
            };
            Board.prototype.touch_start = function () {
                return this._touchStart;
            };
            Board.prototype.touch_current = function () {
                return this._touchCurrent;
            };
            Board.prototype.touch_end = function () {
                return this._touchEnd;
            };
            Board.prototype.touch_velocity = function () {
                return this._touchVelocity;
            };
            Board.prototype.create_boundary = function (distance) {
                if (!isNaN(this._boundaryDistance))
                    return;
                this._boundaryDistance = distance;
                this.initializeCanvasBoundaries(distance);
            };
            Board.prototype.initializeCanvasBoundaries = function (distance) {
                if (isNaN(distance))
                    return;
                this._walls.push(WallSegment.mk(-distance, -distance, this.width() + 2 * distance, 0, 1, 0));
                this._walls.push(WallSegment.mk(this.width() + distance, -distance, 0, this.height() + 2 * distance, 1, 0));
                this._walls.push(WallSegment.mk(this.width() + distance, this.height() + distance, -(this.width() + 2 * distance), 0, 1, 0));
                this._walls.push(WallSegment.mk(-distance, this.height() + distance, 0, -(this.height() + 2 * distance), 1, 0));
            };
            Board.prototype.addObstacle = function (o) {
                this._walls.push(WallSegment.mk(o.x, o.y, o.xextent, o.yextent, o.elasticity, o.friction, o));
                this._walls.push(WallSegment.mk(o.x + o.xextent, o.y + o.yextent, -o.xextent, -o.yextent, o.elasticity, o.friction, o));
                this._obstacles.push(o);
            };
            Board.prototype.create_sprite_set = function () {
                return new RT.SpriteSet();
            };
            Board.prototype.deleteSprite = function (sprite) {
                var idx = this.sprites.indexOf(sprite);
                if (idx < 0)
                    return;
                this.sprites.splice(idx, 1);
                this.spritesChanged();
            };
            Board.prototype.spritesChanged = function () {
                this._orderedSprites = undefined;
            };
            Board.prototype.frame_timer = function (s) {
                if (!this._everyFrameTimer)
                    this._everyFrameTimer = new RT.Timer(s.rt, 0.02, false);
                return this._everyFrameTimer;
            };
            Board.prototype.add_on_every_frame = function (body, s) {
                return this.on_every_frame(body, s);
            };
            Board.prototype.on_every_frame = function (body, s) {
                return this.frame_timer(s).on_trigger(body);
            };
            Board.prototype.clear_every_frame_timers = function () {
                if (this._everyFrameTimer) {
                    this._everyFrameTimer.clear();
                    this._everyFrameTimer = undefined;
                    this._everyFrameOnSprite = false;
                }
            };
            Board.prototype.on_tap = function (tapped) {
                return this.onTap.addHandler(tapped);
            };
            Board.prototype.on_swipe = function (swiped) {
                return this.onSwipe.addHandler(swiped);
            };
            Board.prototype.on_touch_down = function (touch_down) {
                return this.onTouchDown.addHandler(touch_down);
            };
            Board.prototype.on_touch_up = function (touch_up) {
                return this.onTouchUp.addHandler(touch_up);
            };
            Board.prototype.evolve = function () {
                var _this = this;
                TDev.Util.assert(!!this._runtime);
                if (!this._runtime)
                    return;
                this.tick++;
                if (isNaN(this.tick))
                    this.tick = 0;
                var now = this._runtime.currentTime();
                var newDelta = this._lastTimeDelta = (now - this._startTime) - this._lastUpdateMS;
                this._lastUpdateMS += newDelta;
                var dT = RT.Math_.clamp(0, 0.2, newDelta / 1000);
                this.sprites.forEach(function (sprite) { return sprite.update(dT); });
                this.detectCollisions(dT);
                this.sprites.forEach(function (sprite) { return sprite.commitUpdate(_this._runtime, dT); });
            };
            Board.prototype.detectCollisions = function (dT) {
                for (var i = 0; i < this.sprites.length; i++) {
                    var s = this.sprites[i];
                    if (!!s._location)
                        continue;
                    this.detectWallCollision(s, dT);
                }
            };
            Board.prototype.detectWallCollision = function (sprite, dT) {
                sprite.normalTouchPoints.clear();
                for (var i = 0; i < this._walls.length; i++) {
                    var wall = this._walls[i];
                    if (wall.processPotentialCollision(sprite, dT) && wall._obstacle)
                        wall._obstacle.raiseCollision(this._runtime, sprite);
                }
                for (var i = 0; i < this._walls.length; i++) {
                    var wall = this._walls[i];
                    if (wall.processPotentialCollision(sprite, dT) && wall._obstacle)
                        wall._obstacle.raiseCollision(this._runtime, sprite);
                }
            };
            Board.prototype.updateViewCore = function (s, b) {
                if (b instanceof TDev.WallBox)
                    b.fullScreen = this._full;
                this.redrawBoardAndContents();
            };
            Board.prototype.getViewCore = function (s, b) {
                this._touched = false;
                return this.container;
            };
            Board.prototype.equals = function (other_board) {
                return this == other_board;
            };
            Board.prototype.background_scene = function () {
                if (!this._backgroundScene)
                    this._backgroundScene = new RT.BoardBackgroundScene(this);
                return this._backgroundScene;
            };
            Board.prototype.set_background = function (color) {
                this.backgroundCamera = null;
                this.backgroundColor = color;
                this.backgroundPicture = null;
            };
            Board.prototype.set_background_camera = function (camera) {
                this.backgroundCamera = camera;
                this.backgroundColor = null;
                this.backgroundPicture = null;
            };
            Board.prototype.set_background_picture = function (picture, r) {
                this.backgroundCamera = null;
                this.backgroundColor = null;
                this.backgroundPicture = picture;
                picture.loadFirst(r, null);
            };
            Board.prototype.set_debug_mode = function (debug) {
                this._debugMode = debug;
            };
            Board.prototype.set_friction = function (friction) {
                this._worldFriction = friction;
            };
            Board.prototype.is_landscape = function () {
                return this._landscape;
            };
            Board.prototype.set_gravity = function (x, y) {
                this._gravity = new RT.Vector2(x, y);
            };
            Board.prototype.gravity = function () {
                return this._gravity;
            };
            Board.prototype.at = function (i) {
                return this.sprites[i];
            };
            Board.prototype.initialX = function () {
                return this.width() / 2;
            };
            Board.prototype.initialY = function () {
                return this.height() / 2;
            };
            Board.prototype.enableEveryFrameOnSprite = function (s) {
                var _this = this;
                if (this._everyFrameOnSprite)
                    return;
                this._everyFrameOnSprite = true;
                var handler = function (bot, prev) {
                    var q = _this._runtime.eventQ;
                    var args = [];
                    _this.sprites.forEach(function (s) {
                        if (s.onEveryFrame.pendinghandlers == 0)
                            q.addLocalEvent(s.onEveryFrame, args);
                    });
                    bot.entryAddr = prev;
                    return bot;
                };
                this.on_every_frame(handler, s);
            };
            Board.prototype.update_on_wall = function () {
                this.redrawBoardAndContents();
            };
            Board.prototype.orderedSprites = function () {
                if (!this._orderedSprites) {
                    this._orderedSprites = this.sprites.slice(0);
                    this._orderedSprites.stableSort(function (a, b) { return a.z_index() - b.z_index(); });
                }
                return this._orderedSprites;
            };
            Board.prototype.redrawBoardAndContents = function () {
                var _this = this;
                var isDebugMode = this._debugMode && (this._runtime && !this._runtime.currentScriptId);
                this.ctx.save();
                var scale = this.scaleFactor * TDev.SizeMgr.devicePixelRatio;
                this.ctx.scale(scale, scale);
                this.applyBackground();
                this.orderedSprites().forEach(function (s) { return s.redraw(_this.ctx, isDebugMode); });
                this.renderObstacles();
                if (isDebugMode) {
                    this.debugGrid();
                    this.debugSprings();
                    this.debugSegments();
                }
                this.ctx.restore();
            };
            Board.prototype.renderingContext = function () {
                return this.ctx;
            };
            Board.prototype.debugGrid = function () {
                this.ctx.save();
                this.ctx.beginPath();
                var w = this.width();
                var h = this.height();
                this.ctx.strokeStyle = "rgba(90, 90, 90, 0.7)";
                this.ctx.fillStyle = "rgba(90, 90, 90, 0.7)";
                this.ctx.lineWidth = 1;
                this.ctx.font = "12px sans-serif";
                for (var y = 0; y <= h; y += 100) {
                    this.ctx.moveTo(0, y);
                    this.ctx.lineTo(w, y);
                    if (y > 0 && y % 100 == 0)
                        this.ctx.fillText(y.toString(), 2, y - 5);
                    this.ctx.stroke();
                }
                for (var x = 0; x <= w; x += 100) {
                    this.ctx.moveTo(x, 0);
                    this.ctx.lineTo(x, h);
                    if (x > 0 && x % 100 == 0)
                        this.ctx.fillText(x.toString(), x - 15, 10);
                    this.ctx.stroke();
                }
                this.ctx.restore();
            };
            Board.prototype.debugSegments = function () {
                this.ctx.save();
                this.ctx.beginPath();
                for (var i = 0; i < this._minSegments.length; ++i) {
                    var seg = this._minSegments[i];
                    if (seg.overlap) {
                        this.ctx.fillStyle = "green";
                        this.ctx.strokeStyle = "green";
                    }
                    else {
                        this.ctx.fillStyle = "red";
                        this.ctx.strokeStyle = "red";
                    }
                    this.ctx.font = "20px sans-serif";
                    this.ctx.lineWidth = 4;
                    this.ctx.moveTo(seg.x(), seg.y());
                    this.ctx.lineTo(seg.x() + seg.z(), seg.y() + seg.w());
                    this.ctx.fillText(seg.from + "", seg.x() + seg.z(), seg.y() + seg.w());
                }
                this.ctx.stroke();
                this.ctx.restore();
                if (this._minSegments.length > 0) {
                    debugger;
                    this._minSegments = [];
                }
            };
            Board.prototype.debugSprings = function () {
                this.ctx.save();
                this.ctx.strokeStyle = "gray";
                this.ctx.beginPath();
                for (var i = 0; i < this._springs.length; i++) {
                    var o = this._springs[i];
                    this.ctx.moveTo(o.sprite1.x(), o.sprite1.y());
                    this.ctx.lineTo(o.sprite2.x(), o.sprite2.y());
                }
                this.ctx.stroke();
                this.ctx.restore();
            };
            Board.prototype.renderObstacles = function () {
                this.ctx.save();
                for (var i = 0; i < this._obstacles.length; i++) {
                    var o = this._obstacles[i];
                    if (!o.isValid())
                        continue;
                    this.ctx.beginPath();
                    this.ctx.lineWidth = o._thickness;
                    this.ctx.strokeStyle = o._color.toHtml();
                    this.ctx.moveTo(o.x, o.y);
                    this.ctx.lineTo(o.x + o.xextent, o.y + o.yextent);
                    this.ctx.stroke();
                }
                this.ctx.restore();
            };
            Board.prototype.mkSprite = function (tp, w, h) {
                var s = RT.Sprite.mk(tp, this.initialX(), this.initialY(), w, h);
                this.addSprite(s);
                return s;
            };
            Board.prototype.addSprite = function (s) {
                s._parent = this;
                s.set_z_index(0);
                this.sprites.push(s);
                s.changed();
                this.spritesChanged();
            };
            Board.prototype.create_ellipse = function (width, height) {
                return this.mkSprite(0 /* Ellipse */, width, height);
            };
            Board.prototype.create_rectangle = function (width, height) {
                return this.mkSprite(1 /* Rectangle */, width, height);
            };
            Board.prototype.create_text = function (width, height, fontSize, text) {
                var s = this.mkSprite(2 /* Text */, width, height);
                s.fontSize = fontSize;
                s.set_text(text);
                return s;
            };
            Board.prototype.create_picture = function (picture, r) {
                var s = this.mkSprite(3 /* Picture */, 1, 1);
                picture.loadFirst(r, function () {
                    s.setPictureInternal(picture);
                    return s;
                });
            };
            Board.prototype.create_sprite_sheet = function (picture, r) {
                var _this = this;
                picture.loadFirst(r, function () {
                    TDev.Util.log('board: new sprite sheet - ' + picture.widthSync() + 'x' + picture.heightSync());
                    var sheet = new RT.SpriteSheet(_this, picture);
                    return sheet;
                });
            };
            Board.prototype.create_anchor = function (width, height) {
                var anchor = this.mkSprite(4 /* Anchor */, width, height);
                anchor.set_friction(1);
                anchor.hide();
                return anchor;
            };
            Board.prototype.create_obstacle = function (x, y, width, height, elasticity) {
                if (width == 0 && height == 0)
                    return;
                var o = new Obstacle(this, x, y, width, height, elasticity, 1 - elasticity);
                this.addObstacle(o);
                return o;
            };
            Board.prototype.deleteObstacle = function (obstacle) {
                var idx = this._obstacles.indexOf(obstacle);
                if (idx > -1) {
                    this._obstacles.splice(idx, 1);
                    this._walls = this._walls.filter(function (wall) { return wall._obstacle != obstacle; });
                }
            };
            Board.prototype.create_spring = function (sprite1, sprite2, stiffness) {
                var spring = new RT.Spring(this, sprite1, sprite2, stiffness);
                this._springs.push(spring);
                sprite1.addSpring(spring);
                sprite2.addSpring(spring);
                return spring;
            };
            Board.prototype.deleteSpring = function (spring) {
                spring.sprite1.removeSpring(spring);
                spring.sprite2.removeSpring(spring);
                var idx = this._springs.indexOf(spring);
                if (idx > -1)
                    this._springs.splice(idx, 1);
            };
            Board.prototype.clear_events = function () {
            };
            Board.prototype.overlapWithAny = function (sprite, sprites) {
                var result = new RT.SpriteSet();
                for (var i = 0; i < sprites.count(); i++) {
                    var other = sprites.at(i);
                    if (sprite === other)
                        continue;
                    if (sprite.overlaps_with(other)) {
                        result.add(other);
                    }
                }
                return result;
            };
            Board.prototype.clear_background_camera = function () {
                this.backgroundCamera = null;
            };
            Board.prototype.clear_background_picture = function () {
                this.backgroundPicture = null;
            };
            Board.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
                if (this._full) {
                    if (this._landscape)
                        TDev.Runtime.lockOrientation(false, true, false);
                    else
                        TDev.Runtime.lockOrientation(true, false, false);
                }
            };
            return Board;
        })(RT.RTValue);
        RT.Board = Board;
        var Obstacle = (function (_super) {
            __extends(Obstacle, _super);
            function Obstacle(board, x, y, xextent, yextent, elasticity, friction) {
                _super.call(this);
                this.board = board;
                this.x = x;
                this.y = y;
                this.xextent = xextent;
                this.yextent = yextent;
                this.elasticity = elasticity;
                this.friction = friction;
                this._color = RT.Colors.gray();
                this._thickness = 3;
            }
            Obstacle.prototype.on_collision = function (bounce) {
                if (!this._onCollision)
                    this._onCollision = new RT.Event_();
                return this._onCollision.addHandler(bounce);
            };
            Obstacle.prototype.raiseCollision = function (rt, sprite) {
                if (this._onCollision && this._onCollision.handlers)
                    rt.queueLocalEvent(this._onCollision, [sprite], false);
            };
            Obstacle.prototype.set_color = function (color) {
                this._color = color;
            };
            Obstacle.prototype.set_thickness = function (thickness) {
                this._thickness = Math.max(1, thickness);
            };
            Obstacle.prototype.delete_ = function () {
                this.board.deleteObstacle(this);
            };
            Obstacle.prototype.isValid = function () {
                if (!this.IsFinite(this.x))
                    return false;
                if (!this.IsFinite(this.y))
                    return false;
                if (!this.IsFinite(this.xextent))
                    return false;
                if (!this.IsFinite(this.yextent))
                    return false;
                return true;
            };
            Obstacle.prototype.IsFinite = function (x) {
                if (isNaN(x))
                    return false;
                if (isFinite(x))
                    return true;
                return false;
            };
            return Obstacle;
        })(RT.RTValue);
        RT.Obstacle = Obstacle;
        var WallSegment = (function () {
            function WallSegment() {
            }
            WallSegment.mk = function (x, y, xextent, yextent, elasticity, friction, obstacle) {
                if (obstacle === void 0) { obstacle = undefined; }
                var w = new WallSegment();
                w._position = new RT.Vector2(x, y);
                var segment = new RT.Vector2(xextent, yextent);
                w._length = segment.length();
                w._unitExtent = segment.normalize();
                w._elasticity = elasticity;
                w._friction = friction;
                w._obstacle = obstacle;
                return w;
            };
            WallSegment.prototype.processPotentialCollision = function (sprite, dT) {
                var unitNormal = this._unitExtent.rotate90Left();
                var normalSpeedMag = -RT.Vector2.dot(unitNormal, sprite.stepDisplacement());
                if (normalSpeedMag <= 0) {
                    return false;
                }
                var pq = sprite._position.subtract(this._position);
                var distance = RT.Vector2.dot(pq, unitNormal);
                var normalRadius = sprite.radius(unitNormal);
                if (distance < normalRadius / 2) {
                    if (distance <= -normalRadius / 2) {
                        return false;
                    }
                    var unitRadius = sprite.radius(this._unitExtent);
                    var segmentProj = RT.Vector2.dot(sprite._position.subtract(this._position), this._unitExtent);
                    if (segmentProj < -unitRadius / 2 || segmentProj > this._length + unitRadius / 2) {
                        return false;
                    }
                    if (distance < 0) {
                        return false;
                    }
                    else {
                        sprite.newPosition = sprite._position.add(unitNormal.scale(normalRadius - distance));
                    }
                    normalSpeedMag = Math.abs(RT.Vector2.dot(unitNormal, sprite.midSpeed));
                    var normalSpeed = unitNormal.scale(normalSpeedMag);
                    var parallelSpeed = this._unitExtent.scale(RT.Vector2.dot(this._unitExtent, sprite.midSpeed));
                    sprite.midSpeed = sprite.newSpeed = (normalSpeed.scale(sprite._elasticity * this._elasticity).add(parallelSpeed.scale(1 - this._friction)));
                    sprite.normalTouchPoints.push(unitNormal);
                    return true;
                }
                var t = (distance - normalRadius) / normalSpeedMag;
                if (t > 1) {
                    return false;
                }
                var impactPos = sprite._position.add(sprite.stepDisplacement().scale(((t < 0) ? (t * 1.01) : (t * 0.99))));
                var unitRadius2 = sprite.radius(this._unitExtent);
                var segmentIndex = RT.Vector2.dot(impactPos.subtract(this._position), this._unitExtent);
                if (segmentIndex < -unitRadius2 / 2 || segmentIndex > this._length + unitRadius2 / 2) {
                    return false;
                }
                {
                    normalSpeedMag = Math.abs(RT.Vector2.dot(unitNormal, sprite.midSpeed));
                    var normalSpeed = unitNormal.scale(normalSpeedMag);
                    var stepParallelSpeed = this._unitExtent.scale(RT.Vector2.dot(this._unitExtent, sprite.stepDisplacement()));
                    sprite.newPosition = impactPos.add(stepParallelSpeed.scale(1 - t));
                    var parallelSpeed = this._unitExtent.scale(RT.Vector2.dot(this._unitExtent, sprite.newSpeed));
                    sprite.midSpeed = sprite.newSpeed = (normalSpeed.scale(sprite._elasticity * this._elasticity).add(parallelSpeed.scale(1 - this._friction)));
                    sprite.normalTouchPoints.push(unitNormal);
                    return true;
                }
            };
            return WallSegment;
        })();
        RT.WallSegment = WallSegment;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Boolean_;
        (function (Boolean_) {
            function equals(self, right) {
                return self === right;
            }
            Boolean_.equals = equals;
            function not(self) {
                return !self;
            }
            Boolean_.not = not;
            function and(self, right) {
                return self && right;
            }
            Boolean_.and = and;
            function or(self, right) {
                return self || right;
            }
            Boolean_.or = or;
            function to_string(self) {
                return self ? "true" : "false";
            }
            Boolean_.to_string = to_string;
            function to_number(self) {
                return self ? 1 : 0;
            }
            Boolean_.to_number = to_number;
            function post_to_wall(self, s) {
                s.rt.postBoxedText(to_string(self), s.pc);
            }
            Boolean_.post_to_wall = post_to_wall;
            function from_string(s) {
                return s === "true";
            }
            Boolean_.from_string = from_string;
            function picker() {
                var inp = TDev.HTML.mkCheckBox(TDev.lf("true?"));
                return {
                    html: inp,
                    validate: function () { return true; },
                    get: function () { return TDev.HTML.getCheckboxValue(inp); },
                    set: function (v) { return TDev.HTML.setCheckboxValue(inp, v); }
                };
            }
            Boolean_.picker = picker;
            function to_json(self) {
                return RT.JsonObject.wrap(self);
            }
            Boolean_.to_json = to_json;
        })(Boolean_ = RT.Boolean_ || (RT.Boolean_ = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Box;
        (function (Box) {
            var R = TDev.HTML;
            function push_box(s) {
                if (!TDev.LayoutMgr.RenderExecutionMode())
                    TDev.Util.userError(TDev.lf("boxes can only be created in page display code"));
                var parent = TDev.LayoutMgr.getCurrentRenderBox();
                TDev.Util.assert(parent != null);
                TDev.LayoutMgr.createOrRecycleContainerBoxDelayed(s.rt, parent);
            }
            Box.push_box = push_box;
            function pop_box(s) {
                TDev.Util.assert(TDev.LayoutMgr.RenderExecutionMode());
                var box = TDev.LayoutMgr.getCurrentRenderBox();
                var parent = box.parent;
                TDev.Util.assert(parent != null);
                TDev.LayoutMgr.setCurrentRenderBox(box.parent);
            }
            Box.pop_box = pop_box;
            function set_foreground(color, s) {
                var box = s.rt.getCurrentBox();
                box.setForeground(color.toHtml(), s.rt.getTopScriptPc());
            }
            Box.set_foreground = set_foreground;
            function set_background(color, s) {
                var box = s.rt.getCurrentBox();
                box.setBackground(color.toHtml(), s.rt.getTopScriptPc());
            }
            Box.set_background = set_background;
            function add_background_picture(pic, position, size, repeat, attachment, s) {
                var url = pic.getReadonlyUrlSync();
                function validate(str) {
                    var r = str.toLowerCase().trim();
                    if (!/^[a-z %0-9\-]*$/.test(r)) {
                        RT.App.log('invalid box background value: ' + r);
                        return '';
                    }
                    return r;
                }
                if (url) {
                    var box = s.rt.getCurrentBox();
                    box.addBackgroundImage({
                        url: url,
                        position: validate(position),
                        size: validate(size),
                        repeat: validate(repeat),
                        attachment: validate(attachment)
                    }, s.rt.getTopScriptPc());
                }
            }
            Box.add_background_picture = add_background_picture;
            function use_vertical_layout(s) {
                var box = s.rt.getCurrentBox();
                box.setFlow(TDev.WallBox.FLOW_VERTICAL, s.rt.getTopScriptPc());
            }
            Box.use_vertical_layout = use_vertical_layout;
            function use_horizontal_layout(s) {
                var box = s.rt.getCurrentBox();
                box.setFlow(TDev.WallBox.FLOW_HORIZONTAL, s.rt.getTopScriptPc());
            }
            Box.use_horizontal_layout = use_horizontal_layout;
            function use_overlay_layout(s) {
                var box = s.rt.getCurrentBox();
                box.setFlow(TDev.WallBox.FLOW_OVERLAY, s.rt.getTopScriptPc());
            }
            Box.use_overlay_layout = use_overlay_layout;
            function set_width(width, s) {
                var box = s.rt.getCurrentBox();
                box.setEmWidth(width, s.rt.getTopScriptPc());
            }
            Box.set_width = set_width;
            function set_height(height, s) {
                var box = s.rt.getCurrentBox();
                box.setEmHeight(height, s.rt.getTopScriptPc());
            }
            Box.set_height = set_height;
            function set_width_range(min_width, max_width, s) {
                var box = s.rt.getCurrentBox();
                box.setEmWidthRange(min_width, max_width, s.rt.getTopScriptPc());
            }
            Box.set_width_range = set_width_range;
            function set_height_range(min_height, max_height, s) {
                var box = s.rt.getCurrentBox();
                box.setEmHeightRange(min_height, max_height, s.rt.getTopScriptPc());
            }
            Box.set_height_range = set_height_range;
            function set_horizontal_stretch(elasticity, s) {
                var n = elasticity;
                var box = s.rt.getCurrentBox();
                if (n < 0 || n > 1) {
                    TDev.Util.userError(TDev.lf("invalid argument: elasticity must be a number between 0 and 1"));
                    n = 0;
                }
                box.setHorizontalStretch(n, s.rt.getTopScriptPc());
            }
            Box.set_horizontal_stretch = set_horizontal_stretch;
            function set_vertical_stretch(elasticity, s) {
                var n = elasticity;
                var box = s.rt.getCurrentBox();
                if (n < 0 || n > 1) {
                    TDev.Util.userError(TDev.lf("invalid argument: elasticity must be a number between 0 and 1"));
                    n = 0;
                }
                box.setVerticalStretch(n, s.rt.getTopScriptPc());
            }
            Box.set_vertical_stretch = set_vertical_stretch;
            function set_border(color, width, s) {
                var box = s.rt.getCurrentBox();
                box.setEmBorder(color.toHtml(), width, s.rt.getTopScriptPc());
            }
            Box.set_border = set_border;
            function set_border_widths(top, right, bottom, left, s) {
                var box = s.rt.getCurrentBox();
                box.setEmBorderWidth(top, right, bottom, left, s.rt.getTopScriptPc());
            }
            Box.set_border_widths = set_border_widths;
            function set_margins(top, right, bottom, left, s) {
                var box = s.rt.getCurrentBox();
                box.setAllEmMargins(top, right, bottom, left, s.rt.getTopScriptPc());
            }
            Box.set_margins = set_margins;
            function set_padding(top, right, bottom, left, s) {
                var box = s.rt.getCurrentBox();
                box.setEmPadding(top, right, bottom, left, s.rt.getTopScriptPc());
            }
            Box.set_padding = set_padding;
            function set_horizontal_alignment(left, right, s) {
                var box = s.rt.getCurrentBox();
                box.setHorizontalAlignment(left, right, s.rt.getTopScriptPc());
            }
            Box.set_horizontal_alignment = set_horizontal_alignment;
            function set_vertical_alignment(top, bottom, s) {
                var box = s.rt.getCurrentBox();
                box.setVerticalAlignment(top, bottom, s.rt.getTopScriptPc());
            }
            Box.set_vertical_alignment = set_vertical_alignment;
            function set_horizontal_align(arrange, s) {
                var box = s.rt.getCurrentBox();
                var a = TDev.WallBox.ARRANGE_LEFT;
                var what = arrange;
                if (what === "left")
                    a = TDev.WallBox.ARRANGE_LEFT;
                else if (what === "right")
                    a = TDev.WallBox.ARRANGE_RIGHT;
                else if (what === "center")
                    a = TDev.WallBox.ARRANGE_CENTER;
                else if (what === "justify")
                    a = TDev.WallBox.ARRANGE_JUSTIFY;
                else if (what === "spread")
                    a = TDev.WallBox.ARRANGE_SPREAD;
                else
                    TDev.Util.userError(TDev.lf("horizontal align must be one of {left, right, center, justify, spread}"));
                box.setHorizontalArrangement(a, s.rt.getTopScriptPc());
            }
            Box.set_horizontal_align = set_horizontal_align;
            function set_vertical_align(arrange, s) {
                var box = s.rt.getCurrentBox();
                var a = TDev.WallBox.ARRANGE_TOP;
                var what = arrange;
                if (what === "top")
                    a = TDev.WallBox.ARRANGE_TOP;
                else if (what === "bottom")
                    a = TDev.WallBox.ARRANGE_BOTTOM;
                else if (what === "center")
                    a = TDev.WallBox.ARRANGE_CENTER;
                else if (what === "justify")
                    a = TDev.WallBox.ARRANGE_JUSTIFY;
                else if (what === "baseline")
                    a = TDev.WallBox.ARRANGE_BASELINE;
                else if (what === "spread")
                    a = TDev.WallBox.ARRANGE_SPREAD;
                else
                    TDev.Util.userError(TDev.lf("vertical align must be one of {baseline, top, bottom, center, justify, spread}"));
                box.setVerticalArrangement(a, s.rt.getTopScriptPc());
            }
            Box.set_vertical_align = set_vertical_align;
            function set_font_size(font_size, s) {
                var box = s.rt.getCurrentBox();
                box.setEmFontSize(font_size, s.rt.getTopScriptPc());
            }
            Box.set_font_size = set_font_size;
            function set_font_weight(font_weight, s) {
                var box = s.rt.getCurrentBox();
                box.setFontWeight(font_weight, s.rt.getTopScriptPc());
            }
            Box.set_font_weight = set_font_weight;
            function set_font_family(family, s) {
                var box = s.rt.getCurrentBox();
                box.setFontFamily(family, s.rt.getTopScriptPc());
            }
            Box.set_font_family = set_font_family;
            function set_scrolling(horizontal_scrolling, vertical_scrolling, s) {
                var box = s.rt.getCurrentBox();
                box.setScrolling(horizontal_scrolling, vertical_scrolling, s.rt.getTopScriptPc());
            }
            Box.set_scrolling = set_scrolling;
            function on_tapped(handler, s) {
                var box = s.rt.getCurrentBox();
                box.attributes.tappedEvent.addHandler(handler);
            }
            Box.on_tapped = on_tapped;
            function on_text_editing(handler, s) {
                var box = s.rt.getCurrentBox();
                box.attributes.textEditingEvent.addHandler(handler);
            }
            Box.on_text_editing = on_text_editing;
            function on_text_edited(handler, s) {
                var box = s.rt.getCurrentBox();
                box.attributes.textEditedEvent.addHandler(handler);
            }
            Box.on_text_edited = on_text_edited;
            function edit_text(text, multiline, s) {
                s.rt.postEditableText(multiline ? "textarea" : "textline", text, null, s.rt.getTopScriptPc());
            }
            Box.edit_text = edit_text;
            function edit(style, value, changehandler, s) {
                s.rt.postEditableText(style, value, changehandler, s.rt.getTopScriptPc());
            }
            Box.edit = edit;
            function edit_ref(style, ref, s) {
                s.rt.postEditableText(style, ref._get(s), ref, s.rt.getTopScriptPc());
            }
            Box.edit_ref = edit_ref;
            function is_init(s) {
                return s.rt.getCurrentPage().renderCount == 0;
            }
            Box.is_init = is_init;
            function page_width(s) {
                return (s.rt.host.fullWallWidth() - TDev.LayoutMgr.instance.scrollbarWidth) / TDev.SizeMgr.topFontSize;
            }
            Box.page_width = page_width;
            function page_height(s) {
                return s.rt.host.userWallHeight() / TDev.SizeMgr.topFontSize;
            }
            Box.page_height = page_height;
            function pixels_per_em() {
                return TDev.SizeMgr.topFontSize;
            }
            Box.pixels_per_em = pixels_per_em;
            function set_text_wrapping(wrap, minimumwidth, s) {
                var box = s.rt.getCurrentBox();
                box.setWrap(wrap, minimumwidth, s.rt.getTopScriptPc());
            }
            Box.set_text_wrapping = set_text_wrapping;
        })(Box = RT.Box || (RT.Box = {}));
        var Dom;
        (function (Dom) {
            function use_css(stylesheet, s) {
                s.rt.forceNonRender(TDev.lf("cannot change css while displaying page"));
                s.rt.getCurrentPage().csslayout = true;
                s.rt.applyPageAttributes(true);
                if (stylesheet)
                    s.rt.host.importCss(stylesheet);
            }
            Dom.use_css = use_css;
            function set_tag_name(name, s) {
                if (!name)
                    return;
                if (!TDev.HTML.allowedTagName(name))
                    TDev.Util.userError(TDev.lf("tag not allowed"), s.pc);
                TDev.LayoutMgr.setHtmlTagName(name);
            }
            Dom.set_tag_name = set_tag_name;
            function add_css_class(name, s) {
                if (!name)
                    return;
                var box = s.rt.getCurrentHtmlBox();
                box.addClassName(name, s.rt.getTopScriptPc());
            }
            Dom.add_css_class = add_css_class;
            function set_attribute(name, value, s) {
                if (!name)
                    return;
                if (!TDev.HTML.allowedAttribute(name, value))
                    TDev.Util.userError(TDev.lf("attribute not allowed"), s.pc);
                var box = s.rt.getCurrentHtmlBox();
                box.setAttribute(name, value, s.rt.getTopScriptPc());
            }
            Dom.set_attribute = set_attribute;
            function set_style(property, value, s) {
                if (!property)
                    return;
                var box = s.rt.getCurrentHtmlBox();
                box.setStyle(property, value, s.rt.getTopScriptPc());
            }
            Dom.set_style = set_style;
            function bind_value_with_handler(value, changehandler, s) {
                var box = s.rt.getCurrentHtmlBox();
                box.bindEditableText(value, changehandler, s.rt.getTopScriptPc());
            }
            Dom.bind_value_with_handler = bind_value_with_handler;
            function bind_value_to_ref(ref, s) {
                var box = s.rt.getCurrentHtmlBox();
                box.bindEditableText(ref._get(s), ref, s.rt.getTopScriptPc());
            }
            Dom.bind_value_to_ref = bind_value_to_ref;
            function add_on_click(body, s) {
                var box = s.rt.getCurrentHtmlBox();
                box.attributes.tappedEvent.addHandler(body);
            }
            Dom.add_on_click = add_on_click;
        })(Dom = RT.Dom || (RT.Dom = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var BoxFlow = (function (_super) {
            __extends(BoxFlow, _super);
            function BoxFlow() {
                _super.call(this);
            }
            BoxFlow.mk = function (flow) {
                var boxFlow = new BoxFlow();
                boxFlow._flow = flow;
                return boxFlow;
            };
            BoxFlow.prototype.flow = function () {
                return this._flow;
            };
            BoxFlow.prototype.equals = function (other) {
                return this._flow === other._flow;
            };
            return BoxFlow;
        })(RT.RTValue);
        RT.BoxFlow = BoxFlow;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var BoxFlows;
        (function (BoxFlows) {
            var _right = RT.BoxFlow.mk("right");
            var _left = RT.BoxFlow.mk("left");
            var _up = RT.BoxFlow.mk("up");
            var _down = RT.BoxFlow.mk("down");
            function right() {
                return _right;
            }
            BoxFlows.right = right;
            function left() {
                return _left;
            }
            BoxFlows.left = left;
            function up() {
                return _up;
            }
            BoxFlows.up = up;
            function down() {
                return _down;
            }
            BoxFlows.down = down;
        })(BoxFlows = RT.BoxFlows || (RT.BoxFlows = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Camera = (function (_super) {
            __extends(Camera, _super);
            function Camera() {
                _super.call(this);
                this._isFront = false;
                this._deviceId = undefined;
                this._videoUrl = undefined;
                this._video = undefined;
            }
            Camera.prototype.set_is_front = function (isFront) {
                this._isFront = isFront;
            };
            Camera.prototype.device_id = function () {
                return this._deviceId;
            };
            Camera.prototype.set_device_id = function (deviceId) {
                this._deviceId = deviceId;
            };
            Camera.prototype.height = function () {
                return undefined;
            };
            Camera.prototype.is_front = function () {
                return this._isFront;
            };
            Camera.prototype.width = function () {
                return undefined;
            };
            Camera.prototype.getVideoAsync = function (r) {
                var _this = this;
                return this.askCameraAccessAsync(r).then(function (allow) {
                    if (!allow)
                        return TDev.Promise.as(undefined);
                    else
                        return new TDev.Promise(function (onSuccess, onError, onProcess) {
                            if (_this._videoUrl) {
                                var v = TDev.createElement('video');
                                v.src = _this._videoUrl;
                                v.controls = false;
                                v.autoplay = true;
                                onSuccess(v);
                            }
                            else {
                                RT.UserMediaManager.getCameraUrlAsync(_this._isFront, _this._deviceId).then(function (url) {
                                    if (url) {
                                        _this._videoUrl = url;
                                        var v = TDev.createElement('video');
                                        v.src = _this._videoUrl;
                                        v.controls = false;
                                        v.autoplay = true;
                                        onSuccess(v);
                                    }
                                    else {
                                        onSuccess(undefined);
                                    }
                                }).done();
                            }
                        });
                });
            };
            Camera.prototype.askCameraAccessAsync = function (r) {
                return r.host.askSourceAccessAsync("camera", "your camera.", false);
            };
            Camera.prototype.post_to_wall = function (s) {
                var _this = this;
                this.getVideoAsync(s.rt).done(function (v) {
                    _this._video = v;
                    if (_this._video) {
                        _this._video.controls = true;
                        s.rt.postBoxedHtml(_this._video, s.pc);
                    }
                });
            };
            Camera.prototype.previewVideo = function (v, r) {
                var picurl = RT.UserMediaManager.previewVideo(v);
                RT.Picture.fromUrl(picurl).then(function (p) {
                    r.resumeVal(p);
                });
            };
            Camera.prototype.preview = function (r) {
                var _this = this;
                if (this._video) {
                    this.previewVideo(this._video, r);
                }
                else {
                    this.getVideoAsync(r.rt).then(function (v) {
                        if (!v) {
                            r.resumeVal(undefined);
                        }
                        else {
                            _this._video = v;
                            _this._video.controls = true;
                            r.rt.postBoxedHtml(_this._video, r.rt.current.pc);
                            TDev.Util.setTimeout(5 * 1000, function () {
                                _this.previewVideo(_this._video, r);
                            });
                        }
                    }).done();
                }
            };
            return Camera;
        })(RT.RTValue);
        RT.Camera = Camera;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Collections;
        (function (Collections) {
            function create_user_collection() {
                return new RT.Collection(RT.User);
            }
            Collections.create_user_collection = create_user_collection;
            function create_date_time_collection() {
                return new RT.Collection(RT.DateTime);
            }
            Collections.create_date_time_collection = create_date_time_collection;
            function create_picture_collection() {
                return new RT.Collection(RT.Picture);
            }
            Collections.create_picture_collection = create_picture_collection;
            function create_sound_collection() {
                return new RT.Collection(RT.Sound);
            }
            Collections.create_sound_collection = create_sound_collection;
            function create_action_collection() {
                return new RT.Collection(RT.Action);
            }
            Collections.create_action_collection = create_action_collection;
            function create_string_collection() {
                return new RT.Collection("string");
            }
            Collections.create_string_collection = create_string_collection;
            function create_place_collection() {
                return new RT.Collection(RT.Place);
            }
            Collections.create_place_collection = create_place_collection;
            function create_link_collection() {
                return new RT.Collection(RT.Link);
            }
            Collections.create_link_collection = create_link_collection;
            function create_message_collection() {
                return new RT.Collection(RT.Message);
            }
            Collections.create_message_collection = create_message_collection;
            function create_location_collection() {
                return new RT.Collection(RT.Location_);
            }
            Collections.create_location_collection = create_location_collection;
            function create_number_map() {
                return new RT.NumberMap();
            }
            Collections.create_number_map = create_number_map;
            function create_string_map() {
                return new RT.StringMap();
            }
            Collections.create_string_map = create_string_map;
            function create_number_collection() {
                return new RT.Collection("number");
            }
            Collections.create_number_collection = create_number_collection;
        })(Collections = RT.Collections || (RT.Collections = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Color = (function (_super) {
            __extends(Color, _super);
            function Color() {
                _super.call(this);
            }
            Color.fromArtUrl = function (url) {
                return TDev.Promise.wrap(Color.fromHtml(url));
            };
            Color.fromArgb = function (a, r, g, b) {
                var c = new Color();
                c.a = a;
                c.r = r;
                c.g = g;
                c.b = b;
                return c;
            };
            Color.capByte = function (n) {
                var c = Math.floor(n);
                if (c < 0)
                    return 0;
                else if (c > 255)
                    return 255;
                return c;
            };
            Color.normalizeToByte = function (n) {
                if (n < 0)
                    n = 0;
                else if (n > 1)
                    n = 1;
                return Math.floor(n * 255 + 0.499999);
            };
            Color.fromArgbF = function (a, r, g, b) {
                var c = new Color();
                c.a = Color.normalizeToByte(a);
                c.r = Color.normalizeToByte(r);
                c.g = Color.normalizeToByte(g);
                c.b = Color.normalizeToByte(b);
                return c;
            };
            Color.fromHtml = function (c) {
                if (c[0] == "#")
                    c = c.substr(1);
                var n = parseInt(c, 16);
                var r = new Color();
                if (c.length == 3 || c.length == 4) {
                    r.b = (n & 0xf) * 0x11;
                    r.g = ((n >> 4) & 0xf) * 0x11;
                    r.r = ((n >> 8) & 0xf) * 0x11;
                    r.a = ((n >> 12) & 0xf) * 0x11;
                }
                else if (c.length == 6 || c.length == 8) {
                    r.b = (n & 0xff);
                    r.g = ((n >> 8) & 0xff);
                    r.r = ((n >> 16) & 0xff);
                    r.a = ((n >> 24) & 0xff);
                }
                if (c.length == 3 || c.length == 6)
                    r.a = 255;
                return r;
            };
            Color.fromInt32 = function (n) {
                n = Math.round(n);
                var r = new Color();
                r.b = (n & 0xff);
                r.g = ((n >> 8) & 0xff);
                r.r = ((n >> 16) & 0xff);
                r.a = ((n >> 24) & 0xff);
                return r;
            };
            Color.prototype.A = function () {
                return this.a / 255.0;
            };
            Color.prototype.R = function () {
                return this.r / 255.0;
            };
            Color.prototype.G = function () {
                return this.g / 255.0;
            };
            Color.prototype.B = function () {
                return this.b / 255.0;
            };
            Color.prototype.equals = function (other) {
                return this.r == other.r && this.g == other.g && this.b == other.b && this.a == other.a;
            };
            Color.prototype.blend = function (other) {
                var caAlpha = other.A();
                var cbAlpha = this.A() * (1 - caAlpha);
                return Color.fromArgbF(caAlpha + cbAlpha, other.R() * caAlpha + this.R() * cbAlpha, other.G() * caAlpha + this.G() * cbAlpha, other.B() * caAlpha + this.B() * cbAlpha);
            };
            Color.prototype.make_transparent = function (alpha) {
                if (alpha == 1 && this.a == 255)
                    return this;
                var a = Color.normalizeToByte(alpha);
                if (a == this.a)
                    return this;
                return Color.fromArgb(a, this.r, this.g, this.b);
            };
            Color.prototype.darken = function (delta) {
                return Color.fromArgbF(this.A(), this.R() - delta, this.G() - delta, this.B() - delta);
            };
            Color.prototype.lighten = function (delta) {
                return Color.fromArgbF(this.A(), this.R() + delta, this.G() + delta, this.B() + delta);
            };
            Color.prototype.toInt32 = function () {
                return ((this.a << 24) | (this.r << 16) | (this.g << 8) | this.b) >>> 0;
            };
            Color.prototype.toJsonKey = function () {
                return this.toInt32();
            };
            Color.prototype.keyCompareTo = function (other) {
                var o = other;
                var diff = this.r - o.r;
                if (diff)
                    return diff;
                diff = this.b - o.b;
                if (diff)
                    return diff;
                diff = this.g - o.g;
                if (diff)
                    return diff;
                diff = this.a - o.a;
                return diff;
            };
            Color.prototype.toString = function () {
                var h = this.toInt32().toString(16);
                return "#" + "00000000".substr(0, 8 - h.length) + h;
            };
            Color.prototype.getViewCore = function (s, b) {
                var d = TDev.div("item");
                d.style.backgroundColor = this.toHtml();
                var t = TDev.div("item-subtitle", TDev.Util.fmt('alpha:{0:f1.3}, red:{1:f1.3}, green:{2:f1.3}, blue:{3:f1.3}', this.A(), this.R(), this.G(), this.B()));
                t.style.textAlign = 'center';
                t.style.color = ((this.r + this.g + this.b) * this.A()) > 300 ? 'black' : 'white';
                d.appendChild(t);
                return d;
            };
            Color.prototype.toHtml = function () {
                if (this.htmlCache)
                    return this.htmlCache;
                if (this.a == 0xff) {
                    var h = (this.toInt32() & 0xffffff).toString(16);
                    this.htmlCache = "#" + "000000".substr(0, 6 - h.length) + h;
                }
                else
                    this.htmlCache = TDev.Util.fmt("rgba({0}, {1}, {2}, {3})", this.r, this.g, this.b, RT.Math_.round_with_precision(this.a / 0xff, 6));
                return this.htmlCache;
            };
            Color.prototype.getShortStringRepresentation = function () {
                return this.toHtml();
            };
            Color.prototype.exportJson = function (ctx) {
                return this.toHtml();
            };
            Color.prototype.importJson = function (ctx, json) {
                TDev.Util.oops("should not call immutable instance for importing");
                return undefined;
            };
            Color.mkFromJson = function (ctx, json) {
                if (typeof (json) === "string") {
                    var c = Color.fromHtml(json);
                    return c;
                }
                else {
                    return undefined;
                }
            };
            Color.prototype.debuggerDisplay = function (clickHandler) {
                var tempSpan;
                tempSpan = TDev.span(null, "R: " + this.r + " G: " + this.g + " B: " + this.b).withClick(clickHandler);
                var s;
                for (s = (this.toInt32() & 0xffffff).toString(16); s.length < 6; s = "0" + s) {
                }
                tempSpan.style.backgroundColor = "#" + s;
                if ((this.r + this.g + this.b) / 3 < 100) {
                    tempSpan.style.color = "white";
                }
                return tempSpan;
            };
            Color.prototype.to_html = function () {
                return this.toHtml();
            };
            Color.prototype.hue = function () {
                return this.toHsb().x() / 255;
            };
            Color.prototype.saturation = function () {
                return this.toHsb().y() / 255;
            };
            Color.prototype.brightness = function () {
                return this.toHsb().z() / 255;
            };
            Color.prototype.toHsb = function () {
                var max = Math.max(this.r, Math.max(this.g, this.b));
                if (max <= 0)
                    return RT.Vector3.mk(0, 0, 0);
                var min = Math.min(this.r, Math.min(this.g, this.b));
                var dif = max - min;
                var hue = 0;
                if (max > min) {
                    if (this.g === max) {
                        hue = (this.b - this.r) / dif * 60 + 120;
                    }
                    else if (this.b === max) {
                        hue = (this.r - this.g) / dif * 60 + 240;
                    }
                    else if (this.b > this.g) {
                        hue = (this.g - this.b) / dif * 60 + 360;
                    }
                    else {
                        hue = (this.g - this.b) / dif * 60;
                    }
                    if (hue < 0) {
                        hue = hue + 360;
                    }
                }
                else {
                    hue = 0;
                }
                hue *= 255 / 360;
                var saturation = (dif / max) * 255;
                var brightness = max;
                return RT.Vector3.mk(hue, saturation, brightness);
            };
            Color.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Color;
        })(RT.RTValue);
        RT.Color = Color;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Colors;
        (function (Colors) {
            function accent() {
                return RT.Color.fromHtml("#3BA818");
            }
            Colors.accent = accent;
            function subtle() {
                return light_gray();
            }
            Colors.subtle = subtle;
            function chrome() {
                return RT.Color.fromHtml("#FFDDDDDD");
            }
            Colors.chrome = chrome;
            function foreground(s) {
                var p = s && s.rt.getCurrentPage();
                return p ? RT.Color.fromHtml(p.fgColor) : foreground_os();
            }
            Colors.foreground = foreground;
            function background(s) {
                var p = s && s.rt.getCurrentPage();
                return p ? RT.Color.fromHtml(p.bgColor) : background_os();
            }
            Colors.background = background;
            function foreground_os() {
                return black();
            }
            Colors.foreground_os = foreground_os;
            function background_os() {
                return white();
            }
            Colors.background_os = background_os;
            function is_light_theme(s) {
                return background(s).r > 128;
            }
            Colors.is_light_theme = is_light_theme;
            function from_rgb(red, green, blue) {
                return RT.Color.fromArgbF(1, red, green, blue);
            }
            Colors.from_rgb = from_rgb;
            function from_argb(alpha, red, green, blue) {
                return RT.Color.fromArgbF(alpha, red, green, blue);
            }
            Colors.from_argb = from_argb;
            function pink() {
                return RT.Color.fromHtml("#FFFFCBDB");
            }
            Colors.pink = pink;
            function black() {
                return RT.Color.fromHtml("#FF000000");
            }
            Colors.black = black;
            function blue() {
                return RT.Color.fromHtml("#FF0000FF");
            }
            Colors.blue = blue;
            function brown() {
                return RT.Color.fromHtml("#FFA52A2A");
            }
            Colors.brown = brown;
            function cyan() {
                return RT.Color.fromHtml("#FF00FFFF");
            }
            Colors.cyan = cyan;
            function dark_gray() {
                return RT.Color.fromHtml("#FFA9A9A9");
            }
            Colors.dark_gray = dark_gray;
            function gray() {
                return RT.Color.fromHtml("#FF808080");
            }
            Colors.gray = gray;
            function green() {
                return RT.Color.fromHtml("#FF00FF00");
            }
            Colors.green = green;
            function light_gray() {
                return RT.Color.fromHtml("#FFD3D3D3");
            }
            Colors.light_gray = light_gray;
            function magenta() {
                return RT.Color.fromHtml("#FFFF00FF");
            }
            Colors.magenta = magenta;
            function orange() {
                return RT.Color.fromHtml("#FFFFA500");
            }
            Colors.orange = orange;
            function purple() {
                return RT.Color.fromHtml("#FF800080");
            }
            Colors.purple = purple;
            function red() {
                return RT.Color.fromHtml("#FFFF0000");
            }
            Colors.red = red;
            function transparent() {
                return RT.Color.fromHtml("#00FFFFFF");
            }
            Colors.transparent = transparent;
            function white() {
                return RT.Color.fromHtml("#FFFFFFFF");
            }
            Colors.white = white;
            function yellow() {
                return RT.Color.fromHtml("#FFFFFF00");
            }
            Colors.yellow = yellow;
            function sepia() {
                return RT.Color.fromHtml("#FF704214");
            }
            Colors.sepia = sepia;
            function linear_gradient(c1, c2, alpha) {
                var r1 = RT.RTValue.normalize(alpha);
                var r2 = 1 - r1;
                return RT.Color.fromArgbF(c1.A() * r1 + c2.A() * r2, c1.R() * r1 + c2.R() * r2, c1.G() * r1 + c2.G() * r2, c1.B() * r1 + c2.B() * r2);
            }
            Colors.linear_gradient = linear_gradient;
            function rand() {
                return random();
            }
            Colors.rand = rand;
            function random() {
                return RT.Color.fromArgbF(1.0, TDev.Random.normalized(), TDev.Random.normalized(), TDev.Random.normalized());
            }
            Colors.random = random;
            function wheel(hue) {
                return Colors.from_hsb(hue, 1, 1);
            }
            Colors.wheel = wheel;
            function from_hsb(hue, saturation, brightness) {
                return from_ahsb(1.0, hue, saturation, brightness);
            }
            Colors.from_hsb = from_hsb;
            function from_ahsb(alpha, hue, saturation, brightness) {
                return from_ahsbByte(RT.Color.normalizeToByte(alpha), RT.Color.normalizeToByte(hue), RT.Color.normalizeToByte(saturation), RT.Color.normalizeToByte(brightness));
            }
            Colors.from_ahsb = from_ahsb;
            function from_ahsbByte(alpha, hue, saturation, brightness) {
                var r = brightness;
                var g = brightness;
                var b = brightness;
                if (saturation !== 0) {
                    var max = brightness;
                    var dif = brightness * saturation / 255;
                    var min = brightness - dif;
                    var h = hue * 360 / 255;
                    if (h < 60) {
                        r = max;
                        g = h * dif / 60 + min;
                        b = min;
                    }
                    else if (h < 120) {
                        r = -(h - 120) * dif / 60 + min;
                        g = max;
                        b = min;
                    }
                    else if (h < 180) {
                        r = min;
                        g = max;
                        b = (h - 120) * dif / 60 + min;
                    }
                    else if (h < 240) {
                        r = min;
                        g = -(h - 240) * dif / 60 + min;
                        b = max;
                    }
                    else if (h < 300) {
                        r = (h - 240) * dif / 60 + min;
                        g = min;
                        b = max;
                    }
                    else if (h <= 360) {
                        r = max;
                        g = min;
                        b = -(h - 360) * dif / 60 + min;
                    }
                    else {
                        r = 0;
                        g = 0;
                        b = 0;
                    }
                }
                return RT.Color.fromArgb(alpha, RT.Color.capByte(r), RT.Color.capByte(g), RT.Color.capByte(b));
            }
            Colors.from_ahsbByte = from_ahsbByte;
        })(Colors = RT.Colors || (RT.Colors = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Contact = (function (_super) {
            __extends(Contact, _super);
            function Contact() {
                _super.call(this);
                this._id = undefined;
                this._first_name = undefined;
                this._last_name = undefined;
                this._nick_name = undefined;
                this._middle_name = undefined;
                this._title = undefined;
                this._suffix = undefined;
                this._company = undefined;
                this._job_title = undefined;
                this._office = undefined;
                this._work_address = undefined;
                this._home_address = undefined;
                this._source = undefined;
                this._birthday = undefined;
                this._pictureUrl = undefined;
                this._picture = undefined;
                this._email = undefined;
                this._work_email = undefined;
                this._personal_email = undefined;
                this._phone_number = undefined;
                this._home_phone = undefined;
                this._work_phone = undefined;
                this._mobile_phone = undefined;
                this._web_site = undefined;
            }
            Contact.mkFake = function (firstName, middleName, lastName, email, phoneNumber, pictureUrl) {
                var c = new Contact();
                c._first_name = firstName;
                c._middle_name = middleName;
                c._last_name = lastName;
                c._email = email;
                c._phone_number = phoneNumber;
                c._pictureUrl = TDev.Cloud.getServiceUrl() + '/doc/contacts/' + encodeURIComponent(pictureUrl);
                c._source = "AdventureWorks";
                return c;
            };
            Contact.prototype.clone = function () {
                var c = new Contact();
                c._id = this._id;
                c._first_name = this._first_name;
                c._last_name = this._last_name;
                c._nick_name = this._nick_name;
                c._middle_name = this._middle_name;
                c._title = this._title;
                c._suffix = this._suffix;
                c._company = this._company;
                c._job_title = this._job_title;
                c._office = this._office;
                c._work_address = this._work_address;
                c._home_address = this._home_address;
                c._source = this._source;
                c._birthday = this._birthday;
                c._pictureUrl = this._pictureUrl;
                c._picture = this._picture;
                c._email = this._email;
                c._work_email = this._work_email;
                c._personal_email = this._personal_email;
                c._phone_number = this._phone_number;
                c._home_phone = this._home_phone;
                c._work_phone = this._work_phone;
                c._mobile_phone = this._mobile_phone;
                c._web_site = this._web_site;
                return c;
            };
            Contact.mk = function (nickname, email) {
                if (email === void 0) { email = null; }
                var c = new Contact();
                c._nick_name = nickname;
                c._email = email;
                return c;
            };
            Contact.prototype.toString = function () {
                return this.name();
            };
            Contact.prototype.toFullString = function () {
                var r = this.name();
                if (this._title != null)
                    r += '\ntitle: ' + this._title;
                if (this._company != null)
                    r += '\ncompany: ' + this._company;
                if (this._job_title != null)
                    r += '\njob title: ' + this._job_title;
                if (this._office != null)
                    r += '\noffice: ' + this._office;
                if (this._work_address != null)
                    r += '\nwork address: ' + this._work_address;
                if (this._home_address != null)
                    r += '\nhome address: ' + this._home_address;
                if (this._birthday != null)
                    r += '\nbirthday: ' + this._birthday;
                if (this._email != null)
                    r += '\nemail: ' + this._email;
                if (this._work_email != null)
                    r += '\nwork email: ' + this._work_email;
                if (this._personal_email != null)
                    r += '\npersonal email: ' + this._personal_email;
                if (this._phone_number != null)
                    r += '\nphone number: ' + this._phone_number;
                if (this._home_phone != null)
                    r += '\nhome phone: ' + this._home_phone;
                if (this._work_phone != null)
                    r += '\nwork phone: ' + this._work_phone;
                if (this._mobile_phone != null)
                    r += '\nmobile phone: ' + this._mobile_phone;
                if (this._web_site != null)
                    r += '\nweb site: ' + this._web_site;
                return r;
            };
            Contact.prototype.id = function () {
                return this._id;
            };
            Contact.prototype.set_id = function (id) {
                this._id = id;
            };
            Contact.prototype.name = function () {
                if (this._nick_name)
                    return this._nick_name;
                else
                    return [this._first_name, this._middle_name, this._last_name].filter(function (s) { return !!s; }).join(" ");
            };
            Contact.prototype.first_name = function () {
                return this._first_name || '';
            };
            Contact.prototype.set_first_name = function (first_name) {
                this._first_name = first_name;
            };
            Contact.prototype.last_name = function () {
                return this._last_name;
            };
            Contact.prototype.set_last_name = function (last_name) {
                this._last_name = last_name;
            };
            Contact.prototype.nick_name = function () {
                return this._nick_name;
            };
            Contact.prototype.set_nick_name = function (nick_name) {
                this._nick_name = nick_name;
            };
            Contact.prototype.middle_name = function () {
                return this._middle_name;
            };
            Contact.prototype.set_middle_name = function (middle_name) {
                this._middle_name = middle_name;
            };
            Contact.prototype.title = function () {
                return this._title;
            };
            Contact.prototype.set_title = function (title) {
                this._title = title;
            };
            Contact.prototype.suffix = function () {
                return this._suffix;
            };
            Contact.prototype.set_suffix = function (suffix) {
                this._suffix = suffix;
            };
            Contact.prototype.company = function () {
                return this._company;
            };
            Contact.prototype.set_company = function (company) {
                this._company = company;
            };
            Contact.prototype.job_title = function () {
                return this._title;
            };
            Contact.prototype.set_job_title = function (job_title) {
                this._job_title = job_title;
            };
            Contact.prototype.office = function () {
                return this._office;
            };
            Contact.prototype.set_office = function (office) {
                this._office = office;
            };
            Contact.prototype.work_address = function () {
                return this._work_address;
            };
            Contact.prototype.set_work_address = function (work_address) {
                this._work_address = work_address;
            };
            Contact.prototype.home_address = function () {
                return this._home_address;
            };
            Contact.prototype.set_home_address = function (home_address) {
                this._home_address = home_address;
            };
            Contact.prototype.source = function () {
                return this._source;
            };
            Contact.prototype.set_source = function (source) {
                this._source = source;
            };
            Contact.prototype.birthday = function () {
                return this._birthday;
            };
            Contact.prototype.set_birthday = function (birthday) {
                this._birthday = birthday;
            };
            Contact.prototype.picture = function (r) {
                var _this = this;
                if (!this._picture && this._pictureUrl) {
                    RT.Picture.fromUrl(this._pictureUrl, true).then(function (pic) {
                        _this._picture = pic;
                        r.resumeVal(pic);
                    }).done();
                }
                r.resumeVal(this._picture);
            };
            Contact.prototype.set_picture = function (picture) {
                this._pictureUrl = undefined;
                this._picture = picture;
            };
            Contact.prototype.setPicture_url = function (url) {
                this._pictureUrl = url;
                this._picture = null;
            };
            Contact.prototype.getViewCore = function (s, b) {
                var d = TDev.div("item");
                if (this._picture)
                    d.appendChild(TDev.div("item-image contact-image", this._picture.getViewCore(s, b)));
                else if (this._pictureUrl) {
                    var img = TDev.HTML.mkImg(this._pictureUrl);
                    img.className = "item-image contact-image";
                    d.appendChild(img);
                }
                var dc = TDev.div("item-info");
                d.appendChild(dc);
                var n = this.name();
                if (n)
                    dc.appendChild(TDev.div("item-title", n));
                var t = this.title() || this._email || this._work_email || this._personal_email;
                if (t)
                    dc.appendChild(TDev.div("item-subtitle", t));
                if (this.company() || this.job_title())
                    dc.appendChild(TDev.div("item-description", this.job_title() + ' ' + this.company()));
                var ss = this.source();
                if (ss)
                    dc.appendChild(TDev.div("item-subtle", ss));
                return d;
            };
            Contact.prototype.email = function () {
                return this._email ? RT.Link.mk(this._email, 3 /* email */) : undefined;
            };
            Contact.prototype.set_email = function (email) {
                this._email = email;
            };
            Contact.prototype.work_email = function () {
                return this._work_email ? RT.Link.mk(this._work_email, 3 /* email */) : undefined;
            };
            Contact.prototype.set_work_email = function (work_email) {
                this._work_email = work_email;
            };
            Contact.prototype.personal_email = function () {
                return this._personal_email ? RT.Link.mk(this._personal_email, 3 /* email */) : undefined;
            };
            Contact.prototype.set_personal_email = function (personal_email) {
                this._personal_email = personal_email;
            };
            Contact.prototype.phone_number = function () {
                return this._phone_number ? RT.Link.mk(this._phone_number, 4 /* phoneNumber */) : undefined;
            };
            Contact.prototype.set_phone_number = function (phone_number) {
                this._phone_number = phone_number;
            };
            Contact.prototype.home_phone = function () {
                return this._home_phone ? RT.Link.mk(this._home_phone, 4 /* phoneNumber */) : undefined;
            };
            Contact.prototype.set_home_phone = function (home_phone) {
                this._home_phone = home_phone;
            };
            Contact.prototype.work_phone = function () {
                return this._work_phone ? RT.Link.mk(this._work_phone, 4 /* phoneNumber */) : undefined;
            };
            Contact.prototype.set_work_phone = function (work_phone) {
                this._work_phone = work_phone;
            };
            Contact.prototype.mobile_phone = function () {
                return this._mobile_phone ? RT.Link.mk(this._mobile_phone, 4 /* phoneNumber */) : undefined;
            };
            Contact.prototype.set_mobile_phone = function (mobile_phone) {
                this._mobile_phone = mobile_phone;
            };
            Contact.prototype.web_site = function () {
                return this._web_site ? RT.Link.mk(this._web_site, 5 /* hyperlink */) : undefined;
            };
            Contact.prototype.set_web_site = function (web_site) {
                this._web_site = web_site;
            };
            Contact.prototype.set_nickname = function (value) {
                this.set_nickname(value);
            };
            Contact.prototype.set_website = function (value) {
                this.set_web_site(value);
            };
            Contact.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Contact;
        })(RT.RTValue);
        RT.Contact = Contact;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var DateTime = (function (_super) {
            __extends(DateTime, _super);
            function DateTime() {
                _super.call(this);
            }
            DateTime.mkFull = function (year, month, day, hour, minute, second) {
                var r = new DateTime();
                r.d = new Date(year, month - 1, day, hour, minute, Math.floor(second));
                var rem = second - Math.floor(second);
                if (rem) {
                    r.d = new Date(r.d.getTime() + rem * 1000);
                }
                return r;
            };
            DateTime.mkMs = function (ms) {
                var r = new DateTime();
                r.d = new Date(ms);
                return r;
            };
            DateTime.mk = function (d) {
                var r = new DateTime();
                r.d = new Date(d.getTime());
                return r;
            };
            DateTime.parse = function (s) {
                if (!s)
                    return undefined;
                var d = Date.parse(s);
                if (!d)
                    return undefined;
                return DateTime.mkMs(d);
            };
            DateTime.prototype.isSerializable = function () {
                return true;
            };
            DateTime.prototype.toJsonKey = function () {
                return this.d.getTime();
            };
            DateTime.prototype.to_json = function () {
                return RT.JsonObject.wrap(this.d.getTime());
            };
            DateTime.prototype.keyCompareTo = function (o) {
                var other = o;
                return this.d.getTime() - other.d.getTime();
            };
            DateTime.prototype.isDefaultValue = function () {
                return this.equals(DateTime.defaultValue);
            };
            DateTime.prototype.add_days = function (days) {
                return this.add_seconds(days * 24 * 3600);
            };
            DateTime.prototype.add_hours = function (hours) {
                return this.add_seconds(hours * 3600);
            };
            DateTime.prototype.add_minutes = function (minutes) {
                return this.add_seconds(minutes * 60);
            };
            DateTime.prototype.add_seconds = function (seconds) {
                return DateTime.mkMs(this.d.getTime() + seconds * 1000);
            };
            DateTime.prototype.add_milliseconds = function (milliseconds) {
                return DateTime.mkMs(this.d.getTime() + milliseconds);
            };
            DateTime.prototype.subtract = function (value) {
                return (this.d.getTime() - value.d.getTime()) / 1000;
            };
            DateTime.prototype.equals = function (other) {
                return this.d.getTime() == other.d.getTime();
            };
            DateTime.prototype.not_equals = function (other) {
                return !this.equals(other);
            };
            DateTime.prototype.less_or_equals = function (other) {
                return this.d.getTime() <= other.d.getTime();
            };
            DateTime.prototype.less = function (other) {
                return this.d.getTime() < other.d.getTime();
            };
            DateTime.prototype.greater_or_equal = function (other) {
                return this.d.getTime() >= other.d.getTime();
            };
            DateTime.prototype.greater = function (other) {
                return this.d.getTime() > other.d.getTime();
            };
            DateTime.prototype.to_string = function () {
                return this.d.toString();
            };
            DateTime.prototype.toString = function () {
                return this.d.toUTCString();
            };
            DateTime.prototype.exportJson = function (ctx) {
                return this.d.toJSON();
            };
            DateTime.mkFromJson = function (ctx, json) {
                if (typeof (json) === "string") {
                    return DateTime.mk(new Date(json));
                }
                else
                    return undefined;
            };
            DateTime.prototype.clone = function () {
                return DateTime.mk(this.d);
            };
            DateTime.prototype.date = function () {
                var r = this.clone();
                r.d.setHours(0, 0, 0, 0);
                return r;
            };
            DateTime.prototype.milliseconds_since_epoch = function () {
                return this.d.getTime();
            };
            DateTime.prototype.from_now = function () {
                return TDev.Util.timeSince(this.d.getTime() / 1000);
            };
            DateTime.prototype.day = function () {
                return this.d.getDate();
            };
            DateTime.prototype.hour = function () {
                return this.d.getHours();
            };
            DateTime.prototype.millisecond = function () {
                return this.d.getMilliseconds();
            };
            DateTime.prototype.minute = function () {
                return this.d.getMinutes();
            };
            DateTime.prototype.month = function () {
                return this.d.getMonth() + 1;
            };
            DateTime.prototype.second = function () {
                return this.d.getSeconds();
            };
            DateTime.prototype.year = function () {
                return this.d.getFullYear();
            };
            DateTime.prototype.week_day = function () {
                return this.d.getDay();
            };
            DateTime.prototype.year_day = function () {
                var first = new Date(this.d.getTime());
                first.setMonth(0, 1);
                return Math.round((this.d.getTime() - first.getTime()) / (24 * 3600 * 1000)) + 1;
            };
            DateTime.prototype.add_years = function (years) {
                return undefined;
            };
            DateTime.prototype.add_months = function (months) {
                return undefined;
            };
            DateTime.prototype.to_universal_time = function () {
                return DateTime.mk(new Date(this.d.getUTCFullYear(), this.d.getUTCMonth(), this.d.getUTCDate(), this.d.getUTCHours(), this.d.getUTCMinutes(), this.d.getUTCSeconds()));
            };
            DateTime.prototype.to_local_time = function () {
                return undefined;
            };
            DateTime.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            DateTime.prototype.debuggerDisplay = function (clickHandler) {
                var tempSpan;
                tempSpan = TDev.span(null, this.toString()).withClick(clickHandler);
                return tempSpan;
            };
            DateTime.defaultValue = DateTime.mkMs(-62135596800000);
            return DateTime;
        })(RT.RTValue);
        RT.DateTime = DateTime;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var DeviceMotion;
        (function (DeviceMotion) {
            var _raw = undefined;
            var _rawSign = 0;
            var _low = undefined;
            var _optimal = undefined;
            var _rotationRate = undefined;
            var _runtime = undefined;
            var _deviceStableCount = 0;
            var _maximumStabilityTiltDeltaAngle = 0.5 * Math.PI / 180.0;
            var _maximumStabilityDeltaOffset = Math.sin(_maximumStabilityTiltDeltaAngle);
            var _samplesCount = 20;
            function initializeData(r) {
                _raw = RT.Vector3.mk(0, 1, 0);
                _rawSign = 0;
                _low = RT.Vector3.mk(0, 1, 0);
                _optimal = RT.Vector3.mk(0, 1, 0);
                _rotationRate = RT.Vector3.mk(0, 0, 0);
                _deviceStableCount = 0;
                _runtime = r;
            }
            function clearData() {
                _raw = undefined;
                _rawSign = 0;
                _low = undefined;
                _optimal = undefined;
                _rotationRate = undefined;
                _runtime = undefined;
                _deviceStableCount = 0;
            }
            function lowPass(old, current) {
                return old + (current - old) * 0.1;
            }
            function fastLowPass(old, current) {
                if (Math.abs(old - current) < 0.05) {
                    return lowPass(old, current);
                }
                else {
                    return current;
                }
            }
            function isDeviceStable(r) {
                DeviceMotion.start(r.rt);
                r.resumeVal(_deviceStableCount >= _samplesCount);
            }
            DeviceMotion.isDeviceStable = isDeviceStable;
            function setRaw(v, orientation) {
                if (orientation === undefined)
                    orientation = window.orientation;
                if (orientation == 90) {
                    v = RT.Vector3.mk(v.y(), -v.x(), v.z());
                }
                else if (orientation == -90) {
                    v = RT.Vector3.mk(-v.y(), v.x(), v.z());
                }
                else if (orientation == 180) {
                    v = RT.Vector3.mk(-v.x(), -v.y(), v.z());
                }
                _raw = v;
                if (_low) {
                    _low = RT.Vector3.mk(lowPass(_low.x(), _raw.x()), lowPass(_low.y(), _raw.y()), lowPass(_low.z(), _raw.z()));
                }
                else {
                    _low = _raw;
                }
                if (_optimal) {
                    _optimal = RT.Vector3.mk(fastLowPass(_optimal.x(), _raw.x()), fastLowPass(_optimal.y(), _raw.y()), fastLowPass(_optimal.z(), _raw.z()));
                }
                else {
                    _optimal = _raw;
                }
                if (_low && _optimal) {
                    var dv = _low.subtract(_optimal);
                    if (Math.abs(dv.x()) > _maximumStabilityDeltaOffset || Math.abs(dv.y()) > _maximumStabilityDeltaOffset || Math.abs(dv.z()) > _maximumStabilityDeltaOffset)
                        _deviceStableCount = 0;
                    else {
                        if (_deviceStableCount < _samplesCount)
                            ++_deviceStableCount;
                    }
                }
                if (RT.ShakeDetector.accelerationChanged(_raw))
                    RT.Senses.raiseShakeEvent();
            }
            DeviceMotion.setRaw = setRaw;
            function reading(ev) {
                var acc = ev.accelerationIncludingGravity;
                if (acc) {
                    if (!_rawSign)
                        _rawSign = acc.z < 0 ? 1 : -1;
                    var g = 9.81 * _rawSign;
                    var ax = acc.x / g;
                    var ay = -acc.y / g;
                    var az = acc.z / g;
                    setRaw(RT.Vector3.mk(ax, ay, az));
                }
                var rot = ev.rotationRate;
                if (rot) {
                    _rotationRate = RT.Vector3.mk(rot.x, rot.y, rot.z);
                }
                else {
                    _rotationRate = undefined;
                }
            }
            function orientationReading(ev) {
                var beta = RT.Math_.deg_to_rad(ev.beta || 0);
                var gamma = RT.Math_.deg_to_rad(ev.gamma || 0);
                var cosBeta = Math.cos(beta);
                var cosGamma = Math.cos(gamma);
                var v = RT.Vector3.mk(gamma * 1.5, beta * 1.5, -cosBeta * cosGamma * 1.25);
                setRaw(v);
            }
            function mouseReading(ev) {
                var x = 0;
                var y = 0;
                var z = -1;
                var el;
                if (_runtime && _runtime.host && (el = _runtime.host.fullScreenElement())) {
                    var top = el.offsetTop;
                    var left = el.offsetLeft;
                    var parent = el.offsetParent;
                    while (parent) {
                        if (parent.id == 'root')
                            break;
                        if (parent.scrollEnabled)
                            break;
                        top += parent.offsetTop;
                        left += parent.offsetLeft;
                        parent = parent.offsetParent;
                    }
                    x = (ev.pageX - left - el.clientWidth / 2) / el.clientWidth;
                    y = (ev.pageY - top - el.clientHeight / 2) / el.clientHeight;
                    x *= 2;
                    y *= 2;
                    x = RT.Math_.clamp(-1.2, 1.2, x);
                    y = RT.Math_.clamp(-1.2, 1.2, y);
                    z = -Math.sqrt(Math.max(0, 1 - x * x - y * y));
                    _runtime.host.setTransform3d(TDev.Util.fmt("perspective(30em) rotateX({0}deg) rotateY({1}deg)", -y * TDev.Runtime.accelerometerTiltBooster, x * TDev.Runtime.accelerometerTiltBooster), "50% 50% 50%", "30em");
                }
                setRaw(RT.Vector3.mk(x, y, z));
            }
            DeviceMotion.isSupported = function () {
                return DeviceMotion.isMotionSupported() || RT.DeviceOrientation.isOrientationSupported() || TDev.Browser.assumeMouse;
            };
            DeviceMotion.isMotionSupported = function () {
                return TDev.Browser.deviceMotion;
            };
            DeviceMotion.isGyroscopeSupported = function () {
                return TDev.Browser.deviceMotion;
            };
            function rt_start(r) {
                if (r.eventEnabled("shake"))
                    DeviceMotion.start(r);
            }
            DeviceMotion.rt_start = rt_start;
            DeviceMotion.addReadingEvent = function () {
                if (TDev.Browser.assumeMouse) {
                    TDev.Util.log("emulating accelerometer with mouse");
                    window.addEventListener('mousemove', mouseReading, false);
                }
                else if (DeviceMotion.isMotionSupported())
                    window.addEventListener('devicemotion', reading, false);
                else if (RT.DeviceOrientation.isOrientationSupported())
                    window.addEventListener('deviceorientation', orientationReading, false);
            };
            DeviceMotion.removeReadingEvent = function () {
                window.removeEventListener('devicemotion', reading, false);
                window.removeEventListener('deviceorientation', orientationReading, false);
                window.removeEventListener('mousemove', mouseReading, false);
            };
            DeviceMotion.start = function (r) {
                if (r.isHeadless())
                    return;
                if (!_runtime) {
                    initializeData(r);
                    if (DeviceMotion.isSupported())
                        DeviceMotion.addReadingEvent();
                }
            };
            DeviceMotion.stop = function (r) {
                if (r.isHeadless())
                    return;
                DeviceMotion.removeReadingEvent();
                clearData();
            };
            function accelerationStable(r) {
                DeviceMotion.start(r.rt);
                r.resumeVal(_raw);
            }
            DeviceMotion.accelerationStable = accelerationStable;
            function accelerationSmooth(r) {
                DeviceMotion.start(r.rt);
                r.resumeVal(_low);
            }
            DeviceMotion.accelerationSmooth = accelerationSmooth;
            function accelerationQuick(r) {
                DeviceMotion.start(r.rt);
                r.resumeVal(_optimal);
            }
            DeviceMotion.accelerationQuick = accelerationQuick;
            function acceleration(r) {
                DeviceMotion.start(r.rt);
                return _optimal;
            }
            DeviceMotion.acceleration = acceleration;
            function rotationRate(r) {
                DeviceMotion.start(r.rt);
                r.resumeVal(_rotationRate);
            }
            DeviceMotion.rotationRate = rotationRate;
        })(DeviceMotion = RT.DeviceMotion || (RT.DeviceMotion = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        (function (DeviceFaceOrientation) {
            DeviceFaceOrientation[DeviceFaceOrientation["Up"] = 0] = "Up";
            DeviceFaceOrientation[DeviceFaceOrientation["Down"] = 1] = "Down";
        })(RT.DeviceFaceOrientation || (RT.DeviceFaceOrientation = {}));
        var DeviceFaceOrientation = RT.DeviceFaceOrientation;
        (function (DeviceLandscapeOrientation) {
            DeviceLandscapeOrientation[DeviceLandscapeOrientation["Portrait"] = 0] = "Portrait";
            DeviceLandscapeOrientation[DeviceLandscapeOrientation["LandscapeLeft"] = 1] = "LandscapeLeft";
            DeviceLandscapeOrientation[DeviceLandscapeOrientation["LandscapeRight"] = 2] = "LandscapeRight";
        })(RT.DeviceLandscapeOrientation || (RT.DeviceLandscapeOrientation = {}));
        var DeviceLandscapeOrientation = RT.DeviceLandscapeOrientation;
        var DeviceOrientation;
        (function (DeviceOrientation) {
            var _alpha = undefined;
            var _beta = undefined;
            var _gamma = undefined;
            var _heading = 0;
            var _face_orientation = undefined;
            var _landscape_orientation = undefined;
            var _runtime = undefined;
            function clearData(clearRuntime) {
                if (clearRuntime === void 0) { clearRuntime = true; }
                TDev.Util.log('deviceorientation: clear data');
                _alpha = undefined;
                _beta = undefined;
                _gamma = undefined;
                _heading = 0;
                _face_orientation = undefined;
                _landscape_orientation = undefined;
                if (clearRuntime)
                    _runtime = undefined;
            }
            function computeHeading() {
                if (Math.abs(_gamma) < 45 && 45 < Math.abs(_beta) && Math.abs(_beta) < 135) {
                    var sinAlpha = Math.sin(_alpha);
                    var cosAlpha = Math.cos(_alpha);
                    var sinBeta = Math.sin(_beta);
                    var sinGamma = Math.sin(_gamma);
                    var cosGamma = Math.cos(_gamma);
                    _heading = Math.atan((-cosAlpha * sinGamma - sinAlpha * sinBeta * cosGamma) / (-sinAlpha * sinGamma + cosGamma * sinBeta * cosGamma));
                }
                else {
                    _heading = 360 - _alpha;
                }
            }
            DeviceOrientation.computeHeading = computeHeading;
            function orientation(r) {
                start(r.rt);
                if (_alpha && _beta && _gamma)
                    r.resumeVal(RT.Vector3.mk(_alpha, _beta, _gamma));
                else
                    r.resumeVal(RT.Vector3.mk(0, 0, 0));
            }
            DeviceOrientation.orientation = orientation;
            function heading(r) {
                start(r.rt);
                r.resumeVal(_heading);
            }
            DeviceOrientation.heading = heading;
            function detectLandscapeOrientation() {
                var threshold = 30;
                if (_beta > 90 - threshold && _beta < 90 + threshold) {
                    if (_landscape_orientation != 0 /* Portrait */) {
                        TDev.Util.log('phone portrait');
                        _landscape_orientation = 0 /* Portrait */;
                        RT.Senses.raisePhonePortrait();
                    }
                }
                else if ((_beta < threshold || _beta > 360 - threshold) && _gamma > 270 - threshold && _gamma < 270 + threshold) {
                    if (_landscape_orientation != 1 /* LandscapeLeft */) {
                        TDev.Util.log('phone landscape left');
                        _landscape_orientation = 1 /* LandscapeLeft */;
                        RT.Senses.raisePhoneLandscapeLeft();
                    }
                }
                else if ((_beta < threshold || _beta > 360 - threshold) && _gamma > 90 - threshold && _gamma < 90 + threshold) {
                    if (_landscape_orientation != 2 /* LandscapeRight */) {
                        TDev.Util.log('phone landscape right');
                        _landscape_orientation = 2 /* LandscapeRight */;
                        RT.Senses.raisePhoneLandscapeRight();
                    }
                }
                else {
                    _landscape_orientation = undefined;
                }
            }
            function detectFaceOrientation() {
                var threshold = 30;
                if ((_beta < threshold || _beta > 360 - threshold) && (_gamma < threshold || _gamma > 360 - threshold)) {
                    if (_face_orientation != 0 /* Up */) {
                        TDev.Util.log('phone face up');
                        _face_orientation = 0 /* Up */;
                        RT.Senses.raisePhoneFaceUp();
                    }
                }
                else if (((_gamma > 180 - threshold && _gamma < 180 + threshold && (_beta < threshold || _beta > 360 - threshold)) || (_beta > 180 - threshold && _beta < 180 + threshold && (_gamma < threshold || _gamma > 360 - threshold)))) {
                    if (_face_orientation != 1 /* Down */) {
                        TDev.Util.log('phone face down');
                        _face_orientation = 1 /* Down */;
                        RT.Senses.raisePhoneFaceDown();
                    }
                }
                else {
                    _face_orientation = undefined;
                }
            }
            function setOrientation(alpha, beta, gamma) {
                _alpha = alpha;
                if (_alpha && _alpha < 0)
                    _alpha += 360.0;
                _beta = beta;
                if (_beta && _beta < 0)
                    _beta += 360.0;
                _gamma = gamma;
                if (_gamma && _gamma < 0)
                    _gamma += 360.0;
                if (!_alpha || !_beta || !_gamma) {
                    clearData(false);
                    return;
                }
                detectLandscapeOrientation();
                detectFaceOrientation();
            }
            DeviceOrientation.setOrientation = setOrientation;
            function setHeading(heading) {
                _heading = heading;
            }
            DeviceOrientation.setHeading = setHeading;
            function reading(ev) {
                TDev.Util.log('deviceorientation: reading...');
                setOrientation(ev.alpha, ev.beta, ev.gamma);
                setHeading(ev.compassHeading || ev.webkitCompassHeading || undefined);
                if (!_heading && ev.absolute) {
                    computeHeading();
                }
            }
            DeviceOrientation.isOrientationSupported = function () {
                return TDev.Browser.deviceOrientation;
            };
            DeviceOrientation.isHeadingSupported = function () {
                return TDev.Browser.deviceHeading;
            };
            function rt_start(r) {
                if (r.eventEnabled("phone face up") || r.eventEnabled("phone face down") || r.eventEnabled("phone portrait") || r.eventEnabled("phone landscape left") || r.eventEnabled("phone landscape right")) {
                    start(r);
                }
            }
            DeviceOrientation.rt_start = rt_start;
            function rt_stop(rt) {
                stop(rt);
            }
            DeviceOrientation.rt_stop = rt_stop;
            DeviceOrientation.addOrientationReadingEvent = function () {
                TDev.Util.log('deviceorientation: attaching');
                window.addEventListener('deviceorientation', reading, false);
            };
            DeviceOrientation.removeOrientationReadingEvent = function () {
                window.removeEventListener('deviceorientation', reading, false);
            };
            DeviceOrientation.addHeadingReadingEvent = function () {
                TDev.Util.log('compassneedscalibration: attaching');
                window.addEventListener("compassneedscalibration", calibrateCompass, false);
            };
            DeviceOrientation.removeHeadingReadingEvent = function () {
                window.removeEventListener("compassneedscalibration", calibrateCompass, false);
            };
            function calibrateCompass(ev) {
                TDev.HTML.showNotificationText("Your compass needs calibrating! Wave your device in a figure-eight motion.");
            }
            function start(r) {
                if (r.isHeadless())
                    return;
                if (DeviceOrientation.isOrientationSupported() || DeviceOrientation.isHeadingSupported()) {
                    if (!_runtime) {
                        _runtime = r;
                        if (DeviceOrientation.isOrientationSupported())
                            DeviceOrientation.addOrientationReadingEvent();
                        if (DeviceOrientation.isHeadingSupported())
                            DeviceOrientation.addHeadingReadingEvent();
                    }
                }
                else {
                    TDev.Util.log('deviceorientation: not supported');
                    clearData();
                }
            }
            DeviceOrientation.start = start;
            function stop(r) {
                if (r.isHeadless())
                    return;
                TDev.Util.log('deviceorientation: stop');
                DeviceOrientation.removeOrientationReadingEvent();
                DeviceOrientation.removeHeadingReadingEvent();
                clearData(true);
            }
            DeviceOrientation.stop = stop;
        })(DeviceOrientation = RT.DeviceOrientation || (RT.DeviceOrientation = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Docs;
        (function (Docs) {
            function bitmatrix(bits) {
            }
            Docs.bitmatrix = bitmatrix;
        })(Docs = RT.Docs || (RT.Docs = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Enumerator = (function (_super) {
            __extends(Enumerator, _super);
            function Enumerator() {
                _super.call(this);
            }
            Enumerator.prototype.current = function () {
            };
            Enumerator.prototype.move_next = function () {
                return undefined;
            };
            return Enumerator;
        })(RT.RTValue);
        RT.Enumerator = Enumerator;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var GeoLocation;
        (function (GeoLocation) {
            function isSupported() {
                return !!window.navigator.geolocation;
            }
            GeoLocation.isSupported = isSupported;
            function getCurrentPosition(accurate, r) {
                if (isSupported()) {
                    window.navigator.geolocation.getCurrentPosition(function (position) {
                        var coords = position.coords;
                        var loc = RT.Location_.mk(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.altitudeAccuracy, coords.heading, coords.speed);
                        r.resumeVal(loc);
                    }, function (error) {
                        r.resumeVal(undefined);
                    }, { enableHighAccuracy: accurate });
                }
                else {
                    r.resumeVal(undefined);
                }
            }
            function currentLocation(r) {
                getCurrentPosition(false, r);
            }
            GeoLocation.currentLocation = currentLocation;
            function currentLocationAccurate(r) {
                getCurrentPosition(true, r);
            }
            GeoLocation.currentLocationAccurate = currentLocationAccurate;
        })(GeoLocation = RT.GeoLocation || (RT.GeoLocation = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Invalid;
        (function (Invalid) {
            function number() {
                return undefined;
            }
            Invalid.number = number;
            function boolean() {
                return undefined;
            }
            Invalid.boolean = boolean;
            function string() {
                return undefined;
            }
            Invalid.string = string;
            function string_collection() {
                return undefined;
            }
            Invalid.string_collection = string_collection;
            function datetime() {
                return undefined;
            }
            Invalid.datetime = datetime;
            function color() {
                return undefined;
            }
            Invalid.color = color;
            function picture() {
                return undefined;
            }
            Invalid.picture = picture;
            function song() {
                return undefined;
            }
            Invalid.song = song;
            function location() {
                return undefined;
            }
            Invalid.location = location;
            function location_collection() {
                return undefined;
            }
            Invalid.location_collection = location_collection;
            function map() {
                return undefined;
            }
            Invalid.map = map;
            function sound() {
                return undefined;
            }
            Invalid.sound = sound;
            function json_object() {
                return undefined;
            }
            Invalid.json_object = json_object;
            function link() {
                return undefined;
            }
            Invalid.link = link;
            function link_collection() {
                return undefined;
            }
            Invalid.link_collection = link_collection;
            function vector3() {
                return undefined;
            }
            Invalid.vector3 = vector3;
            function number_map() {
                return undefined;
            }
            Invalid.number_map = number_map;
            function string_map() {
                return undefined;
            }
            Invalid.string_map = string_map;
            function message() {
                return undefined;
            }
            Invalid.message = message;
            function message_collection() {
                return undefined;
            }
            Invalid.message_collection = message_collection;
            function board() {
                return undefined;
            }
            Invalid.board = board;
            function sprite() {
                return undefined;
            }
            Invalid.sprite = sprite;
            function sprite_animation() {
                return undefined;
            }
            Invalid.sprite_animation = sprite_animation;
            function sprite_set() {
                return undefined;
            }
            Invalid.sprite_set = sprite_set;
            function xml_object() {
                return undefined;
            }
            Invalid.xml_object = xml_object;
            function place() {
                return undefined;
            }
            Invalid.place = place;
            function place_collection() {
                return undefined;
            }
            Invalid.place_collection = place_collection;
            function textbox() {
                return undefined;
            }
            Invalid.textbox = textbox;
            function contact() {
                return undefined;
            }
            Invalid.contact = contact;
            function contact_collection() {
                return undefined;
            }
            Invalid.contact_collection = contact_collection;
            function camera() {
                return undefined;
            }
            Invalid.camera = camera;
            function web_request() {
                return undefined;
            }
            Invalid.web_request = web_request;
            function web_response() {
                return undefined;
            }
            Invalid.web_response = web_response;
            function number_collection() {
                return undefined;
            }
            Invalid.number_collection = number_collection;
            function page() {
                return undefined;
            }
            Invalid.page = page;
            function page_button() {
                return undefined;
            }
            Invalid.page_button = page_button;
            function page_collection() {
                return undefined;
            }
            Invalid.page_collection = page_collection;
            function box_flow() {
                return undefined;
            }
            Invalid.box_flow = box_flow;
            function matrix() {
                return undefined;
            }
            Invalid.matrix = matrix;
            function action() {
                return undefined;
            }
            Invalid.action = action;
            function text_action() {
                return undefined;
            }
            Invalid.text_action = text_action;
            function position_action() {
                return undefined;
            }
            Invalid.position_action = position_action;
            function vector_action() {
                return undefined;
            }
            Invalid.vector_action = vector_action;
            function webresponse_action() {
                return undefined;
            }
            Invalid.webresponse_action = webresponse_action;
            function sprite_action() {
                return undefined;
            }
            Invalid.sprite_action = sprite_action;
            function sprite_set_action() {
                return undefined;
            }
            Invalid.sprite_set_action = sprite_set_action;
            function json_builder() {
                return undefined;
            }
            Invalid.json_builder = json_builder;
            function message_collection_action() {
                return undefined;
            }
            Invalid.message_collection_action = message_collection_action;
            function oauth_response() {
                return undefined;
            }
            Invalid.oauth_response = oauth_response;
            function form_builder() {
                return undefined;
            }
            Invalid.form_builder = form_builder;
            function user() {
                return undefined;
            }
            Invalid.user = user;
            function gamepad() {
                return undefined;
            }
            Invalid.gamepad = gamepad;
        })(Invalid = RT.Invalid || (RT.Invalid = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var JsonObject = (function (_super) {
            __extends(JsonObject, _super);
            function JsonObject() {
                _super.call(this);
                this._item = undefined;
            }
            JsonObject.fromArtUrl = function (url) {
                var value = RT.String_.valueFromArtUrl(url);
                return TDev.Promise.as(JsonObject.mk(value));
            };
            JsonObject.mk = function (s, log) {
                return RT.JsonParser.parse(s, log);
            };
            JsonObject.wrap = function (json) {
                if (json === undefined)
                    return undefined;
                var js = new JsonObject();
                js._item = json;
                return js;
            };
            JsonObject.prototype.exportJson = function (ctx) {
                return this._item;
            };
            JsonObject.prototype.importJson = function (ctx, json) {
                TDev.Util.oops("should not call immutable instance for importing");
                return undefined;
            };
            JsonObject.mkFromJson = function (ctx, json) {
                if (json === undefined)
                    return undefined;
                var copy = JSON.parse(JSON.stringify(json));
                return JsonObject.wrap(copy);
            };
            JsonObject.prototype.getShortStringRepresentation = function () {
                return JSON.stringify(this._item, null, 2);
            };
            JsonObject.prototype.clone = function () {
                return JsonObject.wrap(JSON.parse(JSON.stringify(this._item)));
            };
            JsonObject.prototype.value = function () {
                return this._item;
            };
            JsonObject.prototype.count = function () {
                return Array.isArray(this._item) ? this._item.length : undefined;
            };
            JsonObject.prototype.at = function (index) {
                return Array.isArray(this._item) ? JsonObject.wrap(this._item[Math.floor(index)]) : undefined;
            };
            JsonObject.prototype.boolean = function (key) {
                if (this._item === null)
                    return undefined;
                var v = this._item[key];
                if (typeof v === 'boolean')
                    return v;
                if (typeof v === 'string')
                    return /^true$/i.test(v) ? true : false;
                if (typeof v === 'number')
                    return v == 0 ? false : true;
                else
                    return !!v;
            };
            JsonObject.prototype.contains_key = function (key) {
                var v = this._item;
                return v !== null && typeof v === 'object' && v.hasOwnProperty(key);
            };
            JsonObject.prototype.time = function (key) {
                if (this._item !== null) {
                    var v = this._item[key];
                    if (typeof v === 'string')
                        return RT.DateTime.mkMs(Date.parse(v));
                    if (typeof v === 'number')
                        return RT.DateTime.mkMs(v);
                }
                return undefined;
            };
            JsonObject.prototype.field = function (key) {
                var v = this._item;
                return v === null ? undefined : JsonObject.wrap(v[key]);
            };
            JsonObject.prototype.keys = function () {
                var v = this._item;
                return RT.Collection.mkStrings(this.kind() === "object" ? Object.keys(v) : []);
            };
            JsonObject.prototype.kind = function () {
                var result = 'array';
                if (this._item === null)
                    result = "null";
                else if (Array.isArray(this._item)) {
                }
                else if (typeof this._item === 'string')
                    result = 'string';
                else if (typeof this._item === 'number')
                    result = 'number';
                else if (typeof this._item === 'boolean')
                    result = 'boolean';
                else if (typeof this._item === 'object')
                    result = 'object';
                return result;
            };
            JsonObject.prototype.number = function (key) {
                if (this._item !== null) {
                    var v = this._item[key];
                    if (typeof v === 'number')
                        return v;
                    if (typeof v === 'string')
                        return parseFloat(v);
                    if (typeof v === 'boolean')
                        return v ? 1 : 0;
                }
                return undefined;
            };
            JsonObject.prototype.string = function (key) {
                if (this._item !== null) {
                    var v = this._item[key];
                    if (typeof v === 'string')
                        return v;
                    if (typeof v === 'number')
                        return v.toString();
                    if (typeof v === 'boolean')
                        return v ? 'true' : 'false';
                }
                return undefined;
            };
            JsonObject.prototype.post_to_wall = function (s) {
                s.rt.postBoxedText(JSON.stringify(this._item, null, 2), s.pc);
            };
            JsonObject.prototype.format = function (spaces) {
                return JSON.stringify(this._item, null, spaces);
            };
            JsonObject.prototype.to_boolean = function () {
                if (typeof this._item === 'boolean')
                    return this._item;
                if (typeof this._item === 'string')
                    return /^true$/i.test(this._item) ? true : false;
                if (typeof this._item === 'number')
                    return this._item == 0 ? false : true;
                return undefined;
            };
            JsonObject.prototype.to_number = function () {
                if (typeof this._item === 'number')
                    return this._item;
                if (typeof this._item === 'string')
                    return parseFloat(this._item);
                if (typeof this._item === 'boolean')
                    return this._item ? 1 : 0;
                return undefined;
            };
            JsonObject.prototype.to_string = function () {
                if (typeof this._item === 'string')
                    return this._item;
                if (typeof this._item === 'number')
                    return this._item.toString();
                if (typeof this._item === 'boolean')
                    return this._item ? 'true' : 'false';
                return undefined;
            };
            JsonObject.prototype.to_time = function () {
                if (typeof this._item === 'string')
                    return RT.DateTime.mkMs(Date.parse(this._item));
                if (typeof this._item === 'number')
                    return RT.DateTime.mkMs(this._item);
                return undefined;
            };
            JsonObject.prototype.to_collection = function () {
                if (Array.isArray(this._item))
                    return RT.Collection.fromArray(this._item.map(function (e) { return JsonObject.wrap(e); }), JsonObject);
                else
                    return undefined;
            };
            JsonObject.prototype.serialize = function () {
                return JSON.stringify(this._item);
            };
            JsonObject.prototype.to_json_builder = function () {
                return RT.JsonBuilder.wrap(JSON.parse(JSON.stringify(this._item)));
            };
            JsonObject.prototype.toString = function () {
                return JSON.stringify(this._item);
            };
            JsonObject.prototype.debuggerDisplay = function (clickHandler) {
                var _this = this;
                var c = this._item;
                if (typeof c === 'boolean' || typeof c === 'string' || typeof c === 'number')
                    return TDev.div(null, c.toString()).withClick(clickHandler);
                else if (c === null)
                    return TDev.div(null, 'null').withClick(clickHandler);
                else if (Array.isArray(c))
                    return TDev.div(null, '[' + c.length + ']').withClick(clickHandler);
                var txt = [];
                Object.keys(c).forEach(function (k) {
                    var v = _this._item[k];
                    if (Array.isArray(v))
                        txt.push(k + ' : [' + v.length + ']');
                    else if (typeof v === 'boolean' || typeof v === 'number')
                        txt.push(k + ' : ' + v);
                    else if (typeof v === 'string')
                        txt.push(k + ' : "' + v.slice(0, 5) + '..."');
                    else
                        txt.push(k + ' : {...}');
                });
                return TDev.div(null, '{' + txt.join(', ') + '}').withClick(clickHandler);
            };
            JsonObject.prototype.debuggerChildren = function () {
                var c = this._item;
                if (c === null || typeof c === 'boolean' || typeof c === 'string' || typeof c === 'number')
                    return null;
                var r = {};
                Object.keys(c).forEach(function (k) {
                    var v = c[k];
                    if (Array.isArray(v) || typeof v === 'object')
                        r[k] = JsonObject.wrap(v);
                    else
                        r[k] = v;
                });
                return r;
            };
            return JsonObject;
        })(RT.RTValue);
        RT.JsonObject = JsonObject;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var JsonBuilder = (function (_super) {
            __extends(JsonBuilder, _super);
            function JsonBuilder() {
                _super.apply(this, arguments);
                this.item = {};
            }
            JsonBuilder.prototype.isSerializable = function () {
                return true;
            };
            JsonBuilder.wrap = function (i) {
                if (i === undefined)
                    return undefined;
                var r = new JsonBuilder();
                r.item = i;
                return r;
            };
            JsonBuilder.prototype.value = function () {
                return this.item;
            };
            JsonBuilder.prototype.exportJson = function (ctx) {
                return TDev.Util.jsonClone(this.item);
            };
            JsonBuilder.prototype.importJson = function (ctx, json) {
                if (json !== undefined) {
                    this.item = TDev.Util.jsonClone(json);
                    return this;
                }
                else
                    return undefined;
            };
            JsonBuilder.prototype.ensureObject = function () {
                if (this.item === null || typeof this.item !== "object" || Array.isArray(this.item))
                    this.item = {};
            };
            JsonBuilder.prototype.set_field = function (name, value) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = this.toValue(value);
            };
            JsonBuilder.prototype.set_builder = function (name, value) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = value.item;
            };
            JsonBuilder.prototype.set_string = function (name, value) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = value;
            };
            JsonBuilder.prototype.clone = function () {
                return JsonBuilder.wrap(TDev.Util.jsonClone(this.item));
            };
            JsonBuilder.prototype.set_number = function (name, value) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = value;
            };
            JsonBuilder.prototype.set_boolean = function (name, value) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = value;
            };
            JsonBuilder.prototype.set_sound = function (name, snd) {
                if (name.length == 0)
                    return;
                this.ensureObject();
                this.item[name] = snd.getDataUri();
            };
            JsonBuilder.prototype.set_picture = function (name, pic, quality, r) {
                var _this = this;
                if (name.length == 0)
                    return;
                this.ensureObject();
                pic.loadFirst(r, function () {
                    _this.item[name] = pic.getDataUri(RT.Math_.normalize(quality));
                });
            };
            JsonBuilder.prototype.set_field_null = function (name) {
                this.set_field(name, null);
            };
            JsonBuilder.prototype.ensureArray = function () {
                if (!Array.isArray(this.item))
                    this.item = [];
            };
            JsonBuilder.prototype.add = function (value) {
                this.ensureArray();
                this.item.push(this.toValue(value));
            };
            JsonBuilder.prototype.add_number = function (value) {
                this.ensureArray();
                this.item.push(value);
            };
            JsonBuilder.prototype.add_string = function (value) {
                this.ensureArray();
                this.item.push(value);
            };
            JsonBuilder.prototype.add_boolean = function (value) {
                this.ensureArray();
                this.item.push(value);
            };
            JsonBuilder.prototype.copy_from = function (value) {
                var _this = this;
                if (value.kind() != "object")
                    TDev.Util.userError("cannot copy from non-object");
                var v = TDev.Util.jsonClone(value.value());
                Object.keys(v).forEach(function (k) {
                    _this.item[k] = v[k];
                });
            };
            JsonBuilder.prototype.add_builder = function (value) {
                if (!Array.isArray(this.item))
                    this.item = [];
                this.item.push(value.item);
            };
            JsonBuilder.prototype.clear = function () {
                if (Array.isArray(this.item))
                    while (this.item.length > 0)
                        this.item.pop();
            };
            JsonBuilder.prototype.add_null = function () {
                this.add(null);
            };
            JsonBuilder.prototype.toString = function () {
                return JSON.stringify(this.item);
            };
            JsonBuilder.prototype.setItem = function (i) {
                this.item = i;
            };
            JsonBuilder.prototype.toValue = function (o) {
                return o === null ? null : o.value();
            };
            JsonBuilder.prototype.to_json = function () {
                return RT.JsonObject.wrap(JSON.parse(JSON.stringify(this.item)));
            };
            JsonBuilder.prototype.count = function () {
                return Array.isArray(this.item) ? this.item.length : undefined;
            };
            JsonBuilder.prototype.at = function (index) {
                return Array.isArray(this.item) ? JsonBuilder.wrap(this.item[Math.floor(index)]) : undefined;
            };
            JsonBuilder.prototype.set_at = function (index, v) {
                if (!Array.isArray(this.item))
                    this.item = [];
                this.item[index] = v.item;
            };
            JsonBuilder.prototype.remove_at = function (index) {
                if (!Array.isArray(this.item))
                    this.item = [];
                this.item.splice(index, 1);
            };
            JsonBuilder.prototype.remove_field = function (name) {
                var v = this.item;
                this.ensureObject();
                delete this.item[name];
            };
            JsonBuilder.prototype.boolean = function (key) {
                if (this.item === null)
                    return undefined;
                var v = this.item[key];
                if (typeof v === 'boolean')
                    return v;
                if (typeof v === 'string')
                    return /^true$/i.test(v) ? true : false;
                if (typeof v === 'number')
                    return v == 0 ? false : true;
                else
                    return !!v;
            };
            JsonBuilder.prototype.contains_key = function (key) {
                var v = this.item;
                return v !== null && typeof v === 'object' && v.hasOwnProperty(key);
            };
            JsonBuilder.prototype.time = function (key) {
                if (this.item !== null) {
                    var v = this.item[key];
                    if (typeof v === 'string')
                        return RT.DateTime.mkMs(Date.parse(v));
                    if (typeof v === 'number')
                        return RT.DateTime.mkMs(v);
                }
                return undefined;
            };
            JsonBuilder.prototype.field = function (key) {
                var v = this.item;
                return v === null ? undefined : JsonBuilder.wrap(v[key]);
            };
            JsonBuilder.prototype.keys = function () {
                return RT.Collection.mkStrings(this.kind() === "object" ? Object.keys(this.item) : []);
            };
            JsonBuilder.prototype.kind = function () {
                var result = 'array';
                if (this.item === null)
                    result = "null";
                else if (Array.isArray(this.item)) {
                }
                else if (typeof this.item === 'string')
                    result = 'string';
                else if (typeof this.item === 'number')
                    result = 'number';
                else if (typeof this.item === 'boolean')
                    result = 'boolean';
                else if (typeof this.item === 'object')
                    result = 'object';
                return result;
            };
            JsonBuilder.prototype.number = function (key) {
                if (this.item !== null) {
                    var v = this.item[key];
                    if (typeof v === 'number')
                        return v;
                    if (typeof v === 'string')
                        return parseFloat(v);
                    if (typeof v === 'boolean')
                        return v ? 1 : 0;
                }
                return undefined;
            };
            JsonBuilder.prototype.string = function (key) {
                if (this.item !== null) {
                    var v = this.item[key];
                    if (typeof v === 'string')
                        return v;
                    if (typeof v === 'number')
                        return v.toString();
                    if (typeof v === 'boolean')
                        return v ? 'true' : 'false';
                }
                return undefined;
            };
            JsonBuilder.prototype.post_to_wall = function (s) {
                var txt;
                try {
                    txt = JSON.stringify(this.item, null, 2);
                }
                catch (e) {
                    txt = "error stringifying json builder: " + e.message;
                }
                s.rt.postBoxedText(txt, s.pc);
            };
            JsonBuilder.prototype.to_boolean = function () {
                if (typeof this.item === 'boolean')
                    return this.item;
                if (typeof this.item === 'string')
                    return /^true$/i.test(this.item) ? true : false;
                if (typeof this.item === 'number')
                    return this.item == 0 ? false : true;
                return undefined;
            };
            JsonBuilder.prototype.to_number = function () {
                if (typeof this.item === 'number')
                    return this.item;
                if (typeof this.item === 'string')
                    return parseFloat(this.item);
                if (typeof this.item === 'boolean')
                    return this.item ? 1 : 0;
                return undefined;
            };
            JsonBuilder.prototype.to_string = function () {
                if (typeof this.item === 'string')
                    return this.item;
                if (typeof this.item === 'number')
                    return this.item.toString();
                if (typeof this.item === 'boolean')
                    return this.item ? 'true' : 'false';
                return undefined;
            };
            JsonBuilder.prototype.to_time = function () {
                if (typeof this.item === 'string')
                    return RT.DateTime.mkMs(Date.parse(this.item));
                if (typeof this.item === 'number')
                    return RT.DateTime.mkMs(this.item);
                return undefined;
            };
            JsonBuilder.prototype.to_collection = function () {
                if (Array.isArray(this.item))
                    return RT.Collection.fromArray(this.item.map(function (e) { return JsonBuilder.wrap(e); }), JsonBuilder);
                else
                    return undefined;
            };
            JsonBuilder.prototype.serialize = function () {
                return JSON.stringify(this.item);
            };
            JsonBuilder.prototype.getShortStringRepresentation = function () {
                return JSON.stringify(this.item, null, 2);
            };
            JsonBuilder.prototype.debuggerDisplay = function (clickHandler) {
                return this.to_json().debuggerDisplay(clickHandler);
            };
            JsonBuilder.prototype.debuggerChildren = function () {
                return this.to_json().debuggerChildren();
            };
            return JsonBuilder;
        })(RT.RTValue);
        RT.JsonBuilder = JsonBuilder;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var FormBuilder = (function (_super) {
            __extends(FormBuilder, _super);
            function FormBuilder() {
                _super.apply(this, arguments);
                this._data = [];
            }
            FormBuilder.prototype.data = function () {
                var fd = new FormData();
                this._data.forEach(function (d) {
                    if (d.blobName)
                        fd.append(d.name, d.value, d.blobName);
                    else
                        fd.append(d.name, d.value);
                });
                return fd;
            };
            FormBuilder.prototype.toString = function () {
                return "form: " + this._data.map(function (d) { return d.name; }).join(", ");
            };
            FormBuilder.prototype.post_to_wall = function (s) {
                s.rt.postText(this.toString(), s.pc);
            };
            FormBuilder.prototype.contains_key = function (name) {
                return !!this._data.filter(function (fv) { return fv.name == name; })[0];
            };
            FormBuilder.prototype.add_text = function (name, content, mimetype, filename) {
                this._data.push({ name: name, value: new Blob([content], { type: mimetype || 'text/plain' }), blobName: filename });
            };
            FormBuilder.prototype.add_buffer = function (name, buffer, filename) {
                this._data.push({ name: name, value: new Blob([buffer.buffer.buffer]), blobName: filename });
            };
            FormBuilder.prototype.add_string_as_file = function (name, text, filename) {
                this._data.push({ name: name, value: new Blob([text], { type: 'text/plain' }), blobName: filename });
            };
            FormBuilder.prototype.add_string = function (name, value) {
                this._data.push({ name: name, value: value });
            };
            FormBuilder.prototype.add_number = function (name, value) {
                this._data.push({ name: name, value: value });
            };
            FormBuilder.prototype.add_boolean = function (name, value) {
                this._data.push({ name: name, value: value });
            };
            FormBuilder.prototype.add_picture = function (name, value, pictureName, r) {
                var _this = this;
                value.loadFirst(r, function () {
                    var blob = TDev.Util.canvasToBlob(value.getCanvas(), pictureName);
                    _this._data.push({ name: name, value: blob, blobName: pictureName });
                });
            };
            return FormBuilder;
        })(RT.RTValue);
        RT.FormBuilder = FormBuilder;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var WebSpeechManager;
        (function (WebSpeechManager) {
            function initialize() {
                var a = window;
                if (a && !a.SpeechRecognition) {
                    a.SpeechRecognition = a.SpeechRecognition || a.webkitSpeechRecognition || a.mozSpeechRecognition || a.oSpeechRecognition || a.msSpeechRecognition;
                }
                if (a && !a.SpeechSynthesisUtterance) {
                    a.SpeechSynthesisUtterance = a.SpeechSynthesisUtterance || a.webkitSpeechSynthesisUtterance || a.mozSpeechSynthesisUtterance || a.oSpeechSynthesisUtterance || a.msSpeechSynthesisUtterance;
                }
            }
            function isSupported() {
                return isRecognitionSupported() || isSynthesisSupported();
            }
            WebSpeechManager.isSupported = isSupported;
            function isRecognitionSupported() {
                initialize();
                var a = window;
                return !!a.SpeechRecognition;
            }
            WebSpeechManager.isRecognitionSupported = isRecognitionSupported;
            function isSynthesisSupported() {
                initialize();
                var a = window;
                return !!a.speechSynthesis && !!a.SpeechSynthesisUtterance;
            }
            WebSpeechManager.isSynthesisSupported = isSynthesisSupported;
            function createRecognition() {
                return isRecognitionSupported() ? new SpeechRecognition() : undefined;
            }
            WebSpeechManager.createRecognition = createRecognition;
            function createSynthesis() {
                return isSynthesisSupported() ? (window.speechSynthesis) : undefined;
            }
            WebSpeechManager.createSynthesis = createSynthesis;
        })(WebSpeechManager = RT.WebSpeechManager || (RT.WebSpeechManager = {}));
        var MicrosoftTranslator;
        (function (MicrosoftTranslator) {
            function createTranslateButton(cls, tk, elementDiv, from, button, replaceContent) {
                if (button === void 0) { button = false; }
                if (replaceContent === void 0) { replaceContent = false; }
                var current = TDev.RT.Languages.current_language();
                if (from.toLowerCase() == current.toLowerCase())
                    return null;
                var translateBtn = null;
                var trDiv = TDev.div('translated');
                var translateCmt = function () {
                    TDev.tick(tk);
                    if (TDev.Cloud.anonMode(TDev.lf("translation")))
                        return;
                    translateBtn.setFlag("working", true);
                    TDev.RT.MicrosoftTranslator.translateAsync(from || '', current, elementDiv.innerHTML, true).done(function (translated) {
                        replaceContent = replaceContent && translated;
                        TDev.Browser.setInnerHTML(trDiv, translated ? translated : TDev.lf(":( Sorry, we could not translate this."));
                        translateBtn.setFlag("working", false);
                        translateBtn.removeSelf();
                        if (replaceContent)
                            elementDiv.setChildren([trDiv]);
                        else
                            elementDiv.appendChild(trDiv);
                    }, function (e) {
                        translateBtn.setFlag("working", false);
                        var trDiv = TDev.div('translated');
                        TDev.Browser.setInnerHTML(trDiv, TDev.lf(":( Sorry, an error occured while translating this text."));
                        elementDiv.appendChild(trDiv);
                    });
                };
                translateBtn = TDev.createElement(button ? "button" : "div", cls, TDev.lf("translate")).withClick(translateCmt);
                return translateBtn;
            }
            MicrosoftTranslator.createTranslateButton = createTranslateButton;
            MicrosoftTranslator.translateAsync = function (source_lang, target_lang, text, html) {
                if (!target_lang) {
                    RT.Time.log('translate: missing target language');
                    return TDev.Promise.as(undefined);
                }
                if (!text || source_lang === target_lang)
                    return TDev.Promise.as(text);
                if (text.length >= 10000) {
                    RT.Time.log('translate: text too long, 10000 characeters max');
                    return TDev.Promise.as(undefined);
                }
                var url = 'runtime/languages/translate?' + 'to=' + encodeURIComponent(target_lang) + '&text=' + encodeURIComponent(text);
                if (source_lang)
                    url += '&from=' + encodeURIComponent(source_lang);
                if (html)
                    url += '&html=true';
                var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                return request.sendAsync().then(function (response) {
                    var translated = response.content_as_json();
                    return translated ? translated.to_string() : undefined;
                });
            };
            MicrosoftTranslator.detectAsync = function (text) {
                if (text.length == 0) {
                    return TDev.Promise.as(undefined);
                }
                var url = 'runtime/languages/detect?text=' + encodeURIComponent(text);
                var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                return request.sendAsync().then(function (response) {
                    var lg = response.content_as_json();
                    return lg.to_string();
                });
            };
            function speakTranslator(lang, text) {
                var url = 'runtime/languages/speak?language=' + encodeURIComponent(lang || Languages.current_language()) + '&text=' + encodeURIComponent(text || "");
                var snd = RT.Sound.mk(url, 1 /* TouchDevelop */, 'audio/mp4');
                return snd;
            }
            MicrosoftTranslator.speakTranslator = speakTranslator;
            MicrosoftTranslator.speak = speakTranslator;
        })(MicrosoftTranslator = RT.MicrosoftTranslator || (RT.MicrosoftTranslator = {}));
        var Languages;
        (function (Languages) {
            function current_language() {
                return navigator.userLanguage || navigator.language || "en-US";
            }
            Languages.current_language = current_language;
            function isSpeechSupported() {
                return WebSpeechManager.isSupported();
            }
            Languages.isSpeechSupported = isSpeechSupported;
            function record_text(r) {
                var recognition = WebSpeechManager.createRecognition();
                if (!recognition) {
                    RT.Wall.ask_string("please enter your text", r);
                    return;
                }
                var res = "";
                var m = new TDev.ModalDialog();
                var status = TDev.div('wall-dialog-body', TDev.lf("initializing..."));
                var btns;
                m.add(TDev.div('wall-dialog-header', TDev.lf("recording text")));
                m.add(status);
                m.onDismiss = function () { return r.resumeVal(""); };
                recognition.continuous = false;
                recognition.interimResults = false;
                recognition.onstart = function (e) {
                    TDev.Util.log('speech recog: start');
                    status.setChildren(['time to talk!']);
                };
                recognition.onresult = function (e) {
                    TDev.Util.log('speech recog: onresult');
                    for (var i = e.resultIndex; i < e.results.length; ++i) {
                        if (e.results[i].isFinal)
                            res += e.results[i][0].transcript;
                    }
                    status.setChildren([res]);
                    m.add(btns = TDev.div('wall-dialog-buttons', TDev.HTML.mkButton('cancel', function () { return m.dismiss(); }), TDev.HTML.mkButton('try again', function () {
                        btns.removeSelf();
                        tryRecognition();
                    }), TDev.HTML.mkButton('ok', function () {
                        m.onDismiss = null;
                        m.dismiss();
                        r.resumeVal(res);
                    })));
                };
                recognition.onerror = function (e) {
                    TDev.Util.log('speech recog: onerror');
                    status.setChildren(['oops, couldn\'t understand what you said.']);
                    m.add(btns = TDev.div('wall-dialog-buttons', TDev.HTML.mkButton('cancel', function () { return m.dismiss(); }), TDev.HTML.mkButton('try again', function () {
                        btns.removeSelf();
                        tryRecognition();
                    })));
                };
                recognition.lang = Languages.current_language();
                function tryRecognition() {
                    res = "";
                    recognition.start();
                }
                tryRecognition();
                m.show();
            }
            Languages.record_text = record_text;
            function translate(source_lang, target_lang, text, r) {
                var rt = r.rt;
                TDev.Cloud.authenticateAsync(TDev.lf("translation")).then(function (authenticated) {
                    if (authenticated)
                        return MicrosoftTranslator.translateAsync(source_lang, target_lang, text, false);
                    else
                        return TDev.Promise.as(undefined);
                }).done(function (translated) { return r.resumeVal(translated); });
            }
            Languages.translate = translate;
            function detect_language(text, r) {
                var rt = r.rt;
                TDev.Cloud.authenticateAsync(TDev.lf("translation")).then(function (authenticated) {
                    if (authenticated)
                        return MicrosoftTranslator.detectAsync(text);
                    else
                        return TDev.Promise.as(undefined);
                }).done(function (lang) { return r.resumeVal(lang); });
            }
            Languages.detect_language = detect_language;
            function speak(lang, text) {
                return MicrosoftTranslator.speakTranslator(lang, text);
            }
            Languages.speak = speak;
            function speak_text(voice_language, voice_gender, text, r) {
                if (!text) {
                    r.resume();
                    return;
                }
                var synthesis = WebSpeechManager.createSynthesis();
                if (synthesis) {
                    var utterance = new SpeechSynthesisUtterance(text);
                    utterance.lang = voice_language || Languages.current_language();
                    synthesis.speak(utterance);
                    r.resume();
                }
                else {
                    var snd = MicrosoftTranslator.speak(voice_language, text);
                    if (snd)
                        snd.play(r);
                    else
                        r.resume();
                }
            }
            Languages.speak_text = speak_text;
            function speak_ssml(ssml, r) {
                var synthesis = WebSpeechManager.createSynthesis();
                if (synthesis) {
                    var utterance = new SpeechSynthesisUtterance(ssml.toString());
                    synthesis.speak(utterance);
                    r.resume();
                }
                else {
                    var text = ssml.value();
                    var snd = MicrosoftTranslator.speak(Languages.current_language(), text);
                    if (snd)
                        snd.play(r);
                    else
                        r.resume();
                }
            }
            Languages.speak_ssml = speak_ssml;
        })(Languages = RT.Languages || (RT.Languages = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        (function (LinkKind) {
            LinkKind[LinkKind["unknown"] = 0] = "unknown";
            LinkKind[LinkKind["media"] = 1] = "media";
            LinkKind[LinkKind["image"] = 2] = "image";
            LinkKind[LinkKind["email"] = 3] = "email";
            LinkKind[LinkKind["phoneNumber"] = 4] = "phoneNumber";
            LinkKind[LinkKind["hyperlink"] = 5] = "hyperlink";
            LinkKind[LinkKind["radio"] = 6] = "radio";
            LinkKind[LinkKind["address"] = 7] = "address";
        })(RT.LinkKind || (RT.LinkKind = {}));
        var LinkKind = RT.LinkKind;
        var Link = (function (_super) {
            __extends(Link, _super);
            function Link() {
                _super.call(this);
                this._title = undefined;
                this._description = undefined;
                this._kind = undefined;
                this._address = undefined;
                this._location = undefined;
                this.previouslyloaded = false;
            }
            Link.prototype.exportJson = function (ctx) {
                return {
                    title: this._title,
                    description: this._description,
                    kind: this._kind && this._kind,
                    address: this._address,
                    location: this._location && this._location.exportJson(ctx)
                };
            };
            Link.prototype.importJson = function (ctx, json) {
                if (typeof json != "object")
                    json = undefined;
                this._title = ctx.importString(json, "title");
                this._description = ctx.importString(json, "description");
                this._kind = ctx.importNumber(json, "kind");
                this._address = ctx.importString(json, "address");
                this._location = ctx.importLocation(json, "location");
                return this;
            };
            Link.mk = function (address, kind) {
                var lnk = new Link();
                lnk._address = address;
                lnk._kind = kind;
                return lnk;
            };
            Link.prototype.toString = function () {
                var s = this.name();
                return s;
            };
            Link.prototype.name = function () {
                if (this._description)
                    return this._title + " : " + this._description;
                else
                    return this._title;
            };
            Link.prototype.set_name = function (name) {
                this._description = "";
                this._title = name;
            };
            Link.prototype.set_title = function (t) {
                this._title = t;
            };
            Link.prototype.set_description = function (d) {
                this._description = d;
            };
            Link.prototype.location = function () {
                return this._location;
            };
            Link.prototype.set_location = function (location) {
                this._location = location;
            };
            Link.prototype.address = function () {
                return this._address;
            };
            Link.prototype.to_picture = function () {
                if (this._kind != 2 /* image */)
                    return undefined;
                return RT.Picture.fromUrlSync(this._address, true);
            };
            Link.prototype.kind = function () {
                return (TDev.enumToString(LinkKind, this._kind)).toLowerCase();
            };
            Link.prototype.getViewCore = function (s, b) {
                if (b === void 0) { b = null; }
                switch (this._kind) {
                    case 2 /* image */:
                        var img = TDev.createElement("img");
                        img.setAttribute('class', 'wall-picture');
                        img.src = this.address();
                        img.alt = this.name();
                        this.slowlyloadingelement = img;
                        b.delayedlayout = true;
                        return img;
                    case 1 /* media */:
                        try {
                            if (/\.(mp3|wav|m4a)$/i.test(this.address())) {
                                var audio = TDev.createElement("audio", "wall-media", this.name());
                                audio.src = this.address();
                                audio.controls = true;
                                audio.autobuffer = true;
                                audio.crossorigin = "anonymous";
                                audio.load();
                                this.slowlyloadingelement = audio;
                                return audio;
                            }
                            else {
                                var video = TDev.createElement("video", "wall-media", this.name());
                                video.src = this.address();
                                video.controls = true;
                                video.autobuffer = true;
                                video.crossorigin = "anonymous";
                                video.load();
                                this.slowlyloadingelement = video;
                                b.delayedlayout = true;
                                return video;
                            }
                        }
                        catch (e) {
                            return TDev.div("item", TDev.div("wall-dialog-header", TDev.lf("invalid media")), TDev.div("wall-dialog-body", this.address()));
                        }
                    default:
                        var url = this.address();
                        var text = "go";
                        switch (this._kind) {
                            case 4 /* phoneNumber */:
                                if (!/^tel:/i.test(url))
                                    url = 'tel:' + url;
                                text = "call";
                                break;
                            case 3 /* email */:
                                if (!/^mailto:/i.test(url))
                                    url = 'mailto:' + encodeURIComponent(url);
                                text = "send";
                                break;
                        }
                        var elt = TDev.div("item link-item", [TDev.div("wall-dialog-header", this._title || this.address() || url), this._description ? TDev.div("wall-dialog-body", this._description) : null]);
                        elt.withClick(function () { return RT.Web.browseAsync(url).done(); });
                        return elt;
                }
            };
            Link.prototype.updateViewCore = function (s, b) {
                if (TDev.LayoutMgr.RenderExecutionMode() && this.slowlyloadingelement) {
                    if (this.slowlyloadingelement.tagName == "IMG") {
                        this.slowlyloadingelement.onload = function () {
                            b.delayedlayout = false;
                            b.RefreshOnScreen();
                        };
                        this.slowlyloadingelement.onerror = function () {
                            b.SwapImageContent(RT.Picture.errorPic());
                        };
                    }
                    else {
                        this.slowlyloadingelement.onloadedmetadata = function () {
                            b.delayedlayout = false;
                            b.RefreshOnScreen();
                        };
                    }
                }
            };
            Link.prototype.share = function (network, r) {
                TDev.HTML.showProgressNotification(TDev.lf("sharing link..."));
                RT.ShareManager.shareLinkAsync(this, network).done(function () { return r.resume(); });
            };
            Link.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Link;
        })(RT.RTValue);
        RT.Link = Link;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Location_ = (function (_super) {
            __extends(Location_, _super);
            function Location_() {
                _super.call(this);
                this._latitude = undefined;
                this._longitude = undefined;
                this._altitude = undefined;
                this._hor_accuracy = undefined;
                this._vert_accuracy = undefined;
                this._speed = undefined;
                this._course = undefined;
            }
            Location_.mkShort = function (lat, lon) {
                return Location_.mk(lat, lon, undefined, undefined, undefined, undefined, undefined);
            };
            Location_.mk = function (lat, lon, alt, horacc, veracc, cou, spe) {
                var l = new Location_();
                l._latitude = lat;
                l._longitude = lon;
                l._altitude = alt;
                l._hor_accuracy = horacc;
                l._vert_accuracy = veracc;
                l._course = cou;
                l._speed = spe;
                return l;
            };
            Location_.mkFromString = function (s) {
                var pos = s.indexOf(",");
                var l = new Location_();
                l._latitude = Number(s.slice(0, pos));
                l._longitude = Number(s.slice(pos + 1));
                return l;
            };
            Location_.prototype.to_string = function () {
                return this._latitude + ',' + this._longitude;
            };
            Location_.prototype.exportJson = function (ctx) {
                return {
                    latitude: this._latitude,
                    longitude: this._longitude,
                    altitude: this._altitude,
                    hor_accuracy: this._hor_accuracy,
                    vert_accuracy: this._vert_accuracy,
                    course: this._course,
                    speed: this._speed
                };
            };
            Location_.prototype.importJson = function (ctx, json) {
                TDev.Util.oops("should not call immutable instance for importing");
                return undefined;
            };
            Location_.mkFromJson = function (ctx, json) {
                if (typeof json != "object")
                    return undefined;
                var loc = new Location_();
                loc._latitude = ctx.importNumber(json, "latitude");
                loc._longitude = ctx.importNumber(json, "longitude");
                loc._altitude = ctx.importNumber(json, "altitude");
                loc._hor_accuracy = ctx.importNumber(json, "hor_accuracy");
                loc._vert_accuracy = ctx.importNumber(json, "vert_accuracy");
                loc._course = ctx.importNumber(json, "course");
                loc._speed = ctx.importNumber(json, "speed");
                return loc;
            };
            Location_.prototype.isSerializable = function () {
                return true;
            };
            Location_.prototype.toJsonKey = function () {
                return [this._latitude, this._longitude, this._altitude, this._hor_accuracy, this._vert_accuracy, this._speed, this._course];
            };
            Location_.prototype.keyCompareTo = function (o) {
                var other = o;
                var diff = this._latitude - other._latitude;
                if (diff)
                    return diff;
                diff = this._longitude - other._longitude;
                if (diff)
                    return diff;
                diff = this._altitude - other._altitude;
                if (diff)
                    return diff;
                diff = this._hor_accuracy - other._hor_accuracy;
                if (diff)
                    return diff;
                diff = this._vert_accuracy - other._vert_accuracy;
                if (diff)
                    return diff;
                diff = this._speed - other._speed;
                if (diff)
                    return diff;
                diff = this._course - other._course;
                return diff;
            };
            Location_.prototype.latitude = function () {
                return this._latitude;
            };
            Location_.prototype.longitude = function () {
                return this._longitude;
            };
            Location_.prototype.altitude = function () {
                return this._altitude;
            };
            Location_.prototype.hor_accuracy = function () {
                return this._hor_accuracy;
            };
            Location_.prototype.vert_accuracy = function () {
                return this._vert_accuracy;
            };
            Location_.prototype.speed = function () {
                return this._speed;
            };
            Location_.prototype.course = function () {
                return this._course;
            };
            Location_.prototype.toString = function () {
                return "(" + this._latitude + "," + this._longitude + ")";
            };
            Location_.prototype.equals = function (other) {
                return (this._latitude === other._latitude && this._longitude === other._longitude && this._altitude === other._altitude && this._hor_accuracy === other._hor_accuracy && this._vert_accuracy === other._vert_accuracy && this._speed === other._speed && this._course === other._course);
            };
            Location_.prototype.share = function (network, message, r) {
                var lnk = RT.Link.mk(RT.Maps.mapUrl(this), 5 /* hyperlink */);
                lnk.set_title(this.to_string());
                lnk.set_description(message);
                TDev.HTML.showProgressNotification(TDev.lf("sharing location..."));
                RT.ShareManager.shareLinkAsync(lnk, network).done(function () { return r.resume(); });
            };
            Location_.prototype.distance = function (other) {
                return Location_.computeDistance(this.latitude(), this.longitude(), other.latitude(), other.longitude());
            };
            Location_.computeDistance = function (lat1, lng1, lat2, lng2) {
                var radius = 6367.0;
                return radius * 2 * Math.asin(Math.min(1, Math.sqrt(Math.pow(Math.sin(((RT.Math_.deg_to_rad(lat2 - lat1))) / 2.0), 2.0) + Math.cos(RT.Math_.deg_to_rad(lat1)) * Math.cos(RT.Math_.deg_to_rad(lat2)) * Math.pow(Math.sin(((RT.Math_.deg_to_rad(lng2 - lng1))) / 2.0), 2.0))));
            };
            Location_.prototype.getViewCore = function (s, b) {
                var map = RT.Maps.create_map();
                map.set_center(this);
                map.add_text(this, this.latitude().toFixed(3) + ', ' + this.longitude().toFixed(3), RT.Colors.background(s), RT.Colors.foreground(s));
                return map.getViewCore(s, b);
            };
            Location_.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Location_;
        })(RT.RTValue);
        RT.Location_ = Location_;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Locations;
        (function (Locations) {
            function create_location(latitude, longitude) {
                return RT.Location_.mk(latitude, longitude, undefined, undefined, undefined, undefined, undefined);
            }
            Locations.create_location = create_location;
            function create_location_list() {
                return RT.Collections.create_location_collection();
            }
            Locations.create_location_list = create_location_list;
            function describe_location(location, r) {
                TDev.Cloud.authenticateAsync(TDev.lf("describing a location")).then(function (authenticated) {
                    if (!authenticated)
                        return TDev.Promise.as(undefined);
                    else {
                        var url = 'runtime/locations/describe?latitude=' + encodeURIComponent(location.latitude().toString()) + '&longitude=' + encodeURIComponent(location.longitude().toString());
                        var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                        r.progress('Describing location...');
                        return request.sendAsync();
                    }
                }).done(function (response) {
                    try {
                        var description = undefined;
                        var json = response ? response.content_as_json() : undefined;
                        if (json)
                            description = json.to_string();
                        r.resumeVal(description);
                    }
                    catch (ex) {
                        RT.Time.log('locations describe failed, ' + ex.message);
                        r.resumeVal(undefined);
                    }
                });
            }
            Locations.describe_location = describe_location;
            function search_location(address, postal_code, city, country, r) {
                TDev.Cloud.authenticateAsync(TDev.lf("searching a location")).then(function (authenticated) {
                    if (!authenticated)
                        return TDev.Promise.as(undefined);
                    else {
                        var url = 'runtime/locations/search?address=' + encodeURIComponent(address);
                        if (postal_code)
                            url += '&postalCode=' + encodeURIComponent(postal_code);
                        if (city)
                            url += '&city=' + encodeURIComponent(city);
                        if (country)
                            url += '&country=' + encodeURIComponent(country);
                        var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                        r.progress('Searching location...');
                        return request.sendAsync();
                    }
                }).done(function (response) {
                    try {
                        var loc = undefined;
                        var json = response ? response.content_as_json() : undefined;
                        if (json)
                            loc = RT.Location_.mkShort(json.number('latitude'), json.number('longitude'));
                        r.resumeVal(loc);
                    }
                    catch (ex) {
                        RT.Time.log('locations search failed, ' + ex.message);
                        r.resumeVal(undefined);
                    }
                });
            }
            Locations.search_location = search_location;
        })(Locations = RT.Locations || (RT.Locations = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var BingMaps;
        (function (BingMaps) {
            function createMap(el, loc, zoom) {
                var options = {
                    credentials: RT.ApiManager.bingMapsKey,
                    enableClickableLogo: false,
                    enableSearchLogo: false,
                    disableBirdseye: true,
                    showMapTypeSelector: false
                };
                if (loc)
                    options.center = new Microsoft.Maps.Location(loc.latitude(), loc.longitude());
                if (zoom)
                    options.zoom = zoom;
                var map = new Microsoft.Maps.Map(el, options);
                return map;
            }
            BingMaps.createMap = createMap;
            function isBingMapsLoaded() {
                return typeof (Microsoft) != 'undefined' && typeof (Microsoft.Maps) != 'undefined' && typeof (Microsoft.Maps.Map) != 'undefined';
            }
            BingMaps.isBingMapsLoaded = isBingMapsLoaded;
            BingMaps.mkMapAsync = function (el, loc, zoom) {
                if (isBingMapsLoaded()) {
                    return TDev.Promise.as(createMap(el, loc, zoom));
                }
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var script = document.createElement("script");
                    var loadWatcher = undefined;
                    var loadWatcher = function (retry) {
                        if (isBingMapsLoaded()) {
                            onSuccess(createMap(el, loc, zoom));
                        }
                        else {
                            if (retry-- < 0) {
                                onError(undefined);
                            }
                            else {
                                TDev.Util.setTimeout(100, function () { return loadWatcher(retry - 1); });
                            }
                        }
                    };
                    script.type = "text/javascript";
                    script.charset = "utf-8";
                    script.onload = function () {
                        if (!script.readyState || script.readyState === 'complete') {
                            loadWatcher(50);
                        }
                    };
                    script.onreadystatechange = script.onload;
                    script.onerror = function () {
                        onSuccess(undefined);
                    };
                    script.src = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1";
                    document.head.appendChild(script);
                });
            };
            function addClickHandler(pp, h) {
                Microsoft.Maps.Events.addHandler(pp, 'click', h);
            }
            BingMaps.addClickHandler = addClickHandler;
        })(BingMaps = RT.BingMaps || (RT.BingMaps = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var MapPushpin = (function (_super) {
            __extends(MapPushpin, _super);
            function MapPushpin() {
                _super.apply(this, arguments);
                this.onTap = new RT.Event_();
            }
            MapPushpin.mk = function (location, text, background, foreground, pictureUrl, taptarget) {
                if (pictureUrl === void 0) { pictureUrl = undefined; }
                if (taptarget === void 0) { taptarget = undefined; }
                var p = new MapPushpin();
                p._location = location;
                p._text = text;
                p._background = background;
                p._foreground = foreground;
                p._pictureUrl = pictureUrl;
                p._taptarget = taptarget;
                return p;
            };
            MapPushpin.prototype.on_tap = function (body) {
                return this.onTap.addHandler(body);
            };
            MapPushpin.prototype.location = function () {
                return this._location;
            };
            MapPushpin.prototype.set_location = function (loc) {
                this._location = loc;
                if (this._pp)
                    this._pp.setLocation(new Microsoft.Maps.Location(this._location.latitude(), this._location.longitude()));
            };
            MapPushpin.prototype.set_visible = function (visible) {
                if (this._pp)
                    this._pp.setOptions({ visible: visible });
            };
            MapPushpin.prototype.setOptions = function () {
                if (!this._pp)
                    return;
                var options = {
                    anchor: new Microsoft.Maps.Point(14, 25 + 16 + 16),
                    width: 39 + 20,
                    height: 25 + 16
                };
                options.htmlContent = "<div class='mapPushpin' style='";
                if (this._foreground)
                    options.htmlContent += "color:" + this._foreground.toHtml() + ";";
                if (this._background)
                    options.htmlContent += "background-color:" + this._background.toHtml() + ";";
                options.htmlContent += "'>";
                if (this._pictureUrl)
                    options.htmlContent += "<img src='" + RT.Web.html_encode(this._pictureUrl) + "' style='float:left;height:auto;max-width:39px;max-height:25px;' />";
                if (this._text)
                    options.htmlContent += "<div class='mapPushpinInner'>" + RT.Web.html_encode(this._text) + "</div>";
                options.htmlContent += "</div>";
                this._pp.setOptions(options);
            };
            MapPushpin.prototype.addToMap = function (map) {
                var _this = this;
                this._map = map;
                if (!map)
                    return;
                this._pp = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(this._location.latitude(), this._location.longitude()), {});
                this.setOptions();
                map.entities.push(this._pp);
                RT.BingMaps.addClickHandler(this._pp, function () {
                    var rt = TDev.Runtime.theRuntime;
                    if (rt) {
                        if (_this.onTap.handlers)
                            rt.queueLocalEvent(_this.onTap, []);
                        if (_this._taptarget) {
                            var evtname = "tap wall " + _this._taptarget.rtType();
                            if (rt.eventEnabled(evtname))
                                rt.eventQ.add(evtname, null, [_this._taptarget]);
                        }
                    }
                });
            };
            MapPushpin.prototype.setPictureUrl = function (url) {
                this._pictureUrl = url;
                this.setOptions();
            };
            return MapPushpin;
        })(RT.RTValue);
        RT.MapPushpin = MapPushpin;
        var MapLine = (function (_super) {
            __extends(MapLine, _super);
            function MapLine() {
                _super.apply(this, arguments);
            }
            MapLine.mk = function (locations, fill, stroke, thickness) {
                var p = new MapLine();
                p._locations = locations;
                p._fill = fill;
                p._stroke = stroke;
                p._thickness = thickness;
                return p;
            };
            MapLine.prototype.addToMap = function (map) {
                var locs = this._locations.a.map(function (l) { return new Microsoft.Maps.Location(l.latitude(), l.longitude()); });
                var options = {
                    strokeColor: new Microsoft.Maps.Color(this._stroke.a, this._stroke.r, this._stroke.g, this._stroke.b),
                    strokeThickness: Math.floor(Math.max(1, this._thickness))
                };
                var pp;
                if (this._fill) {
                    options.fillColor = new Microsoft.Maps.Color(this._fill.a, this._fill.r, this._fill.g, this._fill.b);
                    pp = new Microsoft.Maps.Polygon(locs, options);
                }
                else
                    pp = new Microsoft.Maps.Polyline(locs, options);
                map.entities.push(pp);
            };
            return MapLine;
        })(RT.RTValue);
        RT.MapLine = MapLine;
        var Map = (function (_super) {
            __extends(Map, _super);
            function Map() {
                _super.apply(this, arguments);
                this._full = false;
                this._zoom = 12;
                this._center = undefined;
                this._pushpins = [];
                this._lines = [];
            }
            Map.mk = function (full) {
                var m = new Map();
                m._full = full;
                return m;
            };
            Map.prototype.zoom = function () {
                this.syncView();
                return this._zoom;
            };
            Map.prototype.set_zoom = function (level) {
                this.syncView();
                this._zoom = level;
                this.updateView();
            };
            Map.prototype.center = function () {
                this.syncView();
                return this._center;
            };
            Map.prototype.set_center = function (center) {
                this.syncView();
                this._center = center;
                this.updateView();
            };
            Map.prototype.add_text = function (location, text, background, foreground) {
                var pp = MapPushpin.mk(location, text, background, foreground);
                this._pushpins.push(pp);
                pp.addToMap(this._map);
                return pp;
            };
            Map.prototype.add_link = function (link, background, foreground) {
                var loc = link.location();
                if (loc) {
                    var pp = MapPushpin.mk(loc, link.name() || link.address(), background, foreground, link.kind() == 'image' ? link.address() : null);
                    this._pushpins.push(pp);
                    pp.addToMap(this._map);
                    return pp;
                }
                else
                    return undefined;
            };
            Map.prototype.add_message = function (msg, background, foreground) {
                var loc = msg.location();
                if (loc)
                    return this.add_text(loc, msg.title() || msg.from(), background, foreground);
                else
                    return undefined;
            };
            Map.prototype.add_picture = function (location, picture, background) {
                var pp = MapPushpin.mk(location, undefined, background, undefined, undefined, picture);
                this._pushpins.push(pp);
                pp.addToMap(this._map);
                picture.getUrlAsync().done(function (url) { return pp.setPictureUrl(url); });
                return pp;
            };
            Map.prototype.add_place = function (place, background, foreground) {
                var loc = place.location();
                if (loc) {
                    var pp = MapPushpin.mk(loc, place.name(), background, foreground, place.picture_link(), place);
                    this._pushpins.push(pp);
                    pp.addToMap(this._map);
                    return pp;
                }
                else
                    return undefined;
            };
            Map.prototype.add_line = function (locations, color, thickness) {
                var pp = MapLine.mk(locations, undefined, color, thickness);
                this._lines.push(pp);
                if (this._map)
                    pp.addToMap(this._map);
            };
            Map.prototype.fill_region = function (locations, fill, stroke, thickness) {
                var pp = MapLine.mk(locations, fill, stroke, thickness);
                this._lines.push(pp);
                if (this._map)
                    pp.addToMap(this._map);
            };
            Map.prototype.clear = function () {
                this._pushpins = [];
                this._lines = [];
                if (this._map)
                    this._map.entities.clear();
            };
            Map.prototype.getViewCore = function (s, b) {
                var _this = this;
                var el = TDev.div("");
                el.style.display = 'inline';
                el.style.margin = '8px 8px 8px 8px';
                el.style.verticalAlign = 'top';
                el.style.width = '400px';
                el.style.height = '400px';
                el.fullScreen = this._full;
                RT.BingMaps.mkMapAsync(el, this.center(), this.zoom()).done(function (map) {
                    _this._map = map;
                    if (!_this._full)
                        _this._map.setOptions({ width: 400, height: 400 });
                    _this._lines.forEach(function (p) { return p.addToMap(_this._map); });
                    _this._pushpins.forEach(function (p) { return p.addToMap(_this._map); });
                    if (!_this._center)
                        _this.view_pushpins();
                    b.RefreshOnScreen();
                    if (_this._full && b instanceof TDev.WallBox) {
                        b.attributes.stretchwidth = 1;
                        b.attributes.stretchheight = 1;
                    }
                });
                return el;
            };
            Map.prototype.updateView = function () {
                if (this._map && this._center) {
                    var options = { zoom: this._zoom };
                    if (this._center)
                        options.center = new Microsoft.Maps.Location(this._center.latitude(), this._center.longitude());
                    this._map.setView(options);
                }
            };
            Map.prototype.syncView = function () {
                if (this._map) {
                    var c = this._map.getCenter();
                    this._center = RT.Location_.mkShort(c.latitude, c.longitude);
                    this._zoom = this._map.getZoom();
                }
            };
            Map.prototype.view_pushpins = function () {
                this.syncView();
                if (this._map && this._pushpins.length > 0) {
                    var locs = this._pushpins.map(function (p) { return new Microsoft.Maps.Location(p.location().latitude(), p.location().longitude()); });
                    var rect = Microsoft.Maps.LocationRect.fromLocations(locs);
                    this._map.setView({ bounds: rect });
                    this.syncView();
                }
            };
            Map.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Map;
        })(RT.RTValue);
        RT.Map = Map;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Maps;
        (function (Maps) {
            function create_map() {
                return RT.Map.mk(false);
            }
            Maps.create_map = create_map;
            function create_full_map() {
                return RT.Map.mk(true);
            }
            Maps.create_full_map = create_full_map;
            function directions(from, to, walking, r) {
                if (from.equals(to)) {
                    var col = RT.Collections.create_location_collection();
                    col.add(from);
                    col.add(to);
                    r.resumeVal(col);
                    return;
                }
                var url = 'runtime/maps/directions?' + 'fromLat=' + encodeURIComponent(from.latitude().toString()) + '&fromLong=' + encodeURIComponent(from.longitude().toString()) + '&toLat=' + encodeURIComponent(to.latitude().toString()) + '&toLong=' + encodeURIComponent(to.longitude().toString()) + '&walking=' + (walking ? 'true' : 'false');
                var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                r.progress('Getting directions...');
                request.sendAsync().then(function (response) {
                    try {
                        var locs = undefined;
                        var json = response.content_as_json();
                        if (json) {
                            locs = RT.Collections.create_location_collection();
                            for (var i = 0; i < json.count(); ++i) {
                                var jloc = json.at(i);
                                locs.add(RT.Location_.mkShort(jloc.number('latitude'), jloc.number('longitude')));
                            }
                        }
                        r.resumeVal(locs);
                    }
                    catch (ex) {
                        RT.Time.log('locations describe failed, ' + ex.message);
                        r.resumeVal(undefined);
                    }
                }).done();
            }
            Maps.directions = directions;
            function open_directions(start_search, start_loc, end_search, end_loc, r) {
                var url = "http://www.bing.com/maps/?v=2&rtp=";
                if (start_search)
                    url += "adr." + encodeURIComponent(start_search);
                else if (start_loc)
                    url += "pos." + encodeURIComponent(start_loc.latitude().toString()) + "_" + encodeURIComponent(start_loc.longitude().toString());
                url += "~";
                if (end_search)
                    url += "adr." + encodeURIComponent(end_search);
                else if (end_loc)
                    url += "pos." + encodeURIComponent(end_loc.latitude().toString()) + "_" + encodeURIComponent(end_loc.longitude().toString());
                url += "&lvl=12";
                RT.Web.browse(url, r);
            }
            Maps.open_directions = open_directions;
            function mapUrl(center, search, zoom) {
                if (search === void 0) { search = undefined; }
                if (zoom === void 0) { zoom = undefined; }
                var url = "http://www.bing.com/maps/?v=2&cp=" + encodeURIComponent(center.latitude().toString()) + "~" + encodeURIComponent(center.longitude().toString());
                if (search)
                    url += "&q=" + encodeURIComponent(search);
                if (zoom) {
                    var z = 1.0 + Math.max(0.0, Math.min(1.0, zoom)) * 18.0;
                    url += "&zoom=" + z;
                }
                url += "&lvl=12";
                return url;
            }
            Maps.mapUrl = mapUrl;
            function open_map(center, search, zoom, r) {
                RT.Web.browse(mapUrl(center, search, zoom), r);
            }
            Maps.open_map = open_map;
        })(Maps = RT.Maps || (RT.Maps = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Math_;
        (function (Math_) {
            function map_range(x, in_min, in_max, out_min, out_max) {
                return RT.Bits.add_int32(out_min, RT.Bits.multiply_int32(RT.Bits.subtract_int32(x, in_min), RT.Bits.divide_int32(RT.Bits.subtract_int32(out_max, out_min), RT.Bits.subtract_int32(in_max, in_min))));
            }
            Math_.map_range = map_range;
            function create_matrix(rows, columns) {
                return RT.Matrix.mk(rows, columns);
            }
            Math_.create_matrix = create_matrix;
            function ceiling(x) {
                return Math.ceil(x);
            }
            Math_.ceiling = ceiling;
            function floor(x) {
                return Math.floor(x);
            }
            Math_.floor = floor;
            function pow(x, y) {
                return Math.pow(x, y);
            }
            Math_.pow = pow;
            function random_range(min, max) {
                var r = Math_.random(max - min + 1);
                if (r == undefined)
                    return undefined;
                return min + r;
            }
            Math_.random_range = random_range;
            function random(limit) {
                var max = Math.round(limit);
                if (max == 0)
                    return 0;
                if (is_inf(max) || is_nan(max))
                    return undefined;
                var r = max;
                while (r == max)
                    r = TDev.Random.normalized() * (max);
                return Math.floor(r);
            }
            Math_.random = random;
            function random_normalized() {
                return TDev.Random.normalized();
            }
            Math_.random_normalized = random_normalized;
            function rand_norm() {
                return random_normalized();
            }
            Math_.rand_norm = rand_norm;
            function div(x, y) {
                return (x / y) | 0;
            }
            Math_.div = div;
            function mod(x, y) {
                return x % y;
            }
            Math_.mod = mod;
            function abs(x) {
                return Math.abs(x);
            }
            Math_.abs = abs;
            function acos(x) {
                return Math.acos(x);
            }
            Math_.acos = acos;
            function asin(x) {
                return Math.asin(x);
            }
            Math_.asin = asin;
            function atan(x) {
                return Math.atan(x);
            }
            Math_.atan = atan;
            function atan2(y, x) {
                return Math.atan2(y, x);
            }
            Math_.atan2 = atan2;
            function cos(angle) {
                return Math.cos(angle);
            }
            Math_.cos = cos;
            function e() {
                return Math.E;
            }
            Math_.e = e;
            function exp(x) {
                return Math.exp(x);
            }
            Math_.exp = exp;
            function log(x, base) {
                return base == 0 || base == 1 ? NaN : Math.log(x) / Math.log(base);
            }
            Math_.log = log;
            function loge(x) {
                return Math.log(x);
            }
            Math_.loge = loge;
            function log10(x) {
                return log(x, 10);
            }
            Math_.log10 = log10;
            function max(x, y) {
                return Math.max(x, y);
            }
            Math_.max = max;
            function min(x, y) {
                return Math.min(x, y);
            }
            Math_.min = min;
            function pi() {
                return Math.PI;
            }
            Math_.pi = pi;
            function gravity() {
                return 9.80665;
            }
            Math_.gravity = gravity;
            function round(x) {
                return x < 0 ? Math.ceil(x - 0.5) : Math.floor(x + 0.5);
            }
            Math_.round = round;
            function sign(x) {
                if (x < 0)
                    return -1;
                else if (x > 0)
                    return 1;
                else
                    return 0;
            }
            Math_.sign = sign;
            function sin(angle) {
                return Math.sin(angle);
            }
            Math_.sin = sin;
            function sqrt(x) {
                return Math.sqrt(x);
            }
            Math_.sqrt = sqrt;
            function tan(angle) {
                return Math.tan(angle);
            }
            Math_.tan = tan;
            function deg_to_rad(degrees) {
                return degrees / 180.0 * Math.PI;
            }
            Math_.deg_to_rad = deg_to_rad;
            function rad_to_deg(radians) {
                return radians / Math.PI * 180.0;
            }
            Math_.rad_to_deg = rad_to_deg;
            function pos_inf() {
                return Number.POSITIVE_INFINITY;
            }
            Math_.pos_inf = pos_inf;
            function neg_inf() {
                return Number.NEGATIVE_INFINITY;
            }
            Math_.neg_inf = neg_inf;
            function is_inf(x) {
                return is_pos_inf(x) || is_neg_inf(x);
            }
            Math_.is_inf = is_inf;
            function is_pos_inf(x) {
                return x == Number.POSITIVE_INFINITY;
            }
            Math_.is_pos_inf = is_pos_inf;
            function is_neg_inf(x) {
                return x == Number.NEGATIVE_INFINITY;
            }
            Math_.is_neg_inf = is_neg_inf;
            function is_nan(x) {
                return isNaN(x);
            }
            Math_.is_nan = is_nan;
            function round_with_precision(x, digits) {
                if (digits <= 0)
                    return Math.round(x);
                var d = Math.pow(10, digits);
                return Math.round(x * d) / d;
            }
            Math_.round_with_precision = round_with_precision;
            function cosh(angle) {
                return (Math.pow(Math_.e(), 2 * angle) + 1) / (2 * Math.pow(Math_.e(), angle));
            }
            Math_.cosh = cosh;
            function sinh(angle) {
                return (Math.pow(Math_.e(), 2 * angle) - 1) / (2 * Math.pow(Math_.e(), angle));
            }
            Math_.sinh = sinh;
            function tanh(angle) {
                return (Math.pow(Math_.e(), 2 * angle) - 1) / (Math.pow(Math_.e(), 2 * angle) + 1);
            }
            Math_.tanh = tanh;
            function create_number_map() {
                return RT.Collections.create_number_map();
            }
            Math_.create_number_map = create_number_map;
            function create_vector3(x, y, z) {
                return RT.Vector3.mk(x, y, z);
            }
            Math_.create_vector3 = create_vector3;
            var _epsilon = -1;
            function epsilon() {
                if (_epsilon < 0) {
                    _epsilon = 1;
                    while (1 + _epsilon != 1)
                        _epsilon /= 2;
                }
                return _epsilon;
            }
            Math_.epsilon = epsilon;
            function clamp(min, max, value) {
                return value < min ? min : value > max ? max : value;
            }
            Math_.clamp = clamp;
            function normalize(value) {
                return clamp(0, 1, value);
            }
            Math_.normalize = normalize;
            function ieee_remainder(x, y) {
                return x - (y * Math.round(x / y));
            }
            Math_.ieee_remainder = ieee_remainder;
            function range(start, length) {
                var r = [];
                for (var i = 0; i < length; ++i)
                    r.push(start + i);
                return RT.Collection.fromArray(r, "number");
            }
            Math_.range = range;
        })(Math_ = RT.Math_ || (RT.Math_ = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Media;
        (function (Media) {
            function rt_start(rt) {
            }
            Media.rt_start = rt_start;
            function rt_stop(rt) {
                RT.AudioContextManager.stop();
            }
            Media.rt_stop = rt_stop;
            function tone(frequency, gain) {
                if (RT.Math_.is_nan(frequency) || RT.Math_.is_nan(gain))
                    return;
                if (frequency <= 0)
                    RT.AudioContextManager.stop();
                else
                    RT.AudioContextManager.tone(frequency, gain);
            }
            Media.tone = tone;
            function play_note(frequency, gain, seconds, r) {
                if (RT.Math_.is_nan(frequency) || RT.Math_.is_nan(gain) || RT.Math_.is_nan(seconds) || seconds <= 0)
                    return;
                if (frequency <= 0)
                    RT.AudioContextManager.stop();
                else {
                    RT.AudioContextManager.tone(frequency, gain);
                    TDev.Util.setTimeout(seconds * 1000, function () {
                        RT.AudioContextManager.tone(frequency, 0);
                        TDev.Util.setTimeout(40, function () {
                            r.resume();
                        });
                    });
                }
            }
            Media.play_note = play_note;
            function create_picture(width, height) {
                return RT.Picture.mk(width, height);
            }
            Media.create_picture = create_picture;
            function pictureUriForMedia(uri, media) {
                return uri;
            }
            Media.pictureUriForMedia = pictureUriForMedia;
            function pictureDataUriAsync(uri) {
                return TDev.Promise.as(undefined);
            }
            Media.pictureDataUriAsync = pictureDataUriAsync;
            function choosePictureAsync(title, description) {
                if (title === void 0) { title = 'choose a picture'; }
                if (description === void 0) { description = ''; }
                var cam = navigator.camera;
                if (cam) {
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        cam.getPicture(function (url) {
                            onSuccess(RT.Picture.fromUrlSync(url, false, false));
                        }, function (msg) {
                            TDev.RT.App.logEvent(RT.App.DEBUG, "senses", "choose picture failed: " + msg, undefined);
                            onSuccess(undefined);
                        }, {
                            quality: 85,
                            mediaType: window.Camera.MediaType.JPEG,
                            sourceType: window.Camera.PictureSourceType.PHOTOLIBRARY,
                            destinationType: window.Camera.DestinationType.FILE_URI
                        });
                    });
                }
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var m = new TDev.ModalDialog();
                    var file = TDev.HTML.mkImageInput(true, -1);
                    var pic = null;
                    m.add([TDev.div("wall-dialog-header", title), TDev.div('wall-dialog-body', description), TDev.div("wall-dialog-input", file.element), TDev.div("wall-dialog-buttons", TDev.HTML.mkButtonOnce("ok", function () {
                        file.readAsync().then(function (dataUri) {
                            if (dataUri)
                                return RT.Picture.fromUrl(dataUri);
                            else
                                return TDev.Promise.as(null);
                        }).then(function (p) {
                            pic = p;
                            return p ? p.initAsync() : null;
                        }).done(function () {
                            m.dismiss();
                        });
                    }))]);
                    m.onDismiss = function () { return onSuccess(pic); };
                    m.show();
                });
            }
            Media.choosePictureAsync = choosePictureAsync;
            function choose_picture(r) {
                return choosePictureAsync().done(function (pic) { return r.resumeVal(pic); });
            }
            Media.choose_picture = choose_picture;
            function create_board(height, s) {
                return RT.Board.mk(s.rt, false, 456, height, false);
            }
            Media.create_board = create_board;
            function create_full_board(s) {
                return RT.Board.mk(s.rt, false, 480, 800, true);
            }
            Media.create_full_board = create_full_board;
            function create_portrait_board(width, height, s) {
                return RT.Board.mk(s.rt, false, width, height, true);
            }
            Media.create_portrait_board = create_portrait_board;
            function create_landscape_board(width, height, s) {
                return RT.Board.mk(s.rt, true, width, height, true);
            }
            Media.create_landscape_board = create_landscape_board;
            var iconNames = [
                '123',
                '8ball',
                'abc',
                'acorn',
                'add',
                'addcircle',
                'addfolder',
                'addressbook',
                'adduser',
                'adminuser',
                'airplane',
                'aligncenter',
                'alignleft',
                'alignright',
                'almostequal',
                'alram',
                'anchor',
                'appointment',
                'approvebutton',
                'arrowbox',
                'arrowcirclealt',
                'arrow-circle-r',
                'arrowcirclerounded',
                'arrowdotted',
                'arrowdownl',
                'arrowdownr',
                'arrowdownrounded',
                'arrowhead',
                'arrowlarge',
                'arrowlr',
                'arrowmoving',
                'arrowr',
                'arrowrlarge',
                'arrowrounded',
                'arrowstandard',
                'arrowstandardcircle',
                'award',
                'barchart',
                'beer',
                'bell',
                'binoculars',
                'blankpage',
                'bold',
                'bolt',
                'bomb',
                'book',
                'bookmark',
                'briefcase',
                'brush',
                'bulletlist',
                'bullseye',
                'business',
                'businesscard',
                'businessperson',
                'butterfly',
                'cactus',
                'calculator',
                'callout',
                'camera',
                'capitalize',
                'caution',
                'chapback',
                'chapbackcircle',
                'chapforward',
                'chargingbattery',
                'check',
                'checkalt',
                'checkbox',
                'checkcircle',
                'checkcirclealt',
                'cherry',
                'clipboard',
                'clock',
                'clover',
                'club',
                'coffeecup',
                'command',
                'commandline',
                'construction',
                'contacts',
                'controller',
                'controls',
                'copyright',
                'creditcard',
                'cube',
                'cut',
                'cycle',
                'dashboard',
                'delete',
                'deleteuser',
                'deliverytruck',
                'directions',
                'document',
                'documents',
                'documentsalt',
                'dollar',
                'downbox',
                'download',
                'downloadbutton',
                'downloadbuttonalt',
                'downloadpage',
                'drawing',
                'email',
                'emaildoc',
                'emailopen',
                'emergency',
                'emptybattery',
                'erase',
                'euro',
                'exclamation',
                'exclamationcircle',
                'exclamationcirclealt',
                'exit',
                'expand',
                'eye',
                'farm',
                'female',
                'files',
                'film',
                'fire',
                'fit',
                'fithorizontal',
                'flag',
                'fleurdelis',
                'flipchart',
                'flowchart',
                'folder',
                'formattext',
                'forward',
                'forwardbutton',
                'fourcolumn',
                'fullbattery',
                'funnel',
                'gaspump',
                'globe',
                'globea',
                'globeas',
                'globeaus',
                'globeeua',
                'globesa',
                'globeus',
                'government',
                'gps',
                'grapes',
                'graph',
                'group',
                'halfbattery',
                'hammer',
                'headphones',
                'heart',
                'heartalt',
                'help',
                'home',
                'homealt',
                'horn',
                'horseshoe',
                'hourglass',
                'im',
                'inbox',
                'info',
                'infocircle',
                'infocirclealt',
                'italic',
                'journal',
                'joystick',
                'justified',
                'key',
                'lab',
                'ladder',
                'leaf',
                'lightbulb',
                'linechart',
                'link',
                'loading',
                'loadingalt',
                'location',
                'lock',
                'lockedfolder',
                'male',
                'map',
                'martini',
                'maximize',
                'megaphone',
                'mic',
                'minusbox',
                'minusboxalt',
                'mobilephone',
                'money',
                'monitor',
                'moon',
                'mountains',
                'movie',
                'mp3player',
                'multiply',
                'multiplycircle',
                'music',
                'mute',
                'needle',
                'newpage',
                'newpagealt',
                'nextscenebutton',
                'ninecolumn',
                'notebook',
                'numberedlist',
                'omega',
                'openfolder',
                'package',
                'pagecurl',
                'paint',
                'painting',
                'paperclip',
                'pause',
                'pausecircle',
                'pear',
                'pen',
                'penalt',
                'pencil',
                'person',
                'phone',
                'photo',
                'photos',
                'pie',
                'piechart',
                'play',
                'playbutton',
                'playcircle',
                'plusbox',
                'plusboxalt',
                'pluscircle',
                'pound',
                'power',
                'presentation',
                'pricetag',
                'printer',
                'pushpin',
                'question',
                'questioncircle',
                'questioncirclealt',
                'quote',
                'raindrop',
                'reading',
                'recycle',
                'removebutton',
                'removefolder',
                'removepage',
                'removeuser',
                'restore',
                'revert',
                'rewind',
                'rewindcircle',
                'ribbon',
                'runningman',
                'save',
                'savealt',
                'screwdriver',
                'search',
                'setting',
                'settings',
                'share',
                'sharethis',
                'shield',
                'shirt',
                'shoppingbag',
                'shoppingbasket',
                'shoppingcart',
                'shoppingcartalt',
                'shrink',
                'shuffle',
                'signal',
                'signalalt',
                'sixcolumn',
                'smartphone',
                'smiliehappy',
                'smiliehappyalt',
                'smiliejustok',
                'smiliejustokalt',
                'smiliesad',
                'smiliesadalt',
                'sms',
                'smsalt',
                'snowflake',
                'sort',
                'sortaz',
                'sound',
                'soundhigh',
                'soundlow',
                'space',
                'spade',
                'split',
                'stacks',
                'star',
                'staralt',
                'strikeout',
                'subtract',
                'subtractcircle',
                'suitcase',
                'sun',
                'switch',
                'tableft',
                'tabright',
                'tanktop',
                'target',
                'terminal',
                'text',
                'threecolumn',
                'thumbsdown',
                'ticket',
                'tools',
                'touchpad',
                'trash',
                'tree',
                'umbrella',
                'underline',
                'unlock',
                'upbox',
                'upload',
                'video',
                'videocam',
                'wand',
                'warning',
                'warningalt',
                'watch',
                'weather',
                'wheel',
                'wifi',
                'wine',
                'workorder',
                'wrench',
                'writepage',
                'yen',
                'zoomin',
                'zoomout'
            ];
            function icon_names() {
                return RT.Collection.mkStrings(iconNames.slice(0));
            }
            Media.icon_names = icon_names;
            function load_icon(name, size) {
                if (iconNames.indexOf(name.toLowerCase()) < 0)
                    return undefined;
                return RT.Picture.fromSVGIcon(name.toLowerCase(), size);
            }
            function icon(name) {
                return load_icon(name, 48);
            }
            Media.icon = icon;
            function large_icon(name) {
                return load_icon(name, 96);
            }
            Media.large_icon = large_icon;
        })(Media = RT.Media || (RT.Media = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Message = (function (_super) {
            __extends(Message, _super);
            function Message() {
                _super.call(this);
                this._id = undefined;
                this._title = undefined;
                this._message = undefined;
                this._from = undefined;
                this._to = undefined;
                this._picture_link = undefined;
                this._link = undefined;
                this._media_link = undefined;
                this._location = undefined;
                this._time = undefined;
                this._source = undefined;
                this._values = new RT.StringMap();
            }
            Message.mk = function (message) {
                var m = new Message();
                m.set_message(message);
                m.set_source("");
                m.set_from(TDev.lf("me"));
                return m;
            };
            Message.prototype.title = function () {
                return this._title;
            };
            Message.prototype.set_title = function (title) {
                this._title = title;
            };
            Message.prototype.message = function () {
                return this._message;
            };
            Message.prototype.set_message = function (message) {
                this._message = message;
            };
            Message.prototype.id = function () {
                return this._id;
            };
            Message.prototype.set_id = function (value) {
                this._id = value;
            };
            Message.prototype.from = function () {
                return this._from;
            };
            Message.prototype.set_from = function (author) {
                this._from = author;
            };
            Message.prototype.to = function () {
                return this._to;
            };
            Message.prototype.set_to = function (author) {
                this._to = author;
            };
            Message.prototype.picture_link = function () {
                return this._picture_link;
            };
            Message.prototype.set_picture_link = function (url) {
                this._picture_link = url;
            };
            Message.prototype.link = function () {
                return this._link;
            };
            Message.prototype.set_link = function (url) {
                this._link = url;
            };
            Message.prototype.media_link = function () {
                return this._media_link;
            };
            Message.prototype.set_media_link = function (url) {
                this._media_link = url;
            };
            Message.prototype.location = function () {
                return this._location;
            };
            Message.prototype.set_location = function (location) {
                this._location = location;
            };
            Message.prototype.time = function () {
                return this._time || RT.DateTime.defaultValue;
            };
            Message.prototype.set_time = function (time) {
                this._time = time;
            };
            Message.prototype.source = function () {
                return this._source;
            };
            Message.prototype.set_source = function (source) {
                this._source = source;
            };
            Message.prototype.toString = function () {
                var sb = '';
                if (this.title())
                    sb += this.title() + '\n';
                if (this.message())
                    sb += this.message() + '\n';
                if (this.from() && this.from() != "me")
                    sb += "from " + this.from() + '\n';
                if (this.to())
                    sb += "to " + this.to() + '\n';
                if (this.link())
                    sb += "at " + this.link() + '\n';
                if (this.picture_link())
                    sb += "with " + this.picture_link() + '\n';
                if (this.media_link())
                    sb += "with " + this.media_link() + '\n';
                if (this.location())
                    sb += "at location " + this.location().toString() + '\n';
                if (this.source())
                    sb += "source " + this.source() + '\n';
                if (this.time() && !this.time().isDefaultValue())
                    sb += this.time().from_now() + '\n';
                return sb;
            };
            Message.prototype.getViewCore = function (s, b) {
                var _this = this;
                var d = TDev.div("item");
                if (this.picture_link())
                    d.appendChild(TDev.img("item-image", this.picture_link(), "linked picture"));
                var dc = TDev.div("item-info");
                d.appendChild(dc);
                if (this.from())
                    dc.appendChild(TDev.div("item-title", this.from()));
                if (this.title())
                    dc.appendChild(TDev.div("item-subtitle", this.title()));
                if (this.message())
                    dc.appendChild(TDev.div("item-description", TDev.tweetify(this.message())));
                var subtle = this.source() || '';
                if (this.time() && !this.time().isDefaultValue())
                    subtle += ' ' + this.time().from_now();
                dc.appendChild(TDev.div("item-subtle", subtle));
                if (this.link() || this.media_link()) {
                    var f = function () { return RT.Web.browseAsync(_this.link()).done(); };
                    if (this.media_link()) {
                        f = function () { return RT.Web.play_media(_this.media_link()); };
                    }
                    b.withClick(f);
                }
                return d;
            };
            Message.prototype.share = function (network, r) {
                TDev.HTML.showProgressNotification(TDev.lf("sharing message..."));
                RT.ShareManager.shareTextAsync(this.toString(), network).done(function () { return r.resume(); });
            };
            Message.prototype.values = function () {
                return this._values;
            };
            Message.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Message;
        })(RT.RTValue);
        RT.Message = Message;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Number_;
        (function (Number_) {
            function to_string(self) {
                return self.toString();
            }
            Number_.to_string = to_string;
            function fromArtUrl(url) {
                return TDev.Promise.wrap(RT.String_.to_number(url));
            }
            Number_.fromArtUrl = fromArtUrl;
            function post_to_wall(self, s) {
                var box = s.rt.postBoxedText(self.toString(), s.pc);
            }
            Number_.post_to_wall = post_to_wall;
            function to_character(self) {
                var c = Math.round(self);
                if (c < -0x8000 || c > 0xFFFF)
                    return undefined;
                c &= 0xFFFF;
                return String.fromCharCode(c);
            }
            Number_.to_character = to_character;
            function to_color(self) {
                return RT.Color.fromInt32(self);
            }
            Number_.to_color = to_color;
            function picker() {
                var inp = TDev.HTML.mkTextInput("number", TDev.lf("number"));
                return {
                    html: inp,
                    validate: function () { return /^[+-]?[0-9]+(\.[0-9]+)?$/.test(inp.value); },
                    get: function () { return parseFloat(inp.value); },
                    set: function (v) {
                        inp.value = v + "";
                    }
                };
            }
            Number_.picker = picker;
            function to_json(self) {
                return RT.JsonObject.wrap(self);
            }
            Number_.to_json = to_json;
            function add(self, other) {
                return 0;
            }
            Number_.add = add;
            function subtract(self, other) {
                return 0;
            }
            Number_.subtract = subtract;
            function multiply(self, other) {
                return 0;
            }
            Number_.multiply = multiply;
            function divide(self, other) {
                return 0;
            }
            Number_.divide = divide;
            function eq(self, other) {
                return false;
            }
            Number_.eq = eq;
            function neq(self, other) {
                return false;
            }
            Number_.neq = neq;
            function le(self, other) {
                return false;
            }
            Number_.le = le;
            function lt(self, other) {
                return false;
            }
            Number_.lt = lt;
            function ge(self, other) {
                return false;
            }
            Number_.ge = ge;
            function gt(self, other) {
                return false;
            }
            Number_.gt = gt;
        })(Number_ = RT.Number_ || (RT.Number_ = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var NumberMap = (function (_super) {
            __extends(NumberMap, _super);
            function NumberMap() {
                _super.call(this);
                this.items = new Object();
                this.length = 0;
                this._canvas = undefined;
            }
            NumberMap.prototype.count = function () {
                return this.length;
            };
            NumberMap.prototype.clear = function () {
                this.items = new Object();
                this.length = 0;
            };
            NumberMap.prototype.sum = function () {
                var _this = this;
                var r = 0;
                Object.keys(this.items).forEach(function (key) {
                    var value = _this.at_key(key);
                    r += value;
                });
                return r;
            };
            NumberMap.prototype.avg = function () {
                return this.sum() / this.length;
            };
            NumberMap.prototype.slice = function (start, end) {
                var _this = this;
                var nm = new NumberMap();
                Object.keys(this.items).forEach(function (skey) {
                    var value = _this.at_key(skey);
                    var key = parseFloat(skey);
                    if (start <= key && key < end)
                        nm.set_at_key(skey, value);
                });
                return nm;
            };
            NumberMap.prototype.min = function () {
                var _this = this;
                if (this.length == 0)
                    return undefined;
                var r = Number.MAX_VALUE;
                Object.keys(this.items).forEach(function (key) {
                    var value = _this.at_key(key);
                    if (value < r)
                        r = value;
                });
                return r;
            };
            NumberMap.prototype.max = function () {
                var _this = this;
                if (this.length == 0)
                    return undefined;
                var r = Number.MIN_VALUE;
                Object.keys(this.items).forEach(function (key) {
                    var value = _this.at_key(key);
                    if (value > r)
                        r = value;
                });
                return r;
            };
            NumberMap.prototype.at_key = function (key) {
                var result = (this.items)[key];
                if (!result) {
                    return 0;
                }
                return (result);
            };
            NumberMap.prototype.at = function (index) {
                var key = index.toString();
                return this.at_key(key);
            };
            NumberMap.prototype.set_at = function (index, value) {
                var key = index.toString();
                this.set_at_key(key, value);
            };
            NumberMap.prototype.set_at_key = function (key, value) {
                var val = this.items[key];
                if (val != undefined)
                    this.length--;
                this.items[key] = value;
                if (value != undefined)
                    this.length++;
            };
            NumberMap.prototype.set_many = function (numbers) {
                var _this = this;
                Object.keys(numbers.items).forEach(function (key) {
                    var value = numbers.at_key(key);
                    _this.set_at_key(key, value);
                });
            };
            NumberMap.prototype.remove = function (index) {
                var val = this.items[index];
                if (val != undefined) {
                    this.length--;
                    this.items[index] = undefined;
                }
            };
            NumberMap.prototype.toString = function () {
                var _this = this;
                var s = "{";
                var count = 0;
                Object.keys(this.items).forEach(function (key) {
                    if (count++ <= 20) {
                        var value = _this.at_key(key);
                        if (s.length > 1)
                            s += ", ";
                        s += key + "->" + value;
                    }
                });
                if (count == 20)
                    s += ', ...';
                s += "}";
                return s;
            };
            NumberMap.prototype.get_enumerator = function () {
                var k = Object.keys(this.items).map(parseFloat);
                k.sort(function (a, b) { return a - b; });
                return k;
            };
            NumberMap.prototype.update_on_wall = function () {
                this.updateCanvas();
            };
            NumberMap.prototype.updateCanvas = function () {
                var _this = this;
                if (this._canvas) {
                    this._canvas.height = this._canvas.width;
                    var points = [];
                    Object.keys(this.items).forEach(function (skey) {
                        var key = parseFloat(skey);
                        var value = _this.at_key(skey);
                        points.push(new TDev.RT.Charts.Point(key, value));
                    });
                    new TDev.RT.Charts.CanvasChart().drawChart(this._canvas, points);
                }
            };
            NumberMap.prototype.updateViewCore = function (s, b) {
                this.updateCanvas();
            };
            NumberMap.prototype.getViewCore = function (s, b) {
                this._canvas = document.createElement("canvas");
                return this._canvas;
            };
            NumberMap.prototype.to_json = function () {
                return RT.JsonObject.wrap(this.exportJson(null));
            };
            NumberMap.prototype.from_json = function (jobj) {
                this.importJson(null, jobj.value());
            };
            NumberMap.prototype.exportJson = function (ctx) {
                var _this = this;
                var obj = {};
                Object.keys(this.items).forEach(function (k) {
                    obj[k] = _this.items[k];
                });
                return obj;
            };
            NumberMap.prototype.importJson = function (ctx, json) {
                var _this = this;
                if ((typeof (json) !== "object") || Array.isArray(json)) {
                    this.clear();
                    return this;
                }
                else {
                    this.items = {};
                    this.length = 0;
                    Object.keys(json).forEach(function (k) {
                        var v = json[k];
                        if (typeof v == "number") {
                            _this.items[k] = v;
                            _this.length++;
                        }
                    });
                }
            };
            NumberMap.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            NumberMap.prototype.debuggerDisplay = function (clickHandler) {
                return TDev.span(null, "NumberMap[" + this.length + "]").withClick(clickHandler);
            };
            NumberMap.prototype.debuggerChildren = function () {
                var ret = {};
                var items = this.items;
                Object.keys(items).forEach(function (k) {
                    ret["at(" + k + ")"] = items[k];
                });
                return ret;
            };
            return NumberMap;
        })(RT.RTValue);
        RT.NumberMap = NumberMap;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Page = (function (_super) {
            __extends(Page, _super);
            function Page() {
                _super.call(this);
            }
            Page.mk = function (p) {
                if (!p)
                    return undefined;
                var r = new Page();
                r.page = p;
                return r;
            };
            Page.prototype.on_navigated_from = function (body) {
                return this.page.onNavigatedFrom.addHandler(body);
            };
            Page.prototype.equals = function (other) {
                return this.page === other.page;
            };
            Page.prototype.post_to_wall = function () {
            };
            return Page;
        })(RT.RTValue);
        RT.Page = Page;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var PageButton = (function (_super) {
            __extends(PageButton, _super);
            function PageButton() {
                _super.call(this);
            }
            PageButton.mk = function (icon, text, page) {
                var pb = new PageButton();
                pb._icon = icon;
                pb._text = text;
                pb._page = page;
                return pb;
            };
            PageButton.prototype.page = function () {
                return this._page;
            };
            PageButton.prototype.equals = function (page_button) {
                return this === page_button;
            };
            PageButton.prototype.post_to_wall = function (s) {
            };
            PageButton.prototype.icon = function () {
                return this._icon;
            };
            PageButton.prototype.text = function () {
                return this._text;
            };
            PageButton.prototype.getElement = function () {
                if (!this._element) {
                    this._element = TDev.HTML.mkButtonElt("topMenu-button", [
                        TDev.div("topMenu-button-frame", RT.PageButtonManager.getIconElement(this._icon)),
                        TDev.div("topMenu-button-desc", this._text)
                    ]);
                    this._element.style.display = 'inline-block';
                }
                return this._element;
            };
            return PageButton;
        })(RT.RTValue);
        RT.PageButton = PageButton;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var PageButtonManager;
        (function (PageButtonManager) {
            var _iconSymbols = {
                "add": "add",
                "back": "back",
                "cancel": "cancel",
                "check": "check",
                "close": "cancel",
                "delete": "delete",
                "download": "download",
                "edit": "edit",
                "favs.addto": "heart",
                "favs": "star",
                "feature.camera": "camera",
                "feature.email": "email",
                "feature.search": "search",
                "feature.settings": "settings",
                "feature.video": "video",
                "folder": "folder",
                "minus": "subtract",
                "new": "newpage",
                "next": "forward",
                "questionmark": "question",
                "refresh": "recycle",
                "save": "save",
                "share": "sharethis",
                "stop": "stop",
                "sync": "cycle",
                "transport.ff": "forward",
                "transport.pause": "pause",
                "transport.play": "play",
                "transport.rew": "rewind",
                "upload": "upload"
            };
            PageButtonManager.getIconElement = function (name) {
                var symbol = _iconSymbols[name];
                if (!symbol)
                    return TDev.span('', name.slice(0, 1));
                else
                    return TDev.HTML.mkImg('svg:' + symbol + ",currentColor");
            };
        })(PageButtonManager = RT.PageButtonManager || (RT.PageButtonManager = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Phone;
        (function (Phone) {
            function dial_phone_number(n, r) {
                var m = new TDev.ModalDialog();
                m.add([TDev.div("wall-dialog-header", TDev.lf("call number")), TDev.div("wall-dialog-body", n)]);
                if (TDev.Browser.isCellphone)
                    m.add(TDev.div("wall-dialog-body", TDev.lf("note: install the Skype app to place Skype calls.")));
                else
                    m.add(TDev.div("wall-dialog-body", TDev.lf("note: Phone calls might not be supported on this platform. Install the Skype app to place Skype calls.")));
                m.add(TDev.div("wall-dialog-buttons", [
                    TDev.HTML.mkButton(TDev.lf("call"), function () {
                        m.onDismiss = null;
                        m.dismiss();
                        var url = "tel:" + encodeURIComponent(n || " ");
                        RT.Web.browse(url, r);
                    }),
                    TDev.HTML.mkButton(TDev.lf("Skype"), function () {
                        m.onDismiss = null;
                        m.dismiss();
                        var url = "skype:" + encodeURIComponent(n || " ");
                        RT.Web.browse(url, r);
                    }),
                ]));
                m.onDismiss = function () { return r.resume(); };
                m.show();
            }
            Phone.dial_phone_number = dial_phone_number;
            function save_phone_number(phone_number) {
            }
            Phone.save_phone_number = save_phone_number;
            function save_contact(contact) {
                RT.Social.save_contact(contact);
            }
            Phone.save_contact = save_contact;
            function vibrate(seconds) {
                Phone.vibrateCore(seconds);
            }
            Phone.vibrate = vibrate;
            Phone.vibrateCore = function (seconds) {
                if (window.navigator.vibrate) {
                    var ms = Math.min(5, Math.max(0.02, seconds)) * 1000.0;
                    window.navigator.vibrate(ms);
                }
            };
            function power_source(r) {
                r.resumeVal("");
            }
            Phone.power_source = power_source;
        })(Phone = RT.Phone || (RT.Phone = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Picture = (function (_super) {
            __extends(Picture, _super);
            function Picture() {
                _super.call(this);
                this._date = undefined;
                this._location = undefined;
                this._isResource = false;
                this._isReadOnly = false;
                this.imageData = null;
                this.imageDataHasChanges = false;
                this.fitToColumn = false;
            }
            Picture.prototype.clearUrl = function () {
                this._url = undefined;
            };
            Picture.prototype.getReadonlyUrlSync = function () {
                if (this._isReadOnly && this._url && !this.canvas && !/^data:/.test(this._url))
                    return this._url;
                return undefined;
            };
            Picture.prototype.getUrlAsync = function () {
                var url = this.getReadonlyUrlSync();
                if (url)
                    return TDev.Promise.as(url);
                return this.getDataUriAsync();
            };
            Picture.prototype.getDataUriAsync = function (quality, maxWidth) {
                var _this = this;
                if (quality === void 0) { quality = 0.95; }
                if (maxWidth === void 0) { maxWidth = -1; }
                return this.initAsync().then(function () {
                    _this.commitImageData();
                    return _this.getDataUri(quality, maxWidth);
                });
            };
            Picture.prototype.getImageElement = function () {
                if (this._isReadOnly && this._url && !this.canvas) {
                    TDev.Util.log("img: direct display " + this._url.slice(0, 100));
                    var img = TDev.createElement("img");
                    img.src = this._url;
                    img.alt = this._url;
                    return img;
                }
                return undefined;
            };
            Picture.prototype.getDataUri = function (quality, maxWidth, forceJpeg) {
                if (quality === void 0) { quality = 0.9; }
                if (maxWidth === void 0) { maxWidth = -1; }
                if (forceJpeg === void 0) { forceJpeg = false; }
                this.commitImageData();
                var c = this.getCanvas();
                if (c.width == 0 || c.height == 0) {
                    c = document.createElement('canvas');
                    c.width = 1;
                    c.height = 1;
                }
                if (maxWidth > 0 && c.width > maxWidth) {
                    var temp = document.createElement('canvas');
                    temp.width = maxWidth;
                    temp.height = maxWidth / c.width * c.height;
                    var tempCtx = temp.getContext("2d");
                    tempCtx.drawImage(c, 0, 0, c.width, c.height, 0, 0, temp.width, temp.height);
                    c = temp;
                }
                if (quality >= 1 && !forceJpeg)
                    return c.toDataURL('image/png');
                else
                    return c.toDataURL('image/jpeg', quality);
            };
            Picture.mk = function (w, h) {
                var p = new Picture();
                p.initFn = function () {
                    p._init(w, h);
                    return TDev.Promise.as();
                };
                return p;
            };
            Picture.mkSync = function (w, h) {
                var p = new Picture();
                p.initPromise = TDev.Promise.as();
                p._init(w, h);
                return p;
            };
            Picture.prototype.imgLoadAsync = function (url, cors, dataUrl) {
                var _this = this;
                if (dataUrl === void 0) { dataUrl = null; }
                var rt = TDev.Runtime.theRuntime;
                var auth = (!dataUrl && cors && !TDev.Cloud.isArtUrl(url)) ? TDev.Cloud.authenticateAsync(TDev.lf("image proxying")) : TDev.Promise.as(true);
                return auth.then(function (authenticated) {
                    TDev.Util.log('picture load: 0');
                    if (dataUrl) {
                        TDev.Util.log('picture load: dataurl, skipping wab request');
                        return undefined;
                    }
                    else
                        return RT.Media.pictureDataUriAsync(url);
                }).then(function (d) {
                    if (!dataUrl && d) {
                        TDev.Util.log('picture: updated dataurl');
                        dataUrl = d;
                    }
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        TDev.Util.log('picture: loading');
                        var img = document.createElement("img");
                        img.onload = function () {
                            TDev.Util.log('picture: loaded ' + img.width + 'x' + img.height);
                            _this._init(img.width, img.height);
                            _this._url = url;
                            _this._cors = cors;
                            _this.ctx.drawImage(img, 0, 0);
                            img = null;
                            dataUrl = null;
                            href = null;
                            onSuccess(_this);
                        };
                        img.onerror = function () {
                            TDev.Util.log('picture: failed to load');
                            _this._init(480, 480);
                            _this._url = url;
                            _this._cors = cors;
                            _this.ctx.save();
                            _this.ctx.fillStyle = "lightgray";
                            _this.ctx.fillRect(0, 0, 480, 480);
                            _this.ctx.fillStyle = "white";
                            _this.ctx.textAlign = "center";
                            _this.ctx.textBaseline = "top";
                            _this.ctx.font = "240px sans-serif";
                            _this.ctx.fillText(':(', 240, 60);
                            _this.ctx.font = "42px sans-serif";
                            _this.ctx.fillText('picture failed to load', 240, 360);
                            _this.ctx.restore();
                            img = null;
                            dataUrl = null;
                            href = null;
                            onSuccess(_this);
                        };
                        var href = dataUrl ? dataUrl : cors ? RT.Web.proxy(TDev.Cloud.toCdnUrl(url)) : url;
                        img.src = href;
                        img.alt = url;
                    });
                });
            };
            Picture.prototype.delayLoadSync = function (f) {
                this.initFn = f;
                return this;
            };
            Picture.prototype.delayLoad = function (f) {
                this.delayLoadSync(f);
                return TDev.Promise.as(this);
            };
            Picture.delayed = function (f) {
                return new Picture().delayLoad(f);
            };
            Picture.fromImage = function (img) {
                var p = Picture.mkSync(img.width, img.height);
                p.ctx.save();
                p.ctx.drawImage(img, 0, 0, img.width, img.height);
                p.ctx.restore();
                return p;
            };
            Picture.fromCanvas = function (canvas) {
                var p = Picture.mkSync(canvas.width, canvas.height);
                p.ctx.save();
                p.ctx.drawImage(canvas, 0, 0, canvas.width, canvas.height);
                p.ctx.restore();
                return p;
            };
            Picture.fromDataUrl = function (dataUrl, originalUrl, isResource) {
                if (originalUrl === void 0) { originalUrl = null; }
                if (isResource === void 0) { isResource = false; }
                if (!dataUrl)
                    return TDev.Promise.as(null);
                TDev.Util.log('picture: loading from dataurl');
                TDev.Util.check(/^data:image\/(jpeg|png|svg\+xml);base64,/i.test(dataUrl));
                var img = new Picture();
                img._isResource = isResource;
                img._isReadOnly = isResource;
                return img.delayLoad(function (p) { return p.imgLoadAsync(originalUrl, false, dataUrl); });
            };
            Picture.fromUrlSync = function (url, isReadOnly, cors) {
                if (isReadOnly === void 0) { isReadOnly = false; }
                if (cors === void 0) { cors = true; }
                var img = new Picture();
                img._url = url;
                img._isResource = false;
                img._isReadOnly = isReadOnly;
                return img.delayLoadSync(function (p) { return p.loadAsync(url, cors); });
            };
            Picture.fromUrl = function (url, isReadOnly, cors) {
                if (isReadOnly === void 0) { isReadOnly = false; }
                if (cors === void 0) { cors = true; }
                return TDev.Promise.as(Picture.fromUrlSync(url, isReadOnly, cors));
            };
            Picture.patchLocalArtUrl = function (url) {
                return url;
            };
            Picture.fromArtUrl = function (url) {
                if (/^data:image\/(jpeg|png|svg\+xml);base64,/i.test(url))
                    return Picture.fromDataUrl(url, undefined, true);
                var cors = true;
                if (/^\.\/art\//.test(url)) {
                    url = Picture.patchLocalArtUrl(url);
                    cors = false;
                }
                return RT.ArtCache.getArtAsync(url, "image/*").then(function () {
                    TDev.Util.log('picture: fromArtUrl delayed');
                    var img = new Picture();
                    img._url = url;
                    img._isResource = true;
                    img._isReadOnly = true;
                    return img.delayLoad(function (p) { return p.loadAsync(url, cors); });
                });
            };
            Picture.prototype.loadAsync = function (url, cors) {
                var _this = this;
                if (/^data:image\/(jpeg|png|svg\+xml);base64,/i.test(url))
                    return this.imgLoadAsync(url, false, url);
                if (this._isResource || TDev.Cloud.isArtUrl(url))
                    return RT.ArtCache.getArtAsync(url, "image/*").then(function (dataUrl) { return _this.imgLoadAsync(url, cors, dataUrl); });
                return this.imgLoadAsync(url, cors);
            };
            Picture.fromSVGIcon = function (name, sz) {
                var p = Picture.mkSync(sz, sz);
                p.ctx.save();
                var scale = sz / 480;
                p.ctx.fillStyle = "white";
                p.ctx.scale(scale, scale);
                TDev.SVG.drawSVG(p.ctx, name);
                p.ctx.restore();
                p.fitToColumn = false;
                return p;
            };
            Picture.prototype._init = function (w, h) {
                w = Math.round(w);
                h = Math.round(h);
                this.slowlyloadingelement = undefined;
                this.canvas = document.createElement("canvas");
                this.canvas.width = w;
                this.canvas.height = h;
                this.ctx = this.canvas.getContext("2d");
            };
            Picture.prototype.commitImageData = function () {
                if (this.imageDataHasChanges) {
                    this.imageDataHasChanges = false;
                    this.ctx.putImageData(this.imageData, 0, 0);
                }
            };
            Picture.prototype.changed = function (invalidateData) {
                if (invalidateData === void 0) { invalidateData = true; }
                if (this._isReadOnly)
                    TDev.Util.userError(TDev.lf("This picture cannot be modified. Use 'clone' to get a copy of the picture that can be modified.\n\n    var pic := \u273fmy art->clone"));
                if (invalidateData) {
                    this.commitImageData();
                    this.imageData = null;
                }
                this.versioncounter++;
                this._url = undefined;
            };
            Picture.prototype.getImageData = function () {
                TDev.Util.assert(!!this.ctx);
                if (!this.imageData)
                    this.imageData = this.ctx.getImageData(0, 0, this.widthSync(), this.heightSync());
                return this.imageData;
            };
            Picture.prototype.hasCanvas = function () {
                return !!this.canvas;
            };
            Picture.prototype.widthSync = function () {
                return this.canvas.width;
            };
            Picture.prototype.heightSync = function () {
                return this.canvas.height;
            };
            Picture.prototype.getCanvas = function () {
                TDev.Util.assert(!!this.canvas);
                return this.canvas;
            };
            Picture.prototype.count = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this.canvas.width * _this.canvas.height;
                });
            };
            Picture.prototype.date = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this._date;
                });
            };
            Picture.prototype.height = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this.canvas.height;
                });
            };
            Picture.prototype.equals = function (other_picture) {
                return this == other_picture;
            };
            Picture.prototype.is_panorama = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this.canvas.width > _this.canvas.height;
                });
            };
            Picture.prototype.location = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this._location;
                });
            };
            Picture.prototype.width = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    return _this.canvas.width;
                });
            };
            Picture.prototype.update_on_wall = function () {
                if (this.imageData)
                    this.ctx.putImageData(this.imageData, 0, 0);
            };
            Picture.prototype.at = function (index, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    if (isNaN(index))
                        return RT.Colors.transparent();
                    index = Math.round(index);
                    index *= 4;
                    var id = _this.getImageData();
                    if (index < 0 || index >= id.data.length)
                        return RT.Colors.transparent();
                    return RT.Color.fromArgb(id.data[index + 3], id.data[index], id.data[index + 1], id.data[index + 2]);
                });
            };
            Picture.prototype.initAsync = function () {
                var _this = this;
                if (this.initPromise)
                    return this.initPromise;
                var f = this.initFn;
                if (f) {
                    this.initFn = null;
                    this.initPromise = f(this);
                    this.initPromise.done(function () {
                        _this.initPromise = null;
                    });
                    if (this.initPromise)
                        return this.initPromise;
                }
                return TDev.Promise.as();
            };
            Picture.prototype.loadFirst = function (r, f) {
                TDev.Util.assert(!!r);
                if (!this.initPromise && !this.initFn) {
                    if (!f)
                        r.resume();
                    else
                        r.resumeVal(f());
                }
                else {
                    this.initAsync().done(function () {
                        if (!f)
                            r.resume();
                        else
                            r.resumeVal(f());
                    });
                }
            };
            Picture.prototype.atPosition = function (r, left, top, angle, opacity, f) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    _this.ctx.translate(left, top);
                    _this.ctx.rotate(angle / 180 * Math.PI);
                    _this.ctx.globalAlpha = RT.Math_.normalize(opacity);
                    f();
                    _this.ctx.restore();
                });
            };
            Picture.prototype.blend = function (other, left, top, angle, opacity, r) {
                var _this = this;
                opacity = RT.Math_.normalize(opacity);
                this.atPosition(r, left, top, angle, opacity, function () {
                    other.initAsync().done(function () { return _this.ctx.drawImage(other.getCanvas(), 0, 0); });
                });
            };
            Picture.prototype.clone = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.commitImageData();
                    var p = Picture.mkSync(_this.widthSync(), _this.heightSync());
                    p.ctx.drawImage(_this.canvas, 0, 0);
                    p._url = _this._url;
                    p._cors = _this._cors;
                    p._date = _this._date;
                    p._location = _this._location;
                    return p;
                });
            };
            Picture.prototype.fill_rect = function (left, top, width, height, angle, color, r) {
                var _this = this;
                this.atPosition(r, left, top, angle, color.A(), function () {
                    _this.ctx.fillStyle = color.toHtml();
                    _this.ctx.fillRect(0, 0, width, height);
                });
            };
            Picture.prototype.pixel = function (left, top, r) {
                var _this = this;
                this.initAsync().done(function () {
                    left = Math.round(left);
                    top = Math.round(top);
                    _this.at(left + top * _this.widthSync(), r);
                });
            };
            Picture.prototype.getViewCanvasClone = function () {
                this.commitImageData();
                var rc = document.createElement("canvas");
                rc.width = this.widthSync();
                rc.height = this.heightSync();
                var rx = rc.getContext("2d");
                rx.drawImage(this.canvas, 0, 0);
                return rc;
            };
            Picture.prototype.getViewCanvas = function () {
                this.commitImageData();
                if (this.canvas.parentElement || TDev.LayoutMgr.RenderExecutionMode()) {
                    var rc = document.createElement("canvas");
                    rc.width = this.widthSync();
                    rc.height = this.heightSync();
                    var rx = rc.getContext("2d");
                    rx.drawImage(this.canvas, 0, 0);
                    this.canvas = rc;
                    this.ctx = rx;
                    this.slowlyloadingelement = undefined;
                }
                this.fitToColumn = !TDev.LayoutMgr.RenderExecutionMode();
                if (this.fitToColumn && this.heightSync() > 0 && this.widthSync() > 0) {
                    var r = this.heightSync() / this.widthSync();
                    var colwidth = TDev.SizeMgr.getColumnWidth();
                    if (this.widthSync() > colwidth) {
                        this.canvas.style.width = colwidth + "px";
                        this.canvas.style.height = (colwidth * r) + "px";
                    }
                }
                return this.canvas;
            };
            Picture.prototype.getViewCore = function (s, b) {
                var _this = this;
                var r = TDev.div("viewPicture");
                var img = this.getImageElement();
                if (img) {
                    img.setAttribute('class', 'wall-picture');
                    this.slowlyloadingelement = img;
                    return img;
                }
                else {
                    this.slowlyloadingelement = undefined;
                    this.initAsync().done(function () {
                        _this.commitImageData();
                        r.setChildren(_this.getViewCanvas());
                        b.RefreshOnScreen();
                    });
                }
                return r;
            };
            Picture.prototype.updateViewCore = function (s, b) {
                var _this = this;
                if (TDev.LayoutMgr.RenderExecutionMode() && this.slowlyloadingelement) {
                    this.slowlyloadingelement.onload = function () {
                        if (_this.slowlyloadingelement.offsetParent) {
                            var c = _this.getViewCore(s, b);
                            c.onload = function () {
                                b.RefreshOnScreen();
                            };
                            c.onerror = function () {
                                b.SwapImageContent(Picture.errorPic());
                            };
                            b.SwapImageContent(c);
                        }
                        else {
                            b.RefreshOnScreen();
                        }
                    };
                    this.slowlyloadingelement.onerror = function () {
                        b.SwapImageContent(Picture.errorPic());
                    };
                }
            };
            Picture.errorPic = function () {
                var frowny = TDev.div(null, ":(");
                var msg = TDev.div(null, TDev.lf("picture failed to load"));
                var rect = TDev.div(null, frowny, document.createElement("br"), msg);
                rect.style.background = "lightgray";
                rect.style.fontFamily = "sans-serif";
                rect.style.color = "white";
                frowny.style.fontSize = "240px";
                msg.style.marginBottom = "1em";
                msg.style.marginLeft = "1em";
                msg.style.fontSize = "42px";
                rect.style.height = "480px";
                rect.style.width = "480px";
                return rect;
            };
            Picture.prototype.resize = function (width, height, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    width = Math.round(width);
                    height = Math.round(height);
                    if (width < 1)
                        width = Math.floor(_this.widthSync() / _this.heightSync() * height);
                    if (height < 1)
                        height = Math.floor(_this.heightSync() / _this.widthSync() * width);
                    if (width == _this.widthSync() && height == _this.heightSync())
                        return;
                    var ow = _this.widthSync();
                    var oh = _this.heightSync();
                    var temp = document.createElement('canvas');
                    temp.width = ow;
                    temp.height = oh;
                    var tempCtx = temp.getContext("2d");
                    tempCtx.drawImage(_this.canvas, 0, 0, ow, oh);
                    _this.canvas.width = width;
                    _this.canvas.height = height;
                    _this.ctx.save();
                    _this.ctx.drawImage(temp, 0, 0, ow, oh, 0, 0, width, height);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.save_to_library = function (r) {
                var _this = this;
                TDev.HTML.showProgressNotification(TDev.lf("saving picture"));
                this.loadFirst(r, function () {
                    var defaultName = Picture.niceFilename() + ".png";
                    if (window.navigator.msSaveOrOpenBlob) {
                        try {
                            var result = window.navigator.msSaveOrOpenBlob(_this.canvas.msToBlob(), defaultName);
                            return defaultName;
                        }
                        catch (e) {
                            TDev.HTML.showProgressNotification(TDev.lf("saving picture failed..."));
                            return "";
                        }
                    }
                    else {
                        var url = _this.canvas.toDataURL('image/png');
                        TDev.HTML.browserDownload(url, TDev.Util.toFileName(defaultName, 'pic'));
                    }
                    return defaultName;
                });
            };
            Picture.prototype.clear = function (color, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    _this.ctx.clearRect(0, 0, _this.widthSync(), _this.heightSync());
                    _this.ctx.fillStyle = color.toHtml();
                    _this.ctx.fillRect(0, 0, _this.widthSync(), _this.heightSync());
                    _this.ctx.restore();
                });
            };
            Picture.prototype.clear_rect = function (color, left, top, width, height, r) {
                var _this = this;
                if (isNaN(left) || isNaN(top) || isNaN(width) || isNaN(height) || width <= 0 || height <= 0) {
                    r.resume();
                }
                else {
                    this.loadFirst(r, function () {
                        _this.changed();
                        _this.ctx.save();
                        _this.ctx.clearRect(left, top, width, height);
                        _this.ctx.fillStyle = color.toHtml();
                        _this.ctx.fillRect(left, top, width, height);
                        _this.ctx.restore();
                    });
                }
            };
            Picture.prototype.eraseWhiteBackgroundAsync = function () {
                var _this = this;
                return this.initAsync().then(function () {
                    _this.changed();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    var threshold = 25;
                    for (var i = 0; i < p.length; i += 4) {
                        var dr = 255 - p[i];
                        var dg = 255 - p[i + 1];
                        var db = 255 - p[i + 2];
                        if (dr < threshold && dg < threshold && db < threshold) {
                            p[i + 3] = Math.floor((dr + dg + db) / (3 * threshold) * 255);
                        }
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.colorize = function (background, foreground, threshold, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    var ba = background.a;
                    var br = background.r;
                    var bg = background.g;
                    var bb = background.b;
                    var fa = foreground.a;
                    var fr = foreground.r;
                    var fg = foreground.g;
                    var fb = foreground.b;
                    var threshold255 = 255 * RT.Math_.normalize(threshold) * 3;
                    for (var i = 0; i < p.length; i += 4) {
                        var k = (p[i] + p[i + 1] + p[i + 2]);
                        var isb = k < threshold255;
                        p[i] = isb ? br : fr;
                        p[i + 1] = isb ? bg : fg;
                        p[i + 2] = isb ? bb : fb;
                        p[i + 3] = isb ? ba : fa;
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.negative = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        p[i] = 255 - p[i];
                        p[i + 1] = 255 - p[i + 1];
                        p[i + 2] = 255 - p[i + 2];
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.desaturate = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        var k = (p[i] + p[i + 1] + p[i + 2]) / 3;
                        p[i] = k;
                        p[i + 1] = k;
                        p[i + 2] = k;
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.invert = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        p[i] = 255 - p[i];
                        p[i + 1] = 255 - p[i + 1];
                        p[i + 2] = 255 - p[i + 2];
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.tint = function (color, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    var tint = color;
                    _this.changed();
                    var ta = tint.A();
                    var tr = tint.R();
                    var tg = tint.G();
                    var tb = tint.B();
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        var a = p[i + 3];
                        var r = p[i];
                        var g = p[i + 1];
                        var b = p[i + 2];
                        ;
                        var gray = (r * 0.2126 + g * 0.7152 + b * 0.0722);
                        a = a * ta;
                        r = gray * tr;
                        g = gray * tg;
                        b = gray * tb;
                        p[i + 3] = a;
                        p[i] = r;
                        p[i + 1] = g;
                        p[i + 2] = b;
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.brightness = function (factor, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    var f = factor < -1.0 ? -1.0 : factor > 1.0 ? 1.0 : factor;
                    var fi = f * 255;
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        var r = p[i];
                        var g = p[i + 1];
                        var b = p[i + 2];
                        ;
                        var ri = r + fi;
                        var gi = g + fi;
                        var bi = b + fi;
                        r = ri > 255 ? 255 : (ri < 0 ? 0 : ri);
                        g = gi > 255 ? 255 : (gi < 0 ? 0 : gi);
                        b = bi > 255 ? 255 : (bi < 0 ? 0 : bi);
                        p[i] = r;
                        p[i + 1] = g;
                        p[i + 2] = b;
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.contrast = function (factor, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    var f = factor < -1.0 ? -1.0 : factor > 1.0 ? 1.0 : factor;
                    var cfi = 1 + f;
                    _this.ctx.save();
                    var data = _this.ctx.getImageData(0, 0, _this.widthSync(), _this.heightSync());
                    var p = data.data;
                    for (var i = 0; i < p.length; i += 4) {
                        var r = p[i];
                        var g = p[i + 1];
                        var b = p[i + 2];
                        ;
                        var ri = r - 128;
                        var gi = g - 128;
                        var bi = b - 128;
                        ri = ri * cfi;
                        gi = gi * cfi;
                        bi = bi * cfi;
                        ri = ri + 128;
                        gi = gi + 128;
                        bi = bi + 128;
                        r = ri > 255 ? 255 : (ri < 0 ? 0 : ri);
                        g = gi > 255 ? 255 : (gi < 0 ? 0 : gi);
                        b = bi > 255 ? 255 : (bi < 0 ? 0 : bi);
                        p[i] = r;
                        p[i + 1] = g;
                        p[i + 2] = b;
                    }
                    _this.ctx.putImageData(data, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.crop = function (left, top, width, height, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    var ileft = Math.round(left);
                    var itop = Math.round(top);
                    var iwidth = Math.round(width);
                    var iheight = Math.round(height);
                    if (_this.widthSync() == 0 || _this.heightSync() == 0)
                        return;
                    if (ileft < 0)
                        ileft = 0;
                    else if (ileft >= _this.widthSync())
                        ileft = _this.widthSync() - 1;
                    if (itop < 0)
                        itop = 0;
                    else if (itop >= _this.heightSync())
                        itop = _this.heightSync() - 1;
                    if (ileft + iwidth > _this.widthSync())
                        iwidth = _this.widthSync() - ileft;
                    if (itop + iheight > _this.heightSync())
                        iheight = _this.heightSync() - itop;
                    _this.cropInternal(ileft, itop, iwidth, iheight);
                });
            };
            Picture.prototype.cropInternal = function (left, top, cwidth, cheight) {
                TDev.Util.assertCode(left >= 0 && left < this.widthSync());
                TDev.Util.assertCode(top >= 0 && top < this.heightSync());
                TDev.Util.assertCode(cwidth >= 0 && left + cwidth <= this.widthSync());
                TDev.Util.assertCode(cheight >= 0 && top + cheight <= this.heightSync());
                this.changed();
                var imageData = undefined;
                if (cwidth > 0 && cheight > 0)
                    imageData = this.ctx.getImageData(left, top, cwidth, cheight);
                this.canvas.width = cwidth;
                this.canvas.height = cheight;
                this.ctx = this.canvas.getContext("2d");
                if (imageData)
                    this.ctx.putImageData(imageData, 0, 0);
            };
            Picture.prototype.draw_ellipse = function (left, top, width, height, angle, c, thickness, r) {
                var _this = this;
                if (isNaN(thickness) || thickness < 0)
                    thickness = 2.0;
                this.atPosition(r, left + width / 2, top + height / 2, angle, c.A(), function () {
                    _this.ctx.scale(width / height, 1);
                    _this.ctx.strokeStyle = c.toHtml();
                    _this.ctx.lineWidth = thickness;
                    _this.ctx.beginPath();
                    _this.ctx.arc(0, 0, height / 2, 0, 2 * Math.PI);
                    _this.ctx.stroke();
                });
            };
            Picture.prototype.draw_line = function (x1, y1, x2, y2, color, thickness, r) {
                var _this = this;
                if (isNaN(thickness) || thickness < 0)
                    thickness = 2.0;
                this.atPosition(r, 0, 0, 0, color.A(), function () {
                    _this.ctx.beginPath();
                    _this.ctx.strokeStyle = color.toHtml();
                    _this.ctx.lineWidth = thickness;
                    _this.ctx.moveTo(x1, y1);
                    _this.ctx.lineTo(x2, y2);
                    _this.ctx.stroke();
                });
            };
            Picture.prototype.draw_rect = function (left, top, width, height, angle, color, thickness, r) {
                var _this = this;
                if (isNaN(thickness) || thickness < 0)
                    thickness = 2.0;
                this.atPosition(r, left, top, angle, color.A(), function () {
                    _this.ctx.strokeStyle = color.toHtml();
                    _this.ctx.lineWidth = thickness;
                    _this.ctx.strokeRect(0, 0, width, height);
                });
            };
            Picture.prototype.draw_text = function (left, top, text, font_size, angle, color, r) {
                var _this = this;
                this.atPosition(r, left, top, angle, color.A(), function () {
                    _this.ctx.fillStyle = color.toHtml();
                    _this.ctx.font = font_size + "px sans-serif";
                    _this.ctx.textBaseline = "top";
                    _this.ctx.fillText(text, 0, 0);
                });
            };
            Picture.prototype.fill_ellipse = function (left, top, width, height, angle, color, r) {
                var _this = this;
                this.atPosition(r, left + width / 2, top + height / 2, angle, color.A(), function () {
                    _this.ctx.scale(width / height, 1);
                    _this.ctx.strokeStyle = color.toHtml();
                    _this.ctx.fillStyle = color.toHtml();
                    _this.ctx.beginPath();
                    _this.ctx.arc(0, 0, height / 2, 0, 2 * Math.PI);
                    _this.ctx.fill();
                });
            };
            Picture.prototype.draw_path = function (left, top, angle, color, thickness, data, r) {
                var _this = this;
                this.atPosition(r, left, top, angle, color.A(), function () {
                    var parts = data.split(' ');
                    _this.ctx.strokeStyle = color.toHtml();
                    _this.ctx.lineWidth = thickness;
                    _this.ctx.beginPath();
                    Picture.parsePathData(_this.ctx, data);
                    _this.ctx.stroke();
                });
            };
            Picture.prototype.fill_path = function (left, top, angle, color, data, r) {
                var _this = this;
                this.atPosition(r, left, top, angle, color.A(), function () {
                    _this.ctx.strokeStyle = color.toHtml();
                    _this.ctx.fillStyle = color.toHtml();
                    _this.ctx.beginPath();
                    Picture.parsePathData(_this.ctx, data);
                    _this.ctx.fill();
                });
            };
            Picture.parseSvg = function (xml, width, height) {
                try {
                    var svg = RT.XmlObject.mk(xml);
                    if (!svg || svg.name() != "svg")
                        return null;
                    var svgWidth = parseFloat(svg.attr("width"));
                    var svgHeight = parseFloat(svg.attr("height"));
                    if (height < 0)
                        height = width / svgWidth * svgHeight;
                    else if (width < 0)
                        width = height / svgHeight * svgWidth;
                    var canvas = document.createElement("canvas");
                    canvas.width = width;
                    canvas.height = height;
                    var ctx = canvas.getContext("2d");
                    ctx.scale(width / svgWidth, height / svgHeight);
                    var g = svg.child("g");
                    if (!g)
                        return null;
                    var transform = g.attr("transform");
                    var m = /matrix\(([^)]+)\)/.exec(transform);
                    if (m) {
                        var v = m[1].split(/[, ]/).map(function (p) { return parseFloat(p); });
                        ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
                    }
                    var paths = g.children('');
                    ctx.fillStyle = 'none';
                    ctx.strokeStyle = 'none';
                    for (var i = 0; i < paths.count(); ++i) {
                        var path = paths.at(i);
                        ctx.save();
                        switch (path.name()) {
                            case 'path':
                                ctx.beginPath();
                                if (!Picture.parsePathData(ctx, path.attr('d')))
                                    return null;
                                Picture.parsePathStyle(ctx, path);
                                break;
                            case 'polygon':
                                ctx.beginPath();
                                if (!Picture.parsePolygonData(ctx, path.attr('points')))
                                    return null;
                                ctx.closePath();
                                Picture.parseFillStyle(ctx, path);
                                Picture.parseStrokeStyle(ctx, path);
                                break;
                            case 'line':
                                ctx.moveTo(parseFloat(path.attr('x1')), parseFloat(path.attr('y1')));
                                ctx.lineTo(parseFloat(path.attr('x2')), parseFloat(path.attr('y2')));
                                Picture.parseStrokeStyle(ctx, path);
                                break;
                            case 'rect':
                                ctx.rect(parseFloat(path.attr('x')), parseFloat(path.attr('y')), parseFloat(path.attr('width')), parseFloat(path.attr('height')));
                                Picture.parseFillStyle(ctx, path);
                                Picture.parseStrokeStyle(ctx, path);
                                break;
                            default:
                                TDev.Util.log('svg rendering: unsupported command ' + path.name());
                                return null;
                        }
                        ctx.restore();
                    }
                    return canvas;
                }
                catch (e) {
                    return null;
                }
            };
            Picture.parsePolygonData = function (ctx, data) {
                if (!data)
                    return false;
                var points = data.split(' ').map(function (p) { return p.split(',').map(function (x) { return parseFloat(x); }); });
                for (var i = 0; i < points.length; ++i) {
                    var p = points[i];
                    if (i == 0)
                        ctx.moveTo(p[0], p[1]);
                    else
                        ctx.lineTo(p[0], p[1]);
                }
                return true;
            };
            Picture.parseFillStyle = function (ctx, x) {
                var fill = x.attr('fill');
                if (fill)
                    ctx.fillStyle = x.attr('fill');
                if (!fill || fill != 'none') {
                    ctx.closePath();
                    ctx.fill();
                }
            };
            Picture.parseStrokeStyle = function (ctx, x) {
                var stroke = x.attr('stroke');
                if (stroke && stroke != 'none') {
                    ctx.strokeStyle = stroke;
                    if (x.attr('stroke-width'))
                        ctx.lineWidth = parseFloat(x.attr('stroke-width'));
                    if (x.attr('stroke-linejoin'))
                        ctx.lineJoin = x.attr('stroke-linejoin');
                    ctx.stroke();
                }
            };
            Picture.parsePathStyle = function (ctx, x) {
                if (!x.attr('fill') && !x.attr('style')) {
                    ctx.strokeStyle = '#000000';
                    ctx.closePath();
                    ctx.fill();
                    return;
                }
                Picture.parseFillStyle(ctx, x);
                Picture.parseStrokeStyle(ctx, x);
                var data = x.attr('style');
                if (data) {
                    var m = /fill:([^;]+);/i.exec(data);
                    if (m && !/none/.test(m[1])) {
                        ctx.fillStyle = m[1];
                        ctx.closePath();
                        ctx.fill();
                    }
                    m = /stroke:([^;]+);/i.exec(data);
                    if (m && !/none/.test(m[1])) {
                        ctx.strokeStyle = m[1];
                        m = /stroke-width:([^;]+);/.exec(data);
                        if (m)
                            ctx.lineWidth = parseFloat(m[1]);
                        ctx.stroke();
                    }
                }
            };
            Picture.applyStyle = function (ctx) {
                if (ctx.fillStyle && ctx.fillStyle != 'none')
                    ctx.fill();
            };
            Picture.parsePathData = function (ctx, data) {
                if (!data)
                    return false;
                var parts = data.replace(/-/gm, ' -').replace(/[a-zA-Z]/gm, ' $& ').replace(/,/gm, ' ').split(/\s+/).filter(function (p) { return !!p; });
                var x = 0;
                var y = 0;
                var rx = 0;
                var ry = 0;
                var i = 0;
                var cpx = 0;
                var cpy = 0;
                var lastCommand = '';
                while (i < parts.length) {
                    var command = parts[i++];
                    switch (command) {
                        case 'Z':
                        case 'z':
                            ctx.closePath();
                            break;
                        case 'm':
                            rx = x;
                            ry = y;
                            ctx.moveTo(rx = rx + parseFloat(parts[i++]), ry = ry + parseFloat(parts[i++]));
                            while (i + 1 < parts.length && !isNaN(parseFloat(parts[i])))
                                ctx.lineTo(rx = rx + parseFloat(parts[i++]), ry = ry + parseFloat(parts[i++]));
                            x = rx;
                            y = ry;
                            break;
                        case 'M':
                            ctx.moveTo(x = parseFloat(parts[i++]), y = parseFloat(parts[i++]));
                            while (i + 1 < parts.length && !isNaN(parseFloat(parts[i])))
                                ctx.lineTo(x = parseFloat(parts[i++]), y = parseFloat(parts[i++]));
                            break;
                        case 'l':
                            rx = x;
                            ry = y;
                            do {
                                ctx.lineTo(rx = rx + parseFloat(parts[i++]), ry = ry + parseFloat(parts[i++]));
                            } while (i + 1 < parts.length && !isNaN(parseFloat(parts[i])));
                            x = rx;
                            y = ry;
                            break;
                        case 'L':
                            do {
                                ctx.lineTo(x = parseFloat(parts[i++]), y = parseFloat(parts[i++]));
                            } while (i + 1 < parts.length && !isNaN(parseFloat(parts[i])));
                            break;
                        case 'c':
                            rx = x;
                            ry = y;
                            do {
                                var x1 = rx + parseFloat(parts[i++]);
                                var y1 = ry + parseFloat(parts[i++]);
                                var x2 = rx + parseFloat(parts[i++]);
                                var y2 = ry + parseFloat(parts[i++]);
                                ctx.bezierCurveTo(x1, y1, x2, y2, rx = rx + parseFloat(parts[i++]), ry = ry + parseFloat(parts[i++]));
                            } while (i + 5 < parts.length && !isNaN(parseFloat(parts[i])));
                            cpx = x2;
                            cpy = y2;
                            x = rx;
                            y = ry;
                            break;
                        case 'C':
                            do {
                                ctx.bezierCurveTo(parseFloat(parts[i++]), parseFloat(parts[i++]), cpx = parseFloat(parts[i++]), cpy = parseFloat(parts[i++]), x = parseFloat(parts[i++]), y = parseFloat(parts[i++]));
                            } while (i + 5 < parts.length && !isNaN(parseFloat(parts[i])));
                            break;
                        case 'S':
                            if (!/^[CcSs]$/.test(lastCommand)) {
                                cpx = x;
                                cpy = y;
                            }
                            do {
                                var x2 = parseFloat(parts[i++]);
                                var y2 = parseFloat(parts[i++]);
                                var x1 = 2 * x - cpx;
                                var y1 = 2 * y - cpy;
                                ctx.bezierCurveTo(x1, y1, cpx = x2, cpy = y2, x = parseFloat(parts[i++]), y = parseFloat(parts[i++]));
                            } while (i + 3 < parts.length && !isNaN(parseFloat(parts[i])));
                            break;
                        case 's':
                            rx = x;
                            ry = y;
                            if (!/^[CcSs]$/.test(lastCommand)) {
                                cpx = rx;
                                cpy = ry;
                            }
                            do {
                                var x2 = rx + parseFloat(parts[i++]);
                                var y2 = ry + parseFloat(parts[i++]);
                                var x1 = 2 * rx - cpx;
                                var y1 = 2 * ry - cpy;
                                ctx.bezierCurveTo(x1, y1, cpx = x2, cpy = y2, rx = rx + parseFloat(parts[i++]), ry = ry + parseFloat(parts[i++]));
                            } while (i + 3 < parts.length && !isNaN(parseFloat(parts[i])));
                            x = rx;
                            y = ry;
                            break;
                        case 'H':
                            rx = parseFloat(parts[i++]);
                            ctx.lineTo(rx, y);
                            x = rx;
                            break;
                        case 'h':
                            rx = x + parseFloat(parts[i++]);
                            ctx.lineTo(rx, y);
                            x = rx;
                            break;
                        case 'V':
                            ry = parseFloat(parts[i++]);
                            ctx.lineTo(x, ry);
                            y = ry;
                            break;
                        case 'v':
                            ry = y + parseFloat(parts[i++]);
                            ctx.lineTo(x, ry);
                            y = ry;
                            break;
                        default:
                            TDev.Util.log('svg rendering: unknown path command ' + command);
                            return false;
                    }
                    lastCommand = command;
                }
                return true;
            };
            Picture.prototype.set_pixel = function (left, top, color, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    left = Math.round(left);
                    top = Math.round(top);
                    if (left < 0 || top < 0 || left >= _this.widthSync() || top >= _this.heightSync())
                        return;
                    _this.changed(false);
                    _this.imageDataHasChanges = true;
                    _this.getImageData();
                    var d = _this.imageData.data;
                    var idx = (left + top * _this.widthSync()) * 4;
                    d[idx + 0] = color.r;
                    d[idx + 1] = color.g;
                    d[idx + 2] = color.b;
                    d[idx + 3] = color.a;
                });
            };
            Picture.prototype.to_buffer = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    var d = _this.getImageData();
                    _this.imageData = null;
                    return RT.Buffer.fromImageData(d);
                });
            };
            Picture.prototype.write_buffer = function (buffer, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.changed();
                    var d = buffer.imageData;
                    if (!d) {
                        d = _this.ctx.createImageData(_this.widthSync(), _this.heightSync());
                        var sz = d.width * d.height * 4;
                        var dst = d.data;
                        var src = buffer.buffer;
                        for (var i = 0; i < sz; ++i)
                            dst[i] = src[i];
                    }
                    _this.ctx.putImageData(d, 0, 0);
                });
            };
            Picture.prototype.share = function (where, message, r) {
                var _this = this;
                TDev.HTML.showProgressNotification(TDev.lf("sharing picture..."));
                this.initAsync().then(function () { return RT.ShareManager.sharePictureAsync(_this, where, message); }).done(function () { return r.resume(); });
            };
            Picture.prototype.flip_horizontal = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.commitImageData();
                    _this.changed();
                    var temp = document.createElement("canvas");
                    temp.width = _this.canvas.width;
                    temp.height = _this.canvas.height;
                    var tempCtx = temp.getContext("2d");
                    tempCtx.drawImage(_this.canvas, 0, 0);
                    _this.ctx.save();
                    _this.ctx.translate(temp.width, 0);
                    _this.ctx.scale(-1, 1);
                    _this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
                    _this.ctx.drawImage(temp, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.flip_vertical = function (r) {
                var _this = this;
                this.loadFirst(r, function () {
                    _this.commitImageData();
                    _this.changed();
                    var temp = document.createElement("canvas");
                    temp.width = _this.canvas.width;
                    temp.height = _this.canvas.height;
                    var tempCtx = temp.getContext("2d");
                    tempCtx.drawImage(_this.canvas, 0, 0);
                    _this.ctx.save();
                    _this.ctx.translate(0, _this.canvas.height);
                    _this.ctx.scale(1, -1);
                    _this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
                    _this.ctx.drawImage(temp, 0, 0);
                    _this.ctx.restore();
                });
            };
            Picture.prototype.to_data_uri = function (quality, r) {
                var _this = this;
                this.loadFirst(r, function () {
                    var uri = _this.getDataUri(RT.Math_.normalize(quality));
                    r.resumeVal(uri);
                });
            };
            Picture.prototype.blend_svg = function (markup, left, top, width, height, angle, r) {
                var _this = this;
                if (TDev.Browser.browser == 1 /* ie10 */ || TDev.Browser.browser == 2 /* ie11 */) {
                    var cvs = Picture.parseSvg(markup, width, height);
                    if (cvs) {
                        this.atPosition(r, left, top, angle, 1, function () {
                            _this.ctx.drawImage(cvs, 0, 0, cvs.width, cvs.height);
                        });
                        return;
                    }
                }
                var svg = "data:image/svg+xml;base64," + RT.Web.base64_encode(markup);
                var img = document.createElement("img");
                var svgWidth = markup.match(/width="(\d+)"/);
                if (svgWidth)
                    img.width = parseInt(svgWidth[1]);
                var svgHeight = markup.match(/height="(\d+)"/);
                if (svgHeight)
                    img.height = parseInt(svgHeight[1]);
                var unhappy = function () {
                    _this.ctx.fillStyle = "lightgray";
                    _this.ctx.fillRect(0, 0, 100, 100);
                    _this.ctx.fillStyle = "white";
                    _this.ctx.textAlign = "center";
                    _this.ctx.textBaseline = "top";
                    _this.ctx.font = "80px sans-serif";
                    _this.ctx.fillText(':(', 50, 0);
                };
                var svgLoadFailed = function () {
                    _this.atPosition(r, left, top, angle, 1, function () {
                        unhappy();
                    });
                };
                img.onload = function () {
                    _this.atPosition(r, left, top, angle, 1, function () {
                        if (!img.width || !img.height) {
                            RT.Time.log('blend_svg error: empty svg');
                            unhappy();
                        }
                        else {
                            var w = width > 0 ? width : img.width;
                            var h = height > 0 ? height : img.height;
                            if (width < 0 && height > 0)
                                w = height / img.height * img.width;
                            else if (height < 0 && width > 0)
                                h = width / img.width * img.height;
                            try {
                                _this.ctx.drawImage(img, 0, 0, w, h);
                            }
                            catch (ex) {
                                try {
                                    _this.ctx.drawImage(img, 0, 0, w, h);
                                }
                                catch (ex2) {
                                    unhappy();
                                }
                            }
                        }
                    });
                };
                img.onerror = function () {
                    RT.Time.log('blend_svg error: svg load failed');
                    svgLoadFailed();
                };
                img.src = svg;
            };
            Picture.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            Picture.niceFilename = function () {
                var now = RT.Time.now();
                return now.year() + "-" + now.month() + "-" + now.day() + "-" + now.hour() + "-" + now.minute() + "-" + now.second() + "-" + now.millisecond();
            };
            Picture.prototype.docs_render = function (height, caption) {
            };
            Picture.prototype.readonly_url = function () {
                return this.getReadonlyUrlSync();
            };
            return Picture;
        })(RT.RTValue);
        RT.Picture = Picture;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Place = (function (_super) {
            __extends(Place, _super);
            function Place() {
                _super.call(this);
                this._id = undefined;
                this._location = undefined;
                this._name = undefined;
                this._picture_link = undefined;
                this._link = undefined;
                this._category = undefined;
                this._source = undefined;
                this._values = undefined;
            }
            Place.mk = function (name, location) {
                var m = new Place();
                m.set_name(name);
                m.set_location(location);
                return m;
            };
            Place.prototype.location = function () {
                return this._location;
            };
            Place.prototype.set_location = function (location) {
                this._location = location;
            };
            Place.prototype.id = function () {
                return this._id;
            };
            Place.prototype.set_id = function (id) {
                this._id = id;
            };
            Place.prototype.name = function () {
                return this._name;
            };
            Place.prototype.set_name = function (name) {
                this._name = name;
            };
            Place.prototype.picture_link = function () {
                return this._picture_link;
            };
            Place.prototype.set_picture_link = function (url) {
                this._picture_link = url;
            };
            Place.prototype.link = function () {
                return this._link;
            };
            Place.prototype.set_link = function (url) {
                this._link = url;
            };
            Place.prototype.category = function () {
                return this._category;
            };
            Place.prototype.set_category = function (category) {
                this._category = category;
            };
            Place.prototype.source = function () {
                return this._source;
            };
            Place.prototype.set_source = function (source) {
                this._source = source;
            };
            Place.prototype.values = function () {
                if (!this._values)
                    this._values = RT.Collections.create_string_map();
                return this._values;
            };
            Place.prototype.to_string = function () {
                return this._name;
            };
            Place.prototype.getViewCore = function (s, b) {
                var d = TDev.div("item");
                if (this.picture_link())
                    d.appendChild(TDev.img("item-image", this.picture_link(), "linked picture"));
                var dc = TDev.div("item-info");
                d.appendChild(dc);
                if (this.name())
                    dc.appendChild(TDev.div("item-title", this.name()));
                if (this.category())
                    dc.appendChild(TDev.div("item-subtitle", this.category()));
                if (this.location())
                    dc.appendChild(TDev.div("item-description", this.location().to_string()));
                dc.appendChild(TDev.div("item-subtle", this.source()));
                return d;
            };
            Place.prototype.check_in = function () {
            };
            Place.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Place;
        })(RT.RTValue);
        RT.Place = Place;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Player;
        (function (Player) {
            var _rt;
            var _activeSong;
            var _audio;
            var _source;
            var _shuffled;
            var _onActiveSongChanged;
            var _onPlayerStateChanged;
            function rt_start(rt) {
                _rt = rt;
                _activeSong = null;
                _onActiveSongChanged = undefined;
                _onPlayerStateChanged = undefined;
                if (rt.eventEnabled("active song changed"))
                    Player.addActiveSongChangedEvent(rt);
                if (rt.eventEnabled("player state changed"))
                    Player.addPlayerStateChangedEvent(rt);
            }
            Player.rt_start = rt_start;
            function rt_stop(rt) {
                Player.removeActiveSongChangedEvent();
                Player.removePlayerStateChangedEvent();
                _rt = null;
                _activeSong = null;
                _onActiveSongChanged = undefined;
                _onPlayerStateChanged = undefined;
            }
            Player.rt_stop = rt_stop;
            function addActiveSongChangedEvent(rt) {
            }
            Player.addActiveSongChangedEvent = addActiveSongChangedEvent;
            function removeActiveSongChangedEvent() {
            }
            Player.removeActiveSongChangedEvent = removeActiveSongChangedEvent;
            function addPlayerStateChangedEvent(rt) {
            }
            Player.addPlayerStateChangedEvent = addPlayerStateChangedEvent;
            function removePlayerStateChangedEvent() {
            }
            Player.removePlayerStateChangedEvent = removePlayerStateChangedEvent;
            function active_song(r) {
                r.resumeVal(_activeSong);
            }
            Player.active_song = active_song;
            function on_active_song_changed(body) {
                if (_rt && !_onActiveSongChanged) {
                    _onActiveSongChanged = new RT.Event_();
                    Player.addActiveSongChangedEvent(_rt);
                }
                return _onActiveSongChanged.addHandler(body);
            }
            Player.on_active_song_changed = on_active_song_changed;
            function raiseActiveSongChanged() {
                if (_rt) {
                    if (_rt.eventEnabled("player state changed"))
                        _rt.queueEvent("active song changed", null, []);
                    if (_onActiveSongChanged && _onActiveSongChanged.handlers)
                        _rt.queueLocalEvent(_onActiveSongChanged, [], false);
                }
            }
            function on_player_state_changed(body) {
                if (_rt && !_onPlayerStateChanged) {
                    _onPlayerStateChanged = new RT.Event_();
                    Player.addPlayerStateChangedEvent(_rt);
                }
                return _onPlayerStateChanged.addHandler(body);
            }
            Player.on_player_state_changed = on_player_state_changed;
            function raisePlayerStateChanged() {
                if (_rt) {
                    if (_rt.eventEnabled("player state changed"))
                        _rt.queueEvent("player state changed", null, []);
                    if (_onPlayerStateChanged && _onPlayerStateChanged.handlers)
                        _rt.queueLocalEvent(_onPlayerStateChanged, [], false);
                }
            }
            function ensureAudio() {
                if (!_audio) {
                    _audio = document.createElement("audio");
                    _audio.crossorigin = "anonymous";
                    _audio.style.display = 'none';
                    _audio.onpause = function () {
                        raisePlayerStateChanged();
                    };
                    _audio.onplay = _audio.onpause;
                    _audio.onplaying = _audio.onpause;
                    _audio.onended = function () {
                        raisePlayerStateChanged();
                    };
                    _source = document.createElement("source");
                    _audio.appendChild(_source);
                    document.body.appendChild(_audio);
                }
            }
            function pause() {
                if (_audio) {
                    _audio.pause();
                }
            }
            Player.pause = pause;
            function playOne(song) {
                if (_activeSong != song) {
                    ensureAudio();
                    _activeSong = song;
                    var url = song.url();
                    _source.src = url;
                    if (TDev.RuntimeSettings.sounds()) {
                        TDev.HTML.showProgressNotification(TDev.lf("playing song..."));
                        _audio.play();
                    }
                    raiseActiveSongChanged();
                }
            }
            Player.playOne = playOne;
            function play(song) {
                Player.playOne(song);
            }
            Player.play = play;
            function play_position(r) {
                r.resumeVal(_audio ? _audio.currentTime : undefined);
            }
            Player.play_position = play_position;
            function resume() {
                if (_audio && TDev.RuntimeSettings.sounds()) {
                    _audio.play();
                }
            }
            Player.resume = resume;
            function stop() {
                if (_audio) {
                    _source.src = null;
                    _audio.load();
                }
            }
            Player.stop = stop;
            function is_muted(r) {
                r.resumeVal(_audio ? _audio.muted : false);
            }
            Player.is_muted = is_muted;
            function sound_volume() {
                return undefined;
            }
            Player.sound_volume = sound_volume;
            function set_sound_volume(x) {
            }
            Player.set_sound_volume = set_sound_volume;
            function is_repeating(r) {
                r.resumeVal(_audio ? _audio.loop : false);
            }
            Player.is_repeating = is_repeating;
            function set_repeating(repeating, r) {
                ensureAudio();
                _audio.loop = repeating;
                r.resume();
            }
            Player.set_repeating = set_repeating;
            function is_shuffled(r) {
                r.resumeVal(_shuffled);
            }
            Player.is_shuffled = is_shuffled;
            function set_shuffled(shuffled, r) {
                _shuffled = shuffled;
                r.resume();
            }
            Player.set_shuffled = set_shuffled;
            function is_stopped(r) {
                r.resumeVal(_audio ? _audio.ended : true);
            }
            Player.is_stopped = is_stopped;
            function is_playing(r) {
                r.resumeVal(_audio ? (!_audio.ended && !_audio.paused) : false);
            }
            Player.is_playing = is_playing;
            function is_paused(r) {
                r.resumeVal(_audio ? _audio.paused : false);
            }
            Player.is_paused = is_paused;
            function volume() {
                return 0;
            }
            Player.volume = volume;
        })(Player = RT.Player || (RT.Player = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
;
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Senses;
        (function (Senses) {
            var _rt;
            var _camera = undefined;
            var _frontCamera = undefined;
            var _onShake;
            var _onPhoneFaceUp;
            var _onPhoneFaceDown;
            var _onPhonePortrait;
            var _onPhoneLandscapeLeft;
            var _onPhoneLandscapeRight;
            function clearData() {
                _camera = undefined;
                _frontCamera = undefined;
                _onShake = undefined;
                _onPhoneFaceUp = undefined;
                _onPhoneFaceDown = undefined;
                _onPhonePortrait = undefined;
                _onPhoneLandscapeLeft = undefined;
                _onPhoneLandscapeRight = undefined;
                _rt = undefined;
            }
            function rt_start(rt) {
                clearData();
                _rt = rt;
                RT.DeviceMotion.rt_start(rt);
                RT.DeviceOrientation.rt_start(rt);
                gamepadsSupported = !!(navigator && navigator.getGamepads);
            }
            Senses.rt_start = rt_start;
            function rt_stop(rt) {
                clearData();
                RT.DeviceMotion.stop(rt);
                RT.DeviceOrientation.stop(rt);
            }
            Senses.rt_stop = rt_stop;
            function on_shake(body) {
                if (!_onShake) {
                    _onShake = new RT.Event_();
                    if (_rt)
                        RT.DeviceMotion.start(_rt);
                }
                return _onShake.addHandler(body);
            }
            Senses.on_shake = on_shake;
            function raiseShakeEvent() {
                if (_rt) {
                    _rt.queueEvent("shake", null, []);
                    if (_onShake && _onShake.handlers)
                        _rt.queueLocalEvent(_onShake, []);
                }
            }
            Senses.raiseShakeEvent = raiseShakeEvent;
            function on_phone_face_up(body) {
                if (!_onPhoneFaceUp) {
                    _onPhoneFaceUp = new RT.Event_();
                    if (_rt)
                        RT.DeviceOrientation.start(_rt);
                }
                return _onPhoneFaceUp.addHandler(body);
            }
            Senses.on_phone_face_up = on_phone_face_up;
            function raisePhoneFaceUp() {
                raisePhoneEvent("phone face up", _onPhoneFaceUp);
            }
            Senses.raisePhoneFaceUp = raisePhoneFaceUp;
            function on_phone_face_down(body) {
                if (!_onPhoneFaceDown) {
                    _onPhoneFaceDown = new RT.Event_();
                    if (_rt)
                        RT.DeviceOrientation.start(_rt);
                }
                return _onPhoneFaceDown.addHandler(body);
            }
            Senses.on_phone_face_down = on_phone_face_down;
            function raisePhoneFaceDown() {
                raisePhoneEvent("phone face down", _onPhoneFaceDown);
            }
            Senses.raisePhoneFaceDown = raisePhoneFaceDown;
            function on_phone_portrait(body) {
                if (!_onPhonePortrait) {
                    _onPhonePortrait = new RT.Event_();
                    if (_rt)
                        RT.DeviceOrientation.start(_rt);
                }
                return _onPhonePortrait.addHandler(body);
            }
            Senses.on_phone_portrait = on_phone_portrait;
            function raisePhonePortrait() {
                raisePhoneEvent("phone portrait", _onPhonePortrait);
            }
            Senses.raisePhonePortrait = raisePhonePortrait;
            function on_phone_landscape_left(body) {
                if (!_onPhoneLandscapeLeft) {
                    _onPhoneLandscapeLeft = new RT.Event_();
                    if (_rt)
                        RT.DeviceOrientation.start(_rt);
                }
                return _onPhoneLandscapeLeft.addHandler(body);
            }
            Senses.on_phone_landscape_left = on_phone_landscape_left;
            function raisePhoneLandscapeLeft() {
                raisePhoneEvent("phone landscape left", _onPhoneLandscapeLeft);
            }
            Senses.raisePhoneLandscapeLeft = raisePhoneLandscapeLeft;
            function on_phone_landscape_right(body) {
                if (!_onPhoneLandscapeRight) {
                    _onPhoneLandscapeRight = new RT.Event_();
                    if (_rt)
                        RT.DeviceOrientation.start(_rt);
                }
                return _onPhoneLandscapeRight.addHandler(body);
            }
            Senses.on_phone_landscape_right = on_phone_landscape_right;
            function raisePhoneLandscapeRight() {
                raisePhoneEvent("phone landscape right", _onPhoneLandscapeRight);
            }
            Senses.raisePhoneLandscapeRight = raisePhoneLandscapeRight;
            function raisePhoneEvent(name, ev) {
                if (_rt) {
                    _rt.queueEvent(name, null, []);
                    if (ev && ev.handlers)
                        _rt.queueLocalEvent(ev, []);
                }
            }
            function take_camera_picture(r) {
                var cam = navigator.camera;
                if (cam) {
                    cam.getPicture(function (url) {
                        r.resumeVal(RT.Picture.fromUrlSync(url, false, false));
                    }, function (msg) {
                        TDev.RT.App.logEvent(RT.App.DEBUG, "senses", "take camera picture failed: " + msg, undefined);
                        r.resumeVal(undefined);
                    }, {
                        quality: 85,
                        mediaType: window.Camera.MediaType.JPEG,
                        sourceType: window.Camera.PictureSourceType.CAMERA,
                        destinationType: window.Camera.DestinationType.FILE_URI
                    });
                    return;
                }
                RT.UserMediaManager.getCameraUrlAsync().done(function (url) {
                    if (!url) {
                        RT.Media.choosePictureAsync('take or choose a picture', 'The app wants to take a picture but it could not launch the camera. Try opening the picture chooser to access the camera.').done(function (pic) { return r.resumeVal(pic); });
                    }
                    else {
                        var m = new TDev.ModalDialog();
                        m.add(TDev.div('wall-dialog-header', TDev.lf("take a picture")));
                        var v = TDev.createElement('video');
                        v.src = url;
                        v.controls = false;
                        v.autoplay = true;
                        m.add(TDev.div('wall-dialog-body', v));
                        m.add(TDev.div('wall-dialog-buttons', [
                            TDev.HTML.mkButton(TDev.lf("cancel"), function () {
                                v.pause();
                                m.dismiss();
                                r.resumeVal(undefined);
                            }),
                            TDev.HTML.mkButton(TDev.lf("take picture"), function () {
                                RT.Picture.fromUrl(RT.UserMediaManager.previewVideo(v)).done(function (p) {
                                    v.pause();
                                    m.dismiss();
                                    r.resumeVal(p);
                                });
                            }),
                        ]));
                        m.show();
                    }
                });
            }
            Senses.take_camera_picture = take_camera_picture;
            function record_microphone(r) {
                RT.AudioContextManager.recordMicrophoneAsync().then(function (url) { return url ? RT.Sound.fromArtUrl(url) : undefined; }).done(function (snd) { return r.resumeVal(snd); });
            }
            Senses.record_microphone = record_microphone;
            function is_device_stable(r) {
                RT.DeviceMotion.isDeviceStable(r);
            }
            Senses.is_device_stable = is_device_stable;
            function has_accelerometer() {
                return RT.DeviceMotion.isMotionSupported();
            }
            Senses.has_accelerometer = has_accelerometer;
            function acceleration_stable(r) {
                RT.DeviceMotion.accelerationStable(r);
            }
            Senses.acceleration_stable = acceleration_stable;
            function acceleration_smooth(r) {
                RT.DeviceMotion.accelerationSmooth(r);
            }
            Senses.acceleration_smooth = acceleration_smooth;
            function acceleration_quick(r) {
                RT.DeviceMotion.accelerationQuick(r);
            }
            Senses.acceleration_quick = acceleration_quick;
            function askLocationAccessAsync(r) {
                if (!TDev.RuntimeSettings.location()) {
                    TDev.HTML.showProgressNotification(TDev.lf("denied access to location (global setting)"));
                    return TDev.Promise.as(false);
                }
                return r.rt.host.askSourceAccessAsync("location", "your current geo location, based on your GPS, WiFi or IP address.", false);
            }
            function current_location(r) {
                askLocationAccessAsync(r).then(function (allow) {
                    if (allow)
                        RT.GeoLocation.currentLocation(r);
                    else
                        r.resumeVal(undefined);
                }).done();
            }
            Senses.current_location = current_location;
            function current_location_accurate(r) {
                askLocationAccessAsync(r).then(function (allow) {
                    if (allow)
                        RT.GeoLocation.currentLocationAccurate(r);
                    else
                        r.resumeVal(undefined);
                }).done();
            }
            Senses.current_location_accurate = current_location_accurate;
            function camera(r) {
                if (!_camera && RT.UserMediaManager.isSupported()) {
                    _camera = new RT.Camera();
                }
                r.resumeVal(_camera);
            }
            Senses.camera = camera;
            function front_camera(r) {
                if (!_frontCamera && RT.UserMediaManager.isSupported()) {
                    _frontCamera = new RT.Camera();
                    _frontCamera.set_is_front(true);
                }
                r.resumeVal(_frontCamera);
            }
            Senses.front_camera = front_camera;
            function has_front_camera(r) {
                r.resumeVal(true);
            }
            Senses.has_front_camera = has_front_camera;
            function has_motion() {
                return false;
            }
            Senses.has_motion = has_motion;
            function orientation(r) {
                RT.DeviceOrientation.orientation(r);
            }
            Senses.orientation = orientation;
            function has_compass() {
                return RT.DeviceOrientation.isHeadingSupported();
            }
            Senses.has_compass = has_compass;
            function heading(r) {
                RT.DeviceOrientation.heading(r);
            }
            Senses.heading = heading;
            function has_gyroscope() {
                return RT.DeviceMotion.isSupported();
            }
            Senses.has_gyroscope = has_gyroscope;
            function rotation_speed(r) {
                RT.DeviceMotion.rotationRate(r);
            }
            Senses.rotation_speed = rotation_speed;
            function battery_level(r) {
                var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;
                r.resumeVal(battery ? battery.level : undefined);
            }
            Senses.battery_level = battery_level;
            function is_key_pressed(key, s) {
                return s.rt.host.keyboard.isPressed(key);
            }
            Senses.is_key_pressed = is_key_pressed;
            function on_key_pressed(key, body, s) {
                return s.rt.host.keyboard.registerDown(key, body);
            }
            Senses.on_key_pressed = on_key_pressed;
            var gamepadsSupported = false;
            var _lastGamepadsTimestamp = 0;
            var _lastGamepads = undefined;
            var _emptyGamepads = undefined;
            function gamepads() {
                if (gamepadsSupported) {
                    var ts = TDev.Util.perfNow();
                    if (!_lastGamepads || ts - _lastGamepadsTimestamp > 0.02) {
                        _lastGamepadsTimestamp = ts;
                        if (gamepadsSupported) {
                            _lastGamepads = new RT.Collection(Gamepad_);
                            var gs = navigator.getGamepads();
                            for (var i = 0; i < gs.length; ++i)
                                if (!!gs[i])
                                    _lastGamepads.add(new Gamepad_(gs[i]));
                        }
                        else {
                            _lastGamepads = _emptyGamepads;
                        }
                    }
                }
                if (!_emptyGamepads)
                    _emptyGamepads = new RT.Collection(Gamepad_);
                return _lastGamepads || _emptyGamepads;
            }
            Senses.gamepads = gamepads;
            function first_gamepad() {
                var gs = gamepads();
                for (var i = 0; i < gs.count(); ++i)
                    if (gs.at(i).is_connected())
                        return gs.at(i);
                return undefined;
            }
            Senses.first_gamepad = first_gamepad;
        })(Senses = RT.Senses || (RT.Senses = {}));
        var Gamepad_ = (function (_super) {
            __extends(Gamepad_, _super);
            function Gamepad_(gp) {
                _super.call(this);
                this.gp = gp;
            }
            Gamepad_.prototype.toString = function () {
                return JSON.stringify(this.gp);
            };
            Gamepad_.prototype.equals = function (other) {
                var op = other.gp;
                return this.gp.timestamp == op.timestamp && this.gp.index == op.index && this.gp.buttons.length == op.buttons.length && this.gp.buttons.every(function (v, index) { return op.buttons[index].pressed == v.pressed && op.buttons[index].value == v.value; }) && this.gp.axes.length == op.axes.length && this.gp.axes.every(function (v, index) { return op.axes[index] == v; });
            };
            Gamepad_.prototype.post_to_wall = function (s) {
                s.rt.postText(JSON.stringify(this.gp), s.pc);
            };
            Gamepad_.prototype.id = function () {
                return this.gp.id;
            };
            Gamepad_.prototype.index = function () {
                return this.gp.index;
            };
            Gamepad_.prototype.timestamp = function () {
                return this.gp.timestamp;
            };
            Gamepad_.prototype.is_connected = function () {
                return this.gp.connected;
            };
            Gamepad_.prototype.is_button_pressed = function (name) {
                var index = Gamepad_.buttonNames[name.trim().toLowerCase()];
                if (index == undefined)
                    return false;
                else {
                    var b = this.gp.buttons[index];
                    return b && b.pressed;
                }
            };
            Gamepad_.prototype.button_value = function (name) {
                var index = Gamepad_.buttonNames[name.trim().toLowerCase()];
                if (index == undefined)
                    return 0;
                else {
                    var b = this.gp.buttons[index];
                    return b ? b.value : 0;
                }
            };
            Gamepad_.prototype.axes = function (name) {
                switch (name.trim().toLowerCase()) {
                    case "left stick": return RT.Vector3.mk(this.gp.axes[0], this.gp.axes[1], 0);
                    case "right stick": return RT.Vector3.mk(this.gp.axes[2], this.gp.axes[3], 0);
                    default: return RT.Vector3.zero;
                }
            };
            Gamepad_.prototype.debuggerDisplay = function (clickHandler) {
                return RT.JsonObject.wrap(this.gp).debuggerDisplay(clickHandler);
            };
            Gamepad_.prototype.debuggerChildren = function () {
                return RT.JsonObject.wrap(this.gp).debuggerChildren();
            };
            Gamepad_.buttonNames = {
                "a": 0,
                "b": 1,
                "x": 2,
                "y": 3,
                "left bumper": 4,
                "right bumper": 5,
                "left trigger": 6,
                "right trigger": 7,
                "back": 8,
                "start": 9,
                "left stick": 10,
                "right stick": 11,
                "up": 12,
                "down": 13,
                "left": 14,
                "right": 15,
                "home": 16
            };
            return Gamepad_;
        })(RT.RTValue);
        RT.Gamepad_ = Gamepad_;
        var RuntimeKeyboard = (function () {
            function RuntimeKeyboard(_rt) {
                this._rt = _rt;
                this.keys = {};
                this.repeatDelay = 200;
                this.repeatInterval = 50;
            }
            RuntimeKeyboard.prototype.keyState = function (keyCode, create) {
                var kc = keyCode.toUpperCase();
                var state = this.keys[kc];
                if (!state && create)
                    this.keys[kc] = state = { timeStamp: 0, downTimeStamp: 0, repeating: false };
                return state;
            };
            RuntimeKeyboard.prototype.keyDown = function (evt) {
                TDev.Util.normalizeKeyEvent(evt);
                if (!evt.keyName || evt.fromTextBox || evt.fromTextArea)
                    return false;
                var state = this.keyState(evt.keyName, false);
                if (!state)
                    return false;
                var now = evt.timeStamp || TDev.Util.perfNow();
                if (state.timeStamp == 0) {
                    state.timeStamp = now;
                    state.downTimeStamp = 0;
                }
                if (this._rt && state.down && state.down.handlers && (now - state.downTimeStamp) > (state.repeating ? this.repeatInterval : this.repeatDelay)) {
                    TDev.Util.log("key down " + evt.keyName);
                    this._rt.queueLocalEvent(state.down, [], false);
                    state.downTimeStamp = now;
                    state.repeating = true;
                }
                return true;
            };
            RuntimeKeyboard.prototype.keyUp = function (evt) {
                TDev.Util.normalizeKeyEvent(evt);
                if (!evt.keyName || evt.fromTextBox || evt.fromTextArea)
                    return false;
                var state = this.keyState(evt.keyName, false);
                if (!state)
                    return false;
                if (this._rt && state.timeStamp > 0 && state.up && state.up.handlers)
                    this._rt.queueLocalEvent(state.up, [], false);
                state.timeStamp = 0;
                state.repeating = false;
                return true;
            };
            RuntimeKeyboard.prototype.toKeyCode = function (key, modifier) {
                var k = key;
                if (modifier)
                    k = modifier + "-" + key;
                return k;
            };
            RuntimeKeyboard.prototype.isPressed = function (key) {
                return this.keyState(key, true).timeStamp > 0;
            };
            RuntimeKeyboard.prototype.registerDown = function (key, body) {
                var state = this.keyState(key, true);
                if (!state.down)
                    state.down = new RT.Event_();
                return state.down.addHandler(body);
            };
            RuntimeKeyboard.prototype.registerUp = function (key, body) {
                var state = this.keyState(key, true);
                if (!state.up)
                    state.up = new RT.Event_();
                return state.up.addHandler(body);
            };
            return RuntimeKeyboard;
        })();
        RT.RuntimeKeyboard = RuntimeKeyboard;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Social;
        (function (Social) {
            function send_email(to, subject, body, r) {
                var url = "mailto:" + encodeURIComponent(to || " ") + "?subject=" + encodeURIComponent(subject || " ") + "&body=" + encodeURIComponent(body);
                RT.Web.browse(url, r);
            }
            Social.send_email = send_email;
            function save_email(email_address) {
                TDev.ModalDialog.showText(email_address, 'save email', 'Saving emails is not supported on this platform. Please copy and save this email manually.');
            }
            Social.save_email = save_email;
            function save_contact(contact) {
                TDev.ModalDialog.showText(contact.toFullString(), 'save contact', 'Saving contacts is not supported on this platform. Please copy and save this contact manually.');
            }
            Social.save_contact = save_contact;
            Social.sendSmsAsync = function (to, body) {
                var url = "sms:" + encodeURIComponent(to || " ") + "?body=" + encodeURIComponent(body);
                return RT.Web.browseAsync(url);
            };
            function send_sms(to, body, r) {
                return Social.sendSmsAsync(to, body).done(function () { return r.resume(); });
            }
            Social.send_sms = send_sms;
            function link_phone_number(phone_number) {
                return RT.Link.mk(phone_number, 4 /* phoneNumber */);
            }
            Social.link_phone_number = link_phone_number;
            function link_email(email_address) {
                return RT.Link.mk(email_address, 3 /* email */);
            }
            Social.link_email = link_email;
            function create_message(message) {
                return RT.Message.mk(message);
            }
            Social.create_message = create_message;
            function create_place(name, location) {
                return RT.Place.mk(name, location);
            }
            Social.create_place = create_place;
            function create_contact(nickname) {
                return RT.Contact.mk(nickname);
            }
            Social.create_contact = create_contact;
        })(Social = RT.Social || (RT.Social = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Song = (function (_super) {
            __extends(Song, _super);
            function Song() {
                _super.call(this);
                this._url = undefined;
                this._path = undefined;
                this._albumName = undefined;
                this._artist = undefined;
                this._duration = undefined;
                this._genre = undefined;
                this._name = undefined;
                this._playCount = -1;
                this._rating = -1;
                this._track = -1;
                this._initialized = false;
            }
            Song.mk = function (url, path, name) {
                var song = new Song();
                song._url = url;
                song._path = path;
                song._name = name;
                return song;
            };
            Song.prototype.initAsync = function () {
                this._initialized = true;
                return TDev.Promise.as();
            };
            Song.prototype.initNoData = function () {
                this._initialized = true;
            };
            Song.prototype.init = function (name, albumName, artist, duration, genre, rating, track) {
                this._initialized = true;
                this._name = name;
                this._albumName = albumName;
                this._artist = artist;
                this._duration = duration;
                this._genre = genre;
                this._rating = rating;
                this._track = track;
            };
            Song.prototype.artist = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._artist);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._artist || '');
                    });
            };
            Song.prototype.duration = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._duration);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._duration);
                    });
            };
            Song.prototype.genre = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._genre);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._genre || '');
                    });
            };
            Song.prototype.name = function () {
                return this._name;
            };
            Song.prototype.play_count = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._playCount);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._playCount);
                    });
            };
            Song.prototype.rating = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._rating);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._rating);
                    });
            };
            Song.prototype.track = function (r) {
                var _this = this;
                if (this._initialized)
                    r.resumeVal(this._track);
                else
                    this.initAsync().done(function () {
                        r.resumeVal(_this._track);
                    });
            };
            Song.prototype.url = function () {
                return this._url;
            };
            Song.prototype.path = function () {
                return this._path;
            };
            Song.createAudio = function (url) {
                var audio = document.createElement("audio");
                audio.controls = true;
                audio.crossorigin = "anonymous";
                var source = document.createElement("source");
                source.src = url;
                audio.appendChild(source);
                return audio;
            };
            Song.prototype.play = function () {
                RT.Player.play(this);
            };
            Song.prototype.getViewCore = function (s, b) {
                var _this = this;
                var d = TDev.div("item");
                var dc = TDev.div("item-info item-with-button");
                d.appendChild(dc);
                if (this._name)
                    dc.appendChild(TDev.div("item-title", this._name));
                this.initAsync().done(function () {
                    if (_this._artist)
                        dc.appendChild(TDev.div("item-subtitle", _this._artist));
                    d.appendChild(TDev.div('item-buttons', TDev.HTML.mkRoundButton("svg:play,currentColor", TDev.lf("play"), 469 /* songPlay */, function () { return _this.play(); })));
                });
                return d;
            };
            Song.prototype.protected = function () {
                return undefined;
            };
            Song.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return Song;
        })(RT.RTValue);
        RT.Song = Song;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Sound = (function (_super) {
            __extends(Sound, _super);
            function Sound() {
                _super.call(this);
                this._pan = 0;
                this._pitch = 0;
                this._volume = 1;
                this._url = undefined;
                this._urlToken = 0 /* None */;
                this._originalUrl = undefined;
                this._buffer = undefined;
                this._audio = undefined;
            }
            Sound.mk = function (url, urlToken, originalUrl) {
                if (urlToken === void 0) { urlToken = 0 /* None */; }
                if (originalUrl === void 0) { originalUrl = null; }
                var s = new Sound();
                s._url = url;
                s._urlToken = urlToken;
                s._originalUrl = originalUrl;
                return s;
            };
            Sound.fromDataUrl = function (dataUrl, originalUrl) {
                if (!dataUrl)
                    return TDev.Promise.as(null);
                var m = dataUrl.match(/^data:audio\/(wav|mp4|mp3|mpeg);base64,/i);
                if (!m)
                    return TDev.Promise.as(null);
                var p = Sound.mk(dataUrl, 0 /* None */, originalUrl);
                return p.initAsync();
            };
            Sound.dataUriMimeType = function (url) {
                var m = /^data:(audio\/(wav|mp4|mp3|mpeg));base64,/.exec(url);
                return m ? m[1] : undefined;
            };
            Sound.patchLocalArtUrl = function (url) {
                return url;
            };
            Sound.fromUrl = function (url) {
                if (Sound.dataUriMimeType(url))
                    return Sound.fromDataUrl(url, null);
                var s = Sound.mk(url, 0 /* None */, url);
                return s.initAsync();
            };
            Sound.fromArtId = function (id) {
                return Sound.fromArtUrl(TDev.Cloud.artUrl(id));
            };
            Sound.fromArtUrl = function (url) {
                if (Sound.dataUriMimeType(url))
                    return Sound.fromDataUrl(url, null);
                if (/^\.\/art\//.test(url)) {
                    url = Sound.patchLocalArtUrl(url);
                }
                if (!TDev.Browser.audioWav) {
                    url = TDev.HTML.patchWavToMp4Url(url);
                    TDev.Util.log('fixed art sound: ' + url);
                }
                url = TDev.HTML.proxyResource(url);
                function streamed() {
                    var s = Sound.mk(url, 0 /* None */, url);
                    return s.initAsync();
                }
                if (TDev.Browser.audioDataUrls || RT.AudioContextManager.isSupported()) {
                    return RT.ArtCache.getArtAsync(url, "audio/*").then(function (dataUrl) {
                        if (dataUrl)
                            return Sound.fromDataUrl(dataUrl, url);
                        else
                            return streamed();
                    });
                }
                return streamed();
            };
            Sound.prototype.initAsync = function () {
                var _this = this;
                if (this._buffer || this._audio)
                    return TDev.Promise.as(this);
                if (RT.AudioContextManager.isSupported() && Sound.dataUriMimeType(this._url)) {
                    var array = TDev.Util.decodeDataURL(this._url);
                    if (array)
                        return RT.AudioContextManager.loadAsync(array.buffer).then(function (b) {
                            _this._buffer = b;
                            return _this;
                        });
                }
                return this.createAudioAsync().then(function (audio) { return TDev.HTML.audioLoadAsync(audio); }).then(function (audio) {
                    _this._audio = audio;
                    return _this;
                });
            };
            Sound.prototype.getDataUri = function () {
                if (this._url && Sound.dataUriMimeType(this._url))
                    return this._url;
                return undefined;
            };
            Sound.prototype.createUrlAsync = function () {
                var _this = this;
                var url = this._url;
                switch (this._urlToken) {
                    case 1 /* TouchDevelop */:
                        url = TDev.Cloud.getPrivateApiUrl(url);
                        break;
                    case 2 /* MicrosoftTranslator */:
                        return RT.AzureMarketplace.requestAccessTokenAsync(RT.ApiManager.microsoftTranslatorClientId, RT.ApiManager.microsoftTranslatorClientSecret, "http://api.microsofttranslator.com", "client_credentials").then(function (accessToken) {
                            return url + "&appId=" + encodeURIComponent("BEARER " + accessToken);
                        });
                        break;
                }
                if (/^https?:\/\/.*\.wav$/i.test(url)) {
                    TDev.Util.log('sound createurl: loading online wav file');
                    var wr = RT.WebRequest.mk(url, null);
                    wr.set_accept('audio/wav');
                    return wr.sendAsync().then(function (response) {
                        var bytes = response.contentAsArraybuffer();
                        if (bytes) {
                            var dataUri = 'data:audio/wav;base64,' + TDev.Util.base64EncodeBytes(bytes);
                            TDev.Util.log('sound createurl: loaded online wav file');
                            _this._url = dataUri;
                        }
                        else {
                            TDev.Util.log('sound createurl: failed loading online wav file');
                        }
                        return dataUri;
                    });
                }
                return TDev.Promise.as(url);
            };
            Sound.prototype.createAudioAsync = function () {
                return this.createUrlAsync().then(function (url) {
                    var audio = TDev.HTML.mkAudio(url);
                    return audio;
                });
            };
            Sound.prototype.syncAudioProperties = function (audio) {
                try {
                    audio.volume = this._volume;
                    audio.playbackRate = 1 + this._pitch / 2;
                }
                catch (e) {
                }
            };
            Sound.prototype.pan = function () {
                return this._pan;
            };
            Sound.prototype.set_pan = function (pan) {
                this._pan = pan;
            };
            Sound.prototype.pitch = function () {
                return this._pitch;
            };
            Sound.prototype.set_pitch = function (pitch) {
                this._pitch = pitch;
            };
            Sound.prototype.volume = function () {
                return this._volume;
            };
            Sound.prototype.set_volume = function (v) {
                this._volume = RT.Math_.normalize(v);
                if (this._audio)
                    this.syncAudioProperties(this._audio);
            };
            Sound.prototype.duration = function (r) {
                var _this = this;
                this.initAsync().then(function () {
                    var d = _this._audio ? _this._audio.duration : 0;
                    r.resumeVal(isNaN(d) ? 0 : d);
                }).done();
            };
            Sound.prototype.pause = function () {
            };
            Sound.prototype.resetAsync = function () {
                try {
                    if (this._audio) {
                        this.syncAudioProperties(this._audio);
                        if (this._audio.currentTime != 0) {
                            this._audio.currentTime = 0;
                            if (this._audio.currentTime != 0) {
                                this._audio = null;
                                return this.initAsync();
                            }
                        }
                    }
                }
                catch (e) {
                    RT.Time.log('failed to reset sound position - ' + e);
                }
                return TDev.Promise.as();
            };
            Sound.prototype.playAsync = function () {
                return this.playCoreAsync();
            };
            Sound.prototype.playCoreAsync = function () {
                var _this = this;
                if (!TDev.RuntimeSettings.sounds()) {
                    return TDev.Promise.as(undefined);
                }
                return this.initAsync().then(function () { return _this.resetAsync(); }).then(function () {
                    try {
                        if (_this._buffer && RT.AudioContextManager.isSupported())
                            RT.AudioContextManager.play(_this._buffer, _this._volume);
                        else if (_this._audio)
                            _this._audio.play();
                    }
                    catch (e) {
                        RT.Time.log('failed to play sound - ' + e);
                    }
                });
            };
            Sound.prototype.play = function (r) {
                this.playAsync().done(function () { return r.resumeVal(undefined); });
            };
            Sound.prototype.play_special = function (volume, pitch, pan, r) {
                this.set_volume(volume);
                this.set_pitch(pitch);
                this.set_pan(pan);
                this.play(r);
            };
            Sound.prototype.post_to_wall = function (s) {
                var _this = this;
                s.rt.postBoxedHtml(TDev.HTML.mkButton('play', function () {
                    _this.playAsync().done();
                }), s.pc);
            };
            Sound.prototype.resume = function () {
            };
            Sound.prototype.state = function () {
                return undefined;
            };
            Sound.prototype.stop = function () {
            };
            return Sound;
        })(RT.RTValue);
        RT.Sound = Sound;
        (function (SoundUrlTokenDomain) {
            SoundUrlTokenDomain[SoundUrlTokenDomain["None"] = 0] = "None";
            SoundUrlTokenDomain[SoundUrlTokenDomain["TouchDevelop"] = 1] = "TouchDevelop";
            SoundUrlTokenDomain[SoundUrlTokenDomain["MicrosoftTranslator"] = 2] = "MicrosoftTranslator";
        })(RT.SoundUrlTokenDomain || (RT.SoundUrlTokenDomain = {}));
        var SoundUrlTokenDomain = RT.SoundUrlTokenDomain;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Spring = (function (_super) {
            __extends(Spring, _super);
            function Spring(board, sprite1, sprite2, stiffness) {
                _super.call(this);
                this.board = board;
                this.sprite1 = sprite1;
                this.sprite2 = sprite2;
                this.stiffness = stiffness;
            }
            Spring.prototype.set_stiffness = function (stiffness) {
                this.stiffness = stiffness;
            };
            Spring.prototype.delete_ = function () {
                this.board.deleteSpring(this);
            };
            Spring.prototype.forceOn = function (sprite) {
                var other = sprite === this.sprite1 ? this.sprite2 : this.sprite1;
                var force = other._position.subtract(sprite._position).scale(this.stiffness);
                return force;
            };
            return Spring;
        })(RT.RTValue);
        RT.Spring = Spring;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        (function (SpriteType) {
            SpriteType[SpriteType["Ellipse"] = 0] = "Ellipse";
            SpriteType[SpriteType["Rectangle"] = 1] = "Rectangle";
            SpriteType[SpriteType["Text"] = 2] = "Text";
            SpriteType[SpriteType["Picture"] = 3] = "Picture";
            SpriteType[SpriteType["Anchor"] = 4] = "Anchor";
        })(RT.SpriteType || (RT.SpriteType = {}));
        var SpriteType = RT.SpriteType;
        var SpriteContent = (function (_super) {
            __extends(SpriteContent, _super);
            function SpriteContent() {
                _super.call(this);
            }
            return SpriteContent;
        })(RT.RTValue);
        var Sprite = (function (_super) {
            __extends(Sprite, _super);
            function Sprite() {
                _super.call(this);
                this._parent = undefined;
                this._sheet = undefined;
                this._bubble = undefined;
                this._friction = Number.NaN;
                this._angular_speed = 0;
                this._height = undefined;
                this._location = undefined;
                this._angle = 0;
                this._elasticity = 1;
                this._scale = 1;
                this._speed = RT.Vector2.mk(0, 0);
                this._acceleration = RT.Vector2.mk(0, 0);
                this._width = undefined;
                this._mass = Number.NaN;
                this._position = RT.Vector2.mk(0, 0);
                this._color = RT.Colors.light_gray();
                this._background = undefined;
                this._text = undefined;
                this._textBaseline = undefined;
                this._hidden = false;
                this._opacity = 1;
                this._clip = undefined;
                this._gradient = true;
                this.shapeDirty = true;
                this.hasChanged = true;
                this.normalTouchPoints = [];
                this._springs = [];
                this.onTap = new RT.Event_();
                this.onSwipe = new RT.Event_();
                this.onDrag = new RT.Event_();
                this.onTouchDown = new RT.Event_();
                this.onTouchUp = new RT.Event_();
                this.onEveryFrame = new RT.Event_();
                this._z_index = undefined;
            }
            Sprite.mk = function (tp, x, y, w, h) {
                var s = new Sprite();
                s.spriteType = tp;
                s._width = w;
                s._height = h;
                s._position = new RT.Vector2(x, y);
                s.computeBoundingBox();
                return s;
            };
            Sprite.prototype.friction = function () {
                if (!this._parent)
                    return NaN;
                if (isNaN(this._friction))
                    return this._parent._worldFriction;
                return this._friction;
            };
            Sprite.prototype.set_shadow = function (blur, color, x_offset, y_offset) {
                this._shadowBlur = blur;
                this._shadowColor = color;
                this._shadowOffsetX = x_offset;
                this._shadowOffsetY = y_offset;
            };
            Sprite.prototype.set_friction = function (friction) {
                this._friction = Math.min(1, Math.abs(friction));
            };
            Sprite.prototype.scale = function () {
                return this._scale;
            };
            Sprite.prototype.set_scale = function (value) {
                this._scale = value;
            };
            Sprite.prototype.angular_speed = function () {
                return this._angular_speed;
            };
            Sprite.prototype.set_angular_speed = function (speed) {
                this._angular_speed = speed;
            };
            Sprite.prototype.height = function () {
                return this._height;
            };
            Sprite.prototype.location = function () {
                return this._location;
            };
            Sprite.prototype.set_location = function (location) {
                this._location = location;
            };
            Sprite.prototype.angle = function () {
                return this._angle;
            };
            Sprite.prototype.set_angle = function (angle) {
                if (this._angle != angle) {
                    this._angle = angle;
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.elasticity = function () {
                return this._elasticity;
            };
            Sprite.prototype.set_elasticity = function (elasticity) {
                this._elasticity = Math.abs(elasticity);
            };
            Sprite.prototype.speed_x = function () {
                return this._speed.x();
            };
            Sprite.prototype.set_speed_x = function (vx) {
                this._speed = new RT.Vector2(vx, this._speed.y());
            };
            Sprite.prototype.speed_y = function () {
                return this._speed.y();
            };
            Sprite.prototype.set_speed_y = function (vy) {
                this._speed = new RT.Vector2(this._speed.x(), vy);
            };
            Sprite.prototype.width = function () {
                return this._width;
            };
            Sprite.prototype.set_height = function (height) {
                height = Math.max(1, height);
                if (height != this._height) {
                    this._height = height;
                    if (this._picture)
                        this._width = this._picture.widthSync() / Math.max(1, this._picture.heightSync()) * this._height;
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.set_width = function (width) {
                width = Math.max(1, width);
                if (this._width != width) {
                    this._frame = null;
                    this._width = width;
                    if (this._picture)
                        this._height = this._picture.heightSync() / Math.max(1, this._picture.widthSync()) * this._width;
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.top = function () {
                return this._position.y() - this._height / 2;
            };
            Sprite.prototype.set_top = function (y) {
                this._position = new RT.Vector2(this._position.x(), y + this._height / 2);
            };
            Sprite.prototype.bottom = function () {
                return this._position.y() + this._height / 2;
            };
            Sprite.prototype.set_bottom = function (y) {
                this._position = new RT.Vector2(this._position.x(), y - this._height / 2);
            };
            Sprite.prototype.right = function () {
                return this._position.x() + this._width / 2;
            };
            Sprite.prototype.set_right = function (x) {
                this._position = new RT.Vector2(x - this._width / 2, this._position.y());
            };
            Sprite.prototype.left = function () {
                return this._position.x() - this._width / 2;
            };
            Sprite.prototype.set_left = function (x) {
                this._position = new RT.Vector2(x + this._width / 2, this._position.y());
            };
            Sprite.prototype.x = function () {
                return this._position.x();
            };
            Sprite.prototype.set_x = function (x) {
                this._position = new RT.Vector2(x, this._position.y());
            };
            Sprite.prototype.y = function () {
                return this._position.y();
            };
            Sprite.prototype.set_y = function (y) {
                this._position = new RT.Vector2(this._position.x(), y);
            };
            Sprite.prototype.color = function () {
                return this._color;
            };
            Sprite.prototype.set_color = function (color) {
                this._color = color;
                this.contentChanged();
            };
            Sprite.prototype.opacity = function () {
                return this._opacity;
            };
            Sprite.prototype.set_opacity = function (opacity) {
                this._opacity = Math.min(1, Math.max(0, opacity));
                this.contentChanged();
            };
            Sprite.prototype.gradient = function () {
                return this._gradient;
            };
            Sprite.prototype.set_gradient = function (value) {
                this._gradient = !!value;
            };
            Sprite.prototype.sheet = function () {
                return this._sheet;
            };
            Sprite.prototype.setSheet = function (sheet) {
                this._sheet = sheet;
                this.setPictureInternal(this._sheet._picture);
                this._width = 0;
                this._height = 0;
            };
            Sprite.prototype.set_font_size = function (size, s) {
                var size = Math.round(size);
                if (this.fontSize != size) {
                    this.fontSize = size;
                    this.changed();
                }
            };
            Sprite.prototype.font_size = function () {
                return this.fontSize || 0;
            };
            Sprite.prototype.set_text_baseline = function (pos, s) {
                pos = pos.trim().toLowerCase();
                if (!/^(alphabetic|top|hanging|middle|ideographic|bottom)$/.test(pos))
                    TDev.Util.userError(TDev.lf("invalid text baseline value"), s.pc);
                this._textBaseline = pos;
            };
            Sprite.prototype.text_baseline = function () {
                return this._textBaseline;
            };
            Sprite.prototype.fit_text = function () {
                var ctx;
                if (this._text && this._parent && (ctx = this._parent.renderingContext())) {
                    ctx.save();
                    ctx.font = this.font(this.fontSize);
                    var lines = this._text.split('\n');
                    var w = 0, h = this.fontSize * ((lines.length - 1) * 1.25 + 1);
                    lines.forEach(function (line) { return w = Math.max(w, ctx.measureText(line).width); });
                    ctx.restore();
                    this.set_width(w);
                    this.set_height(h);
                    this._textBaseline = "middle";
                }
            };
            Sprite.prototype.text = function () {
                return this._text;
            };
            Sprite.prototype.set_text = function (text) {
                if (this.spriteType == 2 /* Text */) {
                    this._text = text;
                    this.contentChanged();
                }
            };
            Sprite.prototype.background = function () {
                return this._background ? RT.Colors.transparent() : this._background;
            };
            Sprite.prototype.set_background = function (c) {
                this._background = c;
            };
            Sprite.prototype.bubble = function () {
                return this._bubble;
            };
            Sprite.prototype.set_bubble = function (sprite) {
                if (this._bubble != sprite) {
                    this._bubble = sprite;
                    this.changed();
                }
            };
            Sprite.prototype.say = function (text) {
                this.changed();
                if (!text) {
                    this._bubble = undefined;
                    return undefined;
                }
                var b = this._parent.create_text(10, 10, 16, text);
                b.fit_text();
                b.set_width(b.width() + 8);
                b.set_height(b.height() + 8);
                b.set_color(RT.Colors.black());
                b.set_background(RT.Colors.white());
                b.set_pos(b.width() / 2, -b.height() / 2);
                b.set_friction(1);
                b.set_opacity(0);
                var anim = b.create_animation();
                anim.fade_in(0.5, "linear");
                anim.sleep(text.length * 0.4);
                anim.fade_out(0.5, "linear");
                anim.delete_();
                this.set_bubble(b);
                return b;
            };
            Sprite.prototype.mass = function () {
                if (isNaN(this._mass)) {
                    return Math.max(1e-6, this.width() * this.height());
                }
                return this._mass;
            };
            Sprite.prototype.set_mass = function (mass) {
                if (isNaN(mass) || isFinite(mass) && mass > 0) {
                    this._mass = mass;
                }
            };
            Sprite.prototype.acceleration_x = function () {
                return this._acceleration._x;
            };
            Sprite.prototype.acceleration_y = function () {
                return this._acceleration._y;
            };
            Sprite.prototype.set_acceleration_x = function (x) {
                this._acceleration = new RT.Vector2(x, this._acceleration._y);
            };
            Sprite.prototype.set_acceleration_y = function (y) {
                this._acceleration = new RT.Vector2(this._acceleration._x, y);
            };
            Sprite.prototype.set_acceleration = function (x, y) {
                this._acceleration = new RT.Vector2(x, y);
            };
            Sprite.prototype.on_tap = function (tapped) {
                return this.onTap.addHandler(tapped);
            };
            Sprite.prototype.on_swipe = function (swiped) {
                return this.onSwipe.addHandler(swiped);
            };
            Sprite.prototype.on_drag = function (dragged) {
                return this.onDrag.addHandler(dragged);
            };
            Sprite.prototype.on_touch_down = function (touch_down) {
                return this.onTouchDown.addHandler(touch_down);
            };
            Sprite.prototype.on_touch_up = function (touch_up) {
                return this.onTouchUp.addHandler(touch_up);
            };
            Sprite.prototype.on_every_frame = function (body, s) {
                if (this._parent)
                    this._parent.enableEveryFrameOnSprite(s);
                return this.onEveryFrame.addHandler(body);
            };
            Sprite.prototype.changed = function () {
                this.hasChanged = true;
            };
            Sprite.prototype.contentChanged = function () {
                this.changed();
                this.shapeDirty = true;
            };
            Sprite.prototype.redraw = function (ctx, debug) {
                if (!debug && (this._hidden || this._opacity == 0 || this._width <= 0 || this._height <= 0 || this._scale == 0))
                    return;
                this.drawShape(ctx, debug);
            };
            Sprite.prototype.font = function (size) {
                return size + "px " + '"Segoe UI", "Segoe WP", "Helvetica Neue", Sans-Serif';
            };
            Sprite.prototype.drawShape = function (ctx, debug) {
                var _this = this;
                var fcolor = this.color().toHtml();
                var dcolor = function () { return _this.color().make_transparent(1).toHtml(); };
                var scaledWidth = this._width * this._scale;
                var scaledHeight = this._height * this._scale;
                var scaledFontSize = RT.Math_.round_with_precision(this.fontSize * this._scale, 1);
                ctx.save();
                ctx.translate(this.x(), this.y());
                var ag = this._angle / 180 * Math.PI;
                if (this._frame && this._frame.rotated)
                    ag -= 90;
                ctx.rotate(ag);
                if (this._shadowBlur > 0 && this._shadowColor) {
                    ctx.shadowBlur = this._shadowBlur;
                    ctx.shadowColor = this._shadowColor.toHtml();
                    ctx.shadowOffsetX = this._shadowOffsetX;
                    ctx.shadowOffsetY = this._shadowOffsetY;
                }
                if (this._background && !this._hidden && this._opacity > 0) {
                    ctx.save();
                    ctx.translate(-scaledWidth / 2, -scaledHeight / 2);
                    ctx.fillStyle = this._background.toHtml();
                    ctx.globalAlpha = this._opacity;
                    ctx.fillRect(0, 0, scaledWidth, scaledHeight);
                    ctx.restore();
                }
                switch (this.spriteType) {
                    case 1 /* Rectangle */:
                        ctx.translate(-scaledWidth / 2, -scaledHeight / 2);
                        if (debug) {
                            ctx.strokeStyle = dcolor();
                            ctx.strokeRect(0, 0, scaledWidth, scaledHeight);
                        }
                        ctx.globalAlpha = this._opacity;
                        ctx.fillStyle = fcolor;
                        if (!this._hidden) {
                            ctx.fillRect(0, 0, scaledWidth, scaledHeight);
                        }
                        break;
                    case 0 /* Ellipse */:
                        ctx.scale(scaledWidth / scaledHeight, 1);
                        ctx.translate(-scaledHeight / 2, -scaledHeight / 2);
                        if (debug) {
                            ctx.strokeStyle = dcolor();
                            ctx.strokeRect(0, 0, scaledHeight, scaledHeight);
                        }
                        ctx.globalAlpha = this._opacity;
                        if (!this._hidden) {
                            ctx.beginPath();
                            ctx.arc(scaledHeight / 2, scaledHeight / 2, scaledHeight / 2, 0, 2 * Math.PI);
                            if (TDev.Browser.brokenGradient || !this._gradient) {
                                ctx.fillStyle = fcolor;
                            }
                            else {
                                try {
                                    var radgrad = ctx.createRadialGradient(scaledHeight * 0.75, scaledHeight * 0.25, 1, scaledHeight / 2, scaledHeight / 2, scaledHeight / 2);
                                    radgrad.addColorStop(0, '#FFFFFF');
                                    radgrad.addColorStop(1, fcolor);
                                    ctx.fillStyle = radgrad;
                                }
                                catch (e) {
                                    TDev.Util.log("draw shape crash, color: " + fcolor);
                                    throw e;
                                }
                            }
                            ctx.closePath();
                            ctx.fill();
                        }
                        break;
                    case 3 /* Picture */:
                        ctx.translate(-scaledWidth / 2, -scaledHeight / 2);
                        if (debug) {
                            ctx.strokeStyle = dcolor();
                            ctx.strokeRect(0, 0, scaledWidth, scaledHeight);
                        }
                        if (this._opacity > 0 && this._picture) {
                            ctx.globalAlpha = this._opacity;
                            if (!this._hidden) {
                                if (this._clip) {
                                    if (this._clip[2] > 0 && this._clip[3] > 0)
                                        ctx.drawImage(this._picture.getCanvas(), this._clip[0], this._clip[1], this._clip[2], this._clip[3], 0, 0, scaledWidth, scaledHeight);
                                }
                                else {
                                    ctx.drawImage(this._picture.getCanvas(), 0, 0, this._picture.widthSync(), this._picture.heightSync(), 0, 0, scaledWidth, scaledHeight);
                                }
                            }
                        }
                        break;
                    case 2 /* Text */:
                        ctx.translate(-scaledWidth / 2, -scaledHeight / 2);
                        ctx.fillStyle = fcolor;
                        if (debug) {
                            ctx.strokeStyle = dcolor();
                            ctx.strokeRect(0, 0, scaledWidth, scaledHeight);
                        }
                        if (!this._hidden) {
                            ctx.globalAlpha = this._opacity;
                            ctx.font = this.font(scaledFontSize);
                            var lines = this._text.split("\n");
                            ctx.textBaseline = this._textBaseline || "top";
                            if (!this._textBaseline)
                                ctx.translate(0, scaledFontSize * 0.2);
                            else
                                ctx.translate(0, scaledHeight / 2);
                            for (var line = 0; line < lines.length; line++) {
                                var msr = ctx.measureText(lines[line]);
                                ctx.save();
                                var offset = scaledWidth - msr.width;
                                if (offset > 0) {
                                    offset = offset / 2;
                                }
                                else {
                                    offset = 0;
                                }
                                ctx.translate(offset, 0);
                                ctx.fillText(lines[line], 0, 0);
                                ctx.restore();
                                ctx.translate(0, scaledFontSize * 1.25);
                            }
                        }
                        break;
                    case 4 /* Anchor */:
                        ctx.translate(-scaledWidth / 2, -scaledHeight / 2);
                        if (debug) {
                            ctx.strokeStyle = dcolor();
                            ctx.strokeRect(0, 0, scaledWidth, scaledHeight);
                        }
                        break;
                }
                if (debug) {
                    ctx.restore();
                    ctx.save();
                    ctx.translate(this.x() + this.boundingMaxX + 2, this.y() + this.boundingMinY);
                    ctx.font = "10px sans-serif";
                    ctx.fillStyle = dcolor();
                    ctx.fillText("x:" + this.x().toFixed(1), 0, 0);
                    ctx.translate(0, 10);
                    ctx.fillText("y:" + this.y().toFixed(1), 0, 0);
                    if (this.speed_x() != 0 || this.speed_y() != 0) {
                        ctx.translate(0, 10);
                        ctx.fillText("vx:" + this.speed_x().toFixed(1), 0, 0);
                        ctx.translate(0, 10);
                        ctx.fillText("vy:" + this.speed_y().toFixed(1), 0, 0);
                    }
                    ctx.restore();
                    ctx.save();
                    ctx.strokeStyle = "green";
                    ctx.beginPath();
                    var cap = this.capsule();
                    ctx.moveTo(cap.x(), cap.y());
                    ctx.lineWidth = 5;
                    ctx.lineTo(cap.x() + cap.z(), cap.y() + cap.w());
                    ctx.lineWidth = 1;
                    ctx.moveTo(this.x() + this.boundingMinX, this.y() + this.boundingMinY);
                    ctx.lineTo(this.x() + this.boundingMaxX, this.y() + this.boundingMinY);
                    ctx.lineTo(this.x() + this.boundingMaxX, this.y() + this.boundingMaxY);
                    ctx.lineTo(this.x() + this.boundingMinX, this.y() + this.boundingMaxY);
                    ctx.lineTo(this.x() + this.boundingMinX, this.y() + this.boundingMinY);
                    ctx.moveTo(this.x() - 3, this.y());
                    ctx.lineTo(this.x() + 3, this.y());
                    ctx.moveTo(this.x(), this.y() - 3);
                    ctx.lineTo(this.x(), this.y() + 3);
                    ctx.stroke();
                }
                ctx.restore();
                if (this._bubble && this._bubble.is_deleted())
                    this._bubble = null;
                if (this._bubble && this._bubble.is_visible() && this._bubble.opacity() > 0) {
                    ctx.save();
                    ctx.translate(this.x() + this.width() / 2, this.y() - this.height() / 2);
                    this._bubble.redraw(ctx, debug);
                    ctx.restore();
                }
            };
            Sprite.prototype.computeBoundingBox = function () {
                var rx = this.radiusX();
                var ry = this.radiusY();
                if (this._angle == 0 || this._angle == 180) {
                    this.boundingMinX = -rx;
                    this.boundingMaxX = rx;
                    this.boundingMinY = -ry;
                    this.boundingMaxY = ry;
                    return;
                }
                if (this._angle == 90 || this._angle == 270 || this._angle == -90) {
                    this.boundingMinX = -ry;
                    this.boundingMaxX = ry;
                    this.boundingMinY = -rx;
                    this.boundingMaxY = rx;
                    return;
                }
                this.boundingMinX = Number.MAX_VALUE;
                this.boundingMaxX = Number.MIN_VALUE;
                this.boundingMinY = Number.MAX_VALUE;
                this.boundingMaxY = Number.MIN_VALUE;
                var sine = Math.sin(Math.PI * this._angle / 180);
                var cosine = Math.cos(Math.PI * this._angle / 180);
                this.updateBoundingX(this.rotateX(rx, -ry, sine, cosine));
                this.updateBoundingY(this.rotateY(rx, -ry, sine, cosine));
                this.updateBoundingX(this.rotateX(rx, ry, sine, cosine));
                this.updateBoundingY(this.rotateY(rx, ry, sine, cosine));
                this.updateBoundingX(this.rotateX(-rx, ry, sine, cosine));
                this.updateBoundingY(this.rotateY(-rx, ry, sine, cosine));
                this.updateBoundingX(this.rotateX(-rx, -ry, sine, cosine));
                this.updateBoundingY(this.rotateY(-rx, -ry, sine, cosine));
            };
            Sprite.prototype.rotateX = function (x, y, sine, cosine) {
                return x * cosine - y * sine;
            };
            Sprite.prototype.rotateY = function (x, y, sine, cosine) {
                return x * sine + y * cosine;
            };
            Sprite.prototype.rotate = function (v) {
                var sine = Math.sin(Math.PI * this._angle / 180);
                var cosine = Math.cos(Math.PI * this._angle / 180);
                var x = this.rotateX(v.x(), v.y(), sine, cosine);
                var y = this.rotateY(v.x(), v.y(), sine, cosine);
                return new RT.Vector2(x, y);
            };
            Sprite.prototype.minPointSegment = function (x0, y0, dx0, dy0, x1, y1) {
                var wx = x0 - x1;
                var wy = y0 - y1;
                var d = dx0 * dx0 + dy0 * dy0;
                if (Math.abs(d) < 0.00001) {
                    var result = new RT.Vector2(wx, wy);
                    result.from = 0;
                    return result;
                }
                var from = 1;
                var t = -(wx * dx0 + wy * dy0) / d;
                if (t < 0) {
                    t = 0;
                    from = 2;
                }
                else if (t > 1) {
                    t = 1;
                    from = 3;
                }
                var result = new RT.Vector2(wx + t * dx0, wy + t * dy0);
                result.from = from;
                return result;
            };
            Sprite.prototype.minConnectingSegment = function (x0, y0, dx0, dy0, x1, y1, dx1, dy1) {
                var b = dx0 * dy1 - dy0 * dx1;
                if (b != 0) {
                    var wx = x0 - x1;
                    var wy = y0 - y1;
                    var d = dx0 * wy - dy0 * wx;
                    var e = dx1 * wy - dy1 * wx;
                    var t = d / b;
                    var s = e / b;
                    if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
                        var result = new RT.Vector4(x0 + s * dx0, y0 + s * dy0, 0, 0);
                        result.from = 32;
                        return result;
                    }
                }
                var v1 = this.minPointSegment(x0, y0, dx0, dy0, x1, y1);
                var v2 = this.minPointSegment(x0, y0, dx0, dy0, x1 + dx1, y1 + dy1);
                var v3 = this.minPointSegment(x1, y1, dx1, dy1, x0, y0);
                var v4 = this.minPointSegment(x1, y1, dx1, dy1, x0 + dx0, y0 + dy0);
                var d1 = v1.length();
                var d2 = v2.length();
                var d3 = v3.length();
                var d4 = v4.length();
                var m = Math.min(d1, d2, d3, d4);
                if (m == d1) {
                    var result = new RT.Vector4(x1, y1, v1.x(), v1.y());
                    result.from = v1.from + 4;
                    return result;
                }
                if (m == d2) {
                    var result = new RT.Vector4(x1 + dx1, y1 + dy1, v2.x(), v2.y());
                    result.from = v1.from + 8;
                    return result;
                }
                if (m == d3) {
                    var result = new RT.Vector4(x0, y0, v3.x(), v3.y());
                    result.from = v1.from + 12;
                    return result;
                }
                var result = new RT.Vector4(x0 + dx0, y0 + dy0, v4.x(), v4.y());
                result.from = v1.from + 16;
                return result;
            };
            Sprite.prototype.updateBoundingX = function (newX) {
                this.boundingMaxX = Math.max(this.boundingMaxX, newX);
                this.boundingMinX = Math.min(this.boundingMinX, newX);
            };
            Sprite.prototype.updateBoundingY = function (newY) {
                this.boundingMaxY = Math.max(this.boundingMaxY, newY);
                this.boundingMinY = Math.min(this.boundingMinY, newY);
            };
            Sprite.prototype.bbRadius = function (unitNormal) {
                var angle = Math.atan(unitNormal.y() / unitNormal.x());
                angle = angle - Math.PI * this._angle / 180;
                var tan = Math.tan(angle);
                var horiz = Math.abs(this.radiusY() / tan);
                if (horiz <= this.radiusX()) {
                    return Math.abs(this.radiusY() / Math.sin(angle));
                }
                var vert = Math.abs(this.radiusX() * tan);
                if (vert > this.radiusY()) {
                    debugger;
                }
                return Math.abs(this.radiusX() / Math.cos(angle));
            };
            Sprite.prototype.radius = function (unitNormal) {
                var angle = Math.atan(unitNormal.y() / unitNormal.x());
                angle = angle - Math.PI * this._angle / 180;
                var sin = Math.sin(angle);
                var cos = Math.cos(angle);
                var majorAxis, majorAxisMult;
                var minorAxis, minorAxisMult;
                if (this.width >= this.height) {
                    majorAxis = this.radiusX();
                    minorAxis = this.radiusY();
                    majorAxisMult = sin;
                    minorAxisMult = cos;
                }
                else {
                    majorAxis = this.radiusY();
                    minorAxis = this.radiusX();
                    majorAxisMult = cos;
                    minorAxisMult = -sin;
                }
                var rad = (majorAxis * minorAxis) / (Math.sqrt(majorAxis * majorAxis * majorAxisMult * majorAxisMult + minorAxis * minorAxis * minorAxisMult * minorAxisMult));
                return rad;
            };
            Sprite.prototype.radiusX = function () {
                return this.width() / 2;
            };
            Sprite.prototype.radiusY = function () {
                return this.height() / 2;
            };
            Sprite.prototype.stepDisplacement = function () {
                return this.newPosition.subtract(this._position);
            };
            Sprite.prototype.computeForces = function (positionSpeed) {
                var force = (this._parent.gravity().add(this._acceleration)).scale(this.mass());
                for (var i = 0; i < this._springs.length; i++) {
                    var spring = this._springs[i];
                    force = force.add(spring.forceOn(this));
                }
                for (var i = 0; i < this.normalTouchPoints.length; i++) {
                    var unitNormal = this.normalTouchPoints[i];
                    if (RT.Vector2.dot(unitNormal, force) > 0)
                        continue;
                    if (RT.Vector2.dot(unitNormal, new RT.Vector2(positionSpeed.z(), positionSpeed.w())) > 0)
                        continue;
                    var unitParallel = unitNormal.rotate90Left();
                    var proj = unitParallel.scale(RT.Vector2.dot(force, unitParallel));
                    force = proj;
                }
                if (Math.abs(force.x()) < 0.1)
                    force = new RT.Vector2(0, force.y());
                if (Math.abs(force.y()) < 0.1)
                    force = new RT.Vector2(force.x(), 0);
                return force;
            };
            Sprite.prototype.isEqualToEpsilon = function (x, p) {
                return (Math.round((x - p) / 2) == 0.0);
            };
            Sprite.prototype.derivativePosAndSpeed = function (dT, positionSpeed) {
                var accel = this.computeForces(positionSpeed).scale(1 / this.mass());
                return new RT.Vector4((positionSpeed.z() + dT * accel.x()), (positionSpeed.w() + dT * accel.y()), accel.x(), accel.y());
            };
            Sprite.prototype.actualFriction = function () {
                if (isNaN(this._friction))
                    return this._parent._worldFriction;
                return this._friction;
            };
            Sprite.prototype.RungaKutta = function (dT) {
                var yi = RT.Vector4.fromV2V2(this._position, this._speed);
                var u1 = this.derivativePosAndSpeed(0, yi).scale(dT);
                var u2 = this.derivativePosAndSpeed(dT / 2, yi.add(u1.scale(.5))).scale(dT);
                var u3 = this.derivativePosAndSpeed(dT / 2, yi.add(u2.scale(.5))).scale(dT);
                var u4 = this.derivativePosAndSpeed(dT, yi.add(u3)).scale(dT);
                var avg = (u1.add(u2.scale(2)).add(u3.scale(2)).add(u4)).scale(1 / 6);
                var nz = avg.z();
                if (avg.z() < 0.1 && avg.z() > -0.1)
                    nz = 0;
                var nw = avg.w();
                if (avg.w() < 0.1 && avg.w() > -0.1)
                    nw = 0;
                var nx = avg.x() * (1 - this.actualFriction());
                var ny = avg.y() * (1 - this.actualFriction());
                avg = new RT.Vector4(nx, ny, nz, nw);
                this.midSpeed = new RT.Vector2(avg.x() / dT, avg.y() / dT);
                var yip1 = yi.add(avg);
                yip1 = yip1.withW(yip1.w() * (1 - this.actualFriction()));
                yip1 = yip1.withZ(yip1.z() * (1 - this.actualFriction()));
                return yip1;
            };
            Sprite.prototype.update = function (dT) {
                TDev.Util.assertCode(dT >= 0);
                if (!this._parent)
                    return;
                var yip1 = this.RungaKutta(dT);
                this.newPosition = new RT.Vector2(yip1.x(), yip1.y());
                this.newSpeed = new RT.Vector2(yip1.z(), yip1.w());
                this.newRotation = this._angle + this._angular_speed * dT;
            };
            Sprite.prototype.commitUpdate = function (rt, dT) {
                if (!this._lastPosition || !this._lastPosition.equals(this.newPosition) || this._angle != this.newRotation)
                    this.changed();
                this._position = this.newPosition;
                this._angle = this.newRotation;
                this._speed = this.newSpeed;
                if (this._animations) {
                    var anyDone = false;
                    this._animations.forEach(function (anim) { return anyDone = !anim.evolve(rt, dT) || anyDone; });
                    if (anyDone) {
                        this._animations = this._animations.filter(function (anim) { return anim.isActive; });
                        if (this._animations.length == 0)
                            this._animations = undefined;
                    }
                }
                this.computeBoundingBox();
            };
            Sprite.prototype.hide = function () {
                this._hidden = true;
            };
            Sprite.prototype.is_visible = function () {
                return !this._hidden;
            };
            Sprite.prototype.move = function (delta_x, delta_y) {
                this._position = new RT.Vector2(this._position._x + delta_x, this._position._y + delta_y);
            };
            Sprite.prototype.move_towards = function (other, fraction) {
                var center1 = this._position;
                var center2 = other._position;
                var dir = center2.subtract(center1).scale(fraction);
                this.move(dir._x, dir._y);
            };
            Sprite.prototype.capsule = function () {
                var s0x, s0y, s1x, s1y, d0x, d0y, d1x, d1y;
                if (this._width > this._height) {
                    d0x = (this._width - this._height);
                    d0y = 0;
                    s0x = -d0x / 2;
                    s0y = 0;
                }
                else {
                    d0x = 0;
                    d0y = (this._height - this._width);
                    s0x = 0;
                    s0y = -d0y / 2;
                }
                var d0 = this.rotate(new RT.Vector2(d0x, d0y));
                var s0 = this.rotate(new RT.Vector2(s0x, s0y));
                return new RT.Vector4(this.x() + s0.x(), this.y() + s0.y(), d0.x(), d0.y());
            };
            Sprite.prototype.capsuleRadius = function () {
                if (this._width < this._height) {
                    return this._width / 2;
                }
                return this._height / 2;
            };
            Sprite.prototype.overlaps_with = function (other) {
                if (!this._parent)
                    return false;
                if (!other._parent)
                    return false;
                if (isNaN(this.x()) || isNaN(this.y()) || isNaN(other.x()) || isNaN(other.y()))
                    return false;
                if (this.x() + this.boundingMaxX <= other.x() + other.boundingMinX)
                    return false;
                if (this.x() + this.boundingMinX >= other.x() + other.boundingMaxX)
                    return false;
                if (this.y() + this.boundingMaxY <= other.y() + other.boundingMinY)
                    return false;
                if (this.y() + this.boundingMinY >= other.y() + other.boundingMaxY)
                    return false;
                var cap1 = this.capsule();
                var cap2 = other.capsule();
                var seg = this.minConnectingSegment(cap1.x(), cap1.y(), cap1.z(), cap1.w(), cap2.x(), cap2.y(), cap2.z(), cap2.w());
                if (this._parent) {
                    this._parent._minSegments.push(seg);
                }
                var radi = this.capsuleRadius() + other.capsuleRadius();
                var dist = seg.z() * seg.z() + seg.w() * seg.w();
                if (dist >= radi * radi) {
                    seg.overlap = false;
                    return false;
                }
                seg.overlap = true;
                return true;
                var center1 = this._position;
                var center2 = other._position;
                var distVec = center2.subtract(center1);
                var dist = distVec.length();
                if (dist == 0)
                    return true;
                var norm = distVec.normalize();
                var radius1 = this.radius(norm);
                var radius2 = other.radius(norm);
                if (radius1 + radius2 >= dist)
                    return true;
                return false;
            };
            Sprite.prototype.overlap_with = function (sprites) {
                if (!this._parent)
                    return new RT.SpriteSet();
                return this._parent.overlapWithAny(this, sprites);
            };
            Sprite.prototype.equals = function (other) {
                return this === other;
            };
            Sprite.prototype.set_picture = function (pic, r) {
                var _this = this;
                if (this.spriteType != 3 /* Picture */)
                    r.resume();
                else
                    pic.loadFirst(r, function () {
                        _this.setPictureInternal(pic);
                    });
            };
            Sprite.prototype.setPictureInternal = function (pic) {
                this._picture = pic;
                this._width = pic.widthSync();
                this._height = pic.heightSync();
                this.computeBoundingBox();
                this.contentChanged();
            };
            Sprite.prototype.picture = function () {
                return this._picture;
            };
            Sprite.prototype.set_pos = function (x, y) {
                this._position = new RT.Vector2(x, y);
            };
            Sprite.prototype.set_speed = function (vx, vy) {
                this._speed = new RT.Vector2(vx, vy);
            };
            Sprite.prototype.show = function () {
                this._hidden = false;
            };
            Sprite.prototype.speed_towards = function (other, magnitude) {
                var center1 = this._position;
                var center2 = other._position;
                var speed = center2.subtract(center1);
                speed = speed.normalize();
                speed = speed.scale(magnitude);
                this._speed = speed;
            };
            Sprite.prototype.set_clip = function (left, top, width, height) {
                if (this._picture && isFinite(left) && isFinite(top) && isFinite(width) && isFinite(height)) {
                    this._frame = undefined;
                    this._width = width;
                    this._height = height;
                    this._clip = [left, top, width, height];
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.setFrame = function (frame) {
                if (this._frame != frame) {
                    this._frame = frame;
                    if (this._width <= 0)
                        this._width = frame.width;
                    this._height = frame.width <= 0 ? frame.height : this._width / frame.width * frame.height;
                    this._clip = [frame.x, frame.y, frame.width, frame.height];
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.move_clip = function (x, y) {
                if (this._clip && this._picture) {
                    var left = (this._clip[0] + x) % this._picture.widthSync();
                    if (left < 0)
                        left += this._clip[2];
                    else if (left + this._clip[2] > this._picture.widthSync())
                        left = 0;
                    var top = (this._clip[1] + y) % this._picture.heightSync();
                    if (top < 0)
                        top += this._clip[3];
                    else if (top + this._clip[3] > this._picture.heightSync())
                        top = 0;
                    this._clip = [left, top, this._clip[2], this._clip[3]];
                    this.computeBoundingBox();
                    this.contentChanged();
                }
            };
            Sprite.prototype.delete_ = function () {
                if (!this._parent) {
                    return;
                }
                this._parent.deleteSprite(this);
                this._parent = null;
            };
            Sprite.prototype.is_deleted = function () {
                return !this._parent;
            };
            Sprite.prototype.contains = function (x, y) {
                var diff = RT.Vector2.mk(x, y).subtract(this._position);
                var norm = diff.normalize();
                var rad = this.bbRadius(norm);
                if (diff.length() <= rad)
                    return true;
                return false;
            };
            Sprite.prototype.addSpring = function (sp) {
                this._springs.push(sp);
            };
            Sprite.prototype.removeSpring = function (sp) {
                var idx = this._springs.indexOf(sp);
                if (idx > -1)
                    this._springs.splice(idx, 1);
            };
            Sprite.prototype.z_index = function () {
                return this._z_index;
            };
            Sprite.prototype.set_z_index = function (zindex) {
                if (this._z_index != zindex) {
                    this._z_index = zindex;
                    if (this._parent)
                        this._parent.spritesChanged();
                }
            };
            Sprite.prototype.createAnimation = function () {
                var anim = new RT.SpriteAnimation(this);
                return anim;
            };
            Sprite.prototype.startAnimation = function (anim) {
                TDev.Util.assert(anim._sprite == this);
                if (!this._animations)
                    this._animations = [];
                this._animations.push(anim);
            };
            Sprite.prototype.create_animation = function () {
                var anim = this.createAnimation();
                this.startAnimation(anim);
                return anim;
            };
            Sprite.prototype.debuggerChildren = function () {
                return {
                    'Z-index': this.z_index(),
                    Friction: this.friction(),
                    'Angular speed': this.angular_speed(),
                    Angle: this.angle(),
                    Elasticity: this.elasticity(),
                    'Speed X': this.speed_x(),
                    'Speed Y': this.speed_y(),
                    X: this.x(),
                    Y: this.y(),
                    Color: this.color(),
                    Opacity: this.opacity(),
                    Text: this.text(),
                    Picture: this.picture(),
                    Mass: this.mass(),
                    'Acceleration X': this.acceleration_x(),
                    'Acceleration Y': this.acceleration_y(),
                    Visible: this.is_visible(),
                };
            };
            return Sprite;
        })(RT.RTValue);
        RT.Sprite = Sprite;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var SpriteSet = (function (_super) {
            __extends(SpriteSet, _super);
            function SpriteSet() {
                _super.call(this);
                this._elements = [];
            }
            SpriteSet.prototype.clear = function () {
                this._elements = [];
            };
            SpriteSet.prototype.count = function () {
                return this._elements.length;
            };
            SpriteSet.prototype.add = function (sprite) {
                if (this.contains(sprite))
                    return false;
                this._elements.push(sprite);
                return true;
            };
            SpriteSet.prototype.add_from = function (old_set, sprite) {
                if (!old_set.contains(sprite) || this.contains(sprite))
                    return false;
                old_set.remove(sprite);
                this.add(sprite);
                return true;
            };
            SpriteSet.prototype.remove = function (sprite) {
                var idx = this.index_of(sprite);
                if (idx >= 0) {
                    this._elements.splice(idx, 1);
                    return true;
                }
                return false;
            };
            SpriteSet.prototype.contains = function (sprite) {
                var idx = this.index_of(sprite);
                if (idx < 0) {
                    return false;
                }
                return true;
            };
            SpriteSet.prototype.remove_first = function () {
                var result = this._elements.shift();
                return result;
            };
            SpriteSet.prototype.index_of = function (sprite) {
                var idx = this._elements.indexOf(sprite);
                return idx;
            };
            SpriteSet.prototype.index_of_obj = function (sprite) {
                return this.index_of(sprite);
            };
            SpriteSet.prototype.at = function (index) {
                var elmt = this._elements[index];
                return elmt;
            };
            SpriteSet.prototype.get_enumerator = function () {
                return this._elements.slice(0);
            };
            SpriteSet.prototype.debuggerChildren = function () {
                return this._elements;
            };
            return SpriteSet;
        })(RT.RTValue);
        RT.SpriteSet = SpriteSet;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var String_;
        (function (String_) {
            function split(self, separator) {
                return RT.Collection.mkStrings(self.split(separator));
            }
            String_.split = split;
            function valueFromArtUrl(url) {
                var m = /^data:[^,]*base64,/i.exec(url);
                if (m)
                    return RT.Web.base64_decode(url.substring(m[0].length));
                return null;
            }
            String_.valueFromArtUrl = valueFromArtUrl;
            function valueToArtUrl(value) {
                return "data:text/plain;base64," + RT.Web.base64_encode(value);
            }
            String_.valueToArtUrl = valueToArtUrl;
            function fromArtUrl(url) {
                var value = valueFromArtUrl(url);
                if (value)
                    return TDev.Promise.wrap(value);
                return RT.ArtCache.getArtAsync(url).then(function (dataUrl) {
                    if (dataUrl)
                        return TDev.Promise.as(valueFromArtUrl(dataUrl));
                    else
                        TDev.Util.httpGetTextAsync(url);
                }).then(function (txt) { return txt; }, function (e) {
                    RT.App.logEvent(RT.App.ERROR, "art", TDev.lf("failed to load url {0}", url), undefined);
                    return "";
                });
            }
            String_.fromArtUrl = fromArtUrl;
            function trim_overflow(self, lim) {
                var v = self;
                if (v && v.length > lim)
                    v = v.slice(0, lim) + "...";
                return v;
            }
            String_.trim_overflow = trim_overflow;
            function post_to_wall(self, s) {
                if (TDev.dbg && self != null && self.indexOf("magic trap ") == 0) {
                    var tests = new TDev.Revisions.SessionTests(s.rt);
                    tests.runtest(self.substr(11));
                    return;
                }
                if (self != null) {
                    if (s.rt.onCssPage())
                        s.rt.postUnboxedText(self, s.pc);
                    else
                        s.rt.postBoxedTextWithTap(self, self, s.pc);
                }
            }
            String_.post_to_wall = post_to_wall;
            function count(self) {
                return self.length;
            }
            String_.count = count;
            function code_at(self, index) {
                return self.charCodeAt(index);
            }
            String_.code_at = code_at;
            function at(self, index) {
                return index < 0 || index >= self.length ? undefined : self.charAt(index);
            }
            String_.at = at;
            function to_lower_case(self) {
                return self.toLocaleLowerCase();
            }
            String_.to_lower_case = to_lower_case;
            function to_upper_case(self) {
                return self.toLocaleUpperCase();
            }
            String_.to_upper_case = to_upper_case;
            function to_unicode(self) {
                return self.length == 1 ? self.charCodeAt(0) : undefined;
            }
            String_.to_unicode = to_unicode;
            function to_character_code(self) {
                return self.length == 1 ? self.charCodeAt(0) : 0;
            }
            String_.to_character_code = to_character_code;
            function compare(self, other) {
                var r = self.localeCompare(other);
                if (r < 0)
                    return -1;
                if (r > 0)
                    return 1;
                return 0;
            }
            String_.compare = compare;
            function concat(self, other) {
                return self + other;
            }
            String_.concat = concat;
            function concat_op(self, other) {
                return self + other;
            }
            String_.concat_op = concat_op;
            function concatAny(a, b) {
                function toStr(v) {
                    if (v === undefined || v === null)
                        return "(invalid)";
                    if (typeof v == "string")
                        return v;
                    if (typeof v == "JsonObject")
                        return v.toString();
                    if (v.to_string)
                        return v.to_string();
                    return v + "";
                }
                return toStr(a) + toStr(b);
            }
            String_.concatAny = concatAny;
            function contains(self, value) {
                return self.indexOf(value) > -1;
            }
            String_.contains = contains;
            function equals(self, other) {
                return self == other;
            }
            String_.equals = equals;
            function ends_with(self, value) {
                var i = self.lastIndexOf(value);
                return i > -1 && i == (self.length - value.length);
            }
            String_.ends_with = ends_with;
            function index_of(self, value, start) {
                return self.indexOf(value, start);
            }
            String_.index_of = index_of;
            function insert(self, start, value) {
                if (!value)
                    return self;
                if (start < 0 || start > self.length)
                    return undefined;
                return self.slice(0, start) + value + self.slice(start);
            }
            String_.insert = insert;
            function is_empty(self) {
                return self.length == 0;
            }
            String_.is_empty = is_empty;
            function is_match_regex(self, pattern) {
                var rx = new RegExp(pattern, "");
                return rx.test(self);
            }
            String_.is_match_regex = is_match_regex;
            function last_index_of(self, value, start) {
                return self.lastIndexOf(value, start);
            }
            String_.last_index_of = last_index_of;
            function match(self, pattern) {
                try {
                    var rx = new RegExp(pattern, "");
                    var r = rx.exec(self);
                    if (!r)
                        return RT.Collections.create_string_collection();
                    return RT.Collection.mkStrings(TDev.Util.toArray(r));
                }
                catch (e) {
                    RT.Time.log('invalid regex pattern: ' + pattern);
                    return RT.Collections.create_string_collection();
                }
            }
            String_.match = match;
            function matches(self, pattern) {
                try {
                    var rx = new RegExp(pattern, "g");
                    var r = self.match(rx);
                    return RT.Collection.mkStrings(r || []);
                }
                catch (e) {
                    RT.Time.log('invalid regex pattern: ' + pattern);
                    return RT.Collections.create_string_collection();
                }
            }
            String_.matches = matches;
            function remove(self, start) {
                return self.slice(0, start);
            }
            String_.remove = remove;
            function replace(self, old, new_) {
                if (!old)
                    return self;
                return self.split(old).join(new_);
            }
            String_.replace = replace;
            function replace_regex(self, pattern, replace) {
                try {
                    var rx = new RegExp(pattern, "g");
                    return self.replace(rx, replace);
                }
                catch (e) {
                    RT.Time.log('invalid regex pattern: ' + pattern);
                    return undefined;
                }
            }
            String_.replace_regex = replace_regex;
            function replace_regex_with_converter(self, pattern, replace, s) {
                try {
                    var rx = new RegExp(pattern, "g");
                }
                catch (e) {
                    RT.Time.log('invalid regex pattern: ' + pattern);
                    return undefined;
                }
                return self.replace(rx, function () {
                    var args = [];
                    for (var _i = 0; _i < arguments.length; _i++) {
                        args[_i - 0] = arguments[_i];
                    }
                    return s.rt.runUserAction(replace, [RT.Collection.fromArray(args, "string")]);
                });
            }
            String_.replace_regex_with_converter = replace_regex_with_converter;
            function starts_with(self, value) {
                return self.indexOf(value) == 0;
            }
            String_.starts_with = starts_with;
            function substring(self, start, length) {
                return self.substr(start, length);
            }
            String_.substring = substring;
            function trim(self, chars) {
                if (!self || !chars)
                    return self;
                return trim_start(trim_end(self, chars), chars);
            }
            String_.trim = trim;
            function trim_start(self, chars) {
                if (!self || !chars)
                    return self;
                var i = 0;
                for (; i < self.length && chars.indexOf(self[i]) > -1; i++) {
                }
                return self.substr(i);
            }
            String_.trim_start = trim_start;
            function trim_end(self, chars) {
                if (!self || !chars)
                    return self;
                var i = self.length;
                for (; i > 0 && chars.indexOf(self[i - 1]) > -1; i--) {
                }
                return self.substring(0, i);
            }
            String_.trim_end = trim_end;
            function to_time(self) {
                if (self != null) {
                    var s = trim(self, ' \t\n\r');
                    var m = s.match(/(\d{1,2})\s*:\s*(\d{1,2})\s*(:\s*(\d{1,2}))?\s*(pm|am)?/i);
                    if (m) {
                        var hours = parseFloat(m[1]);
                        if (m[5] && /pm/i.test(m[5]))
                            hours += 12;
                        var minutes = parseFloat(m[2]);
                        var seconds = m[4] ? parseFloat(m[4]) : 0;
                        return RT.Math_.clamp(0, 23, hours) * 3600 + RT.Math_.clamp(0, 59, minutes) * 60 + seconds;
                    }
                }
                return undefined;
            }
            String_.to_time = to_time;
            function to_number(self) {
                var r = undefined;
                if (/^\s*[-+]?\d*\.?(\d+([eE][-+]?\d+)?)?\s*$/.test(self)) {
                    r = parseFloat(self);
                }
                else if (/^\s*[-+]?0x[a-z0-9]{1,4}\s*$/i.test(self)) {
                    r = parseInt(self);
                }
                if (isNaN(r))
                    return undefined;
                return r;
            }
            String_.to_number = to_number;
            function to_boolean(self) {
                return self.trim().toLocaleLowerCase() == "true";
            }
            String_.to_boolean = to_boolean;
            function to_location(self) {
                var s = trim_start(trim_end(self, ")}] "), "([{ ");
                var seps = ',;:';
                for (var i = 0; i < seps.length; ++i) {
                    var index = s.indexOf(seps[i]);
                    if (index > -1) {
                        var lat = to_number(s.substring(0, index));
                        var long = to_number(s.substring(index + 1));
                        if (lat && long && !isNaN(lat) && !isNaN(long)) {
                            return RT.Location_.mkShort(lat, long);
                        }
                    }
                }
                return undefined;
            }
            String_.to_location = to_location;
            function share(self, network, r) {
                TDev.HTML.showProgressNotification(TDev.lf("sharing text..."));
                RT.ShareManager.shareTextAsync(self, network).done(function () { return r.resume(); });
            }
            String_.share = share;
            function copy_to_clipboard(self, r) {
                RT.ShareManager.copyToClipboardAsync(self).done(function () { return r.resume(); });
            }
            String_.copy_to_clipboard = copy_to_clipboard;
            function to_datetime(self) {
                return RT.DateTime.parse(self);
            }
            String_.to_datetime = to_datetime;
            function to_color(self) {
                return RT.Color.fromHtml(self);
            }
            String_.to_color = to_color;
            function picker() {
                var inp = TDev.HTML.mkTextInput("text", TDev.lf("color"));
                return {
                    html: inp,
                    validate: function () { return true; },
                    get: function () { return inp.value; },
                    set: function (v) {
                        inp.value = v + "";
                    }
                };
            }
            String_.picker = picker;
            function to_json(self) {
                return RT.JsonObject.wrap(self);
            }
            String_.to_json = to_json;
        })(String_ = RT.String_ || (RT.String_ = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var StringMap = (function (_super) {
            __extends(StringMap, _super);
            function StringMap() {
                _super.call(this);
                this.items = new Object();
                this.length = 0;
            }
            StringMap.mk = function (items) {
                var r = new StringMap();
                r.items = TDev.Util.clone(items);
                r.length = Object.keys(r.items).length;
                return r;
            };
            StringMap.prototype.count = function () {
                return this.length;
            };
            StringMap.prototype.keys = function () {
                var keys = Object.keys(this.items);
                return RT.Collection.mkStrings(keys);
            };
            StringMap.prototype.at = function (key) {
                var result = (this.items)[key];
                return (result);
            };
            StringMap.prototype.set_at = function (key, value) {
                var val = this.items[key];
                if (val != value) {
                    if (val != null) {
                        this.length--;
                        delete this.items[key];
                    }
                    if (value != null) {
                        this.items[key] = value;
                        this.length++;
                    }
                }
            };
            StringMap.prototype.to_json = function () {
                return RT.JsonObject.wrap(this.exportJson(null));
            };
            StringMap.prototype.from_json = function (jobj) {
                this.importJson(null, jobj.value());
            };
            StringMap.prototype.exportJson = function (ctx) {
                var _this = this;
                var obj = {};
                Object.keys(this.items).forEach(function (k) {
                    obj[k] = _this.items[k];
                });
                return obj;
            };
            StringMap.prototype.importJson = function (ctx, json) {
                var _this = this;
                if ((typeof (json) !== "object") || Array.isArray(json)) {
                    this.clear();
                    return this;
                }
                else {
                    this.items = {};
                    this.length = 0;
                    Object.keys(json).forEach(function (k) {
                        var v = json[k];
                        if (typeof v == "string") {
                            _this.items[k] = v;
                            _this.length++;
                        }
                    });
                }
            };
            StringMap.prototype.clear = function () {
                this.items = new Object();
                this.length = 0;
            };
            StringMap.prototype.set_many = function (strings) {
                var _this = this;
                Object.keys(strings.items).forEach(function (key) {
                    var value = strings.at(key);
                    _this.set_at(key, value);
                });
            };
            StringMap.prototype.remove = function (key) {
                var val = this.items[key];
                if (val != null) {
                    this.length--;
                    delete this.items[key];
                }
            };
            StringMap.prototype.toString = function () {
                var _this = this;
                var s = "{" + Object.keys(this.items).map(function (key) { return key + "->" + _this.at(key); }).join(",") + "}";
                return s;
            };
            StringMap.prototype.get_enumerator = function () {
                return Object.keys(this.items);
            };
            StringMap.prototype.post_to_wall = function (s) {
                s.rt.postBoxedText(this.toString(), s.pc);
            };
            StringMap.prototype.debuggerDisplay = function (clickHandler) {
                return TDev.span(null, "String Map[" + this.length + "]").withClick(clickHandler);
            };
            StringMap.prototype.debuggerChildren = function () {
                var ret = {};
                var items = this.items;
                Object.keys(items).forEach(function (k) { return ret['"' + k + '"'] = items[k]; });
                return ret;
            };
            return StringMap;
        })(RT.RTValue);
        RT.StringMap = StringMap;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var TextBox = (function (_super) {
            __extends(TextBox, _super);
            function TextBox() {
                _super.apply(this, arguments);
                this._text = undefined;
                this._icon = undefined;
                this._font_size = undefined;
                this._background = undefined;
                this._foreground = undefined;
                this._border = undefined;
            }
            TextBox.mk = function (text, font_size) {
                var tb = new TextBox();
                tb._text = text;
                tb._font_size = font_size;
                return tb;
            };
            TextBox.prototype.text = function () {
                return this._text;
            };
            TextBox.prototype.set_text = function (text, s) {
                this._text = text;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.icon = function () {
                return this._icon;
            };
            TextBox.prototype.set_icon = function (pic, s) {
                this._icon = pic;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.font_size = function () {
                return this._font_size;
            };
            TextBox.prototype.set_font_size = function (size, s) {
                this._font_size = size;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.background = function () {
                return this._background;
            };
            TextBox.prototype.set_background = function (color, s) {
                this._background = color;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.foreground = function () {
                return this._foreground;
            };
            TextBox.prototype.set_foreground = function (color, s) {
                this._foreground = color;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.border = function () {
                return this._border;
            };
            TextBox.prototype.set_border = function (color, s) {
                this._border = color;
                this.updateOnWall(s, this.box);
            };
            TextBox.prototype.getViewCore = function (s, b) {
                this._el = TDev.div('wall-text');
                this.box = b;
                this.updateOnWall(s, b);
                return this._el;
            };
            TextBox.prototype.updateOnWall = function (s, b) {
                var el = this._el;
                if (!el)
                    return;
                el.setChildren([]);
                var style = el.style;
                style.margin = '0.5em';
                if (this._background) {
                    style.backgroundColor = this._background.toHtml();
                }
                else {
                    style.backgroundColor = '#F0F0F0';
                }
                if (this._foreground) {
                    style.color = this._foreground.toHtml();
                }
                else {
                    style.color = null;
                }
                if (this._border) {
                    style.border = "3px solid " + this._border.toHtml();
                }
                else {
                    style.border = null;
                }
                if (this._icon) {
                    var pel = TDev.div('', this._icon.getViewCore(s, b));
                    pel.style.display = 'inline';
                    pel.style.margin = '8px 8px 8px 8px';
                    el.appendChild(pel);
                }
                var txt = TDev.div('', this._text);
                txt.style.display = 'inline';
                txt.style.margin = '8px 8px 8px 8px';
                txt.style.verticalAlign = 'top';
                if (this._font_size) {
                    txt.style.fontSize = (this._font_size / 20.0 * 0.8).toFixed(1) + "em";
                }
                el.appendChild(txt);
                b.RefreshOnScreen();
            };
            TextBox.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return TextBox;
        })(RT.RTValue);
        RT.TextBox = TextBox;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Time;
        (function (Time) {
            var _rt;
            var everyFrameTimer;
            function rt_start(rt) {
                _rt = rt;
                everyFrameTimer = undefined;
            }
            Time.rt_start = rt_start;
            function rt_stop(rt) {
                _rt = undefined;
                if (everyFrameTimer)
                    everyFrameTimer.pause();
                everyFrameTimer = undefined;
            }
            Time.rt_stop = rt_stop;
            function on_every_frame(body, s) {
                if (!everyFrameTimer)
                    everyFrameTimer = new RT.Timer(s.rt, 0.02, false);
                return everyFrameTimer.on_trigger(body);
            }
            Time.on_every_frame = on_every_frame;
            function run_after(seconds, body, s) {
                seconds = Math.max(0.02, seconds);
                var timer = new RT.Timer(s.rt, seconds, true);
                timer.on_trigger(body);
                return timer;
            }
            Time.run_after = run_after;
            function run_every(seconds, body, s) {
                seconds = Math.max(0.02, seconds);
                var timer = new RT.Timer(s.rt, seconds, false);
                timer.on_trigger(body);
                return timer;
            }
            Time.run_every = run_every;
            function sleep(seconds, s) {
                s.rt.yield_now();
                TDev.Util.setTimeout(seconds * 1000, function () {
                    s.rt.yield_now();
                    s.resume();
                });
            }
            Time.sleep = sleep;
            function now(s) {
                if (s)
                    s.rt.registerTimeDependency();
                return RT.DateTime.mk(new Date());
            }
            Time.now = now;
            function today() {
                return now().date();
            }
            Time.today = today;
            function tomorrow() {
                return today().add_days(1);
            }
            Time.tomorrow = tomorrow;
            function fail_if_not(condition) {
                RT.App.fail_if_not(condition);
            }
            Time.fail_if_not = fail_if_not;
            function stop(r) {
                RT.App.stop(r);
            }
            Time.stop = stop;
            function log(message) {
                RT.App.log(message);
            }
            Time.log = log;
            function stop_and_close(r) {
                RT.App.stop(r);
            }
            Time.stop_and_close = stop_and_close;
            function create(year, month, day, hour, minute, second) {
                return RT.DateTime.mkFull(year, month, day, hour, minute, second);
            }
            Time.create = create;
        })(Time = RT.Time || (RT.Time = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Timer = (function (_super) {
            __extends(Timer, _super);
            function Timer(rt, interval, oneTime) {
                if (oneTime === void 0) { oneTime = true; }
                _super.call(this);
                this.rt = rt;
                this.interval = interval;
                this.oneTime = oneTime;
                this.armed = false;
                this.active = true;
                this.version = rt.versionNumber;
                this.handlerEvent = new RT.Event_();
            }
            Timer.prototype.clear = function () {
                this.handlerEvent.clearHandlers();
                this.pause();
            };
            Timer.prototype.on_trigger = function (body) {
                var b = this.handlerEvent.addHandler(body);
                this.arm();
                return b;
            };
            Timer.prototype.is_active = function () {
                return this.active;
            };
            Timer.prototype.is_interval = function () {
                return !this.oneTime;
            };
            Timer.prototype.set_interval = function (seconds) {
                this.interval = seconds;
                this.oneTime = false;
            };
            Timer.prototype.set_timeout = function (seconds) {
                this.interval = seconds;
                this.oneTime = true;
            };
            Timer.prototype.pause = function () {
                this.active = false;
            };
            Timer.prototype.resume = function () {
                this.active = true;
                this.arm();
            };
            Timer.prototype.arm = function () {
                var _this = this;
                if (this.armed || this.rt.isStopped() || this.version != this.rt.versionNumber) {
                    return;
                }
                var milli = this.interval * 1000;
                var eventHandler = function () {
                    _this.armed = false;
                    if (_this.version != _this.rt.versionNumber)
                        return;
                    if (_this.oneTime) {
                        _this.active = false;
                    }
                    else {
                        if (_this.rt && _this.handlerEvent.handlers && _this.active && !_this.armed) {
                            _this.armed = true;
                            TDev.Util.setTimeout(milli, eventHandler);
                        }
                    }
                    if (_this.handlerEvent.pendinghandlers == 0)
                        _this.rt.queueLocalEvent(_this.handlerEvent);
                };
                if (this.rt && this.handlerEvent.handlers && this.active && !this.armed) {
                    this.armed = true;
                    TDev.Util.setTimeout(milli, eventHandler);
                }
            };
            return Timer;
        })(RT.RTValue);
        RT.Timer = Timer;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Vector2 = (function (_super) {
            __extends(Vector2, _super);
            function Vector2(_x, _y) {
                _super.call(this);
                this._x = _x;
                this._y = _y;
            }
            Vector2.mk = function (x, y) {
                return new Vector2(x, y);
            };
            Vector2.prototype.x = function () {
                return this._x;
            };
            Vector2.prototype.y = function () {
                return this._y;
            };
            Vector2.prototype.length = function () {
                return Math.sqrt(this._x * this._x + this._y * this._y);
            };
            Vector2.prototype.distance = function (other) {
                return this.subtract(other).length();
            };
            Vector2.prototype.negate = function () {
                return Vector2.mk(-this._x, -this._y);
            };
            Vector2.prototype.normalize = function () {
                return this.scale(1 / this.length());
            };
            Vector2.prototype.add = function (other) {
                return Vector2.mk(this._x + other._x, this._y + other._y);
            };
            Vector2.prototype.subtract = function (other) {
                return Vector2.mk(this._x - other._x, this._y - other._y);
            };
            Vector2.prototype.multiply = function (other) {
                return Vector2.mk(this._x * other._x, this._y * other._y);
            };
            Vector2.prototype.scale = function (scalar) {
                return Vector2.mk(this._x * scalar, this._y * scalar);
            };
            Vector2.dot = function (v1, other) {
                return v1._x * other._x + v1._y * other._y;
            };
            Vector2.prototype.clamp = function (min, max) {
                return Vector2.mk(RT.Math_.clamp(min._x, max._x, this._x), RT.Math_.clamp(min._y, max._y, this._y));
            };
            Vector2.prototype.linear_interpolation = function (other, amount) {
                var a = RT.Math_.normalize(amount);
                var a1 = 1.0 - a;
                return Vector2.mk(a * this._x + a1 * other._x, a * this._y + a1 * other._y);
            };
            Vector2.prototype.to_string = function () {
                return '(' + this._x + ',' + this._y + ')';
            };
            Vector2.prototype.rotate90Left = function () {
                return Vector2.mk(-this._y, this._x);
            };
            Vector2.prototype.equals = function (that) {
                return this._x == that._x && this._y == that._y;
            };
            return Vector2;
        })(RT.RTValue);
        RT.Vector2 = Vector2;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Vector3 = (function (_super) {
            __extends(Vector3, _super);
            function Vector3(_x, _y, _z) {
                _super.call(this);
                this._x = _x;
                this._y = _y;
                this._z = _z;
            }
            Vector3.mk = function (x, y, z) {
                var v = new Vector3(x, y, z);
                return v;
            };
            Vector3.prototype.toJsonKey = function () {
                return [this._x, this._y, this._z];
            };
            Vector3.prototype.keyCompareTo = function (o) {
                var other = o;
                var diff = this._x - other._x;
                if (diff)
                    return diff;
                diff = this._y - other._y;
                if (diff)
                    return diff;
                diff = this._z - other._z;
                return diff;
            };
            Vector3.prototype.exportJson = function (ctx) {
                return [this._x, this._y, this._z];
            };
            Vector3.prototype.importJson = function (ctx, json) {
                TDev.Util.oops("should not call immutable instance for importing");
                return undefined;
            };
            Vector3.mkFromJson = function (ctx, json) {
                if (!Array.isArray(json) || json.length !== 3)
                    return undefined;
                var ensurenr = function (x) { return (typeof x === "number" ? x : 0); };
                return new Vector3(ensurenr(json[0]), ensurenr(json[1]), ensurenr(json[2]));
            };
            Vector3.prototype.x = function () {
                return this._x;
            };
            Vector3.prototype.y = function () {
                return this._y;
            };
            Vector3.prototype.z = function () {
                return this._z;
            };
            Vector3.prototype.length = function () {
                return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z);
            };
            Vector3.prototype.distance = function (other) {
                return this.subtract(other).length();
            };
            Vector3.prototype.negate = function () {
                return Vector3.mk(-this._x, -this._y, -this._z);
            };
            Vector3.prototype.normalize = function () {
                return this.scale(1 / this.length());
            };
            Vector3.prototype.add = function (other) {
                return Vector3.mk(this._x + other._x, this._y + other._y, this._z + other._z);
            };
            Vector3.prototype.subtract = function (other) {
                return Vector3.mk(this._x - other._x, this._y - other._y, this._z - other._z);
            };
            Vector3.prototype.multiply = function (other) {
                return Vector3.mk(this._x * other._x, this._y * other._y, this._z * other._z);
            };
            Vector3.prototype.scale = function (scalar) {
                return Vector3.mk(this._x * scalar, this._y * scalar, this._z * scalar);
            };
            Vector3.prototype.clamp = function (min, max) {
                return Vector3.mk(RT.Math_.clamp(min._x, max._x, this._x), RT.Math_.clamp(min._y, max._y, this._y), RT.Math_.clamp(min._z, max._z, this._z));
            };
            Vector3.prototype.cross = function (other) {
                return Vector3.mk(this._y * other._z - this._z * other._y, this._z * other._x - this._x * other._z, this._x * other._y - this._y * other._x);
            };
            Vector3.prototype.linear_interpolation = function (other, amount) {
                var a = RT.Math_.normalize(amount);
                var a1 = 1.0 - a;
                return Vector3.mk(a * this._x + a1 * other._x, a * this._y + a1 * other._y, a * this._z + a1 * other._z);
            };
            Vector3.prototype.to_string = function () {
                return '(' + this._x.toPrecision(6) + ',' + this._y.toPrecision(6) + ',' + this._z.toPrecision(6) + ')';
            };
            Vector3.prototype.toString = function () {
                return this.to_string();
            };
            Vector3.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            Vector3.zero = Vector3.mk(0, 0, 0);
            return Vector3;
        })(RT.RTValue);
        RT.Vector3 = Vector3;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Vector4 = (function (_super) {
            __extends(Vector4, _super);
            function Vector4(_x, _y, _z, _w) {
                _super.call(this);
                this._x = _x;
                this._y = _y;
                this._z = _z;
                this._w = _w;
            }
            Vector4.mk = function (x, y, z, w) {
                return new Vector4(x, y, z, w);
            };
            Vector4.fromV3 = function (v, w) {
                return new Vector4(v.x(), v.y(), v.z(), w);
            };
            Vector4.fromV2 = function (v, z, w) {
                return new Vector4(v.x(), v.y(), z, w);
            };
            Vector4.fromV2V2 = function (v1, v2) {
                return new Vector4(v1.x(), v1.y(), v2.x(), v2.y());
            };
            Vector4.prototype.x = function () {
                return this._x;
            };
            Vector4.prototype.y = function () {
                return this._y;
            };
            Vector4.prototype.z = function () {
                return this._z;
            };
            Vector4.prototype.w = function () {
                return this._w;
            };
            Vector4.prototype.length = function () {
                return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
            };
            Vector4.prototype.distance = function (other) {
                return this.subtract(other).length();
            };
            Vector4.prototype.negate = function () {
                return Vector4.mk(-this._x, -this._y, -this._z, -this._w);
            };
            Vector4.prototype.normalize = function () {
                return this.scale(1 / this.length());
            };
            Vector4.prototype.add = function (other) {
                return Vector4.mk(this._x + other._x, this._y + other._y, this._z + other._z, this._w + other._w);
            };
            Vector4.prototype.subtract = function (other) {
                return Vector4.mk(this._x - other._x, this._y - other._y, this._z - other._z, this._w - other._w);
            };
            Vector4.prototype.multiply = function (other) {
                return Vector4.mk(this._x * other._x, this._y * other._y, this._z * other._z, this._w * other._w);
            };
            Vector4.prototype.scale = function (scalar) {
                return Vector4.mk(this._x * scalar, this._y * scalar, this._z * scalar, this._w * scalar);
            };
            Vector4.prototype.clamp = function (min, max) {
                return Vector4.mk(RT.Math_.clamp(min._x, max._x, this._x), RT.Math_.clamp(min._y, max._y, this._y), RT.Math_.clamp(min._z, max._z, this._z), RT.Math_.clamp(min._w, max._w, this._w));
            };
            Vector4.prototype.linear_interpolation = function (other, amount) {
                var a = RT.Math_.normalize(amount);
                var a1 = 1.0 - a;
                return Vector4.mk(a * this._x + a1 * other._x, a * this._y + a1 * other._y, a * this._z + a1 * other._z, a * this._w + a1 * other._w);
            };
            Vector4.prototype.to_string = function () {
                return '(' + this._x + ',' + this._y + ',' + this._z + ',' + this._w + ')';
            };
            Vector4.prototype.withX = function (x) {
                return Vector4.mk(x, this._y, this._z, this._w);
            };
            Vector4.prototype.withY = function (y) {
                return Vector4.mk(this._x, y, this._z, this._w);
            };
            Vector4.prototype.withZ = function (z) {
                return Vector4.mk(this._x, this._y, z, this._w);
            };
            Vector4.prototype.withW = function (w) {
                return Vector4.mk(this._x, this._y, this._z, w);
            };
            return Vector4;
        })(RT.RTValue);
        RT.Vector4 = Vector4;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Wall;
        (function (Wall) {
            var R = TDev.HTML;
            function clear(s) {
                s.rt.clearWall();
            }
            Wall.clear = clear;
            function display_search(on) {
            }
            Wall.display_search = display_search;
            function body(text) {
                var r = TDev.div("wall-dialog-body");
                TDev.Browser.setInnerHTML(r, TDev.Util.formatText(text));
                return r;
            }
            Wall.body = body;
            function prompt(text, r) {
                var rt = r.rt;
                var m = new TDev.ModalDialog();
                m.add([body(text), TDev.div("wall-dialog-buttons", [R.mkButtonOnce("ok", function () { return m.dismiss(); })])]);
                m.onDismiss = function () { return r.resume(); };
                m.show();
            }
            Wall.prompt = prompt;
            function ask_boolean(text, caption, r) {
                var rt = r.rt;
                var value = false;
                var m = new TDev.ModalDialog();
                m.add([TDev.div("wall-dialog-header", text), body(caption), TDev.div("wall-dialog-buttons", [R.mkButton(TDev.lf("no"), function () {
                    value = false;
                    m.dismiss();
                }), R.mkButton(TDev.lf("yes"), function () {
                    value = true;
                    m.dismiss();
                })])]);
                m.onDismiss = function () { return r.resumeVal(value); };
                m.show();
            }
            Wall.ask_boolean = ask_boolean;
            function ask_number(text, r) {
                var rt = r.rt;
                var t = R.mkTextInput("number", TDev.lf("enter a number"));
                t.value = "";
                var value = 0;
                var m = new TDev.ModalDialog();
                m.add([
                    body(text),
                    TDev.div("wall-dialog-input", t),
                    TDev.div("wall-dialog-buttons", [R.mkButton(TDev.lf("ok"), function () {
                        value = t.valueAsNumber;
                        if (!isFinite(value))
                            value = parseFloat(t.value);
                        if (!isFinite(value))
                            value = undefined;
                        m.dismiss();
                    })])
                ]);
                m.onDismiss = function () { return r.resumeVal(value); };
                m.show();
                TDev.Util.setKeyboardFocus(t);
            }
            Wall.ask_number = ask_number;
            function ask_string(text, r) {
                var rt = r.rt;
                var t = R.mkTextArea("variableDesc");
                t.value = "";
                var value = "";
                var m = new TDev.ModalDialog();
                m.add([body(text), TDev.div("wall-dialog-input", t), TDev.div("wall-dialog-buttons", [R.mkButton(TDev.lf("ok"), function () {
                    value = t.value;
                    m.dismiss();
                })])]);
                m.onDismiss = function () { return r.resumeVal(value); };
                m.show();
                TDev.Util.setKeyboardFocusTextArea(t);
            }
            Wall.ask_string = ask_string;
            function screenshot(r) {
                ScreenshotManager.toScreenshotURLAsync(r.rt.host, true).then(function (data) {
                    if (data != null)
                        return RT.Picture.fromUrl(data);
                    else
                        return TDev.Promise.as(undefined);
                }).done(function (p) { return r.resumeVal(p); });
            }
            Wall.screenshot = screenshot;
            function create_text_box(text, font_size) {
                return RT.TextBox.mk(text, font_size);
            }
            Wall.create_text_box = create_text_box;
            function pick_string(text, caption, values, r) {
                var rt = r.rt;
                var m = new TDev.ModalDialog();
                var index = -1;
                var btns = values.a.map(function (st, i) { return TDev.div('modalDialogChooseItem', st).withClick(function () {
                    index = i;
                    m.dismiss();
                }); });
                m.add([TDev.div("wall-dialog-header", text), body(caption)]);
                m.onDismiss = function () { return r.resumeVal(index); };
                m.choose(btns);
            }
            Wall.pick_string = pick_string;
            function pick_time(text, caption, r) {
                var rt = r.rt;
                var t = R.mkTextInput("time", TDev.lf("enter a time"));
                t.style.borderStyle = 'hidden';
                t.style.borderColor = 'red';
                t.onkeyup = function (ev) {
                    t.style.borderStyle = RT.String_.to_time(t.value) != null ? 'hidden' : 'solid';
                };
                var value = undefined;
                var m = new TDev.ModalDialog();
                m.add([TDev.div("wall-dialog-header", text), body(caption), TDev.div("wall-dialog-input", t), body("Enter a time like 15:43 or 3:43pm or 15:43:20 or 3:43:20pm"), TDev.div("wall-dialog-buttons", [R.mkButton(TDev.lf("ok"), function () {
                    var tt = RT.String_.to_time(t.value);
                    if (tt != null)
                        value = RT.Time.today().add_seconds(tt);
                    m.dismiss();
                })])]);
                m.onDismiss = function () { return r.resumeVal(value); };
                m.show();
                TDev.Util.setKeyboardFocus(t);
            }
            Wall.pick_time = pick_time;
            function pick_date(text, caption, r) {
                var rt = r.rt;
                var t = R.mkTextInput("date", TDev.lf("enter a date"));
                t.style.borderStyle = 'hidden';
                t.style.borderColor = 'red';
                t.onkeyup = function (ev) {
                    t.style.borderStyle = RT.DateTime.parse(t.value) != null ? 'hidden' : 'solid';
                };
                var value = undefined;
                var m = new TDev.ModalDialog();
                m.add([TDev.div("wall-dialog-header", text), body(caption), TDev.div("wall-dialog-input", t), TDev.div("wall-dialog-buttons", [R.mkButton(TDev.lf("ok"), function () {
                    value = RT.DateTime.parse(t.value);
                    m.dismiss();
                })])]);
                m.onDismiss = function () { return r.resumeVal(value); };
                m.show();
                TDev.Util.setKeyboardFocus(t);
            }
            Wall.pick_date = pick_date;
            function set_foreground(color, s) {
                s.rt.getCurrentPage().fgColor = color.toHtml();
                s.rt.applyPageAttributes(true);
            }
            Wall.set_foreground = set_foreground;
            function clear_background(s) {
                var p = s.rt.getCurrentPage();
                p.bgColor = null;
                p.bgPicture = null;
                p.bgPictureUrl = null;
                p.bgVideo = null;
                s.rt.applyPageAttributes(true);
            }
            Wall.clear_background = clear_background;
            function set_background(color, s) {
                s.rt.getCurrentPage().bgColor = color.toHtml();
                s.rt.applyPageAttributes(true);
            }
            Wall.set_background = set_background;
            function set_page_transition_style(style, s) {
                s.rt.pageTransitionStyle = style;
            }
            Wall.set_page_transition_style = set_page_transition_style;
            function set_background_picture(picture, r) {
                var wp = r.rt.getCurrentPage();
                var url = picture.getReadonlyUrlSync();
                if (url) {
                    wp.bgPictureUrl = url;
                    wp.bgPicture = null;
                    r.rt.applyPageAttributes(true);
                    r.resume();
                }
                else {
                    picture.loadFirst(r, function () {
                        if (picture.widthSync() === 0 || picture.heightSync() === 0)
                            return;
                        wp.bgPictureWidth = picture.widthSync();
                        wp.bgPictureHeight = picture.heightSync();
                        wp.bgPicture = picture.getViewCanvas();
                        wp.bgPictureUrl = null;
                        r.rt.applyPageAttributes(true);
                    });
                }
            }
            Wall.set_background_picture = set_background_picture;
            function set_background_camera(camera, r) {
                camera.getVideoAsync(r.rt).then(function (v) {
                    if (v) {
                        r.rt.getCurrentPage().bgVideo = v;
                        r.rt.applyPageAttributes(true);
                    }
                    r.resume();
                }).done();
            }
            Wall.set_background_camera = set_background_camera;
            function set_transform_matrix(m11, m12, m21, m22, offsetx, offsety) {
            }
            Wall.set_transform_matrix = set_transform_matrix;
            function set_reversed(bottom, s) {
                s.rt.setWallDirection(bottom);
            }
            Wall.set_reversed = set_reversed;
            function show_title_bar(visible, s) {
                s.rt.getCurrentPage().chromeVisible = visible;
                s.rt.applyPageAttributes(true);
            }
            Wall.show_title_bar = show_title_bar;
            function show_back_button(visible, s) {
                s.rt.getCurrentPage().backButtonVisible = visible;
                s.rt.applyPageAttributes(true);
            }
            Wall.show_back_button = show_back_button;
            function set_title(text, s) {
                s.rt.getCurrentPage().title = text;
                s.rt.applyPageAttributes(true);
            }
            Wall.set_title = set_title;
            function set_subtitle(text, s) {
                s.rt.getCurrentPage().subtitle = text;
                s.rt.applyPageAttributes(true);
            }
            Wall.set_subtitle = set_subtitle;
            function icon_names() {
                return button_icon_names();
            }
            Wall.icon_names = icon_names;
            function clear_buttons(s) {
                s.rt.clearPageButtons();
            }
            Wall.clear_buttons = clear_buttons;
            function add_button(icon, text, s) {
                if (s.rt.getPageButtons().length < 4) {
                    if (text.length > 8)
                        text = text.substr(0, 8);
                    else if (text.length == 0)
                        text = "???";
                    var pageButton = RT.PageButton.mk(icon, text, s.rt.getCurrentPage().rtPage());
                    s.rt.addPageButton(pageButton);
                    s.rt.applyPageAttributes(true);
                    return pageButton;
                }
                return undefined;
            }
            Wall.add_button = add_button;
            function current_page(s) {
                return s.rt.getCurrentPage().rtPage();
            }
            Wall.current_page = current_page;
            function push_new_page(s) {
                s.rt.forceNonRender("You may not push a page here");
                return s.rt.pushPage().rtPage();
            }
            Wall.push_new_page = push_new_page;
            function pop_page(s) {
                s.rt.forceNonRender("You may not pop a page here");
                return s.rt.popPage();
            }
            Wall.pop_page = pop_page;
            function pop_page_with_transition(style, s) {
                s.rt.forceNonRender("You may not pop a page here");
                return s.rt.popPage(style);
            }
            Wall.pop_page_with_transition = pop_page_with_transition;
            function pages(s) {
                var c = s.rt.getPageCount();
                var arr = [];
                for (var i = 0; i < c; ++i)
                    arr.push(s.rt.getPageAt(i).rtPage());
                return RT.Collection.mkAny(RT.Page, arr);
            }
            Wall.pages = pages;
            function button_icon_names() {
                return RT.Collection.mkStrings([
                    "add",
                    "back",
                    "cancel",
                    "check",
                    "close",
                    "delete",
                    "download",
                    "edit",
                    "favs.addto",
                    "favs",
                    "feature.camera",
                    "feature.email",
                    "feature.search",
                    "feature.settings",
                    "feature.video",
                    "folder",
                    "minus",
                    "new",
                    "next",
                    "questionmark",
                    "refresh",
                    "save",
                    "share",
                    "stop",
                    "sync",
                    "transport.ff",
                    "transport.pause",
                    "transport.play",
                    "transport.rew",
                    "upload"
                ]);
            }
            Wall.button_icon_names = button_icon_names;
            function width(s) {
                return s.rt.host.fullWallWidth();
            }
            Wall.width = width;
            function height(s) {
                return s.rt.host.fullWallHeight();
            }
            Wall.height = height;
        })(Wall = RT.Wall || (RT.Wall = {}));
        var ScreenshotManager;
        (function (ScreenshotManager) {
            ScreenshotManager.toScreenshotURLAsync = function (rt, background) {
                if (RT.App.env().has_host()) {
                    var durl;
                    return RT.App.hostExecAsync("screen.screenshot").then(function (url) {
                        durl = url;
                        return background ? TDev.Promise.as() : RT.App.hostExecAsync("screen.show");
                    }).then(function () { return durl; });
                }
                var c = rt.toScreenshotCanvas();
                try {
                    var data = c ? c.toDataURL('image/png') : undefined;
                    return TDev.Promise.as(data);
                }
                catch (e) {
                    return TDev.Promise.as(undefined);
                }
            };
        })(ScreenshotManager = RT.ScreenshotManager || (RT.ScreenshotManager = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var BingServices;
        (function (BingServices) {
            function readBingSearchResponse(response) {
                var links = [];
                try {
                    var json = response.content_as_json();
                    if (json) {
                        for (var i = 0; i < json.count(); ++i) {
                            var jlink = json.at(i);
                            var url = jlink.string('address');
                            var name = jlink.string('name');
                            var thumb = jlink.string('thumb');
                            var web = jlink.string('web');
                            if (url != null && url.length > 0)
                                links.push({ url: url, name: name, thumbUrl: thumb, web: web });
                        }
                    }
                    return links;
                }
                catch (ex) {
                }
                return links;
            }
            BingServices.searchAsync = function (kind, query, loc) {
                if (!query)
                    return TDev.Promise.as([]);
                var url = 'runtime/web/search?kind=' + encodeURIComponent(kind) + '&query=' + encodeURIComponent(query);
                if (loc) {
                    url += '&latitude=' + encodeURIComponent(loc.latitude().toString()) + '&longitude=' + encodeURIComponent(loc.longitude().toString());
                }
                var request = RT.WebRequest.mk(TDev.Cloud.getPrivateApiUrl(url), undefined);
                return request.sendAsync().then(function (response) { return readBingSearchResponse(response); });
            };
        })(BingServices = RT.BingServices || (RT.BingServices = {}));
        var WebEventSource = (function (_super) {
            __extends(WebEventSource, _super);
            function WebEventSource(rt, source) {
                _super.call(this, rt);
                this.source = source;
                this.onMessages = {};
            }
            WebEventSource.prototype.on_message = function (name, handler) {
                var _this = this;
                if (!name || /^close|error$/i.test(name))
                    TDev.Util.userError(TDev.lf("name cannot be 'close' or 'error'"));
                var onMessage = this.onMessages[name];
                if (!onMessage) {
                    onMessage = new RT.Event_();
                    if (this.source)
                        this.source.addEventListener(name, function (e) {
                            if (_this.source && onMessage.handlers) {
                                var d = e.data || "";
                                _this.rt.queueLocalEvent(onMessage, [d]);
                            }
                        }, false);
                }
                return onMessage.addHandler(handler);
            };
            WebEventSource.prototype.state = function () {
                if (!this.source)
                    return "closed";
                else
                    switch (this.source.readyState) {
                        case 0: return "connecting";
                        case 1: return "open";
                        case 2: return "closed";
                        default: return "unkown";
                    }
            };
            WebEventSource.prototype.on_open = function (body) {
                var _this = this;
                if (!this.onOpen) {
                    this.onOpen = new RT.Event_();
                    if (this.source)
                        this.source.addEventListener('open', function (e) {
                            if (_this.source && _this.onOpen.handlers)
                                _this.rt.queueLocalEvent(_this.onOpen);
                        }, false);
                }
                return this.onOpen.addHandler(body);
            };
            WebEventSource.prototype.on_error = function (body) {
                var _this = this;
                if (!this.onError) {
                    this.onError = new RT.Event_();
                    if (this.source)
                        this.source.addEventListener('error', function (e) {
                            if (_this.source && _this.onError.handlers)
                                _this.rt.queueLocalEvent(_this.onError);
                        }, false);
                }
                return this.onError.addHandler(body);
            };
            WebEventSource.prototype.close = function () {
                if (this.source) {
                    try {
                        this.source.close();
                    }
                    catch (e) {
                    }
                    this.source = undefined;
                }
            };
            WebEventSource.prototype.dispose = function () {
                this.close();
                _super.prototype.dispose.call(this);
            };
            return WebEventSource;
        })(RT.RTDisposableValue);
        RT.WebEventSource = WebEventSource;
        var Web;
        (function (Web) {
            function rt_start(rt) {
                clearReceivedMessageEvent(rt);
            }
            Web.rt_start = rt_start;
            function rt_stop(rt) {
                clearReceivedMessageEvent(rt);
            }
            Web.rt_stop = rt_stop;
            function toLink(jlink, kind) {
                var link = RT.Link.mk(jlink.url, kind);
                var idx = jlink.name.indexOf(' : ');
                if (idx > 0) {
                    link.set_title(jlink.name.slice(0, idx));
                    link.set_description(jlink.name.slice(idx + 3));
                }
                else {
                    link.set_name(jlink.name);
                }
                return link;
            }
            function bingSearch(kind, query, loc, linkKind, r) {
                BingServices.searchAsync(kind, query, loc).done(function (results) {
                    var links = RT.Collections.create_link_collection();
                    results.forEach(function (result) {
                        links.add(toLink(result, linkKind));
                    });
                    r.resumeVal(links);
                });
            }
            function search(query, r) {
                bingSearch("Web", query, undefined, 5 /* hyperlink */, r);
            }
            Web.search = search;
            function search_nearby(query, location, distance, r) {
                bingSearch("Web", query, location, 5 /* hyperlink */, r);
            }
            Web.search_nearby = search_nearby;
            function search_images(query, r) {
                bingSearch("Images", query, undefined, 2 /* image */, r);
            }
            Web.search_images = search_images;
            function search_images_nearby(query, location, distance, r) {
                bingSearch("Images", query, location, 2 /* image */, r);
            }
            Web.search_images_nearby = search_images_nearby;
            function search_phone_numbers(query) {
                return undefined;
            }
            Web.search_phone_numbers = search_phone_numbers;
            function search_phone_numbers_nearby(query, location, distance) {
                return undefined;
            }
            Web.search_phone_numbers_nearby = search_phone_numbers_nearby;
            function search_news(query, r) {
                bingSearch("News", query, undefined, 5 /* hyperlink */, r);
            }
            Web.search_news = search_news;
            function search_news_nearby(query, location, distance, r) {
                bingSearch("News", query, location, 5 /* hyperlink */, r);
            }
            Web.search_news_nearby = search_news_nearby;
            function is_connected() {
                return window.navigator.onLine;
            }
            Web.is_connected = is_connected;
            function connection_type(r) {
                var res = 'unknown';
                var connection = navigator.connection;
                if (connection) {
                    res = connection.type || 'unknown';
                }
                r.resumeVal(res);
            }
            Web.connection_type = connection_type;
            function connection_name(r) {
                r.resumeVal('');
            }
            Web.connection_name = connection_name;
            function open_connection_settings(page, r) {
                r.resume();
            }
            Web.open_connection_settings = open_connection_settings;
            function browse(url, r) {
                Web.browseAsync(url).done(function () { return r.resume(); });
            }
            Web.browse = browse;
            function redirect(url, r) {
                if (r.rt.devMode)
                    TDev.Util.userError(TDev.lf("web->redirect not available when running in the editor"));
                else {
                    TDev.Util.setTimeout(1500, function () { return TDev.Util.navigateInWindow(url); });
                }
            }
            Web.redirect = redirect;
            Web.browseAsync = function (url) {
                var win = window.open(url, "_blank");
                try {
                    win.focus();
                    return TDev.Promise.as();
                }
                catch (e) {
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        var d = new TDev.ModalDialog();
                        d.onDismiss = function () { return onSuccess(undefined); };
                        d.add(TDev.div("wall-dialog-header", TDev.lf("web browsing...")));
                        d.add(TDev.div("wall-dialog-body", TDev.lf("We tried to open the following web page: {0}", url)));
                        d.add(TDev.div("wall-dialog-body", TDev.lf("If the page did not open, tap the 'open' button below, otherwise tap 'done'.")));
                        d.add(TDev.div("wall-dialog-buttons", TDev.HTML.mkA("button wall-button", url, "_blank", "open"), TDev.HTML.mkButton(TDev.lf("done"), function () {
                            d.dismiss();
                        })));
                        d.show();
                    });
                }
            };
            function play_media(url) {
                window.open(url);
            }
            Web.play_media = play_media;
            function link_media(url) {
                return RT.Link.mk(url, 1 /* media */);
            }
            Web.link_media = link_media;
            function link_image(url) {
                return RT.Link.mk(url, 2 /* image */);
            }
            Web.link_image = link_image;
            function link_url(name, url) {
                var l = RT.Link.mk(url, 5 /* hyperlink */);
                l.set_name(name);
                return l;
            }
            Web.link_url = link_url;
            function link_deep_zoom(url) {
                return undefined;
            }
            Web.link_deep_zoom = link_deep_zoom;
            function proxy(url) {
                if (!TDev.Cloud.hasAccessToken())
                    return url;
                if (!url || /^http:\/\/localhost(:[0-9]+)?\//i.test(url))
                    return url;
                var m = url.match(/^http:\/\/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)(:[0-9]+)?\//i);
                if (m) {
                    var a = parseInt(m[1]);
                    if (a == 10)
                        return url;
                    var b = parseInt(m[2]);
                    if (a == 172 && b >= 16 && b <= 31)
                        return url;
                    if (a == 192 && b == 168)
                        return url;
                }
                return TDev.Cloud.getPrivateApiUrl("runtime/web/proxy?url=" + encodeURIComponent(url));
            }
            Web.proxy = proxy;
            function download(url, r) {
                r.progress('Downloading...');
                var request = create_request(url);
                request.sendAsync().done(function (response) { return r.resumeVal(response.content()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.download = download;
            function download_json(url, r) {
                r.progress('Downloading...');
                var request = create_request(url);
                request.set_accept('application/json');
                request.sendAsync().done(function (response) { return r.resumeVal(response.content_as_json()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.download_json = download_json;
            function download_xml(url, r) {
                var request = create_request(url);
                r.progress('Downloading...');
                request.set_accept('text/xml');
                request.sendAsync().done(function (response) { return r.resumeVal(response.content_as_xml()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.download_xml = download_xml;
            function download_sound(url, r) {
                r.progress("Downloading...");
                RT.Sound.fromUrl(url).done(function (snd) { return r.resumeVal(snd); });
            }
            Web.download_sound = download_sound;
            function download_song(url, name) {
                return RT.Song.mk(url, undefined, name);
            }
            Web.download_song = download_song;
            function upload(url, body, r) {
                var request = create_request(url);
                r.progress('Uploading...');
                request.set_method('post');
                request.set_content(body);
                request.sendAsync().done(function (response) { return r.resumeVal(response.content()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.upload = upload;
            function upload_sound(url, snd, r) {
                var request = create_request(url);
                r.progress('Uploading...');
                request.set_method('post');
                request.setContentAsSoundInternal(snd);
                request.sendAsync().done(function (response) { return r.resumeVal(response.content()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.upload_sound = upload_sound;
            function upload_picture(url, pic, r) {
                var request = create_request(url);
                r.progress('Uploading...');
                request.set_method('post');
                pic.initAsync().then(function () {
                    request.setContentAsPictureInternal(pic, 0.85);
                    return request.sendAsync();
                }).done(function (response) { return r.resumeVal(response.content()); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.upload_picture = upload_picture;
            function download_picture(url, r) {
                r.progress('Downloading...');
                var pic = undefined;
                RT.Picture.fromUrl(url).then(function (p) {
                    pic = p;
                    return p.initAsync();
                }).done(function () { return r.resumeVal(pic); }, function (e) { return r.resumeVal(undefined); });
            }
            Web.download_picture = download_picture;
            function html_decode(html) {
                return TDev.Util.htmlUnescape(html);
            }
            Web.html_decode = html_decode;
            function html_encode(text) {
                return TDev.Util.htmlEscape(text);
            }
            Web.html_encode = html_encode;
            function decode_uri(url) {
                return decodeURI(url);
            }
            Web.decode_uri = decode_uri;
            function encode_uri(text) {
                return encodeURI(text);
            }
            Web.encode_uri = encode_uri;
            function decode_uri_component(url) {
                return decodeURIComponent(url);
            }
            Web.decode_uri_component = decode_uri_component;
            function encode_uri_component(text) {
                return encodeURIComponent(text);
            }
            Web.encode_uri_component = encode_uri_component;
            function url_decode(url) {
                return decodeURIComponent(url);
            }
            Web.url_decode = url_decode;
            function url_encode(text) {
                return encodeURIComponent(text);
            }
            Web.url_encode = url_encode;
            function json(value) {
                return RT.JsonObject.mk(value, function (msg) {
                    RT.App.logEvent(RT.App.DEBUG, 'json', TDev.lf("error parsing json: {0}", msg), undefined);
                });
            }
            Web.json = json;
            function json_object() {
                return RT.JsonObject.wrap({});
            }
            Web.json_object = json_object;
            function json_array() {
                return RT.JsonObject.wrap([]);
            }
            Web.json_array = json_array;
            function xml(value) {
                return RT.XmlObject.mk(value);
            }
            Web.xml = xml;
            function rss(value) {
                return feed(value);
            }
            Web.rss = rss;
            function create_request(url) {
                return RT.WebRequest.mk(url, "text");
            }
            Web.create_request = create_request;
            function open_web_socket(url, r) {
                var ws = new WebSocket(url);
                ws.onopen = function () {
                    ws.onerror = null;
                    ws.onopen = null;
                    r.resumeVal(RT.WebSocket_.mk(ws, r.rt));
                };
                ws.onerror = function (err) {
                    RT.App.log("Error opening WebSocket to " + url + ": " + err.message);
                    r.resumeVal(undefined);
                };
            }
            Web.open_web_socket = open_web_socket;
            function base64_decode(text) {
                var decoded = TDev.Util.base64Decode(text);
                try {
                    return TDev.Util.fromUTF8(decoded);
                }
                catch (e) {
                    return decoded;
                }
            }
            Web.base64_decode = base64_decode;
            function base64_encode(text) {
                return TDev.Util.base64Encode(TDev.Util.toUTF8(text));
            }
            Web.base64_encode = base64_encode;
            function htmlToPictureUrl(value) {
                if (!value)
                    return value;
                var m = value.match(/<img.*?src=['"](.*?)['"].*?\/?>/i);
                if (m)
                    return m[1];
                return null;
            }
            function htmlToText(value) {
                if (!value)
                    return value;
                var r = value.replace(/<[^>]+>/ig, '');
                var decoded = Web.html_decode(r);
                var decodedescaped = decoded.replace(/<[^>]+>/ig, '');
                return decodedescaped;
            }
            function parseRss(rssx, msgs) {
                var channel = rssx.child('channel');
                if (!channel)
                    return;
                var imgRx = /^image\/(png|jpg|jpeg)$/i;
                var mediaRx = TDev.Browser.isGecko ? /^video\/webm|audio\/mp3$/i : /^video\/mp4|audio\/mp3$/i;
                var items = channel.children('item');
                for (var i = 0; i < items.count(); ++i) {
                    var item = items.at(i);
                    var msg = RT.Message.mk("");
                    msg.set_from(undefined);
                    msgs.add(msg);
                    var description = item.child('description');
                    if (description)
                        parseHtmlContent(msg, description.value());
                    var title = item.child('title');
                    if (title)
                        msg.set_title(htmlToText(title.value()));
                    var link = item.child('link');
                    if (link)
                        msg.set_link(link.value());
                    var pubDate = item.child('pubDate');
                    if (pubDate)
                        msg.set_time(RT.DateTime.parse(pubDate.value()));
                    var speaker = item.child('{http://www.microsoft.com/dtds/mavis/}speaker');
                    if (speaker)
                        msg.set_from(htmlToText(speaker.value()));
                    var author = item.child('{http://www.itunes.com/dtds/podcast-1.0.dtd}author');
                    if (author)
                        msg.set_from(htmlToText(author.value()));
                    var creator = item.child('creator');
                    if (creator)
                        msg.set_from(htmlToText(creator.value()));
                    var img = item.child('{http://www.itunes.com/dtds/podcast-1.0.dtd}image');
                    if (img && img.attr('href'))
                        msg.set_picture_link(img.attr('href'));
                    var enclosure = item.child('enclosure');
                    if (enclosure) {
                        var enclosureType = enclosure.attr('type') || "";
                        if (imgRx.test(enclosureType))
                            msg.set_picture_link(enclosure.attr('url'));
                        else if (mediaRx.test(enclosureType))
                            msg.set_media_link(enclosure.attr('url'));
                    }
                    var thumbnails = item.children('{http://search.yahoo.com/mrss/}thumbnail');
                    var tisize = -1;
                    for (var ti = 0; ti < thumbnails.count(); ++ti) {
                        var thumbnail = thumbnails.at(ti);
                        var cisize = (RT.String_.to_number(thumbnail.attr('width')) || 1) * (RT.String_.to_number(thumbnail.attr('height')) || 1);
                        if (thumbnail.attr('url') && cisize > tisize) {
                            msg.set_picture_link(thumbnail.attr('url'));
                            tisize = cisize;
                        }
                    }
                    var group = item.child('{http://search.yahoo.com/mrss/}group');
                    if (group) {
                        var contents = group.children('{http://search.yahoo.com/mrss/}content');
                        var mcsize = 0;
                        for (var ci = 0; ci < contents.count(); ++ci) {
                            var content = contents.at(ci);
                            var csize = RT.String_.to_number(content.attr('fileSize')) || 0;
                            var curl = content.attr('url');
                            var ctype = content.attr('type');
                            if (curl && mediaRx.test(ctype) && csize > mcsize) {
                                msg.set_media_link(curl);
                                mcsize = csize;
                            }
                        }
                    }
                    parseGeoRss(msg, item);
                }
            }
            function parseGeoRss(msg, item) {
                var point = item.child('{http://www.georss.org/georss}point');
                if (point) {
                    var txt = point.value();
                    var i = txt.indexOf(' ');
                    if (i > 0) {
                        var lat = parseFloat(txt.substr(0, i));
                        var long = parseFloat(txt.substr(i + 1));
                        if (!isNaN(lat) && !isNaN(long))
                            msg.set_location(RT.Location_.mkShort(lat, long));
                    }
                }
            }
            function parseProperties(msg, entry) {
                var properties = entry.child('{http://schemas.microsoft.com/ado/2007/08/dataservices/metadata}properties');
                if (properties) {
                    var props = properties.children("");
                    for (var j = 0; j < props.count(); ++j) {
                        var prop = props.at(j);
                        msg.values().set_at(prop.local_name(), prop.value());
                    }
                }
            }
            function parseHtmlContent(msg, value) {
                if (!value)
                    return;
                msg.set_message(htmlToText(value));
                var pic = htmlToPictureUrl(value);
                if (pic)
                    msg.set_picture_link(pic);
            }
            function parseAtom(feed, msgs) {
                var channelTitlex = feed.child('title');
                var channelTitle = channelTitlex ? channelTitlex.value() : "atom";
                var entries = feed.children('entry');
                if (entries) {
                    for (var i = 0; i < entries.count(); ++i) {
                        var entry = entries.at(i);
                        var msg = RT.Message.mk("");
                        msg.set_from(undefined);
                        msgs.add(msg);
                        var summary = entry.child('summary');
                        if (summary)
                            parseHtmlContent(msg, summary.value());
                        var title = entry.child('title');
                        if (title)
                            msg.set_title(htmlToText(title.value()));
                        var updated = entry.child('updated');
                        if (updated) {
                            var updatedd = RT.DateTime.parse(updated.value());
                            if (updatedd)
                                msg.set_time(updatedd);
                        }
                        var content = entry.child('content');
                        if (content) {
                            var contentType = content.attr('type') || "";
                            if (/^image\//i.test(contentType) && content.attr('src'))
                                msg.set_picture_link(content.attr('src'));
                            else if (/^application\/xml/i.test(contentType))
                                parseProperties(msg, content);
                            else if (/html/i.test(contentType))
                                parseHtmlContent(msg, content.value());
                        }
                        var author = entry.child('author');
                        if (author) {
                            var authorName = author.child('name');
                            if (authorName)
                                msg.set_from(authorName.value());
                        }
                        parseGeoRss(msg, entry);
                    }
                }
            }
            function feed(value) {
                var msgs = RT.Collections.create_message_collection();
                var xml = RT.XmlObject.mk(value);
                while (xml != null) {
                    if (xml.name() === 'rss') {
                        parseRss(xml, msgs);
                        break;
                    }
                    else if (xml.name() === 'feed') {
                        parseAtom(xml, msgs);
                        break;
                    }
                    else {
                        xml = xml.next_sibling();
                    }
                }
                return msgs;
            }
            Web.feed = feed;
            function create_json_builder() {
                return new RT.JsonBuilder();
            }
            Web.create_json_builder = create_json_builder;
            function csv(text, delimiter) {
                var file = new TDev.CsvParser().parse(text, delimiter);
                return RT.JsonObject.wrap(file);
            }
            Web.csv = csv;
            function picture(url) {
                return RT.Picture.fromUrlSync(url, true);
            }
            Web.picture = picture;
            function oauth_v2(oauth_url, r) {
                if (!oauth_url) {
                    r.resumeVal(RT.OAuthResponse.mkError("access_denied", "Empty oauth url.", null));
                    return;
                }
                if (/state=|redirect_uri=/i.test(oauth_url)) {
                    r.resumeVal(RT.OAuthResponse.mkError("access_denied", "The `redirect_uri` and `state` query arguments are not allowed.", null));
                    return;
                }
                if (!Web.is_connected()) {
                    r.resumeVal(RT.OAuthResponse.mkError("access_denied", "No internet connection.", null));
                    return;
                }
                var userid = r.rt.currentAuthorId;
                Web.oauth_v2_async(oauth_url, userid).done(function (v) {
                    r.resumeVal(v);
                });
            }
            Web.oauth_v2 = oauth_v2;
            function oauth_v2_async(oauth_url, userid) {
                var redirectURI = "https://www.touchdevelop.com/" + userid + "/oauth";
                var state = TDev.Util.guidGen();
                var stateArg = "state=" + state.replace('-', '');
                var hostM = /^([^\/]+:\/\/[^\/]+)/.exec(document.URL);
                var host = hostM ? hostM[1] : "";
                if (host && !/\.touchdevelop\.com$/i.test(host)) {
                    redirectURI = host + "/api/oauth";
                    userid = "web-app";
                }
                var actualRedirectURI = redirectURI;
                var subdomainRx = /&tdredirectdomainid=([a-z0-9]{1,64})/i;
                var msubdomain = oauth_url.match(subdomainRx);
                if (msubdomain) {
                    var appid = msubdomain[1];
                    actualRedirectURI = 'https://' + appid + '-' + userid + '.users.touchdevelop.com/oauth';
                    redirectURI = "https://www.touchdevelop.com/" + appid + '-' + userid + "/oauth";
                    RT.App.log('oauth appid redirect: ' + appid);
                    oauth_url = oauth_url.replace(subdomainRx, '');
                }
                var stateRx = /&tdstateinredirecturi=true/i;
                if (stateRx.test(oauth_url)) {
                    actualRedirectURI += "?" + stateArg;
                    RT.Time.log('oauth adding state to url');
                    oauth_url = oauth_url.replace(stateRx, '');
                }
                RT.App.log('oauth login uri: ' + oauth_url);
                RT.App.log('oauth redirect uri: ' + actualRedirectURI);
                var url = oauth_url + (/\?/.test(oauth_url) ? '&' : '?') + 'redirect_uri=' + encodeURIComponent(actualRedirectURI) + "&" + stateArg;
                if (!/response_type=(token|code)/i.test(url))
                    url += "&response_type=token";
                RT.App.log('oauth auth url: ' + url);
                return Web.oauth_v2_dance_async(url, actualRedirectURI, userid, stateArg);
            }
            Web.oauth_v2_async = oauth_v2_async;
            function oauth_v2_dance_async(url, redirect_uri, userid, stateArg) {
                var res = new TDev.PromiseInv();
                var response;
                var oauthWindow;
                var m = new TDev.ModalDialog();
                function handleMessage(event) {
                    var origin = document.URL.replace(/(.*:\/\/[^\/]+).*/, function (a, b) { return b; });
                    if (event.origin == origin && Array.isArray(event.data)) {
                        processRedirects(event.data);
                    }
                }
                function handleStorage(event) {
                    if (event.key == "oauth_redirect")
                        processRedirects(JSON.parse(event.newValue || "[]"));
                }
                function dismiss() {
                    window.removeEventListener("message", handleMessage, false);
                    window.removeEventListener("storage", handleStorage, false);
                    if (!response)
                        response = RT.OAuthResponse.mkError("access_denied", "The user cancelled the authentication.", null);
                    if (oauthWindow)
                        oauthWindow.close();
                    res.success(response);
                }
                function processRedirects(redirects) {
                    redirects.reverse();
                    var matches = redirects.filter(function (redirect) { return userid == redirect.user_id && redirect.redirect_url.indexOf(stateArg) > -1; });
                    if (matches.length > 0) {
                        RT.Time.log('oauth redirect_uri: ' + matches[0].redirect_url);
                        response = RT.OAuthResponse.parse(matches[0].redirect_url);
                        m.dismiss();
                        return;
                    }
                    if (!response && oauthWindow && oauthWindow.closed) {
                        response = RT.OAuthResponse.mkError("access_denied", "The authentication window was closed", null);
                        m.dismiss();
                        return;
                    }
                }
                function tracker() {
                    if (response)
                        return;
                    window.localStorage.setItem("last_oauth_check", Date.now() + "");
                    processRedirects(JSON.parse(window.localStorage.getItem("oauth_redirect") || "[]"));
                    if (!response)
                        TDev.Util.setTimeout(100, tracker);
                }
                var woptions = 'menubar=no,toolbar=no';
                oauthWindow = window.open(url, '_blank', woptions);
                m.add(TDev.div('wall-dialog-header', TDev.lf("authenticating...")));
                m.add(TDev.div('wall-dialog-body', TDev.lf("A separate window with the sign in dialog has opened, please sign in in that window.")));
                m.add(TDev.div('wall-dialog-body', TDev.lf("Can't see any window? Try tapping the button below to log in manually.")));
                m.add(TDev.div('wall-dialog-buttons', TDev.HTML.mkA("button wall-button", url, "_blank", "log in")));
                m.onDismiss = function () {
                    dismiss();
                };
                m.show();
                TDev.Util.setTimeout(100, tracker);
                return res;
            }
            Web.oauth_v2_dance_async = oauth_v2_dance_async;
            function create_form_builder() {
                return new RT.FormBuilder();
            }
            Web.create_form_builder = create_form_builder;
            function post_message_to_parent(target_origin, message, s) {
                if (!target_origin || target_origin == "*")
                    TDev.Util.userError(TDev.lf("target origin cannot be empty or *"));
                if (TDev.isWebWorker) {
                    var msg = message.value();
                    if (s && s.rt.pluginSlotId) {
                        msg = TDev.Util.jsonClone(msg);
                        msg.tdSlotId = s.rt.pluginSlotId;
                    }
                    self.postMessage(msg);
                    return;
                }
                var parent = window.parent;
                if (parent && parent != window && parent.postMessage) {
                    try {
                        parent.postMessage(message.value(), target_origin);
                    }
                    catch (e) {
                        RT.App.log("web: posting message to parent failed");
                    }
                }
            }
            Web.post_message_to_parent = post_message_to_parent;
            function receiveMessage(rt, event) {
                var s = rt.webState;
                if (window != window.parent && event.source === window.parent && s._onReceivedMessageEvent) {
                    RT.App.log("web: receiving message from parent");
                    var json = RT.JsonObject.wrap(event.data);
                    var waiters = s._messageWaiters.filter(function (m) { return m.origin === event.origin; });
                    if (waiters.length > 0) {
                        s._messageWaiters = s._messageWaiters.filter(function (m) { return m.origin !== event.origin; });
                        waiters.forEach(function (w) { return w.handler(json); });
                    }
                    if (s._onReceivedMessageEvent.handlers) {
                        rt.queueLocalEvent(s._onReceivedMessageEvent, [json], false, false, function (binding) {
                            var origin = binding.data;
                            return event.origin === origin;
                        });
                    }
                }
            }
            function receiveWorkerMessage(rt, data) {
                var s = rt.webState;
                if (s._onReceivedMessageEvent) {
                    var json = RT.JsonObject.wrap(data);
                    var waiters = s._messageWaiters;
                    if (waiters.length > 0) {
                        s._messageWaiters = [];
                        waiters.forEach(function (w) { return w.handler(json); });
                    }
                    if (s._onReceivedMessageEvent.handlers) {
                        rt.queueLocalEvent(s._onReceivedMessageEvent, [json], false, false);
                    }
                }
            }
            Web.receiveWorkerMessage = receiveWorkerMessage;
            function installReceiveMessage(rt, origin) {
                if (!origin)
                    TDev.Util.userError(TDev.lf("origin cannot be empty"));
                var s = rt.webState;
                if (!s._onReceivedMessageEvent) {
                    s._onReceivedMessageEvent = new RT.Event_();
                    s._messageWaiters = [];
                    if (!TDev.isWebWorker) {
                        s.receiveMessage = function (e) { return receiveMessage(rt, e); };
                        window.addEventListener("message", s.receiveMessage, false);
                    }
                }
            }
            function wait_for_message_from_parent(origin, r) {
                installReceiveMessage(r.rt, origin);
                r.rt.webState._messageWaiters.push({
                    origin: origin,
                    handler: function (j) { return r.resumeVal(j); }
                });
            }
            Web.wait_for_message_from_parent = wait_for_message_from_parent;
            function on_received_message_from_parent(origin, received, s) {
                installReceiveMessage(s.rt, origin);
                var st = s.rt.webState;
                var binding = st._onReceivedMessageEvent.addHandler(received);
                binding.data = origin;
                return binding;
            }
            Web.on_received_message_from_parent = on_received_message_from_parent;
            function clearReceivedMessageEvent(rt) {
                var s = rt.webState;
                if (s._onReceivedMessageEvent) {
                    if (s.receiveMessage)
                        window.removeEventListener("message", s.receiveMessage, false);
                    s._onReceivedMessageEvent = undefined;
                    s._messageWaiters = undefined;
                }
            }
            function create_event_source(url, s) {
                if (!url)
                    TDev.Util.userError(TDev.lf("url cannot be empty"), s.pc);
                if (!!window.EventSource) {
                    var source = new window.EventSource(url);
                    return new WebEventSource(s.rt, source);
                }
                else {
                    return undefined;
                }
            }
            Web.create_event_source = create_event_source;
            function oauth_token_from_url(redirect_url) {
                return RT.OAuthResponse.parse(redirect_url);
            }
            Web.oauth_token_from_url = oauth_token_from_url;
            function oauth_token_from_json(response) {
                return RT.OAuthResponse.parseJSON(response);
            }
            Web.oauth_token_from_json = oauth_token_from_json;
        })(Web = RT.Web || (RT.Web = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var WebRequest = (function (_super) {
            __extends(WebRequest, _super);
            function WebRequest() {
                _super.call(this);
                this._method = undefined;
                this._url = undefined;
                this._showNotifications = true;
                this._proxyResponseType = undefined;
                this._headers = new RT.StringMap();
                this._content = undefined;
                this._credentialsName = undefined;
                this._credentialsPassword = undefined;
                this._responseReceived = new RT.Event_();
            }
            WebRequest.mk = function (url, proxyResponseType) {
                var wr = new WebRequest();
                wr._url = url;
                wr._method = "GET";
                wr._proxyResponseType = proxyResponseType;
                return wr;
            };
            WebRequest.prototype.show_notifications = function (visible) {
                this._showNotifications = visible;
            };
            WebRequest.prototype.proxyResponseType = function () {
                return this._proxyResponseType;
            };
            WebRequest.prototype.method = function () {
                return this._method;
            };
            WebRequest.prototype.set_method = function (method) {
                this._method = method;
            };
            WebRequest.prototype.url = function () {
                return this._url;
            };
            WebRequest.prototype.set_url = function (url) {
                this._url = url;
            };
            WebRequest.prototype.header = function (name) {
                return this._headers.at(name);
            };
            WebRequest.prototype.set_header = function (name, value) {
                if (!value)
                    this._headers.remove(name);
                else
                    this._headers.set_at(name, value);
            };
            WebRequest.prototype.equals = function (other) {
                return this == other;
            };
            WebRequest.prototype.toString = function () {
                return this.method() + " " + this.url();
            };
            WebRequest.prototype.set_accept = function (type) {
                this._headers.set_at("Accept", type);
            };
            WebRequest.prototype.post_to_wall = function (s) {
                var rt = s.rt;
                if (this._content && this._content.length)
                    rt.postBoxedText("Content-Length: " + this._content.length, s.pc);
                var keys = this._headers.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var key = keys.at(i);
                    rt.postBoxedText(keys.at(i) + ": " + this._headers.at(key), s.pc);
                }
                if (this._credentialsName || this._credentialsPassword)
                    rt.postBoxedText("credentials: " + this._credentialsName, s.pc);
                rt.postBoxedText(this.toString(), s.pc);
            };
            WebRequest.prototype.serializeForProxy = function () {
                var _this = this;
                var credentials = undefined;
                if (this._credentialsName || this._credentialsPassword) {
                    credentials = {
                        name: this._credentialsName || "",
                        password: this._credentialsPassword || ""
                    };
                }
                var headers = this._headers.keys().a.map(function (k) {
                    return { name: k, value: _this._headers.at(k) };
                });
                var isString = typeof this._content == "string";
                return {
                    url: this._url,
                    method: this._method,
                    contentText: isString ? this._content : undefined,
                    content: this._content && !isString ? TDev.Util.base64EncodeBytes(this._content) : undefined,
                    responseType: this._proxyResponseType,
                    headers: headers,
                    credentials: credentials
                };
            };
            WebRequest.prototype.set_content_type = function (contentType) {
                this._headers.set_at("Content-Type", contentType);
            };
            WebRequest.prototype.debuggerChildren = function () {
                var r = {
                    'method': this._method,
                    'url': this._url,
                    'headers': this._headers,
                    'content': this._content,
                    'user name': this._credentialsName,
                    'password': this._credentialsPassword,
                    'notifications': this._showNotifications
                };
                return r;
            };
            WebRequest.prototype.mkProxyCrash = function (proxyResponse) {
                return {
                    statusCode: proxyResponse.status_code(),
                    response: RT.WebResponse.mkCrash(this)
                };
            };
            WebRequest.prototype.sendViaProxyAsync = function () {
                var _this = this;
                if (!TDev.Util.check(!!this._proxyResponseType))
                    return TDev.Promise.as({ statusCode: 0, response: RT.WebResponse.mkCrash(this) });
                var proxy = WebRequest.mk(TDev.Cloud.getPrivateApiUrl("runtime/web/request"), undefined);
                proxy.set_method("POST");
                proxy.set_content(JSON.stringify(this.serializeForProxy()));
                return proxy.sendAsync().then(function (proxyResponse) {
                    switch (proxyResponse.status_code()) {
                        case 502:
                            if (_this._showNotifications)
                                TDev.HTML.showProxyNotification("Proxy Error: Could not perform web request. " + TDev.Cloud.onlineInfo(), _this._url);
                            return _this.mkProxyCrash(proxyResponse);
                        case 429:
                        case 503:
                            if (_this._showNotifications)
                                TDev.HTML.showProxyNotification("Proxy Error: Could not perform web request. Did you transfer a lot of data recently? (code 503)", _this._url);
                            return _this.mkProxyCrash(proxyResponse);
                        case 403:
                            TDev.Cloud.accessTokenExpired();
                            if (_this._showNotifications)
                                TDev.HTML.showProxyNotification("Proxy Error: Could not perform web request; access denied; your access token might have expired.", _this._url);
                            return _this.mkProxyCrash(proxyResponse);
                        case 504:
                            if (_this._showNotifications)
                                TDev.HTML.showProxyNotification("Proxy Error: Could not perform web request. Response too big.  (code 504)", _this._url);
                            return _this.mkProxyCrash(proxyResponse);
                        case 400:
                            if (_this._showNotifications)
                                TDev.HTML.showProxyNotification("Proxy Error: Malformed inputs: " + TDev.Util.decodeErrorMessage(proxyResponse.header("ErrorMessage")), _this._url);
                            return _this.mkProxyCrash(proxyResponse);
                        default:
                            return {
                                statusCode: proxyResponse.status_code(),
                                response: RT.WebResponse.mkProxy(_this, JSON.parse(proxyResponse.content()))
                            };
                    }
                });
            };
            WebRequest.prototype.prepareAndSend = function (client) {
                if (this._credentialsName || this._credentialsPassword) {
                    client.open(this.method().toUpperCase(), this.url(), true, this._credentialsName || "", this._credentialsPassword || "");
                    client.withCredentials = true;
                }
                else
                    client.open(this.method().toUpperCase(), this.url(), true);
                var isForms = !TDev.isWebWorker && !!this._content && this._content instanceof FormData;
                var keys = this._headers.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var header = keys.at(i);
                    if (isForms && /^content-type$/i.test(header))
                        continue;
                    var headerValue = this._headers.at(header);
                    client.setRequestHeader(header, headerValue);
                    if (/^accept$/i.test(header) && /^image\/|^audio\//i.test(headerValue)) {
                        client.responseType = 'arraybuffer';
                    }
                }
                RT.Time.log(this.toString());
                client.send(this._content);
            };
            WebRequest.prototype.sendAsync = function () {
                return this.sendCoreAsync();
            };
            WebRequest.prototype.sendCoreAsync = function () {
                var _this = this;
                var request = this;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    if (TDev.Cloud.isOffline()) {
                        if (request._showNotifications)
                            TDev.HTML.showNotificationText('Web request failed, please connect to Internet.');
                        onSuccess(RT.WebResponse.mkCrash(request));
                        return;
                    }
                    var onCORS = function () {
                        if (request._proxyResponseType) {
                            TDev.Cloud.authenticateAsync(TDev.lf("web request proxying")).done(function (authenticated) {
                                if (!authenticated)
                                    onSuccess(RT.WebResponse.mkCrash(request));
                                else
                                    request.sendViaProxyAsync().then(function (r) {
                                        if (r.statusCode == 403) {
                                            TDev.Cloud.authenticateAsync(TDev.lf("web request proxying")).done(function (authenticated) {
                                                if (!authenticated)
                                                    onSuccess(RT.WebResponse.mkCrash(request));
                                                else
                                                    request.sendViaProxyAsync().then(function (r) { return onSuccess(r.response); }, function (e) { return onError(e); });
                                            });
                                        }
                                        else
                                            onSuccess(r.response);
                                    }, function (e) { return onError(e); });
                            });
                        }
                        else {
                            if (request._showNotifications)
                                TDev.HTML.showCorsNotification(request.url());
                            onSuccess(RT.WebResponse.mkCrash(request));
                        }
                    };
                    if (RT.Web.proxy(_this.url()) != _this.url() && /^https:\//i.test(document.URL) && /^http:\//.test(_this.url())) {
                        onCORS();
                        return;
                    }
                    try {
                        var client = new XMLHttpRequest();
                        client.onerror = function (e) {
                            RT.Time.log('error with ' + _this.toString());
                        };
                        client.onreadystatechange = function () {
                            if (client.readyState == (XMLHttpRequest.DONE || 4)) {
                                if (client.status == 0)
                                    onCORS();
                                else {
                                    var r = RT.WebResponse.mk(request, client);
                                    onSuccess(r);
                                }
                            }
                        };
                        if (TDev.HttpLog.enabled)
                            TDev.HttpLog.log(request.serializeForProxy());
                        request.prepareAndSend(client);
                    }
                    catch (e) {
                        onCORS();
                    }
                });
            };
            WebRequest.prototype.testCORSAsync = function () {
                var _this = this;
                if (RT.Web.proxy(this._url) == this._url)
                    return TDev.Promise.as(false);
                var request = this;
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        var client = new XMLHttpRequest();
                        client.onerror = function (e) { return RT.Time.log('error with ' + _this.toString()); };
                        client.onreadystatechange = function () {
                            if (client.readyState == (XMLHttpRequest.DONE || 4)) {
                                onSuccess(client.status == 0);
                            }
                        };
                        request.prepareAndSend(client);
                    }
                    catch (e) {
                        onSuccess(true);
                    }
                });
            };
            WebRequest.prototype.send_async = function (s) {
                var _this = this;
                this.sendAsync().then(function (response) {
                    if (_this._responseReceived && _this._responseReceived.handlers)
                        s.rt.queueLocalEvent(_this._responseReceived, [response]);
                }, function (e) {
                    var r = RT.WebResponse.mkCrash(_this);
                    if (_this._responseReceived && _this._responseReceived.handlers)
                        s.rt.queueLocalEvent(_this._responseReceived, [r]);
                });
            };
            WebRequest.prototype.on_response_received = function (handler) {
                return this._responseReceived.addHandler(handler);
            };
            WebRequest.prototype.send = function (r) {
                var _this = this;
                this.sendAsync().then(function (response) {
                    r.resumeVal(response);
                }, function (e) {
                    r.resumeVal(RT.WebResponse.mkCrash(_this));
                });
            };
            WebRequest.prototype.set_content = function (content) {
                this._content = content;
                this.set_content_type("text/plain; charset=utf-8");
            };
            WebRequest.prototype.set_content_as_json = function (json) {
                this.set_content(json.toString());
                this.set_content_type("application/json; charset=utf-8");
            };
            WebRequest.prototype.set_content_as_buffer = function (bytes) {
                this._content = bytes.buffer;
                this.set_content_type("application/octet-stream");
            };
            WebRequest.prototype.set_content_as_form = function (form) {
                this._content = form.data();
                if (/^get$/i.test(this.method()))
                    this.set_method("post");
            };
            WebRequest.prototype.set_content_as_picture = function (pic, quality, r) {
                var _this = this;
                pic.loadFirst(r, function () {
                    _this.setContentAsPictureInternal(pic, quality);
                });
            };
            WebRequest.prototype.setContentAsSoundInternal = function (snd) {
                var url = snd.getDataUri();
                if (url) {
                    var mimeType = RT.Sound.dataUriMimeType(url);
                    var bytes = TDev.Util.decodeDataURL(url, mimeType);
                    if (bytes) {
                        this._content = bytes;
                        this.set_content_type(mimeType);
                    }
                }
            };
            WebRequest.prototype.setContentAsPictureInternal = function (pic, quality, forceJpeg) {
                if (forceJpeg === void 0) { forceJpeg = false; }
                quality = RT.Math_.normalize(quality);
                var mimeType = (quality >= 1 && !forceJpeg) ? "image/png" : "image/jpeg";
                var jpegUrl = pic.getDataUri(quality, -1, forceJpeg);
                var bytes = TDev.Util.decodeDataURL(jpegUrl, mimeType);
                if (bytes) {
                    this._content = bytes;
                    this.set_content_type(mimeType);
                }
            };
            WebRequest.prototype.set_content_as_xml = function (xml) {
                this.set_content(xml.toString());
                this.set_content_type("text/xml; charset=utf-8");
            };
            WebRequest.prototype.set_credentials = function (name, password) {
                if (!this.url().match(/^https:\/\//i))
                    TDev.Util.userError(TDev.lf("Web Request->set credentials requires a secure HTTP url (https)"));
                this._credentialsName = name;
                this._credentialsPassword = password;
            };
            WebRequest.prototype.header_names = function () {
                return this._headers.keys();
            };
            WebRequest.prototype.set_compress = function (value) {
            };
            return WebRequest;
        })(RT.RTValue);
        RT.WebRequest = WebRequest;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var WebResponse = (function (_super) {
            __extends(WebResponse, _super);
            function WebResponse() {
                _super.call(this);
                this._request = undefined;
                this._content = undefined;
                this._statusCode = undefined;
                this._binaryContent = undefined;
                this._headers = new RT.StringMap();
            }
            WebResponse.mkCrash = function (request) {
                var r = new WebResponse();
                r._request = request;
                r._statusCode = 0;
                r._content = undefined;
                return r;
            };
            WebResponse.mkProxy = function (request, proxyResponse) {
                var r = new WebResponse();
                r._request = request;
                r._statusCode = proxyResponse.code;
                var headers = proxyResponse.headers;
                if (headers)
                    headers.forEach(function (h) { return r._headers.set_at(h.name.toLowerCase(), h.value); });
                if (proxyResponse.forceText || request.proxyResponseType() == "text")
                    r._content = proxyResponse.contentText;
                else
                    r._content = atob(proxyResponse.content);
                r._binaryContent = proxyResponse.binaryContent;
                return r;
            };
            WebResponse.mk = function (request, xrequest) {
                var r = new WebResponse();
                r._request = request;
                r._statusCode = xrequest.status;
                TDev.Util.forEachResponseHeader(xrequest, function (name, value) { return r._headers.set_at(name.toLowerCase(), value); });
                if (r._statusCode == 0) {
                    TDev.HTML.showCorsNotification(request.url());
                    r._content = undefined;
                }
                else {
                    r._content = xrequest.response;
                }
                return r;
            };
            WebResponse.prototype.request = function () {
                return this._request;
            };
            WebResponse.prototype.status_code = function () {
                return this._statusCode;
            };
            WebResponse.prototype.content = function () {
                return this._content;
            };
            WebResponse.prototype.contentAsArraybuffer = function () {
                if (this._binaryContent)
                    return this._binaryContent;
                if (!this._content)
                    return null;
                return new Uint8Array(this._content);
            };
            WebResponse.prototype.content_as_buffer = function () {
                var arr = this.contentAsArraybuffer();
                if (arr)
                    return RT.Buffer.fromTypedArray(arr);
                return undefined;
            };
            WebResponse.prototype.content_as_json = function () {
                if (this.content())
                    return RT.JsonObject.mk(this.content(), RT.Time.log);
                return undefined;
            };
            WebResponse.prototype.toString = function () {
                return this.status_code() + " --> " + this.request().toString();
            };
            WebResponse.prototype.content_as_picture = function (r) {
                var bytes = this.contentAsArraybuffer();
                if (!bytes)
                    r.resumeVal(undefined);
                else {
                    var img = document.createElement('img');
                    img.onload = function (e) {
                        var pic = RT.Picture.fromImage(img);
                        URL.revokeObjectURL(img.src);
                        r.resumeVal(pic);
                    };
                    img.onerror = function (e) {
                        r.resumeVal(undefined);
                    };
                    img.src = URL.createObjectURL(new Blob([bytes.buffer], { type: 'application/octect-stream' }));
                }
            };
            WebResponse.prototype.content_as_sound = function () {
                return undefined;
            };
            WebResponse.prototype.content_as_xml = function () {
                if (this.content())
                    return RT.XmlObject.mk(this._content);
                return undefined;
            };
            WebResponse.prototype.header = function (name) {
                return this._headers.at(name.toLowerCase());
            };
            WebResponse.prototype.header_names = function () {
                return this._headers.keys();
            };
            WebResponse.prototype.post_to_wall = function (s) {
                var rt = s.rt;
                rt.postBoxedText(this.toString(), s.pc);
                var keys = this._headers.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var key = keys.at(i);
                    rt.postBoxedText(keys.at(i) + ": " + this._headers.at(key), s.pc);
                }
                if (this.content())
                    rt.postBoxedText(this.content(), s.pc);
            };
            WebResponse.prototype.debuggerChildren = function () {
                var r = {
                    'status code': this._statusCode,
                    'headers': this._headers,
                    'content': this._content,
                    'request': this._request
                };
                return r;
            };
            return WebResponse;
        })(RT.RTValue);
        RT.WebResponse = WebResponse;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var XmlObject = (function (_super) {
            __extends(XmlObject, _super);
            function XmlObject() {
                _super.call(this);
                this._element = undefined;
                this._nodeList = undefined;
            }
            XmlObject.removeWhitespace = function (node) {
                for (var i = node.childNodes.length; i-- > 0;) {
                    var child = node.childNodes[i];
                    if (child.nodeType === 3 && child.data.match(/^\s*$/))
                        node.removeChild(child);
                    if (child.nodeType === 1)
                        XmlObject.removeWhitespace(child);
                }
            };
            XmlObject.parseToDOM = function (value) {
                try {
                    var x = new XmlObject();
                    var parser = new DOMParser();
                    var doc = parser.parseFromString(value, "application/xml");
                    XmlObject.removeWhitespace(doc);
                    return doc;
                }
                catch (e) {
                    RT.App.logEvent(RT.App.DEBUG, "xml", TDev.lf("error parsing xml: {0}", e.message), undefined);
                    return undefined;
                }
            };
            XmlObject.mk = function (value) {
                var doc = XmlObject.parseToDOM(value);
                if (doc) {
                    var x = new XmlObject();
                    x._element = doc.firstChild;
                    return x;
                }
                return undefined;
            };
            XmlObject.mkNode = function (element) {
                if (element) {
                    var x = new XmlObject();
                    x._element = element;
                    return x;
                }
                else {
                    return null;
                }
            };
            XmlObject.mkNodeList = function (nodeList) {
                if (nodeList) {
                    var x = new XmlObject();
                    x._nodeList = XmlObject.toElements(nodeList);
                    return x;
                }
                else {
                    return null;
                }
            };
            XmlObject.toElements = function (childNodes) {
                var nodes = [];
                for (var i = 0; i < childNodes.length; ++i) {
                    var child = childNodes[i];
                    nodes.push(XmlObject.mkNode(child));
                }
                return nodes;
            };
            XmlObject.prototype.initializeElements = function () {
                if (this._nodeList == null) {
                    var childNodes = this._element.childNodes;
                    var args = [];
                    for (var i = 0; i < childNodes.length; ++i) {
                        var child = childNodes[i];
                        args.push(child);
                    }
                    this._nodeList = XmlObject.toElements(args);
                }
            };
            XmlObject.prototype.count = function () {
                this.initializeElements();
                if (this._nodeList)
                    return this._nodeList.length;
                return 0;
            };
            XmlObject.prototype.is_element = function () {
                return this._element ? true : false;
            };
            XmlObject.prototype.name = function () {
                return this._element ? this.create_name(this._element.localName, this._element.namespaceURI) : "";
            };
            XmlObject.prototype.value = function () {
                if (this._element)
                    return this._element.textContent;
                else if (this._nodeList) {
                    var s = [];
                    this._nodeList.forEach(function (e) {
                        s.push(e.value());
                    });
                    return s.join("\n");
                }
                return "";
            };
            XmlObject.prototype.at = function (index) {
                this.initializeElements();
                if (this._nodeList)
                    return this._nodeList[Math.floor(index)];
                return undefined;
            };
            XmlObject.prototype.attr = function (name) {
                if (this._element)
                    return this._element.getAttribute(name);
                return undefined;
            };
            XmlObject.prototype.attr_names = function () {
                var c = new RT.Collection("string");
                if (this._element) {
                    var attrs = this._element.attributes;
                    if (attrs) {
                        for (var i = 0; i < attrs.length; ++i) {
                            var attr = attrs[i].name;
                            c.add(attr);
                        }
                    }
                }
                return c;
            };
            XmlObject.prototype.child = function (name) {
                if (this._element && name) {
                    var localName = name;
                    var namespaceURI = null;
                    var m = /^\{([^\}]*)\}(.*)$/i.exec(name);
                    if (m) {
                        namespaceURI = m[1];
                        localName = m[2];
                    }
                    var childNodes = this._element.childNodes;
                    for (var i = 0; i < childNodes.length; ++i) {
                        var child = childNodes[i];
                        if (child.nodeType == Node.ELEMENT_NODE && child.localName == localName && (!namespaceURI || child.namespaceURI == namespaceURI))
                            return XmlObject.mkNode(child);
                    }
                }
                return undefined;
            };
            XmlObject.prototype.children = function (name) {
                if (!name)
                    name = '';
                if (this._element) {
                    var localName = name;
                    var namespaceURI = null;
                    if (localName) {
                        var m = /^\{([^\}]*)\}(.*)$/i.exec(name);
                        if (m) {
                            namespaceURI = m[1];
                            localName = m[2];
                        }
                    }
                    var nodes = [];
                    var childNodes = this._element.childNodes;
                    for (var i = 0; i < childNodes.length; ++i) {
                        var child = childNodes[i];
                        if (child.nodeType == Node.ELEMENT_NODE && (name.length === 0 || (child.localName == localName && (!namespaceURI || child.namespaceURI == namespaceURI))))
                            nodes.push(child);
                    }
                    return XmlObject.mkNodeList(nodes);
                }
                return undefined;
            };
            XmlObject.prototype.post_to_wall = function (s) {
                s.rt.postBoxedText(this.to_string(), s.pc);
            };
            XmlObject.prototype.toString = function () {
                return this.to_string();
            };
            XmlObject.prototype.to_string = function () {
                if (this._element) {
                    return (new XMLSerializer()).serializeToString(this._element);
                }
                else if (this._nodeList) {
                    var result = [];
                    this._nodeList.forEach(function (e) {
                        result.push(e.to_string());
                    });
                    return result.join("\n");
                }
                else
                    return "";
            };
            XmlObject.prototype.local_name = function () {
                if (this._element)
                    return this._element.localName || "";
                return "";
            };
            XmlObject.prototype.namespace = function () {
                if (this._element)
                    return this._element.namespaceURI || "";
                return "";
            };
            XmlObject.prototype.next_sibling = function () {
                if (this._element)
                    return XmlObject.mkNode(this._element.nextSibling);
                else
                    return null;
            };
            XmlObject.prototype.previous_sibling = function () {
                if (this._element)
                    return XmlObject.mkNode(this._element.previousSibling);
                else
                    return null;
            };
            XmlObject.prototype.create_name = function (local_name, namespace_uri) {
                if (!namespace_uri)
                    return local_name;
                if (this._element && this._element.isDefaultNamespace(namespace_uri))
                    return local_name;
                return "{" + namespace_uri + "}" + local_name;
            };
            return XmlObject;
        })(RT.RTValue);
        RT.XmlObject = XmlObject;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        (function (ShakeType) {
            ShakeType[ShakeType["X"] = 0] = "X";
            ShakeType[ShakeType["Y"] = 1] = "Y";
            ShakeType[ShakeType["Z"] = 2] = "Z";
        })(RT.ShakeType || (RT.ShakeType = {}));
        var ShakeType = RT.ShakeType;
        var ShakeDetector;
        (function (ShakeDetector) {
            var shakeMagnitudeWithoutGravitationThreshold = 0.2;
            var stillCounterThreshold = 8;
            var stillMagnitudeWithoutGravitationThreshold = 0.02;
            var maximumStillVectorsNeededForAverage = 20;
            var minimumStillVectorsNeededForAverage = 5;
            var minimumShakeVectorsNeededForShake = 8;
            var weakMagnitudeWithoutGravitationThreshold = 0.2;
            var minimumRequiredMovesForShake = 2;
            var _lastStillVector = RT.Vector3.mk(0, -1, 0);
            var _isInShakeState = false;
            var _stillCounter = 0;
            var _shakeSignal = [];
            var _shakeHistogram = [0, 0, 0];
            var _stillSignal = [];
            function accelerationChanged(currentVector) {
                var shakeType = undefined;
                var isShakeMagnitude = Math.abs(_lastStillVector.length() - currentVector.length()) > shakeMagnitudeWithoutGravitationThreshold;
                if ((!_isInShakeState) && (isShakeMagnitude)) {
                    _isInShakeState = true;
                    clearShakeSignal();
                    processStillSignal();
                    addVectorToShakeSignal(currentVector);
                }
                else if ((!_isInShakeState) && (!isShakeMagnitude)) {
                    addVectorToStillSignal(currentVector);
                }
                else if ((_isInShakeState) && (isShakeMagnitude)) {
                    addVectorToShakeSignal(currentVector);
                    _stillCounter = 0;
                    shakeType = processShakeSignal();
                    if (shakeType)
                        clearShakeSignal();
                }
                else if ((_isInShakeState) && (!isShakeMagnitude)) {
                    addVectorToShakeSignal(currentVector);
                    _stillCounter++;
                    if (_stillCounter > stillCounterThreshold) {
                        _stillSignal.clear();
                        for (var i = 0; i < stillCounterThreshold; ++i) {
                            var currentSampleIndex = _shakeSignal.length - stillCounterThreshold + i;
                            addVectorToStillSignal(currentVector);
                        }
                        _shakeSignal.splice(_shakeSignal.length - stillCounterThreshold, stillCounterThreshold);
                        _isInShakeState = false;
                        _stillCounter = 0;
                        shakeType = processShakeSignal();
                        if (shakeType)
                            clearShakeSignal();
                    }
                }
                return !!shakeType;
            }
            ShakeDetector.accelerationChanged = accelerationChanged;
            function addVectorToStillSignal(currentVector) {
                _stillSignal.unshift(currentVector);
                if (_stillSignal.length > 2 * maximumStillVectorsNeededForAverage) {
                    _stillSignal.pop();
                }
            }
            function addVectorToShakeSignal(currentVector) {
                var currentVectorWithoutGravitation = currentVector.subtract(_lastStillVector);
                _shakeSignal.push(currentVectorWithoutGravitation);
                if (currentVectorWithoutGravitation.length() < weakMagnitudeWithoutGravitationThreshold) {
                    return;
                }
                var vectorShakeType = classifyVectorShakeType(currentVectorWithoutGravitation);
                _shakeHistogram[vectorShakeType]++;
            }
            function clearShakeSignal() {
                _shakeSignal.clear();
                for (var i = 0; i < _shakeHistogram.length; ++i)
                    _shakeHistogram[i] = 0;
            }
            function processStillSignal() {
                var sumVector = RT.Vector3.mk(0, 0, 0);
                var count = 0;
                for (var i = 0; i < _stillSignal.length; ++i) {
                    var currentStillVector = _stillSignal[i];
                    var isStillMagnitude = (Math.abs(_lastStillVector.length() - currentStillVector.length()) < stillMagnitudeWithoutGravitationThreshold);
                    if (isStillMagnitude) {
                        sumVector = sumVector.add(currentStillVector);
                        ++count;
                        if (count >= maximumStillVectorsNeededForAverage) {
                            break;
                        }
                    }
                }
                if (count >= minimumStillVectorsNeededForAverage) {
                    _lastStillVector = sumVector.scale(1 / count);
                }
            }
            function classifyVectorShakeType(v) {
                var absX = Math.abs(v.x());
                var absY = Math.abs(v.y());
                var absZ = Math.abs(v.z());
                if ((absX >= absY) && (absX >= absZ)) {
                    return 0 /* X */;
                }
                if ((absY >= absX) && (absY >= absZ)) {
                    return 1 /* Y */;
                }
                return 2 /* Z */;
            }
            function processShakeSignal() {
                var xCount = _shakeHistogram[0];
                var yCount = _shakeHistogram[1];
                var zCount = _shakeHistogram[2];
                var shakeType = undefined;
                if ((xCount >= yCount) && (xCount >= zCount) && (xCount >= minimumShakeVectorsNeededForShake)) {
                    shakeType = 0 /* X */;
                }
                else if ((yCount >= xCount) && (yCount >= zCount) && (yCount >= minimumShakeVectorsNeededForShake)) {
                    shakeType = 1 /* Y */;
                }
                else if ((zCount >= xCount) && (zCount >= yCount) && (zCount >= minimumShakeVectorsNeededForShake)) {
                    shakeType = 2 /* Z */;
                }
                if (shakeType) {
                    var countSignsChanges = countSignChanges(shakeType);
                    if (countSignsChanges < minimumRequiredMovesForShake) {
                        shakeType = undefined;
                    }
                }
                return shakeType;
            }
            function countSignChanges(shakeType) {
                var countSignsChanges = 0;
                var currentSign = 0;
                var prevSign = undefined;
                for (var i = 0; i < _shakeSignal.length; ++i) {
                    switch (shakeType) {
                        case 0 /* X */:
                            currentSign = RT.Math_.sign(_shakeSignal[i].x());
                            break;
                        case 1 /* Y */:
                            currentSign = RT.Math_.sign(_shakeSignal[i].y());
                            break;
                        case 2 /* Z */:
                            currentSign = RT.Math_.sign(_shakeSignal[i].z());
                            break;
                    }
                    if (currentSign == 0) {
                        continue;
                    }
                    if (!prevSign) {
                        prevSign = currentSign;
                    }
                    if (currentSign != prevSign) {
                        ++countSignsChanges;
                    }
                    prevSign = currentSign;
                }
                return countSignsChanges;
            }
        })(ShakeDetector = RT.ShakeDetector || (RT.ShakeDetector = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ShareManager;
        (function (ShareManager) {
            ShareManager.copyToClipboardAsync = function (text) {
                if (window.clipboardData && window.clipboardData.setData) {
                    window.clipboardData.setData('Text', text);
                    return TDev.Promise.as();
                }
                else {
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        TDev.ModalDialog.showText(text, 'copy to clipboard', 'Copy this text to your clipboard.', function () { return onSuccess(undefined); });
                    });
                }
            };
            ShareManager.sharePictureAsync = function (pic, network, message) {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var m = new TDev.ModalDialog();
                    m.onDismiss = function () { return onSuccess(undefined); };
                    m.add(TDev.div('wall-dialog-header', TDev.lf("share picture")));
                    m.add(TDev.div('wall-dialog-body', TDev.lf("Copy this picture or save it on your device.")));
                    var canvas = pic.getViewCanvasClone();
                    canvas.style.maxWidth = '100%';
                    canvas.style.maxHeight = '100%';
                    canvas.style.border = 'solid 2px gray';
                    m.addOk('done');
                    m.add(TDev.div('wall-dialog-body', canvas));
                    m.setScroll();
                    m.show();
                });
            };
            ShareManager.shareButtons = function (m, link, options) {
                if (TDev.Cloud.isRestricted())
                    return [];
                return [
                    TDev.HTML.mkButton('email', function () {
                        shareOnNetwork(link, "email", options);
                        if (!options.noDismiss)
                            m.dismiss();
                    }),
                    TDev.HTML.mkButton('facebook', function () {
                        shareOnNetwork(link, "facebook-share", options);
                        if (!options.noDismiss)
                            m.dismiss();
                    }),
                    TDev.HTML.mkButton('twitter', function () {
                        shareOnNetwork(link, "twitter", options);
                        if (!options.noDismiss)
                            m.dismiss();
                    })
                ];
            };
            function addShareButtons(m, link, options) {
                if (options === void 0) { options = {}; }
                var buttons = ShareManager.shareButtons(m, link, options);
                var cls = 'wall-dialog-buttons';
                if (options.moreButtons) {
                    cls += ' wall-dialog-buttons-many';
                    options.moreButtons.forEach(function (b) {
                        buttons.push(TDev.HTML.mkButton(b.text, function () {
                            if (!options.noDismiss)
                                m.dismiss();
                            b.handler();
                        }));
                    });
                }
                if (!options.justButtons) {
                    m.add(TDev.div('wall-dialog-header', options.header || TDev.lf("share")));
                    m.add(TDev.div('wall-dialog-body', TDev.tweetify(link.name())));
                    var txtAddress = TDev.HTML.mkTextInput('text', TDev.lf("url"));
                    txtAddress.value = link.address();
                    txtAddress.readOnly = true;
                    txtAddress.style.width = '90%';
                    TDev.Util.selectOnFocus(txtAddress);
                    m.add(TDev.div('wall-dialog-body', txtAddress));
                }
                var d = TDev.div(cls, buttons);
                m.add(d);
                return d;
            }
            ShareManager.addShareButtons = addShareButtons;
            function shareOnNetwork(link, network, options) {
                if (options === void 0) { options = {}; }
                var text = link.name() + " " + link.address();
                var encodedText = encodeURIComponent(text);
                var encodedName = encodeURIComponent(link.name());
                var encodedAddress = encodeURIComponent(link.address());
                var features = "menubar=no,status=no,titlebar=no,location=no,scrollbars=no,toolbar=no,width=500,height=550";
                function shareEmail() {
                    window.open('mailto:?subject=' + encodedName + '&body=' + encodedAddress, 'share', features);
                }
                function shareTweet() {
                    window.open('https://twitter.com/intent/tweet?text=' + encodedText, 'share', features);
                }
                function shareFacebookLike() {
                    window.open('http://www.facebook.com/plugins/like.php?send=false&layout=standard&width=200&show_faces=false&font&colorscheme=light&action=like&height=35&href=' + encodedAddress, 'share', features);
                }
                function shareFacebook() {
                    window.open('https://www.facebook.com/sharer/sharer.php?u=' + encodedAddress, 'share', features);
                }
                if (options.tickCallback)
                    options.tickCallback(network);
                switch (RT.String_.trim(network, ' \t').toLowerCase()) {
                    case "email":
                        shareEmail();
                        break;
                    case "facebook":
                        shareFacebookLike();
                        break;
                    case "facebook-share":
                        shareFacebook();
                        break;
                    case "twitter":
                    case "social":
                        shareTweet();
                        break;
                    default: return false;
                }
                return true;
            }
            ShareManager.shareOnNetwork = shareOnNetwork;
            ShareManager.shareSocialAsync = function (provider, text, uri) {
                var encodedText = encodeURIComponent(text || ' ' || uri);
                window.open('https://twitter.com/intent/tweet?text=' + encodedText);
                return TDev.Promise.as();
            };
            function shareLinkAsync(link, network) {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    if (shareOnNetwork(link, network))
                        onSuccess(null);
                    else {
                        var m = new TDev.ModalDialog();
                        addShareButtons(m, link);
                        m.onDismiss = function () {
                            onSuccess(null);
                        };
                        m.show();
                    }
                });
            }
            ShareManager.shareLinkAsync = shareLinkAsync;
            function shareTextAsync(text, network) {
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var encodedText = encodeURIComponent(text);
                    function shareSms() {
                        RT.Social.sendSmsAsync('', text).done();
                    }
                    function shareEmail() {
                        window.open('mailto:?body=' + encodedText);
                    }
                    function shareSocial() {
                        ShareManager.shareSocialAsync(network, text, null).done();
                    }
                    function shareSkype() {
                        window.open("skype:?chat&topic=" + encodedText);
                    }
                    switch (RT.String_.trim(network, ' \t').toLowerCase()) {
                        case "email":
                            shareEmail();
                            onSuccess(null);
                            break;
                        case "twitter":
                        case "social":
                            shareSocial();
                            onSuccess(null);
                            break;
                        case "sms":
                            shareSms();
                            onSuccess(null);
                            break;
                        case "skype":
                            shareSkype();
                            onSuccess(null);
                            break;
                        default:
                            var m = new TDev.ModalDialog();
                            m.add(TDev.div('wall-dialog-header', TDev.lf("share")));
                            m.add(TDev.div('wall-dialog-body', TDev.tweetify(text)));
                            m.add(TDev.div('wall-dialog-body', TDev.HTML.mkButton('email', function () {
                                shareEmail();
                                m.dismiss();
                            }), TDev.HTML.mkButton('sms', function () {
                                shareSms();
                                m.dismiss();
                            }), TDev.HTML.mkButton('Skype', function () {
                                shareSkype();
                                m.dismiss();
                            }), TDev.HTML.mkButton('social', function () {
                                shareSocial();
                                m.dismiss();
                            })));
                            m.onDismiss = function () {
                                onSuccess(null);
                            };
                            m.show();
                            break;
                    }
                });
            }
            ShareManager.shareTextAsync = shareTextAsync;
        })(ShareManager = RT.ShareManager || (RT.ShareManager = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var JsonParser = (function () {
            function JsonParser() {
            }
            JsonParser.parse = function (s, log) {
                var index = 0;
                var current = s[0];
                var onerror = function (m) {
                    throw { message: m };
                };
                var cnext = function (expected) {
                    if (expected != current) {
                        onerror(TDev.lf("got `{0}`, but expected `{1}`", current, expected));
                    }
                    current = s[++index];
                    return current;
                };
                var parseNumber = function () {
                    var value;
                    var sofar = "";
                    if (current === "-") {
                        sofar = "-";
                        cnext("-");
                    }
                    while (current >= "0" && current <= "9") {
                        sofar += current;
                        cnext(current);
                    }
                    if (current === ".") {
                        sofar += current;
                        while (cnext(current) && current >= "0" && current <= "9") {
                            sofar += current;
                        }
                    }
                    if (current === "E" || current === "e") {
                        sofar += current;
                        cnext(current);
                        if (current === "-" || current === "+") {
                            sofar += current;
                            cnext(current);
                        }
                        while (current >= "0" && current <= "9") {
                            sofar += current;
                            cnext(current);
                        }
                    }
                    value = +sofar;
                    if (isNaN(value)) {
                        onerror(TDev.lf("not a number"));
                    }
                    return value;
                };
                var getQuoteChar = function () {
                    if (current == '"')
                        return current;
                    if (current == "'")
                        return current;
                    onerror(TDev.lf("missing quote for string"));
                };
                var parseString = function () {
                    var quote = getQuoteChar();
                    var escapedChar = false;
                    var sofar = "";
                    while (cnext(current)) {
                        if (current === "\\") {
                            if (escapedChar) {
                                sofar += '\\';
                                escapedChar = false;
                            }
                            else {
                                escapedChar = true;
                            }
                            continue;
                        }
                        if (escapedChar) {
                            escapedChar = false;
                            if (current === '"' || current === "'" || current === "/") {
                                sofar += current;
                            }
                            else if (current === "b") {
                                sofar += "\b";
                            }
                            else if (current === "f") {
                                sofar += "\f";
                            }
                            else if (current === "n") {
                                sofar += "\n";
                            }
                            else if (current === "r") {
                                sofar += "\r";
                            }
                            else if (current === "t") {
                                sofar += "\t";
                            }
                            else if (current === "u") {
                                var value = 0;
                                for (var i = 0; i < 4; i++) {
                                    var digit = parseInt(cnext(current), 16);
                                    if (!isFinite(digit)) {
                                        break;
                                    }
                                    value = value * 16 + digit;
                                }
                                sofar += String.fromCharCode(value);
                            }
                            else {
                                onerror(TDev.lf("bad escaped char: {0}", current));
                            }
                        }
                        else {
                            if (current === quote) {
                                cnext(quote);
                                return sofar;
                            }
                            sofar += current;
                        }
                    }
                    onerror(TDev.lf("non-terminated string"));
                };
                var skipWhiteSpace = function () {
                    while (current && current <= " ") {
                        cnext(current);
                    }
                };
                var parsePrimitiveToken = function () {
                    var sofar = "";
                    while (current) {
                        if (current >= "0" && current <= "9" || current >= "a" && current <= "z" || current >= "A" && current <= "Z" || current === "." || current === "-" || current === "_" || current === "+") {
                            sofar += current;
                            cnext(current);
                        }
                        else {
                            break;
                        }
                    }
                    return sofar;
                };
                var parsePrimitive = function () {
                    switch (current) {
                        case 't':
                            cnext("t");
                            cnext("r");
                            cnext("u");
                            cnext("e");
                            return true;
                        case 'f':
                            cnext("f");
                            cnext("a");
                            cnext("l");
                            cnext("s");
                            cnext("e");
                            return false;
                        case 'n':
                            cnext("n");
                            cnext("u");
                            cnext("l");
                            cnext("l");
                            return null;
                    }
                    onerror("expected true, false, or null at \n" + "      " + s.slice(Math.max(0, index - 20), index) + "\n" + " ---->" + s.slice(index + 1, Math.min(s.length, index + 20)));
                };
                var parseArray = function () {
                    var result = [];
                    cnext('[');
                    skipWhiteSpace();
                    if (current === ']') {
                        cnext(']');
                        return result;
                    }
                    while (current) {
                        result.push(parseValue());
                        skipWhiteSpace();
                        if (current === ']') {
                            cnext(']');
                            return result;
                        }
                        cnext(",");
                        skipWhiteSpace();
                    }
                    onerror(TDev.lf("incomplete array"));
                    return result;
                };
                var parseValue = function () {
                    skipWhiteSpace();
                    switch (current) {
                        case '{': return parseObject();
                        case '[': return parseArray();
                        case '"':
                        case "'":
                            return parseString();
                        case '-':
                            return parseNumber();
                        default:
                            if (current >= '0' && current <= '9')
                                return parseNumber();
                            else
                                return parsePrimitive();
                    }
                };
                var parseObject = function () {
                    var result = {};
                    cnext("{");
                    skipWhiteSpace();
                    if (current === "}") {
                        cnext("}");
                        return result;
                    }
                    var key;
                    while (current) {
                        if (current === "'" || current === '"') {
                            key = parseString();
                        }
                        else {
                            key = parsePrimitiveToken();
                        }
                        if (key === null || key === undefined) {
                            onerror(TDev.lf("bad key"));
                        }
                        skipWhiteSpace();
                        cnext(":");
                        result[key] = parseValue();
                        skipWhiteSpace();
                        if (current === "}") {
                            cnext("}");
                            return result;
                        }
                        cnext(",");
                        skipWhiteSpace();
                    }
                    onerror(TDev.lf("incomplete object"));
                };
                try {
                    return RT.JsonObject.wrap(JSON.parse(s));
                }
                catch (e) {
                    try {
                        var value = parseValue();
                        skipWhiteSpace();
                        if (current) {
                            onerror(TDev.lf("illegal json value"));
                        }
                        var js = RT.JsonObject.wrap(value);
                        return js;
                    }
                    catch (e) {
                        if (log)
                            log(TDev.lf("error parsing json {0} {1}", s.length > 100 ? s.slice(0, 100) + "..." : s, e.message));
                        return undefined;
                    }
                }
            };
            return JsonParser;
        })();
        RT.JsonParser = JsonParser;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var UserMediaManager;
        (function (UserMediaManager) {
            var _initialized = false;
            function init() {
                if (!_initialized) {
                    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
                    window.URL = window.URL || window.webkitURL;
                    _initialized = true;
                }
            }
            function isSupported() {
                init();
                return !!(navigator.getUserMedia);
            }
            UserMediaManager.isSupported = isSupported;
            function getMicrophoneStreamAsync() {
                if (!isSupported())
                    return TDev.Promise.as(undefined);
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        navigator.getUserMedia({ audio: true }, function (localMediaStream) {
                            onSuccess(localMediaStream);
                        }, function (e) {
                            RT.Time.log('microphone access failed, ' + e.message);
                            onSuccess(undefined);
                        });
                    }
                    catch (e) {
                        RT.Time.log('microphone access failed, ' + e.message);
                        onError(undefined);
                    }
                });
            }
            UserMediaManager.getMicrophoneStreamAsync = getMicrophoneStreamAsync;
            function getCameraUrlAsync(front, sourceId) {
                if (front === void 0) { front = false; }
                if (sourceId === void 0) { sourceId = undefined; }
                if (!isSupported())
                    return TDev.Promise.as(undefined);
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    try {
                        var constraints = {
                            video: {
                                optional: []
                            }
                        };
                        constraints.video.optional.push({ facingMode: front ? "user" : "environment" });
                        if (sourceId)
                            constraints.video.optional.push({ sourceId: sourceId });
                        navigator.getUserMedia(constraints, function (localMediaStream) {
                            var url = window.URL.createObjectURL(localMediaStream);
                            onSuccess(url);
                        }, function (e) {
                            RT.Time.log('camera access failed, ' + e.message);
                            onSuccess(undefined);
                        });
                    }
                    catch (e) {
                        RT.Time.log('camera access failed, ' + e.message);
                        onError(undefined);
                    }
                });
            }
            UserMediaManager.getCameraUrlAsync = getCameraUrlAsync;
            function previewVideo(v) {
                var canvas = TDev.createElement('canvas');
                canvas.width = v.clientWidth;
                canvas.height = v.clientHeight;
                var ctx = canvas.getContext('2d');
                ctx.drawImage(v, 0, 0);
                var picurl = canvas.toDataURL('image/jpeg');
                return picurl;
            }
            UserMediaManager.previewVideo = previewVideo;
        })(UserMediaManager = RT.UserMediaManager || (RT.UserMediaManager = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Charts;
        (function (Charts) {
            var Point = (function () {
                function Point(x, y) {
                    this.x = x;
                    this.y = y;
                }
                return Point;
            })();
            Charts.Point = Point;
            var CanvasChart = (function () {
                function CanvasChart() {
                    this.lineColor = "#f00";
                    this.gridColor = "#ccc";
                    this.backgroundColor = undefined;
                    this.axesColor = "#fff";
                    this.gridLineWidth = 1;
                    this.graphLineWidth = 2;
                    this.axesFontSize = 6;
                    this.gridRows = 11;
                    this.gridCols = 11;
                    this.area = true;
                    this.axesPaddingX = 20;
                    this.axesPaddingY = 30;
                }
                CanvasChart.prototype.drawChart = function (canvas, points) {
                    this.initialize(canvas, points);
                    if (this.points.length < 2)
                        return;
                    this.points.sort(function (left, right) {
                        if (left.x > right.x) {
                            return 1;
                        }
                        if (left.x < right.x) {
                            return -1;
                        }
                        return 0;
                    });
                    this.calculateScale();
                    this.drawAxes();
                    this.drawChartGrid();
                    this.drawGraphPoints();
                };
                CanvasChart.prototype.initialize = function (canvas, points) {
                    this.canvas = canvas;
                    this.context = this.canvas.getContext("2d");
                    this.points = points;
                    this.chartWidth = canvas.width - this.axesPaddingY;
                    this.chartHeight = canvas.height - this.axesPaddingX;
                    this.context.save();
                    this.context.clearRect(0, 0, canvas.width, canvas.height);
                };
                CanvasChart.prototype.drawChartGrid = function () {
                    if (this.backgroundColor) {
                        this.context.save();
                        this.context.fillStyle = this.backgroundColor;
                        this.context.fillRect(0, 0, this.chartWidth, this.chartHeight);
                        this.context.restore();
                    }
                    this.context.save();
                    this.context.strokeStyle = this.gridColor;
                    this.context.lineWidth = this.gridLineWidth;
                    this.context.strokeRect(0, 0, this.chartWidth, this.chartHeight);
                    var tipLength = 5;
                    for (var i = 0; i < this.gridCols; i++) {
                        this.context.beginPath();
                        this.context.moveTo(i * this.gridWidth, this.chartHeight);
                        this.context.lineTo(i * this.gridWidth, this.chartHeight - tipLength);
                        this.context.stroke();
                        this.context.beginPath();
                        this.context.moveTo(i * this.gridWidth, 0);
                        this.context.lineTo(i * this.gridWidth, tipLength);
                        this.context.stroke();
                    }
                    for (var i = 0; i < this.gridRows; i++) {
                        this.context.beginPath();
                        this.context.moveTo(0, i * this.gridHeight);
                        this.context.lineTo(tipLength, i * this.gridHeight);
                        this.context.stroke();
                        this.context.beginPath();
                        this.context.moveTo(this.chartWidth, i * this.gridHeight);
                        this.context.lineTo(this.chartWidth - tipLength, i * this.gridHeight);
                        this.context.stroke();
                    }
                    this.context.restore();
                };
                CanvasChart.prototype.drawAxes = function () {
                    this.context.save();
                    var xRange = this.scaleXMax - this.scaleXMin;
                    var yRange = this.scaleYMax - this.scaleYMin;
                    var xUnit = xRange / this.gridCols;
                    var yUnit = yRange / this.gridRows;
                    this.context.fillStyle = this.axesColor;
                    this.context.font = this.axesFontSize + "pt Arial";
                    var text = '';
                    for (var i = 0; i <= this.gridRows; i++) {
                        text = RT.Math_.round_with_precision(this.scaleYMax - (i * yUnit), 2).toString();
                        var y = i * this.gridHeight + this.axesFontSize / 2;
                        if (i === this.gridRows)
                            y -= this.axesFontSize / 2;
                        else if (i === 0)
                            y += this.axesFontSize / 2;
                        this.context.fillText(text, this.chartWidth + 5, y);
                    }
                    for (i = 0; i <= this.gridCols; i++) {
                        text = RT.Math_.round_with_precision(this.scaleXMin + (i * xUnit), 2).toString();
                        this.context.fillText(text, i * this.gridWidth, this.chartHeight + (this.axesPaddingX - this.axesFontSize));
                    }
                    this.context.restore();
                };
                CanvasChart.prototype.calculateScale = function () {
                    this.scaleXMin = this.points[0].x;
                    this.scaleXMax = this.points[0].x;
                    this.scaleYMax = this.points[0].y;
                    this.scaleYMin = this.points[0].y;
                    for (var j = 0, len2 = this.points.length; j < len2; j++) {
                        if (this.scaleXMax < this.points[j].x) {
                            this.scaleXMax = this.points[j].x;
                        }
                        if (this.scaleYMax < this.points[j].y) {
                            this.scaleYMax = this.points[j].y;
                        }
                        if (this.scaleXMin > this.points[j].x) {
                            this.scaleXMin = this.points[j].x;
                        }
                        if (this.scaleYMin > this.points[j].y) {
                            this.scaleYMin = this.points[j].y;
                        }
                    }
                    var rx = CanvasChart.generateSteps(this.scaleXMin, this.scaleXMax, this.gridCols);
                    this.scaleXMin = rx[0];
                    this.scaleXMax = rx[1];
                    this.gridCols = rx[2];
                    var ry = CanvasChart.generateSteps(this.scaleYMin, this.scaleYMax, this.gridRows);
                    this.scaleYMin = ry[0];
                    this.scaleYMax = ry[1];
                    this.gridRows = ry[2];
                    if (this.scaleXMin === this.scaleXMax) {
                        this.scaleXMin = 0.5;
                        this.scaleXMax = 0.5;
                    }
                    if (this.scaleYMin === this.scaleYMax) {
                        this.scaleYMin = 0.5;
                        this.scaleYMax = 0.5;
                    }
                    this.gridWidth = this.chartWidth / this.gridCols;
                    this.gridHeight = this.chartHeight / this.gridRows;
                };
                CanvasChart.generateSteps = function (start, end, numberOfTicks) {
                    var bases = [1, 5, 2, 3];
                    var currentBase;
                    var n;
                    var intervalSize, upperBound, lowerBound;
                    var nIntervals, nMaxIntervals;
                    var the_intervalsize = 0.1;
                    var exponentYmax = Math.floor(Math.max(RT.Math_.log10(Math.abs(start)), RT.Math_.log10(Math.abs(end))));
                    var mantissaYmax = end / Math.pow(10.0, exponentYmax);
                    var significative_numbers = Math.min(3, Math.abs(exponentYmax) + 1);
                    var expo = Math.pow(10.0, significative_numbers);
                    var start_norm = Math.abs(start) * expo;
                    var end_norm = Math.abs(end) * expo;
                    var mant_norm = Math.abs(mantissaYmax) * expo;
                    var ip_start, ip_end;
                    var start = ip_start = Math.floor(start_norm * RT.Math_.sign(start));
                    var end = ip_end = Math.ceil(end_norm * RT.Math_.sign(end));
                    mantissaYmax = Math.ceil(mant_norm);
                    nMaxIntervals = 0;
                    for (var k = 0; k < bases.length; ++k) {
                        currentBase = bases[k];
                        n = 4;
                        do {
                            --n;
                            intervalSize = currentBase * Math.pow(10.0, exponentYmax - n);
                            upperBound = Math.ceil(mantissaYmax * Math.pow(10.0, n) / currentBase) * intervalSize;
                            nIntervals = Math.ceil((upperBound - start) / intervalSize);
                            lowerBound = upperBound - nIntervals * intervalSize;
                        } while (nIntervals > numberOfTicks);
                        if (nIntervals > nMaxIntervals) {
                            nMaxIntervals = nIntervals;
                            ip_start = ip_start = lowerBound;
                            ip_end = upperBound;
                            the_intervalsize = intervalSize;
                        }
                    }
                    if (start < 0)
                        start = Math.floor(ip_start) / expo;
                    else
                        start = Math.ceil(ip_start) / expo;
                    if (end < 0)
                        end = Math.floor(ip_end) / expo;
                    else
                        end = Math.ceil(ip_end) / expo;
                    return [start, end, nMaxIntervals];
                };
                CanvasChart.prototype.drawGraphPoints = function () {
                    var _this = this;
                    this.context.save();
                    var xRange = this.scaleXMax - this.scaleXMin;
                    var yRange = this.scaleYMax - this.scaleYMin;
                    var xFactor = this.chartWidth / xRange;
                    var yFactor = this.chartHeight / yRange;
                    var draw = function (close) {
                        var nextX = (_this.points[0].x - _this.scaleXMin) * xFactor;
                        var nextY = (_this.points[0].y - _this.scaleYMin) * yFactor;
                        var startX = nextX;
                        var startY = nextY;
                        _this.context.moveTo(nextX, _this.chartHeight - nextY);
                        for (var i = 1, len = _this.points.length; i < len; i++) {
                            nextX = (_this.points[i].x - _this.scaleXMin) * xFactor, nextY = (_this.points[i].y - _this.scaleYMin) * yFactor;
                            _this.context.lineTo(nextX, (_this.chartHeight - nextY));
                        }
                        if (close) {
                            _this.context.lineTo(nextX, _this.chartHeight);
                            _this.context.lineTo(startX, _this.chartHeight);
                            _this.context.closePath();
                        }
                    };
                    this.context.miterLimit = this.graphLineWidth / 4;
                    this.context.strokeStyle = this.lineColor;
                    this.context.lineWidth = this.graphLineWidth;
                    if (this.area) {
                        this.context.fillStyle = this.lineColor;
                        this.context.globalAlpha = 0.3;
                        this.context.beginPath();
                        draw(true);
                        this.context.fill();
                        this.context.globalAlpha = 1;
                    }
                    this.context.beginPath();
                    draw(false);
                    this.context.stroke();
                    this.context.restore();
                };
                return CanvasChart;
            })();
            Charts.CanvasChart = CanvasChart;
        })(Charts = RT.Charts || (RT.Charts = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ApiManager;
        (function (ApiManager) {
            ApiManager.bingMapsKey;
            ApiManager.bingSearchKey;
            ApiManager.microsoftTranslatorKey;
            ApiManager.microsoftTranslatorClientId;
            ApiManager.microsoftTranslatorClientSecret;
            ApiManager.pubCenterApplicationId;
            ApiManager.pubCenterAdUnitId;
            ApiManager.keys = {};
            function addKey(url, value) {
                ApiManager.keys[url] = value;
            }
            ApiManager.addKey = addKey;
            ApiManager.getKeyAsync = function (url) {
                var v = ApiManager.keys[url];
                if (v)
                    return TDev.Promise.as(v);
                return TDev.Cloud.getPrivateApiAsync("me/keys?uri=" + encodeURIComponent(url)).then(function (k) {
                    if (k.value === null)
                        return undefined;
                    return k.value;
                }, function (e) { return null; });
            };
        })(ApiManager = RT.ApiManager || (RT.ApiManager = {}));
        var AzureMarketplace;
        (function (AzureMarketplace) {
            var tokens = {};
            function requestAccessTokenAsync(clientId, clientSecret, scope, grantType) {
                var form = 'grant_type=' + encodeURIComponent(grantType) + '&client_id=' + encodeURIComponent(clientId) + '&client_secret=' + encodeURIComponent(clientSecret) + '&scope=' + encodeURIComponent(scope);
                var token = tokens[form];
                if (token && token.expires < Date.now()) {
                    return TDev.Promise.as(token.accessToken);
                }
                var url = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13';
                var request = RT.Web.create_request(url);
                request.set_content(form);
                request.set_content_type('application/x-www-form-urlencoded');
                request.set_method('POST');
                return request.sendAsync().then(function (response) {
                    var json = response.content_as_json();
                    if (json) {
                        var expires = Date.now() + RT.String_.to_number(json.string('expires_in')) - 10;
                        var accessToken = json.string('access_token');
                        tokens[form] = { accessToken: accessToken, expires: expires };
                        return accessToken;
                    }
                    return null;
                });
            }
            AzureMarketplace.requestAccessTokenAsync = requestAccessTokenAsync;
        })(AzureMarketplace = RT.AzureMarketplace || (RT.AzureMarketplace = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Matrix = (function (_super) {
            __extends(Matrix, _super);
            function Matrix() {
                _super.apply(this, arguments);
                this.data = [];
                this.rowCount = 0;
                this.columnCount = 0;
            }
            Matrix.mk = function (rowCount, columnCount) {
                if (rowCount < 0 || isNaN(rowCount))
                    return null;
                if (columnCount < 0 || isNaN(columnCount))
                    return null;
                var irow = Math.floor(rowCount);
                if (irow < 0)
                    return null;
                var icolumn = Math.floor(columnCount);
                if (icolumn < 0)
                    return null;
                if (irow * icolumn < 0)
                    return null;
                var m = new Matrix();
                m.rowCount = irow;
                m.columnCount = icolumn;
                m.data = new Array(irow * icolumn);
                m.clear(0);
                return m;
            };
            Matrix.prototype.index = function (i, j) {
                return this.columnCount * Math.floor(i) + Math.floor(j);
            };
            Matrix.prototype.toString = function () {
                var r = ["["];
                for (var i = 0; i < this.rowCount; i++) {
                    if (i > 0)
                        r.push("\n");
                    for (var j = 0; j < this.columnCount; j++) {
                        if (j > 0)
                            r.push(", ");
                        r.push(this.data[this.index(i, j)].toString());
                    }
                }
                r.push("]");
                return r.join("");
            };
            Matrix.prototype.get_enumerator = function () {
                return this.data.slice(0);
            };
            Matrix.prototype.count = function () {
                return this.rowCount * this.columnCount;
            };
            Matrix.prototype.row_count = function () {
                return this.rowCount;
            };
            Matrix.prototype.column_count = function () {
                return this.columnCount;
            };
            Matrix.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            Matrix.prototype.getViewCore = function (s, b) {
                var d = TDev.div("item");
                for (var i = 0; i < this.rowCount; i++) {
                    var r = i == 0 ? "[" : "";
                    for (var j = 0; j < this.columnCount; j++) {
                        if (j > 0)
                            r += ", ";
                        r += this.data[this.index(i, j)];
                    }
                    if (i == this.rowCount - 1)
                        r += "]";
                    d.appendChild(TDev.div(null, r));
                }
                return d;
            };
            Matrix.prototype.copy_from = function (row, column, other) {
                row = Math.floor(row);
                column = Math.floor(column);
                for (var i = 0; i < other.rowCount; ++i) {
                    for (var j = 0; j < other.columnCount; ++j) {
                        this.data[this.index(row + i, column + j)] = other.data[other.index(i, j)];
                    }
                }
            };
            Matrix.prototype.at = function (index) {
                return this.data[Math.floor(index)];
            };
            Matrix.prototype.set_at = function (index, value) {
                var _index = Math.floor(index);
                if (0 <= _index && index < this.data.length)
                    this.data[_index] = value;
            };
            Matrix.prototype.item = function (row, column) {
                return this.at(this.index(row, column));
            };
            Matrix.prototype.set_item = function (row, column, value) {
                this.set_at(this.index(row, column), value);
            };
            Matrix.prototype.clone = function () {
                var m = new Matrix();
                m.rowCount = this.rowCount;
                m.columnCount = this.columnCount;
                m.data = this.data.slice(0);
                return m;
            };
            Matrix.prototype.min = function () {
                if (this.data.length == 0)
                    return undefined;
                var r = this.data[0];
                for (var i = 1; i < this.data.length; ++i)
                    r = this.data[i] < r ? this.data[i] : r;
                return r;
            };
            Matrix.prototype.max = function () {
                if (this.data.length == 0)
                    return undefined;
                var r = this.data[0];
                for (var i = 1; i < this.data.length; ++i)
                    r = this.data[i] > r ? this.data[i] : r;
                return r;
            };
            Matrix.prototype.scale = function (factor) {
                var m = Matrix.mk(this.rowCount, this.columnCount);
                for (var i = 0; i < this.data.length; ++i)
                    m.data[i] = this.data[i] * factor;
                return m;
            };
            Matrix.prototype.negate = function () {
                var m = Matrix.mk(this.rowCount, this.columnCount);
                for (var i = 0; i < this.data.length; ++i)
                    m.data[i] = -this.data[i];
                return m;
            };
            Matrix.prototype.transpose = function () {
                var m = Matrix.mk(this.columnCount, this.rowCount);
                for (var i = 0; i < this.rowCount; ++i)
                    for (var j = 0; j < this.columnCount; ++j)
                        m.data[m.index(j, i)] = this.data[this.index(i, j)];
                return m;
            };
            Matrix.prototype.add = function (b) {
                if (this.rowCount != b.rowCount || this.columnCount != b.columnCount) {
                    RT.Time.log("matrix add error: incompatible matrix sizes");
                    return undefined;
                }
                var m = Matrix.mk(this.rowCount, this.columnCount);
                for (var i = 0; i < this.data.length; ++i)
                    m.data[i] = this.data[i] + b.data[i];
                return m;
            };
            Matrix.prototype.subtract = function (b) {
                if (this.rowCount != b.rowCount || this.columnCount != b.columnCount) {
                    RT.Time.log("matrix subtract error: incompatible matrix sizes");
                    return undefined;
                }
                var m = Matrix.mk(this.rowCount, this.columnCount);
                for (var i = 0; i < this.data.length; ++i)
                    m.data[i] = this.data[i] - b.data[i];
                return m;
            };
            Matrix.prototype.multiply = function (b) {
                if (this.columnCount != b.rowCount) {
                    RT.Time.log("matrix multiply error: incompatible matrix sizes");
                    return undefined;
                }
                var r = Matrix.mk(this.rowCount, b.columnCount);
                var m = this.rowCount;
                var n = this.columnCount;
                var p = b.columnCount;
                for (var i = 0; i < m; i++)
                    for (var j = 0; j < n; j++)
                        for (var k = 0; k < p; k++)
                            r.data[r.index(i, k)] += this.data[this.index(i, j)] * b.data[b.index(j, k)];
                return r;
            };
            Matrix.prototype.to_string = function () {
                return this.toString();
            };
            Matrix.prototype.random = function () {
                return this.data.length == 0 ? undefined : this.at(RT.Math_.random(this.data.length));
            };
            Matrix.prototype.clear = function (value) {
                for (var i = 0; i < this.data.length; ++i)
                    this.data[i] = value;
            };
            Matrix.prototype.debuggerDisplay = function (clickHandler) {
                var container = TDev.div(null).withClick(clickHandler);
                var tableVar;
                var tableDataCell;
                var tableRow;
                tableVar = document.createElement("table").withClick(clickHandler);
                for (var i = 0; i < this.rowCount; ++i) {
                    tableRow = TDev.createElement("tr");
                    for (var j = 0; j < this.columnCount; ++j) {
                        tableDataCell = document.createElement("td").withClick(clickHandler);
                        tableDataCell.innerText = this.data[this.index(i, j)].toString();
                        tableDataCell.style.padding = "0.5em";
                        tableRow.appendChild(tableDataCell);
                    }
                    tableVar.appendChild(tableRow);
                }
                container.appendChild(tableVar);
                return container;
            };
            return Matrix;
        })(RT.RTValue);
        RT.Matrix = Matrix;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ArtCache;
        (function (ArtCache) {
            ArtCache.enabled = true;
            ArtCache.runningTests = false;
            function log(s) {
                TDev.Util.log("art cache: " + s);
            }
            var getArtCacheTableAsync = function () { return TDev.Storage.getTableAsync("ArtCache"); };
            ArtCache.getMaxItems = function () {
                return TDev.Browser.lowMemory ? 0 : TDev.Browser.isMobile ? 25 : 150;
            };
            ArtCache.getMaxItemSize = function () {
                return TDev.Browser.isMobile ? 500000 : 10000000;
            };
            var itemsToDownload = 0;
            var itemsDownloaded = 0;
            function resetProgress() {
                itemsToDownload = 0;
                itemsDownloaded = 0;
            }
            ArtCache.resetProgress = resetProgress;
            function responseToDataUrl(response) {
                if (typeof response.content() == "string") {
                    return "data:text/plain;base64," + TDev.Util.base64Encode(TDev.Util.toUTF8(response.content()));
                }
                var bytes = response.contentAsArraybuffer();
                if (!bytes)
                    return null;
                var contentType = response.header('Content-Type');
                if (!contentType) {
                    log('missing Content-Type');
                    return null;
                }
                if (bytes.length > ArtCache.getMaxItemSize()) {
                    log('item too big ' + (bytes.length / 1e6).toFixed(1) + 'Mb');
                    return "data:none";
                }
                var encoded = TDev.Util.base64EncodeBytes(bytes);
                return "data:" + contentType + ";base64," + encoded;
            }
            ArtCache.responseToDataUrl = responseToDataUrl;
            function snapshotCacheAsync(storage) {
                return getArtCacheTableAsync().then(function (table) { return table.getKeysAsync().then(function (keys) { return table.getItemsAsync(keys).then(function (v) {
                    storage.artCache = v;
                }); }); });
            }
            ArtCache.snapshotCacheAsync = snapshotCacheAsync;
            function restoreCacheAsync(storage) {
                if (!storage.artCache)
                    return TDev.Promise.as();
                return getArtCacheTableAsync().then(function (table) { return table.getKeysAsync().then(function (keys) {
                    var toSet = storage.artCache;
                    keys.forEach(function (k) {
                        if (!toSet.hasOwnProperty(k))
                            toSet[k] = null;
                    });
                    return table.setItemsAsync(toSet);
                }); });
            }
            ArtCache.restoreCacheAsync = restoreCacheAsync;
            function getArtAsync(url, accept) {
                if (accept === void 0) { accept = "*"; }
                if (!ArtCache.enabled || !ArtCache.getMaxItems())
                    return TDev.Promise.as(null);
                if (!url || !/^https?:\/\//.test(url)) {
                    log('must be absolute url');
                    return TDev.Promise.as(null);
                }
                url = TDev.HTML.proxyResource(url);
                var id = url;
                var art = null;
                var table = null;
                return getArtCacheTableAsync().then(function (t) {
                    table = t;
                    return table.getValueAsync(id);
                }).then(function (value) {
                    if (typeof value === "string") {
                        log("art cache: hit " + id);
                        if (value == "data:none") {
                            log("art cache: hit on art too big, streaming " + id);
                            return null;
                        }
                        return value;
                    }
                    log("art cache: miss " + id);
                    var rt = TDev.Runtime.theRuntime;
                    itemsToDownload++;
                    if (!TDev.Cloud.isOnline()) {
                        TDev.Util.log('art cache: no internet');
                        return null;
                    }
                    var request = TDev.RT.WebRequest.mk(url, null);
                    if (accept)
                        request.set_header("Accept", accept);
                    request.show_notifications(false);
                    return request.sendAsync().then(function (response) {
                        itemsDownloaded++;
                        if (!ArtCache.runningTests)
                            TDev.ProgressOverlay.setProgress(TDev.Util.fmt("{0} of {1} done", itemsDownloaded, itemsToDownload));
                        art = responseToDataUrl(response);
                        if (!art) {
                            TDev.Util.log('art cache: request failed ' + id);
                            return null;
                        }
                        return table.getValueAsync("arttable:keys").then(function (k) {
                            if (!k)
                                k = "";
                            var keys = k.split(';');
                            var items = {};
                            items[id] = art;
                            var ii = keys.indexOf(id);
                            if (ii > -1) {
                                keys[ii] = null;
                                keys = keys.filter(function (kk) { return !!kk; });
                            }
                            var maxKeys = ArtCache.getMaxItems();
                            while (keys.length > maxKeys) {
                                items[keys[0]] = null;
                                keys.shift();
                                log("art cache: drop " + id);
                            }
                            keys.push(id);
                            items["arttable:keys"] = keys.join(';');
                            return table.setItemsAsync(items);
                        }).then(function () { return art; });
                    });
                });
            }
            ArtCache.getArtAsync = getArtAsync;
        })(ArtCache = RT.ArtCache || (RT.ArtCache = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var OAuthResponse = (function (_super) {
            __extends(OAuthResponse, _super);
            function OAuthResponse() {
                _super.apply(this, arguments);
            }
            OAuthResponse.prototype.exportJson = function (ctx) {
                return {
                    time: this._time && this._time.exportJson(ctx),
                    accessToken: this._accessToken,
                    expiresIn: this._expiresIn,
                    scope: this._scope,
                    error: this._error,
                    errorDescription: this._errorDescription,
                    errorUri: this._errorUri,
                    others: this._others && this._others.exportJson(ctx),
                };
            };
            OAuthResponse.prototype.importJson = function (ctx, json) {
                if (typeof json != "object")
                    json = undefined;
                this._time = ctx.importDateTime(json, "time");
                this._accessToken = ctx.importString(json, "accessToken");
                this._expiresIn = ctx.importNumber(json, "expiresIn");
                this._scope = ctx.importString(json, "scope");
                this._error = ctx.importString(json, "error");
                this._errorDescription = ctx.importString(json, "errorDescription");
                this._errorUri = ctx.importString(json, "errorUri");
                this._others = ctx.importStringMap(json, this._others, "others");
                return this;
            };
            OAuthResponse.parseJSON = function (json) {
                var accessToken;
                var expiresIn = 0;
                var scope;
                var isError = false;
                var error;
                var errorDescription;
                var errorUri;
                var others = RT.Collections.create_string_map();
                var keys = json.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var key = keys.at(i);
                    var value = json.at(i);
                    switch (key) {
                        case "access_token":
                            accessToken = value.to_string();
                            break;
                        case "expires_in":
                            expiresIn = Math.floor(value.to_number() || -1);
                            break;
                        case "scope":
                            scope = value.to_string();
                            break;
                        case "error":
                            error = value.to_string();
                            isError = true;
                            break;
                        case "error_description":
                            errorDescription = value.to_string();
                            break;
                        case "error_uri":
                            errorUri = value.to_string();
                            break;
                        case "state": break;
                        default:
                            others.set_at(key, value.to_string());
                            break;
                    }
                }
                if (!accessToken && !isError)
                    return undefined;
                else if (accessToken && !isError)
                    return OAuthResponse.mkAccessToken(accessToken, expiresIn, scope, others);
                else
                    return OAuthResponse.mkError(error, errorDescription, errorUri, others);
            };
            OAuthResponse.parse = function (redirect_url) {
                var queryIndex = redirect_url.indexOf('?');
                var markerIndex = redirect_url.indexOf('#', queryIndex + 1);
                if (queryIndex < 0 && markerIndex < 0)
                    return undefined;
                var query = queryIndex < 0 ? "" : redirect_url.substring(queryIndex + 1, markerIndex < 0 ? redirect_url.length : markerIndex);
                var marker = markerIndex < 0 ? "" : redirect_url.substring(markerIndex + 1);
                var args = query.split('&').concat(marker.split('&'));
                var accessToken;
                var expiresIn = 0;
                var scope;
                var isError = false;
                var error;
                var errorDescription;
                var errorUri;
                var others = RT.Collections.create_string_map();
                args.forEach(function (arg) {
                    var ei = arg.indexOf('=');
                    if (ei > -1) {
                        var key = RT.Web.url_decode(arg.substring(0, ei));
                        var value = RT.Web.url_decode(arg.substring(ei + 1));
                        switch (key) {
                            case "access_token":
                                accessToken = value;
                                break;
                            case "expires_in":
                                expiresIn = parseInt(value) || -1;
                                break;
                            case "scope":
                                scope = value;
                                break;
                            case "error":
                                error = value;
                                isError = true;
                                break;
                            case "error_description":
                                errorDescription = value;
                                break;
                            case "error_uri":
                                errorUri = value;
                                break;
                            case "state": break;
                            default:
                                others.set_at(key, value);
                                break;
                        }
                    }
                });
                if (!accessToken && !isError)
                    return undefined;
                else if (accessToken && !isError)
                    return OAuthResponse.mkAccessToken(accessToken, expiresIn, scope, others);
                else
                    return OAuthResponse.mkError(error, errorDescription, errorUri, others);
            };
            OAuthResponse.mkAccessToken = function (accessToken, expiresIn, scope, others) {
                if (others === void 0) { others = null; }
                var r = new OAuthResponse();
                r._time = RT.Time.now();
                r._accessToken = accessToken;
                r._expiresIn = expiresIn || 0;
                r._scope = scope;
                r._others = others;
                return r;
            };
            OAuthResponse.mkError = function (error, errorDescription, errorUri, others) {
                if (others === void 0) { others = null; }
                var r = new OAuthResponse();
                r._time = RT.Time.now();
                r._error = error;
                r._errorDescription = errorDescription;
                r._errorUri = errorUri;
                r._others = others;
                return r;
            };
            OAuthResponse.prototype.toString = function () {
                var s;
                if (this._error)
                    s = this._error + ", " + (this._errorDescription || "no description") + ", " + (this._errorUri || "no error uri");
                else
                    s = this._accessToken + ", " + this._expiresIn + ", " + (this._scope || "no scope");
                if (this._others)
                    s += " ," + this._others.toString();
                return s;
            };
            OAuthResponse.prototype.access_token = function () {
                return this._accessToken;
            };
            OAuthResponse.prototype.expires_in = function () {
                return this._expiresIn;
            };
            OAuthResponse.prototype.scope = function () {
                return this._scope;
            };
            OAuthResponse.prototype.error = function () {
                return this._error;
            };
            OAuthResponse.prototype.error_description = function () {
                return this._errorDescription;
            };
            OAuthResponse.prototype.error_uri = function () {
                return this._errorUri;
            };
            OAuthResponse.prototype.others = function () {
                if (!this._others)
                    this._others = RT.Collections.create_string_map();
                return this._others;
            };
            OAuthResponse.prototype.is_expiring = function (seconds) {
                if (this.is_error())
                    return true;
                return this._expiresIn > 0 && this._time.add_seconds(this._expiresIn + Math.max(0, seconds)).less(RT.Time.now());
            };
            OAuthResponse.prototype.is_error = function () {
                return !this._accessToken;
            };
            OAuthResponse.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return OAuthResponse;
        })(RT.RTValue);
        RT.OAuthResponse = OAuthResponse;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Action = (function (_super) {
            __extends(Action, _super);
            function Action() {
                _super.apply(this, arguments);
            }
            Action.prototype.run = function () {
            };
            return Action;
        })(RT.ActionBase);
        RT.Action = Action;
        var TextAction = (function (_super) {
            __extends(TextAction, _super);
            function TextAction() {
                _super.apply(this, arguments);
            }
            TextAction.prototype.run = function (text) {
            };
            return TextAction;
        })(RT.ActionBase);
        RT.TextAction = TextAction;
        var NumberAction = (function (_super) {
            __extends(NumberAction, _super);
            function NumberAction() {
                _super.apply(this, arguments);
            }
            NumberAction.prototype.run = function (x) {
            };
            return NumberAction;
        })(RT.ActionBase);
        RT.NumberAction = NumberAction;
        var BooleanAction = (function (_super) {
            __extends(BooleanAction, _super);
            function BooleanAction() {
                _super.apply(this, arguments);
            }
            BooleanAction.prototype.run = function (boolean) {
            };
            return BooleanAction;
        })(RT.ActionBase);
        RT.BooleanAction = BooleanAction;
        var PositionAction = (function (_super) {
            __extends(PositionAction, _super);
            function PositionAction() {
                _super.apply(this, arguments);
            }
            PositionAction.prototype.run = function (x, y) {
            };
            return PositionAction;
        })(RT.ActionBase);
        RT.PositionAction = PositionAction;
        var SpriteAction = (function (_super) {
            __extends(SpriteAction, _super);
            function SpriteAction() {
                _super.apply(this, arguments);
            }
            SpriteAction.prototype.run = function (sprite) {
            };
            return SpriteAction;
        })(RT.ActionBase);
        RT.SpriteAction = SpriteAction;
        var SpriteSetAction = (function (_super) {
            __extends(SpriteSetAction, _super);
            function SpriteSetAction() {
                _super.apply(this, arguments);
            }
            SpriteSetAction.prototype.run = function (sprites) {
            };
            return SpriteSetAction;
        })(RT.ActionBase);
        RT.SpriteSetAction = SpriteSetAction;
        var VectorAction = (function (_super) {
            __extends(VectorAction, _super);
            function VectorAction() {
                _super.apply(this, arguments);
            }
            VectorAction.prototype.run = function (x, y, delta_x, delta_y) {
            };
            return VectorAction;
        })(RT.ActionBase);
        RT.VectorAction = VectorAction;
        var WebResponseAction = (function (_super) {
            __extends(WebResponseAction, _super);
            function WebResponseAction() {
                _super.apply(this, arguments);
            }
            WebResponseAction.prototype.run = function (response) {
            };
            return WebResponseAction;
        })(RT.ActionBase);
        RT.WebResponseAction = WebResponseAction;
        var CollectionMessageAction = (function (_super) {
            __extends(CollectionMessageAction, _super);
            function CollectionMessageAction() {
                _super.apply(this, arguments);
            }
            CollectionMessageAction.prototype.run = function (msgs) {
            };
            return CollectionMessageAction;
        })(RT.ActionBase);
        RT.CollectionMessageAction = CollectionMessageAction;
        var JsonAction = (function (_super) {
            __extends(JsonAction, _super);
            function JsonAction() {
                _super.apply(this, arguments);
            }
            JsonAction.prototype.run = function (json) {
            };
            return JsonAction;
        })(RT.ActionBase);
        RT.JsonAction = JsonAction;
        var Comparison = (function (_super) {
            __extends(Comparison, _super);
            function Comparison() {
                _super.apply(this, arguments);
            }
            Comparison.prototype.run = function (a, b) {
                return 0;
            };
            return Comparison;
        })(RT.ActionBase);
        RT.Comparison = Comparison;
        var Predicate = (function (_super) {
            __extends(Predicate, _super);
            function Predicate() {
                _super.apply(this, arguments);
            }
            Predicate.prototype.run = function (elt) {
                return false;
            };
            return Predicate;
        })(RT.ActionBase);
        RT.Predicate = Predicate;
        var AtomicAction = (function (_super) {
            __extends(AtomicAction, _super);
            function AtomicAction() {
                _super.apply(this, arguments);
            }
            AtomicAction.prototype.run = function () {
            };
            return AtomicAction;
        })(RT.ActionBase);
        RT.AtomicAction = AtomicAction;
        var AtomicAction1 = (function (_super) {
            __extends(AtomicAction1, _super);
            function AtomicAction1() {
                _super.apply(this, arguments);
            }
            AtomicAction1.prototype.run = function (v) {
            };
            return AtomicAction1;
        })(RT.ActionBase);
        RT.AtomicAction1 = AtomicAction1;
        var Action1 = (function (_super) {
            __extends(Action1, _super);
            function Action1() {
                _super.apply(this, arguments);
            }
            Action1.prototype.run = function (v) {
            };
            return Action1;
        })(RT.ActionBase);
        RT.Action1 = Action1;
        var NumberConverter = (function (_super) {
            __extends(NumberConverter, _super);
            function NumberConverter() {
                _super.apply(this, arguments);
            }
            NumberConverter.prototype.run = function (elt) {
                return 0;
            };
            return NumberConverter;
        })(RT.ActionBase);
        RT.NumberConverter = NumberConverter;
        var StringConverter = (function (_super) {
            __extends(StringConverter, _super);
            function StringConverter() {
                _super.apply(this, arguments);
            }
            StringConverter.prototype.run = function (elt) {
                return "";
            };
            return StringConverter;
        })(RT.ActionBase);
        RT.StringConverter = StringConverter;
        var Converter = (function (_super) {
            __extends(Converter, _super);
            function Converter() {
                _super.apply(this, arguments);
            }
            Converter.prototype.run = function (elt) {
                return undefined;
            };
            return Converter;
        })(RT.ActionBase);
        RT.Converter = Converter;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Contract;
        (function (Contract) {
            function requires(condition, message, s) {
                if (s.rt.devMode && !condition)
                    TDev.Util.userError(TDev.lf("requirement failed: {0}", message), s.pc, 400);
            }
            Contract.requires = requires;
            function assert(condition, message, s) {
                if (s.rt.devMode && !condition)
                    TDev.Util.userError(TDev.lf("assertion failed: {0}", message), s.pc);
            }
            Contract.assert = assert;
        })(Contract = RT.Contract || (RT.Contract = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var CloudSession = (function (_super) {
            __extends(CloudSession, _super);
            function CloudSession() {
                _super.call(this);
            }
            CloudSession.prototype.isJustMeSession = function () {
                return this.tag === "pr";
            };
            CloudSession.prototype.isEveryoneSession = function () {
                return this.tag === "pu";
            };
            CloudSession.prototype.isBroadcastSession = function () {
                return this.tag === "cr";
            };
            CloudSession.prototype.isShareableSession = function () {
                return this.tag === "cw";
            };
            CloudSession.prototype.isPrivateSession = function () {
                return this.tag === "cp";
            };
            CloudSession.prototype.isNodeSession = function () {
                return this.tag === "pn";
            };
            CloudSession.prototype.type = function () {
                if (this.isBroadcastSession())
                    return "broadcast";
                if (this.isEveryoneSession() || this.isShareableSession())
                    return "public";
                return "";
            };
            CloudSession.prototype.toString = function () {
                return "cloud session: " + this._id + (this._title ? "(" + this._title + ")" : "");
            };
            CloudSession.fromDescriptor = function (desc) {
                if (!desc)
                    return undefined;
                var s = new CloudSession();
                s._id = desc.servername;
                s._title = desc.title;
                s._permissions = desc.permissions;
                return s.validate() ? s : undefined;
            };
            CloudSession.prototype.validate = function () {
                var pos = this._id.indexOf("0");
                if (pos > 3 && pos < this._id.length - 4) {
                    this.ownerid = this._id.substr(0, pos);
                    this.tag = this._id.substr(pos + 1, 2);
                    this.guidhash = this._id.substr(pos + 3);
                    return (/^[a-z]{3,}$/.test(this.ownerid) && /^[a-z]+$/.test(this.guidhash) && /^(pr|pu|cr|cw|cp|pn)$/.test(this.tag));
                }
                else
                    return false;
            };
            CloudSession.makeScriptTag = function (author, scriptname) {
                return (author + "xx" + TDev.Revisions.letterify(scriptname) + "xx");
            };
            CloudSession.makeScriptIdentifier = function (scriptid, authorid) {
                return scriptid + "@" + authorid;
            };
            CloudSession.prototype.equals = function (other) {
                return this._id === other._id;
            };
            CloudSession.prototype.id = function () {
                return this._id;
            };
            CloudSession.prototype.title = function () {
                return this._title;
            };
            CloudSession.prototype.owner = function () {
                return RT.User.mk(this.ownerid);
            };
            CloudSession.prototype.is_owned = function (s) {
                return s.rt.sessions.getUserId() === this.ownerid;
            };
            CloudSession.prototype.post_to_wall = function (s) {
                s.rt.postBoxedHtml(CloudData.formatCloudSessionInfo(this, false, false, true), s.pc, this);
            };
            CloudSession.prototype.server_info = function (r) {
                if (this.isNodeSession())
                    TDev.Util.userError(TDev.lf("cannot get session info for deployed cloud libraries"), r.rt.current.pc);
                if (this.ownerid !== r.rt.sessions.getUserId())
                    TDev.Util.userError(TDev.lf("not permitted: must be session owner"), r.rt.current.pc);
                if (this.isNodeSession())
                    TDev.Util.userError(TDev.lf("cannot query node sessions server info"));
                var promise = TDev.Revisions.getServerInfoAsync(this._id);
                promise.then(function (result) { return r.resumeVal(result); });
                return promise.done();
            };
            return CloudSession;
        })(RT.RTValue);
        RT.CloudSession = CloudSession;
        var CloudData;
        (function (CloudData) {
            function current_session(i) {
                return i.rt.sessions.getCurrentSession().getCloudSession();
            }
            CloudData.current_session = current_session;
            function rebuild_cache(r) {
                r.rt.sessions.resetCurrentSession().then(function (s) {
                    r.resumeVal(s);
                });
            }
            CloudData.rebuild_cache = rebuild_cache;
            function clear_all_data(i) {
                return i.rt.sessions.clearCurrentSession();
            }
            CloudData.clear_all_data = clear_all_data;
            function to_json(s) {
                var ctx = new TDev.JsonExportCtx(s, true);
                var json = s.rt.compiled._exportJson(s.rt.datas["this"], ctx);
                return RT.JsonObject.wrap(json);
            }
            CloudData.to_json = to_json;
            function from_json(jobj, s) {
                var json = jobj.value();
                var ctx = new TDev.JsonImportCtx(s);
                s.rt.compiled._importJson(s.rt.datas["this"], ctx, json);
            }
            CloudData.from_json = from_json;
            function last_session(s) {
                return s.rt.sessions.getCurrentSession().getCloudSession();
            }
            CloudData.last_session = last_session;
            function just_me_session(s) {
                return CloudSession.fromDescriptor(s.rt.sessions.getJustMeSessionDescriptor());
            }
            CloudData.just_me_session = just_me_session;
            function set_token_validator(validator, s) {
                s.rt.authValidator = validator;
            }
            CloudData.set_token_validator = set_token_validator;
            function authenticate(access_token, r) {
                r.rt.authAccessToken = access_token;
                if (!access_token)
                    r.resumeVal(false);
                else
                    r.rt.queryServiceAsync("-internal-/me", {}).done(function (resp) {
                        if (resp.userid) {
                            r.rt.authUserId = resp.userid;
                            r.resumeVal(true);
                        }
                        else {
                            r.resumeVal(false);
                        }
                    }, function (err) {
                        r.resumeVal(false);
                    });
            }
            CloudData.authenticate = authenticate;
            function everyone_session(s) {
                return CloudSession.fromDescriptor(s.rt.sessions.getEveryoneSessionDescriptor());
            }
            CloudData.everyone_session = everyone_session;
            function wait_for_server(timeout, r) {
                var ses = r.rt.sessions;
                var cs = ses.getCurrentSession();
                cs.user_yield();
                if (cs.user_get_connectionstatus(false) === "connected")
                    r.resumeVal(true);
                else if (timeout === 0)
                    r.resumeVal(false);
                else {
                    cs.log("issuing fence");
                    var decided = false;
                    TDev.Util.setTimeout(timeout * 1000, function () {
                        if (!decided) {
                            decided = true;
                            r.resumeVal(false);
                        }
                    });
                    cs.user_issue_fence(function () {
                        if (!decided) {
                            decided = true;
                            r.resumeVal(true);
                        }
                    }, !r.isTaskCtx());
                }
            }
            CloudData.wait_for_server = wait_for_server;
            function create_session(title, type, r) {
                if (!title)
                    TDev.Util.userError(TDev.lf("must specify title"), r.rt.current.pc);
                if (!/^(shareable|private|broadcast)$/.test(type))
                    TDev.Util.userError(TDev.lf("no such session type"), r.rt.current.pc);
                return r.rt.sessions.createCustomSessionAsync(title, type).then(function (val) {
                    r.resumeVal(val);
                }).done();
            }
            CloudData.create_session = create_session;
            function session_of(id, title, s) {
                var cs = new CloudSession();
                cs._id = id;
                cs._title = title;
                cs._permissions = "";
                if (cs.validate() && cs.tag[0] === "c")
                    return cs;
                else
                    TDev.Util.userError(TDev.lf("cannot get session from id"), s.pc);
            }
            CloudData.session_of = session_of;
            function connection_status(include_extra_details, s) {
                return s.rt.sessions.getCurrentSession().user_get_connectionstatus(include_extra_details);
            }
            CloudData.connection_status = connection_status;
            function participant_number(s) {
                return s.rt.sessions.getCurrentSession().getMemberNumber();
            }
            CloudData.participant_number = participant_number;
            function set_sync_enabled(enable, s) {
                s.rt.sessions.getCurrentSession().user_enable_sync(enable);
            }
            CloudData.set_sync_enabled = set_sync_enabled;
            function is_sync_enabled(s) {
                return s.rt.sessions.getCurrentSession().user_sync_enabled();
            }
            CloudData.is_sync_enabled = is_sync_enabled;
            function formatCloudSessionInfo(cloudSession, preselected, includesserverdata, showscriptname, user) {
                if (user === void 0) { user = null; }
                var percentfull = (cloudSession.sessionimpl && cloudSession.sessionimpl.user_get_percent_full()) ? cloudSession.sessionimpl.user_get_percent_full() : (cloudSession.serverinfo && cloudSession.serverinfo.percentfull) ? cloudSession.serverinfo.percentfull : 0;
                var percentfullstring = percentfull ? (" (" + percentfull + "% full)") : "";
                var title = (!showscriptname && cloudSession.isEveryoneSession()) ? "everyone session" : (!showscriptname && cloudSession.isJustMeSession()) ? "just-me session" : (cloudSession._title || ("session \"" + cloudSession._id + "\""));
                var owner = (cloudSession.ownerid === TDev.Cloud.getUserId()) ? "I" : user ? (user.name + " (/" + cloudSession.ownerid + ")") : ("user /" + cloudSession.ownerid);
                var permissions = (cloudSession.isEveryoneSession() || cloudSession.isShareableSession()) ? "everyone can read and modify" : (cloudSession.isJustMeSession() || cloudSession.isPrivateSession()) ? "only " + owner + " can read and modify" : ("only " + owner + " can modify, but everyone can read");
                var connected = cloudSession.sessionimpl && cloudSession.sessionimpl.user_is_websocket_open();
                var localname = cloudSession.sessionimpl ? cloudSession.sessionimpl.localname : cloudSession.localname;
                var existence = (includesserverdata || connected) ? ((cloudSession.serverinfo || connected) ? localname ? "stored in cloud" + percentfullstring + " and locally cached" : "stored in cloud" + percentfullstring + ", not locally cached" : localname ? "not stored in cloud, local only" : "not created yet") + "\n" : "";
                var icon = TDev.div("navImg", TDev.SVG.getCloudSymbol("black", cloudSession.type(), true));
                var titleelt = (preselected) ? TDev.HTML.span("bold", title) : TDev.HTML.span("", title);
                var information = ((owner === "I") ? "" : "owned by " + owner + "\n") + permissions + "\n" + ("session id: " + cloudSession._id + "\n") + existence;
                return TDev.HTML.mkButtonElt("navItem cloudSession", TDev.div("navItemInner", icon, TDev.div("navContent", TDev.div("navName", titleelt), TDev.div("navDescription", information))));
            }
            CloudData.formatCloudSessionInfo = formatCloudSessionInfo;
            var sessionstatusdiv;
            var sessionretrydiv;
            function refreshSessionInfo(session) {
                if (sessionstatusdiv)
                    sessionstatusdiv.setChildren([session.user_get_connectionstatus(true)]);
            }
            CloudData.refreshSessionInfo = refreshSessionInfo;
            function sessionInfoAsync(rt) {
                var session = rt.sessions.getCurrentSession();
                var sessioninfo = CloudData.formatCloudSessionInfo(session.getCloudSession(), false, false, false);
                sessioninfo.style.background = "white";
                if (!sessionstatusdiv)
                    sessionstatusdiv = TDev.div("wall-dialog-body");
                if (!sessionretrydiv)
                    sessionretrydiv = TDev.div("wall-dialog-body").withClick(function (e) { return session.user_retry_now(); });
                this.refreshSessionInfo(session);
                var m = new TDev.ModalDialog();
                m.add([
                    TDev.div("wall-dialog-header", TDev.lf("current cloud session")),
                    sessioninfo,
                    TDev.div("wall-dialog-header wall-dialog-extra-space", TDev.lf("connection status")),
                    sessionstatusdiv,
                    sessionretrydiv
                ]);
                if (session.isMarooned() || session.isClosed() || session.isFaulted()) {
                    m.addOk("discard locally cached data, and try again", function () {
                        rt.sessions.resetCurrentSession();
                        m.dismiss();
                    });
                    m.addOk("cancel");
                }
                else
                    m.addOk("ok");
                var retrytimeindicatorinterval = setInterval(function () {
                    var msg;
                    var mr = session.user_get_missing_rounds();
                    if (mr) {
                        msg = mr + " remaining.";
                    }
                    var rt = session.user_get_next_connection_attempt();
                    if (rt) {
                        var secs = Math.floor((rt - 700 - new Date().getTime()) / 1000);
                        var msg = (secs < 1) ? "connection attempt in progress..." : "next connection attempt in " + secs.toString() + " seconds";
                    }
                    sessionretrydiv.setChildren([msg]);
                }, 50);
                m.onDismiss = function () { return clearInterval(retrytimeindicatorinterval); };
                m.show();
            }
            CloudData.sessionInfoAsync = sessionInfoAsync;
            function mkSimpleBtnConfirm(desc, f) {
                var isRed = false;
                var btn = TDev.HTML.mkButton(desc, function () {
                    if (isRed)
                        f();
                    else {
                        isRed = true;
                        btn.style.color = 'red';
                        TDev.Util.setTimeout(3000, function () {
                            isRed = false;
                            btn.style.color = '';
                        });
                    }
                });
                return btn;
            }
            function managementDialog(rt) {
                var p = TDev.Cloud.getUserId() ? TDev.Promise.as() : TDev.Cloud.authenticateAsync(TDev.lf("cloud data"));
                return p.thenalways(function (x) {
                    if (TDev.Cloud.getUserId())
                        return sessionDialogAsync(undefined, "manage cloud sessions", false, rt);
                });
            }
            CloudData.managementDialog = managementDialog;
            function scriptSessionsDialog(rt) {
                var p = TDev.Cloud.getUserId() ? TDev.Promise.as() : TDev.Cloud.authenticateAsync(TDev.lf("cloud data"));
                return p.thenalways(function (x) {
                    if (TDev.Cloud.getUserId()) {
                        var s = rt.sessions.getLastSession();
                        return sessionDialogAsync(s && s.getCloudSession(), TDev.lf("select cloud session for this script"), true, rt).then(function (s) {
                            if (s)
                                return rt.sessions.connectCurrent(rt.sessions.getCloudSessionDescriptor(s._id, s._title, s._permissions));
                            else
                                return undefined;
                        });
                    }
                });
            }
            CloudData.scriptSessionsDialog = scriptSessionsDialog;
            function sessionDialogAsync(preselectedsession, title, specificscript, rt, rctx) {
                if (rctx === void 0) { rctx = undefined; }
                var p = new TDev.PromiseInv();
                var sessionmap = {};
                var counter = 0;
                var incorporate = function (x) {
                    if (sessionmap.hasOwnProperty(x._id)) {
                        var cur = sessionmap[x._id];
                        ["_title", "localname", "serverinfo", "position", "membernumber", "enable_sync"].forEach(function (s) {
                            if (!cur[s])
                                cur[s] = x[s];
                        });
                    }
                    else {
                        x.position = counter++;
                        sessionmap[x._id] = x;
                    }
                };
                if (specificscript) {
                    incorporate(CloudSession.fromDescriptor(rt.sessions.getJustMeSessionDescriptor()));
                    incorporate(CloudSession.fromDescriptor(rt.sessions.getEveryoneSessionDescriptor()));
                }
                if (preselectedsession)
                    incorporate(preselectedsession);
                var dialog = function (includesSessionsOnRevisionServer) {
                    var sessionarray = [];
                    for (var x in sessionmap)
                        if (sessionmap.hasOwnProperty(x))
                            sessionarray.push(sessionmap[x]);
                    sessionarray.sort(function (a, b) { return (a.position - b.position); });
                    var m = new TDev.ModalDialog();
                    var chosenSession = preselectedsession;
                    var btns = sessionarray.map(function (cloudSession, i) {
                        var deleting = false;
                        var cloudSessionElt = CloudData.formatCloudSessionInfo(cloudSession, preselectedsession && cloudSession.equals(preselectedsession), includesSessionsOnRevisionServer, !specificscript);
                        if (specificscript) {
                            cloudSessionElt.withClick(function () {
                                if (!deleting) {
                                    chosenSession = cloudSession;
                                    m.dismiss();
                                }
                            });
                        }
                        var inuse = (rt.sessions.getLastSession() && rt.sessions.getLastSession().servername === cloudSession.id());
                        var owned = TDev.Cloud.getUserId() === cloudSession.ownerid;
                        var cached = !owned && (cloudSession.isBroadcastSession() || cloudSession.isShareableSession());
                        if (owned || (cached && !inuse)) {
                            var deleteElt = TDev.HTML.mkButtonElt("navItem", inuse ? "clear" : cached ? "remove" : "delete");
                            var isRed = false;
                            deleteElt.withClick(function () {
                                if (!isRed) {
                                    isRed = true;
                                    deleteElt.style.color = 'red';
                                    TDev.Util.setTimeout(3000, function () {
                                        isRed = false;
                                        deleteElt.style.color = '';
                                    });
                                    return;
                                }
                                if (!inuse)
                                    elt.className += " disabledItem";
                                deleting = !inuse;
                                deleteDiv.removeAllChildren();
                                deleteDiv.appendChildren(TDev.div(null, inuse ? "clearing..." : cached ? "removing..." : "deleting..."));
                                var errorhandler = function (e) {
                                    deleteDiv.removeAllChildren();
                                    deleteDiv.appendChildren(TDev.div(null, "" + e));
                                };
                                if (inuse) {
                                    rt.sessions.getCurrentSession().user_clear_all();
                                    TDev.Util.setTimeout(800, function () { return deleteDiv.removeAllChildren(); });
                                }
                                else {
                                    TDev.Revisions.deleteSessionAsync(rt.sessions.getCloudSessionDescriptor(cloudSession._id, cloudSession._title, cloudSession._permissions), rt).then(function () {
                                        deleteDiv.removeAllChildren();
                                        deleteDiv.appendChildren(TDev.div(null, cached ? "removed" : "deleted"));
                                    }, errorhandler).done();
                                }
                            });
                            var deleteDiv = TDev.div("floatright", deleteElt);
                            var elt = TDev.div(null, deleteDiv, TDev.div("floatleft", cloudSessionElt), TDev.div("clear"));
                            return elt;
                        }
                        else
                            return cloudSessionElt;
                    });
                    m.setScroll();
                    var existingTitleDiv = TDev.div("wall-dialog-header", title);
                    m.add([existingTitleDiv]);
                    if (specificscript) {
                        var createDiv = TDev.div("floatright");
                        var addCreateElt = function (type) {
                            var createElt = TDev.HTML.mkButtonElt("wall-button", type);
                            createElt.withClick(function () {
                                var title = createTitle.textarea.value;
                                if (!title) {
                                    createMsgDiv.removeAllChildren();
                                    createMsgDiv.appendChildren(TDev.div(null, TDev.lf("must specify title")));
                                    return;
                                }
                                rt.sessions.createCustomSessionAsync(createTitle.textarea.value, type).then(function (session) {
                                    chosenSession = session;
                                    m.dismiss();
                                }, function (e) {
                                    createMsgDiv.removeAllChildren();
                                    createMsgDiv.appendChildren(TDev.div(null, "" + e));
                                }).done();
                            });
                            createDiv.appendChildren(createElt);
                        };
                        addCreateElt("shareable");
                        addCreateElt("private");
                        addCreateElt("broadcast");
                        var connectToShareableElt = TDev.HTML.mkButtonElt("wall-button", "connect");
                        connectToShareableElt.withClick(function () {
                            var cs = new CloudSession();
                            cs._id = sharableId.textarea.value;
                            cs._title = "";
                            cs._permissions = "";
                            if (cs.validate() && cs.tag[0] === "c") {
                                chosenSession = cs;
                                m.dismiss();
                            }
                            else {
                                sharableMsgDiv.removeAllChildren();
                                sharableMsgDiv.appendChildren(TDev.div(null, "invalid id"));
                            }
                        });
                        var connectToShareableDiv = TDev.div("floatright", connectToShareableElt);
                        var createTitle = TDev.HTML.mkAutoExpandingTextArea();
                        createTitle.textarea.placeholder = "title of new session";
                        var createMsgDiv = TDev.div("wall-dialog-body");
                        var sharableId = TDev.HTML.mkAutoExpandingTextArea();
                        sharableId.textarea.placeholder = "shareable session id";
                        var sharableMsgDiv = TDev.div("wall-dialog-body");
                        var createbutton = TDev.HTML.mkButtonElt("wall-button", "create");
                        var connectbutton = TDev.HTML.mkButtonElt("wall-button", "enter code");
                        var cancelbutton = TDev.HTML.mkButtonElt("wall-button", "cancel");
                        var innested = false;
                        var setCreatePaneDisplay = function (show) {
                            var d = show ? "" : "none";
                            createTitle.div.style.display = d;
                            createDiv.style.display = d;
                            createMsgDiv.style.display = d;
                            createbutton.style.display = (show) ? "none" : "";
                        };
                        var setConnectPaneDisplay = function (show) {
                            var d = show ? "" : "none";
                            sharableId.div.style.display = d;
                            connectToShareableDiv.style.display = d;
                            sharableMsgDiv.style.display = d;
                            connectbutton.style.display = (show) ? "none" : "";
                        };
                        var setButtonsDisplay = function (show) {
                            var d = show ? "" : "none";
                            createbutton.style.display = d;
                            connectbutton.style.display = d;
                        };
                        createbutton.withClick(function () {
                            existingTitleDiv.setChildren(["create a new session"]);
                            setCreatePaneDisplay(true);
                            setConnectPaneDisplay(false);
                            m.showorhidelist(false);
                            setButtonsDisplay(false);
                            innested = true;
                        });
                        connectbutton.withClick(function () {
                            existingTitleDiv.setChildren(["enter a session id"]);
                            setCreatePaneDisplay(false);
                            setConnectPaneDisplay(true);
                            m.showorhidelist(false);
                            setButtonsDisplay(false);
                            innested = true;
                        });
                        cancelbutton.withClick(function () {
                            if (innested) {
                                setCreatePaneDisplay(false);
                                setConnectPaneDisplay(false);
                                m.showorhidelist(true);
                                existingTitleDiv.setChildren([title]);
                                setButtonsDisplay(true);
                                innested = false;
                            }
                            else
                                m.dismiss();
                        });
                        setCreatePaneDisplay(false);
                        setConnectPaneDisplay(false);
                        m.showorhidelist(true);
                        m.add([
                            createTitle.div,
                            createDiv,
                            TDev.div("clear"),
                            createMsgDiv,
                            sharableId.div,
                            connectToShareableDiv,
                            TDev.div("clear"),
                            sharableMsgDiv
                        ]);
                    }
                    var options = {
                        searchHint: 'search sessions',
                        noBackground: true,
                        adjustListSize: true,
                        custombuttons: [createbutton, connectbutton, cancelbutton]
                    };
                    m.choose(btns, options);
                    if (!includesSessionsOnRevisionServer) {
                        m.add([TDev.div("wall-dialog-body", TDev.lf("server unreachable; are you offline?"))]);
                    }
                    m.onDismiss = function () {
                        p.success(chosenSession);
                    };
                };
                TDev.HTML.showProgressNotification(TDev.lf("Loading sessions..."));
                TDev.Revisions.queryCachedSessionsAsync(specificscript, rt).then(function (sessionsInCache) {
                    sessionsInCache.forEach(function (s) { return incorporate(s); });
                    return TDev.Revisions.queryMySessionsOnRevisionServerAsync(rt, specificscript).then(function (sessionsOnRevisionServer) {
                        sessionsOnRevisionServer.forEach(function (s) { return incorporate(s); });
                        return true;
                    }, function (e) { return false; }).then(function (includesSessionsOnRevisionServer) { return dialog(includesSessionsOnRevisionServer); });
                }).done();
                return p;
            }
            CloudData.sessionDialogAsync = sessionDialogAsync;
            function askSwitchAccessAsync(previoussession, session, owner, r, secondchance) {
                if (session.isPrivateSession() || session.ownerid === r.rt.sessions.getUserId())
                    return TDev.Promise.as(session);
                var p = r.rt.host.askSourceAccessAsync("shared cloud data owned by " + owner, "and share data in the cloud. " + owner + " administers the data, and can share it with other users or delete it.", secondchance);
                return p.then(function (allow) {
                    if (!allow) {
                        var mdp = new TDev.PromiseInv();
                        TDev.ModalDialog.askMany("Fall-back session", "Because you have indicated that this script should not participate in cloud sessions owned by " + owner + ", we are using a private just-me session instead.", {
                            ok: function () { return mdp.success(previoussession.getCloudSession()); },
                            reconsider: function () { return askSwitchAccessAsync(previoussession, session, owner, r, true).then(function (s) { return mdp.success(s); }); }
                        });
                        return mdp;
                    }
                    return TDev.Promise.as(session);
                });
            }
            function switch_to_session(session, r) {
                var rt = r.rt;
                if (session.ownerid !== rt.sessions.getUserId() && session.tag === "pr")
                    TDev.Util.userError(TDev.lf("cannot connect to a just-me session of another user"));
                if (session.isNodeSession())
                    TDev.Util.userError(TDev.lf("cannot connect to a node session"));
                var ls = rt.sessions.getCurrentSession();
                ls.user_yield();
                if (session._id === ls.servername) {
                    r.resumeVal(undefined);
                }
                else {
                    var p = TDev.Promise.as();
                    var ownerinfo;
                    p = p.then(function () { return RT.User.getJsonAsync(session.ownerid).then(function (user) { return ownerinfo = user; }, function (e) { return ownerinfo = undefined; }); });
                    p = p.then(function () {
                        var ownername = ownerinfo ? (ownerinfo.name + " (/" + session.ownerid + ")") : ("user /" + session.ownerid);
                        return askSwitchAccessAsync(ls, session, ownername, r, false);
                    });
                    p.then(function (s) {
                        return r.rt.sessions.connectCurrent(r.rt.sessions.getCloudSessionDescriptor(s._id, s._title, s._permissions)).then(function () { return r.resumeVal(undefined); });
                    }).done();
                }
            }
            CloudData.switch_to_session = switch_to_session;
            function switch_sessions(r) {
                var session = r.rt.sessions.getCurrentSession();
                session.user_yield();
                var p = sessionDialogAsync(session.getCloudSession(), "choose a cloud session", true, r.rt, r);
                p.then(function (s) {
                    r.rt.sessions.connectCurrent(r.rt.sessions.getCloudSessionDescriptor(s._id, s._title, s._permissions)).then(function () { return r.resumeVal(undefined); });
                }).done();
            }
            CloudData.switch_sessions = switch_sessions;
        })(CloudData = RT.CloudData || (RT.CloudData = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Buffer = (function (_super) {
            __extends(Buffer, _super);
            function Buffer() {
                _super.apply(this, arguments);
            }
            Buffer.fromString = function (s, encoding) {
                function bin(b) {
                    if (b == null)
                        return undefined;
                    return Buffer.fromTypedArray(TDev.Util.stringToUint8Array(b));
                }
                function hex(s) {
                    var prev = -1;
                    var buf = null;
                    var len = 0;
                    for (var iter = 0; iter < 2; ++iter) {
                        for (var i = 0; i < s.length; ++i) {
                            var c = s.charCodeAt(i);
                            var v = 0;
                            if (48 <= c && c <= 57)
                                v = c - 48;
                            else if (97 <= c && c <= 102)
                                v = c - 97 + 10;
                            else if (65 <= c && c <= 70)
                                v = c - 65 + 10;
                            else if (/^[\s\r\n-,.=]$/.test(s.charAt(i)))
                                continue;
                            else
                                return undefined;
                            if (prev == -1)
                                prev = v * 16;
                            else {
                                prev += v;
                                if (buf)
                                    buf[len++] = prev;
                                else
                                    len++;
                                prev = -1;
                            }
                        }
                        if (buf)
                            return Buffer.fromTypedArray(buf);
                        prev = -1;
                        buf = new Uint8Array(len);
                        len = 0;
                    }
                }
                switch (encoding) {
                    case "base64":
                        return bin(TDev.Util.base64Decode(s));
                    case "hex":
                        return hex(s);
                    case "binary":
                        return bin(s);
                    case "utf8":
                        return bin(TDev.Util.toUTF8(s));
                    case "utf16le":
                        return bin(TDev.Util.toUTF16LE(s));
                    default:
                        return undefined;
                }
            };
            Buffer.fromImageData = function (id) {
                var r = Buffer.fromTypedArray(id.data);
                r.imageData = id;
                return r;
            };
            Buffer.fromTypedArray = function (a) {
                var r = new Buffer();
                r.buffer = a;
                return r;
            };
            Buffer.mk = function (size) {
                return this.fromTypedArray(new Uint8Array(size));
            };
            Buffer.prototype.needSubarray = function () {
                if (this.buffer.subarray)
                    return;
                var newBuf = new Uint8Array(this.buffer.length);
                for (var i = 0; i < newBuf.length; ++i)
                    newBuf[i] = this.buffer[i];
                this.buffer = newBuf;
                this.imageData = null;
            };
            Buffer.prototype.read_number = function (offset, format, endian) {
                var v = 0;
                var b = this.buffer;
                var max = 0;
                var size = 1;
                if (endian == "le") {
                    switch (format) {
                        case "int8":
                            max = 127;
                        case "uint8":
                            v = b[offset];
                            break;
                        case "int16":
                            max = 32767;
                        case "uint16":
                            size = 2;
                            v = (b[offset + 1] << 8) + b[offset];
                            break;
                        case "int32":
                            max = 2147483647;
                        case "uint32":
                            size = 4;
                            v = b[offset + 3] * (1 << 24) + (b[offset + 2] << 16) + (b[offset + 1] << 8) + b[offset];
                            break;
                        default:
                            TDev.Util.userError(TDev.lf("unknown number format: {0}", format));
                    }
                }
                else if (endian == "be") {
                    switch (format) {
                        case "int8":
                            max = 127;
                        case "uint8":
                            v = b[offset];
                            break;
                        case "int16":
                            max = 32767;
                        case "uint16":
                            size = 2;
                            v = (b[offset] << 8) + b[offset + 1];
                            break;
                        case "int32":
                            max = 2147483647;
                        case "uint32":
                            size = 4;
                            v = b[offset] * (1 << 24) + (b[offset + 1] << 16) + (b[offset + 2] << 8) + b[offset + 3];
                            break;
                        default:
                            TDev.Util.userError(TDev.lf("unknown number format: {0}", format));
                    }
                }
                else {
                    TDev.Util.userError(TDev.lf("unknown number endian: {0}", endian));
                }
                if (offset < 0 || offset + size > b.length)
                    TDev.Util.userError(TDev.lf("offset outside of range: {0} (buffer length {1})", offset, b.length));
                if (v === undefined || isNaN(v))
                    return undefined;
                if (max && v > max)
                    v = v - max * 2 - 2;
                return v;
            };
            Buffer.prototype.write_number = function (value, offset, format, endian) {
                var v = value;
                var b = this.buffer;
                var min = 0;
                var max = 0;
                var size = 0;
                if (Math.floor(v) != v)
                    TDev.Util.userError(TDev.lf("number {0} is fractional", v));
                switch (format) {
                    case "int8":
                        size = 1;
                        min = -0x80;
                        max = 0x7f;
                        break;
                    case "uint8":
                        size = 1;
                        max = 0xff;
                        break;
                    case "int16":
                        size = 2;
                        min = -0x8000;
                        max = 0x7fff;
                        break;
                    case "uint16":
                        size = 2;
                        max = 0xffff;
                        break;
                    case "int32":
                        size = 4;
                        min = -0x80000000;
                        max = 0x7fffffff;
                        break;
                    case "uint32":
                        size = 4;
                        max = 0xffffffff;
                        break;
                    default:
                        TDev.Util.userError(TDev.lf("unknown number format: {0}", format));
                }
                if (v < min || v > max)
                    TDev.Util.userError(TDev.lf("number {0} is outside range of {1}", v, format));
                v |= 0;
                if (endian == "be") {
                    for (var i = size - 1; i >= 0; i--) {
                        b[offset + i] = (v & 0xff);
                        v >>= 8;
                    }
                }
                else if (endian == "le") {
                    for (var i = 0; i < size; ++i) {
                        b[offset + i] = (v & 0xff);
                        v >>= 8;
                    }
                }
                else {
                    TDev.Util.userError(TDev.lf("unknown number endian: {0}", endian));
                }
            };
            Buffer.prototype.set = function (index, value) {
                this.buffer[index] = value;
            };
            Buffer.prototype.at = function (index) {
                return this.buffer[index];
            };
            Buffer.prototype.count = function () {
                return this.buffer.length;
            };
            Buffer.prototype.sha256 = function () {
                return TDev.Random.sha256buffer(this.buffer);
            };
            Buffer.prototype.concat = function (other) {
                var r = Buffer.mk(this.count() + other.count());
                r.copy_from(0, this);
                r.copy_from(this.count(), other);
                return r;
            };
            Buffer.prototype.sub_buffer = function (start, length) {
                var len = this.count();
                start = TDev.Util.intBetween(0, start, len);
                length = TDev.Util.intBetween(0, length, len - start);
                if (start == 0 && length == len)
                    return this;
                this.needSubarray();
                return Buffer.fromTypedArray(this.buffer.subarray(start, start + length));
            };
            Buffer.prototype.fill_random = function () {
                TDev.Random.bytes(this.buffer);
            };
            Buffer.prototype.fill = function (value) {
                var buf = this.buffer;
                for (var i = 0; i < buf.length; ++i)
                    buf[i] = value;
            };
            Buffer.prototype.copy_from = function (target_offset, source) {
                var dst = this.buffer;
                var src = source.buffer;
                var len = Math.min(src.length, this.count() - target_offset);
                if (target_offset == 0)
                    for (var i = 0; i < len; ++i)
                        dst[i] = src[i];
                else
                    for (var i = 0; i < len; ++i)
                        dst[target_offset + i] = src[i];
            };
            Buffer.prototype.clone = function () {
                var res = Buffer.mk(this.count());
                res.copy_from(0, this);
                return res;
            };
            Buffer.prototype.to_string = function (encoding) {
                function hex(inp) {
                    var hexDigits = "0123456789abcdef";
                    var len = inp.length;
                    var res = "";
                    for (var i = 0; i < len; ++i) {
                        var v = inp[i];
                        res += hexDigits[(v >> 4) & 0xf] + hexDigits[v & 0xf];
                    }
                    return res;
                }
                function utf16(inp) {
                    if (inp.length & 1)
                        return undefined;
                    var len = inp.length;
                    var res = "";
                    for (var i = 0; i < len; i += 2)
                        res += String.fromCharCode(inp[i] | (inp[i + 1] << 8));
                    return res;
                }
                switch (encoding) {
                    case "base64":
                        return TDev.Util.base64EncodeBytes(this.buffer);
                    case "hex":
                        return hex(this.buffer);
                    case "binary":
                        return TDev.Util.uint8ArrayToString(this.buffer);
                    case "utf8":
                        return TDev.Util.fromUTF8Bytes(this.buffer);
                    case "utf16le":
                        return utf16(this.buffer);
                    default:
                        return undefined;
                }
            };
            return Buffer;
        })(RT.RTValue);
        RT.Buffer = Buffer;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Bits;
        (function (Bits) {
            function add_uint32(x, y) {
                return (x + y) >>> 0;
            }
            Bits.add_uint32 = add_uint32;
            function subtract_uint32(x, y) {
                return (x - y) >>> 0;
            }
            Bits.subtract_uint32 = subtract_uint32;
            function multiply_uint32(x, y) {
                return TDev.Util.intMult(x, y) >>> 0;
            }
            Bits.multiply_uint32 = multiply_uint32;
            function add_int32(x, y) {
                return (x + y) | 0;
            }
            Bits.add_int32 = add_int32;
            function subtract_int32(x, y) {
                return (x - y) | 0;
            }
            Bits.subtract_int32 = subtract_int32;
            function multiply_int32(x, y) {
                return TDev.Util.intMult(x, y) | 0;
            }
            Bits.multiply_int32 = multiply_int32;
            function and_uint32(x, y) {
                return (x & y) >>> 0;
            }
            Bits.and_uint32 = and_uint32;
            function or_uint32(x, y) {
                return (x | y) >>> 0;
            }
            Bits.or_uint32 = or_uint32;
            function and_int32(x, y) {
                return (x & y);
            }
            Bits.and_int32 = and_int32;
            function or_int32(x, y) {
                return (x | y);
            }
            Bits.or_int32 = or_int32;
            function xor_uint32(x, y) {
                return (x ^ y) >>> 0;
            }
            Bits.xor_uint32 = xor_uint32;
            function not_uint32(x) {
                return (~x) >>> 0;
            }
            Bits.not_uint32 = not_uint32;
            function shift_left_uint32(x, bits) {
                return (x << bits) >>> 0;
            }
            Bits.shift_left_uint32 = shift_left_uint32;
            function shift_right_uint32(x, bits) {
                return x >>> bits;
            }
            Bits.shift_right_uint32 = shift_right_uint32;
            function rotate_left_uint32(x, bits) {
                return ((x << bits) | (x >>> (32 - bits))) >>> 0;
            }
            Bits.rotate_left_uint32 = rotate_left_uint32;
            function rotate_right_uint32(x, bits) {
                return ((x >>> bits) | (x << (32 - bits))) >>> 0;
            }
            Bits.rotate_right_uint32 = rotate_right_uint32;
            function create_buffer(size) {
                return RT.Buffer.mk(size);
            }
            Bits.create_buffer = create_buffer;
            function string_to_buffer(s, encoding) {
                return RT.Buffer.fromString(s, encoding);
            }
            Bits.string_to_buffer = string_to_buffer;
            function divide_int32(x, y) {
                return Math.floor(x / y) | 0;
            }
            Bits.divide_int32 = divide_int32;
        })(Bits = RT.Bits || (RT.Bits = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Task = (function (_super) {
            __extends(Task, _super);
            function Task() {
                _super.apply(this, arguments);
                this._completed = false;
            }
            Task.prototype.completed = function () {
                return this._completed;
            };
            Task.prototype.setException = function (e) {
                this._exn = e;
                var q = this.consumeQueue();
                if (!q)
                    return;
                q.forEach(function (r) { return r.rt.quietlyHandleError(e, r.stackframe); });
            };
            Task.prototype.resume = function (v) {
                TDev.Util.assert(!this._completed);
                this._completed = true;
                this._value = v;
                this.runAwaiters();
            };
            Task.prototype.await = function (r) {
                var _this = this;
                if (this._exn) {
                    r.rt.quietlyHandleError(this._exn, r.stackframe);
                }
                else if (this._completed) {
                    r.rt.queueAsyncEvent(function () {
                        return r.rt.continueStackFrame(_this._value, r.stackframe);
                    });
                }
                else {
                    if (!this._awaitQueue)
                        this._awaitQueue = [r];
                    else
                        this._awaitQueue.push(r);
                }
            };
            Task.prototype.value = function () {
                if (!this._completed)
                    TDev.Util.userError(TDev.lf("cannot get value - task has not completed yet"));
                return this._value;
            };
            Task.prototype.await_at_most = function (seconds, r) {
                var _this = this;
                this.await(r);
                if (!this._completed) {
                    TDev.Util.setTimeout(seconds * 1000, function () {
                        if (_this._awaitQueue) {
                            var idx = _this._awaitQueue.indexOf(r);
                            if (idx >= 0) {
                                _this._awaitQueue.splice(idx, 1);
                                r.rt.queueAsyncEvent(function () {
                                    return r.rt.continueStackFrame(undefined, r.stackframe);
                                });
                            }
                        }
                    });
                }
            };
            Task.prototype.consumeQueue = function () {
                var q = this._awaitQueue;
                if (!q)
                    return null;
                this._awaitQueue = null;
                return q;
            };
            Task.prototype.runAwaiters = function () {
                var _this = this;
                var q = this.consumeQueue();
                if (!q)
                    return;
                q.forEach(function (r) {
                    r.rt.queueAsyncEvent(function () {
                        return r.rt.continueStackFrame(_this._value, r.stackframe);
                    });
                });
            };
            return Task;
        })(RT.RTValue);
        RT.Task = Task;
        var TaskResumeCtx = (function (_super) {
            __extends(TaskResumeCtx, _super);
            function TaskResumeCtx(task, s) {
                _super.call(this, s);
                this.task = task;
            }
            TaskResumeCtx.prototype.resumeCore = function (v) {
                this.task.resume(v);
            };
            TaskResumeCtx.prototype.isTaskCtx = function () {
                return true;
            };
            return TaskResumeCtx;
        })(TDev.ResumeCtx);
        RT.TaskResumeCtx = TaskResumeCtx;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Collection = (function (_super) {
            __extends(Collection, _super);
            function Collection(typeInfo) {
                _super.call(this);
                this.typeInfo = typeInfo;
                this.a = [];
            }
            Collection.mkAny = function (typeInfo, a) {
                if (a === void 0) { a = []; }
                return Collection.mk(typeInfo, a);
            };
            Collection.mk = function (a, typeInfo) {
                return Collection.fromArray(a, typeInfo);
            };
            Collection.mkStrings = function (a) {
                return Collection.fromArray(a, "string");
            };
            Collection.mkNumbers = function (a) {
                return Collection.fromArray(a, "number");
            };
            Collection.fromArray = function (a, typeInfo) {
                if (!a)
                    return undefined;
                var r = new Collection(typeInfo);
                r.a = a;
                return r;
            };
            Collection.prototype.get_enumerator = function () {
                return this.a.slice(0);
            };
            Collection.prototype.count = function () {
                return this.a.length;
            };
            Collection.prototype.clear = function () {
                this.a = [];
            };
            Collection.prototype.add = function (item) {
                this.a.push(item);
            };
            Collection.prototype.add_many = function (items) {
                this.a.pushRange(items.a.slice(0));
            };
            Collection.prototype.index_of = function (item, start) {
                if (TDev.Util.isOOB(start, this.count()))
                    return -1;
                for (var i = TDev.Util.indexCheck(start, this.count()); i < this.a.length; ++i)
                    if (this.a[i] === item)
                        return i;
                return -1;
            };
            Collection.prototype.at = function (index) {
                return this.a[Math.floor(index)];
            };
            Collection.prototype.contains = function (item) {
                var i = this.index_of(item, 0);
                return (i >= 0);
            };
            Collection.prototype.remove = function (item) {
                var i = this.index_of(item, 0);
                if (i >= 0) {
                    this.a.splice(i, 1);
                    return true;
                }
                else
                    return false;
            };
            Collection.prototype.remove_at = function (index) {
                if (TDev.Util.isOOB(index, this.count()))
                    return;
                this.a.splice(TDev.Util.indexCheck(index, this.count()), 1);
            };
            Collection.prototype.reverse = function () {
                this.a.reverse();
            };
            Collection.prototype.random = function () {
                return this.a.length == 0 ? undefined : this.at(RT.Math_.random(this.a.length));
            };
            Collection.prototype.set_at = function (index, item) {
                var _index = Math.floor(index);
                if (0 <= _index && index < this.a.length)
                    this.a[_index] = item;
            };
            Collection.prototype.insert_at = function (index, item) {
                if (TDev.Util.isOOB(index, this.count() + 1))
                    return;
                this.a.splice(TDev.Util.indexCheck(index, this.count() + 1), 0, item);
            };
            Collection.prototype.to_json = function (sf) {
                var ctx = new TDev.JsonExportCtx(sf);
                ctx.push(this);
                var json = this.exportJson(ctx);
                ctx.pop(this);
                return RT.JsonObject.wrap(json);
            };
            Collection.prototype.from_json = function (jobj, sf) {
                this.importJson(new TDev.JsonImportCtx(sf), jobj.value());
            };
            Collection.prototype.where = function (condition, s) {
                var rt = s.rt;
                return Collection.fromArray(this.a.filter(function (e) { return !!rt.runUserAction(condition, [e]); }), this.typeInfo);
            };
            Collection.prototype.map_to = function (converter, s, type_S) {
                var rt = s.rt;
                return Collection.fromArray(this.a.map(function (e) { return rt.runUserAction(converter, [e]); }), type_S);
            };
            Collection.prototype.sorted = function (comparison, s) {
                var rt = s.rt;
                return Collection.fromArray(this.a.stableSorted(function (a, b) { return rt.runValidUserAction(comparison, [a, b]); }), this.typeInfo);
            };
            Collection.prototype.ordered_by = function (key, s) {
                var rt = s.rt;
                return Collection.fromArray(this.a.stableSorted(function (a, b) {
                    return rt.runValidUserAction(key, [a]) - rt.runValidUserAction(key, [b]);
                }), this.typeInfo);
            };
            Collection.prototype.ordered_by_string = function (key, s) {
                var rt = s.rt;
                return Collection.fromArray(this.a.stableSorted(function (a, b) {
                    return rt.runValidUserAction(key, [a]).localeCompare(rt.runValidUserAction(key, [b]));
                }), this.typeInfo);
            };
            Collection.prototype.take = function (count, s) {
                return Collection.fromArray(this.a.slice(0, Math.floor(count)), this.typeInfo);
            };
            Collection.prototype.slice = function (start, end) {
                return Collection.fromArray(this.a.slice(Math.floor(start), Math.floor(end)), this.typeInfo);
            };
            Collection.prototype.first = function () {
                return this.at(0);
            };
            Collection.prototype.last = function () {
                return this.at(this.count() - 1);
            };
            Collection.prototype.jsonExportKey = function (ctx) {
                return null;
            };
            Collection.prototype.exportJson = function (ctx) {
                if (this.a.length > 0 && (this.a[0]["exportJson"] === undefined)) {
                    var a0 = this.a[0];
                    if (typeof a0 == "string" || typeof a0 == "number" || typeof a0 == "boolean") {
                    }
                    else
                        TDev.Util.userError(TDev.lf("json export is not supported for this type"));
                }
                return ctx.encodeArrayNode(this, this.a.slice(0));
            };
            Collection.prototype.importJson = function (ctx, json) {
                var _this = this;
                var prev = this.a;
                this.a = [];
                if (!Array.isArray(json))
                    return this;
                if (typeof this.typeInfo == "string") {
                    if (this.typeInfo === "number")
                        json.forEach(function (n) {
                            if (typeof n === "number")
                                _this.a.push(n);
                        });
                    else if (this.typeInfo === "string")
                        json.forEach(function (n) {
                            if (typeof n === "string")
                                _this.a.push(n);
                        });
                    else if (this.typeInfo === "boolean")
                        json.forEach(function (n) {
                            if (typeof n === "boolean")
                                _this.a.push(n);
                        });
                    else
                        TDev.Util.userError("json import is not supported for Collection of " + this.typeInfo);
                }
                else if (this.typeInfo instanceof RT.RecordSingleton) {
                    for (var n = 0; n < json.length; n++) {
                        var o = ctx.importRecord(json, prev[n], n, this.typeInfo);
                        if (o)
                            this.a.push(o);
                    }
                }
                else if (typeof this.typeInfo === "function") {
                    var ctor = this.typeInfo;
                    json.forEach(function (n) {
                        var v = new ctor();
                        v = v.importJson(ctx, n);
                        if (v)
                            _this.a.push(v);
                    });
                }
                else {
                    TDev.Util.userError("json import is not supported for this Collection");
                }
                return this;
            };
            Collection.prototype.getHtml = function () {
                var first = undefined;
                for (var i = 0; i < this.a.length; ++i)
                    if (this.a[i]) {
                        first = this.a[i];
                        break;
                    }
                var s = '[';
                for (var i = 0; i < this.a.length; ++i) {
                    if (i > 0)
                        s += ', ';
                    s += this.a[i];
                }
                s += ']';
                return TDev.span(null, s);
            };
            Collection.prototype.getRecord = function () {
                if (this.typeInfo instanceof RT.RecordSingleton)
                    return this.typeInfo;
                return null;
            };
            Collection.prototype.post_to_wall = function (s) {
                if (this.getRecord())
                    s.rt.postBoxedHtml(this.getRecord().getTable(this.a, s), s.pc);
                else if (this.typeInfo.prototype instanceof RT.RTValue)
                    this.a.forEach(function (v) { return v.post_to_wall(s); });
                else
                    s.rt.postBoxedHtml(this.getHtml(), s.pc);
            };
            Collection.prototype.debuggerDisplay = function (clickHandler) {
                var e;
                if (this.getRecord()) {
                    try {
                        e = this.getRecord().getTable(this.a, null);
                    }
                    catch (e) {
                        e = TDev.span(null, e.message || "");
                    }
                }
                else {
                    e = this.getHtml();
                }
                return e.withClick(clickHandler);
            };
            Collection.prototype.pick_entry = function (text, r) {
                var rt = r.rt;
                var getView = function (o) {
                    if (o.getIndexCard)
                        return o.getIndexCard(r.stackframe);
                    else if (o.getViewCore)
                        return o.getViewCore(r.stackframe, null);
                    else if (o.toString)
                        return o.toString();
                    else
                        return o + "";
                };
                var m = new TDev.ModalDialog();
                var chosen = null;
                var btns = this.a.map(function (o) { return TDev.div('modalDialogChooseItem', getView(o)).withClick(function () {
                    chosen = o;
                    m.dismiss();
                }); });
                m.add([TDev.div("wall-dialog-header", text)]);
                m.onDismiss = function () { return r.resumeVal(chosen); };
                m.choose(btns);
            };
            Collection.prototype.sum_of = function (key, s) {
                var rt = s.rt;
                var v = this.a.map(function (x) { return rt.runValidUserAction(key, [x]); });
                return TDev.Util.stableSum(v);
            };
            Collection.prototype.max_of = function (key, s) {
                var rt = s.rt;
                if (this.a.length == 0)
                    return undefined;
                var m = rt.runValidUserAction(key, [this.a[0]]);
                for (var i = 1; i < this.a.length; ++i) {
                    var v = rt.runValidUserAction(key, [this.a[i]]);
                    if (v > m)
                        m = v;
                }
                return m;
            };
            Collection.prototype.avg_of = function (key, s) {
                var rt = s.rt;
                if (this.a.length == 0)
                    return undefined;
                return this.sum_of(key, s) / this.count();
            };
            Collection.prototype.min_of = function (key, s) {
                var rt = s.rt;
                if (this.a.length == 0)
                    return undefined;
                var m = rt.runValidUserAction(key, [this.a[0]]);
                for (var i = 1; i < this.a.length; ++i) {
                    var v = rt.runValidUserAction(key, [this.a[i]]);
                    if (v < m)
                        m = v;
                }
                return m;
            };
            Collection.prototype.min = function () {
                var a = this.a;
                if (a.length == 0)
                    return undefined;
                return this.a.min();
            };
            Collection.prototype.max = function () {
                if (this.a.length == 0)
                    return undefined;
                var a = this.a;
                return a.max();
            };
            Collection.prototype.sum = function () {
                if (this.a.length == 0)
                    return 0;
                var a = this.a;
                return TDev.Util.stableSum(a);
            };
            Collection.prototype.avg = function () {
                if (this.a.length == 0)
                    return 0;
                return this.sum() / this.a.length;
            };
            Collection.prototype.sort_by_date = function () {
                this.a.sort(function (m1, m2) {
                    if (!m1.time())
                        return 1;
                    if (!m2.time())
                        return -1;
                    return m1.time().d.valueOf() < m2.time().d.valueOf() ? -1 : 1;
                });
            };
            Collection.prototype.sort = function () {
                this.a.sort();
            };
            Collection.prototype.sort_by_distance = function (loc) {
                var getLoc = function (l) {
                    if (l instanceof RT.Place)
                        return l.location();
                    return l;
                };
                this.a.sort(function (l, r) {
                    var lloc = getLoc(l);
                    var rloc = getLoc(r);
                    if (!lloc && !rloc)
                        return 0;
                    if (!lloc)
                        return 1;
                    if (!rloc)
                        return -1;
                    return rloc.distance(lloc) - lloc.distance(rloc);
                });
            };
            Collection.prototype.join = function (separator) {
                return this.a.join(separator);
            };
            Collection.prototype.continuation = function () {
                return this._continuation || "";
            };
            Collection.prototype.set_continuation = function (value) {
                this._continuation = value;
            };
            return Collection;
        })(RT.RTValue);
        RT.Collection = Collection;
        var StringCollection;
        (function (StringCollection) {
            function mk(v) {
                return Collection.mkStrings(v);
            }
            StringCollection.mk = mk;
            function fromArray(v) {
                return Collection.mkStrings(v);
            }
            StringCollection.fromArray = fromArray;
        })(StringCollection = RT.StringCollection || (RT.StringCollection = {}));
        var NumberCollection;
        (function (NumberCollection) {
            function mk(v) {
                return Collection.mkNumbers(v);
            }
            NumberCollection.mk = mk;
            function fromArray(v) {
                return Collection.mkNumbers(v);
            }
            NumberCollection.fromArray = fromArray;
        })(NumberCollection = RT.NumberCollection || (RT.NumberCollection = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var User = (function (_super) {
            __extends(User, _super);
            function User() {
                _super.call(this);
                this._id = undefined;
            }
            User.getJsonAsync = function (userId) {
                if (User.jsonCache.hasOwnProperty(userId))
                    return User.jsonCache[userId];
                var p;
                var m = /^([^:]*):(.*)/.exec(userId);
                if (m) {
                    if (m[1] == "td")
                        p = User.getJsonAsync(m[2]);
                    else if (m[1] == "live" && /^[^0-9a-f]+$/.test(m[2]))
                        p = TDev.Util.httpGetJsonAsync("https://apis.live.net/v5.0/" + m[2]).then(function (resp) {
                            return {
                                kind: "user",
                                id: userId,
                                name: resp.name
                            };
                        });
                    else
                        p = TDev.Promise.as({
                            kind: "user",
                            id: userId,
                        });
                }
                else {
                    p = TDev.Cloud.getPublicApiAsync(encodeURIComponent(userId));
                }
                User.jsonCache[userId] = p;
                return p;
            };
            User.prototype.getJsonAsync = function () {
                return User.getJsonAsync(this._id);
            };
            User.prototype.getApiUrl = function (path) {
                var ns = this.idNamespace();
                var id = this._id;
                if (ns == "td" || ns == "")
                    id = this._id.replace(/^[^:]+:/, "");
                else
                    return undefined;
                return TDev.Cloud.getServiceUrl() + "/api/" + encodeURIComponent(id) + path;
            };
            User.prototype.getPictureUrl = function (user, which) {
                return (user && user.haspicture) ? this.getApiUrl("/picture" + ((which && which != "original") ? ("?type=" + encodeURIComponent(which)) : "")) : undefined;
            };
            User.prototype.idNamespace = function () {
                var m = /^([^:]*):(.*)/.exec(this._id);
                if (m)
                    return m[1];
                else
                    return "";
            };
            User.prototype.toJsonKey = function () {
                return this._id;
            };
            User.prototype.keyCompareTo = function (o) {
                var other = o;
                return (this._id < other._id) ? -1 : (this._id > other._id) ? 1 : 0;
            };
            User.mk = function (id) {
                var u = new User();
                u._id = id;
                return u;
            };
            User.prototype.getShortStringRepresentation = function () {
                return this._id;
            };
            User.prototype.toString = function () {
                var s = "user /" + this._id;
                return s;
            };
            User.prototype.exportJson = function (ctx) {
                return this._id;
            };
            User.prototype.importJson = function (ctx, json) {
                TDev.Util.oops("should not call immutable instance for importing");
                return undefined;
            };
            User.mkFromJson = function (ctx, json) {
                if (typeof (json) !== "string")
                    return undefined;
                else {
                    return User.mk(json);
                }
            };
            User.prototype.equals = function (other) {
                return this._id == other._id;
            };
            User.prototype.id = function () {
                return this._id;
            };
            User.prototype.preload = function (r) {
                this.loadFirst(r, function (user) {
                });
            };
            User.prototype.name = function (r) {
                this.loadFirst(r, function (user) { return user ? user.name : undefined; });
            };
            User.prototype.about = function (r) {
                this.loadFirst(r, function (user) { return user ? user.about : undefined; });
            };
            User.prototype.has_picture = function (r) {
                this.loadFirst(r, function (user) { return user ? user.haspicture : undefined; });
            };
            User.prototype.settings = function (r) {
                var currentUserId = TDev.Cloud.getUserId();
                if (this._id != currentUserId) {
                    r.resumeVal(RT.Web.json("{}"));
                    return;
                }
                r.rt.host.askSourceAccessAsync("settings", "your twitter handle, github user or minecraft user.", false).then(function (allowed) {
                    if (!allowed)
                        return TDev.Promise.as(undefined);
                    else
                        return TDev.Cloud.getUserSettingsAsync().then(function (user) { return user ? RT.JsonObject.wrap({
                            twitterhandle: user.twitterhandle,
                            githubuser: user.githubuser,
                            minecraftuser: user.minecraftuser
                        }) : undefined; });
                }).done(function (se) { return r.resumeVal(se); });
            };
            User.prototype.picture_address = function (which, r) {
                var _this = this;
                this.loadFirst(r, function (user) { return _this.getPictureUrl(user, which); });
            };
            User.prototype.picture = function (which, r) {
                var _this = this;
                TDev.Util.assert(!!r);
                this.getJsonAsync().then(function (user) { return _this.getPictureUrl(user, which); }).then(function (url) { return url ? RT.Picture.fromUrl(url) : undefined; }).done(function (picture) { return r.resumeVal(picture); });
            };
            User.prototype.loadFirst = function (r, f) {
                TDev.Util.assert(!!r);
                this.getJsonAsync().done(function (user) {
                    if (!f)
                        r.resume();
                    else
                        r.resumeVal(f(user));
                }, function (e) {
                    if (!f)
                        r.resume();
                    else
                        r.resumeVal(f(undefined));
                });
            };
            User.prototype.getViewCore = function (s, b) {
                var _this = this;
                if (b === void 0) { b = null; }
                var elt = TDev.div("item", [TDev.div("wall-dialog-header", "user /" + this._id)]);
                this.getJsonAsync().then(function (user) {
                    if (user.kind == "user") {
                        elt.appendChildren(TDev.div("wall-dialog-body", "name: " + user.name));
                        if (user.haspicture) {
                            var img = TDev.createElement("img");
                            img.setAttribute('class', 'wall-picture');
                            img.src = _this.getPictureUrl(user, "large");
                            img.alt = user.name;
                            elt.appendChildren(img);
                        }
                    }
                    else
                        elt.appendChildren(TDev.div("wall-dialog-body", TDev.lf("invalid user id")));
                }, function (e) {
                    elt.appendChildren(TDev.div("wall-dialog-body", TDev.lf("further user information unavailable")));
                }).done();
                return elt;
            };
            User.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            User.jsonCache = {};
            return User;
        })(RT.RTValue);
        RT.User = User;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Ref = (function (_super) {
            __extends(Ref, _super);
            function Ref() {
                _super.call(this);
            }
            Ref.prototype._get = function (s) {
                return this._item;
            };
            Ref.prototype._confirmed = function (s) {
                return true;
            };
            Ref.prototype._set = function (t, s) {
                this._item = t;
            };
            Ref.prototype._clear = function (s) {
                this._set(undefined, s);
            };
            Ref.prototype._ref = function (s) {
                return this;
            };
            Ref.prototype._add = function (v, s) {
                this._set((this._get(s) + v), s);
            };
            Ref.prototype._test_and_set = function (v, s) {
                if (!this._get(s))
                    this._set(v, s);
            };
            Ref.prototype._with_notify = function (on_changed, s) {
                return new RefWithNotify(this, on_changed);
            };
            return Ref;
        })(RT.RTValue);
        RT.Ref = Ref;
        var GlobalVarRef = (function (_super) {
            __extends(GlobalVarRef, _super);
            function GlobalVarRef(d, fieldname) {
                _super.call(this);
                this.d = d;
                this.fieldname = fieldname;
            }
            GlobalVarRef.mk = function (d, fieldname) {
                return new GlobalVarRef(d, fieldname);
            };
            GlobalVarRef.prototype._set = function (v, s) {
                this.d[this.fieldname] = v;
            };
            GlobalVarRef.prototype._get = function (s) {
                return this.d[this.fieldname];
            };
            return GlobalVarRef;
        })(Ref);
        RT.GlobalVarRef = GlobalVarRef;
        var PersistedVarRef = (function (_super) {
            __extends(PersistedVarRef, _super);
            function PersistedVarRef(container, fieldname) {
                _super.call(this);
                this.container = container;
                this.fieldname = fieldname;
            }
            PersistedVarRef.mk = function (container, fieldname) {
                return new PersistedVarRef(container, fieldname);
            };
            PersistedVarRef.prototype._set = function (v, s) {
                this.container.perform_set(this.fieldname, v, s);
            };
            PersistedVarRef.prototype._get = function (s) {
                return this.container.perform_get(this.fieldname, s);
            };
            PersistedVarRef.prototype._clear = function (s) {
                this.container.perform_clear(this.fieldname, s);
            };
            PersistedVarRef.prototype._add = function (v, s) {
                this.container.perform_add(this.fieldname, v, s);
            };
            PersistedVarRef.prototype._test_and_set = function (v, s) {
                this.container.perform_test_and_set(this.fieldname, v, s);
            };
            PersistedVarRef.prototype._confirmed = function (s) {
                return this.container.perform_confirmed(this.fieldname);
            };
            return PersistedVarRef;
        })(Ref);
        RT.PersistedVarRef = PersistedVarRef;
        var FieldRef = (function (_super) {
            __extends(FieldRef, _super);
            function FieldRef(entry, fieldname) {
                _super.call(this);
                this.entry = entry;
                this.fieldname = fieldname;
            }
            FieldRef.mk = function (entry, fieldname) {
                return new FieldRef(entry, fieldname);
            };
            FieldRef.prototype._set = function (v, s) {
                this.entry.perform_set(this.fieldname, v, s);
            };
            FieldRef.prototype._get = function (s) {
                return this.entry.perform_get(this.fieldname, s);
            };
            FieldRef.prototype._clear = function (s) {
                this.entry.perform_clear(this.fieldname, s);
            };
            FieldRef.prototype._add = function (v, s) {
                this.entry.perform_add(this.fieldname, v, s);
            };
            FieldRef.prototype._test_and_set = function (v, s) {
                this.entry.perform_test_and_set(this.fieldname, v, s);
            };
            FieldRef.prototype._confirmed = function (s) {
                return this.entry.perform_confirmed(this.fieldname, s);
            };
            return FieldRef;
        })(Ref);
        RT.FieldRef = FieldRef;
        var RefWithNotify = (function (_super) {
            __extends(RefWithNotify, _super);
            function RefWithNotify(ref, on_changed) {
                _super.call(this);
                this.ref = ref;
                this.ev = new RT.Event_();
                this.ev.addHandler(on_changed);
            }
            RefWithNotify.prototype.notify = function (s) {
                s.rt.queueLocalEvent(this.ev, undefined, true, true);
            };
            RefWithNotify.prototype._set = function (v, s) {
                this.ref._set(v, s);
                this.notify(s);
            };
            RefWithNotify.prototype._get = function (s) {
                return this.ref._get(s);
            };
            RefWithNotify.prototype._clear = function (s) {
                this.ref._clear(s);
                this.notify(s);
            };
            RefWithNotify.prototype._add = function (v, s) {
                this.ref._add(v, s);
                this.notify(s);
            };
            RefWithNotify.prototype._test_and_set = function (v, s) {
                this.ref._test_and_set(v, s);
                this.notify(s);
            };
            RefWithNotify.prototype._confirmed = function (s) {
                return this.ref._confirmed(s);
            };
            return RefWithNotify;
        })(Ref);
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var AudioContextManager;
        (function (AudioContextManager) {
            var _context;
            var _vco;
            var _vca;
            function context() {
                if (!_context)
                    _context = freshContext();
                return _context;
            }
            function freshContext() {
                window.AudioContext = window.AudioContext || window.webkitAudioContext;
                if (window.AudioContext) {
                    try {
                        return new window.AudioContext();
                    }
                    catch (e) {
                    }
                }
                return undefined;
            }
            function stop() {
                if (_vca)
                    _vca.gain.value = 0;
            }
            AudioContextManager.stop = stop;
            function tone(frequency, gain) {
                if (frequency <= 0)
                    return;
                var ctx = context();
                if (!ctx)
                    return;
                gain = RT.Math_.normalize(gain);
                if (!_vco) {
                    try {
                        _vco = ctx.createOscillator();
                        _vca = ctx.createGain();
                        _vco.connect(_vca);
                        _vca.connect(ctx.destination);
                        _vca.gain.value = gain;
                        _vco.start(0);
                    }
                    catch (e) {
                        _vco = undefined;
                        _vca = undefined;
                        return;
                    }
                }
                _vco.frequency.value = frequency;
                _vca.gain.value = gain;
            }
            AudioContextManager.tone = tone;
            function isSupported() {
                return !!context();
            }
            AudioContextManager.isSupported = isSupported;
            function loadAsync(buffer) {
                var ctx = context();
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    ctx.decodeAudioData(buffer, function (b) { return onSuccess(b); }, function (e) { return onSuccess(undefined); });
                });
            }
            AudioContextManager.loadAsync = loadAsync;
            function play(buffer, volume) {
                var ctx = context();
                if (ctx) {
                    var source = ctx.createBufferSource();
                    source.buffer = buffer;
                    var gain = ctx.createGain();
                    gain.gain.value = volume;
                    source.connect(gain);
                    gain.connect(ctx.destination);
                    source.start(0);
                }
            }
            AudioContextManager.play = play;
            function createNode(ctx) {
                if (!ctx.createScriptProcessor)
                    return ctx.createJavaScriptNode(4096, 1, 1);
                else
                    return ctx.createScriptProcessor(4096, 1, 1);
            }
            function isMicrophoneSupported() {
                return isSupported() && RT.UserMediaManager.isSupported();
            }
            AudioContextManager.isMicrophoneSupported = isMicrophoneSupported;
            function recordMicrophoneAsync() {
                if (!isSupported())
                    return TDev.Promise.as(undefined);
                return RT.UserMediaManager.getMicrophoneStreamAsync().then(function (stream) {
                    if (!stream)
                        return TDev.Promise.as(undefined);
                    return new TDev.Promise(function (onSuccess, onError, onProgress) {
                        var ctx = freshContext();
                        if (!ctx) {
                            RT.App.log("failed to acquire AudioContext");
                            onSuccess(undefined);
                            return;
                        }
                        var source = ctx.createMediaStreamSource(stream);
                        var node = createNode(ctx);
                        var buffers = [];
                        var buffersLength = 0;
                        node.onaudioprocess = function (e) {
                            if (!buffers)
                                return;
                            var b = e.inputBuffer.getChannelData(0);
                            var clone = new Float32Array(b.length);
                            clone.set(b);
                            buffers.push(clone);
                            buffersLength += clone.length;
                        };
                        source.connect(node);
                        node.connect(ctx.destination);
                        var wav = undefined;
                        var m = new TDev.ModalDialog();
                        m.add(TDev.div('wall-dialog-header', TDev.lf("recording microphone...")));
                        m.add(TDev.div('wall-dialog-buttons', TDev.HTML.mkButton('done', function () {
                            source.disconnect();
                            source = null;
                            node.disconnect();
                            node.onaudioprocess = null;
                            node = null;
                            var wavBytes = encodeToWav(buffers, buffersLength, ctx.sampleRate);
                            wav = 'data:audio/wav;base64,' + TDev.Util.base64EncodeBytes(wavBytes);
                            m.dismiss();
                        })));
                        m.onDismiss = function () {
                            if (source) {
                                source.disconnect();
                                source = null;
                            }
                            if (node) {
                                node.disconnect();
                                node.onaudioprocess = null;
                                node = null;
                            }
                            ctx = null;
                            onSuccess(wav);
                        };
                        m.show();
                    });
                });
            }
            AudioContextManager.recordMicrophoneAsync = recordMicrophoneAsync;
            function encodeToWav(buffers, buffersLength, sampleRate) {
                var buffer = new ArrayBuffer(44 + buffersLength * 2);
                var view = new DataView(buffer);
                var offset = 0;
                function writeString(s) {
                    for (var i = 0; i < s.length; i++, offset++) {
                        view.setUint8(offset, s.charCodeAt(i));
                    }
                }
                function writeUint32(u) {
                    view.setUint32(offset, u, true);
                    offset += 4;
                }
                function writeUint16(u) {
                    view.setUint16(offset, u, true);
                    offset += 2;
                }
                function writePCM(buffer) {
                    for (var i = 0; i < buffer.length; i++, offset += 2) {
                        var s = Math.max(-1, Math.min(1, buffer[i]));
                        view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
                    }
                }
                var numChannels = 1;
                var bytesPerSample = 2;
                writeString('RIFF');
                writeUint32(36 + buffersLength * bytesPerSample);
                writeString('WAVE');
                writeString('fmt ');
                writeUint32(16);
                writeUint16(1);
                writeUint16(numChannels);
                writeUint32(sampleRate);
                writeUint32(sampleRate * bytesPerSample * numChannels);
                writeUint16(numChannels * bytesPerSample);
                writeUint16(bytesPerSample * 8);
                writeString('data');
                writeUint32(buffersLength * numChannels * bytesPerSample);
                for (var j = 0; j < buffers.length; ++j)
                    writePCM(buffers[j]);
                return new Uint8Array(buffer, 0, buffer.byteLength);
            }
        })(AudioContextManager = RT.AudioContextManager || (RT.AudioContextManager = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var SpriteSheet = (function (_super) {
            __extends(SpriteSheet, _super);
            function SpriteSheet(_board, _picture) {
                _super.call(this);
                this._board = _board;
                this._picture = _picture;
                this.frames = {};
                this.animations = {};
                this.empty = { x: 0, y: 0, width: 0, height: 0, rotated: false };
            }
            SpriteSheet.prototype.picture = function () {
                return this._picture;
            };
            SpriteSheet.prototype.set_frame = function (sprite, frame) {
                var f = this.frames[frame];
                sprite.setFrame(f || this.empty);
            };
            SpriteSheet.prototype.create_sprite = function (frame) {
                var sprite = this._board.mkSprite(3 /* Picture */, 1, 1);
                sprite.setSheet(this);
                this.set_frame(sprite, frame);
                return sprite;
            };
            SpriteSheet.prototype.set_frame_grid = function (rows, columns, frame_width, frame_height, margin_left, margin_top, spacing) {
                this.frames = [];
                if (rows < 1 || columns < 1)
                    return;
                rows = Math.floor(rows);
                columns = Math.floor(columns);
                var h = this._picture.heightSync();
                var w = this._picture.widthSync();
                var fw = frame_width > 0 ? frame_width : w / columns;
                var fh = frame_height > 0 ? frame_height : h / rows;
                var k = 1;
                var y = margin_top;
                for (var i = 0; i < rows; ++i) {
                    var x = margin_left;
                    for (var j = 0; j < columns; ++j) {
                        var name = (k++).toString();
                        this.add_frame(name, x, y, fw, fh, false);
                        x += fw + spacing;
                    }
                    y += fh + spacing;
                }
            };
            SpriteSheet.prototype.add_frame = function (name, x, y, width, height, rotated) {
                this.frames[name] = {
                    x: x,
                    y: y,
                    width: width,
                    height: height,
                    rotated: rotated
                };
            };
            SpriteSheet.prototype.findAnimation = function (name) {
                return this.animations[name];
            };
            SpriteSheet.prototype.add_grid_animation = function (name, start, count, duration, loops, yoyo) {
                var frs = [];
                start = Math.floor(start);
                count = Math.floor(count);
                if (count < 1)
                    return;
                var n = start + count;
                for (var i = start; i <= n; ++i)
                    frs.push(i.toString());
                if (frs.length > 0)
                    this.add_animation(name, RT.Collection.mkStrings(frs), duration, loops, yoyo);
            };
            SpriteSheet.prototype.add_animation = function (name, frames, duration, loops, yoyo) {
                if (duration <= 0)
                    duration = frames.count() * 1 / 30.0;
                this.animations[name] = {
                    frames: frames.a.slice(0),
                    duration: Math.max(0.02, duration),
                    loopCount: Math.floor(loops),
                    yoyo: yoyo
                };
            };
            SpriteSheet.prototype.getDebugCanvas = function () {
                var _this = this;
                var picCanvas = this._picture.getCanvas();
                var canvas = document.createElement("canvas");
                canvas.width = picCanvas.width;
                canvas.height = picCanvas.height;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(picCanvas, 0, 0);
                ctx.strokeStyle = "blue";
                ctx.lineWidth = 1;
                ctx.font = "1em Arial";
                var keys = Object.keys(this.frames);
                keys.forEach(function (key) {
                    var frame = _this.frames[key];
                    ctx.strokeRect(frame.x, frame.y, frame.width, frame.height);
                    ctx.fillText(key, frame.x + 4, frame.y + 12);
                });
                return canvas;
            };
            SpriteSheet.prototype.getViewCore = function (s, b) {
                return this.getDebugCanvas();
            };
            SpriteSheet.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return SpriteSheet;
        })(RT.RTValue);
        RT.SpriteSheet = SpriteSheet;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var SpriteAnimation = (function (_super) {
            __extends(SpriteAnimation, _super);
            function SpriteAnimation(_sprite) {
                _super.call(this);
                this._sprite = _sprite;
                this._tweens = [];
                this._tweenIndex = 0;
                this._t = -1;
                this._timeScale = 1;
                this.isActive = true;
            }
            SpriteAnimation.prototype.pushTween = function (apply, easing, duration) {
                this.ensureActive();
                if (this._tweens.length > 0 && this._tweens[this._tweens.length - 1].repeat < 0)
                    TDev.Util.userError(TDev.lf("the previous animation repeats forever"));
                var tween = { apply: apply, easing: easing, duration: Math.max(duration, 0), repeat: 1, yoyo: false, reversed: false };
                this._tweens.push(tween);
                return tween;
            };
            SpriteAnimation.prototype.ensureActive = function () {
                if (!this.isActive)
                    TDev.Util.userError(TDev.lf("trying to chain a tween that has already stopped"));
            };
            SpriteAnimation.resolveEasing = function (name, shape) {
                var e = SpriteAnimation.easing[name.toLowerCase().replace(' ', '')] || SpriteAnimation.easing['cubic'];
                return e[shape.toLowerCase().replace(' ', '')] || e['inout'];
            };
            SpriteAnimation.prototype.time_scale = function () {
                return this._timeScale;
            };
            SpriteAnimation.prototype.set_time_scale = function (scale) {
                this._timeScale = scale;
            };
            SpriteAnimation.prototype.move_to = function (duration, easing, shape, x, y) {
                var oldx = this._sprite.x();
                var oldy = this._sprite.y();
                var dx = x - oldx;
                var dy = y - oldy;
                var tw = this.pushTween(function (rt, sprite, k) {
                    sprite.set_pos(oldx + k * dx, oldy + k * dy);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
                tw.init = function (sp) {
                    oldx = sp.x();
                    oldy = sp.y();
                    dx = x - oldx;
                    dy = y - oldy;
                };
            };
            SpriteAnimation.prototype.text = function (duration, easing, shape, value) {
                var oldtext = this._sprite.text() || "";
                var oldnumber = parseInt(oldtext);
                var newnumber = parseInt(value);
                if (!isNaN(newnumber) && (!isNaN(oldnumber) || !oldnumber)) {
                    if (isNaN(oldnumber))
                        oldnumber = 0;
                    var d = newnumber - oldnumber;
                    this.pushTween(function (rt, sprite, k) {
                        sprite.set_text(RT.Math_.round(oldnumber + k * d).toString());
                    }, SpriteAnimation.resolveEasing(easing, shape), duration);
                }
                else {
                    var n = Math.max(oldtext.length, value.length);
                    var s = oldtext;
                    this.pushTween(function (rt, sprite, k) {
                        var i = Math.floor(k * n);
                        var c = value[i] || "";
                        s = (value.substring(0, i) || "") + +(oldtext.substring(i) || "");
                        sprite.set_text(s);
                    }, SpriteAnimation.resolveEasing(easing, shape), duration);
                }
            };
            SpriteAnimation.prototype.color = function (duration, easing, shape, c) {
                var old = this._sprite.color();
                var tw = this.pushTween(function (rt, sprite, k) {
                    var onek = 1 - k;
                    sprite.set_color(RT.Color.fromArgb(old.a * k + c.a * onek, old.r * k + c.r * onek, old.g * k + c.g * onek, old.b * k + c.b * onek));
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
                tw.init = function (sprite) {
                    old = sprite.color();
                };
            };
            SpriteAnimation.prototype.beat = function (duration, cycle, value) {
                this.scale(duration, 'quadratic', 'inout', value);
                this.repeat(cycle * 2, true);
            };
            SpriteAnimation.prototype.scale = function (duration, easing, shape, value) {
                var current = 1.0;
                this.pushTween(function (rt, sprite, k) {
                    sprite.set_scale(current * (1 - k) + k * value);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
            };
            SpriteAnimation.prototype.width = function (duration, easing, shape, value) {
                var current = this._sprite.width();
                this.pushTween(function (rt, sprite, k) {
                    sprite.set_width(current * (1 - k) + k * value);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
            };
            SpriteAnimation.prototype.height = function (duration, easing, shape, value) {
                var current = this._sprite.height();
                this.pushTween(function (rt, sprite, k) {
                    sprite.set_height(current * (1 - k) + k * value);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
            };
            SpriteAnimation.prototype.fork = function () {
                var anim = this._sprite.createAnimation();
                this.pushTween(function (rt, sprite, k) {
                    sprite.startAnimation(anim);
                }, SpriteAnimation.easing['linear']['in'], 0);
                return anim;
            };
            SpriteAnimation.prototype.wait = function (r) {
                var _this = this;
                var board = this._sprite._parent;
                var boardTick = board.tick;
                if (!board) {
                    r.resume();
                    return;
                }
                RT.App.allow_other_events(r.stackframe);
                var step = function () {
                    r.rt.yield_now();
                    if (boardTick != board.tick) {
                        boardTick = board.tick;
                        board.evolve();
                        board.update_on_wall();
                    }
                    if (!_this.isActive)
                        r.resume();
                    else
                        TDev.Util.setTimeout(100, step);
                };
                step();
            };
            SpriteAnimation.prototype.wait_for = function (animation) {
                var tween = this.pushTween(function (rt, sprite, k) {
                    if (!animation.isActive)
                        tween.duration = -1;
                }, SpriteAnimation.easing['linear']['in'], 1e6);
            };
            SpriteAnimation.prototype.stop = function () {
                this._tweenIndex = this._tweens.length;
                this._t = 0;
            };
            SpriteAnimation.prototype.repeat = function (count, yoyo) {
                this.ensureActive();
                if (this._tweens.length > 0) {
                    var tween = this._tweens[this._tweens.length - 1];
                    tween.repeat = count;
                    tween.yoyo = yoyo;
                    tween.reversed = false;
                }
            };
            SpriteAnimation.prototype.on_start = function (body) {
                if (!this._onStart)
                    this._onStart = new RT.Event_();
                return this._onStart.addHandler(body);
            };
            SpriteAnimation.prototype.on_stop = function (body) {
                this.ensureActive();
                if (!this._onStop)
                    this._onStop = new RT.Event_();
                return this._onStop.addHandler(body);
            };
            SpriteAnimation.prototype.sleep = function (duration) {
                this.pushTween(function (rt, sprite, x) {
                }, SpriteAnimation.easing['linear']['in'], duration);
            };
            SpriteAnimation.prototype.fade_in = function (duration, easing) {
                var old = this._sprite.opacity();
                var tw = this.pushTween(function (rt, sprite, value) {
                    sprite.set_opacity(old * (1 - value) + value);
                }, SpriteAnimation.resolveEasing(easing, 'in'), duration);
                tw.init = function (sprite) {
                    old = sprite.opacity();
                };
            };
            SpriteAnimation.prototype.fade_out = function (duration, easing) {
                var old = this._sprite.opacity();
                var tw = this.pushTween(function (rt, sprite, value) {
                    sprite.set_opacity(old * (1 - value));
                }, SpriteAnimation.resolveEasing(easing, 'out'), duration);
                tw.init = function (sprite) {
                    old = sprite.opacity();
                };
            };
            SpriteAnimation.prototype.fade = function (duration, easing, shape, opacity) {
                var old = this._sprite.opacity();
                opacity = RT.Math_.normalize(opacity);
                var tw = this.pushTween(function (rt, sprite, value) {
                    sprite.set_opacity(old * (1 - value) + opacity * value);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
                tw.init = function (sprite) {
                    old = sprite.opacity();
                };
            };
            SpriteAnimation.prototype.puff_out = function (duration, easing, scale) {
                var oldop = this._sprite.opacity();
                var oldscale = this._sprite.scale();
                var tw = this.pushTween(function (rt, sprite, value) {
                    sprite.set_opacity(oldop * (1 - value));
                    sprite.set_scale(oldscale * (1 - value) + value * scale);
                }, SpriteAnimation.resolveEasing(easing, 'out'), duration);
                tw.init = function (sprite) {
                    oldop = sprite.opacity();
                    oldscale = sprite.scale();
                };
            };
            SpriteAnimation.prototype.hide = function () {
                this.pushTween(function (rt, sprite, value) {
                    sprite.hide();
                }, SpriteAnimation.easing['linear']['in'], 0);
            };
            SpriteAnimation.prototype.show = function () {
                this.pushTween(function (rt, sprite, value) {
                    sprite.show();
                }, SpriteAnimation.easing['linear']['in'], 0);
            };
            SpriteAnimation.prototype.delete_ = function () {
                this.pushTween(function (rt, sprite, value) {
                    sprite.delete_();
                }, SpriteAnimation.easing['linear']['in'], 0);
            };
            SpriteAnimation.prototype.play_sound = function (sound) {
                this.pushTween(function (rt, sprite, value) {
                    sound.playAsync().done();
                }, SpriteAnimation.easing['linear']['in'], 0);
            };
            SpriteAnimation.prototype.frame = function (name) {
                var sheet = this._sprite.sheet();
                if (sheet)
                    this.pushTween(function (rt, sprite, value) {
                        sheet.set_frame(sprite, name);
                    }, SpriteAnimation.easing['linear']['in'], 0);
            };
            SpriteAnimation.prototype.play_frames = function (animation) {
                var sheet = this._sprite.sheet();
                if (sheet) {
                    var data = sheet.findAnimation(animation);
                    if (data) {
                        this.pushTween(function (rt, sprite, x) {
                            sheet.set_frame(sprite, data.frames[Math.floor(x * (data.frames.length - 1))]);
                        }, SpriteAnimation.resolveEasing('linear', 'in'), data.duration);
                        this.repeat(data.loopCount, data.yoyo);
                    }
                }
            };
            SpriteAnimation.prototype.turn_to = function (duration, easing, shape, angle) {
                var old = this._sprite.angle();
                var tw = this.pushTween(function (rt, sprite, value) {
                    sprite.set_angle(old * value + (1 - value) * angle);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
                tw.init = function (sp) {
                    old = sp.angle();
                };
            };
            SpriteAnimation.prototype.run = function (duration, easing, shape, handler) {
                var ev = new RT.Event_();
                ev.addHandler(handler);
                this.pushTween(function (rt, sprite, x) {
                    rt.queueLocalEvent(ev, [x], false);
                }, SpriteAnimation.resolveEasing(easing, shape), duration);
            };
            SpriteAnimation.prototype.initTween = function (tween) {
                if (tween && tween.init) {
                    tween.init(this._sprite);
                    delete tween.init;
                }
            };
            SpriteAnimation.prototype.evolve = function (rt, dT) {
                if (!this.isActive)
                    return false;
                if (this._t < 0 && this._onStart && this._onStart.handlers)
                    rt.queueLocalEvent(this._onStart, [], false);
                var tween = this._tweens[this._tweenIndex];
                this._t = this._t < 0 ? 0 : this._t + dT * this._timeScale;
                while (tween && this._t > tween.duration) {
                    this.initTween(tween);
                    tween.apply(rt, this._sprite, tween.reversed ? 0 : 1);
                    this._t = tween.duration < 0 ? 0 : this._t - tween.duration;
                    if (tween.repeat == 0)
                        tween = this._tweens[++this._tweenIndex];
                    else if (tween.repeat > 0 && --tween.repeat == 0)
                        tween = this._tweens[++this._tweenIndex];
                    else if (tween.yoyo)
                        tween.reversed = !tween.reversed;
                }
                if (tween) {
                    var x = tween.easing(this._t / tween.duration);
                    this.initTween(tween);
                    tween.apply(rt, this._sprite, tween.reversed ? 1 - x : x);
                    return true;
                }
                else {
                    if (this._onStop && this._onStop.handlers)
                        rt.queueLocalEvent(this._onStop, [], false);
                    return this.isActive = false;
                }
            };
            SpriteAnimation.prototype.is_active = function () {
                return this.isActive;
            };
            SpriteAnimation.prototype.getViewCore = function (s, b) {
                return TDev.div('item', 'tween');
            };
            SpriteAnimation.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            SpriteAnimation.easing = {
                linear: {
                    in: function (x) {
                        return x;
                    },
                    out: function (x) {
                        return x;
                    },
                    inout: function (x) {
                        return x;
                    },
                },
                quadratic: {
                    in: function (x) {
                        return x * x;
                    },
                    out: function (x) {
                        return x * (2 - x);
                    },
                    inout: function (x) {
                        return (x *= 2) < 1 ? x * x / 2 : (1 - (--x) * (x - 2)) / 2;
                    },
                },
                cubic: {
                    in: function (x) {
                        return x * x * x;
                    },
                    out: function (x) {
                        --x;
                        return 1 + x * x * x;
                    },
                    inout: function (x) {
                        return (x *= 2) < 1 ? x * x * x / 2 : ((x -= 2) * x * x + 2) / 2;
                    }
                },
                sine: {
                    in: function (x) {
                        return 1 - Math.cos(x * Math.PI / 2);
                    },
                    out: function (x) {
                        return Math.sin(x * Math.PI / 2);
                    },
                    inout: function (x) {
                        return (1 - Math.cos(Math.PI * x)) / 2;
                    },
                },
                expo: {
                    in: function (x) {
                        return x == 0 ? 0 : Math.pow(1024, x - 1);
                    },
                    out: function (x) {
                        return x == 1 ? 1 : 1 - Math.pow(2, -10 * x);
                    },
                    inout: function (x) {
                        return x == 0 ? 0 : x == 1 ? 1 : (x *= 2) < 1 ? Math.pow(1024, x - 1) / 2 : 1 - Math.pow(2, -10 * (x - 1)) / 2;
                    },
                },
            };
            return SpriteAnimation;
        })(RT.RTValue);
        RT.SpriteAnimation = SpriteAnimation;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var BoardBackgroundScene = (function (_super) {
            __extends(BoardBackgroundScene, _super);
            function BoardBackgroundScene(_board) {
                _super.call(this);
                this._board = _board;
                this._offsetX = 0;
                this._offsetY = 0;
                this._layers = [];
            }
            BoardBackgroundScene.prototype.view_x = function () {
                return this._offsetX;
            };
            BoardBackgroundScene.prototype.set_view_x = function (x) {
                if (!isNaN(x))
                    this._offsetX = x;
            };
            BoardBackgroundScene.prototype.view_y = function () {
                return this._offsetY;
            };
            BoardBackgroundScene.prototype.set_view_y = function (y) {
                if (!isNaN(y))
                    this._offsetY = y;
            };
            BoardBackgroundScene.prototype.sortLayers = function () {
                this._layers.sort(function (a, b) { return b.distance() - a.distance(); });
            };
            BoardBackgroundScene.prototype.create_layer = function (distance, pic, r) {
                var _this = this;
                pic.loadFirst(r, function () {
                    var layer = new BoardBackgroundLayer(_this, distance, pic);
                    _this._layers.push(layer);
                    _this.sortLayers();
                    return layer;
                });
            };
            BoardBackgroundScene.prototype.count = function () {
                return this._layers.length;
            };
            BoardBackgroundScene.prototype.at = function (index) {
                return this._layers[Math.floor(index)];
            };
            BoardBackgroundScene.prototype.clear = function () {
                this._layers = [];
                this._offsetX = this._offsetY = 0;
            };
            BoardBackgroundScene.prototype.render = function (w, h, ctx) {
                var _this = this;
                this._layers.forEach(function (layer) {
                    var ox = Math.round(_this._offsetX / (1 + layer.distance()));
                    var oy = Math.round(_this._offsetY / (1 + layer.distance()));
                    layer.render(w, h, ctx, ox, oy);
                });
            };
            BoardBackgroundScene.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return BoardBackgroundScene;
        })(RT.RTValue);
        RT.BoardBackgroundScene = BoardBackgroundScene;
        var BoardBackgroundLayer = (function (_super) {
            __extends(BoardBackgroundLayer, _super);
            function BoardBackgroundLayer(_scene, _distance, _pic) {
                _super.call(this);
                this._scene = _scene;
                this._distance = _distance;
                this._pic = _pic;
                this._repeatX = true;
                this._repeatY = true;
                this._alignX = BoardBackgroundLayer.ARRANGE_LEFT;
                this._alignY = BoardBackgroundLayer.ARRANGE_TOP;
            }
            BoardBackgroundLayer.prototype.picture = function () {
                return this._pic;
            };
            BoardBackgroundLayer.prototype.distance = function () {
                return this._distance;
            };
            BoardBackgroundLayer.prototype.set_distance = function (d) {
                if (isNaN(d))
                    d = 0;
                var d = Math.max(0, d);
                if (this._distance != d) {
                    this._distance = d;
                    this._scene.sortLayers();
                }
            };
            BoardBackgroundLayer.prototype.align_x = function () {
                return this._alignX;
            };
            BoardBackgroundLayer.prototype.set_align_x = function (align) {
                switch (align.trim().toLowerCase()) {
                    case "left":
                        this._alignX = BoardBackgroundLayer.ARRANGE_LEFT;
                        break;
                    case "right":
                        this._alignX = BoardBackgroundLayer.ARRANGE_RIGHT;
                        break;
                    case "center":
                        this._alignX = BoardBackgroundLayer.ARRANGE_CENTER;
                        break;
                }
            };
            BoardBackgroundLayer.prototype.align_y = function () {
                return this._alignY;
            };
            BoardBackgroundLayer.prototype.set_align_y = function (align) {
                switch (align.trim().toLowerCase()) {
                    case "center":
                        this._alignY = BoardBackgroundLayer.ARRANGE_LEFT;
                        break;
                    case "top":
                        this._alignY = BoardBackgroundLayer.ARRANGE_TOP;
                        break;
                    case "bottom":
                        this._alignY = BoardBackgroundLayer.ARRANGE_BOTTOM;
                        break;
                }
            };
            BoardBackgroundLayer.prototype.repeat_x = function () {
                return this._repeatX;
            };
            BoardBackgroundLayer.prototype.set_repeat_x = function (repeat) {
                this._repeatX = !!repeat;
            };
            BoardBackgroundLayer.prototype.repeat_y = function () {
                return this._repeatY;
            };
            BoardBackgroundLayer.prototype.set_repeat_y = function (repeat) {
                this._repeatY = !!repeat;
            };
            BoardBackgroundLayer.prototype.render = function (w, h, ctx, offsetX, offsetY) {
                var p = this._pic.getCanvas();
                var pw = p.width;
                var ph = p.height;
                if (!pw || !ph)
                    return;
                var rx = -offsetX;
                var ry = -offsetY;
                switch (this._alignX) {
                    case BoardBackgroundLayer.ARRANGE_RIGHT:
                        rx -= (w + pw);
                        break;
                    case BoardBackgroundLayer.ARRANGE_CENTER:
                        rx -= (w + pw) / 2;
                        break;
                }
                switch (this._alignY) {
                    case BoardBackgroundLayer.ARRANGE_BOTTOM:
                        ry -= (h + ph);
                        break;
                    case BoardBackgroundLayer.ARRANGE_CENTER:
                        ry -= (h + ph) / 2;
                        break;
                }
                rx %= w;
                if (rx < 0)
                    rx += w;
                ry %= h;
                if (ry < 0)
                    ry += h;
                rx = Math.floor(rx);
                ry = Math.floor(ry);
                var renderEdge = !TDev.Browser.isWebkit;
                var y = 0;
                var py = 0;
                while (y < h) {
                    py = y % ph;
                    var dh = Math.min(ph - py, h - ry);
                    var x = 0;
                    while (x < w) {
                        var px = x % pw;
                        var dw = Math.min(pw - px, w - rx);
                        try {
                            ctx.drawImage(p, px, py, dw, dh, rx, ry, dw, dh);
                            if (renderEdge) {
                                if (this._repeatX)
                                    ctx.drawImage(p, px, py, 2, dh, rx - 1, ry, 2, dh);
                                if (this._repeatY)
                                    ctx.drawImage(p, px, py, dw, 2, rx, ry - 1, dw, 2);
                            }
                        }
                        catch (e) {
                            TDev.Util.log('scene: ' + JSON.stringify({
                                w: w,
                                h: h,
                                pw: pw,
                                ph: ph,
                                dw: dw,
                                dh: dh,
                                x: x,
                                y: y,
                                px: px,
                                py: py,
                                rx: rx,
                                ry: ry,
                                edge: renderEdge
                            }));
                            TDev.Util.reportError('backgroundScene', e, false);
                            return;
                        }
                        rx = (rx + dw) % w;
                        x += this._repeatX ? dw : w;
                    }
                    ry = (ry + dh) % h;
                    y += this._repeatY ? dh : h;
                }
            };
            BoardBackgroundLayer.ARRANGE_LEFT = 1;
            BoardBackgroundLayer.ARRANGE_RIGHT = 2;
            BoardBackgroundLayer.ARRANGE_TOP = 3;
            BoardBackgroundLayer.ARRANGE_BOTTOM = 4;
            BoardBackgroundLayer.ARRANGE_CENTER = 5;
            return BoardBackgroundLayer;
        })(RT.RTValue);
        RT.BoardBackgroundLayer = BoardBackgroundLayer;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Tutorial;
        (function (Tutorial) {
            function step_completed(s) {
                s.rt.forceNonRender();
                var st = s.rt.tutorialState;
                if (!st)
                    st = s.rt.tutorialState = {};
                st.validated = true;
                s.rt.host.notifyTutorial("stepCompleted");
            }
            Tutorial.step_completed = step_completed;
            function show_hint(message, r) {
                var m = new TDev.ModalDialog();
                m.add([TDev.div("wall-dialog-header", TDev.lf("tutorial hint")), RT.Wall.body(message), TDev.div("wall-dialog-buttons", [TDev.HTML.mkButtonOnce("ok", function () { return m.dismiss(); })])]);
                m.onDismiss = function () { return r.resume(); };
                m.show();
            }
            Tutorial.show_hint = show_hint;
        })(Tutorial = RT.Tutorial || (RT.Tutorial = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ServerRequest = (function (_super) {
            __extends(ServerRequest, _super);
            function ServerRequest() {
                _super.apply(this, arguments);
                this._headers = new RT.StringMap();
                this._querystring = new RT.StringMap();
                this._content = undefined;
            }
            ServerRequest.mk = function (req, _proxy) {
                var r = new ServerRequest();
                r._id = TDev.Random.uniqueId(12);
                r._headers = RT.StringMap.mk(req.headers);
                r._querystring = RT.StringMap.mk(req.tdQueryString);
                r._req = req;
                r._startTime = Date.now();
                var proto = "http";
                if (_proxy)
                    proto = "ws";
                if (req.headers['x-forwarded-proto'] === 'https' || req.headers['x-arr-ssl'] || req.connection.encrypted)
                    proto = "https";
                r._url = proto + "://" + (req.headers.host || "unknown") + req.url;
                r._response = new RT.ServerResponse(r, _proxy);
                return r;
            };
            ServerRequest.prototype.startHandle = function () {
                this._startHandleTime = Date.now();
                this.log(this.toString());
            };
            ServerRequest.prototype.stopHandle = function () {
                var n = Date.now();
                var t0 = (n - this._startHandleTime) / 1000;
                var t1 = (this._startHandleTime - this._startTime) / 1000;
                if (this._onStop !== undefined) {
                    this._onStop.success(true);
                }
                this.log(TDev.Util.fmt("status={0} [{1}s prep, {2}s exec]", this._response.status_code(), t1, t0));
            };
            ServerRequest.prototype.log = function (msg) {
                RT.App.log("[req:" + this._id + (this._user ? ":" + this._user.id() : "") + "] " + msg);
            };
            ServerRequest.prototype.getNodeRequest = function () {
                return this._req;
            };
            ServerRequest.prototype.recvContentAsync = function () {
                var _this = this;
                var r = new TDev.PromiseInv();
                var contentType = this.header("content-type") || "application/octet-stream";
                contentType = contentType.replace(/;.*/, "");
                var isJson = /application\/json/i.test(contentType);
                this._isText = /^text\//.test(contentType) || isJson;
                var req = this._req;
                if (this._isText) {
                    var acc = "";
                    req.setEncoding("utf8");
                    req.on("data", function (buf) { return acc += buf; });
                    req.on("end", function () {
                        _this._content = acc;
                        if (isJson) {
                            var obj = RT.JsonObject.mk(_this._content, RT.Time.log);
                            _this._jsonBody = obj.value();
                        }
                        r.success(null);
                    });
                }
                else {
                    var bufs = [];
                    var len = 0;
                    req.on("data", function (buf) {
                        bufs.push(buf);
                        len += buf.length;
                    });
                    req.on("end", function () {
                        var bf = new Uint8Array(len);
                        var pos = 0;
                        bufs.forEach(function (buf) {
                            for (var i = 0; i < buf.length; ++i)
                                bf[pos++] = buf[i];
                        });
                        _this._content = RT.Buffer.fromTypedArray(bf);
                        r.success(null);
                    });
                }
                return r;
            };
            ServerRequest.prototype.getRestArgument = function (name, tp, s) {
                if (tp == "Server Request")
                    return this;
                if (tp == "Server Response")
                    return this.response();
                var v = this.query(name);
                if (v === undefined && this._jsonBody)
                    v = this._jsonBody[name];
                if (v === undefined)
                    return undefined;
                return TDev.Runtime.fromRestArgument(v, tp, s);
            };
            ServerRequest.prototype.response = function () {
                return this._response;
            };
            ServerRequest.prototype.content = function () {
                if (typeof this._content == "string")
                    return this._content;
                return undefined;
            };
            ServerRequest.prototype.content_as_buffer = function () {
                if (this._content instanceof RT.Buffer)
                    return this._content;
                return undefined;
            };
            ServerRequest.prototype.content_as_json = function () {
                if (this._jsonBody)
                    return RT.JsonObject.wrap(this._jsonBody);
                return undefined;
            };
            ServerRequest.prototype.method = function () {
                return this._req.method.toLowerCase();
            };
            ServerRequest.prototype.url = function () {
                return this._url;
            };
            ServerRequest.prototype.api_path = function () {
                return this._req.tdApiPath;
            };
            ServerRequest.prototype.header = function (name) {
                return this._headers.at(name.toLowerCase());
            };
            ServerRequest.prototype.query = function (name) {
                return this._querystring.at(name);
            };
            ServerRequest.prototype.equals = function (other) {
                return this == other;
            };
            ServerRequest.prototype.toString = function () {
                return this.method() + " " + this.url();
            };
            ServerRequest.prototype.post_to_wall = function (s) {
                var rt = s.rt;
                if (this._content && this._content.length)
                    rt.postBoxedText("Content-Length: " + this._content.length, s.pc);
                var keys = this._headers.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var key = keys.at(i);
                    rt.postBoxedText(keys.at(i) + ": " + this._headers.at(key), s.pc);
                }
                rt.postBoxedText(this.toString(), s.pc);
            };
            ServerRequest.prototype.header_names = function () {
                return this._headers.keys();
            };
            ServerRequest.prototype.query_names = function () {
                return this._querystring.keys();
            };
            ServerRequest.prototype.setJsonBody = function (json) {
                this._jsonBody = json;
            };
            ServerRequest.prototype.user = function () {
                return this._user;
            };
            return ServerRequest;
        })(RT.RTValue);
        RT.ServerRequest = ServerRequest;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var ServerResponse = (function (_super) {
            __extends(ServerResponse, _super);
            function ServerResponse(_request, _proxy) {
                _super.call(this);
                this._request = _request;
                this._proxy = _proxy;
                this._headers = new RT.StringMap();
                this._statusCode = 200;
            }
            ServerResponse.prototype.header = function (name) {
                return this._headers.at(name);
            };
            ServerResponse.prototype.set_header = function (name, value) {
                if (!value)
                    this._headers.remove(name.toLowerCase());
                else
                    this._headers.set_at(name.toLowerCase(), value);
            };
            ServerResponse.prototype.request = function () {
                return this._request;
            };
            ServerResponse.prototype.status_code = function () {
                return this._statusCode;
            };
            ServerResponse.prototype.set_status_code = function (code) {
                this._statusCode = code;
            };
            ServerResponse.prototype.equals = function (other) {
                return this == other;
            };
            ServerResponse.prototype.toString = function () {
                return "Response to " + this._request.toString();
            };
            ServerResponse.prototype.post_to_wall = function (s) {
                var rt = s.rt;
                if (this._content && this._content.length)
                    rt.postBoxedText("Content-Length: " + this._content.length, s.pc);
                var keys = this._headers.keys();
                for (var i = 0; i < keys.count(); ++i) {
                    var key = keys.at(i);
                    rt.postBoxedText(keys.at(i) + ": " + this._headers.at(key), s.pc);
                }
                rt.postBoxedText(this.toString(), s.pc);
            };
            ServerResponse.prototype.set_content_type = function (type) {
                this._headers.set_at("Content-Type", type);
            };
            ServerResponse.prototype.set_content = function (content) {
                this._content = content;
                this.set_content_type("text/plain; charset=utf-8");
            };
            ServerResponse.prototype.set_content_as_json = function (json) {
                this.set_content(json.toString());
                this.set_content_type("application/json; charset=utf-8");
            };
            ServerResponse.prototype.set_content_as_buffer = function (bytes) {
                this._content = bytes.toNodeBuffer();
                this.set_content_type("application/octet-stream");
            };
            ServerResponse.prototype.set_content_as_xml = function (xml) {
                this.set_content(xml.toString());
                this.set_content_type("text/xml; charset=utf-8");
            };
            ServerResponse.prototype.header_names = function () {
                return this._headers.keys();
            };
            ServerResponse.prototype.addRestResult = function (name, v) {
                if (!this._restResult)
                    this._restResult = {};
                this._restResult[name] = TDev.Runtime.toRestArgument(v, this._request._stackframe);
            };
            ServerResponse.prototype.sendNow = function () {
                var resp = this.request().getNodeRequest().tdResponse;
                var headers = this._headers.items;
                var data = this._content;
                if (this._proxy) {
                    return this._proxy.success(this._restResult || {});
                }
                if (data == undefined && this.request().header("TouchDevelop-Accept") == "text/plain") {
                    if (!headers["content-type"])
                        headers["content-type"] = "text/plain";
                    data = TDev.Util.values(this._restResult || {}).map(function (v) { return v + ""; }).join(";");
                }
                else if (data === undefined) {
                    var format = parseInt(this.request().query("x-td-format") || "0");
                    format = TDev.Util.between(0, format, 8);
                    if (format)
                        data = JSON.stringify(this._restResult || {}, null, format);
                    else
                        data = JSON.stringify(this._restResult || {});
                    if (!headers["content-type"])
                        headers["content-type"] = "application/json; charset=utf-8";
                }
                else {
                    if (this._restResult)
                        TDev.Util.userError(TDev.lf("set_content_... cannot be called on the response object when function has result(s)"));
                }
                if (typeof data == "string")
                    data = ServerResponse.toUtfBuffer(data);
                if (!headers["content-length"])
                    headers["content-length"] = data.length;
                resp.writeHead(this._statusCode, headers);
                resp.end(data);
                this.request().stopHandle();
            };
            return ServerResponse;
        })(RT.RTValue);
        RT.ServerResponse = ServerResponse;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var EditorServices;
        (function (EditorServices) {
            function getTokenAsync(aud) {
                if (!TDev.Cloud.hasAccessToken())
                    return TDev.Promise.as(undefined);
                var tokens;
                try {
                    tokens = JSON.parse(localStorage["touchDevelopTokens"]);
                }
                catch (e) {
                    tokens = {};
                }
                var token = tokens[aud];
                if (token)
                    return TDev.Promise.as(token);
                var url = "https://touchdevelopuserauth.azurewebsites.net/api/sign_token?aud=" + encodeURIComponent(aud) + "&access_token=" + TDev.Cloud.getAccessToken();
                return TDev.Util.httpPostJsonAsync(url, {}).then(function (resp) {
                    if (!resp.jwt)
                        TDev.Util.oops(resp ? resp.status : "bad");
                    return resp.jwt;
                }).then(function (token) {
                    if (token) {
                        tokens[aud] = token;
                        localStorage["touchDevelopTokens"] = JSON.stringify(tokens);
                    }
                    return token;
                }, function (e) { return undefined; });
            }
            EditorServices.getTokenAsync = getTokenAsync;
        })(EditorServices = RT.EditorServices || (RT.EditorServices = {}));
        var Editor = (function (_super) {
            __extends(Editor, _super);
            function Editor(rt, headless) {
                _super.call(this);
                this.allAnnotations = [];
                rt.headlessPluginMode = headless;
                rt.editorObj = this;
            }
            Editor.prototype.progress = function (message, s) {
                TDev.ProgressOverlay.setProgress(message);
            };
            Editor.prototype.annotate_ast = function (id, category, message) {
                this.allAnnotations.push({ id: id, category: category, message: message });
            };
            Editor.prototype.annotate_caller = function (category, message, s) {
                var ed = TDev.TheEditor;
                if (ed)
                    ed.injectCallerAnnotation(category, message, s);
            };
            Editor.prototype.current_script_id = function (s) {
                return s.rt.runningPluginOn;
            };
            Editor.prototype.current_script_ast = function (r) {
                RT.Bazaar.ast_of(this.current_script_id(r.stackframe), r);
            };
            Editor.prototype.tutorial_step_completed = function (s) {
                RT.Tutorial.step_completed(s);
            };
            Editor.prototype.deployment_settings = function (r) {
                r.rt.host.deploymentSettingsAsync(r.rt.runningPluginOn).done(function (ds) { return r.resumeVal(ds ? RT.JsonObject.wrap(ds) : undefined); });
            };
            Editor.prototype.user_token = function (app_name, r) {
                if (TDev.Cloud.anonMode(TDev.lf("user token"))) {
                    r.resumeVal("");
                    return;
                }
                if (!app_name || app_name.length < 4)
                    TDev.Util.userError(TDev.lf("app name must be at least 4 character long"));
                var userid = TDev.Cloud.getUserId();
                var pluginid = TDev.lf("{0} - {1}", app_name, userid);
                if (!r.rt.host.askSourceAccessAsync("a user token for " + pluginid, "an authentication token for the `" + pluginid + "` application. The token allows this script to authenticate you in their services. The script does not have access to any other personal information.", true)) {
                    r.resumeVal("");
                    return;
                }
                EditorServices.getTokenAsync(pluginid).done(function (token) { return r.resumeVal(token); });
            };
            Editor.prototype.package_current_script = function (options, r) {
                var id = this.current_script_id(r.stackframe);
                if (!id) {
                    r.resumeVal(undefined);
                    return;
                }
                TDev.HTML.showProgressNotification(TDev.lf("packaging script..."), true);
                r.rt.host.packageScriptAsync(id, options.value()).done(function (instr) { return r.resumeVal(RT.JsonObject.wrap(instr)); }, function (err) { return r.resumeVal(RT.JsonObject.wrap({ error: err.message || "an error occured" })); });
            };
            return Editor;
        })(RT.RTValue);
        RT.Editor = Editor;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Create;
        (function (Create) {
            function Collection_of(s, type_T) {
                return new RT.Collection(type_T);
            }
            Create.Collection_of = Collection_of;
            function Ref_of(s, type_T) {
                var r = new RT.Ref();
                if (type_T == "string")
                    r._set("", s);
                else if (type_T == "number")
                    r._set(0, s);
                else if (type_T == "boolean")
                    r._set(false, s);
                return r;
            }
            Create.Ref_of = Ref_of;
        })(Create = RT.Create || (RT.Create = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var WebSocketMessage = (function (_super) {
            __extends(WebSocketMessage, _super);
            function WebSocketMessage() {
                _super.call(this);
            }
            WebSocketMessage.mk = function (data) {
                var msg = new WebSocketMessage();
                if (typeof data == "string")
                    msg.stringData = data;
                else
                    msg.binaryData = data;
                return msg;
            };
            WebSocketMessage.mkError = function (err) {
                var msg = new WebSocketMessage();
                msg.err = err;
                return msg;
            };
            WebSocketMessage.prototype.is_error = function () {
                return !!this.err;
            };
            WebSocketMessage.prototype.error = function () {
                return this.err;
            };
            WebSocketMessage.prototype.string = function () {
                return this.stringData;
            };
            WebSocketMessage.prototype.json = function () {
                if (!this.stringData)
                    return undefined;
                if (!this._json)
                    this._json = RT.JsonObject.mk(this.stringData);
                return this._json;
            };
            WebSocketMessage.prototype.buffer = function () {
                if (this.binaryData instanceof RT.Buffer)
                    return this.binaryData;
                if (this.binaryData instanceof ArrayBuffer) {
                    this.binaryData = RT.Buffer.fromTypedArray(new Uint8Array(this.binaryData));
                    return this.binaryData;
                }
                return undefined;
            };
            WebSocketMessage.prototype.toString = function () {
                if (this.err)
                    return "error: " + this.err;
                if (this.binaryData && this.binaryData.toString)
                    return this.binaryData.toString();
                return JSON.stringify(this.stringData);
            };
            WebSocketMessage.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return WebSocketMessage;
        })(RT.RTValue);
        RT.WebSocketMessage = WebSocketMessage;
        var WebSocket_ = (function (_super) {
            __extends(WebSocket_, _super);
            function WebSocket_(ws, rt) {
                _super.call(this, rt);
                this.ws = ws;
                this.msgs = [];
            }
            WebSocket_.prototype.dispose = function () {
                this.close();
                _super.prototype.dispose.call(this);
            };
            WebSocket_.mk = function (ws, rt) {
                var w = new WebSocket_(ws, rt);
                w.attachEvents();
                return w;
            };
            WebSocket_.prototype.attachEvents = function () {
                var _this = this;
                this.ws.addEventListener("error", function (ev) {
                    RT.App.logEvent(RT.App.DEBUG, "ws", "error: " + ev.message, undefined);
                    _this.receiveMessage(WebSocketMessage.mkError(ev.message));
                }, false);
                this.ws.addEventListener("message", function (ev) {
                    _this.receiveMessage(WebSocketMessage.mk(ev.data));
                }, false);
                this.ws.addEventListener("close", function (ev) {
                    _this.gotClose();
                }, false);
            };
            WebSocket_.prototype.gotClose = function () {
                var closeMsg = WebSocketMessage.mkError("closed");
                while (this.msgs[0] && !(this.msgs[0] instanceof WebSocketMessage)) {
                    this.receiveMessage(closeMsg);
                }
            };
            WebSocket_.prototype.receiveMessage = function (msg) {
                var r = this.msgs[0];
                if (r && !(r instanceof WebSocketMessage)) {
                    this.msgs.shift()(msg);
                }
                else
                    this.msgs.push(msg);
            };
            WebSocket_.prototype.close = function () {
                this.ws.close();
            };
            WebSocket_.prototype.ready_state = function () {
                var rs = this.ws.readyState;
                switch (rs) {
                    case 0: return "connecting";
                    case 1: return "open";
                    case 2: return "closing";
                    case 3: return "closed";
                    default: return rs.toString();
                }
            };
            WebSocket_.prototype.buffered_amount = function () {
                return this.ws.bufferedAmount;
            };
            WebSocket_.prototype.receive = function (r) {
                var d = this.msgs[0];
                if (d && d instanceof WebSocketMessage)
                    r.resumeVal(this.msgs.shift());
                else if (this.ready_state() == "closed")
                    r.resumeVal(WebSocketMessage.mkError("closed"));
                else
                    this.msgs.push(function (msg) { return r.resumeVal(msg); });
            };
            WebSocket_.prototype.sendPacket = function (d) {
                try {
                    this.ws.send(d);
                }
                catch (e) {
                    RT.App.logEvent(RT.App.DEBUG, "ws", "error: send" + e.message, undefined);
                    this.receiveMessage(WebSocketMessage.mkError(e));
                }
            };
            WebSocket_.prototype.send = function (msg) {
                this.sendPacket(msg);
            };
            WebSocket_.prototype.send_json = function (json) {
                this.send(JSON.stringify(json ? json.value() : null));
            };
            WebSocket_.prototype.send_buffer = function (buf) {
                this.sendPacket(buf.buffer);
            };
            WebSocket_.prototype.toString = function () {
                return this.ready_state() + " " + this.ws.url;
            };
            WebSocket_.prototype.post_to_wall = function (s) {
                _super.prototype.post_to_wall.call(this, s);
            };
            return WebSocket_;
        })(RT.RTDisposableValue);
        RT.WebSocket_ = WebSocket_;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Document_ = (function (_super) {
            __extends(Document_, _super);
            function Document_() {
                _super.call(this);
                this._url = undefined;
            }
            Document_.fromArtUrl = function (url) {
                var doc = new Document_();
                doc._url = url;
                return TDev.Promise.as(doc);
            };
            Document_.prototype.docs_render = function (caption) {
            };
            Document_.prototype.url = function () {
                return this._url;
            };
            return Document_;
        })(RT.RTValue);
        RT.Document_ = Document_;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var RecordEntry = (function (_super) {
            __extends(RecordEntry, _super);
            function RecordEntry() {
                _super.call(this);
            }
            RecordEntry.prototype.rtType = function () {
                return this.parent.rtType() + "$entry";
            };
            RecordEntry.prototype.noMagicRtType = function () {
                return true;
            };
            RecordEntry.prototype.equals = function (other) {
                return this === other;
            };
            RecordEntry.prototype.invalidate = function () {
                this.isDeleted = true;
                this.clear_fields();
                this.decorators = undefined;
            };
            RecordEntry.prototype.getShortStringRepresentation = function () {
                return "[" + this.parent.entryKindName + "]";
            };
            RecordEntry.prototype.post_to_wall = function (frame) {
                frame.rt.postBoxedHtml(this.parent.getTable([this], frame), frame.pc);
            };
            RecordEntry.prototype.to_json = function (s) {
                var ctx = new TDev.JsonExportCtx(s);
                ctx.push(this);
                var json = this.exportJson(ctx);
                ctx.pop(this);
                return RT.JsonObject.wrap(json);
            };
            RecordEntry.prototype.from_json = function (jobj, s) {
                this.parent.logMutation(s);
                this.importJsonFields(new TDev.JsonImportCtx(s), jobj.value());
            };
            RecordEntry.prototype.importJsonFields = function (ctx, jobj) {
                TDev.Util.oops("compiled code is supposed to override this method");
            };
            RecordEntry.prototype.jsonExportKey = function (ctx) {
                return null;
            };
            RecordEntry.prototype.exportJson = function (ctx) {
                var _this = this;
                if (this.is_deleted())
                    return undefined;
                var keys = this.fields.map(function (k) { return _this[k + "_realname"]; });
                var vals = this.fields.map(function (k) { return _this.getFieldValue(k, ctx.stackframe); });
                return ctx.encodeObjectNode(this, keys, vals);
            };
            RecordEntry.prototype.getIndexCard = function (sf) {
                var _this = this;
                var div = document.createElement("div");
                div.className = "wall-record";
                var hr = document.createElement("h3");
                hr.textContent = this.parent.entryKindName;
                hr.className = "wall-record";
                div.appendChild(hr);
                if (this.is_deleted()) {
                    var p = document.createElement("p");
                    p.className = "wall-record";
                    p.textContent = "(deleted)";
                    div.appendChild(p);
                }
                else {
                    var ul = document.createElement("ul");
                    ul.className = "wall-record";
                    this.fields.forEach(function (k) {
                        var name = _this[k + "_realname"];
                        var val = _this.getFieldValue(k, sf);
                        var s = name + ": ";
                        if (val instanceof RT.RTValue)
                            s = s + val.getShortStringRepresentation();
                        else if (typeof val !== "undefined")
                            s = s + val;
                        var li = document.createElement("li");
                        li.className = "wall-record";
                        li.textContent = s;
                        ul.appendChild(li);
                    });
                    div.appendChild(ul);
                }
                return div;
            };
            RecordEntry.prototype.debuggerDisplay = function (clickHandler) {
                var full;
                try {
                    full = this.getIndexCard(null);
                }
                catch (e) {
                    return TDev.span(null, e.message || "").withClick(clickHandler);
                }
                var sized = TDev.div("wall-record", this.parent.entryKindName);
                var fullDisplay = false;
                var updateButton = function () {
                    full.style.display = fullDisplay ? "block" : "none";
                    sized.style.display = fullDisplay ? "none" : "block";
                };
                updateButton();
                return TDev.div(null, sized, full).withClick(function () {
                    clickHandler();
                    updateButton();
                    fullDisplay = !fullDisplay;
                });
            };
            RecordEntry.prototype.debuggerChildren = function () {
                var _this = this;
                if (this.is_deleted())
                    return undefined;
                var r = {};
                this.fields.forEach(function (k) {
                    var val = _this.getFieldValue(k, undefined);
                    r[_this[k + "_realname"]] = val;
                });
                return r;
            };
            RecordEntry.prototype.getFieldValue = function (fieldname, sf) {
                return this[fieldname];
            };
            RecordEntry.prototype.getTableHeader = function () {
                var _this = this;
                var tr = document.createElement("tr");
                this.fields.forEach(function (k) {
                    var th = document.createElement("th");
                    th.setAttribute("scope", "col");
                    th.textContent = _this[k + "_realname"];
                    tr.appendChild(th);
                });
                return tr;
            };
            RecordEntry.prototype.getTableRow = function (sf) {
                var _this = this;
                var tr = document.createElement("tr");
                this.fields.forEach(function (k) {
                    var td = document.createElement("td");
                    var val = _this.getFieldValue(k, sf);
                    td.textContent = (val instanceof RT.RTValue) ? val.getShortStringRepresentation() : ((typeof val === "undefined") ? "" : val);
                    tr.appendChild(td);
                });
                return tr;
            };
            RecordEntry.prototype.clear_fields = function (s) {
                var _this = this;
                if (s)
                    this.parent.logMutation(s);
                this.values.forEach(function (k) {
                    delete _this[k];
                });
            };
            RecordEntry.prototype.is_deleted = function () {
                return false;
            };
            RecordEntry.prototype.confirmed = function () {
                return true;
            };
            RecordEntry.prototype.perform_get = function (fieldname, s) {
                return TDev.Util.abstract();
            };
            RecordEntry.prototype.perform_set = function (fieldname, value, s) {
                return TDev.Util.abstract();
            };
            RecordEntry.prototype.perform_confirmed = function (fieldname, s) {
                return true;
            };
            RecordEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                return TDev.Util.abstract();
            };
            RecordEntry.prototype.perform_add = function (fieldname, value, s) {
                return TDev.Util.abstract();
            };
            RecordEntry.prototype.perform_clear = function (fieldname, s) {
                return TDev.Util.abstract();
            };
            return RecordEntry;
        })(RT.RTValue);
        RT.RecordEntry = RecordEntry;
        var TableEntry = (function (_super) {
            __extends(TableEntry, _super);
            function TableEntry() {
                _super.call(this);
            }
            TableEntry.prototype.toJsonKey = function () {
                return this.rownumber;
            };
            TableEntry.prototype.jsonExportKey = function (ctx) {
                return this.rownumber.toString();
            };
            TableEntry.prototype.getShortStringRepresentation = function () {
                return "[" + this.parent.entryKindName + this.rownumber + "]";
            };
            TableEntry.prototype.delete_row = function (s) {
                this.parent.logMutation(s);
                if (this.isDeleted)
                    return;
                var idx = this.parent._elements.indexOf(this);
                if (idx >= 0)
                    this.parent._elements.splice(idx, 1);
                this.invalidate();
                this.parent.clearCachedData();
            };
            TableEntry.prototype.perform_get = function (fieldname, s) {
                this.is_deleted();
                return this[fieldname];
            };
            TableEntry.prototype.perform_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted) {
                    if (value == undefined)
                        delete this[fieldname];
                    else
                        this[fieldname] = value;
                }
            };
            TableEntry.prototype.perform_add = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted && value)
                    this[fieldname] += value;
            };
            TableEntry.prototype.perform_clear = function (fieldname, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted)
                    delete this[fieldname];
            };
            TableEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted && !this[fieldname] && value)
                    this[fieldname] = value;
            };
            TableEntry.prototype.is_deleted = function () {
                var _this = this;
                if (this.isDeleted)
                    return true;
                var deleted = false;
                if (this.keys.length > 0) {
                    this.keys.forEach(function (k) {
                        if (deleted)
                            return;
                        var key = _this[k];
                        if (((key instanceof TableEntry) && key.is_deleted()) || ((key instanceof CloudTableEntry) && key.is_deleted()))
                            deleted = true;
                    });
                }
                if (deleted && !this.isDeleted) {
                    this.invalidate();
                }
                return deleted;
            };
            TableEntry.prototype.keyCompareTo = function (other) {
                return this.rownumber - other.rownumber;
            };
            return TableEntry;
        })(RecordEntry);
        RT.TableEntry = TableEntry;
        var CloudTableEntry = (function (_super) {
            __extends(CloudTableEntry, _super);
            function CloudTableEntry() {
                _super.call(this);
            }
            CloudTableEntry.prototype.toJsonKey = function () {
                return this.sessionname + this.uid;
            };
            CloudTableEntry.prototype.equals = function (other) {
                var o = other;
                return this.uid === o.uid && this.sessionname === o.sessionname;
            };
            CloudTableEntry.prototype.getShortStringRepresentation = function () {
                return "[" + this.parent.entryKindName + ": " + this.uid + "]";
            };
            CloudTableEntry.prototype.hookup = function (item) {
                this.sessionname = item.session.servername;
                this.uid = item.uid;
                this.item = item;
                item.backlink = this;
                this.read_cloud_fields(item);
            };
            CloudTableEntry.prototype.unlink = function () {
                this.decorators = undefined;
                this.item = undefined;
                for (var i = 0; i < this.values.length; i++) {
                    this[this.values[i]] = undefined;
                }
            };
            CloudTableEntry.prototype.getFieldValue = function (fieldname, s) {
                this.check();
                var f = this[fieldname];
                if (f instanceof TDev.Revisions.LVal)
                    return Conv.read(this.parent.session(), f, s);
                else
                    return f;
            };
            CloudTableEntry.prototype.check = function (abort) {
                if (abort === void 0) { abort = true; }
                if (this.sessionname !== this.parent.session().servername) {
                    if (abort)
                        TDev.Util.userError(TDev.lf("stale row: originated in a different session"));
                    else
                        return false;
                }
                if (this.item === undefined || this.item.backlink != this || this.item.session !== this.parent.session()) {
                    var session = this.parent.session();
                    var item = session.user_get_item(this.uid);
                    if (item === undefined)
                        item = session.user_create_tombstone(this.parent.cloudtype, this.uid, this.keys.map(function (k) { return undefined; }), []);
                    this.hookup(item);
                }
                return true;
            };
            CloudTableEntry.prototype.confirmed = function () {
                var _this = this;
                this.check();
                var session = this.parent.session();
                var confirmed = this.existenceConfirmed() && !this.values.some(function (val) { return !session.user_is_datum_confirmed(_this[val]); });
                return confirmed;
            };
            CloudTableEntry.prototype.existenceConfirmed = function () {
                var _this = this;
                return this.parent.session().user_is_datum_confirmed(this.item) && !this.keys.some(function (key) {
                    var r = _this[key];
                    return (r && r instanceof CloudTableEntry && !r.existenceConfirmed());
                });
            };
            CloudTableEntry.prototype.jsonExportKey = function (ctx) {
                this.check();
                var uid = this.uid;
                if (uid.indexOf(".") === -1) {
                    var membernumber = this.parent.session().membernumber.toString();
                    if (membernumber === "-1")
                        membernumber = "";
                    uid = membernumber + "." + uid;
                }
                return uid;
            };
            CloudTableEntry.prototype.delete_row = function (s) {
                if (s)
                    this.parent.logMutation(s);
                this.check();
                this.parent.session().user_delete_item(this.item);
                this.parent.clearCachedData();
            };
            CloudTableEntry.prototype.clear_fields = function (s) {
                if (s)
                    this.parent.logMutation(s);
                this.check();
                for (var i = 0; i < this.values.length; i++) {
                    var lval = this[this.values[i]];
                    Conv.clear(this.parent.session(), lval);
                }
            };
            CloudTableEntry.prototype.perform_get = function (fieldname, s) {
                this.check();
                return Conv.read(this.parent.session(), this[fieldname], s);
            };
            CloudTableEntry.prototype.perform_confirmed = function (fieldname) {
                this.check();
                return this.parent.session().user_is_datum_confirmed(this[fieldname]);
            };
            CloudTableEntry.prototype.perform_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, false);
            };
            CloudTableEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, true);
            };
            CloudTableEntry.prototype.perform_add = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, true);
            };
            CloudTableEntry.prototype.perform_clear = function (fieldname, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], undefined, false);
            };
            CloudTableEntry.prototype.is_deleted = function () {
                if (!this.check())
                    return true;
                return this.parent.session().user_is_datum_deleted(this.item);
            };
            CloudTableEntry.prototype.keyCompareTo = function (other) {
                return this.item.compareTo(other.item);
            };
            CloudTableEntry.prototype.read_cloud_fields = function (datum) {
                var lkeycount = 0;
                var ukeycount = 0;
                TDev.Util.assert(this.parent.key_cloudtypes.length === this.keys.length);
                for (var i = 0; i < this.keys.length; i++) {
                    var keytype = this.parent.key_cloudtypes[i];
                    var val;
                    if (keytype.charAt(keytype.length - 1) === ")") {
                        var uid = datum.ukeys[ukeycount];
                        var linkedtable = this.parent.linked_cloudtables[ukeycount];
                        val = linkedtable.import_item_from_uid(uid);
                        ukeycount += 1;
                    }
                    else {
                        val = Conv.fromCloud(keytype, datum.lkeys[lkeycount]);
                        lkeycount += 1;
                    }
                    this[this.keys[i]] = val;
                }
                TDev.Util.assert(this.parent.value_cloudtypes.length === this.values.length);
                for (var i = 0; i < this.values.length; i++) {
                    var property = this.parent.value_cloudtypes[i];
                    this[this.values[i]] = this.parent.session().user_get_lval(property, [this.uid], []);
                }
            };
            return CloudTableEntry;
        })(RecordEntry);
        RT.CloudTableEntry = CloudTableEntry;
        var IndexEntry = (function (_super) {
            __extends(IndexEntry, _super);
            function IndexEntry() {
                _super.call(this);
                this.isDeleted = false;
            }
            IndexEntry.prototype.compareTo = function (other) {
                var _this = this;
                var diff = 0;
                this.keys.forEach(function (k) {
                    if (!diff) {
                        var a = _this[k];
                        var b = other[k];
                        switch (typeof a) {
                            case "string":
                                diff = a.localeCompare(b);
                                break;
                            case "number":
                                diff = a - b;
                                break;
                            case "boolean":
                                if (a !== b)
                                    diff = (a ? 1 : -1);
                                break;
                            default:
                                diff = RT.RTValue.CompareKeys(a, b);
                                break;
                        }
                    }
                });
                return diff;
            };
            IndexEntry.prototype.is_deleted = function () {
                var _this = this;
                if (this.isDeleted)
                    return true;
                var deleted = false;
                if (this.keys.length > 0) {
                    this.keys.forEach(function (k) {
                        if (deleted)
                            return;
                        var key = _this[k];
                        if (key && key instanceof TableEntry) {
                            if (key.is_deleted())
                                deleted = true;
                        }
                    });
                }
                if (deleted && !this.isDeleted) {
                    this.invalidate();
                }
                return deleted;
            };
            IndexEntry.prototype.perform_get = function (fieldname, s) {
                this.is_deleted();
                return this[fieldname];
            };
            IndexEntry.prototype.perform_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted) {
                    if (value == undefined)
                        delete this[fieldname];
                    else
                        this[fieldname] = value;
                }
            };
            IndexEntry.prototype.perform_add = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted && value)
                    this[fieldname] += value;
            };
            IndexEntry.prototype.perform_clear = function (fieldname, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted)
                    delete this[fieldname];
            };
            IndexEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                if (!this.isDeleted && !this[fieldname] && value)
                    this[fieldname] = value;
            };
            IndexEntry.prototype.hasNondefaultValue = function () {
                var _this = this;
                var found = false;
                this.values.forEach(function (v) {
                    if (found)
                        return;
                    var val = _this[v];
                    if (val) {
                        if (typeof val !== "object")
                            found = true;
                        else {
                            TDev.Util.assert(val instanceof RT.RTValue);
                            found = !val.isDefaultValue();
                        }
                    }
                });
                return found;
            };
            return IndexEntry;
        })(RecordEntry);
        RT.IndexEntry = IndexEntry;
        var ObjectEntry = (function (_super) {
            __extends(ObjectEntry, _super);
            function ObjectEntry() {
                _super.call(this);
                this.on_render_heap = false;
            }
            ObjectEntry.prototype.perform_get = function (fieldname, s) {
                return this[fieldname];
            };
            ObjectEntry.prototype.perform_set = function (fieldname, value, s) {
                s.rt.logDataWrite(this.on_render_heap);
                this[fieldname] = value;
            };
            ObjectEntry.prototype.perform_add = function (fieldname, value, s) {
                s.rt.logDataWrite(this.on_render_heap);
                if (value)
                    this[fieldname] += value;
            };
            ObjectEntry.prototype.perform_clear = function (fieldname, s) {
                s.rt.logDataWrite(this.on_render_heap);
                delete this[fieldname];
            };
            ObjectEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                s.rt.logDataWrite(this.on_render_heap);
                if (!this[fieldname] && value)
                    this[fieldname] = value;
            };
            return ObjectEntry;
        })(RecordEntry);
        RT.ObjectEntry = ObjectEntry;
        var DecoratorEntry = (function (_super) {
            __extends(DecoratorEntry, _super);
            function DecoratorEntry() {
                _super.call(this);
                this._written = 0;
            }
            DecoratorEntry.prototype.post_to_wall = function (frame) {
                this.clear_if_necessary();
                _super.prototype.post_to_wall.call(this, frame);
            };
            DecoratorEntry.prototype.clear_if_necessary = function () {
                var decsing = this.parent;
                if (this._written < decsing._generation) {
                    this._written = decsing._generation;
                    this.clear_fields();
                }
            };
            DecoratorEntry.prototype.target = function () {
                return this[this.keys[0]];
            };
            DecoratorEntry.prototype.perform_get = function (fieldname, s) {
                this.clear_if_necessary();
                return this[fieldname];
            };
            DecoratorEntry.prototype.perform_set = function (fieldname, value, s) {
                s.rt.logDataWrite(this.target().on_render_heap);
                this.clear_if_necessary();
                this[fieldname] = value;
            };
            DecoratorEntry.prototype.perform_add = function (fieldname, value, s) {
                s.rt.logDataWrite(this.target().on_render_heap);
                this.clear_if_necessary();
                if (value)
                    this[fieldname] += value;
            };
            DecoratorEntry.prototype.perform_clear = function (fieldname, s) {
                s.rt.logDataWrite(this.target().on_render_heap);
                this.clear_if_necessary();
                delete this[fieldname];
            };
            DecoratorEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                s.rt.logDataWrite(this.target().on_render_heap);
                this.clear_if_necessary();
                if (!this[fieldname] && value)
                    this[fieldname] = value;
            };
            return DecoratorEntry;
        })(RecordEntry);
        RT.DecoratorEntry = DecoratorEntry;
        var RecordSingleton = (function (_super) {
            __extends(RecordSingleton, _super);
            function RecordSingleton() {
                _super.call(this);
            }
            RecordSingleton.prototype.rtType = function () {
                return this.libName + "$" + this.stableName;
            };
            RecordSingleton.prototype.noMagicRtType = function () {
                return true;
            };
            RecordSingleton.prototype.initParent = function () {
            };
            RecordSingleton.prototype.isSerializable = function () {
                return true;
            };
            RecordSingleton.prototype.session = function () {
                var s = (this.localsession) ? TDev.Runtime.theRuntime.sessions.getLocalSession() : TDev.Runtime.theRuntime.sessions.getCurrentSession();
                if (!s)
                    TDev.Util.oops("missing " + (this.localsession ? "local" : "cloud") + " session, " + this.stableName);
                return s;
            };
            RecordSingleton.prototype.create_collection = function (s) {
                var o = RT.Collection.fromArray([], this);
                o.on_render_heap = s.rt.rendermode;
                return o;
            };
            RecordSingleton.prototype.copy_to_collection = function (s) {
                var o = this.create_collection(s);
                o.a.pushRange(this.get_enumerator());
                return o;
            };
            RecordSingleton.prototype.my_entries = function (s) {
                var o = this.create_collection(s);
                var userid = TDev.Cloud.getUserId();
                if (userid === undefined)
                    return undefined;
                o.a.pushRange(this.get_enumerator().filter(function (e) {
                    var u = e[e.keys[0]];
                    return u._id === userid;
                }));
                return o;
            };
            RecordSingleton.prototype.entries_linked_to = function () {
                var supplied = arguments;
                var o = this.create_collection(arguments[arguments.length - 1]);
                o.a.pushRange(this.get_enumerator().filter(function (e) {
                    for (var i = 0; i < e.keys.length; i++)
                        if (e[e.keys[i]] !== supplied[i])
                            return false;
                    return true;
                }));
                return o;
            };
            RecordSingleton.prototype.on_changed = function (body, s) {
                if (!this.onChangeEvent)
                    this.onChangeEvent = new RT.Event_();
                var b = this.onChangeEvent.addHandler(body);
                s.rt.queueLocalEvent(this.onChangeEvent, undefined, true, true);
                return b;
            };
            RecordSingleton.prototype.logMutation = function (s) {
                s.rt.logDataWrite(false);
                if (this.onChangeEvent)
                    s.rt.queueLocalEvent(this.onChangeEvent, undefined, true, true);
            };
            RecordSingleton.prototype.wait_for_update = function (r) {
                if (!this.onChangeEvent)
                    this.onChangeEvent = new RT.Event_();
                this.onChangeEvent.addAwaiter(function (v) {
                    r.resume();
                });
            };
            RecordSingleton.prototype.getTable = function (entries, sf) {
                var tab = document.createElement("table");
                tab.className = "wall-table";
                if (entries.length === 0) {
                    var tr = document.createElement("tr");
                    var td = document.createElement("td");
                    tr.textContent = "(empty table)";
                    tr.appendChild(td);
                    tab.appendChild(tr);
                }
                else {
                    tab.appendChild(entries[0].getTableHeader());
                    entries.forEach(function (e) { return tab.appendChild(e.getTableRow(sf)); });
                }
                return tab;
            };
            RecordSingleton.prototype.debuggerDisplay = function (_) {
                return null;
            };
            RecordSingleton.prototype.invalid_row = function () {
                return undefined;
            };
            RecordSingleton.prototype.invalid = function () {
                return undefined;
            };
            RecordSingleton.prototype.get_enumerator = function () {
                TDev.Util.oops("not implemented: enumerator");
                return [];
            };
            RecordSingleton.prototype.exportJson = function (ctx) {
                var entries = this.get_enumerator();
                return ctx.encodeArrayNode(this, entries.slice(0));
            };
            RecordSingleton.prototype.to_json = function (s) {
                var ctx = new TDev.JsonExportCtx(s);
                ctx.push(this);
                var json = this.exportJson(ctx);
                ctx.pop(this);
                return RT.JsonObject.wrap(json);
            };
            RecordSingleton.prototype.prune_to = function (entries) {
                TDev.Util.oops("must be overridden by index and table");
            };
            RecordSingleton.prototype.from_json = function (jobj, s) {
                this.logMutation(s);
                var ctx = new TDev.JsonImportCtx(s);
                var json = jobj.value();
                this.importJsonTableOrIndex(ctx, json);
            };
            RecordSingleton.prototype.importJsonTableOrIndex = function (ctx, json) {
                var _this = this;
                if (typeof json !== "object")
                    return;
                if (Array.isArray(json)) {
                    var elts = json.map(function (jsonelt) { return _this.importJsonRecord(ctx, undefined, jsonelt, true); });
                    for (var i = 0; i < elts.length; i++)
                        elts[i].importJsonFields(ctx, json[i]);
                    this.prune_to(elts);
                }
                else {
                    this.importJsonRecord(ctx, undefined, json, false);
                }
            };
            RecordSingleton.prototype.jsonExportKey = function (ctx) {
                return null;
            };
            RecordSingleton.prototype.importJsonKeys = function (ctx, jobj) {
                return [];
            };
            RecordSingleton.prototype.findImportTarget = function (ctx, id, target, json) {
                TDev.Util.oops("subclasses are supposed to override this method");
                return null;
            };
            RecordSingleton.prototype.importJsonRecord = function (ctx, target, json, delayrecursion) {
                this.logMutation(ctx.s);
                var id;
                if (typeof (json) === "string") {
                    id = ctx.map(this.stableName, json);
                }
                else if (typeof (json) !== "object" || Array.isArray(json)) {
                    return undefined;
                }
                else {
                    id = ctx.map(this.stableName, json["⌹id"]);
                }
                target = this.findImportTarget(ctx, id, target, json);
                if (target) {
                    if (!delayrecursion)
                        target.importJsonFields(ctx, json);
                    if (id)
                        ctx.addmapping(this.stableName, id, target.jsonExportKey(undefined));
                }
                return target;
            };
            return RecordSingleton;
        })(RT.RTValue);
        RT.RecordSingleton = RecordSingleton;
        var TableSingleton = (function (_super) {
            __extends(TableSingleton, _super);
            function TableSingleton() {
                _super.call(this);
                this.row_counter = 0;
                this.dependentcaches = [];
            }
            TableSingleton.prototype.initParent = function () {
                this._elements = [];
            };
            TableSingleton.prototype.next_row_number = function () {
                this.row_counter = this.row_counter + 1;
                return this.row_counter;
            };
            TableSingleton.prototype.add_row = function (s) {
                return this.constructrow(arguments);
            };
            TableSingleton.prototype.constructrow = function (args) {
                this.clearCachedData();
                var ent = new this.entryCtor(this);
                ent.rownumber = this.next_row_number();
                this._elements.push(ent);
                TDev.Util.assert(args.length == ent.keys.length + 1);
                this.logMutation(args[args.length - 1]);
                for (var i = 0; i < ent.keys.length; ++i)
                    ent[ent.keys[i]] = args[i];
                return ent;
            };
            TableSingleton.prototype.row_at = function (index) {
                this.cacheItems();
                return this.cacheditems[Math.floor(index)];
            };
            TableSingleton.prototype.count = function () {
                this.cacheItems();
                return this.cacheditems.length;
            };
            TableSingleton.prototype.clear = function (s) {
                this.logMutation(s);
                this.clearCachedData();
                this._elements.forEach(function (e) {
                    e.invalidate();
                });
                this._elements = [];
            };
            TableSingleton.prototype.prune_to = function (entries) {
                this._elements = entries;
            };
            TableSingleton.prototype.findImportTarget = function (ctx, id, target, json) {
                if (id && (!target || target.jsonExportKey(undefined) !== id)) {
                    target = undefined;
                    this._elements.forEach(function (e) {
                        if (e.jsonExportKey(undefined) === id)
                            target = e;
                    });
                }
                if (target && target.is_deleted())
                    target = undefined;
                if (!target && (typeof (json) !== "string")) {
                    var keys = this.importJsonKeys(ctx, json);
                    keys.push(ctx.s);
                    target = this.constructrow(keys);
                }
                return target;
            };
            TableSingleton.prototype.cacheItems = function () {
                var _this = this;
                if (this.cacheditems === undefined) {
                    this.cacheditems = this._elements.filter(function (val) { return !val.is_deleted(); });
                    if (this.cacheditems.length > 0) {
                        var e = this.cacheditems[0];
                        if (e.keys.length > 0) {
                            e.keys.forEach(function (k) {
                                var key = e[k];
                                TDev.Util.assert(key instanceof TableEntry || key instanceof CloudTableEntry);
                                key.parent.dependentcaches[_this.stableName] = _this;
                            });
                        }
                    }
                }
            };
            TableSingleton.prototype.clearCachedData = function () {
                this.cacheditems = undefined;
                for (var l in this.dependentcaches) {
                    if (this.dependentcaches.hasOwnProperty(l))
                        this.dependentcaches[l].clearCachedData();
                }
            };
            TableSingleton.prototype.get_enumerator = function () {
                this.cacheItems();
                return this.cacheditems;
            };
            TableSingleton.prototype.post_to_wall = function (s) {
                s.rt.postBoxedHtml(this.getTable(this.get_enumerator(), s), s.pc);
            };
            return TableSingleton;
        })(RecordSingleton);
        RT.TableSingleton = TableSingleton;
        var CloudTableSingleton = (function (_super) {
            __extends(CloudTableSingleton, _super);
            function CloudTableSingleton() {
                _super.call(this);
                this.dependentcaches = [];
            }
            CloudTableSingleton.prototype.add_row = function (s) {
                return this.constructrow(arguments);
            };
            CloudTableSingleton.prototype.constructrow = function (args) {
                this.clearCachedData();
                var ent = new this.entryCtor(this);
                TDev.Util.assert(args.length == ent.keys.length + 1);
                this.logMutation(args[args.length - 1]);
                var links = new Array();
                for (var i = 0; i < ent.keys.length; ++i) {
                    var x = args[i];
                    var correctsession = x.check(false);
                    if (!correctsession)
                        TDev.Util.userError(TDev.lf("invalid link argument: originated in a different session"));
                    links.push(x.uid);
                    ent[ent.keys[i]] = x;
                }
                ent.hookup(this.session().user_create_item(this.cloudtype, links, []));
                return ent;
            };
            CloudTableSingleton.prototype.prune_to = function (entries) {
                var map = {};
                entries.forEach(function (e) { return map[e.uid] = true; });
                this.get_enumerator().forEach(function (r) { return map[r.uid] ? undefined : r.delete_row(); });
            };
            CloudTableSingleton.prototype.import_item = function (item) {
                if (item.backlink !== undefined)
                    return (item.backlink);
                else {
                    var ent = new this.entryCtor(this);
                    ent.hookup(item);
                    return ent;
                }
            };
            CloudTableSingleton.prototype.import_item_from_uid = function (uid, def) {
                if (!uid)
                    return undefined;
                var session = this.session();
                var item = session.user_get_item(uid);
                if (def && (!item || item.definition !== def))
                    return undefined;
                if (item === undefined)
                    item = session.user_create_tombstone(this.cloudtype, uid, this.key_cloudtypes.map(function (k) { return undefined; }), []);
                return this.import_item(item);
            };
            CloudTableSingleton.prototype.fromRest = function (json) {
                return this.import_item_from_uid(json["⌹id"]);
            };
            CloudTableSingleton.prototype.cacheItems = function () {
                var _this = this;
                if (this.cacheditems === undefined) {
                    var session = this.session();
                    this.cacheditems = session.user_get_items_in_domain(this.cloudtype).sort(function (a, b) { return a.compareTo(b); });
                    this.linked_cloudtables.forEach(function (t) { return t.dependentcaches[_this.stableName] = _this; });
                    TDev.Runtime.theRuntime.sessions.registerDataCache(this.stableName, this);
                }
            };
            CloudTableSingleton.prototype.clearCachedData = function () {
                var _this = this;
                this.cacheditems = undefined;
                this.linked_cloudtables.forEach(function (t) { return delete t.dependentcaches[_this.stableName]; });
                TDev.Runtime.theRuntime.sessions.unregisterDataCache(this.stableName);
                for (var l in this.dependentcaches) {
                    if (this.dependentcaches.hasOwnProperty(l))
                        this.dependentcaches[l].clearCachedData();
                }
            };
            CloudTableSingleton.prototype.count = function () {
                this.cacheItems();
                return this.cacheditems.length;
            };
            CloudTableSingleton.prototype.row_at = function (index) {
                this.cacheItems();
                var item = this.cacheditems[Math.floor(index)];
                return item ? this.import_item(item) : undefined;
            };
            CloudTableSingleton.prototype.clear = function () {
                var _this = this;
                this.cacheItems();
                this.cacheditems.forEach(function (item) { return _this.session().user_delete_item(item); });
                this.clearCachedData();
            };
            CloudTableSingleton.prototype.get_enumerator = function () {
                var _this = this;
                this.cacheItems();
                var entries = this.cacheditems.map(function (i) { return _this.import_item(i); });
                return entries;
            };
            CloudTableSingleton.prototype.post_to_wall = function (frame) {
                frame.rt.postBoxedHtml(this.getTable(this.get_enumerator(), frame), frame.pc);
            };
            CloudTableSingleton.prototype.findImportTarget = function (ctx, id, t, json) {
                var target = t;
                if (id && (!target || target.jsonExportKey(undefined) !== id)) {
                    if (id[0] === ".")
                        id = id.slice(1);
                    target = this.import_item_from_uid(id, this.cloudtype);
                }
                if (target && target.is_deleted())
                    target = undefined;
                if (!target && (typeof (json) !== "string")) {
                    var keys = this.importJsonKeys(ctx, json);
                    keys.push(ctx.s);
                    target = this.constructrow(keys);
                }
                return target;
            };
            return CloudTableSingleton;
        })(RecordSingleton);
        RT.CloudTableSingleton = CloudTableSingleton;
        var CloudIndexEntry = (function (_super) {
            __extends(CloudIndexEntry, _super);
            function CloudIndexEntry() {
                _super.call(this);
            }
            CloudIndexEntry.prototype.equals = function (other) {
                var o = other;
                this.check();
                o.check();
                return (this.sessionname === o.sessionname) && (this.entry === o.entry);
            };
            CloudIndexEntry.prototype.getShortStringRepresentation = function () {
                return "[" + this.parent.entryKindName + "]";
            };
            CloudIndexEntry.prototype.hookup = function (entry) {
                this.sessionname = entry.session.servername;
                this.entry = entry;
                entry.backlink = this;
                this.read_cloud_fields(entry);
            };
            CloudIndexEntry.prototype.unlink = function () {
                this.decorators = undefined;
                this.entry = undefined;
                for (var i = 0; i < this.values.length; i++) {
                    this[this.values[i]] = undefined;
                }
            };
            CloudIndexEntry.prototype.getFieldValue = function (fieldname, s) {
                this.check();
                var f = this[fieldname];
                if (f instanceof TDev.Revisions.LVal)
                    return Conv.read(this.parent.session(), f, s);
                else
                    return f;
            };
            CloudIndexEntry.prototype.check = function (abort) {
                if (abort === void 0) { abort = true; }
                if (this.sessionname !== this.parent.session().servername) {
                    if (abort)
                        TDev.Util.userError(TDev.lf("stale index entry: originated in a different session"));
                    else
                        return false;
                }
                if (typeof (this.entry) === "undefined" || this.entry.backlink != this || this.entry.session !== this.parent.session()) {
                    TDev.Util.assert(this.keys.length === this.parent.key_cloudtypes.length);
                    var ukeys = new Array();
                    var lkeys = new Array();
                    for (var i = 0; i < this.keys.length; i++) {
                        var cloudtype = this.parent.key_cloudtypes[i];
                        if (cloudtype.charAt(cloudtype.length - 1) === ')') {
                            var uid = this[this.keys[i]].uid;
                            ukeys.push(uid);
                        }
                        else {
                            lkeys.push(Conv.toCloud(cloudtype, this[this.keys[i]], false));
                        }
                        this.hookup(this.parent.session().user_get_entry(this.parent.cloudtype, ukeys, lkeys));
                    }
                    return true;
                }
                return true;
            };
            CloudIndexEntry.prototype.clear_fields = function (s) {
                if (s)
                    this.parent.logMutation(s);
                this.check();
                for (var i = 0; i < this.values.length; i++) {
                    var lval = this[this.values[i]];
                    Conv.clear(this.parent.session(), lval);
                }
            };
            CloudIndexEntry.prototype.confirmed = function () {
                var _this = this;
                this.check();
                var session = this.parent.session();
                var confirmed = this.dependenciesconfirmed && !this.values.some(function (val) { return !session.user_is_datum_confirmed(_this[val]); });
                return confirmed;
            };
            CloudIndexEntry.prototype.dependenciesconfirmed = function () {
                var _this = this;
                return !this.keys.some(function (key) {
                    var r = _this[key];
                    return (r && r instanceof CloudTableEntry && !r.existenceConfirmed());
                });
            };
            CloudIndexEntry.prototype.compareTo = function (other) {
                var _this = this;
                this.check();
                other.check();
                var diff = 0;
                this.keys.forEach(function (k) {
                    if (!diff) {
                        var a = _this[k];
                        var b = other[k];
                        switch (typeof a) {
                            case "string":
                                diff = a.localeCompare(b);
                                break;
                            case "number":
                                diff = a - b;
                                break;
                            case "boolean":
                                if (a !== b)
                                    diff = (a ? 1 : -1);
                                break;
                            default:
                                diff = RT.RTValue.CompareKeys(a, b);
                                break;
                        }
                    }
                });
                return diff;
            };
            CloudIndexEntry.prototype.is_deleted = function () {
                if (!this.check())
                    return true;
                return this.parent.session().user_is_datum_deleted(this.entry);
            };
            CloudIndexEntry.prototype.perform_get = function (fieldname, s) {
                this.check();
                return Conv.read(this.parent.session(), this[fieldname], s);
            };
            CloudIndexEntry.prototype.perform_confirmed = function (fieldname) {
                this.check();
                return this.parent.session().user_is_datum_confirmed(this[fieldname]);
            };
            CloudIndexEntry.prototype.perform_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, false);
            };
            CloudIndexEntry.prototype.perform_test_and_set = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, true);
            };
            CloudIndexEntry.prototype.perform_add = function (fieldname, value, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], value, true);
            };
            CloudIndexEntry.prototype.perform_clear = function (fieldname, s) {
                this.parent.logMutation(s);
                this.check();
                Conv.modify(this.parent.session(), this[fieldname], undefined, false);
            };
            CloudIndexEntry.prototype.read_cloud_fields = function (datum) {
                var ukeys = new Array();
                var lkeys = new Array();
                TDev.Util.assert(this.parent.key_cloudtypes.length === this.keys.length);
                for (var i = 0; i < this.keys.length; i++) {
                    var keytype = this.parent.key_cloudtypes[i];
                    var val;
                    if (keytype.charAt(keytype.length - 1) === ")") {
                        var uid = datum.ukeys[ukeys.length];
                        var linkedtable = this.parent.linked_cloudtables[ukeys.length];
                        val = linkedtable.import_item_from_uid(uid);
                        ukeys.push(uid);
                    }
                    else {
                        var lit = datum.lkeys[lkeys.length];
                        val = Conv.fromCloud(keytype, lit);
                        lkeys.push(lit);
                    }
                    this[this.keys[i]] = val;
                }
                TDev.Util.assert(this.parent.value_cloudtypes.length === this.values.length);
                for (var i = 0; i < this.values.length; i++) {
                    var property = this.parent.value_cloudtypes[i];
                    this[this.values[i]] = this.parent.session().user_get_lval(property, ukeys, lkeys);
                }
            };
            return CloudIndexEntry;
        })(RecordEntry);
        RT.CloudIndexEntry = CloudIndexEntry;
        var PersistentVars = (function () {
            function PersistentVars(rt) {
                this.rt = rt;
                this.sessions = rt.sessions;
            }
            PersistentVars.prototype.check = function () {
                if (!this.session || (!this.localsession && this.session !== this.sessions.getCurrentSession())) {
                    this.session = (this.localsession ? this.sessions.getLocalSession() : this.sessions.getCurrentSession());
                    var prefix = (this.libName === "this") ? "" : (this.libName + ".");
                    for (var i = 0; i < this.names.length; i++) {
                        var name = this.names[i];
                        var property = prefix + this.cloudtypes[i];
                        this[name] = this.session.user_get_lval(property, [], []);
                    }
                }
            };
            PersistentVars.prototype.perform_get = function (fieldname, s) {
                this.check();
                return Conv.read(this.session, this[fieldname], s);
            };
            PersistentVars.prototype.perform_confirmed = function (fieldname) {
                this.check();
                return this.session.user_is_datum_confirmed(this[fieldname]);
            };
            PersistentVars.prototype.perform_set = function (fieldname, value, s) {
                s.rt.logDataWrite(false);
                this.check();
                Conv.modify(this.session, this[fieldname], value, false);
            };
            PersistentVars.prototype.perform_test_and_set = function (fieldname, value, s) {
                s.rt.logDataWrite(false);
                this.check();
                Conv.modify(this.session, this[fieldname], value, true);
            };
            PersistentVars.prototype.perform_add = function (fieldname, value, s) {
                s.rt.logDataWrite(false);
                this.check();
                Conv.modify(this.session, this[fieldname], value, true);
            };
            PersistentVars.prototype.perform_clear = function (fieldname, s) {
                s.rt.logDataWrite(false);
                this.check();
                Conv.modify(this.session, this[fieldname], undefined, false);
            };
            return PersistentVars;
        })();
        RT.PersistentVars = PersistentVars;
        var CloudIndexSingleton = (function (_super) {
            __extends(CloudIndexSingleton, _super);
            function CloudIndexSingleton() {
                _super.call(this);
            }
            CloudIndexSingleton.prototype.clear = function () {
                var session = this.session();
                var entries = session.user_get_entries_in_indexdomain(this.cloudtype);
                entries.forEach(function (e) { return e.lvals.forEach(function (l) { return Conv.clear(session, l); }); });
            };
            CloudIndexSingleton.prototype.count = function () {
                return this.session().user_get_entries_in_indexdomain(this.cloudtype).length;
            };
            CloudIndexSingleton.prototype.get_enumerator = function () {
                var _this = this;
                var entries = this.session().user_get_entries_in_indexdomain(this.cloudtype);
                var x = entries.map(function (e) { return _this.import_item(e); });
                x.sort(function (a, b) { return a.compareTo(b); });
                return x;
            };
            CloudIndexSingleton.prototype.post_to_wall = function (frame) {
                frame.rt.postBoxedHtml(this.getTable(this.get_enumerator(), frame), frame.pc);
            };
            CloudIndexSingleton.prototype.import_item = function (entry) {
                if (typeof (entry.backlink) != "undefined")
                    return (entry.backlink);
                else {
                    var ent = new this.entryCtor(this);
                    ent.hookup(entry);
                    return ent;
                }
            };
            CloudIndexSingleton.prototype.singleton = function () {
                return this.access(arguments);
            };
            CloudIndexSingleton.prototype.at = function () {
                return this.access(arguments);
            };
            CloudIndexSingleton.prototype.access = function (args) {
                TDev.Util.assert(args.length - 1 === this.key_cloudtypes.length);
                var ukeys = new Array();
                var lkeys = new Array();
                for (var i = 0; i < this.key_cloudtypes.length; i++) {
                    var cloudtype = this.key_cloudtypes[i];
                    if (cloudtype.charAt(cloudtype.length - 1) === ')') {
                        var uid = args[i].uid;
                        ukeys.push(uid);
                    }
                    else {
                        lkeys.push(Conv.toCloud(cloudtype, args[i], false));
                    }
                }
                var entry = this.session().user_get_entry(this.cloudtype, ukeys, lkeys);
                return this.import_item(entry);
            };
            CloudIndexSingleton.prototype.findImportTarget = function (ctx, id, target, json) {
                var keys = this.importJsonKeys(ctx, json);
                keys.push(ctx.s);
                return this.access(keys);
            };
            CloudIndexSingleton.prototype.prune_to = function (entries) {
                entries.forEach(function (e) { return e.flagthatthisentryispresentusingalongnoncollidingname = true; });
                this.get_enumerator().forEach(function (r) { return r.flagthatthisentryispresentusingalongnoncollidingname ? undefined : r.clear_fields(); });
                entries.forEach(function (e) { return delete e.flagthatthisentryispresentusingalongnoncollidingname; });
            };
            return CloudIndexSingleton;
        })(RecordSingleton);
        RT.CloudIndexSingleton = CloudIndexSingleton;
        var IndexSingleton = (function (_super) {
            __extends(IndexSingleton, _super);
            function IndexSingleton() {
                _super.call(this);
            }
            IndexSingleton.prototype.initParent = function () {
                this._index = TDev.Hashtable.forJson();
            };
            IndexSingleton.prototype.clear = function () {
                return this._index.clear();
            };
            IndexSingleton.prototype.count = function () {
                return this._index.countFiltered(function (val) { return (!val.is_deleted() && val.hasNondefaultValue()); });
            };
            IndexSingleton.prototype.singleton = function () {
                return this.access(arguments);
            };
            IndexSingleton.prototype.at = function () {
                return this.access(arguments);
            };
            IndexSingleton.prototype.makekey = function (args) {
                var key = [];
                for (var i = 0; i < args.length - 1; ++i) {
                    var a = args[i];
                    switch (typeof a) {
                        case "string":
                        case "number":
                        case "boolean":
                            key.push(a);
                            break;
                        default:
                            TDev.Util.assert(!!a);
                            key.push(a.toJsonKey());
                            break;
                    }
                }
                return key;
            };
            IndexSingleton.prototype.access = function (args) {
                var key = this.makekey(args);
                var e = this._index.get(key);
                if (!e) {
                    e = new this.entryCtor(this);
                    TDev.Util.assert((args.length === 0 && e.keys.length === 0) || (args.length - 1 === e.keys.length));
                    for (var i = 0; i < e.keys.length; ++i)
                        e[e.keys[i]] = args[i];
                    this._index.set(key, e);
                }
                return e;
            };
            IndexSingleton.prototype.get_enumerator = function () {
                var a = this._index.filteredValues(function (val) { return (!val.is_deleted() && val.hasNondefaultValue()); });
                a.sort(function (a, b) { return a.compareTo(b); });
                return a;
            };
            IndexSingleton.prototype.post_to_wall = function (frame) {
                frame.rt.postBoxedHtml(this.getTable(this.get_enumerator(), frame), frame.pc);
            };
            IndexSingleton.prototype.findImportTarget = function (ctx, id, target, json) {
                var keys = this.importJsonKeys(ctx, json);
                keys.push(ctx.s);
                return this.access(keys);
            };
            IndexSingleton.prototype.prune_to = function (entries) {
                var _this = this;
                entries.forEach(function (e) { return e.flagthatthisentryispresentusingalongnoncollidingname = true; });
                var tobedeleted = this._index.filteredValues(function (e) { return !e.flagthatthisentryispresentusingalongnoncollidingname; });
                entries.forEach(function (e) { return delete e.flagthatthisentryispresentusingalongnoncollidingname; });
                tobedeleted.forEach(function (e) {
                    var keys = e.keys.map(function (k) { return e[k]; });
                    keys.push(null);
                    var key = _this.makekey(keys);
                    _this._index.remove(key);
                });
            };
            return IndexSingleton;
        })(RecordSingleton);
        RT.IndexSingleton = IndexSingleton;
        var ObjectSingleton = (function (_super) {
            __extends(ObjectSingleton, _super);
            function ObjectSingleton() {
                _super.call(this);
            }
            ObjectSingleton.prototype.create = function (s) {
                var o = new this.entryCtor(this);
                o.on_render_heap = s.rt.rendermode;
                return o;
            };
            ObjectSingleton.prototype.create_from_json = function (jobj, s) {
                var o = this.create(s);
                o.from_json(jobj, s);
                return o;
            };
            ObjectSingleton.prototype.invalid = function () {
                return undefined;
            };
            ObjectSingleton.prototype.clear = function () {
            };
            ObjectSingleton.prototype.importJsonRecord = function (ctx, target, json) {
                if (!target)
                    target = this.create(ctx.s);
                target.importJsonFields(ctx, json);
                return target;
            };
            return ObjectSingleton;
        })(RecordSingleton);
        RT.ObjectSingleton = ObjectSingleton;
        var DecoratorSingleton = (function (_super) {
            __extends(DecoratorSingleton, _super);
            function DecoratorSingleton() {
                _super.call(this);
                this._generation = 0;
            }
            DecoratorSingleton.prototype.clear = function () {
                this._generation = this._generation + 1;
            };
            DecoratorSingleton.prototype.at = function (obj, s) {
                var decs = obj.decorators;
                if (!decs)
                    decs = obj.decorators = new RT.DecoratorCollection();
                var key = s.d["libName"] + "$" + this.stableName;
                var dec = decs[key];
                if (!dec) {
                    dec = new this.entryCtor(this);
                    dec[dec.keys[0]] = obj;
                    decs[key] = dec;
                }
                return dec;
            };
            return DecoratorSingleton;
        })(RecordSingleton);
        RT.DecoratorSingleton = DecoratorSingleton;
        var Conv = (function () {
            function Conv() {
            }
            Conv.modify = function (session, lval, val, relative) {
                if (val instanceof CloudTableEntry)
                    val = val.uid;
                var op = Conv.toCloud(lval.codomain, val, relative);
                session.user_modify_lval(lval, op);
            };
            Conv.read = function (session, lval, s) {
                var cur = session.user_get_value(lval);
                cur = Conv.fromCloud(lval.codomain, cur);
                if (cur && s && lval.codomain.charAt(0) === "^") {
                    var table = s.d["$" + lval.codomain.slice(1)];
                    cur = table.import_item_from_uid(cur);
                }
                return cur;
            };
            Conv.clear = function (session, lval) {
                var op = Conv.toCloud(lval.codomain, undefined, false);
                session.user_modify_lval(lval, op);
            };
            Conv.getCloudDomain = function (kind) {
                switch (kind) {
                    case "Location": return "location";
                    case "User": return "user";
                    case "Boolean": return "boolean";
                    case "Color": return "color";
                    case "DateTime": return "datetime";
                    case "String": return "string";
                    case "Number": return "double";
                    case "Vector3": return "vector3";
                    default: TDev.Util.oops("unhandled case for cloud domain: " + (kind || "none"));
                }
            };
            Conv.getCloudCodomain = function (kind) {
                switch (kind) {
                    case "Location": return "location";
                    case "User": return "user";
                    case "Boolean": return "boolean";
                    case "Color": return "color";
                    case "DateTime": return "datetime";
                    case "String": return "string";
                    case "Number": return "double";
                    case "OAuth Response": return "oauthresponse";
                    case "Link": return "link";
                    case "Json Object": return "json";
                    default: TDev.Util.oops("unhandled case for cloud codomain: " + (kind || "none"));
                }
            };
            Conv.toCloud = function (kind, val, relative) {
                if (relative === void 0) { relative = false; }
                switch (kind) {
                    case "location":
                        if (!val)
                            return "";
                        TDev.Util.assert(val instanceof RT.Location_);
                        return val.to_string();
                    case "user":
                        if (!val)
                            return "";
                        TDev.Util.assert(val instanceof RT.User);
                        return val.id();
                    case "boolean":
                        return val ? "t" : "";
                    case "color":
                        if (!val)
                            return "";
                        TDev.Util.assert(val instanceof RT.Color);
                        return val.toInt32().toString();
                    case "vector3":
                        if (!val)
                            return "";
                        return JSON.stringify(val.exportJson(null));
                    case "datetime":
                        if (!val)
                            return "";
                        TDev.Util.assert(val instanceof RT.DateTime);
                        return val.milliseconds_since_epoch().toString();
                    case "string":
                        if (typeof (val) != "string")
                            val = "";
                        if (relative)
                            return "^?" + val;
                        if (val.charAt(0) === "^")
                            return "^!" + val;
                        return val;
                    case "double":
                        var newval = (typeof val !== "number" ? 0 : val);
                        return relative ? ("A" + newval) : newval.toString();
                    case "oauthresponse":
                        if (!val)
                            return "";
                        return JSON.stringify(val.exportJson(null));
                    case "link":
                        if (!val)
                            return "";
                        return JSON.stringify(val.exportJson(null));
                    case "json":
                        if (!val)
                            return "";
                        return JSON.stringify(val.exportJson(null));
                    default:
                        TDev.Util.assert(kind[0] === "^");
                        return val || "";
                }
            };
            Conv.fromCloud = function (kind, val) {
                switch (kind) {
                    case "location":
                        if (!val)
                            return;
                        return RT.Location_.mkFromString(val);
                    case "user":
                        if (!val)
                            return;
                        return RT.User.mk(val);
                    case "boolean":
                        return !!val && val !== "false";
                    case "color":
                        if (!val)
                            return;
                        return RT.Color.fromInt32(Number(val));
                    case "datetime":
                        var nr = Number(val || 0);
                        return RT.DateTime.mkMs(nr);
                    case "oauthresponse":
                        if (!val)
                            return;
                        return (new RT.OAuthResponse()).importJson(new TDev.JsonImportCtx(null), JSON.parse(val));
                    case "vector3":
                        if (!val)
                            return;
                        return RT.Vector3.mkFromJson(new TDev.JsonImportCtx(null), JSON.parse(val));
                    case "link":
                        if (!val)
                            return;
                        return (new RT.Link()).importJson(new TDev.JsonImportCtx(null), JSON.parse(val));
                    case "json":
                        if (!val)
                            return;
                        return RT.JsonObject.wrap(JSON.parse(val));
                    case "string":
                        if (typeof (val) !== "string")
                            val = "";
                        else if (val.charAt(0) === "^")
                            val = val.substr(2);
                        return val;
                    case "double":
                        if (typeof (val) !== "string")
                            return 0;
                        TDev.Util.assert(val.charAt(0) !== "A");
                        return Number(val);
                    default:
                        TDev.Util.assert(kind[0] === "^");
                        return val || undefined;
                }
            };
            return Conv;
        })();
        RT.Conv = Conv;
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var StackUtil;
    (function (StackUtil) {
        var idChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        function combineIds(a, b) {
            if (!a || a == "this")
                a = "";
            if (!b || b == "this")
                b = "";
            var maxLen = 8;
            var buf = new Uint32Array(maxLen);
            var ptr = 0;
            var add = function (s) {
                for (var i = 0; i < s.length; ++i) {
                    buf[ptr] = buf[ptr] * 13 + s.charCodeAt(i);
                    if (++ptr >= maxLen)
                        ptr = 0;
                }
            };
            add(a);
            add(b);
            var r = "";
            for (var i = 0; i < maxLen; ++i) {
                r += idChars[buf[i] % 62];
            }
            return r;
        }
        StackUtil.combineIds = combineIds;
        function compress(trace) {
            if (!trace)
                return "";
            trace = trace.filter(function (f) { return !!f.pc; });
            if (trace.length > 15)
                trace = trace.slice(0, 15);
            var r = "";
            trace.forEach(function (f, i) {
                r += combineIds(f.pc, f.d ? f.d.libName : "");
            });
            return r;
        }
        StackUtil.compress = compress;
    })(StackUtil = TDev.StackUtil || (TDev.StackUtil = {}));
    var HeadlessHost = (function () {
        function HeadlessHost() {
            this.crashes = [];
            this.wallWidth = 1000;
            this.wallHeight = 1000;
            this.wallOrientation = 0;
            this.wallVisible = false;
            this.keyboard = new TDev.RT.RuntimeKeyboard(undefined);
        }
        HeadlessHost.prototype.getWall = function () {
            return null;
        };
        HeadlessHost.prototype.astOfAsync = function (id) {
            return TDev.Promise.as(undefined);
        };
        HeadlessHost.prototype.pickScriptAsync = function (mode, message) {
            return TDev.Promise.as(undefined);
        };
        HeadlessHost.prototype.saveAstAsync = function (id, ast) {
            return TDev.Promise.as(undefined);
        };
        HeadlessHost.prototype.deploymentSettingsAsync = function (id) {
            return TDev.Promise.as(undefined);
        };
        HeadlessHost.prototype.packageScriptAsync = function (id, options) {
            return TDev.Promise.as(undefined);
        };
        HeadlessHost.prototype.fullWallWidth = function () {
            return this.wallWidth;
        };
        HeadlessHost.prototype.fullWallHeight = function () {
            return this.wallHeight;
        };
        HeadlessHost.prototype.userWallHeight = function () {
            return this.wallWidth;
        };
        HeadlessHost.prototype.isHeadless = function () {
            return true;
        };
        HeadlessHost.prototype.init = function (rt) {
            this.currentRt = rt;
        };
        HeadlessHost.prototype.liveMode = function () {
            return false;
        };
        HeadlessHost.prototype.dontWaitForEvents = function () {
            return false;
        };
        HeadlessHost.prototype.applyPageAttributes = function (wp) {
        };
        HeadlessHost.prototype.setTransform3d = function (trans, origin, perspective) {
        };
        HeadlessHost.prototype.setFullScreenElement = function (element) {
        };
        HeadlessHost.prototype.fullScreenElement = function () {
            return undefined;
        };
        HeadlessHost.prototype.isFullScreen = function () {
            return false;
        };
        HeadlessHost.prototype.applyWallStyle = function () {
        };
        HeadlessHost.prototype.publishSizeUpdate = function () {
        };
        HeadlessHost.prototype.notifyPageButtonUpdate = function () {
        };
        HeadlessHost.prototype.additionalButtons = function () {
            return [];
        };
        HeadlessHost.prototype.additionalFullScreenButtons = function () {
            return [];
        };
        HeadlessHost.prototype.updateCloudState = function (hasCloudState, type, status) {
        };
        HeadlessHost.prototype.agreeTermsOfUseAsync = function () {
            return TDev.Promise.as();
        };
        HeadlessHost.prototype.notifyTutorial = function (cmd) {
        };
        HeadlessHost.prototype.showWall = function () {
            this.wallVisible = true;
        };
        HeadlessHost.prototype.getFullScreenCanvas = function () {
            return undefined;
        };
        HeadlessHost.prototype.toScreenshotCanvas = function () {
            return undefined;
        };
        HeadlessHost.prototype.otherwiseBack = function () {
        };
        HeadlessHost.prototype.backBtnHandler = function () {
        };
        HeadlessHost.prototype.notifyRunState = function () {
        };
        HeadlessHost.prototype.notifyBreakpointHit = function () {
        };
        HeadlessHost.prototype.notifyBreakpointContinue = function () {
        };
        HeadlessHost.prototype.notifyPagePush = function () {
        };
        HeadlessHost.prototype.notifyPagePop = function (p) {
        };
        HeadlessHost.prototype.attachProfilingInfo = function (profile) {
        };
        HeadlessHost.prototype.attachCoverageInfo = function (coverage) {
        };
        HeadlessHost.prototype.notifyStopAsync = function () {
            TDev.Ticker.dbg("notifyStop");
            var p = this.currentRt.saveDataAsync();
            TDev.Util.log("program stopped");
            if (this.onProgramEnd)
                this.onProgramEnd();
            return p;
        };
        HeadlessHost.prototype.hideWallAsync = function () {
            TDev.Ticker.dbg("hideWallAsync");
            if (!this.wallVisible) {
                return TDev.Promise.as();
            }
            this.wallVisible = false;
            return TDev.Promise.as();
        };
        HeadlessHost.prototype.goBack = function () {
        };
        HeadlessHost.prototype.notifyHideWall = function () {
            var _this = this;
            TDev.Ticker.dbg("notifyHideWall");
            this.hideWallAsync().done(function () {
                _this.goBack();
            });
        };
        HeadlessHost.prototype.exceptionActions = function (e) {
            return null;
        };
        HeadlessHost.prototype.respondToCrash = function (bug) {
        };
        HeadlessHost.prototype.fillCrashInfo = function (crash) {
        };
        HeadlessHost.prototype.exceptionHandler = function (e) {
            e.includeSource = true;
            try {
                this.currentRt.augmentException(e);
            }
            catch (ee) {
            }
            var bug = TDev.Ticker.mkBugReport(e, "runtime error");
            var msg = bug.exceptionMessage;
            var crash = {
                time: Date.now(),
                stack: e.tdStack,
                msg: msg,
                meta: e.tdMeta,
            };
            this.fillCrashInfo(crash);
            this.crashes.push(crash);
            TDev.RT.App.logException(e);
            this.respondToCrash(bug);
            if (!TDev.Browser.isNodeJS && !e.isUserError)
                TDev.Util.sendErrorReport(bug);
            this.lastError = TDev.Ticker.bugReportToString(bug);
        };
        HeadlessHost.prototype.askSourceAccessAsync = function (source, description, critical) {
            return TDev.Promise.as(true);
        };
        HeadlessHost.prototype.initFromPrecompiled = function (precompiled) {
            if (precompiled === void 0) { precompiled = null; }
            var rt = this.currentRt;
            var cs = new TDev.CompiledScript();
            cs.initFromPrecompiled(precompiled);
            rt.initFrom(cs);
            rt.setHost(this);
            if (cs.setupRestRoutes)
                cs.setupRestRoutes(rt);
            rt.killTempState();
        };
        return HeadlessHost;
    })();
    TDev.HeadlessHost = HeadlessHost;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Plugins;
    (function (Plugins) {
        var PluginHost = (function (_super) {
            __extends(PluginHost, _super);
            function PluginHost() {
                _super.call(this);
                this.currentRt = new TDev.Runtime();
                this.currentRt.runtimeKind = function () { return "plugin"; };
            }
            PluginHost.prototype.exceptionHandler = function (e) {
                _super.prototype.exceptionHandler.call(this, e);
                self.postMessage({
                    tdSlotId: this.slotId,
                    id: TDev.Random.uniqueId(),
                    op: "plugin_crashed",
                    message: this.lastError,
                });
            };
            return PluginHost;
        })(TDev.HeadlessHost);
        var hosts = {};
        function uninstallPlugin(d) {
            var h = hosts[d.slotId];
            if (h) {
                TDev.Util.log("shutting down plugin, id:" + d.slotId);
                h.currentRt.stopAsync().done();
                delete hosts[d.slotId];
            }
        }
        function installPlugin(d) {
            TDev.Util.log("installing plugin, id:" + d.slotId);
            var host = new PluginHost();
            hosts[d.slotId] = host;
            host.slotId = d.slotId;
            TDev.Promise.errorHandler = function (ctx, err) { return host.exceptionHandler(err); };
            eval(d.precompiled.replace(/^var TDev;/, ""));
            TDev.Random.strongEntropySource = function (buf) {
                for (var i = 0; i < buf.length; ++i)
                    buf[i] = d.entropy.charAt(i);
            };
            host.initFromPrecompiled();
            var rt = host.currentRt;
            TDev.Runtime.theRuntime = rt;
            rt.pluginSlotId = d.slotId;
            rt.initDataAsync().then(function () {
                var cs = rt.compiled;
                var fn = cs.actionsByName[cs.mainActionName];
                rt.run(fn, null);
            }).done();
        }
        function processMessage(e) {
            var d = e.data;
            if (!d)
                return;
            if (!d.tdOperation) {
                var send = function (h) {
                    if (h && !h.currentRt.isStopped())
                        TDev.RT.Web.receiveWorkerMessage(h.currentRt, e.data);
                };
                if (d.tdSlotId) {
                    send(hosts[d.tdSlotId]);
                }
                else {
                    TDev.Util.values(hosts).forEach(send);
                }
            }
            else {
                switch (d.tdOperation) {
                    case "install":
                        installPlugin(d);
                        break;
                    case "uninstall":
                        uninstallPlugin(d);
                        break;
                    default:
                        TDev.Util.log("operation unknown: " + d.tdOperation);
                        break;
                }
            }
        }
        function initWebWorker() {
            var w = window;
            w.setTimeout = function (a, b) { return self.setTimeout(a, b); };
            var ls = {};
            w.localStorage = ls;
            ls.getItem = function (s) { return ls[s]; };
            ls.setItem = function (s, v) { return ls[s] = v + ""; };
            ls.removeItem = function (s) { return delete ls[s]; };
            TDev.Cloud.authenticateAsync = function () { return TDev.Promise.as(false); };
            TDev.Browser.detect();
            TDev.Util.log("initilize web worker for plugins");
            self.onmessage = TDev.Util.catchErrors("worker-msg", processMessage);
            TDev.Util.initGenericExtensions();
            TDev.Ticker.disable();
            self.postMessage({ tdStatus: "ready" }, null);
        }
        Plugins.initWebWorker = initWebWorker;
        var worker;
        function startWorker() {
            worker = new Worker("worker.js");
            worker.postMessage({
                op: "load",
                url: "browser.js"
            });
            worker.postMessage({
                op: "load",
                url: "main.js"
            });
        }
        Plugins.startWorker = startWorker;
    })(Plugins = TDev.Plugins || (TDev.Plugins = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    TDev.baseUrl = "./";
    var LocalShell;
    (function (LocalShell) {
        function localProxyHandler() {
            return function (cmd, data) {
                if (cmd == "shell")
                    return LocalShell.runShellAsync(data);
                else if (cmd == "socket")
                    return LocalShell.mgmtRequestAsync("stats").then(function () {
                        return { url: mgmtUrl("").replace(/^http/, "ws") };
                    });
                else
                    return LocalShell.mgmtRequestAsync("plugin/" + cmd, data);
            };
        }
        LocalShell.localProxyHandler = localProxyHandler;
        function deploymentKey() {
            var mg = mgmtUrl("");
            var m = mg ? mg.match(/^.*?\/-tdevmgmt-\/([a-z0-9]+)$/) : undefined;
            return m ? m[1] : undefined;
        }
        LocalShell.deploymentKey = deploymentKey;
        function url() {
            var mg = mgmtUrl("");
            var m = mg ? mg.match(/^(.*?\/)-tdevmgmt-\/[a-z0-9]+$/) : undefined;
            return m ? m[1] : undefined;
        }
        LocalShell.url = url;
        function mgmtUrl(path) {
            if (path && !/^\//.test(path))
                path = "/" + path;
            var localProxy = window.localStorage.getItem("local_proxy");
            if (localProxy) {
                var r = localProxy + path;
                TDev.Util.log('shell: local proxy {0}', r);
                return r;
            }
            var tok = window.localStorage.getItem("td_deployment_key");
            if (!tok) {
                TDev.Util.log('shell: missing deployment key');
                return null;
            }
            var m = /(.*:\/\/[^\/]+\/)/.exec(TDev.baseUrl);
            if (!m) {
                TDev.Util.log('shell: invalid base url {0}', TDev.baseUrl);
                return null;
            }
            var r = m[1] + "-tdevmgmt-/" + tok + path;
            TDev.Util.log('shell: mgmturl {0}', r);
            return r;
        }
        LocalShell.mgmtUrl = mgmtUrl;
        function mgmtRequestAsync(path, data) {
            TDev.Util.log("shell mgmtRequest " + path);
            if (!data)
                return TDev.Util.httpGetJsonAsync(mgmtUrl(path));
            else
                return TDev.Util.httpPostRealJsonAsync(mgmtUrl(path), data);
        }
        LocalShell.mgmtRequestAsync = mgmtRequestAsync;
        var lastShell = undefined;
        function runShellAsync(data) {
            TDev.Util.log('shell run {0}', JSON.stringify(data));
            if (lastShell) {
                TDev.Util.log('killing previous shell process');
                lastShell.send(JSON.stringify({ op: "kill" }));
                lastShell.close();
                lastShell = undefined;
            }
            var res = new TDev.PromiseInv();
            var wsurl = mgmtUrl("").replace(/^http/, "ws");
            TDev.Util.log('shell socket: {0}', wsurl);
            var ws = lastShell = new WebSocket(wsurl);
            TDev.Util.log('socket created');
            ws.onopen = function () {
                data = TDev.Util.jsonClone(data);
                data.op = "shell";
                ws.send(JSON.stringify(data));
            };
            ws.onerror = function (e) {
                if (res.isPending())
                    res.error(e);
            };
            ws.onclose = function (e) {
                if (res.isPending())
                    res.error("shell connection closed");
            };
            var stdout = [];
            var stdoutbuf = "";
            var stderr = [];
            var stderrbuf = "";
            ws.onmessage = function (msg) {
                var d = JSON.parse(msg.data);
                if (d.op == "stdout") {
                    stdout.push(d.data);
                    stdoutbuf += d.data;
                    if (/\r?\n$/.test(stdoutbuf)) {
                        stdoutbuf.split(/\r?\n/).filter(function (s) { return !!s; }).forEach(function (s) { return TDev.RT.App.logEvent(TDev.RT.App.DEBUG, "", s, undefined); });
                        stdoutbuf = "";
                    }
                }
                else if (d.op == "stderr") {
                    stderr.push(d.data);
                    stderrbuf += d.data;
                    if (/\r?\n$/.test(stderrbuf)) {
                        stderrbuf.split(/\r?\n/).filter(function (s) { return !!s; }).forEach(function (s) { return TDev.RT.App.logEvent(TDev.RT.App.WARNING, "", s, undefined); });
                        stderrbuf = "";
                    }
                }
                else if (d.op == "error") {
                    TDev.RT.App.logEvent(TDev.RT.App.ERROR, "", d.message, undefined);
                    if (res.isPending())
                        res.error(d.message);
                    ws.close();
                    lastShell = undefined;
                }
                else if (d.op == "exit") {
                    TDev.RT.App.logEvent(d.code == 0 ? TDev.RT.App.INFO : TDev.RT.App.WARNING, "", "exited with " + d.code, undefined);
                    if (res.isPending())
                        res.success({
                            stdout: stdout.join(""),
                            stderr: stderr.join(""),
                            code: d.code,
                        });
                    ws.close();
                    lastShell = undefined;
                }
            };
            return res;
        }
        LocalShell.runShellAsync = runShellAsync;
    })(LocalShell = TDev.LocalShell || (TDev.LocalShell = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var TokenWriter = (function () {
            function TokenWriter() {
                this.buf = "";
                this.indentLevel = 0;
                this.newlinesPending = 0;
                this.lastChar = " ";
                this.lastBlockEnd = -1;
                this.lastAfterBlockEnd = -1;
                this.skipActionBodies = false;
                this.indentString = "  ";
                this.unicodeOps = true;
                this.unicodeStrings = true;
            }
            TokenWriter.forStorage = function () {
                var tw = new TokenWriter();
                return tw;
            };
            TokenWriter.prototype.write = function (s) {
                if (this.newlinesPending > 0) {
                    while (this.newlinesPending > 0) {
                        this.newlinesPending--;
                        this.buf += "\n";
                    }
                    for (var i = 0; i < this.indentLevel; ++i)
                        this.buf += this.indentString;
                    this.lastChar = ' ';
                }
                this.buf += s;
                if (s.length > 0)
                    this.lastChar = s.charAt(s.length - 1);
                return this;
            };
            TokenWriter.prototype.clear = function () {
                this.buf = "";
            };
            TokenWriter.prototype.finalizeShort = function () {
                return this.buf;
            };
            TokenWriter.prototype.finalize = function (skipNL) {
                if (skipNL === void 0) { skipNL = false; }
                if (!skipNL)
                    this.nl().write("");
                return this.buf;
            };
            TokenWriter.prototype.backspaceBlockEnd = function () {
                TDev.Util.assert(this.lastAfterBlockEnd == this.buf.length);
                this.buf = this.buf.slice(0, this.lastBlockEnd);
                this.newlinesPending = 1;
                this.lastChar = ' ';
                this.indentLevel++;
            };
            TokenWriter.prototype.beginBlock = function () {
                this.sep().op0("{").nl();
                this.indentLevel++;
            };
            TokenWriter.prototype.endBlock = function (add) {
                if (add === void 0) { add = ""; }
                this.lastBlockEnd = this.buf.length;
                this.indentLevel--;
                this.op0("}");
                if (add)
                    this.write(add);
                this.nl();
                this.lastAfterBlockEnd = this.buf.length;
            };
            TokenWriter.prototype.space = function () {
                if (this.lastChar != ' ') {
                    this.buf += " ";
                    this.lastChar = ' ';
                }
                return this;
            };
            TokenWriter.prototype.sep = function () {
                var c = this.lastChar;
                if (!(c == ' ' || c == '(' || c == '[')) {
                    this.buf += ' ';
                    this.lastChar = ' ';
                }
                return this;
            };
            TokenWriter.prototype.id = function (id) {
                return this.sep().write(AST.Lexer.quoteId(id));
            };
            TokenWriter.prototype.id0 = function (id) {
                return this.write(AST.Lexer.quoteId(id));
            };
            TokenWriter.prototype.string = function (id) {
                return this.sep().write(AST.Lexer.quoteString(id, !this.unicodeStrings));
            };
            TokenWriter.prototype.uniqueId = function (id) {
                if (!id) {
                    return this;
                }
                this.op0("#").id0(id);
                return this;
            };
            TokenWriter.prototype.kind = function (app, k) {
                var _this = this;
                var par = k.parentLibrary();
                if (par && !par.isThis()) {
                    par.writeRef(this);
                    this.op("\u2192");
                }
                else if (k.isUserDefined()) {
                    this.op("*");
                }
                this.id(k.getRoot().getName());
                if (k instanceof TDev.ParametricKind) {
                    var pk = k;
                    if (pk.parameters && pk.parameters.length > 0) {
                        this.op0("[");
                        pk.parameters.forEach(function (p, i) {
                            if (i > 0)
                                _this.op(",");
                            _this.kind(app, p);
                        });
                        this.op0("]");
                    }
                }
                return this;
            };
            TokenWriter.prototype.op0 = function (op) {
                if (op == ")" && this.lastAfterBlockEnd == this.buf.length)
                    this.newlinesPending = 0;
                if (!this.unicodeOps)
                    op = AST.Lexer.asciiOperator(op);
                if (AST.Lexer.quotedOp(op))
                    op = "`" + op + "`";
                return this.write(op);
            };
            TokenWriter.prototype.op = function (op) {
                return this.space().op0(op).space();
            };
            TokenWriter.prototype.keyword = function (kw) {
                return this.sep().write(kw);
            };
            TokenWriter.prototype.nl = function () {
                this.newlinesPending++;
                this.lastChar = ' ';
                return this;
            };
            TokenWriter.prototype.metaOpt = function (k, v) {
                if (!v)
                    return this;
                else
                    return this.meta(k, v);
            };
            TokenWriter.prototype.meta = function (k, v) {
                return this.keyword("meta").id(k).string(v).op0(";").nl();
            };
            TokenWriter.normalizeComment = function (lines) {
                lines = lines.replace(/\r\n/g, "\n");
                lines = lines.replace(/\r/g, "\n");
                return lines.trim();
            };
            TokenWriter.prototype.comment = function (lines) {
                var _this = this;
                TokenWriter.normalizeComment(lines).split('\n').forEach(function (l) {
                    _this.op("//").space().write(l.trim().replace(/\\/g, "\\\\")).nl();
                });
                return this;
            };
            TokenWriter.prototype.stringAttr = function (n, v) {
                return this.id(n).op("=").string(v).op0(";").nl();
            };
            TokenWriter.prototype.boolOptAttr = function (n, v) {
                if (v)
                    this.id(n).op("=").keyword("true").op0(";").nl();
                return this;
            };
            TokenWriter.prototype.boolAttr = function (n, v) {
                return this.id(n).op("=").keyword(v ? "true" : "false").op0(";").nl();
            };
            TokenWriter.prototype.node = function (n) {
                n.writeTo(this);
                return this;
            };
            return TokenWriter;
        })();
        AST.TokenWriter = TokenWriter;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var TDev;
(function (TDev) {
    TDev.PrevScript = undefined;
    TDev.Script;
    function setGlobalScript(s) {
        TDev.Script = s;
    }
    TDev.setGlobalScript = setGlobalScript;
    var CoreApi = (function () {
        function CoreApi(api) {
            this.refPropPrefix = "\u25C8";
            this.currentPlatform = 0 /* None */;
            this.currentPlatformImpl = 16 /* Web */;
            this.stmtUsageData = {};
            this.Number = api.getKind("Number");
            this.String = api.getKind("String");
            this.Boolean = api.getKind("Boolean");
            this.Color = api.getKind("Color");
            this.Event = api.getKind("Event");
            this.EventBinding = api.getKind("Event Binding");
            this.Action = api.getKind("Action");
            this.Unknown = api.getKind("Unknown");
            this.Nothing = api.getKind("Nothing");
            this.App = api.getKind("App");
            this.Box = api.getKind("Box");
            this.Dom = api.getKind("Dom");
            this.CloudData = api.getKind("Cloud Data");
            this.Picture = api.getKind("Picture");
            this.Sound = api.getKind("Sound");
            this.Editor = api.getKind("Editor");
            this.JsonObject = api.getKind("Json Object");
            this.Task = api.getKind("Task");
            this.Collection = api.getKind("Collection");
            this.Ref = api.getKind("Ref");
            this.TupleProp = this.Unknown.getProperty(",");
            this.AssignmentProp = this.Unknown.getProperty(":=");
            this.EqualsProp = this.Number.getProperty("=");
            this.AsyncProp = this.Unknown.getProperty("async");
            this.FunProp = this.Unknown.getProperty("fun");
            this.ShowProp = this.Unknown.getProperty("show");
            this.BreakProp = this.Unknown.getProperty("break");
            this.ContinueProp = this.Unknown.getProperty("continue");
            this.ReturnProp = this.Unknown.getProperty("return");
            this.AndProp = this.Boolean.getProperty("and");
            this.OrProp = this.Boolean.getProperty("or");
            this.NotProp = this.Boolean.getProperty("not");
            this.StringConcatProp = this.String.getProperty("\u2225");
        }
        CoreApi.prototype.stmtUsage = function (id) {
            if (!this.stmtUsageData.hasOwnProperty(id))
                this.stmtUsageData[id] = new TokenUsage(this);
            return this.stmtUsageData[id];
        };
        CoreApi.prototype.allStmtUsage = function () {
            var _this = this;
            return Object.keys(this.stmtUsageData).map(function (k) { return _this.stmtUsageData[k]; });
        };
        return CoreApi;
    })();
    TDev.CoreApi = CoreApi;
    var Api = (function () {
        function Api() {
            this._kinds = {};
            this._singletons = {};
            this._singletonList = [];
            this._kindList = [];
            this.operatorKeys = {};
            this.restoreFlags = false;
            this.opStmtPriority = 0.5;
            this.rt_start = "";
            this.rt_stop = "";
        }
        Api.prototype.getKind = function (name) {
            if (!this._kinds.hasOwnProperty(name))
                return null;
            return this._kinds[name];
        };
        Api.prototype.getThing = function (name) {
            if (this._singletons.hasOwnProperty(name))
                return this._singletons[name];
            if (TDev.Script && TDev.Script.libNamespaceCache.singletons.hasOwnProperty(name))
                return TDev.Script.libNamespaceCache.singletons[name];
            return null;
        };
        Api.prototype.getKinds = function () {
            return this._kindList;
        };
        Api.prototype.cleanup = function () {
            this.getKinds().forEach(function (k) {
                if (k instanceof ParametricKind) {
                    k.cleanup();
                }
            });
        };
        Api.prototype.getSingletons = function () {
            if (!TDev.Script || TDev.Script.libNamespaceCache.singletonList.length == 0)
                return this._singletonList;
            return this._singletonList.concat(TDev.Script.libNamespaceCache.singletonList);
        };
        Api.runtimeName = function (s) {
            switch (s) {
                case "": return "x";
                case "Number":
                case "String":
                case "Boolean":
                case "Location":
                case "Math":
                case "Event":
                case "arguments":
                case "break":
                case "case":
                case "catch":
                case "continue":
                case "debugger":
                case "default":
                case "delete":
                case "do":
                case "else":
                case "finally":
                case "for":
                case "function":
                case "if":
                case "in":
                case "instanceof":
                case "new":
                case "return":
                case "switch":
                case "this":
                case "throw":
                case "try":
                case "typeof":
                case "var":
                case "void":
                case "while":
                case "with":
                    return s + "_";
                default: return s.replace(/ (?=[A-Z])/g, "").replace(/[ -]/g, "_");
            }
        };
        Api.prototype.mkSpecialProp = function (name, prio) {
            var mkParam = function (name) {
                return { name: name, kind: "Unknown" };
            };
            return {
                name: name,
                help: "",
                flags: "",
                infixPriority: prio,
                result: mkParam("result"),
                inParameters: [mkParam("left"), mkParam("right")]
            };
        };
        Api.prototype.md_addKind = function (k) {
            this._kindList.push(k);
            this._kinds[k.getName()] = k;
        };
        Api.prototype.initFrom = function () {
            new ThingSetKind("code", TDev.lf("Functions in the current script"), function () { return !TDev.Script ? [] : TDev.Script.actions(); }, "\u25b7");
            new ThingSetKind("data", TDev.lf("Global variables in the current script"), function () { return !TDev.Script ? [] : TDev.Script.variables(); }, "\u25f3");
            new ThingSetKind("art", TDev.lf("Pictures, sounds, etc. in the current script"), function () { return !TDev.Script ? [] : TDev.Script.resources(); }, "\u273f");
            new ThingSetKind(TDev.AST.libSymbol, TDev.lf("Libraries referenced by the current script"), function () { return !TDev.Script ? [] : TDev.Script.libraries(); }, TDev.AST.libSymbol);
            new ThingSetKind("records", TDev.lf("Objects, tables and indexes in the current script"), function () { return !TDev.Script ? [] : TDev.Script.records(); }, TDev.AST.recordSymbol);
            TDev.md_initApis();
            var invl = Kind.md_make(0, "Unknown", "an unknown value");
            function specProp(name, prio) {
                var mkp = function (n) { return PropertyParameter.md_make(n, invl); };
                var p = Property.md_make(1, invl, name, "", prio == TDev.api.opStmtPriority ? [] : prio == 98 || prio == 2.5 ? [mkp("arg")] : [mkp("left"), mkp("right")], invl);
                p._infixPriority = prio;
            }
            specProp(":=", 1);
            specProp(",", 2);
            specProp("async", 98);
            specProp("fun", 2.5);
            specProp("return", TDev.api.opStmtPriority);
            specProp("show", TDev.api.opStmtPriority);
            specProp("break", TDev.api.opStmtPriority);
            specProp("continue", TDev.api.opStmtPriority);
            invl.isData = true;
            this.core = new CoreApi(this);
            this._kindList.forEach(function (k) {
                k.initProperties();
            });
            this.initSingletons();
            this.initSpecialApply();
            this.eventMgr = new TDev.AST.EventMgr();
            this.eventMgr.init();
            this.getKinds().forEach(function (k) {
                if (k instanceof ParametricKind) {
                    k.markInitial();
                }
            });
        };
        Api.prototype.initSpecialApply = function () {
            var _this = this;
            this.core.Number.isBuiltin = true;
            this.core.String.isBuiltin = true;
            this.core.Boolean.isBuiltin = true;
            this.core.Unknown.isError = function () { return true; };
            this.core.Nothing._contexts = 0;
            var rt = TDev.RT;
            if (!rt)
                return;
            var missingProps = [];
            this._kindList.forEach(function (k) {
                var hasProp = function (p, o) { return o != undefined && p in o; };
                var n = k.runtimeName();
                if (rt.hasOwnProperty(n)) {
                    var c = rt[n];
                    if ("rt_start" in c) {
                        _this.rt_start += "lib." + n + ".rt_start(rt);\n";
                    }
                    if ("rt_stop" in c) {
                        _this.rt_stop += "lib." + n + ".rt_stop(rt);\n";
                    }
                    if ("picker" in c) {
                        k.picker = "lib." + n + ".picker()";
                    }
                    if (hasProp("get_enumerator", c.prototype))
                        k._hasEnumerator = true;
                }
            });
            TDev.RT.RTValue.initApis();
            missingProps.forEach(function (f) { return f(); });
        };
        Api.prototype.initSingletons = function () {
            var _this = this;
            this._kindList.forEach(function (k) {
                k.initSingleton();
                if (!!k.singleton) {
                    _this._singletons[k.singleton.getName()] = k.singleton;
                    _this._singletonList.push(k.singleton);
                }
            });
            var maxUsage = this._kindList.map(function (k) { return !k.singleton ? 0 : k.usage_count; }).max() + 1;
            this._kindList.forEach(function (k) {
                if (k.usage_count < 0)
                    k.usage_count = maxUsage;
                if (!!k.singleton) {
                    k.singleton.usage.apiFreq = k.usage_count / maxUsage;
                }
            });
            this.core.PlaceholderThing = TDev.AST.mkSingletonDef("$skip", this.core.Unknown);
            this._singletons[this.core.PlaceholderThing.getName()] = this.core.PlaceholderThing;
            this.core.PlaceholderThing._isBrowsable = false;
        };
        Api.prototype.asyncReport = function () {
            var byReason = {};
            this.getKinds().forEach(function (k) {
                if (k instanceof ThingSetKind)
                    return;
                k.listProperties().forEach(function (p) {
                    var pp = p;
                    if (!pp.asyncReason)
                        return;
                    var r = pp.asyncReason();
                    if (!r)
                        return;
                    if (!byReason.hasOwnProperty(r))
                        byReason[r] = "\n*** " + r + "\n";
                    byReason[r] += "      " + p.parentKind.toString() + "->" + p.getName() + "\n";
                });
            });
        };
        return Api;
    })();
    TDev.Api = Api;
    TDev.api = new Api();
    var ApiNode = (function () {
        function ApiNode(_name) {
            this._name = _name;
        }
        ApiNode.prototype.getName = function () {
            return this._name;
        };
        ApiNode.prototype.toString = function () {
            return this.getName();
        };
        return ApiNode;
    })();
    TDev.ApiNode = ApiNode;
    (function (KindContext) {
        KindContext[KindContext["None"] = 0x0000] = "None";
        KindContext[KindContext["Parameter"] = 0x0001] = "Parameter";
        KindContext[KindContext["GlobalVar"] = 0x0002] = "GlobalVar";
        KindContext[KindContext["CloudField"] = 0x0004] = "CloudField";
        KindContext[KindContext["IndexKey"] = 0x0010] = "IndexKey";
        KindContext[KindContext["GcKey"] = 0x0020] = "GcKey";
        KindContext[KindContext["RowKey"] = 0x0040] = "RowKey";
        KindContext[KindContext["WallTap"] = 0x0100] = "WallTap";
        KindContext[KindContext["Enumerable"] = 0x0200] = "Enumerable";
        KindContext[KindContext["Json"] = 0x0400] = "Json";
        KindContext[KindContext["General"] = 1 /* Parameter */ | 2 /* GlobalVar */] = "General";
        KindContext[KindContext["ArtResource"] = 0x04000000] = "ArtResource";
    })(TDev.KindContext || (TDev.KindContext = {}));
    var KindContext = TDev.KindContext;
    (function (PlatformCapability) {
        PlatformCapability[PlatformCapability["None"] = 0] = "None";
        PlatformCapability[PlatformCapability["Accelerometer"] = 0x00000001] = "Accelerometer";
        PlatformCapability[PlatformCapability["Camera"] = 0x00000004] = "Camera";
        PlatformCapability[PlatformCapability["Compass"] = 0x00000008] = "Compass";
        PlatformCapability[PlatformCapability["Gyroscope"] = 0x00000010] = "Gyroscope";
        PlatformCapability[PlatformCapability["Location"] = 0x00000040] = "Location";
        PlatformCapability[PlatformCapability["Maps"] = 0x00000080] = "Maps";
        PlatformCapability[PlatformCapability["Media"] = 0x00000100] = "Media";
        PlatformCapability[PlatformCapability["Microphone"] = 0x00000200] = "Microphone";
        PlatformCapability[PlatformCapability["Motion"] = 0x00000400] = "Motion";
        PlatformCapability[PlatformCapability["Contacts"] = 0x00000800] = "Contacts";
        PlatformCapability[PlatformCapability["Phone"] = 0x00001000] = "Phone";
        PlatformCapability[PlatformCapability["Radio"] = 0x00002000] = "Radio";
        PlatformCapability[PlatformCapability["Orientation"] = 0x00004000] = "Orientation";
        PlatformCapability[PlatformCapability["Search"] = 0x00008000] = "Search";
        PlatformCapability[PlatformCapability["Translation"] = 0x00010000] = "Translation";
        PlatformCapability[PlatformCapability["EditorOnly"] = 0x00040000] = "EditorOnly";
        PlatformCapability[PlatformCapability["MusicAndSounds"] = 0x00080000] = "MusicAndSounds";
        PlatformCapability[PlatformCapability["Network"] = 0x00100000] = "Network";
        PlatformCapability[PlatformCapability["Tiles"] = 0x00400000] = "Tiles";
        PlatformCapability[PlatformCapability["Proximity"] = 0x00800000] = "Proximity";
        PlatformCapability[PlatformCapability["Speech"] = 0x01000000] = "Speech";
        PlatformCapability[PlatformCapability["CloudData"] = 0x02000000] = "CloudData";
        PlatformCapability[PlatformCapability["Npm"] = 0x20000000] = "Npm";
        PlatformCapability[PlatformCapability["Cordova"] = 0x40000000] = "Cordova";
        PlatformCapability[PlatformCapability["Shell"] = 0x80000000] = "Shell";
        PlatformCapability[PlatformCapability["Current"] = 0x10000000] = "Current";
        PlatformCapability[PlatformCapability["AnyWeb"] = PlatformCapability.Location | PlatformCapability.Maps | PlatformCapability.Search | PlatformCapability.Translation | PlatformCapability.EditorOnly | PlatformCapability.MusicAndSounds | PlatformCapability.Network | PlatformCapability.CloudData] = "AnyWeb";
        PlatformCapability[PlatformCapability["iOS"] = PlatformCapability.Accelerometer | PlatformCapability.Compass | PlatformCapability.Gyroscope | PlatformCapability.Location | PlatformCapability.Maps | PlatformCapability.Orientation | PlatformCapability.Search | PlatformCapability.Translation | PlatformCapability.MusicAndSounds | PlatformCapability.Network] = "iOS";
        PlatformCapability[PlatformCapability["Android"] = PlatformCapability.Accelerometer | PlatformCapability.Camera | PlatformCapability.Compass | PlatformCapability.Gyroscope | PlatformCapability.Location | PlatformCapability.Maps | PlatformCapability.Microphone | PlatformCapability.Orientation | PlatformCapability.Search | PlatformCapability.Speech | PlatformCapability.Translation | PlatformCapability.MusicAndSounds | PlatformCapability.Network] = "Android";
        PlatformCapability[PlatformCapability["CordovaApp"] = PlatformCapability.Accelerometer | PlatformCapability.Compass | PlatformCapability.Gyroscope | PlatformCapability.Location | PlatformCapability.Orientation | PlatformCapability.MusicAndSounds | PlatformCapability.Network | PlatformCapability.Phone | PlatformCapability.Cordova] = "CordovaApp";
        PlatformCapability[PlatformCapability["AnyClient"] = PlatformCapability.Location | PlatformCapability.Maps | PlatformCapability.Search | PlatformCapability.Translation] = "AnyClient";
        PlatformCapability[PlatformCapability["All"] = ((-1) | 0) & ~PlatformCapability.Current] = "All";
    })(TDev.PlatformCapability || (TDev.PlatformCapability = {}));
    var PlatformCapability = TDev.PlatformCapability;
    var PlatformCapabilityManager;
    (function (PlatformCapabilityManager) {
        var _cap;
        function current() {
            if (!_cap) {
                _cap = PlatformCapability.AnyWeb;
                if (TDev.RT.DeviceOrientation.isHeadingSupported())
                    _cap |= 8 /* Compass */;
                if (TDev.RT.DeviceOrientation.isOrientationSupported())
                    _cap |= 16384 /* Orientation */;
                if (TDev.RT.DeviceMotion.isSupported())
                    _cap |= 1 /* Accelerometer */;
                if (TDev.RT.DeviceMotion.isGyroscopeSupported())
                    _cap |= 16 /* Gyroscope */;
                if (TDev.RT.UserMediaManager.isSupported())
                    _cap |= 4 /* Camera */;
                if (TDev.RT.Languages.isSpeechSupported())
                    _cap |= 16777216 /* Speech */;
                if (TDev.RT.AudioContextManager.isMicrophoneSupported())
                    _cap |= 512 /* Microphone */;
                if (TDev.Browser.isNodeJS)
                    _cap |= 536870912 /* Npm */;
                if (TDev.Browser.localProxy)
                    _cap |= 2147483648 /* Shell */;
            }
            return _cap;
        }
        PlatformCapabilityManager.current = current;
    })(PlatformCapabilityManager = TDev.PlatformCapabilityManager || (TDev.PlatformCapabilityManager = {}));
    (function (ImplementationStatus) {
        ImplementationStatus[ImplementationStatus["None"] = 0x00000000] = "None";
        ImplementationStatus[ImplementationStatus["Pauses"] = 0x00000001] = "Pauses";
        ImplementationStatus[ImplementationStatus["UsesStackFrame"] = 0x00000002] = "UsesStackFrame";
        ImplementationStatus[ImplementationStatus["Web"] = 0x00000010] = "Web";
        ImplementationStatus[ImplementationStatus["WebAll"] = 16 /* Web */] = "WebAll";
    })(TDev.ImplementationStatus || (TDev.ImplementationStatus = {}));
    var ImplementationStatus = TDev.ImplementationStatus;
    var Kind = (function (_super) {
        __extends(Kind, _super);
        function Kind(name, _help) {
            _super.call(this, name);
            this._help = _help;
            this.generalCapabilities = 0 /* None */;
            this.generalFlags = 0 /* None */;
            this._isImmutable = false;
            this.minSkill = 0;
            this._contexts = 0 /* None */;
            this._hasEnumerator = false;
            this._propByName = {};
            this._propList = [];
            this._icon = "";
            this._id = ++Kind.currentId;
        }
        Kind.prototype.getStemName = function () {
            return this._stemName || this.getName().toLowerCase();
        };
        Kind.prototype.getRoot = function () {
            return this;
        };
        Kind.prototype.kill = function () {
            TDev.Util.abstract();
        };
        Kind.prototype.getParameterCount = function () {
            return 0;
        };
        Kind.prototype.getParameter = function (idx) {
            return undefined;
        };
        Kind.prototype.getHtmlName = function () {
            return [this.getName()];
        };
        Kind.prototype.runtimeName = function () {
            return Api.runtimeName(this.getName());
        };
        Kind.prototype.matches = function (other) {
            if (other instanceof TDev.AST.RecordDef)
                return this.equals(other.entryKind);
        };
        Kind.prototype.equals = function (other) {
            return this == other;
        };
        Kind.prototype.helpTopic = function () {
            return TDev.Util.tagify(this._name);
        };
        Kind.prototype.isUserDefined = function () {
            return false;
        };
        Kind.prototype.isExtensionEnabled = function () {
            return false;
        };
        Kind.prototype.isImmutable = function () {
            return this._isImmutable;
        };
        Kind.prototype.md_skill = function (sk) {
            this.minSkill = sk;
        };
        Kind.prototype.md_stem = function (n) {
            this._stemName = n;
        };
        Kind.prototype.md_obsolete = function () {
            this.isObsolete = true;
        };
        Kind.prototype.md_isData = function () {
            this.isData = true;
        };
        Kind.prototype.md_private = function () {
            this.isPrivate = true;
        };
        Kind.prototype.md_builtin = function () {
            this.isBuiltin = true;
            this.isSerializable = true;
        };
        Kind.prototype.md_walltap = function () {
            this._contexts |= KindContext.General | 256 /* WallTap */;
        };
        Kind.prototype.md_enumerable = function () {
            this._contexts |= KindContext.General | 512 /* Enumerable */;
        };
        Kind.prototype.md_icon = function (name) {
            this._icon = "svg:" + name + ",white";
        };
        Kind.prototype.md_dbgOnly = function () {
            this.isDbgOnly = true;
            if (!TDev.dbg)
                this.isPrivate = true;
        };
        Kind.prototype.md_betaOnly = function () {
            this.isBetaOnly = true;
            if (!TDev.isBeta)
                this.isPrivate = true;
        };
        Kind.prototype.md_serializable = function () {
            this.isSerializable = true;
        };
        Kind.prototype.md_robust = function () {
            this.generalFlags |= 16384 /* Robust */;
        };
        Kind.prototype.md_idempotent = function () {
            this.generalFlags |= 32768 /* Idempotent */;
        };
        Kind.prototype.md_oops = function (msg) {
            throw new Error(msg + " at " + this.getName());
        };
        Kind.prototype.md_cap = function () {
            var _this = this;
            var caps = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                caps[_i - 0] = arguments[_i];
            }
            this.generalCapabilities |= Property.getPlatform(caps, function (s) { return _this.md_oops(s); });
        };
        Kind.prototype.md_immutable = function () {
            this._isImmutable = true;
        };
        Kind.prototype.md_ctx = function () {
            var ctxs = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                ctxs[_i - 0] = arguments[_i];
            }
            for (var i = 0; i < ctxs.length; ++i)
                switch (ctxs[i]) {
                    case "none":
                        this._contexts = 0 /* None */;
                        break;
                    case "general":
                        this._contexts |= KindContext.General;
                        break;
                    case "indexkey":
                        this._contexts |= 16 /* IndexKey */;
                        break;
                    case "gckey":
                        this._contexts |= 32 /* GcKey */;
                        break;
                    case "json":
                        this._contexts |= 1024 /* Json */;
                        break;
                    case "walltap":
                        this._contexts |= 256 /* WallTap */;
                        break;
                    case "enumerable":
                        this._contexts |= 512 /* Enumerable */;
                        break;
                    case "cloudfield":
                        this._contexts |= 4 /* CloudField */;
                        break;
                    default:
                        this.md_oops("unknown context " + ctxs[i]);
                }
        };
        Kind.md_make = function (usage_count, name, help, kindClass) {
            if (kindClass === void 0) { kindClass = null; }
            var k;
            if (kindClass == "action") {
                k = new ActionKind(name, help);
            }
            else if (kindClass == "parametric") {
                k = new ParametricKind(name, help);
                k._contexts = KindContext.General;
            }
            else {
                k = new Kind(name, help);
                k._contexts = KindContext.General;
            }
            k.usage_count = usage_count;
            TDev.api.md_addKind(k);
            return k;
        };
        Kind.prototype.initProperties = function () {
            var maxUsage = this._propList.map(function (p) { return p._usage_count; }).max() + 1;
            this._propList.forEach(function (p) {
                p.getUsage().apiFreq = p._usage_count / maxUsage;
            });
        };
        Kind.prototype.getContexts = function () {
            return this._contexts;
        };
        Kind.prototype.hasContext = function (k) {
            return !k || !!(this.getContexts() & k);
        };
        Kind.prototype.hasEnumerator = function () {
            return this._hasEnumerator;
        };
        Kind.prototype.isError = function () {
            return false;
        };
        Kind.prototype.listPriority = function () {
            return this.isBuiltin ? 10 : 0;
        };
        Kind.prototype.getRecord = function () {
            return null;
        };
        Kind.defaultValueDescription = function (k) {
            switch (k.getName()) {
                case "Number": return "0";
                case "String": return "\"\"";
                case "Boolean": return "false";
                case "DateTime": return "01/01/0000 00:00:00";
                default: return "the invalid value";
            }
        };
        Kind.prototype.icon = function () {
            return this._icon;
        };
        Kind.prototype.getHelp = function (account) {
            if (account === void 0) { account = true; }
            return TDev.lf_static(this._help, account);
        };
        Kind.prototype.shortName = function () {
            return null;
        };
        Kind.prototype.md_addProperty = function (p) {
            this._propList.push(p);
            this._propByName[p.getName()] = p;
            p._addFlags(this.generalFlags);
        };
        Kind.prototype.initSingleton = function () {
            if (!this.isData) {
                this._contexts = 0 /* None */;
                this.singleton = TDev.AST.mkSingletonDef(this.getName().toLowerCase(), this);
            }
        };
        Kind.prototype.getProperty = function (name) {
            if (!this._propByName.hasOwnProperty(name)) {
                var e = this.singletonExtensions();
                if (e && e.actions.hasOwnProperty(name))
                    return e.actions[name];
                return null;
            }
            return this._propByName[name];
        };
        Kind.prototype.singletonExtensions = function () {
            if (this.isData || !TDev.Script)
                return null;
            return TDev.Script.libNamespaceCache.extensions[this.getName()];
        };
        Kind.prototype.listProperties = function () {
            var e = this.singletonExtensions();
            if (e)
                return this._propList.concat(e.actionList);
            return this._propList;
        };
        Kind.prototype.toString = function () {
            return this.getName();
        };
        Kind.prototype.isEnumerable = function () {
            return this.hasContext(512 /* Enumerable */);
        };
        Kind.prototype.getDescription = function () {
            return this.getHelp();
        };
        Kind.prototype.toJson = function () {
            return this.getName();
        };
        Kind.prototype.getPropPrefix = function () {
            var par = this.toString();
            if (this.isData)
                par = "(" + par + ")";
            else
                par = par.toLowerCase();
            return par;
        };
        Kind.prototype.serialize = function () {
            var tw = TDev.AST.TokenWriter.forStorage();
            tw.kind(null, this);
            return tw.finalize(true);
        };
        Kind.prototype.parentLibrary = function () {
            return null;
        };
        Kind.currentId = 0;
        return Kind;
    })(ApiNode);
    TDev.Kind = Kind;
    var UnresolvedKind = (function (_super) {
        __extends(UnresolvedKind, _super);
        function UnresolvedKind(name) {
            _super.call(this, name, "a type yet unknown");
        }
        UnresolvedKind.prototype.isUserDefined = function () {
            return true;
        };
        UnresolvedKind.prototype.isError = function () {
            return true;
        };
        return UnresolvedKind;
    })(Kind);
    TDev.UnresolvedKind = UnresolvedKind;
    var KindVariable = (function (_super) {
        __extends(KindVariable, _super);
        function KindVariable(name, parent) {
            _super.call(this, name, "a type parameter");
            this.parent = parent;
        }
        return KindVariable;
    })(Kind);
    TDev.KindVariable = KindVariable;
    var ParametricKind = (function (_super) {
        __extends(ParametricKind, _super);
        function ParametricKind(name, help) {
            _super.call(this, name, help);
            this.generatedInitialSize = 0;
            this.root = this;
            this.propsInstantiated = true;
            this.generated = [];
        }
        ParametricKind.prototype.matches = function (other) {
            return _super.prototype.matches.call(this, other) || this.parameters.some(function (p) { return p.matches(other); });
        };
        ParametricKind.prototype.cleanup = function () {
            if (this.generated) {
                if (this.generatedInitialSize == 0)
                    this.generated = [];
                else
                    this.generated.splice(this.generatedInitialSize, this.generated.length);
            }
        };
        ParametricKind.prototype.markInitial = function () {
            if (!this.parameterPrefixes)
                this.parameterPrefixes = this.parameters.map(function (_) { return "of"; });
            this.generatedInitialSize = this.generated.length;
        };
        ParametricKind.prototype.subst = function (k) {
            var _this = this;
            if (k instanceof KindVariable) {
                var idx = this.root.parameters.indexOf(k);
                if (idx >= 0)
                    return this.parameters[idx];
                else
                    return k;
            }
            if (k instanceof ParametricKind) {
                var pk = k;
                var newArgs = pk.parameters.map(function (x) { return _this.subst(x); });
                for (var i = 0; i < newArgs.length; ++i)
                    if (newArgs[i] != pk.parameters[i])
                        break;
                if (i < newArgs.length)
                    return pk.createInstance(newArgs);
            }
            return k;
        };
        ParametricKind.prototype.hasEnumerator = function () {
            return this.root == this ? _super.prototype.hasEnumerator.call(this) : this.root.hasEnumerator();
        };
        ParametricKind.prototype.getRoot = function () {
            return this.root;
        };
        ParametricKind.prototype.getParameterCount = function () {
            return this.parameters.length;
        };
        ParametricKind.prototype.getSignature = function () {
            return this.root == this ? this.root.parameterPrefixes.map(function (p) { return " " + p + " ..."; }).join("") : "";
        };
        ParametricKind.prototype.getName = function () {
            if (this == this.root)
                return this._name;
            var res = this._name;
            for (var i = 0; i < this.parameters.length; ++i) {
                res += " " + this.root.parameterPrefixes[i] + " " + this.parameters[i].getName();
            }
            return res;
        };
        ParametricKind.prototype.createInstance = function (args) {
            if (this.parameters.length == 0)
                return this.root;
            if (this.root != this)
                return this.root.createInstance(args);
            var r = this.generated.filter(function (g) {
                for (var i = 0; i < args.length; ++i)
                    if (!g.parameters[i].equals(args[i]))
                        return false;
                return true;
            })[0];
            if (r)
                return r;
            r = TDev.Util.clone(this);
            r._propList = [];
            r._propByName = {};
            r.propsInstantiated = false;
            r.parameters = args;
            this.generated.push(r);
            return r;
        };
        ParametricKind.prototype.listProperties = function () {
            this.instantiateProps();
            return _super.prototype.listProperties.call(this);
        };
        ParametricKind.prototype.getProperty = function (n) {
            this.instantiateProps();
            return _super.prototype.getProperty.call(this, n);
        };
        ParametricKind.prototype.instantiateProps = function () {
            var _this = this;
            if (this.propsInstantiated)
                return;
            this.propsInstantiated = true;
            this.root.listProperties().forEach(function (p) {
                if (p.availableOnlyOn && p.availableOnlyOn.indexOf(_this.parameters[0]) < 0)
                    return;
                _this.md_addProperty(p.substFor(_this));
            });
        };
        ParametricKind.prototype.getParameter = function (idx) {
            return this.parameters[idx];
        };
        ParametricKind.prototype.getParameterPrefix = function (idx) {
            return this.root.parameterPrefixes[idx];
        };
        ParametricKind.prototype.md_parametric = function () {
            var _this = this;
            var argNames = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                argNames[_i - 0] = arguments[_i];
            }
            this.parameters = argNames.map(function (n) { return new KindVariable(n, _this); });
        };
        ParametricKind.prototype.md_parameterPrefixes = function () {
            var argNames = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                argNames[_i - 0] = arguments[_i];
            }
            this.parameterPrefixes = argNames;
        };
        ParametricKind.prototype.listPriority = function () {
            return this.root.getName() == "Collection" ? 5 : 0;
        };
        ParametricKind.prototype.isError = function () {
            return this.parameters.some(function (p) { return p != TDev.api.core.Nothing && (!p.hasContext(1 /* Parameter */) || p.isError()); });
        };
        ParametricKind.prototype.getContexts = function () {
            var ctx = _super.prototype.getContexts.call(this);
            if ((ctx & 1024 /* Json */) && this.parameters.some(function (p) { return !p.hasContext(1024 /* Json */); }))
                ctx = ctx & ~1024 /* Json */;
            return ctx;
        };
        return ParametricKind;
    })(Kind);
    TDev.ParametricKind = ParametricKind;
    var ActionKind = (function (_super) {
        __extends(ActionKind, _super);
        function ActionKind(name, help) {
            _super.call(this, name, help);
            this.parameters = [];
            this.isAction = true;
            this._isAtomic = false;
        }
        ActionKind.prototype.md_isAction = function () {
        };
        ActionKind.prototype.md_isAtomic = function () {
            this._isAtomic = true;
        };
        ActionKind.prototype.isImmutable = function () {
            return true;
        };
        ActionKind.prototype.icon = function () {
            return "svg:Bolt,white";
        };
        ActionKind.prototype.getInParameters = function () {
            return this.getProperty("run").getParameters().slice(1);
        };
        ActionKind.prototype.getOutParameters = function () {
            var app = this.getProperty("run");
            if (app.getResult().getKind() == TDev.api.core.Nothing)
                return [];
            return [app.getResult()];
        };
        ActionKind.prototype.getSignature = function () {
            var s = this.getInParameters().map(function (p) { return p.getName() + ":" + p.getKind(); }).join(", ");
            var outParm = this.getOutParameters()[0];
            var resKind = outParm ? outParm.getKind() : null;
            if (!resKind || resKind == TDev.api.core.Nothing) {
                return "(" + s + ")";
            }
            else {
                if (s != "")
                    return "(" + s + ") : " + resKind.toString();
                else
                    return "() : " + resKind.toString();
            }
        };
        ActionKind.prototype.isAtomic = function () {
            return this._isAtomic;
        };
        ActionKind.prototype.initProperties = function () {
            _super.prototype.initProperties.call(this);
            var prop = this.getProperty("run");
            prop.md_resumes();
            if (!this.isAtomic())
                prop.md_async();
        };
        return ActionKind;
    })(ParametricKind);
    TDev.ActionKind = ActionKind;
    var UserActionKind = (function (_super) {
        __extends(UserActionKind, _super);
        function UserActionKind(userAction) {
            _super.call(this, userAction.getName(), userAction.getDescription());
            this.userAction = userAction;
            this._contexts = KindContext.General;
            this.isData = true;
            this.md_addProperty(new UserActionRunProperty(this));
            var invl = Property.md_make(0, this, "is invalid", TDev.lf("Returns true if the current instance is useless"), [], TDev.api.core.Boolean);
            invl.md_runOnInvalid();
            this.md_addProperty(invl);
        }
        UserActionKind.prototype.isAtomic = function () {
            return this.userAction.isAtomic;
        };
        UserActionKind.prototype.getOutParameters = function () {
            var _this = this;
            return this.userAction.getOutParameters().map(function (p) { return _this.userAction.mkPP(p.getName(), p.getKind()); });
        };
        UserActionKind.prototype.getName = function () {
            return this.userAction.getName();
        };
        UserActionKind.prototype.isUserDefined = function () {
            return true;
        };
        UserActionKind.prototype.kill = function () {
            this.deleted = true;
        };
        UserActionKind.prototype.isError = function () {
            return _super.prototype.isError.call(this) || this.deleted || this.userAction.deleted;
        };
        UserActionKind.prototype.parentLibrary = function () {
            return this.userAction.parentLibrary();
        };
        UserActionKind.prototype.listPriority = function () {
            return 4;
        };
        return UserActionKind;
    })(ActionKind);
    TDev.UserActionKind = UserActionKind;
    var ThingSetKind = (function (_super) {
        __extends(ThingSetKind, _super);
        function ThingSetKind(name, help, getProps, _theShortName) {
            _super.call(this, name, help);
            this.getProps = getProps;
            this._theShortName = _theShortName;
            this.usage_count = -1;
            TDev.api.md_addKind(this);
        }
        ThingSetKind.prototype.listProperties = function () {
            return this.getProps().map(Property.withParent(this));
        };
        ThingSetKind.prototype.getHelp = function () {
            return this._help;
        };
        ThingSetKind.prototype.shortName = function () {
            return this._theShortName;
        };
        ThingSetKind.prototype.getProperty = function (name) {
            var a = this.getProps().filter(function (a) { return a.getName() == name; });
            if (!a[0])
                return undefined;
            return Property.withParent(this)(a[0]);
        };
        ThingSetKind.prototype.initSingleton = function () {
            var _this = this;
            _super.prototype.initSingleton.call(this);
            this.singleton.usageMult = function () {
                if (_this.getProps().length > 0)
                    return 1;
                else
                    return 1e-10;
            };
        };
        return ThingSetKind;
    })(Kind);
    TDev.ThingSetKind = ThingSetKind;
    var MultiplexKind = (function (_super) {
        __extends(MultiplexKind, _super);
        function MultiplexKind(args) {
            _super.call(this, "Unfinished Type", "not fully specified generic API");
            this.args = args;
        }
        MultiplexKind.prototype.getKinds = function () {
            return TDev.Script.getKinds().filter(function (k) { return k.isData; });
        };
        MultiplexKind.argsFor = function (k) {
            if (!(k instanceof ParametricKind))
                return [];
            return TDev.Util.range(0, k.getParameterCount()).map(function (i) {
                return {
                    ofKind: k,
                    idx: i,
                    prefix: i == 0 ? "" : k.getParameterPrefix(i) + " "
                };
            });
        };
        MultiplexKind.prototype.createFinal = function (k) {
            var args = [k];
            var p = this.parentProp;
            while (!(p instanceof MultiplexRootProperty)) {
                var mp = p;
                args.push(mp.forKind);
                p = mp.parentKind.parentProp;
            }
            args.reverse();
            var idx = 0;
            var parseType = function () {
                var a = args[idx++];
                if (a instanceof ParametricKind) {
                    var pk = a;
                    if (pk.getRoot() != pk)
                        return pk;
                    return pk.createInstance(TDev.Util.range(0, pk.getParameterCount()).map(function (_) { return parseType(); }));
                }
                else
                    return a;
            };
            var rp = p;
            var res = rp.instanceFor(this, k, rp.getResult().getKind().args.map(function (_) { return parseType(); }));
            res.getParameters()[0]._kind = this;
            return res;
        };
        MultiplexKind.propName = function (k) {
            var n = "";
            if (k.parentLibrary() && !k.parentLibrary().isThis())
                n += TDev.AST.libSymbol + k.parentLibrary().getName() + "\u200A\u2192\u00A0" + k.getName();
            else if (k.isUserDefined())
                n += TDev.AST.recordSymbol + k.getName();
            else
                n += k.getRoot().getName();
            if (k.getParameterCount() > 0)
                n += " " + k.getParameterPrefix(0);
            return n;
        };
        MultiplexKind.prototype.getNameFor = function (k) {
            return this.args[0].prefix + MultiplexKind.propName(k);
        };
        MultiplexKind.prototype.mkProp = function (args1, k) {
            var argsN = args1;
            if (k.getParameterCount() > 0)
                argsN = MultiplexKind.argsFor(k).concat(argsN);
            if (argsN.length == 0)
                return this.createFinal(k);
            return new MultiplexProperty(k, this, new MultiplexKind(argsN));
        };
        MultiplexKind.prototype.getProperty = function (name) {
            var _this = this;
            var k = this.getKinds().filter(function (k) { return _this.getNameFor(k) == name; })[0];
            if (k)
                return this.mkProp(this.args.slice(1), k);
        };
        MultiplexKind.prototype.listProperties = function () {
            var _this = this;
            var args1 = this.args.slice(1);
            return this.getKinds().map(function (k) { return _this.mkProp(args1, k); });
        };
        return MultiplexKind;
    })(Kind);
    TDev.MultiplexKind = MultiplexKind;
    (function (PropertyCategory) {
        PropertyCategory[PropertyCategory["Builtin"] = 0] = "Builtin";
        PropertyCategory[PropertyCategory["Action"] = 1] = "Action";
        PropertyCategory[PropertyCategory["Data"] = 2] = "Data";
        PropertyCategory[PropertyCategory["Library"] = 3] = "Library";
        PropertyCategory[PropertyCategory["Record"] = 4] = "Record";
    })(TDev.PropertyCategory || (TDev.PropertyCategory = {}));
    var PropertyCategory = TDev.PropertyCategory;
    (function (PropertyFlags) {
        PropertyFlags[PropertyFlags["None"] = 0x0000] = "None";
        PropertyFlags[PropertyFlags["RunOnInvalidArguments"] = 0x0001] = "RunOnInvalidArguments";
        PropertyFlags[PropertyFlags["IsObsolete"] = 0x0002] = "IsObsolete";
        PropertyFlags[PropertyFlags["IsHidden"] = 0x0004] = "IsHidden";
        PropertyFlags[PropertyFlags["IsPrivate"] = 0x0008] = "IsPrivate";
        PropertyFlags[PropertyFlags["NeedsTracing"] = 0x0010] = "NeedsTracing";
        PropertyFlags[PropertyFlags["NeedsTracing2"] = 0x0020] = "NeedsTracing2";
        PropertyFlags[PropertyFlags["NeedsTimestamping"] = 0x0040] = "NeedsTimestamping";
        PropertyFlags[PropertyFlags["NeedsTimestamping2"] = 0x0080] = "NeedsTimestamping2";
        PropertyFlags[PropertyFlags["HasPauseContinue"] = 0x0100] = "HasPauseContinue";
        PropertyFlags[PropertyFlags["HasPauseContinue2"] = 0x0200] = "HasPauseContinue2";
        PropertyFlags[PropertyFlags["IsDebugOnly"] = 0x0400] = "IsDebugOnly";
        PropertyFlags[PropertyFlags["Preserves"] = 0x0800] = "Preserves";
        PropertyFlags[PropertyFlags["Async"] = 0x1000] = "Async";
        PropertyFlags[PropertyFlags["IsBetaOnly"] = 0x2000] = "IsBetaOnly";
        PropertyFlags[PropertyFlags["Robust"] = 0x4000] = "Robust";
        PropertyFlags[PropertyFlags["Idempotent"] = 0x8000] = "Idempotent";
        PropertyFlags[PropertyFlags["NoCanvas"] = 0x10000] = "NoCanvas";
        PropertyFlags[PropertyFlags["HideIntelliButton"] = 0x20000] = "HideIntelliButton";
        PropertyFlags[PropertyFlags["IgnoreReturnValue"] = 0x40000] = "IgnoreReturnValue";
        PropertyFlags[PropertyFlags["DocsOnly"] = 0x80000] = "DocsOnly";
        PropertyFlags[PropertyFlags["LibsOnly"] = 0x100000] = "LibsOnly";
        PropertyFlags[PropertyFlags["NonBrowsable"] = 2 /* IsObsolete */ | 4 /* IsHidden */ | 8 /* IsPrivate */] = "NonBrowsable";
    })(TDev.PropertyFlags || (TDev.PropertyFlags = {}));
    var PropertyFlags = TDev.PropertyFlags;
    (function (ParameterFlags) {
        ParameterFlags[ParameterFlags["None"] = 0x0000] = "None";
        ParameterFlags[ParameterFlags["WritesMutable"] = 0x0001] = "WritesMutable";
        ParameterFlags[ParameterFlags["ReadsMutable"] = 0x0002] = "ReadsMutable";
    })(TDev.ParameterFlags || (TDev.ParameterFlags = {}));
    var ParameterFlags = TDev.ParameterFlags;
    var Property = (function (_super) {
        __extends(Property, _super);
        function Property(parentKind, name, _help, parms, retType) {
            _super.call(this, name);
            this.parentKind = parentKind;
            this._help = _help;
            this._infixPriority = 0;
            this._explicitPlatform = 0 /* None */;
            this._implStatus = ImplementationStatus.WebAll;
            this.flags = 0;
            parms.unshift(PropertyParameter.md_make("this", parentKind));
            this._inParameters = parms;
            this._usage_count = 0;
            this._result = PropertyParameter.md_make("result", retType);
            this._platform = this.parentKind ? this.parentKind.generalCapabilities : 0 /* None */;
            this._usage = new TokenUsage(this);
            for (var i = 0; i < parms.length; ++i)
                parms[i].parentProperty = this;
            this._result.parentProperty = this;
        }
        Property.prototype.isExtensionAction = function () {
            return false;
        };
        Property.prototype.substFor = function (par) {
            return this.substForInternal(par, null);
        };
        Property.prototype.substForInternal = function (par, mk) {
            var params = this._inParameters.slice(1).map(function (p) { return p.substFor(par); });
            var rk = par.subst(this._result.getKind());
            var r = mk ? mk(params, rk) : new Property(par, this._name, this._help, params, rk);
            params.forEach(function (p) {
                p.parentProperty = r;
            });
            if (!r._inParameters[0] || !this._inParameters[0]) {
                TDev.Util.oops("no inparms, len=" + this._inParameters.length + "; " + this.parentKind.getName() + "->" + this.getName());
            }
            r._inParameters[0]._flags = this._inParameters[0]._flags;
            r.flags = this.flags;
            r._runtimeName = this._runtimeName;
            r._infixPriority = this._infixPriority;
            r._specialApply = this._specialApply;
            r._implStatus = this._implStatus;
            return r;
        };
        Property.md_make = function (usage_count, parentKind, name, help, parms, retType) {
            var p = new Property(parentKind, name, help, parms, retType);
            p._usage_count = usage_count;
            parentKind.md_addProperty(p);
            return p;
        };
        Property.prototype.runtimeName = function () {
            return this._runtimeName || Api.runtimeName(this.getName());
        };
        Property.prototype.helpTopic = function () {
            if (!this.topicCache)
                this.topicCache = TDev.Util.tagify(this.parentKind.helpTopic() + " " + (this._runtimeName || this.getName()));
            return this.topicCache;
        };
        Property.prototype.usageKey = function () {
            if (!this.usageKeyCache)
                this.usageKeyCache = TDev.Util.tagify(this._runtimeName || this.getName());
            return this.usageKeyCache;
        };
        Property.prototype.canRename = function () {
            return false;
        };
        Property.prototype._addFlags = function (f) {
            this.flags |= f;
        };
        Property.prototype.md_async = function () {
            if (this._implStatus & 1 /* Pauses */)
                this.flags |= 4096 /* Async */;
            else
                this.md_oops("async specified on method with no ResumeCtx");
        };
        Property.prototype.md_authAsync = function () {
            this._asyncReason = "auth";
        };
        Property.prototype.md_uiAsync = function () {
            this._asyncReason = "ui";
        };
        Property.prototype.md_quickAsync = function () {
            this._asyncReason = "quick";
        };
        Property.prototype.md_picAsync = function () {
            this._asyncReason = "pic";
        };
        Property.prototype.md_cachedAsync = function () {
            this._asyncReason = "cached";
        };
        Property.prototype.asyncReason = function () {
            if (!(this._implStatus & 1 /* Pauses */))
                return null;
            if (this._asyncReason)
                return this._asyncReason;
            if (this.getFlags() & 4096 /* Async */)
                return "async";
            if (this.getFlags() & 2 /* IsObsolete */)
                return "obsolete";
            if (!this.isImplemented())
                return "unimplemented";
            return "todo";
        };
        Property.prototype.md_runOnInvalid = function () {
            this.flags |= 1 /* RunOnInvalidArguments */;
        };
        Property.prototype.md_obsolete = function () {
            this.flags |= 2 /* IsObsolete */ | 4 /* IsHidden */;
        };
        Property.prototype.md_hidden = function () {
            this.flags |= 4 /* IsHidden */;
        };
        Property.prototype.md_private = function () {
            this.flags |= 8 /* IsPrivate */;
        };
        Property.prototype.md_ignoreReturnValue = function () {
            this.flags |= 262144 /* IgnoreReturnValue */;
        };
        Property.prototype.md_dbgOnly = function () {
            this.flags |= 1024 /* IsDebugOnly */;
        };
        Property.prototype.md_docsOnly = function () {
            this.flags |= 524288 /* DocsOnly */;
        };
        Property.prototype.md_betaOnly = function () {
            this.flags |= 8192 /* IsBetaOnly */;
        };
        Property.prototype.md_preserves = function () {
            this.flags |= 2048 /* Preserves */;
        };
        Property.prototype.md_tandre2 = function () {
            this.flags |= 32 /* NeedsTracing2 */ | 128 /* NeedsTimestamping2 */ | 512 /* HasPauseContinue2 */;
        };
        Property.prototype.md_trace2 = function () {
            this.flags |= 32 /* NeedsTracing2 */;
        };
        Property.prototype.md_timestamp2 = function () {
            this.flags |= 128 /* NeedsTimestamping2 */;
        };
        Property.prototype.md_hasPauseContinue2 = function () {
            this.flags |= 512 /* HasPauseContinue2 */;
        };
        Property.prototype.md_tandre = function () {
            this.flags |= 16 /* NeedsTracing */ | 64 /* NeedsTimestamping */;
        };
        Property.prototype.md_trace = function () {
            this.flags |= 16 /* NeedsTracing */;
        };
        Property.prototype.md_timestamp = function () {
            this.flags |= 64 /* NeedsTimestamping */;
        };
        Property.prototype.md_hasPauseContinue = function () {
            this.flags |= 256 /* HasPauseContinue */;
        };
        Property.prototype.md_robust = function () {
            this.flags |= 16384 /* Robust */;
        };
        Property.prototype.md_nonRobust = function () {
            this.flags &= ~16384 /* Robust */;
        };
        Property.prototype.md_idempotent = function () {
            this.flags |= 32768 /* Idempotent */;
        };
        Property.prototype.md_noCanvas = function () {
            this.flags |= 65536 /* NoCanvas */;
        };
        Property.prototype.md_jsName = function (n) {
            this._runtimeName = n;
        };
        Property.prototype.md_infixPriority = function (n) {
            this._infixPriority = n;
            TDev.api.operatorKeys[this.getName()] = 1;
        };
        Property.prototype.md_inlineApply = function (n) {
            this._specialApply = n;
        };
        Property.prototype.md_flow = function (n) {
        };
        Property.prototype.md_allowInRestricted = function () {
            this.allowInRestricted = true;
        };
        Property.prototype.md_writesMutable = function () {
            this._inParameters[0].md_writesMutable();
        };
        Property.prototype.md_readsMutable = function () {
            this._inParameters[0].md_readsMutable();
        };
        Property.prototype.md_allocates = function () {
            this.getResult().md_writesMutable();
        };
        Property.prototype.md_onlyOn = function () {
            var s = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                s[_i - 0] = arguments[_i];
            }
            this.availableOnlyOn = s.map(function (ss) { return TDev.api.getKind(ss); });
        };
        Property.prototype.md_import = function (manager, name, version) {
            if (!this._imports)
                this._imports = [];
            this._imports.push({ manager: manager, name: name, version: version || "*" });
        };
        Property.prototype.md_oldName = function (s) {
            var pref = this.parentKind.getName() + "->";
            if (/->/.test(s))
                s = TDev.Util.capitalizeFirst(s);
            else
                s = pref + s;
            if (TDev.Util.startsWith(s, pref))
                TDev.AST.propRenames[s] = this.getName();
            else {
                var m = /(.*)->(.*)/.exec(s);
                var k = TDev.api.getKind(m[1]);
                if (!k)
                    this.md_oops("no such kind: " + m[1]);
                TDev.AST.crossKindRenames[k.getName().toLowerCase() + "->" + m[2]] = this.parentKind.getName().toLowerCase() + "->" + this.getName();
            }
        };
        Property.prototype.getImports = function () {
            return this._imports;
        };
        Property.prototype.md_oops = function (msg) {
            throw new Error(msg + " at " + this.parentKind.toString() + "->" + this.getName());
        };
        Property.prototype.md_stub = function () {
            var platforms = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                platforms[_i - 0] = arguments[_i];
            }
            this._implStatus = this._implStatus & ~ImplementationStatus.WebAll;
            for (var i = 0; i < platforms.length; ++i)
                switch (platforms[i]) {
                    case "": break;
                    default: this.md_oops("unknown platform for stub " + platforms[i]);
                }
        };
        Property.getPlatform = function (caps, oops) {
            var r = 0;
            for (var i = 0; i < caps.length; ++i) {
                if (caps[i] == "none")
                    continue;
                var c = TDev.AST.App.capabilityByName(caps[i]);
                if (c != 0 /* None */)
                    r |= c;
                else
                    oops("unknown platform cap " + caps[i]);
            }
            return r;
        };
        Property.prototype.md_cap = function () {
            var _this = this;
            var caps = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                caps[_i - 0] = arguments[_i];
            }
            if (this._md_cap_set)
                this.md_oops("cap() called twice; use cap(foo,bar) instead");
            this._md_cap_set = true;
            this._platform = Property.getPlatform(caps, function (s) { return _this.md_oops(s); });
            this._explicitPlatform = this._platform;
        };
        Property.prototype.md_embedsLink = function (from, to) {
        };
        Property.prototype.md_resumes = function () {
            this._implStatus |= 1 /* Pauses */;
        };
        Property.prototype.md_needsFrame = function () {
            this._implStatus |= 2 /* UsesStackFrame */;
        };
        Property.prototype.md_arg = function (name) {
            if (name == "result")
                return this.getResult();
            var r = this._inParameters.filter(function (p) { return p.getName() == name; })[0];
            if (!r) {
                TDev.Util.log("wrong annotations: parameter '" + name + "' doesn't exist on " + this.parentKind.toString() + "->" + this.getName());
                return PropertyParameter.md_make(name, this.parentKind);
            }
            return r;
        };
        Property.prototype.canCacheSearch = function () {
            return true;
        };
        Property.prototype.getFlags = function () {
            return this.flags;
        };
        Property.prototype.getInfixPriority = function () {
            return this._infixPriority;
        };
        Property.prototype.getCapability = function () {
            return this._platform;
        };
        Property.prototype.getExplicitCapability = function () {
            return this._explicitPlatform;
        };
        Property.prototype.shouldPauseInterperter = function () {
            return !!(this._implStatus & 1 /* Pauses */);
        };
        Property.prototype.isImplemented = function () {
            return !!(this._implStatus & TDev.api.core.currentPlatformImpl);
        };
        Property.prototype.isImplementedAnywhere = function () {
            return !!(this._implStatus & ImplementationStatus.WebAll);
        };
        Property.prototype.getSpecialApply = function () {
            return this._specialApply;
        };
        Property.prototype.needsSpecialTracing = function () {
            var mask = 32 /* NeedsTracing2 */ | 128 /* NeedsTimestamping2 */ | 512 /* HasPauseContinue2 */;
            return (this.getFlags() & mask) == mask;
        };
        Property.prototype.needsTracing = function () {
            return !!(this.getFlags() & (16 /* NeedsTracing */ | 32 /* NeedsTracing2 */));
        };
        Property.prototype.needsTimestamping = function () {
            return !!(this.getFlags() & (64 /* NeedsTimestamping */ | 128 /* NeedsTimestamping2 */));
        };
        Property.prototype.hasPauseContinue = function () {
            return !!(this.getFlags() & (256 /* HasPauseContinue */ | 512 /* HasPauseContinue2 */));
        };
        Property.withParent = function (par) {
            return function (p) {
                p.parentKind = par;
                return p;
            };
        };
        Property.prototype.getUsage = function () {
            return this._usage;
        };
        Property.prototype.getResult = function () {
            return this._result;
        };
        Property.prototype.getParameters = function () {
            return this._inParameters;
        };
        Property.prototype.getHelp = function (account) {
            if (account === void 0) { account = true; }
            return TDev.lf_static(this._help, account);
        };
        Property.prototype.isBeta = function () {
            return (this.parentKind && this.parentKind.isBetaOnly) || !!(this.getFlags() & 8192 /* IsBetaOnly */);
        };
        Property.prototype.getDescription = function (skip) {
            var h = this.getHelp(!skip);
            if ((this.parentKind && this.parentKind.isDbgOnly) || this.getFlags() & 1024 /* IsDebugOnly */)
                h = "[**dbg**] " + h;
            else if (this.isBeta())
                h = "[**beta**] " + h;
            if (this.flags & 2 /* IsObsolete */)
                h = "[**obsolete**] " + h;
            if (!this.isImplementedAnywhere())
                h = "[**not implemented**] " + h;
            return h;
        };
        Property.prototype.getCategory = function () {
            return 0 /* Builtin */;
        };
        Property.prototype.isQuick = function () {
            return false;
        };
        Property.prototype.forwardsTo = function () {
            return null;
        };
        Property.prototype.forwardsToStmt = function () {
            return null;
        };
        Property.prototype.isBrowsable = function () {
            return ((this.flags & PropertyFlags.NonBrowsable) == 0 && (!this.parentKind.isPrivate) && ((this.flags & 524288 /* DocsOnly */) == 0 || !TDev.Script || TDev.Script.isDocsTopic()) && ((this.flags & 1048576 /* LibsOnly */) == 0 || !TDev.Script || TDev.Script.isLibrary) && (TDev.dbg || !(this.flags & 1024 /* IsDebugOnly */)) && (TDev.isBeta || !(this.flags & 8192 /* IsBetaOnly */)));
        };
        Property.prototype.showIntelliButton = function () {
            return !(this.flags & 131072 /* HideIntelliButton */);
        };
        Property.getSignatureCore = function (pp) {
            var s = pp.getParameters().slice(1).map(function (p) { return p.getName(); }).join(", ");
            var resKind = pp.getResult().getKind();
            if (!resKind || resKind == TDev.api.core.Nothing) {
                return "(" + s + ")";
            }
            else {
                if (s != "")
                    return "(" + s + ") : " + resKind.toString();
                else if (resKind == TDev.api.core.Unknown)
                    return "";
                else
                    return " : " + resKind.toString();
            }
        };
        Property.prototype.getSignature = function () {
            return Property.getSignatureCore(this);
        };
        Property.prototype.getName = function () {
            if (this.useFullName)
                return this.parentKind.getPropPrefix() + this.getArrow() + this._name;
            else
                return this._name;
        };
        Property.prototype.isRefMethod = function () {
            return this.parentKind.getRoot() == TDev.api.core.Ref && this._name.slice(0, 1) == TDev.api.core.refPropPrefix;
        };
        Property.prototype.getArrow = function () {
            if (this.isRefMethod())
                return "\u200A\u2192\u200A";
            return "\u200A\u2192\u00A0";
        };
        return Property;
    })(ApiNode);
    TDev.Property = Property;
    var UserActionRunProperty = (function (_super) {
        __extends(UserActionRunProperty, _super);
        function UserActionRunProperty(parentActionKind) {
            _super.call(this, parentActionKind, "run", parentActionKind.userAction.getDescription(), [], TDev.api.core.Nothing);
            this.parentActionKind = parentActionKind;
        }
        UserActionRunProperty.prototype.getFlags = function () {
            return this.parentActionKind.isAtomic() ? 0 /* None */ : 4096 /* Async */;
        };
        UserActionRunProperty.prototype.getResult = function () {
            return this.parentActionKind.userAction.getResult();
        };
        UserActionRunProperty.prototype.getParameters = function () {
            var act = this.parentActionKind.userAction;
            var parms = act.getParameters().slice(1);
            parms.unshift(act.mkPP("this", this.parentKind));
            return parms;
        };
        return UserActionRunProperty;
    })(Property);
    var UnresolvedProperty = (function (_super) {
        __extends(UnresolvedProperty, _super);
        function UnresolvedProperty(par, name) {
            _super.call(this, par, name, "i cannot find " + name + " on " + par.toString(), [], TDev.api.core.Unknown);
        }
        return UnresolvedProperty;
    })(Property);
    TDev.UnresolvedProperty = UnresolvedProperty;
    var PropertyParameter = (function (_super) {
        __extends(PropertyParameter, _super);
        function PropertyParameter(name, kind) {
            _super.call(this, name);
            this._flags = 0;
            this._kind = kind;
        }
        PropertyParameter.md_make = function (name, kind) {
            return new PropertyParameter(name, kind);
        };
        PropertyParameter.prototype.md_defl = function (v) {
            this.getDefaultValue = function () { return [TDev.AST.mkLit(v)]; };
        };
        PropertyParameter.prototype.md_deflExpr = function (s) {
            this.getDefaultValue = function () { return TDev.AST.Parser.parseExprHolder(s).tokens; };
        };
        PropertyParameter.prototype.md_lang = function (s) {
            this.languageHint = s;
        };
        PropertyParameter.prototype.setDeflStrings = function (v) {
            var _this = this;
            this._stringValues = v;
            if (!this.hasOwnProperty('getDefaultValue')) {
                this.getDefaultValue = function () { return [TDev.AST.mkLit(_this.getKind() == TDev.api.core.Number ? parseFloat(v[0]) : _this.getKind() == TDev.api.core.Boolean ? v[0] == "true" : v[0])]; };
            }
        };
        PropertyParameter.prototype.setDeflStringArtIds = function (v) {
            this._stringValueArtIds = v;
        };
        PropertyParameter.prototype.md_deflStrings = function () {
            var v = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                v[_i - 0] = arguments[_i];
            }
            this.setDeflStrings(v);
        };
        PropertyParameter.prototype.md_writesMutable = function () {
            this._flags |= 1 /* WritesMutable */;
        };
        PropertyParameter.prototype.md_readsMutable = function () {
            this._flags |= 2 /* ReadsMutable */;
        };
        PropertyParameter.prototype.getKind = function () {
            return this._kind || TDev.api.core.Nothing;
        };
        PropertyParameter.prototype.getFlags = function () {
            return this._flags;
        };
        PropertyParameter.prototype.getDefaultValue = function () {
            return null;
        };
        PropertyParameter.prototype.getStringValues = function () {
            return this._stringValues;
        };
        PropertyParameter.prototype.getStringValueArtIds = function () {
            return this._stringValueArtIds;
        };
        PropertyParameter.prototype.substFor = function (par) {
            var r = new PropertyParameter(this.getName(), par.subst(this._kind));
            r._stringValues = this._stringValues;
            r._stringValueArtIds = this._stringValueArtIds;
            r._flags = this._flags;
            return r;
        };
        return PropertyParameter;
    })(ApiNode);
    TDev.PropertyParameter = PropertyParameter;
    var MultiplexRootProperty = (function (_super) {
        __extends(MultiplexRootProperty, _super);
        function MultiplexRootProperty(_parametricKind, parentKind, name, desc, parms, retType) {
            _super.call(this, parentKind, name, desc, parms, retType);
            this._parametricKind = _parametricKind;
            var mk = new MultiplexKind(MultiplexKind.argsFor(this._parametricKind));
            mk.parentProp = this;
            this._multiResult = new PropertyParameter("result", mk);
        }
        MultiplexRootProperty.md_make_kind = function () {
            var k = new ParametricKind("MultiplexAPI", "");
            k.md_parameterPrefixes("", "", "", "", "");
            k._contexts = KindContext.General;
            k.md_isData();
            return k;
        };
        MultiplexRootProperty.md_make_prop = function (k, usage_count, parentKind, name, desc, parms, retType) {
            var p = new MultiplexRootProperty(k, parentKind, name, desc, parms, retType);
            p._usage_count = usage_count;
            parentKind.md_addProperty(p);
            return p;
        };
        MultiplexRootProperty.prototype.getParameters = function () {
            return [_super.prototype.getParameters.call(this)[0]];
        };
        MultiplexRootProperty.prototype.getResult = function () {
            return this._multiResult;
        };
        MultiplexRootProperty.prototype.instanceFor = function (parK, k, args) {
            var par = this._parametricKind.createInstance(args);
            var r = _super.prototype.substForInternal.call(this, par, function (pp, rk) { return new MultiplexProperty(k, parK, rk, pp); });
            r.savedArgs = args;
            return r;
        };
        MultiplexRootProperty.prototype.substFor = function (par, mk) {
            var _this = this;
            if (mk === void 0) { mk = null; }
            return _super.prototype.substForInternal.call(this, par, function (pp, rk) { return new MultiplexRootProperty(_this._parametricKind, par, _this._name, _this._help, pp, rk); });
        };
        return MultiplexRootProperty;
    })(Property);
    TDev.MultiplexRootProperty = MultiplexRootProperty;
    var MultiplexProperty = (function (_super) {
        __extends(MultiplexProperty, _super);
        function MultiplexProperty(forKind, parentKind, retKind, pp) {
            if (pp === void 0) { pp = []; }
            _super.call(this, parentKind, "", forKind.getHelp(false), pp, retKind);
            this.forKind = forKind;
            if (retKind instanceof MultiplexKind)
                retKind.parentProp = this;
            this.getUsage().globalCount = forKind.usage_count;
        }
        MultiplexProperty.prototype.getName = function () {
            return this.parentKind.getNameFor(this.forKind);
        };
        return MultiplexProperty;
    })(Property);
    TDev.MultiplexProperty = MultiplexProperty;
    var TokenUsage = (function () {
        function TokenUsage(parent) {
            this.parent = parent;
            this.globalCount = 0;
            this.localCount = 0;
            this.lastUsed = 0;
            this.apiFreq = 0;
        }
        TokenUsage.prototype.count = function () {
            return this.localCount * 5 + this.globalCount + this.apiFreq * 20;
        };
        return TokenUsage;
    })();
    TDev.TokenUsage = TokenUsage;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        AST.api = TDev.api;
        var currentNodeId = 1;
        AST.proMode = false;
        AST.blockMode = false;
        AST.legacyMode = true;
        AST.propRenames = {};
        AST.crossKindRenames = {};
        AST.writableLocalsInClosures = true;
        AST.allowCppCompiler = false;
        function reset() {
            currentNodeId = 1;
            AST.api.cleanup();
        }
        AST.reset = reset;
        function stableReset(entropy) {
            reset();
            var r = new TDev.Random.RC4();
            r.addEntropy(TDev.Util.stringToUint8Array(TDev.Util.toUTF8(entropy)));
            AST.uniqueAstId = function (len) { return r.uniqueId(len); };
        }
        AST.stableReset = stableReset;
        var AstNode = (function () {
            function AstNode() {
                this.nodeId = currentNodeId++;
                this._error = null;
            }
            AstNode.prototype.isAstNode = function () {
                return true;
            };
            AstNode.prototype.isPlaceholder = function () {
                return false;
            };
            AstNode.prototype.hasValue = function () {
                return false;
            };
            AstNode.prototype.isStmt = function () {
                return false;
            };
            AstNode.prototype.getKind = function () {
                return this._kind;
            };
            AstNode.prototype.nodeType = function () {
                return null;
            };
            AstNode.prototype.children = function () {
                return [];
            };
            AstNode.prototype.errorOf = function (e) {
                if (this._error != null)
                    return this._error;
                else
                    return e.getError();
            };
            AstNode.prototype.shouldCopy = function (propName) {
                return propName != "kind" && propName != "type";
            };
            AstNode.prototype.getError = function () {
                return this._error;
            };
            AstNode.prototype.setError = function (m) {
                this._error = m;
            };
            AstNode.prototype.clearError = function () {
                this._error = null;
            };
            AstNode.prototype.writeTo = function (tw) {
                TDev.Util.oops("writeTo not implemented");
            };
            AstNode.prototype.serialize = function () {
                var tw = AST.TokenWriter.forStorage();
                this.writeTo(tw);
                return tw.finalize();
            };
            AstNode.prototype.accept = function (v) {
                TDev.Util.oops("accept not implemented");
                return null;
            };
            AstNode.freshNameCore = function (n, nameExists) {
                if (n == "")
                    n = "x";
                if (!nameExists(n))
                    return n;
                if (n == "i") {
                    var better = ["j", "k", "l", "m", "n"].filter(function (n) { return !nameExists(n); })[0];
                    if (better)
                        return better;
                }
                var prefix = TDev.RT.String_.trim_end(n, "0123456789");
                var k = parseFloat(n.substr(prefix.length)) || 2;
                while (nameExists(prefix + k))
                    k++;
                return prefix + k;
            };
            return AstNode;
        })();
        AST.AstNode = AstNode;
        AST.uniqueAstId = function (len) { return TDev.Random.uniqueId(len); };
        var Stmt = (function (_super) {
            __extends(Stmt, _super);
            function Stmt() {
                _super.call(this);
                this.debuggerRenderContext = {};
            }
            Stmt.prototype.isStmt = function () {
                return true;
            };
            Stmt.prototype.isJump = function () {
                return false;
            };
            Stmt.prototype.isExecutableStmt = function () {
                return false;
            };
            Stmt.prototype.primaryBody = function () {
                return null;
            };
            Stmt.prototype.calcNode = function () {
                return null;
            };
            Stmt.prototype.children = function () {
                return this.calcNode() != null ? [this.calcNode()] : [];
            };
            Stmt.prototype.getError = function () {
                var c = this.calcNode();
                if (c != null)
                    return this.errorOf(c);
                else
                    return this._error;
            };
            Stmt.prototype.getHint = function () {
                var r = null;
                if (this.calcNode())
                    r = this.calcNode().hint;
                if (!r)
                    return this._hint;
                if (this._hint)
                    return r + "\n" + this._hint;
                return r;
            };
            Stmt.prototype.addHint = function (msg) {
                if (!this._hint)
                    this._hint = msg;
                else
                    this._hint += "\n" + msg;
            };
            Stmt.prototype.clearError = function () {
                this._error = null;
                this._hint = null;
                this.isUnreachable = false;
            };
            Stmt.prototype.loopVariable = function () {
                return null;
            };
            Stmt.prototype.setupForEdit = function () {
            };
            Stmt.prototype.nextStmt = function () {
                if (this.parent instanceof Block) {
                    var stmts = this.parent.stmts;
                    var idx = stmts.indexOf(this);
                    if (idx >= 0)
                        return stmts[idx + 1];
                }
                return null;
            };
            Stmt.prototype.isCommentedOut = function () {
                return this.parent && (this.parent.isTopCommentedOut() || this.parent.isCommentedOut());
            };
            Stmt.prototype.isTopCommentedOut = function () {
                return false;
            };
            Stmt.prototype.parentBlock = function () {
                return this.parent instanceof AST.Block ? this.parent : null;
            };
            Stmt.prototype.isLoneChild = function () {
                var p = this.parentBlock();
                return p && p.stmts.length == 1;
            };
            Stmt.prototype.isLastChild = function () {
                var p = this.parentBlock();
                return p && p.stmts.peek() == this;
            };
            Stmt.prototype.isFirstChild = function () {
                var p = this.parentBlock();
                return p && p.stmts[0] == this;
            };
            Stmt.prototype.allowSimplify = function () {
                return false;
            };
            Stmt.prototype.onDelete = function () {
            };
            Stmt.prototype.isFirstNonComment = function () {
                var p = this.parentBlock();
                return p && p.firstNonComment() == this;
            };
            Stmt.prototype.isLastNonComment = function () {
                var p = this.parentBlock();
                return p && p.lastNonComment() == this;
            };
            Stmt.prototype.getName = function () {
                return this._name;
            };
            Stmt.prototype.setName = function (s) {
                this._name = s;
            };
            Stmt.prototype.getStableName = function () {
                return this.stableName;
            };
            Stmt.prototype.setStableName = function (s) {
                if (s instanceof Array) {
                    this.stableName = s ? s.pop() : undefined;
                    this.stableVersions = undefined;
                }
                else {
                    this.stableName = s;
                    this.stableVersions = undefined;
                }
            };
            Stmt.prototype.initStableName = function (refresh) {
                if (refresh === void 0) { refresh = false; }
                if (!this.stableName || refresh) {
                    this.setStableName(AST.uniqueAstId(16));
                }
            };
            Stmt.prototype.deriveStableName = function (s, ix) {
                this.setStableName(s.getStableName() + "$" + ix);
            };
            Stmt.prototype.writeId = function (tw) {
                if (this.stableVersions) {
                    this.stableVersions.forEach(function (x) { return tw.uniqueId(x); });
                }
                tw.uniqueId(this.getStableName());
            };
            Stmt.prototype.writeIdOpt = function (tw) {
                this.writeId(tw);
            };
            Stmt.prototype.parentApp = function () {
                var pa = this.parentAction();
                if (pa)
                    return pa.parent;
                return null;
            };
            Stmt.prototype.parentAction = function () {
                for (var p = this.parent; p && !(p instanceof ActionHeader); p = p.parent)
                    ;
                if (p)
                    return p.action;
                else
                    return null;
            };
            Stmt.prototype.helpTopic = function () {
                return this.nodeType();
            };
            Stmt.prototype.forSearch = function () {
                return "";
            };
            Stmt.prototype.notifyChange = function () {
                if (this.parent)
                    this.parent.notifyChange();
            };
            Stmt.prototype.innerBlocks = function () {
                return this.children().filter(function (c) { return c instanceof Block; });
            };
            Stmt.prototype.isDescendant = function (stmt) {
                while (!!stmt) {
                    stmt = stmt.parent;
                    if (stmt == this)
                        return true;
                }
                return false;
            };
            Stmt.prototype.matches = function (d) {
                var n = this.calcNode();
                if (n)
                    for (var i = 0; i < n.tokens.length; ++i)
                        if (n.tokens[i].matches(d))
                            return true;
                return false;
            };
            Stmt.prototype.docText = function () {
                return null;
            };
            return Stmt;
        })(AstNode);
        AST.Stmt = Stmt;
        var InlineStmt = (function (_super) {
            __extends(InlineStmt, _super);
            function InlineStmt() {
                _super.call(this);
            }
            InlineStmt.prototype.accept = function (v) {
                v.visitInlineStmt(this);
            };
            InlineStmt.prototype.nodeType = function () {
                return "inlineStmt";
            };
            return InlineStmt;
        })(Stmt);
        AST.InlineStmt = InlineStmt;
        var DeclNameHolder = (function (_super) {
            __extends(DeclNameHolder, _super);
            function DeclNameHolder(parentDecl) {
                _super.call(this);
                this.parentDecl = parentDecl;
                this.maxLength = -1;
                this.exprHolder = new AST.ExprHolder();
                this.exprHolder.tokens = [new DeclName()];
                this.exprHolder.parsed = new Literal();
                this.exprHolder.locals = [];
            }
            DeclNameHolder.prototype.children = function () {
                return this.exprHolder.tokens;
            };
            DeclNameHolder.prototype.calcNode = function () {
                return this.exprHolder;
            };
            DeclNameHolder.prototype.notifyChange = function () {
                var toks = this.exprHolder.tokens;
                if (toks[0] && toks[0] instanceof DeclName) {
                    var newName = toks[0].data;
                    if (newName.length)
                        _super.prototype.setName.call(this, newName);
                    else
                        toks[0].data = this.getName();
                }
                this.parentDecl.notifyChange();
            };
            DeclNameHolder.prototype.setName = function (v) {
                _super.prototype.setName.call(this, v);
                var toks = this.exprHolder.tokens;
                if (toks[0] && toks[0] instanceof DeclName)
                    toks[0].data = v;
            };
            return DeclNameHolder;
        })(InlineStmt);
        AST.DeclNameHolder = DeclNameHolder;
        var Comment = (function (_super) {
            __extends(Comment, _super);
            function Comment() {
                _super.call(this);
            }
            Comment.prototype.nodeType = function () {
                return "comment";
            };
            Comment.prototype.accept = function (v) {
                return v.visitComment(this);
            };
            Comment.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.comment(this.text);
            };
            Comment.prototype.forSearch = function () {
                return this.text.toLowerCase();
            };
            Comment.prototype.docText = function () {
                return this.text;
            };
            Comment.prototype.isExecutableStmt = function () {
                return true;
            };
            return Comment;
        })(Stmt);
        AST.Comment = Comment;
        var FieldComment = (function (_super) {
            __extends(FieldComment, _super);
            function FieldComment(field) {
                _super.call(this);
                this.field = field;
            }
            FieldComment.prototype.notifyChange = function () {
                this.field.description = this.parent.children().map(function (c) { return c.text; }).join("\n");
                if (!this.field.description)
                    this.parent.setChildren([]);
                _super.prototype.notifyChange.call(this);
            };
            return FieldComment;
        })(Comment);
        AST.FieldComment = FieldComment;
        var Block = (function (_super) {
            __extends(Block, _super);
            function Block() {
                _super.call(this);
                this.immutableReason = null;
            }
            Block.prototype.nodeType = function () {
                return "block";
            };
            Block.prototype.children = function () {
                return this.stmts;
            };
            Block.prototype.count = function () {
                return this.stmts.length;
            };
            Block.prototype.newChild = function (s) {
                s.parent = this;
            };
            Block.prototype.setChild = function (i, s) {
                this.stmts[i] = s;
                this.newChild(s);
                this.notifyChange();
            };
            Block.prototype.setChildren = function (s) {
                var _this = this;
                this.stmts = s;
                this.stmts.forEach(function (q) { return _this.newChild(q); });
                this.notifyChange();
            };
            Block.prototype.push = function (s) {
                this.stmts.push(s);
                this.newChild(s);
                this.notifyChange();
            };
            Block.prototype.pushRange = function (s) {
                var _this = this;
                this.stmts.pushRange(s);
                this.stmts.forEach(function (q) { return _this.newChild(q); });
                this.notifyChange();
            };
            Block.prototype.writeTo = function (tw) {
                tw.beginBlock();
                this.stmts.forEach(function (s) {
                    s.writeTo(tw);
                });
                tw.endBlock();
            };
            Block.prototype.emptyStmt = function () {
                return TDev.Util.abstract();
            };
            Block.prototype.allowEmpty = function () {
                return false;
            };
            Block.prototype.allowAdding = function () {
                return true;
            };
            Block.prototype.allowAddOf = function (n) {
                return false;
            };
            Block.prototype.isBlockPlaceholder = function () {
                return this.stmts.length == 0 || (this.stmts.length == 1 && this.stmts[0].isPlaceholder());
            };
            Block.prototype.replaceChild = function (s, newOnes) {
                var idx = this.stmts.indexOf(s);
                var newCh = (idx >= 0 ? this.stmts.slice(0, idx) : []).concat(newOnes).concat(this.stmts.slice(idx + 1));
                this.setChildren(newCh);
            };
            Block.prototype.forEach = function (f) {
                this.stmts.forEach(f);
            };
            Block.prototype.map = function (f) {
                return this.stmts.map(f);
            };
            Block.prototype.firstNonComment = function () {
                return this.stmts.filter(function (stmt) { return stmt.nodeType() !== "comment"; })[0];
            };
            Block.prototype.lastNonComment = function () {
                return this.stmts.filter(function (stmt) { return stmt.nodeType() !== "comment"; }).peek();
            };
            Block.prototype.stmtsWithDiffs = function () {
                if (this.diffStmts || this.stmts.some(function (s) { return !!s.diffStmts; })) {
                    var res = [];
                    if (this.diffStmts)
                        res.pushRange(this.diffStmts);
                    this.stmts.forEach(function (s) {
                        res.push(s);
                        if (s.diffStmts)
                            res.pushRange(s.diffStmts);
                    });
                    return res;
                }
                else {
                    return this.stmts;
                }
            };
            Block.prototype.forEachInnerBlock = function (f) {
                for (var i = 0; i < this.stmts.length; ++i) {
                    var ch = this.stmts[i].children();
                    for (var j = 0; j < ch.length; ++j) {
                        if (ch[j] instanceof Block)
                            f(ch[j]);
                    }
                }
            };
            return Block;
        })(Stmt);
        AST.Block = Block;
        (function (BlockFlags) {
            BlockFlags[BlockFlags["None"] = 0x0000] = "None";
            BlockFlags[BlockFlags["IsPageRender"] = 0x0001] = "IsPageRender";
            BlockFlags[BlockFlags["IsPageInit"] = 0x0002] = "IsPageInit";
        })(AST.BlockFlags || (AST.BlockFlags = {}));
        var BlockFlags = AST.BlockFlags;
        var CodeBlock = (function (_super) {
            __extends(CodeBlock, _super);
            function CodeBlock() {
                _super.call(this);
            }
            CodeBlock.prototype.emptyStmt = function () {
                return AST.Parser.emptyExprStmt();
            };
            CodeBlock.prototype.accept = function (v) {
                return v.visitCodeBlock(this);
            };
            CodeBlock.prototype.nodeType = function () {
                return "codeBlock";
            };
            CodeBlock.prototype.allowAddOf = function (n) {
                return n && n.isExecutableStmt();
            };
            CodeBlock.prototype.writeTo = function (tw) {
                tw.beginBlock();
                for (var i = 0; i < this.stmts.length; ++i) {
                    var s = this.stmts[i];
                    if (s instanceof If && isElseIf(this.stmts[i + 1])) {
                        var si = s;
                        si.writeCore(tw);
                        var numOpen = 1;
                        tw.keyword("else").op("{");
                        while (true) {
                            if (!isElseIf(this.stmts[i + 1]))
                                break;
                            i++;
                            si = this.stmts[i];
                            si.writeCore(tw);
                            tw.keyword("else");
                            if (!si.rawElseBody.isBlockPlaceholder()) {
                                tw.node(si.rawElseBody);
                                break;
                            }
                            tw.op("{");
                            numOpen++;
                        }
                        while (numOpen-- > 0)
                            tw.op("}");
                        tw.nl();
                    }
                    else {
                        s.writeTo(tw);
                    }
                }
                tw.endBlock();
            };
            return CodeBlock;
        })(Block);
        AST.CodeBlock = CodeBlock;
        var ConditionBlock = (function (_super) {
            __extends(ConditionBlock, _super);
            function ConditionBlock() {
                _super.call(this);
            }
            ConditionBlock.prototype.emptyStmt = function () {
                return AST.Parser.emptyCondition();
            };
            ConditionBlock.prototype.accept = function (v) {
                return v.visitConditionBlock(this);
            };
            ConditionBlock.prototype.nodeType = function () {
                return "conditionBlock";
            };
            ConditionBlock.prototype.allowAddOf = function (n) {
                return n instanceof ForeachClause;
            };
            ConditionBlock.prototype.allowEmpty = function () {
                return true;
            };
            return ConditionBlock;
        })(Block);
        AST.ConditionBlock = ConditionBlock;
        var ParameterBlock = (function (_super) {
            __extends(ParameterBlock, _super);
            function ParameterBlock() {
                _super.call(this);
                this.stmts = [];
            }
            ParameterBlock.prototype.allowEmpty = function () {
                return true;
            };
            ParameterBlock.prototype.emptyStmt = function (name, kind) {
                var isOut = this.parent.outParameters == this;
                var r = new ActionParameter(mkLocal(this.parent.action.nameLocal(name || (isOut ? "r" : "p")), kind || AST.api.core.Number), isOut);
                r.parent = this;
                return r;
            };
            ParameterBlock.prototype.accept = function (v) {
                return v.visitParameterBlock(this);
            };
            ParameterBlock.prototype.allowAddOf = function (n) {
                return n instanceof ActionParameter;
            };
            ParameterBlock.prototype.nodeType = function () {
                return "parameterBlock";
            };
            ParameterBlock.prototype.children = function () {
                if (this.parent && this.parent.inParameters == this) {
                    var act = this.parent.action;
                    if (act && act.modelParameter)
                        return [act.modelParameter].concat(this.stmts);
                }
                return this.stmts;
            };
            return ParameterBlock;
        })(Block);
        AST.ParameterBlock = ParameterBlock;
        var BindingBlock = (function (_super) {
            __extends(BindingBlock, _super);
            function BindingBlock() {
                _super.call(this);
                this.stmts = [];
            }
            BindingBlock.prototype.allowEmpty = function () {
                return true;
            };
            BindingBlock.prototype.emptyStmt = function () {
                return null;
            };
            BindingBlock.prototype.accept = function (v) {
                return v.visitBindingBlock(this);
            };
            BindingBlock.prototype.nodeType = function () {
                return "bindingBlock";
            };
            BindingBlock.prototype.allowAddOf = function (n) {
                return n instanceof AST.Binding;
            };
            return BindingBlock;
        })(Block);
        AST.BindingBlock = BindingBlock;
        var ResolveBlock = (function (_super) {
            __extends(ResolveBlock, _super);
            function ResolveBlock() {
                _super.call(this);
                this.stmts = [];
            }
            ResolveBlock.prototype.allowEmpty = function () {
                return true;
            };
            ResolveBlock.prototype.emptyStmt = function () {
                return null;
            };
            ResolveBlock.prototype.accept = function (v) {
                return v.visitResolveBlock(this);
            };
            ResolveBlock.prototype.push = function (s) {
                this.stmts.push(s);
                s.parent = this;
            };
            ResolveBlock.prototype.nodeType = function () {
                return "resolveBlock";
            };
            ResolveBlock.prototype.allowAddOf = function (n) {
                return n instanceof AST.ResolveClause;
            };
            return ResolveBlock;
        })(Block);
        AST.ResolveBlock = ResolveBlock;
        var FieldBlock = (function (_super) {
            __extends(FieldBlock, _super);
            function FieldBlock() {
                _super.call(this);
                this.stmts = [];
            }
            FieldBlock.prototype.allowEmpty = function () {
                return true;
            };
            FieldBlock.prototype.isKeyBlock = function () {
                return this.parentDef.keys == this;
            };
            FieldBlock.prototype.allowAddOf = function (n) {
                return n instanceof AST.RecordField;
            };
            FieldBlock.prototype.mkUniqName = function (basename) {
                var names = this.parentDef.getFields().map(function (f) { return f.getName(); });
                return AstNode.freshNameCore(basename, function (n) { return names.indexOf(n) >= 0; });
            };
            FieldBlock.prototype.mkField = function (basename, k) {
                var n = this.mkUniqName(basename);
                var r = new AST.RecordField(n, k, this.isKeyBlock());
                return r;
            };
            FieldBlock.prototype.emptyStmt = function () {
                var _this = this;
                var basename = "f";
                var k = AST.api.core.String;
                if (this.isKeyBlock()) {
                    if (this.parentDef.recordType == 2 /* Table */) {
                        var kinds = TDev.Script.getKinds().filter(function (k) { return (k != _this.parentDef.entryKind && k.isData && k.hasContext(64 /* RowKey */)) && (!_this.parentDef.locallypersisted() || k.getRecord().locallypersisted()) && (!_this.parentDef.cloudEnabled || k.getRecord().cloudEnabled); });
                        if (kinds.length == 0)
                            return null;
                        k = kinds[0];
                        basename = "l";
                    }
                    else {
                        basename = "k";
                    }
                }
                return this.mkField(basename, k);
            };
            FieldBlock.prototype.accept = function (v) {
                return v.visitFieldBlock(this);
            };
            FieldBlock.prototype.notifyChange = function () {
                _super.prototype.notifyChange.call(this);
                this.parentDef.notifyChange();
            };
            FieldBlock.prototype.fields = function () {
                return this.stmts;
            };
            FieldBlock.prototype.nodeType = function () {
                return "fieldBlock";
            };
            return FieldBlock;
        })(Block);
        AST.FieldBlock = FieldBlock;
        var InlineActionBlock = (function (_super) {
            __extends(InlineActionBlock, _super);
            function InlineActionBlock() {
                _super.call(this);
                this.stmts = [];
            }
            InlineActionBlock.prototype.allowAdding = function () {
                return !!this.parent.getOptionsParameter();
            };
            InlineActionBlock.prototype.allowEmpty = function () {
                return true;
            };
            InlineActionBlock.prototype.emptyStmt = function () {
                return OptionalParameter.mk("");
            };
            InlineActionBlock.prototype.accept = function (v) {
                return v.visitInlineActionBlock(this);
            };
            InlineActionBlock.prototype.push = function (s) {
                this.stmts.push(s);
                s.parent = this;
            };
            InlineActionBlock.prototype.nodeType = function () {
                return "inlineActionBlock";
            };
            InlineActionBlock.prototype.allowAddOf = function (n) {
                return n instanceof InlineAction;
            };
            return InlineActionBlock;
        })(Block);
        AST.InlineActionBlock = InlineActionBlock;
        var Loop = (function (_super) {
            __extends(Loop, _super);
            function Loop() {
                _super.apply(this, arguments);
            }
            Loop.prototype.primaryBody = function () {
                return this.body;
            };
            Loop.prototype.isExecutableStmt = function () {
                return true;
            };
            Loop.prototype.loopVariable = function () {
                return null;
            };
            return Loop;
        })(Stmt);
        AST.Loop = Loop;
        var For = (function (_super) {
            __extends(For, _super);
            function For() {
                _super.apply(this, arguments);
            }
            For.prototype.nodeType = function () {
                return "for";
            };
            For.prototype.calcNode = function () {
                return this.upperBound;
            };
            For.prototype.children = function () {
                return [this.upperBound, this.body];
            };
            For.prototype.accept = function (v) {
                return v.visitFor(this);
            };
            For.prototype.allowSimplify = function () {
                return true;
            };
            For.prototype.loopVariable = function () {
                return this.boundLocal;
            };
            For.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("for").op("0").op("\u2264").id(this.boundLocal.getName()).op("<");
                tw.node(this.upperBound).keyword("do").node(this.body);
            };
            For.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                p.skipOp("0");
                p.skipOp("\u2264");
                this.boundLocal = mkLocal(p.parseId("i"), AST.api.core.Number);
                p.skipOp("<");
                this.upperBound = p.parseExpr();
                p.skipKw("do");
                this.body = p.parseBlock();
                this.body.parent = this;
            };
            For.prototype.forSearch = function () {
                return "for do " + this.upperBound.forSearch();
            };
            return For;
        })(Loop);
        AST.For = For;
        var Foreach = (function (_super) {
            __extends(Foreach, _super);
            function Foreach() {
                _super.apply(this, arguments);
            }
            Foreach.prototype.nodeType = function () {
                return "foreach";
            };
            Foreach.prototype.calcNode = function () {
                return this.collection;
            };
            Foreach.prototype.accept = function (v) {
                return v.visitForeach(this);
            };
            Foreach.prototype.children = function () {
                return [this.collection, this.conditions, this.body];
            };
            Foreach.prototype.allowSimplify = function () {
                return true;
            };
            Foreach.prototype.loopVariable = function () {
                return this.boundLocal;
            };
            Foreach.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("foreach").id(this.boundLocal.getName()).keyword("in").node(this.collection).nl();
                this.conditions.stmts.forEach(function (c) {
                    c.writeTo(tw);
                });
                tw.keyword("do").node(this.body);
            };
            Foreach.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                this.boundLocal = mkLocal(p.parseId("e"), AST.api.core.Unknown);
                p.skipKw("in");
                this.collection = p.parseExpr();
                var conds = [];
                p.shiftLabel();
                while (p.gotKw("where")) {
                    p.shift();
                    var wh = mkWhere(p.parseExpr());
                    wh.setStableName(p.consumeLabel());
                    conds.push(wh);
                    p.shiftLabel();
                }
                if (conds.every(function (s) { return s instanceof Where && s.condition.getLiteral() === true; }))
                    conds = [];
                this.conditions = new ConditionBlock();
                this.conditions.setChildren(conds);
                this.conditions.parent = this;
                p.skipKw("do");
                this.body = p.parseBlock();
                this.body.parent = this;
            };
            Foreach.prototype.forSearch = function () {
                return "foreach for each in do " + this.collection.forSearch();
            };
            return Foreach;
        })(Loop);
        AST.Foreach = Foreach;
        var While = (function (_super) {
            __extends(While, _super);
            function While() {
                _super.apply(this, arguments);
            }
            While.prototype.nodeType = function () {
                return "while";
            };
            While.prototype.calcNode = function () {
                return this.condition;
            };
            While.prototype.accept = function (v) {
                return v.visitWhile(this);
            };
            While.prototype.children = function () {
                return [this.condition, this.body];
            };
            While.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("while").node(this.condition);
                tw.keyword("do").node(this.body);
            };
            While.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                this.condition = p.parseExpr();
                p.skipKw("do");
                this.body = p.parseBlock();
                this.body.parent = this;
            };
            While.prototype.forSearch = function () {
                return "while do " + this.condition.forSearch();
            };
            return While;
        })(Loop);
        AST.While = While;
        var If = (function (_super) {
            __extends(If, _super);
            function If() {
                _super.call(this);
                this.displayElse = true;
            }
            If.prototype.allowSimplify = function () {
                return !this.isElseIf;
            };
            If.prototype.nodeType = function () {
                return this.isElseIf ? "elseIf" : "if";
            };
            If.prototype.accept = function (v) {
                return this.isElseIf ? v.visitElseIf(this) : v.visitIf(this);
            };
            If.prototype.calcNode = function () {
                return this.rawCondition;
            };
            If.prototype.children = function () {
                return [this.rawCondition, this.rawThenBody, this.rawElseBody];
            };
            If.prototype.setElse = function (s) {
                this.rawElseBody = s;
                s.parent = this;
            };
            If.prototype.isTopCommentedOut = function () {
                if (!this.isElseIf && this.rawElseBody.isBlockPlaceholder() && this.rawCondition.getLiteral() === false) {
                    var n = this.nextStmt();
                    if (n instanceof If && n.isElseIf)
                        return false;
                    return true;
                }
                return false;
            };
            If.prototype.primaryBody = function () {
                return this.rawThenBody;
            };
            If.prototype.isExecutableStmt = function () {
                return true;
            };
            If.prototype.writeTo = function (tw) {
                if (this.isElseIf)
                    tw.keyword("else");
                this.writeCore(tw);
                if (!this.rawElseBody.isBlockPlaceholder())
                    tw.keyword("else").node(this.rawElseBody);
            };
            If.prototype.writeCore = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("if").node(this.rawCondition).keyword("then").node(this.rawThenBody);
            };
            If.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                this.rawCondition = p.parseExpr();
                p.skipKw("then");
                this.rawThenBody = p.parseBlock();
                this.rawThenBody.parent = this;
                this.setElse(AST.Parser.emptyBlock());
            };
            If.prototype.forSearch = function () {
                return "if then " + this.rawCondition.forSearch();
            };
            If.prototype.bodies = function () {
                if (this.isElseIf)
                    return [];
                return this.branches.map(function (b) { return b.body; });
            };
            return If;
        })(Stmt);
        AST.If = If;
        function isElseIf(s) {
            return s instanceof If && s.isElseIf;
        }
        AST.isElseIf = isElseIf;
        var Box = (function (_super) {
            __extends(Box, _super);
            function Box() {
                _super.call(this);
                this.emptyExpr = AST.Parser.emptyExpr();
            }
            Box.prototype.nodeType = function () {
                return "boxed";
            };
            Box.prototype.calcNode = function () {
                return this.emptyExpr;
            };
            Box.prototype.primaryBody = function () {
                return this.body;
            };
            Box.prototype.accept = function (v) {
                return v.visitBox(this);
            };
            Box.prototype.children = function () {
                return [this.body];
            };
            Box.prototype.isExecutableStmt = function () {
                return true;
            };
            Box.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("do").id("box").node(this.body);
            };
            Box.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                this.body = p.parseBlock();
                this.body.parent = this;
            };
            Box.prototype.forSearch = function () {
                return "boxed";
            };
            return Box;
        })(Stmt);
        AST.Box = Box;
        var ExprStmt = (function (_super) {
            __extends(ExprStmt, _super);
            function ExprStmt() {
                _super.call(this);
            }
            ExprStmt.prototype.isVarDef = function () {
                return this.expr.looksLikeVarDef || (!!this.expr.assignmentInfo() && this.expr.assignmentInfo().definedVars.length > 0);
            };
            ExprStmt.prototype.isPagePush = function () {
                return !!this.expr.assignmentInfo() && this.expr.assignmentInfo().isPagePush;
            };
            ExprStmt.prototype.nodeType = function () {
                return "exprStmt";
            };
            ExprStmt.prototype.calcNode = function () {
                return this.expr;
            };
            ExprStmt.prototype.isPlaceholder = function () {
                return this.expr.isPlaceholder();
            };
            ExprStmt.prototype.accept = function (v) {
                return v.visitExprStmt(this);
            };
            ExprStmt.prototype.isExecutableStmt = function () {
                return true;
            };
            ExprStmt.prototype.allowSimplify = function () {
                return true;
            };
            ExprStmt.prototype.isJump = function () {
                if (this.expr.parsed) {
                    var p = this.expr.parsed.getCalledProperty();
                    if (p == AST.api.core.ReturnProp || p == AST.api.core.BreakProp || p == AST.api.core.ContinueProp)
                        return true;
                }
                return false;
            };
            ExprStmt.prototype.helpTopic = function () {
                return this.isVarDef() ? "var" : "commands";
            };
            ExprStmt.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                if (this.isPlaceholder())
                    tw.keyword("skip");
                else
                    tw.node(this.expr);
                tw.op0(";").nl();
            };
            ExprStmt.prototype.forSearch = function () {
                return (this.isVarDef() ? "var " : "") + this.expr.forSearch();
            };
            ExprStmt.prototype.docText = function () {
                var prop = this.expr.parsed ? this.expr.parsed.getCalledProperty() : null;
                if (!prop)
                    return null;
                if (prop.getName() == "docs render")
                    return this.docsRender();
                else if (prop.parentKind == AST.api.getKind("Docs") && prop.getName() == "bitmatrix")
                    return this.bitmatrixRender();
                return null;
            };
            ExprStmt.prototype.bitmatrixRender = function () {
                var c = this.expr.parsed;
                if (c.args.length != 2)
                    return null;
                var bits = c.args[1].getStringLiteral() || "";
                return "```` bitmatrix\n" + bits + "\n````";
            };
            ExprStmt.prototype.docsRender = function () {
                var c = this.expr.parsed;
                var arg0 = c.args[0].getCalledProperty();
                if (arg0 instanceof GlobalDef) {
                    var url = arg0.url;
                }
                if (!url)
                    return null;
                if (arg0.getKind() == AST.api.core.Picture) {
                    var h = c.args[1].getNumberLiteral() || 12;
                    var cap = c.args[2].getStringLiteral() || "";
                    return "{pic:" + arg0.getName() + ":" + h + "x" + h + (cap ? ":" + cap : "") + "}";
                }
                if (arg0.getKind().getName() == "Document") {
                    var cap = c.args[1].getStringLiteral() || arg0.getName();
                    return "[" + cap + "] (" + url + ")";
                }
                return null;
            };
            return ExprStmt;
        })(Stmt);
        AST.ExprStmt = ExprStmt;
        var InlineActionBase = (function (_super) {
            __extends(InlineActionBase, _super);
            function InlineActionBase() {
                _super.apply(this, arguments);
            }
            InlineActionBase.prototype.getName = function () {
                return "";
            };
            return InlineActionBase;
        })(Stmt);
        AST.InlineActionBase = InlineActionBase;
        var OptionalParameter = (function (_super) {
            __extends(OptionalParameter, _super);
            function OptionalParameter() {
                _super.call(this);
            }
            OptionalParameter.prototype.getName = function () {
                return this.recordField ? this.recordField.getName() : this._opt_name;
            };
            OptionalParameter.mk = function (name) {
                var opt = new AST.OptionalParameter();
                opt.expr = AST.Parser.emptyExpr();
                opt._opt_name = name;
                return opt;
            };
            OptionalParameter.prototype.nodeType = function () {
                return "optionalParameter";
            };
            OptionalParameter.prototype.calcNode = function () {
                return this.expr;
            };
            OptionalParameter.prototype.accept = function (v) {
                return v.visitOptionalParameter(this);
            };
            OptionalParameter.prototype.children = function () {
                return [this.expr];
            };
            OptionalParameter.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("where").id(this.getName()).op(":=").node(this.expr).op0(";").nl();
            };
            OptionalParameter.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                this._opt_name = p.parseId();
                p.skipOp(":=");
                this.expr = p.parseExpr();
                p.skipOp(";");
            };
            OptionalParameter.prototype.forSearch = function () {
                return "with " + this.getName() + " := " + this.expr.forSearch();
            };
            OptionalParameter.optionsParameter = function (prop) {
                if (!prop)
                    return null;
                var last = prop.getParameters().peek();
                if (!last)
                    return null;
                if (!/\?$/.test(last.getName()))
                    return null;
                var lk = last.getKind();
                if (!lk.isUserDefined())
                    return null;
                var rec = lk.getRecord();
                if (rec && rec.tableKind.getProperty("create"))
                    return last;
                return null;
            };
            return OptionalParameter;
        })(InlineActionBase);
        AST.OptionalParameter = OptionalParameter;
        var InlineAction = (function (_super) {
            __extends(InlineAction, _super);
            function InlineAction() {
                _super.call(this);
                this.inParameters = [];
                this.outParameters = [];
            }
            InlineAction.prototype.children = function () {
                return [this.body];
            };
            InlineAction.prototype.nodeType = function () {
                return "inlineAction";
            };
            InlineAction.prototype.helpTopic = function () {
                return "inlineActions";
            };
            InlineAction.prototype.getName = function () {
                return this.recordField ? this.recordField.getName() : this.name.getName();
            };
            InlineAction.mk = function (name) {
                var inl = new InlineAction();
                inl.name = name;
                inl.body = new CodeBlock();
                inl.body.parent = inl;
                inl.body.setChildren([inl.body.emptyStmt()]);
                return inl;
            };
            InlineAction.prototype.writeTo = function (tw) {
                var _this = this;
                this.writeIdOpt(tw);
                var writeParms = function (parms) {
                    var first = true;
                    parms.forEach(function (l) {
                        if (!first)
                            tw.op0(",").space();
                        l.writeWithType(_this.parentApp(), tw);
                        first = false;
                    });
                };
                tw.keyword("where");
                if (this.isImplicit)
                    tw.op("implicit");
                if (this.isOptional)
                    tw.op("optional");
                tw.id(this.name.getName()).op0("(");
                writeParms(this.inParameters);
                tw.op0(")");
                if (this.outParameters.length > 0) {
                    tw.space().keyword("returns").space().op0("(");
                    writeParms(this.outParameters);
                    tw.op0(")");
                }
                this.body.writeTo(tw);
            };
            InlineAction.prototype.parseFrom = function (p) {
                this.setStableName(p.consumeLabel());
                if (p.gotOp("implicit")) {
                    this.isImplicit = true;
                    p.shift();
                }
                if (p.gotOp("optional")) {
                    this.isOptional = true;
                    p.shift();
                }
                var hd = p.parseActionHeader();
                this.name = mkLocal(hd.name, AST.api.core.Unknown);
                if (this.isImplicit)
                    this.name.isSynthetic = true;
                this.inParameters = hd.inParameters.map(function (p) { return p.local; });
                this.outParameters = hd.outParameters.map(function (p) { return p.local; });
                this.body = p.parseBlock();
                this.body.parent = this;
            };
            InlineAction.prototype.forSearch = function () {
                return "where " + this.name.getName();
            };
            InlineAction.prototype.accept = function (v) {
                return v.visitInlineAction(this);
            };
            return InlineAction;
        })(InlineActionBase);
        AST.InlineAction = InlineAction;
        var InlineActions = (function (_super) {
            __extends(InlineActions, _super);
            function InlineActions() {
                _super.call(this);
                this.actions = new InlineActionBlock();
                this.actions = new InlineActionBlock();
                this.actions.parent = this;
            }
            InlineActions.prototype.nodeType = function () {
                return "inlineActions";
            };
            InlineActions.prototype.isPlaceholder = function () {
                return false;
            };
            InlineActions.prototype.accept = function (v) {
                return v.visitInlineActions(this);
            };
            InlineActions.prototype.children = function () {
                return [this.expr, this.actions];
            };
            InlineActions.prototype.getOptionsParameter = function () {
                var topCall = this.calcNode().topCall();
                if (!topCall)
                    return null;
                var optionsParm = AST.OptionalParameter.optionsParameter(topCall.getCalledProperty());
                return optionsParm;
            };
            InlineActions.prototype.optionalParameters = function () {
                return this.actions.stmts.filter(function (s) {
                    if (s instanceof InlineAction)
                        return s.isOptional;
                    else if (s instanceof OptionalParameter)
                        return true;
                    else
                        TDev.Util.oops("bad element " + s.nodeType());
                });
            };
            InlineActions.prototype.normalActions = function () {
                return this.actions.stmts.filter(function (s) { return s instanceof InlineAction && !s.isOptional; });
            };
            InlineActions.prototype.implicitAction = function () {
                var last = this.actions.stmts.peek();
                if (last instanceof InlineAction) {
                    var i = last;
                    return i.isImplicit ? i : null;
                }
                return null;
            };
            InlineActions.isImplicitActionKind = function (k) {
                if (k instanceof TDev.ActionKind) {
                    var ak = k;
                    return ak.getInParameters().length == 0 && ak.getOutParameters().length == 0;
                }
                return false;
            };
            InlineActions.prototype.writeTo = function (tw) {
                _super.prototype.writeTo.call(this, tw);
                this.actions.forEach(function (a) { return a.writeTo(tw); });
            };
            InlineActions.prototype.sortOptionals = function () {
                var opt0 = this.optionalParameters()[0];
                if (!opt0 || !opt0.recordField)
                    return;
                var lst = opt0.recordField.def().values.stmts;
                var problem = false;
                this.actions.forEach(function (iab) {
                    if (iab.recordField) {
                        iab._sort_key = lst.indexOf(iab.recordField);
                        if (iab._sort_key < 0)
                            problem = true;
                    }
                    else if (iab instanceof InlineAction) {
                        iab._sort_key = iab.isImplicit ? 1.1e10 : 1e10;
                    }
                    else {
                        problem = true;
                    }
                });
                if (problem)
                    return;
                this.actions.stmts.sort(function (a, b) { return a._sort_key - b._sort_key; });
                this.actions.notifyChange();
            };
            InlineActions.implicitActionParameter = function (prop) {
                if (!prop)
                    return null;
                var parms = prop.getParameters();
                if (OptionalParameter.optionsParameter(prop))
                    parms.pop();
                var last = parms.peek();
                if (!last)
                    return null;
                if (last.getName() == "body" && InlineActions.isImplicitActionKind(last.getKind()))
                    return last;
                return null;
            };
            return InlineActions;
        })(ExprStmt);
        AST.InlineActions = InlineActions;
        var ForeachClause = (function (_super) {
            __extends(ForeachClause, _super);
            function ForeachClause() {
                _super.call(this);
            }
            return ForeachClause;
        })(Stmt);
        AST.ForeachClause = ForeachClause;
        var Where = (function (_super) {
            __extends(Where, _super);
            function Where() {
                _super.call(this);
            }
            Where.prototype.nodeType = function () {
                return "where";
            };
            Where.prototype.calcNode = function () {
                return this.condition;
            };
            Where.prototype.accept = function (v) {
                return v.visitWhere(this);
            };
            Where.prototype.isPlaceholder = function () {
                return this.condition.isPlaceholder() || (this.condition.tokens.length == 1 && this.condition.tokens[0].getText() == "true");
            };
            Where.prototype.writeTo = function (tw) {
                this.writeIdOpt(tw);
                tw.keyword("where").node(this.condition).nl();
            };
            Where.prototype.forSearch = function () {
                return "where " + this.condition.forSearch();
            };
            return Where;
        })(ForeachClause);
        AST.Where = Where;
        var ActionParameter = (function (_super) {
            __extends(ActionParameter, _super);
            function ActionParameter(local, isOut, isClosure) {
                if (isOut === void 0) { isOut = false; }
                if (isClosure === void 0) { isClosure = false; }
                _super.call(this);
                this.local = local;
                this.isOut = isOut;
                this.isClosure = isClosure;
                this.exprHolder = new AST.ExprHolder();
                this.setupForEdit();
            }
            ActionParameter.prototype.setupForEdit = function () {
                var name = new AST.FieldName(this.isOut);
                name.data = this.getName();
                this.exprHolder.tokens = [name].concat(AST.propertyRefsForKind(this.local.getKind()));
                this.exprHolder.parsed = new AST.Literal();
                this.exprHolder.locals = [];
            };
            ActionParameter.prototype.calcNode = function () {
                return this.exprHolder;
            };
            ActionParameter.prototype.notifyChange = function () {
                var _this = this;
                var toks = this.exprHolder.tokens;
                if (toks.length == 0 && this.parent) {
                    var pb = this.parent;
                    var ch = pb.children().filter(function (x) { return x != _this; });
                    pb.setChildren(ch);
                }
                else if (toks[0] && toks[0] instanceof AST.FieldName) {
                    var newName = toks[0].data;
                    if (this.getName() != newName) {
                        var uniqName = this.parentAction().nameLocal(newName);
                        this.local.rename(uniqName);
                        toks[0].data = uniqName;
                    }
                    if (toks.length > 1) {
                        var k = this.exprHolder.getKind();
                        if (isProperKind(k) && k != this.local.getKind()) {
                            this.local.setKind(k);
                            AST.TypeChecker.tcApp(TDev.Script);
                        }
                    }
                }
                if (toks.length > 1 && toks[1] instanceof AST.PropertyRef)
                    toks[1].skipArrow = true;
                _super.prototype.notifyChange.call(this);
            };
            ActionParameter.prototype.getName = function () {
                return this.local.getName();
            };
            ActionParameter.prototype.getKind = function () {
                return this.local.getKind();
            };
            ActionParameter.prototype.nodeType = function () {
                return "actionParameter";
            };
            ActionParameter.prototype.accept = function (v) {
                return v.visitActionParameter(this);
            };
            ActionParameter.prototype.theAction = function () {
                return this.parent.parent.action;
            };
            ActionParameter.prototype.forSearch = function () {
                return this.getName() + " " + this.getKind().toString();
            };
            ActionParameter.prototype.writeTo = function (tw) {
                tw.keyword("var");
                this.local.writeWithType(this.parentApp(), tw);
                tw.op0(";").nl();
            };
            ActionParameter.prototype.matches = function (d) {
                return this.getKind() && this.getKind().matches(d);
            };
            return ActionParameter;
        })(Stmt);
        AST.ActionParameter = ActionParameter;
        var ActionHeader = (function (_super) {
            __extends(ActionHeader, _super);
            function ActionHeader(action) {
                _super.call(this);
                this.action = action;
                this.inParameters = new ParameterBlock();
                this.outParameters = new ParameterBlock();
                this.inParameters.parent = this;
                this.outParameters.parent = this;
            }
            ActionHeader.prototype.getName = function () {
                return this.action.getName();
            };
            ActionHeader.prototype.nodeType = function () {
                return "actionHeader";
            };
            ActionHeader.prototype.children = function () {
                return [this.inParameters, this.outParameters, this.action.body];
            };
            ActionHeader.prototype.primaryBody = function () {
                return this.action.body;
            };
            ActionHeader.prototype.accept = function (v) {
                return v.visitActionHeader(this);
            };
            ActionHeader.prototype.writeTo = function (tw) {
                this.action.writeHeader(tw);
            };
            ActionHeader.prototype.notifyChange = function () {
                _super.prototype.notifyChange.call(this);
                this.action.notifyChange();
            };
            return ActionHeader;
        })(Stmt);
        AST.ActionHeader = ActionHeader;
        var Decl = (function (_super) {
            __extends(Decl, _super);
            function Decl() {
                _super.call(this);
                this._wasTypechecked = false;
                this.wasAutoNamed = false;
                this.nameHolder = new DeclNameHolder(this);
            }
            Decl.prototype.getCoreName = function () {
                return this.nameHolder.getName();
            };
            Decl.prototype.getName = function () {
                return this.nameHolder.getName();
            };
            Decl.prototype.setName = function (name) {
                this.nameHolder.setName(name);
            };
            Decl.prototype.getIconArtId = function () {
                return null;
            };
            Decl.prototype.hasErrors = function () {
                return !!this.getError();
            };
            Decl.prototype.hasWarnings = function () {
                return false;
            };
            Decl.prototype.getDescription = function (skip) {
                return "";
            };
            Decl.prototype.isBrowsable = function () {
                return true;
            };
            Decl.prototype.propertyForSearch = function () {
                return null;
            };
            Decl.prototype.toString = function () {
                return this.getName();
            };
            Decl.prototype.helpTopic = function () {
                return null;
            };
            Decl.prototype.usageKey = function () {
                return null;
            };
            Decl.prototype.freshlyCreated = function () {
            };
            Decl.prototype.getDefinedKind = function () {
                return null;
            };
            Decl.prototype.matches = function (d) {
                if (this.getKind() && this.getKind().matches(d))
                    return true;
                return this == d;
            };
            Decl.prototype.canRename = function () {
                return true;
            };
            Decl.prototype.notifyChange = function () {
                _super.prototype.notifyChange.call(this);
                if (this.cachedSerialized) {
                    var idx = this.cachedSerialized.idx;
                    if (idx > 0)
                        this.cachedSerialized.idx = -idx;
                }
            };
            Decl.prototype.nodeType = function () {
                return "decl";
            };
            Decl.prototype.accept = function (v) {
                return v.visitDecl(this);
            };
            return Decl;
        })(Stmt);
        AST.Decl = Decl;
        var PropertyDecl = (function (_super) {
            __extends(PropertyDecl, _super);
            function PropertyDecl() {
                _super.call(this);
                this._usage = new TDev.TokenUsage(this);
            }
            PropertyDecl.prototype.getSignature = function () {
                return TDev.Property.getSignatureCore(this);
            };
            PropertyDecl.prototype.canCacheSearch = function () {
                return false;
            };
            PropertyDecl.prototype.thingSetKindName = function () {
                return null;
            };
            PropertyDecl.prototype.getInfixPriority = function () {
                return 0;
            };
            PropertyDecl.prototype.forwardsTo = function () {
                return this;
            };
            PropertyDecl.prototype.forwardsToStmt = function () {
                return null;
            };
            PropertyDecl.prototype.propertyForSearch = function () {
                return this;
            };
            PropertyDecl.prototype.getCapability = function () {
                return 0 /* None */;
            };
            PropertyDecl.prototype.getExplicitCapability = function () {
                return this.getCapability();
            };
            PropertyDecl.prototype.isBeta = function () {
                return false;
            };
            PropertyDecl.prototype.showIntelliButton = function () {
                return true;
            };
            PropertyDecl.prototype.getImports = function () {
                return undefined;
            };
            PropertyDecl.prototype.isExtensionAction = function () {
                return false;
            };
            PropertyDecl.prototype.shouldPauseInterperter = function () {
                return false;
            };
            PropertyDecl.prototype.isImplemented = function () {
                return true;
            };
            PropertyDecl.prototype.isImplementedAnywhere = function () {
                return this.isImplemented();
            };
            PropertyDecl.prototype.isSupported = function () {
                return true;
            };
            PropertyDecl.prototype.getSpecialApply = function () {
                return null;
            };
            PropertyDecl.prototype.isBrowsable = function () {
                return true;
            };
            PropertyDecl.prototype.getUsage = function () {
                return this._usage;
            };
            PropertyDecl.prototype.helpTopic = function () {
                return this.nodeType();
            };
            PropertyDecl.prototype.getFlags = function () {
                return 0 /* None */;
            };
            PropertyDecl.prototype.getArrow = function () {
                return "\u200A";
            };
            PropertyDecl.prototype.runtimeName = function () {
                return TDev.Api.runtimeName(this.getName());
            };
            PropertyDecl.prototype.needsSpecialTracing = function () {
                return false;
            };
            PropertyDecl.prototype.needsTracing = function () {
                return false;
            };
            PropertyDecl.prototype.needsTimestamping = function () {
                return false;
            };
            PropertyDecl.prototype.hasPauseContinue = function () {
                return false;
            };
            PropertyDecl.mkPPext = function (s, name, k) {
                var pp = new TDev.PropertyParameter(name, k);
                pp.parentProperty = s;
                return pp;
            };
            PropertyDecl.prototype.mkPP = function (name, k) {
                return PropertyDecl.mkPPext(this, name, k);
            };
            PropertyDecl.prototype.getParameters = function () {
                return [this.mkPP("_this_", this.parentKind)];
            };
            PropertyDecl.prototype.getResult = function () {
                return this.mkPP(this.getName(), this.getKind());
            };
            PropertyDecl.prototype.getNamespace = function () {
                var pkn = this.thingSetKindName();
                if (!pkn)
                    return null;
                var k = AST.api.getKind(pkn);
                if (!k)
                    return null;
                return k.shortName() + "\u200A";
            };
            PropertyDecl.prototype.setName = function (s) {
                _super.prototype.setName.call(this, s);
                if (this.parent) {
                    this.parent.notifyChangeAll();
                }
            };
            return PropertyDecl;
        })(Decl);
        AST.PropertyDecl = PropertyDecl;
        AST.artSymbol = "\u273f";
        AST.dataSymbol = "\u25f3";
        AST.codeSymbol = "\u25b7";
        var GlobalDef = (function (_super) {
            __extends(GlobalDef, _super);
            function GlobalDef() {
                _super.call(this);
                this.readonly = false;
                this.comment = "";
                this.url = "";
                this.isResource = false;
                this.isTransient = true;
                this.cloudEnabled = false;
            }
            GlobalDef.prototype.children = function () {
                return [];
            };
            GlobalDef.prototype.nodeType = function () {
                return "globalDef";
            };
            GlobalDef.prototype.helpTopic = function () {
                return this.thingSetKindName();
            };
            GlobalDef.prototype.accept = function (v) {
                return v.visitGlobalDef(this);
            };
            GlobalDef.prototype.getDescription = function () {
                if (this.isResource && this.getKind() == AST.api.core.Color)
                    return TDev.lf("color #{0}", this.url);
                return TDev.lf("a global variable");
            };
            GlobalDef.prototype.forSearch = function () {
                return this.stringResourceValue() || this.url || "";
            };
            GlobalDef.prototype.stringResourceValue = function () {
                if (this.isResource && this.getKind() == AST.api.core.String && this.url) {
                    return TDev.RT.String_.valueFromArtUrl(this.url);
                }
                return null;
            };
            GlobalDef.prototype.thingSetKindName = function () {
                return this.isResource ? "art" : "data";
            };
            GlobalDef.prototype.getCategory = function () {
                return 2 /* Data */;
            };
            GlobalDef.prototype.setKind = function (k) {
                this._kind = k;
            };
            GlobalDef.prototype.writeTo = function (tw) {
                this.writeId(tw);
                tw.nl().keyword("var").id(this.getName()).op(":").kind(this.parent, this.getKind());
                tw.beginBlock();
                if (!!this.comment)
                    tw.comment(this.comment);
                if (this.isResource) {
                    tw.boolOptAttr("is_resource", this.isResource);
                    if (!!this.url)
                        tw.stringAttr("url", this.url);
                }
                else
                    tw.boolOptAttr("readonly", this.readonly);
                tw.boolOptAttr("transient", this.isTransient);
                tw.boolOptAttr("cloudenabled", this.cloudEnabled);
                tw.endBlock();
            };
            GlobalDef.parse = function (p) {
                var v = new GlobalDef();
                v.setStableName(p.consumeLabel());
                v.isTransient = false;
                p.addDecl(v);
                v.setName(p.parseId());
                v.setKind(p.parseTypeAnnotation());
                p.parseBraced(function () {
                    if (p.gotKey("readonly"))
                        v.readonly = p.parseBool();
                    if (p.gotKey("transient"))
                        v.isTransient = p.parseBool();
                    if (p.gotKey("cloudenabled"))
                        v.cloudEnabled = p.parseBool();
                    if (p.gotKey("is_resource")) {
                        v.isResource = p.parseBool();
                        if (v.isResource)
                            v.readonly = true;
                    }
                    if (p.gotKey("url"))
                        v.url = p.parseString();
                    if (p.got(4 /* Comment */))
                        v.comment += p.shift().data + "\n";
                });
                if (v.cloudEnabled)
                    v.isTransient = false;
            };
            GlobalDef.prototype.getRecordPersistence = function () {
                if (this.cloudEnabled)
                    return 2 /* Cloud */;
                if (!this.isTransient)
                    return 1 /* Local */;
                return 0 /* Temporary */;
            };
            GlobalDef.prototype.notifyChange = function () {
                _super.prototype.notifyChange.call(this);
                if (TDev.Runtime.theRuntime)
                    TDev.Runtime.theRuntime.resetData();
            };
            return GlobalDef;
        })(PropertyDecl);
        AST.GlobalDef = GlobalDef;
        var SingletonDef = (function (_super) {
            __extends(SingletonDef, _super);
            function SingletonDef() {
                _super.call(this);
                this.isExtension = false;
                this._isBrowsable = true;
                this.usage = new TDev.TokenUsage(this);
            }
            SingletonDef.prototype.getUsage = function () {
                return this.usage;
            };
            SingletonDef.prototype.nodeType = function () {
                return "singletonDef";
            };
            SingletonDef.prototype.accept = function (v) {
                return v.visitSingletonDef(this);
            };
            SingletonDef.prototype.getDescription = function (skip) {
                if (!this._description) {
                    this._description = this.getKind().getHelp(!skip);
                    if (this.isExtension && this.firstLibraryRef.resolved) {
                        var stringResource = this.firstLibraryRef.resolved.resources().filter(function (n) { return n.getName() == "namespacedocs.json"; })[0];
                        if (stringResource) {
                            try {
                                var jsdocs = JSON.parse(TDev.RT.String_.valueFromArtUrl(stringResource.url));
                                if (jsdocs[this.getName()])
                                    this._description = jsdocs[this.getName()];
                            }
                            catch (e) {
                            }
                        }
                    }
                }
                return this._description;
            };
            SingletonDef.prototype.isBrowsable = function () {
                return this._isBrowsable;
            };
            SingletonDef.prototype.usageMult = function () {
                return 1;
            };
            SingletonDef.prototype.usageKey = function () {
                return TDev.Util.tagify(this.getKind().getName());
            };
            return SingletonDef;
        })(Decl);
        AST.SingletonDef = SingletonDef;
        var PlaceholderDef = (function (_super) {
            __extends(PlaceholderDef, _super);
            function PlaceholderDef() {
                _super.call(this);
            }
            PlaceholderDef.prototype.nodeType = function () {
                return "placeholderDef";
            };
            PlaceholderDef.prototype.getDescription = function () {
                return "need " + this.getKind().toString() + " here";
            };
            PlaceholderDef.prototype.isBrowsable = function () {
                return false;
            };
            PlaceholderDef.prototype.getName = function () {
                return "need " + this.getKind().serialize() + (this.label ? ":" + this.label : "");
            };
            PlaceholderDef.prototype.longError = function () {
                return TDev.lf("TD100: insert {0:a} here", this.label || this.getKind().toString());
            };
            return PlaceholderDef;
        })(Decl);
        AST.PlaceholderDef = PlaceholderDef;
        var Action = (function (_super) {
            __extends(Action, _super);
            function Action() {
                _super.call(this);
                this.numUnsupported = 0;
                this.isAtomic = false;
                this.canBeInlined = false;
                this.header = new ActionHeader(this);
            }
            Action.prototype.nodeType = function () {
                return "action";
            };
            Action.prototype.isTest = function () {
                return this._isTest && (this.isCompilerTest() || !this.hasInParameters());
            };
            Action.prototype.isNormalAction = function () {
                return !this.isPage() && !this.isEvent() && !this.isLambda;
            };
            Action.prototype.isEvent = function () {
                return !!this.eventInfo;
            };
            Action.prototype.isPage = function () {
                return this._isPage;
            };
            Action.prototype.accept = function (v) {
                return v.visitAction(this);
            };
            Action.prototype.children = function () {
                return [this.header];
            };
            Action.prototype.hasErrors = function () {
                return this._hasErrors;
            };
            Action.prototype.isMainAction = function () {
                return this.parent && this.parent.mainAction() == this;
            };
            Action.prototype.parentLibrary = function () {
                return this.parent && this.parent.isTopLevel && this.parent.thisLibRef;
            };
            Action.prototype.thingSetKindName = function () {
                return this.isEvent() ? null : "code";
            };
            Action.prototype.isActionTypeDef = function () {
                return this._isActionTypeDef;
            };
            Action.prototype.isExtensionAction = function () {
                return false;
            };
            Action.prototype.extensionForward = function () {
                return this;
            };
            Action.prototype.hasWarnings = function () {
                return this.numUnsupported > 0;
            };
            Action.prototype.getExtensionKind = function () {
                var p = this.getInParameters();
                if (p.length >= 1 && !/\?$/.test(p[0].getName()) && p[0].getKind().isExtensionEnabled())
                    return p[0].getKind();
                return null;
            };
            Action.prototype.getHelpPath = function () {
                var desc = this.getDescription();
                var m = /{help:([^}]+)}/i.exec(desc);
                return m ? m[1] : undefined;
            };
            Action.prototype.getNamespaces = function () {
                var desc = this.getDescription();
                if (!/{namespace:/.test(desc))
                    return [];
                var res = [];
                desc.replace(/{namespace:([^}]+)}/g, function (m, ns) {
                    res.push(ns);
                    return "";
                });
                return res;
            };
            Action.prototype.getShimName = function () {
                var shm = /{(shim|asm):([^{}]*)}/.exec(this.getDescription());
                if (shm)
                    return shm[2];
                return null;
            };
            Action.prototype.getFlags = function () {
                var _this = this;
                var flags = !this.isAtomic ? 4096 /* Async */ : 0 /* None */;
                if (this.body)
                    for (var i = 0; i < this.body.stmts.length; ++i) {
                        var s = this.body.stmts[i].docText();
                        if (s != null) {
                            var m = /{action:([^\}]+)}/i.exec(s);
                            if (m) {
                                m[1].split(',').forEach(function (fl) {
                                    switch (fl.toLowerCase()) {
                                        case "ignorereturn":
                                            flags |= 262144 /* IgnoreReturnValue */;
                                            break;
                                        case "libsonly":
                                            flags |= 1048576 /* LibsOnly */;
                                            break;
                                        default:
                                            _this.setError(TDev.lf("unknown flag"));
                                            break;
                                    }
                                });
                            }
                        }
                        else {
                            break;
                        }
                    }
                return flags;
            };
            Action.prototype.clearError = function () {
                _super.prototype.clearError.call(this);
                this.numUnsupported = 0;
            };
            Action.prototype.isInLibrary = function () {
                return false;
            };
            Action.prototype.markUsed = function () {
            };
            Action.prototype.isLibInit = function () {
                return !this.isPrivate && this.getName() == "_libinit" && this.getOutParameters().length == 0 && this.getInParameters().length == 0;
            };
            Action.prototype.helpTopic = function () {
                return this.isActionTypeDef() ? "action types" : this.isPage() ? "pages" : this.isEvent() ? "events" : "code";
            };
            Action.prototype.isCompilerTest = function () {
                return this._isTest && /^E: /.test(this.getName());
            };
            Action.prototype.getModelDef = function () {
                if (!this.modelParameter)
                    return null;
                if (this.modelParameter.getKind() instanceof AST.RecordEntryKind) {
                    return this.modelParameter.getKind().getRecord();
                }
                return null;
            };
            Action.prototype.getInlineHelp = function () {
                if (this.eventInfo)
                    return this.eventInfo.type.help;
                if (!this.body)
                    return "";
                var desc = "";
                for (var i = 0; i < this.body.stmts.length; ++i) {
                    var s = this.body.stmts[i];
                    if (s instanceof Comment) {
                        var c = s;
                        if (desc)
                            desc += "\n";
                        desc += c.text;
                    }
                    else {
                        break;
                    }
                }
                return desc;
            };
            Action.prototype.getDescription = function () {
                var desc = this.getInlineHelp();
                if (desc)
                    return desc;
                return this.isActionTypeDef() ? TDev.lf("an function type definition") : this.isEvent() ? TDev.lf("an event handler") : this.isPage() ? TDev.lf("a page") : TDev.lf("a function");
            };
            Action.prototype.getCategory = function () {
                return 1 /* Action */;
            };
            Action.prototype.getParameters = function () {
                var _this = this;
                return _super.prototype.getParameters.call(this).concat(this.getInParameters().map(function (p) { return _this.mkPP(p.getName(), p.getKind()); }));
            };
            Action.prototype.getResult = function () {
                var op = this.getOutParameters();
                if (op.length == 1)
                    return this.mkPP(op[0].getName(), op[0].getKind());
                else
                    return this.mkPP("result", AST.api.core.Nothing);
            };
            Action.prototype.getDefinedKind = function () {
                if (!this.isActionTypeDef())
                    return null;
                if (!this.definedKind)
                    this.definedKind = new TDev.UserActionKind(this);
                return this.definedKind;
            };
            Action.prototype.setEventInfo = function (ei) {
                this.eventInfo = ei;
                this.isAtomic = false;
                if (!!ei) {
                    this.header.inParameters.immutableReason = TDev.lf("Types, order, and number of event parameters cannot be edited.");
                    this.header.outParameters.immutableReason = TDev.lf("Events cannot have out parameters.");
                }
            };
            Action.prototype.getPageBlock = function (init) {
                var ch = this.body.children();
                if (ch.length != 2 || !(ch[0] instanceof If) || !(ch[1] instanceof If))
                    return null;
                var ifInit = ch[0];
                var renderIf = ch[1];
                var ifToks = ifInit.rawCondition.tokens;
                if (!ifInit.rawElseBody.isBlockPlaceholder())
                    return null;
                if (!renderIf.rawElseBody.isBlockPlaceholder())
                    return null;
                if (ifToks.length != 2 || !(ifToks[0] instanceof ThingRef) || !(ifToks[1] instanceof PropertyRef))
                    return null;
                if (ifToks[0].data != "box" || ifToks[1].data != "is init")
                    return null;
                this.body.isInvisible = true;
                function markInvisible(i) {
                    i.isInvisible = true;
                    i.rawElseBody.isInvisible = true;
                    var s0 = i.rawElseBody.stmts[0];
                    if (s0)
                        s0.isInvisible = true;
                }
                markInvisible(ifInit);
                markInvisible(renderIf);
                return init ? ifInit.rawThenBody : renderIf.rawThenBody;
            };
            Action.prototype.getInParameters = function () {
                return this.header.inParameters.stmts;
            };
            Action.prototype.getOutParameters = function () {
                return this.header.outParameters.stmts;
            };
            Action.prototype.getAllParameters = function () {
                return this.getInParameters().concat(this.getOutParameters());
            };
            Action.prototype.hasInParameters = function () {
                return this.getInParameters().length > 0;
            };
            Action.prototype.hasOutParameters = function () {
                return this.getOutParameters().length > 0;
            };
            Action.prototype.nameLocal = function (n, usedNames) {
                var _this = this;
                if (usedNames === void 0) { usedNames = {}; }
                return AstNode.freshNameCore(n, function (n) { return usedNames.hasOwnProperty(n) || _this.allLocals.some(function (l) { return l.getName() == n; }) || AST.api.getThing(n) != null; });
            };
            Action.prototype.isPlugin = function () {
                if (this.getName() != "plugin")
                    return false;
                var parms = this.getInParameters();
                if (parms.length != 1)
                    return false;
                if (parms[0].getKind() == AST.api.core.String || parms[0].getKind() == AST.api.core.Editor)
                    return true;
                return false;
            };
            Action.prototype.isButtonPlugin = function () {
                if (this.isPrivate)
                    return false;
                var parms = this.getInParameters();
                if (parms.length != 1)
                    return false;
                return parms[0].getKind().getName() == "Editor";
            };
            Action.prototype.isRunnable = function () {
                if (this.isActionTypeDef() || this.isEvent() || this.isPrivate)
                    return false;
                if (TDev.Cloud.isRestricted() && this.hasInParameters())
                    return false;
                return this.isPlugin() || this.isButtonPlugin() || !this.hasInParameters() || (!this.isPage() && this.getInParameters().every(function (a) { return !!a.getKind().picker; }));
            };
            Action.prototype.writeHeader = function (tw, forLibSig) {
                var _this = this;
                if (forLibSig === void 0) { forLibSig = false; }
                var writeParms = function (parms) {
                    var first = true;
                    parms.forEach(function (l) {
                        if (!first)
                            tw.op0(",").space();
                        if (!forLibSig)
                            l.writeIdOpt(tw);
                        l.local.writeWithType(_this.parent, tw);
                        first = false;
                    });
                };
                tw.nl().keyword(this.isEvent() ? "event" : "action");
                if (forLibSig) {
                    tw.op(!this.isAtomic ? "async" : "sync");
                }
                if (this.isActionTypeDef())
                    tw.op("type");
                tw.id(this.getName()).op0("(");
                var parms = this.getInParameters();
                if (this.modelParameter) {
                    parms = parms.slice(0);
                    parms.unshift(this.modelParameter);
                }
                writeParms(parms);
                tw.op0(")");
                if (this.hasOutParameters()) {
                    tw.keyword("returns").op0("(");
                    writeParms(this.getOutParameters());
                    tw.op0(")");
                }
            };
            Action.prototype.writeTo = function (tw) {
                this.writeId(tw);
                this.writeHeader(tw);
                if (tw.skipActionBodies) {
                    tw.beginBlock();
                    tw.endBlock();
                }
                else {
                    this.body.writeTo(tw);
                }
                tw.backspaceBlockEnd();
                if (this.isPrivate)
                    tw.keyword("meta").keyword("private").op0(";").nl();
                if (this.isPage())
                    tw.keyword("meta").keyword("page").op0(";").nl();
                if (this.isAtomic && !this.isEvent())
                    tw.keyword("meta").keyword("sync").op0(";").nl();
                if (this.isTest())
                    tw.keyword("meta").keyword("test").op0(";").nl();
                if (this.isOffline)
                    tw.keyword("meta").keyword("offline").op0(";").nl();
                if (this.isQuery)
                    tw.keyword("meta").keyword("query").op0(";").nl();
                tw.endBlock();
            };
            Action.prototype.toString = function () {
                return this.getName();
            };
            Action.prototype.getStats = function () {
                var s = new StatsComputer();
                s.dispatch(this);
                return s;
            };
            Action.prototype.freshlyCreated = function () {
                if (!this.isPage() || this.modelParameter)
                    return;
                var decl = AST.Parser.parseDecl("table __name__ { type = 'Object'; fields { } }");
                decl.setName(TDev.Script.freshName(this.getName() + " page data"));
                TDev.Script.addDecl(decl);
                var l = AST.mkLocal(AST.modelSymbol, decl.entryKind);
                this.modelParameter = new ActionParameter(l);
            };
            Action.prototype.initParameterAnnotations = function () {
                var _this = this;
                if (this.parameterAnnotations)
                    return;
                this.parameterAnnotations = {};
                var descr = this.getDescription();
                descr.replace(/\{(hints|enum):([^:{}]*):([^{}]*)/g, function (mtch, tp, arg, vals) {
                    var annot = _this.getParameterAnnotation(arg);
                    annot.hints = vals.split(',');
                    if (tp == "enum") {
                        annot.enumMap = {};
                        annot.hints = annot.hints.map(function (a) {
                            var m = /([^=]*)=(.+)$/i.exec(a);
                            if (m) {
                                annot.enumMap[m[1]] = m[2];
                                return m[1];
                            }
                            else {
                                annot.enumMap[a] = a;
                                return a;
                            }
                        });
                        annot.hints.enumMap = annot.enumMap;
                    }
                    return "";
                });
                descr.replace(/\{pichints:([^:{}]*):([^{}]*)/g, function (mtch, arg, vals) {
                    _this.getParameterAnnotation(arg).pichints = TDev.Util.splitKeyValues(vals);
                    return "";
                });
                descr.replace(/\{language:([^:{}]*):([^{}]*)/g, function (mtch, arg, vals) {
                    _this.getParameterAnnotation(arg).language = vals;
                    return "";
                });
            };
            Action.prototype.getParameterAnnotation = function (name) {
                this.initParameterAnnotations();
                if (!this.parameterAnnotations.hasOwnProperty(name))
                    this.parameterAnnotations[name] = {};
                return this.parameterAnnotations[name];
            };
            Action.prototype.mkPP = function (name, k) {
                var r = _super.prototype.mkPP.call(this, name, k);
                var annot = this.getParameterAnnotation(name);
                if (annot.hints)
                    r.setDeflStrings(annot.hints);
                if (annot.pichints)
                    r.setDeflStringArtIds(annot.pichints);
                if (annot.language)
                    r.languageHint = annot.language;
                if (annot.enumMap)
                    r.enumMap = annot.enumMap;
                return r;
            };
            return Action;
        })(PropertyDecl);
        AST.Action = Action;
        var ExtensionProperty = (function (_super) {
            __extends(ExtensionProperty, _super);
            function ExtensionProperty(shortcutTo) {
                _super.call(this, shortcutTo.getInParameters()[0].getKind(), shortcutTo.getName(), shortcutTo.getDescription(), [], AST.api.core.Nothing);
                this.shortcutTo = shortcutTo;
            }
            ExtensionProperty.prototype.getCategory = function () {
                return 1 /* Action */;
            };
            ExtensionProperty.prototype.getParameters = function () {
                return this.shortcutTo.getParameters().slice(1);
            };
            ExtensionProperty.prototype.getResult = function () {
                return this.shortcutTo.getResult();
            };
            ExtensionProperty.prototype.getName = function () {
                return this.shortcutTo.getName();
            };
            ExtensionProperty.prototype.getDescription = function () {
                return this.shortcutTo.getDescription();
            };
            ExtensionProperty.prototype.getSignature = function () {
                return this.shortcutTo.getSignature();
            };
            ExtensionProperty.prototype.getFlags = function () {
                return this.shortcutTo.getFlags();
            };
            ExtensionProperty.prototype.canRename = function () {
                return false;
            };
            return ExtensionProperty;
        })(TDev.Property);
        AST.ExtensionProperty = ExtensionProperty;
        var LocalDef = (function (_super) {
            __extends(LocalDef, _super);
            function LocalDef() {
                _super.call(this);
                this.lastUsedAt = 0;
            }
            LocalDef.prototype.nodeType = function () {
                return "localDef";
            };
            LocalDef.prototype.accept = function (v) {
                return v.visitLocalDef(this);
            };
            LocalDef.prototype.getDescription = function () {
                return ": " + this.getKind().toString() + TDev.lf(" -- a local variable");
            };
            LocalDef.prototype.rename = function (nn) {
                this.setName(nn);
            };
            LocalDef.prototype.setKind = function (k) {
                this._kind = k;
            };
            LocalDef.prototype.usageKey = function () {
                return this.getName();
            };
            LocalDef.prototype.isByRef = function () {
                return this._isMutable && this._isCaptured;
            };
            LocalDef.prototype.writeWithType = function (app, tw) {
                tw.id(this.getName()).op0(':').kind(app, this.getKind());
            };
            LocalDef.prototype.clone = function () {
                return mkLocal(this.getName(), this.getKind());
            };
            return LocalDef;
        })(Decl);
        AST.LocalDef = LocalDef;
        (function (LanguageFeature) {
            LanguageFeature[LanguageFeature["None"] = 0x0000] = "None";
            LanguageFeature[LanguageFeature["JS"] = 0x0001] = "JS";
            LanguageFeature[LanguageFeature["ContextCheck"] = 0x0002] = "ContextCheck";
            LanguageFeature[LanguageFeature["Refs"] = 0x0004] = "Refs";
            LanguageFeature[LanguageFeature["LocalCloud"] = 0x0008] = "LocalCloud";
            LanguageFeature[LanguageFeature["UnicodeModel"] = 0x0010] = "UnicodeModel";
            LanguageFeature[LanguageFeature["AllAsync"] = 0x0020] = "AllAsync";
            LanguageFeature[LanguageFeature["UppercaseMultiplex"] = 0x0040] = "UppercaseMultiplex";
            LanguageFeature[LanguageFeature["Current"] = LanguageFeature.JS | LanguageFeature.Refs | LanguageFeature.ContextCheck | LanguageFeature.LocalCloud | LanguageFeature.UnicodeModel | LanguageFeature.AllAsync | LanguageFeature.UppercaseMultiplex] = "Current";
        })(AST.LanguageFeature || (AST.LanguageFeature = {}));
        var LanguageFeature = AST.LanguageFeature;
        (function (AnnotationMode) {
            AnnotationMode[AnnotationMode["None"] = 0] = "None";
            AnnotationMode[AnnotationMode["Coverage"] = 1] = "Coverage";
            AnnotationMode[AnnotationMode["Profiling"] = 2] = "Profiling";
            AnnotationMode[AnnotationMode["Crash"] = 3] = "Crash";
        })(AST.AnnotationMode || (AST.AnnotationMode = {}));
        var AnnotationMode = AST.AnnotationMode;
        var AppImports = (function () {
            function AppImports() {
                this.npmModules = {};
                this.bowerModules = {};
                this.clientScripts = {};
                this.cordovaPlugins = {};
                this.pipPackages = {};
                this.touchDevelopPlugins = {};
            }
            AppImports.prototype.importTouchDevelop = function (tc, t, plugin, scriptId) {
                if (scriptId) {
                    this.touchDevelopPlugins[scriptId] = "1";
                }
            };
            AppImports.prototype.importPip = function (tc, t, pkg, v) {
                if (pkg) {
                    var pkgs = this.pipPackages;
                    if (pkgs.hasOwnProperty(pkg)) {
                        if (pkgs[pkg] == "error")
                            return;
                        var newOne = AppImports.combinePipVersions(pkgs[pkg], v);
                        if (newOne == "error")
                            tc.markError(t, TDev.lf("TD196: pip package '{0}' versions '{1}' and '{2}' conflict", pkg, pkgs[pkg], v));
                        pkgs[pkg] = newOne;
                    }
                    else
                        pkgs[pkg] = v;
                }
            };
            AppImports.prototype.importCordova = function (tc, t, plugin, v) {
                if (plugin) {
                    var plugins = this.cordovaPlugins;
                    if (plugins.hasOwnProperty(plugin)) {
                        if (plugins[plugin] == "error")
                            return;
                        var newOne = AppImports.combineNpmVersions(plugins[plugin], v);
                        if (newOne == "error")
                            tc.markError(t, TDev.lf("TD187: cordova plugin '{0}' versions '{1}' and '{2}' conflict", plugin, plugins[plugin], v));
                        plugins[plugin] = newOne;
                    }
                    else
                        plugins[plugin] = v;
                }
            };
            AppImports.combineNpmModules = function (topApp) {
                var imports = {};
                topApp.librariesAndThis().filter(function (l) { return !!l.resolved; }).forEach(function (l) {
                    Object.keys(l.resolved.imports.npmModules).forEach(function (k) {
                        var v = l.resolved.imports.npmModules[k];
                        if (imports.hasOwnProperty(k)) {
                            imports[k] = AppImports.combineNpmVersions(imports[k], v);
                        }
                        else {
                            imports[k] = v;
                        }
                    });
                });
                return imports;
            };
            AppImports.combinePipPackages = function (topApp) {
                var imports = {};
                topApp.librariesAndThis().filter(function (l) { return !!l.resolved; }).forEach(function (l) {
                    Object.keys(l.resolved.imports.pipPackages).forEach(function (k) {
                        var v = l.resolved.imports.pipPackages[k];
                        if (imports.hasOwnProperty(k)) {
                            imports[k] = AppImports.combinePipVersions(imports[k], v);
                        }
                        else {
                            imports[k] = v;
                        }
                    });
                });
                return imports;
            };
            AppImports.combineCordovaPlugins = function (topApp) {
                var plugins = {
                    "cordova-plugin-console": "*",
                    "cordova-plugin-websql": "*",
                    "cordova-plugin-inappbrowser": "*",
                };
                Object.keys(topApp.imports.cordovaPlugins).filter(function (k) { return topApp.imports.cordovaPlugins.hasOwnProperty(k); }).forEach(function (k) { return plugins[k] = AppImports.combineNpmVersions(plugins[k], topApp.imports.cordovaPlugins[k]); });
                topApp.librariesAndThis().filter(function (l) { return !!l.resolved; }).forEach(function (l) {
                    Object.keys(l.resolved.imports.cordovaPlugins).forEach(function (k) {
                        var v = l.resolved.imports.cordovaPlugins[k];
                        if (plugins.hasOwnProperty(k)) {
                            plugins[k] = AppImports.combineNpmVersions(plugins[k], v);
                        }
                        else {
                            plugins[k] = v;
                        }
                    });
                });
                return plugins;
            };
            AppImports.combineTouchDevelopPlugins = function (topApp) {
                var plugins = {};
                Object.keys(topApp.imports.touchDevelopPlugins).forEach(function (k) { return plugins[k] = "1"; });
                topApp.librariesAndThis().filter(function (l) { return !!l.resolved; }).forEach(function (l) {
                    Object.keys(l.resolved.imports.touchDevelopPlugins).forEach(function (k) { return plugins[k] = "1"; });
                });
                return plugins;
            };
            AppImports.prototype.importClientScript = function (tc, t, mod, v) {
                if (mod && v != null) {
                    var imports = this.clientScripts;
                    imports[mod] = v;
                }
            };
            AppImports.prototype.importNpm = function (tc, t, mod, v) {
                if (mod && v != null) {
                    var imports = this.npmModules;
                    if (imports.hasOwnProperty(mod)) {
                        if (imports[mod] == "error")
                            return;
                        var newOne = AppImports.combineNpmVersions(imports[mod], v);
                        if (newOne == "error")
                            tc.markError(t, TDev.lf("TD180: npm module '{0}' versions '{1}' and '{2}' conflict", mod, imports[mod], v));
                        imports[mod] = newOne;
                    }
                    else
                        imports[mod] = v;
                }
            };
            AppImports.prototype.importBower = function (tc, t, mod, v) {
                if (mod && v != null) {
                    var imports = this.bowerModules;
                    if (imports.hasOwnProperty(mod)) {
                        if (imports[mod] == "error")
                            return;
                        var newOne = AppImports.combineNpmVersions(imports[mod], v);
                        if (newOne == "error")
                            tc.markError(t, TDev.lf("TD197: bower module '{0}' versions '{1}' and '{2}' conflict", mod, imports[mod], v));
                        imports[mod] = newOne;
                    }
                    else
                        imports[mod] = v;
                }
            };
            AppImports.combinePipVersions = function (v0, v1) {
                if (v0 === v1)
                    return v0;
                if (v0 === undefined || (v1 && v0 === "*"))
                    return v1;
                if (v1 === undefined || (v0 && v1 === "*"))
                    return v0;
                return "error";
            };
            AppImports.combineNpmVersions = function (v0, v1) {
                if (v0 === v1)
                    return v0;
                if (v0 === undefined || (v1 && v0 === "*"))
                    return v1;
                if (v1 === undefined || (v0 && v1 === "*"))
                    return v0;
                return "error";
            };
            return AppImports;
        })();
        AST.AppImports = AppImports;
        var AppHeaderStmt = (function (_super) {
            __extends(AppHeaderStmt, _super);
            function AppHeaderStmt(parentDef) {
                _super.call(this);
                this.parentDef = parentDef;
            }
            return AppHeaderStmt;
        })(InlineStmt);
        AST.AppHeaderStmt = AppHeaderStmt;
        var App = (function (_super) {
            __extends(App, _super);
            function App(p) {
                _super.call(this);
                this.things = [];
                this.editorState = {};
                this.parentIds = [];
                this.rootId = AST.uniqueAstId(24);
                this.languageFeatures = LanguageFeature.Current;
                this.usedIds = {};
                this.syntheticIds = {};
                this.imports = new AppImports();
                this.notifyVersionMarker = new Object();
                this.libNamespaceCache = new AST.LibNamespaceCache(this);
                this.blockExternalLinks = undefined;
                this.entireShim = false;
                this.annotatedBy = 0 /* None */;
                this.comment = "";
                this.localGuid = TDev.Util.guidGen();
                this.isTopLevel = false;
                this.stillParsing = true;
                this._platform = 268435456 /* Current */;
                this.meta = {};
                this.setStableName("app");
                this.thisLibRef = AST.LibraryRef.topScriptLibrary(this);
                this.setName("no name");
                this.version = App.currentVersion;
                this.headerStmt = new AppHeaderStmt(this);
                this.nameHolder.maxLength = 52;
                this.nameHolder.defaultTemplate = TDev.lf("ADJ script");
            }
            App.prototype.nodeType = function () {
                return "app";
            };
            App.prototype.getDescription = function () {
                return this.comment;
            };
            App.prototype.clearRecompiler = function () {
                this.recompiler = null;
                this.recompiledScript = null;
            };
            App.prototype.htmlColor = function () {
                if (TDev.Cloud.isRestricted())
                    return "#0095ff";
                if (!this.color)
                    return TDev.ScriptIcons.stableColorFromName(this.getName());
                else
                    return "#" + this.color.replace("#", "").slice(-6);
            };
            App.prototype.iconName = function () {
                return "emptycircle";
            };
            App.prototype.iconPath = function () {
                return "svg:" + this.iconName() + ",white";
            };
            App.prototype.hasLibraries = function () {
                return this.libraries().length > 0;
            };
            App.prototype.hasTests = function () {
                return this.allActions().some(function (a) { return a.isTest(); });
            };
            App.prototype.isTestOnly = function () {
                return !this.mainAction() && this.hasTests();
            };
            App.prototype.isDocsTopic = function () {
                return this.comment && /#docs/i.test(this.comment);
            };
            App.prototype.isTutorial = function () {
                return this.isDocsTopic() && this.allActions().some(function (a) { return /^#\d/.test(a.getName()); });
            };
            App.prototype.accept = function (v) {
                return v.visitApp(this);
            };
            App.prototype.children = function () {
                return this.things;
            };
            App.prototype.usesCloud = function () {
                return this.records().some(function (r) { return r.cloudEnabled; }) || this.variables().some(function (r) { return r.cloudEnabled; });
            };
            App.prototype.usesCloudLibs = function () {
                return this.librariesAndThis().some(function (l) { return l.isCloud(); });
            };
            App.prototype.usesCppCompiler = function () {
                return this.librariesAndThis().some(function (l) { return l.resolved && l.resolved.useCppCompiler; });
            };
            App.prototype.notifyChange = function () {
                this.notifyVersionMarker = new Object();
                _super.prototype.notifyChange.call(this);
            };
            App.prototype.getGlobalErrorDecl = function (ignoreLibs) {
                return this.things.filter(function (t) { return t.hasErrors() && !(t instanceof Action) && (!ignoreLibs || !(t instanceof AST.LibraryRef)); })[0];
            };
            App.prototype.getDefinedKinds = function () {
                var kindList = [];
                this.things.map(function (t) {
                    var tp = t.getDefinedKind();
                    if (tp)
                        kindList.push(tp);
                });
                return kindList;
            };
            App.prototype.getKinds = function () {
                var kindList = AST.api.getKinds().concat(this.getDefinedKinds());
                this.libraries().forEach(function (l) {
                    kindList.pushRange(l.getPublicKinds());
                });
                return kindList;
            };
            App.capabilityName = function (p) {
                return App.platforms.filter(function (k) { return !!(k.cap & p); }).map(function (k) { return k.name; }).join(", ");
            };
            App.capabilityString = function (p) {
                return App.platforms.filter(function (k) { return !!(k.cap & p); }).map(function (k) { return k.id; }).join(",");
            };
            App.orderThings = function (things, mixActions) {
                if (mixActions === void 0) { mixActions = false; }
                var score = function (t) {
                    if (t instanceof Action) {
                        var a = t;
                        if (mixActions)
                            return 1;
                        if (a.isPage())
                            return 3;
                        else if (a.isEvent())
                            return 2;
                        else if (a.isMainAction())
                            return 0.5;
                        else if (a.isPrivate)
                            return 1.5;
                        else
                            return 1;
                    }
                    else if (t instanceof GlobalDef) {
                        var g = t;
                        if (g.isResource)
                            return 5;
                        else
                            return 4;
                    }
                    else if (t instanceof AST.RecordDef) {
                        return 6;
                    }
                    else if (t instanceof AST.LibraryRef) {
                        return 7;
                    }
                    else {
                        return 0;
                    }
                };
                var cmp = function (a, b) {
                    var diff = score(a) - score(b);
                    if (diff == 0) {
                        var an = a.getName();
                        var bn = b.getName();
                        for (var i = 0; i < an.length; ++i)
                            if (an.charAt(i) != bn.charAt(i))
                                break;
                        if (/^[0-9]$/.test(an.charAt(i)) && /^[0-9]$/.test(bn.charAt(i))) {
                            var dot = false;
                            var c = "";
                            var beg = i - 1;
                            while (beg > 0 && /^[0-9\.]$/.test(c = an.charAt(beg))) {
                                if (c == ".") {
                                    if (dot)
                                        break;
                                    dot = true;
                                }
                                beg--;
                            }
                            beg++;
                            var am = /^(\d*(\.\d+)?)/.exec(an.slice(beg));
                            var bm = /^(\d*(\.\d+)?)/.exec(bn.slice(beg));
                            return parseFloat(am[1]) - parseFloat(bm[1]);
                        }
                        if (a.getName() < b.getName())
                            return -1;
                        else if (a == b)
                            return 0;
                        else
                            return 1;
                    }
                    else
                        return diff;
                };
                things.sort(cmp);
            };
            App.prototype.orderedThings = function (mixActions) {
                if (mixActions === void 0) { mixActions = false; }
                var th = this.things.slice(0);
                App.orderThings(th, mixActions);
                return th;
            };
            App.prototype.canUseProperty = function (p) {
                return (this.getPlatform() & p.getCapability()) == p.getCapability();
            };
            App.prototype.canUseCapability = function (p) {
                return (this.getPlatform() & p) == p;
            };
            App.prototype.supportsAllPlatforms = function (p) {
                return (this.getPlatform() & p) == this.getPlatform();
            };
            App.prototype.getPlatform = function () {
                if (this._platform & 268435456 /* Current */)
                    return AST.api.core.currentPlatform;
                return this._platform;
            };
            App.prototype.getPlatformRaw = function () {
                return this._platform;
            };
            App.prototype.setPlatform = function (p) {
                this._platform = p;
            };
            App.prototype.setPlatformString = function (p) {
                if (!p)
                    this._platform = 0 /* None */;
                var platform = App.fromCapabilityList(p.split(/,/));
                if (platform == 0x3fffff)
                    platform = 268435456 /* Current */;
                if (platform)
                    this._platform = platform;
            };
            App.capabilityByName = function (n) {
                if (!App._platformMapping) {
                    App._platformMapping = {};
                    App.platforms.forEach(function (k) { return App._platformMapping[k.id] = k.cap; });
                }
                n = n.toLowerCase();
                if (App._platformMapping.hasOwnProperty(n))
                    return App._platformMapping[n];
                else
                    return 0 /* None */;
            };
            App.fromCapabilityList = function (ps) {
                var platform = 0 /* None */;
                ps.forEach(function (p) {
                    platform |= App.capabilityByName(p);
                });
                return platform;
            };
            App.prototype.getCapabilityString = function () {
                return App.capabilityString(this._platform);
            };
            App.prototype.getIconArtId = function () {
                return this.iconArtId;
            };
            App.prototype.getBoxInfo = function () {
                return TDev.lf("script properties");
            };
            App.prototype.setVersion = function (v) {
                var f = 0 /* None */;
                v.split(/,/).forEach(function (t) {
                    switch (t) {
                        case 'js':
                            f |= 1 /* JS */;
                            break;
                        case 'ctx':
                            f |= 2 /* ContextCheck */;
                            break;
                        case 'refs':
                            f |= 4 /* Refs */;
                            break;
                        case 'localcloud':
                            f |= 8 /* LocalCloud */;
                            break;
                        case 'unicodemodel':
                            f |= 16 /* UnicodeModel */;
                            break;
                        case 'allasync':
                            f |= 32 /* AllAsync */;
                            break;
                        case 'upperplex':
                            f |= 64 /* UppercaseMultiplex */;
                            break;
                        default: break;
                    }
                });
                this.languageFeatures = f;
            };
            App.prototype.addFeatures = function (f) {
                this.languageFeatures |= f;
            };
            App.prototype.featureMissing = function (f) {
                return (this.languageFeatures & f) == 0;
            };
            App.prototype.setMeta = function (k, v) {
                if (v === true)
                    v = "yes";
                switch (k) {
                    case "icon":
                        this.icon = v;
                        break;
                    case "name":
                        this.setName(v);
                        break;
                    case "color":
                        this.color = v;
                        break;
                    case "seed":
                        this.seed = v;
                        break;
                    case "version":
                        this.setVersion(v);
                        break;
                    case "platform":
                        this.setPlatformString(v);
                        break;
                    case "parentIds":
                        this.parentIds = v.split(/,\s*/).filter(function (x) { return !!x; });
                        break;
                    case "editorState":
                        if (v)
                            try {
                                this.editorState = JSON.parse(v);
                            }
                            catch (e) {
                                TDev.Util.check(false, "editor state corrupted");
                            }
                        break;
                    case "rootId":
                        this.rootId = v;
                        break;
                    case "iconArtId":
                        this.iconArtId = v;
                        break;
                    case "splashArtId":
                        this.splashArtId = v;
                        break;
                    default:
                        if (App.metaMapping.indexOf(k) >= 0)
                            this[k] = v == "yes";
                        this.meta[k] = v;
                }
            };
            App.prototype.mainAction = function () {
                var c0 = this.allActions().filter(function (a) { return a.isRunnable(); });
                if (this.isTutorial()) {
                    var main0 = c0.filter(function (a) { return a.getName() == "#0 main"; })[0];
                    if (main0)
                        return main0;
                }
                var c1 = c0.filter(function (a) { return !a.isPage(); });
                var c2 = c0.filter(function (a) { return a.getName() == "main"; });
                if (c2.length == 0)
                    c2 = c1;
                if (c2.length == 0)
                    c2 = c0;
                if (c2.length > 0)
                    return c2[0];
                else
                    return null;
            };
            App.prototype.findActionByName = function (name) {
                for (var i = 0; i < this.things.length; i++) {
                    var t = this.things[i];
                    if (t instanceof Action && t.getName() == name)
                        return t;
                }
                return null;
            };
            App.prototype.allActions = function () {
                return this.things.filter(function (t) { return t instanceof Action; });
            };
            App.prototype.actions = function () {
                return this.things.filter(function (t) { return t instanceof Action && !(t.isEvent()) && !(t.isActionTypeDef()); });
            };
            App.prototype.events = function () {
                return this.things.filter(function (t) { return t instanceof Action && (t.isEvent()); });
            };
            App.prototype.actionTypeDefs = function () {
                return this.things.filter(function (t) { return t instanceof Action && (t.isActionTypeDef()); });
            };
            App.prototype.libraries = function () {
                return this.things.filter(function (t) { return t instanceof AST.LibraryRef; });
            };
            App.prototype.librariesAndThis = function () {
                return [this.thisLibRef].concat(this.libraries());
            };
            App.prototype.variables = function () {
                return this.things.filter(function (t) { return t instanceof GlobalDef && !t.isResource; });
            };
            App.prototype.resources = function () {
                return this.things.filter(function (t) { return t instanceof GlobalDef && !!t.isResource; });
            };
            App.prototype.variablesAndResources = function () {
                return this.things.filter(function (t) { return t instanceof GlobalDef; });
            };
            App.prototype.records = function () {
                return this.things.filter(function (t) { return t instanceof AST.RecordDef; });
            };
            App.prototype.parsingFinished = function () {
                this.stillParsing = false;
            };
            App.prototype.setStableNames = function () {
            };
            App.prototype.findStableName = function (s) {
                if (!s)
                    return null;
                if (s == this.getStableName())
                    return this;
                return this.things.filter(function (d) { return d.getStableName() == s; })[0];
            };
            App.prototype.toMeta = function () {
                var _this = this;
                var r = {
                    type: "app",
                    version: App.currentVersion,
                    name: this.getName(),
                    icon: this.iconName(),
                    color: this.htmlColor(),
                    comment: AST.TokenWriter.normalizeComment(this.comment),
                    seed: this.seed,
                    localGuid: this.localGuid,
                    platform: this.getCapabilityString(),
                    rootId: this.rootId,
                    parentIds: this.parentIds.join(","),
                };
                if (this.iconArtId)
                    r["iconArtId"] = this.iconArtId;
                if (this.splashArtId)
                    r["splashArtId"] = this.splashArtId;
                App.metaMapping.forEach(function (k) {
                    r[k] = _this[k] ? "yes" : "no";
                });
                return r;
            };
            App.prototype.toJsonScript = function () {
                var r = {
                    kind: "script",
                    time: 0,
                    id: "",
                    userid: "me",
                    username: TDev.lf("Me"),
                    name: this.getName(),
                    description: this.comment,
                    icon: this.icon,
                    iconbackground: this.color,
                    iconArtId: this.iconArtId,
                    splashArtId: this.splashArtId,
                    positivereviews: 0,
                    cumulativepositivereviews: 0,
                    comments: 0,
                    capabilities: [],
                    flows: [],
                    haserrors: this.hasErrors(),
                    rootid: "",
                    updateid: "",
                    ishidden: true,
                    islibrary: this.isLibrary,
                    useCppCompiler: this.useCppCompiler,
                    installations: 0,
                    runs: 0,
                };
                return r;
            };
            App.prototype.loadMeta = function (m) {
                var _this = this;
                Object.keys(m).forEach(function (k) {
                    _this.setMeta(k, m[k]);
                });
                this.comment = m.comment || "";
            };
            App.prototype.serializeFinal = function () {
                var tw = AST.TokenWriter.forStorage();
                this.writeFinal(tw);
                return tw.finalize();
            };
            App.prototype.serializeMeta = function () {
                var tw = AST.TokenWriter.forStorage();
                this.writeMeta(tw);
                return tw.finalize();
            };
            App.prototype.writeMeta = function (tw) {
                var _this = this;
                tw.meta("version", App.currentVersion);
                tw.meta("name", this.getName());
                tw.metaOpt("icon", this.icon);
                var c = this.color;
                if (c) {
                    if (c.length == 7 && c[0] == '#')
                        c = "#ff" + c.slice(1);
                    c = c.toLowerCase();
                    tw.metaOpt("color", c);
                }
                tw.meta("rootId", this.rootId);
                tw.metaOpt("iconArtId", this.iconArtId);
                tw.metaOpt("splashArtId", this.splashArtId);
                App.metaMapping.forEach(function (k) {
                    tw.metaOpt(k, _this[k] ? "yes" : "");
                });
                tw.meta("platform", this.getCapabilityString());
                tw.meta("parentIds", this.parentIds.join(","));
                if (!!this.comment)
                    tw.comment(this.comment);
            };
            App.prototype.writeFinal = function (tw) {
            };
            App.prototype.writeTo = function (tw) {
                this.writeMeta(tw);
                this.things.forEach(function (t) { return t.writeTo(tw); });
                if (!tw.skipActionBodies)
                    this.writeFinal(tw);
            };
            App.prototype.notifyChangeAll = function () {
                this.notifyChange();
                for (var i = 0; i < this.things.length; ++i)
                    this.things[i].notifyChange();
            };
            App.sanitizeScriptTextForCloud = function (s) {
                var r = "";
                if (s) {
                    s = s.replace(/(\r?\n)+$/, "");
                    s.split(/\n/).forEach(function (ln) {
                        if (/^meta (stableNames|editorState)/.test(ln)) {
                        }
                        else {
                            r += ln + "\n";
                        }
                    });
                }
                return r;
            };
            App.prototype.addToUsedIds = function (t) {
                var _this = this;
                var u = this.usedIds;
                var process = function (t) {
                    if (!t.getStableName() || /_/.test(t.getStableName())) {
                        var enc = "";
                        if (!_this.stillParsing) {
                            enc = AST.uniqueAstId(16);
                        }
                        else {
                            enc = TDev.Util.toUTF8(t.getName().replace(/[ _]/g, ""));
                            enc = enc.replace(/[^a-zA-Z0-9]/g, function (c) { return c.charCodeAt(0).toString(16); });
                            if (enc.length > 20)
                                enc = enc.slice(0, 20);
                            if (/^[0-9]/.test(enc))
                                enc = "x" + enc;
                            if (u.hasOwnProperty(enc)) {
                                var add = 1;
                                while (u.hasOwnProperty(enc + add))
                                    add++;
                                enc = enc + add;
                            }
                        }
                        _this.syntheticIds[enc] = true;
                        t.setStableName(enc);
                    }
                    u[t.getStableName()] = t;
                };
                var declExists = function (d) {
                    return d && (d == t || _this.things.indexOf(d) >= 0);
                };
                if (t.getStableName() && declExists(u[t.getStableName()]))
                    t.setStableName(null);
                process(t);
                if (t instanceof AST.RecordDef)
                    t.getFields().forEach(function (f) {
                        if (f.getStableName()) {
                            var q = u[f.getStableName()];
                            if (q && (declExists(q) || (q instanceof AST.RecordField && declExists(q.def()) && q.def().getFields().indexOf(q) >= 0)))
                                f.setStableName(null);
                        }
                        process(f);
                    });
            };
            App.prototype.recomputeStableName = function (t) {
                this.addToUsedIds(t);
            };
            App.prototype.resetStableName = function (t) {
                t.setStableName(null);
                this.recomputeStableName(t);
            };
            App.prototype.addDecl = function (t) {
                t.parent = this;
                this.addToUsedIds(t);
                this.things.push(t);
            };
            App.prototype.deleteDecl = function (t) {
                var i = this.things.indexOf(t);
                t.deleted = true;
                if (i >= 0)
                    this.things.splice(i, 1);
            };
            App.prototype.hasDecl = function (t) {
                return t == this || this.things.indexOf(t) >= 0;
            };
            App.prototype.namesMatch = function (a, b) {
                return a.replace(/\s*\d+$/, "") == b.replace(/\s*\d+$/, "");
            };
            App.prototype.freshName = function (n) {
                var _this = this;
                return AstNode.freshNameCore(n, function (n) { return n == "this" || _this.things.some(function (d) { return d.getName() == n || d.getCoreName() == n; }); });
            };
            App.prototype.findAstNodeById = function (id, allowNonStmt) {
                if (allowNonStmt === void 0) { allowNonStmt = false; }
                if (!id)
                    return null;
                var s = new SearchForId(id);
                s.dispatch(this);
                if (s.foundNode && (allowNonStmt || s.foundNode instanceof Stmt))
                    return { node: s.foundNode, stmt: s.lastStmt, decl: s.lastDecl };
                else
                    return null;
            };
            App.prototype.findStmtByStableName = function (name) {
                var s = new SearchForStableName(name);
                s.dispatch(this);
                return s.found;
            };
            App.currentVersion = "v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex";
            App.metaMapping = ["showAd", "isLibrary", "isCloud", "hasIds", "splitScreen", "useCppCompiler"];
            App.platforms = [
                { cap: 268435456 /* Current */, id: "current", name: TDev.lf("Current device (overrides the rest)") },
                { cap: 1 /* Accelerometer */, id: "accelerometer", name: TDev.lf("Accelerometer") },
                { cap: 4 /* Camera */, id: "camera", name: TDev.lf("Camera") },
                { cap: 33554432 /* CloudData */, id: "clouddata", name: TDev.lf("Cloud Data") },
                { cap: 8 /* Compass */, id: "compass", name: TDev.lf("Compass") },
                { cap: 2048 /* Contacts */, id: "contacts", name: TDev.lf("Contacts") },
                { cap: 262144 /* EditorOnly */, id: "editoronly", name: TDev.lf("Editor only") },
                { cap: 16 /* Gyroscope */, id: "gyroscope", name: TDev.lf("Gyroscope") },
                { cap: 64 /* Location */, id: "location", name: TDev.lf("Location") },
                { cap: 128 /* Maps */, id: "maps", name: TDev.lf("Maps") },
                { cap: 256 /* Media */, id: "media", name: TDev.lf("Media libraries on device") },
                { cap: 512 /* Microphone */, id: "microphone", name: TDev.lf("Microphone") },
                { cap: 1024 /* Motion */, id: "motion", name: TDev.lf("Motion") },
                { cap: 524288 /* MusicAndSounds */, id: "musicandsounds", name: TDev.lf("Music and Sounds") },
                { cap: 1048576 /* Network */, id: "network", name: TDev.lf("Network") },
                { cap: 8388608 /* Proximity */, id: "proximity", name: TDev.lf("NFC") },
                { cap: 16384 /* Orientation */, id: "orientation", name: TDev.lf("Orientation") },
                { cap: 4096 /* Phone */, id: "phone", name: TDev.lf("Phone specific") },
                { cap: 8192 /* Radio */, id: "radio", name: TDev.lf("Radio") },
                { cap: 32768 /* Search */, id: "search", name: TDev.lf("Search") },
                { cap: 16777216 /* Speech */, id: "speech", name: TDev.lf("Speech") },
                { cap: 65536 /* Translation */, id: "translation", name: TDev.lf("Translation") },
                { cap: 4194304 /* Tiles */, id: "tiles", name: TDev.lf("Tiles") },
                { cap: 536870912 /* Npm */, id: "npm", name: TDev.lf("Node Package Manager") },
                { cap: 1073741824 /* Cordova */, id: "cordova", name: TDev.lf("Cordova Plugin Manager") },
                { cap: 2147483648 /* Shell */, id: "shell", name: TDev.lf("Touch Develop Local Shell") },
            ];
            return App;
        })(Decl);
        AST.App = App;
        var ExprHolder = (function (_super) {
            __extends(ExprHolder, _super);
            function ExprHolder() {
                _super.call(this);
                this.debuggingData = {};
                this.hint = "";
            }
            ExprHolder.prototype.nodeType = function () {
                return "exprHolder";
            };
            ExprHolder.prototype.hasValue = function () {
                return true;
            };
            ExprHolder.prototype.isPlaceholder = function () {
                return this.tokens.length == 0 || (this.tokens.length == 1 && this.tokens[0].isPlaceholder());
            };
            ExprHolder.prototype.calcNode = function () {
                return this;
            };
            ExprHolder.prototype.accept = function (v) {
                return v.visitExprHolder(this);
            };
            ExprHolder.prototype.children = function () {
                return this.tokens;
            };
            ExprHolder.prototype.assignmentInfo = function () {
                return !this.parsed ? null : this.parsed.assignmentInfo();
            };
            ExprHolder.prototype.getError = function () {
                if (this._error != null)
                    return this._error;
                if (this.debuggingData.errorMessage)
                    return this.debuggingData.errorMessage;
                for (var i = 0; i < this.tokens.length; ++i)
                    if (this.tokens[i]._error != null)
                        return this.tokens[i]._error;
                return null;
            };
            ExprHolder.prototype.topCall = function (e) {
                if (e === void 0) { e = null; }
                if (!e)
                    e = this.parsed;
                if (!e)
                    return null;
                var prop = e.getCalledProperty();
                if (prop == AST.api.core.AssignmentProp)
                    return this.topCall(e.args[1]);
                else if (prop == AST.api.core.AsyncProp)
                    return this.topCall(e.args[1]);
                else if (e instanceof Call)
                    return e;
                return null;
            };
            ExprHolder.prototype.getLiteral = function () {
                if (this.tokens.length == 1)
                    return this.tokens[0].getLiteral();
                return undefined;
            };
            ExprHolder.prototype.clearError = function () {
                _super.prototype.clearError.call(this);
                this.hint = "";
                this.hasFix = false;
            };
            ExprHolder.prototype.writeTo = function (tw) {
                if (this.isPlaceholder()) {
                    tw.op("...");
                    return;
                }
                var isDigit = function (o) { return o instanceof Operator && /^[0-9\.]$/.test(o.data); };
                var prev = null;
                this.tokens.forEach(function (t) {
                    if (isDigit(t)) {
                        if (!isDigit(prev))
                            tw.sep();
                        tw.op0(t.data);
                    }
                    else {
                        tw.node(t);
                    }
                    prev = t;
                });
            };
            ExprHolder.prototype.forSearch = function () {
                var r = "";
                var wasDigit = false;
                this.tokens.forEach(function (t) {
                    var isDigit = false;
                    var s = t.forSearch();
                    if (t instanceof Operator)
                        isDigit = /[0-9\.]/.test(s);
                    if (!!s) {
                        if (wasDigit && isDigit)
                            r += s;
                        else
                            r += " " + s;
                        wasDigit = isDigit;
                    }
                });
                return r;
            };
            ExprHolder.heatmapColors = ["#ffffff", "#fff5f5", "#fff3ef", "#fff0e9", "#ffeee3", "#ffebdc", "#ffe8d5", "#ffe4ce", "#ffe1c6", "#ffddbe", "#ffd9b6", "#ffd5ad", "#ffd1a3", "#ffcc99", "#ffc78f", "#ffc184", "#ffbb78", "#ffb46b", "#ffad5e", "#ffa54f", "#ff9d3f", "#ff932c", "#ff8912", "#ff7e00", "#ff7300", "#ff6500", "#ff5300", "#ff3800"];
            return ExprHolder;
        })(AstNode);
        AST.ExprHolder = ExprHolder;
        var Token = (function (_super) {
            __extends(Token, _super);
            function Token() {
                _super.call(this);
            }
            Token.prototype.getText = function () {
                return null;
            };
            Token.prototype.toString = function () {
                return this.getText();
            };
            Token.prototype.hasValue = function () {
                return true;
            };
            Token.prototype.forSearch = function () {
                return "";
            };
            Token.prototype.matches = function (d) {
                return false;
            };
            Token.prototype.getCall = function () {
                return null;
            };
            Token.prototype.getOperator = function () {
                return null;
            };
            Token.prototype.getFunArgs = function () {
                return null;
            };
            Token.prototype.getProperty = function () {
                return null;
            };
            Token.prototype.getCalledProperty = function () {
                return null;
            };
            Token.prototype.getLiteral = function () {
                return null;
            };
            Token.prototype.getStringLiteral = function () {
                if (typeof this.getLiteral() == "string")
                    return this.getLiteral();
                return null;
            };
            Token.prototype.getNumberLiteral = function () {
                if (typeof this.getLiteral() == "number")
                    return this.getLiteral();
                return null;
            };
            Token.prototype.getThing = function () {
                return null;
            };
            Token.prototype.getLocalDef = function () {
                var r = this.getThing();
                if (r instanceof LocalDef)
                    return r;
                else
                    return null;
            };
            Token.prototype.isDigit = function () {
                return false;
            };
            Token.prototype.getForwardedDecl = function () {
                var p = this.getProperty();
                if (!p)
                    return null;
                return p.forwardsTo();
            };
            Token.prototype.eq = function (other) {
                return this.nodeType() == other.nodeType() && this.getText() == other.getText();
            };
            return Token;
        })(AstNode);
        AST.Token = Token;
        var Expr = (function (_super) {
            __extends(Expr, _super);
            function Expr() {
                _super.call(this);
            }
            Expr.prototype.flatten = function (prop) {
                return [this];
            };
            Expr.prototype.calledAction = function () {
                return null;
            };
            Expr.prototype.anyCalledAction = function () {
                return this.calledAction() || this.calledExtensionAction();
            };
            Expr.prototype.calledExtensionAction = function () {
                return null;
            };
            Expr.prototype.referencedRecordField = function () {
                return null;
            };
            Expr.prototype.referencedRecord = function () {
                return null;
            };
            Expr.prototype.referencedData = function () {
                return null;
            };
            Expr.prototype.referencedLibrary = function () {
                return null;
            };
            Expr.prototype.referencedLocal = function () {
                return null;
            };
            Expr.prototype.getLiftedSetter = function () {
                return null;
            };
            Expr.prototype.calledProp = function () {
                return null;
            };
            Expr.prototype.assignmentInfo = function () {
                return null;
            };
            Expr.prototype.isRefValue = function () {
                return false;
            };
            Expr.prototype.allowRefUse = function () {
                return false;
            };
            Expr.prototype.isEscapeDef = function () {
                return false;
            };
            return Expr;
        })(Token);
        AST.Expr = Expr;
        var Literal = (function (_super) {
            __extends(Literal, _super);
            function Literal() {
                _super.call(this);
            }
            Literal.prototype.nodeType = function () {
                return "literal";
            };
            Literal.prototype.getText = function () {
                return this.data + "";
            };
            Literal.prototype.accept = function (v) {
                return v.visitLiteral(this);
            };
            Literal.prototype.getLiteral = function () {
                return this.data;
            };
            Literal.prototype.writeTo = function (tw) {
                switch (typeof this.data) {
                    case "string":
                        tw.string(this.data);
                        break;
                    case "number":
                        tw.op(this.data.toString());
                        break;
                    case "boolean":
                        tw.id(this.data ? "true" : "false");
                        break;
                    default:
                        TDev.Util.oops("cannot writeTo " + this.data);
                        break;
                }
            };
            Literal.prototype.forSearch = function () {
                switch (typeof this.data) {
                    case "string":
                        return this.data.toLowerCase();
                    case "number":
                        return this.data.toString();
                    case "boolean":
                        return this.data ? "true" : "false";
                    default:
                        TDev.Util.oops("cannot writeTo " + this.data);
                        return "";
                }
            };
            return Literal;
        })(Expr);
        AST.Literal = Literal;
        var DeclName = (function (_super) {
            __extends(DeclName, _super);
            function DeclName() {
                _super.call(this);
            }
            DeclName.prototype.accept = function (v) {
                return v.visitDeclName(this);
            };
            return DeclName;
        })(Literal);
        AST.DeclName = DeclName;
        var Operator = (function (_super) {
            __extends(Operator, _super);
            function Operator() {
                _super.call(this);
            }
            Operator.prototype.getText = function () {
                return this.data;
            };
            Operator.prototype.nodeType = function () {
                return "operator";
            };
            Operator.prototype.accept = function (v) {
                return v.visitOperator(this);
            };
            Operator.prototype.getOperator = function () {
                return this.data;
            };
            Operator.prototype.isDigit = function () {
                return /^[0-9.\-]$/.test(this.data);
            };
            Operator.prototype.writeTo = function (tw) {
                if (this.data == "(" || this.data == ")")
                    tw.op0(this.data);
                else if (this.data == ",")
                    tw.op0(this.data).space();
                else if (/^fun:/.test(this.data))
                    tw.op("fun:" + this.getFunArgs().map(idUrlQuote).join(","));
                else
                    tw.op(this.data);
            };
            Operator.prototype.forSearch = function () {
                return this.data;
            };
            Operator.prototype.getFunArgs = function () {
                if (!/^fun:/.test(this.data))
                    return;
                if (this.funArgs)
                    return this.funArgs.map(function (p) { return p.getName(); });
                return this.data.slice(4).split(",").map(idUrlUnquote);
            };
            return Operator;
        })(Token);
        AST.Operator = Operator;
        var PropertyRef = (function (_super) {
            __extends(PropertyRef, _super);
            function PropertyRef() {
                _super.call(this);
            }
            PropertyRef.prototype.nodeType = function () {
                return "propertyRef";
            };
            PropertyRef.prototype.accept = function (v) {
                return v.visitPropertyRef(this);
            };
            PropertyRef.prototype.getText = function () {
                return !this.prop ? this.data : this.prop.getName();
            };
            PropertyRef.prototype.getProperty = function () {
                return this.prop;
            };
            PropertyRef.prototype.getOrMakeProp = function () {
                if (this.prop)
                    return this.prop;
                return new TDev.UnresolvedProperty(AST.api.core.Unknown, this.data);
            };
            PropertyRef.mkProp = function (p) {
                var r = new PropertyRef();
                r.prop = p;
                return r;
            };
            PropertyRef.prototype.writeTo = function (tw) {
                var c = tw.lastChar;
                if (!/^[A-Za-z0-9_\)]$/.test(c))
                    tw.space();
                tw.op0("\u2192").id0(this.getText());
            };
            PropertyRef.prototype.forSearch = function () {
                return this.getText().toLowerCase();
            };
            PropertyRef.prototype.matches = function (d) {
                if (!this.prop)
                    return false;
                if (this.prop.forwardsTo() == d)
                    return true;
                if (d instanceof AST.RecordField && d.asProperty() == this.prop)
                    return true;
                return false;
            };
            PropertyRef.prototype.getCall = function () {
                return this.call;
            };
            return PropertyRef;
        })(Token);
        AST.PropertyRef = PropertyRef;
        var ThingRef = (function (_super) {
            __extends(ThingRef, _super);
            function ThingRef() {
                _super.call(this);
                this.forceLocal = false;
            }
            ThingRef.prototype.getText = function () {
                return !this.def ? this.data : this.def.getName();
            };
            ThingRef.prototype.shortName = function () {
                return !this.def ? null : this.def instanceof SingletonDef ? this.def.getKind().shortName() : null;
            };
            ThingRef.prototype.nodeType = function () {
                return "thingRef";
            };
            ThingRef.prototype.isPlaceholder = function () {
                return this.getText() == "$skip" || this.getText() == "...";
            };
            ThingRef.prototype.accept = function (v) {
                return v.visitThingRef(this);
            };
            ThingRef.prototype.getThing = function () {
                return this.def;
            };
            ThingRef.prototype.referencedLocal = function () {
                if (this.def instanceof LocalDef)
                    return this.def;
                return null;
            };
            ThingRef.prototype.isEscapeDef = function () {
                return this.def instanceof PlaceholderDef && !!this.def.escapeDef;
            };
            ThingRef.prototype.namespaceLibraryName = function () {
                if (this.namespaceLibrary)
                    return (this._namespaceLibraryName = this.namespaceLibrary.getName());
                return this._namespaceLibraryName;
            };
            ThingRef.prototype.writeTo = function (tw) {
                if (this.def instanceof LocalDef)
                    tw.sep().op0("$").id0(this.getText());
                else if (this.def instanceof PlaceholderDef)
                    tw.id("\u0001" + this.def.getName());
                else if (this.namespaceLibraryName())
                    tw.id(this.getText()).op0("[").id("lib").id(this.namespaceLibraryName()).op0("]");
                else if (this.def instanceof SingletonDef && this.def.firstLibraryRef)
                    tw.id(this.getText()).op0("[").id("lib").id(this.def.firstLibraryRef.getName()).op0("]");
                else
                    tw.id(this.getText());
            };
            ThingRef.prototype.forSearch = function () {
                return this.getText().toLowerCase();
            };
            ThingRef.prototype.matches = function (d) {
                return this.def == d;
            };
            ThingRef.placeholderPrefix = "\u0001need ";
            return ThingRef;
        })(Expr);
        AST.ThingRef = ThingRef;
        var AssignmentInfo = (function () {
            function AssignmentInfo() {
                this.missingArguments = 0;
                this.definedVars = [];
                this.targets = [];
                this.sources = [];
                this.isPagePush = false;
            }
            return AssignmentInfo;
        })();
        AST.AssignmentInfo = AssignmentInfo;
        var Call = (function (_super) {
            __extends(Call, _super);
            function Call() {
                _super.call(this);
            }
            Call.prototype.children = function () {
                return this.args;
            };
            Call.prototype.assignmentInfo = function () {
                return this._assignmentInfo;
            };
            Call.prototype.nodeType = function () {
                return "call";
            };
            Call.prototype.getCalledProperty = function () {
                return this.prop();
            };
            Call.prototype.getText = function () {
                var res = this.propRef.getText() + "(";
                for (var i = 0; i < this.args.length; ++i) {
                    if (i > 0)
                        res += ", ";
                    res += this.args[i].getText();
                }
                res += ")";
                return res;
            };
            Call.prototype.referencedRecord = function () {
                var prop = this.prop();
                if (prop instanceof AST.RecordDef)
                    return prop;
                return null;
            };
            Call.prototype.referencedRecordField = function () {
                var prop = this.prop();
                if (!prop)
                    return null;
                var fwd = prop.forwardsToStmt();
                if (fwd instanceof AST.RecordField)
                    return fwd;
                return null;
            };
            Call.prototype.referencedData = function () {
                if (this.prop() && this.prop().getCategory() == 2 /* Data */)
                    return this.prop().forwardsTo();
                else
                    return null;
            };
            Call.prototype.referencedLibrary = function () {
                var prop = this.prop();
                if (prop instanceof AST.LibraryRef)
                    return prop;
                return null;
            };
            Call.prototype.getCall = function () {
                return this;
            };
            Call.prototype.getLiftedSetter = function () {
                var prop = this.prop();
                if (!prop)
                    return null;
                if (prop.getFlags() & 4096 /* Async */)
                    return null;
                if (prop.getParameters().length != 1)
                    return null;
                var tp = prop.getResult().getKind();
                if (tp.equals(AST.api.core.Nothing))
                    return null;
                var setter = prop.parentKind.getProperty("set " + prop.getName());
                if (setter && !(setter.getFlags() & 4096 /* Async */) && setter.getResult().getKind().equals(AST.api.core.Nothing)) {
                    var parms = setter.getParameters();
                    if (parms.length == 2 && parms[1].getKind().equals(tp))
                        return setter;
                }
                return null;
            };
            Call.prototype.isRefValue = function () {
                var gd = this.referencedData();
                if (gd)
                    return true;
                var rcf = this.referencedRecordField();
                if (rcf && !rcf.isKey)
                    return true;
                return false;
            };
            Call.prototype.allowAssignment = function () {
                return this.allowRefUse() || !!this.getLiftedSetter();
            };
            Call.prototype.allowRefUse = function () {
                if (!this.isRefValue())
                    return false;
                var gd = this.referencedData();
                if (gd && gd.readonly)
                    return false;
                return true;
            };
            Call.prototype.prop = function () {
                return this.propRef.prop;
            };
            Call.prototype.calledProp = function () {
                return this.prop();
            };
            Call.prototype.flatten = function (prop) {
                if (this.propRef.prop == prop) {
                    return this.args.collect(function (e) { return e.flatten(prop); });
                }
                else {
                    return [this];
                }
            };
            Call.prototype.accept = function (v) {
                var p = this.prop();
                if (!p || p.parentKind != AST.api.core.Unknown)
                    return v.visitCall(this);
                if (p == AST.api.core.AssignmentProp)
                    return v.visitAssignment(this);
                else if (p == AST.api.core.ReturnProp)
                    return v.visitReturn(this);
                else if (p == AST.api.core.BreakProp)
                    return v.visitBreak(this);
                else if (p == AST.api.core.ContinueProp)
                    return v.visitContinue(this);
                else if (p == AST.api.core.ShowProp)
                    return v.visitShow(this);
                return v.visitCall(this);
            };
            Call.prototype.calledAction = function () {
                if (this.prop() && this.prop().getCategory() == 1 /* Action */)
                    return this.prop().forwardsTo();
                else
                    return null;
            };
            Call.prototype.calledExtensionAction = function () {
                var prop = this.prop();
                if (prop instanceof ExtensionProperty)
                    return prop.shortcutTo;
                var act = this.calledAction();
                if (act && act.isExtensionAction())
                    return act.extensionForward();
                return null;
            };
            Call.prototype.awaits = function () {
                return !this.runAsAsync && this.prop() && !!(this.prop().getFlags() & 4096 /* Async */);
            };
            return Call;
        })(Expr);
        AST.Call = Call;
        function mkLocal(name, k) {
            var r = new LocalDef();
            r.setName(name);
            r._kind = k;
            return r;
        }
        AST.mkLocal = mkLocal;
        function mkLit(v) {
            var r = new Literal();
            r.data = v;
            return r;
        }
        AST.mkLit = mkLit;
        function mkOp(v) {
            var o = new Operator();
            o.data = v;
            return o;
        }
        AST.mkOp = mkOp;
        function mkFunOp(args) {
            return mkOp("fun:" + args.map(idUrlQuote).join(","));
        }
        AST.mkFunOp = mkFunOp;
        function mkThing(v, forceLocal) {
            if (forceLocal === void 0) { forceLocal = false; }
            if (v == "true" || v == "false")
                return mkLit(v == "true");
            var t = new ThingRef();
            t.data = v;
            t.forceLocal = forceLocal;
            return t;
        }
        AST.mkThing = mkThing;
        function mkLocalRef(l) {
            return mkThing(l.getName(), true);
        }
        AST.mkLocalRef = mkLocalRef;
        function mkPlaceholderByKind(k) {
            return mkPlaceholder({ getName: function () { return "this"; }, getKind: function () { return k; } });
        }
        AST.mkPlaceholderByKind = mkPlaceholderByKind;
        function mkPlaceholder(p) {
            var name = p.getName();
            if (name == "this" || p.parentProperty.getInfixPriority() > 0 || name == p.getKind().getStemName())
                name = "";
            var def = new PlaceholderDef();
            def.label = name;
            def._kind = p.getKind();
            var t = new ThingRef();
            t.def = def;
            t.data = def.getName();
            return t;
        }
        AST.mkPlaceholder = mkPlaceholder;
        function mkPropRef(v) {
            var p = new PropertyRef();
            p.data = v;
            return p;
        }
        AST.mkPropRef = mkPropRef;
        function mkSingletonDef(n, k) {
            var s = new SingletonDef();
            s.setName(n);
            s._kind = k;
            if (k.isPrivate)
                s._isBrowsable = false;
            return s;
        }
        AST.mkSingletonDef = mkSingletonDef;
        function mkTok(json) {
            switch (json.type) {
                case "literal": return mkLit(json.data);
                case "operator": return mkOp(json.data);
                case "propertyRef": return mkPropRef(json.data);
                case "thingRef": return mkThing(json.data, json.forceLocal);
                default: TDev.Util.die();
            }
        }
        AST.mkTok = mkTok;
        function mkParam(name, k) {
            return mkLocal(name, k);
        }
        AST.mkParam = mkParam;
        function mkPlaceholderThingRef() {
            return mkThing("$skip");
        }
        AST.mkPlaceholderThingRef = mkPlaceholderThingRef;
        function mkExprStmt(expr, p) {
            if (p === void 0) { p = null; }
            var r = new ExprStmt();
            if (p) {
                r.setStableName(p.consumeLabel());
            }
            r.expr = expr;
            return r;
        }
        AST.mkExprStmt = mkExprStmt;
        function exprToStmt(expr) {
            var r = new ExprHolder();
            r.tokens = [];
            r.locals = [];
            r.parsed = expr;
            return mkExprStmt(r);
        }
        AST.exprToStmt = exprToStmt;
        function mkWhere(expr) {
            var r = new Where();
            r.condition = expr;
            return r;
        }
        AST.mkWhere = mkWhere;
        function mkFakeCall(prop, args) {
            if (args === void 0) { args = []; }
            var t = new Call();
            t.propRef = prop;
            t.args = args;
            t.isSynthetic = true;
            return t;
        }
        AST.mkFakeCall = mkFakeCall;
        function mkCall(prop, a) {
            var t = new Call();
            TDev.Util.assert(a.length > 0);
            t.propRef = prop;
            prop.call = t;
            t.args = a;
            return t;
        }
        AST.mkCall = mkCall;
        function idUrlQuote(s) {
            var sb = "";
            for (var i = 0; i < s.length; ++i) {
                var c = s.charAt(i);
                if (/[A-Za-z0-9]/.test(c))
                    sb += c;
                else if (c == " ")
                    sb += "_";
                else
                    sb += "-" + (c.charCodeAt(0) | 0x10000).toString(16).slice(-4);
            }
            return sb;
        }
        AST.idUrlQuote = idUrlQuote;
        function idUrlUnquote(s) {
            var r = "";
            for (var i = 0; i < s.length; ++i) {
                var c = s.charAt(i);
                if (c == "_") {
                    r += " ";
                }
                else if (c == "/" || c == "-") {
                    r += String.fromCharCode(parseInt(s.slice(i + 1, i + 5), 16));
                    i += 4;
                }
                else {
                    r += c;
                }
            }
            return r;
        }
        AST.idUrlUnquote = idUrlUnquote;
        function isProperKind(k) {
            return k && k != AST.api.core.Unknown && !(k instanceof TDev.MultiplexKind);
        }
        AST.isProperKind = isProperKind;
        var NodeVisitor = (function () {
            function NodeVisitor() {
            }
            NodeVisitor.prototype.visitAstNode = function (node) {
                return null;
            };
            NodeVisitor.prototype.visitToken = function (tok) {
                return this.visitAstNode(tok);
            };
            NodeVisitor.prototype.visitOperator = function (n) {
                return this.visitToken(n);
            };
            NodeVisitor.prototype.visitPropertyRef = function (n) {
                return this.visitToken(n);
            };
            NodeVisitor.prototype.visitExpr = function (tok) {
                return this.visitToken(tok);
            };
            NodeVisitor.prototype.visitLiteral = function (n) {
                return this.visitExpr(n);
            };
            NodeVisitor.prototype.visitThingRef = function (n) {
                return this.visitExpr(n);
            };
            NodeVisitor.prototype.visitCall = function (n) {
                return this.visitExpr(n);
            };
            NodeVisitor.prototype.visitShow = function (n) {
                return this.visitCall(n);
            };
            NodeVisitor.prototype.visitBreak = function (n) {
                return this.visitCall(n);
            };
            NodeVisitor.prototype.visitContinue = function (n) {
                return this.visitCall(n);
            };
            NodeVisitor.prototype.visitReturn = function (n) {
                return this.visitCall(n);
            };
            NodeVisitor.prototype.visitAssignment = function (n) {
                return this.visitCall(n);
            };
            NodeVisitor.prototype.visitExprHolder = function (n) {
                return this.visitAstNode(n);
            };
            NodeVisitor.prototype.visitStmt = function (n) {
                return this.visitAstNode(n);
            };
            NodeVisitor.prototype.visitComment = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitBlock = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitCodeBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitConditionBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitParameterBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitResolveBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitBindingBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitFieldBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitInlineActionBlock = function (n) {
                return this.visitBlock(n);
            };
            NodeVisitor.prototype.visitFor = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitForeach = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitWhile = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitBox = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitAnyIf = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitIf = function (n) {
                return this.visitAnyIf(n);
            };
            NodeVisitor.prototype.visitElseIf = function (n) {
                return this.visitAnyIf(n);
            };
            NodeVisitor.prototype.visitForeachClause = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitWhere = function (n) {
                return this.visitForeachClause(n);
            };
            NodeVisitor.prototype.visitExprStmt = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitInlineActions = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitInlineAction = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitOptionalParameter = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitActionParameter = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitActionHeader = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitDecl = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitGlobalDef = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitLibraryRef = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitRecordDef = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitSingletonDef = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitAction = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitLocalDef = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitApp = function (n) {
                return this.visitDecl(n);
            };
            NodeVisitor.prototype.visitKindBinding = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitActionBinding = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitResolveClause = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitRecordField = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.visitFieldName = function (n) {
                return this.visitLiteral(n);
            };
            NodeVisitor.prototype.visitDeclName = function (n) {
                return this.visitLiteral(n);
            };
            NodeVisitor.prototype.visitInlineStmt = function (n) {
                return this.visitStmt(n);
            };
            NodeVisitor.prototype.dispatch = function (n) {
                return n.accept(this);
            };
            NodeVisitor.prototype.visitChildren = function (n) {
                var _this = this;
                n.children().forEach(function (c) { return c.accept(_this); });
            };
            return NodeVisitor;
        })();
        AST.NodeVisitor = NodeVisitor;
        var SearchForStableName = (function (_super) {
            __extends(SearchForStableName, _super);
            function SearchForStableName(name) {
                _super.call(this);
                this.name = name;
            }
            SearchForStableName.prototype.visitStmt = function (s) {
                if (s.getStableName() == this.name)
                    this.found = s;
                this.visitChildren(s);
            };
            return SearchForStableName;
        })(AST.NodeVisitor);
        var SearchForId = (function (_super) {
            __extends(SearchForId, _super);
            function SearchForId(id) {
                _super.call(this);
                this.id = id;
            }
            SearchForId.prototype.check = function (n) {
                if (n.stableId == this.id)
                    this.foundNode = n;
            };
            SearchForId.prototype.visitDecl = function (d) {
                this.check(d);
                if (!this.foundNode) {
                    this.lastDecl = d;
                    this.visitChildren(d);
                }
                return null;
            };
            SearchForId.prototype.visitExprHolder = function (eh) {
                if (eh.parsed)
                    this.dispatch(eh.parsed);
                this.visitAstNode(eh);
            };
            SearchForId.prototype.visitAstNode = function (n) {
                this.check(n);
                this.visitChildren(n);
            };
            SearchForId.prototype.visitStmt = function (s) {
                if (!this.foundNode) {
                    this.lastStmt = s;
                    this.check(s);
                    this.visitChildren(s);
                }
                return null;
            };
            return SearchForId;
        })(AST.NodeVisitor);
        var StatsComputer = (function (_super) {
            __extends(StatsComputer, _super);
            function StatsComputer() {
                _super.call(this);
                this.stmtCount = 0;
                this.weight = 0;
            }
            StatsComputer.prototype.visitAction = function (n) {
                this.action = n;
                this.visitChildren(n);
                if (n.isPage())
                    this.weight = 2;
                else if (n.isEvent())
                    this.weight = 1;
                else if (n.isPrivate)
                    this.weight = 0;
                else if (n.isMainAction())
                    this.weight = 4;
                else
                    this.weight = 3;
                return null;
            };
            StatsComputer.prototype.visitBlock = function (b) {
                this.visitChildren(b);
                return null;
            };
            StatsComputer.prototype.visitStmt = function (s) {
                if (!s.isPlaceholder())
                    this.stmtCount++;
                this.visitChildren(s);
                return null;
            };
            return StatsComputer;
        })(NodeVisitor);
        AST.StatsComputer = StatsComputer;
        var StackOp = (function () {
            function StackOp() {
                this.expr = null;
                this.beg = 0;
                this.len = 0;
                this.prioOverride = 0;
            }
            StackOp.prototype.prio = function () {
                if (this.prioOverride != 0)
                    return this.prioOverride;
                if (!this.infixProperty)
                    return 0;
                return this.infixProperty.getInfixPriority();
            };
            StackOp.prototype.markError = function (msg) {
                var i = this.beg;
                if (i < 0 || i >= this.tokens.length)
                    i = this.tokens.length - 1;
                var end = i + this.len;
                if (end <= i || end > this.tokens.length)
                    end = this.tokens.length;
                while (i < end) {
                    this.tokens[i].setError(msg);
                    i++;
                }
            };
            StackOp.prototype.copyFrom = function (other) {
                this.tokens = other.tokens;
                this.beg = other.beg;
                this.len = other.len;
            };
            return StackOp;
        })();
        AST.StackOp = StackOp;
        var VariableFinder = (function (_super) {
            __extends(VariableFinder, _super);
            function VariableFinder() {
                _super.apply(this, arguments);
                this.saveWrites = false;
                this.getGlobals = false;
            }
            VariableFinder.prototype.add = function (s, l, lst) {
                if (l instanceof LocalDef && lst.indexOf(l) < 0) {
                    if (this.saveWrites && s)
                        l._lastWriteLocation = s;
                    lst.push(l);
                }
            };
            VariableFinder.prototype.getLocal = function (e) {
                if (e instanceof ThingRef) {
                    var d = e.def;
                    if (d instanceof LocalDef)
                        return d;
                }
                return null;
            };
            VariableFinder.realName = function (g) {
                return "$" + g.getStableName();
            };
            VariableFinder.prototype.writtenGlobalNames = function () {
                return this.writtenGlobals.map(VariableFinder.realName);
            };
            VariableFinder.prototype.readGlobalNames = function () {
                return this.readGlobals.map(VariableFinder.realName);
            };
            VariableFinder.prototype.addGlobal = function (l, lst) {
                if (lst.indexOf(l) < 0)
                    lst.push(l);
            };
            VariableFinder.prototype.getGlobal = function (e) {
                if (e instanceof Call) {
                    var prop = e.prop();
                    if (prop instanceof GlobalDef || prop instanceof AST.RecordDef)
                        return prop;
                }
                return null;
            };
            VariableFinder.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            VariableFinder.prototype.visitStmt = function (s) {
                this.lastStmt = s;
                this.visitChildren(s);
                return null;
            };
            VariableFinder.prototype.visitAction = function (n) {
                if (this.visitedActions && this.visitedActions.indexOf(n) < 0) {
                    this.visitedActions.push(n);
                    _super.prototype.visitAction.call(this, n);
                }
            };
            VariableFinder.prototype.visitThingRef = function (n) {
                this.add(null, n.def, this.readLocals0);
                return null;
            };
            VariableFinder.prototype.visitCall = function (n) {
                var _this = this;
                var prop = n.prop();
                if (prop == AST.api.core.AssignmentProp) {
                    n.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                        var l = _this.getLocal(e);
                        if (l)
                            _this.add(null, l, _this.writtenLocals0);
                        else if (_this.getGlobals) {
                            var g = _this.getGlobal(e);
                            if (g)
                                _this.addGlobal(g, _this.writtenGlobals);
                            else
                                _this.dispatch(e);
                        }
                        else
                            _this.dispatch(e);
                    });
                    this.dispatch(n.args[1]);
                }
                else if (this.getGlobals) {
                    var act = n.calledAction();
                    if (act && this.visitedActions && this.visitedActions.indexOf(act) < 0) {
                        var readLocals0 = this.readLocals0;
                        var writtenLocals0 = this.writtenLocals0;
                        var readLocals = this.readLocals;
                        var writtenLocals = this.writtenLocals;
                        var readGlobals = this.readGlobals;
                        var writtenGlobals = this.writtenGlobals;
                        this.traverse(act, true, this.visitedActions);
                        readGlobals.forEach(function (g) { return _this.addGlobal(g, _this.readGlobals); });
                        writtenGlobals.forEach(function (g) { return _this.addGlobal(g, _this.writtenGlobals); });
                        this.readLocals0 = readLocals0;
                        this.writtenLocals0 = writtenLocals0;
                        this.readLocals = readLocals;
                        this.writtenLocals = writtenLocals;
                    }
                    if (prop instanceof GlobalDef) {
                        this.addGlobal(prop, this.readGlobals);
                        this.addGlobal(prop, this.writtenGlobals);
                    }
                    else if (prop instanceof AST.RecordDef) {
                        this.addGlobal(prop, this.readGlobals);
                        this.addGlobal(prop, this.writtenGlobals);
                    }
                    else {
                        _super.prototype.visitCall.call(this, n);
                    }
                }
                else {
                    _super.prototype.visitCall.call(this, n);
                }
                return null;
            };
            VariableFinder.prototype.visitInlineAction = function (n) {
                var _this = this;
                n.inParameters.forEach(function (i) { return _this.add(n, i, _this.writtenLocals); });
                _super.prototype.visitInlineAction.call(this, n);
            };
            VariableFinder.prototype.visitExprHolder = function (n) {
                var _this = this;
                var stmt = this.lastStmt;
                this.readLocals0 = [];
                this.writtenLocals0 = [];
                if (n.parsed)
                    this.dispatch(n.parsed);
                n.tokens.forEach(function (t) {
                    var l = _this.getLocal(t);
                    if (l && _this.readLocals0.indexOf(l) < 0 && _this.writtenLocals0.indexOf(l) < 0)
                        _this.add(null, l, _this.readLocals0);
                });
                this.readLocals0.forEach(function (l) { return _this.add(null, l, _this.readLocals); });
                this.writtenLocals0.forEach(function (l) { return _this.add(stmt, l, _this.writtenLocals); });
                return null;
            };
            VariableFinder.prototype.visitFor = function (n) {
                this.add(n, n.boundLocal, this.writtenLocals);
                _super.prototype.visitFor.call(this, n);
                return null;
            };
            VariableFinder.prototype.visitForeach = function (n) {
                this.add(n, n.boundLocal, this.writtenLocals);
                _super.prototype.visitForeach.call(this, n);
                return null;
            };
            VariableFinder.prototype.traverse = function (node, getGlobals, visitedActions) {
                if (getGlobals === void 0) { getGlobals = false; }
                if (visitedActions === void 0) { visitedActions = []; }
                this.readLocals = [];
                this.writtenLocals = [];
                this.getGlobals = getGlobals;
                if (getGlobals) {
                    this.readGlobals = [];
                    this.writtenGlobals = [];
                    this.visitedActions = visitedActions;
                }
                this.dispatch(node);
            };
            return VariableFinder;
        })(NodeVisitor);
        AST.VariableFinder = VariableFinder;
        var Extractor = (function (_super) {
            __extends(Extractor, _super);
            function Extractor(extracted, action, callPlaceholder, name) {
                _super.call(this);
                this.extracted = extracted;
                this.action = action;
                this.callPlaceholder = callPlaceholder;
                this.name = name;
                this.numAwait = 0;
                this.failed = [];
            }
            Extractor.prototype.visitCall = function (c) {
                _super.prototype.visitCall.call(this, c);
                if (c.awaits())
                    this.numAwait++;
            };
            Extractor.prototype.run = function () {
                var _this = this;
                AST.visitStmtsCtx({ inLoop: false, inHandler: false }, this.extracted, function (ctx, s) {
                    if (s.calcNode() && s.calcNode().parsed) {
                        var prop = s.calcNode().parsed.calledProp();
                        if (!ctx.inLoop && (prop == AST.api.core.BreakProp || prop == AST.api.core.ContinueProp))
                            _this.failed.push(s);
                        if (!ctx.inHandler && (prop == AST.api.core.ReturnProp))
                            _this.failed.push(s);
                    }
                    ctx = TDev.Util.jsonClone(ctx);
                    if (s instanceof Loop)
                        ctx.inLoop = true;
                    if (s instanceof InlineAction) {
                        ctx.inHandler = true;
                        ctx.inLoop = true;
                    }
                    return ctx;
                });
                if (this.failed.length > 0)
                    return;
                this.saveWrites = true;
                this.traverse(this.extracted);
                var hasAwait = this.numAwait > 0;
                var readSub = this.readLocals;
                var writtenSub = this.writtenLocals;
                this.saveWrites = false;
                this.traverse(this.action.body);
                this.action.getInParameters().forEach(function (p) { return _this.add(null, p.local, _this.writtenLocals); });
                if (this.action.modelParameter)
                    this.add(null, this.action.modelParameter.local, this.writtenLocals);
                this.action.getOutParameters().forEach(function (p) { return _this.add(null, p.local, _this.readLocals); });
                var outgoing = writtenSub.filter(function (l) { return _this.readLocals.indexOf(l) >= 0; });
                var incoming = readSub.filter(function (l) { return _this.writtenLocals.indexOf(l) >= 0; });
                var useReturn = outgoing.length == 1;
                if (outgoing.length > 1) {
                    this.failed = outgoing.map(function (l) { return l._lastWriteLocation; });
                    return;
                }
                var refLocal = function (l) { return mkThing(l.getName()); };
                var copyNames = {};
                var extractedStmts = this.extracted.stmts.slice(0);
                var extractedAction = AST.Parser.parseDecl("action go() { meta private; }");
                extractedAction.setName(this.name);
                extractedAction.body = this.extracted;
                extractedAction.isAtomic = !hasAwait;
                extractedAction.header.inParameters.pushRange(incoming.map(function (l) { return new ActionParameter(l); }));
                outgoing.forEach(function (l) {
                    if (useReturn || incoming.indexOf(l) >= 0) {
                        var copy = mkLocal(_this.action.nameLocal(l.getName(), copyNames), l.getKind());
                        copyNames[copy.getName()] = true;
                        var stmt = AST.Parser.emptyExprStmt();
                        if (useReturn)
                            stmt.expr.tokens = [AST.mkOp("return"), refLocal(l)];
                        else
                            stmt.expr.tokens = [refLocal(copy), mkOp(":="), refLocal(l)];
                        extractedStmts.push(stmt);
                        l = copy;
                    }
                    extractedAction.header.outParameters.push(new ActionParameter(l, true));
                });
                this.extracted.setChildren(extractedStmts);
                var res = AST.Parser.parseDecl(extractedAction.serialize());
                this.extractedAction = res;
                var toks = this.callPlaceholder.expr.tokens;
                if (outgoing.length > 0) {
                    outgoing.forEach(function (l, i) {
                        if (i > 0)
                            toks.push(mkOp(","));
                        toks.push(refLocal(l));
                    });
                    toks.push(mkOp(":="));
                }
                toks.push(mkThing("code"));
                toks.push(mkPropRef(this.name));
                if (incoming.length > 0) {
                    toks.push(mkOp("("));
                    incoming.forEach(function (l, i) {
                        if (i > 0)
                            toks.push(mkOp(","));
                        toks.push(refLocal(l));
                    });
                    toks.push(mkOp(")"));
                }
            };
            return Extractor;
        })(VariableFinder);
        AST.Extractor = Extractor;
        var MethodFinder = (function (_super) {
            __extends(MethodFinder, _super);
            function MethodFinder() {
                _super.apply(this, arguments);
            }
            MethodFinder.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            MethodFinder.prototype.visitCall = function (n) {
                var act = n.calledAction();
                if (act && this.called.indexOf(act) < 0) {
                    this.called.push(act);
                    this.traverse(act, this.called);
                }
                _super.prototype.visitCall.call(this, n);
            };
            MethodFinder.prototype.visitExprHolder = function (n) {
                if (n.parsed)
                    this.dispatch(n.parsed);
            };
            MethodFinder.prototype.traverse = function (node, called) {
                if (called === void 0) { called = []; }
                this.called = called;
                this.dispatch(node);
            };
            return MethodFinder;
        })(NodeVisitor);
        AST.MethodFinder = MethodFinder;
        var ScriptCompacter = (function (_super) {
            __extends(ScriptCompacter, _super);
            function ScriptCompacter() {
                _super.call(this);
            }
            ScriptCompacter.compact = function (s) {
                s.setMeta("stableNames", null);
                s.accept(new ScriptCompacter());
                return s;
            };
            ScriptCompacter.prototype.visitDecl = function (d) {
                this.visitChildren(d);
                return null;
            };
            ScriptCompacter.prototype.visitAction = function (n) {
                this.visitChildren(n);
                return null;
            };
            ScriptCompacter.prototype.visitBlock = function (n) {
                n.stmts = n.stmts.filter(function (s) { return s.nodeType() != "comment" && !s.isPlaceholder(); });
                this.visitChildren(n);
            };
            ScriptCompacter.prototype.visitStmt = function (s) {
                this.visitChildren(s);
                return null;
            };
            return ScriptCompacter;
        })(TDev.AST.NodeVisitor);
        AST.ScriptCompacter = ScriptCompacter;
        var DeepVisitor = (function (_super) {
            __extends(DeepVisitor, _super);
            function DeepVisitor() {
                _super.apply(this, arguments);
                this.includeUnreachable = false;
                this.localActions = [];
                this.libActions = [];
            }
            DeepVisitor.prototype.useBuiltinProperty = function (p) {
            };
            DeepVisitor.prototype.useKind = function (k) {
            };
            DeepVisitor.prototype.useAction = function (a) {
                if (!a)
                    return;
                if (a.visitorState)
                    return;
                a.visitorState = true;
                if (a instanceof AST.LibraryRefAction) {
                    this.libActions.push(a);
                }
                else {
                    this.localActions.push(a);
                }
            };
            DeepVisitor.clearVisitorState = function (app) {
                app.libraries().forEach(function (l) {
                    var pubs = l.getPublicActions();
                    if (pubs)
                        pubs.forEach(function (a) { return a.visitorState = null; });
                    if (l.resolved)
                        l.resolved.things.forEach(function (a) { return a.visitorState = null; });
                });
                app.things.forEach(function (a) { return a.visitorState = null; });
            };
            DeepVisitor.prototype.visitAstNode = function (n) {
                _super.prototype.visitChildren.call(this, n);
            };
            DeepVisitor.prototype.visitGlobalDef = function (g) {
                this.useKind(g.getKind());
            };
            DeepVisitor.prototype.visitRecordField = function (rf) {
                this.useKind(rf.dataKind);
            };
            DeepVisitor.prototype.runOnDecl = function (d) {
                if (d.visitorState)
                    return;
                if (d instanceof Action)
                    this.useAction(d);
                else {
                    d.visitorState = true;
                    this.dispatch(d);
                }
            };
            DeepVisitor.prototype.visitRecordDef = function (r) {
                this.useKind(r.entryKind);
                _super.prototype.visitChildren.call(this, r);
            };
            DeepVisitor.prototype.visitDeclOrProp = function (c, p) {
                var d = null;
                if (c)
                    d = c.calledExtensionAction();
                if (!d)
                    d = p.forwardsTo();
                this.useKind(p.parentKind);
                if (d) {
                    this.runOnDecl(d);
                }
                else {
                    this.useBuiltinProperty(p);
                }
            };
            DeepVisitor.prototype.visitOperator = function (o) {
                var _this = this;
                var c = o.call;
                if (c) {
                    if (c._assignmentInfo && c._assignmentInfo.targets) {
                        c._assignmentInfo.targets.forEach(function (t) {
                            var setter = t.getLiftedSetter();
                            if (setter)
                                _this.visitDeclOrProp(mkFakeCall(PropertyRef.mkProp(setter), []), setter);
                        });
                    }
                }
                _super.prototype.visitOperator.call(this, o);
            };
            DeepVisitor.prototype.visitPropertyRef = function (n) {
                var p = n.prop;
                if (!p)
                    return;
                this.visitDeclOrProp(n.getCall(), p);
            };
            DeepVisitor.prototype.visitActionParameter = function (ap) {
                this.useKind(ap.getKind());
                _super.prototype.visitChildren.call(this, ap);
            };
            DeepVisitor.prototype.visitAction = function (a) {
                _super.prototype.visitChildren.call(this, a);
            };
            DeepVisitor.prototype.traverseActions = function () {
                while (this.localActions.length > 0) {
                    var a = this.localActions.pop();
                    this.dispatch(a);
                }
            };
            DeepVisitor.prototype.findActionMapping = function (app) {
                var _this = this;
                app.libraries().forEach(function (l) {
                    if (!l.resolved)
                        return;
                    var acts = _this.libActions.filter(function (a) { return a.parentLibrary() == l; });
                    if (acts.length == 0)
                        return;
                    var names = {};
                    acts.forEach(function (a) { return names[a.getName()] = true; });
                    l.resolved.allActions().forEach(function (a) {
                        if (names.hasOwnProperty(a.getName()))
                            _this.useAction(a);
                    });
                });
            };
            DeepVisitor.prototype.secondaryRun = function (app) {
            };
            DeepVisitor.prototype.run = function (app) {
                var _this = this;
                DeepVisitor.clearVisitorState(app);
                app.libraries().forEach(function (l) {
                    l.resolveClauses.forEach(function (r) {
                        r.actionBindings.forEach(function (b) {
                            if (b instanceof AST.ActionBinding) {
                                _this.useAction(b.actual);
                            }
                        });
                    });
                });
                if (this.includeUnreachable)
                    app.things.forEach(function (d) { return _this.runOnDecl(d); });
                else
                    app.allActions().forEach(function (a) {
                        if (a.isEvent() || (!a.isPrivate || a.isTest()))
                            _this.useAction(a);
                    });
                this.secondaryRun(app);
                this.traverseActions();
                if (this.includeUnreachable) {
                    app.libraries().forEach(function (l) {
                        if (!l.resolved)
                            return;
                        l.resolved.things.forEach(function (d) { return _this.runOnDecl(d); });
                    });
                }
                else {
                    this.findActionMapping(app);
                }
                this.traverseActions();
            };
            return DeepVisitor;
        })(TDev.AST.NodeVisitor);
        AST.DeepVisitor = DeepVisitor;
        var PlatformDetector = (function (_super) {
            __extends(PlatformDetector, _super);
            function PlatformDetector() {
                _super.apply(this, arguments);
                this.propsByName = {};
                this.featuresByName = {};
                this.errors = "";
                this.platform = 0 /* None */;
                this.requiredPlatform = TDev.PlatformCapability.All;
                this.compatMode = true;
            }
            PlatformDetector.prototype.useBuiltinProperty = function (p) {
                var n = p.parentKind.toString() + "->" + p.getName();
                if (this.propsByName[n])
                    return;
                this.propsByName[n] = p;
                var plat = this.compatMode ? p.getExplicitCapability() : p.getCapability();
                if (p.parentKind.toString() == "Invalid")
                    plat = 0 /* None */;
                this.useFeature(plat, n);
            };
            PlatformDetector.prototype.useKind = function (k) {
                if (!this.compatMode)
                    this.useFeature(k.generalCapabilities, "type " + k.getName());
            };
            PlatformDetector.prototype.usePlatform = function (plat, name) {
                this.platform |= plat;
                if ((plat & this.requiredPlatform) != plat) {
                    this.errors += name + " is not supported on this platform.\n";
                }
            };
            PlatformDetector.prototype.useFeature = function (plat, name) {
                if (this.featuresByName[name])
                    return;
                this.featuresByName[name] = true;
                this.usePlatform(plat, name);
            };
            PlatformDetector.prototype.visitAction = function (a) {
                _super.prototype.visitAction.call(this, a);
                if (a.isEvent())
                    this.useFeature(a.eventInfo.type.platform, a.getName());
            };
            PlatformDetector.prototype.visitRecordDef = function (r) {
                if (r.cloudEnabled)
                    this.useFeature(33554432 /* CloudData */, "cloud records");
            };
            PlatformDetector.prototype.visitApp = function (a) {
                _super.prototype.visitApp.call(this, a);
            };
            return PlatformDetector;
        })(DeepVisitor);
        AST.PlatformDetector = PlatformDetector;
        var DeclRefFinder = (function (_super) {
            __extends(DeclRefFinder, _super);
            function DeclRefFinder(decl) {
                _super.call(this);
                this.decl = decl;
                this.found = false;
            }
            DeclRefFinder.prototype.visitAstNode = function (n) {
                if (this.found)
                    return;
                this.visitChildren(n);
            };
            DeclRefFinder.prototype.visitToken = function (t) {
                this.found = this.found || t.matches(this.decl);
            };
            return DeclRefFinder;
        })(NodeVisitor);
        AST.DeclRefFinder = DeclRefFinder;
        var ExprVisitor = (function (_super) {
            __extends(ExprVisitor, _super);
            function ExprVisitor() {
                _super.apply(this, arguments);
            }
            ExprVisitor.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
            };
            ExprVisitor.prototype.visitExprHolder = function (eh) {
                if (eh.parsed)
                    this.dispatch(eh.parsed);
            };
            return ExprVisitor;
        })(NodeVisitor);
        AST.ExprVisitor = ExprVisitor;
        var ShallowMethodFinder = (function (_super) {
            __extends(ShallowMethodFinder, _super);
            function ShallowMethodFinder() {
                _super.apply(this, arguments);
                this.called = [];
            }
            ShallowMethodFinder.prototype.visitCall = function (n) {
                var act = n.calledAction();
                if (act && this.called.indexOf(act) < 0)
                    this.called.push(act);
                _super.prototype.visitCall.call(this, n);
            };
            return ShallowMethodFinder;
        })(ExprVisitor);
        AST.ShallowMethodFinder = ShallowMethodFinder;
        var StmtVisitor = (function (_super) {
            __extends(StmtVisitor, _super);
            function StmtVisitor(f) {
                _super.call(this);
                this.f = f;
            }
            StmtVisitor.prototype.visitStmt = function (s) {
                var prev = this.t;
                this.t = this.f(prev, s);
                this.visitChildren(s);
                this.t = prev;
            };
            return StmtVisitor;
        })(NodeVisitor);
        function visitStmts(s, f) {
            var v = new StmtVisitor(function (ctx, s) {
                f(s);
                return ctx;
            });
            v.dispatch(s);
        }
        AST.visitStmts = visitStmts;
        function visitStmtsCtx(ctx, s, f) {
            var v = new StmtVisitor(f);
            v.t = ctx;
            v.dispatch(s);
        }
        AST.visitStmtsCtx = visitStmtsCtx;
        function visitExprHolders(s, f) {
            visitStmts(s, function (stmt) {
                if (stmt.calcNode())
                    f(stmt, stmt.calcNode());
            });
        }
        AST.visitExprHolders = visitExprHolders;
        var AllNodeVisitor = (function (_super) {
            __extends(AllNodeVisitor, _super);
            function AllNodeVisitor(f) {
                _super.call(this);
                this.f = f;
            }
            AllNodeVisitor.prototype.visitAstNode = function (n) {
                this.f(n);
                this.visitChildren(n);
            };
            AllNodeVisitor.prototype.visitExprHolder = function (eh) {
                this.f(eh);
                if (eh.parsed)
                    this.dispatch(eh.parsed);
                this.visitChildren(eh);
            };
            return AllNodeVisitor;
        })(NodeVisitor);
        function visitNodes(s, f) {
            var v = new AllNodeVisitor(f);
            v.dispatch(s);
        }
        AST.visitNodes = visitNodes;
        function loadScriptAsync(getText, currentId) {
            if (currentId === void 0) { currentId = ""; }
            var res = { numErrors: 0, status: "", parseErrs: [], errLibs: [], prevScript: TDev.Script, numLibErrors: 0 };
            var problem = function (msg) {
                res.numErrors++;
                res.status += "    " + msg + "\n";
            };
            return getText(currentId).then(function (text) {
                if (!text)
                    throw new Error("cannot get script text: " + currentId);
                var app = AST.Parser.parseScript(text, res.parseErrs);
                var byId = {};
                app.libraries().forEach(function (lib) {
                    var id = lib.getId();
                    if (id)
                        byId[id] = getText(id).then(function (r) {
                            if (!r)
                                throw new Error("empty script text: " + id);
                            return r;
                        }).then(function (r) { return r; }, function (e) {
                            problem("cannot fetch library: " + id + "; " + e.toString());
                            return "";
                        });
                });
                return TDev.Promise.join(byId).then(function (byId) {
                    res.prevScript = TDev.Script;
                    TDev.setGlobalScript(app);
                    TDev.Script.isTopLevel = true;
                    var prevPlatform = TDev.Script.getPlatformRaw();
                    if (prevPlatform & 268435456 /* Current */)
                        TDev.Script.setPlatform(TDev.PlatformCapability.All);
                    TDev.Script.localGuid = TDev.Util.guidGen();
                    if (res.parseErrs.length > 0)
                        problem("Parse errors");
                    var resolved = {};
                    var errLibs = [];
                    var hasEmptyLib = false;
                    TDev.Script.libraries().forEach(function (lib) {
                        var id = lib.getId();
                        if (!id) {
                            lib.setError("TD131: unbound library");
                            problem("Library '" + lib.getName() + "' is unbound");
                            res.numLibErrors++;
                            return;
                        }
                        else if (id == "sixvorgj") {
                            hasEmptyLib = true;
                        }
                        if (!resolved[id] && byId[id]) {
                            var libParseErrs = [];
                            var app = AST.Parser.parseScript(byId[id], libParseErrs);
                            app.isTopLevel = true;
                            if (libParseErrs.length > 0)
                                problem("Parse errors in library " + id);
                            if (lib.guid)
                                app.localGuid = lib.guid;
                            app.setPlatform(TDev.PlatformCapability.All);
                            var numErr = AST.TypeChecker.tcScript(app, true);
                            app.things.forEach(function (t) {
                                t.isExternal = true;
                            });
                            if (numErr > 0) {
                                problem("Library " + id + " has errors");
                                res.numLibErrors++;
                                res.errLibs.push(app);
                            }
                            resolved[id] = app;
                        }
                        if (resolved[id]) {
                            lib.resolved = resolved[id];
                        }
                        else {
                            lib.setError("TD132: cannot bind library");
                            res.numLibErrors++;
                            problem("Library " + id + " not provided");
                        }
                    });
                    AST.TypeChecker.tcScript(TDev.Script, false, false);
                    TDev.Script.setStableNames();
                    TDev.Script.things.forEach(function (th) {
                        if (th.hasErrors())
                            problem("Declaration '" + th.getName() + "' has errors");
                    });
                    TDev.Script.setPlatform(prevPlatform);
                    if (res.numErrors && hasEmptyLib)
                        res.numLibErrors++;
                    return res;
                });
            });
        }
        AST.loadScriptAsync = loadScriptAsync;
        var ErrorChecker = (function (_super) {
            __extends(ErrorChecker, _super);
            function ErrorChecker() {
                _super.apply(this, arguments);
                this.surplusErrors = 0;
                this.mismatches = 0;
                this.missingErrors = 0;
                this.matches = 0;
            }
            ErrorChecker.prototype.resetError = function () {
                if (this.lastErrorNode)
                    this.surplusErrors++;
                this.lastErrorNode = null;
            };
            ErrorChecker.prototype.expectError = function (node, rx) {
                if (this.lastErrorNode) {
                    var err = this.lastErrorNode.getError();
                    if (new RegExp(rx).test(err)) {
                        this.lastErrorNode.errorIsOk = true;
                        this.matches++;
                    }
                    else {
                        this.mismatches++;
                        node.setError("TD133: the error message doesn't match");
                    }
                    this.lastErrorNode = null;
                }
                else {
                    this.missingErrors++;
                    node.setError("TD134: no error to match");
                }
            };
            ErrorChecker.prototype.visitComment = function (n) {
                n.errorIsOk = false;
                var m = /^E: (.*)/.exec(n.text);
                if (m) {
                    this.expectError(n, m[1]);
                }
                else {
                    _super.prototype.visitComment.call(this, n);
                }
            };
            ErrorChecker.prototype.visitBlock = function (n) {
                n.errorIsOk = false;
                this.visitChildren(n);
            };
            ErrorChecker.prototype.visitStmt = function (n) {
                n.errorIsOk = false;
                if (n.parent instanceof CodeBlock || n.getError())
                    this.resetError();
                if (n.getError())
                    this.lastErrorNode = n;
                this.visitChildren(n);
            };
            ErrorChecker.prototype.visitDecl = function (d) {
                this.resetError();
                if (d.getError())
                    this.lastErrorNode = d;
                this.visitChildren(d);
                this.resetError();
            };
            return ErrorChecker;
        })(NodeVisitor);
        function runErrorChecker(a) {
            var e = new ErrorChecker();
            e.dispatch(a);
            return e.surplusErrors + e.mismatches + e.missingErrors == 0;
        }
        AST.runErrorChecker = runErrorChecker;
        var FindErrorVisitor = (function (_super) {
            __extends(FindErrorVisitor, _super);
            function FindErrorVisitor() {
                _super.apply(this, arguments);
            }
            FindErrorVisitor.prototype.visitStmt = function (s) {
                if (this.firstError)
                    return;
                if (s.getError())
                    this.firstError = s;
                else
                    this.visitChildren(s);
            };
            FindErrorVisitor.prototype.visitDecl = function (d) {
                this.visitChildren(d);
            };
            FindErrorVisitor.run = function (n) {
                var vis = new FindErrorVisitor();
                vis.dispatch(n);
                return vis.firstError;
            };
            return FindErrorVisitor;
        })(NodeVisitor);
        AST.FindErrorVisitor = FindErrorVisitor;
        var IntelliCollector = (function (_super) {
            __extends(IntelliCollector, _super);
            function IntelliCollector() {
                _super.apply(this, arguments);
                this.props = {};
                this.singletonOrder = {};
                this.singletonNo = 0;
            }
            IntelliCollector.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
            };
            IntelliCollector.prototype.visitAction = function (a) {
                var _this = this;
                if (a._skipIntelliProfile)
                    return;
                if (a.isAtomic)
                    this.incr("scriptPropertiesPropertyAtomic");
                a.getInParameters().forEach(function (ai) {
                    _this.incr(ai.getKind().getName());
                });
                a.getOutParameters().forEach(function (ai) {
                    _this.incr(ai.getKind().getName());
                });
                this.visitChildren(a);
            };
            IntelliCollector.prototype.incrKind = function (k) {
                if (k && k != AST.api.core.Unknown)
                    this.incr(k.getName());
            };
            IntelliCollector.prototype.incr = function (n) {
                if (!n)
                    return;
                if (!this.props.hasOwnProperty(n))
                    this.props[n] = 0;
                this.props[n]++;
            };
            IntelliCollector.prototype.visitExprHolder = function (eh) {
                if (eh.parsed)
                    this.dispatch(eh.parsed);
            };
            IntelliCollector.prototype.visitExpr = function (expr) {
                this.incrKind(expr.getKind());
                _super.prototype.visitExpr.call(this, expr);
            };
            IntelliCollector.prototype.visitCall = function (c) {
                if (c.prop())
                    this.incr(c.prop().usageKey());
                this.visitChildren(c);
            };
            IntelliCollector.prototype.visitThingRef = function (t) {
                if (t.def)
                    this.incr(t.def.usageKey());
                if (t.def instanceof SingletonDef) {
                    var n = t.def.getName();
                    if (!this.singletonOrder.hasOwnProperty(n))
                        this.singletonOrder[n] = ++this.singletonNo;
                }
            };
            IntelliCollector.prototype.visitGlobalDef = function (t) {
                this.incr("addNewButton");
                this.incrKind(t.getKind());
                if (t.isResource) {
                    this.incr("artSection");
                    if (t.getKind() == AST.api.core.Picture || t.getKind() == AST.api.core.Sound) {
                        this.incr("calcSearchArt");
                        this.incr("searchArtRefactoring");
                    }
                }
                else {
                    this.incr("dataSection");
                    this.incr("promoteRefactoring");
                }
                _super.prototype.visitGlobalDef.call(this, t);
            };
            IntelliCollector.prototype.visitRecordDef = function (t) {
                this.incr("addNewButton");
                this.incrKind(t.getKind());
                switch (t.recordType) {
                    case 4 /* Decorator */:
                        this.incr("decoratorsSection");
                        break;
                    case 1 /* Object */:
                        this.incr("objectsSection");
                        break;
                    case 3 /* Index */:
                    case 2 /* Table */:
                        this.incr("persistanceRadio");
                        this.incr("databaseSection");
                        break;
                }
                _super.prototype.visitRecordDef.call(this, t);
            };
            IntelliCollector.prototype.visitComment = function (c) {
                var _this = this;
                var dummy = c.text.replace(/#allow:(\w+)/, function (match, feature) {
                    _this.incr(feature);
                    return "";
                });
                var dummy2 = c.text.replace(/\{widgets:([\w,]*)\}/, function (match, features) {
                    _this.incr("tutorialWidgets");
                    features.split(',').forEach(function (feature) { return _this.incr(feature); });
                    return "";
                });
                var dummy2 = c.text.replace(/\{flags:([\w,]*)\}/, function (match, features) {
                    _this.incr("tutorialFlags");
                    features.split(',').forEach(function (feature) { return _this.incr("flag:" + feature); });
                    return "";
                });
                var dummy2 = c.text.replace(/\{topic:([\w-\/@]*)\}/, function (match, top) {
                    _this.topicPath = top;
                    return "";
                });
            };
            IntelliCollector.prototype.visitExprStmt = function (e) {
                if (e.isVarDef())
                    this.incr("var");
                _super.prototype.visitExprStmt.call(this, e);
            };
            IntelliCollector.prototype.visitStmt = function (s) {
                if (!(s instanceof App))
                    this.incr(s.nodeType());
                _super.prototype.visitStmt.call(this, s);
            };
            return IntelliCollector;
        })(NodeVisitor);
        AST.IntelliCollector = IntelliCollector;
        var IntelliProfile = (function () {
            function IntelliProfile() {
                this.allowAllLibraries = true;
                this.singletonOrder = {};
            }
            IntelliProfile.prototype.merge = function (other) {
                var _this = this;
                this.allowAllLibraries = this.allowAllLibraries && other.allowAllLibraries;
                if (other.properties) {
                    if (!this.properties)
                        this.properties = TDev.Util.clone(other.properties);
                    else
                        Object.keys(other.properties).forEach(function (k) {
                            if (_this.properties[k])
                                _this.properties[k] += other.properties[k];
                            else
                                _this.properties[k] = other.properties[k];
                        });
                }
                Object.keys(other.singletonOrder).forEach(function (k) {
                    _this.singletonOrder[k] = other.singletonOrder[k];
                });
            };
            IntelliProfile.prototype.hasKey = function (k) {
                if (!k)
                    return true;
                return !this.properties || !!this.properties[k.toLowerCase()];
            };
            IntelliProfile.prototype.hasTokenUsage = function (p) {
                if (!p)
                    return true;
                var tok = p.getUsage ? p.getUsage() : null;
                return tok && tok.localCount + tok.globalCount > 0;
            };
            IntelliProfile.prototype.hasProperty = function (p, strict) {
                if (strict === void 0) { strict = false; }
                if (!this.properties)
                    return true;
                return (!strict && this.hasTokenUsage(p)) || this.hasKey(p.usageKey()) || (this.allowAllLibraries && (p instanceof AST.LibraryRefAction || (p instanceof TDev.MultiplexProperty && p.forKind instanceof AST.LibraryRefAbstractKind))) || (p instanceof AST.RecordCtorProperty && !p.from_json);
            };
            IntelliProfile.prototype.hasFlag = function (flg) {
                if (!this.properties)
                    return false;
                return this.hasKey("flag:" + flg);
            };
            IntelliProfile.prototype.hasKind = function (k) {
                if (!this.properties)
                    return true;
                return this.hasTokenUsage(k) || this.hasKey(k.getName());
            };
            IntelliProfile.prototype.hasDecl = function (p) {
                if (!this.properties)
                    return true;
                if (p instanceof LocalDef)
                    return true;
                if (p.getName() == AST.libSymbol)
                    return this.hasKey("libSingleton");
                return this.hasTokenUsage(p) || this.hasKey(p.usageKey());
            };
            IntelliProfile.prototype.incr = function (k) {
                if (!this.properties)
                    return;
                k = k.toLowerCase();
                if (this.properties.hasOwnProperty(k))
                    this.properties[k]++;
                else
                    this.properties[k] = 1;
            };
            IntelliProfile.prototype.getSingletonOrder = function (name) {
                if (this.singletonOrder.hasOwnProperty(name))
                    return this.singletonOrder[name];
                return 0;
            };
            IntelliProfile.prototype.loadFrom = function (node, builtin) {
                var _this = this;
                var v = new IntelliCollector();
                v.props = builtin ? TDev.Util.clone(IntelliProfile.helpfulProperties) : {};
                v.dispatch(node);
                this.properties = {};
                Object.keys(v.props).forEach(function (k) {
                    _this.properties[k.toLowerCase()] = v.props[k];
                });
                this.singletonOrder = v.singletonOrder;
            };
            IntelliProfile.helpfulProperties = {
                ColorsBlack: 1,
                ColorsBlue: 1,
                ColorsCyan: 1,
                ColorsGreen: 1,
                ColorsMagenta: 1,
                ColorsOrange: 1,
                ColorsPurple: 1,
                ColorsRed: 1,
                ColorsWhite: 1,
                ColorsYellow: 1,
                ColorsPink: 1,
            };
            return IntelliProfile;
        })();
        AST.IntelliProfile = IntelliProfile;
        var AtomicVisitor = (function (_super) {
            __extends(AtomicVisitor, _super);
            function AtomicVisitor() {
                _super.apply(this, arguments);
                this.calls = {};
                this.nonAtomic = new TDev.Set();
            }
            AtomicVisitor.prototype.visitCall = function (c) {
                var act = c.calledAction() || c.calledExtensionAction();
                if (act && !act.isInLibrary()) {
                    if (act.isPage())
                        this.numNonAtomic++;
                    else
                        this.currentCalls.add(act);
                }
                else {
                    if (c.prop().getFlags() & 4096 /* Async */)
                        this.numNonAtomic++;
                }
                _super.prototype.visitCall.call(this, c);
            };
            AtomicVisitor.prototype.visitInlineAction = function (a) {
            };
            AtomicVisitor.prototype.visitAction = function (a) {
                if (a.isPage() || a.isEvent())
                    this.nonAtomic.add(a);
                if (a.isActionTypeDef() || a.isAtomic)
                    return;
                this.currentAction = a;
                this.currentCalls = new TDev.Set();
                this.calls[a.getName()] = this.currentCalls;
                this.numNonAtomic = 0;
                _super.prototype.visitAction.call(this, a);
                if (this.numNonAtomic > 0)
                    this.nonAtomic.add(a);
            };
            AtomicVisitor.run = function (app) {
                var v = new AtomicVisitor();
                v.dispatch(app);
                var nonAtomic = v.nonAtomic;
                while (true) {
                    var prev = nonAtomic.length();
                    app.actions().forEach(function (a) {
                        if (nonAtomic.contains(a) || !v.calls.hasOwnProperty(a.getName()))
                            return;
                        if (v.calls[a.getName()].elts().some(function (x) { return nonAtomic.contains(x); }))
                            nonAtomic.add(a);
                    });
                    if (prev == nonAtomic.length())
                        break;
                }
                return app.actions().filter(function (a) { return !nonAtomic.contains(a); });
            };
            return AtomicVisitor;
        })(ExprVisitor);
        AST.AtomicVisitor = AtomicVisitor;
        var InitIdVisitor = (function (_super) {
            __extends(InitIdVisitor, _super);
            function InitIdVisitor(refresh) {
                _super.call(this);
                this.refresh = refresh;
                this.expectAllSet = false;
                this.usedIds = {};
            }
            InitIdVisitor.prototype.expectSet = function (n) {
                this.expectAllSet = true;
                this.unsetNodes = [];
                this.usedIds = {};
                this.dispatch(n);
                if (this.unsetNodes.length > 0) {
                    var dict = TDev.Util.toDictionary(this.unsetNodes, function (n) { return n.nodeType(); });
                    TDev.Util.oops("id not set on " + Object.keys(dict).join(", "));
                }
            };
            InitIdVisitor.prototype.visitAstNode = function (node) {
            };
            InitIdVisitor.prototype.visitToken = function (tok) {
            };
            InitIdVisitor.prototype.visitOperator = function (n) {
            };
            InitIdVisitor.prototype.visitPropertyRef = function (n) {
            };
            InitIdVisitor.prototype.visitExpr = function (tok) {
            };
            InitIdVisitor.prototype.visitLiteral = function (n) {
            };
            InitIdVisitor.prototype.visitThingRef = function (n) {
            };
            InitIdVisitor.prototype.visitCall = function (n) {
            };
            InitIdVisitor.prototype.visitExprHolder = function (eh) {
                var n = this.lastStmt;
                var ai = eh.assignmentInfo();
                if (ai)
                    ai.definedVars.forEach(function (x, i) { return x.setStableName(n.getStableName() + "$l" + i); });
            };
            InitIdVisitor.prototype.visitStmt = function (n) {
                if (this.expectAllSet && !n.getStableName() && !n.isPlaceholder())
                    this.unsetNodes.push(n);
                n.initStableName(this.refresh);
                if (!this.refresh) {
                    var u = this.usedIds;
                    var nn = n.getStableName();
                    if (u.hasOwnProperty(nn) && u[nn] != n) {
                        n.initStableName(true);
                    }
                    else
                        u[nn] = n;
                }
            };
            InitIdVisitor.prototype.visitBlock = function (n) {
                this.visitStmt(n);
                this.visitChildren(n);
            };
            InitIdVisitor.prototype.visitChStmt = function (n) {
                this.visitStmt(n);
                this.deriveIdChildren(n);
            };
            InitIdVisitor.prototype.withBoundLocal = function (n, loc) {
                this.visitChStmt(n);
                if (loc)
                    loc.setStableName(n.getStableName() + "$l0");
            };
            InitIdVisitor.prototype.visitFor = function (n) {
                this.withBoundLocal(n, n.boundLocal);
            };
            InitIdVisitor.prototype.visitForeach = function (n) {
                this.withBoundLocal(n, n.boundLocal);
            };
            InitIdVisitor.prototype.visitWhile = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitBox = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitAnyIf = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitInlineActions = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitActionHeader = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitExprStmt = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitActionParameter = function (n) {
                this.withBoundLocal(n, n.local);
            };
            InitIdVisitor.prototype.visitInlineAction = function (n) {
                this.withBoundLocal(n, n.name);
                n.inParameters.forEach(function (p, i) { return p.setStableName(n.getStableName() + "$inlIn" + i); });
                n.outParameters.forEach(function (p, i) { return p.setStableName(n.getStableName() + "$inlOut" + i); });
            };
            InitIdVisitor.prototype.visitGlobalDef = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitRecordDef = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitAction = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitLibraryRef = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitLocalDef = function (n) {
            };
            InitIdVisitor.prototype.visitApp = function (n) {
                this.visitDecl(n);
                this.visitChildren(n);
            };
            InitIdVisitor.prototype.visitKindBinding = function (n) {
                if (n.isExplicit)
                    this.visitStmt(n);
            };
            InitIdVisitor.prototype.visitActionBinding = function (n) {
                if (n.isExplicit)
                    this.visitStmt(n);
            };
            InitIdVisitor.prototype.visitResolveClause = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitRecordField = function (n) {
                this.visitChStmt(n);
            };
            InitIdVisitor.prototype.visitChildren = function (n) {
                var _this = this;
                n.children().forEach(function (c) {
                    if (c)
                        c.accept(_this);
                });
            };
            InitIdVisitor.prototype.deriveIdChildren = function (n) {
                var _this = this;
                this.lastStmt = n;
                n.children().forEach(function (c, ix) {
                    if (c) {
                        if (c instanceof Stmt) {
                            c.deriveStableName(n, ix);
                        }
                        c.accept(_this);
                    }
                });
            };
            InitIdVisitor.ensureOK = function (app) {
                if (app.hasIds)
                    new InitIdVisitor(false).dispatch(app);
            };
            return InitIdVisitor;
        })(NodeVisitor);
        AST.InitIdVisitor = InitIdVisitor;
        function decompressStack(compressed) {
            var stmtById = {};
            var add = function (rtid, rt) {
                visitStmts(rt, function (s) {
                    stmtById[TDev.StackUtil.combineIds(s.getStableName(), rtid)] = { pc: s.getStableName(), d: { libName: rtid } };
                });
            };
            add("", TDev.Script);
            TDev.Script.libraries().forEach(function (l) {
                if (l.resolved)
                    add(l.getStableName(), l.resolved);
            });
            var r = [];
            for (var i = 0; i < compressed.length; i += 8) {
                var fr = compressed.slice(i, i + 8);
                if (stmtById.hasOwnProperty(fr))
                    r.push(stmtById[fr]);
            }
            return r;
        }
        AST.decompressStack = decompressStack;
        function getEmbeddedLangaugeToken(n) {
            if (!(n instanceof ExprStmt))
                return null;
            var toks = n.expr.tokens;
            if (toks.length == 5 && toks[0].getThing() == AST.api.core.App.singleton && toks[1].getProperty() && /^thumb$/.test(toks[1].getProperty().getName()) && toks[2].getOperator() == "(" && toks[3].getStringLiteral() != null && toks[4].getOperator() == ")")
                return toks[3];
            if (TDev.Cloud.isRestricted())
                return null;
            if (toks.length == 7 && toks[0].getThing() == AST.api.core.App.singleton && toks[1].getProperty() && /^javascript|javascript async$/.test(toks[1].getProperty().getName()) && toks[2].getOperator() == "(" && toks[3].getStringLiteral() != null && toks[4].getOperator() == "," && toks[5].getStringLiteral() != null && toks[6].getOperator() == ")")
                return toks[5];
            return null;
        }
        AST.getEmbeddedLangaugeToken = getEmbeddedLangaugeToken;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var NextFinder = (function (_super) {
            __extends(NextFinder, _super);
            function NextFinder() {
                _super.call(this);
            }
            NextFinder.enclosingStmt = function (stmt) {
                return stmt.parentBlock() && stmt.parentBlock().parent;
            };
            NextFinder.asLoop = function (stmt) {
                if (stmt instanceof AST.While || stmt instanceof AST.For || stmt instanceof AST.Foreach)
                    return stmt;
                else
                    return null;
            };
            NextFinder.prototype.nextInBlock = function (stmt) {
                if (!stmt || !stmt.parentBlock())
                    return [];
                var container = stmt.parentBlock().stmts;
                var ix = container.indexOf(stmt);
                var enclosing = NextFinder.enclosingStmt(stmt);
                ++ix;
                while ((ix < container.length) && (container[ix].isPlaceholder() || container[ix].nodeType() === "comment"))
                    ++ix;
                var ret = [];
                if (ix >= container.length) {
                    ret = this.nextInBlock(enclosing);
                }
                else {
                    ret = [container[ix]];
                }
                return ret.concat(this.visitLoop(NextFinder.asLoop(enclosing)));
            };
            NextFinder.firstInCodeBlock = function (body) {
                if (body == null)
                    return null;
                var ix = 0;
                var container = body.stmts;
                while ((ix < container.length) && (container[ix].isPlaceholder() || container[ix].nodeType() === "comment"))
                    ++ix;
                if (ix >= container.length) {
                    return null;
                }
                return container[ix];
            };
            NextFinder.prototype.visitCodeBlock = function (body) {
                var ret = NextFinder.firstInCodeBlock(body);
                return ret ? [ret] : [];
            };
            NextFinder.prototype.visitLoop = function (stmt) {
                if (stmt == null)
                    return [];
                var ret = this.visitCodeBlock(stmt.body);
                return ret.concat(this.nextInBlock(stmt));
            };
            NextFinder.prototype.visitFor = function (stmt) {
                return this.visitLoop(stmt);
            };
            NextFinder.prototype.visitForeach = function (stmt) {
                return this.visitLoop(stmt);
            };
            NextFinder.prototype.visitWhile = function (stmt) {
                return this.visitLoop(stmt);
            };
            NextFinder.prototype.visitExprStmt = function (stmt) {
                return this.nextInBlock(stmt);
            };
            NextFinder.prototype.visitBox = function (box) {
                return this.visitCodeBlock(box.body);
            };
            NextFinder.prototype.visitInlineActions = function (ia) {
                return this.visitExprStmt(ia);
            };
            NextFinder.prototype.visitAnyIf = function (stmt) {
                var _this = this;
                var arrs = stmt.parentIf.bodies().map(function (b) { return _this.visitCodeBlock(b); });
                arrs.push(this.nextInBlock(stmt));
                return TDev.Util.concatArraysVA(arrs);
            };
            NextFinder.find = function (stmt) {
                if (!stmt)
                    return [];
                var ret = new NextFinder().dispatch(stmt);
                if (!ret) {
                    return [];
                }
                return ret;
            };
            return NextFinder;
        })(AST.NodeVisitor);
        AST.NextFinder = NextFinder;
        var InnerNextFinder = (function (_super) {
            __extends(InnerNextFinder, _super);
            function InnerNextFinder() {
                _super.apply(this, arguments);
                this.called = [];
            }
            InnerNextFinder.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            InnerNextFinder.prototype.visitCall = function (n) {
                var act = n.calledAction();
                if (act && this.called.indexOf(act) < 0) {
                    this.called.push(act);
                }
                else {
                    _super.prototype.visitCall.call(this, n);
                }
            };
            InnerNextFinder.prototype.visitExprHolder = function (n) {
                if (n.parsed)
                    this.dispatch(n.parsed);
            };
            InnerNextFinder.find = function (stmt) {
                if (!stmt)
                    return [];
                var finder = new InnerNextFinder();
                finder.dispatch(stmt);
                return finder.called.filter(function (a) { return !!a.body; }).map(function (a) {
                    var fst = NextFinder.firstInCodeBlock(a.body);
                    return fst ? [fst] : [];
                }).reduce(function (a, b) { return a.concat(b); }, []);
            };
            return InnerNextFinder;
        })(AST.NodeVisitor);
        AST.InnerNextFinder = InnerNextFinder;
        var AwaitChecker = (function (_super) {
            __extends(AwaitChecker, _super);
            function AwaitChecker() {
                _super.apply(this, arguments);
                this.res = false;
            }
            AwaitChecker.prototype.visitAstNode = function (n) {
                if (!n)
                    return;
                this.visitChildren(n);
            };
            AwaitChecker.prototype.visitExprHolder = function (eh) {
                if (!eh)
                    return;
                this.dispatch(eh.parsed);
            };
            AwaitChecker.prototype.visitCall = function (n) {
                if (!n)
                    return;
                _super.prototype.visitCall.call(this, n);
                if (n.awaits())
                    this.res = true;
            };
            AwaitChecker.isAwait = function (n) {
                if (!n)
                    return;
                var checker = new AwaitChecker();
                checker.dispatch(n);
                return checker.res;
            };
            return AwaitChecker;
        })(AST.NodeVisitor);
        var PredecessorsFinder = (function (_super) {
            __extends(PredecessorsFinder, _super);
            function PredecessorsFinder() {
                _super.call(this);
            }
            PredecessorsFinder.enclosingStmt = function (stmt) {
                return stmt.parentBlock() && stmt.parentBlock().parent;
            };
            PredecessorsFinder.asLoop = function (stmt) {
                if (stmt instanceof AST.While || stmt instanceof AST.For || stmt instanceof AST.Foreach)
                    return stmt;
                else
                    return null;
            };
            PredecessorsFinder.unpeelAndGetLast = function (stmt) {
                var ret = [];
                if (stmt instanceof AST.Comment) {
                    ret = [stmt];
                }
                else if (stmt instanceof AST.For) {
                    ret = ret.concat(PredecessorsFinder.lastInCodeBlock(stmt.body));
                }
                else if (stmt instanceof AST.Foreach) {
                    ret = ret.concat(PredecessorsFinder.lastInCodeBlock(stmt.body));
                }
                else if (stmt instanceof AST.While) {
                    ret = ret.concat(PredecessorsFinder.lastInCodeBlock(stmt.body));
                }
                else if (stmt instanceof AST.If) {
                    TDev.Util.assert(!(stmt.isElseIf));
                    ret = ret.concat(TDev.Util.concatArraysVA(stmt.bodies().map(PredecessorsFinder.lastInCodeBlock)));
                }
                else if (stmt instanceof AST.Box) {
                    ret = ret.concat(PredecessorsFinder.lastInCodeBlock(stmt.body));
                }
                else if (stmt instanceof AST.ExprStmt) {
                    ret = [stmt];
                }
                if (ret.length == 0)
                    ret = [stmt];
                return ret;
            };
            PredecessorsFinder.prototype.findPreviousIf = function (ifstmt) {
                TDev.Util.assert(!!ifstmt && !!(ifstmt.parentBlock()));
                var container = ifstmt.parentBlock().stmts;
                var ix = container.indexOf(ifstmt);
                --ix;
                TDev.Util.assert(ix >= 0);
                var previous = container[ix];
                TDev.Util.assert(previous instanceof AST.If);
                return [previous];
            };
            PredecessorsFinder.prototype.previousInBlock = function (stmt) {
                if (!stmt || !stmt.parentBlock())
                    return [];
                var container = stmt.parentBlock().stmts;
                var ix = container.indexOf(stmt);
                var enclosing = PredecessorsFinder.enclosingStmt(stmt);
                --ix;
                var ret = [];
                if (ix < 0) {
                    var l = PredecessorsFinder.asLoop(enclosing);
                    if (!!l || (enclosing instanceof AST.If)) {
                        ret = ret.concat(enclosing);
                    }
                    else if (enclosing instanceof AST.InlineAction) {
                        ret = [];
                    }
                    else {
                        ret = ret.concat(this.previousInBlock(enclosing));
                    }
                }
                else {
                    var prev = container[ix];
                    if ((prev instanceof AST.For) || (prev instanceof AST.While) || (prev instanceof AST.Foreach)) {
                        ret = ret.concat([prev]);
                    }
                    else if ((prev instanceof AST.If) && (prev.isElseIf)) {
                        ret = ret.concat(PredecessorsFinder.unpeelAndGetLast(prev.parentIf));
                    }
                    else {
                        ret = ret.concat(PredecessorsFinder.unpeelAndGetLast(prev));
                    }
                    if (ret.length == 0)
                        ret = this.previousInBlock(prev);
                }
                return ret;
            };
            PredecessorsFinder.lastInCodeBlock = function (body) {
                if (body == null)
                    return [];
                var enclosing = PredecessorsFinder.enclosingStmt(body);
                var container = body.stmts;
                var ix = container.length - 1;
                if (ix < 0) {
                    return [];
                }
                var last = container[ix];
                if ((last instanceof AST.For) || (last instanceof AST.While) || (last instanceof AST.Foreach))
                    return [last];
                if (last instanceof AST.If && last.isElseIf) {
                    return PredecessorsFinder.unpeelAndGetLast(last.parentIf);
                }
                return PredecessorsFinder.unpeelAndGetLast(last);
            };
            PredecessorsFinder.prototype.visitCodeBlock = function (body) {
                return PredecessorsFinder.lastInCodeBlock(body);
            };
            PredecessorsFinder.prototype.visitLoop = function (stmt) {
                if (stmt == null)
                    return [];
                var ret = this.previousInBlock(stmt);
                return ret.concat(PredecessorsFinder.unpeelAndGetLast(stmt));
            };
            PredecessorsFinder.prototype.visitFor = function (stmt) {
                return this.visitLoop(stmt);
            };
            PredecessorsFinder.prototype.visitForeach = function (stmt) {
                return this.visitLoop(stmt);
            };
            PredecessorsFinder.prototype.visitWhile = function (stmt) {
                return this.visitLoop(stmt);
            };
            PredecessorsFinder.prototype.visitStmt = function (stmt) {
                return this.previousInBlock(stmt);
            };
            PredecessorsFinder.prototype.visitIf = function (stmt) {
                TDev.Util.assert(!stmt.isElseIf);
                return this.previousInBlock(stmt);
            };
            PredecessorsFinder.prototype.visitElseIf = function (n) {
                return this.findPreviousIf(n);
            };
            PredecessorsFinder.find = function (stmt) {
                if (!stmt)
                    return [];
                return new PredecessorsFinder().dispatch(stmt);
            };
            return PredecessorsFinder;
        })(AST.NodeVisitor);
        AST.PredecessorsFinder = PredecessorsFinder;
        var SuccessorsFinder = (function (_super) {
            __extends(SuccessorsFinder, _super);
            function SuccessorsFinder() {
                _super.call(this);
            }
            SuccessorsFinder.enclosingStmt = function (stmt) {
                return stmt.parentBlock() && stmt.parentBlock().parent;
            };
            SuccessorsFinder.asLoop = function (stmt) {
                if (stmt instanceof AST.While || stmt instanceof AST.For || stmt instanceof AST.Foreach)
                    return stmt;
                else
                    return null;
            };
            SuccessorsFinder.unpeelAndGetFirst = function (stmt) {
                var ret = [];
                if (stmt instanceof AST.Comment) {
                    ret = ret.concat(stmt);
                }
                else if (stmt instanceof AST.For)
                    ret = ret.concat(stmt);
                else if (stmt instanceof AST.Foreach) {
                    ret = ret.concat(stmt);
                }
                else if (stmt instanceof AST.While) {
                    ret = ret.concat(stmt);
                }
                else if (stmt instanceof AST.If) {
                    ret = ret.concat(stmt);
                }
                else if (stmt instanceof AST.Box) {
                    ret = ret.concat(SuccessorsFinder.firstInCodeBlock(stmt.body));
                }
                else if (stmt instanceof AST.ExprStmt) {
                    ret = ret.concat(stmt);
                }
                if (ret.length == 0)
                    ret = [stmt];
                return ret;
            };
            SuccessorsFinder.prototype.findNextIf = function (ifstmt) {
                TDev.Util.assert(!!ifstmt && !!(ifstmt.parentBlock()));
                var container = ifstmt.parentBlock().stmts;
                var ix = container.indexOf(ifstmt);
                ++ix;
                if (ix >= container.length)
                    return [];
                var next = container[ix];
                if (!(next instanceof AST.If) || !(next.isElseIf))
                    return [];
                return [next];
            };
            SuccessorsFinder.prototype.jumpToEndOfIfElse = function (ifstmt) {
                TDev.Util.assert(!!ifstmt && !!(ifstmt.parentBlock()));
                var container = ifstmt.parentBlock().stmts;
                var ix = container.indexOf(ifstmt);
                var enclosing = PredecessorsFinder.enclosingStmt(ifstmt);
                ++ix;
                while (container[ix] && container[ix] instanceof AST.If && (container[ix]).isElseIf)
                    ++ix;
                var ret = [];
                if (ix >= container.length) {
                    var l = SuccessorsFinder.asLoop(enclosing);
                    if (!!l) {
                        ret = ret.concat(enclosing);
                    }
                    else if (enclosing instanceof AST.If) {
                        ret = ret.concat(this.jumpToEndOfIfElse(enclosing));
                    }
                    else if (enclosing instanceof AST.InlineAction) {
                        ret = [];
                    }
                    else {
                        ret = ret.concat(this.nextInBlock(enclosing));
                    }
                }
                else {
                    var next = container[ix];
                    ret = ret.concat(SuccessorsFinder.unpeelAndGetFirst(next));
                    if (ret.length == 0)
                        ret = this.nextInBlock(next);
                }
                return ret;
            };
            SuccessorsFinder.prototype.nextInBlock = function (stmt) {
                if (!stmt || !stmt.parentBlock())
                    return [];
                var container = stmt.parentBlock().stmts;
                var ix = container.indexOf(stmt);
                var enclosing = PredecessorsFinder.enclosingStmt(stmt);
                ++ix;
                var ret = [];
                if (ix >= container.length) {
                    var l = SuccessorsFinder.asLoop(enclosing);
                    if (!!l) {
                        ret = ret.concat(enclosing);
                    }
                    else if (enclosing instanceof AST.If) {
                        ret = ret.concat(this.jumpToEndOfIfElse(enclosing));
                    }
                    else if (enclosing instanceof AST.InlineAction) {
                        ret = [];
                    }
                    else {
                        ret = ret.concat(this.nextInBlock(enclosing));
                    }
                }
                else {
                    var next = container[ix];
                    ret = ret.concat(SuccessorsFinder.unpeelAndGetFirst(next));
                    if (ret.length == 0)
                        ret = this.nextInBlock(next);
                }
                return ret;
            };
            SuccessorsFinder.firstInCodeBlock = function (body) {
                if (body == null)
                    return [];
                var container = body.stmts;
                var ix = 0;
                var enclosing = SuccessorsFinder.enclosingStmt(body);
                if (ix >= container.length) {
                    return [];
                }
                var first = container[ix];
                return SuccessorsFinder.unpeelAndGetFirst(first);
            };
            SuccessorsFinder.prototype.visitCodeBlock = function (body) {
                return SuccessorsFinder.firstInCodeBlock(body);
            };
            SuccessorsFinder.prototype.visitLoop = function (stmt) {
                if (stmt == null)
                    return [];
                var ret = this.nextInBlock(stmt);
                return ret.concat(this.visitCodeBlock(stmt.body));
            };
            SuccessorsFinder.prototype.visitFor = function (stmt) {
                return this.visitLoop(stmt);
            };
            SuccessorsFinder.prototype.visitForeach = function (stmt) {
                return this.visitLoop(stmt);
            };
            SuccessorsFinder.prototype.visitWhile = function (stmt) {
                return this.visitLoop(stmt);
            };
            SuccessorsFinder.prototype.visitStmt = function (stmt) {
                return this.nextInBlock(stmt);
            };
            SuccessorsFinder.prototype.visitIf = function (stmt) {
                var ret = SuccessorsFinder.firstInCodeBlock(stmt.rawThenBody);
                if (stmt.displayElse)
                    return ret.concat(SuccessorsFinder.firstInCodeBlock(stmt.rawElseBody));
                return ret.concat(this.findNextIf(stmt));
            };
            SuccessorsFinder.prototype.visitElseIf = function (n) {
                return this.visitIf(n);
            };
            SuccessorsFinder.find = function (stmt) {
                if (!stmt)
                    return [];
                return new SuccessorsFinder().dispatch(stmt);
            };
            return SuccessorsFinder;
        })(AST.NodeVisitor);
        AST.SuccessorsFinder = SuccessorsFinder;
        var SetElement = (function () {
            function SetElement(id, key, refNode) {
                this.id = id;
                this.key = key;
                this.refNode = refNode;
            }
            return SetElement;
        })();
        AST.SetElement = SetElement;
        var SetElementsPool = (function () {
            function SetElementsPool(curId) {
                if (curId === void 0) { curId = 0; }
                this.curId = curId;
                this.map = {};
                this.pool = [];
            }
            SetElementsPool.prototype.getElm = function (key, refNode) {
                var idx = this.map[["a_", key].join("")];
                if (idx == undefined) {
                    idx = this.curId++;
                    var elm = new SetElement(idx, key, refNode);
                    this.pool.push(elm);
                    this.map[["a_", key].join("")] = idx;
                }
                return this.pool[idx];
            };
            SetElementsPool.prototype.getElmById = function (id) {
                if (id >= this.pool.length)
                    return null;
                return this.pool[id];
            };
            SetElementsPool.prototype.size = function () {
                return this.pool.length;
            };
            return SetElementsPool;
        })();
        var BitSet = (function () {
            function BitSet(allSet) {
                if (allSet === void 0) { allSet = false; }
                this.allSet = allSet;
                this._myset = [];
                if (allSet)
                    this._myset.push(0xFFFFFFFF);
                else
                    this._myset.push(0);
                this.setSize = 1;
                this.largestIndex = -1;
            }
            BitSet.prototype.growSet = function (idx) {
                idx -= this.setSize * 32;
                while (idx >= 0) {
                    if (this.allSet)
                        this._myset.push(0xFFFFFFFF);
                    else
                        this._myset.push(0);
                    ++this.setSize;
                    idx -= 32;
                }
            };
            BitSet.prototype.cloneSet = function () {
                var a = [];
                for (var i = 0; i < this.setSize; ++i) {
                    a.push(this._myset[i]);
                }
                return a;
            };
            BitSet.prototype.makeAllSet = function () {
                this._myset = [0xFFFFFFFF];
                this.setSize = 1;
                this.allSet = true;
                this.largestIndex = -1;
            };
            BitSet.prototype.add = function (elm) {
                if (elm >= this.setSize * 32)
                    this.growSet(elm);
                if (elm > this.largestIndex)
                    this.largestIndex = elm;
                this._myset[Math.floor(elm / 32)] |= 1 << elm % 32;
            };
            BitSet.prototype.setLargestIndex = function (idx) {
                if (idx > this.setSize * 32)
                    this.growSet(idx);
                this.largestIndex = idx;
            };
            BitSet.prototype.remove = function (elm) {
                if (elm >= this.setSize * 32)
                    this.growSet(elm);
                if (elm > this.largestIndex)
                    this.largestIndex = elm;
                this._myset[Math.floor(elm / 32)] &= ~(1 << elm % 32);
            };
            BitSet.prototype.contains = function (elm) {
                if (elm >= this.setSize * 32)
                    this.growSet(elm);
                if (elm > this.largestIndex)
                    this.largestIndex = elm;
                return !!(this._myset[Math.floor(elm / 32)] & (1 << elm % 32));
            };
            BitSet.prototype.union = function (a) {
                if (a.largestIndex > this.largestIndex) {
                    this.setLargestIndex(a.largestIndex);
                }
                else if (this.largestIndex > a.largestIndex) {
                    a.setLargestIndex(this.largestIndex);
                }
                for (var i = 0; i < a.setSize; ++i) {
                    this._myset[i] |= a._myset[i];
                }
                if (a.allSet)
                    this.allSet = true;
            };
            BitSet.prototype.intersection = function (a) {
                if (a.largestIndex > this.largestIndex) {
                    this.setLargestIndex(a.largestIndex);
                }
                else if (this.largestIndex > a.largestIndex) {
                    a.setLargestIndex(this.largestIndex);
                }
                for (var i = 0; i < a.setSize; ++i) {
                    this._myset[i] &= a._myset[i];
                }
                if (this.allSet && !a.allSet)
                    this.allSet = false;
            };
            BitSet.prototype.forEach = function (cb) {
                if (this.largestIndex < 0)
                    return;
                for (var i = 0; i <= this.largestIndex / 32; ++i) {
                    var idx = i * 32;
                    var val = this._myset[i];
                    while (val != 0 && idx <= this.largestIndex) {
                        if (val & 1)
                            cb(idx);
                        ++idx;
                        val = val >>> 1;
                    }
                }
            };
            BitSet.prototype.clone = function () {
                var a = new BitSet(this.allSet);
                a._myset = this.cloneSet();
                a.setSize = this.setSize;
                a.largestIndex = this.largestIndex;
                return a;
            };
            BitSet.prototype.equals = function (a) {
                if ((this.allSet && !a.allSet) || (!this.allSet && a.allSet))
                    return false;
                if (a.largestIndex > this.largestIndex) {
                    this.setLargestIndex(a.largestIndex);
                }
                else if (this.largestIndex > a.largestIndex) {
                    a.setLargestIndex(this.largestIndex);
                }
                for (var i = 0; i < a.setSize; ++i) {
                    if (this._myset[i] != a._myset[i])
                        return false;
                }
                return true;
            };
            return BitSet;
        })();
        AST.BitSet = BitSet;
        var DataflowVisitor = (function (_super) {
            __extends(DataflowVisitor, _super);
            function DataflowVisitor(df, pool, backwards, intersection, useWorklist) {
                if (backwards === void 0) { backwards = false; }
                if (intersection === void 0) { intersection = false; }
                if (useWorklist === void 0) { useWorklist = true; }
                _super.call(this);
                this.df = df;
                this.pool = pool;
                this.backwards = backwards;
                this.intersection = intersection;
                this.useWorklist = useWorklist;
                this.worklist = [];
                this.Ins = {};
                this.Outs = {};
                this.starting = false;
                this.changed = false;
                this.visited = {};
                this.genZeroMap = {};
                this.genIncMap = {};
            }
            DataflowVisitor.prototype.generateAssignZero = function (l) {
                var res = this.genZeroMap[["d_", l.getName()].join("")];
                if (res != undefined)
                    return res;
                var localThing = AST.mkThing(l.getName());
                localThing.def = l;
                var initialVal = AST.mkLit(0);
                res = AST.mkCall(AST.PropertyRef.mkProp(AST.api.core.AssignmentProp), [localThing, initialVal]);
                this.genZeroMap[["d_", l.getName()].join("")] = res;
                return res;
            };
            DataflowVisitor.prototype.generateInc = function (l) {
                var res = this.genIncMap[["d_", l.getName()].join("")];
                if (res != undefined)
                    return res;
                var localThing = AST.mkThing(l.getName());
                localThing.def = l;
                var incVal = AST.mkLit(1);
                var sum = AST.mkCall(AST.PropertyRef.mkProp(AST.api.core.Number.getProperty("+")), [localThing, incVal]);
                res = AST.mkCall(AST.PropertyRef.mkProp(AST.api.core.AssignmentProp), [localThing, sum]);
                this.genIncMap[["d_", l.getName()].join("")] = res;
                return res;
            };
            DataflowVisitor.prototype.visitAstNode = function (node) {
                this.visitChildren(node);
            };
            DataflowVisitor.prototype.visitExprHolderHolder = function (stmt) {
                var _this = this;
                var preds = this.backwards ? AST.SuccessorsFinder.find(stmt) : AST.PredecessorsFinder.find(stmt);
                var newIn;
                if (this.starting) {
                    newIn = this.startNodeSet.clone();
                    this.starting = false;
                }
                else {
                    var validPreds = 0;
                    newIn = this.intersection ? new BitSet(true) : new BitSet();
                    preds.forEach(function (x) {
                        var nOut = _this.Outs[x.nodeId];
                        if (nOut != undefined) {
                            ++validPreds;
                            if (_this.intersection)
                                newIn.intersection(nOut);
                            else
                                newIn.union(nOut);
                        }
                    });
                    if (validPreds == 0) {
                        newIn = this.startingSet.clone();
                    }
                }
                this.Ins[stmt.nodeId] = newIn;
                var newOut = newIn.clone();
                if (stmt instanceof AST.ExprStmt && !stmt.isPlaceholder()) {
                    this.df.kill(stmt.expr, newOut, false);
                    this.df.gen(stmt.expr, newOut, newIn, false);
                }
                else if (!!stmt.calcNode()) {
                    if (stmt instanceof AST.For) {
                        var forInitialAssgn = AST.exprToStmt(this.generateAssignZero(stmt.boundLocal));
                        var forIncAssgn = AST.exprToStmt(this.generateInc(stmt.boundLocal));
                        this.df.kill(forInitialAssgn.expr, newOut, true);
                        this.df.kill(forIncAssgn.expr, newOut, true);
                        this.df.gen(forIncAssgn.expr, newOut, newIn, true);
                        this.df.gen(forInitialAssgn.expr, newOut, newIn, true);
                    }
                    this.df.kill(stmt.calcNode(), newOut, false);
                    this.df.gen(stmt.calcNode(), newOut, newIn, false);
                }
                var oldOut = this.Outs[stmt.nodeId];
                if (!oldOut || !oldOut.equals(newOut)) {
                    if (this.useWorklist) {
                        if (this.backwards) {
                            AST.PredecessorsFinder.find(stmt).forEach(function (s) {
                                _this.worklist.push(s);
                                _this.visited[s.nodeId] = false;
                            });
                        }
                        else {
                            AST.SuccessorsFinder.find(stmt).forEach(function (s) {
                                _this.worklist.push(s);
                                _this.visited[s.nodeId] = false;
                            });
                        }
                    }
                    else {
                        this.changed = true;
                    }
                    this.Outs[stmt.nodeId] = newOut;
                }
                if (stmt instanceof AST.ExprStmt) {
                    this.df.updateNode(stmt, stmt.expr);
                }
                else if (!!stmt.calcNode()) {
                    this.df.updateNode(stmt, stmt.calcNode());
                }
                if (!this.useWorklist)
                    this.visitChildren(stmt);
            };
            DataflowVisitor.prototype.visitComment = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitFor = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitIf = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitElseIf = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitForeach = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitWhile = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.visitExprStmt = function (n) {
                this.visitExprHolderHolder(n);
            };
            DataflowVisitor.prototype.topologicalSort = function (a) {
                var _this = this;
                var incomingEdges = {};
                var visited = {};
                var noIncomingEdges = {};
                var idToNode = {};
                var numNodesVisited = 0;
                a.body.forEach(function (s) {
                    var todo = _this.backwards ? PredecessorsFinder.unpeelAndGetLast(s) : SuccessorsFinder.unpeelAndGetFirst(s);
                    while (todo.length > 0) {
                        var cur = todo.shift();
                        if (visited[cur.nodeId])
                            continue;
                        visited[cur.nodeId] = true;
                        ++numNodesVisited;
                        idToNode[cur.nodeId] = cur;
                        if (!(incomingEdges[cur.nodeId] > 0)) {
                            noIncomingEdges[cur.nodeId] = true;
                        }
                        var succs = _this.backwards ? AST.PredecessorsFinder.find(cur) : AST.SuccessorsFinder.find(cur);
                        succs.forEach(function (x) {
                            if (incomingEdges[x.nodeId] == undefined)
                                incomingEdges[x.nodeId] = 1;
                            else
                                incomingEdges[x.nodeId]++;
                            noIncomingEdges[x.nodeId] = false;
                            todo.push(x);
                        });
                    }
                });
                var s = [];
                for (var key in noIncomingEdges) {
                    if (noIncomingEdges[key]) {
                        var node = idToNode[key];
                        TDev.Util.assert(node !== undefined);
                        s.push(node);
                    }
                }
                while (this.worklist.length < numNodesVisited) {
                    if (s.length == 0) {
                        var found = false;
                        for (var key in visited) {
                            var cand = idToNode[key];
                            if (cand !== undefined && incomingEdges[key] > 0) {
                                incomingEdges[key] = 0;
                                s.push(cand);
                                found = true;
                                break;
                            }
                        }
                        TDev.Util.assert(found);
                    }
                    var cur = s.shift();
                    this.worklist.push(cur);
                    var succs = this.backwards ? AST.PredecessorsFinder.find(cur) : AST.SuccessorsFinder.find(cur);
                    for (var i = 0; i < succs.length; ++i) {
                        var x = succs[i];
                        if (--incomingEdges[x.nodeId] == 0)
                            s.unshift(x);
                        else if (incomingEdges[x.nodeId] > 0 && i == succs.length - 1 && s.length == 0) {
                            incomingEdges[x.nodeId] = 0;
                            s.push(x);
                        }
                    }
                }
            };
            DataflowVisitor.prototype.dfTesting = function (s) {
                var preds = AST.PredecessorsFinder.find(s);
                var succs;
                for (var i = 0; i < preds.length; ++i) {
                    var elmi = preds[i];
                    succs = AST.SuccessorsFinder.find(elmi);
                    var found = false;
                    for (var j = 0; j < succs.length; ++j) {
                        var elmj = succs[j];
                        if (elmj === s)
                            found = true;
                    }
                    TDev.Util.assert(found);
                }
                succs = AST.SuccessorsFinder.find(s);
                for (var i = 0; i < succs.length; ++i) {
                    var elmi2 = succs[i];
                    preds = AST.PredecessorsFinder.find(elmi2);
                    var found = false;
                    for (var j = 0; j < preds.length; ++j) {
                        var elmj2 = preds[j];
                        if (elmj2 === s)
                            found = true;
                    }
                    TDev.Util.assert(found);
                }
            };
            DataflowVisitor.prototype.visitAction = function (n) {
                var _this = this;
                if (n instanceof AST.LibraryRefAction)
                    return;
                if (n.isPage())
                    return;
                if (this.useWorklist) {
                    this.worklist = [];
                    this.topologicalSort(n);
                    this.visited = {};
                    this.startNodeSet = new BitSet();
                    this.df.buildStartNodeSet(n, this.startNodeSet);
                    this.startingSet = new BitSet();
                    this.df.buildStartingSet(n, this.startingSet);
                    this.starting = true;
                    while (this.worklist.length > 0) {
                        var cur = this.worklist.shift();
                        if (this.visited[cur.nodeId])
                            continue;
                        this.visited[cur.nodeId] = true;
                        cur.accept(this);
                    }
                }
                else {
                    this.startNodeSet = new BitSet();
                    this.df.buildStartNodeSet(n, this.startNodeSet);
                    this.startingSet = new BitSet();
                    this.df.buildStartingSet(n, this.startingSet);
                    this.changed = true;
                    this.starting = true;
                    while (this.changed) {
                        this.changed = false;
                        n.body.forEach(function (c) {
                            c.accept(_this);
                        });
                    }
                }
            };
            return DataflowVisitor;
        })(AST.NodeVisitor);
        var ReachingDefsMgr = (function () {
            function ReachingDefsMgr(defs, node) {
                this.defs = defs;
                this.node = node;
            }
            ReachingDefsMgr.prototype.getLocal = function (e) {
                if (e instanceof AST.ThingRef) {
                    var d = e.def;
                    if (d instanceof AST.LocalDef)
                        return d.getName();
                }
                return null;
            };
            ReachingDefsMgr.prototype.toString = function () {
                return "RD #" + this.node.nodeId + ": {" + this.defs.join() + "}";
            };
            ReachingDefsMgr.prototype.mayBeInvalid = function (d) {
                var _this = this;
                var ret = false;
                this.defs.forEach(function (e) {
                    var refcall = e;
                    if (refcall.prop() != AST.api.core.AssignmentProp)
                        return;
                    refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                        var l = _this.getLocal(a);
                        if (l && l == d.getName()) {
                            if (refcall.args.length > 1) {
                                refcall.args.slice(1).forEach(function (val) {
                                    if (val instanceof AST.Call && val.args.length > 0 && val.args[0] instanceof AST.ThingRef && val.args[0].data == "invalid") {
                                        ret = true;
                                    }
                                    if (val instanceof AST.Call && !(val.prop().getFlags() & 16384 /* Robust */)) {
                                        ret = true;
                                    }
                                });
                            }
                        }
                    });
                });
                return ret;
            };
            return ReachingDefsMgr;
        })();
        AST.ReachingDefsMgr = ReachingDefsMgr;
        var ReachingDefinitions = (function () {
            function ReachingDefinitions() {
            }
            ReachingDefinitions.prototype.getLocal = function (e) {
                if (e instanceof AST.ThingRef) {
                    var d = e.def;
                    if (d instanceof AST.LocalDef)
                        return d;
                }
                return null;
            };
            ReachingDefinitions.prototype.getLocalName = function (e) {
                var ld = this.getLocal(e);
                if (ld != null) {
                    return ld.getName();
                }
                return null;
            };
            ReachingDefinitions.prototype.handleCopy = function (c, _set) {
                var _this = this;
                var bypassGen = false;
                if (c.prop() == AST.api.core.AssignmentProp && c.args.length == 2 && c.args[0] instanceof AST.ThingRef && c.args[1] instanceof AST.ThingRef) {
                    var dst = this.getLocal(c.args[0]);
                    var src = this.getLocal(c.args[1]);
                    if (src != null && dst != null) {
                        _set.forEach(function (idx) {
                            var elm = _this.pool.getElmById(idx);
                            var refcall = elm.refNode;
                            if (refcall) {
                                refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                                    var l2 = _this.getLocalName(a);
                                    if (l2 == src.getName()) {
                                        var newCall = _this.cloneAndChangeDst(refcall, dst);
                                        var newElm = _this.pool.getElm(newCall.getText(), newCall);
                                        _set.add(newElm.id);
                                        bypassGen = true;
                                    }
                                });
                            }
                        });
                    }
                }
                if (c.prop() == AST.api.core.AssignmentProp && c.args.length == 2 && c.args[0] instanceof AST.ThingRef && c.args[1] instanceof AST.Call) {
                    var dst = this.getLocal(c.args[0]);
                    var srcCall = c.args[1];
                    if (dst != null && srcCall != null && srcCall.args.length == 2 && (srcCall.prop() == AST.api.core.AndProp || srcCall.prop() == AST.api.core.OrProp) && srcCall.args[1] instanceof AST.ThingRef) {
                        var src = this.getLocal(srcCall.args[1]);
                        if (src != null && dst != null) {
                            _set.forEach(function (idx) {
                                var elm = _this.pool.getElmById(idx);
                                var refcall = elm.refNode;
                                if (refcall) {
                                    refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                                        var l2 = _this.getLocalName(a);
                                        if (l2 == src.getName()) {
                                            var newCall = _this.cloneAndChangeDst(refcall, dst);
                                            var newElm = _this.pool.getElm(newCall.getText(), newCall);
                                            _set.add(newElm.id);
                                        }
                                    });
                                }
                            });
                        }
                    }
                }
                return bypassGen;
            };
            ReachingDefinitions.prototype.updateSet = function (n, _set, genKill) {
                var _this = this;
                if (!n.parsed || !(n.parsed instanceof AST.Call))
                    return;
                var c = n.parsed;
                var exprVisitQueue = [];
                exprVisitQueue.push(c);
                while (exprVisitQueue.length > 0) {
                    var cur = exprVisitQueue.shift();
                    if (!(cur instanceof AST.Call))
                        continue;
                    var curCall = cur;
                    exprVisitQueue = exprVisitQueue.concat(curCall.children());
                    var prop = curCall.prop();
                    if (prop == AST.api.core.AssignmentProp) {
                        c.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                            var l = _this.getLocalName(e);
                            if (l) {
                                if (genKill) {
                                    if (!_this.handleCopy(curCall, _set)) {
                                        var elm = _this.pool.getElm(curCall.getText(), curCall);
                                        _set.add(elm.id);
                                    }
                                }
                                else {
                                    _set.forEach(function (idx) {
                                        var elm = _this.pool.getElmById(idx);
                                        var refcall = elm.refNode;
                                        var remove = false;
                                        if (refcall) {
                                            refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                                                var l2 = _this.getLocalName(a);
                                                if (l2 == l)
                                                    remove = true;
                                            });
                                        }
                                        if (remove)
                                            _set.remove(idx);
                                    });
                                }
                            }
                        });
                    }
                }
            };
            ReachingDefinitions.prototype.gen = function (n, _set, inSet, isIV) {
                if (isIV === void 0) { isIV = false; }
                this.updateSet(n, _set, true);
            };
            ReachingDefinitions.prototype.kill = function (n, _set, isIV) {
                if (isIV === void 0) { isIV = false; }
                this.updateSet(n, _set, false);
            };
            ReachingDefinitions.prototype.updateNode = function (s, n) {
                var _this = this;
                n.reachingDefs = null;
                var defs = [];
                this.df.Ins[s.nodeId].forEach(function (idx) {
                    defs.push(_this.pool.getElmById(idx).refNode);
                });
                if (defs.length > 0)
                    n.reachingDefs = new ReachingDefsMgr(defs, s);
            };
            ReachingDefinitions.prototype.generateInvalidAssignmentFor = function (l) {
                var localThing = AST.mkThing(l.getName());
                localThing.def = l;
                var invalidThing = AST.mkThing("invalid");
                invalidThing.def = AST.api.getKind("Invalid").singleton;
                return AST.mkCall(AST.PropertyRef.mkProp(AST.api.core.AssignmentProp), [localThing, AST.mkCall(AST.PropertyRef.mkProp(AST.api.getKind("Invalid").getProperty("number")), [invalidThing])]);
            };
            ReachingDefinitions.prototype.cloneAndChangeDst = function (c, dst) {
                var args = c.args.slice(0);
                args[0] = AST.mkThing(dst.getName());
                args[0].def = dst;
                return AST.mkCall(c.propRef, args);
            };
            ReachingDefinitions.prototype.buildStartNodeSet = function (a, _set) {
                var _this = this;
                a.allLocals.forEach(function (e) {
                    if (!(e instanceof AST.LocalDef))
                        return;
                    var l = e.getName();
                    var elm = _this.pool.getElm(l, _this.generateInvalidAssignmentFor(e));
                    _set.add(elm.id);
                });
            };
            ReachingDefinitions.prototype.buildStartingSet = function (a, _set) {
            };
            ReachingDefinitions.prototype.visitApp = function (n) {
                var _this = this;
                n.things.forEach(function (a) {
                    if (a instanceof AST.Action && !a.isPage()) {
                        _this.pool = new SetElementsPool();
                        _this.df = new DataflowVisitor(_this, _this.pool, false, false, true);
                        _this.df.dispatch(a);
                    }
                });
            };
            return ReachingDefinitions;
        })();
        AST.ReachingDefinitions = ReachingDefinitions;
        var DominatorsMgr = (function () {
            function DominatorsMgr(doms, node) {
                this.doms = doms;
                this.node = node;
            }
            DominatorsMgr.prototype.toString = function () {
                var str = "DOMS(" + this.node.nodeId + ") : {";
                str += this.doms.map(function (e) {
                    return e.nodeId.toString();
                }).join();
                return str + "}";
            };
            return DominatorsMgr;
        })();
        AST.DominatorsMgr = DominatorsMgr;
        var Dominators = (function () {
            function Dominators() {
            }
            Dominators.prototype.gen = function (n, _set, inSet, isIV) {
                if (isIV === void 0) { isIV = false; }
                if (!n.parsed)
                    return;
                var elm = this.pool.getElm(n.parsed.nodeId.toString(), n.parsed);
                _set.add(elm.id);
            };
            Dominators.prototype.kill = function (n, _set, isIV) {
                if (isIV === void 0) { isIV = false; }
            };
            Dominators.prototype.updateNode = function (s, n) {
                var _this = this;
                n.dominators = null;
                var doms = [];
                this.df.Ins[s.nodeId].forEach(function (idx) {
                    doms.push(_this.pool.getElmById(idx).refNode);
                });
                if (doms.length > 0)
                    n.dominators = new DominatorsMgr(doms, s);
            };
            Dominators.prototype.buildStartNodeSet = function (a, _set) {
            };
            Dominators.prototype.buildStartingSet = function (a, _set) {
                _set.makeAllSet();
            };
            Dominators.prototype.visitApp = function (n) {
                var _this = this;
                n.things.forEach(function (a) {
                    if (a instanceof AST.Action && !a.isPage()) {
                        _this.pool = new SetElementsPool();
                        _this.df = new DataflowVisitor(_this, _this.pool, false, true, true);
                        _this.df.dispatch(a);
                    }
                });
            };
            return Dominators;
        })();
        AST.Dominators = Dominators;
        var UsedSetMgr = (function () {
            function UsedSetMgr(used, node) {
                this.used = used;
                this.node = node;
            }
            UsedSetMgr.getLocal = function (e) {
                if (e instanceof AST.ThingRef) {
                    var d = e.def;
                    if (d instanceof AST.LocalDef)
                        return d;
                }
                return null;
            };
            UsedSetMgr.getLocalName = function (e) {
                var ld = this.getLocal(e);
                if (ld != null) {
                    return ld.getName();
                }
                return null;
            };
            UsedSetMgr.prototype.alreadyUsed = function (ld) {
                var res = false;
                this.used.forEach(function (e) {
                    var name1 = UsedSetMgr.getLocalName(e);
                    if (name1 && name1 == ld.getName()) {
                        res = true;
                    }
                });
                return res;
            };
            UsedSetMgr.prototype.toString = function () {
                var str = "USED(" + this.node.nodeId + ") : {";
                str += this.used.map(function (e) {
                    return UsedSetMgr.getLocalName(e);
                }).join();
                return str + "}";
            };
            return UsedSetMgr;
        })();
        AST.UsedSetMgr = UsedSetMgr;
        var UsedAnalysis = (function () {
            function UsedAnalysis() {
            }
            UsedAnalysis.prototype.gen = function (n, _set, inSet, isIV) {
                var _this = this;
                if (isIV === void 0) { isIV = false; }
                if (!n.parsed || !(n.parsed instanceof AST.Call))
                    return;
                var c = n.parsed;
                var exprVisitQueue = [];
                exprVisitQueue.push(c);
                while (exprVisitQueue.length > 0) {
                    var cur = exprVisitQueue.shift();
                    if (!(cur instanceof AST.Call))
                        continue;
                    var curCall = cur;
                    exprVisitQueue = exprVisitQueue.concat(curCall.children());
                    var prop = curCall.prop();
                    if (prop == AST.api.core.AssignmentProp) {
                        c.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                            var l = UsedSetMgr.getLocalName(e);
                            if (l) {
                                {
                                    _set.forEach(function (idx) {
                                        var elm = _this.pool.getElmById(idx);
                                        if (elm.key == l)
                                            _set.remove(idx);
                                    });
                                }
                            }
                        });
                    }
                }
            };
            UsedAnalysis.prototype.kill = function (n, _set, isIV) {
                if (isIV === void 0) { isIV = false; }
                if (!n.parsed)
                    return;
                var exprVisitQueue = [];
                exprVisitQueue.push(n.parsed);
                while (exprVisitQueue.length > 0) {
                    var e = exprVisitQueue.shift();
                    var refcall = e;
                    if (!(e instanceof AST.Call)) {
                        if (e instanceof AST.ThingRef) {
                            var ed = e.def;
                            if (ed instanceof AST.LocalDef) {
                                var elm = this.pool.getElm(ed.getName(), e);
                                _set.add(elm.id);
                            }
                        }
                    }
                    else {
                        if (refcall.prop() && refcall.prop().getName() == "is invalid") {
                        }
                        else if (refcall.prop() != AST.api.core.AssignmentProp) {
                            exprVisitQueue = exprVisitQueue.concat(refcall.children());
                        }
                        else {
                            exprVisitQueue = exprVisitQueue.concat(refcall.args.slice(1));
                        }
                    }
                }
            };
            UsedAnalysis.prototype.updateNode = function (s, n) {
                var _this = this;
                n.usedSet = null;
                var usedSet = [];
                this.df.Ins[s.nodeId].forEach(function (idx) {
                    usedSet.push(_this.pool.getElmById(idx).refNode);
                });
                if (usedSet.length > 0)
                    n.usedSet = new UsedSetMgr(usedSet, s);
            };
            UsedAnalysis.prototype.buildStartNodeSet = function (a, _set) {
            };
            UsedAnalysis.prototype.buildStartingSet = function (a, _set) {
                _set.makeAllSet();
            };
            UsedAnalysis.prototype.visitApp = function (n) {
                var _this = this;
                n.things.forEach(function (a) {
                    if (a instanceof AST.Action && !a.isPage()) {
                        _this.pool = new SetElementsPool();
                        _this.df = new DataflowVisitor(_this, _this.pool, false, true, true);
                        _this.df.dispatch(a);
                    }
                });
            };
            return UsedAnalysis;
        })();
        AST.UsedAnalysis = UsedAnalysis;
        var AvailableExpressionsMgr = (function () {
            function AvailableExpressionsMgr(aeSet, node) {
                this.aeSet = aeSet;
                this.node = node;
            }
            AvailableExpressionsMgr.prototype.hasOnlyIdempotentNodes = function (e) {
                var exprVisitQueue = [];
                exprVisitQueue.push(e);
                while (exprVisitQueue.length > 0) {
                    var e = exprVisitQueue.shift();
                    var refcall = e;
                    if (!(e instanceof AST.Call)) {
                        if (!(e instanceof AST.Literal || (e instanceof AST.ThingRef && e.def.nodeType() == "localDef")))
                            return false;
                    }
                    else {
                        if (refcall.prop() != AST.api.core.AssignmentProp && refcall.prop().getFlags() & 32768 /* Idempotent */) {
                            exprVisitQueue = exprVisitQueue.concat(refcall.children());
                        }
                        else {
                            return false;
                        }
                    }
                }
                return true;
            };
            AvailableExpressionsMgr.prototype.checkForIdenticalExpressions = function (e) {
                var _this = this;
                var res = [];
                if (e == undefined)
                    return;
                this.aeSet.forEach(function (ae) {
                    if (ae.toString() == e.toString() && _this.hasOnlyIdempotentNodes(e))
                        res.push(ae);
                });
                return res;
            };
            AvailableExpressionsMgr.prototype.toString = function () {
                var str = "AE(" + this.node.nodeId + ") : {";
                str += this.aeSet.join();
                return str + "}";
            };
            return AvailableExpressionsMgr;
        })();
        AST.AvailableExpressionsMgr = AvailableExpressionsMgr;
        var AvailableExpressions = (function () {
            function AvailableExpressions() {
            }
            AvailableExpressions.prototype.usesLocal = function (e, l) {
                var exprVisitQueue = [];
                exprVisitQueue.push(e);
                while (exprVisitQueue.length > 0) {
                    var e = exprVisitQueue.shift();
                    var refcall = e;
                    if (!(e instanceof AST.Call)) {
                        if (UsedSetMgr.getLocalName(e) == l)
                            return true;
                    }
                    else {
                        if (refcall.prop() != AST.api.core.AssignmentProp) {
                            exprVisitQueue = exprVisitQueue.concat(refcall.children());
                        }
                        else {
                            exprVisitQueue = exprVisitQueue.concat(refcall.args.slice(1));
                        }
                    }
                }
                return false;
            };
            AvailableExpressions.prototype.gen = function (n, _set, inSet, isIV) {
                var _this = this;
                if (isIV === void 0) { isIV = false; }
                if (isIV)
                    return;
                if (!n.parsed || !(n.parsed instanceof AST.Call))
                    return;
                var c = n.parsed;
                var exprVisitQueue = [];
                exprVisitQueue.push(c);
                while (exprVisitQueue.length > 0) {
                    var cur = exprVisitQueue.shift();
                    if (!(cur instanceof AST.Call))
                        continue;
                    var curCall = cur;
                    exprVisitQueue = exprVisitQueue.concat(curCall.children());
                    var prop = curCall.prop();
                    if (prop == AST.api.core.AssignmentProp) {
                        c.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                            var l = UsedSetMgr.getLocalName(e);
                            if (l) {
                                {
                                    _set.forEach(function (idx) {
                                        var elm = _this.pool.getElmById(idx);
                                        if (_this.usesLocal(elm.refNode, l))
                                            _set.remove(idx);
                                    });
                                }
                            }
                        });
                    }
                }
            };
            AvailableExpressions.prototype.kill = function (n, _set, isIV) {
                if (isIV === void 0) { isIV = false; }
                if (isIV)
                    return;
                if (!n.parsed)
                    return;
                var exprVisitQueue = [];
                exprVisitQueue.push(n.parsed);
                while (exprVisitQueue.length > 0) {
                    var e = exprVisitQueue.shift();
                    var refcall = e;
                    if (e instanceof AST.Call) {
                        if (refcall.prop() != AST.api.core.AssignmentProp) {
                            var elm = this.pool.getElm(refcall.toString(), refcall);
                            _set.add(elm.id);
                            exprVisitQueue = exprVisitQueue.concat(refcall.args.slice(1));
                        }
                        else {
                            exprVisitQueue = exprVisitQueue.concat(refcall.children());
                        }
                    }
                }
            };
            AvailableExpressions.prototype.updateNode = function (s, n) {
                var _this = this;
                n.aeSet = null;
                var aeSet = [];
                this.df.Ins[s.nodeId].forEach(function (idx) {
                    aeSet.push(_this.pool.getElmById(idx).refNode);
                });
                if (aeSet.length > 0)
                    n.aeSet = new AvailableExpressionsMgr(aeSet, s);
            };
            AvailableExpressions.prototype.buildStartNodeSet = function (a, _set) {
            };
            AvailableExpressions.prototype.buildStartingSet = function (a, _set) {
                _set.makeAllSet();
            };
            AvailableExpressions.prototype.visitApp = function (n) {
                var _this = this;
                n.things.forEach(function (a) {
                    if (a instanceof AST.Action && !a.isPage()) {
                        _this.pool = new SetElementsPool();
                        _this.df = new DataflowVisitor(_this, _this.pool, false, true, true);
                        _this.df.dispatch(a);
                    }
                });
            };
            return AvailableExpressions;
        })();
        AST.AvailableExpressions = AvailableExpressions;
        var ConstantPropagationMgr = (function () {
            function ConstantPropagationMgr(constantSet, node) {
                this.constantSet = constantSet;
                this.node = node;
            }
            ConstantPropagationMgr.prototype.getLiteralValueFor = function (d) {
                var res = null;
                this.constantSet.forEach(function (e) {
                    if (e instanceof AST.Call && e.prop() == AST.api.core.AssignmentProp && e.args.length == 2 && e.args[0] instanceof AST.ThingRef && (e.args[0]).def instanceof AST.LocalDef && ((e.args[0]).def).getName() == d.getName() && e.args[1] instanceof AST.Literal && (e.args[1]).data != null)
                        res = (e.args[1]).data;
                });
                return res;
            };
            ConstantPropagationMgr.evaluate = function (c, args) {
                if (c.prop().getCategory() == 0 /* Builtin */) {
                    if (c.prop().getSpecialApply() == "+")
                        return args[0] + args[1];
                    else if (c.prop().getSpecialApply() == "-")
                        return args[0] - args[1];
                    else if (c.prop().getSpecialApply() == "/")
                        return args[0] / args[1];
                    else if (c.prop().getSpecialApply() == "*")
                        return args[0] * args[1];
                    else if (c.prop().getSpecialApply() == "===")
                        return args[0] === args[1];
                }
                return null;
            };
            ConstantPropagationMgr.prototype.precomputeLiteralExpression = function (e) {
                var _this = this;
                var visitExpr = function (exp) {
                    var refcall = exp;
                    if (!(exp instanceof AST.Call)) {
                        if (exp instanceof AST.Literal)
                            return exp.data;
                        if (exp instanceof AST.ThingRef && exp.def.nodeType() == "localDef" && _this.getLiteralValueFor(exp.def) != null)
                            return _this.getLiteralValueFor(exp.def);
                    }
                    else {
                        if (refcall.prop() != AST.api.core.AssignmentProp && refcall.prop().getFlags() & 32768 /* Idempotent */) {
                            var values = refcall.children().map(function (ea) { return visitExpr(ea); });
                            var hasNull = false;
                            values.forEach(function (ea) {
                                if (ea == null)
                                    hasNull = true;
                            });
                            if (!hasNull) {
                                return ConstantPropagationMgr.evaluate(refcall, values);
                            }
                        }
                        return null;
                    }
                };
                return visitExpr(e);
            };
            ConstantPropagationMgr.prototype.toString = function () {
                var str = "CP(" + this.node.nodeId + ") : {";
                str += this.constantSet.join();
                return str + "}";
            };
            return ConstantPropagationMgr;
        })();
        AST.ConstantPropagationMgr = ConstantPropagationMgr;
        var ConstantPropagation = (function () {
            function ConstantPropagation() {
            }
            ConstantPropagation.prototype.generateAssignmentFor = function (l, value) {
                var localThing = AST.mkThing(l.getName());
                localThing.def = l;
                var literal = AST.mkLit(value);
                return AST.mkCall(AST.PropertyRef.mkProp(AST.api.core.AssignmentProp), [localThing, literal]);
            };
            ConstantPropagation.prototype.cloneAndChangeDst = function (c, dst) {
                var args = c.args.slice(0);
                args[0] = AST.mkThing(dst.getName());
                args[0].def = dst;
                return AST.mkCall(c.propRef, args);
            };
            ConstantPropagation.prototype.getLocal = function (e) {
                if (e instanceof AST.ThingRef) {
                    var d = e.def;
                    if (d instanceof AST.LocalDef)
                        return d;
                }
                return null;
            };
            ConstantPropagation.prototype.getLocalName = function (e) {
                var ld = this.getLocal(e);
                if (ld != null) {
                    return ld.getName();
                }
                return null;
            };
            ConstantPropagation.prototype.handleCopy = function (c, _set) {
                var _this = this;
                var bypassGen = false;
                if (c.prop() == AST.api.core.AssignmentProp && c.args.length == 2 && c.args[0] instanceof AST.ThingRef && c.args[1] instanceof AST.ThingRef) {
                    var dst = this.getLocal(c.args[0]);
                    var src = this.getLocal(c.args[1]);
                    if (src != null && dst != null) {
                        _set.forEach(function (idx) {
                            var elm = _this.pool.getElmById(idx);
                            var refcall = elm.refNode;
                            if (refcall) {
                                refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                                    var l2 = _this.getLocalName(a);
                                    if (l2 == src.getName()) {
                                        var newCall = _this.cloneAndChangeDst(refcall, dst);
                                        var newElm = _this.pool.getElm(newCall.getText(), newCall);
                                        _set.add(newElm.id);
                                        bypassGen = true;
                                    }
                                });
                            }
                        });
                    }
                }
                return bypassGen;
            };
            ConstantPropagation.prototype.updateSet = function (n, _set, genKill) {
                var _this = this;
                if (!n.parsed || !(n.parsed instanceof AST.Call))
                    return;
                var c = n.parsed;
                var exprVisitQueue = [];
                exprVisitQueue.push(c);
                while (exprVisitQueue.length > 0) {
                    var cur = exprVisitQueue.shift();
                    if (!(cur instanceof AST.Call))
                        continue;
                    var curCall = cur;
                    exprVisitQueue = exprVisitQueue.concat(curCall.children());
                    var prop = curCall.prop();
                    if (prop == AST.api.core.AssignmentProp) {
                        c.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                            var l = _this.getLocalName(e);
                            if (l) {
                                if (genKill) {
                                    if (!_this.handleCopy(curCall, _set)) {
                                        var lit = (new ConstantPropagationMgr(_this.generateCpSet(_set), null)).precomputeLiteralExpression(c.args[1]);
                                        if (lit != null) {
                                            var assgn = _this.generateAssignmentFor(_this.getLocal(e), lit);
                                            var elm = _this.pool.getElm(assgn.getText(), assgn);
                                            _set.add(elm.id);
                                        }
                                    }
                                }
                                else {
                                    _set.forEach(function (idx) {
                                        var elm = _this.pool.getElmById(idx);
                                        var refcall = elm.refNode;
                                        var remove = false;
                                        if (refcall) {
                                            refcall.args[0].flatten(AST.api.core.TupleProp).forEach(function (a) {
                                                var l2 = _this.getLocalName(a);
                                                if (l2 == l)
                                                    remove = true;
                                            });
                                        }
                                        if (remove)
                                            _set.remove(idx);
                                    });
                                }
                            }
                        });
                    }
                }
            };
            ConstantPropagation.prototype.gen = function (n, _set, inSet, isIV) {
                if (isIV === void 0) { isIV = false; }
                if (!isIV)
                    this.updateSet(n, _set, true);
            };
            ConstantPropagation.prototype.kill = function (n, _set, isIV) {
                if (isIV === void 0) { isIV = false; }
                if (!isIV)
                    this.updateSet(n, _set, false);
            };
            ConstantPropagation.prototype.generateCpSet = function (_set) {
                var _this = this;
                var cpSet = [];
                _set.forEach(function (idx) {
                    cpSet.push(_this.pool.getElmById(idx).refNode);
                });
                return cpSet;
            };
            ConstantPropagation.prototype.updateNode = function (s, n) {
                var cpSet = this.generateCpSet(this.df.Ins[s.nodeId]);
                n.cpSet = new ConstantPropagationMgr(cpSet, s);
            };
            ConstantPropagation.prototype.buildStartNodeSet = function (a, _set) {
            };
            ConstantPropagation.prototype.buildStartingSet = function (a, _set) {
                _set.makeAllSet();
            };
            ConstantPropagation.prototype.visitApp = function (n) {
                var _this = this;
                n.things.forEach(function (a) {
                    if (a instanceof AST.Action && !a.isPage()) {
                        _this.pool = new SetElementsPool();
                        _this.df = new DataflowVisitor(_this, _this.pool, false, true, true);
                        _this.df.dispatch(a);
                    }
                });
            };
            return ConstantPropagation;
        })();
        AST.ConstantPropagation = ConstantPropagation;
        var CallGraphNode = (function () {
            function CallGraphNode(action, succs, preds, canInline) {
                if (canInline === void 0) { canInline = false; }
                this.action = action;
                this.succs = succs;
                this.preds = preds;
                this.canInline = canInline;
            }
            CallGraphNode.prototype.addSucc = function (succ) {
                for (var i = 0; i < this.succs.length; ++i) {
                    if (this.succs[i] == succ)
                        return;
                }
                this.succs.push(succ);
            };
            CallGraphNode.prototype.addPred = function (pred) {
                for (var i = 0; i < this.preds.length; ++i) {
                    if (this.preds[i] == pred)
                        return;
                }
                this.preds.push(pred);
            };
            return CallGraphNode;
        })();
        AST.CallGraphNode = CallGraphNode;
        var InlineAnalysis = (function (_super) {
            __extends(InlineAnalysis, _super);
            function InlineAnalysis() {
                _super.call(this);
                this.hasChanged = false;
                this.nodes = [];
                this.nodeMap = {};
            }
            InlineAnalysis.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitExprHolder = function (n) {
                if (n.parsed)
                    this.dispatch(n.parsed);
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitFor = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitForeach = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitWhile = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitBox = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitForeachClause = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitInlineActions = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitInlineAction = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitOptionalParameter = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitContinue = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitBreak = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitReturn = function (n) {
                this.nowVisiting.canInline = false;
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.visitCall = function (n) {
                var a = n.calledAction();
                var prop = n.prop();
                if (prop && prop.getCategory() == 3 /* Library */) {
                    this.nowVisiting.canInline = false;
                    return;
                }
                if (prop && prop.shouldPauseInterperter()) {
                    this.nowVisiting.canInline = false;
                    return;
                }
                if (prop && prop.getName() == "run" && prop.parentKind.isAction) {
                    this.nowVisiting.canInline = false;
                    return;
                }
                if (a == null) {
                    this.visitChildren(n);
                    return;
                }
                if (a instanceof AST.LibraryRefAction) {
                    this.nowVisiting.canInline = false;
                    return;
                }
                var cgNode = this.nodeMap[["a_", a.getName()].join("")];
                if (cgNode == undefined) {
                    cgNode = new CallGraphNode(a, [], []);
                    this.nodeMap[["a_", a.getName()].join("")] = cgNode;
                    this.nodes.push(cgNode);
                }
                this.nowVisiting.addSucc(cgNode);
                cgNode.addPred(this.nowVisiting);
                this.visitChildren(n);
            };
            InlineAnalysis.prototype.actionHasDesiredProperties = function (a) {
                return (a.isNormalAction() && a.isPrivate && !a.isLambda && !a.isTest() && a.isAtomic && a.getOutParameters().length <= 1);
            };
            InlineAnalysis.prototype.visitAction = function (n) {
                if (n instanceof AST.LibraryRefAction)
                    return;
                var cgNode = this.nodeMap[["a_", n.getName()].join("")];
                if (cgNode == undefined) {
                    cgNode = new CallGraphNode(n, [], []);
                    this.nodeMap[["a_", n.getName()].join("")] = cgNode;
                    this.nodes.push(cgNode);
                }
                this.nowVisiting = cgNode;
                this.nowVisiting.canInline = true;
                this.visitChildren(n);
                if (this.nowVisiting.canInline && this.actionHasDesiredProperties(n) && this.nowVisiting.succs.length == 0) {
                    n.canBeInlined = true;
                }
            };
            InlineAnalysis.prototype.topologicalSort = function () {
                var _this = this;
                var traversalOrder = [];
                var visited = {};
                var indexMap = {};
                for (var i = 0; i < this.nodes.length; ++i) {
                    visited[i] = false;
                    indexMap[["a_", this.nodes[i].action.getName()].join("")] = i;
                }
                var visit = function (cur) {
                    if (visited[cur])
                        return;
                    visited[cur] = true;
                    for (var i = 0; i < _this.nodes[cur].preds.length; ++i) {
                        visit(indexMap[["a_", _this.nodes[cur].preds[i].action.getName()].join("")]);
                    }
                    traversalOrder.unshift(_this.nodes[cur]);
                };
                for (var i = 0; i < this.nodes.length; ++i) {
                    visit(i);
                }
                return traversalOrder;
            };
            InlineAnalysis.prototype.nestedInlineAnalysis = function () {
                var sorted = this.topologicalSort();
                for (var i = 0; i < sorted.length; ++i) {
                    if (sorted[i].action.canBeInlined)
                        continue;
                    var canInline = this.actionHasDesiredProperties(sorted[i].action) && sorted[i].canInline;
                    if (!canInline)
                        continue;
                    for (var j = 0; j < sorted[i].succs.length; ++j) {
                        if (!sorted[i].succs[j].action.canBeInlined)
                            canInline = false;
                    }
                    sorted[i].action.canBeInlined = canInline;
                }
            };
            InlineAnalysis.prototype.dumpCallGraph = function () {
                for (var i = 0; i < this.nodes.length; ++i) {
                    if (this.nodes[i].action.canBeInlined)
                        TDev.Util.log("Node " + i + ": " + this.nodes[i].action.toString() + " [can be inlined]");
                    else
                        TDev.Util.log("Node " + i + ": " + this.nodes[i].action.toString());
                    for (var j = 0; j < this.nodes[i].succs.length; ++j) {
                        TDev.Util.log(" |-> calls " + this.nodes[i].succs[j].action.toString());
                    }
                }
            };
            return InlineAnalysis;
        })(AST.NodeVisitor);
        AST.InlineAnalysis = InlineAnalysis;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var SplitAppIntoAppAndLibrary = (function () {
            function SplitAppIntoAppAndLibrary() {
                this.ddManager = null;
                this.theApp = null;
                this.targetLibrary = null;
                this.declsSelectedToMove = [];
                this.otherDeclsToMove = [];
                this.remainingDecls = null;
                this.appRewritten = null;
                this.library = null;
                this.ddManager = new DeclAndDepsManager();
            }
            SplitAppIntoAppAndLibrary.prototype.getAllDeclsToMove = function () {
                return this.declsSelectedToMove.concat(this.otherDeclsToMove);
            };
            SplitAppIntoAppAndLibrary.prototype.getRemainingDecls = function () {
                return this.remainingDecls;
            };
            SplitAppIntoAppAndLibrary.prototype.programChanged = function () {
                var _this = this;
                var all = this.ddManager.getAll().filter(function (dd) { return !(dd.decl instanceof AST.LibraryRef); });
                if (all.length == this.theApp.things.length) {
                    var ret = true;
                    this.theApp.things.forEach(function (d) {
                        ret = ret && d.cachedSerialized.idx >= 0;
                    });
                    this.ddManager.getAll().forEach(function (dd) {
                        ret = ret && _this.theApp.things.indexOf(dd.decl) >= 0;
                    });
                    return ret;
                }
                else {
                    return false;
                }
            };
            SplitAppIntoAppAndLibrary.prototype.invalidate = function () {
                var _this = this;
                if (this.targetLibrary != null && this.programChanged()) {
                    this.ddManager.invalidate();
                    this.otherDeclsToMove = [];
                    this.remainingDecls = null;
                    var remove = [];
                    this.ddManager.getAll().forEach(function (dd) {
                        if (_this.theApp.things.indexOf(dd.decl) < 0) {
                            remove.push(dd);
                        }
                    });
                    remove.forEach(function (dd) {
                        _this.ddManager.remove(dd);
                        var idx = _this.declsSelectedToMove.indexOf(dd);
                        if (idx >= 0)
                            _this.declsSelectedToMove.splice(idx);
                    });
                    this.addToDeclsToMove(this.declsSelectedToMove);
                }
            };
            SplitAppIntoAppAndLibrary.prototype.getAll = function () {
                return this.ddManager.getAll();
            };
            SplitAppIntoAppAndLibrary.prototype.getter = function (d) {
                return this.ddManager.getter(d);
            };
            SplitAppIntoAppAndLibrary.prototype.setAppAndLib = function (a, l) {
                if (this.targetLibrary == null) {
                    this.theApp = a;
                    this.targetLibrary = l;
                    return true;
                }
                else {
                    return false;
                }
            };
            SplitAppIntoAppAndLibrary.prototype.getApp = function () {
                return this.theApp;
            };
            SplitAppIntoAppAndLibrary.prototype.getLib = function () {
                return this.targetLibrary;
            };
            SplitAppIntoAppAndLibrary.prototype.addToDeclsToMove = function (newOnes) {
                var _this = this;
                var theRest = this.computeClosure(newOnes);
                newOnes.forEach(function (dd) {
                    if (_this.declsSelectedToMove.indexOf(dd) < 0) {
                        _this.declsSelectedToMove.push(dd);
                    }
                });
                theRest.forEach(function (dd) {
                    if (_this.declsSelectedToMove.indexOf(dd) < 0 && _this.otherDeclsToMove.indexOf(dd) < 0) {
                        _this.otherDeclsToMove.push(dd);
                    }
                });
                this.computeRemaining();
            };
            SplitAppIntoAppAndLibrary.prototype.computeClosure = function (roots) {
                return this.computeClosureRaw(roots, this.getAllDeclsToMove());
            };
            SplitAppIntoAppAndLibrary.prototype.computeRemaining = function () {
                var _this = this;
                if (this.remainingDecls == null) {
                    this.remainingDecls = [];
                    this.theApp.things.forEach(function (t) {
                        if (!(t instanceof AST.Action && t.isEvent())) {
                            var dd = _this.ddManager.getter(t);
                            if (_this.getAllDeclsToMove().indexOf(dd) < 0) {
                                _this.remainingDecls.push(dd);
                            }
                        }
                    });
                }
                else {
                    this.remainingDecls = this.remainingDecls.filter(function (a) { return _this.getAllDeclsToMove().indexOf(a) < 0; });
                }
            };
            SplitAppIntoAppAndLibrary.prototype.computeClosureRaw = function (roots, alreadyIn) {
                var _this = this;
                var theRest = [];
                DeclAndDeps.computeClosure(roots, alreadyIn, theRest);
                return theRest.filter(function (dd) { return dd.decl != _this.targetLibrary; });
            };
            SplitAppIntoAppAndLibrary.prototype.makeSplit = function () {
                var _this = this;
                if (this.targetLibrary == null || this.getAllDeclsToMove() == [])
                    return;
                var actions = this.getAllDeclsToMove().filter(function (dd) { return dd.decl instanceof AST.Action; });
                actions.forEach(function (dd) { return dd.decl.isPrivate = true; });
                this.remainingDecls.filter(function (dd) { return dd.decl instanceof AST.Action; }).forEach(function (a) {
                    a.getActions().forEach(function (b) {
                        if (actions.indexOf(b) >= 0) {
                            var act = b.decl;
                            act.isPrivate = false;
                            act.getInParameters().forEach(function (p) {
                                if (p.local.getKind() instanceof TDev.UserActionKind) {
                                    p.local.getKind().userAction.isPrivate = false;
                                }
                            });
                        }
                    });
                });
                this.getAllDeclsToMove().forEach(function (dd) {
                    dd.serialized = dd.decl.serialize();
                });
                var removeTarget = new RemoveLibraryReference(this.targetLibrary);
                this.getAllDeclsToMove().forEach(function (dd) { return removeTarget.dispatch(dd.decl); });
                var accessors = new CreateAccessors(this.theApp, this.getAllDeclsToMove().filter(function (dd) { return !(dd.decl instanceof AST.Action); }).map(function (dd) { return dd.decl; }), this.remainingDecls);
                accessors.getAccessorActions().forEach(function (act) { return _this.targetLibrary.resolved.addDecl(act); });
                var rewriter = new RewriteApp(this.targetLibrary, actions.map(function (dd) { return dd.decl; }), accessors);
                rewriter.performRewrite(this.theApp);
                var libraryReferences = [];
                this.getAllDeclsToMove().forEach(function (dd) {
                    if (dd.decl != _this.targetLibrary && dd.decl.parent == _this.theApp) {
                        var decls = AST.Parser.parseDecls(dd.decl.serialize(), _this.targetLibrary.resolved);
                        decls.forEach(function (d) {
                            if (d instanceof AST.LibraryRef) {
                                if (libraryReferences.indexOf(d) < 0) {
                                    libraryReferences.push(d);
                                    _this.targetLibrary.resolved.addDecl(d);
                                }
                            }
                            else {
                                _this.targetLibrary.resolved.addDecl(d);
                            }
                        });
                    }
                });
                this.targetLibrary.initializeResolves();
                this.getAllDeclsToMove().forEach(function (dd) {
                    if (!(dd.decl instanceof AST.LibraryRef)) {
                        _this.theApp.deleteDecl(dd.decl);
                        dd.decl = null;
                    }
                    else {
                    }
                });
                AST.InitIdVisitor.ensureOK(this.theApp);
                AST.InitIdVisitor.ensureOK(this.targetLibrary.resolved);
                this.appRewritten = this.theApp.serialize();
                this.library = this.targetLibrary.resolved.serialize();
            };
            return SplitAppIntoAppAndLibrary;
        })();
        AST.SplitAppIntoAppAndLibrary = SplitAppIntoAppAndLibrary;
        var CreateAccessors = (function () {
            function CreateAccessors(theApp, declsToLibrary, remaining) {
                var _this = this;
                this.theApp = theApp;
                this.declsToLibrary = declsToLibrary;
                this.remaining = remaining;
                this.rewriteFields = [];
                this.fieldModes = [];
                this.rewriteGlobals = [];
                this.globalModes = [];
                this.globalThings = [];
                this.rewriteProperties = [];
                this.rewritePropertiesExpr = [];
                this.collectionOfRecords = [];
                this.collectionTemplate = "action $NAME_collection() returns(coll: Collection[ * $ENTRY]) { " + "$coll := records→$NAME→create_collection; " + "foreach e in records→$NAME where true do { $coll→add($e); } " + "}";
                remaining.forEach(function (dd) {
                    dd.direct.readGlobals.forEach(function (rg) { return _this.addGlobal(rg, "R"); });
                    dd.direct.writtenGlobals.forEach(function (wg) { return _this.addGlobal(wg, "W"); });
                    dd.direct.readFields.forEach(function (rf) {
                        var stmt = rf.forwardsToStmt();
                        _this.addField(stmt, "R");
                    });
                    dd.direct.readProps.forEach(function (rp, i) {
                        _this.addProperty(rp, dd.direct.readPropsWhat[i]);
                    });
                    dd.direct.writtenFields.forEach(function (wp) {
                        var stmt = wp.forwardsToStmt();
                        _this.addField(stmt, "W");
                    });
                    dd.direct.asIEnumerable.forEach(function (e) {
                        if (_this.declsToLibrary.indexOf(e) >= 0 && _this.collectionOfRecords.indexOf(e) < 0)
                            _this.collectionOfRecords.push(e);
                    });
                });
            }
            CreateAccessors.prototype.getRecordName = function (prop) {
                var rd = prop.parentKind.getRecord();
                if (rd && this.declsToLibrary.indexOf(rd) >= 0) {
                    return rd.getName() + " " + prop.getName();
                }
                return null;
            };
            CreateAccessors.prototype.getAccessorName = function (e, mode) {
                if (e.referencedData()) {
                    var glob = e.referencedData();
                    if (this.declsToLibrary.indexOf(e.referencedData()) >= 0) {
                        return (mode == "R" ? "" : "set ") + glob.getName();
                    }
                }
                else if (e.referencedRecordField()) {
                    var field = e.referencedRecordField();
                    var recordDef = field.def();
                    if (this.declsToLibrary.indexOf(recordDef) >= 0) {
                        return (mode == "R" ? "" : "set ") + field.getName();
                    }
                }
                else if (e.calledProp()) {
                    var c = e;
                    if (e.calledProp() instanceof AST.RecordDef) {
                        var rd2 = c.prop();
                        if (this.declsToLibrary.indexOf(rd2) >= 0)
                            return rd2.getName() + (mode == "E" ? " collection" : "");
                    }
                    else {
                        return this.getRecordName(c.prop());
                    }
                }
                return null;
            };
            CreateAccessors.prototype.getName = function (name, mode) {
                return (mode == "W" ? "set " : "") + name;
            };
            CreateAccessors.prototype.makeActionFromGlobOrField = function (thing, glob, field, mode) {
                var writer = new AST.TokenWriter();
                writer.keyword("action").id(this.getName(glob ? glob.getName() : field.getName(), mode));
                writer.op("(");
                if (!glob) {
                    writer.id("r").op(":").kind(this.theApp, field.def().entryKind);
                    if (mode == "W")
                        writer.op(",");
                }
                if (mode == "W") {
                    writer.id("val").op(":").kind(this.theApp, glob ? glob.getKind() : field.dataKind);
                }
                writer.op(")");
                if (mode == "R") {
                    writer.keyword("returns").op("(").id("val").op(":").kind(this.theApp, glob ? glob.getKind() : field.dataKind).op(")");
                }
                writer.op("{");
                if (mode == "R") {
                    writer.id("val").op(":=");
                }
                if (glob) {
                    writer.id(thing);
                }
                else {
                    writer.id("r");
                }
                writer.op("→").id(glob ? glob.getName() : field.getName());
                if (mode == "W") {
                    writer.op(":=").id("val");
                }
                writer.op("}");
                return AST.Parser.parseDecl(writer.finalize());
            };
            CreateAccessors.prototype.makeActionFromProperty = function (prop, expr) {
                var record = prop.parentKind.getRecord();
                var writer = new AST.TokenWriter();
                writer.keyword("action");
                var name = this.getRecordName(prop);
                if (name == null)
                    name = prop.getName();
                writer.id(name).op("(");
                var parms = prop.getParameters();
                var first = true;
                if (expr.getKind() instanceof AST.RecordEntryKind) {
                    writer.id("r").op(":").id(record.entryKind.getName());
                    first = false;
                }
                var i = 1;
                while (i < parms.length) {
                    if (!first)
                        writer.op(",");
                    var p = parms[i];
                    writer.id(p.getName()).op(":").kind(this.theApp, p.getKind());
                    i++;
                }
                writer.op(")");
                var res = prop.getResult();
                if (res) {
                    writer.keyword("returns").op("(");
                    writer.id("res").op(":").kind(this.theApp, res.getKind());
                    writer.op(")");
                }
                writer.op("{");
                if (res) {
                    writer.id("res").op(":=");
                }
                if (expr.getKind() instanceof AST.RecordEntryKind) {
                    writer.id("r");
                }
                else {
                    writer.id(record.thingSetKindName()).op("→").id(record.getName());
                }
                writer.op("→").id(prop.getName());
                i = 1;
                if (i < parms.length && parms.length > 0) {
                    writer.op("(");
                    var first = true;
                    while (i < parms.length) {
                        if (!first)
                            writer.op(",");
                        writer.id(parms[i].getName());
                        i++;
                        first = false;
                    }
                    writer.op(")");
                }
                writer.op("}");
                return AST.Parser.parseDecl(writer.finalize());
            };
            CreateAccessors.prototype.makeCollectionAccessor = function (rd) {
                var text = this.collectionTemplate;
                text = text.replace(/\$NAME/g, AST.Lexer.quoteId(rd.getName())).replace(/\$ENTRY/g, AST.Lexer.quoteId(rd.entryKind.getName()));
                return AST.Parser.parseDecl(text);
            };
            CreateAccessors.prototype.getAccessorActions = function () {
                var _this = this;
                var actions = [];
                for (var i = 0; i < this.rewriteGlobals.length; i++) {
                    for (var j = 0; j < this.globalModes[i].length; j++) {
                        actions.push(this.makeActionFromGlobOrField(this.globalThings[i], this.rewriteGlobals[i], null, this.globalModes[i][j]));
                    }
                }
                for (var i = 0; i < this.rewriteFields.length; i++) {
                    for (var j = 0; j < this.fieldModes[i].length; j++) {
                        actions.push(this.makeActionFromGlobOrField(null, null, this.rewriteFields[i], this.fieldModes[i][j]));
                    }
                }
                this.rewriteProperties.forEach(function (p, i) { return actions.push(_this.makeActionFromProperty(p, _this.rewritePropertiesExpr[i])); });
                this.collectionOfRecords.forEach(function (r) { return actions.push(_this.makeCollectionAccessor(r)); });
                return actions;
            };
            CreateAccessors.prototype.addField = function (field, mode) {
                var recordDef = field.def();
                if (this.declsToLibrary.indexOf(recordDef) >= 0) {
                    var index = this.rewriteFields.indexOf(field);
                    if (index < 0) {
                        this.rewriteFields.push(field);
                        this.fieldModes.push(mode);
                    }
                    else {
                        if (this.fieldModes[index].indexOf(mode) < 0) {
                            this.fieldModes[index] += mode;
                        }
                    }
                }
            };
            CreateAccessors.prototype.addGlobal = function (decl, mode) {
                if (this.declsToLibrary.indexOf(decl) >= 0 && decl instanceof AST.GlobalDef) {
                    var glob = decl;
                    var index = this.rewriteGlobals.indexOf(glob);
                    if (index < 0) {
                        this.rewriteGlobals.push(glob);
                        this.globalModes.push(mode);
                        this.globalThings.push(glob.thingSetKindName());
                    }
                    else {
                        if (this.globalModes[index].indexOf(mode) < 0) {
                            this.globalModes[index] += mode;
                        }
                    }
                }
            };
            CreateAccessors.prototype.addProperty = function (p, e) {
                var rd = p.parentKind.getRecord();
                if (rd && this.declsToLibrary.indexOf(rd) >= 0 && this.rewriteProperties.indexOf(p) < 0) {
                    this.rewriteProperties.push(p);
                    this.rewritePropertiesExpr.push(e);
                }
            };
            return CreateAccessors;
        })();
        var RewriteKind = (function () {
            function RewriteKind(targetLibrary, declsToMove, replaceTarget) {
                this.targetLibrary = targetLibrary;
                this.declsToMove = declsToMove;
                this.replaceTarget = replaceTarget;
            }
            RewriteKind.prototype.rewriteKind = function (k) {
                var _this = this;
                if (k.getRecord()) {
                    var rec = k.getRecord();
                    if (this.declsToMove.indexOf(rec) >= 0) {
                        return this.targetLibrary.getAbstractKind(k.getName());
                    }
                }
                else if (k instanceof TDev.UserActionKind) {
                    var act = k.userAction;
                    if (this.declsToMove.indexOf(act) >= 0) {
                    }
                    else {
                        act.getParameters().forEach(function (p) {
                            p._kind = _this.rewriteKind(p.getKind());
                        });
                    }
                }
                else if (k instanceof AST.LibraryRefAbstractKind) {
                    var absKind = k;
                    var lib = absKind.parentLibrary();
                    if (this.replaceTarget && lib == this.targetLibrary) {
                        return new TDev.UnresolvedKind(absKind.getName());
                    }
                }
                else if (k instanceof TDev.ParametricKind) {
                    var pk = k;
                    pk.parameters.forEach(function (p, i) { return pk.parameters[i] = _this.rewriteKind(pk.parameters[i]); });
                }
                else if (k instanceof TDev.ActionKind) {
                    var params = k.getInParameters().concat(k.getOutParameters());
                    params.forEach(function (p) {
                        p._kind = _this.rewriteKind(p.getKind());
                    });
                }
                return k;
            };
            return RewriteKind;
        })();
        var RemoveLibraryReference = (function (_super) {
            __extends(RemoveLibraryReference, _super);
            function RemoveLibraryReference(targetLibrary) {
                _super.call(this);
                this.targetLibrary = targetLibrary;
                this.rewriteKind = new RewriteKind(this.targetLibrary, [], true);
            }
            RemoveLibraryReference.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            RemoveLibraryReference.prototype.visitExprHolder = function (n) {
                this.lastExprHolder = n;
                if (n.parsed)
                    this.dispatch(n.parsed);
                return null;
            };
            RemoveLibraryReference.prototype.visitAction = function (n) {
                var _this = this;
                _super.prototype.visitAction.call(this, n);
                n.getInParameters().concat(n.getOutParameters()).forEach(function (p) {
                    p.local.setKind(_this.rewriteKind.rewriteKind(p.local.getKind()));
                });
            };
            RemoveLibraryReference.prototype.visitGlobalDef = function (n) {
                n.setKind(this.rewriteKind.rewriteKind(n.getKind()));
            };
            RemoveLibraryReference.prototype.visitRecordDef = function (n) {
                var _this = this;
                n.getFields().forEach(function (f) {
                    f.dataKind = _this.rewriteKind.rewriteKind(f.dataKind);
                });
            };
            RemoveLibraryReference.prototype.visitCall = function (n) {
                var _this = this;
                n.args.forEach(function (e) {
                    _this.dispatch(e);
                });
                var prop = n.prop();
                var thingref = n.args[0];
                if (prop && prop.forwardsTo() instanceof AST.LibraryRefAction) {
                    var lra = prop.forwardsTo();
                    if (lra.parentLibrary() == this.targetLibrary) {
                        var subcall = n.args[0];
                        var tokens = this.lastExprHolder.tokens;
                        var leftmost = getLeftmost(n.args[0]);
                        var leftIdx = tokens.indexOf(leftmost);
                        var rightIdx = tokens.indexOf(subcall.propRef);
                        if (!(lra instanceof AST.LibExtensionAction) && leftmost instanceof AST.ThingRef) {
                            var writer = new AST.TokenWriter();
                            writer.keyword("code");
                            var newExprHolder = AST.Parser.parseExprHolder(writer.finalize());
                            tokens.spliceArr(leftIdx, rightIdx - leftIdx + 1, newExprHolder.tokens);
                        }
                    }
                }
            };
            return RemoveLibraryReference;
        })(AST.NodeVisitor);
        var RewriteApp = (function (_super) {
            __extends(RewriteApp, _super);
            function RewriteApp(targetLibrary, libActions, acc) {
                _super.call(this);
                this.targetLibrary = targetLibrary;
                this.libActions = libActions;
                this.acc = acc;
                this.lastExprHolder = null;
                this.mode = "";
                this.rewriteKind = new RewriteKind(this.targetLibrary, this.acc.declsToLibrary, false);
            }
            RewriteApp.prototype.visitExprHolder = function (n) {
                this.lastExprHolder = n;
                this.mode = "R";
                if (n.parsed)
                    this.dispatch(n.parsed);
                return null;
            };
            RewriteApp.prototype.visitForeach = function (n) {
                var _this = this;
                if (n.collection.parsed) {
                    this.mode = "E";
                    this.lastExprHolder = n.collection;
                    this.dispatch(n.collection.parsed);
                }
                [n.conditions, n.body].forEach(function (c) { return c.accept(_this); });
            };
            RewriteApp.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            RewriteApp.prototype.visitAction = function (n) {
                var _this = this;
                if (this.libActions.indexOf(n) < 0) {
                    _super.prototype.visitAction.call(this, n);
                    n.getInParameters().concat(n.getOutParameters()).forEach(function (p) { return _this.rewriteActionParameter(p); });
                }
            };
            RewriteApp.prototype.rewriteActionParameter = function (n) {
                n.local.setKind(this.rewriteKind.rewriteKind(n.local.getKind()));
            };
            RewriteApp.prototype.visitGlobalDef = function (n) {
                if (this.acc.declsToLibrary.indexOf(n) < 0) {
                    n.setKind(this.rewriteKind.rewriteKind(n.getKind()));
                }
            };
            RewriteApp.prototype.visitRecordDef = function (n) {
                var _this = this;
                if (this.acc.declsToLibrary.indexOf(n) < 0) {
                    n.getFields().forEach(function (f) {
                        f.dataKind = _this.rewriteKind.rewriteKind(f.dataKind);
                    });
                }
            };
            RewriteApp.prototype.rewriteThingRef = function (t) {
                var tokens = this.lastExprHolder.tokens;
                var idx = tokens.indexOf(t);
                var writer = new AST.TokenWriter();
                this.targetLibrary.writeRef(writer);
                var newExprHolder = AST.Parser.parseExprHolder(writer.finalize());
                this.lastExprHolder.tokens.spliceArr(idx, 1, newExprHolder.tokens);
            };
            RewriteApp.prototype.visitCall = function (n) {
                var _this = this;
                var prop = n.prop();
                if (!prop)
                    return;
                if (prop == AST.api.core.AssignmentProp) {
                    var lhs = n.args[0].flatten(AST.api.core.TupleProp);
                    lhs.forEach((function (e) {
                        _this.mode = "W";
                        _this.dispatch(e);
                    }));
                    this.mode = "R";
                    var rhs = n.args[1];
                    this.dispatch(rhs);
                    if (lhs.length == 1) {
                        var oneLHS = lhs[0];
                        var accessor = this.acc.getAccessorName(oneLHS, "W");
                        if (accessor != null) {
                            var writer = new AST.TokenWriter();
                            var tokens = this.lastExprHolder.tokens;
                            if (oneLHS.referencedRecordField()) {
                                var oneLHStok = tokens.filter(function (t) { return t == oneLHS.propRef; })[0];
                                var oneLHSidx = tokens.indexOf(oneLHStok);
                                tokens.slice(0, oneLHSidx).forEach(function (t) { return t.writeTo(writer); });
                            }
                            else {
                                this.targetLibrary.writeRef(writer);
                            }
                            writer.op("→").id(accessor).op("(");
                            var assign = tokens.filter(function (t) { return t.getOperator() == ":="; })[0];
                            var idx = tokens.indexOf(assign);
                            tokens.slice(idx + 1, tokens.length).forEach(function (t) { return t.writeTo(writer); });
                            writer.op(")");
                            var newExprHolder = AST.Parser.parseExprHolder(writer.finalize());
                            this.lastExprHolder.tokens = newExprHolder.tokens;
                        }
                    }
                }
                else if (n.referencedData() || n.referencedRecordField()) {
                    var mode = this.mode;
                    this.mode = "R";
                    n.args.forEach(function (e) { return _this.dispatch(e); });
                    var accessor = this.acc.getAccessorName(n, mode);
                    if (accessor != null && mode != "W") {
                        n.propRef.data = accessor;
                        if (n.referencedData()) {
                            this.rewriteThingRef(n.args[0]);
                        }
                        else {
                            n.propRef.prop = null;
                        }
                    }
                }
                else if (prop instanceof AST.RecordDef) {
                    if (this.mode == "E") {
                        var accessor = this.acc.getAccessorName(n, "E");
                        if (accessor != null) {
                            var tokens = this.lastExprHolder.tokens;
                            var leftmost = getLeftmost(n);
                            var leftIdx = tokens.indexOf(leftmost);
                            var rightIdx = tokens.indexOf(n.propRef);
                            var writer = new AST.TokenWriter();
                            this.targetLibrary.writeRef(writer).op("→").id(accessor);
                            var newExprHolder = AST.Parser.parseExprHolder(writer.finalize());
                            tokens.spliceArr(leftIdx, rightIdx - leftIdx + 1, newExprHolder.tokens);
                        }
                    }
                }
                else if (prop && (prop.forwardsTo() instanceof AST.Action || prop instanceof AST.ExtensionProperty)) {
                    this.mode = "R";
                    n.args.forEach(function (e) { return _this.dispatch(e); });
                    var callee = prop.forwardsTo();
                    if (callee && this.libActions.indexOf(callee) >= 0) {
                        this.rewriteThingRef(n.args[0]);
                    }
                    else {
                        callee = prop.shortcutTo;
                        if (this.libActions.indexOf(callee) >= 0) {
                        }
                    }
                }
                else {
                    n.args.forEach(function (e) {
                        _this.mode = "R";
                        _this.dispatch(e);
                    });
                    var accessor = this.acc.getAccessorName(n, "");
                    if (accessor != null && prop) {
                        n.propRef.data = accessor;
                        n.propRef.prop = null;
                        var kind = prop.parentKind;
                        if (kind instanceof AST.RecordDefKind) {
                            var rd = kind.getRecord();
                            if (rd) {
                                var subcall = n.args[0];
                                var leftmost = getLeftmost(subcall);
                                if (leftmost instanceof AST.ThingRef) {
                                    var tokens = this.lastExprHolder.tokens;
                                    var leftIdx = tokens.indexOf(leftmost);
                                    var rightIdx = tokens.indexOf(subcall.propRef);
                                    var writer = new AST.TokenWriter();
                                    this.targetLibrary.writeRef(writer);
                                    var newExprHolder = AST.Parser.parseExprHolder(writer.finalize());
                                    tokens.spliceArr(leftIdx, rightIdx - leftIdx + 1, newExprHolder.tokens);
                                }
                                else {
                                }
                            }
                        }
                        else {
                        }
                    }
                }
                return null;
            };
            RewriteApp.prototype.performRewrite = function (n) {
                this.dispatch(n);
            };
            return RewriteApp;
        })(AST.NodeVisitor);
        var UserDefinedTypeFinder = (function (_super) {
            __extends(UserDefinedTypeFinder, _super);
            function UserDefinedTypeFinder() {
                _super.apply(this, arguments);
                this.recurse = false;
                this.decls = [];
            }
            UserDefinedTypeFinder.prototype.visitGlobalDef = function (n) {
                this.visitKind(n.getKind(), this.recurse);
            };
            UserDefinedTypeFinder.prototype.visitLocalDef = function (n) {
                this.visitKind(n.getKind(), this.recurse);
            };
            UserDefinedTypeFinder.prototype.visitRecordDef = function (r) {
                var _this = this;
                if (this.decls.indexOf(r) < 0) {
                    this.decls.push(r);
                    if (this.recurse) {
                        r.values.fields().concat(r.keys.fields()).forEach(function (f) {
                            _this.visitRecordField(f);
                        });
                    }
                }
            };
            UserDefinedTypeFinder.prototype.visitRecordField = function (n) {
                this.visitKind(n.dataKind, this.recurse);
            };
            UserDefinedTypeFinder.prototype.visitKind = function (k, recurse) {
                var _this = this;
                this.recurse = recurse;
                if (k.isUserDefined()) {
                    if (k.getRecord())
                        this.visitRecordDef(k.getRecord());
                    else if (k instanceof TDev.UserActionKind) {
                        var act = k.userAction;
                        if (this.decls.indexOf(act) < 0) {
                            this.decls.push(act);
                            if (recurse) {
                                act.getParameters().forEach(function (p) { return _this.visitKind(p.getKind(), recurse); });
                            }
                        }
                    }
                    else if (k instanceof AST.LibraryRefAbstractKind) {
                        var lib = k.parentLibrary();
                        if (this.decls.indexOf(lib) < 0) {
                            this.decls.push(lib);
                        }
                    }
                    else if (k instanceof TDev.ParametricKind) {
                        if (recurse) {
                            var pk = k;
                            var i = 0;
                            while (i < pk.getParameterCount()) {
                                this.visitKind(pk.getParameter(i), recurse);
                                i++;
                            }
                        }
                    }
                    else if (k instanceof TDev.ActionKind) {
                        if (recurse) {
                            var params = k.getInParameters().concat(k.getInParameters());
                            params.forEach(function (p) { return _this.visitKind(p.getKind(), recurse); });
                        }
                    }
                    else {
                    }
                }
            };
            UserDefinedTypeFinder.prototype.traverse = function (d, recurse) {
                this.recurse = recurse;
                this.dispatch(d);
            };
            return UserDefinedTypeFinder;
        })(AST.NodeVisitor);
        var DeclAndDepsManager = (function () {
            function DeclAndDepsManager() {
                this.cache = [];
                this.last = null;
            }
            DeclAndDepsManager.prototype.resetCache = function () {
                this.cache = [];
                this.last = null;
            };
            DeclAndDepsManager.prototype.invalidate = function () {
                this.cache.forEach(function (dd) { return dd.reset(); });
            };
            DeclAndDepsManager.prototype.getFromCache = function (d) {
                if (this.last != null && this.last.decl == d) {
                    return this.last;
                }
                else {
                    var filter = this.cache.filter(function (dd) { return dd.decl == d; });
                    if (filter.length > 0) {
                        this.last = filter[0];
                        return this.last;
                    }
                    else
                        return null;
                }
            };
            DeclAndDepsManager.prototype.remove = function (dd) {
                this.last = null;
                var idx = this.cache.indexOf(dd);
                if (idx >= 0) {
                    this.cache.splice(idx);
                }
            };
            DeclAndDepsManager.prototype.getter = function (decl) {
                TDev.Util.assert(decl != null);
                var res = this.getFromCache(decl);
                if (res == null) {
                    res = new DeclAndDeps(this);
                    res.decl = decl;
                    this.cache.push(res);
                }
                return res;
            };
            DeclAndDepsManager.prototype.getAll = function () {
                return this.cache;
            };
            return DeclAndDepsManager;
        })();
        AST.DeclAndDepsManager = DeclAndDepsManager;
        var DeclAndDeps = (function () {
            function DeclAndDeps(m) {
                this.decl = null;
                this.direct = null;
                this.actions = null;
                this.otherDecls = [];
                this.accessedTypes = [];
                this.accessedGlobals = [];
                this.transitiveClosure = null;
                this.include = false;
                this.manager = m;
            }
            DeclAndDeps.prototype.reset = function () {
                this.actions = null;
                this.serialized = null;
                this.otherDecls = [];
                this.direct = null;
                this.accessedGlobals = [];
                this.accessedTypes = [];
                this.transitiveClosure = [];
            };
            DeclAndDeps.prototype.getActions = function () {
                this.fillDeclDependencies();
                return this.actions;
            };
            DeclAndDeps.prototype.getOthers = function () {
                this.fillDeclDependencies();
                return this.otherDecls;
            };
            DeclAndDeps.prototype.getAllDirectAccesses = function () {
                this.fillDeclDependencies();
                if (this.decl instanceof AST.Action)
                    return this.accessedTypes.concat(this.accessedGlobals).concat(this.getActions());
                else
                    return this.getOthers();
            };
            DeclAndDeps.prototype.getTransitiveClosure = function () {
                this.fillDeclDependencies();
                if (!this.transitiveClosure) {
                    this.transitiveClosure = [];
                    DeclAndDeps.computeClosure([this], [], this.transitiveClosure);
                }
                return this.transitiveClosure;
            };
            DeclAndDeps.prototype.setInclude = function (b) {
                this.include = b;
            };
            DeclAndDeps.prototype.getInclude = function () {
                return this.include;
            };
            DeclAndDeps.rateTargetAgainstDecls = function (pending, tgt) {
                tgt.numberDirectDeclsToMove = 0;
                tgt.getAllDirectAccesses().filter(function (dd) { return !(dd.decl instanceof AST.LibraryRef); }).forEach(function (t) {
                    if (pending.indexOf(t) >= 0)
                        tgt.numberDirectDeclsToMove++;
                });
            };
            DeclAndDeps.compareSize = function (d1, d2) {
                var len1 = d1.getTransitiveClosure().length;
                var len2 = d2.getTransitiveClosure().length;
                return len1 - len2;
            };
            DeclAndDeps.prototype.fillDeclDependencies = function () {
                var _this = this;
                if (this.actions != null)
                    return;
                var directDecls = [];
                function add(decl) {
                    if (directDecls.indexOf(decl) < 0)
                        directDecls.push(decl);
                }
                function processDeclDirect(decl) {
                    if (!(decl instanceof AST.LocalDef))
                        add(decl);
                    var finder = new UserDefinedTypeFinder();
                    finder.traverse(decl, false);
                    finder.decls.forEach(function (d) { return add(d); });
                }
                var finder = new DirectAccessFinder();
                finder.traverse(this.decl);
                this.direct = finder;
                finder.referencedLibraries.forEach(function (l) { return add(l); });
                if (this.decl instanceof AST.Action) {
                    this.actions = finder.calledActions.map(function (a) { return _this.manager.getter(a); });
                    finder.readGlobals.concat(finder.writtenGlobals).forEach(function (g) {
                        var ng = _this.manager.getter(g);
                        if (_this.accessedGlobals.indexOf(ng) < 0)
                            _this.accessedGlobals.push(ng);
                        processDeclDirect(g);
                    });
                    finder.inParams.concat(finder.outParams).forEach(processDeclDirect);
                    finder.readProps.concat(finder.readFields).concat(finder.writtenFields).forEach(function (p) {
                        var rd = p.parentKind.getRecord();
                        if (rd) {
                            var newOne = _this.manager.getter(rd);
                            if (_this.accessedTypes.indexOf(newOne) < 0)
                                _this.accessedTypes.push(newOne);
                        }
                    });
                }
                else {
                    this.actions = [];
                    finder.referencedRecords.forEach(processDeclDirect);
                }
                this.otherDecls = directDecls.map(function (a) { return _this.manager.getter(a); });
            };
            DeclAndDeps.computeClosure = function (roots, alreadyIn, newOnes) {
                var add = function (dd2) {
                    if (roots.indexOf(dd2) < 0 && alreadyIn.indexOf(dd2) < 0 && newOnes.indexOf(dd2) < 0) {
                        newOnes.push(dd2);
                        return true;
                    }
                    else {
                        return false;
                    }
                };
                var recurseNotAction = function (r) {
                    if (add(r)) {
                        var finder = new UserDefinedTypeFinder();
                        finder.traverse(r.decl, true);
                        finder.decls.forEach(function (d) { return add(r.manager.getter(d)); });
                    }
                };
                roots.forEach(function (dd) {
                    if (dd.decl instanceof AST.Action) {
                        var closure = new CallGraphClosure(dd);
                        closure.allActions.forEach(function (a) {
                            if (add(a))
                                a.getOthers().forEach(recurseNotAction);
                        });
                    }
                    else {
                        recurseNotAction(dd);
                    }
                    dd.getOthers().forEach(recurseNotAction);
                });
            };
            return DeclAndDeps;
        })();
        AST.DeclAndDeps = DeclAndDeps;
        var CallGraphClosure = (function () {
            function CallGraphClosure(action) {
                var _this = this;
                this.allActions = [];
                var wl = action.getActions().map(function (x) { return x; });
                while (wl.length > 0) {
                    var a = wl.pop();
                    this.allActions.push(a);
                    a.getActions().forEach(function (b) {
                        if (_this.allActions.indexOf(b) < 0 && wl.indexOf(b) < 0)
                            wl.push(b);
                    });
                }
            }
            return CallGraphClosure;
        })();
        function getLeftmost(e) {
            if (e instanceof AST.Call) {
                return getLeftmost(e.args[0]);
            }
            else {
                return e;
            }
        }
        var DirectAccessFinder = (function (_super) {
            __extends(DirectAccessFinder, _super);
            function DirectAccessFinder() {
                _super.apply(this, arguments);
                this.referencedLibraries = [];
                this.calledActions = [];
                this.inParams = [];
                this.outParams = [];
                this.readGlobals = [];
                this.writtenGlobals = [];
                this.readFields = [];
                this.writtenFields = [];
                this.readProps = [];
                this.readPropsWhat = [];
                this.referencedRecords = [];
                this.asIEnumerable = [];
                this.mode = "";
            }
            DirectAccessFinder.prototype.addDecl = function (l, lst) {
                if (lst.indexOf(l) < 0)
                    lst.push(l);
            };
            DirectAccessFinder.prototype.addField = function (l, lst) {
                if (lst.indexOf(l) < 0)
                    lst.push(l);
            };
            DirectAccessFinder.prototype.addProp = function (l, e) {
                if (this.readProps.indexOf(l) < 0) {
                    this.readProps.push(l);
                    this.readPropsWhat.push(e);
                }
            };
            DirectAccessFinder.prototype.getGlobal = function (e) {
                if (e instanceof AST.Call) {
                    var prop = e.prop();
                    if (prop instanceof AST.GlobalDef || prop instanceof AST.RecordDef)
                        return prop;
                }
                return null;
            };
            DirectAccessFinder.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
                return null;
            };
            DirectAccessFinder.prototype.visitAction = function (n) {
                var _this = this;
                n.getInParameters().forEach(function (p) { return _this.addDecl(p.local, _this.inParams); });
                n.getOutParameters().forEach(function (p) { return _this.addDecl(p.local, _this.outParams); });
                _super.prototype.visitAction.call(this, n);
            };
            DirectAccessFinder.prototype.visitGlobalDef = function (n) {
                var _this = this;
                var finder = new UserDefinedTypeFinder();
                finder.traverse(n, false);
                finder.decls.forEach(function (t) { return _this.addDecl(t, _this.referencedRecords); });
            };
            DirectAccessFinder.prototype.visitRecordDef = function (r) {
                var _this = this;
                var finder = new UserDefinedTypeFinder();
                r.values.fields().concat(r.keys.fields()).forEach(function (f) {
                    finder.traverse(f, false);
                });
                finder.decls.forEach(function (t) { return _this.addDecl(t, _this.referencedRecords); });
            };
            DirectAccessFinder.prototype.visitForeach = function (n) {
                var _this = this;
                if (n.collection.parsed) {
                    this.mode = "E";
                    this.dispatch(n.collection.parsed);
                }
                [n.conditions, n.body].forEach(function (c) { return c.accept(_this); });
            };
            DirectAccessFinder.prototype.visitCall = function (n) {
                var _this = this;
                var prop = n.prop();
                if (prop == AST.api.core.AssignmentProp) {
                    n.args[0].flatten(AST.api.core.TupleProp).forEach(function (e) {
                        _this.mode = "W";
                        var g = _this.getGlobal(e);
                        if (g && _this.writtenGlobals.indexOf(g) < 0)
                            _this.addDecl(g, _this.writtenGlobals);
                        else
                            _this.dispatch(e);
                    });
                    this.mode = "R";
                    this.dispatch(n.args[1]);
                }
                else if (n.referencedRecordField() || n.referencedData()) {
                    if (n.referencedRecordField()) {
                        this.addField(n.referencedRecordField().asProperty(), this.mode == "R" ? this.readFields : this.writtenFields);
                    }
                    else {
                        this.addDecl(n.referencedData(), this.mode == "R" ? this.readGlobals : this.writtenGlobals);
                    }
                }
                else if (prop instanceof AST.RecordDef) {
                    if (this.mode == "E") {
                        this.addDecl(prop, this.asIEnumerable);
                    }
                    this.addDecl(prop, this.readGlobals);
                }
                else if (prop.forwardsTo() instanceof AST.Action || prop instanceof AST.ExtensionProperty) {
                    var act = prop.forwardsTo() ? prop.forwardsTo() : prop.shortcutTo;
                    var lib = act.parentLibrary();
                    if (lib && !lib.isThis()) {
                        if (this.referencedLibraries.indexOf(lib) < 0)
                            this.referencedLibraries.push(lib);
                    }
                    else {
                        if (this.calledActions.indexOf(act) < 0)
                            this.calledActions.push(act);
                    }
                }
                else if (prop.parentKind.getRecord()) {
                    this.addProp(prop, getLeftmost(n));
                }
                else if (prop.parentKind instanceof TDev.UserActionKind) {
                    var act = (prop.parentKind).userAction;
                    if (this.calledActions.indexOf(act) < 0)
                        this.calledActions.push(act);
                }
                if (prop != AST.api.core.AssignmentProp) {
                    n.args.forEach(function (e) {
                        _this.mode = "R";
                        _this.dispatch(e);
                    });
                }
            };
            DirectAccessFinder.prototype.visitExprHolder = function (n) {
                if (n.parsed) {
                    this.mode = "R";
                    this.dispatch(n.parsed);
                }
                return null;
            };
            DirectAccessFinder.prototype.traverse = function (node) {
                this.dispatch(node);
            };
            return DirectAccessFinder;
        })(AST.NodeVisitor);
        AST.DirectAccessFinder = DirectAccessFinder;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var crashOnInvalid = false;
        var blockChaining = false;
        var StmtIdCollector = (function (_super) {
            __extends(StmtIdCollector, _super);
            function StmtIdCollector(ids) {
                if (ids === void 0) { ids = []; }
                _super.call(this);
                this.ids = ids;
            }
            StmtIdCollector.prototype.visitAstNode = function (node) {
                return this.visitChildren(node);
            };
            StmtIdCollector.prototype.visitDecl = function (decl) {
                return this.visitChildren(decl);
            };
            StmtIdCollector.prototype.visitStmt = function (stmt) {
                this.ids.push(stmt.stableId);
                _super.prototype.visitStmt.call(this, stmt);
            };
            StmtIdCollector.collect = function (script) {
                var self = new StmtIdCollector();
                self.dispatch(script);
                return self.ids;
            };
            return StmtIdCollector;
        })(AST.NodeVisitor);
        AST.StmtIdCollector = StmtIdCollector;
        var QuotingCtx = (function () {
            function QuotingCtx() {
                this.mapping = {};
                this.nameMapping = {};
                this.usedNames = {};
                this.reservedNames = {};
            }
            QuotingCtx.prototype.unUnicode = function (s) {
                s = s.replace(/[^a-zA-Z0-9]+/g, "_");
                if (s == "" || /^[0-9]/.test(s))
                    s = "_" + s;
                return s;
            };
            QuotingCtx.prototype.isUsed = function (s) {
                return this.usedNames.hasOwnProperty(s) || this.reservedNames.hasOwnProperty(s);
            };
            QuotingCtx.prototype.snapshotUsed = function () {
                var r = {};
                Object.keys(this.reservedNames).forEach(function (k) { return r[k] = 1; });
                Object.keys(this.usedNames).forEach(function (k) { return r[k] = 1; });
                return r;
            };
            QuotingCtx.prototype.quote = function (s, id) {
                var si = s + ":" + id;
                var name = s;
                if (this.mapping.hasOwnProperty(si)) {
                    return this.mapping[si];
                }
                s = this.unUnicode(s);
                if (this.isUsed(s)) {
                    var n = 1;
                    while (this.isUsed(s + n.toString())) {
                        n++;
                    }
                    s = s + n.toString();
                }
                this.usedNames[s] = 1;
                this.mapping[si] = s;
                this.nameMapping[name] = s;
                return s;
            };
            QuotingCtx.prototype.getNameMapping = function () {
                return this.nameMapping;
            };
            return QuotingCtx;
        })();
        AST.QuotingCtx = QuotingCtx;
        (function (JsNodeCategory) {
            JsNodeCategory[JsNodeCategory["Bad"] = 0] = "Bad";
            JsNodeCategory[JsNodeCategory["ExprStmt"] = 1] = "ExprStmt";
            JsNodeCategory[JsNodeCategory["Goto"] = 2] = "Goto";
            JsNodeCategory[JsNodeCategory["If"] = 3] = "If";
            JsNodeCategory[JsNodeCategory["Label"] = 4] = "Label";
            JsNodeCategory[JsNodeCategory["TmpDef"] = 5] = "TmpDef";
            JsNodeCategory[JsNodeCategory["TmpRef"] = 6] = "TmpRef";
            JsNodeCategory[JsNodeCategory["LabelRef"] = 7] = "LabelRef";
            JsNodeCategory[JsNodeCategory["Call"] = 8] = "Call";
            JsNodeCategory[JsNodeCategory["Infix"] = 9] = "Infix";
            JsNodeCategory[JsNodeCategory["Term"] = 10] = "Term";
            JsNodeCategory[JsNodeCategory["DeleteStmt"] = 11] = "DeleteStmt";
            JsNodeCategory[JsNodeCategory["Lambda"] = 12] = "Lambda";
        })(AST.JsNodeCategory || (AST.JsNodeCategory = {}));
        var JsNodeCategory = AST.JsNodeCategory;
        var JsNode = (function () {
            function JsNode() {
            }
            JsNode.prototype.category = function () {
                return 0 /* Bad */;
            };
            JsNode.prototype.toString = function () {
                return "<???>";
            };
            JsNode.prototype.isUsedLabel = function () {
                return false;
            };
            JsNode.prototype.injectEndIfJumps = function () {
            };
            JsNode.prototype.dump = function (wr) {
                wr(this.toString());
            };
            JsNode.prototype.forEachExpr = function (f) {
                TDev.Util.die();
            };
            return JsNode;
        })();
        AST.JsNode = JsNode;
        var JsStmt = (function (_super) {
            __extends(JsStmt, _super);
            function JsStmt() {
                _super.call(this);
            }
            return JsStmt;
        })(JsNode);
        AST.JsStmt = JsStmt;
        var JsExpr = (function (_super) {
            __extends(JsExpr, _super);
            function JsExpr() {
                _super.call(this);
                this._alwaysValid = false;
            }
            JsExpr.prototype.alwaysValid = function () {
                return this._alwaysValid;
            };
            JsExpr.prototype.gets = function (v) {
                return new JsExprStmt(new JsInfix(this, "=", v));
            };
            JsExpr.prototype.makeValid = function () {
                this._alwaysValid = true;
                return this;
            };
            return JsExpr;
        })(JsNode);
        AST.JsExpr = JsExpr;
        var JsCall = (function (_super) {
            __extends(JsCall, _super);
            function JsCall(recv, method, args) {
                _super.call(this);
                this.recv = recv;
                this.method = method;
                this.args = args;
            }
            JsCall.prototype.category = function () {
                return 8 /* Call */;
            };
            JsCall.prototype.forEachExpr = function (f) {
                f(this);
                if (this.recv != null)
                    this.recv.forEachExpr(f);
                if (this.args)
                    this.args.forEach(function (a) { return a.forEachExpr(f); });
            };
            JsCall.prototype.toString = function () {
                var isAlwaysValid = function (e) {
                    if (crashOnInvalid)
                        return true;
                    if (e.alwaysValid())
                        return true;
                    if (e instanceof JsTerm) {
                        var t = e;
                        if (t.code == "s")
                            return true;
                    }
                    return false;
                };
                var meth = this.method;
                var args2 = this.args;
                if (meth == "ok") {
                    args2 = args2.filter(function (e) { return !isAlwaysValid(e); });
                    if (args2.length == 0)
                        return "true";
                    meth += args2.length;
                    args2.unshift(new JsTerm("s"));
                }
                var a = meth;
                if (args2)
                    a += "(" + args2.map(function (e) { return e.toString(); }).join(", ") + ")";
                if (this.recv == null)
                    return a;
                else {
                    var r = this.recv.toString();
                    if (meth == "[")
                        return r + a + "]";
                    else if (meth == "")
                        return r + a;
                    else
                        return r + "." + a;
                }
            };
            JsCall.direct = function (meth, args) {
                return new JsCall(null, meth, args);
            };
            JsCall.directInst = function (recv, meth, args) {
                return new JsCall(recv, meth, args);
            };
            JsCall.okAnd = function (args, andThen) {
                return new JsInfix(JsCall.direct("ok", args), "&&", andThen);
            };
            JsCall.mk = function (recv, method, args) {
                return JsCall.okAnd(recv == null ? args : [recv].concat(args), new JsCall(recv, method, args));
            };
            return JsCall;
        })(JsExpr);
        AST.JsCall = JsCall;
        var JsInfix = (function (_super) {
            __extends(JsInfix, _super);
            function JsInfix(left, op, right) {
                _super.call(this);
                this.left = left;
                this.op = op;
                this.right = right;
            }
            JsInfix.prototype.category = function () {
                return 9 /* Infix */;
            };
            JsInfix.prototype.forEachExpr = function (f) {
                f(this);
                if (this.left != null)
                    this.left.forEachExpr(f);
                if (this.right != null)
                    this.right.forEachExpr(f);
            };
            JsInfix.prototype.toString = function () {
                if (this.left == null)
                    return "(" + this.op + this.right.toString() + ")";
                var ll = this.left.toString();
                if (this.right == null)
                    return "(" + ll + this.op + ")";
                else {
                    var rr = this.right.toString();
                    if (this.op == "&&" && ll == "true")
                        return rr;
                    return "(" + ll + " " + this.op + " " + rr + ")";
                }
            };
            return JsInfix;
        })(JsExpr);
        AST.JsInfix = JsInfix;
        var JsTerm = (function (_super) {
            __extends(JsTerm, _super);
            function JsTerm(code) {
                _super.call(this);
                this.code = code;
            }
            JsTerm.prototype.category = function () {
                return 10 /* Term */;
            };
            JsTerm.prototype.forEachExpr = function (f) {
                f(this);
            };
            JsTerm.prototype.toString = function () {
                return this.code;
            };
            return JsTerm;
        })(JsExpr);
        AST.JsTerm = JsTerm;
        var JsLiteral = (function (_super) {
            __extends(JsLiteral, _super);
            function JsLiteral(c) {
                _super.call(this, c);
            }
            JsLiteral.prototype.alwaysValid = function () {
                return true;
            };
            return JsLiteral;
        })(JsTerm);
        AST.JsLiteral = JsLiteral;
        var JsTmpRef = (function (_super) {
            __extends(JsTmpRef, _super);
            function JsTmpRef(tmp) {
                _super.call(this);
                this.tmp = tmp;
            }
            JsTmpRef.prototype.category = function () {
                return 6 /* TmpRef */;
            };
            JsTmpRef.prototype.forEachExpr = function (f) {
                f(this);
            };
            JsTmpRef.prototype.toString = function () {
                return this.tmp.getRef();
            };
            return JsTmpRef;
        })(JsExpr);
        AST.JsTmpRef = JsTmpRef;
        var JsLabelRef = (function (_super) {
            __extends(JsLabelRef, _super);
            function JsLabelRef(label) {
                _super.call(this);
                this.label = label;
            }
            JsLabelRef.prototype.category = function () {
                return 7 /* LabelRef */;
            };
            JsLabelRef.prototype.forEachExpr = function (f) {
                f(this);
            };
            JsLabelRef.prototype.toString = function () {
                return this.label.id;
            };
            return JsLabelRef;
        })(JsExpr);
        AST.JsLabelRef = JsLabelRef;
        var JsTmpDef = (function (_super) {
            __extends(JsTmpDef, _super);
            function JsTmpDef(stem, initial) {
                _super.call(this);
                this.stem = stem;
                this.initial = initial;
                this.isLocal = true;
            }
            JsTmpDef.prototype.category = function () {
                return 5 /* TmpDef */;
            };
            JsTmpDef.prototype.forEachExpr = function (f) {
                this.initial.forEachExpr(f);
            };
            JsTmpDef.prototype.getName = function () {
                return "t_" + this.stem + "_" + this.id.toString();
            };
            JsTmpDef.prototype.getRef = function () {
                return this.isLocal ? this.getName() : "s." + this.getName();
            };
            JsTmpDef.prototype.toString = function () {
                if (this.isLocal)
                    return "var " + this.getName() + " = " + this.initial.toString() + ";";
                else
                    return this.getRef() + " = " + this.initial.toString() + ";";
            };
            return JsTmpDef;
        })(JsStmt);
        AST.JsTmpDef = JsTmpDef;
        var JsExprStmt = (function (_super) {
            __extends(JsExprStmt, _super);
            function JsExprStmt(code) {
                _super.call(this);
                this.code = code;
                TDev.Util.assert(!!code);
            }
            JsExprStmt.prototype.category = function () {
                return 1 /* ExprStmt */;
            };
            JsExprStmt.prototype.toString = function () {
                return this.code.toString() + ";";
            };
            JsExprStmt.prototype.forEachExpr = function (f) {
                this.code.forEachExpr(f);
            };
            return JsExprStmt;
        })(JsStmt);
        AST.JsExprStmt = JsExprStmt;
        var JsDeleteStmt = (function (_super) {
            __extends(JsDeleteStmt, _super);
            function JsDeleteStmt(target) {
                _super.call(this);
                this.target = target;
            }
            JsDeleteStmt.prototype.category = function () {
                return 11 /* DeleteStmt */;
            };
            JsDeleteStmt.prototype.toString = function () {
                return "delete " + this.target.toString() + ";";
            };
            JsDeleteStmt.prototype.forEachExpr = function (f) {
                this.target.forEachExpr(f);
            };
            return JsDeleteStmt;
        })(JsStmt);
        AST.JsDeleteStmt = JsDeleteStmt;
        var JsLambda = (function (_super) {
            __extends(JsLambda, _super);
            function JsLambda(argCount, body) {
                _super.call(this);
                this.argCount = argCount;
                this.body = body;
            }
            JsLambda.prototype.alwaysValid = function () {
                return true;
            };
            JsLambda.prototype.category = function () {
                return 12 /* Lambda */;
            };
            JsLambda.prototype.toString = function () {
                return ("function(" + TDev.Util.range(0, this.argCount).map(function (i) { return "la" + i; }).join(", ") + ") { " + "return " + this.body.toString() + " }");
            };
            JsLambda.prototype.forEachExpr = function (f) {
                this.body.forEachExpr(f);
            };
            return JsLambda;
        })(JsExpr);
        AST.JsLambda = JsLambda;
        var JsGoto = (function (_super) {
            __extends(JsGoto, _super);
            function JsGoto(target, canChain) {
                if (canChain === void 0) { canChain = blockChaining; }
                _super.call(this);
                this.target = target;
                this.canChain = canChain;
                this.jumpsToOptimizedLoop = false;
            }
            JsGoto.prototype.toString = function () {
                if (!this.canChain)
                    return "return " + this.target.toString() + ";";
                if (!this.jumpsToOptimizedLoop)
                    return "if (callstackcurdepth++ < 50) return " + this.target.toString() + "(s); else { callstackcurdepth = 0; return " + this.target.toString() + ";}";
                return "if (callstackcurdepth++ >= 500) { callstackcurdepth = 0; return " + this.target.toString() + ";}";
            };
            JsGoto.prototype.category = function () {
                return 2 /* Goto */;
            };
            JsGoto.prototype.forEachExpr = function (f) {
                this.target.forEachExpr(f);
            };
            JsGoto.simple = function (t, canChain) {
                if (canChain === void 0) { canChain = blockChaining; }
                return new JsGoto(new JsLabelRef(t), canChain);
            };
            JsGoto.prototype.isSimple = function (t) {
                return this.target instanceof JsLabelRef && this.target.label == t;
            };
            return JsGoto;
        })(JsStmt);
        AST.JsGoto = JsGoto;
        var JsIf = (function (_super) {
            __extends(JsIf, _super);
            function JsIf(finalLabel) {
                _super.call(this);
                this.finalLabel = finalLabel;
                this.isWhile = false;
            }
            JsIf.prototype.category = function () {
                return 3 /* If */;
            };
            JsIf.prototype.injectEndIfJumps = function () {
                var _this = this;
                var inject = function (lst) {
                    var wasJmp = false;
                    var hadLbl = false;
                    for (var i = 0; i < lst.length; ++i) {
                        wasJmp = lst[i].category() == 2 /* Goto */;
                        if (wasJmp || lst[i].isUsedLabel())
                            hadLbl = true;
                    }
                    if (hadLbl && !wasJmp) {
                        var j = JsGoto.simple(_this.finalLabel);
                        _this.finalLabel.refs.push(j);
                        lst.push(j);
                    }
                };
                this.thenBody.forEach(function (t) { return t.injectEndIfJumps(); });
                this.elseBody.forEach(function (t) { return t.injectEndIfJumps(); });
                if (this.finalLabel != null) {
                    inject(this.thenBody);
                    inject(this.elseBody);
                }
            };
            JsIf.prototype.forEachExpr = function (f) {
                this.condition.forEachExpr(f);
                this.thenBody.concat(this.elseBody).forEach(function (t) { return t.forEachExpr(f); });
            };
            JsIf.prototype.dump = function (wr) {
                wr("if (" + this.condition + ") {");
                var wri = function (s) {
                    wr("  " + s);
                };
                this.thenBody.forEach(function (n) {
                    n.dump(wri);
                });
                if (this.elseBody.length > 0) {
                    wr("} else {");
                    this.elseBody.forEach(function (n) {
                        n.dump(wri);
                    });
                }
                wr("}");
            };
            return JsIf;
        })(JsStmt);
        AST.JsIf = JsIf;
        var JsLabel = (function (_super) {
            __extends(JsLabel, _super);
            function JsLabel(id) {
                _super.call(this);
                this.id = id;
                this.refs = [];
            }
            JsLabel.prototype.category = function () {
                return 4 /* Label */;
            };
            JsLabel.prototype.isUsedLabel = function () {
                return this.refs.length > 0;
            };
            JsLabel.prototype.dump = function (wr) {
                wr("LABEL " + this.id + ":");
            };
            JsLabel.prototype.forEachExpr = function (f) {
            };
            return JsLabel;
        })(JsStmt);
        AST.JsLabel = JsLabel;
        var Compiler = (function (_super) {
            __extends(Compiler, _super);
            function Compiler(options) {
                _super.call(this);
                this.options = options;
                this.stepIdx = 0;
                this.inlineCurrentAction = false;
                this.numInlinedFunctions = 0;
                this.numInlinedCalls = 0;
                this.numOkEliminations = 0;
                this.numActions = 0;
                this.numStatements = 0;
                this.termsReused = 0;
                this.constantsPropagated = 0;
                this.output = "";
                this.steps = 0;
                this.todo = [];
                this.innerActions = [];
                this.aux = [];
                this.needsScriptText = false;
                this.profilingBlocks = {};
                this.profilingScopes = [];
                this.unit = new JsTerm("<unit>");
                this.api = TDev.api;
                this.tmpIdx = 0;
                this.blockId = 1;
                this.missingApis = [];
                this.maxArgsToCheck = 0;
                this.initGlobals = "";
                this.initGlobals2 = "";
                this.resetGlobals = "";
                this.cloudstateJsonExport = "";
                this.cloudstateJsonImport = "";
                this.persistentvars = [];
                this.imports = new AST.AppImports();
                this.packageResources = [];
                this.mapExprToVar = {};
                this.debuggerLocalCtxs = {};
                this.runmap_variables = [];
                this.libInits = function (nm) {
                };
                crashOnInvalid = !!options.crashOnInvalid;
                blockChaining = !!options.blockChaining;
            }
            Compiler.prototype.wr = function (s) {
                this.output += s;
            };
            Compiler.prototype.term = function (s) {
                return new JsTerm(s);
            };
            Compiler.prototype.outRef = function (d) {
                var outp = this.currentAction.getOutParameters();
                for (var i = 0; i < outp.length; ++i)
                    if (outp[i].local == d) {
                        if (outp.length <= 1)
                            return "result";
                        else
                            return "results[" + i + "]";
                    }
                return null;
            };
            Compiler.prototype.localVarName = function (d) {
                var l = this.outRef(d);
                if (l)
                    return l;
                return (this.inlineCurrentAction ? "l_" : "$") + this.localNameCtx.quote(d.getName(), d.nodeId);
            };
            Compiler.prototype.localVarRef = function (d, direct) {
                if (direct === void 0) { direct = false; }
                var t = this.inlineCurrentAction ? this.localVarName(d) : "s." + this.localVarName(d);
                if (!direct && d.isByRef())
                    t += ".ref";
                return this.term(t);
            };
            Compiler.prototype.globalVarId = function (d) {
                return "$" + d.getStableName();
            };
            Compiler.prototype.comment = function (s) {
                return "/* " + s.replace(/\//g, "") + " */";
            };
            Compiler.prototype.globalVarRef = function (d) {
                return this.term(this.comment(d.getName()) + " s.d." + this.globalVarId(d));
            };
            Compiler.prototype.newTmpVarOK = function (stem, initial, astref) {
                if (astref === void 0) { astref = null; }
                var r = this.newTmpVar(stem, initial, astref);
                r._alwaysValid = true;
                return r;
            };
            Compiler.prototype.newTmpVar = function (stem, initial, astref) {
                if (astref === void 0) { astref = null; }
                if (this.options.constantPropagation && this.currentCP && astref != null) {
                    var val = this.currentCP.precomputeLiteralExpression(astref);
                    if (val != null) {
                        ++this.constantsPropagated;
                        initial = new JsLiteral(val);
                    }
                }
                if (this.options.commonSubexprElim && this.currentAE && astref != null) {
                    var ref = null;
                    var exprs = this.currentAE.checkForIdenticalExpressions(astref);
                    for (var i = 0; i < exprs.length; ++i) {
                        var cur = exprs[i];
                        ref = this.mapExprToVar[cur.nodeId];
                        if (ref != null)
                            break;
                    }
                    if (ref != null) {
                        ++this.termsReused;
                        return ref;
                    }
                }
                var t = new JsTmpDef(stem, initial);
                this.aux.push(t);
                var r = new JsTmpRef(t);
                if (this.options.commonSubexprElim && astref != null) {
                    this.mapExprToVar[astref.nodeId] = r;
                }
                return r;
            };
            Compiler.prototype.newTmpVarOrUnit = function (rk, stem, initial, astref) {
                if (astref === void 0) { astref = null; }
                if (rk == AST.api.core.Nothing) {
                    this.aux.push(new JsExprStmt(initial));
                    return this.unit;
                }
                else {
                    return this.newTmpVar(stem, initial, astref);
                }
            };
            Compiler.prototype.allocateLabel = function () {
                return new JsLabel(this.actionName + "$" + this.stepIdx++);
            };
            Compiler.prototype.visitCodeBlock = function (b) {
                var _this = this;
                var blockId = "";
                if (this.needsProfiling()) {
                    blockId = b.stableId.replace(/\./g, "_");
                    if (!this.profilingBlocks[blockId])
                        this.profilingBlocks[blockId] = [];
                }
                var res = b.stmts.collect(function (s) { return s.isUnreachable ? [] : _this.dispatch(s); });
                if (this.needsProfiling()) {
                    var blockId = b.stableId.replace(/\./g, "_");
                    var hits = new JsTerm("profilingExecutions" + blockId);
                    res.unshift(new JsExprStmt(new JsInfix(hits, "-=", new JsLiteral("1"))));
                    var hitsNext = new JsTerm("profilingExecutionsNext" + blockId);
                    var hitsNextCount = new JsTerm("profilingExecutionsNextCount" + blockId);
                    var resetHits = this.allocateIf();
                    resetHits.condition = new JsInfix(hits, "==", new JsLiteral("0"));
                    resetHits.thenBody = [
                        hits.gets(hitsNext),
                        new JsExprStmt(new JsInfix(hitsNextCount, "+=", hitsNext)),
                        hitsNext.gets(JsCall.direct("s.rt.nextHitCount", [hitsNext])),
                    ];
                    resetHits.elseBody = [];
                    res.push(resetHits);
                }
                if (b.flags & (2 /* IsPageInit */ | 1 /* IsPageRender */)) {
                    var p = this.currentAction.modelParameter;
                    if (p) {
                        var rk = p.local.getKind();
                        if (rk.record) {
                            var stored = this.term("s.rt.getCurrentPage().model");
                            res.unshift(this.localVarRef(p.local).gets(stored));
                            if (b.flags & 2 /* IsPageInit */)
                                res.unshift(stored.gets(this.term("s.d.$" + rk.record.getStableName() + ".create(s)")));
                        }
                        else {
                            TDev.Util.check(false);
                        }
                    }
                }
                if (b.flags & 1 /* IsPageRender */) {
                    res.unshift(new JsExprStmt(JsCall.direct("s.rt.enter_render", [])));
                    res.push(new JsExprStmt(JsCall.direct("s.rt.leave_render", [])));
                }
                return res;
            };
            Compiler.prototype.flushAux = function () {
                var r = this.aux;
                this.aux = [];
                return r;
            };
            Compiler.prototype.doExpr = function (e) {
                return this.dispatch(e);
            };
            Compiler.prototype.topExpr = function (eHolder, s) {
                var _this = this;
                var ai = eHolder.assignmentInfo();
                if (ai && ai.definedVars)
                    ai.definedVars.forEach(function (l) {
                        if (l.isByRef())
                            _this.aux.push(_this.localVarRef(l, true).gets(_this.term("{ref:undefined}")));
                    });
                var nodeId = eHolder.stableId.replace(/\./g, "_");
                var blockId = s.parent.stableId.replace(/\./g, "_");
                if (this.needsProfiling()) {
                    var profilingLastCallTimeStamp = new JsTmpRef(this.profilingScopes.peek());
                    var sampleThisStmt = this.allocateIf();
                    sampleThisStmt.condition = new JsInfix(new JsInfix(new JsTerm("profilingExecutions" + blockId), "==", new JsLiteral("0")), "&&", new JsInfix(profilingLastCallTimeStamp, "==", new JsLiteral("0")));
                    sampleThisStmt.thenBody = [profilingLastCallTimeStamp.gets(JsCall.direct("perfNow", []))];
                    sampleThisStmt.elseBody = [];
                    this.aux.push(sampleThisStmt);
                }
                var res = this.dispatch(eHolder.parsed);
                if (!this.needsProfiling())
                    return res;
                this.profilingBlocks[blockId].push(nodeId);
                var duration = new JsTerm("tmp");
                var durationCallSite = new JsTerm("profilingDuration" + nodeId);
                var durationSamplesCallSite = new JsTerm("profilingDurationSamples" + nodeId);
                var profilingLastCallTimeStamp = new JsTmpRef(this.profilingScopes.peek());
                var hits = new JsTerm("profilingExecutions" + blockId);
                var captureDuration = this.allocateIf();
                captureDuration.condition = new JsInfix(hits, "==", new JsLiteral("0"));
                captureDuration.thenBody = [
                    duration.gets(new JsInfix(JsCall.direct("perfNow", []), "-", profilingLastCallTimeStamp)),
                    new JsExprStmt(new JsInfix(durationCallSite, "+=", duration)),
                    new JsExprStmt(new JsInfix(durationSamplesCallSite, "+=", new JsLiteral("1"))),
                    new JsExprStmt(new JsInfix(profilingLastCallTimeStamp, "+=", duration))
                ];
                captureDuration.elseBody = [
                    profilingLastCallTimeStamp.gets(new JsLiteral("0"))
                ];
                this.aux.push(captureDuration);
                if (this.needsProfilingDebug())
                    this.aux.push(new JsExprStmt(JsCall.direct("alert", [JsCall.direct("JSON.stringify", [new JsTerm("cs._getProfilingResults()")])])));
                return res;
            };
            Compiler.prototype.markLocation = function (s) {
                this.numStatements++;
                var currentId = new JsLiteral(this.stringLiteral(s.stableId));
                if (this.debugBuild())
                    this.buildBreakpoint(s.stableId);
                this.aux.push(this.term("s.pc").gets(currentId));
                if (this.instrumentForCoverage() && (s.isFirstNonComment() || s.isLastNonComment())) {
                    var lit = "c$" + s.stableId.replace(/\./g, "_");
                    this.runmap_variables.push([s.stableId, lit]);
                    this.aux.push(this.term(lit).gets(this.term('1')));
                }
            };
            Compiler.prototype.instrumentForCoverage = function () {
                return !!this.options.coverage;
            };
            Compiler.prototype.updateAnalysisInfo = function (e) {
                if (this.options.okElimination) {
                    this.currentReachingDefs = e.reachingDefs;
                    this.currentDoms = e.dominators;
                    this.currentUsedSet = e.usedSet;
                    if (this.currentReachingDefs && TDev.dbg) {
                        this.aux.push(this.term(this.comment(this.currentReachingDefs.toString())));
                    }
                    if (this.currentUsedSet && TDev.dbg) {
                        this.aux.push(this.term(this.comment(this.currentUsedSet.toString())));
                    }
                }
                if (this.options.commonSubexprElim) {
                    this.currentAE = e.aeSet;
                    if (this.currentAE && TDev.dbg) {
                        this.aux.push(this.term(this.comment(this.currentAE.toString())));
                    }
                }
                if (this.options.constantPropagation) {
                    this.currentCP = e.cpSet;
                    if (this.currentCP && TDev.dbg) {
                        this.aux.push(this.term(this.comment(this.currentCP.toString())));
                    }
                }
            };
            Compiler.prototype.resetAnalysisInfo = function () {
                if (this.options.okElimination) {
                    this.currentReachingDefs = null;
                    this.currentDoms = null;
                    this.currentUsedSet = null;
                }
                if (this.options.commonSubexprElim) {
                    this.currentAE = null;
                }
                if (this.options.constantPropagation) {
                    this.currentCP = null;
                }
            };
            Compiler.prototype.visitExprStmt = function (e) {
                this.updateAnalysisInfo(e.expr);
                this.markLocation(e);
                var ex = this.topExpr(e.expr, e);
                var r = this.flushAux();
                if (ex != this.unit)
                    r.push(new JsExprStmt(ex));
                this.resetAnalysisInfo();
                return r;
            };
            Compiler.prototype.visitInlineActions = function (n) {
                var _this = this;
                n.actions.forEach(function (a) {
                    if (a instanceof AST.InlineAction)
                        _this.compileInlineAction(a);
                });
                return this.visitExprStmt(n);
            };
            Compiler.prototype.allocateIf = function () {
                return new JsIf(this.allocateLabel());
            };
            Compiler.prototype.visitElseIf = function (i) {
                return [];
            };
            Compiler.prototype.visitIf = function (i) {
                var _this = this;
                if (i.isTopCommentedOut())
                    return [];
                var elseMarker = i.branches.length > 1 ? this.newTmpVarOK("elseIf", new JsLiteral("true")) : null;
                var res = this.flushAux();
                i.branches.forEach(function (b, idx) {
                    if (idx == i.branches.length - 1)
                        return;
                    _this.updateAnalysisInfo(b.condition);
                    var par = b.body.parent;
                    _this.markLocation(par);
                    var cond = _this.topExpr(b.condition, par);
                    _this.resetAnalysisInfo();
                    var body = _this.flushAux();
                    body.push(new JsExprStmt(JsCall.direct("ok", [cond])));
                    var ifNode = _this.allocateIf();
                    body.push(ifNode);
                    ifNode.condition = cond;
                    ifNode.thenBody = _this.dispatch(b.body);
                    if (idx == i.branches.length - 2) {
                        ifNode.elseBody = _this.dispatch(i.branches[idx + 1].body);
                    }
                    else {
                        if (elseMarker)
                            ifNode.thenBody.unshift(elseMarker.gets(new JsLiteral("false")));
                        ifNode.elseBody = [];
                    }
                    if (idx > 0) {
                        var outer = _this.allocateIf();
                        outer.condition = elseMarker;
                        outer.thenBody = body;
                        outer.elseBody = [];
                        res.push(outer);
                    }
                    else {
                        res.pushRange(body);
                    }
                });
                return res;
            };
            Compiler.prototype.visitWhile = function (w) {
                this.updateAnalysisInfo(w.calcNode());
                this.markLocation(w);
                var begLabel = this.allocateLabel();
                w._compilerContinueLabel = begLabel;
                w._compilerBreakLabel = this.allocateLabel();
                this.aux.push(begLabel);
                var cond = this.topExpr(w.condition, w);
                this.resetAnalysisInfo();
                var res = this.flushAux();
                var ifNode = this.allocateIf();
                ifNode.condition = cond;
                ifNode.thenBody = this.dispatch(w.body);
                ifNode.thenBody.push(JsGoto.simple(begLabel));
                ifNode.elseBody = [];
                res.push(ifNode);
                res.push(w._compilerBreakLabel);
                return res;
            };
            Compiler.prototype.visitBreak = function (b) {
                if (b.topAffectedStmt)
                    this.aux.push(JsGoto.simple(b.topAffectedStmt._compilerBreakLabel));
                return this.unit;
            };
            Compiler.prototype.visitContinue = function (b) {
                if (b.topAffectedStmt)
                    this.aux.push(JsGoto.simple(b.topAffectedStmt._compilerContinueLabel));
                return this.unit;
            };
            Compiler.prototype.visitReturn = function (r) {
                if (r.topRetLocal) {
                    var val = this.doExpr(r.args[0]);
                    this.aux.push(this.localVarRef(r.topRetLocal).gets(val));
                }
                this.aux.push(JsGoto.simple(r.topAffectedStmt._compilerBreakLabel));
                return this.unit;
            };
            Compiler.prototype.visitShow = function (s) {
                var ex = this.doExpr(s.topPostCall);
                if (ex != this.unit)
                    this.aux.push(new JsExprStmt(ex));
                return this.unit;
            };
            Compiler.prototype.compileInlineAction = function (inl) {
                var _this = this;
                var a = new AST.Action();
                a._compilerParentAction = this.currentAction;
                a._compilerInlineAction = inl;
                a.body = inl.body;
                a.isLambda = true;
                a.setStableName(this.actionName + "$" + this.stepIdx);
                a.stableId = inl.stableId;
                a.setName(this.actionName + "::lambda::" + this.stepIdx);
                a.isPrivate = true;
                this.stepIdx++;
                inl.inParameters.forEach(function (p) { return a.header.inParameters.push(new AST.ActionParameter(p)); });
                inl.outParameters.forEach(function (p) { return a.header.outParameters.push(new AST.ActionParameter(p)); });
                a.allLocals = inl.allLocals;
                inl.closure.forEach(function (p) { return a.header.inParameters.push(new AST.ActionParameter(p, false, true)); });
                this.innerActions.push(a);
                this.markLocation(inl);
                var refs = inl.closure.map(function (l) { return _this.newTmpVar("lmbv", _this.localVarRef(l, true)); });
                var n = inl.inParameters.length - 1 + 2;
                while (n >= 1)
                    refs.unshift(this.term("la" + n--));
                var mkProxy = this.newTmpVarOK("lmbProxy", this.term("s.libs.mkLambdaProxy"));
                refs.unshift(JsCall.directInst(mkProxy, "", [this.term("la0")]));
                var frame = new JsLambda(inl.inParameters.length + 2, JsCall.direct("a_" + a.getStableName(), refs));
                this.aux.push(this.localVarRef(inl.name).gets(frame));
            };
            Compiler.prototype.visitBox = function (b) {
                this.markLocation(b);
                var res = this.flushAux();
                res.push(new JsExprStmt(JsCall.direct("lib.Box.push_box", [this.term("s")])));
                res.pushRange(this.dispatch(b.body));
                res.push(new JsExprStmt(JsCall.direct("lib.Box.pop_box", [this.term("s")])));
                return res;
            };
            Compiler.prototype.mkCall = function (prop, args) {
                var call = new AST.Call();
                call.propRef = AST.PropertyRef.mkProp(prop);
                call.args = args;
                return call;
            };
            Compiler.prototype.visitForeach = function (f) {
                var collExpr = f.collection.parsed;
                var collTmp;
                var isArray = false;
                this.updateAnalysisInfo(f.calcNode());
                this.markLocation(f);
                if (collExpr.getKind().hasEnumerator()) {
                    isArray = true;
                    collTmp = this.newTmpVarOK("collArr", JsCall.mk(this.topExpr(f.collection, f), "get_enumerator", []));
                }
                else {
                    collTmp = this.newTmpVar("coll", this.topExpr(f.collection, f));
                }
                this.resetAnalysisInfo();
                f._compilerBreakLabel = this.allocateLabel();
                var idxTmp = this.newTmpVarOK("idx", this.term("0"));
                var begLabel = this.allocateLabel();
                f._compilerContinueLabel = begLabel;
                this.aux.push(begLabel);
                var lenExpr;
                if (isArray)
                    lenExpr = new JsInfix(collTmp, ".length", null);
                else {
                    var countProp = collExpr.getKind().getProperty("count");
                    lenExpr = this.callProperty(countProp, [collTmp]);
                }
                var res = this.flushAux();
                var ifNode = this.allocateIf();
                ifNode.condition = JsCall.okAnd([collTmp], new JsInfix(idxTmp, "<", lenExpr));
                var atExpr;
                if (isArray) {
                    atExpr = new JsCall(collTmp, "[", [idxTmp]);
                }
                else {
                    var atProp = collExpr.getKind().getProperty("at");
                    atExpr = this.callProperty(atProp, [collTmp, idxTmp]);
                }
                this.aux.push(this.localVarRef(f.boundLocal).gets(atExpr));
                this.aux.push(new JsExprStmt(new JsInfix(idxTmp, "++", null)));
                if (f.conditions.stmts.length == 0) {
                    ifNode.thenBody = this.flushAux();
                    ifNode.thenBody.pushRange(this.dispatch(f.body));
                }
                else {
                    var where = function (idx) { return f.conditions.stmts[idx].condition.parsed; };
                    var cond = where(0);
                    for (var i = 1; i < f.conditions.stmts.length; ++i) {
                        cond = this.mkCall(AST.api.core.AndProp, [cond, where(i)]);
                    }
                    var innerIf = this.allocateIf();
                    innerIf.condition = this.doExpr(cond);
                    this.aux.push(innerIf);
                    ifNode.thenBody = this.flushAux();
                    innerIf.thenBody = this.dispatch(f.body);
                    innerIf.elseBody = [];
                }
                ifNode.thenBody.push(JsGoto.simple(begLabel));
                ifNode.elseBody = [];
                res.push(ifNode);
                res.push(f._compilerBreakLabel);
                return res;
            };
            Compiler.prototype.visitFor = function (f) {
                this.updateAnalysisInfo(f.calcNode());
                this.markLocation(f);
                var bndTmp = this.newTmpVar("bnd", this.topExpr(f.upperBound, f));
                this.resetAnalysisInfo();
                var idx = this.localVarRef(f.boundLocal);
                this.aux.push(idx.gets(this.term("0")));
                var begLabel = this.allocateLabel();
                f._compilerContinueLabel = this.allocateLabel();
                f._compilerBreakLabel = this.allocateLabel();
                var res = this.flushAux();
                res.push(begLabel);
                var ifNode = this.allocateIf();
                ifNode.condition = new JsInfix(idx, "<", bndTmp);
                ifNode.thenBody = this.dispatch(f.body);
                ifNode.thenBody.push(f._compilerContinueLabel);
                ifNode.thenBody.push(new JsExprStmt(new JsInfix(idx, "++", null)));
                ifNode.thenBody.push(JsGoto.simple(begLabel));
                ifNode.elseBody = [];
                res.push(ifNode);
                res.push(f._compilerBreakLabel);
                return res;
            };
            Compiler.prototype.visitComment = function (c) {
                if (this.options.usedProperties.hasOwnProperty("appconsumerenderedcomments")) {
                    var par = c.parent.stmts;
                    var idx = par.indexOf(c);
                    if (par[idx - 1] && par[idx - 1].docText() != null)
                        return [];
                    var end = idx;
                    while (par[end] && par[end].docText() != null)
                        end++;
                    var d = AST.Step.renderDocs(par.slice(idx, end));
                    return [new JsExprStmt(JsCall.direct("s.rt.saveComment", [new JsLiteral(this.stringLiteral(d))]))];
                }
                return [];
            };
            Compiler.prototype.callString = function (prop, args, ctxArg, astref) {
                var _this = this;
                var pk = prop.parentKind;
                var propName = prop.runtimeName();
                var parName = prop.parentKind.runtimeName();
                var rk = prop.getResult().getKind();
                var specApply = prop.getSpecialApply();
                var robust = prop.getFlags() & 16384 /* Robust */;
                var res;
                var doMagic = function () {
                    if (specApply) {
                        TDev.Util.assertCode(args.length == 2);
                        if (astref && astref.isSynthetic)
                            astref = null;
                        var inner = new JsInfix(args[0], specApply, args[1]);
                        if (TDev.Cloud.isRestricted() && parName == "Number_" && astref && !astref.isShim) {
                            var over = Compiler.restrictedIntOps[propName];
                            if (over)
                                inner = JsCall.direct("lib." + over, [args[0], args[1]]);
                        }
                        res = _this.newTmpVar("infix", JsCall.okAnd([args[0], args[1]], inner), astref);
                    }
                    else if (propName == "is_invalid") {
                        res = new JsInfix(args[0], "==", _this.term("undefined"));
                        res._alwaysValid = true;
                    }
                    else if (!prop.isImplemented()) {
                        var meth = "";
                        var apiName = parName + "->" + propName;
                        if ((prop.getCapability() & AST.api.core.currentPlatform) == 0) {
                            meth = "TDev.Util.notSupported";
                        }
                        else {
                            meth = "TDev.Util.notImplementedYet";
                            apiName += " (yet)";
                        }
                        if (_this.missingApis.indexOf(apiName) < 0)
                            _this.missingApis.push(apiName);
                        res = _this.newTmpVarOrUnit(rk, "notImpl", JsCall.direct(meth, [_this.term("s"), _this.term("'" + apiName + "'")]));
                    }
                    else if (pk == AST.api.core.App && (propName == "javascript" || propName == "javascript_async")) {
                        _this.emitJavascriptEscape(astref, ctxArg);
                        res = _this.unit;
                    }
                    else if (pk.isBuiltin || !pk.isData) {
                        if (!pk.isData)
                            args.shift();
                        args.push(ctxArg);
                        if (astref && astref.compiledTypeArgs)
                            args.pushRange(astref.compiledTypeArgs);
                        if (TDev.Cloud.isRestricted() && parName == "Bits" && /^(or|and)_uint32$/.test(propName))
                            propName = propName.replace("uint32", "int32");
                        res = _this.newTmpVarOrUnit(rk, "call", JsCall.mk(null, "lib." + parName + "." + propName, args));
                    }
                    else {
                        var th = args.shift();
                        args.push(ctxArg);
                        if (astref && astref.compiledTypeArgs)
                            args.pushRange(astref.compiledTypeArgs);
                        res = _this.newTmpVarOrUnit(rk, "call", JsCall.mk(th, propName, args));
                    }
                };
                doMagic();
                if (this.options.okElimination && robust) {
                    this.numOkEliminations++;
                    res._alwaysValid = true;
                }
                return res;
            };
            Compiler.prototype.markAllocated = function (prop, res) {
                if (!!(prop.getResult().getFlags() & 1 /* WritesMutable */)) {
                    this.aux.push(new JsExprStmt(JsCall.direct("s.rt.markAllocated", [res])));
                }
            };
            Compiler.prototype.returnedFrom = function (numOut, idx) {
                var name = "result";
                if (numOut > 1)
                    name = "results[" + idx + "]";
                return this.term("s.rt.returnedFrom." + name);
            };
            Compiler.prototype.isDataRef = function (e) {
                return (e instanceof AST.Call) && !!e.referencedData();
            };
            Compiler.prototype.assignTo = function (e, src) {
                if (e.referencedRecordField() || e.referencedData())
                    this.emitRefOperation(e, "set", null, [src]);
                else {
                    var setter = e.getLiftedSetter();
                    if (setter) {
                        var c = AST.mkFakeCall(AST.PropertyRef.mkProp(setter));
                        this.emitNormalCall(c, [this.doExpr(e.args[0]), src]);
                    }
                    else
                        this.aux.push(this.doExpr(e).gets(src));
                }
            };
            Compiler.prototype.doAssignment = function (c) {
                var _this = this;
                var targets = c.args[0].flatten(AST.api.core.TupleProp);
                var src = this.doExpr(c.args[1]);
                if (targets.length == 1) {
                    if (c.args[1].getKind() != AST.api.core.Nothing)
                        this.assignTo(targets[0], src);
                }
                else {
                    var act = c.args[1].anyCalledAction();
                    TDev.Util.assertCode(act != null);
                    for (var i = 0; i < act.getOutParameters().length; ++i) {
                        this.assignTo(targets[i], this.returnedFrom(act.getOutParameters().length, i));
                    }
                }
                if (targets.some(function (e) { return _this.isDataRef(e); }))
                    this.aux.push(new JsExprStmt(JsCall.direct("s.rt.logDataWrite", [])));
                return this.unit;
            };
            Compiler.prototype.doLazy = function (c, isAnd) {
                var arg0 = this.doExpr(c.args[0]);
                var tmp = this.newTmpVar("lazy", arg0);
                var cond = this.allocateIf();
                if (this.options.okElimination && arg0.alwaysValid()) {
                    this.numOkEliminations++;
                    cond.condition = isAnd ? tmp : new JsInfix(null, "!", tmp);
                }
                else
                    cond.condition = JsCall.okAnd([tmp], isAnd ? tmp : new JsInfix(null, "!", tmp));
                this.aux.push(cond);
                var tmpAux = this.flushAux();
                var arg1 = this.doExpr(c.args[1]);
                this.aux.push(tmp.gets(arg1));
                if (this.options.okElimination)
                    tmp._alwaysValid = arg0.alwaysValid() && arg1.alwaysValid();
                cond.thenBody = this.flushAux();
                cond.elseBody = [];
                this.aux = tmpAux;
                return tmp;
            };
            Compiler.prototype.forceNonRender = function () {
                this.aux.push(new JsExprStmt(JsCall.direct("s.rt.forceNonRender", [])));
                this.aux.push(new JsExprStmt(JsCall.direct("s.rt.forcePageRefresh", [])));
            };
            Compiler.prototype.emitRefOperation = function (fieldRef, op, args, compiledArgs) {
                if (compiledArgs === void 0) { compiledArgs = null; }
                if (op == "ref" || op == "with notify")
                    return null;
                if (fieldRef instanceof AST.Call) {
                    var rcf = fieldRef.referencedRecordField();
                    if (rcf)
                        return this.emitRecordOperation(fieldRef, op, rcf, args, compiledArgs);
                    var rd = fieldRef.referencedData();
                    if (rd)
                        return this.emitDataOperation(fieldRef, op, rd, args, compiledArgs);
                }
                return null;
            };
            Compiler.prototype.emitRefCall = function (c) {
                return this.emitRefOperation(c.args[0], c.prop().getName().slice(1), c.args.slice(1));
            };
            Compiler.prototype.emitDataOperation = function (fieldRef, op, rd, opargs, args) {
                var _this = this;
                if (op == "get") {
                    if (rd.isTransient)
                        return this.globalVarRef(rd);
                    else {
                        if (!args)
                            args = opargs.map(function (e) { return _this.doExpr(e); });
                        args.unshift(new JsLiteral(this.stringLiteral("$" + rd.getStableName())));
                        args.push(this.term("s"));
                        return this.newTmpVar("val", JsCall.direct("s.d.$$" + (rd.cloudEnabled ? "cloud" : "local") + "persistentvars.perform_get", args));
                    }
                }
                if (op == "set") {
                    if (!args)
                        args = opargs.map(function (e) { return _this.doExpr(e); });
                    if (rd.isTransient)
                        this.aux.push(this.globalVarRef(rd).gets(args[0]));
                    else {
                        args.unshift(new JsLiteral(this.stringLiteral("$" + rd.getStableName())));
                        args.push(this.term("s"));
                        this.aux.push(new JsExprStmt(JsCall.direct("s.d.$$" + (rd.cloudEnabled ? "cloud" : "local") + "persistentvars.perform_set", args)));
                    }
                }
                return null;
            };
            Compiler.prototype.emitRecordOperation = function (fieldRef, op, rcf, opargs, args) {
                var _this = this;
                var recvRecord = this.doExpr(fieldRef.args[0]);
                var fieldName = new JsLiteral(this.stringLiteral(rcf.referenceName()));
                if (!args)
                    args = opargs.map(function (e) { return _this.doExpr(e); });
                args.unshift(fieldName);
                args.push(this.term("s"));
                var prevAux = this.flushAux();
                var result;
                if (op === "get" || op === "confirmed") {
                    if (rcf.def().recordType === 1 /* Object */) {
                        result = JsCall.directInst(recvRecord, "[", [fieldName]);
                    }
                    else {
                        result = JsCall.directInst(recvRecord, "perform_" + op, args);
                    }
                }
                else {
                    var name = op;
                    name = "perform_" + ((name === "test and set") ? "test_and_set" : name);
                    this.aux.push(new JsExprStmt(JsCall.directInst(recvRecord, name, args)));
                    result = this.unit;
                }
                if (result != this.unit) {
                    result = this.newTmpVar("recOp", result);
                }
                var ifNode = this.allocateIf();
                ifNode.condition = recvRecord;
                ifNode.thenBody = this.flushAux();
                ifNode.elseBody = [];
                prevAux.push(ifNode);
                this.aux = prevAux;
                return result;
            };
            Compiler.prototype.needsProfiling = function () {
                return this.options.profiling;
            };
            Compiler.prototype.needsProfilingDebug = function () {
                return /profilingDebug/.test(document.URL);
            };
            Compiler.prototype.debugBuild = function () {
                return !!this.options.debugging;
            };
            Compiler.prototype.buildBreakpoint = function (s) {
                var check = new JsExprStmt(new JsInfix(this.term("bp$" + s.replace(/\./g, "_")), "&&", JsCall.direct("s.rt.hitBreakpoint", [new JsLiteral(this.stringLiteral(s))])));
                var l = this.allocateLabel();
                var g = JsGoto.simple(l, false);
                this.aux.push(check, g, l);
            };
            Compiler.prototype.buildActionCall = function (numOut, isAsync, args, mkCall) {
                var l = this.allocateLabel();
                args.splice(0, 1, this.term("s"), new JsLabelRef(l));
                var call = mkCall();
                var rtEnter;
                if (isAsync) {
                    var task = this.newTmpVar("task", JsCall.direct("s.rt.mkActionTask", []));
                    rtEnter = JsCall.direct("s.rt.enterAsync", [task, call]);
                }
                else {
                    rtEnter = JsCall.direct("s.rt.enter", [call]);
                }
                var g = new JsGoto(rtEnter, false);
                this.aux.push(g, l);
                if (isAsync)
                    return task;
                if (numOut == 1)
                    return this.newTmpVar("actRes", this.returnedFrom(numOut, 0));
                else
                    return this.unit;
            };
            Compiler.prototype.buildStringArray = function (strings) {
                var _this = this;
                return this.term("[" + strings.reduce(function (str, current, i) { return (!current) ? str : (i == 0) ? _this.stringLiteral(current) : (str + ", " + _this.stringLiteral(current)); }, "") + "]");
            };
            Compiler.prototype.emitJavascriptEscape = function (c, ctxArg) {
                var _this = this;
                if (!this.options.javascript)
                    return;
                var code = "";
                function localName(l) {
                    var r = TDev.Api.runtimeName(l.getName().replace(/[?]/g, ""));
                    if (r == "s" || r == "lib")
                        return "_" + r;
                    return r;
                }
                function unterm(t) {
                    if (t instanceof JsTerm)
                        return t.code;
                    TDev.Util.die();
                    return "";
                }
                if (c.args[1].getStringLiteral() != "local") {
                    this.problem(TDev.lf("wrong JS calling convention"));
                    code = "TDev.Util.userError('wrong JS calling convention');";
                }
                else {
                    var isAsync = c.prop().getName() == "javascript async";
                    if (isAsync) {
                        code = "(function(_resumeCtx){\n" + "   var s = _resumeCtx.stackframe;\n" + "   function resume() { _saveResults(); _resumeCtx.resume() }\n" + "   s.localResume = resume;\n" + "";
                    }
                    else {
                        code = "(function(s){\n";
                    }
                    code += "  function _saveResults() {\n";
                    this.currentAction.getOutParameters().forEach(function (p) {
                        code += "    " + unterm(_this.localVarRef(p.local)) + " = " + localName(p.local) + ";\n";
                    });
                    code += "  }\n";
                    var imp = this.currentApp.imports.npmModules;
                    var impKeys = Object.keys(imp);
                    if (impKeys.length > 0) {
                        impKeys.forEach(function (k) {
                            k = TDev.Api.runtimeName(k);
                            code += "  var " + k + " = s.rt.nodeModules." + k + ";\n";
                        });
                    }
                    this.currentAction.allLocals.forEach(function (l) {
                        code += "  var " + localName(l) + " = " + unterm(_this.localVarRef(l)) + ";\n";
                    });
                    code += "  var rt = s.rt;\n";
                    code += "  function _userCode() {\n\n";
                    var theCode = c.args[2].getStringLiteral();
                    code += c.args[2].getStringLiteral();
                    code += "\n\n  }\n";
                    code += "  s.rt.runInlineJavascript(_userCode);\n";
                    if (!isAsync)
                        code += "  _saveResults();\n";
                    code += "})";
                }
                try {
                }
                catch (e) {
                    this.problem("syntax error in app->javascript, " + e + "\n" + code);
                }
                this.aux.push(new JsExprStmt(JsCall.direct(code, [ctxArg])));
            };
            Compiler.prototype.problem = function (s) {
                TDev.Util.log("compiler problem: " + s);
                if (this.options.problemCallback)
                    this.options.problemCallback(s);
            };
            Compiler.prototype.doFun = function (c) {
                if (c.funAction) {
                    this.compileInlineAction(c.funAction);
                    return this.localVarRef(c.funAction.name);
                }
                else
                    return this.term("null");
            };
            Compiler.prototype.visitCall = function (c) {
                var _this = this;
                var prop = c.prop();
                if (prop == AST.api.core.AssignmentProp)
                    return this.doAssignment(c);
                if (prop == AST.api.core.AndProp)
                    return this.doLazy(c, true);
                if (prop == AST.api.core.OrProp)
                    return this.doLazy(c, false);
                if (prop == AST.api.core.AsyncProp)
                    return this.dispatch(c.args[1]);
                if (prop == AST.api.core.FunProp)
                    return this.doFun(c);
                if (prop.getCategory() == 3 /* Library */)
                    return this.unit;
                if (prop.parentKind.getRoot() == AST.api.core.Ref) {
                    var tmp = this.emitRefCall(c);
                    if (tmp)
                        return tmp;
                }
                if (c.autoGet)
                    return this.emitRefOperation(c, "get", []);
                var args = c.args.slice(0);
                var typeArgs = [];
                if (prop instanceof TDev.MultiplexProperty && prop.savedArgs)
                    typeArgs = prop.savedArgs.map(function (p) {
                        var r = _this.term(_this.reifyType(p) || "null");
                        r._alwaysValid = true;
                        return r;
                    });
                while (prop instanceof TDev.MultiplexProperty) {
                    var inner = c.args[0];
                    if (inner instanceof AST.Call) {
                        c = inner;
                        prop = c.prop();
                    }
                    else {
                        break;
                    }
                }
                c.compiledTypeArgs = typeArgs;
                args[0] = c.args[0];
                return this.emitNormalCall(c, args.map(function (e) { return _this.doExpr(e); }));
            };
            Compiler.prototype.reifyType = function (p) {
                if (p.isBuiltin)
                    return this.stringLiteral(p.getName().toLowerCase());
                else if (p.getRecord()) {
                    if (!p.parentLibrary() || p.parentLibrary().isThis())
                        return this.globalVarRef(p.getRecord()).code;
                    else
                        return "s.rt.getLibRecordSingleton(" + this.stringLiteral(p.parentLibrary().getStableName()) + ", " + this.stringLiteral(p.getName()) + ")";
                }
                else if (p.isData && !p.isUserDefined() && p.getParameterCount() == 0)
                    return "lib." + p.runtimeName();
                else
                    return null;
            };
            Compiler.prototype.emitNormalCall = function (c, args) {
                var _this = this;
                var prop = c.prop();
                var dat = c.referencedData();
                var act = c.calledAction();
                var rcd = (prop && prop.forwardsTo() instanceof AST.RecordDef && prop.forwardsTo());
                var str = function (s) { return _this.stringLiteral(s); };
                if (prop instanceof AST.ExtensionProperty) {
                    act = prop.shortcutTo;
                    args.unshift(null);
                }
                if (dat) {
                    if (dat.isTransient)
                        return JsCall.direct("lib.GlobalVarRef.mk", [this.term("s.d"), new JsLiteral(this.stringLiteral(this.globalVarId(dat)))]).makeValid();
                    else
                        return JsCall.direct("lib.PersistedVarRef.mk", [this.term("s.d.$$" + (dat.cloudEnabled ? "cloud" : "local") + "persistentvars"), new JsLiteral(this.stringLiteral("$" + dat.getStableName()))]).makeValid();
                }
                else if (rcd) {
                    return this.globalVarRef(rcd);
                }
                else if (act && act.isPage()) {
                    var par;
                    if (act instanceof AST.LibraryRefAction)
                        par = new JsLiteral(str(act.parentLibrary().getStableName()));
                    else
                        par = this.term("s.d.libName");
                    var pageName = [par, new JsLiteral(str(act.getName()))];
                    args.splice(0, 1);
                    this.forceNonRender();
                    this.aux.push(new JsExprStmt(JsCall.direct("s.rt.postAutoPage", pageName.concat(args))));
                    return this.unit;
                }
                else if (act && act.canBeInlined && this.options.inlining) {
                    var numOut = act.getOutParameters().length;
                    var call = undefined;
                    this.numInlinedCalls++;
                    args.shift();
                    args.unshift(new JsTerm("s"));
                    call = JsCall.direct("a_" + act.getStableName(), args);
                    if (numOut == 1)
                        return this.newTmpVar("fast_call", call);
                    else {
                        this.aux.push(new JsExprStmt(call));
                        return this.unit;
                    }
                }
                else if (act) {
                    if (act.isExtensionAction()) {
                        act = act.extensionForward();
                        args.unshift(null);
                    }
                    return this.buildActionCall(!act.isAtomic ? 1 : act.getOutParameters().length, c.runAsAsync, args, function () {
                        if (act instanceof AST.LibraryRefAction) {
                            var refAct = act;
                            if (act.parentLibrary().isCloud()) {
                                args = [new JsTerm(refAct.template.isQuery ? "true" : "false"), new JsLiteral(_this.stringLiteral(_this.options.azureSite)), new JsLiteral(_this.stringLiteral(act.parentLibrary().getName())), new JsLiteral(_this.stringLiteral(act.parentLibrary().getStableName())), new JsLiteral(_this.stringLiteral(act.getName())), _this.buildStringArray(act.getInParameters().map(function (ap) {
                                    return ap.getName();
                                })), _this.buildStringArray(act.getOutParameters().map(function (ap) {
                                    return ap.getName();
                                })), _this.buildStringArray(act.getOutParameters().map(function (ap) {
                                    var kind = ap.getKind();
                                    if (kind instanceof AST.LibraryRefAbstractKind) {
                                        var ak = kind;
                                        var lb = ak.parentLibrary().getStableName();
                                        return lb + "→" + ak.getName();
                                    }
                                    else if (kind instanceof TDev.ParametricKind && kind._name === "Collection") {
                                        var pm = kind.parameters[0];
                                        if (pm instanceof AST.LibraryRefAbstractKind) {
                                            var ak = pm;
                                            var lb = ak.parentLibrary().getStableName();
                                            var name = lb + "→" + ak.getName();
                                        }
                                        else {
                                            var name = pm.getName();
                                        }
                                        return "Collection of " + name;
                                    }
                                    return kind.toString();
                                }))].concat(args);
                                return JsCall.direct(refAct.template.isOffline ? "s.rt.callServiceOffline" : "s.rt.callService", args);
                            }
                            else {
                                var tmp = _this.newTmpVar("libcall", _this.term("s.libs[" + str(act.parentLibrary().getStableName()) + "][" + str(act.getName()) + "](s)"));
                                args[0] = tmp;
                                return JsCall.directInst(tmp, "invoke", args);
                            }
                        }
                        else {
                            return JsCall.direct("a_" + act.getStableName(), args);
                        }
                    });
                }
                else if (prop.getName() == "run" && prop.parentKind.isAction) {
                    var lmb = args[0];
                    return this.buildActionCall(prop.parentKind.getOutParameters().length, c.runAsAsync, args, function () {
                        return JsCall.okAnd([lmb], JsCall.directInst(lmb, "", args));
                    });
                }
                else {
                    var rcf = c.referencedRecordField();
                    if (rcf) {
                        var keyname = new JsLiteral(this.stringLiteral(rcf.referenceName()));
                        if (prop.isKey)
                            return JsCall.mk(args[0], "[", [keyname]);
                        else
                            return JsCall.mk(null, "lib.FieldRef.mk", [args[0], keyname]).makeValid();
                    }
                    return this.callProperty(prop, args, c, c.runAsAsync);
                }
            };
            Compiler.prototype.callProperty = function (prop, args, astref, runAsAsync) {
                if (astref === void 0) { astref = null; }
                if (runAsAsync === void 0) { runAsAsync = false; }
                var writes = function (p) { return !!(p.getFlags() & 1 /* WritesMutable */); };
                var parms = prop.getParameters();
                for (var i = 0; i < parms.length; i++)
                    if (writes(parms[i]))
                        this.aux.push(new JsExprStmt(JsCall.direct("s.rt.logObjectMutation", [args[i]])));
                if (prop.shouldPauseInterperter() && prop.isImplemented()) {
                    if (runAsAsync) {
                        var rctx = this.newTmpVarOK("resumeCtx", JsCall.direct("s.rt.getAsyncResumeCtx", []));
                        this.callString(prop, args, rctx, astref);
                        return JsCall.directInst(rctx, "task", null);
                    }
                    var l = this.allocateLabel();
                    var r = new JsLabelRef(l);
                    var fnName = prop.getFlags() & 4096 /* Async */ ? "s.rt.getAwaitResumeCtx" : "s.rt.getBlockingResumeCtx";
                    var rctx = this.newTmpVarOK("resumeCtx", JsCall.direct(fnName, [r]));
                    this.callString(prop, args, rctx, astref);
                    this.aux.push(new JsGoto(r, false));
                    this.aux.push(l);
                    if (prop.getResult().getKind() == AST.api.core.Nothing)
                        return this.unit;
                    else {
                        var res = this.newTmpVar("pauseRes", this.term("s.pauseValue"));
                        this.markAllocated(prop, res);
                        return res;
                    }
                }
                else if (prop == AST.api.core.StringConcatProp) {
                    return this.newTmpVar("concat", JsCall.direct("lib.String_.concatAny", args));
                }
                else {
                    var res = this.callString(prop, args, this.term("s"), astref);
                    this.markAllocated(prop, res);
                    return res;
                }
            };
            Compiler.prototype.stringLiteral = function (s) {
                return TDev.Util.jsStringLiteral(s);
            };
            Compiler.prototype.visitLiteral = function (l) {
                switch (typeof l.data) {
                    case "string":
                        return new JsLiteral(this.stringLiteral(l.data));
                    case "number":
                        return new JsLiteral(l.data.toString());
                    case "boolean":
                        return new JsLiteral(l.data.toString());
                    default: TDev.Util.die();
                }
            };
            Compiler.prototype.handlePlaceholder = function (pdef) {
                var _this = this;
                var str = function (s) { return new JsLiteral(_this.stringLiteral(s)); };
                var data = pdef.escapeDef;
                var lk = data.objectToMake;
                var parentLib = lk.parentLibrary() ? lk.parentLibrary().getStableName() : "this";
                var call = JsCall.direct("s.rt.mkLibObject", [str(parentLib), str(lk.getName())]);
                var res = this.newTmpVarOK("obj", call);
                if (data.optionalConstructor) {
                    data.optionalConstructor.optionalParameters().forEach(function (p) {
                        var fieldName = new JsLiteral(_this.stringLiteral(p.recordField.referenceName()));
                        var arg = p instanceof AST.OptionalParameter ? _this.doExpr(p.expr.parsed) : _this.localVarRef(p.name);
                        _this.aux.push(new JsExprStmt(JsCall.directInst(res, "perform_set", [fieldName, arg, _this.term("s")])));
                    });
                }
                return res;
            };
            Compiler.prototype.visitThingRef = function (t) {
                switch (t.def.nodeType()) {
                    case "singletonDef":
                        return this.term("null");
                    case "localDef":
                        var term = this.localVarRef(t.def);
                        if (this.options.okElimination && this.currentReachingDefs) {
                            if (!this.currentReachingDefs.mayBeInvalid(t.def) || (this.currentUsedSet && this.currentUsedSet.alreadyUsed(t.def))) {
                                this.numOkEliminations++;
                                term._alwaysValid = true;
                            }
                        }
                        return term;
                    case "placeholderDef":
                        return this.handlePlaceholder(t.def);
                    default: TDev.Util.die();
                }
            };
            Compiler.prototype.visitAstNode = function (n) {
                TDev.Util.oops(TDev.lf("compilation not implemented for {0}", n.nodeType()));
            };
            Compiler.prototype.emitOk = function (n) {
                var a = TDev.Util.range(0, n).map(function (k) { return "a" + k; });
                this.wr("function ok" + n + "(s, " + a.join(", ") + ") {\n");
                this.wr("  return (" + a.map(function (x) { return x + " == undefined"; }).join(" || ") + ") ?\n");
                this.wr("       TDev.Util.userError(\"using invalid value\") : true;\n");
                this.wr("}\n\n");
            };
            Compiler.prototype.visitLibraryRef = function (l) {
            };
            Compiler.prototype.visitRecordDef = function (r) {
                var _this = this;
                if (!this.shouldCompile(r))
                    return;
                var mkEntry = "Ent_" + r.getStableName();
                var mkTable = "Tbl_" + r.getStableName();
                if (r.cloudEnabled)
                    this.options.hasCloudData = true;
                if (r.locallypersisted())
                    this.options.hasLocalData = true;
                if (r.cloudPartiallyEnabled)
                    this.options.hasPartialData = true;
                var rt = (r.persistent ? "Cloud" : "") + AST.RecordDef.recordTypeToString(r.recordType);
                var wrProto = function (target, fnName, expr) {
                    if (fnName != "")
                        fnName = "." + fnName;
                    _this.wr(target + ".prototype" + fnName + " = " + expr + ";\n");
                };
                var wrProtoQ = function (target, fnName, expr) {
                    _this.wr(target + ".prototype[" + _this.stringLiteral(fnName) + "] = " + expr + ";\n");
                };
                var wrFields = function (target, id, flds) {
                    wrProto(target, id, "[" + flds.map(function (f) { return _this.stringLiteral(f.referenceName()); }).join(", ") + "]");
                };
                this.wr("\n//" + mkEntry + "\n");
                this.wr("function " + mkEntry + "(p) {\n");
                this.wr("  this.parent = p;\n");
                this.wr("}\n");
                wrProto(mkEntry, "", "new lib." + rt + "Entry()");
                wrFields(mkEntry, "keys", r.keys.fields());
                wrFields(mkEntry, "values", r.values.fields());
                wrFields(mkEntry, "fields", r.getFields());
                var wrFieldName = function (f) {
                    wrProtoQ(mkEntry, f.referenceName() + "_realname", _this.stringLiteral(f.getName()));
                };
                var wrFieldDefaultValue = function (f) {
                    var defl = "";
                    switch (f.dataKind.getName()) {
                        case "Boolean":
                            defl = 'false';
                            break;
                        case "Number":
                            defl = '0';
                            break;
                        case "String":
                            defl = '""';
                            break;
                        case "DateTime":
                            defl = 'lib.DateTime.defaultValue';
                            break;
                        default: break;
                    }
                    if (defl)
                        wrProtoQ(mkEntry, f.referenceName(), defl);
                };
                r.getFields().forEach(wrFieldName);
                if (!r.persistent)
                    r.getValueFields().forEach(wrFieldDefaultValue);
                this.wr("//" + mkTable + "\n");
                this.wr("function " + mkTable + "(l) {\n");
                this.wr("  this.libName = l;\n");
                this.wr("  this.initParent();\n");
                this.wr("}\n");
                wrProto(mkTable, "", "new lib." + rt + "Singleton()");
                wrProto(mkTable, "entryCtor", mkEntry);
                this.wr("cs.objectSingletons[" + this.stringLiteral(r.getCoreName()) + "] " + "= function(d) { return d." + this.globalVarId(r) + " };\n");
                wrProto(mkTable, "selfCtor", mkTable);
                wrProto(mkTable, "stableName", this.stringLiteral(r.getStableName()));
                wrProto(mkTable, "entryKindName", this.stringLiteral(r.entryKind.getName()));
                if (r.persistent && !r.hasErrors()) {
                    wrProto(mkTable, "cloudtype", this.stringLiteral(r.getCloudType()));
                    wrProto(mkTable, "key_cloudtypes", "[" + r.keys.fields().map(function (f) { return _this.stringLiteral(f.getCloudType()); }).join(", ") + "]");
                    wrProto(mkTable, "value_cloudtypes", "[" + r.values.fields().map(function (f) { return _this.stringLiteral(f.getCloudType()); }).join(", ") + "]");
                    if (r.locallypersisted() && !this.options.cloud) {
                        wrProto(mkTable, "localsession", "true");
                    }
                    else {
                        this.cloudstateJsonExport = this.cloudstateJsonExport + "  json[" + this.stringLiteral(r.getName()) + "] = d." + this.globalVarId(r) + ".exportJson(ctx);\n";
                        this.cloudstateJsonImport = this.cloudstateJsonImport + "  d." + this.globalVarId(r) + ".importJsonTableOrIndex(ctx,json[" + this.stringLiteral(r.getName()) + "]);\n";
                        wrProto(mkTable, "replication", r.cloudPartiallyEnabled ? this.stringLiteral("partial") : r.cloudEnabled ? this.stringLiteral("full") : this.stringLiteral("local"));
                    }
                }
                this.wr("\n// jsonimport\n");
                if ((r.recordType === 2 /* Table */ || r.recordType === 3 /* Index */) && r.keys.fields().length > 0) {
                    this.wr(mkTable + ".prototype.importJsonKeys = function (ctx, json) {\n");
                    this.wr("  var s = ctx.s;\n");
                    this.wr("  var a = [];\n");
                    r.keys.fields().forEach(function (f) {
                        if (f.dataKind.hasContext(1024 /* Json */)) {
                            var typename = f.dataKind.getName().replace(/ /g, "");
                            switch (typename) {
                                case "Boolean":
                                case "Number":
                                case "String":
                                case "DateTime":
                                case "Color":
                                case "User":
                                case "Location":
                                case "Vector3":
                                    _this.wr("  a.push(ctx.import" + typename + "(json, " + _this.stringLiteral(f.getName()) + "));\n");
                                    break;
                                default:
                                    if (f.dataKind instanceof AST.RecordEntryKind) {
                                        _this.wr("  a.push(ctx.importRecord(json, undefined," + _this.stringLiteral(f.getName()) + ", " + "s.d." + _this.globalVarId(f.dataKind.record) + "));\n");
                                    }
                                    break;
                            }
                        }
                    });
                    this.wr("  return a;\n");
                    this.wr("}\n");
                }
                this.wr(mkEntry + ".prototype.importJsonFields = function (ctx, json) {\n");
                this.wr("  var s = ctx.s;\n");
                r.values.fields().forEach(function (f) {
                    if (f.dataKind.hasContext(1024 /* Json */)) {
                        var typename = f.dataKind.getName().replace(/ /g, "");
                        var fieldname = _this.stringLiteral(f.referenceName());
                        switch (typename) {
                            case "Boolean":
                            case "Number":
                            case "String":
                            case "DateTime":
                            case "Color":
                            case "JsonObject":
                            case "User":
                            case "Location":
                            case "Vector3":
                                _this.wr("  this.perform_set(" + fieldname + ", " + "ctx.import" + typename + "(json, " + _this.stringLiteral(f.getName()) + "), s);\n");
                                break;
                            case "JsonBuilder":
                            case "Link":
                            case "OAuthResponse":
                            case "StringMap":
                            case "NumberMap":
                                _this.wr("  this.perform_set(" + fieldname + ", " + "ctx.import" + typename + "(json, this.perform_get(" + fieldname + ",s)," + _this.stringLiteral(f.getName()) + "), s);\n");
                                break;
                            default:
                                if (f.dataKind instanceof AST.RecordEntryKind) {
                                    _this.wr("  this.perform_set(" + fieldname + ", " + "ctx.importRecord(json, this.perform_get(" + fieldname + ",s)," + _this.stringLiteral(f.getName()) + ", " + "s.d." + _this.globalVarId(f.dataKind.record) + "), s);\n");
                                }
                                else if (f.dataKind._name === "Collection") {
                                    var containedkind = f.dataKind.parameters[0];
                                    var rt = containedkind.hasContext(1024 /* Json */) ? _this.reifyType(containedkind) : null;
                                    if (rt) {
                                        _this.wr("  this.perform_set(" + fieldname + ", " + "ctx.importCollection(json, this.perform_get(" + fieldname + ",s)," + _this.stringLiteral(f.getName()) + ", " + rt + "), s);\n");
                                    }
                                }
                                break;
                        }
                    }
                });
                this.wr("}\n");
                var id = this.globalVarId(r);
                this.initGlobals += "  if(!d.hasOwnProperty(" + this.stringLiteral(id) + ") || !d[" + this.stringLiteral(id) + "]) d." + id + " = new " + mkTable + "(d.libName);\n";
                this.initGlobals2 += "d." + id + ".name = \"" + r.getCoreName() + "\";";
                if (r.persistent) {
                    this.initGlobals2 += "d." + id + ".linked_cloudtables = [" + r.keys.fields().filter(function (f) { return f.dataKind instanceof AST.RecordEntryKind; }).map(function (ff) { return ("d." + _this.globalVarId(ff.dataKind.record)); }).join(", ") + "];\n";
                }
                this.resetGlobals += "  d." + id + " = undefined;\n";
                this.wr("cs.registerGlobal(" + this.stringLiteral(id) + ");\n");
            };
            Compiler.prototype.throwSyntaxError = function (a) {
                var _this = this;
                var str = function (s) { return _this.stringLiteral(s); };
                var userErr = function (msg, id) {
                    _this.wr("  TDev.Util.syntaxError(" + _this.stringLiteral(msg) + ", " + _this.stringLiteral(id) + ");\n");
                };
                if (a.hasErrors()) {
                    userErr(TDev.lf("function '{0}' (in '{1}') has errors and will not run", a.getName(), this.currentApp.getName()), a.getStableName());
                    return true;
                }
                else if (this.globalError) {
                    userErr(this.globalError, this.globalErrorId);
                    return true;
                }
                return false;
            };
            Compiler.prototype.visitInlinedAction = function (a) {
                var _this = this;
                this.inlineCurrentAction = true;
                this.localNameCtx = new QuotingCtx();
                this.actionName = "a_" + a.getStableName();
                this.currentAction = a;
                this.wr(this.comment("ACTION: " + a.getName() + " (inlined)") + "\n");
                this.wr("function " + this.actionName + "(s ");
                a.getInParameters().forEach(function (l) {
                    _this.wr(", " + _this.localVarName(l.local));
                });
                this.wr(") {\n");
                a._compilerBreakLabel = this.allocateLabel();
                if (this.throwSyntaxError(a)) {
                    this.wr("\n }\n");
                    return;
                }
                TDev.Util.assert(a.getOutParameters().length <= 1);
                if (a.getOutParameters().length > 0) {
                    var param = a.getOutParameters()[0];
                    if (param.local == undefined) {
                        this.wr("  var " + param.getName() + " = undefined;\n");
                    }
                }
                a.allLocals.forEach(function (l) {
                    if (!a.getInParameters().some(function (p) { return p.local == l; })) {
                        _this.wr("  var " + _this.localVarName(l) + " = undefined;\n");
                    }
                });
                var jsNodes = this.dispatch(a.body);
                jsNodes.push(a._compilerBreakLabel);
                var prevMax = this.maxArgsToCheck + 1;
                this.insertFinalLabels(jsNodes);
                jsNodes.forEach(function (n) { return n.forEachExpr(function (e) {
                    if (e instanceof JsLabelRef) {
                        e.label.refs.push(e);
                    }
                    if (e instanceof JsCall) {
                        var c = e;
                        if (c.method == "ok" && _this.maxArgsToCheck < c.args.length)
                            _this.maxArgsToCheck = c.args.length;
                    }
                    TDev.Util.assertCode(e !== _this.unit);
                }); });
                this.blockId = 1;
                this.tmpIdx = 0;
                this.markBlocks(jsNodes);
                jsNodes.forEach(function (n) { return n.injectEndIfJumps(); });
                this.dumpInlinedContents(jsNodes);
                if (a.getOutParameters().length > 0) {
                    var param = a.getOutParameters()[0];
                    if (param.local == undefined)
                        this.wr("  return " + param.getName() + ";\n");
                    else
                        this.wr("  return " + this.localVarRef(param.local) + ";\n");
                }
                this.wr("}\n");
                while (prevMax <= this.maxArgsToCheck)
                    this.emitOk(prevMax++);
                this.inlineCurrentAction = false;
            };
            Compiler.prototype.shouldCompile = function (d) {
                return d.visitorState === true;
            };
            Compiler.prototype.visitAction = function (a) {
                var _this = this;
                if (!this.shouldCompile(a))
                    return;
                this.numActions++;
                if (this.options.inlining && a.canBeInlined) {
                    this.numInlinedFunctions++;
                    return this.visitInlinedAction(a);
                }
                this.inlineCurrentAction = false;
                this.mapExprToVar = {};
                this.localNameCtx = new QuotingCtx();
                this.stepIdx = 0;
                var str = function (s) { return _this.stringLiteral(s); };
                this.actionName = "a_" + a.getStableName();
                this.currentAction = a;
                this.wr(this.comment("ACTION: " + a.getName()) + "\n");
                this.wr("function " + this.actionName + "(previous, returnAddr");
                a.getInParameters().forEach(function (l) {
                    _this.wr(", " + _this.localVarName(l.local));
                });
                var lab0 = this.allocateLabel();
                this.wr(") {\n");
                a._compilerBreakLabel = this.allocateLabel();
                if (a._compilerInlineAction)
                    a._compilerInlineAction._compilerBreakLabel = a._compilerBreakLabel;
                if (!this.throwSyntaxError(a)) {
                    this.wr("  var s = TDev.Runtime.mkStackFrame(previous, returnAddr);\n" + "  s.entryAddr = " + lab0.id + ";\n" + "  s.name = " + str((a._compilerParentAction || a).getName()) + ";\n");
                    if (a.getOutParameters().length > 1)
                        this.wr("  s.results = [];\n");
                    a.allLocals.forEach(function (l) {
                        _this.wr("  " + _this.localVarRef(l, true).toString() + " = ");
                        var ap = a.getInParameters().filter(function (p) { return p.local == l; })[0];
                        if (ap) {
                            if (l.isByRef() && !ap.isClosure)
                                _this.wr("{ref:" + _this.localVarName(l) + "}");
                            else
                                _this.wr(_this.localVarName(l));
                        }
                        else {
                            _this.wr("undefined");
                        }
                        _this.wr(";\n");
                    });
                    this.wr("  return s;\n");
                }
                this.wr("}\n");
                this.wr("cs.register" + (a.isLambda ? "Lambda" : a.isPage() ? "Page" : "Action") + "(" + str(a.getName()) + ", " + str(a.getStableName()) + ", " + this.actionName + (!a.isAtomic ? ", true" : ", false") + ");\n");
                if (a.isEvent()) {
                    var inf = a.eventInfo;
                    if (!inf.disabled) {
                        var varId = !inf.onVariable ? "null" : str(this.globalVarId(inf.onVariable));
                        this.wr("cs.registerEventHandler(" + str(inf.type.category) + ", " + varId + ", " + this.actionName + ");\n");
                    }
                }
                this.wr("\n");
                if (a.hasErrors() || !!this.globalError)
                    return;
                function setFlag(b, f) {
                    if (b)
                        b.flags |= f;
                }
                if (a.isPage()) {
                    setFlag(a.getPageBlock(true), 2 /* IsPageInit */);
                    setFlag(a.getPageBlock(false), 1 /* IsPageRender */);
                }
                if (this.needsProfiling())
                    this.profilingScopes.push(new JsTmpDef("profilingLastCallTimeStamp", new JsLiteral("0")));
                var jsNodes = this.dispatch(a.body);
                jsNodes.push(a._compilerBreakLabel);
                if (this.needsProfiling())
                    jsNodes.unshift(this.profilingScopes.pop());
                var cloudPicker = this.options.cloud && !a.isPrivate;
                if (cloudPicker || (a.isRunnable() && a.hasInParameters()))
                    jsNodes.unshift(this.synthesizePicker(a.getInParameters()));
                if (cloudPicker || (a.isRunnable() && a.hasOutParameters()))
                    jsNodes.push(this.synthesizeOutput(a.getOutParameters()));
                jsNodes.unshift(lab0);
                lab0.refs.push(lab0);
                var prevMax = this.maxArgsToCheck + 1;
                this.insertFinalLabels(jsNodes);
                jsNodes.forEach(function (n) { return n.forEachExpr(function (e) {
                    if (e instanceof JsLabelRef) {
                        e.label.refs.push(e);
                    }
                    if (e instanceof JsCall) {
                        var c = e;
                        if (c.method == "ok" && _this.maxArgsToCheck < c.args.length)
                            _this.maxArgsToCheck = c.args.length;
                    }
                    TDev.Util.assertCode(e !== _this.unit);
                }); });
                while (prevMax <= this.maxArgsToCheck)
                    this.emitOk(prevMax++);
                this.blockId = 1;
                this.tmpIdx = 0;
                this.markBlocks(jsNodes);
                jsNodes.forEach(function (n) { return n.injectEndIfJumps(); });
                jsNodes.push(new JsGoto(this.term("s.rt.leave()"), false));
                this.dumpFunction(jsNodes, 0);
                while (this.todo.length > 0) {
                    var f = this.todo.shift();
                    f();
                }
                this.debuggerLocalCtxs[a.stableId] = this.localNameCtx.getNameMapping();
                while (this.innerActions.length > 0) {
                    var aa = this.innerActions.shift();
                    aa.visitorState = true;
                    this.dispatch(aa);
                }
            };
            Compiler.prototype.recompileAction = function (a, cs) {
                this.initGlobals = "";
                this.initGlobals2 = "";
                this.maxArgsToCheck = 0;
                this.output = "";
                this.wr("'use strict';\n");
                this.wr("(function (cs) {\n");
                this.wr("var libs = cs.libs;\n");
                this.wr("var lib = TDev.RT;\n");
                this.dispatch(a);
                this.wr("})");
                cs.reinit(this.output);
            };
            Compiler.prototype.insertFinalLabels = function (nodes) {
                for (var i = 0; i < nodes.length; ++i) {
                    if (nodes[i] instanceof JsIf) {
                        var s = nodes[i];
                        nodes.splice(i + 1, 0, s.finalLabel);
                        this.insertFinalLabels(s.thenBody);
                        this.insertFinalLabels(s.elseBody);
                    }
                }
            };
            Compiler.prototype.markBlocks = function (nodes) {
                var _this = this;
                var mark = function (e) {
                    if (e instanceof JsTmpRef) {
                        var t = e;
                        if (_this.blockId != t.tmp.definitionPoint)
                            t.tmp.isLocal = false;
                    }
                };
                nodes.forEach(function (s) {
                    if (s instanceof JsIf) {
                        var i = s;
                        i.condition.forEachExpr(mark);
                        _this.markBlocks(i.thenBody);
                        _this.markBlocks(i.elseBody);
                        return;
                    }
                    else if (s instanceof JsTmpDef) {
                        var t = s;
                        t.definitionPoint = _this.blockId;
                        t.id = _this.tmpIdx++;
                    }
                    else if (s instanceof JsLabel) {
                        var l = s;
                        if (l.refs.length > 0)
                            _this.blockId++;
                    }
                    s.forEachExpr(mark);
                });
            };
            Compiler.prototype.dumpFunction = function (nodes, idx) {
                var lab = nodes[idx];
                this.wr("function " + lab.id + "(s) {\n");
                if (idx == 0)
                    this.libInits(lab.id);
                if (this.options.optimizeLoops) {
                    var head = nodes[idx + 1];
                    if (head instanceof JsIf && head.elseBody.length == 0) {
                        var last = head.thenBody.peek();
                        if (last instanceof JsGoto && last.isSimple(lab)) {
                            (function () {
                                var hasLabels = function (n) {
                                    for (var i = 0; i < n.length; ++i) {
                                        var ifs = n[i];
                                        if (ifs instanceof JsIf)
                                            if (hasLabels(ifs.thenBody) || hasLabels(ifs.elseBody))
                                                return true;
                                        if (n[i].isUsedLabel())
                                            return true;
                                    }
                                    return false;
                                };
                                var innerBody = head.thenBody.slice(0, head.thenBody.length - 1);
                                if (!hasLabels(innerBody)) {
                                    head.thenBody = innerBody;
                                    head.isWhile = true;
                                }
                            })();
                        }
                    }
                }
                else if (this.options.blockChaining) {
                    var head = nodes[idx + 1];
                    if (head instanceof JsIf && head.elseBody.length == 0) {
                        var last = head.thenBody.peek();
                        if (last instanceof JsGoto && last.isSimple(lab)) {
                            (function () {
                                var hasLabels = function (n) {
                                    for (var i = 0; i < n.length; ++i) {
                                        var ifs = n[i];
                                        if (ifs instanceof JsIf)
                                            if (hasLabels(ifs.thenBody) || hasLabels(ifs.elseBody))
                                                return true;
                                        if (n[i].isUsedLabel())
                                            return true;
                                    }
                                    return false;
                                };
                                var innerBody = head.thenBody.slice(0, head.thenBody.length - 1);
                                if (!hasLabels(innerBody)) {
                                    last.jumpsToOptimizedLoop = true;
                                    head.isWhile = true;
                                }
                            })();
                        }
                    }
                }
                this.dumpInner(nodes, idx + 1);
                this.wr("}\n");
                this.wr("cs.registerStep(" + lab.id + ", '" + lab.id + "');\n\n");
            };
            Compiler.prototype.dumpSimple = function (n) {
                this.wr("  " + n.toString() + "\n");
            };
            Compiler.prototype.dumpInner = function (nodes, idx) {
                var _this = this;
                while (idx < nodes.length) {
                    var n = nodes[idx];
                    if (n.isUsedLabel()) {
                        this.dumpSimple(JsGoto.simple(n));
                        this.todo.push(function () {
                            _this.dumpFunction(nodes, idx);
                        });
                        return;
                    }
                    else if (n.category() == 2 /* Goto */) {
                        this.dumpSimple(n);
                        while (++idx < nodes.length) {
                            if (nodes[idx].category() == 4 /* Label */) {
                                this.todo.push(function () {
                                    _this.dumpFunction(nodes, idx);
                                });
                                return;
                            }
                        }
                        return;
                    }
                    else if (n.category() == 3 /* If */) {
                        var i = n;
                        this.wr("  " + (i.isWhile ? "while" : "if") + " (" + i.condition.toString() + ") {\n");
                        this.dumpInner(i.thenBody, 0);
                        if (i.elseBody.length > 0) {
                            this.wr("  } else {\n");
                            this.dumpInner(i.elseBody, 0);
                        }
                        this.wr("  }\n");
                    }
                    else if (n.category() == 4 /* Label */) {
                    }
                    else {
                        this.dumpSimple(n);
                    }
                    idx++;
                }
            };
            Compiler.prototype.dumpInlinedContents = function (nodes) {
                var idx = 0;
                while (idx < nodes.length) {
                    var n = nodes[idx];
                    if (n.isUsedLabel()) {
                        TDev.Util.assert(false && !!"Should not have used labels in inlined function!");
                        return;
                    }
                    else if (n.category() == 2 /* Goto */) {
                        TDev.Util.assert(false && !!"Should not have Gotos in inlined function!");
                        return;
                    }
                    else if (n.category() == 3 /* If */) {
                        var i = n;
                        this.wr("  " + (i.isWhile ? "while" : "if") + " (" + i.condition.toString() + ") {\n");
                        this.dumpInlinedContents(i.thenBody);
                        if (i.elseBody.length > 0) {
                            this.wr("  } else {\n");
                            this.dumpInlinedContents(i.elseBody);
                        }
                        this.wr("  }\n");
                    }
                    else if (n.category() == 4 /* Label */) {
                    }
                    else {
                        this.dumpSimple(n);
                    }
                    idx++;
                }
            };
            Compiler.prototype.defaultValue = function (k, forPicker) {
                if (forPicker === void 0) { forPicker = false; }
                switch (k.getName()) {
                    case "Number": return "0";
                    case "String": return "\"\"";
                    case "Boolean": return "false";
                    case "DateTime": return "lib.DateTime.defaultValue";
                    case "Tile": return "lib.Tile.mkDefaultValue()";
                }
                if (!forPicker)
                    return null;
                switch (k.getName()) {
                    case "Collection": return "lib.Collection.fromArray([], " + (this.reifyType(k.getParameter(0)) || "null") + ")";
                }
                return null;
            };
            Compiler.prototype.addResourceAsFile = function (res) {
                if (/^([a-z0-9\-_][a-z0-9\-_\.]*\/)*[a-z0-9\-_][a-z0-9\-_\.]*\.[a-z0-9]+$/i.test(res.sourceName)) {
                    var resFile = TDev.Util.clone(res);
                    resFile.packageUrl = res.sourceName;
                    resFile.usageLevel = 1;
                    this.packageResources.push(resFile);
                }
            };
            Compiler.prototype.visitGlobalDef = function (d) {
                if (!this.shouldCompile(d))
                    return;
                if (d.isResource && !!d.url) {
                    var resourceId = this.globalVarId(d);
                    var resourceUrl = d.url;
                    if (this.options.packaging) {
                        var kindName = d.getKind().getName();
                        var qualId = this.options.libStaticPrefix + resourceId.replace(/\$/, "");
                        var suff = this.options.artUrlSuffix || "";
                        var resource = {
                            kind: 'art',
                            id: qualId,
                            url: resourceUrl,
                            packageUrl: null,
                            sourceName: d.getName(),
                            usageLevel: d.usageLevel,
                            type: kindName.toLowerCase()
                        };
                        if ((kindName === 'Picture' || kindName === 'Sound') && !/^data:\/\//i.test(resourceUrl)) {
                            resource.packageUrl = encodeURI('./art/' + qualId + suff);
                            resourceUrl = resource.packageUrl;
                            this.packageResources.push(resource);
                            this.addResourceAsFile(resource);
                        }
                        else if (kindName === 'String') {
                            if (!TDev.RT.String_.valueFromArtUrl(resourceUrl)) {
                                resource.packageUrl = encodeURI('./art/' + qualId + suff);
                                resourceUrl = resource.packageUrl;
                                this.packageResources.push(resource);
                            }
                            if (resourceUrl) {
                                var value = TDev.RT.String_.valueFromArtUrl(resourceUrl);
                                if (value) {
                                    resource.content = value;
                                    resource.url = undefined;
                                }
                                this.addResourceAsFile(resource);
                            }
                        }
                    }
                    if (d.usageLevel > 0 && resourceUrl)
                        this.wr("cs.registerArtResource(" + this.stringLiteral(d.getKind().runtimeName()) + ", " + this.stringLiteral(resourceId) + ", " + this.stringLiteral(resourceUrl) + ");\n");
                }
                if (d.cloudEnabled)
                    this.options.hasCloudData = true;
                else if (!d.isTransient)
                    this.options.hasLocalData = true;
                if (!d.isTransient && !d.hasErrors()) {
                    this.persistentvars.push({
                        local: !d.cloudEnabled,
                        name: d.getStableName(),
                        cloudtype: TDev.Revisions.Parser.MakeProperty(d.getStableName(), "global[]", AST.KindToCodomain(d.getKind()))
                    });
                }
                if (!d.isResource && !d.isTransient)
                    this.wr("cs.registerGlobal(" + this.stringLiteral(this.globalVarId(d)) + ");\n");
                var initVal = this.defaultValue(d.getKind());
                if (!!initVal) {
                    this.initGlobals += "  if(!d.hasOwnProperty(" + this.stringLiteral(this.globalVarId(d)) + ")) d." + this.globalVarId(d) + " = " + initVal + ";\n";
                }
                if (!d.getKind().isSerializable || d.isTransient) {
                    this.resetGlobals += "  d." + this.globalVarId(d) + " = " + (initVal || "undefined") + ";\n";
                }
            };
            Compiler.prototype.initPersistentVars = function (local) {
                var _this = this;
                var collect = this.persistentvars.filter(function (v) { return !!v.local === local; });
                if (collect.length == 0)
                    return;
                var pv = "  d.$$" + (local ? "local" : "cloud") + "persistentvars";
                this.wr(pv + " = new lib.PersistentVars(rt);\n");
                this.wr(pv + ".localsession = " + local.toString() + ";\n");
                this.wr(pv + ".libName = d.libName;\n");
                this.wr(pv + ".names = [" + collect.map(function (v) { return _this.stringLiteral("$" + v.name); }).join(", ") + "]; \n");
                this.wr(pv + ".cloudtypes = [" + collect.map(function (v) { return _this.stringLiteral(v.cloudtype); }).join(", ") + "]; \n");
                this.resetGlobals += (pv + " = undefined;\n");
            };
            Compiler.compileCore = function (a, cs, options) {
                var comp = new Compiler(options);
                a.setStableNames();
                var usage = new UsageComputer();
                usage.dispatch(a);
                comp.dispatch(a);
                cs.init(comp.output, comp.missingApis, comp.packageResources, !options.javascript);
                cs.localNamesBindings = comp.debuggerLocalCtxs;
                if (options.dynamic) {
                    a.recompiler = comp;
                    a.recompiledScript = cs;
                }
                cs.optStatistics.inlinedCalls += comp.numInlinedCalls;
                cs.optStatistics.inlinedFunctions += comp.numInlinedFunctions;
                cs.optStatistics.eliminatedOks += comp.numOkEliminations;
                cs.optStatistics.numActions += comp.numActions;
                cs.optStatistics.numStatements += comp.numStatements;
                cs.optStatistics.termsReused += comp.termsReused;
                cs.optStatistics.constantsPropagated += comp.constantsPropagated;
                cs.imports = comp.imports;
            };
            Compiler.annotateWithIds = function (a) {
                var compiled = [];
                var k = 0;
                a.libraries().forEach(function (l) {
                    var prev = compiled.filter(function (e) { return e.app == l.resolved; })[0];
                    if (!prev && l.resolved) {
                        AST.Json.setStableId(l.resolved, (++k) + ".");
                        compiled.push(l.resolved);
                    }
                });
                AST.Json.setStableId(a, "0.");
            };
            Compiler.getCompiledCode = function (that, options) {
                Object.keys(that.libScripts).forEach(function (name) {
                    that.libScripts[name].primaryName = null;
                });
                var res = "";
                if (options.cloud) {
                    res += "require('./noderuntime.js')\n" + "var TDev     = global.TDev;\n" + "var window   = global.TDev.window;\n" + "var document = global.TDev.window.document;\n";
                }
                else {
                    res += "var TDev;\n" + "if (!TDev) TDev = {};\n";
                }
                res += "\nTDev.precompiledScript = {\n";
                var first = true;
                Object.keys(that.libScripts).forEach(function (name) {
                    if (!first)
                        res += ",\n\n// **************************************************************\n";
                    first = false;
                    res += TDev.Util.jsStringLiteral(name) + ": ";
                    var cs = that.libScripts[name];
                    if (cs.primaryName)
                        res += TDev.Util.jsStringLiteral(cs.primaryName);
                    else {
                        cs.primaryName = name;
                        res += cs.code;
                    }
                });
                res += "}\n";
                if (options.cloud) {
                    res += "\nTDev.RT.Node.runMainAsync().done();\n";
                }
                return res;
            };
            Compiler.getCompiledScript = function (a, options, initialBreakpoints) {
                var prep = new PreCompiler(options);
                prep.run(a);
                var cs = new TDev.CompiledScript();
                cs.getCompiledCode = function () { return Compiler.getCompiledCode(cs, options); };
                a.clearRecompiler();
                var compiled = [];
                a.setStableNames();
                var k = 0;
                a.libraries().forEach(function (l) {
                    var prev = compiled.filter(function (e) { return e.app == l.resolved; })[0];
                    if (!prev) {
                        prev = { app: l.resolved, cs: new TDev.CompiledScript() };
                        if (prev.app) {
                            var opts = TDev.Util.flatClone(options);
                            opts.dynamic = false;
                            opts.isTopLevel = false;
                            AST.Json.setStableId(prev.app, (++k) + ".");
                            opts.libStaticPrefix = "l" + k + "_";
                            if (opts.debugging)
                                prev.cs.initBreakpoints = (initialBreakpoints || TDev.Hashtable.forStrings());
                            Compiler.compileCore(prev.app, prev.cs, opts);
                            if (opts.hasCloudData)
                                options.hasCloudData = true;
                            if (opts.hasPartialData)
                                options.hasPartialData = true;
                            if (opts.hasLocalData)
                                options.hasLocalData = true;
                        }
                        cs.missingApis.pushRange(prev.cs.missingApis);
                        cs.packageResources.pushRange(prev.cs.packageResources);
                    }
                    cs.registerLibRef(l.getStableName(), prev.cs);
                });
                AST.Json.setStableId(a, "0.");
                options.libStaticPrefix = "l0_";
                var reachingDefsTime = 0;
                var usedAnalysisTime = 0;
                var availableExpressionsTime = 0;
                var constantPropagationTime = 0;
                var inlineAnalysisTime = 0;
                var compileTime = 0;
                if (options.profiling || options.debugging)
                    options.inlining = false;
                if (options.inlining) {
                    try {
                        var iaCounter = TDev.RT.Perf.start("inlineanalysis");
                        var ia = new AST.InlineAnalysis();
                        ia.dispatch(a);
                        ia.nestedInlineAnalysis();
                        inlineAnalysisTime = TDev.RT.Perf.stop(iaCounter);
                    }
                    catch (err) {
                        TDev.Util.reportError('Inline Analysis failed', err, false);
                        inlineAnalysisTime = -1;
                        options.inlining = false;
                    }
                }
                if (options.okElimination) {
                    try {
                        var rdCounter = TDev.RT.Perf.start("reachingdefs");
                        var rd = new AST.ReachingDefinitions();
                        rd.visitApp(a);
                        reachingDefsTime = TDev.RT.Perf.stop(rdCounter);
                        var uaCounter = TDev.RT.Perf.start("usedanalysis");
                        var ua = new AST.UsedAnalysis();
                        ua.visitApp(a);
                        usedAnalysisTime = TDev.RT.Perf.stop(uaCounter);
                    }
                    catch (err) {
                        TDev.Util.reportError('Reaching Definitions failed', err, false);
                        reachingDefsTime = -1;
                        options.okElimination = false;
                    }
                }
                if (options.commonSubexprElim) {
                    var aeCounter = TDev.RT.Perf.start("availableexpressions");
                    var ae = new AST.AvailableExpressions();
                    ae.visitApp(a);
                    availableExpressionsTime = TDev.RT.Perf.stop(aeCounter);
                    try {
                    }
                    catch (err) {
                        TDev.Util.reportError('CSE failed', err, false);
                        availableExpressionsTime = -1;
                        options.commonSubexprElim = false;
                    }
                }
                if (options.constantPropagation) {
                    var cpCounter = TDev.RT.Perf.start("constantpropagation");
                    var cp = new AST.ConstantPropagation();
                    cp.visitApp(a);
                    constantPropagationTime = TDev.RT.Perf.stop(cpCounter);
                    try {
                    }
                    catch (err) {
                        TDev.Util.reportError('ConstantPropagation failed', err, false);
                        constantPropagationTime = -1;
                        options.constantPropagation = false;
                    }
                }
                var opts = TDev.Util.flatClone(options);
                opts.isTopLevel = true;
                if (options.debugging)
                    cs.initBreakpoints = (initialBreakpoints || TDev.Hashtable.forStrings());
                var beCounter = TDev.RT.Perf.start("backend");
                Compiler.compileCore(a, cs, opts);
                compileTime = TDev.RT.Perf.stop(beCounter);
                if (options.inlining) {
                    TDev.Util.log(TDev.Util.fmt("Inliner: {0} inlined call(s), {1} inlined action(s)", cs.optStatistics.inlinedCalls, cs.optStatistics.inlinedFunctions));
                }
                if (options.okElimination) {
                    TDev.Util.log(TDev.Util.fmt("Ok elimination: {0} check(s) eliminated (estimated)", cs.optStatistics.eliminatedOks));
                }
                if (options.commonSubexprElim) {
                    TDev.Util.log(TDev.Util.fmt("CSE: {0} term(s) reused (estimated)", cs.optStatistics.termsReused));
                }
                if (options.constantPropagation) {
                    TDev.Util.log(TDev.Util.fmt("CP: {0} constant(s) propagated (estimated)", cs.optStatistics.constantsPropagated));
                }
                cs.optStatistics.reachingDefsTime = reachingDefsTime;
                cs.optStatistics.usedAnalysisTime = usedAnalysisTime;
                cs.optStatistics.inlineAnalysisTime = inlineAnalysisTime;
                cs.optStatistics.availableExpressionsTime = availableExpressionsTime;
                cs.optStatistics.constantPropagationTime = constantPropagationTime;
                cs.optStatistics.compileTime = compileTime;
                return cs;
            };
            Compiler.prototype.compileLibs = function (a) {
                var _this = this;
                if (this.globalError) {
                    this.wr("cs.libBindings = {};\n");
                    return;
                }
                this.wr("(function () {\n");
                this.wr("  var lib, bnd, resolve;\n");
                this.wr("  var bnds = cs.libBindings = {};\n");
                a.librariesAndThis().forEach(function (l) {
                    var ln = _this.stringLiteral(l.getStableName());
                    _this.wr("  lib = libs[" + ln + "] = {};\n");
                    _this.wr("  bnd = bnds[" + ln + "] = " + (l.getStableName() == "this" ? "libs" : "{}") + ";\n");
                    _this.wr("  bnd.mkLambdaProxy = cs.mkLambdaProxy(bnd, " + ln + ");\n");
                    if (_this.options.scriptId) {
                        var libid = l.isThis() ? _this.options.scriptId : l.pubid ? l.pubid : l.guid;
                        if (l.resolved)
                            _this.wr("  bnd.scriptName = " + _this.stringLiteral(l.resolved.getName() + " (" + libid + ")") + ";\n");
                        _this.wr("  bnd.scriptId = " + _this.stringLiteral(libid) + ";\n");
                        _this.wr("  bnd.topScriptId = " + _this.stringLiteral(_this.options.scriptId) + ";\n");
                    }
                    l.getPublicActions().forEach(function (act) {
                        if (!_this.shouldCompile(act))
                            return;
                        var an = _this.stringLiteral(act.getName());
                        _this.wr("    lib[" + an + "] = cs.mkLibProxyFactory(bnd, " + ln + ", " + an + ");\n");
                    });
                });
                a.libraries().forEach(function (l) {
                    var ln = _this.stringLiteral(l.getStableName());
                    _this.wr("  bnd = bnds[" + ln + "];\n");
                    _this.wr("  bnd[\"this$lib\"] = " + ln + ";\n");
                    l.resolveClauses.forEach(function (r) {
                        var rn = _this.stringLiteral(r.formalLib.getStableName());
                        _this.wr("    resolve = bnd[" + rn + "] = {};\n");
                        _this.wr("    bnd[" + rn + " + \"$lib\"] = " + _this.stringLiteral(r.defaultLib.getStableName()) + ";\n");
                        r.actionBindings.forEach(function (ab) {
                            var fn = _this.stringLiteral(ab.actualLib.getStableName());
                            var act = "libs[" + fn + "][" + _this.stringLiteral(ab.actual.getName()) + "]";
                            _this.wr("      resolve[" + _this.stringLiteral(ab.formalName) + "] = " + act + ";\n");
                        });
                    });
                });
                this.wr("}());\n");
            };
            Compiler.prototype.visitApp = function (a) {
                var _this = this;
                this.stmtIds = StmtIdCollector.collect(a);
                if (this.options.isTopLevel) {
                    var libInits = [];
                    a.libraries().forEach(function (l) {
                        if (l.getLibInit())
                            libInits.push(l.getStableName());
                    });
                    if (libInits.length > 0) {
                        this.libInits = function (nm) {
                            _this.wr("  if (!s.rt._libinitDone) return s.rt.runLibInits(" + JSON.stringify(libInits) + ", " + nm + ");\n");
                        };
                    }
                }
                this.initGlobals = "";
                this.initGlobals2 = "";
                this.currentApp = a;
                this.needsScriptText = false;
                var err = this.currentApp.getGlobalErrorDecl(!this.options.isTopLevel);
                if (err) {
                    this.globalError = TDev.Util.fmt("'{0}' (in '{1}') has errors; the script will not run", err.getName(), this.currentApp.getName());
                    this.globalErrorId = err.getStableName();
                }
                else {
                    this.globalError = null;
                    this.globalErrorId = null;
                }
                this.runmap_variables.clear();
                this.wr("(function (cs) {\n");
                this.wr("'use strict';\n");
                this.wr("var libs = cs.libs = {};\n");
                this.wr("var lib = TDev.RT;\n");
                this.wr("var callstackcurdepth = 0;\n");
                if (this.needsProfiling()) {
                    this.wr("var profilingScriptStart = Date.now();\n");
                }
                if (this.debugBuild()) {
                    this.wr("cs.breakpointBindings = {};\n");
                    this.stmtIds.forEach(function (v) {
                        var varname = "bp$" + v.replace(/\./g, "_");
                        _this.wr("var " + varname + " = !!cs.initBreakpoints.get(" + _this.stringLiteral(v) + ");\n");
                        _this.wr("cs.breakpointBindings[" + _this.stringLiteral(v) + "] = { setter : function(smth) { " + varname + " = smth; }, getter: function () { return " + varname + "; } };\n");
                    });
                }
                this.wr("cs.scriptTitle = " + this.stringLiteral(a.getName()) + ";\n");
                this.wr("cs.scriptColor = " + this.stringLiteral(a.htmlColor()) + ";\n");
                this.wr("cs.objectSingletons = {};\n");
                if (a.showAd)
                    this.wr("cs.showAd = true;\n");
                a.things.forEach(function (t) { return _this.dispatch(t); });
                if (this.options.isTopLevel)
                    this.compileLibs(a);
                this.wr("cs.startFn = function(rt) {\n" + AST.api.rt_start + "};\n\n");
                this.wr("cs.stopFn = function(rt) {\n" + AST.api.rt_stop + "};\n\n");
                if (this.instrumentForCoverage()) {
                    this.wr("cs.extractRunMap = function(rt) {\n");
                    this.runmap_variables.forEach(function (v) { return _this.wr("    if(" + v[1] + ") rt.beenHere(" + _this.stringLiteral(v[0]) + ");\n"); });
                    this.wr("};\n\n");
                }
                if (!this.options.cloud && this.options.isTopLevel) {
                    this.imports.cordovaPlugins = AST.AppImports.combineCordovaPlugins(a);
                }
                if (this.options.cloud && this.options.isTopLevel) {
                    this.imports.pipPackages = AST.AppImports.combinePipPackages(a);
                    if (!a.isCloud) {
                        this.wr("cs.autoRouting = true;\n");
                        if (this.options.hasCloudData)
                            this.options.hostCloudData = true;
                    }
                    this.wr("cs.setupRestRoutes = function(rt) {\n");
                    var host = /^https?:\/\/(.+?)\/?$/i.exec(this.options.azureSite)[1];
                    a.librariesAndThis().stableSorted(function (l1, l2) { return l1.getStableName().localeCompare(l2.getStableName()); }).forEach(function (l) {
                        if (!l.isCloud())
                            return;
                        l.getPublicActions().stableSorted(function (a1, a2) { return a1.getName().localeCompare(a2.getName()); }).forEach(function (a) {
                            var ref = "libs[" + _this.stringLiteral(l.getStableName()) + "][" + _this.stringLiteral(a.getName()) + "]";
                            if (a.getName() == "_init") {
                                _this.wr("  rt.addRestInit(" + ref + ");\n");
                            }
                            else {
                                var name = (l.isThis() || l.getName() == "*") ? "" : l.getName() + "/";
                                if (a.getName() != "*")
                                    name += a.getName();
                                name = name.replace(/\/+$/, "");
                                _this.wr("  rt.addRestRoute(" + _this.stringLiteral(name) + ", " + ref + ");\n");
                            }
                            if (l.isThis() && a.getName() == "main")
                                _this.wr("  rt.setMainAction(" + ref + ");\n");
                        });
                    });
                    this.wr("  rt.nodeModules = {};\n");
                    var imports = AST.AppImports.combineNpmModules(a);
                    var deps = this.imports.npmModules;
                    Object.keys(imports).forEach(function (k) {
                        if (imports[k] == "error") {
                            _this.wr("  TDev.Util.syntaxError(" + _this.stringLiteral("node.js module version conflict on " + k) + ");\n");
                        }
                        else {
                            _this.wr("  rt.nodeModules." + TDev.Api.runtimeName(k) + " = require(" + _this.stringLiteral(k) + ");\n");
                            var v = imports[k];
                            if (v)
                                deps[k] = v;
                        }
                    });
                    this.wr("}\n\n");
                }
                this.wr("cs._compilerVersion = '" + Compiler.version + "';\n");
                this.wr("cs._initGlobals = function(d,rt) {\n" + this.initGlobals + "\n");
                this.initPersistentVars(true);
                this.initPersistentVars(false);
                this.wr("};\n\n");
                this.wr("cs._initGlobals2 = function(d) {\n" + this.initGlobals2 + "};\n\n");
                this.wr("cs._resetGlobals = function(d) {\n" + this.resetGlobals + "};\n\n");
                this.wr("cs._importJson = function(d,ctx,json) {\n" + this.cloudstateJsonImport + "};\n\n");
                this.wr("cs._exportJson = function(d,ctx) {\n" + "  var json = {};\n" + this.cloudstateJsonExport + "  return json;\n};\n\n");
                if (this.needsProfiling()) {
                    for (var blockId in this.profilingBlocks) {
                        this.wr("var profilingExecutions" + blockId + " = 1;\n");
                        this.wr("var profilingExecutionsNext" + blockId + " = 1;\n");
                        this.wr("var profilingExecutionsNextCount" + blockId + " = 1;\n");
                        var stmtIds = this.profilingBlocks[blockId];
                        for (var i = 0; i < stmtIds.length; i++) {
                            this.wr("var profilingDuration" + stmtIds[i] + " = 0;\n");
                            this.wr("var profilingDurationSamples" + stmtIds[i] + " = 0;\n");
                        }
                    }
                    this.wr("\n");
                    this.wr("var tmp = 0;\n\n");
                    this.wr("var perfNow = TDev.Util.perfNow;\n\n");
                    this.wr("cs._getProfilingResults = function() {\n");
                    this.wr("  var profilingDataCollection = {\n");
                    this.wr("    unitduration: " + localStorage["perfunit"] + ",\n");
                    this.wr("    compilerversion: '" + Compiler.version + "',\n");
                    this.wr("    astnodes: {},\n");
                    this.wr("    show: " + this.options.showProfiling + "\n");
                    this.wr("  };\n");
                    this.wr("  var astnodes = profilingDataCollection.astnodes;\n");
                    this.wr("  astnodes[''] = {count: 1, duration: (Date.now() - profilingScriptStart)};\n");
                    this.wr("  var hits;\n");
                    for (var blockId in this.profilingBlocks) {
                        var stmtIds = this.profilingBlocks[blockId];
                        for (var i = 0; i < stmtIds.length; i++) {
                            var stmtId = stmtIds[i];
                            var duration = "profilingDuration" + stmtId;
                            var samples = "profilingDurationSamples" + stmtId;
                            this.wr("  hits = profilingExecutionsNextCount" + blockId + "-" + "profilingExecutions" + blockId + ";\n");
                            var d = "Math.ceil(" + duration + "/" + samples + "*hits)";
                            this.wr("  if (hits) astnodes['" + stmtId + "'] = {count: hits, duration: " + d + "};\n");
                        }
                    }
                    if (this.needsProfilingDebug())
                        this.wr("  alert(JSON.stringify(profilingDataCollection));\n");
                    this.wr("  return profilingDataCollection;\n");
                    this.wr("};\n\n");
                }
                if (this.options.showCoverage)
                    this.wr("cs._showCoverage = true;\n");
                var main = a.mainAction();
                if (main)
                    this.wr("cs.mainActionName = " + this.stringLiteral(main.getName()) + ";\n");
                if (this.options.authorId)
                    this.wr("cs.authorId = " + this.stringLiteral(this.options.authorId) + ";\n");
                if (this.options.scriptId && !/-/.test(this.options.scriptId))
                    this.wr("cs.scriptId = " + this.stringLiteral(this.options.scriptId) + ";\n");
                if (this.options.scriptGuid)
                    this.wr("cs.scriptGuid = " + this.stringLiteral(this.options.scriptGuid) + ";\n");
                if (this.options.baseScriptId && !/-/.test(this.options.baseScriptId))
                    this.wr("cs.baseScriptId = " + this.stringLiteral(this.options.baseScriptId) + ";\n");
                if (this.options.logoUrl)
                    this.wr("cs.logoUrl = " + this.stringLiteral(this.options.logoUrl) + ";\n");
                if (this.options.hasCloudData)
                    this.wr("cs.hasCloudData = 1;\n");
                if (this.options.hasPartialData)
                    this.wr("cs.hasPartialData = 1;\n");
                if (this.options.azureSite)
                    this.wr("cs.azureSite = " + this.stringLiteral(this.options.azureSite) + ";\n");
                if (this.options.hasLocalData)
                    this.wr("cs.hasLocalData = 1;\n");
                if (this.options.hostCloudData)
                    this.wr("cs.hostCloudData = 1;\n");
                if (this.needsScriptText)
                    this.wr("var scriptText = " + this.stringLiteral(a.serialize()) + ";\n");
                if (this.options.isTopLevel && this.options.usedProperties.hasOwnProperty("appreflect"))
                    this.wr("cs.reflectionInfo = { actions: " + JSON.stringify(AST.Json.reflectionInfo(a)) + " };\n");
                if (this.options.packaging && this.options.artResolver) {
                    if (a.iconArtId)
                        this.packageResources.push({
                            kind: 'art',
                            id: "scripticon",
                            url: this.options.artResolver(a.iconArtId),
                            packageUrl: null,
                            sourceName: "icon",
                            usageLevel: 1,
                            type: "picture"
                        });
                    if (a.splashArtId)
                        this.packageResources.push({
                            kind: 'art',
                            id: "scriptsplash",
                            url: this.options.artResolver(a.splashArtId),
                            packageUrl: null,
                            sourceName: "splash",
                            usageLevel: 1,
                            type: "picture"
                        });
                }
                this.runmap_variables.forEach(function (v) { return _this.wr("var " + v[1] + ";\n"); });
                this.wr("})");
            };
            Compiler.prototype.synthesizeOutput = function (params) {
                var _this = this;
                var pickerIf = this.allocateIf();
                pickerIf.condition = this.term("s.previous.needsPicker");
                params = params.slice(0);
                var cloud = this.options.rest || this.options.cloud;
                if (!cloud)
                    params.reverse();
                pickerIf.thenBody = params.map(function (p) { return JsCall.direct((cloud ? "s.response.addRestResult" : "s.rt.displayResult"), [new JsLiteral(_this.stringLiteral(p.getName())), _this.localVarRef(p.local)]); });
                pickerIf.elseBody = [];
                return pickerIf;
            };
            Compiler.prototype.synthesizePicker = function (params) {
                var _this = this;
                var pickerIf = this.allocateIf();
                pickerIf.condition = this.term("s.previous.needsPicker");
                pickerIf.elseBody = [];
                var l = this.allocateLabel();
                var r = new JsLabelRef(l);
                var str = function (s) { return new JsLiteral(_this.stringLiteral(s)); };
                if (this.options.rest || this.options.cloud) {
                    pickerIf.thenBody = params.map(function (p) {
                        var kind = p.getKind();
                        var v = JsCall.direct("s.rt.getRestArgument", [str(p.getName()), (kind instanceof AST.RecordEntryKind) ? str(kind.record.getStableName()) : str(p.getKind().toString()), _this.term("s")]);
                        return _this.localVarRef(p.local).gets(v);
                    });
                    pickerIf.thenBody.push(this.term("s.response").gets(this.term("s.rt.getRestRequest().response()")));
                }
                else {
                    var args = params.map(function (p) { return !p.getKind().picker ? _this.term("undefined") : JsCall.direct("lib.RTValue.mkPicker", [_this.term(p.getKind().picker), _this.term(_this.defaultValue(p.getKind(), true)), str(p.getName()), str(_this.localVarName(p.local))]); });
                    args.unshift(r);
                    pickerIf.thenBody = [new JsExprStmt(JsCall.direct("s.rt.pickParameters", args)), new JsGoto(r, false), l];
                }
                return pickerIf;
            };
            Compiler.markUsedStuff = function (a) {
                var pre = new PreCompiler({});
                pre.run(a);
            };
            Compiler.version = "1";
            Compiler.restrictedIntOps = {
                "add": "Bits.add_int32",
                "subtract": "Bits.subtract_int32",
                "multiply": "Bits.multiply_int32",
                "divide": "Bits.divide_int32",
            };
            return Compiler;
        })(AST.NodeVisitor);
        AST.Compiler = Compiler;
        var UsageComputer = (function (_super) {
            __extends(UsageComputer, _super);
            function UsageComputer() {
                _super.apply(this, arguments);
            }
            UsageComputer.prototype.visitApp = function (a) {
                a.variablesAndResources().forEach(function (v) { return v.usageLevel = 0; });
                _super.prototype.visitChildren.call(this, a);
            };
            UsageComputer.prototype.visitDecl = function (d) {
                _super.prototype.visitChildren.call(this, d);
            };
            UsageComputer.prototype.visitStmt = function (s) {
                _super.prototype.visitChildren.call(this, s);
            };
            UsageComputer.prototype.visitExprHolder = function (eh) {
                if (eh.parsed)
                    this.dispatch(eh.parsed);
            };
            UsageComputer.prototype.doCall = function (c, outerFlags) {
                var p = c.getCalledProperty();
                if (p && p.forwardsTo() instanceof AST.GlobalDef) {
                    var gd = p.forwardsTo();
                    var lev = (outerFlags & 65536 /* NoCanvas */) ? 1 : 2;
                    if (gd.usageLevel < lev)
                        gd.usageLevel = lev;
                }
                var flags = p ? p.getFlags() : 0 /* None */;
                var a = c.args;
                for (var i = 0; i < a.length; ++i) {
                    if (a[i] instanceof AST.Call)
                        this.doCall(a[i], flags);
                    else
                        this.dispatch(a[i]);
                }
            };
            UsageComputer.prototype.visitCall = function (c) {
                this.doCall(c, 0 /* None */);
            };
            return UsageComputer;
        })(AST.NodeVisitor);
        var PreCompiler = (function (_super) {
            __extends(PreCompiler, _super);
            function PreCompiler(options) {
                _super.call(this);
                this.options = options;
                this.options.usedProperties = {};
            }
            PreCompiler.prototype.useKind = function (k) {
                var r = k.getRecord();
                if (r)
                    this.runOnDecl(r);
            };
            PreCompiler.prototype.useBuiltinProperty = function (p) {
                this.options.usedProperties[p.usageKey().toLowerCase()] = true;
            };
            PreCompiler.prototype.secondaryRun = function (app) {
                var _this = this;
                app.libraries().forEach(function (l) {
                    if (l.isTutorial() || l.isCloud()) {
                        l.getPublicActions().forEach(function (a) { return _this.runOnDecl(a); });
                    }
                    var li = l.getLibInit();
                    if (li)
                        _this.runOnDecl(li);
                });
            };
            return PreCompiler;
        })(AST.DeepVisitor);
        AST.PreCompiler = PreCompiler;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        AST.eventSigs = [
            { sig: "gameloop()", help: "raised many times per second", alt: "time->on every frame" },
            { sig: "shake()", help: "raised when device is shaken", alt: "senses->on shake" },
            { sig: "phone_face_up()", help: "raised when screen is facing up", alt: "senses->on phone face up" },
            { sig: "phone_face_down()", help: "raised when screen is facing down", alt: "senses->on phone face down" },
            { sig: "phone_portrait()", help: "raised when device is in the default screen orientation", alt: "senses->on phone portrait" },
            { sig: "phone_landscape_left()", help: "raised when device is rotated 90 degrees to the left", alt: "senses->on phone landscape left" },
            { sig: "phone_landscape_right()", help: "raised when device is rotated 90 degrees to the right", alt: "senses->on phone landscape right" },
            { sig: "active_song_changed()", help: "raised when the active song changes in the player" },
            { sig: "player_state_changed()", help: "raised when the player is paused, stopped or started" },
            { sig: "camera_button_half_pressed()", help: "not supported", obsolete: true },
            { sig: "camera_button_pressed()", help: "not supported", obsolete: true },
            { sig: "camera_button_released()", help: "not supported", obsolete: true },
            { sig: "empty_space_on_wall()", help: "not implemented yet" },
            { sig: "page_navigated_from()", help: "raised when a page is popped", alt: "wall->current page->on navigated from" },
            { sig: "cloud_data_updated()", help: "raised when cloud data was synchronized with the cloud" },
            { sig: "touch_down\\:_(Var:Board, x:Number, y:Number)", help: "" },
            { sig: "touch_up\\:_(Var:Board, x:Number, y:Number)", help: "" },
            { sig: "touch_over_(Var:Sprite_Set, sprite:Sprite, index_in_set:Number, x:Number, y:Number)", help: "" },
            { sig: "tap_board\\:_(Var:Board, x:Number, y:Number)", help: "raised when the board is tapped" },
            { sig: "swipe_board\\:_(Var:Board, x:Number, y:Number, delta_x:Number, delta_y:Number)", help: "raised when the board is swiped" },
            { sig: "tap_sprite_in_(Var:Sprite_Set, sprite:Sprite, index_in_set:Number, x:Number, y:Number)", help: "raised when a sprite from the sprite set is tapped" },
            { sig: "swipe_sprite_in_(Var:Sprite_Set, sprite:Sprite, index_in_set:Number, x:Number, y:Number, delta_x:Number, delta_y:Number)", help: "raised when a sprite from the sprite set is swipped" },
            { sig: "drag_sprite_in_(Var:Sprite_Set, sprite:Sprite, index_in_set:Number, x:Number, y:Number, delta_x:Number, delta_y:Number)", help: "raised when a sprite from the sprite set is dragged" },
            { sig: "tap_sprite\\:_(Var:Sprite, sprite:Sprite, x:Number, y:Number)", help: "raised when the sprite is tapped" },
            { sig: "swipe_sprite\\:_(Var:Sprite, sprite:Sprite, x:Number, y:Number, delta_x:Number, delta_y:Number)", help: "raised when the sprite is swiped" },
            { sig: "drag_sprite\\:_(Var:Sprite, sprite:Sprite, x:Number, y:Number, delta_x:Number, delta_y:Number)", help: "raised when the sprite is dragged" }
        ];
        var EventClass = (function () {
            function EventClass(p, sig) {
                this.globalKind = null;
                this.platform = 0 /* None */;
                this.lowPriority = false;
                var hds = sig.sig;
                this.help = sig.help;
                this.lowPriority = !!sig.obsolete;
                p.tokenize(hds);
                var hd = p.parseActionHeader();
                this.category = hd.name;
                this.inParameters = hd.inParameters.map(function (p) { return p.local; });
                if (this.inParameters.length > 0 && this.inParameters[0].getName() == "Var") {
                    this.globalKind = this.inParameters[0].getKind();
                    this.inParameters.shift();
                }
                if (/^phone_/.test(hds))
                    this.platform = 16384 /* Orientation */;
                else if (/^shake/.test(hds))
                    this.platform = 1 /* Accelerometer */;
                else if (/^(active_song_changed|player_state_changed)/.test(hds))
                    this.platform = 256 /* Media */;
                else if (/^camera_button/.test(hds)) {
                    this.platform = 4 /* Camera */;
                    this.lowPriority = true;
                }
                if (/^empty_space/.test(hds))
                    this.lowPriority = true;
            }
            return EventClass;
        })();
        AST.EventClass = EventClass;
        var EventInfo = (function () {
            function EventInfo(type) {
                this.type = type;
                this.disabled = false;
            }
            return EventInfo;
        })();
        AST.EventInfo = EventInfo;
        var EventMgr = (function () {
            function EventMgr() {
            }
            EventMgr.prototype.genericEvent = function () {
                return this.mkAction(this.eventClasses[0], "event");
            };
            EventMgr.prototype.init = function () {
                var _this = this;
                var p = new AST.Parser();
                this.eventClasses = AST.eventSigs.map(function (s) { return new EventClass(p, s); });
                AST.api.getKinds().forEach(function (k) {
                    if (k.isData && k.hasContext(256 /* WallTap */)) {
                        var ec = new EventClass(p, { sig: "evt()", help: "raised when a " + k.getName() + " is tapped on the wall" });
                        ec.category = "tap wall " + k.getName();
                        ec.lowPriority = k.getName() != "TextBox";
                        ec.inParameters = [AST.mkLocal("item", k)];
                        _this.eventClasses.push(ec);
                    }
                });
            };
            EventMgr.prototype.setInfo = function (a, p) {
                var name = a.getName();
                var clses = this.eventClasses.filter(function (c) { return name.slice(0, c.category.length) == c.category; });
                clses.sort(function (a, b) { return b.category.length - a.category.length; });
                var cls = clses[0];
                if (cls === undefined) {
                    a.isPrivate = true;
                    p.error("no such event category " + a.getName());
                }
                else {
                    a.setEventInfo(new EventInfo(cls));
                }
            };
            EventMgr.prototype.mkAction = function (ec, name) {
                var a = new AST.Action();
                a.parent = TDev.Script;
                a.header.inParameters.setChildren(ec.inParameters.map(function (p) { return new AST.ActionParameter(p.clone()); }));
                a.setName(name);
                a.body = AST.Parser.emptyBlock();
                a.body.parent = a.header;
                a.setEventInfo(new EventInfo(ec));
                return a;
            };
            EventMgr.prototype.availableEvents = function () {
                var _this = this;
                var existing = {};
                TDev.Script.events().forEach(function (a) {
                    existing[a.getName()] = true;
                });
                var res = [];
                this.eventClasses.forEach(function (ec) {
                    if (!TDev.Script.canUseCapability(ec.platform))
                        return;
                    var add = function (name) {
                        if (!existing[name]) {
                            res.push(_this.mkAction(ec, name));
                        }
                    };
                    if (!ec.globalKind) {
                        add(ec.category);
                    }
                    else {
                        TDev.Script.variables().forEach(function (d) {
                            if (d.getKind() == ec.globalKind)
                                add(ec.category + d.getName());
                        });
                    }
                });
                return res;
            };
            return EventMgr;
        })();
        AST.EventMgr = EventMgr;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var ExprParser;
        (function (ExprParser) {
            ExprParser.infixProps = null;
            function getInfixProperty(o) {
                if (ExprParser.infixProps == null) {
                    ExprParser.infixProps = {};
                    var api = TDev.api;
                    [api.core.Number, api.core.Boolean, api.core.String, api.core.Unknown].forEach(function (k) {
                        k.listProperties().forEach(function (p) {
                            if (p.getInfixPriority() > 0 && !ExprParser.infixProps[p.getName()])
                                ExprParser.infixProps[p.getName()] = p;
                        });
                    });
                }
                if (/^fun:/.test(o))
                    o = "fun";
                return ExprParser.infixProps[o];
            }
            var isDigit = function (c) { return /^[0-9]$/.test(c); };
            function mkComma(op0) {
                var r = new AST.StackOp();
                r.copyFrom(op0);
                r.type = "operator";
                r.infixProperty = getInfixProperty(",");
                r.op = ",";
                return r;
            }
            function mkZero(op0) {
                var r = new AST.StackOp();
                r.copyFrom(op0);
                r.type = "literal";
                r.expr = AST.mkLit(0.0);
                r.expr.loc = r;
                return r;
            }
            function parse0(tokens) {
                var dt;
                var res = [];
                for (var i = 0; i < tokens.length; ++i) {
                    tokens[i].clearError();
                }
                for (var i = 0; i < tokens.length; ++i) {
                    var t = tokens[i];
                    var r = new AST.StackOp();
                    r.type = t.nodeType();
                    r.tokens = tokens;
                    r.beg = i;
                    r.len = 1;
                    res.push(r);
                    switch (r.type) {
                        case "literal":
                        case "thingRef":
                            r.expr = t;
                            r.expr.loc = r;
                            break;
                        case "propertyRef":
                            r.propertyRef = t;
                            break;
                        case "operator":
                            dt = t.getText();
                            if (/^[0-9\.]$/.test(dt)) {
                                var seenDot = false;
                                var num = "";
                                var c = "";
                                while (i < tokens.length) {
                                    if (tokens[i].nodeType() !== "operator")
                                        break;
                                    c = tokens[i].getText();
                                    if (isDigit(c)) {
                                        num += c;
                                    }
                                    else if (c === "." && !seenDot) {
                                        num += c;
                                        seenDot = true;
                                    }
                                    else
                                        break;
                                    i++;
                                }
                                r.len = i - r.beg;
                                i--;
                                if (num === ".") {
                                    r.markError(TDev.lf("TD142: expecting a digit before or after the dot"));
                                    num = "0.0";
                                }
                                r.type = "literal";
                                var lit = AST.mkLit(parseFloat(num));
                                lit.stringForm = num;
                                r.expr = lit;
                                r.expr.loc = r;
                            }
                            else {
                                if (dt === "(" || dt === ")")
                                    r.prioOverride = -1;
                                else
                                    r.infixProperty = getInfixProperty(dt);
                                if (!r.prio())
                                    r.markError(TDev.lf("TD143: unknown operator {0}", dt));
                                r.op = dt;
                            }
                            break;
                        default:
                            TDev.Util.die();
                            break;
                    }
                }
                return res;
            }
            ExprParser.parse0 = parse0;
            function parse1(tokens0) {
                var tokens = parse0(tokens0);
                var currentTok = 0;
                if (tokens.length == 1 && tokens[0].prio() == AST.api.opStmtPriority) {
                    var z = mkZero(tokens[0]);
                    z.expr = AST.mkPlaceholderThingRef();
                    tokens.push(z);
                }
                function expect(op) {
                    var loc = null;
                    if (currentTok >= tokens.length)
                        loc = tokens.peek();
                    else
                        loc = tokens[currentTok];
                    if (currentTok >= tokens.length || loc.op !== op) {
                        loc.markError(TDev.lf("TD144: it seems you're missing '{0}', try adding it", op));
                        return false;
                    }
                    else {
                        currentTok++;
                        return true;
                    }
                }
                function reduceOps(stack, minPrio) {
                    if (minPrio == 4 || minPrio == 98)
                        minPrio++;
                    var top = stack.pop();
                    while (stack.length > 0 && stack.peek().prio() >= minPrio) {
                        var curOp = stack.pop();
                        var leftArg = stack.pop();
                        TDev.Util.assert(!!leftArg.expr);
                        var prop = curOp.infixProperty;
                        var args = [leftArg.expr, top.expr];
                        if (prop.getInfixPriority() > 0 && prop.getParameters().length === 1) {
                            args = [top.expr];
                        }
                        var endLoc = top.beg + top.len;
                        var newTop = new AST.StackOp();
                        newTop.tokens = top.tokens;
                        top = newTop;
                        var pr = AST.PropertyRef.mkProp(curOp.infixProperty);
                        top.expr = AST.mkCall(pr, args);
                        var op = curOp.tokens[curOp.beg];
                        if (op instanceof AST.Operator) {
                            op.call = top.expr;
                            pr.fromOp = op;
                        }
                        top.beg = leftArg.beg;
                        top.len = endLoc - top.beg;
                        TDev.Util.assert(!isNaN(top.len));
                        top.expr.loc = top;
                    }
                    stack.push(top);
                }
                function parseCallArgs(firstArg) {
                    var args = [];
                    var t = tokens[currentTok];
                    if (!t)
                        return [firstArg];
                    if (t.op === "(") {
                        currentTok++;
                        t = tokens[currentTok];
                        if (!t) {
                            expect(")");
                            return [firstArg];
                        }
                    }
                    else if (t.expr) {
                        t.markError(TDev.lf("TD145: there seem to be an operator (like '+', '(' or ',') missing here"));
                    }
                    else {
                        return [firstArg];
                    }
                    if (!!t && t.op == ")") {
                        currentTok++;
                        return [firstArg];
                    }
                    var e = parseParenFree(false);
                    args = e.flatten(TDev.api.core.TupleProp);
                    expect(")");
                    return [firstArg].concat(args);
                }
                function parseParenFree(isTop) {
                    var stack = [];
                    while (currentTok < tokens.length) {
                        var prev = stack.peek();
                        var op = tokens[currentTok++];
                        var prevExpr = prev != null ? prev.expr : null;
                        if (op.expr !== null) {
                            if (prev != null && prev.prio() === 0) {
                                op.markError(TDev.lf("TD145: there seem to be an operator (like '+', '(' or ',') missing here"));
                                stack.push(mkComma(op));
                            }
                            if (prev != null && prev.prioOverride == 98 && op.expr instanceof AST.Literal) {
                                op.expr.possiblyNegative = true;
                            }
                            stack.push(op);
                        }
                        else if (op.prio() > 0) {
                            if (prevExpr === null && op.op === "-") {
                                op.prioOverride = 98;
                                prev = mkZero(op);
                                stack.push(prev);
                            }
                            if (op.op === "not" || op.op == "async" || op.op == "await" || /^fun:/.test(op.op) || op.prio() == AST.api.opStmtPriority) {
                                if (prevExpr === null) {
                                    prev = mkZero(op);
                                    stack.push(prev);
                                }
                                else {
                                    op.markError(TDev.lf("TD146: we didn't expect '{0}' here", op.op));
                                }
                            }
                            if (!prev || !prev.expr) {
                                op.markError(TDev.lf("TD147: we didn't expect '{0}' here", op.op));
                                if (op.op == ",") {
                                    stack.push(mkZero(op));
                                    reduceOps(stack, op.prio());
                                    stack.push(op);
                                }
                            }
                            else {
                                reduceOps(stack, op.prio());
                                stack.push(op);
                            }
                        }
                        else if (op.type === "propertyRef") {
                            if (!prevExpr) {
                                if (stack.length > 1 && stack[stack.length - 2].expr !== null) {
                                    var stackTop = stack.pop();
                                    stackTop.markError(TDev.lf("TD148: we didn't expect {0} here", stackTop.op ? "'" + stackTop.op + "'" : TDev.lf("this")));
                                    prevExpr = stack.peek().expr;
                                }
                                else {
                                    op.markError(TDev.lf("TD149: property needs an expression in front"));
                                    continue;
                                }
                            }
                            else {
                                var end = op.beg + op.len;
                                op.beg = prev.beg;
                                op.len = end - op.beg;
                                stack.pop();
                            }
                            var args = parseCallArgs(prevExpr);
                            op.expr = AST.mkCall(op.propertyRef, args);
                            op.expr.loc = op;
                            var prevTok = tokens[currentTok - 1];
                            op.len = prevTok.beg + prevTok.len - op.beg;
                            TDev.Util.assert(!isNaN(op.len));
                            stack.push(op);
                        }
                        else if (op.prio() < 0) {
                            if (op.op === "(") {
                                if (prevExpr) {
                                    op.markError(TDev.lf("TD150: cannot call the thing before '('"));
                                    stack.push(mkComma(op));
                                }
                                var nl = new AST.StackOp();
                                nl.expr = parseParenFree(false);
                                nl.expr.loc = nl;
                                nl.copyFrom(op);
                                stack.push(nl);
                                if (!expect(")")) {
                                    op.markError(TDev.lf("TD151: unclosed '('"));
                                }
                                var lasttok = tokens[currentTok - 1];
                                nl.len = lasttok.beg + lasttok.len - op.beg;
                            }
                            else if (op.op === ")") {
                                if (isTop) {
                                    op.markError(TDev.lf("TD152: unexpected ')'"));
                                }
                                else {
                                    currentTok--;
                                    break;
                                }
                            }
                        }
                        else {
                            op.markError(TDev.lf("TD153: parse error"));
                        }
                    }
                    while (stack.length > 0) {
                        if (stack.peek().expr === null) {
                            stack.peek().markError(TDev.lf("TD154: the operator needs something after it"));
                            if (/^fun:/.test(stack.peek().op)) {
                                stack.push(mkZero(stack.peek()));
                                break;
                            }
                            else {
                                stack.pop();
                            }
                        }
                        else {
                            break;
                        }
                    }
                    reduceOps(stack, 0.1);
                    var t = stack.peek();
                    if (!t || !t.expr)
                        return AST.mkPlaceholderThingRef();
                    else
                        return t.expr;
                }
                return parseParenFree(true);
            }
            ExprParser.parse1 = parse1;
        })(ExprParser = AST.ExprParser || (AST.ExprParser = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Lexer;
        (function (Lexer) {
            var operators = [
                "+",
                "-",
                "*",
                "/",
                "=",
                "\u2260",
                "\u2264",
                "<",
                "\u2265",
                ">",
                ":=",
                "(",
                ")",
                ",",
                "\u2225",
                "\u2192",
                "$",
                "...",
                ";",
                "{",
                "}",
                "//",
                ":",
                "?",
                "[",
                "]",
                "\u267B"
            ];
            var asciiOps = {
                "!=": "\u2260",
                "<=": "\u2264",
                ">=": "\u2265",
                "||": "\u2225",
                "->": "\u2192",
                "`": "\u267B"
            };
            var invAsciiOps = {};
            var keywordList = [
                "for",
                "do",
                "foreach",
                "if",
                "then",
                "else",
                "action",
                "event",
                "table",
                "var",
                "script",
                "in",
                "while",
                "meta",
                "skip",
                "returns",
                "apply",
                "distinct",
                "reverse",
                "top",
                "bottom",
                "where",
                "order by",
                "transform to",
                "function",
                "global",
                "goto",
                "break",
                "continue",
                "return",
                "match",
                "switch",
                "case",
                "public",
                "private",
                "this",
                "self",
                "try",
                "finally",
                "catch",
                "throw",
                "and",
                "or",
                "not"
            ];
            var keywords = {};
            var jsRegexpChars = /[\\\(\)\|\[\]\^\$\.\?\+\*\{\}]/g;
            var operatorRx = /x/;
            function init() {
                var ops = operators.slice(0);
                for (var k in asciiOps)
                    if (asciiOps.hasOwnProperty(k)) {
                        ops.push(k);
                        invAsciiOps[asciiOps[k]] = k;
                    }
                ops.push("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".");
                ops.sort(function (a, b) { return b.length - a.length; });
                var opRx = "^(?:";
                var first = true;
                ops.forEach(function (s) {
                    if (!first)
                        opRx += "|";
                    first = false;
                    opRx += s.replace(jsRegexpChars, "\\$&");
                    keywords[s] = true;
                });
                operatorRx = new RegExp(opRx + ")");
                keywordList.forEach(function (s) {
                    keywords[s] = true;
                });
            }
            Lexer.init = init;
            function quotedOp(op) {
                return /^[a-zA-Z]/.test(op);
            }
            Lexer.quotedOp = quotedOp;
            function escapeStr(s, quoted, asciiOnly) {
                var sb = "";
                for (var i = 0; i < s.length; ++i) {
                    var c = s.charAt(i);
                    if (/[A-Za-z0-9]/.test(c))
                        sb += c;
                    else
                        switch (c) {
                            case "\\":
                            case "'":
                            case "\"":
                                sb += "\\" + c;
                                break;
                            case " ":
                                if (quoted)
                                    sb += c;
                                else
                                    sb += "_";
                                break;
                            case "_":
                                if (quoted)
                                    sb += c;
                                else
                                    sb += "\\_";
                                break;
                            case "\t":
                                sb += "\\t";
                                break;
                            case "\n":
                                sb += "\\n";
                                break;
                            case "\r":
                                sb += "\\r";
                                break;
                            default:
                                var k = c.charCodeAt(0);
                                if (!quoted || k < 32 || (asciiOnly && k > 127))
                                    sb += "\\u" + (k | 0x10000).toString(16).slice(-4);
                                else
                                    sb += c;
                                break;
                        }
                }
                return sb;
            }
            var isKeyword = function (id) { return keywords.hasOwnProperty(id); };
            function quoteId(id) {
                if (id == "")
                    return "\\j";
                var sb = "";
                if (isKeyword(id) || /^[0-9]/.test(id))
                    sb += "@";
                sb += escapeStr(id, false, true);
                return sb;
            }
            Lexer.quoteId = quoteId;
            function quoteString(id, useAscii) {
                return "\"" + escapeStr(id, true, useAscii) + "\"";
            }
            Lexer.quoteString = quoteString;
            function asciiOperator(id) {
                return invAsciiOps.hasOwnProperty(id) ? invAsciiOps[id] : id;
            }
            Lexer.asciiOperator = asciiOperator;
            var idBegChar = function (s) { return /[_\\A-Za-z]/.test(s); };
            var idMidChar = function (s) { return /[_\\A-Za-z0-9]/.test(s); };
            function tokenize(input) {
                var inputPos = 0;
                var res = [];
                function addTok(cat, d) {
                    TDev.Util.assert(typeof d == "string");
                    res.push(new LexToken(input, inputPos, cat, d));
                }
                function getId(delim) {
                    var sb = "";
                    var len = 0;
                    while (true) {
                        if (inputPos + len >= input.length)
                            break;
                        var c = input.charAt(inputPos + len++);
                        if (c == '\\') {
                            c = input.charAt(inputPos + len++);
                            switch (c) {
                                case 's':
                                    c = ' ';
                                    break;
                                case 't':
                                    c = '\t';
                                    break;
                                case 'n':
                                    c = '\n';
                                    break;
                                case 'r':
                                    c = '\r';
                                    break;
                                case 'q':
                                    c = '\"';
                                    break;
                                case 'j':
                                    c = '';
                                    break;
                                case 'z':
                                    c = '\u0000';
                                    break;
                                case '_':
                                    c = '_';
                                    break;
                                case 'x':
                                    var hex = input.slice(inputPos + len, inputPos + len + 2);
                                    if (!/^[a-f0-9]+$/i.test(hex)) {
                                        error("invalid \\x sequence");
                                        sb += "\\";
                                    }
                                    else {
                                        c = String.fromCharCode(parseInt(hex, 16));
                                        len += 2;
                                    }
                                    break;
                                case 'u':
                                    var hex = input.slice(inputPos + len, inputPos + len + 4);
                                    if (!/^[a-f0-9]+$/i.test(hex)) {
                                        error("invalid unicode sequence");
                                        sb += "\\";
                                    }
                                    else {
                                        c = String.fromCharCode(parseInt(hex, 16));
                                        len += 4;
                                    }
                                    break;
                                default:
                                    if (/[A-Za-z0-9]/.test(c)) {
                                        error("invalid escape sequence");
                                        sb += "\\";
                                    }
                                    break;
                            }
                            sb += c;
                        }
                        else {
                            if (delim != null) {
                                if (c == delim)
                                    break;
                                else
                                    sb += c;
                            }
                            else {
                                if (c == '_')
                                    sb += ' ';
                                else if (idMidChar(c))
                                    sb += c;
                                else {
                                    len--;
                                    break;
                                }
                            }
                        }
                    }
                    inputPos += len;
                    return sb;
                }
                function error(msg) {
                    addTok(6 /* Error */, msg);
                }
                while (inputPos < input.length) {
                    var c = input.charAt(inputPos);
                    if (/[ \t\n\r]/.test(c)) {
                        inputPos++;
                        continue;
                    }
                    if (c == '@' && idMidChar(input.charAt(inputPos + 1))) {
                        inputPos++;
                        addTok(1 /* Id */, getId(null));
                    }
                    else if (c == "\"" || c == "'") {
                        inputPos++;
                        addTok(3 /* String */, getId(c));
                    }
                    else if (c == "`") {
                        inputPos++;
                        addTok(0 /* Op */, getId(c));
                    }
                    else if (c == '#') {
                        inputPos++;
                        if (input.charAt(inputPos) == '@')
                            inputPos++;
                        addTok(5 /* Label */, getId(null));
                    }
                    else if (idBegChar(c)) {
                        var id = getId(null);
                        if (/^(and|or|not)$/.test(id))
                            addTok(0 /* Op */, id);
                        else if (isKeyword(id))
                            addTok(2 /* Keyword */, id);
                        else
                            addTok(1 /* Id */, id);
                    }
                    else {
                        var possibleOp = input.slice(inputPos, inputPos + 3);
                        var matchRes = operatorRx.exec(possibleOp);
                        var rs = null;
                        if (!!matchRes)
                            rs = matchRes[0];
                        if (!!rs) {
                            inputPos += rs.length;
                            if (rs == "//") {
                                addTok(4 /* Comment */, getId('\n').trim());
                            }
                            else {
                                rs = asciiOps[rs] || rs;
                                addTok(0 /* Op */, rs);
                            }
                        }
                        else {
                            error("unexpected character " + c);
                            inputPos++;
                        }
                    }
                }
                addTok(7 /* EOF */, "");
                return res;
            }
            Lexer.tokenize = tokenize;
        })(Lexer = AST.Lexer || (AST.Lexer = {}));
        var LexToken = (function () {
            function LexToken(input, inputPos, category, data) {
                this.input = input;
                this.inputPos = inputPos;
                this.category = category;
                this.data = data;
            }
            LexToken.prototype.toString = function () {
                return this.data;
            };
            return LexToken;
        })();
        AST.LexToken = LexToken;
        (function (TokenType) {
            TokenType[TokenType["Op"] = 0] = "Op";
            TokenType[TokenType["Id"] = 1] = "Id";
            TokenType[TokenType["Keyword"] = 2] = "Keyword";
            TokenType[TokenType["String"] = 3] = "String";
            TokenType[TokenType["Comment"] = 4] = "Comment";
            TokenType[TokenType["Label"] = 5] = "Label";
            TokenType[TokenType["Error"] = 6] = "Error";
            TokenType[TokenType["EOF"] = 7] = "EOF";
        })(AST.TokenType || (AST.TokenType = {}));
        var TokenType = AST.TokenType;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Parser = (function () {
            function Parser() {
                this.libRefs = {};
                this.currentLabel = [];
                this.declarationCallbacks = {
                    "action": this.parseAction,
                    "event": this.parseAction,
                    "meta": this.parseMetaDecl,
                    "var": AST.GlobalDef.parse,
                    "table": AST.RecordDef.parse
                };
                this.statementCallbacks = {
                    "meta": this.parseMetaStmt,
                    "skip": this.parseSkip,
                    "for": Parser.stmtCtor(AST.For),
                    "foreach": Parser.stmtCtor(AST.Foreach),
                    "while": Parser.stmtCtor(AST.While),
                    "if": Parser.stmtCtor(AST.If),
                    "else": this.parseElseIf,
                    "do": this.parseDo,
                    "where": this.parseWhere,
                    "var": this.parseField,
                };
            }
            Parser.stmtCtor = function (f) {
                return function (p) {
                    var r = new f();
                    p.stmtList.push(r);
                    r.parseFrom(p);
                };
            };
            Parser.prototype.errorLoc = function (loc, msg) {
                var args = [];
                for (var _i = 2; _i < arguments.length; _i++) {
                    args[_i - 2] = arguments[_i];
                }
                debugger;
                this.errors.push(new ParseError(loc, TDev.Util.fmt_va(msg, args)));
            };
            Parser.prototype.error = function (msg) {
                var args = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    args[_i - 1] = arguments[_i];
                }
                debugger;
                this.errors.push(new ParseError(this.curr(), TDev.Util.fmt_va(msg, args)));
            };
            Parser.prototype.getLibraryRef = function (name) {
                if (name == "this")
                    return this.currentApp.thisLibRef;
                var existing = this.currentApp && this.currentApp.libraries().filter(function (l) { return l.getName() == name; })[0];
                if (existing)
                    return existing;
                if (this.libRefs.hasOwnProperty(name))
                    return this.libRefs[name];
                var l = new AST.LibraryRef();
                this.libRefs[name] = l;
                l.setName(name);
                this.declList.push(l);
                return l;
            };
            Parser.prototype.declareLibrary = function (l) {
                var idx = this.declList.indexOf(l);
                this.declList.splice(idx, 1);
                this.declList.push(l);
            };
            Parser.prototype.consumeLabel = function () {
                var r = this.currentLabel;
                this.currentLabel = [];
                return r;
            };
            Parser.prototype.featureMissing = function (f) {
                if (!this.currentApp)
                    return false;
                return this.currentApp.featureMissing(f);
            };
            Parser.prototype.lookahead = function (n) {
                var t = this.tokens[this.tokenPos + n];
                if (!t)
                    return this.tokens[this.tokens.length - 1];
                return t;
            };
            Parser.prototype.curr = function () {
                return this.tokens[this.tokenPos];
            };
            Parser.prototype.got = function (t) {
                return this.curr().category == t;
            };
            Parser.prototype.gotOp = function (s) {
                return this.got(0 /* Op */) && this.curr().data == s;
            };
            Parser.prototype.gotKw = function (s) {
                return this.got(2 /* Keyword */) && this.curr().data == s;
            };
            Parser.prototype.gotId = function (s) {
                return this.got(1 /* Id */) && this.curr().data == s;
            };
            Parser.prototype.tokenize = function (s) {
                var _this = this;
                this.errors = [];
                this.stmtList = [];
                this.declList = [];
                this.currentAction = null;
                this.currentApp = null;
                var toks = AST.Lexer.tokenize(s);
                toks.forEach(function (l) {
                    if (l.category == 6 /* Error */)
                        _this.errorLoc(l, l.data);
                });
                this.tokenPos = 0;
                this.tokens = toks.filter(function (l) { return l.category != 6 /* Error */; });
            };
            Parser.parseEndpoint = function (text, f, errs, script) {
                var p = new Parser();
                p.tokenize(text);
                p.currentApp = script || TDev.Script;
                var r = f(p);
                if (errs)
                    errs.pushRange(p.errors.map(function (e) { return e.toString(); }));
                else
                    p.handleErrors();
                return r;
            };
            Parser.parseType = function (text, script) {
                if (script === void 0) { script = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseType(); }, null, script);
            };
            Parser.parseExprHolder = function (text, script) {
                if (script === void 0) { script = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseExpr(); }, null, script);
            };
            Parser.parseStmt = function (text, script) {
                if (script === void 0) { script = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseOneStmt(); }, null, script);
            };
            Parser.parseDecl = function (text, script) {
                if (script === void 0) { script = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseOneDecl(); }, null, script);
            };
            Parser.parseDecls = function (text, script) {
                if (script === void 0) { script = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseManyDecls(); }, null, script);
            };
            Parser.parseScript = function (text, errs) {
                if (errs === void 0) { errs = null; }
                return Parser.parseEndpoint(text, function (p) { return p.parseApp(); }, errs, null);
            };
            Parser.prototype.handleErrors = function () {
                var errors = this.errors.map(function (e) { return e.toString(); }).join("\n");
                if (errors != "") {
                    TDev.Util.log("Parse error: " + errors);
                    debugger;
                }
            };
            Parser.prototype.gotKey = function (s) {
                var t = this.curr();
                if (t.data == s) {
                    this.shift();
                    if (this.gotOp("=") || this.gotOp(":="))
                        this.shift();
                    return true;
                }
                return false;
            };
            Parser.prototype.trySkipId = function (s) {
                if (this.gotId(s)) {
                    this.shift();
                    return true;
                }
                else
                    return false;
            };
            Parser.prototype.gotTerminator = function () {
                switch (this.curr().category) {
                    case 2 /* Keyword */:
                    case 7 /* EOF */:
                    case 5 /* Label */:
                        return true;
                    case 0 /* Op */:
                        switch (this.curr().data) {
                            case ";":
                            case "{":
                            case "}":
                                return true;
                        }
                }
                return false;
            };
            Parser.prototype.shift = function () {
                var r = this.curr();
                if (r.category != 7 /* EOF */)
                    this.tokenPos++;
                return r;
            };
            Parser.prototype.skipOp = function (s) {
                if (this.gotOp(s))
                    this.shift();
                else
                    this.error("expecting operator {0}, got {1}", s, this.curr());
            };
            Parser.prototype.skipKw = function (s) {
                if (this.gotKw(s))
                    this.shift();
                else
                    this.error("expecting keyword {0}, got {1}", s, this.curr());
            };
            Parser.prototype.parseString = function () {
                if (!this.got(3 /* String */)) {
                    this.error("expecting string, got {0}", this.curr());
                    this.shift();
                    return "";
                }
                else
                    return this.shift().data;
            };
            Parser.prototype.parseBool = function () {
                return this.parseId() == "true";
            };
            Parser.prototype.parseLibRef = function () {
                if (this.gotOp(AST.libSymbol)) {
                    this.shift();
                    return this.getLibraryRef(this.parseId("this"));
                }
                else {
                    this.error("expecting library reference, got {0}", this.curr());
                    return this.getLibraryRef("this");
                }
            };
            Parser.prototype.parseId = function (defl) {
                if (defl === void 0) { defl = "?"; }
                if (!this.got(1 /* Id */)) {
                    this.error("expecting identifier, got {0}", this.curr());
                    this.shift();
                    return defl;
                }
                else {
                    return this.shift().data;
                }
            };
            Parser.prototype.parseType = function () {
                if (this.gotOp(AST.libSymbol)) {
                    var lib = this.parseLibRef();
                    this.skipOp("\u2192");
                    if (this.got(1 /* Id */))
                        return lib.getAbstractKind(this.parseId());
                }
                var forceRecord = false;
                if (this.gotOp("*")) {
                    this.shift();
                    forceRecord = true;
                }
                var n = this.parseId();
                var k = forceRecord ? new TDev.UnresolvedKind(n) : AST.api.getKind(n);
                if (!k && / field$/.test(n)) {
                    n = n.slice(0, n.length - 6);
                    if (/^Collection of /.test(n))
                        n = n.slice(14) + " Collection";
                    k = AST.api.getKind(n);
                }
                var collKind = null;
                switch (n) {
                    case "Appointment Collection":
                        collKind = AST.api.getKind("Appointment");
                        break;
                    case "Contact Collection":
                        collKind = AST.api.getKind("Contact");
                        break;
                    case "Link Collection":
                        collKind = AST.api.getKind("Link");
                        break;
                    case "Location Collection":
                        collKind = AST.api.getKind("Location");
                        break;
                    case "Message Collection":
                        collKind = AST.api.getKind("Message");
                        break;
                    case "Number Collection":
                        collKind = AST.api.core.Number;
                        break;
                    case "Page Collection":
                        collKind = AST.api.getKind("Page");
                        break;
                    case "Place Collection":
                        collKind = AST.api.getKind("Place");
                        break;
                    case "String Collection":
                        collKind = AST.api.core.String;
                        break;
                }
                if (collKind)
                    k = AST.api.core.Collection.createInstance([collKind]);
                if (!k) {
                    if (/ Collection$/.test(n))
                        k = AST.api.core.Collection.createInstance([new TDev.UnresolvedKind(n.slice(0, n.length - 11))]);
                    else
                        k = new TDev.UnresolvedKind(n);
                }
                if (n == "Unknown")
                    k = AST.api.core.String;
                if (!k) {
                    this.error("unknown type {0}", n);
                    k = AST.api.core.Unknown;
                }
                if (this.gotOp("[")) {
                    this.shift();
                    var parms = [];
                    while (true) {
                        var t = this.parseType();
                        parms.push(t);
                        if (this.gotOp("]")) {
                            this.shift();
                            break;
                        }
                        else if (this.gotOp(",")) {
                            this.shift();
                            continue;
                        }
                        else {
                            this.error("bad type syntax");
                            break;
                        }
                    }
                    if (k instanceof TDev.ParametricKind) {
                        var pk = k;
                        var numF = pk.parameters.length;
                        if (parms.length > numF) {
                            this.error("too many type arguments");
                            parms = parms.slice(0, numF);
                        }
                        else if (parms.length < numF) {
                            this.error("too few type arguments");
                            while (parms.length < numF)
                                parms.push(AST.api.core.Nothing);
                        }
                        k = pk.createInstance(parms);
                    }
                    else {
                        this.error("{0} is not parametric type", k.getName());
                    }
                }
                return k;
            };
            Parser.prototype.parseTypeAnnotation = function () {
                this.skipOp(":");
                return this.parseType();
            };
            Parser.prototype.addDecl = function (s) {
                this.declList.push(s);
            };
            Parser.prototype.addStmt = function (s) {
                this.stmtList.push(s);
            };
            Parser.prototype.parseElseIf = function () {
                this.shiftLabel();
                this.skipKw("if");
                var r = new AST.If();
                this.stmtList.push(r);
                r.isElseIf = true;
                r.parseFrom(this);
            };
            Parser.prototype.parseParameters = function (lbl, sep, out) {
                if (out === void 0) { out = false; }
                var parens = false;
                var res = [];
                if (this.gotOp("(")) {
                    this.shift();
                    parens = true;
                }
                var index = 0;
                while (true) {
                    if (parens && this.gotOp(")")) {
                        this.shift();
                        break;
                    }
                    this.shiftLabel();
                    var lbl2 = this.consumeLabel();
                    if (this.gotTerminator())
                        break;
                    var n = this.parseId();
                    var t = this.parseTypeAnnotation();
                    var loc = AST.mkLocal(n, t);
                    var ap = new AST.ActionParameter(loc, out);
                    ap.setStableName(lbl2);
                    index++;
                    res.push(ap);
                    if (this.gotOp(","))
                        this.shift();
                }
                return res;
            };
            Parser.prototype.parseActionHeader = function (lbl) {
                if (lbl === void 0) { lbl = ""; }
                var isType = false;
                while (this.got(0 /* Op */) && !this.gotTerminator()) {
                    if (this.gotOp("type")) {
                        isType = true;
                    }
                    else {
                        this.error("expecting identifier, got {0}", this.curr());
                    }
                    this.shift();
                }
                var res = {
                    name: this.parseId(),
                    inParameters: [],
                    outParameters: [],
                    isType: isType,
                };
                res.inParameters = this.parseParameters(lbl, "_3");
                if (this.gotKw("returns")) {
                    this.shift();
                    res.outParameters = this.parseParameters(lbl, "_4", true);
                }
                return res;
            };
            Parser.prototype.parseTokenSequenceStmt = function () {
                var eh = this.parseTokenSequence();
                if (eh != null)
                    this.addStmt(AST.mkExprStmt(eh, this));
            };
            Parser.emptyExpr = function () {
                var eh = new AST.ExprHolder();
                eh.tokens = [];
                eh.locals = [];
                eh.parsed = AST.mkPlaceholderThingRef();
                return eh;
            };
            Parser.prototype.parseExpr = function () {
                var eh = this.parseTokenSequence();
                if (eh == null) {
                    eh = Parser.emptyExpr();
                }
                return eh;
            };
            Parser.prototype.parseTokenSequence = function () {
                var toks = [];
                var t;
                var add = function (tp, json) {
                    if (json === void 0) { json = undefined; }
                    if (json === undefined)
                        json = {};
                    json.type = tp;
                    if (json.data === undefined)
                        json.data = t.data;
                    toks.push(AST.mkTok(json));
                };
                while (true) {
                    if (this.gotTerminator())
                        break;
                    t = this.curr();
                    switch (t.category) {
                        case 0 /* Op */:
                            if (t.data == "...") {
                                add("thingRef", { data: "$skip" });
                            }
                            else if (t.data == "$") {
                                this.shift();
                                var pos = this.tokenPos;
                                var id = this.parseId();
                                this.tokenPos = pos;
                                add("thingRef", { data: id, forceLocal: true });
                            }
                            else if (t.data == "[") {
                                var annot = [];
                                this.shift();
                                while (this.curr().category == 1 /* Id */) {
                                    annot.push(this.curr().data);
                                    this.shift();
                                }
                                this.skipOp("]");
                                this.tokenPos--;
                                if (annot[0] == "lib") {
                                    var l = toks.peek();
                                    if (l instanceof AST.ThingRef) {
                                        l._namespaceLibraryName = annot[1];
                                    }
                                }
                            }
                            else {
                                add("operator");
                            }
                            break;
                        case 1 /* Id */:
                            if (toks.peek() instanceof AST.Operator) {
                                var pt = toks.peek().data;
                                if (pt == "→")
                                    toks[toks.length - 1] = AST.mkPropRef(t.data);
                                else if (pt == "♻") {
                                    toks[toks.length - 1] = AST.mkThing(pt);
                                    add("propertyRef");
                                }
                                else {
                                    add("thingRef");
                                }
                            }
                            else {
                                add("thingRef");
                            }
                            break;
                        case 3 /* String */:
                            add("literal", { kind: "String" });
                            break;
                        case 4 /* Comment */:
                            break;
                        case 2 /* Keyword */:
                        case 7 /* EOF */:
                            TDev.Util.die();
                            break;
                        default:
                            TDev.Util.die();
                            break;
                    }
                    this.shift();
                }
                if (TDev.Cloud.isRestricted()) {
                    toks.forEach(function (t, i) {
                        if (t instanceof AST.PropertyRef && t.getText() == "plot image" && toks[i - 1] instanceof AST.ThingRef && toks[i - 1].getText() == "basic" && toks[i + 3] && toks[i + 1].getOperator() == "(" && toks[i + 2].getStringLiteral() != null && toks[i + 3].getOperator() == ")") {
                            t.data = "show leds";
                            toks.splice(i + 3, 0, AST.mkOp(","), AST.mkOp("4"), AST.mkOp("0"), AST.mkOp("0"));
                        }
                    });
                }
                if (toks.length > 0) {
                    var r = new AST.ExprHolder();
                    if (toks.length > 300)
                        toks = toks.slice(0, 300);
                    r.tokens = toks;
                    return r;
                }
                else {
                    return null;
                }
            };
            Parser.emptyBlock = function () {
                var r = new AST.CodeBlock();
                r.setChildren([Parser.emptyExprStmt()]);
                return r;
            };
            Parser.prototype.parseBlock = function () {
                var _this = this;
                var nesting = 0;
                var loc0 = this.curr();
                var elseStack = [];
                var mkCodeBlock = function (stmts) {
                    var r = new AST.CodeBlock();
                    if (stmts.length == 0)
                        stmts.push(r.emptyStmt());
                    r.setChildren(stmts);
                    return r;
                };
                var unwind1 = function () {
                    var br = elseStack.pop();
                    var curr = _this.stmtList;
                    _this.stmtList = br.stmtList;
                    if (br.ifStmt) {
                        if (curr[0] instanceof AST.If && curr.slice(1).every(AST.isElseIf)) {
                            curr[0].isElseIf = true;
                            _this.stmtList.pushRange(curr);
                        }
                        else {
                            br.ifStmt.setElse(mkCodeBlock(curr));
                        }
                    }
                    else if (elseStack.length == 0) {
                        return mkCodeBlock(curr);
                    }
                    else {
                        _this.stmtList.pushRange(curr);
                    }
                    return null;
                };
                var unwind = function () {
                    while (true) {
                        var r = unwind1();
                        if (r)
                            return r;
                    }
                };
                var pushBrace = function (ifStmt) {
                    if (ifStmt === void 0) { ifStmt = null; }
                    elseStack.push({
                        stmtList: _this.stmtList,
                        ifStmt: ifStmt,
                    });
                    _this.stmtList = [];
                };
                if (this.gotOp("{"))
                    this.shift();
                else
                    this.error("expecting {{ at the beginning of the block, got {0}", this.curr());
                pushBrace();
                while (true) {
                    var t = this.curr();
                    switch (t.category) {
                        case 0 /* Op */:
                            switch (t.data) {
                                case "}":
                                    this.shift();
                                    var r = unwind1();
                                    if (r)
                                        return r;
                                    break;
                                case "{":
                                    this.shift();
                                    pushBrace();
                                    break;
                                case ";":
                                    this.shift();
                                    break;
                                default:
                                    this.parseStmtCore();
                                    break;
                            }
                            break;
                        case 7 /* EOF */:
                            this.errorLoc(loc0, "unclosed {{ (got end of file)");
                            return unwind();
                        default:
                            if (this.gotKw("else") && this.stmtList.peek() instanceof AST.If) {
                                this.shift();
                                if (this.gotOp("{")) {
                                    this.shift();
                                    pushBrace(this.stmtList.peek());
                                }
                            }
                            else if (this.parseStmtCore()) {
                                this.errorLoc(loc0, "unclosed {{ (got next declaration)");
                                return unwind();
                            }
                            break;
                    }
                }
            };
            Parser.prototype.parseStmtCore = function () {
                this.shiftLabel();
                var t = this.curr();
                switch (t.category) {
                    case 2 /* Keyword */:
                        var a = this.statementCallbacks[t.data];
                        if (!a) {
                            if (!!this.declarationCallbacks[t.data]) {
                                return true;
                            }
                            else {
                                this.error("keyword {0} is unexpected here (or reserved for future use)", t);
                                this.shift();
                            }
                        }
                        else {
                            this.shift();
                            a.call(this, this);
                        }
                        break;
                    case 4 /* Comment */:
                        var c = new AST.Comment();
                        c.setStableName(this.consumeLabel());
                        c.text = t.data.trim();
                        this.addStmt(c);
                        this.shift();
                        break;
                    case 0 /* Op */:
                    case 1 /* Id */:
                    case 3 /* String */:
                        this.parseTokenSequenceStmt();
                        break;
                    default:
                        TDev.Util.die();
                        break;
                }
                return false;
            };
            Parser.prototype.parseOneStmt = function () {
                TDev.Util.assert(this.tokenPos == 0);
                this.stmtList = [];
                if (this.gotOp("{"))
                    return this.parseBlock();
                this.parseStmtCore();
                if (this.stmtList.length != 1)
                    this.error("expecting a single statement");
                return this.stmtList[0];
            };
            Parser.prototype.shiftLabel = function () {
                var arr = [];
                while (this.got(5 /* Label */)) {
                    arr.push(this.curr().data);
                    this.shift();
                }
                this.currentLabel = arr;
                if (this.currentLabel.length == 1 && !(this.currentLabel[0]))
                    this.currentLabel = [];
                var res = (this.currentLabel.length > 0);
                return res;
            };
            Parser.prototype.parseBraced = function (a) {
                if (!this.gotOp("{"))
                    return;
                var nesting = 0;
                while (true) {
                    this.shiftLabel();
                    if (this.gotOp("{")) {
                        nesting++;
                        this.shift();
                        continue;
                    }
                    else if (this.gotOp("}")) {
                        nesting--;
                        this.shift();
                        if (nesting == 0)
                            break;
                        else
                            continue;
                    }
                    else if (this.got(7 /* EOF */)) {
                        break;
                    }
                    var prevPos = this.tokenPos;
                    a();
                    if (prevPos == this.tokenPos)
                        this.shift();
                }
            };
            Parser.prototype.skipBlock = function () {
                return this.parseBraced(function () {
                });
            };
            Parser.prototype.parseDeclCore = function () {
                this.shiftLabel();
                if (this.got(2 /* Keyword */)) {
                    var a = this.declarationCallbacks[this.curr().data];
                    if (a) {
                        this.shift();
                        a.call(this, this);
                        return true;
                    }
                }
                return false;
            };
            Parser.prototype.parseOneDecl = function () {
                var decls = this.parseManyDecls();
                if (decls.length != 1)
                    this.error("expecting a single declaration");
                return decls[0];
            };
            Parser.prototype.parseManyDecls = function () {
                TDev.Util.assert(this.tokenPos == 0);
                this.declList = [];
                this.parseDeclCore();
                return this.declList;
            };
            Parser.prototype.parseApp = function () {
                TDev.Util.assert(this.tokenPos == 0);
                this.currentApp = new AST.App(this);
                var printedError = false;
                var description = "";
                while (true) {
                    if (this.got(7 /* EOF */))
                        break;
                    if (this.parseDeclCore()) {
                        printedError = false;
                        continue;
                    }
                    if (this.got(4 /* Comment */)) {
                        description += this.curr().data.trim() + "\n";
                        this.shift();
                        printedError = false;
                        continue;
                    }
                    if (!printedError)
                        this.error("expecting declaration, got {0}", this.curr());
                    printedError = true;
                    this.shift();
                }
                var app = this.currentApp;
                app.comment = description.trim();
                this.declList.forEach(function (d) {
                    if (d instanceof AST.LibraryRef) {
                        var l = d;
                        if (!l.isDeclared) {
                            l.deleted = true;
                            return;
                        }
                    }
                    app.addDecl(d);
                });
                app.parsingFinished();
                this.currentApp = null;
                return app;
            };
            Parser.prototype.parseAction = function () {
                var prevTok = this.tokens[this.tokenPos - 1];
                var lbl = this.consumeLabel();
                var hd = this.parseActionHeader(lbl.peek());
                this.currentAction = new AST.Action();
                this.currentAction.setStableName(lbl);
                this.addDecl(this.currentAction);
                this.currentAction.header.inParameters.setChildren(hd.inParameters);
                this.currentAction.header.outParameters.setChildren(hd.outParameters);
                this.currentAction.setName(hd.name);
                this.currentAction.body = this.parseBlock();
                this.currentAction._isActionTypeDef = hd.isType;
                if (this.currentAction.isPage() && !this.currentAction.getPageBlock(false)) {
                    var bl = Parser.parseStmt("{ if box->is_init then { } if true then { } }");
                    bl.children()[1].rawThenBody.setChildren(this.currentAction.body.children());
                    this.currentAction.body = bl;
                }
                this.currentAction.body.parent = this.currentAction.header;
                if (prevTok.data == "event")
                    AST.api.eventMgr.setInfo(this.currentAction, this);
                if (this.currentAction.isPage()) {
                    this.currentAction.isAtomic = true;
                    var parms = this.currentAction.header.inParameters;
                    var parm0 = parms.stmts[0];
                    if (parm0 && parms.stmts[0] && (parm0.getKind().isExtensionEnabled() || parm0.getKind() instanceof TDev.UnresolvedKind) && ((this.featureMissing(16 /* UnicodeModel */) && (parm0.getName() == "model" || parm0.getName() == "page data")) || parm0.getName() == AST.modelSymbol || parm0.getName() == AST.oldModelSymbol)) {
                        parms.setChildren(parms.stmts.slice(1));
                        this.currentAction.modelParameter = parm0;
                    }
                }
                this.currentAction = null;
            };
            Parser.prototype.parseMetaDecl = function () {
                var tag = "";
                if (this.got(2 /* Keyword */))
                    tag = this.shift().data;
                else
                    tag = this.parseId();
                if (tag == "import") {
                    AST.LibraryRef.parse(this);
                    return;
                }
                if (this.gotOp("{"))
                    this.skipBlock();
                else {
                    var v = this.shift().data;
                    if (this.currentApp)
                        this.currentApp.setMeta(tag, v);
                    this.skipOp(";");
                }
            };
            Parser.prototype.parseMetaStmt = function () {
                var tag = "";
                if (this.got(2 /* Keyword */))
                    tag = this.shift().data;
                else
                    tag = this.parseId();
                if (tag == "private") {
                    if (this.currentAction)
                        this.currentAction.isPrivate = true;
                    this.skipOp(";");
                }
                else if (tag == "page") {
                    if (this.currentAction)
                        this.currentAction._isPage = true;
                    this.skipOp(";");
                }
                else if (tag == "offloaded") {
                    this.skipOp(";");
                }
                else if (tag == "async") {
                    if (this.currentAction)
                        this.currentAction.isAtomic = false;
                    this.skipOp(";");
                }
                else if (tag == "sync") {
                    if (this.currentAction)
                        this.currentAction.isAtomic = true;
                    this.skipOp(";");
                }
                else if (tag == "test") {
                    if (this.currentAction)
                        this.currentAction._isTest = true;
                    this.skipOp(";");
                }
                else if (tag == "offline") {
                    if (this.currentAction)
                        this.currentAction.isOffline = true;
                    this.skipOp(";");
                }
                else if (tag == "query") {
                    if (this.currentAction)
                        this.currentAction.isQuery = true;
                    this.skipOp(";");
                }
                else {
                    if (this.gotOp("{"))
                        this.skipBlock();
                    else {
                        this.shift();
                        this.skipOp(";");
                    }
                }
            };
            Parser.emptyCondition = function () {
                var e = Parser.emptyExpr();
                e.tokens.push(AST.mkThing("true"));
                return AST.mkWhere(e);
            };
            Parser.emptyExprStmt = function (p) {
                if (p === void 0) { p = null; }
                return AST.mkExprStmt(Parser.emptyExpr(), p);
            };
            Parser.prototype.parseSkip = function () {
                if (this.gotOp(";"))
                    this.shift();
                this.addStmt(Parser.emptyExprStmt(this));
            };
            Parser.prototype.parseDo = function () {
                var id = this.parseId();
                var node;
                if (id == "box")
                    node = AST.Box;
                else {
                    this.error("expecting 'box' here");
                    return;
                }
                (Parser.stmtCtor(node))(this);
            };
            Parser.prototype.parseWhere = function () {
                var len = this.stmtList.length;
                var stmt;
                var eq = this.lookahead(1);
                if (eq.category == 0 /* Op */ && eq.data == ":=") {
                    var opt = new AST.OptionalParameter();
                    opt.parseFrom(this);
                    stmt = opt;
                }
                else {
                    var inl = new AST.InlineAction();
                    inl.parseFrom(this);
                    stmt = inl;
                }
                if (len == 0 || !(this.stmtList[len - 1] instanceof AST.ExprStmt)) {
                    this.error("'where' should follow an expression");
                }
                else {
                    var prev = this.stmtList[len - 1];
                    var inls = prev;
                    if (!(prev instanceof AST.InlineActions)) {
                        inls = new AST.InlineActions();
                        inls.setStableName(prev.getStableName());
                        inls.expr = prev.expr;
                        inls.parent = prev.parent;
                        this.stmtList[len - 1] = inls;
                    }
                    inls.actions.push(stmt);
                }
            };
            Parser.prototype.parseField = function () {
                var name = this.parseId();
                this.skipOp(":");
                var kind = this.parseType();
                this.skipOp(";");
                var description = "";
                if (this.got(4 /* Comment */)) {
                    description = this.curr().data;
                    this.shift();
                }
                this.stmtList.push(new AST.RecordField(name, kind, false, description));
            };
            return Parser;
        })();
        AST.Parser = Parser;
        var ParseError = (function () {
            function ParseError(loc, msg) {
                this.loc = loc;
                this.msg = msg;
            }
            ParseError.prototype.toString = function () {
                var beg = this.loc.inputPos - 30;
                if (beg < 0)
                    beg = 0;
                var desc = this.loc.input.slice(beg, this.loc.inputPos) + "<*>" + this.loc.input.slice(this.loc.inputPos, beg + 60);
                return this.msg + " at >>>" + desc + "<<<";
            };
            return ParseError;
        })();
        AST.ParseError = ParseError;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var TypeResolver = (function (_super) {
            __extends(TypeResolver, _super);
            function TypeResolver(parent) {
                _super.call(this);
                this.parent = parent;
            }
            TypeResolver.prototype.fixupKind = function (n, k) {
                var _this = this;
                if (k instanceof TDev.UnresolvedKind && this.parent.topApp) {
                    var k0 = this.parent.topApp.getDefinedKinds().filter(function (n) { return n.getName() == k.getName(); })[0];
                    if (k0)
                        k = k0;
                }
                if (k.getRoot() != k) {
                    var pk = k;
                    var parms = pk.parameters.map(function (kk) { return _this.fixupKind(n, kk); });
                    if (parms.some(function (kk, i) { return pk.parameters[i] != kk; })) {
                        k = pk.createInstance(parms);
                    }
                }
                if (k.isError()) {
                    if (k instanceof AST.LibraryRefAbstractKind || k.getRecord() instanceof AST.LibraryRecordDef) {
                        if (k.parentLibrary().hasAbstractKind(k.getName())) {
                            k = k.parentLibrary().getAbstractKind(k.getName());
                        }
                    }
                }
                if (k.isError()) {
                    this.parent.errorCount++;
                    n.setError(TDev.lf("TD121: cannot find type {0}", k.toString()));
                }
                return k;
            };
            TypeResolver.prototype.visitGlobalDef = function (node) {
                node._kind = this.fixupKind(node, node.getKind());
            };
            TypeResolver.prototype.visitAction = function (node) {
                var _this = this;
                var fixupLocal = function (a) {
                    var l = a.local;
                    l._kind = _this.fixupKind(node, l.getKind());
                };
                if (node.modelParameter)
                    fixupLocal(node.modelParameter);
                node.getInParameters().forEach(fixupLocal);
                node.getOutParameters().forEach(fixupLocal);
            };
            TypeResolver.prototype.visitBlock = function (b) {
                this.visitChildren(b);
            };
            TypeResolver.prototype.visitRecordDef = function (r) {
                this.visitChildren(r);
            };
            TypeResolver.prototype.visitRecordField = function (node) {
                node.setKind(this.fixupKind(node, node.dataKind));
            };
            TypeResolver.prototype.visitApp = function (a) {
                this.visitChildren(a);
            };
            return TypeResolver;
        })(AST.NodeVisitor);
        AST.TypeResolver = TypeResolver;
        (function (ActionSection) {
            ActionSection[ActionSection["Normal"] = 0] = "Normal";
            ActionSection[ActionSection["Init"] = 1] = "Init";
            ActionSection[ActionSection["Display"] = 2] = "Display";
            ActionSection[ActionSection["Lambda"] = 3] = "Lambda";
        })(AST.ActionSection || (AST.ActionSection = {}));
        var ActionSection = AST.ActionSection;
        var TypeChecker = (function (_super) {
            __extends(TypeChecker, _super);
            function TypeChecker() {
                _super.call(this);
                this.isTopExpr = false;
                this.seenAwait = false;
                this.numFixes = 0;
                this.nothingLocals = [];
                this.localScopes = [[]];
                this.readOnlyLocals = [];
                this.outsideScopeLocals = [];
                this.invisibleLocals = [];
                this.writtenLocals = [];
                this.readLocals = [];
                this.inAtomic = false;
                this.inShim = false;
                this.actionSection = 0 /* Normal */;
                this.saveFixes = 0;
                this.outLocals = [];
                this.reportedUnassigned = false;
                this.allLocals = [];
                this.recentErrors = [];
                this.errorCount = 0;
                this.countToUpdate = 0;
                this.timestamp = 1;
                this.seenCurrent = false;
                this.missingLocals = [];
                this.errorLevel = 0;
                this.hintsToFlush = [];
                this.storeLocalsAt = null;
                this.ignoreLibErrors = false;
                this.core = TDev.api.core;
                this.typeResolver = new TypeResolver(this);
            }
            TypeChecker.tcAction = function (a, first, storeAt) {
                if (storeAt === void 0) { storeAt = null; }
                var ctx = new TypeChecker();
                ctx.topApp = TDev.Script;
                ctx.storeLocalsAt = storeAt;
                TypeChecker.lastStoreLocalsAt = storeAt;
                if (first) {
                    TypeChecker.iterTokenUsage(function (t) {
                        t.localCount = 0;
                    });
                    ctx.countToUpdate = 1;
                }
                ctx.dispatch(a);
            };
            TypeChecker.tcFragment = function (e) {
                var ctx = new TypeChecker();
                ctx.topApp = TDev.Script;
                ctx.storeLocalsAt = e;
                TypeChecker.lastStoreLocalsAt = e;
                var es = AST.mkExprStmt(e);
                ctx.dispatch(es);
            };
            TypeChecker.tcScript = function (a, ignoreLibErrors, isTop, depth) {
                if (ignoreLibErrors === void 0) { ignoreLibErrors = false; }
                if (isTop === void 0) { isTop = false; }
                if (depth === void 0) { depth = 0; }
                var ctx = new TypeChecker();
                ctx.topApp = a;
                a.imports = new AST.AppImports();
                var prev = TDev.Script;
                ctx.storeLocalsAt = TypeChecker.lastStoreLocalsAt;
                ctx.ignoreLibErrors = ignoreLibErrors;
                try {
                    TDev.setGlobalScript(a);
                    ctx.typecheckLibraries(a);
                    a.libNamespaceCache.recompute();
                    ctx.typeResolver.dispatch(a);
                    if (isTop) {
                        TypeChecker.iterTokenUsage(function (t) {
                            t.globalCount = 0;
                        });
                        ctx.countToUpdate = 2;
                    }
                    ctx.dispatch(a);
                    a.addFeatures(4 /* Refs */);
                    if (ctx.numFixes > 0 && depth < 5) {
                        return TypeChecker.tcScript(a, ignoreLibErrors, isTop, depth + 1);
                    }
                    a.addFeatures(AST.LanguageFeature.Current);
                    a.things.forEach(function (t) {
                        if (ignoreLibErrors && t instanceof AST.LibraryRef) {
                            t._hasErrors = false;
                            return;
                        }
                        if (t.hasErrors())
                            ctx.errorCount++;
                    });
                    return ctx.errorCount;
                }
                finally {
                    TDev.setGlobalScript(prev);
                }
            };
            TypeChecker.tcApp = function (a) {
                return TypeChecker.tcScript(a, false, true);
            };
            TypeChecker.iterTokenUsage = function (f) {
                TDev.api.getKinds().forEach(function (k) {
                    if (!!k.singleton) {
                        f(k.singleton.usage);
                    }
                    k.listProperties().forEach(function (p) {
                        f(p.getUsage());
                    });
                });
                TDev.api.getKind("code").singleton.usage.apiFreq = TDev.Script.actions().length > 0 ? 1.0 : 0.0;
                TDev.api.getKind("data").singleton.usage.apiFreq = TDev.Script.variables().length > 0 ? 0.9 : 0.0;
                TDev.api.getKind("art").singleton.usage.apiFreq = TDev.Script.resources().length > 0 ? 0.8 : 0.0;
                AST.api.core.allStmtUsage().forEach(f);
            };
            TypeChecker.resolveKind = function (k) {
                var ctx = new TypeChecker();
                ctx.topApp = TDev.Script;
                var a = new AST.GlobalDef();
                a._kind = k;
                ctx.typeResolver.dispatch(a);
                return a._kind;
            };
            TypeChecker.prototype.markError = function (expr, msg) {
                if (!!expr.getError())
                    return;
                if (this.errorLevel > 0)
                    return;
                expr.setError(msg);
                this.recentErrors.push(msg);
                this.errorCount++;
                var loc = expr.loc;
                if (loc) {
                    var i = loc.beg;
                    var e = i + loc.len;
                    while (i < e) {
                        var t = loc.tokens[i];
                        if (!t.getError())
                            t.setError(msg);
                        i++;
                    }
                }
            };
            TypeChecker.prototype.markHolderError = function (eh, msg) {
                if (!!eh.getError())
                    return;
                if (!msg)
                    return;
                if (this.errorLevel > 0)
                    return;
                this.errorCount++;
                eh.setError(msg);
            };
            TypeChecker.prototype.setNodeError = function (n, msg) {
                if (this.errorLevel == 0) {
                    this.errorCount++;
                    n.setError(msg);
                }
            };
            TypeChecker.prototype.typeCheck = function (expr) {
                expr.clearError();
                expr._kind = null;
                this.dispatch(expr);
            };
            TypeChecker.prototype.snapshotLocals = function () {
                var locs = [];
                this.localScopes.forEach(function (l) {
                    locs.pushRange(l);
                });
                return locs;
            };
            TypeChecker.prototype.tcTokens = function (toks) {
                var e = new AST.ExprHolder();
                e.tokens = toks;
                this.expect(e, null, "void");
            };
            TypeChecker.prototype.expectsMessage = function (whoExpects, tp) {
                switch (whoExpects) {
                    case "if": return TDev.lf("TD118: 'if' condition wants {1:a}", whoExpects, tp);
                    case "where": return TDev.lf("TD128: 'where' condition wants {1:a}", whoExpects, tp);
                    case "while": return TDev.lf("TD129: 'while' condition wants {1:a}", whoExpects, tp);
                    case "for": return TDev.lf("TD130: bound of 'for' wants {1:a}", whoExpects, tp);
                    case "optional": return TDev.lf("TD186: this optional parameter wants {1:a}", whoExpects, tp);
                    case "return": return TDev.lf("TD204: 'return' value wants {1:a}", whoExpects, tp);
                    default: TDev.Util.die();
                }
            };
            TypeChecker.prototype.expect = function (expr, tp, whoExpects) {
                var _this = this;
                this.hintsToFlush = [];
                if (expr.tokens.length == 1) {
                    if (expr.isPlaceholder())
                        expr.tokens = [];
                }
                if (this.topApp.featureMissing(32 /* AllAsync */) && expr.tokens.some(function (t) { return t.getOperator() == 'await'; })) {
                    expr.tokens = expr.tokens.filter(function (t) { return t.getOperator() != 'await'; });
                    this.numFixes++;
                }
                expr.clearError();
                expr.tokens.forEach(function (t, i) {
                    if (!(t instanceof AST.ThingRef))
                        return;
                    var tt = t;
                    if (tt.forceLocal)
                        return;
                    if (!(expr.tokens[i + 1] instanceof AST.PropertyRef))
                        return;
                    var pp = expr.tokens[i + 1];
                    var key = tt.data + "->" + pp.data;
                    if (AST.crossKindRenames.hasOwnProperty(key)) {
                        var m = /(.*)->(.*)/.exec(AST.crossKindRenames[key]);
                        tt.data = m[1];
                        pp.data = m[2];
                    }
                });
                var parsed = AST.ExprParser.parse1(expr.tokens);
                parsed.clearError();
                parsed._kind = null;
                expr.parsed = parsed;
                this.seenAwait = false;
                this.recentErrors = [];
                var parseErr = expr.tokens.filter(function (n) { return n.getError() != null; })[0];
                var prevLocals = this.allLocals.length;
                this.saveFixes = expr == this.storeLocalsAt ? 1 : 0;
                if (!parseErr) {
                    this.isTopExpr = (whoExpects == "void");
                    this.dispatch(parsed);
                    expr.hasFix = this.saveFixes > 1;
                }
                else {
                    expr.hasFix = true;
                    if (this.errorLevel == 0)
                        this.errorCount++;
                    this.errorLevel++;
                    this.dispatch(parsed);
                    this.errorLevel--;
                }
                this.saveFixes = 0;
                expr._kind = expr.parsed.getKind();
                var seenAssign = false;
                var prevTok = null;
                var tokErr = null;
                expr.tokens.forEach(function (t) {
                    if (t instanceof AST.PropertyRef) {
                        var p = t;
                        if (!p.prop)
                            p.prop = p.getOrMakeProp();
                        if (prevTok && prevTok.getThing() instanceof AST.LocalDef && prevTok.getThing().getName() == AST.modelSymbol && AST.mkFakeCall(p).referencedRecordField())
                            p.skipArrow = true;
                        else if (p.skipArrow)
                            p.skipArrow = false;
                    }
                    else if (t instanceof AST.ThingRef) {
                        var tt = t;
                        if (tt._lastTypechecker != _this)
                            _this.dispatch(tt);
                    }
                    else if (t.getOperator() == ":=") {
                        seenAssign = true;
                    }
                    else if (t instanceof AST.Literal) {
                        if (!t._kind) {
                            _this.dispatch(t);
                        }
                    }
                    prevTok = t;
                    if (!tokErr && t.getError() != null)
                        tokErr = t;
                });
                if (whoExpects == "void") {
                    if (seenAssign && (this.allLocals.length == prevLocals || !this.allLocals.slice(prevLocals).some(function (l) { return l.isRegular; })))
                        seenAssign = false;
                    expr.looksLikeVarDef = seenAssign;
                }
                var errNode = parseErr || tokErr || expr.parsed;
                this.markHolderError(expr, errNode.getError());
                this.markHolderError(expr, this.recentErrors[0]);
                expr.isAwait = this.seenAwait;
                if (expr == this.storeLocalsAt) {
                    this.seenCurrent = true;
                    expr.locals = this.snapshotLocals();
                }
                else {
                    expr.locals = null;
                }
                if (!TDev.Util.check(expr.getKind() != null, "expr type unset")) {
                    expr._kind = AST.api.core.Unknown;
                }
                if (!expr.getError() && tp != null && !expr.getKind().equals(tp)) {
                    var msg = this.expectsMessage(whoExpects, tp.toString());
                    if (expr.getKind() != this.core.Unknown)
                        msg += TDev.lf(", got {0:a} instead", expr.getKind().toString());
                    this.markHolderError(expr, msg);
                }
                if (!expr.getError() && parsed instanceof AST.Call) {
                    var call = parsed;
                    if (tp == null && whoExpects == "void") {
                        var par = call.prop().parentKind;
                        var act = call.anyCalledAction();
                        if (AST.legacyMode && par == this.core.Number && call.prop().getName() == "=")
                            expr.hint = TDev.lf("the '=' comparison has no effect here; did you mean assignment ':=' instead?");
                        else if (expr.getKind() != this.core.Nothing && expr.getKind() != this.core.Unknown && expr.getKind().getRoot() != this.core.Task) {
                            var exception = !!(call.prop().getFlags() & 262144 /* IgnoreReturnValue */);
                            var k = expr.getKind();
                            var msg = "";
                            if (k.hasContext(1 /* Parameter */))
                                msg = TDev.lf("did you want to use this value?");
                            else
                                msg = TDev.lf("now you can select a property on it");
                            if (call.prop() instanceof AST.LibraryRef)
                                expr.hint = TDev.lf("we have a library '{0}' here; {1}", call.prop().getName(), msg);
                            else if ((par.isBuiltin || call.args.length == 1) && !exception)
                                expr.hint = TDev.lf("'{0}' returns a '{1}'; {2}", call.prop().getName(), call.getKind(), msg);
                            else if (!exception) {
                                expr.hint = TDev.lf("'{0}' returns a '{1}'; {2}", call.prop().getName(), call.getKind(), msg);
                            }
                        }
                        else if (act && act.getOutParameters().length > 0)
                            expr.hint = TDev.lf("'{0}' returns {1} values; you can use 'store in var' button to save them to locals", call.prop().getName(), act.getOutParameters().length);
                    }
                }
                else if (tp == null && whoExpects == "void") {
                    var k = expr.getKind();
                    if (k != this.core.Nothing && k != this.core.Unknown) {
                        if (k.singleton)
                            expr.hint = TDev.lf("now you can select a property of {0}; it doesn't do anything by itself", k);
                        else
                            expr.hint = TDev.lf("we have {0:a} here; did you want to do something with it?", k);
                    }
                }
                if (this.hintsToFlush.length > 0) {
                    var hh = this.hintsToFlush.join("\n");
                    if (expr.hint)
                        expr.hint += "\n" + hh;
                    else
                        expr.hint = hh;
                    this.hintsToFlush = [];
                }
                if (expr.assignmentInfo() && expr.assignmentInfo().fixContextError && expr.tokens[1].getOperator() == ":=") {
                    this.numFixes++;
                    this.nothingLocals.push(expr.tokens[0].getThing());
                    expr.tokens.splice(0, 2);
                }
                if (this.nothingLocals.length > 0 && expr.tokens.length == 1 && this.nothingLocals.indexOf(expr.tokens[0].getThing()) >= 0) {
                    expr.tokens = [];
                    this.numFixes++;
                }
                if (this.topApp.featureMissing(4 /* Refs */) && expr.tokens.some(function (t) { return !!t.tokenFix; })) {
                    var t0 = expr.tokens.filter(function (t) { return t.tokenFix == ":="; })[0];
                    if (t0) {
                        var idx = expr.tokens.indexOf(t0);
                        if (expr.tokens[idx + 1] && expr.tokens[idx + 1].getOperator() == "(") {
                            expr.tokens[idx] = AST.mkOp(":=");
                            expr.tokens.splice(idx + 1, 1);
                            if (expr.tokens.peek().getOperator() == ")")
                                expr.tokens.pop();
                        }
                    }
                    expr.tokens = expr.tokens.filter(function (t) { return t.tokenFix != "delete"; });
                    this.numFixes++;
                }
            };
            TypeChecker.prototype.declareLocal = function (v) {
                this.localScopes.peek().push(v);
                this.allLocals.push(v);
                v._isMutable = false;
                v._isCaptured = false;
                v.lastUsedAt = this.timestamp++;
                this.recordLocalRead(v);
            };
            TypeChecker.prototype.lookupSymbol = function (t) {
                var n = t.data;
                for (var i = this.localScopes.length - 1; i >= 0; i--) {
                    var s = this.localScopes[i];
                    for (var j = s.length - 1; j >= 0; j--)
                        if (s[j].getName() === n)
                            return s[j];
                }
                if (n == "...")
                    n = "$skip";
                if (t.forceLocal)
                    return undefined;
                return TDev.api.getThing(n);
            };
            TypeChecker.prototype.scope = function (f) {
                this.localScopes.push([]);
                var r = f();
                this.localScopes.pop();
                return r;
            };
            TypeChecker.prototype.conditionalScope = function (f) {
                var prevWritten = this.writtenLocals.slice(0);
                var prevLoop = this.currLoop;
                try {
                    return this.scope(f);
                }
                finally {
                    this.writtenLocals = prevWritten;
                    this.currLoop = prevLoop;
                }
            };
            TypeChecker.prototype.visitAstNode = function (node) {
                TDev.Util.oops("typechecking " + node.nodeType() + " not implemented!");
            };
            TypeChecker.prototype.visitAnyIf = function (node) {
                this.updateStmtUsage(node);
                this.expect(node.rawCondition, this.core.Boolean, "if");
                var isComment = node.isTopCommentedOut();
                if (isComment) {
                    var vis = new ClearErrors();
                    vis.dispatch(node.rawThenBody);
                }
                var prevWritten = this.writtenLocals.slice(0);
                if (node.rawThenBody == this.pageInit)
                    this.actionSection = 1 /* Init */;
                else if (node.rawThenBody == this.pageDisplay)
                    this.actionSection = 2 /* Display */;
                if (isComment)
                    this.errorLevel++;
                this.typeCheck(node.rawThenBody);
                node.rawThenBody.newlyWrittenLocals = this.writtenLocals.slice(prevWritten.length);
                if (node.rawElseBody.stmts.length == 1 && node.rawElseBody.stmts[0] instanceof AST.If) {
                    var ei = node.rawElseBody.stmts[0];
                    ei.isElseIf = true;
                    node.setElse(AST.Parser.emptyBlock());
                    var bl = node.parentBlock();
                    var idx = bl.stmts.indexOf(node);
                    bl.stmts.splice(idx + 1, 0, ei);
                    bl.newChild(ei);
                }
                if (node.rawElseBody.isBlockPlaceholder()) {
                    node.rawElseBody.newlyWrittenLocals = [];
                    this.typeCheck(node.rawElseBody);
                }
                else {
                    this.writtenLocals = prevWritten.slice(0);
                    this.typeCheck(node.rawElseBody);
                    node.rawElseBody.newlyWrittenLocals = this.writtenLocals.slice(prevWritten.length);
                }
                if (isComment)
                    this.errorLevel--;
                this.writtenLocals = prevWritten;
            };
            TypeChecker.prototype.visitWhere = function (node) {
                this.expect(node.condition, this.core.Boolean, 'where');
            };
            TypeChecker.prototype.visitWhile = function (node) {
                var _this = this;
                this.updateStmtUsage(node);
                this.expect(node.condition, this.core.Boolean, 'while');
                this.conditionalScope(function () {
                    _this.currLoop = node;
                    _this.typeCheck(node.body);
                });
            };
            TypeChecker.prototype.visitBreakContinue = function (node, tp) {
                node._kind = this.core.Nothing;
                node.topAffectedStmt = this.currLoop;
                if (!this.currLoop)
                    this.markError(node, TDev.lf("TD200: '{0}' can be only used inside a loop", tp));
                if (!node.args[0].isPlaceholder())
                    this.markError(node, TDev.lf("TD205: '{0}' cannot take arguments", tp));
                this.expectExpr(node.args[0], null, tp);
            };
            TypeChecker.prototype.visitBreak = function (node) {
                this.visitBreakContinue(node, "break");
            };
            TypeChecker.prototype.visitContinue = function (node) {
                this.visitBreakContinue(node, "continue");
            };
            TypeChecker.prototype.visitShow = function (node) {
                node._kind = this.core.Nothing;
                this.expectExpr(node.args[0], null, "show");
                node.topPostCall = null;
                if (node.args[0].isPlaceholder()) {
                    this.markError(node, TDev.lf("TD207: we need something to show"));
                }
                else {
                    var tp = node.args[0].getKind();
                    if (tp == AST.api.core.Unknown)
                        return;
                    var show = tp.getProperty("post to wall");
                    if (!show)
                        this.markError(node, TDev.lf("TD201: we don't know how to display {0}", tp.toString()));
                    else
                        node.topPostCall = AST.mkFakeCall(AST.PropertyRef.mkProp(show), [node.args[0]]);
                }
            };
            TypeChecker.prototype.visitReturn = function (node) {
                node._kind = this.core.Nothing;
                node.topRetLocal = null;
                var exp = null;
                if (!node.args[0].isPlaceholder()) {
                    if (this.outLocals.length == 0)
                        this.markError(node.args[0], TDev.lf("TD202: the function doesn't have output parameters; return with a value is not allowed"));
                    else if (this.outLocals.length > 1)
                        this.markError(node.args[0], TDev.lf("TD203: the function has more than one output parameter; return with a value is not allowed"));
                    else {
                        node.topRetLocal = this.outLocals[0];
                        exp = node.topRetLocal.getKind();
                        this.recordLocalWrite(node.topRetLocal);
                    }
                }
                else {
                    if (this.outLocals.length == 1)
                        this.markError(node, TDev.lf("TD206: we need a value to return here"));
                }
                this.expectExpr(node.args[0], exp, "return");
                node.topAffectedStmt = this.currentAnyAction;
                this.checkAssignment(this.lastStmt);
            };
            TypeChecker.prototype.visitActionParameter = function (node) {
            };
            TypeChecker.prototype.visitBlock = function (node) {
                var _this = this;
                this.scope(function () {
                    var ss = node.stmts;
                    var unreach = false;
                    var reported = false;
                    for (var i = 0; i < ss.length; ++i) {
                        _this.typeCheck(ss[i]);
                        if (unreach) {
                            ss[i].isUnreachable = true;
                            if (!reported && !(ss[i] instanceof AST.Comment)) {
                                reported = true;
                                ss[i].addHint(TDev.lf("code after return, break or continue won't ever run"));
                            }
                        }
                        if (ss[i].isJump())
                            unreach = true;
                    }
                    for (var i = 0; i < ss.length; ++i) {
                        if (ss[i] instanceof AST.If) {
                            var si = ss[i];
                            si.isElseIf = false;
                            var end = i + 1;
                            while (AST.isElseIf(ss[end])) {
                                end++;
                                if (!ss[end - 1].rawElseBody.isBlockPlaceholder())
                                    break;
                            }
                            si.branches = [];
                            while (i < end) {
                                var innerIf = ss[i++];
                                innerIf.parentIf = si;
                                si.branches.push({
                                    condition: innerIf.rawCondition,
                                    body: innerIf.rawThenBody
                                });
                                if (i == end) {
                                    si.branches.push({
                                        condition: null,
                                        body: innerIf.rawElseBody
                                    });
                                    innerIf.displayElse = true;
                                }
                                else {
                                    innerIf.displayElse = false;
                                }
                            }
                            i--;
                            _this.writtenLocals.pushRange(TDev.Util.intersectArraysVA(si.branches.map(function (b) { return b.body.newlyWrittenLocals; })));
                        }
                    }
                });
            };
            TypeChecker.prototype.updateStmtUsage = function (s, tp) {
                if (tp === void 0) { tp = null; }
                this.lastStmt = s;
                if (this.countToUpdate != 0) {
                    var u = AST.api.core.stmtUsage(tp || s.nodeType());
                    if (this.countToUpdate == 1)
                        u.localCount++;
                    else
                        u.globalCount++;
                }
            };
            TypeChecker.prototype.visitFor = function (node) {
                var _this = this;
                this.updateStmtUsage(node);
                this.expect(node.upperBound, this.core.Number, 'for');
                node.boundLocal._kind = this.core.Number;
                this.readOnlyLocals.push(node.boundLocal);
                this.conditionalScope(function () {
                    _this.currLoop = node;
                    _this.declareLocal(node.boundLocal);
                    _this.typeCheck(node.body);
                });
            };
            TypeChecker.prototype.visitForeach = function (node) {
                var _this = this;
                this.updateStmtUsage(node);
                this.expect(node.collection, null, null);
                var k = node.collection.getKind();
                if (!k.isEnumerable() && !node.collection.getError()) {
                    if (k == this.core.Unknown) {
                        this.markHolderError(node.collection, TDev.lf("TD119: i need something to iterate on"));
                    }
                    else {
                        this.markHolderError(node.collection, TDev.lf("TD120: i cannot iterate over {0}", k.toString()));
                    }
                }
                var ek;
                if (k instanceof AST.RecordDefKind)
                    ek = k.record.entryKind;
                var atProp = k.getProperty("at");
                if (!ek && !!atProp)
                    ek = atProp.getResult().getKind();
                if (!!ek)
                    node.boundLocal._kind = ek;
                this.readOnlyLocals.push(node.boundLocal);
                this.conditionalScope(function () {
                    _this.currLoop = node;
                    _this.declareLocal(node.boundLocal);
                    _this.typeCheck(node.conditions);
                    _this.typeCheck(node.body);
                });
            };
            TypeChecker.prototype.visitBox = function (node) {
                this.updateStmtUsage(node);
                this.typeCheck(node.body);
            };
            TypeChecker.prototype.visitComment = function (node) {
                this.updateStmtUsage(node);
            };
            TypeChecker.prototype.setOutLocals = function (locs) {
                this.outLocals = locs;
                var isHiddenOut = locs.length == 1;
                locs.forEach(function (l) {
                    l.isHiddenOut = isHiddenOut;
                    l.isOut = true;
                });
            };
            TypeChecker.prototype.visitAction = function (node) {
                var _this = this;
                this.writtenLocals = [];
                this.readOnlyLocals = [];
                this.allLocals = [];
                this.currentAction = node;
                this.currentAnyAction = node;
                node.clearError();
                this.actionSection = 0 /* Normal */;
                this.inAtomic = node.isAtomic;
                this.inShim = this.topApp.entireShim || node.getShimName() != null;
                node._compilerInlineBody = null;
                this.scope(function () {
                    var prevErr = _this.errorCount;
                    _this.setOutLocals(node.getOutParameters().map(function (p) { return p.local; }));
                    _this.reportedUnassigned = false;
                    _this.typeResolver.visitAction(node);
                    var fixupLocalInp = function (a) {
                        _this.declareLocal(a.local);
                        if (node.isPage())
                            _this.readOnlyLocals.push(a.local);
                    };
                    if (node.modelParameter)
                        fixupLocalInp(node.modelParameter);
                    node.getInParameters().forEach(fixupLocalInp);
                    node.getOutParameters().forEach(function (a) { return _this.declareLocal(a.local); });
                    if (node.isPage()) {
                        _this.pageInit = node.getPageBlock(true);
                        _this.pageDisplay = node.getPageBlock(false);
                    }
                    _this.typeCheck(node.body);
                    if (node.isActionTypeDef()) {
                        var outp1 = node.getOutParameters()[1];
                        if (outp1) {
                            _this.setNodeError(node, TDev.lf("TD171: function types support at most one output parameter; sorry"));
                        }
                    }
                    else {
                        if (!_this.reportedUnassigned)
                            _this.checkAssignment(node);
                    }
                    node._hasErrors = _this.errorCount > prevErr;
                    node.allLocals = _this.allLocals;
                });
                if (node.modelParameter && node.modelParameter.local.getName() != AST.modelSymbol) {
                    node.modelParameter.local.setName(AST.modelSymbol);
                    this.numFixes++;
                }
                if (this.missingLocals.length > 0 && this.storeLocalsAt && this.storeLocalsAt.locals) {
                    this.storeLocalsAt.locals.pushRange(this.missingLocals);
                }
                var inf = node.eventInfo;
                if (inf != null) {
                    inf.disabled = false;
                    if (inf.type.globalKind != null && !inf.onVariable) {
                        var varName = node.getName().slice(inf.type.category.length);
                        var v = this.topApp.variables().filter(function (v) { return v.getName() == varName; })[0];
                        if (v === undefined) {
                            node.setError(TDev.lf("TD122: i cannot find variable {0}", varName));
                            inf.disabled = true;
                        }
                        inf.onVariable = v;
                    }
                    if (!!inf.onVariable) {
                        var newName = inf.type.category + inf.onVariable.getName();
                        if (!TDev.Script.things.filter(function (t) { return t.getName() == newName; })[0])
                            node.setName(newName);
                        if (node.getName() != newName)
                            inf.onVariable = null;
                    }
                    if (node.hasOutParameters())
                        node.setError(TDev.lf("TD123: events cannot have out parameters"));
                    if (node.getInParameters().length != inf.type.inParameters.length)
                        node.setError(TDev.lf("TD124: wrong number of in parameters to an event"));
                    else {
                        var inParms = node.getInParameters();
                        for (var i = 0; i < inParms.length; ++i)
                            if (inParms[i].getKind() != inf.type.inParameters[i].getKind())
                                node.setError(TDev.lf("TD125: wrong type of parameter #{0}", i));
                    }
                    if (this.topApp.isLibrary && !this.ignoreLibErrors)
                        node.setError(TDev.lf("TD126: libraries cannot define global events"));
                }
                if (!node.isExternal) {
                    if (this.topApp.isCloud && node.isPage())
                        node.setError(TDev.lf("TD177: cloud libraries cannot define pages"));
                    if (this.topApp.isCloud && !node.isPrivate && node.isAtomic)
                        node.setError(TDev.lf("TD178: cloud libraries cannot define atomic functions"));
                }
                if (!!node.getError())
                    node._hasErrors = true;
                node._errorsOK = undefined;
                if (node.isCompilerTest()) {
                    node._errorsOK = AST.runErrorChecker(node);
                }
            };
            TypeChecker.prototype.visitLibraryRef = function (node) {
            };
            TypeChecker.prototype.persistentStorageError = function (whatr, wherep, where) {
                var error;
                var wheres;
                switch (wherep) {
                    case 2 /* Cloud */:
                        wheres = TDev.lf("replicated ");
                        break;
                    case 3 /* Partial */:
                        wheres = TDev.lf("replicated ");
                        break;
                    case 1 /* Local */:
                        wheres = TDev.Script.isCloud ? TDev.lf("server-local ") : TDev.lf("locally persisted ");
                        break;
                }
                wheres = wheres + (!where ? TDev.lf("variable") : (where.recordType === 2 /* Table */ ? TDev.lf("table") : TDev.lf("index")));
                if (whatr.recordType === 1 /* Object */) {
                    return TDev.lf("TD169: {0:a} cannot be persisted between script runs", whatr.toString());
                    ;
                }
                else {
                    TDev.Util.assert(whatr.recordType === 2 /* Table */);
                    var whats;
                    switch (whatr.getRecordPersistence()) {
                        case 2 /* Cloud */:
                            whats = TDev.lf("replicated table rows");
                            break;
                        case 1 /* Local */:
                            whats = TDev.Script.isCloud ? TDev.lf("server-local table rows") : TDev.lf("locally persisted table rows");
                            break;
                        case 0 /* Temporary */:
                            whats = TDev.lf("temporary table rows");
                            break;
                        case 3 /* Partial */:
                            whats = TDev.lf("replicated table rows");
                            break;
                    }
                    return TDev.lf("TD166: cannot store {0} in a {1}", whats, wheres);
                }
            };
            TypeChecker.prototype.visitGlobalDef = function (node) {
                node.clearError();
                if (node.isResource) {
                    node.isTransient = true;
                    node.cloudEnabled = false;
                }
                this.typeResolver.visitGlobalDef(node);
                if (node.getRecordPersistence() != 0 /* Temporary */ && (node.getKind().getContexts() & 4 /* CloudField */) == 0) {
                    this.setNodeError(node, TDev.lf("TD165: {0:a} cannot be saved between script runs", node.getKind().toString()));
                    if (this.topApp.featureMissing(8 /* LocalCloud */)) {
                        node.isTransient = true;
                        node.cloudEnabled = false;
                        this.numFixes++;
                    }
                }
                if (node.getKind() instanceof AST.RecordEntryKind) {
                    var rdef = (node.getKind()).getRecord();
                    if (rdef.recordType == 4 /* Decorator */) {
                        this.setNodeError(node, TDev.lf("TD175: must not store decorators in variables"));
                    }
                    else if (node.getRecordPersistence() > rdef.getRecordPersistence()) {
                        this.setNodeError(node, this.persistentStorageError(rdef, node.getRecordPersistence()));
                        if (!node.isTransient && this.topApp.featureMissing(8 /* LocalCloud */)) {
                            node.isTransient = true;
                            node.cloudEnabled = false;
                            this.numFixes++;
                        }
                    }
                }
            };
            TypeChecker.prototype.cyclefree = function (start, current) {
                var _this = this;
                return (current != start) && (!current._wasTypechecked || current.linkedtables.every(function (t) { return _this.cyclefree(start, t); }));
            };
            TypeChecker.prototype.visitRecordField = function (node) {
                node.clearError();
                this.typeResolver.visitRecordField(node);
                var pers = node.def().getRecordPersistence();
                var cl = pers != 0 /* Temporary */;
                var ctx = cl ? (node.isKey ? 16 /* IndexKey */ : 4 /* CloudField */) : (node.isKey ? 16 /* IndexKey */ : 2 /* GlobalVar */);
                var k = node.dataKind;
                var c = k.getContexts();
                var newtype = node.def().recordType;
                if (node.def().recordType == 4 /* Decorator */ && ctx == 16 /* IndexKey */)
                    ctx = 32 /* GcKey */;
                if (!!(c & 64 /* RowKey */) && (newtype == 3 /* Index */ || newtype == 2 /* Table */)) {
                    var other = node.dataKind.getRecord();
                    var otherpers = other.getRecordPersistence();
                    if (otherpers < pers && !(otherpers == 2 /* Cloud */ && pers == 3 /* Partial */)) {
                        this.setNodeError(node, this.persistentStorageError(other, pers, node.def()));
                        this.errorCount++;
                        if (this.topApp.featureMissing(8 /* LocalCloud */) && pers != 2 /* Cloud */ && other.getRecordPersistence() != 2 /* Cloud */) {
                            node.def().persistent = false;
                            other.persistent = false;
                            this.numFixes++;
                        }
                    }
                    if (node.isKey && newtype == 2 /* Table */) {
                        if (!this.cyclefree(node.def(), other)) {
                            this.setNodeError(node, TDev.lf("TD176: links must not be circular"));
                        }
                        else
                            node.def().linkedtables.push(other);
                    }
                    return;
                }
                if (!(c & ctx)) {
                    if (cl)
                        this.setNodeError(node, TDev.lf("TD167: {0:a} cannot be persisted between script runs", k.toString()));
                    else
                        this.setNodeError(node, TDev.lf("TD168: {0:a} cannot be used as a {1}", node.isKey ? TDev.lf("key") : TDev.lf("field"), k.toString()));
                    if (this.topApp.featureMissing(8 /* LocalCloud */) && pers == 1 /* Local */) {
                        node.def().persistent = false;
                        this.numFixes++;
                    }
                }
                if (pers === 3 /* Partial */ && node.isKey && node.isFirstChild()) {
                    if (node.dataKind.getName() !== "User") {
                        this.errorCount++;
                        node.setError("A partially replicated Index should have a User as first key");
                    }
                }
            };
            TypeChecker.prototype.visitRecordDef = function (node) {
                node.isModel = false;
                node.linkedtables = [];
                this.visitChildren(node);
            };
            TypeChecker.prototype.typecheckLibraries = function (node) {
                node.libraries().forEach(function (l) { return l.resolve(); });
                node.libraries().forEach(function (l) { return l.typeCheck(); });
            };
            TypeChecker.prototype.visitApp = function (node) {
                var _this = this;
                this.typecheckLibraries(node);
                if (TDev.Cloud.isRestricted())
                    node.entireShim = /#entireshim/i.test(node.comment) || node.actions().some(function (a) { return a.isPage(); }) || node.libraries().some(function (l) { return l.resolved && l.resolved.entireShim; });
                node.things.forEach(function (n) {
                    var wt = n._wasTypechecked;
                    n._wasTypechecked = true;
                    _this.dispatch(n);
                    if (!wt)
                        n.notifyChange();
                });
                var usedNames = {};
                node.things.forEach(function (n) {
                    if (usedNames.hasOwnProperty(n.getName())) {
                        _this.numFixes++;
                        n.setName(node.freshName(n.getName() + " " + _this.numFixes));
                    }
                    else {
                        usedNames[n.getName()] = n;
                    }
                });
                node.actions().forEach(function (a) {
                    var d = a.getModelDef();
                    if (d)
                        d.isModel = true;
                });
            };
            TypeChecker.prototype.visitExprStmt = function (expr) {
                this.updateStmtUsage(expr);
                this.expect(expr.expr, null, "void");
                if (expr.isVarDef())
                    this.updateStmtUsage(expr, "var");
            };
            TypeChecker.prototype.checkAssignment = function (node) {
                var _this = this;
                var unassigned = this.outLocals.filter(function (v) { return _this.writtenLocals.indexOf(v) < 0; });
                if (unassigned.length > 0) {
                    this.reportedUnassigned = true;
                    node.addHint(TDev.lf("the function may not always return a value; insert a return statement?"));
                }
            };
            TypeChecker.prototype.actionScope = function (k, f) {
                var _this = this;
                this.scope(function () {
                    var prevReadOnly = _this.readOnlyLocals;
                    var prevRead = _this.readLocals;
                    var prevOutsideScopeLocals = _this.outsideScopeLocals;
                    var prevWritten = _this.writtenLocals;
                    var prevSect = _this.actionSection;
                    var prevAtomic = _this.inAtomic;
                    var prevOut = _this.outLocals;
                    var prevRep = _this.reportedUnassigned;
                    var prevAct = _this.currentAnyAction;
                    var prevLoop = _this.currLoop;
                    var prevInvisibleLocals = _this.invisibleLocals;
                    _this.currLoop = null;
                    _this.writtenLocals = [];
                    _this.readLocals = [];
                    _this.actionSection = 3 /* Lambda */;
                    _this.inAtomic = k instanceof TDev.ActionKind && k.isAtomic();
                    _this.outsideScopeLocals = _this.snapshotLocals();
                    _this.readOnlyLocals = AST.writableLocalsInClosures ? _this.outsideScopeLocals.filter(function (l) { return !l.isRegular; }) : _this.outsideScopeLocals.slice(0);
                    if (TDev.Cloud.isRestricted())
                        _this.invisibleLocals = _this.snapshotLocals();
                    try {
                        f();
                    }
                    finally {
                        _this.readLocals = prevRead;
                        _this.writtenLocals = prevWritten;
                        _this.readOnlyLocals = prevReadOnly;
                        _this.inAtomic = prevAtomic;
                        _this.actionSection = prevSect;
                        _this.outLocals = prevOut;
                        _this.currentAnyAction = prevAct;
                        _this.reportedUnassigned = prevRep;
                        _this.currLoop = prevLoop;
                        _this.invisibleLocals = prevInvisibleLocals;
                        _this.outsideScopeLocals = prevOutsideScopeLocals;
                    }
                });
            };
            TypeChecker.prototype.typeCheckInlineAction = function (inl) {
                var _this = this;
                this.actionScope(inl.name.getKind(), function () {
                    _this.currentAnyAction = inl;
                    inl.inParameters.forEach(function (d) { return _this.declareLocal(d); });
                    inl.outParameters.forEach(function (d) { return _this.declareLocal(d); });
                    if (TDev.Cloud.isRestricted())
                        _this.readOnlyLocals.pushRange(inl.inParameters);
                    _this.setOutLocals(inl.outParameters.slice(0));
                    _this.reportedUnassigned = false;
                    _this.typeCheck(inl.body);
                    if (!_this.reportedUnassigned)
                        _this.checkAssignment(inl);
                    _this.computeClosure(inl);
                });
            };
            TypeChecker.prototype.visitInlineActions = function (inl) {
                var _this = this;
                this.updateStmtUsage(inl);
                var names = inl.normalActions().map(function (a) { return a.name; });
                names.forEach(function (n) {
                    _this.declareLocal(n);
                    n.lambdaNameStatus = 2;
                });
                inl.actions.forEach(function (iab) {
                    iab.clearError();
                });
                this.topInline = inl;
                this.expect(inl.expr, null, "void");
                var p = this.localScopes.length - 1;
                this.localScopes[p] = this.localScopes[p].filter(function (l) { return names.indexOf(l) < 0; });
                var defined = (inl.expr.assignmentInfo() ? inl.expr.assignmentInfo().definedVars : null) || [];
                var prevScope = this.localScopes[p];
                this.localScopes[p] = prevScope.filter(function (l) { return defined.indexOf(l) < 0; });
                var rename = function (s) { return s; };
                inl.actions.forEach(function (iab) {
                    if (iab instanceof AST.OptionalParameter) {
                        var op = iab;
                        var knd = op.recordField ? op.recordField.dataKind : null;
                        _this.expect(op.expr, knd, "optional");
                        return;
                    }
                    var ia = iab;
                    var coerced = false;
                    var coerce = function (locs, parms) {
                        if (locs.length > parms.length) {
                            locs.splice(parms.length, locs.length - parms.length);
                            coerced = true;
                        }
                        else if (parms.length > locs.length) {
                            coerced = true;
                            parms.slice(locs.length).forEach(function (pp) {
                                locs.push(AST.mkLocal(rename(pp.getName()), pp.getKind()));
                            });
                        }
                        locs.forEach(function (l, i) {
                            var pp = parms[i];
                            if (pp.getKind() != l.getKind()) {
                                l.rename(rename(pp.getName()));
                                l._kind = pp.getKind();
                                coerced = true;
                            }
                        });
                    };
                    if (ia.isOptional && ia.recordField) {
                        var ak = ia.recordField.dataKind;
                        ia.name.setKind(ak);
                        if (ak.isAction) {
                            coerce(ia.inParameters, ak.getInParameters());
                            coerce(ia.outParameters, ak.getOutParameters());
                        }
                        else {
                            _this.setNodeError(ia, TDev.lf("TD189: type of optional parameter '{0}' is not a function type", ia.getName()));
                        }
                    }
                    else if (ia.name.lambdaNameStatus != 2 && ia.name.getKind().isAction) {
                        var ak = ia.name.getKind();
                        coerce(ia.inParameters, ak.getInParameters());
                        coerce(ia.outParameters, ak.getOutParameters());
                    }
                    _this.typeCheckInlineAction(ia);
                    ia.closure.forEach(function (l) { return _this.recordLocalRead(l); });
                });
                this.localScopes[p] = prevScope;
            };
            TypeChecker.prototype.visitThingRef = function (t) {
                if (TDev.Util.startsWith(t.data, AST.ThingRef.placeholderPrefix)) {
                    var kn = t.data.slice(AST.ThingRef.placeholderPrefix.length);
                    var plName = null;
                    var colon = kn.indexOf(':');
                    if (colon > 0) {
                        plName = kn.slice(colon + 1);
                        kn = kn.slice(0, colon);
                    }
                    var k = AST.api.getKind(kn);
                    if (!k && /[_\[]/.test(kn)) {
                        k = AST.Parser.parseType(kn);
                        if (k)
                            k = TypeChecker.resolveKind(k);
                        if (k == AST.api.core.Unknown)
                            k = null;
                    }
                    if (!!k) {
                        var pl = new AST.PlaceholderDef();
                        pl.setName("");
                        pl._kind = k;
                        if (plName)
                            pl.label = plName;
                        t.def = pl;
                    }
                }
                t._lastTypechecker = this;
                if (t.def instanceof AST.PlaceholderDef) {
                    if (!t.isEscapeDef())
                        this.markError(t, t.def.longError());
                }
                else {
                    if (!!t.def && !t.def.deleted && t.data != t.def.getName())
                        t.data = t.def.getName();
                    t.def = this.lookupSymbol(t);
                    if (!t.def && t.namespaceLibraryName()) {
                        if (!t.namespaceLibrary || t.namespaceLibrary.deleted)
                            t.namespaceLibrary = TDev.Script.libraries().filter(function (l) { return l.getName() == t.namespaceLibraryName(); })[0];
                        t.def = TDev.Script.libNamespaceCache.createSingleton(t.data, t.namespaceLibrary);
                    }
                    if (!t.def) {
                        this.markError(t, TDev.lf("TD101: cannot find '{0}'", t.data));
                        var loc = AST.mkLocal(t.data, this.core.Unknown);
                        t.def = loc;
                        loc.isRegular = true;
                        if (this.seenCurrent)
                            this.missingLocals.push(loc);
                        this.declareLocal(loc);
                    }
                }
                if (t.def instanceof AST.LocalDef)
                    this.recordLocalRead(t.def);
                if (t.def instanceof AST.LocalDef)
                    t.forceLocal = true;
                else if (t.def instanceof AST.SingletonDef)
                    t.forceLocal = false;
                var l = t.def;
                if (l instanceof AST.LocalDef && l.lambdaNameStatus) {
                    if (l.lambdaNameStatus == 1)
                        this.markError(t, TDev.lf("TD102: lambda reference '{0}' cannot be used more than once", l.getName()));
                    else {
                        l.lambdaNameStatus = 1;
                        if (this.typeHint && this.typeHint.isAction) {
                            l._kind = this.typeHint;
                        }
                    }
                }
                t._kind = t.def.getKind();
                if (t.def instanceof AST.LocalDef) {
                    var l = t.def;
                    if (!this.seenCurrent)
                        l.lastUsedAt = this.timestamp++;
                }
                else if (this.countToUpdate != 0) {
                    if (t.def instanceof AST.SingletonDef) {
                        var u = t.def.usage;
                        if (this.countToUpdate == 1)
                            u.localCount++;
                        else
                            u.globalCount++;
                    }
                }
            };
            TypeChecker.prototype.visitLiteral = function (l) {
                if (l instanceof AST.FieldName) {
                    var mkKind = function () {
                        var mk = TDev.MultiplexRootProperty.md_make_kind();
                        mk.md_parametric("T");
                        var prop = TDev.MultiplexRootProperty.md_make_prop(mk, 0, TDev.api.core.Unknown, ":", "Whatever", [], mk.getParameter(0));
                        return prop.getResult().getKind();
                    };
                    l._kind = mkKind();
                }
                else
                    switch (typeof l.data) {
                        case "number":
                            if (TDev.Cloud.isRestricted() && !this.inShim) {
                                if (TDev.Util.between(-0x80000000, l.data, l.possiblyNegative ? 0x80000000 : 0x7fffffff) != l.data) {
                                    this.markError(l, TDev.lf("TD209: the number is outside of the allowed range (between {0} and {1})", -0x80000000, 0x7fffffff));
                                }
                                else if (Math.round(l.data) != l.data) {
                                    this.markError(l, TDev.lf("TD210: fractional numbers not allowed"));
                                }
                            }
                            l._kind = this.core.Number;
                            break;
                        case "string":
                            l._kind = this.core.String;
                            break;
                        case "boolean":
                            l._kind = this.core.Boolean;
                            break;
                        default: TDev.Util.die();
                    }
            };
            TypeChecker.prototype.typeCheckExpr = function (e) {
                e._kind = null;
                this.dispatch(e);
                TDev.Util.assert(e.getKind() != null);
            };
            TypeChecker.prototype.expectExpr = function (expr, tp, whoExpects, skipTypecheck) {
                if (skipTypecheck === void 0) { skipTypecheck = false; }
                if (!skipTypecheck) {
                    var prevHint = this.typeHint;
                    this.typeHint = tp;
                    this.typeCheckExpr(expr);
                    this.typeHint = prevHint;
                }
                if (!TDev.Util.check(expr.getKind() != null, "expr type unset2")) {
                    expr._kind = AST.api.core.Unknown;
                }
                if (tp != null && expr.getKind() !== tp) {
                    var code = "TD103: ";
                    var suff = "";
                    if (tp.getRoot() == AST.api.core.Ref && (expr.referencedData() || expr.referencedRecordField())) {
                        code = "TD164: ";
                        suff = TDev.lf("; are you missing  → ◈ref?");
                    }
                    var msg = TDev.lf("'{0}' expects {1} here", whoExpects, tp.toString());
                    var k = expr.getKind();
                    if (k != this.core.Unknown)
                        msg += TDev.lf(", got {0}", k.toString());
                    this.markError(expr, code + msg + suff);
                }
            };
            TypeChecker.prototype.handleAsync = function (t, args) {
                t._kind = this.core.Unknown;
                if (args.length != 2) {
                    this.markError(t, TDev.lf("TD104: syntax error in async"));
                    return;
                }
                var arg = args[1];
                if (arg instanceof AST.Call)
                    arg.runAsAsync = true;
                this.expectExpr(arg, null, "async");
                var calledProp = arg.getCalledProperty();
                var isAsyncable = calledProp && !!(calledProp.getFlags() & 4096 /* Async */);
                if (calledProp == AST.api.core.AsyncProp)
                    isAsyncable = false;
                if (!isAsyncable) {
                    this.markError(t, TDev.lf("TD157: 'async' keyword needs a non-atomic API or function to call"));
                    return;
                }
                arg.runAsAsync = true;
                if (calledProp && calledProp.forwardsTo() instanceof AST.Action) {
                    var act = calledProp.forwardsTo();
                    if (act.getOutParameters().length > 1)
                        this.markError(t, TDev.lf("TD170: cannot use 'async' on functions with more than one output parameter"));
                }
                t._kind = this.core.Task.createInstance([arg.getKind()]);
            };
            TypeChecker.prototype.computeClosure = function (inl) {
                var _this = this;
                inl.closure = [];
                inl.allLocals = [];
                this.readLocals.forEach(function (l) {
                    if (_this.outsideScopeLocals.indexOf(l) >= 0) {
                        inl.closure.push(l);
                        l._isCaptured = true;
                    }
                    inl.allLocals.push(l);
                });
            };
            TypeChecker.prototype.handleFun = function (t, args) {
                var _this = this;
                var ak = null;
                var resKind = null;
                if (this.typeHint && this.typeHint.isAction) {
                    ak = this.typeHint;
                    var outp = ak.getOutParameters();
                    if (outp.length != 1)
                        this.markError(t, TDev.lf("TD194: lambda expressions need to return exactly one value; function type '{0}' returns {1}", ak.getName(), outp.length));
                    else
                        resKind = outp[0].getKind();
                }
                else {
                    this.markError(t, TDev.lf("TD195: lambda expressions can only be used as arguments of function type"));
                }
                this.actionScope(this.typeHint, function () {
                    if (ak) {
                        var synth = new AST.InlineAction();
                        synth.name = AST.mkLocal(TDev.Random.uniqueId(), ak);
                        _this.declareLocal(synth.name);
                        var names = t.propRef.fromOp.getFunArgs() || [];
                        synth.inParameters = ak.getInParameters().map(function (p, i) { return AST.mkLocal(names[i] || p.getName(), p.getKind()); });
                        t.propRef.fromOp.funArgs = synth.inParameters;
                        synth.outParameters = ak.getOutParameters().map(function (p) { return AST.mkLocal(p.getName(), p.getKind()); });
                        synth.inParameters.forEach(function (p) { return _this.declareLocal(p); });
                        synth.body = new AST.CodeBlock();
                        synth.body.parent = synth;
                        synth.parent = _this.lastStmt.parent;
                        var bb = AST.Parser.emptyExprStmt();
                        synth.body.setChildren([bb]);
                        var outp0 = synth.outParameters[0];
                        if (outp0) {
                            var resR = AST.mkThing(outp0.getName(), true);
                            resR.def = outp0;
                            bb.expr.parsed = AST.mkFakeCall(AST.PropertyRef.mkProp(AST.api.core.AssignmentProp), [
                                resR,
                                args[1]
                            ]);
                            t.funAction = synth;
                        }
                    }
                    _this.expectExpr(args[1], resKind, "lambda expression");
                    if (ak)
                        _this.computeClosure(synth);
                });
                t._kind = ak || this.core.Unknown;
            };
            TypeChecker.prototype.recordLocalRead = function (loc) {
                if (this.readLocals.indexOf(loc) < 0)
                    this.readLocals.push(loc);
            };
            TypeChecker.prototype.recordLocalWrite = function (loc) {
                this.recordLocalRead(loc);
                if (this.writtenLocals.indexOf(loc) < 0)
                    this.writtenLocals.push(loc);
            };
            TypeChecker.prototype.handleAssignment = function (t, args) {
                t._kind = this.core.Nothing;
                if (args.length != 2) {
                    this.markError(t, TDev.lf("TD104: syntax error in assignment"));
                    return;
                }
                TDev.Util.assert(args.length == 2);
                var lhs = args[0].flatten(this.core.TupleProp);
                var rhs = args[1];
                this.isTopExpr = true;
                this.typeCheckExpr(rhs);
                var info = new AST.AssignmentInfo();
                t._assignmentInfo = info;
                var sources = [AST.mkLocal("", rhs.getKind())];
                var act = rhs.anyCalledAction();
                if (act != null) {
                    sources = act.getOutParameters().map(function (a) { return a.local; });
                    var missing = sources.length - lhs.length;
                    if (missing > 0) {
                        this.markError(t, TDev.lf("TD105: function '{0}' returns {1} more value{1:s}", act, missing));
                        info.missingArguments = missing;
                    }
                }
                info.targets = lhs;
                info.sources = sources;
                for (var i = 0; i < lhs.length; ++i) {
                    var trg = lhs[i];
                    var src = sources[i];
                    if (src == undefined) {
                        this.markError(trg, TDev.lf("TD106: not enough values returned to assign to {0}", trg));
                        continue;
                    }
                    var prevErr = this.errorCount;
                    if (trg.nodeType() === "thingRef") {
                        var tr = trg;
                        tr._lastTypechecker = this;
                        if (!!tr.def)
                            tr.data = tr.def.getName();
                        var name = tr.data;
                        var thing = this.lookupSymbol(tr);
                        if (!thing) {
                            var loc = AST.mkLocal(name, src.getKind());
                            info.definedVars.push(loc);
                            thing = loc;
                            loc.isRegular = true;
                            this.declareLocal(loc);
                            if (!src.getKind().hasContext(1 /* Parameter */)) {
                                if (src.getKind() == AST.api.core.Nothing && this.topApp.featureMissing(2 /* ContextCheck */))
                                    info.fixContextError = true;
                                this.markError(tr, TDev.lf("TD155: '{0}' cannot be assigned to a local variable", src.getKind()));
                            }
                        }
                        else {
                            var loc = thing;
                            if (this.readOnlyLocals.indexOf(loc) >= 0) {
                                if (!AST.writableLocalsInClosures && this.actionSection == 3 /* Lambda */) {
                                    this.markError(trg, TDev.lf("TD107: inline functions cannot assign to locals from outside like '{0}'", name));
                                }
                                else {
                                    this.markError(trg, TDev.lf("TD108: you cannot assign to the local variable '{0}'", name));
                                }
                            }
                            else {
                                if (this.outsideScopeLocals.indexOf(loc) >= 0)
                                    loc._isCaptured = true;
                                this.recordLocalWrite(loc);
                            }
                            if (loc._isCaptured || this.currLoop)
                                loc._isMutable = true;
                        }
                        this.typeCheckExpr(trg);
                    }
                    else {
                        this.typeCheckExpr(trg);
                        var gd = trg.referencedData();
                        var rcf = trg.referencedRecordField();
                        var setter = trg.getLiftedSetter();
                        if (rcf == null && gd == null && setter == null) {
                            this.markError(trg, TDev.lf("TD109: cannot assign to this"));
                            continue;
                        }
                        if (gd && gd.readonly) {
                            this.markError(trg, TDev.lf("TD110: trying to assign to a read-only variable"));
                        }
                        else if (rcf && rcf.isKey) {
                            this.markError(trg, TDev.lf("TD163: trying to assign to an index key"));
                        }
                        else {
                            TDev.Util.assert(!!setter || trg.isRefValue());
                        }
                        trg.autoGet = false;
                    }
                    if (src.getKind() != trg.getKind() && prevErr == this.errorCount)
                        this.markError(trg, TDev.lf("TD111: cannot assign from {0} to {1}", src.getKind(), trg.getKind()));
                }
            };
            TypeChecker.prototype.lintJavaScript = function (js, isAsync) {
                var _this = this;
                var toks = AST.Lexer.tokenize(js).map(function (l) {
                    switch (l.category) {
                        case 0 /* Op */:
                        case 1 /* Id */:
                        case 2 /* Keyword */:
                        case 5 /* Label */:
                            return l.data;
                        default:
                            return "";
                    }
                }).filter(function (s) { return !!s; });
                var nextProtected = false;
                var hasResume = false;
                var hasUnprotected = 0;
                var hasOverprotected = 0;
                var brStack = [];
                var hasBrError = false;
                toks.forEach(function (t, i) {
                    if ((t == "resume" || t == "checkAndResume") && toks[i + 1] == "(")
                        hasResume = true;
                    if (t == "protect" && toks[i + 1] == "(")
                        nextProtected = true;
                    if (t == "function") {
                        if (isAsync) {
                            if (!nextProtected)
                                hasUnprotected++;
                        }
                        else {
                            if (nextProtected)
                                hasOverprotected++;
                        }
                        nextProtected = false;
                    }
                    if (t == "(")
                        brStack.push(")");
                    if (t == "{")
                        brStack.push("}");
                    if (t == "[")
                        brStack.push("]");
                    if (t == ")" || t == "}" || t == "]") {
                        if (brStack.peek() != t) {
                            if (!hasBrError)
                                _this.hintsToFlush.push(TDev.lf("JS hint: possible brace mismatch: got '{0}', expecting '{1}'", t, brStack.peek()));
                            hasBrError = true;
                        }
                        else
                            brStack.pop();
                    }
                });
                if (!hasBrError && brStack.length > 0)
                    this.hintsToFlush.push(TDev.lf("JS hint: possible missing closing brace: '{0}'", brStack.peek()));
                if (isAsync && !hasResume)
                    this.hintsToFlush.push(TDev.lf("JS hint: using 'javascript async' but no call to 'resume()'"));
                if (!isAsync && hasResume)
                    this.hintsToFlush.push(TDev.lf("JS hint: using 'resume()' outside of 'javascript async'"));
                if (hasUnprotected)
                    this.hintsToFlush.push(TDev.lf("JS hint: found function() without lib.protect(...) around it"));
                if (hasOverprotected)
                    this.hintsToFlush.push(TDev.lf("JS hint: found function() with lib.protect(...) outside of `javascript async`"));
            };
            TypeChecker.prototype.checkStringLiteralArguments = function (t) {
                var _this = this;
                var propName = t.prop().getName();
                if (!t.args.slice(1).every(function (a) { return a.getStringLiteral() != null; })) {
                    this.markError(t, TDev.lf("TD179: arguments to `{0}` have to be string literals", propName));
                    return undefined;
                }
                var checkArgumentCount = function (c) {
                    if (t.args.length != c) {
                        _this.markError(t, TDev.lf("TD181: wrong number of arguments to `{0}`", propName));
                        return false;
                    }
                    return true;
                };
                return checkArgumentCount;
            };
            TypeChecker.prototype.handleJavascriptImport = function (t) {
                var _this = this;
                var checkArgumentCount = this.checkStringLiteralArguments(t);
                if (!checkArgumentCount)
                    return;
                var propName = t.prop().getName();
                switch (propName) {
                    case "javascript":
                    case "javascript async":
                        if (!checkArgumentCount(3))
                            return;
                        this.currentAction.getOutParameters().forEach(function (p) { return _this.recordLocalWrite(p.local); });
                        this.lintJavaScript(t.args[2].getStringLiteral(), /async/.test(t.prop().getName()));
                        break;
                    case "thumb":
                        if (!TDev.Cloud.isRestricted()) {
                            this.markError(t, TDev.lf("app->thumb not supported in full Touch Develop"));
                            return;
                        }
                        if (!checkArgumentCount(2))
                            return;
                        if (!this.inShim)
                            this.markError(t, TDev.lf("TD213: app->thumb only supported inside of {asm:}"));
                        if (this.currentAction._compilerInlineBody)
                            this.markError(t, TDev.lf("TD214: only one app->thumb allowed"));
                        this.currentAction._compilerInlineBody = this.lastStmt;
                        this.currentAction.getOutParameters().forEach(function (p) { return _this.recordLocalWrite(p.local); });
                        if (TypeChecker.lintThumb) {
                            var errs = TypeChecker.lintThumb(this.currentAction, t.args[1].getStringLiteral());
                            if (errs.length > 0) {
                                this.markError(t, TDev.lf("TD212: thumb assembler error"));
                                this.lastStmt._inlineErrors = errs;
                            }
                            else {
                                this.lastStmt._inlineErrors = null;
                            }
                        }
                        break;
                    case "import":
                        if (!checkArgumentCount(4))
                            return;
                        var manager = t.args[1].getStringLiteral() || "";
                        var plugin = t.args[2].getStringLiteral();
                        var v = t.args[3].getStringLiteral();
                        if (v == null)
                            v = "*";
                        switch (manager.trim().toLowerCase()) {
                            case "npm":
                                if (!this.topApp.canUseCapability(536870912 /* Npm */))
                                    this.unsupportedCapability(plugin, 536870912 /* Npm */);
                                this.topApp.imports.importNpm(this, t, plugin, v);
                                break;
                            case "cordova":
                                if (!this.topApp.canUseCapability(1073741824 /* Cordova */))
                                    this.unsupportedCapability(plugin, 1073741824 /* Cordova */);
                                this.topApp.imports.importCordova(this, t, plugin, v);
                                break;
                            case "bower":
                                this.topApp.imports.importBower(this, t, plugin, v);
                                break;
                            case "client":
                                this.topApp.imports.importClientScript(this, t, plugin, v);
                                break;
                            case "pip":
                                if (!this.topApp.canUseCapability(536870912 /* Npm */))
                                    this.unsupportedCapability(plugin, 536870912 /* Npm */);
                                this.topApp.imports.importPip(this, t, plugin, v);
                                break;
                            case "touchdevelop": {
                                if (!/^\/?[a-z]{4,}$/.test(v))
                                    this.markError(t, TDev.lf("TD190: version must be a published script id"));
                                else {
                                    if (!this.topApp.canUseCapability(262144 /* EditorOnly */))
                                        this.unsupportedCapability(plugin, 262144 /* EditorOnly */);
                                    this.topApp.imports.importTouchDevelop(this, t, plugin, v.replace(/^\/?/, ""));
                                }
                                break;
                            }
                            default:
                                this.markError(t, TDev.lf("TD191: unknown package manager"));
                                break;
                        }
                        break;
                }
            };
            TypeChecker.prototype.visitCall = function (t) {
                var _this = this;
                var args = t.args;
                var prop = t.prop();
                var wasTopExpr = this.isTopExpr;
                this.isTopExpr = false;
                if (this.inShim)
                    t.isShim = this.inShim;
                t._assignmentInfo = null;
                if (prop === this.core.AssignmentProp) {
                    this.handleAssignment(t, args);
                    return;
                }
                if (prop === this.core.AsyncProp) {
                    this.handleAsync(t, args);
                    return;
                }
                if (prop == this.core.FunProp) {
                    this.handleFun(t, args);
                    return;
                }
                var topInline = this.topInline;
                this.topInline = null;
                var prevErr = this.errorCount;
                this.typeCheckExpr(args[0]);
                var k0 = args[0].getKind();
                if (this.topApp.featureMissing(4 /* Refs */) && args[0].referencedRecordField() && /^(get|set|test and set|confirmed|clear|add)$/.test(t.propRef.data)) {
                    this.numFixes++;
                    prop = null;
                    t.propRef.data = AST.api.core.refPropPrefix + t.propRef.data;
                    if (/^.(get)$/.test(t.propRef.data)) {
                        t.propRef.tokenFix = "delete";
                    }
                    else if (/^.(set)$/.test(t.propRef.data)) {
                        t.propRef.tokenFix = ":=";
                    }
                }
                if (t.propRef.getText().slice(0, 1) == AST.api.core.refPropPrefix && args[0].allowRefUse()) {
                    var innerCall = args[0];
                    TDev.Util.assert(innerCall.autoGet);
                    innerCall._kind = k0 = AST.api.core.Ref.createInstance([k0]);
                    innerCall.autoGet = false;
                }
                if (prop) {
                    if (k0 != this.core.Unknown && prop.getInfixPriority() == 0 && prop.parentKind != k0)
                        prop = null;
                }
                if (prop && prop.deleted) {
                    var nn = prop.getName();
                    if (nn)
                        t.propRef.data = nn;
                    prop = null;
                }
                if (!prop || prop instanceof TDev.UnresolvedProperty) {
                    prop = k0.getProperty(t.propRef.data);
                    if (!prop && this.topApp.featureMissing(64 /* UppercaseMultiplex */)) {
                        if (k0 instanceof TDev.MultiplexKind) {
                            var otherOption = function (s) { return false; };
                            if (t.propRef.data[0] == AST.recordSymbol) {
                                var libsuffix = "\u00A0" + t.propRef.data.slice(1);
                                otherOption = function (s) { return s.slice(-libsuffix.length) == libsuffix; };
                            }
                            prop = k0.listProperties().filter(function (p) { return p.getName().toLowerCase() == t.propRef.data || otherOption(p.getName()); })[0];
                        }
                        else if (k0.getName() == "Create" && t.propRef.data == "collection of") {
                            prop = k0.getProperty("Collection of");
                        }
                    }
                    if (!prop) {
                        var pref = k0.getName() + "->";
                        var autoRenameKey = pref + t.propRef.data;
                        if (AST.propRenames.hasOwnProperty(autoRenameKey))
                            prop = k0.getProperty(AST.propRenames[autoRenameKey]);
                    }
                    if (!prop && args[0] instanceof AST.ThingRef) {
                        var nl = args[0].namespaceLibrary;
                        if (nl && !nl.deleted)
                            prop = nl.getKind().getProperty(t.propRef.data);
                    }
                    if (!prop) {
                        if (prevErr == this.errorCount)
                            this.markError(t, TDev.lf("TD112: i cannot find property '{0}' on {1}", t.propRef.data, k0));
                        prop = new TDev.UnresolvedProperty(k0, t.propRef.data);
                    }
                    t.propRef.prop = prop;
                }
                if (prop instanceof TDev.UnresolvedProperty) {
                    args.slice(1).forEach(function (p) {
                        _this.typeCheckExpr(p);
                    });
                    t._kind = this.core.Unknown;
                    return;
                }
                if (prop && prop.parentKind == this.core.App && /^(javascript|import|thumb)/.test(prop.getName())) {
                    this.handleJavascriptImport(t);
                }
                var imports = prop.getImports();
                if (imports)
                    imports.forEach(function (imp) {
                        switch (imp.manager) {
                            case "cordova":
                                _this.topApp.imports.importCordova(_this, null, imp.name, imp.version);
                                break;
                            case "npm":
                                _this.topApp.imports.importNpm(_this, null, imp.name, imp.version);
                                break;
                            default:
                                TDev.Util.assert(false, imp.manager + " not supported");
                                break;
                        }
                    });
                t.autoGet = t.isRefValue();
                var decl = prop.forwardsTo();
                if (!!decl && decl.deleted) {
                    try {
                        TDev.Util.log("deleted decl name: " + decl.getName());
                        TDev.Util.log("deleted decl: " + decl.serialize());
                    }
                    catch (e) {
                    }
                    TDev.Util.check(false, "deleted decl");
                    decl.deleted = false;
                }
                var cacc = t.calledExtensionAction() || t.calledAction();
                if (cacc) {
                    cacc.markUsed();
                    if (cacc.isPage()) {
                        t._assignmentInfo = new AST.AssignmentInfo();
                        t._assignmentInfo.isPagePush = true;
                    }
                }
                if ((prop.getFlags() & 4096 /* Async */) && !t.runAsAsync) {
                    if (this.inAtomic) {
                        if (this.actionSection == 1 /* Init */) {
                        }
                        else if (this.actionSection == 2 /* Display */) {
                            var isRun = prop.getName() == "run" && prop.parentKind.isAction;
                            if (cacc || isRun) {
                            }
                            else {
                                this.markError(t, TDev.lf("TD172: '{0}' cannot be used in page display section (which is treated as 'atomic')", prop.getName()));
                            }
                        }
                        else {
                            this.markError(t, TDev.lf("TD158: '{0}' cannot be used in functions marked with 'atomic'", prop.getName()));
                        }
                    }
                    this.seenAwait = true;
                }
                if (!prop.isImplementedAnywhere()) {
                    if (prop.getFlags() & 2 /* IsObsolete */)
                        this.hintsToFlush.push(TDev.lf("'{0}' is obsolete and not implemented", prop.getName()));
                    else
                        this.hintsToFlush.push(TDev.lf("'{0}' is currently not implemented", prop.getName()));
                }
                else if (TDev.Cloud.isRestricted() && prop.getCapability() && !(prop.allowInRestricted || (TDev.Cloud.hasPermission("post-raw") && prop.getCapability() == 1048576 /* Network */))) {
                    this.markError(t, TDev.lf("TD211: this call is not supported in the restricted profile"));
                }
                else if (!TDev.Browser.isNodeJS && !this.topApp.canUseProperty(prop)) {
                    this.unsupportedCapability(prop.getName(), prop.getCapability());
                }
                else if (prop.getFlags() & 2 /* IsObsolete */) {
                    this.hintsToFlush.push(TDev.lf("'{0}' is obsolete and should not be used", prop.getName()));
                }
                t._kind = prop.getResult().getKind();
                var inP = prop.getParameters();
                if (this.countToUpdate > 0)
                    if (this.countToUpdate == 1)
                        prop.getUsage().localCount++;
                    else
                        prop.getUsage().globalCount++;
                if (topInline)
                    (function () {
                        var impl = topInline.implicitAction();
                        if (impl) {
                            var implIdx = -1;
                            inP.forEach(function (p, i) {
                                if (AST.InlineActions.isImplicitActionKind(p.getKind()))
                                    implIdx = i;
                            });
                            if (implIdx < 0) {
                                _this.setNodeError(topInline, TDev.lf("TD182: '{0}' doesn't take an implicit inline function", prop));
                            }
                            else {
                                var tok = AST.mkThing(impl.getName(), true);
                                args.splice(implIdx, 0, tok);
                            }
                        }
                    })();
                var optionsParm = AST.OptionalParameter.optionsParameter(prop);
                if (optionsParm && inP.length > args.length)
                    (function () {
                        var lk = optionsParm.getKind();
                        var rec = lk.getRecord();
                        var maker = new AST.PlaceholderDef();
                        maker._kind = lk;
                        maker.escapeDef = {
                            objectToMake: lk,
                            optionalConstructor: topInline,
                            isEmpty: true
                        };
                        var t = AST.mkThing("_libobj_");
                        t.def = maker;
                        args.push(t);
                        if (!topInline)
                            return;
                        var used = {};
                        topInline.optionalParameters().forEach(function (opt) {
                            var fld = lk.getProperty(opt.getName());
                            var stmt = fld ? fld.forwardsToStmt() : null;
                            if (stmt instanceof AST.RecordField) {
                                if (used.hasOwnProperty(opt.getName()))
                                    _this.setNodeError(opt, TDev.lf("TD185: optional parameter '{0}' specified more than once", opt.getName()));
                                used[opt.getName()] = true;
                                var rf = stmt;
                                opt.recordField = rf;
                                maker.escapeDef.isEmpty = false;
                            }
                            else if (!opt.getName()) {
                                _this.setNodeError(opt, TDev.lf("TD193: we need a name for optional parameter of '{0}' (from type '{1}')", prop, lk));
                            }
                            else {
                                _this.setNodeError(opt, TDev.lf("TD183: '{0}' doesn't take optional parameter named '{1}' (in type '{2}')", prop, opt.getName(), lk));
                            }
                        });
                        topInline = null;
                    })();
                if (topInline && topInline.optionalParameters().length > 0)
                    if (optionsParm)
                        this.markError(t, TDev.lf("TD188: '{0}' already has the optional parameters object passed explicitly", prop));
                    else
                        this.markError(t, TDev.lf("TD184: '{0}' doesn't take optional parameters", prop));
                if (inP.length < args.length)
                    this.markError(t, TDev.lf("TD115: excessive parameter(s) supplied to {0}", prop));
                else if (inP.length > args.length)
                    this.markError(t, TDev.lf("TD116: not enough parameters supplied to {0}", prop));
                var concatOk = function (e) {
                    var k = e.getKind();
                    if (k == AST.api.core.Unknown)
                        return;
                    if (k == AST.api.core.Nothing || k.singleton || k instanceof AST.LibraryRefKind)
                        _this.markError(e, TDev.lf("TD117: cannot use this expression as argument to ||; are you missing parenthesis?"));
                };
                if (prop == this.core.StringConcatProp) {
                    this.typeCheckExpr(args[1]);
                    concatOk(args[0]);
                    concatOk(args[1]);
                    if (this.saveFixes)
                        this.fixConcat(t);
                    return;
                }
                for (var i = 0; i < args.length; ++i) {
                    if (i >= inP.length) {
                        if (i > 0)
                            this.typeCheckExpr(args[i]);
                    }
                    else {
                        var expK = inP[i].getKind();
                        if (i == 0 && args[i].getThing() instanceof AST.SingletonDef && expK instanceof AST.LibraryRefKind) {
                            args[i].namespaceLibrary = expK.lib;
                            args[i].namespaceLibraryName();
                        }
                        else {
                            this.expectExpr(args[i], expK, prop.getName(), i == 0);
                        }
                        args[i].languageHint = inP[i].languageHint;
                        var str = inP[i].getStringValues();
                        if (str) {
                            var emap = str.enumMap;
                            if (emap) {
                                var lit = args[i].getLiteral();
                                if (typeof lit == "string") {
                                    var picMap = inP[i].getStringValueArtIds();
                                    if (picMap)
                                        args[i].hintArtId = picMap[lit];
                                    if (str.indexOf(lit) >= 0) {
                                        args[i].enumVal = emap.hasOwnProperty(lit) ? emap[lit] : undefined;
                                    }
                                    else {
                                        this.markError(args[i], TDev.lf("TD199: we didn't expect {0} here; try something like {1}", JSON.stringify(lit), str.map(function (s) { return JSON.stringify(s); }).join(", ").slice(0, 100)));
                                    }
                                }
                                else {
                                    this.markError(args[i], TDev.lf("TD198: we need an enum string here, something like {0}", str.map(function (s) { return JSON.stringify(s); }).join(", ").slice(0, 100)));
                                }
                            }
                            else {
                                var lit = args[i].getLiteral();
                                if (typeof lit == "string") {
                                    var picMap = inP[i].getStringValueArtIds();
                                    if (picMap)
                                        args[i].hintArtId = picMap[lit];
                                    if (str.indexOf(lit) >= 0)
                                        args[i].hintVal = lit;
                                }
                            }
                        }
                        if (/^bitmatrix|bitframe$/i.test(args[i].languageHint)) {
                            var lit = args[i].getLiteral();
                            if (!(typeof lit == "string")) {
                                this.markError(args[i], TDev.lf("TD179: we need a string here"));
                            }
                        }
                    }
                }
                if (this.saveFixes)
                    this.argumentFixes(t, inP);
            };
            TypeChecker.prototype.unsupportedCapability = function (name, cap) {
                var missing = AST.App.capabilityString(cap & ~(this.topApp.getPlatform()));
                if (this.topApp.getPlatformRaw() & 268435456 /* Current */)
                    this.hintsToFlush.push(TDev.lf("your current device does not support '{0}'; to develop scripts for other devices, enable the '{1}' capability in the platform settings in the script properties pane", name, missing));
                else
                    this.hintsToFlush.push(TDev.lf("your current platform settings do not include the '{1}' capability required for '{0}'; you can change platform settings in the script properties pane", name, missing));
                if (this.currentAction)
                    this.currentAction.numUnsupported++;
            };
            TypeChecker.prototype.cloneCall = function (t, args) {
                return AST.mkFakeCall(t.propRef, args);
            };
            TypeChecker.prototype.fixConcat = function (t) {
                var prop = t.args[1].getCalledProperty();
                var c = t.args[1];
                if (prop && prop.getResult().getKind() == AST.api.core.Nothing && c.args.length == 1) {
                    t.savedFix = this.cloneCall(c, [this.cloneCall(t, [t.args[0], c.args[0]])]);
                    this.saveFixes++;
                }
            };
            TypeChecker.prototype.argumentFixes = function (t, inP) {
                if (t.prop() == AST.api.core.TupleProp) {
                    if (t.args[0].getKind() == AST.api.core.String || t.args[1].getKind() == AST.api.core.String) {
                        t.savedFix = AST.mkFakeCall(AST.PropertyRef.mkProp(AST.api.core.StringConcatProp), t.args.slice(0));
                        this.saveFixes++;
                    }
                }
                else if (inP.length > t.args.length) {
                    var args = t.args.slice(0);
                    var locs = this.snapshotLocals();
                    for (var i = args.length; i < inP.length; ++i) {
                        var toks = AST.Fixer.findDefault(inP[i], locs);
                        var innExpr = AST.ExprParser.parse1(toks);
                        this.typeCheckExpr(innExpr);
                        args.push(innExpr);
                    }
                    t.savedFix = this.cloneCall(t, args);
                    this.saveFixes++;
                }
            };
            return TypeChecker;
        })(AST.NodeVisitor);
        AST.TypeChecker = TypeChecker;
        var ClearErrors = (function (_super) {
            __extends(ClearErrors, _super);
            function ClearErrors() {
                _super.apply(this, arguments);
            }
            ClearErrors.prototype.visitAstNode = function (n) {
                n.clearError();
                this.visitChildren(n);
            };
            return ClearErrors;
        })(AST.NodeVisitor);
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var ScriptIcons;
    (function (ScriptIcons) {
        function getScriptIcons() {
            var commonIcon = "M 172.862,139.945L 240.453,207.537L 308.045,139.945L 339.499,171.399L 271.907,238.991L 339.499,306.582L 308.045,338.036L 240.453,270.445L 172.862,338.036L 141.408,306.582L 208.999,238.991L 141.408,171.399L 172.862,139.945 Z ";
            var r = {};
            (["facebook", "twitter"]).concat(ScriptIcons.icons).forEach(function (k) {
                r[k.toLowerCase()] = commonIcon;
            });
            return r;
        }
        ScriptIcons.getScriptIcons = getScriptIcons;
        ScriptIcons.icons = [
            "123",
            "8Ball",
            "ABC",
            "Acorn",
            "Add",
            "AddCircle",
            "AddFolder",
            "AddressBook",
            "AddUser",
            "AdminUser",
            "Airplane",
            "AlignCenter",
            "AlignLeft",
            "AlignRight",
            "AlmostEqual",
            "Alram",
            "Anchor",
            "Appointment",
            "ApproveButton",
            "Arrow-Circle-R",
            "ArrowBox",
            "ArrowCircleAlt",
            "ArrowCircleRounded",
            "ArrowDotted",
            "ArrowDownL",
            "ArrowDownR",
            "ArrowDownRounded",
            "ArrowHead",
            "ArrowLarge",
            "ArrowLR",
            "ArrowMoving",
            "ArrowR",
            "ArrowRLarge",
            "ArrowRounded",
            "ArrowStandard",
            "ArrowStandardCircle",
            "Award",
            "BarChart",
            "Beer",
            "Bell",
            "Binoculars",
            "BlankPage",
            "Bold",
            "Bolt",
            "Bomb",
            "Book",
            "Bookmark",
            "Briefcase",
            "Brush",
            "BulletList",
            "Bullseye",
            "Business",
            "BusinessCard",
            "BusinessPerson",
            "Butterfly",
            "Cactus",
            "Calculator",
            "Callout",
            "Camera",
            "Capitalize",
            "Caution",
            "ChapBack",
            "ChapBackCircle",
            "ChapForward",
            "ChargingBattery",
            "Check",
            "CheckAlt",
            "CheckBox",
            "CheckCircle",
            "CheckCircleAlt",
            "Cherry",
            "Clipboard",
            "Clock",
            "Clover",
            "Club",
            "CoffeeCup",
            "Command",
            "CommandLine",
            "Construction",
            "Contacts",
            "Controller",
            "Controls",
            "Copyright",
            "CreditCard",
            "Cube",
            "Cut",
            "Cycle",
            "Dashboard",
            "Delete",
            "DeleteUser",
            "DeliveryTruck",
            "Directions",
            "Document",
            "Documents",
            "DocumentsAlt",
            "Dollar",
            "DownBox",
            "Download",
            "DownloadButton",
            "DownloadButtonAlt",
            "DownloadPage",
            "Drawing",
            "Email",
            "EmailDoc",
            "EmailOpen",
            "Emergency",
            "EmptyBattery",
            "Erase",
            "Euro",
            "Exclamation",
            "ExclamationCircle",
            "ExclamationCircleAlt",
            "Exit",
            "Expand",
            "Eye",
            "Farm",
            "Female",
            "Files",
            "Film",
            "Fire",
            "Fit",
            "FitHorizontal",
            "Flag",
            "Fleurdelis",
            "FlipChart",
            "FlowChart",
            "Folder",
            "FormatText",
            "Forward",
            "ForwardButton",
            "FourColumn",
            "FullBattery",
            "Funnel",
            "GasPump",
            "Globe",
            "GlobeA",
            "GlobeAS",
            "GlobeAUS",
            "GlobeEUA",
            "GlobeSA",
            "GlobeUS",
            "Government",
            "GPS",
            "Grapes",
            "Graph",
            "Group",
            "HalfBattery",
            "Hammer",
            "Headphones",
            "Heart",
            "HeartAlt",
            "Help",
            "Home",
            "HomeAlt",
            "Horn",
            "Horseshoe",
            "HourGlass",
            "IM",
            "Inbox",
            "Info",
            "InfoCircle",
            "InfoCircleAlt",
            "Italic",
            "Journal",
            "JoyStick",
            "Justified",
            "Key",
            "Lab",
            "Ladder",
            "Leaf",
            "Lightbulb",
            "LineChart",
            "Link",
            "Loading",
            "LoadingAlt",
            "Location",
            "Lock",
            "LockedFolder",
            "Male",
            "Map",
            "Martini",
            "Maximize",
            "Megaphone",
            "Mic",
            "MinusBox",
            "MinusBoxAlt",
            "MobilePhone",
            "Money",
            "Monitor",
            "Moon",
            "Mountains",
            "Movie",
            "MP3Player",
            "Multiply",
            "MultiplyCircle",
            "Music",
            "Mute",
            "Needle",
            "NewPage",
            "NewPageAlt",
            "NextSceneButton",
            "NineColumn",
            "Notebook",
            "NumberedList",
            "Omega",
            "OpenFolder",
            "Package",
            "PageCurl",
            "Paint",
            "Painting",
            "PaperClip",
            "Pause",
            "PauseCircle",
            "Pear",
            "Pen",
            "PenAlt",
            "Pencil",
            "Person",
            "Phone",
            "Photo",
            "Photos",
            "Pie",
            "PieChart",
            "Play",
            "PlayButton",
            "PlayCircle",
            "PlusBox",
            "PlusBoxAlt",
            "PlusCircle",
            "Pound",
            "Power",
            "Presentation",
            "PriceTag",
            "Printer",
            "PushPin",
            "Question",
            "QuestionCircle",
            "QuestionCircleAlt",
            "Quote",
            "Raindrop",
            "Reading",
            "Recycle",
            "RemoveButton",
            "RemoveFolder",
            "RemovePage",
            "RemoveUser",
            "Restore",
            "Revert",
            "Rewind",
            "RewindCircle",
            "Ribbon",
            "RunningMan",
            "Save",
            "SaveAlt",
            "Screwdriver",
            "Search",
            "Setting",
            "Settings",
            "Share",
            "ShareThis",
            "Shield",
            "Shirt",
            "ShoppingBag",
            "ShoppingBasket",
            "ShoppingCart",
            "ShoppingCartAlt",
            "Shrink",
            "Shuffle",
            "Signal",
            "SignalAlt",
            "SixColumn",
            "SmartPhone",
            "SmilieHappy",
            "SmilieHappyAlt",
            "SmilieJustOk",
            "SmilieJustOkAlt",
            "SmilieSad",
            "SmilieSadAlt",
            "SMS",
            "SMSAlt",
            "Snowflake",
            "Sort",
            "SortAZ",
            "Sound",
            "SoundHigh",
            "SoundLow",
            "Space",
            "Spade",
            "Split",
            "Stacks",
            "Star",
            "StarAlt",
            "StrikeOut",
            "Subtract",
            "SubtractCircle",
            "Suitcase",
            "Sun",
            "Switch",
            "TabLeft",
            "TabRight",
            "Tanktop",
            "Target",
            "Terminal",
            "Text",
            "ThreeColumn",
            "ThumbsDown",
            "Ticket",
            "Tools",
            "TouchPad",
            "Trash",
            "Tree",
            "Umbrella",
            "Underline",
            "Unlock",
            "UpBox",
            "Upload",
            "Video",
            "VideoCam",
            "Wand",
            "Warning",
            "WarningAlt",
            "Watch",
            "Weather",
            "Wheel",
            "Wifi",
            "Wine",
            "WorkOrder",
            "Wrench",
            "WritePage",
            "Yen",
            "ZoomIn",
            "ZoomOut",
        ];
        var winIcons = {
            html5: { width: 150, height: 34, path: "<path fill='#E34F29' d='M 6.8512e-006,0.00515747L 29.9015,-6.10352e-005L 27.1782,30.6422L 14.9442,34L 2.7297,30.6422L 6.8512e-006,0.00515747 Z M 24.2843,6.37619L 5.62171,6.37097L 6.61292,17.6124L 19.5937,17.6237L 19.1291,22.5482L 14.9439,23.6255L 10.7365,22.5826L 10.4577,19.523L 6.79574,19.5367L 7.26726,25.3395L 14.9439,27.549L 22.6413,25.4152L 23.639,13.8833L 9.93759,13.8833L 9.68507,9.99295L 24.0851,10.0756L 24.2843,6.37619 Z M 69.6986,6.62717L 64.1534,26.2192L 61.4639,26.2192L 57.4274,11.9013C 57.2553,11.292 57.1519,10.6272 57.1169,9.9072L 57.0601,9.9072C 57.0046,10.5806 56.8866,11.2366 56.7058,11.875L 52.6387,26.2192L 49.9754,26.2192L 44.229,6.62717L 46.7612,6.62717L 50.9332,21.6535C 51.1052,22.2833 51.2145,22.9393 51.2612,23.6216L 51.3311,23.6216C 51.3748,23.1376 51.5162,22.4816 51.7553,21.6535L 56.0892,6.62717L 58.2889,6.62717L 62.4478,21.7629C 62.5936,22.2819 62.7029,22.8927 62.7758,23.5952L 62.8326,23.5952C 62.8676,23.1229 62.9901,22.4948 63.2,21.7104L 67.2103,6.62717L 69.6986,6.62717 Z M 82.7133,19.7818L 72.9173,19.7818C 72.9552,21.3008 73.3765,22.4735 74.1812,23.3C 74.9858,24.1265 76.0937,24.5398 77.5048,24.5398C 79.0908,24.5398 80.5471,24.0733 81.8737,23.1404L 81.8737,25.1914C 80.6491,26.0631 79.0281,26.499 77.0106,26.499C 75.0398,26.499 73.4917,25.8678 72.3663,24.6054C 71.2409,23.343 70.6782,21.566 70.6782,19.2744C 70.6782,17.1111 71.2869,15.3488 72.5041,13.9873C 73.7213,12.6258 75.2337,11.9449 77.0412,11.9449C 78.8459,11.9449 80.2424,12.5332 81.2308,13.7096C 82.2191,14.886 82.7133,16.5208 82.7133,18.614L 82.7133,19.7818 Z M 80.4742,17.8225C 80.4655,16.5864 80.155,15.6243 79.5427,14.9362C 78.9305,14.2483 78.0791,13.9042 76.9888,13.9042C 75.9363,13.9042 75.0427,14.2657 74.308,14.9887C 73.5733,15.7117 73.12,16.6564 72.9479,17.8225L 80.4742,17.8225 Z M 88.3679,24.0718L 88.3111,24.0718L 88.3111,26.219L 86.072,26.219L 86.072,5.50754L 88.3111,5.50754L 88.3111,14.805L 88.3679,14.805C 89.47,12.8982 91.0822,11.9449 93.2047,11.9449C 95.0006,11.9449 96.4066,12.5673 97.4226,13.8123C 98.4387,15.0572 98.9467,16.7248 98.9467,18.8152C 98.9467,21.1418 98.3774,23.004 97.239,24.402C 96.1005,25.7999 94.5414,26.4989 92.5618,26.4989C 90.7134,26.4989 89.3154,25.6899 88.3679,24.0718 Z M 88.3111,18.5659L 88.3111,20.477C 88.3111,21.6082 88.6893,22.5681 89.4459,23.3568C 90.2025,24.1454 91.1639,24.5398 92.33,24.5398C 93.6974,24.5398 94.7688,24.0317 95.5443,23.0157C 96.3199,21.9996 96.7076,20.5879 96.7076,18.7802C 96.7076,17.2583 96.3454,16.0652 95.6209,15.2007C 94.8964,14.3363 93.9146,13.9041 92.6755,13.9041C 91.3636,13.9041 90.3081,14.3472 89.5093,15.2335C 88.7105,16.1199 88.3111,17.2306 88.3111,18.5659 Z M 118.259,26.219L 115.687,26.219L 113.531,20.6213L 105.244,20.6213L 103.211,26.219L 100.626,26.219L 108.227,6.62692L 110.632,6.62692L 118.259,26.219 Z M 112.797,18.662L 109.714,10.4448L 109.416,9.14597L 109.359,9.14597C 109.266,9.69699 109.158,10.1299 109.036,10.4448L 105.974,18.662L 112.797,18.662 Z M 123.074,24.0717L 123.017,24.0717L 123.017,32.6563L 120.778,32.6563L 120.778,12.2246L 123.017,12.2246L 123.017,14.8048L 123.074,14.8048C 124.176,12.8981 125.788,11.9447 127.911,11.9447C 129.715,11.9447 131.123,12.5671 132.135,13.8121C 133.147,15.057 133.653,16.7246 133.653,18.815C 133.653,21.1416 133.083,23.0039 131.945,24.4018C 130.806,25.7998 129.247,26.4987 127.268,26.4987C 125.454,26.4987 124.056,25.6897 123.074,24.0717 Z M 123.017,18.5658L 123.017,20.4768C 123.017,21.608 123.395,22.568 124.152,23.3567C 124.908,24.1452 125.87,24.5396 127.036,24.5396C 128.403,24.5396 129.475,24.0315 130.25,23.0155C 131.026,21.9995 131.413,20.5877 131.413,18.78C 131.413,17.2582 131.051,16.0651 130.327,15.2006C 129.602,14.3362 128.62,13.9039 127.381,13.9039C 126.069,13.9039 125.014,14.347 124.215,15.2334C 123.416,16.1198 123.017,17.2304 123.017,18.5658 Z M 139.587,24.0716L 139.53,24.0716L 139.53,32.6562L 137.291,32.6562L 137.291,12.2246L 139.53,12.2246L 139.53,14.8047L 139.587,14.8047C 140.689,12.898 142.301,11.9446 144.424,11.9446C 146.228,11.9446 147.637,12.567 148.648,13.812C 149.66,15.0569 150.166,16.7246 150.166,18.8149C 150.166,21.1416 149.597,23.0038 148.458,24.4017C 147.32,25.7997 145.761,26.4987 143.781,26.4987C 141.967,26.4987 140.57,25.6897 139.587,24.0716 Z M 139.53,18.5657L 139.53,20.4768C 139.53,21.6079 139.908,22.5679 140.665,23.3566C 141.422,24.1451 142.383,24.5395 143.549,24.5395C 144.916,24.5395 145.988,24.0315 146.763,23.0154C 147.539,21.9994 147.927,20.5876 147.927,18.7799C 147.927,17.2581 147.564,16.065 146.84,15.2005C 146.116,14.3361 145.134,13.9038 143.895,13.9038C 142.583,13.9038 141.527,14.347 140.728,15.2333C 139.93,16.1197 139.53,17.2303 139.53,18.5657 Z '/>" }
        };
        function getWinLogo(name, height, color) {
            if (height === void 0) { height = 2; }
            if (color === void 0) { color = null; }
            var img = winIcons[name];
            if (!img)
                img = winIcons["html5"];
            var path = img.path;
            if (color) {
                path = path.replace(/fill='[^']*'/, "fill='" + color + "'");
            }
            var r = TDev.SVG.svgToElement(TDev.SVG.svgBoilerPlate('0 0 ' + img.width + ' ' + img.height, path));
            r.style.height = height + "em";
            r.style.width = (img.width / img.height * height) + "em";
            return r;
        }
        ScriptIcons.getWinLogo = getWinLogo;
        function stableIconFromName(name) {
            return ScriptIcons.icons[(TDev.Util.getStableHashCode(name) & 0x7fffffff) % ScriptIcons.icons.length];
        }
        ScriptIcons.stableIconFromName = stableIconFromName;
        function stableColorFromName(name) {
            return TDev.Util.colors[(TDev.Util.getStableHashCode(name) & 0x7fffffff) % (TDev.Util.colors.length - 1)];
        }
        ScriptIcons.stableColorFromName = stableColorFromName;
    })(ScriptIcons = TDev.ScriptIcons || (TDev.ScriptIcons = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        AST.recordSymbol = "\u2339";
        AST.oldModelSymbol = "\u229E";
        AST.modelSymbol = "\u2756";
        var RecordKind = (function (_super) {
            __extends(RecordKind, _super);
            function RecordKind(parentDef) {
                _super.call(this);
                this.parentDef = parentDef;
            }
            return RecordKind;
        })(AST.InlineStmt);
        AST.RecordKind = RecordKind;
        var RecordPersistenceKind = (function (_super) {
            __extends(RecordPersistenceKind, _super);
            function RecordPersistenceKind(parentDef) {
                _super.call(this);
                this.parentDef = parentDef;
            }
            return RecordPersistenceKind;
        })(AST.InlineStmt);
        AST.RecordPersistenceKind = RecordPersistenceKind;
        var FieldName = (function (_super) {
            __extends(FieldName, _super);
            function FieldName(isOut) {
                if (isOut === void 0) { isOut = false; }
                _super.call(this);
                this.isOut = isOut;
            }
            FieldName.prototype.accept = function (v) {
                return v.visitFieldName(this);
            };
            return FieldName;
        })(AST.Literal);
        AST.FieldName = FieldName;
        (function (RecordType) {
            RecordType[RecordType["Object"] = 1] = "Object";
            RecordType[RecordType["Table"] = 2] = "Table";
            RecordType[RecordType["Index"] = 3] = "Index";
            RecordType[RecordType["Decorator"] = 4] = "Decorator";
        })(AST.RecordType || (AST.RecordType = {}));
        var RecordType = AST.RecordType;
        (function (RecordPersistence) {
            RecordPersistence[RecordPersistence["Temporary"] = 0] = "Temporary";
            RecordPersistence[RecordPersistence["Local"] = 1] = "Local";
            RecordPersistence[RecordPersistence["Cloud"] = 2] = "Cloud";
            RecordPersistence[RecordPersistence["Partial"] = 3] = "Partial";
        })(AST.RecordPersistence || (AST.RecordPersistence = {}));
        var RecordPersistence = AST.RecordPersistence;
        var SimpleProperty = (function (_super) {
            __extends(SimpleProperty, _super);
            function SimpleProperty(name, help, writesmutable, parentKind, resultKind, isField, paramKind1, paramKind2) {
                if (isField === void 0) { isField = false; }
                if (paramKind1 === void 0) { paramKind1 = null; }
                if (paramKind2 === void 0) { paramKind2 = null; }
                _super.call(this, parentKind, name, help, [], AST.api.core.Unknown);
                this.name = name;
                this.help = help;
                this.writesmutable = writesmutable;
                this.parentKind = parentKind;
                this.resultKind = resultKind;
                this.isField = isField;
                this.paramkinds = [];
                if (paramKind1)
                    this.paramkinds.push(paramKind1);
                if (paramKind2)
                    this.paramkinds.push(paramKind2);
            }
            SimpleProperty.prototype.getName = function () {
                return typeof this.name === "string" ? this.name : this.name.getName();
            };
            SimpleProperty.prototype.setParameterKinds = function (paramkinds) {
                this.paramkinds = paramkinds;
                this.cachedParameters = undefined;
            };
            SimpleProperty.prototype.getParameters = function () {
                var _this = this;
                if (!this.cachedParameters) {
                    var selfParm = AST.PropertyDecl.mkPPext(this, "_this_", this.parentKind);
                    if (this.writesmutable)
                        selfParm._flags |= 1 /* WritesMutable */;
                    this.cachedParameters = [selfParm];
                    this.paramkinds.forEach(function (paramKind) {
                        _this.cachedParameters.push(AST.PropertyDecl.mkPPext(_this, paramKind.getStemName(), paramKind));
                    });
                }
                return this.cachedParameters;
            };
            SimpleProperty.prototype.makeObsolete = function () {
                this._addFlags(2 /* IsObsolete */);
                return this;
            };
            SimpleProperty.prototype.hideIntelliButton = function () {
                this._addFlags(131072 /* HideIntelliButton */);
                return this;
            };
            SimpleProperty.prototype.ignoreReturnValue = function () {
                this._addFlags(262144 /* IgnoreReturnValue */);
                return this;
            };
            SimpleProperty.prototype.getResult = function () {
                return AST.PropertyDecl.mkPPext(this, "", this.resultKind);
            };
            SimpleProperty.prototype.getHelp = function () {
                return this.help;
            };
            SimpleProperty.prototype.isImplemented = function () {
                return true;
            };
            SimpleProperty.prototype.canCacheSearch = function () {
                return false;
            };
            SimpleProperty.deleteProperties = function (props) {
                if (props)
                    props.forEach(function (p) {
                        p.deleted = true;
                    });
            };
            return SimpleProperty;
        })(TDev.Property);
        function memoize(f) {
            var cache;
            var cached = false;
            return function () {
                if (cached)
                    return cache;
                cached = true;
                cache = f();
                return cache;
            };
        }
        function propertyRefsForKind(forKind) {
            var mkRootProp = function () {
                var mk = TDev.MultiplexRootProperty.md_make_kind();
                mk.md_parametric("T");
                var prop = TDev.MultiplexRootProperty.md_make_prop(mk, 0, TDev.api.core.Unknown, ":", "Whatever", [], mk.getParameter(0));
                return prop;
            };
            var acc = [];
            var genPropRef = function (parentProp, forKind, prefix) {
                var parentKind = parentProp.getResult().getKind();
                var argsN = TDev.MultiplexKind.argsFor(forKind);
                var prop;
                if (argsN.length == 0) {
                    prop = parentKind.createFinal(forKind);
                }
                else {
                    prop = new TDev.MultiplexProperty(forKind, parentKind, new TDev.MultiplexKind(argsN));
                }
                var propRef = new AST.PropertyRef();
                propRef.prop = prop;
                propRef.data = prefix + TDev.MultiplexKind.propName(prop.forKind);
                acc.push(propRef);
                if (forKind.getParameterCount() > 0)
                    forKind.parameters.forEach(function (p, i) { return genPropRef(prop, p, argsN[i].prefix); });
            };
            genPropRef(mkRootProp(), forKind, "");
            return acc;
        }
        AST.propertyRefsForKind = propertyRefsForKind;
        function KindToCodomain(kind) {
            if (kind instanceof RecordEntryKind)
                return "^" + kind.getRecord().getStableName();
            else
                return TDev.RT.Conv.getCloudCodomain(kind.getName());
        }
        AST.KindToCodomain = KindToCodomain;
        var RecordField = (function (_super) {
            __extends(RecordField, _super);
            function RecordField(name, k, isKey, description) {
                var _this = this;
                if (description === void 0) { description = ""; }
                _super.call(this);
                this.isKey = isKey;
                this.description = description;
                this.exprHolder = new AST.ExprHolder();
                this.commentBlock = new AST.CodeBlock();
                this.setStableName(AST.uniqueAstId(16));
                this.commentBlock.setChildren([]);
                description.split(/\n/).forEach(function (l) {
                    if (!l)
                        return;
                    var c = new AST.FieldComment(_this);
                    c.text = l;
                    _this.commentBlock.push(c);
                });
                this.commentBlock.parent = this;
                this.setKind(k);
                _super.prototype.setName.call(this, name);
                this.setupForEdit();
            }
            RecordField.prototype.forSearch = function () {
                return this.getName() + " " + this.dataKind.toString();
            };
            RecordField.prototype.setupForEdit = function () {
                this.exprHolder.tokens = [new FieldName()].concat(propertyRefsForKind(this.dataKind));
                this.exprHolder.parsed = new AST.Literal();
                this.exprHolder.locals = [];
                this.setName(this.getName());
            };
            RecordField.prototype.calcNode = function () {
                return this.exprHolder;
            };
            RecordField.prototype.notifyChange = function () {
                var _this = this;
                var toks = this.exprHolder.tokens;
                if (toks.length == 0) {
                    var fb = this.parent;
                    var ch = fb.children().filter(function (x) { return x != _this; });
                    fb.setChildren(ch);
                }
                else if (toks[0] && toks[0] instanceof FieldName) {
                    var newName = toks[0].data;
                    if (newName != this.getName() && this.def().getFields().every(function (f) { return f.getName() != newName; })) {
                        _super.prototype.setName.call(this, newName);
                        TDev.Script.notifyChangeAll();
                    }
                    var needTc = false;
                    if (toks.length > 1) {
                        var newk = this.exprHolder.getKind();
                        if (AST.isProperKind(newk) && newk != this.dataKind) {
                            this.setKind(newk);
                            this.def().clearPropertyCaches();
                            needTc = true;
                        }
                    }
                    if (needTc)
                        AST.TypeChecker.tcApp(TDev.Script);
                }
                if (toks.length > 1 && toks[1] instanceof AST.PropertyRef) {
                    toks[1].skipArrow = true;
                }
                this.propertyDeflStrings = undefined;
                _super.prototype.notifyChange.call(this);
            };
            RecordField.prototype.accept = function (v) {
                return v.visitRecordField(this);
            };
            RecordField.prototype.isLastChild = function () {
                return false;
            };
            RecordField.prototype.nodeType = function () {
                return "recordField";
            };
            RecordField.prototype.setName = function (v) {
                _super.prototype.setName.call(this, v);
                var toks = this.exprHolder.tokens;
                if (toks.length > 0 && toks[0] instanceof FieldName)
                    toks[0].data = v;
            };
            RecordField.prototype.def = function () {
                return this.parent.parentDef;
            };
            RecordField.prototype.getDescription = function () {
                return this.description;
            };
            RecordField.prototype.setKind = function (k) {
                if (this.dataKind != k) {
                    this.dataKind = k;
                    this.fieldKind = AST.api.core.Ref.createInstance([k]);
                    this.clearPropertyCaches();
                }
            };
            RecordField.prototype.matches = function (d) {
                return this.dataKind.matches(d);
            };
            RecordField.prototype.bogusPropertyParameter = function () {
                if (this.propertyDeflStrings === undefined) {
                    var m = /\{hints:([^{}]*)/.exec(this.getDescription());
                    if (m)
                        this.propertyDeflStrings = m[1].split(/,/);
                    else if (this.dataKind == AST.api.core.Boolean)
                        this.propertyDeflStrings = RecordField.trueFalse;
                    else
                        this.propertyDeflStrings = null;
                }
                var r = this.def().mkPP(this.getName(), this.dataKind);
                if (this.propertyDeflStrings) {
                    r.setDeflStrings(this.propertyDeflStrings);
                    if (this.propertyDeflStrings == RecordField.trueFalse)
                        r.setDeflStrings(null);
                }
                return r;
            };
            RecordField.prototype.clearPropertyCaches = function () {
                if (this.propertyCache) {
                    this.propertyCache.deleted = true;
                    this.propertyCache = null;
                }
            };
            RecordField.prototype.onDelete = function () {
                this.clearPropertyCaches();
            };
            RecordField.prototype.asProperty = function () {
                if (!this.propertyCache) {
                    if (this.isKey) {
                        var sp = new SimpleProperty(this, TDev.lf("get the {0} key", this.dataKind.toString()), false, this.def().entryKind, this.dataKind, true);
                        sp.isKey = true;
                        this.propertyCache = sp;
                    }
                    else {
                        this.propertyCache = new SimpleProperty(this, TDev.lf("access the {0} field", this.dataKind.toString()), false, this.def().entryKind, this.dataKind, true);
                    }
                    var s = this;
                    this.propertyCache.forwardsToStmt = function () { return s; };
                }
                return this.propertyCache;
            };
            RecordField.prototype.writeDef = function (tw) {
                if (this.description)
                    tw.comment(this.description);
                tw.uniqueId(this.getStableName());
                tw.id(this.getName()).op(":").kind(this.def().parent, this.dataKind).nl();
            };
            RecordField.prototype.writeTo = function (tw) {
                tw.keyword("var").id(this.getName()).op(":").kind(this.def().parent, this.dataKind).op0(";").nl().comment(this.description);
            };
            RecordField.prototype.getCloudType = function () {
                if (this.isKey) {
                    if (this.dataKind instanceof RecordEntryKind) {
                        return (this.dataKind).record.getCloudType();
                    }
                    else {
                        return TDev.RT.Conv.getCloudDomain(this.dataKind.getName());
                    }
                }
                else {
                    return TDev.Revisions.Parser.MakeProperty(this.getStableName(), this.def().getCloudType(), AST.KindToCodomain(this.dataKind));
                }
            };
            RecordField.prototype.referenceName = function () {
                if (this.def().recordType == 1 /* Object */)
                    return "$" + this.getName();
                return this.getStableName();
            };
            RecordField.trueFalse = ["true", "false"];
            return RecordField;
        })(AST.Stmt);
        AST.RecordField = RecordField;
        var ExtensionEnabledKind = (function (_super) {
            __extends(ExtensionEnabledKind, _super);
            function ExtensionEnabledKind(name, desc) {
                _super.call(this, name, desc);
                this.extActions = [];
                this.isData = true;
            }
            ExtensionEnabledKind.prototype.addExtensionAction = function (a) {
                this.cachedVersion = null;
                this.extActions.push(a);
            };
            ExtensionEnabledKind.prototype.listExtensions = function () {
                var _this = this;
                if (this.cachedVersion === TDev.Script.notifyVersionMarker) {
                    return this.cachedExtensions;
                }
                var res = [];
                TDev.Script.things.forEach(function (t) {
                    if (t instanceof AST.Action) {
                        var a = t;
                        if (a.getExtensionKind() == _this) {
                            res.push(new AST.ExtensionProperty(a));
                        }
                    }
                });
                if (res.length > 0) {
                    if (this.extActions.length > 0)
                        this.cachedExtensions = this.extActions.concat(res);
                    else
                        this.cachedExtensions = res;
                }
                else {
                    this.cachedExtensions = this.extActions;
                }
                this.cachedVersion = TDev.Script.notifyVersionMarker;
                return this.cachedExtensions;
            };
            ExtensionEnabledKind.prototype.getExtension = function (name) {
                return this.listExtensions().filter(function (p) { return p.getName() == name; })[0];
            };
            ExtensionEnabledKind.prototype.isUserDefined = function () {
                return true;
            };
            ExtensionEnabledKind.prototype.isExtensionEnabled = function () {
                return true;
            };
            return ExtensionEnabledKind;
        })(TDev.Kind);
        AST.ExtensionEnabledKind = ExtensionEnabledKind;
        var RecordEntryKind = (function (_super) {
            __extends(RecordEntryKind, _super);
            function RecordEntryKind(record) {
                _super.call(this, "none", "record entry");
                this.record = record;
                this.collectionKind = AST.api.core.Collection.createInstance([this]);
                this.isSerializable = true;
            }
            RecordEntryKind.prototype.getRecord = function () {
                return this.record;
            };
            RecordEntryKind.prototype.isError = function () {
                return this.record.deleted;
            };
            RecordEntryKind.prototype.listPriority = function () {
                return 5;
            };
            RecordEntryKind.prototype.isUserDefined = function () {
                return true;
            };
            RecordEntryKind.prototype.getDescription = function () {
                return this.record ? this.record.getEntryKindDescription() : "";
            };
            RecordEntryKind.prototype.getHelp = function () {
                return this.record.getEntryKindDescription();
            };
            RecordEntryKind.prototype.getStemName = function () {
                return this.record.getCoreName();
            };
            RecordEntryKind.prototype.icon = function () {
                return RecordDef.GetIcon(this.record.recordType);
            };
            RecordEntryKind.prototype.parentLibrary = function () {
                return this.getRecord().parentLibrary();
            };
            RecordEntryKind.prototype.getContexts = function () {
                switch (this.record.recordType) {
                    case 1 /* Object */:
                        return TDev.KindContext.General | 256 /* WallTap */ | 32 /* GcKey */ | 1024 /* Json */;
                    case 2 /* Table */:
                        return TDev.KindContext.General | 64 /* RowKey */ | 32 /* GcKey */ | 4 /* CloudField */ | 256 /* WallTap */ | 1024 /* Json */;
                    case 4 /* Decorator */:
                        return TDev.KindContext.General | 256 /* WallTap */;
                    case 3 /* Index */:
                        return TDev.KindContext.General | 256 /* WallTap */ | 32 /* GcKey */;
                }
                TDev.Util.die();
            };
            RecordEntryKind.prototype.getCommonProps = function () {
                if (!this.props) {
                    var clear = new SimpleProperty("clear fields", TDev.lf("sets all fields to their default values"), true, this, AST.api.core.Nothing);
                    var eq = new SimpleProperty("equals", TDev.lf("tests if two references refer to the same object"), false, this, AST.api.core.Boolean, false, this);
                    var post = new SimpleProperty("post to wall", TDev.lf("displays the object on the wall"), false, this, AST.api.core.Nothing);
                    var tojson = new SimpleProperty("to json", TDev.lf("export a JSON representation of the contents"), false, this, AST.api.core.JsonObject);
                    switch (this.record.recordType) {
                        case 1 /* Object */:
                            this.props = [
                                post,
                                clear,
                                eq,
                                new SimpleProperty("is invalid", TDev.lf("checks if reference has not been set"), false, this, AST.api.core.Boolean),
                                tojson,
                                new SimpleProperty("from json", TDev.lf("import field values from a JSON object"), false, this, AST.api.core.Nothing, false, AST.api.core.JsonObject)
                            ];
                            break;
                        case 2 /* Table */:
                            var dr = new SimpleProperty("delete row", TDev.lf("deletes this row from the table"), true, this, AST.api.core.Nothing);
                            var conf = new SimpleProperty("confirmed", TDev.lf("true if last update of row has been confirmed by server"), false, this, AST.api.core.Boolean);
                            this.props = [
                                post,
                                eq,
                                dr,
                                tojson,
                                new SimpleProperty("from json", TDev.lf("import column values from a JSON object"), false, this, AST.api.core.Nothing, false, AST.api.core.JsonObject),
                                new SimpleProperty("is invalid", TDev.lf("checks if reference has not been set"), false, this, AST.api.core.Boolean),
                                new SimpleProperty("is deleted", TDev.lf("checks if this row (or any of its linked rows) has been deleted"), false, this, AST.api.core.Boolean),
                                conf
                            ];
                            if (!(this.record.cloudEnabled || this.record.cloudPartiallyEnabled))
                                conf.hideIntelliButton();
                            break;
                        case 4 /* Decorator */:
                            this.props = [post, clear, eq, tojson, new SimpleProperty("from json", TDev.lf("import field values from a JSON object"), false, this, AST.api.core.Nothing, false, AST.api.core.JsonObject),];
                            break;
                        case 3 /* Index */:
                            this.props = [post, clear, eq, tojson, new SimpleProperty("from json", TDev.lf("import field values from a JSON object"), false, this, AST.api.core.Nothing, false, AST.api.core.JsonObject), new SimpleProperty("is invalid", TDev.lf("checks if reference has not been set"), false, this, AST.api.core.Boolean), new SimpleProperty("is deleted", TDev.lf("checks if this index entry is deleted, i.e. has a deleted row key"), false, this, AST.api.core.Boolean), new SimpleProperty("confirmed", TDev.lf("true if last update of entry has been confirmed by server"), false, this, AST.api.core.Boolean)];
                            break;
                        default: TDev.Util.die();
                    }
                }
                return this.props;
            };
            RecordEntryKind.prototype.clearPropertyCaches = function () {
                SimpleProperty.deleteProperties(this.props);
                this.props = null;
            };
            RecordEntryKind.prototype.kill = function () {
                this.clearPropertyCaches();
                this.record.deleted = true;
            };
            RecordEntryKind.prototype.listProperties = function () {
                return this.getCommonProps().concat(this.record.getFields().map(function (p) { return p.asProperty(); })).concat(this.listExtensions());
            };
            RecordEntryKind.prototype.getProperty = function (name) {
                var flt = function (p) { return p.getName() === name; };
                var a = this.getCommonProps().filter(flt)[0];
                if (a)
                    return a;
                var b = this.record.getFields().filter(flt)[0];
                if (b)
                    return b.asProperty();
                return this.getExtension(name);
            };
            RecordEntryKind.prototype.getName = function () {
                return this.record.getCoreName();
            };
            RecordEntryKind.prototype.toString = function () {
                return this.record.getNamespace() + this.getName();
            };
            RecordEntryKind.prototype.recordType = function () {
                return this.record.recordType;
            };
            return RecordEntryKind;
        })(ExtensionEnabledKind);
        AST.RecordEntryKind = RecordEntryKind;
        var RecordDefKind = (function (_super) {
            __extends(RecordDefKind, _super);
            function RecordDefKind(record) {
                _super.call(this, "no name", "record definition");
                this.record = record;
                this.isData = true;
                this.isSerializable = true;
            }
            RecordDefKind.prototype.getRecord = function () {
                return this.record;
            };
            RecordDefKind.prototype.listProperties = function () {
                return this.record.getProperties();
            };
            RecordDefKind.prototype.getProperty = function (name) {
                return this.record.getProperties().filter(function (a) { return a.getName() === name; })[0];
            };
            RecordDefKind.prototype.getName = function () {
                return this.record.getName();
            };
            RecordDefKind.prototype.toString = function () {
                return this.record.toString();
            };
            RecordDefKind.prototype.getDescription = function () {
                return this.record.getDescription();
            };
            RecordDefKind.prototype.getHelp = function () {
                return this.record.getDescription();
            };
            RecordDefKind.prototype.isEnumerable = function () {
                return this.record.recordType === 2 /* Table */ || this.record.recordType === 3 /* Index */;
            };
            RecordDefKind.prototype.hasEnumerator = function () {
                return true;
            };
            RecordDefKind.prototype.getContexts = function () {
                if (!this.record)
                    return 0 /* None */;
                switch (this.record.recordType) {
                    case 4 /* Decorator */:
                    case 1 /* Object */:
                        return 512 /* Enumerable */;
                    case 2 /* Table */:
                    case 3 /* Index */:
                        return 512 /* Enumerable */;
                }
                TDev.Util.die();
            };
            return RecordDefKind;
        })(TDev.Kind);
        AST.RecordDefKind = RecordDefKind;
        var RecordCtorProperty = (function (_super) {
            __extends(RecordCtorProperty, _super);
            function RecordCtorProperty(record, from_json) {
                if (from_json === void 0) { from_json = false; }
                _super.call(this, record.entryKind, "", "", [], AST.api.core.Unknown);
                this.record = record;
                this.from_json = from_json;
                this.parentKind = this.record.tableKind;
            }
            RecordCtorProperty.prototype.getName = function () {
                var suff = this.from_json ? " from json" : "";
                switch (this.record.recordType) {
                    case 1 /* Object */: return "create" + suff;
                    case 2 /* Table */: return "add row" + suff;
                    case 4 /* Decorator */: return "at";
                    case 3 /* Index */: return (this.record.keys.count() === 0 ? "singleton" : "at");
                    default: TDev.Util.die();
                }
            };
            RecordCtorProperty.prototype.getParameters = function () {
                var _this = this;
                var res = [AST.PropertyDecl.mkPPext(this, "_this_", this.record.tableKind)];
                this.record.keys.forEach(function (p) {
                    res.push(AST.PropertyDecl.mkPPext(_this, p.getName(), p.dataKind));
                });
                if (this.from_json)
                    res.push(AST.PropertyDecl.mkPPext(this, "json", AST.api.core.JsonObject));
                return res;
            };
            RecordCtorProperty.prototype.getResult = function () {
                var rs = AST.PropertyDecl.mkPPext(this, "k", this.record.entryKind);
                if (this.record.recordType === 1 /* Object */)
                    rs.md_writesMutable();
                return rs;
            };
            RecordCtorProperty.prototype.getDescription = function () {
                switch (this.record.recordType) {
                    case 1 /* Object */:
                        return this.from_json ? "create a fresh object and initialize from given JSON object" : "create a fresh object";
                    case 2 /* Table */:
                        if (this.record.keys.count() === 0)
                            return "create a fresh row in the table";
                        else
                            return "create a fresh row in the table, with the given links";
                    case 4 /* Decorator */:
                        return "access the decoration for a target";
                    case 3 /* Index */:
                        if (this.record.keys.count() === 0)
                            return "access the single entry (there is only one, since there are no keys)";
                        else
                            return "accesses the entry indexed by the given keys";
                    default: TDev.Util.die();
                }
            };
            RecordCtorProperty.prototype.isImplemented = function () {
                return true;
            };
            RecordCtorProperty.prototype.canCacheSearch = function () {
                return false;
            };
            return RecordCtorProperty;
        })(TDev.Property);
        AST.RecordCtorProperty = RecordCtorProperty;
        var RecordDef = (function (_super) {
            __extends(RecordDef, _super);
            function RecordDef() {
                _super.call(this);
                this.keys = new AST.FieldBlock();
                this.values = new AST.FieldBlock();
                this.description = "";
                this.recordType = 1 /* Object */;
                this.recordKind = new RecordKind(this);
                this.recordPersistence = new RecordPersistenceKind(this);
                this.cloudEnabled = false;
                this.cloudPartiallyEnabled = false;
                this.persistent = false;
                this.isModel = false;
                this._isExported = false;
                this.keys.parentDef = this;
                this.values.parentDef = this;
                this.tableKind = new RecordDefKind(this);
                this.entryKind = new RecordEntryKind(this);
                this.ctorProperty = new RecordCtorProperty(this);
                this.ctorJsonProperty = new RecordCtorProperty(this, true);
                this._kind = this.tableKind;
            }
            RecordDef.prototype.parentLibrary = function () {
                return null;
            };
            RecordDef.prototype.locallypersisted = function () {
                return this.persistent && !(this.cloudEnabled || this.cloudPartiallyEnabled);
            };
            RecordDef.prototype.hasErrors = function () {
                return !!this.getError() || this.getFields().some(function (r) { return !!r.getError(); });
            };
            RecordDef.prototype.children = function () {
                return [
                    this.keys,
                    this.values
                ];
            };
            RecordDef.prototype.thingSetKindName = function () {
                return "records";
            };
            RecordDef.prototype.getDefinedKind = function () {
                return this.entryKind;
            };
            RecordDef.prototype.isExported = function () {
                return this._isExported && this.recordType == 1 /* Object */;
            };
            RecordDef.prototype.getName = function () {
                switch (this.recordType) {
                    case 1 /* Object */: return this.getCoreName();
                    case 2 /* Table */: return this.getCoreName() + " table";
                    case 3 /* Index */: return this.getCoreName() + " index";
                    case 4 /* Decorator */:
                        var k = this.getTargetKind();
                        if (!k)
                            return this.getCoreName() + " decorator";
                        else
                            return k.getName() + " decorator";
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getSignature = function () {
                return "";
            };
            RecordDef.prototype.getRecordPersistence = function () {
                if (this.recordType === 3 /* Index */ || this.recordType === 2 /* Table */) {
                    if (this.cloudPartiallyEnabled)
                        return 3 /* Partial */;
                    if (this.cloudEnabled)
                        return 2 /* Cloud */;
                    if (this.persistent)
                        return 1 /* Local */;
                }
                return 0 /* Temporary */;
            };
            RecordDef.prototype.getPersistenceDescription = function () {
                switch (this.recordType) {
                    case 3 /* Index */:
                    case 2 /* Table */: return RecordDef.recordPersistenceToString(this.getRecordPersistence(), TDev.Script && TDev.Script.isCloud);
                    case 1 /* Object */:
                    case 4 /* Decorator */: return "";
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getDescription = function () {
                if (this.description)
                    return this.description;
                var pref = "A " + this.getPersistenceDescription();
                switch (this.recordType) {
                    case 1 /* Object */: return "A loose collection of " + this.getCoreName() + " objects.";
                    case 2 /* Table */: return pref + " table containing " + this.getCoreName() + " records.";
                    case 3 /* Index */: return pref + " index containing " + this.getCoreName() + " entries.";
                    case 4 /* Decorator */: return "A decorator for " + (this.getTargetKind().getName() || "") + " objects.";
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getEntryKindDescription = function () {
                switch (this.recordType) {
                    case 1 /* Object */: return "A reference to a " + this.getCoreName() + " object.";
                    case 2 /* Table */: return "A reference to a " + this.getCoreName() + " table row.";
                    case 3 /* Index */: return "A reference to a " + this.getCoreName() + " index entry.";
                    case 4 /* Decorator */: return "A reference to a " + (this.getTargetKind().getName() || "") + " decoration.";
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getDefTerminology = function () {
                return RecordDef.recordTypeToString(this.recordType).toLowerCase();
            };
            RecordDef.prototype.getKeyTerminology = function () {
                switch (this.recordType) {
                    case 1 /* Object */: return null;
                    case 2 /* Table */: return "link";
                    case 3 /* Index */: return "key";
                    case 4 /* Decorator */: return null;
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getValueTerminology = function () {
                switch (this.recordType) {
                    case 1 /* Object */: return "field";
                    case 2 /* Table */: return "column";
                    case 3 /* Index */: return "field";
                    case 4 /* Decorator */: return "field";
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getCloudType = function () {
                TDev.Util.assert(this.persistent);
                switch (this.recordType) {
                    case 2 /* Table */:
                        {
                            var links = this.keys.stmts.map(function (x) {
                                var dk = x.dataKind;
                                return dk.record.getCloudType();
                            });
                            return TDev.Revisions.Parser.MakeDomain(this.getStableName(), TDev.Revisions.Parser.DOMAIN_DYNAMIC, links);
                        }
                    case 3 /* Index */:
                        {
                            var keys = this.keys.stmts.map(function (x) {
                                var dk = x.dataKind;
                                var record = dk.record;
                                if (record)
                                    return dk.record.getCloudType();
                                else {
                                    return TDev.RT.Conv.getCloudDomain(dk.getName());
                                }
                            });
                            return TDev.Revisions.Parser.MakeDomain(this.getStableName(), TDev.Revisions.Parser.DOMAIN_STATIC, keys);
                        }
                    default: TDev.Util.die();
                }
            };
            RecordDef.prototype.getProperties = function () {
                this.initalizeProperties();
                return this._properties;
            };
            RecordDef.prototype.clearPropertyCaches = function () {
                SimpleProperty.deleteProperties(this._properties);
                this._properties = null;
                this.entryKind.clearPropertyCaches();
                this.getFields().forEach(function (r) { return r.clearPropertyCaches(); });
            };
            RecordDef.prototype.fixupFields = function (oldtype) {
                if (oldtype === void 0) { oldtype = undefined; }
                if (this.recordType != 2 /* Table */ && this.recordType != 3 /* Index */) {
                    this.cloudEnabled = false;
                    this.cloudPartiallyEnabled = false;
                    this.persistent = false;
                }
                var origtype = oldtype || this.recordType;
                var newtype = this.recordType;
                if (origtype === 4 /* Decorator */ && newtype != 4 /* Decorator */) {
                    this.keys.setChildren([]);
                }
                else if (origtype != newtype && newtype != 3 /* Index */) {
                    this.keys.setChildren([]);
                }
                if (newtype === 4 /* Decorator */) {
                    var theKey = this.keys.stmts[0];
                    if (!theKey)
                        theKey = new RecordField("target", AST.api.getKind("Sprite"), true);
                    this.keys.setChildren([theKey]);
                    theKey.setName("target");
                }
            };
            RecordDef.prototype.initalizeProperties = function () {
                if (this._properties)
                    return;
                switch (this.recordType) {
                    case 1 /* Object */:
                        var p = new SimpleProperty("create collection", TDev.lf("creates an empty collection of objects"), false, this.tableKind, this.entryKind.collectionKind);
                        p.md_writesMutable();
                        var p1 = new SimpleProperty("invalid", TDev.lf("Create an invalid value of this object type"), false, this.tableKind, this.entryKind);
                        this._properties = [p, p1];
                        break;
                    case 2 /* Table */:
                        var p = new SimpleProperty("create collection", TDev.lf("creates an empty collection of rows"), false, this.tableKind, this.entryKind.collectionKind);
                        p.md_writesMutable();
                        var p2 = new SimpleProperty("copy to collection", TDev.lf("loads the table rows into a collection"), false, this.tableKind, this.entryKind.collectionKind);
                        p2.md_writesMutable();
                        this._properties = [
                            new SimpleProperty("post to wall", TDev.lf("Post all rows to the wall"), false, this.tableKind, AST.api.core.Nothing),
                            new SimpleProperty("count", TDev.lf("Counts the number of rows"), false, this.tableKind, AST.api.core.Number),
                            new SimpleProperty("clear", TDev.lf("Clear all rows from the table"), true, this.tableKind, AST.api.core.Nothing),
                            p,
                            p2,
                            new SimpleProperty("invalid row", TDev.lf("Creates an invalid reference to a row"), false, this.tableKind, this.entryKind).makeObsolete(),
                            new SimpleProperty("invalid", TDev.lf("Creates an invalid reference to a row"), false, this.tableKind, this.entryKind),
                            new SimpleProperty("row at", TDev.lf("Gets the row at the specified position. Returns invalid if out of range"), false, this.tableKind, this.entryKind, false, AST.api.core.Number),
                        ];
                        this._properties.push(p = new SimpleProperty("wait for update", TDev.lf("waits until there is an update (possibly change) to the table contents"), false, this.tableKind, AST.api.core.Nothing));
                        p.md_resumes();
                        p.md_async();
                        p.md_betaOnly();
                        if (this.keys.stmts.length >= 1) {
                            var p3 = new SimpleProperty("entries linked to", TDev.lf("returns all rows with matching links"), false, this.tableKind, this.entryKind.collectionKind);
                            p3.setParameterKinds(this.keys.stmts.map(function (p) { return p.dataKind; }));
                            p3.md_writesMutable();
                            this._properties.push(p3);
                        }
                        this._properties.push(new SimpleProperty("to json", TDev.lf("export a JSON representation of the table contents"), false, this.tableKind, AST.api.core.JsonObject));
                        this._properties.push(new SimpleProperty("from json", TDev.lf("import a JSON representation of the table contents"), false, this.tableKind, AST.api.core.Nothing, false, AST.api.core.JsonObject));
                        break;
                    case 3 /* Index */:
                        var p = new SimpleProperty("create collection", TDev.lf("creates an empty collection of entries"), false, this.tableKind, this.entryKind.collectionKind);
                        p.md_writesMutable();
                        var p2 = new SimpleProperty("copy to collection", TDev.lf("loads the index entries into a collection"), false, this.tableKind, this.entryKind.collectionKind);
                        p2.md_writesMutable();
                        this._properties = [
                            new SimpleProperty("post to wall", TDev.lf("Posts all non-empty entries (i.e. entries with at least one non-default field) to the wall"), false, this.tableKind, AST.api.core.Nothing),
                            new SimpleProperty("count", TDev.lf("Counts the number of entries that contain non-default values"), false, this.tableKind, AST.api.core.Number),
                            new SimpleProperty("clear", TDev.lf("Clear all entries, all fields assume default value"), true, this.tableKind, AST.api.core.Nothing),
                            p,
                            p2,
                            new SimpleProperty("invalid", TDev.lf("Creates an invalid reference to an entry"), false, this.tableKind, this.entryKind)
                        ];
                        if (this.isUserIndex()) {
                            var p2 = new SimpleProperty("my entries", TDev.lf("returns all non-empty entries whose first key matchest the current user"), false, this.tableKind, this.entryKind.collectionKind);
                            p2.md_writesMutable();
                            this._properties.push(p2);
                        }
                        this._properties.push(p = new SimpleProperty("wait for update", TDev.lf("waits until there is an update (possibly change) to the index contents"), false, this.tableKind, AST.api.core.Nothing));
                        p.md_resumes();
                        p.md_async();
                        p.md_betaOnly();
                        this._properties.push(new SimpleProperty("to json", TDev.lf("export a JSON representation of the table contents"), false, this.tableKind, AST.api.core.JsonObject));
                        this._properties.push(new SimpleProperty("from json", TDev.lf("import a JSON representation of the table contents"), false, this.tableKind, AST.api.core.Nothing, false, AST.api.core.JsonObject));
                        break;
                    case 4 /* Decorator */:
                        this._properties = [
                            new SimpleProperty("clear", TDev.lf("Clears all decorations, all fields assume initial value"), true, this.tableKind, AST.api.core.Nothing)
                        ];
                        break;
                    default: TDev.Util.die();
                }
                this._properties.unshift(this.ctorProperty);
                if (this.recordType == 1 /* Object */)
                    this._properties.unshift(this.ctorJsonProperty);
            };
            RecordDef.prototype.getTargetKind = function () {
                if (this.recordType != 4 /* Decorator */)
                    return null;
                var k = this.keys.stmts[0];
                if (!k)
                    return null;
                return k.dataKind;
            };
            RecordDef.prototype.isUserIndex = function () {
                if (this.recordType !== 3 /* Index */ || this.keys.stmts.length < 1)
                    return false;
                var k = this.keys.stmts[0];
                return k && k.dataKind._name === "User";
            };
            RecordDef.prototype.getFields = function () {
                return this.keys.stmts.concat(this.values.stmts);
            };
            RecordDef.prototype.getValueFields = function () {
                return this.values.stmts;
            };
            RecordDef.prototype.getKeyFields = function () {
                return this.keys.stmts;
            };
            RecordDef.prototype.nodeType = function () {
                return "recordDef";
            };
            RecordDef.prototype.accept = function (v) {
                return v.visitRecordDef(this);
            };
            RecordDef.prototype.getCategory = function () {
                return 4 /* Record */;
            };
            RecordDef.prototype.getNamespace = function () {
                return AST.recordSymbol + "\u200A";
            };
            RecordDef.prototype.toString = function () {
                return this.getNamespace() + this.getName();
            };
            RecordDef.prototype.writeTo = function (tw) {
                this.writeId(tw);
                tw.nl().keyword("table").id(this.getCoreName());
                tw.beginBlock();
                if (this.description)
                    tw.comment(this.description);
                tw.stringAttr("type", RecordDef.recordTypeToString(this.recordType));
                tw.boolOptAttr("cloudenabled", this.cloudEnabled);
                tw.boolOptAttr("cloudpartiallyenabled", this.cloudPartiallyEnabled);
                tw.boolOptAttr("exported", this._isExported);
                tw.boolAttr("persistent", this.persistent);
                var dumpList = function (id, b) {
                    if (b.stmts.length === 0)
                        return;
                    tw.id(id);
                    tw.beginBlock();
                    b.forEach(function (f) { return f.writeDef(tw); });
                    tw.endBlock();
                };
                dumpList("keys", this.keys);
                dumpList("fields", this.values);
                tw.endBlock();
            };
            RecordDef.prototype.notifyChange = function () {
                _super.prototype.notifyChange.call(this);
                if (TDev.Runtime.theRuntime)
                    TDev.Runtime.theRuntime.resetData();
            };
            RecordDef.parse = function (p) {
                var r = new RecordDef();
                p.addDecl(r);
                r._initalizeFromParser(p);
            };
            RecordDef.prototype._initalizeFromParser = function (p) {
                var _this = this;
                this.setStableName(p.consumeLabel());
                this.setName(p.parseId());
                this.persistent = true;
                function encode(s) {
                    return TDev.Util.base64Encode(TDev.Util.toUTF8(s)).replace(/[^A-Za-z0-9]/g, "a");
                }
                p.parseBraced(function () {
                    var parseFields = function (lst, keys) {
                        p.shift();
                        var usedNames = {};
                        var desc = "";
                        p.parseBraced(function () {
                            if (p.got(4 /* Comment */)) {
                                desc += p.shift().data + "\n";
                                return;
                            }
                            var lbl = p.consumeLabel().pop();
                            var nm = p.parseId();
                            var tp = p.parseTypeAnnotation();
                            var r = new RecordField(nm, tp, keys, desc);
                            desc = "";
                            if (/_/.test(lbl))
                                lbl = null;
                            if (lbl) {
                                r.setStableName(lbl);
                            }
                            else if (_this.getStableName()) {
                                r.setStableName(_this.getStableName() + encode(r.getName()));
                                if (usedNames[r.getStableName()])
                                    r.setStableName(r.getStableName() + Object.keys(usedNames).length);
                                usedNames[r.getStableName()] = true;
                            }
                            lst.push(r);
                        });
                    };
                    if (p.gotKey("tableGuid"))
                        p.shift();
                    else if (p.gotKey("type")) {
                        var tp = RecordDef.recordTypeFromString(p.parseString());
                        if (tp)
                            _this.recordType = tp;
                    }
                    else if (p.gotKey("cloudenabled")) {
                        _this.cloudEnabled = p.parseBool();
                    }
                    else if (p.gotKey("cloudpartiallyenabled")) {
                        _this.cloudPartiallyEnabled = p.parseBool();
                    }
                    else if (p.gotKey("persistent")) {
                        _this.persistent = p.parseBool();
                    }
                    else if (p.gotKey("exported")) {
                        _this._isExported = p.parseBool();
                    }
                    else if (p.got(4 /* Comment */)) {
                        _this.description += p.shift().data + "\n";
                    }
                    else if (p.gotId("keys")) {
                        parseFields(_this.keys, true);
                    }
                    else if (p.gotId("fields")) {
                        parseFields(_this.values, false);
                    }
                });
                if (this.persistent && !this.getStableName())
                    this.setStableName("B" + encode(this.getName()));
                if (this.cloudEnabled)
                    this.persistent = true;
                if (this.cloudPartiallyEnabled) {
                    this.persistent = true;
                    this.cloudEnabled = true;
                }
                this.fixupFields();
            };
            RecordDef.recordPersistenceToString = function (v, service) {
                switch (v) {
                    case 0 /* Temporary */: return TDev.lf("temporary");
                    case 1 /* Local */: return service ? TDev.lf("server-local") : TDev.lf("local");
                    case 2 /* Cloud */: return service ? TDev.lf("fully replicated") : TDev.lf("replicated");
                    case 3 /* Partial */: return TDev.lf("partially replicated");
                    default: TDev.Util.die();
                }
            };
            RecordDef.recordTypeToString = function (v) {
                switch (v) {
                    case 1 /* Object */: return "Object";
                    case 2 /* Table */: return "Table";
                    case 3 /* Index */: return "Index";
                    case 4 /* Decorator */: return "Decorator";
                    default: TDev.Util.die();
                }
            };
            RecordDef.recordTypeFromString = function (s) {
                var v = RecordType[s];
                if (v === undefined)
                    return undefined;
                if (RecordDef.recordTypeToString(v) != s)
                    return undefined;
                return v;
            };
            RecordDef.GetIcon = function (rt) {
                switch (rt) {
                    case 1 /* Object */:
                        return "svg:fa-list-alt,white";
                    case 2 /* Table */:
                        return "svg:fa-table,white";
                    case 4 /* Decorator */:
                        return "svg:fa-subscript,white";
                    case 3 /* Index */:
                        return "svg:fa-th-list,white";
                    default: TDev.Util.die();
                }
            };
            RecordDef.colorByPersistence = function (icon, pers) {
                if (!TDev.Script.isCloud) {
                    if (pers === 2 /* Cloud */)
                        return icon.replace(/,white$/, ",cyan");
                    else if (pers === 1 /* Local */)
                        return icon.replace(/,white$/, ",gold");
                    else
                        return icon;
                }
                else {
                    if (pers === 2 /* Cloud */)
                        return icon.replace(/,white$/, ",cyan");
                    else if (pers === 3 /* Partial */)
                        return icon.replace(/,white$/, ",powderblue");
                    else if (pers === 1 /* Local */)
                        return icon.replace(/,white$/, ",gold");
                    else
                        return icon;
                }
            };
            return RecordDef;
        })(AST.PropertyDecl);
        AST.RecordDef = RecordDef;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        AST.libSymbol = "\u267B";
        var LibraryRefAction = (function (_super) {
            __extends(LibraryRefAction, _super);
            function LibraryRefAction(_lib) {
                _super.call(this);
                this._lib = _lib;
                this._weight = 50;
                this.parentKind = _lib.getKind();
            }
            LibraryRefAction.prototype.isInLibrary = function () {
                return true;
            };
            LibraryRefAction.prototype.getNamespace = function () {
                return AST.libSymbol + this.parentLibrary().getName() + this.getArrow();
            };
            LibraryRefAction.prototype.parentLibrary = function () {
                return this._lib;
            };
            LibraryRefAction.prototype.getFlags = function () {
                return this._flags;
            };
            LibraryRefAction.prototype.getDescription = function () {
                if (this._description)
                    return this._description;
                return _super.prototype.getDescription.call(this);
            };
            LibraryRefAction.prototype.getArrow = function () {
                return "\u200A\u2192\u00A0";
            };
            LibraryRefAction.prototype.markUsed = function () {
                this.wasUsed = true;
            };
            LibraryRefAction.prototype.canRename = function () {
                return false;
            };
            LibraryRefAction.prototype.usageKey = function () {
                return TDev.Util.tagify(this._lib.getName() + " " + this.getName());
            };
            LibraryRefAction.prototype.setAllLocals = function () {
                this.allLocals = this.getAllParameters().map(function (ap) { return ap.local; });
                this.body = AST.Parser.emptyBlock();
            };
            LibraryRefAction.prototype.updateSubstitution = function () {
                var _this = this;
                if (!this.template)
                    return;
                var copyParam = function (ap) { return new AST.ActionParameter(AST.mkLocal(ap.getName(), _this.parentLibrary().substitute(ap.getKind()))); };
                this.header.inParameters.setChildren(this.template.getInParameters().map(copyParam));
                this.header.outParameters.setChildren(this.template.getOutParameters().map(copyParam));
                this.setAllLocals();
            };
            LibraryRefAction.prototype.fromTemplateCore = function (template) {
                this.template = template;
                this.updateSubstitution();
                this._description = template.getInlineHelp();
                this._flags = template.getFlags();
                this.setName(template.getName());
                this._isPage = template.isPage();
                this.isAtomic = template.isAtomic;
                this._isActionTypeDef = template.isActionTypeDef();
                this.setStableName(template.getStableName());
                this.setAllLocals();
            };
            LibraryRefAction.prototype.addExtensionAction = function () {
                if (this.isActionTypeDef())
                    return;
                var k = this.getExtensionKind();
                if (k)
                    k.addExtensionAction(this._extensionAction = new LibExtensionAction(this));
            };
            LibraryRefAction.prototype.fromTemplate = function (template) {
                this.fromTemplateCore(template);
                if (!template.isPage())
                    this.addExtensionAction();
                return this;
            };
            LibraryRefAction.prototype.parse = function (p) {
                this.setStableName(p.consumeLabel());
                while (true) {
                    if (p.gotOp("sync")) {
                        p.shift();
                        this.isAtomic = true;
                        continue;
                    }
                    if (p.gotOp("async")) {
                        p.shift();
                        this.isAtomic = false;
                        continue;
                    }
                    if (p.gotOp("page")) {
                        p.shift();
                        this._isPage = true;
                        continue;
                    }
                    break;
                }
                var hd = p.parseActionHeader();
                this.setName(hd.name);
                this.header.inParameters.setChildren(hd.inParameters);
                this.header.outParameters.setChildren(hd.outParameters);
                this._isActionTypeDef = hd.isType;
                this.setAllLocals();
                this.addExtensionAction();
                this._flags = _super.prototype.getFlags.call(this);
            };
            LibraryRefAction.prototype.isBrowsable = function () {
                return !(this._flags & TDev.PropertyFlags.NonBrowsable) && ((this._flags & 1048576 /* LibsOnly */) == 0 || !TDev.Script || TDev.Script.isLibrary) && !this.isLibInit();
            };
            LibraryRefAction.prototype.toString = function () {
                var ns = this.getNamespaces();
                if (ns && ns[0])
                    return ns[0] + " → " + this.getName();
                return this.getNamespace() + this.getName();
            };
            LibraryRefAction.prototype.showIntelliButton = function () {
                if (this.isExtensionAction())
                    return true;
                return this.getExtensionKind() == null;
            };
            return LibraryRefAction;
        })(AST.Action);
        AST.LibraryRefAction = LibraryRefAction;
        var LibExtensionAction = (function (_super) {
            __extends(LibExtensionAction, _super);
            function LibExtensionAction(shortcutTo) {
                _super.call(this, shortcutTo._lib);
                this.shortcutTo = shortcutTo;
                this.fromTemplateCore(shortcutTo);
            }
            LibExtensionAction.prototype.updateSubstitution = function () {
                _super.prototype.updateSubstitution.call(this);
                this.parentKind = this.getInParameters()[0].getKind();
                this.header.inParameters.stmts.shift();
            };
            LibExtensionAction.prototype.isExtensionAction = function () {
                return true;
            };
            LibExtensionAction.prototype.extensionForward = function () {
                return this.shortcutTo;
            };
            LibExtensionAction.prototype.getDescription = function () {
                return this.shortcutTo.getDescription();
            };
            LibExtensionAction.prototype.getFlags = function () {
                return this.shortcutTo.getFlags();
            };
            LibExtensionAction.prototype.markUsed = function () {
                _super.prototype.markUsed.call(this);
                this.shortcutTo.markUsed();
            };
            return LibExtensionAction;
        })(LibraryRefAction);
        AST.LibExtensionAction = LibExtensionAction;
        var LibraryRefAbstractKind = (function (_super) {
            __extends(LibraryRefAbstractKind, _super);
            function LibraryRefAbstractKind(_lib, n) {
                _super.call(this, n, "a kind from library");
                this._lib = _lib;
                this.deleted = false;
                this._stemName = n;
                this._contexts = TDev.KindContext.General | 32 /* GcKey */;
                var invl = TDev.Property.md_make(0, this, "is invalid", "Returns true if the current instance is useless", [], AST.api.core.Boolean);
                invl.md_runOnInvalid();
                this.addExtensionAction(invl);
            }
            LibraryRefAbstractKind.prototype.kill = function () {
                this.deleted = true;
            };
            LibraryRefAbstractKind.prototype.isError = function () {
                return this.deleted || this._lib.deleted;
            };
            LibraryRefAbstractKind.prototype.isUserDefined = function () {
                return true;
            };
            LibraryRefAbstractKind.prototype.parentLibrary = function () {
                return this._lib;
            };
            LibraryRefAbstractKind.prototype.getNamespace = function () {
                return LibraryRef.libNamespace(this.parentLibrary().getName());
            };
            LibraryRefAbstractKind.prototype.toString = function () {
                return this.getNamespace() + this.getName();
            };
            LibraryRefAbstractKind.prototype.listPriority = function () {
                return 3;
            };
            LibraryRefAbstractKind.prototype.listProperties = function () {
                return this.listExtensions();
            };
            LibraryRefAbstractKind.prototype.getProperty = function (name) {
                return this.getExtension(name);
            };
            return LibraryRefAbstractKind;
        })(AST.ExtensionEnabledKind);
        AST.LibraryRefAbstractKind = LibraryRefAbstractKind;
        var LibraryRefKind = (function (_super) {
            __extends(LibraryRefKind, _super);
            function LibraryRefKind(lib) {
                _super.call(this, "no name yet", "a library reference");
                this.lib = lib;
            }
            LibraryRefKind.prototype.listProperties = function () {
                return this.lib.getPublicActions().map(TDev.Property.withParent(this));
            };
            LibraryRefKind.prototype.getProperty = function (name) {
                var a = this.lib.getPublicActions().filter(function (a) { return a.getName() == name; });
                if (!a[0])
                    return undefined;
                return TDev.Property.withParent(this)(a[0]);
            };
            LibraryRefKind.prototype.getHtmlName = function () {
                return [TDev.span('symbol', AST.libSymbol), this.lib.getName()];
            };
            LibraryRefKind.prototype.getName = function () {
                return this.lib.getName();
            };
            LibraryRefKind.prototype.toString = function () {
                return this.lib.toString();
            };
            LibraryRefKind.prototype.getHelp = function () {
                return this.lib.getDescription();
            };
            return LibraryRefKind;
        })(TDev.Kind);
        AST.LibraryRefKind = LibraryRefKind;
        var LibraryRecordDef = (function (_super) {
            __extends(LibraryRecordDef, _super);
            function LibraryRecordDef(_lib) {
                _super.call(this);
                this._lib = _lib;
            }
            LibraryRecordDef.prototype.updateSubstitution = function () {
                var _this = this;
                if (!this.template)
                    return;
                var copyField = function (fld) {
                    var k = _this.parentLibrary().substitute(fld.dataKind);
                    var rf = new AST.RecordField(fld.getName(), k, fld.isKey, fld.getDescription());
                    rf.setStableName(fld.getStableName());
                    return rf;
                };
                this.keys.setChildren(this.template.keys.map(copyField));
                this.values.setChildren(this.template.values.map(copyField));
            };
            LibraryRecordDef.prototype.fromTemplate = function (template) {
                this.template = template;
                this.recordType = template.recordType;
                this.cloudEnabled = template.cloudEnabled;
                this.cloudPartiallyEnabled = template.cloudPartiallyEnabled;
                this._isExported = template._isExported;
                this.persistent = template.persistent;
                this.description = template.description;
                this.setName(template.getCoreName());
                this.setStableName(template.getStableName());
                this.updateSubstitution();
            };
            LibraryRecordDef.prototype.parentLibrary = function () {
                return this._lib;
            };
            LibraryRecordDef.prototype.getNamespace = function () {
                return LibraryRef.libNamespace(this.parentLibrary().getName());
            };
            return LibraryRecordDef;
        })(AST.RecordDef);
        AST.LibraryRecordDef = LibraryRecordDef;
        var UnificationCtx = (function () {
            function UnificationCtx(lib) {
                this.lib = lib;
                this.mapping = {};
                this.clause = null;
                this.assumptions = [];
            }
            UnificationCtx.prototype.resolve = function (form) {
                if (form instanceof LibraryRefAbstractKind) {
                    var fk = form;
                    if (fk.parentLibrary().parent == this.lib.resolved) {
                        var n = fk.toString();
                        if (this.mapping.hasOwnProperty(n)) {
                            return this.mapping[n];
                        }
                        else {
                            return null;
                        }
                    }
                }
                return form;
            };
            UnificationCtx.prototype.unifyActionKinds = function (form, act) {
                var _this = this;
                var cmpLists = function (a, b) {
                    if (a.length != b.length)
                        return false;
                    return a.every(function (aa, i) { return _this.unify(aa.getKind(), b[i].getKind()); });
                };
                return cmpLists(form.getInParameters(), act.getInParameters()) && cmpLists(form.getOutParameters(), act.getOutParameters());
            };
            UnificationCtx.prototype.unifyParametricKinds = function (form, act) {
                var _this = this;
                return form.getRoot().equals(act.getRoot()) && form.parameters.length == act.parameters.length && form.parameters.every(function (f, i) { return _this.unify(f, act.parameters[i]); });
            };
            UnificationCtx.prototype.unifyRecords = function (form, act) {
                var _this = this;
                if (form.getName() != act.getName() || form.recordType != act.recordType || form.getRecordPersistence() != act.getRecordPersistence())
                    return false;
                var actFields = TDev.Util.toDictionary(act.getFields(), function (f) { return f.getName(); });
                var allOK = true;
                form.getFields().forEach(function (f) {
                    if (actFields.hasOwnProperty(f.getName())) {
                        var a = actFields[f.getName()];
                        if (f.isKey != a.isKey || !_this.unify(f.dataKind, a.dataKind))
                            allOK = false;
                    }
                    else {
                        allOK = false;
                    }
                });
                return allOK;
            };
            UnificationCtx.prototype.unify = function (form, act) {
                if (form.equals(act))
                    return true;
                if (form instanceof TDev.ActionKind && act instanceof TDev.ActionKind)
                    return this.unifyActionKinds(form, act);
                if (form instanceof TDev.ParametricKind && act instanceof TDev.ParametricKind)
                    return this.unifyParametricKinds(form, act);
                if (form.getRecord() && act.getRecord()) {
                    if (this.assumptions.some(function (a) { return a.formal == form && a.actual == act; }))
                        return true;
                    this.assumptions.push({ formal: form, actual: act });
                    try {
                        return this.unifyRecords(form.getRecord(), act.getRecord());
                    }
                    finally {
                        this.assumptions.pop();
                    }
                }
                var resolved = this.resolve(form);
                if (!resolved) {
                    this.mapping[form.toString()] = act;
                    return true;
                }
                else
                    return resolved.equals(act);
            };
            return UnificationCtx;
        })();
        AST.UnificationCtx = UnificationCtx;
        var ResolveClause = (function (_super) {
            __extends(ResolveClause, _super);
            function ResolveClause(name) {
                _super.call(this);
                this.name = name;
                this.kindBindings = new AST.BindingBlock();
                this.actionBindings = new AST.BindingBlock();
                this.kindBindings.parent = this;
                this.actionBindings.parent = this;
            }
            ResolveClause.prototype.primaryBody = function () {
                return this.actionBindings;
            };
            ResolveClause.prototype.children = function () {
                return [this.kindBindings, this.actionBindings];
            };
            ResolveClause.prototype.accept = function (v) {
                return v.visitResolveClause(this);
            };
            ResolveClause.prototype.nodeType = function () {
                return "resolveClause";
            };
            ResolveClause.prototype.getName = function () {
                return this.name;
            };
            ResolveClause.prototype.resolveExplicit = function (par) {
                this.clearError();
                if (!this.defaultLib) {
                    par._hasErrors = true;
                    this.setError("TD135: not bound to any library; tap to bind");
                    return;
                }
                this.actionBindings.stmts.forEach(function (binding) {
                    var al = binding.actualLib;
                    var act = al.getPublicActions().filter(function (a) { return a.getName() == binding.actualName; })[0];
                    binding.actual = act;
                    if (!act)
                        binding.setError(TDev.lf("TD138: cannot find function '{1}' in {0}", al, binding.actualName));
                });
            };
            ResolveClause.prototype.typeCheck = function (ctx) {
                var _this = this;
                this.clearError();
                if (!this.defaultLib) {
                    this.setError("TD135: not bound to any library; tap to bind");
                    return;
                }
                this.defaultLib.typeCheck();
                ctx.clause = this;
                this.kindBindings.setChildren([]);
                var newBindings = this.formalLib.getPublicActions().filter(function (a) { return a.wasUsed; }).map(function (form, ix) {
                    TDev.Util.assert(form instanceof LibraryRefAction);
                    var binding = (_this.actionBindings.stmts.filter(function (a) { return a.formalName == form.getName(); })[0]);
                    if (!binding)
                        binding = new ActionBinding(form.getName());
                    if (!binding.isExplicit) {
                        binding.actualLib = _this.defaultLib;
                        binding.actualName = form.getName();
                    }
                    var al = binding.actualLib;
                    al.typeCheck();
                    var act = al.getPublicActions().filter(function (a) { return a.getName() == binding.actualName; })[0];
                    binding.formal = form;
                    binding.actual = act;
                    if (act) {
                        var err = binding.getSignatureError(ctx, act);
                        if (err) {
                            binding.setError(err);
                        }
                        else {
                            binding.clearError();
                        }
                        if (!al.isTypechecked)
                            binding.setError("TD174: cause of circular library reference");
                    }
                    else if (al.isReal()) {
                        binding.setError(TDev.lf("TD138: cannot find function '{1}' in {0}", al, binding.actualName));
                    }
                    else {
                        _this.setError(TDev.lf("TD139: no library reference named {0}", al));
                    }
                    return binding;
                });
                var cmpBindings = function (a, b) {
                    if (a.isExplicit == b.isExplicit)
                        return a.formalName.localeCompare(b.formalName);
                    else if (a.isExplicit)
                        return -1;
                    else
                        return 1;
                };
                newBindings.sort(cmpBindings);
                this.actionBindings.setChildren(newBindings);
                if (!this.getError()) {
                    var err = newBindings.filter(function (b) { return !!b.getError(); })[0];
                    if (err)
                        this.setError("TD173: some binding(s) have errors");
                }
            };
            return ResolveClause;
        })(AST.Stmt);
        AST.ResolveClause = ResolveClause;
        var Binding = (function (_super) {
            __extends(Binding, _super);
            function Binding(formalName) {
                _super.call(this);
                this.formalName = formalName;
                this.isExplicit = false;
            }
            return Binding;
        })(AST.Stmt);
        AST.Binding = Binding;
        var KindBinding = (function (_super) {
            __extends(KindBinding, _super);
            function KindBinding(f) {
                _super.call(this, f);
            }
            KindBinding.prototype.accept = function (v) {
                return v.visitKindBinding(this);
            };
            KindBinding.prototype.nodeType = function () {
                return "kindBinding";
            };
            return KindBinding;
        })(Binding);
        AST.KindBinding = KindBinding;
        var ActionBinding = (function (_super) {
            __extends(ActionBinding, _super);
            function ActionBinding(f) {
                _super.call(this, f);
            }
            ActionBinding.prototype.accept = function (v) {
                return v.visitActionBinding(this);
            };
            ActionBinding.prototype.nodeType = function () {
                return "actionBinding";
            };
            ActionBinding.prototype.getActualName = function () {
                return this.actual ? this.actual.getName() : this.actualName || "?";
            };
            ActionBinding.prototype.getSignatureError = function (ctx, act) {
                var form = this.formal;
                var err = null;
                var compareParameters = function (formal, actual, tp) {
                    if (formal.length != actual.length)
                        err = TDev.lf("TD136: '{0}' has {1} {2}-paramters, but '{3}' requires {4}", act, actual.length, tp, form.getName(), formal.length);
                    else
                        for (var i = 0; i < formal.length; ++i) {
                            var fk = formal[i].getKind();
                            var ak = actual[i].getKind();
                            if (!ctx.unify(fk, ak))
                                err = TDev.lf("TD137: '{0}' has {1} as {3}-paramter #{2}, but '{4}' requires {5}", act, ak, i, tp, form.getName(), ctx.resolve(fk));
                        }
                };
                if (form.isAtomic && !act.isAtomic)
                    return TDev.lf("TD162: an atomic function is required for '{0}'", form.getName());
                compareParameters(form.getInParameters(), act.getInParameters(), "in");
                compareParameters(form.getOutParameters(), act.getOutParameters(), "out");
                return err;
            };
            return ActionBinding;
        })(Binding);
        AST.ActionBinding = ActionBinding;
        var LibNamespaceCache = (function () {
            function LibNamespaceCache(app) {
                this.app = app;
                this.singletonList = [];
                this.singletons = {};
                this.extensions = {};
            }
            LibNamespaceCache.prototype.createSingleton = function (name, lib) {
                var k = new TDev.Kind(name, TDev.lf("Extensions"));
                k._contexts = 0 /* None */;
                var th = AST.mkSingletonDef(name, k);
                th.isExtension = true;
                th.firstLibraryRef = lib;
                return th;
            };
            LibNamespaceCache.prototype.addSingleton = function (name, lib) {
                if (AST.api.getThing(name))
                    return;
                var th = this.createSingleton(name, lib);
                this.singletonList.push(th);
                this.singletons[th.getName()] = th;
            };
            LibNamespaceCache.prototype.recompute = function () {
                var _this = this;
                TDev.Util.assert(this.app == TDev.Script);
                this.singletons = {};
                this.singletonList = [];
                this.extensions = {};
                this.app.libraries().forEach(function (l) {
                    l.getPublicActions().forEach(function (a) {
                        a.getNamespaces().forEach(function (ns) {
                            _this.addSingleton(ns, l);
                            if (!_this.extensions.hasOwnProperty(ns))
                                _this.extensions[ns] = { actions: {}, actionList: [] };
                            var e = _this.extensions[ns];
                            if (!e.actions[a.getName()]) {
                                e.actionList.push(a);
                                e.actions[a.getName()] = a;
                            }
                        });
                    });
                });
            };
            return LibNamespaceCache;
        })();
        AST.LibNamespaceCache = LibNamespaceCache;
        var LibraryRef = (function (_super) {
            __extends(LibraryRef, _super);
            function LibraryRef() {
                _super.call(this);
                this.guid = "";
                this.pubid = "";
                this._publicActions = [];
                this._publicKinds = [];
                this.kindMapping = {};
                this.externalKindMapping = {};
                this.isTypechecked = false;
                this.isTypechecking = false;
                this.publicActionsCopiedFromResolved = false;
                this.resolveClauses = new AST.ResolveBlock();
                this.listedKinds = [];
                this._kind = new LibraryRefKind(this);
            }
            LibraryRef.prototype.isCloud = function () {
                return this.resolved && this.resolved.isCloud;
            };
            LibraryRef.prototype.isTopLevel = function () {
                return this.parent.isTopLevel;
            };
            LibraryRef.prototype.isReal = function () {
                return !!this.getId();
            };
            LibraryRef.prototype.children = function () {
                return [this.resolveClauses];
            };
            LibraryRef.prototype.isThis = function () {
                return false;
            };
            LibraryRef.prototype.isPublished = function () {
                return !this.guid;
            };
            LibraryRef.prototype.thingSetKindName = function () {
                return AST.libSymbol;
            };
            LibraryRef.prototype.getPublicActions = function () {
                return this._publicActions;
            };
            LibraryRef.prototype.getPublicKinds = function () {
                return this._publicKinds;
            };
            LibraryRef.prototype.getIconArtId = function () {
                return this.resolved ? this.resolved.iconArtId : "";
            };
            LibraryRef.prototype.getLibInit = function () {
                return this.getPublicActions().filter(function (a) { return a.isLibInit(); })[0];
            };
            LibraryRef.prototype.getPublicActionsAndActionTypes = function () {
                var acts = this.getPublicKinds().map(function (k) { return k instanceof TDev.UserActionKind ? k.userAction : null; }).filter(function (a) { return a != null; });
                if (acts.length == 0)
                    return this.getPublicActions();
                else
                    return acts.concat(this.getPublicActions());
            };
            LibraryRef.prototype.getId = function () {
                return this.guid ? this.guid : this.pubid;
            };
            LibraryRef.prototype.hasErrors = function () {
                return this._hasErrors;
            };
            LibraryRef.prototype.getCategory = function () {
                return 3 /* Library */;
            };
            LibraryRef.prototype.helpTopic = function () {
                return "libraries";
            };
            LibraryRef.prototype.nodeType = function () {
                return "libraryRef";
            };
            LibraryRef.prototype.accept = function (v) {
                return v.visitLibraryRef(this);
            };
            LibraryRef.prototype.getDescription = function () {
                return ": " + (this.resolved ? this.resolved.getName() : "?") + (this.pubid ? "" : " (local)");
            };
            LibraryRef.prototype.getNamespace = function () {
                return AST.libSymbol + "\u200A";
            };
            LibraryRef.prototype.toString = function () {
                return this.getNamespace() + this.getName();
            };
            LibraryRef.prototype.hasAbstractKind = function (n) {
                return !!this.kindMapping[n];
            };
            LibraryRef.prototype.isTutorial = function () {
                return this.getStableName() == "tutorialLib";
            };
            LibraryRef.prototype.isBrowsable = function () {
                if (AST.followingTutorial && /^_/.test(this.getName()))
                    return false;
                return true;
            };
            LibraryRef.prototype.updateSubstitutions = function () {
                this._publicActions.forEach(function (a) {
                    a.updateSubstitution();
                    if (a._extensionAction)
                        a._extensionAction.updateSubstitution();
                });
                this._publicKinds.forEach(function (k) {
                    if (k.getRecord() instanceof LibraryRecordDef)
                        k.getRecord().updateSubstitution();
                });
            };
            LibraryRef.prototype.importBindings = function () {
                this.externalKindMapping = {};
                this.updateSubstitutions();
            };
            LibraryRef.prototype.getAbstractKind = function (n) {
                var k = this.kindMapping[n];
                if (k)
                    return k;
                k = new LibraryRefAbstractKind(this, n);
                this.defKind(k);
                return k;
            };
            LibraryRef.prototype.resolve = function () {
                var _this = this;
                this._hasErrors = false;
                this.isTypechecked = false;
                if (!this.isTopLevel())
                    return;
                if (!this.resolved) {
                    this._hasErrors = true;
                    return;
                }
                if (!this.publicActionsCopiedFromResolved) {
                    this.resolved.setStableNames();
                    this.publicActionsCopiedFromResolved = true;
                    this._publicActions.forEach(function (a) {
                        a.deleted = true;
                    });
                    this._publicKinds.forEach(function (k) {
                        k.kill();
                    });
                    this.kindMapping = {};
                    this._publicKinds = [];
                    var tasks = this.resolved.actionTypeDefs().filter(function (a) { return !a.isPrivate; }).map(function (a) {
                        var la = new LibraryRefAction(_this);
                        la._isActionTypeDef = true;
                        la.setName(a.getName());
                        _this.defKind(la.getDefinedKind());
                        return function () {
                            la.fromTemplate(a);
                        };
                    });
                    tasks.pushRange(this.resolved.records().filter(function (r) { return r.isExported(); }).map(function (r) {
                        var rec = new LibraryRecordDef(_this);
                        rec.setName(r.getCoreName());
                        _this.defKind(rec.entryKind);
                        return function () {
                            rec.fromTemplate(r);
                        };
                    }));
                    tasks.forEach(function (f) { return f(); });
                    this._publicActions = this.resolved.actions().filter(function (a) { return !a.isPrivate; }).map(function (a) { return new LibraryRefAction(_this).fromTemplate(a); });
                    var maxW = 0;
                    this._publicActions.forEach(function (a) {
                        var ad = a.getDescription();
                        var m = /{weight:(\d+)}/i.exec(ad);
                        if (m)
                            a._weight = parseInt(m[1]);
                        maxW = Math.max(a._weight, maxW);
                    });
                    this._publicActions.forEach(function (a) {
                        a.getUsage().apiFreq = a._weight / (maxW + 1);
                    });
                }
            };
            LibraryRef.prototype.substitute = function (k) {
                var _this = this;
                if (k instanceof LibraryRefAbstractKind) {
                    var r = this.externalKindMapping[k.toString()];
                    if (r) {
                        if (r.deleted)
                            r = r.parentLibrary().getAbstractKind(r.getName());
                        return r;
                    }
                    else
                        return k;
                }
                else if (k.isUserDefined()) {
                    return this.getAbstractKind(k.getName());
                }
                else if (k instanceof TDev.ParametricKind) {
                    var pk = k;
                    return pk.createInstance(pk.parameters.map(function (kk) { return _this.substitute(kk); }));
                }
                else {
                    return k;
                }
            };
            LibraryRef.prototype.rebind = function () {
                this.publicActionsCopiedFromResolved = false;
            };
            LibraryRef.prototype.typeCheck = function () {
                var _this = this;
                if (this.isTypechecked || this.deleted)
                    return;
                if (this.isTypechecking) {
                    this.setError("TD174: cicular library reference");
                    return;
                }
                if (!this.isTopLevel())
                    return;
                if (!this.resolved) {
                    this.resolveClauses.forEach(function (r) { return r.resolveExplicit(_this); });
                    return;
                }
                this.isTypechecking = true;
                this.clearError();
                var existing = {};
                this.resolveClauses.forEach(function (r) {
                    existing[r.name] = r;
                });
                var newResolves = this.resolved.libraries().map(function (l, ix) {
                    var clause = existing[l.getName()];
                    if (!(clause instanceof ResolveClause))
                        clause = new ResolveClause(l.getName());
                    clause.formalLib = l;
                    return clause;
                });
                this.resolveClauses.setChildren(newResolves);
                var ctx = new UnificationCtx(this);
                this.resolveClauses.forEach(function (r) {
                    r.typeCheck(ctx);
                    if (r.getError())
                        _this._hasErrors = true;
                });
                this.updateExternalKindMapping(ctx);
                this.isTypechecking = false;
                this.isTypechecked = true;
            };
            LibraryRef.prototype.updateExternalKindMapping = function (ctx) {
                var _this = this;
                var k0 = Object.keys(ctx.mapping);
                var changed = k0.length != Object.keys(this.externalKindMapping).length;
                if (!changed)
                    k0.forEach(function (k) {
                        if (ctx.mapping[k] != _this.externalKindMapping[k])
                            changed = true;
                    });
                if (changed) {
                    this.externalKindMapping = ctx.mapping;
                    this.updateSubstitutions();
                }
            };
            LibraryRef.prototype.writeTo = function (tw) {
                var _this = this;
                this.writeId(tw);
                tw.keyword("meta").id("import").id(this.getName());
                tw.beginBlock();
                if (this.pubid)
                    tw.id("pub").string(this.pubid).nl();
                else
                    tw.id("guid").string(this.guid).nl();
                tw.id("usage");
                tw.beginBlock();
                this.getPublicKinds().forEach(function (k) {
                    if (k instanceof LibraryRefAbstractKind)
                        tw.keyword("type").id(k.getName()).nl();
                    else if (k instanceof TDev.UserActionKind) {
                        k.userAction.writeHeader(tw, true);
                        tw.nl();
                    }
                    else if (k instanceof AST.RecordEntryKind) {
                        k.getRecord().writeTo(tw);
                    }
                });
                this.getPublicActions().forEach(function (a) {
                    a.writeHeader(tw, true);
                });
                tw.nl();
                tw.endBlock();
                this.resolveClauses.forEach(function (r) {
                    r.writeId(tw);
                    if (!r.defaultLib)
                        return;
                    tw.id("resolve").id(r.name).op("=");
                    r.defaultLib.writeRef(tw);
                    tw.id("with");
                    tw.beginBlock();
                    r.kindBindings.forEach(function (k) {
                        if (k.isExplicit) {
                            k.writeId(tw);
                            tw.keyword("type").id(k.formalName).op("=").kind(_this.parent, k.actual).nl();
                        }
                    });
                    r.actionBindings.forEach(function (a) {
                        if (a.isExplicit) {
                            a.writeId(tw);
                            tw.keyword("action").id(a.formalName).op("=");
                            a.actualLib.writeRef(tw);
                            tw.op("\u2192").id(a.getActualName()).nl();
                        }
                    });
                    tw.endBlock();
                });
                tw.endBlock();
            };
            LibraryRef.prototype.writeRef = function (tw) {
                return tw.op(AST.libSymbol).id(this.getName());
            };
            LibraryRef.prototype.defKind = function (k) {
                this._publicKinds.push(k);
                this.kindMapping[k.getName()] = k;
            };
            LibraryRef.parse = function (p) {
                var l = p.getLibraryRef(p.parseId());
                l.setStableName(p.consumeLabel());
                if (l.isDeclared) {
                    p.parseBraced(function () {
                        p.shift();
                    });
                    return;
                }
                l.isDeclared = true;
                p.declareLibrary(l);
                p.parseBraced(function () {
                    if (p.gotKey("pub"))
                        l.pubid = p.parseString();
                    if (p.gotKey("guid"))
                        l.guid = p.parseString();
                    if (p.gotKey("usage")) {
                        var seenNames = {};
                        p.parseBraced(function () {
                            if (p.gotKw("action")) {
                                p.shift();
                                var a = new LibraryRefAction(l);
                                a.parse(p);
                                if (!seenNames.hasOwnProperty(a.getName())) {
                                    seenNames[a.getName()] = true;
                                    if (a.isActionTypeDef()) {
                                        l.defKind(a.getDefinedKind());
                                    }
                                    else {
                                        l._publicActions.push(a);
                                    }
                                }
                            }
                            else if (p.gotId("type")) {
                                p.shift();
                                l.listedKinds.push(p.parseId());
                            }
                            else if (p.gotKw("table")) {
                                p.shift();
                                var rec = new LibraryRecordDef(l);
                                rec._initalizeFromParser(p);
                                l.defKind(rec.entryKind);
                            }
                        });
                    }
                    if (p.gotKey("resolve")) {
                        var r = new ResolveClause(p.parseId());
                        r.setStableName(p.consumeLabel());
                        l.resolveClauses.push(r);
                        p.skipOp("=");
                        r.defaultLib = p.parseLibRef();
                        if (p.gotId("with"))
                            p.shift();
                        p.parseBraced(function () {
                            if (p.gotKw("action")) {
                                p.shift();
                                var a = new ActionBinding(p.parseId());
                                a.setStableName(p.consumeLabel());
                                a.isExplicit = true;
                                p.skipOp("=");
                                a.actualLib = p.parseLibRef();
                                p.skipOp("\u2192");
                                a.actualName = p.parseId();
                                r.actionBindings.push(a);
                            }
                            else if (p.gotId("type")) {
                                p.shift();
                                var k = new KindBinding(p.parseId());
                                k.setStableName(p.consumeLabel());
                                k.isExplicit = true;
                                p.skipOp("=");
                                k.actual = p.parseType();
                                r.kindBindings.push(k);
                            }
                        });
                    }
                });
                if (!l.getId())
                    l.pubid = "sixvorgj";
                l.importBindings();
            };
            LibraryRef.topScriptLibrary = function (par) {
                return new ThisLibraryRef(par);
            };
            LibraryRef.fresh = function () {
                var decl = AST.Parser.parseDecl("meta import __touch_develop__library__ { }");
                decl.setName(TDev.Script.freshName("lib"));
                decl.wasAutoNamed = true;
                decl.pubid = "";
                return decl;
            };
            LibraryRef.prototype.initializeResolves = function () {
                var _this = this;
                var findMatching = function (l) { return TDev.Script.libraries().filter(function (q) { return l.getId() == q.getId() || (q.resolved && l.resolved && q.resolved.getName() == l.resolved.getName()); })[0]; };
                var findMapped = function (l) { return l == _this.resolved.thisLibRef ? _this : _this.resolveClauses.map(function (r) { return r.formalLib == l ? r.defaultLib : null; }).filter(function (x) { return !!x; })[0]; };
                if (!this.resolved)
                    return [];
                this.isTypechecked = false;
                this.typeCheck();
                var newLibs = [];
                this.resolveClauses.forEach(function (r) {
                    var lib = findMatching(r.formalLib);
                    if (lib) {
                        r.defaultLib = lib;
                        return;
                    }
                    lib = LibraryRef.fresh();
                    r.defaultLib = lib;
                    newLibs.push(r);
                });
                newLibs.forEach(function (r) {
                    var lib = r.defaultLib;
                    TDev.Script.addDecl(lib);
                    lib.setName(TDev.Script.freshName(r.formalLib.getName()));
                    lib.pubid = r.formalLib.pubid;
                    lib.guid = r.formalLib.guid;
                    lib.typeCheck();
                });
                newLibs.forEach(function (r) {
                    var lib = r.defaultLib;
                    var copyResolve = function (c, ix) {
                        var o = new ResolveClause(c.name);
                        o.defaultLib = findMapped(c.defaultLib);
                        o.actionBindings.setChildren(c.actionBindings.stmts.map(function (a, ix) {
                            var ao = new ActionBinding(a.formalName);
                            ao.isExplicit = a.isExplicit;
                            ao.actualLib = findMapped(a.actualLib);
                            ao.actualName = a.actualName;
                            return ao;
                        }));
                        return o;
                    };
                    lib.resolveClauses.setChildren(r.formalLib.resolveClauses.stmts.map(copyResolve));
                });
                return newLibs.map(function (r) { return r.defaultLib; });
            };
            LibraryRef.libNamespace = function (name) {
                if (!name)
                    return "";
                return AST.libSymbol + name + "\u200A\u2192\u00A0";
            };
            return LibraryRef;
        })(AST.PropertyDecl);
        AST.LibraryRef = LibraryRef;
        var ThisLibraryRef = (function (_super) {
            __extends(ThisLibraryRef, _super);
            function ThisLibraryRef(p) {
                _super.call(this);
                this.resolved = p;
                this.parent = p;
                this.setName("this");
                this.setStableName("this");
            }
            ThisLibraryRef.prototype.isReal = function () {
                return true;
            };
            ThisLibraryRef.prototype.getPublicActions = function () {
                return this.resolved.things.filter(function (a) { return a instanceof AST.Action && !a.isPrivate; });
            };
            ThisLibraryRef.prototype.isThis = function () {
                return true;
            };
            ThisLibraryRef.prototype.typeCheck = function () {
                this.isTypechecked = true;
            };
            return ThisLibraryRef;
        })(LibraryRef);
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Renderer = (function (_super) {
        __extends(Renderer, _super);
        function Renderer() {
            _super.call(this);
            this.isAux = false;
            this.shortNameHeuristicsApplied = false;
            this.shortNameHeuristics = false;
            this.stringLimit = 30;
            this.renderingSnippet = false;
            this.highlightLevel = 0;
            this.showDiff = false;
            this.hideErrors = false;
            this.formatComments = true;
            this.skipComments = false;
            this.numDiffs = 0;
            this.mdComments = new TDev.MdComments(this, null);
        }
        Renderer.spacedText = function (t) {
            switch (t) {
                case "0":
                case "1":
                case "2":
                case "3":
                case "4":
                case "5":
                case "6":
                case "7":
                case "8":
                case "9":
                case "(":
                case ")":
                case ".":
                case "":
                case " ":
                    return t;
                case ",":
                    return ", ";
                case "not":
                    return "not ";
                default:
                    return " " + t + " ";
            }
        };
        Renderer.opName = function (s) {
            if (!TDev.AST.proMode)
                return s;
            switch (s) {
                case "\u2260": return "!=";
                case "\u2264": return "<=";
                case "\u2265": return ">=";
                case "=": return "==";
                default:
                    return s;
            }
        };
        Renderer.quoteString = function (s) {
            var r = "";
            for (var i = 0; i < s.length; ++i) {
                var c = s.charAt(i);
                var o;
                switch (c) {
                    case "\t":
                        o = "\\t";
                        break;
                    case "\"":
                        o = "\\\"";
                        break;
                    case "\\":
                        o = "\\\\";
                        break;
                    case "\r":
                        o = "\\r";
                        break;
                    case "\n":
                        o = "\\n";
                        break;
                    default:
                        o = c;
                        break;
                }
                r = r + o;
            }
            return r;
        };
        Renderer.tdiv = function (cl, s) {
            return "<div class='" + cl + "'>" + s + "</div>";
        };
        Renderer.tspan = function (cl, s) {
            return "<span class='" + cl + "'>" + TDev.Util.htmlEscape(s) + "</span>";
        };
        Renderer.tspanRaw = function (cl, s) {
            return "<span class='" + cl + "'>" + s + "</span>";
        };
        Renderer.prototype.kw = function (k) {
            return Renderer.tspan("kw", " " + k + " ");
        };
        Renderer.prototype.kw0 = function (k) {
            return Renderer.tspan("kw", k);
        };
        Renderer.prototype.greyKw = function (k) {
            return Renderer.tspan("greyed", " " + k + " ");
        };
        Renderer.prototype.id = function (kw) {
            return TDev.Util.htmlEscape(kw);
        };
        Renderer.prototype.name = function (name) {
            return Renderer.tspan("name", TDev.Util.htmlEscape(name));
        };
        Renderer.prototype.kind = function (k) {
            return TDev.Util.htmlEscape(k.toString());
        };
        Renderer.prototype.op = function (kw) {
            return TDev.Util.htmlEscape(Renderer.spacedText(kw));
        };
        Renderer.prototype.st = function (kw) {
            return Renderer.tspan("st", kw);
        };
        Renderer.prototype.tline = function (s) {
            return Renderer.tdiv("line", s.trim() + (this.showDiff || TDev.AST.blockMode ? "" : "<span class='lineSpacer'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>")) + "<br/>";
        };
        Renderer.prototype.interpretedComment = function (n) {
            if (!this.renderingSnippet)
                return false;
            var m = /^\s*\{(\/)?highlight\}\s*$/.exec(n.text);
            if (m) {
                if (m[1])
                    this.highlightLevel--;
                else
                    this.highlightLevel++;
                return true;
            }
            return false;
        };
        Renderer.prototype.renderBlock = function (lst) {
            if (this.isAux)
                return "";
            if (this.showDiff)
                return this.renderSnippet(lst.stmtsWithDiffs());
            return this.renderSnippet(lst.stmts);
        };
        Renderer.prototype.renderDecl = function (d) {
            this.highlightLevel = 0;
            this.renderingSnippet = true;
            try {
                return Renderer.tdiv("decl", d.accept(this));
            }
            finally {
                this.renderingSnippet = false;
            }
        };
        Renderer.prototype.renderSnippet = function (s) {
            var res = "";
            var prevHl = this.highlightLevel;
            var prevSnip = this.renderingSnippet;
            this.highlightLevel = 0;
            this.renderingSnippet = true;
            try {
                for (var i = 0; i < s.length; ++i)
                    res += s[i].accept(this);
                return Renderer.tdiv("block", res);
            }
            finally {
                this.renderingSnippet = prevSnip;
                this.highlightLevel = prevHl;
            }
        };
        Renderer.prototype.wrapError = function (n, r) {
            if (n.getError() != null)
                return "<span class='errorSq'>" + r + "</span>";
            else
                return "<span class='calcToken'>" + r + "</span>";
        };
        Renderer.prototype.renderTokens = function (t) {
            var res = "";
            if (this.shortNameHeuristics) {
                var sna = -2;
                for (var i = 0; i < t.length; ++i) {
                    if (t[i] instanceof TDev.AST.PropertyRef && sna == i - 1) {
                        res += this.id("\u200A" + t[i].getText());
                    }
                    else {
                        this.shortNameHeuristicsApplied = false;
                        res += t[i].accept(this);
                        if (this.shortNameHeuristicsApplied)
                            sna = i;
                    }
                }
            }
            else {
                for (var i = 0; i < t.length; ++i)
                    res += t[i].accept(this);
            }
            return res;
        };
        Renderer.prototype.renderArtUrl = function (kind, v) {
            if (kind == TDev.api.core.String && v)
                return Renderer.tdiv("stringLiteral", TDev.Util.htmlEscape(TDev.RT.String_.trim_overflow(TDev.RT.String_.valueFromArtUrl(v), 400)));
            return this.renderString(v, 200);
        };
        Renderer.prototype.renderBitmatrix = function (v, options) {
            options = options || {};
            var bits = (v || "").trim().split("\n").map(function (row) { return row.split(/[\s\r\n]+/).map(function (s) {
                var x = parseInt(s);
                if (isNaN(x))
                    x = 0;
                return !!x;
            }); });
            var maxCols = options.maxCols || 45;
            var height = options.height || 1;
            var f = 50;
            var f2 = f / 2;
            var r1 = "";
            var r0 = "";
            var w = 0;
            var rows = bits.length;
            if (!v)
                rows = 5;
            var h = rows * f;
            var ellipse = false;
            for (var y = 0; y < rows; ++y) {
                var row = bits[y] || [];
                var cols = Math.max(rows, Math.min(row.length, maxCols));
                w = Math.max(w, cols * f + Math.floor(cols / 5) * f);
                ellipse = ellipse || cols < row.length;
                for (var x = 0; x < cols; ++x) {
                    var bit = row[x];
                    var left = f * x + Math.floor(x / 5) * f;
                    var top = f * y;
                    var width = f2;
                    if (bit) {
                        width += 4;
                        left -= 2;
                        top -= 2;
                    }
                    var path = TDev.Util.fmt(" M {0} {1} {2} {3} {4} {5} {6} {7} Z", left, top, left + width, top, left + width, top + width, left, top + width);
                    if (bit)
                        r1 += path;
                    else
                        r0 += path;
                }
            }
            var viewPort = TDev.Util.fmt("0 0 {0} {1}", w, h);
            var svg = TDev.Util.fmt("<path class='biton' d='{0}'/><path class='bitoff' d='{1}'/>", r1, r0);
            var result = TDev.Util.fmt("<span class='kbm {0}' style='width:{1}em'>{2}</span>", options.cls || "", w / h * height + 0.1, TDev.SVG.svgBoilerPlate(viewPort, svg));
            if (ellipse)
                result += Renderer.tspan("stringLiteral", "...");
            return result;
        };
        Renderer.prototype.renderHintArtId = function (v, id) {
            var url = TDev.Cloud.artUrl(id, true);
            return TDev.Util.fmt("<img class='picLiteral' src='{0}' alt='{1}' />", url, Renderer.quoteString(TDev.RT.String_.trim_overflow(v, this.stringLimit)));
        };
        Renderer.prototype.renderEnumVal = function (v) {
            return Renderer.tspan("stringLiteral", Renderer.quoteString(TDev.RT.String_.trim_overflow(v, this.stringLimit)));
        };
        Renderer.prototype.renderString = function (v, lim) {
            if (lim === void 0) { lim = this.stringLimit; }
            return Renderer.tspan("stringLiteral", "\"" + Renderer.quoteString(TDev.RT.String_.trim_overflow(v, lim)) + "\"");
        };
        Renderer.prototype.visitDeclName = function (n) {
            return this.id(n.data);
        };
        Renderer.prototype.visitFieldName = function (n) {
            return this.id(n.data) + this.op(":");
        };
        Renderer.prototype.visitLiteral = function (n) {
            var v = n.data;
            var div;
            switch (typeof v) {
                case "number":
                    v = v + "";
                    TDev.Util.die();
                    break;
                case "boolean":
                    div = Renderer.tspan("kw", v ? "true" : "false");
                    break;
                case "string":
                    if (/^bitmatrix|bitframe$/i.test(n.languageHint))
                        div = this.renderBitmatrix(v);
                    else if (n.enumVal)
                        div = this.renderEnumVal(v);
                    else
                        div = this.renderString(v);
                    if (n.hintArtId)
                        div += this.renderHintArtId(v, n.hintArtId);
                    break;
                default:
                    TDev.Util.die();
            }
            return this.wrapError(n, div);
        };
        Renderer.prototype.visitPropertyRef = function (n) {
            var nm = n.getText();
            var arrow = n.getOrMakeProp().getArrow();
            if (n.skipArrow)
                arrow = "\u200A";
            return this.wrapError(n, this.id(arrow + nm));
        };
        Renderer.prototype.visitThingRef = function (n) {
            if (this.codeReplacement && !n.forceLocal && n.getText() == 'code')
                return this.codeReplacement;
            var sn = n.shortName();
            if (!sn && this.shortNameHeuristics && !n.forceLocal) {
                var knd = TDev.api.getKind(n.getText());
                if (knd && knd instanceof TDev.ThingSetKind)
                    sn = knd.shortName();
                this.shortNameHeuristicsApplied = true;
            }
            if (n.def instanceof TDev.AST.PlaceholderDef) {
                var pl = n.def;
                return this.wrapError(n, TDev.Util.fmt("<span class='placeholder'>{0:q}</span>", pl.label || pl.getKind().toString()));
            }
            var content = "";
            if (!sn)
                content = this.id(n.getText());
            else {
                if (TDev.Browser.isAndroid) {
                    var svg = TDev.SVG.codeSignHtml(sn);
                    if (svg)
                        content = "<span class='svg-symbol'>" + svg + "</span>";
                    else
                        content = Renderer.tspan("id symbol", sn);
                }
                else {
                    content = Renderer.tspan("id symbol", sn);
                }
            }
            return this.wrapError(n, content);
        };
        Renderer.prototype.visitOperator = function (n) {
            var s = n.getText();
            var r = this.op(Renderer.opName(s));
            if (/^[a-z]+$/.test(s))
                r = this.kw(s);
            var args = n.getFunArgs();
            if (args) {
                if (args.length == 1)
                    s = args[0];
                else
                    s = "(" + args.join(", ") + ")";
                r = this.id(s + " ⇒ ");
            }
            return this.wrapError(n, r);
        };
        Renderer.prototype.diffWords = function (tokens) {
            var res = "";
            for (var i = 0; i < tokens.length; i += 2) {
                if (tokens[i] == null || tokens[i + 1] == null)
                    break;
                res += tokens[i + 1];
            }
            if (i >= tokens.length)
                return res;
            this.numDiffs++;
            res = "";
            for (var i = 0; i < tokens.length; i += 2) {
                if (tokens[i] != null && tokens[i + 1] != null)
                    res += Renderer.tspanRaw("diffTokenUnchanged", tokens[i + 1]);
                else if (tokens[i] != null)
                    res += Renderer.tspanRaw("diffTokenRemoved", tokens[i]);
                else
                    res += Renderer.tspanRaw("diffTokenAdded", tokens[i + 1]);
            }
            return Renderer.tspanRaw("diffTokensChanged", res);
        };
        Renderer.prototype.renderDiffTokens = function (tokens) {
            var _this = this;
            var toks = tokens.map(function (t) { return t ? t.accept(_this) : null; });
            return this.diffWords(toks);
        };
        Renderer.prototype.visitExprHolder = function (e) {
            return this.renderExprHolder(e, e.tokens);
        };
        Renderer.prototype.renderExprHolder = function (e, tokens) {
            if (this.showDiff && e.diffTokens)
                return this.renderDiffTokens(e.diffTokens);
            var res = this.renderTokens(tokens);
            if (!e.profilingExprData && !e.debuggingData)
                return res;
            if (e.profilingExprData) {
                var index = Math.floor(e.profilingExprData.duration / TDev.AST.ExprHolder.profilingDurationBucketSize);
                var color = TDev.AST.ExprHolder.heatmapColors[index];
                return "<span style='background-color:" + color + "'>" + res + "</span>" + "<span class='profile' style='background-color:" + color + "'>" + Math.round(e.profilingExprData.duration) + "ms/" + Math.round(e.profilingExprData.count) + "</span>";
            }
            if (e.debuggingData) {
                if (e.debuggingData.critical && e.debuggingData.max) {
                    var scorePartial = e.debuggingData.critical / e.debuggingData.max.critical;
                    var score = Math.floor(scorePartial * 27);
                    var color = TDev.AST.ExprHolder.heatmapColors[score];
                    var ret = "<span style='background-color:" + color + "'>" + res + "</span>";
                    if (TDev.dbg)
                        ret += ("<span class='profile' style='background-color:" + color + "'>" + Math.floor(scorePartial * 100) + "%</span>");
                    return ret;
                }
                else if (e.debuggingData.visited) {
                    return "<span style='background-color:#eaf3ff'>" + res + "</span>";
                }
                else if (e.debuggingData.alwaysTrue) {
                    return "<span style='background-color:#daffda'>" + res + "</span>";
                }
                else if (e.debuggingData.alwaysFalse) {
                    return "<span style='background-color:#ffdada'>" + res + "</span>";
                }
                else
                    return res;
            }
        };
        Renderer.prototype.diffClass = function (n) {
            var diffClass = "";
            if (this.showDiff) {
                if (n.diffStatus < 0) {
                    this.numDiffs++;
                    return " diffStmtRemoved";
                }
                else if (n.diffStatus > 0) {
                    this.numDiffs++;
                    return " diffStmtAdded";
                }
            }
            return "";
        };
        Renderer.prototype.diffMoveMarker = function (n) {
            if (this.showDiff) {
                var moveId = 0;
                moveId = -n.diffStatus - 2;
                if (moveId < 0 && n.diffAltStmt)
                    moveId = -n.diffAltStmt.diffStatus - 2;
                if (moveId >= 0)
                    return "<div class='diffMoveMarker'>" + moveId + "</div>";
            }
            return "";
        };
        Renderer.prototype.stmtClass = function (n) {
            var tp = n.nodeType();
            var cat = "other";
            switch (tp) {
                case "inlineActions":
                case "exprStmt":
                    cat = "exprStmt";
                    break;
                case "actionHeader":
                case "inlineAction":
                    cat = "action";
                    break;
                case "recordDef":
                case "libraryRef":
                case "globalDef":
                    cat = "decl";
                    break;
                case "while":
                case "for":
                case "foreach":
                    cat = "loop";
                    break;
                case "elseIf":
                case "if":
                    cat = "if";
                    break;
                case "recordField":
                case "actionParameter":
                    cat = "field";
                    break;
            }
            return " stmt-" + cat + " stmt-" + tp;
        };
        Renderer.prototype.stmt = function (n, args, f, blockNode) {
            if (f === void 0) { f = undefined; }
            if (blockNode === void 0) { blockNode = null; }
            if (this.showDiff)
                args = Renderer.tdiv(this.diffClass(n) + this.stmtClass(blockNode || n), args + this.diffMoveMarker(n));
            if (this.highlightLevel > 0)
                return Renderer.tdiv("code-highlight", args) + "<!-- HL -->";
            return Renderer.tdiv("stmt" + this.stmtClass(blockNode || n), args);
        };
        Renderer.prototype.expr = function (e) {
            if (e.isPlaceholder())
                return TDev.AST.proMode ? this.id("...") : Renderer.tspanRaw("greyed", "add code here");
            else
                return this.dispatch(e);
        };
        Renderer.prototype.message = function (cls, content) {
            return Renderer.tdiv(cls, content) + "<br class='errorBr'/>";
        };
        Renderer.prototype.errorNum = function (num) {
            if (!num)
                return "";
            else
                return "<span class='errorNumber'> [" + num + "]</span>";
        };
        Renderer.prototype.errorHTML = function (node) {
            if (node instanceof TDev.AST.ExprStmt) {
                var exprStmt = node;
                if (exprStmt.expr) {
                    var dd = exprStmt.expr.debuggingData;
                    if (dd && dd.errorMessage)
                        return "<span class='symbol'>\u26a1</span> " + TDev.Util.htmlEscape(dd.errorMessage);
                }
            }
            var err = node.getError();
            if (err != null) {
                var errNum = "";
                err = err.replace(/^(TD\d\d\d): /, function (mtch, en) {
                    errNum = en;
                    return "";
                });
                return TDev.Util.htmlEscape("\u2639 " + err) + this.errorNum(errNum);
            }
            else {
                return "";
            }
        };
        Renderer.prototype.possibleError = function (node) {
            var _this = this;
            if (this.isAux || this.showDiff || this.hideErrors)
                return "";
            var err = node.getError();
            var res = "";
            var errH = this.errorHTML(node);
            if (errH)
                res += this.message(node.errorIsOk ? "hintMessage" : "errorMessage", errH);
            if (res == "" && node instanceof TDev.AST.Stmt) {
                var tw = node.tutorialWarning;
                if (tw) {
                    tw.split("\n").forEach(function (m) {
                        if (m)
                            res += _this.message("errorMessage", TDev.Util.htmlEscape("[T] " + m));
                    });
                }
            }
            if (res == "" && node instanceof TDev.AST.Stmt) {
                var hint = node.getHint();
                if (hint)
                    hint.split("\n").forEach(function (h) {
                        res += _this.message("hintMessage", TDev.Util.htmlEscape("\u270e " + h));
                    });
            }
            if (node.annotations)
                node.annotations.forEach(function (a) {
                    res += _this.message(a.category == "error" ? "errorMessage fromPlugin" : "hintMessage fromPlugin", "<span class='svg-symbol'>" + (a.pluginRef == "caller" ? TDev.SVG.getIconSVGCore("bug,#7057D3,clip=100") : TDev.SVG.getIconSVGCore("plug,#7057D3,clip=100")) + "</span> " + TDev.Util.htmlEscape(a.message));
                });
            return res;
        };
        Renderer.prototype.renderEmbeddedLangauge = function (n) {
            var emb = TDev.AST.getEmbeddedLangaugeToken(n);
            if (emb) {
                var lines = emb.getStringLiteral().split(/\n/);
                var shift = 0;
                var inlErr = (n._inlineErrors || []).slice(0);
                inlErr.sort(function (a, b) { return a.lineNo - b.lineNo; });
                if (lines.length > 50) {
                    if (inlErr[0] && inlErr[0].lineNo > 10) {
                        shift = inlErr[0].lineNo - 10;
                    }
                    lines = lines.slice(shift, shift + 50).concat(["..."]);
                    if (shift > 0) {
                        lines.unshift("...");
                        shift--;
                    }
                }
                lines = lines.map(function (s) { return s.length > 80 ? s.slice(0, 80) + "..." : s; });
                lines = lines.map(function (s) { return TDev.Util.htmlEscape(s); });
                var str = "";
                var j = 0;
                lines.forEach(function (l, i) {
                    while (inlErr[j] && inlErr[j].lineNo == i + shift) {
                        var err = inlErr[j++];
                        str += Renderer.tdiv("error", Renderer.tdiv("main", TDev.Util.htmlEscape(err.coremsg)) + Renderer.tdiv("hints", TDev.Util.htmlEscape(err.hints)));
                    }
                    str += l + "\n";
                });
                return (this.tline(this.renderExprHolder(n.expr, n.expr.tokens.slice(0, 2)) + this.kw(" inline")) + this.possibleError(n) + Renderer.tdiv("inline-language", str));
            }
            return null;
        };
        Renderer.prototype.renderExprStmt = function (n, suffix) {
            if (suffix === void 0) { suffix = ""; }
            if (n.isPlaceholder()) {
                if (TDev.AST.proMode)
                    return this.tline("<span class='greyed'>&nbsp;;</span>");
                else
                    return this.tline("<span class='greyed greyer'>" + TDev.Cloud.config.doNothingText + "</span>");
            }
            else {
                var r = this.renderEmbeddedLangauge(n);
                if (r)
                    return r;
                var toks = this.renderExprHolder(n.expr, n.expr.tokens);
                toks += suffix;
                if (n.isVarDef())
                    toks = this.kw("var ") + toks;
                else if (!TDev.AST.blockMode && n.isPagePush())
                    toks = this.kw("push ") + toks;
                return this.tline(toks) + this.possibleError(n);
            }
        };
        Renderer.prototype.visitExprStmt = function (n) {
            if (!this.showDiff && this.formatComments) {
                var doc = n.docText();
                if (doc != null) {
                    var inner = this.tline(Renderer.tdiv("md-comment", this.mdComments.formatText(doc)));
                    return this.stmt(n, inner + this.possibleError(n));
                }
            }
            return this.stmt(n, this.renderExprStmt(n));
        };
        Renderer.prototype.visitOptionalParameter = function (o) {
            var name = this.diffTwoWords(o.getName(), o.diffAltStmt ? o.diffAltStmt.getName() : null);
            return this.stmt(o, this.tline(this.kw("with ") + name + this.op("=") + this.dispatch(o.expr)) + this.possibleError(o));
        };
        Renderer.prototype.visitInlineAction = function (a) {
            var _this = this;
            var renderHead = function (a) {
                var r = [_this.kw(a.isOptional ? "with " : "where "), _this.id(a.name.getName())];
                var renderParms = function (parms) {
                    var first = true;
                    r.push(_this.op("("));
                    parms.forEach(function (p) {
                        if (!first)
                            r.push(_this.op(", "));
                        first = false;
                        r.push(_this.id(p.getName()), _this.op(":"), _this.kind(p.getKind()));
                    });
                    r.push(_this.op(")"));
                };
                renderParms(a.inParameters);
                if (a.outParameters.length > 0) {
                    r.push(_this.kw(" returns "));
                    renderParms(a.outParameters);
                }
                if (TDev.AST.proMode)
                    r.push(_this.st(" {"));
                else
                    r.push(_this.kw(" is"));
                return r;
            };
            var ss = this.diffLine(a, a.diffAltStmt, renderHead) + this.possibleError(a) + this.renderBlock(a.body) + this.endKeyword("");
            return this.stmt(a, ss);
        };
        Renderer.prototype.visitInlineActions = function (n) {
            var last = n.implicitAction();
            var hasImplicit = !!last;
            var suff = "";
            if (!this.isAux && hasImplicit && n.actions.stmts.length == 1)
                suff = TDev.AST.proMode ? this.st(" {") : this.kw("do");
            var expr = this.renderExprStmt(n, suff);
            if (!this.isAux) {
                var body = n.actions.stmts.slice(0);
                if (hasImplicit) {
                    body.pop();
                    expr += this.renderSnippet(body);
                    if (!suff)
                        expr += this.tline(TDev.AST.proMode ? this.st(" {") : this.kw("do"));
                    expr += this.possibleError(last);
                    expr += this.renderBlock(last.body);
                    expr += this.tline(TDev.AST.proMode ? this.st("}") : this.kw("end"));
                }
                else {
                    expr += this.renderSnippet(body);
                    if (!TDev.AST.proMode && body.length > 0)
                        expr += this.endKeyword("");
                }
            }
            return this.stmt(n, expr);
        };
        Renderer.prototype.visitWhile = function (n) {
            return this.stmt(n, (TDev.AST.proMode ? this.tline(this.kw("while") + this.st(" (") + this.expr(n.condition) + this.st(") {")) : this.tline(this.kw("while") + this.expr(n.condition) + this.kw("do"))) + this.possibleError(n) + this.renderBlock(n.body) + this.endKeyword("while"));
        };
        Renderer.prototype.visitBox = function (n) {
            return this.stmt(n, this.tline(this.kw("boxed") + (TDev.AST.proMode ? this.st("{") : "")) + this.possibleError(n) + this.renderBlock(n.body) + this.endKeyword("boxed"));
        };
        Renderer.prototype.visitComment = function (n) {
            function tokenize(n) {
                var toks = ["<div translate=yes class='md-comment'>"];
                n.text.replace(/[^\s]+\s*/g, function (m) {
                    toks.push(TDev.Util.htmlEscape(m));
                    return "";
                });
                toks.push("</div>");
                return toks;
            }
            var inner = "";
            if (this.showDiff) {
                inner = this.diffLine(n, n.diffAltStmt, tokenize);
            }
            else {
                if (this.interpretedComment(n))
                    return "";
                if (!this.skipComments) {
                    if (this.formatComments)
                        inner = this.tline(Renderer.tdiv("md-comment", this.mdComments.formatText(n.text, n)));
                    else
                        inner = this.tline("<span class='comment'> " + TDev.Util.formatText(n.text) + "</span>");
                }
            }
            return this.stmt(n, inner + this.possibleError(n));
        };
        Renderer.prototype.endKeyword = function (name) {
            if (TDev.AST.proMode)
                return this.tline(this.st("}"));
            else
                return this.tline(this.kw("end ") + this.greyKw(name));
        };
        Renderer.prototype.visitFor = function (n) {
            var idiff = this.diffTwoWords(n.boundLocal.getName(), n.diffAltStmt ? n.diffAltStmt.boundLocal.getName() : null);
            var i = this.kw(n.boundLocal.getName());
            return this.stmt(n, (TDev.AST.proMode ? this.tline(this.kw("for") + this.st("(") + this.kw0("var ") + idiff + this.st(" < ") + this.expr(n.upperBound) + this.st(") {")) : this.tline(this.kw("for") + this.kw("0") + this.kw("\u2264") + idiff + this.kw("<") + this.expr(n.upperBound) + this.kw("do"))) + this.possibleError(n) + this.renderBlock(n.body) + this.endKeyword("for"));
        };
        Renderer.prototype.visitForeach = function (n) {
            var hasWhere = n.conditions.stmts.length > 0;
            return this.stmt(n, this.tline(this.kw("for each ") + (TDev.AST.proMode ? this.st("(") + this.kw0("var ") : "") + this.diffTwoWords(n.boundLocal.getName(), n.diffAltStmt ? n.diffAltStmt.boundLocal.getName() : null) + this.kw("in") + this.expr(n.collection) + (TDev.AST.proMode ? this.st(")") + (hasWhere ? "" : this.st(" {")) : (!hasWhere ? this.kw("do") : ""))) + this.possibleError(n) + (hasWhere ? this.renderBlock(n.conditions) + this.tline(TDev.AST.proMode ? this.st("{") : this.kw("do")) : "") + this.renderBlock(n.body) + this.endKeyword("for each"));
        };
        Renderer.prototype.visitWhere = function (n) {
            return this.stmt(n, this.tline(this.kw("where") + this.expr(n.condition)) + this.possibleError(n));
        };
        Renderer.prototype.visitAnyIf = function (n) {
            var children = TDev.AST.proMode ? this.tline((n.isElseIf ? this.st("}") + this.kw("else if") : this.kw("if")) + this.st(" (") + this.expr(n.rawCondition) + this.st(") {")) : this.tline(this.kw(n.isElseIf ? "else if" : "if") + this.expr(n.rawCondition) + this.kw("then"));
            children += this.possibleError(n);
            if (n.isTopCommentedOut()) {
                children += Renderer.tdiv("block-comment", this.renderBlock(n.rawThenBody));
                return this.stmt(n, children);
            }
            else {
                children += this.renderBlock(n.rawThenBody);
            }
            if (this.isAux)
                return children;
            if (n.displayElse) {
                if (n.rawElseBody.isBlockPlaceholder()) {
                    return this.stmt(n, children) + this.stmt(n.rawElseBody.stmts[0] || n, TDev.AST.proMode ? this.tline(this.st("}") + this.kw("else") + this.st("{ }")) : this.tline(this.kw("else") + Renderer.tspanRaw("greyed", TDev.Cloud.config.doNothingText) + this.kw(" end ") + this.greyKw("if")), function (e) { return e.setFlag("elseDoNothing", true); }, n);
                }
                else {
                    if (TDev.AST.proMode)
                        children += this.tline(this.st("}") + this.kw("else") + this.st("{"));
                    else
                        children += this.tline(this.kw("else"));
                    children += this.renderBlock(n.rawElseBody);
                    children += this.endKeyword("if");
                }
            }
            return this.stmt(n, children);
        };
        Renderer.prototype.visitActionParameter = function (n) {
            var _this = this;
            var finaltok = this.op(n.parent.stmts.peek() == n ? ")" : ",");
            var str = this.diffLine(n, n.diffAltStmt, function (n) { return [_this.id(n.getName()), _this.op(":"), _this.kind(n.getKind()), finaltok]; });
            return this.stmt(n, str + this.possibleError(n));
        };
        Renderer.prototype.actionKeyword = function (a) {
            if (a.isEvent())
                return "event";
            else if (a.isPage())
                return "page";
            return "function";
        };
        Renderer.prototype.renderAppHeader = function (app) {
            var hd = "";
            var sig = this.kw("script");
            if (app.isLibrary)
                sig = this.kw("library") + " " + sig;
            hd += this.stmt(app.headerStmt, this.tline(sig));
            hd += " ";
            hd += this.stmt(app.nameHolder, this.tline(this.id(TDev.RT.String_.trim_overflow(app.getName(), 64))));
            return TDev.Util.fmt("<div id='stmt-script' class='stmt stmt-appHeader'>{0}</div>", this.tline(hd));
        };
        Renderer.prototype.renderActionHeader = function (n) {
            var inParms = "";
            var returns = "";
            var outParms = "";
            var hd = "";
            if (n.action.isPrivate)
                hd += this.kw("private ");
            if (n.action.isAtomic && !n.action.isPage())
                hd += this.kw("atomic ");
            if (n.action.isTest())
                hd += this.kw("test ");
            if (n.action.isOffline)
                hd += this.kw("offline ");
            if (n.action.isQuery)
                hd += this.kw("query ");
            hd += this.kw(this.actionKeyword(n.action));
            if (n.action.isActionTypeDef())
                hd += this.kw(" type");
            if (n.getName() == "main")
                hd += this.id(n.getName());
            else
                hd += this.stmt(n.action.nameHolder, this.tline(this.id(n.getName())));
            if (n.action.hasInParameters()) {
                hd += this.op(" (");
                inParms = this.renderBlock(n.inParameters);
            }
            else {
                hd += this.op(" ()");
            }
            if (n.action.hasOutParameters()) {
                returns = this.tline(this.kw("returns") + this.op(" ("));
                outParms = this.renderBlock(n.outParameters);
            }
            if (TDev.AST.proMode && !inParms && !outParms)
                hd += this.st(" {");
            return this.tline(hd) + inParms + returns + outParms + this.possibleError(n.action);
        };
        Renderer.prototype.addModelFieldHint = function () {
            return "";
        };
        Renderer.prototype.visitActionHeader = function (n) {
            var body = this.renderActionHeader(n);
            var a = n.action;
            if (a.isActionTypeDef())
                return this.stmt(n, body);
            if (a.isPage()) {
                var inner = "";
                if (a.modelParameter) {
                    var k = a.modelParameter.getKind();
                    if (k instanceof TDev.AST.RecordEntryKind) {
                        var r = k.getRecord();
                        inner += this.tline(this.kw("data")) + (r.values.stmts.length == 0 ? this.addModelFieldHint() : this.renderBlock(r.values));
                    }
                }
                inner += this.tline(this.kw("initialize")) + this.renderBlock(a.getPageBlock(true)) + this.tline(this.kw("display")) + this.renderBlock(a.getPageBlock(false));
                return this.stmt(n, body + inner + this.endKeyword("page"));
            }
            if (a.hasOutParameters() || a.hasInParameters())
                body += this.tline(TDev.AST.proMode ? this.st("{") : this.kw("do"));
            return this.stmt(n, body + this.renderBlock(a.body) + this.endKeyword(this.actionKeyword(a)));
        };
        Renderer.prototype.visitLibraryRef = function (n) {
            return this.stmt(n, this.tline(this.kw("import") + this.id(n.getName())) + this.tline(this.kw(n.isPublished() ? "published" : "local") + this.id(n.getId())) + this.possibleError(n) + this.renderBlock(n.resolveClauses));
        };
        Renderer.prototype.visitRecordDef = function (n) {
            var keys = n.keys.count() > 0 ? (this.tline(this.kw((n.getKeyTerminology() || "key") + "s")) + this.renderBlock(n.keys)) : "";
            var values = (n.values.count() > 0 && n.getValueTerminology()) ? (this.tline(this.kw(n.getValueTerminology() + "s")) + this.renderBlock(n.values)) : "";
            var kw1 = this.stmt(n.recordPersistence, this.tline(this.kw(n.getPersistenceDescription())));
            var spacer = n.getPersistenceDescription().length ? "&nbsp;" : "";
            var kw2 = this.stmt(n.recordKind, this.tline(this.kw(n.getDefTerminology())));
            var kw3 = this.stmt(n.nameHolder, this.tline(this.id(n.getCoreName())));
            var header = this.diffLine(n, n.diffAltDecl, function (n) { return [kw1, spacer, kw2, "&nbsp;", kw3]; });
            return this.stmt(n, this.possibleError(n) + header + keys + values);
        };
        Renderer.prototype.diffTwoWords = function (s, alt) {
            if (!this.showDiff || !alt || alt == s)
                return TDev.AST.proMode ? Renderer.tspan("greyed", s) : this.id(s);
            return this.diffWords([this.id(alt), null, null, this.id(s)]);
        };
        Renderer.prototype.diffLine = function (stmt, alt, f) {
            var w0 = f(stmt);
            var r = "";
            if (this.showDiff && alt) {
                var w1 = f(alt);
                var w2 = TDev.AST.Diff.minimalEditDistance(w1, w0, function (a, b) { return a == b; });
                r = this.diffWords(w2);
            }
            else {
                if (w0.length == 0)
                    return "";
                r = w0.join("");
            }
            return this.tline(r);
        };
        Renderer.prototype.visitRecordField = function (n) {
            var _this = this;
            var comments = n.commentBlock.children().map(function (c) { return _this.visitComment(c); }).join("");
            var pref = n.def() && n.def().isModel ? TDev.AST.modelSymbol + "\u200A" : "";
            var str = this.diffLine(n, n.diffAltStmt, function (n) { return [
                _this.id(pref + n.getName()),
                _this.op(":"),
                _this.kind(n.dataKind)
            ]; });
            return comments + this.stmt(n, str + this.possibleError(n));
        };
        Renderer.prototype.libName = function (l) {
            return Renderer.tspan("id symbol", TDev.AST.libSymbol) + (l ? this.id(l.getName()) : "?");
        };
        Renderer.prototype.visitResolveClause = function (n) {
            return this.stmt(n, this.tline(this.kw("uses") + this.id(n.getName()) + this.kw("bound to") + this.libName(n.defaultLib) + this.kw("with")) + this.possibleError(n) + this.renderBlock(n.kindBindings) + this.renderBlock(n.actionBindings));
        };
        Renderer.prototype.visitActionBinding = function (n) {
            if (this.showDiff && !n.isExplicit)
                return "";
            return this.stmt(n, this.tline((n.isExplicit ? this.kw("explicit") : "") + this.kw("function") + this.id(n.formalName) + this.kw("bound to") + this.libName(n.actualLib) + this.id("\u200A\u2192\u00A0" + (n.getActualName()))) + this.possibleError(n));
        };
        Renderer.prototype.visitKindBinding = function (n) {
            if (this.showDiff && !n.isExplicit)
                return "";
            return this.stmt(n, this.tline(this.kw("type") + this.id(n.formalName) + this.kw("bound to") + this.kind(n.actual)) + this.possibleError(n));
        };
        Renderer.prototype.visitAction = function (n) {
            return this.dispatch(n.header);
        };
        Renderer.prototype.visitGlobalDef = function (n) {
            var _this = this;
            var l0 = this.diffLine(n, n.diffAltDecl, function (n) { return [_this.kw(n.isResource ? "art" : "data"), _this.id(n.getName()), _this.op(":"), _this.kind(n.getKind())]; });
            var l1 = this.diffLine(n, n.diffAltDecl, function (n) { return n.isResource && n.url ? [_this.kw("with"), _this.id("data: "), _this.renderArtUrl(n.getKind(), n.url)] : []; });
            return this.stmt(n, l0 + l1) + this.possibleError(n);
        };
        Renderer.prototype.visitDecl = function (n) {
            TDev.Util.check(false);
            return this.tline("Displaying " + n.getName() + " not implemented.");
        };
        Renderer.prototype.renderDiff = function (n, showAll) {
            var _this = this;
            if (showAll === void 0) { showAll = false; }
            this.showDiff = true;
            var th = n.things.concat(n.diffRemovedThings || []);
            TDev.AST.App.orderThings(th);
            var r = "";
            th.forEach(function (t) {
                var show = showAll || t.diffStatus;
                var prevNum = _this.numDiffs;
                var str = _this.dispatch(t);
                if (prevNum != _this.numDiffs)
                    show = true;
                if (show)
                    r += Renderer.tdiv("decl " + (t.diffStatus < 0 ? "diffDeclRemoved" : t.diffStatus > 0 ? "diffDeclAdded" : ""), str);
            });
            return r;
        };
        Renderer.prototype.visitApp = function (n) {
            var _this = this;
            var r = "";
            n.orderedThings().forEach(function (t) {
                r += Renderer.tdiv("decl", _this.dispatch(t));
            });
            return r;
        };
        Renderer.prototype.renderPropertySig = function (prop, withLinks, withKind, withKeyword) {
            var _this = this;
            if (withLinks === void 0) { withLinks = false; }
            if (withKind === void 0) { withKind = true; }
            if (withKeyword === void 0) { withKeyword = true; }
            var inParms = "";
            var returns = "";
            var outParms = "";
            var topicLink = function (name, topic) {
                if (topic === void 0) { topic = name; }
                if (!withLinks)
                    return _this.id(name);
                return "<a href='" + topicLink(topic) + "'>" + _this.id(name) + "</a>";
            };
            var kindLink = function (k) {
                if (!withLinks)
                    return _this.id(k.getName());
                return "<a href='" + topicLink(k.getName()) + "'>" + _this.kind(k) + "</a>";
            };
            if (prop._extensionAction)
                prop = prop._extensionAction;
            var propi = prop;
            var isExtension = propi.isExtensionAction && propi.isExtensionAction();
            var params = prop.getParameters().slice(0);
            var hd = "";
            if (withKeyword)
                hd += this.kw("function ");
            if (withKind) {
                if (isExtension) {
                    var __this = params[0];
                    hd += kindLink(__this.getKind());
                }
                else {
                    if (prop.parentKind.singleton)
                        hd += topicLink(prop.parentKind.singleton.getName());
                    else {
                        var ns = prop.getNamespaces ? prop.getNamespaces()[0] : undefined;
                        this.id;
                        if (ns)
                            hd += this.name(ns);
                        else
                            hd += "(" + kindLink(prop.parentKind) + ")";
                    }
                }
                params.shift();
                hd += "\u200A\u2192\u00A0";
            }
            hd += this.name(prop.getName());
            var parms = params.map(function (p) { return (withLinks ? "<br/>" : "") + "<span class='sig-parameter'>" + _this.id(p.getName()) + "</span>" + _this.op(":") + kindLink(p.getKind()); });
            if (parms.length > 0)
                hd += "(" + parms.join(", ") + ")";
            var rt = prop.getResult().getKind();
            if (rt != TDev.api.core.Nothing) {
                hd += (withLinks ? "<br/>" : "");
                hd += this.kw("returns") + kindLink(rt);
            }
            return Renderer.tdiv("signature", hd);
        };
        return Renderer;
    })(TDev.AST.NodeVisitor);
    TDev.Renderer = Renderer;
    var CopyRenderer = (function (_super) {
        __extends(CopyRenderer, _super);
        function CopyRenderer() {
            _super.call(this);
            this.stringLimit = 1000;
            this.formatComments = false;
        }
        CopyRenderer.prototype.tline = function (s) {
            return Renderer.tdiv("line", s.trim());
        };
        CopyRenderer.prototype.kw = function (s) {
            return " <span class='keyword'>" + TDev.Util.htmlEscape(s) + "</span> ";
        };
        CopyRenderer.prototype.message = function (cls, s) {
            if (/error/.test(cls))
                return "<div class='error'>" + s.trim() + "</div>";
            else
                return "<div class='hint'>" + s.trim() + "</div>";
        };
        CopyRenderer.prototype.visitActionBinding = function (n) {
            if (!n.isExplicit && !n.getError())
                return "";
            return _super.prototype.visitActionBinding.call(this, n);
        };
        CopyRenderer.prototype.visitKindBinding = function (n) {
            if (!n.isExplicit && !n.getError())
                return "";
            return _super.prototype.visitKindBinding.call(this, n);
        };
        CopyRenderer.inlineStyles = function (text) {
            var bodyStyle = "font-family: 'Segoe UI', 'Helvetica', sans-serif;" + "font-size:16px;" + "margin: 0.5em;" + "";
            Object.keys(CopyRenderer.styleMap).forEach(function (s) {
                var inl = CopyRenderer.styleMap[s];
                var ss = TDev.Util.fmt(" style='{0:q}'", inl);
                text = text.replace(new RegExp(s + "[\"']", "g"), function (m) { return m + ss; });
            });
            return TDev.Util.fmt("<div class='column' style='{0:q}'><!--HEADER-->{1}<!--FOOTER--></div>", bodyStyle, text);
        };
        CopyRenderer.css = "<style>\n" + "@font-face { font-family: \"TD Symbols\"; src:url(data:application/x-font-woff;base64, );}\n" + "@page { margin: 1in; }\n" + ".md-tutorial { font-size: 1.0em; line-height: 1.4em; }\n" + "@media print { .md-tutorial a:link:after, .md-tutorial a:visited:after  { content:\" (\" attr(href) \") \"; } }\n" + ".parse-error, .decl { margin-bottom: 1em; }\n" + ".parse-error, .error { color: #d00; }\n" + ".hint { color: #444; }\n" + ".errorNumber { color: #aaa; }\n" + ".kw, .keyword { font-weight: bold; color: black; }\n" + ".kbm { display:inline-block;} .kbm svg { height: 1em; vertical-align: middle; margin-left: 0.2em; }\n" + ".kbm svg > path.biton { fill:#000; } .kbm svg > path.bitoff { fill:#ccc; }\n" + ".code-highlight { border: 1px dashed gray; font-weight:bold; }\n" + ".comment { color:#444; font-style:italic; }\n" + ".greyed { color:#444; } .greyer { color: #555; }\n" + ".api-kind { border: 1px dotted #BBB; padding: 0.4em; clear: both; font-size: 1.2em; margin-bottom: 0.6em; }\n" + ".md-snippet { border: 1px dotted #bbb; padding: 0.4em 0; clear: both; line-height: 1.3em; page-break-inside:avoid; }\n" + ".md-iframe-wrapper iframe { overflow: hidden; width: 100%; left: 0; top: 0; position: absolute; border: 1px dotted #bbb;}\n" + ".md-iframe-wrapper { width:100%;clear:both;display:block; overflow:hidden;}\n" + ".md-snippet .signature { padding:0em 0.2em 0em 0.2em; }\n" + ".md-snippet .name { font-weight: bold;}\n" + ".md-img { margin:0.5em; clear:both; width:100%; text-align:center; position:relative; }\n" + ".md-img-inner { position:relative; display:inline-block; width:100%; }\n" + ".md-img .caption { font-size:0.8em; }\n" + ".md-img img { max-height: 100%; max-width: 100%; width:auto;}\n" + ".md-box { page-break-inside: avoid; }\n" + ".md-box-header, .md-box-header-print { font-weight: bold; font-size: 1.2em; }\n" + ".md-box, .md-box-landscape, .md-box-portrait { margin-left: 2em;  margin-bottom:0.5em; border: 1px solid #555; border-left-width: 0.5em; padding: 1em; }\n" + ".md-box-avatar { margin-bottom:0.5em; } .md-box-avatar-img { width:4em; display:inline-block; vertical-align:top;} .phone .md-box-avatar-img { width:3em; } .md-box-avatar-body { position:relative; padding:0em 0.5em 0em 0.5em; color:#000; background:#eeeeee; margin-left:1.5em; display:inline-block; width: calc(100% - 7em); } .phone .md-box-avatar-body { width: calc(100% - 6em); } .md-box-avatar-body:after { top: 1.1em; left: -1.5em; bottom: auto; border-width: 0px 1.5em 0.7em 0; border-color: transparent #eeeeee; content: ''; position: absolute; border-style: solid; display: block; width: 0; }\n" + "@media print { .md-box-screen { display:none; } }\n" + ".md-box-card { border: solid 1px black; background: inherit; margin-left:inherit; min-height:4em;}\n" + "a { color:black; }\n" + "a.md-api-entry-link, .api-kind a { text-decoration: none; }\n" + ".api-desc { color: black; font-size: 0.8em; }\n" + ".signature { font-size: 1.3em; }\n" + ".md-api-entry { color: black; border: 1px dotted #BBB; padding: 0.6em 1em 0.5em 1em; margin: 0.5em 0; }\n" + ".md-api-header { font-size: 1.4em; margin-bottom: 1em; }\n" + ".md-api-header .signature { margin-bottom: 0.4em; }\n" + ".md-api-header .sig-parameter { display:inline-block; margin-left: 4em; }\n" + ".md-para { margin-top: 1em; margin-bottom: 1em; }\n" + ".block .md-para { margin: 0; }\n" + "span.stringLiteral { word-break: break-all; } div.stringLiteral { white-space:pre-wrap; }\n" + ".picLiteral { height:1em; vertical-align: bottom;}\n" + ".md-warning { background-color:lightyellow; border-left:solid 0.25em red; padding:0.5em; margin-left:2em;}\n" + "div.md-video-link { position: relative; } div.md-video-link > img { width: calc(100 % - 1em); } div.md-video-link > svg { position: absolute;left:0em; bottom: 0em; width:25%; } @media print { div.md-video-link > svg { display:none; }  }\n" + "@media print { a.md-external-link:link:after, a.md-external-link:visited:after { content: ' (' attr(href) ') '; font-size: 80%; } }\n" + "svg.video-play { width: calc(100% - 1em); background-size:cover; background-repeat:no-repeat;}\n" + ".nopara .md-para { margin:0; }\n" + '.symbol { font-family: "TD Symbols", inherit; }\n' + ".placeholder { font-size: 0.7em; padding: 0.2em; border: 1px dotted gray; }\n" + ".md-comment, .md-comment h1, .md-comment h2, .md-comment h3, .md-comment h4 { display: inline-block; margin:0; }\n" + 'code { font-size: 1.0em; font-family: Calibri, \"Helvetica Neue\", HelveticaNeue, Helvetica, Arial, "TD Symbols", sans-serif; border: 1px dotted #bbb; padding: 0em 0.2em 0.1em 0.2em; white-space:nowrap; }\n' + "code.md-ui { border: 2px solid #777; padding-left:0.2em; padding-right:0.2em; white-space:nowrap; }\n" + ".block { margin-left: 1em; }\n" + ".stmt { border-left: 0.2em solid #aaa; margin-top: 0.2em; }\n" + ".line { margin-left: 0.4em; }\n" + ".tutorial-step { font-size: 1.7em; }\n" + ".tutorial-step .md-comment { font-size: 0.6em; }\n" + ".decl > .stmt { border: none; }\n" + ".print-big { font-size: 1.5em; }\n" + "a.md-bigbutton {}\n" + "@media print { #MicrosoftTranslatorWidget { display: none; } .body, .inner, .primary-content__inner, .md-tutorial { margin:0; padding:0; } }\n" + 'body { font-family: Calibri, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, "TD Symbols", sans-serif; }\n' + "@page { size: auto; margin: 1cm 1cm 1cm 1cm; }" + "</style>";
        CopyRenderer.styleMap = {
            '<span class=.keyword': "font-weight: bold; color: #41900D",
            '<div class=.block': "margin-left: 1em",
            '<div class=.md-snippet': "border: 1px dotted #bbb; padding: 0.5em; margin-left: 2em",
            '<div class=.md-para': "margin: 1em 0",
            '<div class=.md-img': "margin: 0.5em; text-align: center",
        };
        return CopyRenderer;
    })(Renderer);
    TDev.CopyRenderer = CopyRenderer;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    function getScriptHeartCount(j) {
        if (!j)
            return -1;
        if (j.updateid && j.updateid == j.id)
            return j.cumulativepositivereviews;
        else
            return j.positivereviews || 0;
    }
    TDev.getScriptHeartCount = getScriptHeartCount;
    function patchScriptHeartCount(j, d) {
        if (!j)
            return -1;
        if (j.updateid && j.updateid == j.id)
            j.cumulativepositivereviews = d;
        else
            j.positivereviews = d;
    }
    TDev.patchScriptHeartCount = patchScriptHeartCount;
    var oembedCache = {};
    var _socialNetworks = [
        {
            id: "art",
            name: "TouchDevelop Art",
            description: TDev.lf("Cover art ({0}/...)", TDev.Cloud.config.primaryCdnUrl),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https?:\/\/.*\/pub\/([a-z]+)/gi, function (m, id) {
                        var ytid = id;
                        links.push(id);
                    });
                return links;
            },
            idToUrl: function (id) { return TDev.Cloud.config.primaryCdnUrl + "/pub/" + id; },
            idToHTMLAsync: function (id) { return TDev.Promise.as(TDev.HTML.mkImg(TDev.Cloud.config.primaryCdnUrl + "/pub/" + id, '', TDev.lf("open"))); }
        },
        {
            id: "youtube",
            name: "YouTube",
            description: TDev.lf("YouTube video (https://youtu.be/...)"),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https?:\/\/(youtu\.be\/([^\s]+))|(www\.youtube\.com\/watch\?v=([^\s]+))/gi, function (m, m2, id1, m3, id2) {
                        var ytid = id1 || id2;
                        links.push(ytid);
                    });
                return links;
            },
            idToUrl: function (id) { return 'https://youtu.be/' + id; },
            idToHTMLAsync: function (id) { return TDev.Promise.as(TDev.HTML.mkYouTubePlayer(id)); }
        },
        {
            id: "videoptr",
            name: "TouchDevelop Video",
            description: TDev.lf("Touch Develop video (/td/videos/...)"),
            parseIds: function (text, ismeta) {
                var pref = TDev.Cloud.getServiceUrl().replace(/(test|stage|live)/, "www");
                var m = /^(https:\/\/[^\/]+)\/(\S+)/.exec(text);
                if (!ismeta && (!m || m[1] != pref))
                    return [];
                if (m)
                    text = m[2];
                text = text.replace(/^\/+/, "");
                text = text.replace(/^embed\//, "");
                text = text.replace(/[^a-z0-9-\/]/g, "-");
                return [text];
            },
            idToUrl: function (id) { return TDev.Cloud.getServiceUrl().replace(/(test|stage|live)/, "www") + "/embed/" + id; },
            idToHTMLAsync: function (id) {
                id = id.replace(/[^a-z0-9-\/]/g, "-");
                return TDev.Promise.as(TDev.HTML.mkLazyVideoPlayer(TDev.Util.fmt("{0}/{1}/thumb", TDev.Cloud.getServiceUrl(), id), TDev.Util.fmt("{0}/embed/{1}", TDev.Cloud.getServiceUrl(), id)));
            }
        },
        {
            id: "bbc",
            name: "BBC Video",
            description: TDev.lf("BBC video (https://files.microbit.co.uk/clips/...)"),
            parseIds: function (text, ismeta) {
                var m = /^(https:\/\/[^\/]+)\/(.*)/.exec(text);
                if (!ismeta && (!m || m[1] != "https://files.microbit.co.uk"))
                    return [];
                if (m)
                    text = m[2];
                text = text.replace(/^\/+/, "");
                text = text.replace(/^clips\//, "");
                text = text.replace(/[^a-z0-9-\/]/g, "-");
                return [text];
            },
            idToUrl: function (id) { return "https://files.microbit.co.uk/clips/" + id; },
            idToHTMLAsync: function (id) {
                id = id.replace(/[^a-z0-9-\/]/g, "-");
                return TDev.Promise.as(TDev.HTML.mkLazyVideoPlayer(TDev.Util.fmt("https://files.microbit.co.uk/clips/{0}/thumb", id), TDev.Util.fmt("https://files.microbit.co.uk/clips/{0}/embed", id)));
            }
        },
        {
            id: "vimeo",
            name: "Vimeo",
            description: TDev.lf("vimeo video (https://vimeo.com/...)"),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https?:\/\/vimeo\.com\/\S*?(\d{6,})/gi, function (m, id) {
                        links.push(id);
                    });
                return links;
            },
            idToUrl: function (id) { return "https://vimeo.com/" + id; },
            idToHTMLAsync: function (id) {
                return TDev.Promise.as(TDev.HTML.mkLazyVideoPlayer(TDev.Util.fmt("{0}/thumbnail/512/vimeo/{1:uri}", TDev.Cloud.getServiceUrl(), id), "https://player.vimeo.com/video/" + id));
            },
        },
        {
            id: "instagram",
            name: "Instagram",
            description: TDev.lf("Instagram photo (https://instagram.com/p/...)"),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https?:\/\/instagram\.com\/p\/([a-z0-9]+)\/?/gi, function (m, id) {
                        links.push(id);
                    });
                return links;
            },
            idToUrl: function (id) { return 'https://instagram.com/p/' + id + '/'; },
        },
        {
            id: "vine",
            name: "Vine",
            description: TDev.lf("Vine animation (https://vine.co/v/...)"),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https?:\/\/vine\.co\/v\/([a-z0-9]+)\/?/gi, function (m, id) {
                        links.push(id);
                    });
                return links;
            },
            idToUrl: function (id) { return 'https://vine.co/v/' + id; },
        },
        {
            id: "twitter",
            name: "Twitter",
            description: TDev.lf("Twitter picture or tweet (https://twitter.com/.../status/...)"),
            parseIds: function (text) {
                var links = [];
                if (text)
                    text.replace(/https:\/\/twitter\.com\/[^\/]+\/status\/[0-9]+\/?/gi, function (m) {
                        links.push(m);
                    });
                return links;
            },
            idToUrl: function (id) { return id; },
        },
    ];
    function socialNetworks(widgets) {
        if (!TDev.Cloud.hasPermission("post-script-meta"))
            return [];
        return _socialNetworks.filter(function (sn) { return !!widgets["socialNetwork" + sn.id]; });
    }
    TDev.socialNetworks = socialNetworks;
    var MdComments = (function () {
        function MdComments(renderer, libName) {
            if (renderer === void 0) { renderer = null; }
            if (libName === void 0) { libName = null; }
            this.renderer = renderer;
            this.libName = libName;
            this.print = false;
            this.showCopy = true;
            this.useSVG = true;
            this.useExternalLinks = false;
            this.blockExternalLinks = undefined;
            this.pointerHelp = true;
            this.allowLinks = true;
            this.allowImages = true;
            this.allowVideos = true;
            this.designTime = false;
            this.forWeb = false;
            this.relativeLinks = false;
            this.depthLimit = 0;
        }
        MdComments.prototype.serviceUrlOr = function (path, local) {
            if (this.useExternalLinks)
                return this.relativeLinks ? path : TDev.Cloud.getServiceUrl() + path;
            else
                return local;
        };
        MdComments.prototype.topicLink = function (id) {
            return this.serviceUrlOr(TDev.Cloud.config.topicPath, TDev.Cloud.config.topicPath) + MdComments.shrink(id);
        };
        MdComments.prototype.appLink = function (id) {
            return this.serviceUrlOr("/app/", "") + id;
        };
        MdComments.shrink = function (s) {
            return s ? s.replace(/[^A-Za-z0-9]/g, "").toLowerCase() : "";
        };
        MdComments.error = function (msg) {
            return "<span class='md-error'>" + TDev.Util.htmlEscape(msg) + " </span>";
        };
        MdComments.proxyVideos = function (v) {
            v.poster = TDev.HTML.proxyResource(v.poster);
            v.sources.forEach(function (s) {
                s.poster = TDev.HTML.proxyResource(s.poster);
                s.src = TDev.HTML.proxyResource(s.src);
            });
            v.tracks.forEach(function (t) {
                t.src = TDev.HTML.proxyResource(t.src);
            });
        };
        MdComments.attachVideoHandlers = function (e, autoPlay) {
            if (!TDev.Browser.directionAuto) {
                TDev.Util.toArray(e.getElementsByClassName('md-tutorial')).forEach(function (v) { return TDev.dirAuto(v); });
                TDev.Util.toArray(e.getElementsByClassName('md-box-avatar-body')).forEach(function (v) { return TDev.dirAuto(v); });
            }
            TDev.Util.toArray(e.getElementsByClassName('md-video-link')).forEach(function (v) {
                if (v.hasAttribute("data-playerurl"))
                    v.withClick(function () { return v.innerHTML = TDev.HTML.mkVideoIframe(v.getAttribute("data-playerurl")); });
                else if (v.hasAttribute("data-video")) {
                    var lang = TDev.Util.getTranslationLanguage();
                    var jsvideo = JSON.parse(decodeURIComponent(v.getAttribute("data-video")));
                    if (!jsvideo) {
                        v.setChildren(TDev.div('', TDev.lf(":( invalid in video information")));
                        return;
                    }
                    MdComments.proxyVideos(jsvideo);
                    var jssource = MdComments.findBestSource(jsvideo.sources);
                    if (!jssource) {
                        v.setChildren(TDev.div('', TDev.lf(":( could not find any video source")));
                        return;
                    }
                    var video = TDev.createElement("video");
                    video.crossOrigin = "anonymous";
                    video.width = 300;
                    video.height = 150;
                    video.controls = true;
                    video.autoplay = autoPlay;
                    video.preload = autoPlay ? "auto" : "none";
                    video.poster = jssource.poster || jsvideo.poster;
                    var source = TDev.createElement("source");
                    source.src = jssource.src;
                    source.type = jssource.type;
                    video.appendChild(source);
                    if (jsvideo.tracks && jsvideo.tracks.length > 0) {
                        TDev.Util.log('loading tracks');
                        if (!TDev.Browser.videoTracks) {
                            var jstrack = MdComments.findBestTrack(jsvideo.tracks);
                            TDev.Util.log('best track: ' + jstrack.label);
                            TDev.Util.httpGetTextAsync(jstrack.src).done(function (wtt) {
                                var cues = TDev.HTML.parseWtt(wtt);
                                TDev.Util.log('found {0} cues', cues.length);
                                if (cues.length > 0) {
                                    if (video.addTextTrack) {
                                        var track = video.addTextTrack(jstrack.kind || "subtitles", jstrack.label || jstrack.srclang, jstrack.srclang);
                                        cues.forEach(function (cue) { return track.addCue(TextTrackCue(cue.startTime, cue.endTime, cue.message)); });
                                        track.mode = track.SHOWING;
                                    }
                                    else {
                                        var caption = document.createElement('span');
                                        caption.className = 'videoCaption';
                                        var lastCue = undefined;
                                        video.ontimeupdate = function (ev) {
                                            var t = video.currentTime;
                                            if (lastCue && lastCue.startTime <= t && t <= lastCue.endTime)
                                                return;
                                            lastCue = undefined;
                                            var i = 0;
                                            while (i < cues.length) {
                                                if (cues[i].startTime <= t && t <= cues[i].endTime) {
                                                    lastCue = cues[i];
                                                    break;
                                                }
                                                if (cues[i].endTime > t)
                                                    break;
                                                i++;
                                            }
                                            if (lastCue) {
                                                caption.innerText = lastCue.message;
                                                caption.style.opacity = "1.0";
                                            }
                                            else {
                                                caption.style.opacity = "0.0";
                                            }
                                        };
                                        v.classList.add('videoOuter');
                                        v.setChildren([video, caption]);
                                    }
                                }
                            }, function (e) {
                                TDev.Util.log('wtt: failed to load caption: ' + (e.message || ""));
                            });
                        }
                        else {
                            video.appendChildren(jsvideo.tracks.map(function (jstrack, i) {
                                var track = TDev.createElement("track");
                                if (i == 0)
                                    track.default = true;
                                track.src = jstrack.src;
                                track.kind = jstrack.kind || "subtitles";
                                if (jstrack.srclang)
                                    track.srclang = jstrack.srclang;
                                track.label = jstrack.label || jstrack.srclang;
                                return track;
                            }));
                        }
                    }
                    v.setChildren(video);
                }
                else if (v.hasAttribute("data-videosrc")) {
                    var vtid = v.getAttribute("data-videosrc");
                    var pid = v.getAttribute("data-videoposter");
                    if (autoPlay) {
                        var video = TDev.createElement("video");
                        video.crossOrigin = "anonymous";
                        video.width = 300;
                        video.height = 150;
                        video.controls = true;
                        video.autoplay = true;
                        video.src = decodeURI(vtid);
                        video.poster = decodeURI(pid);
                        v.setChildren(video);
                    }
                    else {
                        v.withClick(function () {
                            var video = TDev.createElement("video");
                            video.crossOrigin = "anonymous";
                            video.width = 300;
                            video.height = 150;
                            video.controls = true;
                            video.autoplay = true;
                            video.src = decodeURI(vtid);
                            video.poster = decodeURI(pid);
                            v.setChildren(video);
                            v.withClick(function () {
                            });
                        });
                    }
                }
            });
        };
        MdComments.findBestSource = function (sources) {
            if (!sources)
                return undefined;
            var lang = TDev.Util.getTranslationLanguage() || "en";
            var video = sources.filter(function (t) { return t.srclang == lang; })[0];
            if (video)
                return video;
            lang = lang.substr(0, 2);
            video = sources.filter(function (t) { return t.srclang == lang; })[0];
            if (video)
                return video;
            return sources[0];
        };
        MdComments.findBestTrack = function (tracks) {
            if (!tracks)
                return undefined;
            var lang = TDev.Util.getTranslationLanguage() || "en";
            var track = tracks.filter(function (t) { return t.srclang == lang; })[0];
            if (track)
                return track;
            lang = lang.substr(0, 2);
            track = tracks.filter(function (t) { return t.srclang == lang; })[0];
            if (track)
                return track;
            return tracks[0];
        };
        MdComments.prototype.sig = function (arg, full) {
            if (full === void 0) { full = false; }
            var t = HelpTopic.findById(arg);
            if (t && t.isPropertyHelp()) {
                return t.getSig(this, full);
            }
            var m = arg.split(/->/);
            var property = undefined;
            if (m) {
                var kindName = m[0];
                var propertyName = m[1];
                if (kindName && propertyName) {
                    if (TDev.Script) {
                        var lib = TDev.Script.librariesAndThis().filter(function (lib) { return lib.getName() == kindName; })[0];
                        if (lib) {
                            var action = lib.getPublicActions().filter(function (action) { return action.getName() == propertyName; })[0];
                            if (action) {
                                var r = "<div class=notranslate translate=no dir=ltr style='display:inline-block'><div class='md-snippet'>";
                                r += this.renderer.renderPropertySig(action, false, true, false);
                                r += "</div></div>";
                                return r;
                            }
                        }
                    }
                }
            }
            return TDev.lf("could not find decl '{0}'", m);
        };
        MdComments.prototype.apiList = function (arg) {
            var _this = this;
            var prefix = "";
            var m = /^([^:]*):(.*)/.exec(arg);
            if (m) {
                prefix = m[1];
                arg = m[2];
            }
            var res = "";
            arg.split(/,/).forEach(function (t) {
                if (/^\s*$/.test(t))
                    return;
                var id = prefix + "_" + t;
                var topic = HelpTopic.findById(id);
                if (!topic)
                    res += MdComments.error("no such topic: " + id);
                else if (topic.isPropertyHelp())
                    res += topic.renderLink(_this, true);
                else {
                    var st = topic.getSubTopics();
                    if (st.length > 0) {
                        res += st.map(function (t) { return t.renderLink(_this, true); }).join("");
                    }
                    else {
                        res += MdComments.error(id + " is neither property nor type");
                    }
                }
            });
            return res;
        };
        MdComments.findArtStringResource = function (app, id) {
            var artVar = app ? app.resources().filter(function (r) { return MdComments.shrink(r.getName()) == MdComments.shrink(id); })[0] : null;
            if (artVar && artVar.url) {
                return TDev.RT.String_.valueFromArtUrl(artVar.url);
            }
            return undefined;
        };
        MdComments.findArtId = function (id) {
            var artVar = TDev.Script ? TDev.Script.resources().filter(function (r) { return MdComments.shrink(r.getName()) == MdComments.shrink(id); })[0] : null;
            TDev.Cloud.config.altCdnUrls.forEach(function (artHost) {
                var artPref = artHost + "/pub/";
                if (artVar && artVar.url && artVar.url.slice(0, artPref.length) == artPref) {
                    var newId = artVar.url.slice(artPref.length);
                    if (/^\w+$/.test(newId))
                        id = newId;
                }
            });
            return id;
        };
        MdComments.prototype.defaultRepl = function (macro, arg) {
            if (macro == "var") {
                switch (arg) {
                    case "userid": return this.userid || TDev.Cloud.getUserId();
                    case "apihelp":
                        return MdComments.error("var:apihelp no longer supported");
                    default: return MdComments.error("unknown variable " + arg);
                }
            }
            else if (macro == "pic") {
                var m = /^((https:\/\/[^:]+)|([\w ]+))(:(\d+)x(\d+))?(:.*)?/i.exec(arg);
                if (m) {
                    var url = m[2];
                    var artId = m[3];
                    var width = parseFloat(m[5] || "12");
                    var height = parseFloat(m[6] || "12");
                    if (width > 40) {
                        height = 40 / width * height;
                        width = 40;
                    }
                    if (height > 40) {
                        width = 40 / height * width;
                        height = 40;
                    }
                    var caption = m[7];
                    if (caption)
                        caption = caption.slice(1);
                    else
                        caption = "";
                    if (artId && !url) {
                        artId = MdComments.findArtId(artId);
                        url = TDev.Cloud.artUrl(artId);
                    }
                    else if (!TDev.Cloud.isArtUrl(url)) {
                        url = "no-such-image";
                    }
                    url = TDev.Cloud.toCdnUrl(url);
                    url = TDev.HTML.proxyResource(url);
                    var r = "<div class='md-img'><div class='md-img-inner'>";
                    r += TDev.Util.fmt("<img src=\"{0:q}\" alt='{1:q}'", url, caption);
                    if (m[6] || (!this.forWeb && !this.print))
                        r += TDev.Util.fmt(" style='height:{0}em'", height);
                    r += "/></div>";
                    r += "</div>";
                    return r;
                }
                else {
                    m = /^(:(\d+)x(\d+))?(:.*)?/.exec(arg);
                    if (!m)
                        return MdComments.error(TDev.lf("invalid picture id"));
                }
            }
            else if (macro == "pici") {
                var args = arg.split(/:/);
                var artId = MdComments.findArtId(args[0]);
                var width = args[1] ? parseFloat(args[1]) : 0;
                if (!width)
                    width = 2;
                var r = TDev.Util.fmt("<img class='md-img-inline' src='{0}' style='width:{1}em' alt='picture' />", TDev.Cloud.artUrl(artId), width);
                return r;
            }
            else if (macro == "snippet") {
                var args = arg.split(/:/);
                if (args.length != 3)
                    return MdComments.error(TDev.lf("invalid snippet"));
                var editor = args[0];
                var renderer = TDev.Cloud.config.scriptRenderers[editor];
                if (!renderer)
                    return MdComments.error(TDev.lf("unknown editor"));
                var scriptid = args[1];
                var h = parseFloat(args[2]) || 1;
                var r = TDev.Util.fmt('<div class="md-iframe-wrapper" style="height:{1}em;"><iframe src="{0}"  frameborder="0" sandbox="allow-scripts allow-same-origin" scrollbars="no" style="height:{1}em;"></iframe></div>', renderer(scriptid), h);
                return r;
            }
            else if (macro == "hex") {
                var args = arg.split(':');
                if (args.length != 2)
                    return MdComments.error(TDev.lf("missing script title: {hex:id:title}"));
                return TDev.Util.fmt("<a href=\"{0:q}\" target=\"_blank\">{1:q}</a>", "/api/" + MdComments.shrink(args[0]) + "/hex?applyupdates=true", args[1]);
            }
            else if (macro == "decl" || macro == "decl*") {
                var decl = !TDev.Script ? null : !arg ? TDev.Script : TDev.Script.things.filter(function (t) { return t.getName() == arg; })[0];
                if (this.currComment && this.currComment.mdDecl)
                    decl = this.currComment.mdDecl;
                if (!decl)
                    return MdComments.error(TDev.lf("no such decl {0}", arg));
                return this.mkDeclSnippet(decl, macro == "decl*");
            }
            else if (macro == "imports") {
                if (!TDev.Script)
                    return MdComments.error(TDev.lf("import can only be used from a script context"));
                var r = "";
                [
                    { name: 'npm', url: 'https://www.npmjs.com/package/{0:q}', pkgs: TDev.Script.imports.npmModules },
                    { name: 'cordova', url: 'http://plugins.cordova.io/#/package/{0:q}/', pkgs: TDev.Script.imports.cordovaPlugins },
                    { name: 'bower', url: 'https://www.npmjs.com/package/{0:q}/', pkgs: TDev.Script.imports.bowerModules },
                    { name: 'client', url: '{0}', pkgs: TDev.Script.imports.clientScripts },
                    { name: 'pip', url: 'https://pypi.python.org/pypi/{0:q}/', pkgs: TDev.Script.imports.pipPackages },
                    { name: 'touchdevelop', url: '#pub:{0:q}', pkgs: TDev.Script.imports.touchDevelopPlugins }
                ].forEach(function (imports) {
                    var keys = Object.keys(imports.pkgs);
                    if (keys.length > 0) {
                        keys.forEach(function (key) {
                            var url = TDev.Util.fmt(imports.url, key);
                            var ver = imports.pkgs[key];
                            r += TDev.Util.fmt("<li>{3}: <a target='blank' href='{1}'>{0:q}{2}</a></li>\n", key, url, ver ? " " + ver : "", imports.name);
                        });
                    }
                });
                if (!r)
                    return this.designTime ? "{imports}" : "";
                else
                    return "<h3>" + TDev.lf("imports") + "</h3><ul>" + r + "</ul>";
            }
            else if (macro == "stlaunch") {
                if (!this.scriptid)
                    return "";
                return "<h2>" + TDev.lf("follow tutorial online") + "</h2><div class='md-box-print print-big'>" + TDev.lf("Follow this tutorial online at <b>{1}/{0:q}</b>", this.scriptid, TDev.Cloud.config.shareUrl) + ".</div>";
            }
            else if (macro == "stcmd") {
                var mrun = /^run(:(.*))?/.exec(arg);
                if (mrun)
                    return TDev.Util.fmt("<b>Run your program: {0:q}</b>", mrun[2] || "");
                var mcomp = /^compile(:(.*))?/.exec(arg);
                if (mcomp)
                    return TDev.Util.fmt("<b>Compile your program: {0:q}</b>", mcomp[2] || "");
                return TDev.Util.fmt("<b>tutorial command: {0:q}</b>", arg);
            }
            else if (macro == "adddecl") {
                return this.designTime ? TDev.Util.fmt("<b>Add the declaration:</b>") : "";
            }
            else if (macro == "stcode") {
                return "<b>(code of the step)</b>";
            }
            else if (macro == "internalstepid") {
                return TDev.Util.fmt("<h1 class='stepid'>{0:q}</h1>", arg);
            }
            else if (macro == "follow") {
                return TDev.Util.fmt("<!-- FOLLOW --><a href=\"{0:q}\">{1:q}</a>", this.appLink("#hub:follow-tile:" + MdComments.shrink(arg)), arg);
            }
            else if (macro == "topictile") {
                return TDev.Util.fmt("<!-- FOLLOW --><a href=\"{0:q}\">{1:q}</a>", this.appLink("#topic-tile:" + MdComments.shrink(arg)), arg);
            }
            else if (macro == "pub") {
                var args = arg.split(':');
                if (args.length != 2)
                    return MdComments.error(TDev.lf("missing publication title: {pub:id:title}"));
                return TDev.Util.fmt("<!-- FOLLOW --><a href=\"{0:q}\">{1:q}</a>", this.appLink("#pub:" + MdComments.shrink(args[0])), args[1]);
            }
            else if (macro == "section") {
                var mm = /^([^:;]+)[;:](.*)/.exec(arg);
                var sectName = mm ? mm[1] : arg;
                var output = TDev.Util.fmt("--------------------------- <b>{0:q}</b> ---------------------------", sectName);
                if (mm) {
                    mm[2].split(';').forEach(function (a) {
                        output += TDev.Util.fmt("<div class='md-section'>;; {0:q}</div>", a);
                    });
                }
                return output;
            }
            else if (macro == "hide" || macro == "priority" || macro == "template" || macro == "highlight" || macro == 'box' || macro == "code" || macro == "widgets" || macro == "templatename" || macro == "hints" || macro == "pichints" || macro == "enum" || macro == "language" || macro == "weight" || macro == "namespace" || macro == "parenttopic" || macro == "docflags" || macro == "stprecise" || macro == "flags" || macro == "action" || macro == "topic" || macro == "breadcrumbtitle" || macro == "stvalidator" || macro == "stnoprofile" || macro == "stauto" || macro == "sthints" || macro == "stcode" || macro == "storder" || macro == "stdelete" || macro == "stcheckpoint" || macro == "sthashtags" || macro == "stnocheers" || macro == "steditormode" || macro == "stnexttutorials" || macro == "stmoretutorials" || macro == "translations" || macro == "stpixeltracking" || macro == "steventhubstracking" || macro == "icon" || macro == "help") {
                if (this.designTime)
                    return "{" + macro + (arg ? ":" + TDev.Util.htmlEscape(arg) : "") + "}";
                else
                    return "";
            }
            else if (macro == "api") {
                return this.apiList(arg);
            }
            else if (macro == "sig") {
                return this.sig(arg);
            }
            else if (macro == "fullsig") {
                return this.sig(arg, true);
            }
            else if (macro == "youtube") {
                if (!this.allowVideos)
                    return "";
                if (this.blockExternal())
                    return this.blockLink("");
                if (!arg)
                    return MdComments.error("youtube: missing video id");
                else {
                    return TDev.Util.fmt("<div class='md-video-link' data-playerurl='{0:q}'>{1}</div>", TDev.Util.fmt("//www.youtube-nocookie.com/embed/{0:uri}?modestbranding=1&autoplay=1&autohide=1", arg), TDev.SVG.getVideoPlay(TDev.Util.fmt('https://img.youtube.com/vi/{0:q}/hqdefault.jpg', arg)));
                }
            }
            else if (macro == "videoptr") {
                if (!this.allowVideos)
                    return "";
                if (this.blockExternal())
                    return this.blockLink("");
                if (!arg)
                    return MdComments.error("videoptr: missing video id");
                else {
                    var prefix = this.relativeLinks ? "" : TDev.Cloud.getServiceUrl();
                    var args = arg.split(/:/);
                    if (!/^[a-z0-9\-\/@]+$/.test(args[0]))
                        return MdComments.error("videoptr: invalid pointer path");
                    var id = args[0].replace(/^\/+/, "");
                    var url = TDev.Util.fmt("{0}/{1}/sd", prefix, id);
                    var playerUrl = TDev.Util.fmt("{0}/embed/{1}", prefix, id);
                    var posterUrl = TDev.Util.fmt("{0}/{1}/thumb", prefix, id);
                    if (TDev.Cloud.config.anonToken) {
                        var suff = "?anon_token=" + encodeURIComponent(TDev.Cloud.config.anonToken);
                        url += suff;
                        posterUrl += suff;
                    }
                    var alt = args.slice(1).join(":") || "";
                    return TDev.Util.fmt("<div class='md-video-link' data-videoposter='{0:url}' data-playerurl='{1:url}' data-alt='{3:q}'>{2}</div>", posterUrl, playerUrl, TDev.SVG.getVideoPlay(posterUrl, alt), alt);
                }
            }
            else if (macro == "bbc") {
                if (!this.allowVideos)
                    return "";
                if (this.blockExternal())
                    return this.blockLink("");
                var args = arg.split(/:/);
                var id = args[0];
                var caption = args.slice(1).join(":");
                if (!id)
                    return MdComments.error("bbc: missing video id");
                else {
                    return TDev.Util.fmt("<div class='md-video-link' data-playerurl='{0:q}' data-alt='{2:q}'>{1}</div>", TDev.Util.fmt("https://files.microbit.co.uk/clips/{0:uri}/embed", id), TDev.SVG.getVideoPlay(TDev.Util.fmt('https://files.microbit.co.uk/clips/{0:uri}/thumb', id), caption), caption);
                }
            }
            else if (macro == "vimeo") {
                if (!this.allowVideos)
                    return "";
                if (TDev.Cloud.isRestricted())
                    return MdComments.error("vimeo not allowed");
                if (!arg)
                    return MdComments.error("vimeo: missing video id");
                if (this.blockExternal())
                    return this.blockLink("");
                var args = arg.split(/:/);
                if (!/^\d+$/.test(args[0]))
                    return MdComments.error("vimeo: video id should be a number");
                else {
                    var prefix = this.relativeLinks ? "" : TDev.Cloud.getServiceUrl();
                    var url = TDev.Util.fmt("{0}/vimeo/{1:uri}/sd", prefix, args[0]);
                    var posterUrl = TDev.Util.fmt("{0}/vimeo/{1:uri}/thumb512", prefix, args[0]);
                    return TDev.Util.fmt("<div class='md-video-link' data-videoposter='{0:url}' data-videosrc='{1:url}'>{2}</div>", posterUrl, url, TDev.SVG.getVideoPlay(posterUrl));
                }
            }
            else if (macro == "channel9") {
                if (!this.allowVideos)
                    return "";
                if (this.blockExternal())
                    return this.blockLink("");
                if (!arg)
                    return MdComments.error("channel9: missing MP4 url");
                var video = arg.replace(/^http:\/\/video/, 'https://sec');
                var poster = video.replace(/\.mp4$/, '_512.jpg');
                return TDev.Util.fmt("<div class='md-video-link' data-videoposter='{0:url}' data-videosrc='{1:url}'>{2}</div>", poster, video, TDev.SVG.getVideoPlay(poster));
            }
            else if (macro == "video") {
                if (!this.allowVideos)
                    return "";
                if (this.blockExternal())
                    return this.blockLink("");
                if (!arg)
                    return MdComments.error("video: missing video preview and url");
                var res = MdComments.findArtStringResource(TDev.Script, arg);
                if (res)
                    return MdComments.expandJsonVideo(res);
                var urls = arg.split(',');
                if (urls.length != 2)
                    return MdComments.error("video: must have <preview url>,<mp4 url> arguments");
                else {
                    return TDev.Util.fmt("<div class='md-video-link' data-videoposter='{0:url}' data-videosrc='{1:url}'>{2}</div>", urls[0], urls[1], TDev.SVG.getVideoPlay(urls[0]));
                }
            }
            else if (macro == "cap") {
                if (!arg)
                    return MdComments.error("cap: requires a comma separated list of required capabilities");
                var required = TDev.AST.App.fromCapabilityList(arg.split(/,/));
                var current = TDev.PlatformCapabilityManager.current();
                var missing = required & ~current;
                if (!missing)
                    return "";
                else
                    return "<div class='md-tutorial md-warning'>" + "<strong>" + TDev.lf("This code might not work on your current device") + "</strong>: " + TDev.lf("missing {0} capabilities.", TDev.AST.App.capabilityName(missing)) + "</div>";
            }
            else if (macro == "webonly") {
                if (this.designTime)
                    return MdComments.error("{webonly} macro doesn't do anything anymore");
                else
                    return "";
            }
            else if (macro == "bigbutton") {
                if (!arg)
                    return MdComments.error("bigbutton: requires <text>,<url> arguments");
                var ms = arg.split(',');
                if (ms.length != 2)
                    return MdComments.error(TDev.lf("bigbutton: must have <text>,<url> arguments"));
                return this.blockLink(ms[1]) || TDev.Util.fmt("<a class='md-bigbutton' target='_blank'  rel='nofollow' href='{0:url}'>{1:q}</a>", ms[1], ms[0]);
            }
            else if (macro == "shim" || macro == "asm") {
                if (this.designTime || macro == "asm")
                    return "{" + macro + ":" + TDev.Util.htmlEscape(arg) + "}";
                if (!arg)
                    return "";
                else
                    return TDev.Util.fmt("<b>{0:q}</b> <span class='font-family: monospace'>{1:q}</span>", TDev.lf("compiles to C++ function:"), arg);
            }
            else {
                return null;
            }
        };
        MdComments.expandJsonVideo = function (res) {
            var video;
            try {
                video = JSON.parse(res);
            }
            catch (e) {
            }
            if (!video)
                return MdComments.error("video: missing data");
            var source = MdComments.findBestSource(video.sources);
            if (!source)
                return MdComments.error('videoset: missing sources');
            var poster = source.poster || video.poster;
            if (!poster)
                return MdComments.error('video: missing poster');
            return TDev.Util.fmt("<div class='md-video-link' data-video='{0:uri}'>{1}</div>", JSON.stringify(video), TDev.SVG.getVideoPlay(poster));
        };
        MdComments.prototype.blockExternal = function () {
            if (this.blockExternalLinks === undefined)
                this.blockExternalLinks = !!(TDev.Cloud.isRestricted() && !TDev.Cloud.hasPermission("external-links"));
            return this.blockExternalLinks;
        };
        MdComments.prototype.blockLink = function (href) {
            if (!this.blockExternal())
                return null;
            return MdComments.error(TDev.lf("sorry, external link not allowed"));
        };
        MdComments.prototype.expandInline = function (s, allowStyle, allowRepl) {
            var _this = this;
            if (allowStyle === void 0) { allowStyle = false; }
            if (allowRepl === void 0) { allowRepl = true; }
            var inp = s;
            var outp = "";
            var applySpan = function (rx, repl) {
                var m = rx.exec(inp);
                if (m) {
                    inp = inp.slice(m[0].length);
                    outp += repl(m);
                    return true;
                }
                return false;
            };
            var replace = function (tag) {
                return function (m) { return "<" + tag + ">" + _this.expandInline(m[1]) + "</" + tag + ">"; };
            };
            var getReplCode = function (m) {
                var s = m[2];
                if (m[1].length == 1) {
                    s = s.replace(/->/g, "\u2192");
                    s = s.replace(/(^|\s)(\w+)\u2192/, function (m, pr, w) {
                        switch (w) {
                            case "code": return pr + TDev.AST.codeSymbol;
                            case "data": return pr + TDev.AST.dataSymbol;
                            case "art": return pr + TDev.AST.artSymbol;
                            case "libs": return pr + TDev.AST.libSymbol;
                            case "records": return pr + TDev.AST.recordSymbol;
                            default: return m;
                        }
                    });
                }
                var inner = _this.expandInline(s, false, false);
                inner = inner.replace(/[\u25b7\u25f3\u273f\u267B\u2339]/, '<span class="symbol">$&</span>');
                return inner;
            };
            var replCode = function (m) {
                var inner = getReplCode(m);
                if (_this.allowLinks && m[1].length == 1)
                    inner = inner.replace(/(^|[\s\(,])([\u2192\w ]+)($|[\s\(,])/g, function (all, before, topic, after) {
                        if (HelpTopic.findById(topic))
                            return before + "<a class='md-code-link' href='" + _this.topicLink(topic) + "'>" + topic + "</a>" + after;
                        else
                            return all;
                    });
                return "<code class=notranslate translate=no dir=ltr>" + inner + "</code>";
            };
            var replUI = function (m) {
                var inner = getReplCode(m);
                return "<code class='md-ui' translate=no dir=ltr>" + inner + "</code>";
            };
            var quote = TDev.Util.htmlEscape;
            while (inp) {
                if (allowRepl && applySpan(/^\{([\w\*]+)(:([^{}]*))?\}/, function (m) {
                    if (!_this.allowImages)
                        return "";
                    var res = _this.defaultRepl(m[1].toLowerCase(), m[3]);
                    if (res == null)
                        return MdComments.error("unknown macro '" + m[1] + "'");
                    else
                        return res;
                }))
                    continue;
                if (applySpan(/^\&(\w+|#\d+);/, function (m) { return m[0]; }) || (allowStyle && applySpan(/^<br\s*\/>/, function (m) { return "<br/>"; })) || applySpan(/^([<>&])/, function (m) { return TDev.Util.htmlEscape(m[1]); }) || applySpan(/^\t/, function (m) { return MdComments.error("<tab>"); }) || false)
                    continue;
                if (allowStyle && (applySpan(/^(``)(.+?)``/, replCode) || applySpan(/^(``)\[(.+?)\]``/, replUI) || applySpan(/^(`)\[(.+?)\]`/, replUI) || applySpan(/^(`)([^\n`]+)`/, replCode) || applySpan(/^\*\*(.+?)\*\*/, replace("strong")) || applySpan(/^\*([^\n\*]+)\*/, replace("em")) || applySpan(/^__(.+?)__/, replace("strong")) || applySpan(/^_([^\n_]+)_/, replace("em")) || (this.allowLinks && applySpan(/^(http|https|ftp):\/\/[^\s]*/gi, function (m) {
                    var msg = _this.blockLink(str);
                    if (msg)
                        return msg;
                    var str = m[0];
                    var suff = "";
                    var mm = /(.*?)([,\.;:\)]+)$/.exec(str);
                    if (mm) {
                        str = mm[1];
                        suff = mm[2];
                    }
                    str = _this.expandInline(str);
                    str = str.replace(/"/g, "&quot;");
                    return "<a href=\"" + quote(str) + "\" target='_blank' rel='nofollow'>" + str + "</a>" + suff;
                })) || false))
                    continue;
                var tdev = this.serviceUrlOr("/", "");
                if (allowRepl && (applySpan(/^\{\#(\w+)\}/g, function (m) { return "<a name='" + quote(m[1]) + "'></a>"; }) || applySpan(/^\[([^\[\]]*)\]\s*\(([^ \(\)\s]+)\)/, function (m) {
                    var name = m[1];
                    var href = m[2];
                    var acls = '';
                    var additions = "";
                    if (!name) {
                        name = href.replace(/^\//, "");
                        if (_this.pointerHelp)
                            name = name.replace(/^[\w\/]+\//, "");
                    }
                    if (_this.pointerHelp && /^\/[\w\-\/]+(#\w+)?$/.test(href))
                        href = href;
                    else if (/^\/\w+(->\w+)?(#\w+)?$/.test(href))
                        href = _this.topicLink(href.slice(1));
                    else if (/^\/script:\w+$/.test(href)) {
                        acls = 'md-link';
                        href = (_this.useExternalLinks ? tdev + href.slice(8) : "#" + href.slice(1));
                    }
                    else if (/^#[\w\-]+:[\w,\-:]*$/.test(href))
                        href = (_this.useExternalLinks ? tdev + "/app/#" : "#") + href.slice(1);
                    else if (/^#[\w\-]+$/.test(href))
                        href = (_this.useExternalLinks ? "#" : "#goto:") + href.slice(1);
                    else if (/^(http|https|ftp):\/\//.test(href) || /^mailto:/.test(href)) {
                        var msg = _this.blockLink(href);
                        if (msg)
                            return msg;
                        href = href;
                        acls = "md-link md-external-link";
                        additions = " rel=\"nofollow\" target=\"_blank\"";
                        if (!_this.useExternalLinks && _this.allowLinks)
                            name += " \u2197";
                    }
                    else
                        return MdComments.error("invalid link '" + href + "'");
                    if (_this.allowLinks)
                        return "<a class=\"" + acls + "\" href=\"" + quote(href) + "\"" + additions + ">" + _this.expandInline(name) + "</a>";
                    else
                        return _this.expandInline(name);
                }) || false))
                    continue;
                if (applySpan(/^(\s+)/, function (m) { return m[0]; }) || applySpan(/^(\w+\s*|.)/, function (m) { return m[0]; }))
                    continue;
            }
            return outp;
        };
        MdComments.prototype.formatInline = function (s) {
            var prev = this.allowLinks;
            var prevI = this.allowImages;
            var prevV = this.allowVideos;
            this.allowLinks = false;
            this.allowImages = false;
            this.allowVideos = false;
            try {
                return this.expandInline(s, true, true);
            }
            finally {
                this.allowLinks = prev;
                this.allowImages = prevI;
                this.allowVideos = prevV;
            }
        };
        MdComments.prototype.formatTextNoLinks = function (s) {
            var prev = this.allowLinks;
            this.allowLinks = false;
            try {
                return this.formatText(s);
            }
            finally {
                this.allowLinks = prev;
            }
        };
        MdComments.prototype.formatText = function (s, comment) {
            if (comment === void 0) { comment = null; }
            if (!s)
                return s;
            this.init();
            var start = "";
            var final = "";
            var wrap = function (tag, end) {
                if (end === void 0) { end = ""; }
                if (!end)
                    end = "/" + tag;
                return function (m, s) {
                    if (start != "")
                        return m;
                    start = "<" + tag + ">";
                    final = "<" + end + ">";
                    return s;
                };
            };
            if (/^    /.test(s))
                return "<pre>" + TDev.Util.htmlEscape(s.slice(4)) + "</pre>";
            if (/^-{5,}\s*$/.test(s))
                return this.designTime ? s : "<hr/>";
            if (/^\*{5,}\s*$/.test(s))
                return this.designTime ? s : "<div style='page-break-after:always'></div>";
            s = s.replace(/^#\s+(.*)/, wrap("h1"));
            s = s.replace(/^##\s+(.*)/, wrap("h2"));
            s = s.replace(/^###\s+(.*)/, wrap("h3"));
            s = s.replace(/^####\s+(.*)/, wrap("h4"));
            s = s.replace(/^>\s+(.*)/, wrap("blockquote"));
            s = s.replace(/^[-+*]\s+(.*)/, wrap("ul><li", "/li></ul"));
            s = s.replace(/^\d+\.\s+(.*)/, wrap("ol><li", "/li></ol"));
            wrap("div class='md-para'", "/div")("", "");
            var prevComment = this.currComment;
            try {
                this.currComment = comment;
                return start + this.expandInline(s, true, true) + final;
            }
            finally {
                this.currComment = prevComment;
            }
        };
        MdComments.prototype.mkCopyButton = function (tp, dt) {
            var r = TDev.Util.fmt("<button class='{0} copy-button' data-type='{1:q}' data-data='{2:q}'>", this.useSVG ? "code-button" : "wall-button", tp, dt);
            if (!this.useSVG)
                r += "copy";
            else
                r += TDev.Util.fmt('<div class="code-button-frame">{0}</div>', TDev.SVG.getIconSVGCore("copy,currentColor"));
            r += "</button>";
            return r;
        };
        MdComments.prototype.mkDeclSnippet = function (decl, skipComments, formatComments, cls, addDepth) {
            if (skipComments === void 0) { skipComments = false; }
            if (formatComments === void 0) { formatComments = false; }
            if (cls === void 0) { cls = 'md-snippet'; }
            if (addDepth === void 0) { addDepth = 0; }
            if (this.depthLimit < 0 || !this.renderer)
                return "<div class='md-message'>[" + TDev.Util.htmlEscape(decl.getName()) + " goes here]</div>";
            var r = "<div class=notranslate translate=no dir=ltr><div class='" + cls + "'>";
            var prev = this.renderer.formatComments;
            var prevSc = this.renderer.skipComments;
            var prevMd = this.renderer.mdComments;
            try {
                this.depthLimit += addDepth - 1;
                this.renderer.mdComments = this;
                this.renderer.formatComments = formatComments;
                this.renderer.skipComments = skipComments;
                r += this.renderer.renderDecl(decl);
            }
            finally {
                this.depthLimit -= addDepth - 1;
                this.renderer.formatComments = prev;
                this.renderer.skipComments = prevSc;
                this.renderer.mdComments = prevMd;
            }
            if (this.showCopy && !formatComments)
                r += this.mkCopyButton("decls", decl.serialize());
            r += "</div></div>";
            return r;
        };
        MdComments.prototype.mkSnippet = function (stmts) {
            if (!this.renderer)
                return "<div class='md-message'>[inline snippet goes here]</div>";
            var r = "<div class=notranslate translate=no dir=ltr><div class='md-snippet'>";
            r += this.renderer.renderSnippet(stmts);
            if (this.showCopy) {
                var block = new TDev.AST.Block();
                block.stmts = stmts;
                var d = block.serialize();
                if (this.libName)
                    d = d.replace(/code\u2192/g, '@\\u267b ->' + TDev.AST.Lexer.quoteId(this.libName) + '->');
                r += this.mkCopyButton("block", d);
            }
            r += "</div></div>";
            return r;
        };
        MdComments.prototype.init = function () {
            if (!this.renderer)
                return;
            if (this.libName) {
                this.renderer.codeReplacement = '<span class="id symbol">' + TDev.AST.libSymbol + '</span>\u200A' + this.libName + '\u200A';
                if (this.showCopy)
                    this.renderer.codeReplacement += '\u2192\u00A0';
            }
            else {
                this.renderer.codeReplacement = null;
            }
        };
        MdComments.prototype.extract = function (a) {
            return this.extractStmts(a.body.stmts);
        };
        MdComments.prototype.extractStmts = function (stmts) {
            this.init();
            var output = "";
            var currBox = null;
            for (var i = 0; i < stmts.length;) {
                var cmt = stmts[i].docText();
                if (cmt != null) {
                    var m = /^\s*\{hide(:[^{}]*)?\}\s*$/.exec(cmt);
                    if (m) {
                        if (m[1])
                            output += this.formatText(m[1]);
                        var j = i + 1;
                        while (j < stmts.length) {
                            if (/^\s*\{\/hide\}\s*$/.test(stmts[j].docText())) {
                                j++;
                                break;
                            }
                            j++;
                        }
                        i = j;
                    }
                    else if (i == 0 && cmt == '{var:apihelp}') {
                        i++;
                    }
                    else if ((m = /^```` bitmatrix((.|\n)*)````$/.exec(cmt)) != null) {
                        var bits = m[1];
                        output += "<div class='md-para'>" + this.renderer.renderBitmatrix(bits, { cls: 'docs', height: 7 }) + "</div>";
                        i++;
                    }
                    else if ((m = /^\s*(\{code\}|````)\s*$/.exec(cmt)) != null) {
                        var j = i + 1;
                        var seenStmt = false;
                        while (j < stmts.length) {
                            if (/^\s*(\{\/code\}|````)\s*$/.test(stmts[j].docText()))
                                break;
                            j++;
                        }
                        output += this.mkSnippet(stmts.slice(i + 1, j));
                        i = j + 1;
                    }
                    else if ((m = /^\s*\{section:(.*)\}\s*$/.exec(cmt)) != null) {
                        var mm = /^([^:;]+)[;:](.*)/.exec(m[1]);
                        var sectName = mm ? mm[1] : m[1];
                        output += TDev.Util.fmt("<hr class='md-section' data-name='{0:uri}' data-arguments='{1:uri}' />", sectName, mm ? mm[2] : "");
                        i++;
                    }
                    else if ((m = /^\s*\{box:([^{}]*)\}\s*$/.exec(cmt)) != null) {
                        if (currBox)
                            output += "</div>";
                        var parts = m[1].split(':');
                        var boxClass = parts[0];
                        var boxDir = "";
                        var boxHd = "";
                        var boxFt = "";
                        var boxCss = "md-box";
                        switch (boxClass) {
                            case "card":
                                boxHd = "<h3 class='md-box-header'>" + this.expandInline(parts.slice(1).join(':'), true, false) + "</h3>";
                                break;
                            case "hint":
                                boxHd = "<div class='md-box-header'>" + TDev.lf("hint") + "</div>";
                                break;
                            case "exercise":
                                boxHd = "<div class='md-box-header'>" + TDev.lf("exercise") + "</div>";
                                break;
                            case "example":
                                boxHd = "<div class='md-box-header'>" + TDev.lf("example") + "</div>";
                                break;
                            case "nointernet":
                                boxHd = "<div class='md-box-header'>" + TDev.lf("no internet?") + "</div>";
                                break;
                            case "portrait":
                                boxHd = "<div class='md-box-header-print'>" + TDev.lf("device in portrait") + "</div>";
                                boxCss = "";
                                break;
                            case "landscape":
                                boxHd = "<div class='md-box-header-print'>" + TDev.lf("device in landscape") + "</div>";
                                boxCss = "";
                                break;
                            case "print":
                            case "screen":
                            case "block":
                                boxHd = "";
                                boxCss = "";
                                break;
                            case "avatar":
                                var artId = MdComments.findArtId(parts[1]);
                                boxHd = TDev.Util.fmt("<img class='md-box-avatar-img' src='{0}' /><div class='md-box-avatar-body' dir='auto'>", TDev.Cloud.artUrl(artId));
                                boxFt = '</div>';
                                boxCss = '';
                                boxClass = 'avatar';
                                boxDir = "dir='ltr'";
                                break;
                            case "column":
                                boxHd = "";
                                boxCss = "col-xs-12 col-sm-6 col-md-4";
                                break;
                            default:
                                boxHd = MdComments.error("no such box type " + m[1] + ", use hint, exercise, example or nointernet");
                                boxClass = 'hint';
                                break;
                        }
                        currBox = boxClass;
                        output += TDev.Util.fmt("<div class='{0} md-box-{1}' {2}>{3}", boxCss, boxClass, boxDir, boxHd);
                        i++;
                    }
                    else if (/^\s*\{\/box(:[^{}]*)?\}\s*$/.test(cmt)) {
                        if (currBox) {
                            output += boxFt + "</div>";
                            currBox = null;
                        }
                        else {
                            output += MdComments.error("no box to close");
                        }
                        i++;
                    }
                    else {
                        output += this.formatText(cmt);
                        i++;
                    }
                }
                else {
                    var j = i;
                    while (j < stmts.length) {
                        if (stmts[j].docText() != null)
                            break;
                        j++;
                    }
                    output += this.mkSnippet(stmts.slice(i, j));
                    i = j;
                }
            }
            if (currBox)
                output += "</div>";
            var fixMultiline = function (s) {
                s = s.replace(/(<\/ul><ul>|<\/ol><ol>|<\/pre><pre>|<\/div><!-- HL --><div class='code-highlight'>)/g, "");
                s = s.replace(/<ul><li><!-- FOLLOW -->/g, "<ul class='tutorial-list'><li>");
                return s;
            };
            output = fixMultiline(output);
            return "<div class='md-tutorial' dir='auto'>" + output + "</div>";
        };
        MdComments.splitDivs = function (tut) {
            var splits = [];
            var leftovers = tut.replace(/([^<]+|<[^<>]+>)/g, function (m, g) {
                splits.push(g);
                return "";
            });
            TDev.Util.assert(!leftovers, "should be nothing left: " + leftovers);
            if (/<div.*md-tutorial.*>/.test(splits[0]) && /<\/div>/.test(splits.peek())) {
                splits.shift();
                splits.pop();
            }
            var stack = [];
            var output = [];
            var curr = "";
            var norm = function (s) { return s.toLowerCase().replace(/\s*/g, ""); };
            splits.forEach(function (s) {
                curr += s;
                if (norm(s) == stack.peek())
                    stack.pop();
                else {
                    var m = /<([a-z0-9\-]+)(\s|>)/i.exec(s);
                    if (m && /^(div|p|ul|ol|h[1-9]|blockquote)$/i.test(m[1]))
                        stack.push(norm("</" + m[1] + ">"));
                }
                if (stack.length == 0) {
                    output.push(curr);
                    curr = "";
                }
            });
            if (curr)
                output.push(curr);
            return output;
        };
        return MdComments;
    })();
    TDev.MdComments = MdComments;
    var HelpTopic = (function () {
        function HelpTopic(json) {
            this.json = json;
            this.isBuiltIn = false;
            this.parentTopic = null;
            this.childTopics = [];
            this.id = MdComments.shrink(this.json.name);
        }
        HelpTopic.prototype.isTutorial = function () {
            return this.hashTags() && /#(stepbystep|hourofcode)\b/i.test(this.allHashTags) && !/template|notes/i.test(this.json.name);
        };
        HelpTopic.prototype.isHourOfCode = function () {
            return this.hashTags() && /#HourOfCode\b/i.test(this.allHashTags);
        };
        HelpTopic.fromJsonScript = function (e) {
            var t = new HelpTopic({
                name: e.name,
                id: e.id,
                description: e.description,
                icon: e.icon,
                iconbackground: e.iconbackground,
                iconArtId: e.iconArtId,
                userid: e.userid,
                time: e.time,
                text: null,
                rootid: e.rootid,
                platforms: e.platforms,
                priority: 20000,
            });
            t.id = e.id;
            t.hashTags();
            t.fromJson = e;
            return t;
        };
        HelpTopic.fromScriptText = function (id, text) {
            var app = TDev.AST.Parser.parseScript(text);
            var t = HelpTopic.fromScript(app, false);
            if (id) {
                t.id = id;
                t.json.id = id;
            }
            return t;
        };
        HelpTopic.fromScript = function (app, useApp) {
            if (useApp === void 0) { useApp = true; }
            var t = new HelpTopic({
                name: app.getName(),
                id: "none",
                description: app.getDescription(),
                icon: TDev.SVG.justName(app.iconPath()),
                iconbackground: app.htmlColor(),
                text: app.serialize(),
                rootid: "none",
                priority: 20000
            });
            if (useApp) {
                t.app = app;
                t.initPromise = TDev.Promise.as();
            }
            return t;
        };
        HelpTopic.lookupHelpPath = function (topic) {
            topic = topic.toLowerCase().replace(/^#/, "");
            var paths = TDev.Cloud.config.specHelpPaths;
            if (paths)
                for (var i = topic.length; i >= 2; --i)
                    if (paths.hasOwnProperty(topic.slice(0, i)))
                        return paths[topic.slice(0, i)];
            return null;
        };
        HelpTopic.justHelpPath = function (topic) {
            if (!topic)
                return null;
            var path = HelpTopic.lookupHelpPath(topic);
            if (!path)
                return null;
            var t = new HelpTopic({
                name: path,
                id: "",
                description: "",
                icon: "Recycle",
                iconbackground: "#008800",
                text: "",
                rootid: "none",
                priority: 20000,
                helpPath: path,
            });
            t.id = path;
            return t;
        };
        HelpTopic.forLibraryAction = function (act) {
            var t = new HelpTopic({
                name: act.getName(),
                id: "",
                description: act.getDescription(),
                icon: "Recycle",
                iconbackground: "#008800",
                text: "",
                rootid: "none",
                priority: 20000,
                helpPath: act.getHelpPath()
            });
            t.apiProperty = act;
            t.apiKind = TDev.api.core.Nothing;
            t.app = act.parentLibrary().resolved;
            t.id = TDev.Util.tagify(t.app.getName() + " " + act.getName());
            t.json.description += " #" + t.id;
            return t;
        };
        HelpTopic.getAll = function () {
            if (!HelpTopic._initalized) {
                HelpTopic._initalized = true;
                var bestForTag = {};
                HelpTopic._topics = [];
                TDev.api.getKinds().forEach(function (k) {
                    if (k.isPrivate || k instanceof TDev.ThingSetKind || (k.isData && k.getContexts() == 0 /* None */))
                        return;
                    var tagName = TDev.Util.toHashTag(k.getName());
                    var topic = bestForTag[MdComments.shrink(tagName)];
                    if (!topic) {
                        topic = new HelpTopic({
                            name: k.getName(),
                            id: "",
                            description: "",
                            icon: TDev.SVG.justName(k.icon()) || "Document",
                            iconbackground: "#7d26cd",
                            priority: 11000,
                            rootid: "none",
                            text: ""
                        });
                        topic.hashTagsCache = ["#docs", tagName];
                        HelpTopic._topics.push(topic);
                    }
                    topic.id = MdComments.shrink(tagName.replace(/^#/, ""));
                    topic.json.name = k.getName();
                    topic.json.description = k.getHelp(false);
                    topic.json.parentTopic = "api";
                    topic.apiKind = k;
                    var outerTopic = topic;
                    outerTopic.subTopics = {};
                    k.listProperties().forEach(function (prop) {
                        if (!prop.isBrowsable())
                            return;
                        var propname = prop.parentKind.getName() + prop.getArrow() + prop.getName();
                        var tagName = "#" + prop.helpTopic();
                        var topic = bestForTag[MdComments.shrink(tagName)];
                        if (!topic) {
                            var j = outerTopic.json;
                            topic = new HelpTopic({
                                name: propname,
                                id: "",
                                rootid: "none",
                                description: "",
                                icon: j.icon,
                                iconbackground: j.iconbackground,
                                priority: 10000 + j.priority,
                                text: ""
                            });
                            topic.hashTagsCache = ["#docs", tagName];
                            HelpTopic._topics.push(topic);
                        }
                        topic.id = MdComments.shrink(tagName.replace(/^#/, ""));
                        topic.json.name = propname;
                        topic.json.description = prop.getDescription(true);
                        if (outerTopic.id != topic.id)
                            topic.json.parentTopic = outerTopic.id;
                        outerTopic.subTopics[topic.id] = topic;
                        topic.apiKind = k;
                        topic.apiProperty = prop;
                    });
                });
                HelpTopic._topics.sort(function (a, b) {
                    var d = a.json.priority - b.json.priority;
                    if (d)
                        return d;
                    return TDev.Util.stringCompare(a.json.name, b.json.name);
                });
                HelpTopic._topics.forEach(function (t) { return t.isBuiltIn = true; });
                HelpTopic.topicCache = {};
                HelpTopic.topicByScriptId = {};
                HelpTopic._topics.forEach(function (t) {
                    HelpTopic.topicByScriptId[t.json.id] = t;
                    HelpTopic.topicCache[t.id] = t;
                });
                var workSet = {};
                var getNesting = function (t) {
                    if (workSet.hasOwnProperty(t.id) && workSet[t.id])
                        workSet[t.id] = 2;
                    if (t.nestingLevel !== undefined)
                        return t.nestingLevel;
                    t.nestingLevel = 0;
                    if (t.json.parentTopic && HelpTopic.topicCache.hasOwnProperty(t.json.parentTopic)) {
                        var par = HelpTopic.topicCache[t.json.parentTopic];
                        workSet[t.id] = 1;
                        var pn = getNesting(par);
                        if (workSet[t.id] == 1) {
                            t.parentTopic = par;
                            t.nestingLevel = getNesting(par) + 1;
                            t.parentTopic.childTopics.push(t);
                        }
                        else {
                            if (TDev.dbg)
                                TDev.Util.log("DOCERR: cycle in help topics involving " + t.id);
                        }
                        workSet[t.id] = 0;
                    }
                    else {
                        if (TDev.dbg) {
                            if (t.json.parentTopic)
                                TDev.Util.log("DOCERR: parent topic " + t.json.parentTopic + " doesn't exists (in '" + t.json.name + "' /" + t.json.id + ")");
                            else
                                TDev.Util.log("DOCERR: no parent topic set for '" + t.json.name + "' /" + t.json.id);
                        }
                    }
                    return t.nestingLevel;
                };
                HelpTopic._topics.forEach(getNesting);
                HelpTopic._topics.forEach(function (t) {
                    if (t.childTopics.length > 0)
                        t.childTopics.sort(function (a, b) { return TDev.Util.stringCompare(a.json.name, b.json.name); });
                });
            }
            return HelpTopic._topics;
        };
        HelpTopic.prototype.renderLink = function (mdcmt, withKind) {
            if (withKind === void 0) { withKind = false; }
            var p = this.apiProperty;
            var r = "";
            r += TDev.Util.fmt("<a href='{0:q}' id='{1:q}' class='md-api-entry-link'><div class='md-api-entry'>", mdcmt.topicLink(this.id), p ? MdComments.shrink(p.getName()) : MdComments.shrink(this.id));
            if (this.json.text)
                r += "<div class='md-more'>more info</div>";
            if (mdcmt.renderer)
                r += mdcmt.renderer.renderPropertySig(p, false, withKind);
            else
                r += TDev.Renderer.tdiv("signature", "function " + p.getName());
            r += "<div class='nopara'>" + mdcmt.formatTextNoLinks(p.getDescription()) + "</div>";
            r += "</div></a>";
            return r;
        };
        HelpTopic.prototype.isBetterThan = function (other) {
            var d = this.hashTags().length - other.hashTags().length;
            if (d != 0)
                return d < 0;
            d = this.json.priority - other.json.priority;
            if (d != 0)
                return d < 0;
            return TDev.Util.stringCompare(this.id, other.id) < 0;
        };
        HelpTopic.prototype.updateKey = function () {
            var j = this.fromJson;
            if (j)
                return j.rootid + ":" + j.userid + ":" + j.name;
            return this.json.rootid + ":jeiv:" + this.json.name;
        };
        HelpTopic.prototype.hashTags = function () {
            if (!this.hashTagsCache) {
                var r = this.hashTagsCache = [];
                var ht = "";
                this.json.description = this.json.description.replace(/(#\w+)/g, function (m, h) {
                    r.push(m);
                    ht += " " + m;
                    return "";
                });
                this.allHashTags = ht;
            }
            return this.hashTagsCache;
        };
        HelpTopic.prototype.translations = function () {
            var m = /\{translations:([^\}]+)\}/i.exec(this.json.text);
            if (!m)
                return undefined;
            var res = MdComments.findArtStringResource(this.app, m[1]);
            if (!res)
                return undefined;
            var r = {};
            res.split('\n').map(function (p) { return p.split('='); }).forEach(function (parts) { return r[parts[0].toLowerCase()] = parts[1]; });
            return r;
        };
        HelpTopic.prototype.templateHashTags = function () {
            var m = /\{sthashtags:([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return m[1].split(',');
            else
                return [];
        };
        HelpTopic.prototype.templateEditorMode = function () {
            var m = /\{steditormode:([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return m[1].trim().toLowerCase();
            return "";
        };
        HelpTopic.prototype.eventHubsTracking = function () {
            var m = /\{steventhubstracking:([^\:]+):([^\:]+):([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return { namespace: m[1], hub: m[2], token: m[3] };
            return undefined;
        };
        HelpTopic.prototype.pixelTrackingUrl = function () {
            var m = /\{stpixeltracking:([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return m[1];
            return "";
        };
        HelpTopic.prototype.nextTutorials = function () {
            var m = /\{stnexttutorials:([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return m[1].split(',');
            return [];
        };
        HelpTopic.prototype.moreTutorials = function () {
            var m = /\{stmoretutorials:([^\}]+)\}/i.exec(this.json.text);
            if (m)
                return m[1];
            return undefined;
        };
        HelpTopic.prototype.translateAsync = function (to) {
            if (this.translatedTopic)
                return TDev.Promise.as(this.translatedTopic);
            if (!to || /^en/i.test(to) || TDev.Cloud.isOffline())
                return TDev.Promise.as(undefined);
            TDev.tick(31 /* translateDocTopic */, to);
            return this.translateToScriptAsync(to, this.json.id);
        };
        HelpTopic.prototype.translateToScriptAsync = function (to, tutorialId) {
            var _this = this;
            if (!tutorialId || !TDev.Cloud.config.translateCdnUrl || !TDev.Cloud.config.translateApiUrl)
                return TDev.Promise.as(this.translatedTopic = { body: undefined });
            return TDev.ProgressOverlay.lockAndShowAsync(TDev.lf("translating topic...") + (TDev.dbg ? tutorialId : "")).then(function () {
                var blobUrl = TDev.HTML.proxyResource(TDev.Cloud.config.translateCdnUrl + "/docs/" + to + "/" + tutorialId);
                return TDev.Util.httpGetJsonAsync(blobUrl).then(function (blob) {
                    _this.translatedTopic = blob;
                    return _this.translatedTopic;
                }, function (e) {
                    TDev.Util.log('requesting topic translation');
                    var url = TDev.Cloud.config.translateApiUrl + '/translate_doc?scriptId=' + tutorialId + '&to=' + to;
                    return TDev.Util.httpGetJsonAsync(url).then(function (js) {
                        _this.translatedTopic = js.info;
                        return _this.translatedTopic;
                    }, function (e) {
                        TDev.Util.log('tutorial topic failed, ' + e);
                        return _this.translatedTopic = { body: undefined };
                    });
                });
            }).then(function () { return TDev.ProgressOverlay.hide(); }, function (e) { return function () { return TDev.ProgressOverlay.hide(); }; });
        };
        HelpTopic.prototype.forSearch = function () {
            if (!this.searchCache) {
                var j = this.json;
                var c = j.name + " " + j.description;
                if (this.apiProperty) {
                    c += " " + this.apiProperty.parentKind.toString();
                    this.apiProperty.getParameters().forEach(function (p) {
                        c += " " + p.getName() + " " + p.getKind().toString();
                    });
                    c += " " + this.apiProperty.getResult().getKind().toString();
                    c += " " + this.apiProperty.getDescription();
                }
                else if (this.apiKind) {
                    c += " " + this.apiKind.toString();
                    c += " " + this.apiKind.getDescription();
                }
                if (j.text)
                    c += " " + j.text;
                this.searchCache = c.toLowerCase();
            }
            return this.searchCache;
        };
        HelpTopic.prototype.reloadAppAsync = function () {
            var _this = this;
            var j = this.json;
            var loadScript = function (id) {
                if (id == "") {
                    if (j.text == null && j.id)
                        return HelpTopic.getScriptAsync(j.id).then(function (text) {
                            j.text = text;
                            return text;
                        });
                    else
                        return TDev.Promise.as(j.text);
                }
                else {
                    return HelpTopic.getScriptAsync(id);
                }
            };
            return TDev.AST.loadScriptAsync(loadScript).then(function (tcRes) {
                var s = TDev.Script;
                TDev.setGlobalScript(tcRes.prevScript);
                if (_this.fromJson)
                    s.blockExternalLinks = _this.fromJson.noexternallinks;
                return s;
            });
        };
        HelpTopic.prototype.initAsync = function () {
            var _this = this;
            if (!this.json.text && !this.json.id)
                return TDev.Promise.as(this.app);
            if (this.initPromise)
                return this.initPromise;
            this.initPromise = this.reloadAppAsync().then(function (s) {
                _this.app = s;
                return s;
            });
            return this.initPromise;
        };
        HelpTopic.prototype.isApiHelp = function () {
            return !!this.apiProperty;
        };
        HelpTopic.prototype.getSig = function (mdcmt, full) {
            var ch = "<div class='md-api-header md-tutorial'>" + (new TDev.Renderer()).renderPropertySig(this.apiProperty, true) + (!full ? "" : "<div class='md-prop-desc'>" + mdcmt.formatText(this.apiProperty.getDescription()) + "</div>") + "</div>";
            if (full) {
                var cap = this.apiProperty.getCapability();
                ch += "<div class='md-tutorial'>" + "<ul>" + (cap == 0 /* None */ ? "" : "<li>" + TDev.lf("<strong>required platform:</strong>") + " " + TDev.Util.htmlEscape(TDev.AST.App.capabilityName(cap))) + (!this.apiProperty.isBeta() ? "" : "<li>" + TDev.lf("<strong>feature in beta testing:</strong> the syntax and semantics is subject to change")) + (this.apiProperty.isImplementedAnywhere() ? "" : "<li><strong>" + TDev.lf("API not implemented") + "</strong>, sorry ") + "</ul>" + "</div>";
            }
            if (mdcmt.useExternalLinks)
                ch = ch.replace(/#topic(:|%3a)/g, TDev.Cloud.config.rootUrl + TDev.Cloud.config.topicPath);
            return ch;
        };
        HelpTopic.prototype.renderCore = function (mdcmt) {
            var _this = this;
            if (!mdcmt) {
                var rend = new TDev.Renderer();
                rend.stringLimit = 90;
                mdcmt = new MdComments(rend, null);
                if (this.app)
                    mdcmt.blockExternalLinks = this.app.blockExternalLinks;
            }
            var ch = "";
            if (this.apiProperty)
                ch += this.getSig(mdcmt, true);
            if (this.app) {
                var acts = this.app.orderedThings().filter(function (a) { return a instanceof TDev.AST.Action; });
                var noTutorial = acts.some(function (a) { return a.getName() == "this is no tutorial"; });
                if (this.apiProperty instanceof TDev.AST.LibraryRefAction) {
                    acts = acts.filter(function (a) { return a.getName() == "docs " + _this.apiProperty.getName(); });
                }
                else {
                    if (this.isTutorial())
                        acts = acts.filter(function (a) { return /^main$/.test(a.getName()); });
                    else {
                        acts = acts.filter(function (a) { return a.isNormalAction() && /^example/.test(a.getName()); });
                        if (acts.length == 0 && this.app.mainAction())
                            acts = [this.app.mainAction()];
                    }
                }
                acts.forEach(function (a) {
                    ch += mdcmt.extract(a);
                });
                var tutorialSteps = noTutorial ? [] : TDev.AST.Step.splitActions(this.app);
                if (tutorialSteps.length > 0 && mdcmt.forWeb)
                    ch = ch.replace(/<\/div>$/, "<hr class='md-section' data-name='startTutorial' data-arguments='' /></div>");
                if (mdcmt.print) {
                    if (tutorialSteps.length > 0) {
                        tutorialSteps.forEach(function (s) {
                            if (s.printOut) {
                                ch += mdcmt.mkDeclSnippet(s.printOut, false, true, "tutorial-step", 1);
                            }
                        });
                        var finalAct = this.app.actions().filter(function (a) { return a.getName() == "final"; })[0];
                        if (finalAct)
                            ch += mdcmt.extract(finalAct);
                    }
                }
            }
            if (this.apiKind && !this.apiProperty) {
                var r = this.getSubTopics().map(function (st) { return st.renderLink(mdcmt); });
                ch += "<div class='md-tutorial'>" + r.join('') + "</div>";
            }
            if (this.id == "api") {
                var r = [];
                var kindTopics = HelpTopic.getAll().filter(function (st) { return st.apiKind && !st.apiProperty; });
                kindTopics.sort(function (a, b) { return TDev.Util.stringCompare(a.id, b.id); });
                r.push('<h3>' + TDev.lf("services") + '</h3>');
                kindTopics.filter(function (st) { return !st.apiKind.isData && !st.apiKind.isObsolete; }).forEach(function (st) { return HelpTopic.renderKindDecl(r, st, mdcmt); });
                r.push('<h3>' + TDev.lf("types") + '</h3>');
                kindTopics.filter(function (st) { return st.apiKind.isData && !st.apiKind.isAction && !st.apiKind.isObsolete; }).forEach(function (st) { return HelpTopic.renderKindDecl(r, st, mdcmt); });
                r.push('<h3>' + TDev.lf("function types") + '</h3>');
                kindTopics.filter(function (st) { return st.apiKind.isData && st.apiKind.isAction && !st.apiKind.isObsolete; }).forEach(function (st) { return HelpTopic.renderKindDecl(r, st, mdcmt); });
                ch += "<div class='md-tutorial'>" + r.join('') + "</div>";
            }
            return ch;
        };
        HelpTopic.prototype.isPropertyHelp = function () {
            return !!this.apiProperty;
        };
        HelpTopic.prototype.getSubTopics = function () {
            var _this = this;
            var names = Object.keys(this.subTopics);
            names.sort(TDev.Util.stringCompare);
            return names.map(function (k) { return _this.subTopics[k]; });
        };
        HelpTopic.prototype.renderTranslated = function () {
            if (this.translatedTopic && this.translatedTopic.body) {
                var ch = "<div class='md-tutorial' dir='auto'>" + this.translatedTopic.body.join('\n') + "</div>";
                return ch;
            }
            return undefined;
        };
        HelpTopic.prototype.renderAsync = function (mdcmt) {
            var _this = this;
            if (mdcmt === void 0) { mdcmt = null; }
            return this.initAsync().then(function () {
                var prevScript = TDev.Script;
                try {
                    TDev.setGlobalScript(_this.app);
                    return _this.renderCore(mdcmt);
                }
                finally {
                    TDev.setGlobalScript(prevScript);
                }
            });
        };
        HelpTopic.prototype.docInfoAsync = function () {
            var md = new TDev.MdComments(new TDev.CopyRenderer());
            md.useSVG = false;
            md.showCopy = false;
            var ht = this;
            return this.renderAsync(md).then(function (text) {
                var r = {
                    title: "<h1>" + TDev.Util.htmlEscape(ht.json.name) + "</h1>",
                    description: ht.isApiHelp() ? "" : "<p>" + TDev.Util.htmlEscape(ht.json.description) + "</p>",
                    body: MdComments.splitDivs(text),
                };
                var translations = ht.translations();
                if (translations)
                    r.translations = translations;
                return r;
            });
        };
        HelpTopic.prototype.renderHeader = function () {
            var _this = this;
            var r = TDev.div(null);
            this.initAsync().done(function () {
                var appName = _this.app.getName().replace(/ tutorial$/, "");
                var i = appName.indexOf(':');
                if (i > 0)
                    appName = appName.substr(i + 1);
                else
                    appName = TDev.lf("tutorial: ") + appName;
                r.setChildren(appName);
            });
            return r;
        };
        HelpTopic.prototype.render = function (whenDone) {
            var _this = this;
            var d = TDev.div(null);
            d.style.marginRight = "0.2em";
            this.translateAsync(TDev.Util.getTranslationLanguage()).then(function () { return _this.renderAsync(); }).done(function (text) {
                var translatedDocs = _this.renderTranslated();
                if (!translatedDocs)
                    TDev.Browser.setInnerHTML(d, text);
                else if (_this.translatedTopic && _this.translatedTopic.manual) {
                    TDev.Browser.setInnerHTML(d, translatedDocs);
                }
                else {
                    var elementDiv = TDev.div('');
                    TDev.Browser.setInnerHTML(elementDiv, text);
                    var trElementDiv = TDev.div('');
                    TDev.Browser.setInnerHTML(trElementDiv, translatedDocs);
                    var trNotice = TDev.div('translate-notice', TDev.lf("Translations by Microsoft® Translator, tap to see original...")).withClick(function () {
                        trElementDiv.style.display = 'none';
                        elementDiv.style.display = 'block';
                        TDev.Util.seeTranslatedText(false);
                    });
                    trElementDiv.insertBefore(trNotice, trElementDiv.firstElementChild);
                    var elNotice = TDev.div('translate-notice', TDev.lf("tap to translate with Microsoft® Translator...")).withClick(function () {
                        elementDiv.style.display = 'none';
                        trElementDiv.style.display = 'block';
                        TDev.Util.seeTranslatedText(true);
                    });
                    elementDiv.insertBefore(elNotice, elementDiv.firstElementChild);
                    if (TDev.Util.seeTranslatedText())
                        elementDiv.style.display = 'none';
                    else
                        trElementDiv.style.display = 'none';
                    d.setChildren([elementDiv, trElementDiv]);
                }
                TDev.HTML.fixWp8Links(d);
                whenDone(d);
            });
            return d;
        };
        HelpTopic.printManyAsync = function (topics) {
            return TDev.Promise.join(topics.map(function (t) { return t.printedAsync(); })).then(function (arr) { return HelpTopic.printText(arr.join("<div style='page-break-after:always'></div>\n"), "Help"); });
        };
        HelpTopic.prototype.printedAsync = function (newsletter) {
            var _this = this;
            if (newsletter === void 0) { newsletter = false; }
            var r = new TDev.CopyRenderer();
            var md = new MdComments(r);
            md.scriptid = this.json.id;
            md.useSVG = false;
            md.useExternalLinks = true;
            md.showCopy = false;
            md.print = true;
            return this.renderAsync(md).then(function (text) {
                if (newsletter)
                    return TDev.CopyRenderer.inlineStyles(text);
                else
                    return ("<h1>" + TDev.Util.htmlEscape(_this.json.name) + "</h1>" + text);
            });
        };
        HelpTopic.printText = function (text, title) {
            try {
                var w = window.open("about:blank", "tdTopic" + TDev.Util.guidGen());
                var html = "<!DOCTYPE html><html><head>" + TDev.CopyRenderer.css + "<title>" + TDev.Util.htmlEscape(title) + "</title>" + "<meta name='microsoft' content='notranslateclasses stmt keyword'/>" + "</head><body onload='try { window.print(); } catch(ex) {}'>" + text + "</body></html>";
                w.document.write(html);
                w.document.close();
            }
            catch (e) {
                TDev.ModalDialog.info(":( can't print from here", TDev.lf("Your browser might have blocked the print page or try to print from another device..."));
            }
        };
        HelpTopic.prototype.print = function () {
            var _this = this;
            this.printedAsync().done(function (text) { return HelpTopic.printText(text, _this.json.name); });
        };
        HelpTopic.renderKindDecl = function (r, st, mdcmt) {
            var j = st.json;
            var n = j.name;
            if (!st.apiKind.isData)
                n = n.toLowerCase();
            r.push("<div class='api-kind'><a href='" + mdcmt.topicLink(st.id) + "'>");
            r.push("<div class='api-kind-inner'>");
            if (mdcmt.useSVG)
                r.push("<span class='api-icon' style='background:" + j.iconbackground + "'>" + (mdcmt.useSVG ? TDev.SVG.getIconSVGCore(j.icon + ",white") : "<img src='/replaceicons/" + j.icon + ".png' alt='" + j.icon + "'>") + "</span>");
            r.push("<div class='api-names'><div class='api-name'>" + TDev.Util.htmlEscape(n) + "</div>");
            r.push("<div class='api-desc'>" + TDev.Util.htmlEscape(j.description) + "</div>");
            r.push("</div></div></a></div>");
        };
        HelpTopic.findById = function (id) {
            if (TDev.Cloud.isRestricted())
                return null;
            HelpTopic.getAll();
            if (id)
                id = id.replace(/^t:/, "");
            id = MdComments.shrink(id);
            if (HelpTopic.topicCache.hasOwnProperty(id))
                return HelpTopic.topicCache[id];
            return null;
        };
        HelpTopic.contextTopics = [];
        HelpTopic._topics = [];
        HelpTopic._initalized = false;
        return HelpTopic;
    })();
    TDev.HelpTopic = HelpTopic;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Json;
        (function (Json) {
            Json.docs;
            function isPlaceholder(j) {
                return j === "" || j.tokens && (j.tokens.length == 0 || (j.tokens.length == 1 && j.tokens[0].nodeType == "placeholder"));
            }
            function isEmptyBlock(b) {
                return !b || b.length == 0 || (b.length == 1 && b[0].nodeType == "exprStmt" && isPlaceholder(b[0].expr));
            }
            function setStableId(a, prefix) {
                if (a.hasIds) {
                    var s0 = new AST.InitIdVisitor(false);
                    s0.dispatch(a);
                    var s1 = new IdFromStableSetter();
                    s1.dispatch(a);
                }
                else {
                    var i = new IdSetter(prefix);
                    i.dispatch(a);
                }
            }
            Json.setStableId = setStableId;
            function addIdsAndDumpNode(a) {
                var i = new IdSetter("");
                i.dispatch(a);
                return (new Dumper()).toJson(a);
            }
            Json.addIdsAndDumpNode = addIdsAndDumpNode;
            function dump(a) {
                try {
                    setStableId(a);
                    return (new Dumper()).toJson(a);
                }
                catch (e) {
                    e.bugAttachments = [a.serialize()];
                    throw e;
                }
            }
            Json.dump = dump;
            function dumpForDiff(a) {
                var d = new Dumper();
                d.shortMode = true;
                return d.toJson(a);
            }
            Json.dumpForDiff = dumpForDiff;
            var IdFromStableSetter = (function (_super) {
                __extends(IdFromStableSetter, _super);
                function IdFromStableSetter() {
                    _super.call(this);
                    this.currId = 0;
                }
                IdFromStableSetter.prototype.visitStmt = function (n) {
                    this.lastStmt = n;
                    this.currId = 0;
                    var id = n.getStableName();
                    if (!id)
                        TDev.Util.oops("no stable name on " + n.nodeType());
                    n.stableId = id;
                    this.visitChildren(n);
                };
                IdFromStableSetter.prototype.visitKindBinding = function (n) {
                    if (n.isExplicit) {
                        this.visitStmt(n);
                    }
                    else {
                        n.stableId = this.makeId();
                        this.visitChildren(n);
                    }
                };
                IdFromStableSetter.prototype.visitActionBinding = function (n) {
                    if (n.isExplicit) {
                        this.visitStmt(n);
                    }
                    else {
                        n.stableId = this.makeId();
                        this.visitChildren(n);
                    }
                };
                IdFromStableSetter.prototype.makeId = function () {
                    return this.lastStmt.stableId + "$i" + this.currId++;
                };
                IdFromStableSetter.prototype.visitAction = function (a) {
                    a.allLocals.forEach(function (l) {
                        l.stableId = l.getStableName();
                    });
                    var copyId = function (p) { return p.local.stableId = p.getStableName(); };
                    a.getInParameters().forEach(copyId);
                    a.getOutParameters().forEach(copyId);
                    if (a.modelParameter)
                        copyId(a.modelParameter);
                    this.visitStmt(a);
                };
                IdFromStableSetter.prototype.visitLibraryRef = function (l) {
                    var _this = this;
                    this.visitStmt(l);
                    l.getPublicActionsAndActionTypes().forEach(function (a, i) {
                        a.stableId = l.stableId + "$a" + i;
                        a.header.stableId = l.stableId + "$ah" + i;
                        a.getInParameters().concat(a.getOutParameters()).forEach(function (p, j) {
                            p.stableId = a.stableId + "$p" + j;
                            p.local.stableId = p.stableId + "$l";
                        });
                    });
                    l.getPublicKinds().forEach(function (k) {
                        var r = k.getRecord();
                        if (r) {
                            r.keys.setStableName(r.getStableName() + "$ks");
                            r.values.setStableName(r.getStableName() + "$vs");
                            _this.dispatch(r);
                        }
                    });
                };
                IdFromStableSetter.prototype.visitExprHolder = function (n) {
                    var id = this.lastStmt.stableId;
                    n.stableId = id + "$eh";
                    if (n.parsed)
                        this.dispatch(n.parsed);
                    n.tokens.forEach(function (t, i) {
                        t.stableId = id + "$t" + i;
                        var loc = t.getLocalDef();
                        if (loc && !loc.stableId)
                            loc.stableId = id + "$err" + i;
                        if (t.getFunArgs()) {
                            var fa = t.call.funAction;
                            if (fa) {
                                fa.stableId = id + "$fn" + i;
                                fa.body.stableId = id + "$fnb" + i;
                                fa.body.stmts[0].stableId = id + "$fns" + i;
                                fa.body.stmts[0].expr.stableId = id + "$fneh" + i;
                            }
                        }
                    });
                };
                IdFromStableSetter.prototype.visitInlineAction = function (n) {
                    n.name.stableId = n.getStableName() + "$inlan";
                    _super.prototype.visitInlineAction.call(this, n);
                };
                IdFromStableSetter.prototype.visitAstNode = function (n) {
                    n.stableId = this.makeId();
                    this.visitChildren(n);
                };
                return IdFromStableSetter;
            })(AST.NodeVisitor);
            var IdSetter = (function (_super) {
                __extends(IdSetter, _super);
                function IdSetter(prefix) {
                    if (prefix === void 0) { prefix = ""; }
                    _super.call(this);
                    this.prefix = prefix;
                    this.currId = 0;
                }
                IdSetter.prototype.makeId = function () {
                    var r = this.prefix;
                    if (this.currId < IdSetter.begIds.length)
                        r += IdSetter.begIds[this.currId];
                    else {
                        if (/\d$/.test(r))
                            r += ".";
                        r += this.currId + ".";
                    }
                    this.currId++;
                    return r;
                };
                IdSetter.prototype.scope = function (f) {
                    var id = this.makeId();
                    var prevPrefix = this.prefix;
                    var prevId = this.currId;
                    try {
                        this.prefix = this.makeId();
                        this.currId = 0;
                        f();
                        return id;
                    }
                    finally {
                        this.prefix = prevPrefix;
                        this.currId = prevId;
                    }
                };
                IdSetter.prototype.visitLocalDef = function (l) {
                };
                IdSetter.prototype.visitApp = function (a) {
                    a.stableId = this.makeId();
                    this.visitChildren(a);
                };
                IdSetter.prototype.visitAction = function (a) {
                    var _this = this;
                    a.stableId = this.scope(function () { return a.allLocals.forEach(function (l) {
                        l.stableId = _this.makeId();
                    }); });
                    this.visitChildren(a);
                };
                IdSetter.prototype.visitLibraryRef = function (l) {
                    _super.prototype.visitLibraryRef.call(this, l);
                    this.scopedList(l.getPublicActionsAndActionTypes());
                };
                IdSetter.prototype.scopedList = function (ns) {
                    var _this = this;
                    this.scope(function () {
                        ns.forEach(function (n) { return _this.dispatch(n); });
                    });
                };
                IdSetter.prototype.scoped = function (n) {
                    var _this = this;
                    n.stableId = this.scope(function () { return _this.visitChildren(n); });
                };
                IdSetter.prototype.visitDecl = function (n) {
                    this.scoped(n);
                };
                IdSetter.prototype.visitBlock = function (n) {
                    this.scoped(n);
                };
                IdSetter.prototype.visitCall = function (n) {
                    this.scoped(n);
                };
                IdSetter.prototype.visitExprHolder = function (n) {
                    this.scoped(n);
                    if (n.parsed)
                        this.dispatch(n.parsed);
                };
                IdSetter.prototype.visitAstNode = function (n) {
                    n.stableId = this.makeId();
                    this.visitChildren(n);
                };
                IdSetter.begIds = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                return IdSetter;
            })(AST.NodeVisitor);
            function getApis() {
                return (new Dumper(false)).getApis();
            }
            Json.getApis = getApis;
            var Dumper = (function (_super) {
                __extends(Dumper, _super);
                function Dumper(useIds) {
                    if (useIds === void 0) { useIds = true; }
                    _super.call(this);
                    this.useIds = useIds;
                    this.seenIds = {};
                    this.addLocals = [];
                    this.deletedDecls = [];
                    this.shortMode = false;
                    this.reflectionMode = false;
                }
                Dumper.prototype.getApis = function () {
                    var _this = this;
                    var optBool = function (v) {
                        if (v)
                            return true;
                        else
                            return undefined;
                    };
                    var tc = new AST.TypeChecker();
                    tc.topApp = AST.Parser.parseScript("");
                    var doParam = function (p) {
                        var defl = p.getDefaultValue();
                        var toks = undefined;
                        if (defl) {
                            tc.tcTokens(defl);
                            toks = _this.toJsons(defl);
                        }
                        return {
                            name: p.getName(),
                            type: _this.kind(p.getKind()),
                            writesMutable: optBool(p.getFlags() & 1 /* WritesMutable */),
                            readsMutable: optBool(p.getFlags() & 2 /* ReadsMutable */),
                            defaultValue: toks,
                            stringValues: p.getStringValues() || undefined,
                        };
                    };
                    var doProp = function (p) {
                        if (!(p instanceof TDev.Property))
                            TDev.Util.die();
                        var f = p.getFlags();
                        return {
                            name: p.getName(),
                            help: p.getDescription(),
                            usage_count: p._usage_count,
                            isAsync: optBool(f & 4096 /* Async */),
                            runOnInvalid: optBool(f & 1 /* RunOnInvalidArguments */),
                            isHidden: optBool(f & 4 /* IsHidden */),
                            isObsolete: optBool(f & 2 /* IsObsolete */),
                            isDbgOnly: optBool(f & 1024 /* IsDebugOnly */),
                            isBetaOnly: optBool(f & 8192 /* IsBetaOnly */),
                            jsName: p.runtimeName(),
                            infixPriority: p._infixPriority,
                            pausesInterpreter: optBool(p._implStatus & 1 /* Pauses */),
                            usesStackFrame: optBool(p._implStatus & 2 /* UsesStackFrame */),
                            missingWeb: optBool(!(p._implStatus & 16 /* Web */)),
                            capabilities: AST.App.capabilityString(p.getCapability()) || undefined,
                            result: doParam(p.getResult()),
                            parameters: p.getParameters().map(doParam),
                        };
                    };
                    var doKind = function (k) {
                        var ctx = k.getContexts();
                        return {
                            name: k.getName(),
                            help: k.getDescription(),
                            icon: TDev.SVG.justName(k.icon()),
                            isAction: optBool(k.isAction),
                            isData: k.isData,
                            isDbgOnly: optBool(k.isDbgOnly),
                            isBetaOnly: optBool(k.isBetaOnly),
                            isSerializable: k.isSerializable,
                            stemName: k.getStemName(),
                            jsName: k.runtimeName(),
                            isBuiltin: k.isBuiltin,
                            ctxLocal: optBool(ctx & 1 /* Parameter */),
                            ctxGlobal: optBool(ctx & 2 /* GlobalVar */),
                            ctxLocalKey: optBool(ctx & 16 /* IndexKey */),
                            ctxGcKey: optBool(ctx & 32 /* GcKey */),
                            ctxCloudKey: optBool(ctx & 16 /* IndexKey */),
                            ctxRowKey: optBool(ctx & 64 /* RowKey */),
                            ctxCloudField: optBool(ctx & 4 /* CloudField */),
                            ctxWallTap: optBool(ctx & 256 /* WallTap */),
                            ctxEnumerable: optBool(ctx & 512 /* Enumerable */),
                            ctxJson: optBool(ctx & 1024 /* Json */),
                            properties: k.listProperties().map(doProp),
                        };
                    };
                    return {
                        textVersion: AST.App.currentVersion,
                        jsonVersion: Dumper.version,
                        types: AST.api.getKinds().filter(function (k) { return !(k instanceof TDev.ThingSetKind); }).map(doKind)
                    };
                };
                Dumper.prototype.visitAstNode = function (node) {
                    TDev.Util.oops("cannot jsonize " + node.nodeType());
                    return null;
                };
                Dumper.prototype.fixupJson = function (n, r) {
                    var _this = this;
                    if (Array.isArray(r) || typeof r === "string")
                        return r;
                    Object.keys(r).forEach(function (k) {
                        var v = r[k];
                        if (v instanceof AST.AstNode)
                            r[k] = _this.toJson(v);
                        else if (v instanceof TDev.Kind)
                            r[k] = _this.kind(v);
                    });
                    if (!r.nodeType) {
                        r.nodeType = n.nodeType();
                        if (!r.nodeType)
                            TDev.Util.oops("cannot get nodetype");
                    }
                    if (this.useIds && !r.id) {
                        r.id = n.stableId;
                        if (!r.id)
                            TDev.Util.oops("no id on " + r.nodeType);
                        this.seenIds[r.id] = true;
                    }
                    if (this.shortMode && n.calcNode) {
                        var eh = n.calcNode();
                        if (eh && eh.definedLocals) {
                            r.locals = this.toJsons(eh.definedLocals);
                        }
                        var boundLocal = "";
                        if (n instanceof AST.For)
                            boundLocal = "index";
                        else if (n instanceof AST.Foreach)
                            boundLocal = "iterator";
                        else if (n instanceof AST.InlineAction)
                            boundLocal = "reference";
                        if (boundLocal) {
                            if (!r.locals)
                                r.locals = [];
                            r.locals.unshift(r[boundLocal]);
                            delete r[boundLocal];
                        }
                    }
                    return r;
                };
                Dumper.prototype.kindJson = function (k) {
                    var _this = this;
                    var par = k.parentLibrary();
                    if (par && !par.isThis())
                        return { l: this.ref(par), o: k.getName() };
                    if (k instanceof AST.RecordEntryKind)
                        return { o: k.getName() };
                    if (k instanceof TDev.ParametricKind) {
                        var pk = k;
                        if (pk.parameters && pk.parameters.length)
                            return { g: pk.root.getName(), a: pk.parameters.map(function (k) { return _this.kindJson(k); }) };
                        else
                            return { g: pk.root.getName() };
                    }
                    return k.getName();
                };
                Dumper.prototype.kind = function (k) {
                    var r = this.kindJson(k);
                    if (typeof r === "object")
                        return JSON.stringify(r);
                    return r;
                };
                Dumper.prototype.toJson = function (n) {
                    return this.fixupJson(n, this.dispatch(n));
                };
                Dumper.prototype.possiblyEmptyBlock = function (b) {
                    var s = this.toJsons(b.stmts);
                    if (isEmptyBlock(s))
                        return undefined;
                    else
                        return s;
                };
                Dumper.prototype.toJsons = function (n) {
                    var _this = this;
                    return n.map(function (e) { return _this.toJson(e); });
                };
                Dumper.prototype.ref = function (n) {
                    var _this = this;
                    if (!n)
                        return null;
                    if (n instanceof AST.Decl && n.deleted) {
                        var d = n;
                        if (this.deletedDecls.indexOf(d) < 0) {
                            this.deletedDecls.push(d);
                            var nm = d.getName();
                            if (d instanceof AST.Action) {
                                var par = d.parentLibrary();
                                if (!par.isThis())
                                    nm = par.getName() + "->" + nm;
                            }
                            var id = TDev.Util.base64Encode(TDev.Util.toUTF8("\u0002" + d.nodeType() + ":" + nm)).replace(/[^a-zA-Z0-9]/g, "") + "Z";
                            d.stableId = AST.AstNode.freshNameCore(id, function (n) { return _this.deletedDecls.some(function (d) { return d.stableId == n; }); });
                        }
                    }
                    return n.stableId;
                };
                Dumper.prototype.visitOperator = function (n) {
                    if (this.shortMode)
                        return "," + n.data;
                    return { op: n.data };
                };
                Dumper.prototype.visitPropertyRef = function (n) {
                    var fwd = n.prop.forwardsTo();
                    if (fwd instanceof AST.Action)
                        fwd = fwd.extensionForward();
                    if (this.shortMode)
                        return fwd ? "#" + fwd.stableId : "." + AST.idUrlQuote(n.getText());
                    var r = {
                        name: n.getText(),
                        parent: n.prop.parentKind,
                    };
                    if (fwd)
                        r.declId = this.ref(fwd);
                    return r;
                };
                Dumper.prototype.visitLiteral = function (n) {
                    if (this.shortMode) {
                        switch (typeof n.data) {
                            case "string": return "'" + AST.idUrlQuote(n.data);
                            case "boolean": return n.data ? "T" : "F";
                            default: TDev.Util.oops("bad literal " + n.data);
                        }
                    }
                    return {
                        nodeType: (typeof n.data) + "Literal",
                        value: n.data,
                        stringForm: n.stringForm,
                        enumValue: n.enumVal,
                        hintValue: n.hintVal,
                        hintArtId: n.hintArtId,
                    };
                };
                Dumper.prototype.visitThingRef = function (n) {
                    if (n.def instanceof AST.LocalDef) {
                        if (!this.seenIds.hasOwnProperty(n.def.stableId))
                            this.addLocals.push(this.toJson(n.def));
                        if (this.shortMode)
                            return "$" + n.def.stableId;
                        return {
                            nodeType: "localRef",
                            name: n.getText(),
                            localId: this.ref(n.def),
                        };
                    }
                    else if (n.def instanceof AST.PlaceholderDef) {
                        var pl = n.def;
                        if (this.shortMode)
                            return "?" + AST.idUrlQuote(this.kind(n.def.getKind())) + ":" + AST.idUrlQuote(pl.label || "");
                        return {
                            nodeType: "placeholder",
                            name: pl.label || "",
                            type: n.def.getKind(),
                        };
                    }
                    else if (n.def instanceof AST.SingletonDef) {
                        if (this.shortMode)
                            return ":" + AST.idUrlQuote(n.getText());
                        return {
                            nodeType: "singletonRef",
                            name: n.getText(),
                            type: n.def.getKind(),
                            libraryName: n.namespaceLibrary ? n.namespaceLibrary.getName() : undefined,
                        };
                    }
                    else
                        TDev.Util.oops("unknown def " + (n.def ? n.def.nodeType() : "null"));
                };
                Dumper.prototype.visitCall = function (n) {
                    var _this = this;
                    var r = this.visitPropertyRef(n.propRef);
                    r.nodeType = "call";
                    r.args = this.toJsons(n.args);
                    if (n.prop() instanceof TDev.MultiplexProperty) {
                        var args = n.prop().savedArgs;
                        if (args)
                            r.typeArgs = args.map(function (x) { return _this.kindJson(x); });
                    }
                    if (n.calledExtensionAction() != null)
                        r.callType = "extension";
                    if (n.referencedRecordField() != null)
                        r.callType = "field";
                    return r;
                };
                Dumper.prototype.visitExprHolder = function (n) {
                    var _this = this;
                    if (this.shortMode)
                        return n.tokens.map(function (t) { return t.accept(_this); }).join(" ");
                    var ai = n.assignmentInfo();
                    var locals = ai ? this.toJsons(ai.definedVars).slice(0) : [];
                    var r = {
                        tokens: this.toJsons(n.tokens),
                        tree: this.toJson(n.parsed),
                        locals: locals
                    };
                    if (this.addLocals.length > 0) {
                        locals.pushRange(this.addLocals);
                        this.addLocals = [];
                    }
                    if (n.locals)
                        r.allLocals = this.toJsons(n.locals);
                    return r;
                };
                Dumper.prototype.visitComment = function (n) {
                    return { text: n.text };
                };
                Dumper.prototype.visitBlock = function (n) {
                    return this.toJsons(n.stmts);
                };
                Dumper.prototype.visitFor = function (n) {
                    return {
                        index: n.boundLocal,
                        bound: n.upperBound,
                        body: n.body
                    };
                };
                Dumper.prototype.visitForeach = function (n) {
                    return {
                        iterator: n.boundLocal,
                        collection: n.collection,
                        conditions: n.conditions,
                        body: n.body
                    };
                };
                Dumper.prototype.visitWhile = function (n) {
                    return {
                        condition: n.condition,
                        body: n.body
                    };
                };
                Dumper.prototype.visitShow = function (n) {
                    return {
                        nodeType: "show",
                        expr: n.args[0],
                    };
                };
                Dumper.prototype.visitReturn = function (n) {
                    return {
                        nodeType: "return",
                        expr: n.args[0],
                    };
                };
                Dumper.prototype.visitBreak = function (n) {
                    return {
                        nodeType: "break",
                    };
                };
                Dumper.prototype.visitContinue = function (n) {
                    return {
                        nodeType: "continue",
                    };
                };
                Dumper.prototype.visitBox = function (n) {
                    return { body: n.body };
                };
                Dumper.prototype.visitAnyIf = function (n) {
                    return {
                        nodeType: "if",
                        condition: n.rawCondition,
                        thenBody: n.rawThenBody,
                        elseBody: this.possiblyEmptyBlock(n.rawElseBody),
                        isElseIf: n.isElseIf,
                    };
                };
                Dumper.prototype.visitWhere = function (n) {
                    return { condition: n.condition };
                };
                Dumper.prototype.visitExprStmt = function (n) {
                    return { expr: n.expr };
                };
                Dumper.prototype.visitInlineActions = function (n) {
                    var r = this.visitExprStmt(n);
                    r.actions = n.actions;
                    return r;
                };
                Dumper.prototype.visitInlineAction = function (n) {
                    var _this = this;
                    return {
                        reference: n.name,
                        inParameters: this.toJsons(n.inParameters),
                        outParameters: this.toJsons(n.outParameters),
                        allLocals: n.allLocals.map(function (l) { return _this.ref(l); }),
                        capturedLocals: n.closure.map(function (l) { return _this.ref(l); }),
                        isImplicit: n.isImplicit,
                        isOptional: n.isOptional,
                        body: n.body,
                    };
                };
                Dumper.prototype.visitOptionalParameter = function (n) {
                    return {
                        name: n.getName(),
                        declId: this.ref(n.recordField),
                        expr: n.expr
                    };
                };
                Dumper.prototype.visitActionParameter = function (n) {
                    return this.toJson(n.local);
                };
                Dumper.prototype.visitAction = function (n) {
                    return this.visitActionCore(n, !this.reflectionMode);
                };
                Dumper.prototype.visitActionCore = function (n, includeBody) {
                    var r = {
                        name: n.getName(),
                        inParameters: this.toJsons(n.header.inParameters.stmts),
                        outParameters: n.header.outParameters,
                        isPrivate: !!n.isPrivate,
                        isTest: !!n.isTest(),
                        isQuery: !!n.isQuery,
                        isOffline: !!n.isOffline,
                        isAsync: !n.isAtomic,
                        description: n.getInlineHelp() || "",
                        unused: n.visitorState !== true,
                    };
                    if (n.isPage()) {
                        r.nodeType = "page";
                        if (n.modelParameter) {
                            r.inParameters.unshift(this.toJson(n.modelParameter));
                            r.hasModelParameter = true;
                        }
                        if (includeBody) {
                            var b = n.getPageBlock(true);
                            r.initBody = b;
                            r.initBodyId = b.parent.stableId;
                            b = n.getPageBlock(false);
                            r.displayBody = b;
                            r.displayBodyId = b.parent.stableId;
                        }
                    }
                    else if (n.isEvent()) {
                        r.nodeType = "event";
                        r.eventName = n.eventInfo.type.category;
                        r.eventVariableId = this.ref(n.eventInfo.onVariable);
                        if (includeBody)
                            r.body = n.body;
                    }
                    else if (n.isActionTypeDef()) {
                        r.nodeType = "actionType";
                        if (includeBody)
                            r.body = n.body;
                    }
                    else {
                        r.nodeType = "action";
                        if (includeBody)
                            r.body = n.body;
                    }
                    return r;
                };
                Dumper.prototype.visitGlobalDef = function (n) {
                    var r = {
                        name: n.getName(),
                        comment: n.comment,
                        type: n.getKind(),
                        isReadonly: n.readonly,
                        isTransient: n.isTransient,
                        isCloudEnabled: n.cloudEnabled,
                        value: n.stringResourceValue(),
                        unused: n.visitorState !== true,
                    };
                    if (n.isResource) {
                        r.nodeType = "art";
                        r.url = n.url;
                    }
                    else {
                        r.nodeType = "data";
                    }
                    return r;
                };
                Dumper.prototype.visitLibraryRef = function (n) {
                    var _this = this;
                    return {
                        nodeType: "library",
                        name: n.getName(),
                        libIdentifier: n.getId(),
                        libIsPublished: n.isPublished(),
                        scriptName: n.resolved ? n.resolved.getName() : null,
                        exportedTypes: n.getPublicKinds().map(function (k) { return AST.Lexer.quoteId(k.getName()); }).join(" "),
                        exportedTypeDefs: n.getPublicKinds().map(function (k, i) {
                            if (k instanceof AST.LibraryRefAbstractKind)
                                return {
                                    nodeType: "libAbstractType",
                                    name: k.getName(),
                                    id: n.stableId + "$tp" + i
                                };
                            else if (k instanceof TDev.UserActionKind) {
                                var a = k.userAction;
                                var j = _this.visitActionCore(a, false);
                                j.nodeType = "libActionType";
                                return _this.fixupJson(a, j);
                            }
                            else if (k.getRecord()) {
                                var j = _this.toJson(k.getRecord());
                                j.nodeType = "libRecordType";
                                return j;
                            }
                            else {
                                TDev.Util.die();
                            }
                        }),
                        exportedActions: n.getPublicActions().map(function (a) {
                            var j = _this.visitActionCore(a, false);
                            j.nodeType = "libAction";
                            var p = a.parentLibrary();
                            if (p && p.isThis())
                                p = null;
                            j.parentLibId = _this.ref(p) || "";
                            return _this.fixupJson(a, j);
                        }),
                        resolveClauses: n.resolveClauses,
                    };
                };
                Dumper.prototype.visitRecordDef = function (n) {
                    return {
                        nodeType: "record",
                        name: n.getCoreName(),
                        sourceName: n.getName(),
                        comment: n.description,
                        category: n.getDefTerminology(),
                        isCloudEnabled: n.cloudEnabled,
                        isCloudPartiallyEnabled: n.cloudPartiallyEnabled,
                        isPersistent: n.persistent,
                        isExported: n.isExported(),
                        keys: n.keys,
                        fields: n.values,
                        unused: n.visitorState !== true,
                    };
                };
                Dumper.prototype.visitLocalDef = function (n) {
                    return {
                        name: n.getName(),
                        type: n.getKind(),
                        isByRef: n.isByRef(),
                    };
                };
                Dumper.prototype.visitApp = function (n) {
                    var _this = this;
                    n.stableId = "app";
                    var r = {
                        textVersion: AST.App.currentVersion,
                        jsonVersion: this.shortMode ? Dumper.shortVersion : Dumper.version,
                        name: n.getName(),
                        comment: n.comment,
                        icon: n.icon,
                        color: n.color,
                        iconArtId: n.iconArtId,
                        spashArtId: n.splashArtId,
                        autoIcon: TDev.SVG.justName(n.iconPath()),
                        autoColor: n.htmlColor(),
                        platform: n.getCapabilityString(),
                        rootId: n.rootId,
                    };
                    AST.App.metaMapping.forEach(function (k) {
                        r[k] = !!n[k];
                    });
                    if (this.reflectionMode) {
                        r.decls = this.toJsons(n.actions().filter(function (a) { return !a.isPrivate; }));
                    }
                    else {
                        r.decls = this.toJsons(n.things);
                        r.deletedDecls = this.deletedDecls.map(function (d) {
                            var j = { name: d.getName() };
                            if (d instanceof AST.LibraryRefAction) {
                                var par = d.parentLibrary();
                                j.parentLibId = _this.ref(par);
                            }
                            return _this.fixupJson(d, j);
                        });
                    }
                    return r;
                };
                Dumper.prototype.visitKindBinding = function (n) {
                    return {
                        nodeType: "typeBinding",
                        name: n.formalName,
                        isExplicit: n.isExplicit,
                        type: n.actual
                    };
                };
                Dumper.prototype.visitActionBinding = function (n) {
                    var act = n.actual;
                    if (act && act.parentLibrary() && act.parentLibrary().deleted)
                        act.deleted = true;
                    if (!act) {
                        act = new AST.LibraryRefAction(n.actualLib);
                        act.deleted = true;
                        act.setName(n.actualName);
                    }
                    this.ref(act.parentLibrary());
                    return {
                        name: n.formalName,
                        isExplicit: n.isExplicit,
                        actionId: this.ref(act),
                    };
                };
                Dumper.prototype.visitResolveClause = function (n) {
                    return {
                        name: n.name,
                        defaultLibId: !n.defaultLib || n.defaultLib.isThis() ? null : this.ref(n.defaultLib),
                        withTypes: n.kindBindings,
                        withActions: n.actionBindings,
                    };
                };
                Dumper.prototype.visitRecordField = function (n) {
                    return {
                        nodeType: n.isKey ? "recordKey" : "recordField",
                        name: n.getName(),
                        type: n.dataKind,
                    };
                };
                Dumper.version = "v0.1,resolved";
                Dumper.shortVersion = "v1.1,resolved,short";
                return Dumper;
            })(AST.NodeVisitor);
            function shortToTokens(shortForm) {
                var uq = AST.idUrlUnquote;
                function oneToken(s) {
                    var v = s.slice(1);
                    switch (s[0]) {
                        case ",": return { nodeType: "operator", op: v };
                        case "#": return { nodeType: "propertyRef", declId: v };
                        case ".": return { nodeType: "propertyRef", name: uq(v) };
                        case "'": return { nodeType: "stringLiteral", value: uq(v) };
                        case "F":
                        case "T": return { nodeType: "booleanLiteral", value: (s[0] == "T") };
                        case "$": return { nodeType: "localRef", localId: v };
                        case ":": return { nodeType: "singletonRef", name: uq(v) };
                        case "?":
                            var cln = v.indexOf(':');
                            if (cln > 0)
                                return { nodeType: "placeholder", type: uq(v.slice(0, cln)), name: uq(v.slice(cln + 1)) };
                            else
                                return { nodeType: "placeholder", type: uq(v) };
                        default:
                            throw new Error("wrong short form: " + s);
                    }
                }
                if (!shortForm)
                    return [];
                return shortForm.split(" ").map(oneToken);
            }
            Json.shortToTokens = shortToTokens;
            function longToShort(t) {
                var q = AST.idUrlQuote;
                switch (t.nodeType) {
                    case "operator": return "," + t.op;
                    case "propertyRef":
                        if (t.declId !== undefined)
                            return "#" + t.declId;
                        else
                            return "." + q(t.name);
                    case "stringLiteral": return "'" + q(t.value);
                    case "booleanLiteral": return t.value ? "T" : "F";
                    case "localRef": return "$" + t.localId;
                    case "singletonRef": return ":" + q(t.name);
                    case "placeholder":
                        return "?" + q(t.type) + (t.name != null ? ":" + q(t.name) : "");
                    default:
                        TDev.Util.oops("wrong " + t.nodeType);
                }
            }
            Json.longToShort = longToShort;
            function serialize(j, skipIds) {
                if (skipIds === void 0) { skipIds = false; }
                var tw = AST.TokenWriter.forStorage();
                var lookup;
                var nodesById = {};
                var skipStmtIds = skipIds;
                function addNode(j) {
                    if (!j)
                        return;
                    if (Array.isArray(j))
                        j.forEach(addNode);
                    else if (j.nodeType) {
                        if (j.id)
                            nodesById[j.id] = j;
                        Object.keys(j).forEach(function (k) { return addNode(j[k]); });
                    }
                }
                addNode(j);
                function self(j) {
                    if (!j.nodeType)
                        TDev.Util.oops("no node type");
                    if (lookup.hasOwnProperty(j.nodeType))
                        lookup[j.nodeType](j);
                    else
                        TDev.Util.oops("unhandled nodeType: " + j.nodeType);
                }
                function selfEh(n, j) {
                    if (typeof j == "string") {
                        var sj = j;
                        j = { nodeType: "exprHolder", tokens: shortToTokens(sj) };
                    }
                    self(j);
                }
                function lines(js) {
                    js.forEach(function (n) {
                        self(n);
                        tw.nl();
                    });
                }
                function block(js) {
                    tw.beginBlock();
                    var isElseIf = function (n) { return n && n.nodeType == "if" && n.isElseIf; };
                    for (var i = 0; i < js.length; ++i) {
                        var s = js[i];
                        if (s.nodeType == "if" && isElseIf(js[i + 1])) {
                            var si = s;
                            self(si);
                            var numOpen = 0;
                            while (true) {
                                tw.keyword("else").op("{");
                                numOpen++;
                                if (!isElseIf(js[i + 1]))
                                    break;
                                i++;
                                si = js[i];
                                self(si);
                                if (!isEmptyBlock(si.elseBody))
                                    break;
                            }
                            while (numOpen-- > 0)
                                tw.op("}");
                            tw.nl();
                        }
                        else {
                            self(s);
                        }
                    }
                    tw.endBlock();
                }
                function jsonKind(k) {
                    if (k.g) {
                        kind(k.g);
                        if (k.a) {
                            tw.op0("[");
                            k.a.forEach(function (a, i) {
                                if (i > 0)
                                    tw.op(",");
                                jsonKind(a);
                            });
                            tw.op0("]");
                        }
                    }
                    else if (k.o) {
                        if (k.l) {
                            var nn = findNode(k.l);
                            tw.op(AST.libSymbol).id(nn.name).op("\u2192").id(k.o);
                        }
                        else
                            tw.op0("*").id(k.o);
                    }
                    else if (typeof k === "string") {
                        tw.id(k);
                    }
                    else {
                        TDev.Util.oops("bad kind: " + JSON.stringify(k));
                    }
                }
                function kind(k) {
                    if (typeof k === "string") {
                        var s = k;
                        if (s[0] == "{" || s[0] == '"')
                            jsonKind(JSON.parse(s));
                        else
                            tw.id(s);
                    }
                    else
                        jsonKind(k);
                }
                function actionParms(a) {
                    function writeParms(ps) {
                        ps.forEach(function (p, i) {
                            if (i > 0)
                                tw.op0(",").space();
                            stmt(p);
                            tw.id(p.name).op(":");
                            kind(p.type);
                        });
                    }
                    tw.op0("(");
                    writeParms(a.inParameters);
                    tw.op0(")");
                    if (a.outParameters.length > 0) {
                        tw.keyword("returns").op0("(");
                        writeParms(a.outParameters);
                        tw.op0(")");
                    }
                    tw.nl();
                }
                function decl(d) {
                    if (!skipIds)
                        tw.uniqueId(d.id);
                }
                function stmt(s) {
                    if (!skipStmtIds)
                        tw.uniqueId(s.id);
                }
                function actionHeader(a) {
                    decl(a);
                    tw.keyword(a.nodeType == "event" ? "event" : "action");
                    if (a.nodeType == "libAction" || a.nodeType == "libActionType")
                        tw.op(a.isAsync ? "async" : "sync");
                    if (a.nodeType == "libActionType" || a.nodeType == "actionType")
                        tw.op("type");
                    tw.id(a.name);
                    actionParms(a);
                }
                function actionMeta(a) {
                    if (a.isPrivate)
                        tw.keyword("meta").keyword("private").op0(";").nl();
                    if (a.nodeType == "page")
                        tw.keyword("meta").keyword("page").op0(";").nl();
                    if (a.isOffline)
                        tw.keyword("meta").keyword("offline").op0(";").nl();
                    if (a.isQuery)
                        tw.keyword("meta").keyword("query").op0(";").nl();
                    if (a.isTest)
                        tw.keyword("meta").keyword("test").op0(";").nl();
                    if (!a.isAsync)
                        tw.keyword("meta").keyword("sync").op0(";").nl();
                }
                function libRef(n) {
                    return tw.op(AST.libSymbol).id(n);
                }
                function findNode(id) {
                    var i = id;
                    if (nodesById.hasOwnProperty(i))
                        return nodesById[i];
                    return null;
                }
                function stringForm(n) {
                    var s = n.stringForm;
                    if (!s || (typeof n.value == "number" && parseFloat(s) !== n.value)) {
                        s = TDev.Util.numberToStringNoE(n.value);
                        if (/e/.test(s))
                            TDev.Util.oops("too big of a number in flattening; sorry, not implemented yet");
                    }
                    return s.split("");
                }
                function flatten(e0) {
                    var r = [];
                    function pushOp(c) {
                        r.push({
                            nodeType: "operator",
                            id: "",
                            op: c
                        });
                    }
                    function call(e, outPrio) {
                        var infixPri = 0;
                        var k = AST.api.getKind(e.parent || "");
                        if (k) {
                            var p = k.getProperty(e.name || "");
                            if (p)
                                infixPri = p.getInfixPriority() || 0;
                        }
                        if (infixPri) {
                            if (e.name == "-" && (e.args[0].nodeType == "numberLiteral") && (e.args[0].value === 0.0) && (!e.args[0].stringForm)) {
                                pushOp(e.name);
                                rec(e.args[1], 98);
                                return;
                            }
                            if (infixPri < outPrio)
                                pushOp("(");
                            if (e.args.length == 1) {
                                pushOp(e.name);
                                rec(e.args[0], infixPri);
                            }
                            else {
                                var bindLeft = infixPri != 4 && infixPri != 98;
                                rec(e.args[0], bindLeft ? infixPri : infixPri + 0.1);
                                pushOp(e.name);
                                rec(e.args[1], !bindLeft ? infixPri : infixPri + 0.1);
                            }
                            if (infixPri < outPrio)
                                pushOp(")");
                        }
                        else {
                            rec(e.args[0], 1000);
                            r.push({
                                nodeType: "propertyRef",
                                name: e.name,
                                parent: e.parent,
                                declId: e.declId,
                            });
                            if (e.args.length > 1) {
                                pushOp("(");
                                e.args.slice(1).forEach(function (ee, i) {
                                    if (i > 0)
                                        pushOp(",");
                                    rec(ee, -1);
                                });
                                pushOp(")");
                            }
                        }
                    }
                    function rec(e, prio) {
                        switch (e.nodeType) {
                            case "call":
                                call(e, prio);
                                break;
                            case "numberLiteral":
                                stringForm(e).forEach(pushOp);
                                break;
                            case "stringLiteral":
                            case "booleanLiteral":
                            case "localRef":
                            case "placeholder":
                            case "singletonRef":
                                r.push(e);
                                break;
                            case "show":
                            case "break":
                            case "return":
                            case "continue":
                                pushOp(e.nodeType);
                                var ee = e.expr;
                                if (ee)
                                    rec(ee, prio);
                                break;
                            default:
                                TDev.Util.oops("invalid nodeType when flattning: " + e.nodeType);
                        }
                    }
                    rec(e0, -1);
                    return r;
                }
                var isDigit = function (o) { return o && o.nodeType == "operator" && /^[0-9\.]$/.test(o.op); };
                lookup = {
                    "stringLiteral": function (n) {
                        tw.string(n.value);
                    },
                    "booleanLiteral": function (n) {
                        tw.id(n.value ? "true" : "false");
                    },
                    "numberLiteral": function (n) {
                        stringForm(n).forEach(function (v) { return tw.op(v); });
                    },
                    "libAbstractType": function (n) {
                        tw.keyword("type").sep().id(n.name).nl();
                    },
                    "libActionType": function (n) {
                        actionHeader(n);
                    },
                    "libRecordType": function (n) {
                        lookup.record(n);
                    },
                    "actionType": function (n) {
                        lookup.action(n);
                    },
                    "library": function (n) {
                        decl(n);
                        tw.keyword("meta").id("import").id(n.name);
                        tw.beginBlock();
                        tw.id(n.libIsPublished ? "pub" : "guid").string(n.libIdentifier).nl();
                        tw.id("usage");
                        tw.beginBlock();
                        var exp = n.exportedTypeDefs || [];
                        exp.forEach(self);
                        n.exportedActions.forEach(actionHeader);
                        tw.nl();
                        tw.endBlock();
                        n.resolveClauses.forEach(self);
                        tw.endBlock();
                    },
                    "resolveClause": function (r) {
                        stmt(r);
                        tw.id("resolve").id(r.name).op("=");
                        if (!r.defaultLibId)
                            libRef("this");
                        else
                            libRef(findNode(r.defaultLibId).name);
                        tw.id("with");
                        tw.beginBlock();
                        r.withTypes.forEach(self);
                        r.withActions.forEach(self);
                        tw.endBlock();
                    },
                    "typeBinding": function (n) {
                        if (n.isExplicit) {
                            stmt(n);
                            tw.keyword("type").id(n.name).op("=");
                            kind(n.type);
                        }
                    },
                    "actionBinding": function (n) {
                        if (n.isExplicit) {
                            stmt(n);
                            tw.keyword("action").id(n.name).op("=");
                            var a = findNode(n.actionId);
                            libRef(a.parentLibId ? findNode(a.parentLibId).name : "this");
                            tw.op("\u2192").id(a.name).nl();
                        }
                    },
                    "record": function (n) {
                        decl(n);
                        tw.keyword("table").id(n.name);
                        tw.beginBlock();
                        if (n.comment)
                            tw.comment(n.comment);
                        tw.stringAttr("type", TDev.Util.capitalizeFirst(n.category));
                        tw.boolOptAttr("cloudenabled", n.isCloudEnabled);
                        tw.boolOptAttr("cloudpartiallyenabled", n.isCloudPartiallyEnabled);
                        tw.boolOptAttr("exported", n.isExported);
                        tw.boolAttr("persistent", n.isPersistent);
                        if (n.keys.length > 0) {
                            tw.id("keys");
                            block(n.keys);
                        }
                        if (n.fields.length > 0) {
                            tw.id("fields");
                            block(n.fields);
                        }
                        tw.endBlock();
                    },
                    "recordKey": function (n) {
                        lookup.recordField(n);
                    },
                    "recordField": function (n) {
                        if (!skipIds)
                            tw.uniqueId(n.id);
                        tw.id(n.name).op(":");
                        kind(n.type);
                        tw.nl();
                    },
                    "data": function (n) {
                        lookup.art(n);
                    },
                    "art": function (n) {
                        decl(n);
                        tw.keyword("var").id(n.name).op(":");
                        kind(n.type);
                        tw.beginBlock();
                        if (!!n.comment)
                            tw.comment(n.comment);
                        tw.boolOptAttr("readonly", n.isReadonly);
                        tw.boolOptAttr("is_resource", n.nodeType == "art");
                        tw.boolOptAttr("transient", n.isTransient);
                        tw.boolOptAttr("cloudenabled", n.isCloudEnabled);
                        if (!!n.url)
                            tw.stringAttr("url", n.url);
                        tw.endBlock();
                    },
                    "page": function (n) {
                        actionHeader(n);
                        tw.beginBlock();
                        if (!skipStmtIds)
                            tw.uniqueId(n.initBodyId);
                        tw.keyword("if").id("box").op("->").id("is init").keyword("then");
                        block(n.initBody);
                        if (!skipStmtIds)
                            tw.uniqueId(n.displayBodyId);
                        tw.keyword("if").id("true").keyword("then");
                        block(n.displayBody);
                        actionMeta(n);
                        tw.endBlock();
                    },
                    "action": function (n) {
                        actionHeader(n);
                        block(n.body);
                        tw.backspaceBlockEnd();
                        actionMeta(n);
                        tw.endBlock();
                    },
                    "event": function (n) {
                        lookup.action(n);
                    },
                    "localDef": function (n) {
                        TDev.Util.die();
                    },
                    "app": function (n) {
                        if (!n.hasIds)
                            skipStmtIds = true;
                        tw.meta("version", AST.App.currentVersion);
                        tw.meta("name", n.name);
                        tw.metaOpt("icon", n.icon);
                        if (n.color)
                            tw.metaOpt("color", /^#......$/.test(n.color) ? "#ff" + n.color.slice(1) : n.color);
                        AST.App.metaMapping.forEach(function (k) {
                            tw.metaOpt(k, n[k] ? "yes" : "");
                        });
                        tw.meta("platform", n.platform);
                        tw.meta("rootId", n.rootId);
                        if (!!n.comment)
                            tw.comment(n.comment);
                        n.decls.forEach(self);
                    },
                    "comment": function (n) {
                        stmt(n);
                        tw.comment(n.text);
                    },
                    "for": function (n) {
                        stmt(n);
                        var idx = n.index || n.locals[0];
                        tw.keyword("for").op("0").op("\u2264").id(idx.name).op("<");
                        selfEh(n, n.bound);
                        tw.keyword("do");
                        block(n.body);
                    },
                    "foreach": function (n) {
                        stmt(n);
                        var idx = n.iterator || n.locals[0];
                        tw.keyword("foreach").id(idx.name).keyword("in");
                        selfEh(n, n.collection);
                        tw.nl();
                        n.conditions.forEach(self);
                        tw.keyword("do");
                        block(n.body);
                    },
                    "where": function (n) {
                        stmt(n);
                        tw.keyword("where");
                        selfEh(n, n.condition);
                        tw.nl();
                    },
                    "while": function (n) {
                        stmt(n);
                        tw.keyword("while");
                        selfEh(n, n.condition);
                        tw.keyword("do");
                        block(n.body);
                    },
                    "if": function (n) {
                        stmt(n);
                        tw.keyword("if");
                        selfEh(n, n.condition);
                        tw.keyword("then");
                        block(n.thenBody);
                        if (!isEmptyBlock(n.elseBody)) {
                            tw.keyword("else");
                            block(n.elseBody);
                        }
                    },
                    "boxed": function (n) {
                        stmt(n);
                        tw.keyword("do").id("box");
                        block(n.body);
                    },
                    "exprStmt": function (n) {
                        stmt(n);
                        if (isPlaceholder(n.expr))
                            tw.keyword("skip");
                        else
                            selfEh(n, n.expr);
                        tw.op0(";").nl();
                    },
                    "inlineActions": function (n) {
                        lookup.exprStmt(n);
                        n.actions.forEach(self);
                    },
                    "inlineAction": function (n) {
                        var idx = n.reference || n.locals[0];
                        stmt(n);
                        tw.keyword("where");
                        if (n.isImplicit)
                            tw.op("implicit");
                        if (n.isOptional)
                            tw.op("optional");
                        tw.id(idx.name);
                        actionParms(n);
                        block(n.body);
                    },
                    "optionalParameter": function (n) {
                        stmt(n);
                        tw.keyword("where").id(n.declId ? findNode(n.declId).name : n.name).op(":=");
                        selfEh(n, n.expr);
                        tw.op0(";").nl();
                    },
                    "exprHolder": function (n) {
                        if (n.tree && !n.tokens) {
                            n.tokens = flatten(n.tree);
                        }
                        if (n.tokens.length == 0) {
                            tw.op("...");
                        }
                        else {
                            var prev = null;
                            n.tokens.forEach(function (t) {
                                if (isDigit(t)) {
                                    if (!isDigit(prev))
                                        tw.sep();
                                    tw.op0(t.op);
                                }
                                else {
                                    self(t);
                                }
                                prev = t;
                            });
                        }
                    },
                    "operator": function (n) {
                        tw.op(n.op);
                    },
                    "propertyRef": function (n) {
                        if (n.declId) {
                            var d = findNode(n.declId);
                            if (d) {
                                var cat = d.category || "object";
                                var nm = d.name;
                                if (cat == "decorator" && d.keys[0]) {
                                    var tp = d.keys[0].type;
                                    if (tp[0] == '{') {
                                        var kk = JSON.parse(tp);
                                        if (!kk.o)
                                            TDev.Util.oops("complex decorator: " + tp);
                                        else
                                            tp = kk.o;
                                    }
                                    nm = tp + " decorator";
                                }
                                else if (cat != "object") {
                                    nm = nm + " " + cat;
                                }
                                tw.sep().op0("\u2192").id0(nm);
                                return;
                            }
                        }
                        tw.sep().op0("\u2192").id0(n.name == null ? "<unbound>" : n.name);
                    },
                    "singletonRef": function (n) {
                        tw.id(n.name);
                        if (n.libraryName)
                            tw.op0("[").id("lib").id(n.libraryName).op0("]");
                    },
                    "localRef": function (n) {
                        tw.sep().op0("$");
                        if (n.localId)
                            tw.id0(findNode(n.localId).name);
                        else
                            tw.id0(n.name);
                    },
                    "placeholder": function (n) {
                        tw.id(AST.ThingRef.placeholderPrefix + n.type + (n.name ? ":" + n.name : ""));
                    },
                    "call": function (n) {
                        TDev.Util.die();
                    },
                };
                self(j);
                var scriptText = tw.finalize();
                return scriptText;
            }
            Json.serialize = serialize;
            function reflectionInfo(a) {
                var d = new Dumper(false);
                d.reflectionMode = true;
                var res = [];
                a.librariesAndThis().map(function (l) {
                    if (l.resolved) {
                        var r = d.toJson(l.resolved);
                        r.libraryName = l.getName();
                        r.libraryId = l.getStableName();
                        res.push(r);
                    }
                });
                return res;
            }
            Json.reflectionInfo = reflectionInfo;
        })(Json = AST.Json || (AST.Json = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var FeatureDetector = (function (_super) {
            __extends(FeatureDetector, _super);
            function FeatureDetector() {
                _super.apply(this, arguments);
                this.features = { script: 1 };
                this.stmtCount = 0;
                this.includeCaps = false;
                this.anonBrowser = true;
            }
            FeatureDetector.prototype.use = function (feature) {
                if (!feature)
                    return;
                var n = this.features[feature] || 0;
                this.features[feature] = n + 1;
            };
            FeatureDetector.prototype.visitAstNode = function (n) {
                _super.prototype.visitChildren.call(this, n);
            };
            FeatureDetector.prototype.visitExprHolder = function (eh) {
                _super.prototype.visitExprHolder.call(this, eh);
                if (eh.parsed)
                    this.dispatch(eh.parsed);
            };
            FeatureDetector.prototype.visitCall = function (c) {
                var _this = this;
                _super.prototype.visitCall.call(this, c);
                var p = c.prop();
                if (this.libroots) {
                    var act = c.calledExtensionAction();
                    if (!act)
                        act = c.calledAction();
                    if (act instanceof AST.LibraryRefAction) {
                        var lib = this.libroots(act.parentLibrary().getId());
                        if (lib) {
                            this.use("l:" + lib + ":" + act.getName());
                        }
                    }
                }
                if (c.referencedRecordField() || c.referencedData() || c.calledExtensionAction()) {
                }
                else if (p.forwardsTo() || p.forwardsToStmt()) {
                }
                else if (p == AST.api.core.AssignmentProp) {
                    this.use("assignment");
                }
                else if (p == AST.api.core.TupleProp) {
                }
                else if (p.parentKind instanceof AST.RecordEntryKind || p.parentKind instanceof AST.RecordDefKind) {
                }
                else if (p) {
                    this.use(p.helpTopic());
                    if (p.parentKind)
                        this.use(p.parentKind.helpTopic());
                    var cap = p.getCapability();
                    if (cap & ~(1 /* Accelerometer */ | 524288 /* MusicAndSounds */))
                        this.anonBrowser = false;
                    if (this.includeCaps) {
                        if (cap)
                            AST.App.capabilityString(p.getCapability()).split(/,/).forEach(function (k) {
                                _this.use(TDev.Util.tagify("cap " + k));
                            });
                    }
                }
            };
            FeatureDetector.prototype.visitWhere = function (w) {
                _super.prototype.visitStmt.call(this, w);
                if (w.condition.tokens.length > 1)
                    this.use("where");
            };
            FeatureDetector.prototype.visitStmt = function (s) {
                _super.prototype.visitStmt.call(this, s);
                if (s instanceof AST.Block)
                    return;
                if (s instanceof AST.ActionHeader)
                    return;
                if (!s.isPlaceholder())
                    this.stmtCount++;
                this.use(s.helpTopic());
            };
            FeatureDetector.prototype.visitDecl = function (d) {
                _super.prototype.visitChildren.call(this, d);
                this.use(d.helpTopic());
            };
            FeatureDetector.prototype.visitApp = function (a) {
                _super.prototype.visitApp.call(this, a);
                if (a.isLibrary)
                    this.use("library");
                if (a.useCppCompiler)
                    this.use("cppCompiler");
                if (a.isCloud)
                    this.use("cloud");
                if (this.includeCaps && this.anonBrowser)
                    this.use("anonBrowser");
            };
            FeatureDetector.bucketId = function (features) {
                var f = TDev.Util.clone(features);
                delete f['assignment'];
                delete f['commands'];
                delete f['var'];
                var kk = Object.keys(f);
                kk.sort(TDev.Util.stringCompare);
                return kk.map(function (k) { return k + ":" + f[k]; }).join(",");
            };
            FeatureDetector.astInfo = function (a, libroots, flags) {
                if (libroots === void 0) { libroots = null; }
                if (flags === void 0) { flags = null; }
                var fd = new FeatureDetector();
                fd.libroots = libroots;
                if (!flags)
                    flags = {};
                if (TDev.Runtime.stringToBoolean(flags["caps"]))
                    fd.includeCaps = true;
                fd.dispatch(a);
                var b = FeatureDetector.bucketId(fd.features);
                fd.features['anystmt'] = fd.stmtCount;
                fd.features['anycode'] = a.allActions().length;
                return {
                    features: fd.features,
                    bucketId: b,
                };
            };
            return FeatureDetector;
        })(AST.NodeVisitor);
        AST.FeatureDetector = FeatureDetector;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Diff;
        (function (Diff) {
            var RandomIdSetter = (function (_super) {
                __extends(RandomIdSetter, _super);
                function RandomIdSetter() {
                    _super.apply(this, arguments);
                    this.definedLocals = {};
                    this.keep = false;
                }
                RandomIdSetter.prototype.makeId = function (defl) {
                    if (this.keep && defl)
                        return (this.lastId = defl);
                    return (this.lastId = AST.uniqueAstId(16));
                };
                RandomIdSetter.prototype.visitLocalDef = function (l) {
                };
                RandomIdSetter.prototype.setDeclId = function (d) {
                    if (d instanceof AST.RecordDef && d.getStableName() && !/_/.test(d.getStableName())) {
                        d.stableId = d.getStableName();
                    }
                    else if (!this.keep || !d.stableId) {
                        d.stableId = this.makeId(d.stableId);
                    }
                };
                RandomIdSetter.prototype.visitDecl = function (d) {
                    this.setDeclId(d);
                    this.visitChildren(d);
                };
                RandomIdSetter.prototype.visitLibraryRef = function (l) {
                    var _this = this;
                    l.getPublicActions().forEach(function (a) {
                        _this.visitAction(a);
                    });
                    _super.prototype.visitLibraryRef.call(this, l);
                };
                RandomIdSetter.prototype.visitExprHolder = function (eh) {
                    var _this = this;
                    var locs = [];
                    eh.tokens.forEach(function (t) {
                        var tt = t.getThing();
                        if (tt instanceof AST.LocalDef) {
                            var l = tt;
                            TDev.Util.assert(!!l.stableId);
                            if (locs.indexOf(l) < 0 && !_this.definedLocals.hasOwnProperty(l.stableId))
                                locs.push(l);
                        }
                    });
                    eh.definedLocals = locs;
                    locs.forEach(function (l, i) { return _this.defineLocal(l, _this.lastId + "L" + i); });
                    this.makeId(null);
                };
                RandomIdSetter.prototype.visitStmt = function (s) {
                    s.stableId = this.makeId(s.stableId);
                    this.visitChildren(s);
                };
                RandomIdSetter.prototype.visitInlineActions = function (n) {
                    n.stableId = this.makeId(n.stableId);
                    this.dispatch(n.actions);
                    this.dispatch(n.expr);
                };
                RandomIdSetter.prototype.visitInlineAction = function (n) {
                    var _this = this;
                    n.stableId = this.makeId(n.stableId);
                    this.defineLocal(n.name, n.stableId + "B0");
                    n.inParameters.concat(n.outParameters).forEach(function (p, i) {
                        _this.defineLocal(p, n.stableId + "P" + i);
                    });
                    this.visitChildren(n);
                };
                RandomIdSetter.prototype.visitForeach = function (n) {
                    n.stableId = this.makeId(n.stableId);
                    this.defineLocal(n.boundLocal, n.stableId + "B0");
                    this.visitChildren(n);
                };
                RandomIdSetter.prototype.visitFor = function (n) {
                    n.stableId = this.makeId(n.stableId);
                    this.defineLocal(n.boundLocal, n.stableId + "B0");
                    this.visitChildren(n);
                };
                RandomIdSetter.prototype.defineLocal = function (l, id) {
                    this.definedLocals[id] = true;
                    l.stableId = id;
                };
                RandomIdSetter.prototype.visitAction = function (a) {
                    var _this = this;
                    this.setDeclId(a);
                    this.definedLocals = {};
                    a.getInParameters().concat(a.getOutParameters()).forEach(function (p, i) {
                        _this.defineLocal(p.local, a.stableId + "P" + i);
                    });
                    if (a.modelParameter)
                        this.defineLocal(a.modelParameter.local, a.stableId + "PM");
                    a.allLocals.forEach(function (l) {
                        if (!l.stableId)
                            l.stableId = _this.makeId(null);
                    });
                    this.visitChildren(a);
                };
                RandomIdSetter.prototype.visitRecordField = function (d) {
                    d.stableId = !d.getStableName() || /_/.test(d.getStableName()) ? this.makeId(d.stableId) : d.getStableName();
                    this.visitChildren(d);
                };
                return RandomIdSetter;
            })(AST.NodeVisitor);
            var DiffFeatureDetector = (function (_super) {
                __extends(DiffFeatureDetector, _super);
                function DiffFeatureDetector(options) {
                    _super.call(this);
                    this.options = options;
                }
                DiffFeatureDetector.approxName = function (s) {
                    return s.toLowerCase().replace(/\s/g, "");
                };
                DiffFeatureDetector.prototype.visitThingRef = function (t) {
                    _super.prototype.visitThingRef.call(this, t);
                    if (t.def instanceof AST.LocalDef)
                        this.use("local:" + t.def.getName());
                    else if (t.def instanceof AST.SingletonDef)
                        this.use("singl:" + t.def.getName());
                };
                DiffFeatureDetector.prototype.visitLiteral = function (l) {
                    _super.prototype.visitLiteral.call(this, l);
                    var d = l.data;
                    switch (typeof d) {
                        case "string":
                            this.use("stringLiteral:" + d);
                            var len = d.length;
                            this.use("stringLiteralLen10:" + Math.round(len / 10));
                            this.use("stringLiteralLen100:" + Math.round(len / 100));
                            break;
                        case "number":
                            this.use("numberLiteral:" + d.toString());
                            break;
                        case "boolean":
                            this.use(d ? "true" : "false");
                            break;
                    }
                };
                DiffFeatureDetector.prototype.visitCall = function (c) {
                    _super.prototype.visitCall.call(this, c);
                    var act = c.calledExtensionAction();
                    if (!act)
                        act = c.calledAction();
                    if (act instanceof AST.LibraryRefAction) {
                        this.use("libact:" + act.getName());
                        return;
                    }
                    var fld = c.referencedRecordField();
                    if (fld) {
                        if (this.options.approxNameMatching)
                            this.use("decl:" + DiffFeatureDetector.approxName(fld.getName()));
                        else
                            this.use("decl:" + fld.stableId);
                        return;
                    }
                    var p = c.prop();
                    if (p.parentKind instanceof AST.RecordEntryKind || p.parentKind instanceof AST.RecordDefKind) {
                        this.use("recordProp:" + p.getName());
                    }
                    var decl = c.prop().forwardsTo();
                    if (decl) {
                        if (this.options.approxNameMatching)
                            this.use("decl:" + DiffFeatureDetector.approxName(decl.getName()));
                        else
                            this.use("decl:" + decl.stableId);
                    }
                };
                DiffFeatureDetector.prototype.visitOperator = function (op) {
                    this.use("op:" + op.data);
                };
                DiffFeatureDetector.prototype.visitComment = function (c) {
                    var _this = this;
                    c.text.split(/\s+/).forEach(function (s) {
                        _this.use("commentWord:" + s);
                    });
                };
                DiffFeatureDetector.prototype.kind = function (k) {
                    return k.toString();
                };
                DiffFeatureDetector.prototype.visitRecordField = function (r) {
                    _super.prototype.visitRecordField.call(this, r);
                    this.use("recordFieldName:" + r.getName());
                    this.use("recordFieldKind:" + this.kind(r.dataKind));
                };
                DiffFeatureDetector.run = function (n, opt) {
                    var d = new DiffFeatureDetector(opt);
                    d.dispatch(n);
                    var f = d.features;
                    Object.keys(f).forEach(function (k) {
                        if (/^numberLiteral:/.test(k) || /^op:[0-9]/.test(k))
                            f[k] = f[k] * 0.2;
                    });
                    if (opt.tutorialMode && f["var"]) {
                        f["commands"] = f["var"];
                        f["var"] = 0;
                    }
                    return f;
                };
                DiffFeatureDetector.cmp = function (a, b) {
                    var ka = Object.keys(a);
                    var similarity = 0;
                    var dissimilarity = 0;
                    for (var i = 0; i < ka.length; ++i) {
                        var k = ka[i];
                        var va = a[k];
                        var vb = 0;
                        if (b.hasOwnProperty(k)) {
                            vb = b[k];
                            similarity += Math.min(va, vb);
                        }
                        dissimilarity += Math.abs(va - vb);
                    }
                    var ka = Object.keys(b);
                    for (var i = 0; i < ka.length; ++i) {
                        var k = ka[i];
                        if (!a.hasOwnProperty(k)) {
                            dissimilarity += b[k];
                        }
                    }
                    return similarity - dissimilarity / 2;
                };
                DiffFeatureDetector.updateSize = function (a, b, tutorialMode) {
                    var ka = Object.keys(a);
                    var similarity = 0;
                    var dissimilarity = 0;
                    for (var i = 0; i < ka.length; ++i) {
                        var k = ka[i];
                        var va = a[k];
                        var vb = 0;
                        if (b.hasOwnProperty(k)) {
                            vb = b[k];
                            similarity += Math.min(va, vb);
                        }
                        dissimilarity += Math.abs(va - vb);
                    }
                    var ka = Object.keys(b);
                    for (var i = 0; i < ka.length; ++i) {
                        var k = ka[i];
                        if (!a.hasOwnProperty(k)) {
                            dissimilarity += b[k];
                        }
                    }
                    return dissimilarity;
                };
                return DiffFeatureDetector;
            })(AST.FeatureDetector);
            function classify(d) {
                var r = d.nodeType();
                switch (r) {
                    case "action":
                        var a = d;
                        if (a.isEvent())
                            return "event:" + a.eventInfo.type.category;
                        if (a.isPage())
                            return "page";
                        break;
                    case "globalDef":
                        return d.isResource ? "art" : "data";
                }
                return r;
            }
            function setId(t, id) {
                t.stableId = id;
                if (t instanceof AST.RecordField) {
                    var f = t;
                    if (!f.def().persistent)
                        f.setStableName(id);
                }
                else if (t instanceof AST.RecordDef) {
                    if (!t.persistent)
                        t.setStableName(id);
                }
            }
            function matchDecls(older, newer, opts) {
                var olderByStable = TDev.Util.toDictionary(older.things, function (t) { return t.getStableName(); });
                var olderByName = TDev.Util.toDictionary(older.things, function (t) { return t.getName(); });
                var assignedIds = {};
                var missing = newer.things.filter(function (t) {
                    var ot = null;
                    if (opts.useStableNames && t.getStableName() && !newer.syntheticIds[t.getStableName()] && olderByStable.hasOwnProperty(t.getStableName()))
                        ot = olderByStable[t.getStableName()];
                    if (!ot && olderByName.hasOwnProperty(t.getName()))
                        ot = olderByName[t.getName()];
                    if (ot && classify(ot) == classify(t)) {
                        setId(t, ot.stableId);
                        assignedIds[ot.stableId] = true;
                        delete olderByName[t.getName()];
                        return false;
                    }
                    else {
                        return true;
                    }
                });
                var olderClassified = TDev.Util.groupBy(older.things.filter(function (t) { return !assignedIds[t.stableId]; }), classify);
                var newerClassified = TDev.Util.groupBy(missing, classify);
                var getFeatures = TDev.Util.memoizeHashed(function (d) { return d.stableId; }, function (d) { return DiffFeatureDetector.run(d, opts); });
                Object.keys(newerClassified).forEach(function (k) {
                    var ns = newerClassified[k];
                    var os = olderClassified[k];
                    if (!os)
                        return;
                    var matches = [];
                    ns.forEach(function (n) {
                        var fn = getFeatures(n);
                        os.forEach(function (o) {
                            var score = DiffFeatureDetector.cmp(getFeatures(o), fn);
                            if (score > 0)
                                matches.push({
                                    score: score,
                                    n: n,
                                    o: o,
                                });
                        });
                    });
                    matches.sort(function (a, b) { return b.score - a.score; });
                    matches.forEach(function (m) {
                        if (assignedIds[m.o.stableId] || assignedIds[m.n.stableId])
                            return;
                        setId(m.n, m.o.stableId);
                        assignedIds[m.o.stableId] = true;
                    });
                });
            }
            function matchBlocks(oldStmts, newStmts, opts) {
                if (oldStmts.length == 0 && newStmts.length == 0)
                    return;
                oldStmts.forEach(function (s) {
                    s.diffFeatures = DiffFeatureDetector.run(s, opts);
                });
                newStmts.forEach(function (s, i) {
                    s.diffFeatures = DiffFeatureDetector.run(s, opts);
                    if (opts.tutorialMode)
                        s.diffFeatures.positionWeight = ((newStmts.length - i) / newStmts.length) * 0.5;
                    else
                        s.diffFeatures.positionWeight = 0;
                });
                var getFeatures = function (s) {
                    if (!s)
                        return {};
                    return s.diffFeatures;
                };
                var cmp = function (a, b) {
                    var off = 0;
                    if (a && b && classify(a) != classify(b) && (!opts.placeholderOk || !a.isPlaceholder()))
                        off = 1e20;
                    var fa = getFeatures(a);
                    var fb = getFeatures(b);
                    if (!a)
                        off += fb.positionWeight;
                    return DiffFeatureDetector.updateSize(fa, fb, opts.tutorialMode) + off;
                };
                var diff = minimalUpdateDistance(oldStmts, newStmts, null, cmp);
                var firstAdded = -1;
                for (var i = 0; i < diff.length; i += 2) {
                    if (diff[i]) {
                        if (diff[i].isPlaceholder() && firstAdded != -1) {
                            diff[firstAdded] = diff[i];
                            diff[i] = null;
                            firstAdded = -1;
                        }
                        if (diff[i + 1])
                            firstAdded = -1;
                    }
                    else {
                        if (firstAdded == -1)
                            firstAdded = i;
                    }
                }
                for (var i = 0; i < diff.length; i += 2) {
                    if (diff[i] && diff[i + 1])
                        setId(diff[i + 1], diff[i].stableId);
                }
                var oldById = TDev.Util.toDictionary(oldStmts, function (s) { return s.stableId; });
                newStmts.forEach(function (s) {
                    var oldStmt = oldById[s.stableId];
                    if (oldStmt)
                        matchStmts(oldStmt, s, opts);
                });
            }
            function matchStmts(o, n, opts) {
                if (!n || !o)
                    return;
                if (classify(n) != classify(o))
                    return;
                if (o instanceof AST.Block) {
                    matchBlocks(o.stmts, n.stmts, opts);
                }
                else {
                    setId(n, o.stableId);
                    var ch0 = o.children();
                    var ch1 = n.children();
                    ch0.forEach(function (oo, i) {
                        if (oo instanceof AST.Stmt && ch1[i] instanceof AST.Stmt)
                            matchStmts(oo, ch1[i], opts);
                    });
                    if (o instanceof AST.LibraryRef) {
                        var actByName = TDev.Util.toDictionary(o.getPublicActions(), function (a) { return a.getName(); });
                        n.getPublicActions().forEach(function (a) {
                            var aa = actByName[a.getName()];
                            if (aa)
                                setId(a, aa.stableId);
                        });
                    }
                }
            }
            function matchActions(older, newer, opts) {
                var oldById = TDev.Util.toDictionary(older.things, function (t) { return t.stableId; });
                var th = [];
                newer.things.forEach(function (a) {
                    a.diffAltDecl = null;
                    var old = oldById[a.stableId];
                    if (!old)
                        return;
                    a.diffAltDecl = old;
                    th.push(a);
                });
                th.forEach(function (a) {
                    if (!(a instanceof AST.Action))
                        matchStmts(a.diffAltDecl, a, opts);
                });
                th.forEach(function (a) {
                    if (a instanceof AST.Action)
                        matchStmts(a.diffAltDecl, a, opts);
                });
            }
            function setLongIds(a) {
                var s = new RandomIdSetter();
                s.dispatch(a);
            }
            Diff.setLongIds = setLongIds;
            function prepApp(a) {
                a.isTopLevel = true;
                AST.TypeChecker.tcScript(a, true);
                setLongIds(a);
            }
            function matchIds(older, newer, opts) {
                prepApp(older);
                prepApp(newer);
                matchPreped(older, newer, opts);
            }
            function matchPreped(older, newer, opts) {
                matchDecls(older, newer, opts);
                matchActions(older, newer, opts);
                var s = new RandomIdSetter();
                s.keep = true;
                s.dispatch(newer);
            }
            function randTest() {
                for (var i = 0; i < 10; ++i) {
                    var a = TDev.Random.uint32() + "";
                    var b = TDev.Random.uint32() + "";
                    medTest(a, b);
                }
            }
            Diff.randTest = randTest;
            function medTest(s, t) {
                var res = minimalEditDistance(s.toUpperCase().split(""), t.toLowerCase().split(""), function (a, b) { return a.toUpperCase() == b.toUpperCase(); });
                var toStr = function () {
                    var p = "";
                    for (var i = 0; i < res.length; i += 2) {
                        if (res[i] && res[i + 1])
                            p += "=" + res[i] + res[i + 1];
                        else if (res[i])
                            p += "-" + res[i];
                        else
                            p += "+" + res[i + 1];
                    }
                    return p;
                };
                var r0 = toStr();
                res = minimalUpdateDistance(s.toUpperCase().split(""), t.toLowerCase().split(""), "", function (a, b) { return a == "" || b == "" ? 1 : a.toLowerCase() == b.toLowerCase() ? 0 : 2; });
                var r1 = toStr();
            }
            Diff.medTest = medTest;
            function minimalEditDistance(s, t, eq) {
                var m = s.length;
                var n = t.length;
                var d = new Array(m + 1);
                for (var i = 0; i <= m; ++i) {
                    d[i] = new Array(n + 1);
                    d[i][0] = i;
                }
                for (var j = 0; j <= n; ++j) {
                    d[0][j] = j;
                }
                for (var j = 0; j < n; ++j) {
                    for (var i = 0; i < m; ++i) {
                        if (eq(s[i], t[j])) {
                            d[i + 1][j + 1] = d[i][j];
                        }
                        else {
                            var del = d[i][j + 1] + 1;
                            var ins = d[i + 1][j] + 1;
                            var sub = d[i][j] + 2;
                            d[i + 1][j + 1] = Math.min(del, ins, sub);
                        }
                    }
                }
                var res = [];
                var i = m - 1;
                var j = n - 1;
                var lastDel = false;
                while (i >= 0 || j >= 0) {
                    var curr = d[i + 1][j + 1];
                    if (i >= 0 && j >= 0 && eq(s[i], t[j]) && curr == d[i][j]) {
                        res.push(t[j]);
                        res.push(s[i]);
                        i--;
                        j--;
                    }
                    else {
                        var isDel = i >= 0 && curr == d[i][j + 1] + 1;
                        var isIns = j >= 0 && curr == d[i + 1][j] + 1;
                        if (isDel && lastDel)
                            isIns = false;
                        if (isIns && !lastDel)
                            isDel = false;
                        if (isDel) {
                            res.push(null);
                            res.push(s[i]);
                            i--;
                            lastDel = true;
                        }
                        else if (isIns) {
                            res.push(t[j]);
                            res.push(null);
                            j--;
                            lastDel = false;
                        }
                        else {
                            TDev.Util.assert(curr == d[i][j] + 2);
                            res.push(t[j]);
                            res.push(null);
                            res.push(null);
                            res.push(s[i]);
                            i--;
                            j--;
                            lastDel = true;
                        }
                    }
                }
                res.reverse();
                return res;
            }
            Diff.minimalEditDistance = minimalEditDistance;
            function minimalUpdateDistance(s, t, zero, cmp) {
                var m = s.length;
                var n = t.length;
                var d = new Array(m + 1);
                var ss = s.map(function (e) { return cmp(e, zero); });
                var tt = t.map(function (e) { return cmp(zero, e); });
                for (var i = 0; i <= m; ++i) {
                    d[i] = new Array(n + 1);
                    d[i][0] = i == 0 ? 0 : (d[i - 1][0] + ss[i - 1]);
                }
                for (var j = 0; j <= n; ++j) {
                    d[0][j] = j == 0 ? 0 : (d[0][j - 1] + tt[j - 1]);
                }
                for (var j = 0; j < n; ++j) {
                    for (var i = 0; i < m; ++i) {
                        var del = d[i][j + 1] + ss[i];
                        var ins = d[i + 1][j] + tt[j];
                        var sub = d[i][j] + cmp(s[i], t[j]);
                        var su2 = d[i][j] + ss[i] + tt[j];
                        d[i + 1][j + 1] = Math.min(del, ins, sub);
                    }
                }
                var res = [];
                var i = m - 1;
                var j = n - 1;
                var lastDel = false;
                while (i >= 0 || j >= 0) {
                    var curr = d[i + 1][j + 1];
                    if (i >= 0 && j >= 0 && curr == d[i][j] + cmp(s[i], t[j])) {
                        res.push(t[j]);
                        res.push(s[i]);
                        i--;
                        j--;
                    }
                    else {
                        var isDel = i >= 0 && curr == d[i][j + 1] + ss[i];
                        var isIns = j >= 0 && curr == d[i + 1][j] + tt[j];
                        if (isDel && lastDel)
                            isIns = false;
                        if (isIns && !lastDel)
                            isDel = false;
                        if (isDel) {
                            res.push(null);
                            res.push(s[i]);
                            i--;
                            lastDel = true;
                        }
                        else if (isIns) {
                            res.push(t[j]);
                            res.push(null);
                            j--;
                            lastDel = false;
                        }
                        else {
                            TDev.Util.assert(curr == d[i][j] + ss[i] + tt[j]);
                            res.push(t[j]);
                            res.push(null);
                            res.push(null);
                            res.push(s[i]);
                            i--;
                            j--;
                            lastDel = true;
                        }
                    }
                }
                res.reverse();
                return res;
            }
            Diff.minimalUpdateDistance = minimalUpdateDistance;
            function stmtsEq(a, b) {
                return a.stableId && a.stableId == b.stableId;
            }
            function clearDiff(s) {
                if (s) {
                    s.diffAltStmt = null;
                    s.diffStatus = undefined;
                    s.diffStmts = null;
                }
            }
            function addDiffStmt(newer, older) {
                if (!newer.diffStmts)
                    newer.diffStmts = [];
                newer.diffStmts.push(older);
            }
            function diffSize(decl) {
                var size = 0;
                function desc(s, justSize) {
                    if (s instanceof AST.Block) {
                    }
                    else if (s instanceof AST.Decl) {
                    }
                    else if (s instanceof AST.Stmt) {
                        var df = s.diffStatus;
                        if (df < 0) {
                            size += 2;
                            return;
                        }
                        if (df > 0) {
                            size += 1;
                            justSize = true;
                        }
                    }
                    else if (s instanceof AST.ExprHolder) {
                        var eh = s;
                        if (justSize) {
                            size += eh.tokens.length * 2;
                        }
                        else if (eh.diffTokens) {
                            var d = eh.diffTokens;
                            for (var i = 0; i < d.length; i += 2) {
                                if (d[i] == null)
                                    size += 1;
                                if (d[i + 1] == null)
                                    size += 0.1;
                            }
                        }
                        return;
                    }
                    else {
                        return;
                    }
                    var arr = s.children();
                    for (var i = 0; i < arr.length; ++i)
                        desc(arr[i], justSize);
                }
                desc(decl, false);
                return size;
            }
            Diff.diffSize = diffSize;
            function isArt(d) {
                return d instanceof AST.GlobalDef && d.isResource;
            }
            function diffRatio(eh) {
                function measure(t) {
                    return Math.min(t.getText().length, 5) + 1;
                }
                var dt = eh.diffTokens;
                var lenCommon = 0;
                var lenDiff = 0;
                for (var i = 0; i < dt.length; i += 2) {
                    if (dt[i] && dt[i + 1])
                        lenCommon += measure(dt[i]);
                    else if (dt[i])
                        lenDiff += measure(dt[i]);
                    else
                        lenDiff += measure(dt[i + 1]);
                }
                if (!lenDiff)
                    return 0;
                return lenDiff / (lenDiff + lenCommon);
            }
            function diffExprs(eh0, eh1, opts, f) {
                if (f === void 0) { f = undefined; }
                function tokenDistance(a, b) {
                    if (!b)
                        return 1;
                    if (!a) {
                        if (/^[0-9\.]$/.test(b.getText()))
                            return 1 + (0.1 / (eh1.tokens.indexOf(b) + 2));
                        else
                            return 1 + (0.1 / (eh1.tokens.indexOf(b) + 2));
                    }
                    if (a.nodeType() != b.nodeType())
                        return 3;
                    if (opts.approxNameMatching) {
                        var cust = opts.tutorialCustomizations;
                        var fa = a.getForwardedDecl();
                        var fb = b.getForwardedDecl();
                        if (isArt(fa) && isArt(fb) && fa.getKind() == fb.getKind()) {
                            cust.artMapping[fb.getName()] = fa.getName();
                            return 0;
                        }
                        var pa = a.getProperty();
                        var pb = b.getProperty();
                        if (pa && pb) {
                            var ka = pa.parentKind;
                            var kb = pb.parentKind;
                            if (ka && ka == kb && ka.getName() == "Colors" && /#[a-fA-F0-9]{6}/.test(pa.getDescription(true)) && /#[a-fA-F0-9]{6}/.test(pb.getDescription(true)))
                                return 0;
                        }
                        var da = a.getLiteral();
                        var db = b.getLiteral();
                        var isName = b instanceof AST.FieldName;
                        if (!isName && typeof da === "string" && typeof db === "string") {
                            if (b.enumVal != null || (opts.preciseStrings && opts.preciseStrings[db]))
                                return (da == db) ? 0 : 3;
                            if (da == "" && db == "")
                                return 0;
                            if (da != "" && db != "") {
                                if (cust)
                                    cust.stringMapping[db] = da;
                                return 0;
                            }
                        }
                    }
                    return a.getText() == b.getText() ? 0 : 3;
                }
                eh1.diffTokens = minimalUpdateDistance(eh0.tokens, eh1.tokens, null, f ? f(tokenDistance) : tokenDistance);
            }
            Diff.diffExprs = diffExprs;
            function diffDecls(decl0, decl1, opts) {
                var oldById = {};
                var newById = {};
                function clearAndIndex(idx, s) {
                    if (s instanceof AST.Decl) {
                    }
                    else if (s instanceof AST.Stmt) {
                        idx[s.stableId] = s;
                        clearDiff(s);
                    }
                    else if (s instanceof AST.ExprHolder) {
                        s.diffTokens = null;
                    }
                    else {
                        return;
                    }
                    var arr = s.children();
                    for (var i = 0; i < arr.length; ++i)
                        clearAndIndex(idx, arr[i]);
                }
                function linkStmts(oldStmt, newStmt) {
                    newStmt.diffAltStmt = oldStmt;
                    oldStmt.diffAltStmt = newStmt;
                    TDev.Util.assert(oldStmt.nodeType() == newStmt.nodeType());
                    var oo = oldStmt.children();
                    var nn = newStmt.children();
                    TDev.Util.assert(oo.length == nn.length);
                    for (var i = 0; i < oo.length; ++i) {
                        TDev.Util.assert(oo[i].nodeType() == nn[i].nodeType());
                        if (oo[i] instanceof AST.ExprHolder) {
                            diffExprs(oo[i], nn[i], opts);
                            if (!opts.tutorialMode && oo.length == 1 && newStmt instanceof AST.ExprStmt && diffRatio(nn[i]) > 0.5) {
                                return false;
                            }
                        }
                        else if (oo[i] instanceof AST.Block)
                            diffBlocks(oo[i], nn[i]);
                        else if (oo[i] instanceof AST.Stmt)
                            linkStmts(oo[i], nn[i]);
                        else
                            TDev.Util.oops("wrong node type in diff " + oo[i].nodeType());
                    }
                    return true;
                }
                function diffBlocks(older, newer) {
                    var combined = minimalEditDistance(older.stmts, newer.stmts, stmtsEq);
                    var lastNewStmt = null;
                    clearDiff(newer);
                    for (var i = 0; i < combined.length; i += 2) {
                        var oldStmt = combined[i];
                        var newStmt = combined[i + 1];
                        if (oldStmt && newStmt) {
                            if (oldStmt.isPlaceholder() && oldStmt.nodeType() != newStmt.nodeType()) {
                                newStmt.diffStatus = 1;
                                oldStmt.diffStatus = -1;
                                addDiffStmt(newStmt, oldStmt);
                            }
                            else {
                                if (linkStmts(oldStmt, newStmt)) {
                                    newStmt.diffStatus = 0;
                                    oldStmt.diffStatus = 0;
                                }
                                else {
                                    newStmt.diffAltStmt = null;
                                    oldStmt.diffAltStmt = null;
                                    newStmt.diffStatus = 2;
                                    oldStmt.diffStatus = -1;
                                    newStmt.calcNode().diffTokens = null;
                                    addDiffStmt(newStmt, oldStmt);
                                }
                            }
                        }
                        else if (newStmt) {
                            newStmt.diffStatus = 1;
                        }
                        else {
                            oldStmt.diffStatus = -1;
                            addDiffStmt(lastNewStmt || newer, oldStmt);
                        }
                        if (newStmt)
                            lastNewStmt = newStmt;
                    }
                }
                clearAndIndex(oldById, decl0);
                clearAndIndex(newById, decl1);
                linkStmts(decl0, decl1);
                var diffId = 2;
                Object.keys(newById).forEach(function (k) {
                    var newStmt = newById[k];
                    if (newStmt.diffStatus == 2) {
                        newStmt.diffStatus = 1;
                        return;
                    }
                    if (newStmt.diffAltStmt)
                        return;
                    var oldStmt = oldById[k];
                    if (oldStmt) {
                        oldStmt.diffStatus = -1;
                        newStmt.diffStatus = 1;
                        if (oldStmt.nodeType() == newStmt.nodeType())
                            linkStmts(oldStmt, newStmt);
                    }
                    else {
                        newStmt.diffStatus = 1;
                    }
                });
                Object.keys(oldById).forEach(function (k) {
                    var oldStmt = oldById[k];
                    if (oldStmt.diffAltStmt && oldStmt.diffStatus == -1) {
                        oldStmt.diffStatus = -diffId;
                        diffId++;
                    }
                    if (oldStmt.diffStatus === undefined)
                        oldStmt.diffStatus = -1;
                });
            }
            function templateDiff(act, templ, opts) {
                setLongIds(act);
                setLongIds(templ);
                matchStmts(act, templ, opts);
                diffDecls(act, templ, opts);
            }
            Diff.templateDiff = templateDiff;
            function diffApps(older, newer, opts) {
                if (opts === void 0) { opts = {}; }
                matchIds(older, newer, opts);
                var olderD = TDev.Util.toDictionary(older.things, function (t) { return t.stableId; });
                newer.things.forEach(function (t) {
                    var o = olderD[t.stableId];
                    if (o) {
                        delete olderD[t.stableId];
                        t.diffStatus = 0;
                        diffDecls(o, t, opts);
                    }
                    else {
                        AST.visitStmts(t, function (s) { return s.diffStatus = 1; });
                    }
                });
                newer.diffRemovedThings = [];
                Object.keys(olderD).forEach(function (k) {
                    var o = olderD[k];
                    newer.diffRemovedThings.push(o);
                    AST.visitStmts(o, function (s) { return s.diffStatus = -1; });
                });
            }
            Diff.diffApps = diffApps;
            function indexIds(obj) {
                var oldById = {};
                function findIds(o) {
                    if (!o)
                        return;
                    if (Array.isArray(o)) {
                        for (var i = 0; i < o.length; ++i)
                            findIds(o[i]);
                    }
                    else if (typeof o === "object") {
                        if (!o.id)
                            TDev.Util.oops("no id for " + JSON.stringify(o));
                        if (oldById.hasOwnProperty(o.id))
                            TDev.Util.oops("duplicate id " + o.id);
                        oldById[o.id] = o;
                        var k = Object.keys(o);
                        for (var i = 0; i < k.length; ++i)
                            findIds(o[k[i]]);
                    }
                }
                findIds(obj);
                return oldById;
            }
            function jsonDiff(o0, n0) {
                var oldById = indexIds(o0);
                var updateSet = {};
                function compareArrays(n, o) {
                    for (var i = 0; i < n.length; ++i) {
                        if (n[i].id)
                            compare(n[i]);
                    }
                    if (!o || n.length != o.length)
                        return true;
                    for (var i = 0; i < n.length; ++i) {
                        var id0 = o[i].id || o[i];
                        var id1 = n[i].id || n[i];
                        if (id0 !== id1)
                            return true;
                    }
                    return false;
                }
                function compare(n) {
                    if (!n.id)
                        TDev.Util.oops("no id on new " + JSON.stringify(n));
                    var o;
                    if (oldById.hasOwnProperty(n.id)) {
                        var o = oldById[n.id];
                        if (!o)
                            TDev.Util.oops("duplicate new id " + n.id);
                        oldById[n.id] = null;
                    }
                    else {
                        o = { id: n.id };
                    }
                    var hasUpdate = false;
                    var update = {};
                    var k = Object.keys(n);
                    for (var i = 0; i < k.length; ++i) {
                        var v = n[k[i]];
                        if (v === undefined)
                            continue;
                        var ov = o[k[i]];
                        if (false && v.id) {
                            compare(v);
                            v = v.id;
                        }
                        if (ov && ov.id)
                            ov = ov.id;
                        switch (typeof v) {
                            case "string":
                            case "number":
                            case "boolean":
                                if (ov !== v)
                                    update[k[i]] = v;
                                break;
                            default:
                                if (Array.isArray(v)) {
                                    if (compareArrays(v, ov))
                                        update[k[i]] = v.map(function (vv) { return vv.id || vv; });
                                }
                                else if (v === null) {
                                    if (ov !== v)
                                        update[k[i]] = v;
                                }
                                else
                                    TDev.Util.oops("cannot compare " + JSON.stringify(v));
                        }
                    }
                    k = Object.keys(o);
                    for (var i = 0; i < k.length; ++i) {
                        if (n[k[i]] === undefined && o[k[i]] !== undefined)
                            update[k[i]] = null;
                    }
                    if (Object.keys(update).length > 0)
                        updateSet[n.id] = update;
                }
                compare(n0);
                var k = Object.keys(oldById);
                for (var i = 0; i < k.length; ++i) {
                    var oo = oldById[k[i]];
                    if (oo)
                        updateSet[oo.id] = null;
                }
                return updateSet;
            }
            Diff.jsonDiff = jsonDiff;
            Diff.lastSeqNo = 0;
            function computeMicroEdits(entries) {
                function getApp(s) {
                    var a = AST.Parser.parseScript(s, []);
                    prepApp(a);
                    return a;
                }
                entries.forEach(function (e) {
                    e.updateSize = 0;
                });
                Diff.lastSeqNo = entries[0].seqNo;
                var prevApp = getApp(entries[0].script);
                var prevAst = AST.Json.dumpForDiff(prevApp);
                entries[0].ast = prevAst;
                for (var i = 1; i < entries.length; ++i) {
                    Diff.lastSeqNo = entries[i].seqNo;
                    var newApp = getApp(entries[i].script);
                    matchPreped(prevApp, newApp, {});
                    var newAst = AST.Json.dumpForDiff(newApp);
                    entries[i].updates = jsonDiff(prevAst, newAst);
                    prevAst = newAst;
                    prevApp = newApp;
                    AST.reset();
                    newApp.things.forEach(function (t) { return t.diffAltDecl = null; });
                    newApp.diffAltDecl = null;
                }
                entries.forEach(function (e) {
                    e.updateSize = JSON.stringify(e.ast || e.updates).length;
                });
            }
            Diff.computeMicroEdits = computeMicroEdits;
            function applyJsonDiff(base, diff) {
                var byId = indexIds(base);
                var k = Object.keys(diff);
                for (var i = 0; i < k.length; ++i) {
                    var id = k[i];
                    var upd = diff[id];
                    if (upd === undefined)
                        continue;
                    var trg = byId[id];
                    if (upd === null) {
                        if (!trg)
                            TDev.Util.oops("apply diff: no target id " + id);
                        trg.__deleted = true;
                        continue;
                    }
                    if (!trg) {
                        byId[id] = trg = { id: id };
                    }
                    var kk = Object.keys(upd);
                    for (var j = 0; j < kk.length; ++j) {
                        var f = kk[j];
                        var v = upd[f];
                        if (Array.isArray(v) && typeof v[0] === "string")
                            v = v.map(function (id) {
                                var r = byId[id];
                                if (!r) {
                                    r = byId[id] = { id: id };
                                }
                                return r;
                            });
                        TDev.Util.assert(f != "nodeType" || !trg[f]);
                        trg[f] = v;
                    }
                }
                var newIds = indexIds(base);
                k = Object.keys(newIds);
                for (var i = 0; i < k.length; ++i) {
                    var id = k[i];
                    if (newIds[k[i]].__deleted)
                        TDev.Util.oops("dangling id after diff " + id);
                }
            }
            Diff.applyJsonDiff = applyJsonDiff;
            function lineDiff(a, b) {
                var res = minimalEditDistance(a.split(/\r?\n/), b.split(/\r?\n/), function (a, b) { return a == b; });
                var p = "";
                for (var i = 0; i < res.length; i += 2) {
                    if (res[i] != null && res[i + 1] != null)
                        p += " " + res[i];
                    else if (res[i] != null)
                        p += "-" + res[i];
                    else
                        p += "+" + res[i + 1];
                    p += "\n";
                }
                return p;
            }
            Diff.lineDiff = lineDiff;
            function sanityCheckEdits(entries) {
                var ast = null;
                function format(s) {
                    var app = AST.Parser.parseScript(s, []);
                    app.isTopLevel = true;
                    AST.TypeChecker.tcScript(app, true);
                    app.rootId = "none";
                    return AST.App.sanitizeScriptTextForCloud(app.serialize());
                }
                entries.forEach(function (e) {
                    Diff.lastSeqNo = e.seqNo;
                    if (e.ast)
                        ast = JSON.parse(JSON.stringify(e.ast));
                    else
                        applyJsonDiff(ast, e.updates);
                    var prevAst = JSON.stringify(ast);
                    var pre0 = e.script;
                    var pre1 = AST.Json.serialize(ast);
                    AST.reset();
                    var a0 = format(pre0);
                    var a1 = format(pre1);
                    if (a0 != a1) {
                        if (a0.split(/\n/).length < 250) {
                            var diff = lineDiff(a0, a1);
                        }
                        TDev.Util.oops("mismatch!", [diff || "<too big>", a0, a1]);
                    }
                    if (JSON.stringify(ast) != prevAst)
                        TDev.Util.oops("serialize modified json", [JSON.stringify(ast), prevAst]);
                    delete e.script;
                });
            }
            Diff.sanityCheckEdits = sanityCheckEdits;
            function scrub(entries) {
                function desc(e, f) {
                    if (!e || typeof e != "object")
                        return;
                    if (Array.isArray(e)) {
                        for (var i = 0; i < e.length; ++i) {
                            desc(e[i], f);
                        }
                    }
                    else {
                        var k = Object.keys(e);
                        for (var i = 0; i < k.length; ++i) {
                            var kk = k[i];
                            var v0 = e[kk];
                            var v1 = f(kk, v0);
                            if (v0 !== v1)
                                e[kk] = v1;
                            if (typeof v1 === "object")
                                desc(v1, f);
                        }
                    }
                }
                function ehField(k) {
                    return (k == "condition" || k == "expr" || k == "bound" || k == "collection");
                }
                function quote(s) {
                    return s.toLowerCase().replace(/[ \r\n\t]/g, "");
                }
                function allowString(e) {
                    if (!e.scriptId)
                        return;
                    desc([e.ast, e.updates], function (k, v) {
                        if (ehField(k)) {
                            AST.Json.shortToTokens(v).forEach(function (tok) {
                                if (tok.nodeType === "stringLiteral") {
                                    allowedStrings[quote(tok.value)] = 1;
                                }
                            });
                        }
                        return v;
                    });
                }
                var allowedStrings = {};
                ([
                    "Touch Develop is cool!",
                    "tap to create bubbles",
                    "hello",
                    "hello world",
                    "hello world!"
                ]).forEach(function (s) {
                    allowedStrings[quote(s)] = 1;
                });
                var disallowCount = 0;
                var disallowStrings = {};
                function checkStrings(e) {
                    desc([e.ast, e.updates], function (k, v) {
                        if (ehField(k)) {
                            var toks = AST.Json.shortToTokens(v);
                            var numSmurf = 0;
                            toks.forEach(function (tok) {
                                if (tok.nodeType === "stringLiteral" && tok.value.length > 3 && !allowedStrings.hasOwnProperty(quote(tok.value))) {
                                    if (!disallowStrings.hasOwnProperty(tok.value)) {
                                        disallowStrings[tok.value] = "scrub" + disallowCount++;
                                    }
                                    tok.value = disallowStrings[tok.value];
                                    numSmurf++;
                                }
                            });
                            var v1 = toks.map(AST.Json.longToShort).join(" ");
                            TDev.Util.assert(numSmurf > 0 || v == v1);
                            return v1;
                        }
                        return v;
                    });
                }
                entries.forEach(allowString);
                entries.forEach(checkStrings);
            }
            Diff.scrub = scrub;
            var IdCopier = (function (_super) {
                __extends(IdCopier, _super);
                function IdCopier() {
                    _super.apply(this, arguments);
                }
                IdCopier.prototype.visitStmt = function (s) {
                    if (s.diffAltStmt && !s.getStableName())
                        s.setStableName(s.diffAltStmt.getStableName());
                    this.visitChildren(s);
                };
                return IdCopier;
            })(AST.NodeVisitor);
            var DiffStat = (function (_super) {
                __extends(DiffStat, _super);
                function DiffStat() {
                    _super.apply(this, arguments);
                    this.stats = {
                        numStmts: 0,
                        numMatched: 0,
                        numAdd: 0,
                        numDel: 0,
                        numChanged: 0,
                        totalChangedRatio: 0,
                        numHighlyChanged: 0,
                        numArtChanges: 0,
                        numNumberChanges: 0,
                        numStringChanges: 0,
                        numCommentChanges: 0,
                        numOtherChanges: 0,
                    };
                }
                DiffStat.prototype.visitBlock = function (b) {
                    this.visitChildren(b);
                };
                DiffStat.prototype.processDiffTokens = function (dt) {
                    var stringChanges = 0;
                    var numChanges = 0;
                    var generalChanges = 0;
                    var artChanges = 0;
                    var prevArt = false;
                    for (var i = 0; i < dt.length; i += 2) {
                        if (dt[i] && dt[i + 1]) {
                            prevArt = (dt[i] instanceof AST.ThingRef && dt[i].data == "art");
                        }
                        else {
                            var tok = dt[i] || dt[i + 1];
                            if (tok instanceof AST.Literal && typeof tok.data == "string")
                                stringChanges++;
                            else if (tok instanceof AST.Operator && /^[0-9\.]$/.test(tok.data))
                                numChanges++;
                            else if (prevArt && tok instanceof AST.PropertyRef)
                                artChanges++;
                            else
                                generalChanges++;
                        }
                    }
                    var st = this.stats;
                    st.numArtChanges += artChanges;
                    st.numStringChanges += stringChanges;
                    if (numChanges)
                        st.numNumberChanges++;
                    if (generalChanges)
                        st.numOtherChanges++;
                };
                DiffStat.prototype.visitStmt = function (s) {
                    var st = this.stats;
                    if (s.diffAltStmt) {
                        st.numMatched++;
                        if (s instanceof AST.GlobalDef && s.isResource) {
                            if (s.diffAltStmt.url != s.url)
                                st.numArtChanges++;
                        }
                    }
                    else {
                        if (s.diffStatus < 0)
                            st.numDel++;
                        else if (s.diffStatus > 0)
                            st.numAdd++;
                        if (s.diffStatus > 0) {
                            if (s instanceof AST.GlobalDef && s.isResource) {
                                st.numArtChanges++;
                            }
                            else {
                                st.numOtherChanges++;
                            }
                        }
                    }
                    st.numStmts++;
                    if (s.diffAltStmt && s instanceof AST.Comment) {
                        if (s.text != s.diffAltStmt.text) {
                            st.numMatched--;
                            st.numAdd++;
                            st.numDel++;
                            st.numCommentChanges++;
                        }
                    }
                    var eh = s.calcNode();
                    if (eh && eh.diffTokens) {
                        st.numChanged++;
                        var dr = diffRatio(eh);
                        st.totalChangedRatio += dr;
                        if (dr > 0.5)
                            st.numHighlyChanged++;
                        if (s.diffAltStmt)
                            this.processDiffTokens(eh.diffTokens);
                    }
                    this.visitChildren(s);
                };
                DiffStat.run = function (a) {
                    var ds = new DiffStat();
                    ds.dispatch(a);
                    return ds.stats;
                };
                return DiffStat;
            })(AST.NodeVisitor);
            Diff.DiffStat = DiffStat;
            function assignIds(oldText, newText) {
                function prep(s) {
                    var app = AST.Parser.parseScript(s, []);
                    app.isTopLevel = true;
                    AST.TypeChecker.tcScript(app, true);
                    return app;
                }
                var oldApp = prep(oldText);
                var newApp = prep(newText);
                new AST.InitIdVisitor(false).dispatch(oldApp);
                diffApps(oldApp, newApp, {
                    useStableNames: true,
                });
                var info = {
                    oldApp: DiffStat.run(oldApp),
                    newApp: DiffStat.run(newApp)
                };
                var copier = new IdCopier();
                copier.dispatch(newApp);
                new AST.InitIdVisitor(false).dispatch(newApp);
                if (oldText)
                    newApp.rootId = oldApp.rootId;
                newApp.hasIds = true;
                var newTextIds = newApp.serialize();
                var app2 = prep(newTextIds);
                new AST.InitIdVisitor(false).expectSet(app2);
                return {
                    text: newTextIds,
                    info: info
                };
            }
            Diff.assignIds = assignIds;
        })(Diff = AST.Diff || (AST.Diff = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var SyntacticMethodFinder = (function (_super) {
            __extends(SyntacticMethodFinder, _super);
            function SyntacticMethodFinder() {
                _super.apply(this, arguments);
                this.calledActions = {};
            }
            SyntacticMethodFinder.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
            };
            SyntacticMethodFinder.prototype.visitExprHolder = function (eh) {
                var _this = this;
                eh.tokens.forEach(function (t, i) {
                    if (t.getText() == "code" && eh.tokens[i + 1] instanceof AST.PropertyRef)
                        _this.calledActions[eh.tokens[i + 1].getText()] = true;
                });
            };
            return SyntacticMethodFinder;
        })(AST.NodeVisitor);
        var DeclFinder = (function (_super) {
            __extends(DeclFinder, _super);
            function DeclFinder() {
                _super.apply(this, arguments);
                this.usedDecls = {};
            }
            DeclFinder.prototype.use = function (d) {
                if (!d)
                    return;
                if (!this.usedDecls.hasOwnProperty(d.getCoreName())) {
                    this.usedDecls[d.getCoreName()] = d;
                    this.dispatch(d);
                }
            };
            DeclFinder.prototype.useKind = function (k) {
                this.use(k.getRecord());
            };
            DeclFinder.prototype.visitRecordField = function (r) {
                this.useKind(r.dataKind);
                _super.prototype.visitRecordField.call(this, r);
            };
            DeclFinder.prototype.visitActionParameter = function (r) {
                this.useKind(r.getKind());
                _super.prototype.visitActionParameter.call(this, r);
            };
            DeclFinder.prototype.visitCall = function (c) {
                var a = c.calledExtensionAction() || c.calledAction();
                if (a && a.parentLibrary().isThis()) {
                    this.use(a);
                }
                else {
                    this.use(c.referencedRecord());
                    this.use(c.referencedData());
                    this.use(c.referencedLibrary());
                }
                _super.prototype.visitCall.call(this, c);
            };
            return DeclFinder;
        })(AST.ExprVisitor);
        function stripStepIdx(n) {
            return n.replace(/^#(S\.)?\d+(\.\d+)?\s*/, "");
        }
        AST.followingTutorial = false;
        var Step = (function () {
            function Step() {
                this.avatars = false;
                this.stcheckpoint = false;
                this.noCheers = false;
                this.stdelete = 0;
            }
            Step.prototype.computeMeta = function () {
                var _this = this;
                this.docs.forEach(function (d) {
                    if (d instanceof AST.Comment) {
                        var c = d;
                        var m = /\{storder:(\d+(\.\d+)?)\}/.exec(c.text);
                        if (m)
                            _this.storder = parseFloat(m[1]);
                        m = /\{stdelete:(\d+)\}/.exec(c.text);
                        if (m)
                            _this.stdelete = parseInt(m[1]);
                        if (/\{stcheckpoint\}/.test(c.text))
                            _this.stcheckpoint = true;
                        if (/\{stnocheers\}/.test(c.text))
                            _this.noCheers = true;
                        if (/\{box:avatar:/.test(c.text))
                            _this.avatars = true;
                    }
                });
            };
            Step.tutorialInfo = function (app) {
                var topic = TDev.HelpTopic.fromScript(app);
                var docs = function (name) {
                    var act = app.actions().filter(function (a) { return a.getName() == name; })[0];
                    if (act)
                        return Step.renderDocs(act.body.stmts);
                    else
                        return undefined;
                };
                var tut = {
                    title: "<h1>" + TDev.Util.htmlEscape(app.getName() || "") + "</h1>",
                    description: "<p>" + TDev.Util.htmlEscape(app.getDescription() || "") + "</p>",
                    steps: Step.splitActions(app).map(function (s) { return s.jsonInfo(); }),
                    startDocs: docs("main"),
                    finalDocs: docs("final"),
                };
                var translations = topic.translations();
                if (translations)
                    tut.translations = translations;
                return tut;
            };
            Step.renderDocs = function (stmts) {
                var r = new TDev.CopyRenderer();
                var md = new TDev.MdComments(r);
                md.useSVG = false;
                md.useExternalLinks = true;
                md.showCopy = false;
                return md.extractStmts(stmts);
            };
            Step.prototype.jsonInfo = function () {
                return {
                    stcheckpoint: this.stcheckpoint ? true : undefined,
                    actionName: this.declName(),
                    command: this.command,
                    commandArg: this.commandArg,
                    docs: Step.renderDocs(this.docs)
                };
            };
            Step.prototype.declName = function () {
                return this._actionName;
            };
            Step.prototype.matchesDecl = function (a) {
                return a.getCoreName() == this.declName() && this.template.nodeType() == a.nodeType();
            };
            Step.splitActions = function (app) {
                var visibleRecordFields = {};
                var hashActions = {};
                var seenAct = {};
                var nameIdx = 0;
                var preciseStrings = {};
                var problems = "";
                function problem(s, p) {
                    problems += p + "\n";
                    if (s) {
                        if (!s.tutorialWarning)
                            s.tutorialWarning = "";
                        s.tutorialWarning += p + "\n";
                    }
                }
                function splitAction(combined) {
                    var steps = [];
                    var currStepIdx = -1;
                    var dummyStep = new Step();
                    dummyStep.preciseStrings = preciseStrings;
                    dummyStep.showAt = 0;
                    dummyStep.hideAt = 1e10;
                    var currStep = dummyStep;
                    var serialized = combined.serialize();
                    var docIndex = false;
                    var index = function (stmts) {
                        var boxNesting = 0;
                        var docMode = false;
                        stmts.forEach(function (s) {
                            var isDoc = boxNesting > 0;
                            var isCommand = false;
                            var isAutoStep = "";
                            var hintLevel = "";
                            s.tutorialWarning = null;
                            var ctext = s.docText();
                            if (ctext != null) {
                                if (/^\s*\{box:([^{}]*)\}\s*$/i.test(ctext))
                                    boxNesting++;
                                if (/^\s*\{\/box\}\s*$/i.test(ctext))
                                    boxNesting--;
                                if (currStepIdx < 0 && /^\s*\{adddecl\}\s*$/i.test(ctext))
                                    currStep.addDecl = [];
                                var m = /^\s*\{stprecise:(.*)\}\s*$/i.exec(ctext);
                                if (m) {
                                    var vs = m[1];
                                    if (/^["']/.test(vs)) {
                                        var toks = AST.Lexer.tokenize(vs);
                                        if (toks && toks[0])
                                            vs = toks[0].data;
                                    }
                                    preciseStrings[vs] = true;
                                }
                                m = /^\s*\{stnoprofile}\s*$/i.exec(ctext);
                                if (m) {
                                    combined._skipIntelliProfile = true;
                                }
                                m = /^\s*\{stauto(:(.*))?}\s*$/i.exec(ctext);
                                if (m)
                                    isAutoStep = m[2] || "yes";
                                m = /^\s*\{stcmd:([^:]*)(:(.*))?\}\s*$/i.exec(ctext);
                                if (m) {
                                    currStep.command = m[1];
                                    currStep.commandArg = m[3] || "";
                                    isCommand = true;
                                    if (currStep.command == "change") {
                                        var found = false;
                                        AST.visitExprHolders(combined, function (stmt, eh) {
                                            eh.tokens.forEach(function (t) {
                                                var call = t.getCall();
                                                if (call && call.referencedData() && call.referencedData().getName() == currStep.commandArg)
                                                    found = true;
                                            });
                                        });
                                        if (!found)
                                            problem(s, TDev.lf("art resource '{0}' not found in current function", currStep.commandArg));
                                    }
                                }
                                m = /^\s*\{sthints:([^:]*)\}\s*$/i.exec(ctext);
                                if (m) {
                                    hintLevel = m[1];
                                }
                                m = /^\s*\{stvalidator:([^:]*)(:(.*))?\}\s*$/i.exec(ctext);
                                if (m) {
                                    currStep.validator = m[1];
                                    currStep.validatorArg = m[3] || "";
                                    var validAct = app.actions().filter(function (a) { return a.getName() == currStep.validator && !a.isPrivate; })[0];
                                    if (validAct) {
                                        validAct._skipIntelliProfile = true;
                                    }
                                    else {
                                        problem(s, "public validator function " + currStep.validator + " not found");
                                    }
                                    isCommand = true;
                                }
                                if (!isCommand) {
                                    isDoc = true;
                                }
                            }
                            if (isDoc) {
                                if (!docMode) {
                                    docMode = true;
                                    if (currStepIdx >= 0)
                                        currStep = steps[currStepIdx++];
                                    else {
                                        steps.push(currStep = new Step());
                                        currStep.firstStmt = s;
                                        currStep.preciseStrings = preciseStrings;
                                        currStep.docs = [];
                                    }
                                }
                                if (hintLevel) {
                                    currStep.hintLevel = hintLevel;
                                    hintLevel = "";
                                }
                                if (isAutoStep) {
                                    docMode = false;
                                    currStep.autoMode = isAutoStep;
                                    if (currStep.docs.length > 0) {
                                        problem(s, "{stauto} step cannot have regular comments attached to it");
                                    }
                                    if (currStep.validator) {
                                        problem(s, "{stauto} step cannot have a {stvalidator}");
                                    }
                                }
                                else {
                                    if (currStepIdx < 0)
                                        currStep.docs.push(s);
                                    if (docIndex)
                                        s.stepState = currStep;
                                }
                            }
                            else {
                                docMode = false;
                                if (!isCommand || docIndex)
                                    s.stepState = currStep;
                                if (currStepIdx < 0 && currStep.addDecl)
                                    currStep.addDecl.push(s);
                                s.children().forEach(function (ch) {
                                    if (ch instanceof AST.Block)
                                        index(ch.stmts);
                                });
                            }
                        });
                    };
                    var actionName = stripStepIdx(combined.getName());
                    var reindexed = function (idx) {
                        var act = AST.Parser.parseDecl(serialized, app);
                        act.autoGenerated = "yes";
                        act.setName("#S." + idx + " " + actionName);
                        app.addDecl(act);
                        currStepIdx = 0;
                        currStep = dummyStep;
                        index(act.body.stmts);
                        return act;
                    };
                    index(combined.body.stmts);
                    steps.forEach(function (s) { return s.computeMeta(); });
                    var steps0 = steps.filter(function (s) { return s.storder === undefined; });
                    var steps1 = steps.filter(function (s) { return s.storder !== undefined; });
                    steps1.stableSortObjs(function (a, b) { return a.storder - b.storder; });
                    var orderedSteps = steps0.concat(steps1);
                    orderedSteps.forEach(function (s, i) {
                        s.showAt = i;
                        s._actionName = actionName;
                    });
                    steps.forEach(function (s, i) {
                        var n = s.stdelete || 0;
                        while (n-- > 0) {
                            var ss = steps[--i];
                            if (!ss)
                                break;
                            ss.hideAt = s.showAt;
                        }
                        if (s.addDecl)
                            s.hideAt = s.showAt;
                    });
                    steps.forEach(function (s) {
                        if (s.hideAt === undefined)
                            s.hideAt = steps.length;
                    });
                    var stepStmts = [];
                    var prune = function (currStep, b) {
                        b.setChildren(b.stmts.filter(function (s) {
                            var t = s.stepState;
                            if (!t)
                                return false;
                            if (!s.isPlaceholder() && t.showAt == currStep && (!s.parent || stepStmts.indexOf(s.parent.parent) < 0))
                                stepStmts.push(s);
                            return s.isInvisible || t.showAt <= currStep && currStep < t.hideAt;
                        }));
                        b.forEachInnerBlock(function (b) { return prune(currStep, b); });
                    };
                    orderedSteps.forEach(function (s, i) {
                        var act = reindexed(nameIdx++);
                        stepStmts = [];
                        prune(i, act.body);
                        var newDocs = [];
                        s.docs.forEach(function (d) {
                            if (d.docText() == "{stcode}") {
                                newDocs.pushRange(stepStmts);
                            }
                            else
                                newDocs.push(d);
                        });
                        s.docs = newDocs;
                        s.template = act;
                        if (s.addDecl) {
                            var rec = null;
                            var gdecl = null;
                            s.addDecl.forEach(function (stmt) {
                                if (stmt instanceof AST.ExprStmt) {
                                    var p = stmt.expr.parsed;
                                    if (!p)
                                        return;
                                    var f = p.referencedRecordField();
                                    var d = p.referencedData();
                                    if (d && d.isResource)
                                        d = null;
                                    var r0 = rec;
                                    if (f) {
                                        rec = f.def();
                                        visibleRecordFields[rec.getName() + "->" + f.getName()] = true;
                                    }
                                    else if (p.referencedRecord()) {
                                        rec = p.referencedRecord();
                                    }
                                    else if (d) {
                                        gdecl = d;
                                    }
                                    else if (p.calledProp() == AST.api.core.AssignmentProp) {
                                    }
                                    else {
                                        problem(s.firstStmt, "no record or record field to add");
                                    }
                                    if (r0 && rec != r0)
                                        problem(s.firstStmt, "more than one record in a step");
                                }
                                else {
                                    problem(s.firstStmt, "bad stmt type: " + stmt.nodeType());
                                }
                            });
                            if (!rec && !gdecl)
                                problem(s.firstStmt, "no decl to add");
                            if (rec) {
                                var rec2 = AST.Parser.parseDecl(rec.serialize(), app);
                                s.template = rec2;
                                var clean = function (f) {
                                    var newStmts = f.stmts.filter(function (f) { return visibleRecordFields[f.def().getName() + "->" + f.getName()]; });
                                    f.setChildren(newStmts);
                                };
                                clean(rec2.keys);
                                clean(rec2.values);
                                s._actionName = rec2.getCoreName();
                            }
                            else if (gdecl) {
                                s.template = gdecl;
                                s._actionName = gdecl.getCoreName();
                            }
                            else {
                                return;
                            }
                        }
                    });
                    if (orderedSteps.length == 0)
                        return [];
                    docIndex = true;
                    var s0 = orderedSteps[0];
                    var forDoc = reindexed(nameIdx++);
                    s0.printOut = forDoc;
                    var resSteps = [];
                    orderedSteps.forEach(function (s) {
                        seenAct[s._actionName] = true;
                        var m = new SyntacticMethodFinder();
                        m.dispatch(s.template);
                        Object.keys(m.calledActions).forEach(function (name) {
                            if (!seenAct.hasOwnProperty(name)) {
                                seenAct[name] = true;
                                var act = app.allActions().filter(function (a) { return a.getName() == name; })[0];
                                if (act) {
                                    resSteps.pushRange(splitAction(act));
                                    s.addsAction = true;
                                }
                            }
                        });
                        resSteps.push(s);
                    });
                    if (problems)
                        TDev.HTML.showWarningNotification("tutorial problem: " + problems);
                    return resSteps;
                }
                function addHeaders(b) {
                    var acc = [];
                    var prevStep = b.parent ? b.parent.stepState : null;
                    var isPage = b.parent instanceof AST.ActionHeader && b.parent.action.isPage();
                    if (!isPage && b instanceof AST.CodeBlock) {
                        b.stmts.forEach(function (s) {
                            if (s.stepState) {
                                var ss = s.stepState;
                                if (ss != prevStep && !s.isPlaceholder()) {
                                    prevStep = ss;
                                    if (prevStep.globalIdx !== undefined) {
                                        var c = new AST.Comment();
                                        c.text = "{internalstepid:" + prevStep.globalIdx + (prevStep.stcheckpoint ? " - checkpoint" : "") + "}";
                                        acc.push(c);
                                    }
                                }
                                if (ss.addDecl) {
                                    if (s instanceof AST.Comment) {
                                        var cc = s;
                                        acc.push(s);
                                        if (/^\s*\{adddecl\}\s*$/.test(cc.text)) {
                                            cc.text = "**Add the declaration:**";
                                            cc = new AST.Comment();
                                            cc.text = "{decl:" + ss.template.getName() + "}";
                                            cc.mdDecl = ss.template;
                                            acc.push(cc);
                                        }
                                    }
                                    return;
                                }
                            }
                            acc.push(s);
                        });
                        b.setChildren(acc);
                    }
                    b.forEachInnerBlock(addHeaders);
                }
                var hasMainPage = false;
                var stepActions = app.orderedThings(true).filter(function (a) {
                    if (a instanceof AST.Action) {
                        var n = stripStepIdx(a.getName());
                        if (n != a.getName()) {
                            hashActions[n] = true;
                            if (n == "main" && a.isPage())
                                hasMainPage = true;
                            return true;
                        }
                        else
                            return false;
                    }
                    else
                        return false;
                });
                AST.visitStmts(app, function (s) {
                    s.tutorialWarning = "";
                    if (s instanceof AST.Comment) {
                        var t = s.text;
                        var m = /^\s*\{template:([^:]*)\}\s*$/i.exec(t);
                        if (m && hasMainPage && m[1] == "empty") {
                            problem(s, "use {template:emptyapp} for tutorials with main page");
                        }
                    }
                });
                if (stepActions.length == 0)
                    return [];
                var res = stepActions.collect(splitAction);
                res.forEach(function (s, i) { return s.globalIdx = i; });
                res.forEach(function (s) {
                    if (s.printOut)
                        addHeaders(s.printOut.body);
                });
                var maxCount = 2;
                if (!res.every(function (s) { return s.hintLevel === undefined; }))
                    maxCount = 1e10;
                var currLevel = TDev.Cloud.config.hintLevel;
                res.forEach(function (s) {
                    if (s.hintLevel) {
                        currLevel = s.hintLevel;
                        maxCount = 1e10;
                    }
                    s.hintLevel = currLevel;
                    if (!s.autoMode)
                        maxCount--;
                    if (maxCount <= 0)
                        currLevel = "semi";
                    if (s.validator)
                        s.hintLevel = "free";
                });
                AST.TypeChecker.tcScript(app);
                app.things = app.things.filter(function (t) { return !t.autoGenerated; });
                res.forEach(function (s) {
                    if (s.printOut)
                        s.printOut.setName(s._actionName);
                });
                return res;
            };
            Step.reply = function (orig, app, steps, customizations) {
                var last = {};
                steps.forEach(function (s) {
                    last[s.declName()] = s.template;
                });
                var finder = new DeclFinder();
                Object.keys(last).forEach(function (n) { return finder.dispatch(last[n]); });
                app.libraries().forEach(function (l) { return finder.use(l); });
                Object.keys(finder.usedDecls).forEach(function (n) {
                    if (!last.hasOwnProperty(n))
                        last[n] = finder.usedDecls[n];
                });
                var str = Object.keys(last).map(function (n) { return last[n].serialize(); }).join("\n");
                var newApp = AST.Parser.parseScript(str);
                newApp.setName(orig.getName());
                newApp.comment = orig.comment;
                AST.TypeChecker.tcScript(newApp);
                AST.visitExprHolders(newApp, function (stmt, eh) {
                    eh.tokens = eh.tokens.map(function (t) {
                        var sl = t.getStringLiteral();
                        if (sl && customizations.stringMapping.hasOwnProperty(sl))
                            return AST.mkLit(customizations.stringMapping[sl]);
                        return t;
                    });
                });
                newApp.resources().forEach(function (r) {
                    if (customizations.artMapping.hasOwnProperty(r.getName())) {
                        var nn = customizations.artMapping[r.getName()];
                        var other = orig.resources().filter(function (t) { return t.getName() == nn; })[0];
                        if (other && other.getKind() == r.getKind()) {
                            r.setName(nn);
                            r.url = other.url;
                            r.comment = other.comment;
                        }
                    }
                });
                newApp.hasIds = true;
                new AST.InitIdVisitor(false).dispatch(newApp);
                newApp.things.forEach(function (t) {
                    var n = t.getCoreName();
                    if (stripStepIdx(n) != n)
                        t.setName(stripStepIdx(n));
                    if (t.getName() == "main" && t instanceof AST.Action)
                        t.isPrivate = false;
                });
                return newApp.serialize();
            };
            return Step;
        })();
        AST.Step = Step;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Merge;
        (function (Merge) {
            var mergeLog = function (x) {
                return;
            };
            var getTime = function () { return TDev.Util.perfNow(); };
            var seqTime = [];
            var sccTime = 0;
            var treeTime = [];
            var imTime = 0;
            var oldSeqMerge = false;
            var numChecks = 0;
            Merge.badAstMsg = "malformed ASTs";
            function enc(s) {
                return "!" + s;
            }
            function dec(s) {
                return s.substr(1);
            }
            function getStableName(x) {
                if (x instanceof AST.App) {
                    return "***";
                }
                else {
                    return enc(x.getStableName());
                }
            }
            function setStableName(x, name) {
                x.setStableName(dec(name));
            }
            function containsId(table, id) {
                if (table[id]) {
                    return true;
                }
                else {
                    return false;
                }
            }
            function containsArrow(table, id1, id2) {
                var a = table[id1];
                if (oldSeqMerge) {
                    if (a && a.successors.indexOf(id2) >= 0) {
                        return true;
                    }
                    else {
                        return false;
                    }
                }
                else {
                    var b = table[id2];
                    if (a && b && a.order < b.order) {
                        return true;
                    }
                    else {
                        return false;
                    }
                }
            }
            function getNodeHash(sh) {
                var result = {};
                sh.forEach(function (x) {
                    result[x.name] = x;
                });
                return result;
            }
            function getChildren(s) {
                if (!s)
                    return [];
                var stmts = (s.stmt.children().filter(function (x) { return x instanceof AST.Stmt; }));
                if (s.stmt instanceof AST.If && stmts.length == 2 && stmts[1] instanceof AST.CodeBlock && stmts[1].isBlockPlaceholder())
                    stmts.pop();
                return stmts.map(function (x, i) {
                    return new HashNode(s.name, getStableName(x), [], x);
                });
            }
            var HashNode = (function () {
                function HashNode(parent, name, successors, stmt) {
                    this.parent = parent;
                    this.name = name;
                    this.successors = successors;
                    this.stmt = stmt;
                }
                HashNode.prototype.toString = function () {
                    return "" + this.name + ":(" + this.parent + "):[" + "]";
                };
                return HashNode;
            })();
            Merge.HashNode = HashNode;
            function getStmt(table, key) {
                if (table[key]) {
                    return table[key].stmt;
                }
                else {
                    return null;
                }
            }
            function getIds(sl, allIds) {
                var nodeIndex = 0;
                function flatten(sl, table, arr) {
                    return sl.reduce(function (acc2, x, i) {
                        x.order = nodeIndex++;
                        table[x.name] = null;
                        var theParent = undefined;
                        theParent = x.parent;
                        table[x.name] = x;
                        allIds.push(x.name);
                        acc2.push(x.name);
                        return flatten(getChildren(x), table, acc2);
                    }, arr);
                }
                var result = {};
                var flat = flatten(sl.map(function (x) { return new HashNode(undefined, getStableName(x), [], x); }), result, []);
                flat.forEach(function (x, i) {
                    result[x].successors = flat.slice(i + 1, flat.length);
                });
                return result;
            }
            Merge.getIds = getIds;
            function transitiveClosure(succMap) {
                var keys = Object.keys(succMap);
                mergeLog(">>> transitive closure: " + keys.length);
                keys.forEach(function (k) {
                    keys.forEach(function (i) {
                        keys.forEach(function (j) {
                            succMap[i][j] = succMap[i][j] || (succMap[i][k] && succMap[k][j]);
                        });
                    });
                });
            }
            function stronglyConnectedComponents(succMap, keys, resultAssignment, debug) {
                if (debug === void 0) { debug = false; }
                var index = 0;
                var stack = [];
                var stackVals = {};
                var indices = {};
                var lowlink = {};
                var result = [];
                var currentComponent = [];
                keys.forEach(function (v) {
                    if (!indices[v])
                        strongConnect(v);
                });
                function strongConnect(v, depth) {
                    if (depth === void 0) { depth = 0; }
                    indices[v] = index;
                    lowlink[v] = index;
                    index++;
                    stack.push(v);
                    stackVals[v] = true;
                    var temp = succMap[v];
                    if (temp) {
                        Object.keys(temp).forEach(function (w) {
                            if (indices[w] == undefined) {
                                strongConnect(w, depth + 1);
                                lowlink[v] = Math.min(lowlink[v], lowlink[w]);
                            }
                            else {
                                var ind = stackVals[w];
                                if (ind >= 0) {
                                    lowlink[v] = Math.min(lowlink[v], indices[w]);
                                }
                            }
                        });
                    }
                    if (lowlink[v] == indices[v]) {
                        currentComponent = [];
                        do {
                            var w = stack.pop();
                            delete stackVals[w];
                            currentComponent.push(w);
                        } while (w != v);
                        result.push(currentComponent);
                    }
                }
                result.forEach(function (comp, index) {
                    comp.forEach(function (v) {
                        resultAssignment[v] = index;
                    });
                });
                return result;
            }
            Merge.stronglyConnectedComponents = stronglyConnectedComponents;
            function initMatrix(succMap, keys, init) {
                if (init === void 0) { init = 0; }
                keys.forEach(function (i) {
                    succMap[i] = {};
                });
            }
            function printMatrix(m) {
                var str = "";
                Object.keys(m).forEach(function (j) {
                    str += ", " + j;
                });
                mergeLog(str);
                Object.keys(m).forEach(function (i) {
                    str = "";
                    Object.keys(m).forEach(function (j) {
                        str += ", " + m[i][j];
                    });
                    mergeLog(i + str);
                });
            }
            function tokensToStr(a) {
                return a.map(function (x) { return x.getText(); }).join(" ");
            }
            function strToTokens(s) {
                return s.split(/\s+/).map(function (y) {
                    var t = new AST.Literal();
                    t.data = y;
                    return t;
                });
            }
            function merge3(o, a, b, datacollector) {
                if (datacollector) {
                    sccTime = 0;
                    imTime = 0;
                    seqTime = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
                    treeTime = [0, 0, 0, 0, 0, 0, 0];
                    numChecks = 0;
                }
                var start = getTime();
                mergeLog(">>> Merge: " + getTime() + " begin merge3");
                mergeLog(">>> Merge: " + getTime() + " get IDs");
                var lo = [];
                var la = [];
                var lb = [];
                var hashO = getIds([o], lo);
                var hashA = getIds([a], la);
                var hashB = getIds([b], lb);
                function combineTokens(tl) {
                    return TDev.AST.ExprParser.parse0(tl).map(function (x) {
                        if (x.expr) {
                            return (x.expr);
                        }
                        else {
                            return TDev.AST.mkOp(x.op);
                        }
                    });
                }
                function merge3tokens(eOt, eAt, eBt, combine) {
                    var i = 0;
                    var com = (function (x) { return x; });
                    var eO = new AST.ExprHolder();
                    eO.tokens = com(eOt);
                    var eA = new AST.ExprHolder();
                    eA.tokens = com(eAt);
                    var eB = new AST.ExprHolder();
                    eB.tokens = com(eBt);
                    var tmap = {};
                    var index = 0;
                    var f = function (tokenDist) {
                        return function (a, b) {
                            if ((!a) || (!b)) {
                                return tokenDist(a, b);
                            }
                            else {
                                return tokenDist(a, b);
                            }
                        };
                    };
                    TDev.AST.Diff.diffExprs(eO, eA, {}, f);
                    TDev.AST.Diff.diffExprs(eO, eB, {}, f);
                    var da = eA.diffTokens;
                    var db = eB.diffTokens;
                    var arrO = [];
                    for (var i = 0; i < da.length; i += 2) {
                        if (da[i]) {
                            var name = "" + index;
                            tmap[name] = da[i];
                            index++;
                            arrO.push(name);
                        }
                    }
                    var arrA = [];
                    var j = 0;
                    for (i = 1; i < da.length; i += 2) {
                        if (da[i]) {
                            if (da[i - 1]) {
                                arrA.push("" + j);
                            }
                            else {
                                var name = "" + index;
                                tmap["" + index] = da[i];
                                index++;
                                arrA.push(name);
                            }
                        }
                        if (da[i - 1])
                            j++;
                    }
                    var arrB = [];
                    j = 0;
                    for (i = 1; i < db.length; i += 2) {
                        if (db[i]) {
                            if (db[i - 1]) {
                                arrB.push("" + j);
                            }
                            else {
                                var name = "" + index;
                                tmap["" + index] = db[i];
                                index++;
                                arrB.push(name);
                            }
                        }
                        if (db[i - 1])
                            j++;
                    }
                    function mapper(x) {
                        var v = new AST.App(null);
                        v.things = x.map(function (y) {
                            var z = new AST.Decl();
                            z.setStableName(y);
                            return z;
                        });
                        return v;
                    }
                    var result = merge3(mapper(arrO), mapper(arrA), mapper(arrB));
                    return result.things.map(function (x) { return tmap[x.getStableName()]; });
                }
                var maxDepth = 0;
                function merge3node(oN, aN, bN, cmap, depth) {
                    if (depth === void 0) { depth = 0; }
                    maxDepth = Math.max(depth, maxDepth);
                    var id;
                    if (oN) {
                        id = oN.name;
                    }
                    else if (aN) {
                        id = aN.name;
                    }
                    else if (bN) {
                        id = bN.name;
                    }
                    else {
                        return null;
                    }
                    var childs = cmap[id];
                    if (!childs) {
                        childs = [];
                    }
                    var newChilds = [];
                    newChilds = childs.map(function (x) {
                        return merge3node(hashO[x], hashA[x], hashB[x], cmap, depth + 1);
                    });
                    function getNewChild(index) {
                        var rc = newChilds[index];
                        if (rc) {
                            return rc;
                        }
                        else {
                            return null;
                        }
                    }
                    function merge3inputs(f, combine) {
                        var oTok = [];
                        if (oN)
                            oTok = f(oN.stmt);
                        var aTok = [];
                        if (aN)
                            aTok = f(aN.stmt);
                        var bTok = [];
                        if (bN)
                            bTok = f(bN.stmt);
                        return merge3tokens(oTok, aTok, bTok, combine);
                    }
                    function test(x) {
                        var t1 = !oN || (oN.stmt instanceof x);
                        var t2 = !aN || (aN.stmt instanceof x);
                        var t3 = !bN || (bN.stmt instanceof x);
                        return t1 && t2 && t3;
                    }
                    function getChange(f) {
                        if (!aN && !bN) {
                            return undefined;
                        }
                        else if (!aN) {
                            return f(bN.stmt);
                        }
                        else if (!bN) {
                            return f(aN.stmt);
                        }
                        else if (!oN) {
                            return f(aN.stmt);
                        }
                        if (f(oN.stmt) == f(aN.stmt)) {
                            return f(bN.stmt);
                        }
                        else {
                            return f(aN.stmt);
                        }
                    }
                    function mergeExprHolder(f) {
                        var temp = new AST.ExprHolder();
                        temp.tokens = merge3inputs(function (x) { return f(x).tokens; }, true);
                        return temp;
                    }
                    var result = null;
                    var newName = undefined;
                    if (test(AST.RecordField)) {
                        var dataKind = getChange(function (x) { return x.dataKind; });
                        var isKey = getChange(function (x) { return x.isKey; });
                        var nm = getChange(function (x) { return x.getName(); });
                        result = new AST.RecordField(nm, dataKind, isKey);
                    }
                    else if (test(AST.ResolveClause)) {
                        var nm = getChange(function (x) { return x.name; });
                        result = new AST.ResolveClause(nm);
                        result.kindBindings = getNewChild(0);
                        result.actionBindings = getNewChild(1);
                        result.defaultLib = getChange(function (x) { return x.defaultLib; });
                    }
                    else if (test(AST.ActionBinding)) {
                        var nm = getChange(function (x) { return x.formalName; });
                        result = new AST.ActionBinding(nm);
                        result.actualLib = getChange(function (x) { return x.actualLib; });
                        result.actualName = getChange(function (x) { return x.actualName; });
                        result.actual = getChange(function (x) { return x.actual; });
                        result.isExplicit = getChange(function (x) { return x.isExplicit; });
                    }
                    else if (test(AST.KindBinding)) {
                        var nm = getChange(function (x) { return x.formalName; });
                        result = new AST.KindBinding(nm);
                        result.actual = getChange(function (x) { return x.actual; });
                        result.isExplicit = getChange(function (x) { return x.isExplicit; });
                    }
                    else if (test(AST.Binding)) {
                        var nm = getChange(function (x) { return x.formalName; });
                        result = new AST.Binding(nm);
                        result.isExplicit = getChange(function (x) { return x.isExplicit; });
                    }
                    else if (test(AST.Comment)) {
                        result = new AST.Comment();
                        result.text = tokensToStr(merge3inputs(function (x) { return strToTokens(x.text); }, false));
                    }
                    else if (test(AST.CodeBlock)) {
                        result = new AST.CodeBlock();
                        result.stmts = newChilds;
                        result.flags = getChange(function (x) { return x.flags; });
                    }
                    else if (test(AST.ConditionBlock)) {
                        result = new AST.ConditionBlock();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.ParameterBlock)) {
                        result = new AST.ParameterBlock();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.BindingBlock)) {
                        result = new AST.BindingBlock();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.ResolveBlock)) {
                        result = new AST.ResolveBlock();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.FieldBlock)) {
                        result = new AST.FieldBlock();
                        result.stmts = newChilds;
                        result.parentDef = getChange(function (x) { return x.parentDef; });
                    }
                    else if (test(AST.InlineActionBlock)) {
                        result = new AST.InlineActionBlock();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.Block)) {
                        throw Error(Merge.badAstMsg);
                        result = new AST.Block();
                        result.stmts = newChilds;
                    }
                    else if (test(AST.For)) {
                        result = new AST.For();
                        result.body = getNewChild(0);
                        result.boundLocal = getChange(function (x) { return x.boundLocal; });
                        result.upperBound = mergeExprHolder(function (x) { return x.upperBound; });
                    }
                    else if (test(AST.Foreach)) {
                        result = new AST.Foreach();
                        result.conditions = getNewChild(0);
                        result.body = getNewChild(1);
                        result.boundLocal = getChange(function (x) { return x.boundLocal; });
                        result.collection = mergeExprHolder(function (x) { return x.collection; });
                    }
                    else if (test(AST.While)) {
                        result = new AST.While();
                        result.body = getNewChild(0);
                        result.condition = mergeExprHolder(function (x) { return x.condition; });
                    }
                    else if (test(AST.OptionalParameter)) {
                        result = new AST.OptionalParameter();
                        result._opt_name = getChange(function (x) { return x.getName(); });
                        result.expr = mergeExprHolder(function (x) { return x.expr; });
                    }
                    else if (test(AST.If)) {
                        result = new AST.If();
                        result.rawThenBody = getNewChild(0);
                        var elseBody = getNewChild(1);
                        if (!elseBody) {
                            elseBody = AST.Parser.emptyBlock();
                            elseBody.stmts[0].initStableName();
                        }
                        result.rawElseBody = elseBody;
                        result.rawCondition = mergeExprHolder(function (x) { return x.rawCondition; });
                        result.isElseIf = getChange(function (x) { return x.isElseIf; });
                        result.displayElse = getChange(function (x) { return x.displayElse; });
                    }
                    else if (test(AST.Box)) {
                        result = new AST.Box();
                        result.body = getNewChild(0);
                    }
                    else if (test(AST.InlineActions)) {
                        result = new AST.InlineActions();
                        result.actions = getNewChild(0);
                        result.expr = mergeExprHolder(function (x) { return x.expr; });
                    }
                    else if (test(AST.ExprStmt)) {
                        result = new AST.ExprStmt();
                        result.expr = mergeExprHolder(function (x) { return x.expr; });
                    }
                    else if (test(AST.InlineAction)) {
                        result = new AST.InlineAction();
                        result.body = getNewChild(0);
                        result.name = getChange(function (x) { return x.name; });
                        result.isOptional = getChange(function (x) { return x.isOptional; });
                        result.isImplicit = getChange(function (x) { return x.isImplicit; });
                        result.inParameters = getChange(function (x) { return x.inParameters; });
                        result.outParameters = getChange(function (x) { return x.outParameters; });
                    }
                    else if (test(AST.Where)) {
                        result = new AST.Where();
                        result.condition = mergeExprHolder(function (x) { return x.condition; });
                    }
                    else if (test(AST.ForeachClause)) {
                        result = new AST.ForeachClause();
                    }
                    else if (test(AST.ActionParameter)) {
                        result = new AST.ActionParameter(AST.mkLocal(getChange(function (x) { return x.getName(); }), getChange(function (x) { return x.getKind(); })));
                    }
                    else if (test(AST.ActionHeader)) {
                        result = new AST.ActionHeader(new AST.Action());
                        result.inParameters = getNewChild(0);
                        result.outParameters = getNewChild(1);
                        result.action.body = getNewChild(2);
                    }
                    else if (test(AST.GlobalDef)) {
                        result = new AST.GlobalDef();
                        result.readonly = getChange(function (x) { return x.readonly; });
                        result.comment = getChange(function (x) { return x.comment; });
                        result.url = getChange(function (x) { return x.url; });
                        result.isResource = getChange(function (x) { return x.isResource; });
                        result.isTransient = getChange(function (x) { return x.isTransient; });
                        result.cloudEnabled = getChange(function (x) { return x.cloudEnabled; });
                        result.debuggingData = getChange(function (x) { return x.debuggingData; });
                        result.cloudEnabled = getChange(function (x) { return x.cloudEnabled; });
                    }
                    else if (test(AST.Action)) {
                        result = new AST.Action();
                        var ah = getNewChild(0);
                        result.body = ah.action.body;
                        ah.action = result;
                        ah.inParameters.parent = result;
                        ah.outParameters.parent = result;
                        result.header = ah;
                        result.isPrivate = getChange(function (x) { return x.isPrivate; });
                        result._isPage = getChange(function (x) { return x._isPage; });
                        result._isTest = getChange(function (x) { return x._isTest; });
                        result._isActionTypeDef = getChange(function (x) { return x._isActionTypeDef; });
                        result.isAtomic = getChange(function (x) { return x.isAtomic; });
                        result.eventInfo = getChange(function (x) { return x.eventInfo; });
                        result.isOffline = getChange(function (x) { return x.isOffline; });
                        result.isQuery = getChange(function (x) { return x.isQuery; });
                        result._isTest = getChange(function (x) { return x._isTest; });
                        if (getChange(function (x) { return x.modelParameter; })) {
                            result.modelParameter = ah.inParameters.stmts.shift();
                        }
                    }
                    else if (test(AST.RecordDef)) {
                        result = new AST.RecordDef();
                        result.keys = getNewChild(0);
                        result.values = getNewChild(1);
                        result.description = getChange(function (x) { return x.description; });
                        result.recordType = getChange(function (x) { return x.recordType; });
                        result.cloudEnabled = getChange(function (x) { return x.cloudEnabled; });
                        result.persistent = getChange(function (x) { return x.persistent; });
                        result._isExported = getChange(function (x) { return x._isExported; });
                        newName = getChange(function (x) { return x.getCoreName(); });
                    }
                    else if (test(AST.LibraryRef)) {
                        result = new AST.LibraryRef();
                        result.resolveClauses = getNewChild(0);
                        result.guid = getChange(function (x) { return x.guid; });
                        result.pubid = getChange(function (x) { return x.pubid; });
                        result._publicActions = getChange(function (x) { return x._publicActions; });
                        result._publicKinds = getChange(function (x) { return x._publicKinds; });
                    }
                    else if (test(AST.PropertyDecl)) {
                        throw Error(Merge.badAstMsg);
                        result = new AST.PropertyDecl();
                    }
                    else if (test(AST.SingletonDef)) {
                        throw Error(Merge.badAstMsg);
                        result = new AST.SingletonDef();
                        result._isBrowsable = getChange(function (x) { return x._isBrowsable; });
                    }
                    else if (test(AST.PlaceholderDef)) {
                        throw Error(Merge.badAstMsg);
                        result = new AST.PlaceholderDef();
                    }
                    else if (test(AST.LocalDef)) {
                        result = new AST.LocalDef();
                    }
                    else if (test(AST.App)) {
                        result = new AST.App(null);
                        result.rootId = getChange(function (x) { return x.rootId; });
                        result.icon = getChange(function (x) { return x.icon; });
                        result.color = getChange(function (x) { return x.color; });
                        result.comment = getChange(function (x) { return x.comment; });
                        result.iconArtId = getChange(function (x) { return x.iconArtId; });
                        result.splashArtId = getChange(function (x) { return x.splashArtId; });
                        AST.App.metaMapping.forEach(function (k) {
                            result[k] = getChange(function (x) { return x[k]; });
                        });
                        result.setPlatform(getChange(function (x) { return x.getPlatformRaw(); }));
                        result.things = newChilds;
                    }
                    else if (test(AST.Decl)) {
                        result = new AST.Decl();
                        result._wasTypechecked = getChange(function (x) { return x._wasTypechecked; });
                        result.deleted = getChange(function (x) { return x.deleted; });
                        result.wasAutoNamed = getChange(function (x) { return x.wasAutoNamed; });
                        result.diffStatus = getChange(function (x) { return x.diffStatus; });
                        result.diffAltDecl = getChange(function (x) { return x.diffAltDecl; });
                    }
                    else if (test(AST.Stmt)) {
                        throw Error(Merge.badAstMsg);
                        result = new AST.Stmt();
                    }
                    else {
                        throw Error(Merge.badAstMsg);
                    }
                    result._kind = getChange(function (x) { return x._kind; });
                    setStableName(result, id);
                    if (newName)
                        result.setName(newName);
                    else
                        result.setName(getChange(function (x) { return x.getName(); }));
                    newChilds.forEach(function (x) {
                        x.parent = result;
                    });
                    return result;
                }
                mergeLog(">>> Merge: " + getTime() + " init maps");
                var tt = getTime();
                var parentMap = {};
                var parentTemp = {};
                var added = {};
                var succMap = {};
                Object.keys(hashO).forEach(function (key) {
                    parentMap[key] = null;
                });
                Object.keys(hashA).forEach(function (key) {
                    parentMap[key] = null;
                });
                Object.keys(hashB).forEach(function (key) {
                    parentMap[key] = null;
                });
                var tt2 = getTime();
                treeTime[0] += (tt2 - tt);
                tt = tt2;
                mergeLog(">>> Merge: " + getTime() + " step 1");
                Object.keys(parentMap).forEach(function (x) {
                    var intersect = (containsId(hashA, x) && containsId(hashB, x) && containsId(hashO, x));
                    if (!(((containsId(hashA, x) || containsId(hashB, x)) && !(containsId(hashO, x))) || intersect)) {
                        delete parentMap[x];
                    }
                    else if (!intersect) {
                        added[x] = true;
                    }
                });
                var tt2 = getTime();
                treeTime[1] += (tt2 - tt);
                tt = tt2;
                mergeLog(">>> Merge: " + getTime() + " step 2");
                function applyChanges(f) {
                    Object.keys(parentMap).forEach(function (x) {
                        var pO = hashO[x];
                        var pA = hashA[x];
                        var pB = hashB[x];
                        f(x, parentMap, (pO ? pO.parent : undefined), (pA ? pA.parent : undefined), (pB ? pB.parent : undefined));
                    });
                }
                applyChanges(function (x, parentMap, pO, pA, pB) {
                    if (pA != pO) {
                        parentTemp[x] = true;
                    }
                    parentMap[x] = pA;
                });
                applyChanges(function (x, parentMap, pO, pA, pB) {
                    if (pB != pA && !parentTemp[x])
                        parentMap[x] = pB;
                });
                var tt2 = getTime();
                treeTime[2] += (tt2 - tt);
                tt = tt2;
                var roots = [];
                var pk = Object.keys(parentMap);
                pk.forEach(function (k) {
                    var src = parentMap[k];
                    var dst = k;
                    if (src && dst) {
                        if (!succMap[src])
                            succMap[src] = {};
                        succMap[src][dst] = 1;
                    }
                    if (!src)
                        roots.push(dst);
                });
                var tt2 = getTime();
                treeTime[3] += (tt2 - tt);
                tt = tt2;
                var table = {};
                var conn = stronglyConnectedComponents(succMap, pk, table);
                succMap = null;
                var tt2 = getTime();
                treeTime[4] += (tt2 - tt);
                tt = tt2;
                function processChildren(cl, done) {
                    cl.forEach(function (x) {
                        var pA = hashA[x];
                        var childA = getNodeHash(getChildren(pA));
                        var childAll = Object.keys(childA);
                        childAll.forEach(function (y) {
                            if (table[x] != table[y] && !done[table[y]]) {
                                if (parentMap[y])
                                    parentMap[y] = x;
                                done[table[y]] = true;
                            }
                        });
                        processChildren(childAll, done);
                    });
                }
                var initDone = {};
                conn.forEach(function (comp) {
                    comp.forEach(function (x) {
                        if (comp.length <= 1)
                            initDone[table[x]] = true;
                    });
                });
                var tt2 = getTime();
                treeTime[5] += (tt2 - tt);
                tt = tt2;
                processChildren(roots, initDone);
                var tt2 = getTime();
                treeTime[6] += (tt2 - tt);
                tt = tt2;
                mergeLog(">>> Merge: " + getTime() + " step 3: " + Object.keys(parentMap).length);
                var startX = getTime();
                var childMap = {};
                Object.keys(parentMap).forEach(function (x) {
                    var p = parentMap[x];
                    if (childMap[p]) {
                        if (childMap[p].indexOf(x) < 0) {
                            childMap[p].push(x);
                        }
                    }
                    else {
                        childMap[p] = [x];
                    }
                });
                var tt2 = getTime();
                seqTime[0] += (tt2 - tt);
                tt = tt2;
                function addEdge(theX, theY, edgeMap, v) {
                    if (v === void 0) { v = 1; }
                    if (!edgeMap[theY][theX]) {
                        edgeMap[theX][theY] = v;
                    }
                }
                Object.keys(childMap).forEach(function (px) {
                    var childs = childMap[px];
                    mergeLog(">>> processing children: " + px + ": " + getTime());
                    var addMap = {};
                    var edgeMap = {};
                    initMatrix(edgeMap, childs);
                    if (oldSeqMerge) {
                        mergeLog(">>> part A: " + childs.length);
                        childs.forEach(function (i) {
                            childs.forEach(function (j) {
                                if (i != j) {
                                    var theX = i;
                                    var theY = j;
                                    if (containsArrow(hashA, theX, theY) && (!containsArrow(hashO, theX, theY) || !containsArrow(hashB, theY, theX)))
                                        addEdge(theX, theY, edgeMap);
                                }
                            });
                        });
                        transitiveClosure(edgeMap);
                        mergeLog(">>> part C");
                        childs.forEach(function (i) {
                            childs.forEach(function (j) {
                                if (i != j) {
                                    var theX = i;
                                    var theY = j;
                                    if (containsArrow(hashB, theX, theY) && ((containsArrow(hashO, theY, theX) && containsArrow(hashA, theY, theX)) || (!containsArrow(hashO, theY, theX) && !containsArrow(hashA, theY, theX)))) {
                                        addEdge(theX, theY, edgeMap);
                                    }
                                }
                            });
                        });
                        transitiveClosure(edgeMap);
                        mergeLog(">>> part E");
                        childs.forEach(function (i) {
                            childs.forEach(function (j) {
                                if (i != j) {
                                    var theX = i;
                                    var theY = j;
                                    if ((containsId(hashA, theX) && !containsId(hashB, theX)) && (containsId(hashB, theY) && !containsId(hashA, theY))) {
                                        addEdge(theX, theY, edgeMap);
                                    }
                                }
                            });
                        });
                        transitiveClosure(edgeMap);
                    }
                    else {
                        var imStart = getTime();
                        var sla = childs.reduce(function (acc, x) {
                            var y = hashA[x];
                            if (y) {
                                y.used = false;
                                acc.push(y);
                            }
                            return acc;
                        }, []).sort(function (x, y) { return x.order < y.order ? -1 : 1; });
                        var slb = childs.reduce(function (acc, x) {
                            var y = hashB[x];
                            if (y) {
                                y.used = false;
                                acc.push(y);
                            }
                            return acc;
                        }, []).sort(function (x, y) { return x.order < y.order ? -1 : 1; });
                        var imEnd = getTime();
                        imTime += (imEnd - imStart);
                        var tt2 = getTime();
                        seqTime[1] += (tt2 - tt);
                        tt = tt2;
                        sla.reduce(function (prevs, curr) {
                            if (added[curr ? curr.name : undefined]) {
                                prevs.forEach(function (prev) {
                                    if (!addMap[prev ? prev.name : undefined])
                                        addMap[prev ? prev.name : undefined] = [];
                                    addMap[prev ? prev.name : undefined].unshift(curr);
                                });
                            }
                            prevs.push(curr);
                            return prevs;
                        }, [undefined]);
                        slb.reduce(function (prevs, curr) {
                            if (added[curr ? curr.name : undefined]) {
                                prevs.forEach(function (prev) {
                                    if (!addMap[prev ? prev.name : undefined])
                                        addMap[prev ? prev.name : undefined] = [];
                                    addMap[prev ? prev.name : undefined].unshift(curr);
                                });
                            }
                            prevs.push(curr);
                            return prevs;
                        }, [undefined]);
                        childs = childs.filter(function (x) { return !added[x]; });
                        var tt2 = getTime();
                        seqTime[2] += (tt2 - tt);
                        tt = tt2;
                        mergeLog(">>> part A: " + childs.length);
                        childs.forEach(function (i) {
                            childs.forEach(function (j) {
                                if (i != j) {
                                    var theX = i;
                                    var theY = j;
                                    if (containsArrow(hashA, theX, theY) && (!containsArrow(hashO, theX, theY) || !containsArrow(hashB, theY, theX)))
                                        addEdge(theX, theY, edgeMap, 1);
                                }
                            });
                        });
                        var tt2 = getTime();
                        seqTime[3] += (tt2 - tt);
                        tt = tt2;
                        mergeLog(">>> part B");
                        childs.forEach(function (i) {
                            childs.forEach(function (j) {
                                if (i != j) {
                                    var theX = i;
                                    var theY = j;
                                    if (containsArrow(hashB, theX, theY) && ((containsArrow(hashO, theY, theX) && containsArrow(hashA, theY, theX)))) {
                                        addEdge(theX, theY, edgeMap, 2);
                                    }
                                }
                            });
                        });
                        var tt2 = getTime();
                        seqTime[4] += (tt2 - tt);
                        tt = tt2;
                        mergeLog(">>> SCC: " + childs.length);
                        var nums = {};
                        var comps = stronglyConnectedComponents(edgeMap, childs, nums, (childs.length > 100));
                        var tt2 = getTime();
                        seqTime[5] += (tt2 - tt);
                        tt = tt2;
                        mergeLog(">>> comps");
                        comps.forEach(function (comp) {
                            if (comp.length <= 1)
                                return;
                            comp.forEach(function (x) {
                                comp.forEach(function (y) {
                                    if (edgeMap[x][y] >= 2) {
                                        edgeMap[x][y] = 0;
                                        edgeMap[y][x] = 1;
                                    }
                                });
                            });
                        });
                        var tt2 = getTime();
                        seqTime[6] += (tt2 - tt);
                        tt = tt2;
                    }
                    mergeLog(">>> sorting");
                    childs.sort(function (a, b) {
                        if (true || oldSeqMerge) {
                            if (edgeMap[a][b] > 0) {
                                return -1;
                            }
                            else if (edgeMap[b][a] > 0) {
                                return 1;
                            }
                            else {
                                throw "merge exception: (" + a + ", " + b + ") not ordered";
                            }
                        }
                    });
                    edgeMap = null;
                    var tt2 = getTime();
                    seqTime[7] += (tt2 - tt);
                    tt = tt2;
                    function pop(answer) {
                        if (childs.length == 0)
                            return answer;
                        var first = childs.pop();
                        var a = addMap[first];
                        if (a) {
                            a.forEach(function (x) {
                                if (x && !x.used) {
                                    x.used = true;
                                    answer.unshift(x.name);
                                }
                            });
                        }
                        if (first)
                            answer.unshift(first);
                        return pop(answer);
                    }
                    if (!oldSeqMerge) {
                        childs.unshift(undefined);
                        childs = pop([]);
                        childMap[px] = childs;
                    }
                    sla.forEach(function (x) { return x.used = false; });
                    slb.forEach(function (x) { return x.used = false; });
                    addMap = null;
                    var tt2 = getTime();
                    seqTime[8] += (tt2 - tt);
                    tt = tt2;
                });
                var endX = getTime();
                var theTemp = undefined;
                delete childMap[theTemp];
                Object.keys(childMap).forEach(function (x) {
                    var childs = childMap[x];
                    var s = "";
                    if (x == getStableName(o)) {
                        s = "<<ROOT>>";
                    }
                    mergeLog(">>> Merge: parent=" + x + ", child=" + childs.join(", ") + " | " + s);
                });
                var end1 = getTime();
                mergeLog(">>> Merge: " + getTime() + " doing node-level merge...");
                var rtemp = merge3node(new HashNode(undefined, getStableName(o), [], o), new HashNode(undefined, getStableName(a), [], a), new HashNode(undefined, getStableName(b), [], b), childMap);
                var end = getTime();
                if (datacollector) {
                    var mergedata = {};
                    mergedata.totaltime = (end - start);
                    mergedata.nodeleveltime = (end - end1);
                    mergedata.seqtime = seqTime;
                    mergedata.treetime = treeTime;
                    mergedata.scctime = sccTime;
                    mergedata.numchecks = numChecks;
                    mergedata.deviceinfo = TDev.Browser.platformCaps;
                    mergedata.releaseid = TDev.Cloud.currentReleaseId;
                    datacollector(mergedata);
                }
                return rtemp;
            }
            Merge.merge3 = merge3;
            Merge.theO = undefined;
            Merge.theA = undefined;
            Merge.theB = undefined;
            Merge.theM = undefined;
            function getApp(text) {
                var app = TDev.AST.Parser.parseScript(text);
                TDev.AST.TypeChecker.tcApp(app);
                var v = new TDev.AST.InitIdVisitor(false);
                v.dispatch(app);
                return app;
            }
            function testMerge(idO, idA, idB) {
                if (idO === void 0) { idO = "yqum"; }
                if (idA === void 0) { idA = "yqum"; }
                if (idB === void 0) { idB = "xspn"; }
                TDev.ScriptCache.getScriptAsync(idO).then(function (textO) { return TDev.ScriptCache.getScriptAsync(idA).then(function (textA) { return TDev.ScriptCache.getScriptAsync(idB).then(function (textB) {
                    var table = {};
                    [[idO, textO], [idA, textA], [idB, textB]].forEach(function (x) {
                        if (!table[x[0]]) {
                            table[x[0]] = getApp(x[1]);
                        }
                    });
                    function doMerge(idO, idA, idB, compareTo) {
                        Merge.theO = table[idO];
                        Merge.theA = table[idA];
                        Merge.theB = table[idB];
                        var m = TDev.AST.Merge.merge3(Merge.theO, Merge.theA, Merge.theB);
                        TDev.AST.TypeChecker.tcApp(m);
                        Merge.theM = m;
                        var success = false;
                        var str = "merge(" + idO + "," + idA + "," + idB + ")";
                        if (table[compareTo] && m.serialize().replace(/\s*/g, "") != table[compareTo].serialize().replace(/\s*/g, "")) {
                            str += (" =/= ");
                            m.things.forEach(function (th, i) {
                                if (m.things[i].serialize().replace(/\s*/g, "") != table[compareTo].things[i].serialize().replace(/\s*/g, "")) {
                                    console.log("unequal: " + i);
                                }
                            });
                        }
                        else {
                            success = true;
                            str += (" = ");
                        }
                        console.log(str + "" + compareTo + (!success ? " ((FAIL!))" : " (success)"));
                    }
                    console.log("testing merge(x,x,x)");
                    doMerge(idO, idO, idO, idO);
                    doMerge(idA, idA, idA, idA);
                    doMerge(idB, idB, idB, idB);
                    console.log("testing merge(x,y,x)");
                    doMerge(idO, idA, idO, idA);
                    doMerge(idO, idB, idO, idB);
                    doMerge(idA, idB, idA, idB);
                    doMerge(idA, idO, idA, idO);
                    doMerge(idB, idA, idB, idA);
                    doMerge(idB, idO, idB, idO);
                    console.log("testing merge(x,x,y)");
                    doMerge(idO, idO, idA, idA);
                    doMerge(idO, idO, idB, idB);
                    doMerge(idA, idA, idB, idB);
                    doMerge(idA, idA, idO, idO);
                    doMerge(idB, idB, idA, idA);
                    doMerge(idB, idB, idO, idO);
                }); }); });
            }
            Merge.testMerge = testMerge;
            function basicTest(o, a, b) {
                if (!o) {
                    o = "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync\";\n" + "meta name \"awe-inspiring script\";\n" + "meta rootId \"nLWNALhDdDnO6mTvydoNe8aI\";\n" + "meta allowExport \"yes\";\n" + "meta platform \"current\";\n" + "meta parentIds \"\";\n" + "#main\n" + "action main() {\n" + "  #x1QgKIXXV6P3GL4v $x1 := 1;\n" + "  #nrxemFg0cPs5bQh7 $x2 := 12;\n" + "}\n" + "#main2\n" + "action main2() {\n" + "  #x1QgKIXXV6P3GL4v1 $x1 := 1;\n" + "  #nrxemFg0cPs5bQh72 $x2 := 12;\n" + "  #rpYjyryilrIApEv14 $x4 := 123;\n" + "}\n";
                }
                if (!a) {
                    a = "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync\";\n" + "meta name \"awe-inspiring script\";\n" + "meta rootId \"nLWNALhDdDnO6mTvydoNe8aI\";\n" + "meta allowExport \"yes\";\n" + "meta platform \"current\";\n" + "meta parentIds \"\";\n" + "#main\n" + "action main() {\n" + "  #nrxemFg0cPs5bQh7 $x2 := 12;\n" + "  #x1QgKIXXV6P3GL4v $x1 := 1;\n" + "}\n" + "#main2\n" + "action main2() {\n" + "  #x1QgKIXXV6P3GL4v1 $x1 := 1;\n" + "  #nrxemFg0cPs5bQh72 $x2 := 12;\n" + "  #rpYjyryilrIApEv03 $x3 := 123;\n" + "}\n";
                }
                if (!b) {
                    b = "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync\";\n" + "meta name \"awe-inspiring script\";\n" + "meta rootId \"nLWNALhDdDnO6mTvydoNe8aI\";\n" + "meta allowExport \"yes\";\n" + "meta platform \"current\";\n" + "meta parentIds \"\";\n" + "#main\n" + "action main() {\n" + "  #x1QgKIXXV6P3GL4v $x1 := 1;\n" + "  #nrxemFg0cPs5bQh7 $x2 := 12;\n" + "  #rpYjyryilrIApEv0 $x3 := 123;\n" + "  #rpYjyryilrIApEv1 $x4 := 123;\n" + "  #rpYjyryilrIApEv2 $x5 := 123;\n" + "  #rpYjyryilrIApEv3 $x6 := 123;\n" + "}\n" + "#main2\n" + "action main2() {\n" + "  #nrxemFg0cPs5bQh72 $x2 := 12;\n" + "  #x1QgKIXXV6P3GL4v1 $x1 := 1;\n" + "}\n";
                }
                Merge.theO = getApp(o);
                Merge.theA = getApp(a);
                Merge.theB = getApp(b);
                var m = TDev.AST.Merge.merge3(Merge.theO, Merge.theA, Merge.theB);
                TDev.AST.TypeChecker.tcApp(m);
                Merge.theM = m;
            }
            Merge.basicTest = basicTest;
        })(Merge = AST.Merge || (AST.Merge = {}));
        var Normalizer = (function (_super) {
            __extends(Normalizer, _super);
            function Normalizer() {
                _super.apply(this, arguments);
            }
            Normalizer.prototype.visitStmt = function (s) {
                this.visitChildren(s);
            };
            Normalizer.prototype.visitCodeBlock = function (b) {
                var newStmts = [];
                var lastPlace = false;
                b.stmts.forEach(function (s) {
                    if (s.isPlaceholder() && lastPlace)
                        return;
                    lastPlace = s.isPlaceholder();
                    newStmts.push(s);
                });
                b.stmts = newStmts;
                this.visitChildren(b);
            };
            return Normalizer;
        })(AST.NodeVisitor);
        function mergeScripts(baseText, ourText, otherText) {
            var prep = function (s) {
                var app = AST.Parser.parseScript(s, []);
                AST.TypeChecker.tcScript(app, true);
                new AST.InitIdVisitor(false).dispatch(app);
                return app;
            };
            var baseApp = prep(baseText);
            var ourApp = prep(ourText);
            var otherApp = prep(otherText);
            var mergedApp = Merge.merge3(baseApp, ourApp, otherApp);
            mergedApp.parentIds = ourApp.parentIds.slice(0);
            AST.Diff.diffApps(ourApp, mergedApp, { useStableNames: false });
            return mergedApp;
        }
        AST.mergeScripts = mergeScripts;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Apps;
        (function (Apps) {
            function cordovaDefaultOptions() {
                var opts = {
                    email: "",
                    website: "",
                    domain: "",
                    platforms: {}
                };
                Object.keys(cordovaPlatforms).forEach(function (p) {
                    if (!!cordovaPlatforms[p].build) {
                        opts.platforms[p] = {
                            build: !!cordovaPlatforms[p].build,
                            runs: cordovaPlatforms[p].runs || [p]
                        };
                    }
                });
                return opts;
            }
            Apps.cordovaDefaultOptions = cordovaDefaultOptions;
            function getDeploymentInstructionsAsync(app, options) {
                var html = TDev.webappHtml;
                if (!options.userId)
                    options.userId = "unknown";
                if (!options.filePrefix)
                    options.filePrefix = "";
                var isCloud = options.compileServer && (options.skipClient || app.isCloud);
                var opts = {
                    packaging: true,
                    javascript: true,
                    scriptId: options.scriptId,
                    authorId: options.userId,
                    scriptGuid: app.localGuid,
                    azureSite: options.azureSite,
                };
                var setProp = function (s, v) {
                    html = html.replace(s.replace(/{.*}/, ""), TDev.Util.fmt(s, v));
                };
                html = html.replace("precompiled.js?a=", "precompiled.js");
                var instructions = {
                    meta: {},
                    files: []
                };
                if (!isCloud) {
                    var head = Object.keys(app.imports.clientScripts).map(function (url) {
                        if (/\.css$/i.test(url))
                            return TDev.Util.fmt('<link rel="stylesheet" href="{0:url}">', url);
                        if (/\.js$/i.test(url))
                            return TDev.Util.fmt('<script type="text/javascript" src="{0:url}"></script>', url);
                    });
                    html = html.replace("</head>", "    " + head.join("\n    ") + "\n</head>");
                }
                if (options.cordova) {
                    html = html.replace("</head>", "    <script src='cordova.js'></script>\n</head>");
                    instructions.cordova = {
                        plugins: [],
                        platforms: {},
                        runs: []
                    };
                }
                setProp("<title>{0:q}</title>", app.getName());
                setProp('property="og:title" content="{0:q}"', app.getName());
                setProp('var userId = "{0:jq}"', options.userId);
                setProp('var webAppName = "{0:jq}"', app.getName());
                setProp('var webAppGuid = "{0:jq}"', app.localGuid);
                setProp('var runtimeFlags = "{0:jq}"', options.runtimeFlags || "");
                var theBase = TDev.Cloud.config.primaryCdnUrl + "/app/" + options.relId + "/c/";
                AST.TypeChecker.tcApp(app);
                var compiled = AST.Compiler.getCompiledScript(app, opts);
                var errs = "";
                app.librariesAndThis().forEach(function (lib) {
                    if (!lib.resolved)
                        errs += "Unresolved library: " + lib.getName() + "\n";
                    else
                        lib.resolved.things.forEach(function (t) {
                            if (t.hasErrors())
                                errs += "Errors in " + lib.getName() + "->" + t.getName() + "\n";
                        });
                });
                if (errs) {
                    instructions.error = errs;
                    if (options.failOnError) {
                        TDev.ModalDialog.info(TDev.lf("compilation errors"), errs);
                        return new TDev.PromiseInv();
                    }
                }
                instructions.packageResources = compiled.packageResources;
                var clientCode = "";
                if (isCloud) {
                    TDev.Util.assert(opts.javascript, "javascript should have been on");
                    clientCode = "var TDev; if (!TDev) TDev = {}; TDev.isWebserviceOnly = true;";
                }
                else {
                    clientCode = compiled.getCompiledCode();
                    if (options.cordova) {
                        TDev.Util.assert(opts.javascript, "javascript should have been on");
                        instructions.files.push({
                            path: options.filePrefix + "cordovaPlugins.json",
                            content: JSON.stringify(compiled.imports.cordovaPlugins, null, 2)
                        });
                        Object.keys(options.cordova.platforms).forEach(function (p) {
                            if (options.cordova.platforms[p].build) {
                                instructions.cordova.platforms[p] = cordovaPlatforms[p];
                                options.cordova.platforms[p].runs.forEach(function (run) { return instructions.cordova.runs.push(run); });
                            }
                        });
                        instructions.cordova.plugins = Object.keys(compiled.imports.cordovaPlugins).map(function (k) { return k + (!k || /^https?:\/\//.test(k) || /^\*?$/.test(compiled.imports.cordovaPlugins[k]) ? "" : "@" + compiled.imports.cordovaPlugins[k]); });
                    }
                    compiled.packageResources.forEach(function (pr) {
                        instructions.files.push({
                            path: options.filePrefix + pr.packageUrl.replace(/^\.\//, ""),
                            url: TDev.HTML.proxyResource(pr.url),
                            content: pr.content,
                            kind: pr.kind,
                            type: pr.type,
                            sourceName: pr.sourceName,
                            isUnused: pr.usageLevel === 0,
                        });
                        if (pr.type == "sound") {
                            var mp4 = TDev.HTML.patchWavToMp4Url(pr.url);
                            if (pr.url != mp4)
                                instructions.files.push({
                                    path: options.filePrefix + pr.packageUrl.replace(/^\.\//, "") + ".m4a",
                                    url: mp4,
                                    kind: pr.kind,
                                    sourceName: pr.sourceName,
                                    isUnused: pr.usageLevel === 0,
                                });
                        }
                    });
                    if (app.getIconArtId()) {
                        instructions.files.push({
                            path: options.filePrefix + 'art/icon',
                            url: TDev.Cloud.artUrl(app.getIconArtId()),
                            kind: "art",
                            type: "picture",
                            sourceName: "icon",
                            isUnused: false,
                        });
                    }
                    if (app.splashArtId) {
                        instructions.files.push({
                            path: options.filePrefix + 'art/splash',
                            url: TDev.Cloud.artUrl(app.splashArtId),
                            kind: "art",
                            type: "picture",
                            sourceName: "splash",
                            isUnused: false,
                        });
                    }
                }
                if (options.compileServer) {
                    opts.packaging = false;
                    opts.cloud = true;
                    opts.javascript = true;
                    compiled = AST.Compiler.getCompiledScript(app, opts);
                    var serverCode = compiled.getCompiledCode();
                    compiled.imports.npmModules["faye-websocket"] = "0.8.1";
                    var pkgJson = {
                        name: "td-" + app.getName().replace(/[^a-zA-Z0-9]/g, "-"),
                        version: "0.0.0",
                        private: true,
                        dependencies: compiled.imports.npmModules
                    };
                    instructions.files.push({
                        path: "package.json",
                        content: JSON.stringify(pkgJson, null, 2)
                    });
                    instructions.files.push({
                        path: "script/compiled.js",
                        content: serverCode,
                    });
                    var pipPkgs = Object.keys(compiled.imports.pipPackages);
                    if (pipPkgs.length > 0) {
                        instructions.files.push({
                            path: "requirements.txt",
                            content: pipPkgs.map(function (pkg) {
                                var r = pkg;
                                var v = compiled.imports.pipPackages[pkg] || "";
                                if (v != "*" && !/^(==|>=)/.test(v))
                                    r += "==" + v;
                                return r;
                            }).join('\n')
                        });
                        instructions.files.push({
                            path: "runtime.txt",
                            content: "python-2.7"
                        });
                    }
                }
                instructions.files.push({
                    path: options.filePrefix + "precompiled.js",
                    content: clientCode,
                });
                instructions.files.push({
                    path: options.filePrefix + "index.html",
                    content: html,
                });
                var baseUrl = options.baseUrl;
                var addFileAsync = function (fn, pref) {
                    if (!pref)
                        pref = options.filePrefix;
                    if (options.downloadLocalFilesFrom) {
                        return TDev.Util.httpGetTextAsync(options.downloadLocalFilesFrom + fn).then(function (content) {
                            instructions.files.push({
                                path: pref + fn,
                                content: content
                            });
                        });
                    }
                    else {
                        instructions.files.push({
                            path: pref + fn,
                            url: theBase + fn
                        });
                        return TDev.Promise.as();
                    }
                };
                var lst = ["default.css", "browser.js", "runtime.js"].map(function (n) { return addFileAsync(n); });
                if (options.compileServer)
                    lst.push(addFileAsync("noderuntime.js", "script/"));
                if (!options.cordova) {
                    if (options.downloadLocalFilesFrom) {
                        lst.push(addFileAsync("error.html"));
                        lst.push(addFileAsync("browsers.html"));
                    }
                    else {
                        ["error", "browsers"].forEach(function (n) { return instructions.files.push({
                            path: options.filePrefix + n + ".html",
                            url: TDev.Cloud.getServiceUrl() + "/app/" + n + ".html?releaseid=" + options.relId
                        }); });
                    }
                }
                instructions.meta.isCloud = app.isCloud;
                return TDev.Promise.join(lst).then(function () { return instructions; });
            }
            Apps.getDeploymentInstructionsAsync = getDeploymentInstructionsAsync;
            var densitySizes = {
                hdpi: 72,
                ldpi: 36,
                mdpi: 48,
                xhdpi: 96,
                xxhdpi: 144
            };
            var cordovaPlatforms = {
                "windows": {
                    build: true,
                    runs: ["windows -- --win", "windows --device -- --phone", "windows -- --phone"],
                    res: "windows8",
                    icons: [
                        { src: "res/windows8/logo.png", width: 150 },
                        { src: "res/windows8/smalllogo.png", width: 30 },
                        { src: "res/windows8/storelogo.png", width: 50 }
                    ],
                    splash: [
                        { src: "res/screen/windows8/splashscreen.png", width: 620, height: 300 },
                    ]
                },
                "ios": {
                    build: true,
                    icons: [
                        { src: "res/ios/icon-60@3x.png", width: 180 },
                        { src: "res/ios/icon-60.png", width: 60 },
                        { src: "res/ios/icon-60@2x.png", width: 120 },
                        { src: "res/ios/icon-76.png", width: 76 },
                        { src: "res/ios/icon-76@2x.png", width: 152 },
                        { src: "res/ios/icon-40.png", width: 40 },
                        { src: "res/ios/icon-40@2x.png", width: 80 },
                        { src: "res/ios/icon.png", width: 57 },
                        { src: "res/ios/icon@2x.png", width: 114 },
                        { src: "res/ios/icon-72.png", width: 72 },
                        { src: "res/ios/icon-72@2x.png", width: 144 },
                        { src: "res/ios/icon-small.png", width: 29 },
                        { src: "res/ios/icon-small@2x.png", width: 58 },
                        { src: "res/ios/icon-50.png", width: 50 },
                        { src: "res/ios/icon-50@2x.png", width: 100 },
                    ],
                    splash: [
                        { src: "res/screen/ios/Default~iphone.png", width: 320, height: 480 },
                        { src: "res/screen/ios/Default@2x~iphone.png", width: 640, height: 960 },
                        { src: "res/screen/ios/Default-Portrait~ipad.png", width: 768, height: 1024 },
                        { src: "res/screen/ios/Default-Portrait@2x~ipad.png", width: 1536, height: 2048 },
                        { src: "res/screen/ios/Default-Landscape~ipad.png", width: 1024, height: 768 },
                        { src: "res/screen/ios/Default-Landscape@2x~ipad.png", width: 2048, height: 1536 },
                        { src: "res/screen/ios/Default-568h@2x~iphone.png", width: 640, height: 1136 },
                        { src: "res/screen/ios/Default-667h.png", width: 750, height: 1334 },
                        { src: "res/screen/ios/Default-736h.png", width: 1242, height: 2208 },
                        { src: "res/screen/ios/Default-Landscape-736h.png", width: 2208, height: 1242 }
                    ]
                },
                "android": {
                    build: true,
                    icons: [
                        { src: "res/android/ldpi.png", density: "ldpi", width: densitySizes["ldpi"] },
                        { src: "res/android/mdpi.png", density: "mdpi", width: densitySizes["mdpi"] },
                        { src: "res/android/hdpi.png", density: "hdpi", width: densitySizes["hdpi"] },
                        { src: "res/android/xhdpi.png", density: "xhdpi", width: densitySizes["xhdpi"] }
                    ],
                    splash: [
                        { src: "res/screen/android/splash-land-hdpi.png", density: "land-hdpi", width: densitySizes["hdpi"] },
                        { src: "res/screen/android/splash-land-ldpi.png", density: "land-ldpi", width: densitySizes["ldpi"] },
                        { src: "res/screen/android/splash-land-mdpi.png", density: "land-mdpi", width: densitySizes["mdpi"] },
                        { src: "res/screen/android/splash-land-xhdpi.png", density: "land-xhdpi", width: densitySizes["xhdpi"] },
                        { src: "res/screen/android/splash-port-hdpi.png", density: "port-hdpi", width: densitySizes["hdpi"] },
                        { src: "res/screen/android/splash-port-ldpi.png", density: "port-ldpi", width: densitySizes["ldpi"] },
                        { src: "res/screen/android/splash-port-mdpi.png", density: "port-mdpi", width: densitySizes["mdpi"] },
                        { src: "res/screen/android/splash-port-xhdpi.png", density: "port-xhdpi", width: densitySizes["xhdpi"] }
                    ]
                },
                "amazon-fireos": {
                    icons: [
                        { src: "res/android/ldpi.png", density: "ldpi", width: densitySizes["ldpi"] },
                        { src: "res/android/mdpi.png", density: "mdpi", width: densitySizes["mdpi"] },
                        { src: "res/android/hdpi.png", density: "hdpi", width: densitySizes["hdpi"] },
                        { src: "res/android/xhdpi.png", density: "xhdpi", width: densitySizes["xhdpi"] }
                    ]
                },
                "blackberry10": {
                    res: "bb10",
                    icons: [
                        { src: "res/bb10/icon-86.png", width: 86 },
                        { src: "res/bb10/icon-150.png", width: 150 },
                    ],
                },
                "firefoxos": {
                    res: "ff",
                    icons: [
                        { src: "res/ff/logo.png", width: 60 }
                    ]
                },
                "tizen": {
                    icons: [{ src: "res/tizen/icon-128.png", width: 128 }]
                },
            };
        })(Apps = AST.Apps || (AST.Apps = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Fixer;
        (function (Fixer) {
            function flatten(e0) {
                var r = [];
                function pushOp(c) {
                    r.push(AST.mkOp(c));
                }
                function call(e, outPrio) {
                    if (e.savedFix)
                        e = e.savedFix;
                    if (e.propRef.fromOp && e.propRef.fromOp.getFunArgs()) {
                        r.push(e.propRef.fromOp);
                        rec(e.args[1], -1);
                        return;
                    }
                    var p = e.getCalledProperty();
                    var infixPri = p.getInfixPriority() || 0;
                    if (infixPri) {
                        if (p.getName() == "-" && e.args[0].getLiteral() === 0.0) {
                            pushOp(p.getName());
                            rec(e.args[1], 98);
                            return;
                        }
                        if (infixPri < outPrio)
                            pushOp("(");
                        if (e.args.length == 1) {
                            pushOp(p.getName());
                            rec(e.args[0], infixPri);
                        }
                        else {
                            var bindLeft = infixPri != 4 && infixPri != 98;
                            rec(e.args[0], bindLeft ? infixPri : infixPri + 0.1);
                            pushOp(p.getName());
                            rec(e.args[1], !bindLeft ? infixPri : infixPri + 0.1);
                        }
                        if (infixPri < outPrio)
                            pushOp(")");
                    }
                    else {
                        rec(e.args[0], 1000);
                        r.push(AST.mkPropRef(p.getName()));
                        var args = e.args.slice(1).filter(function (a) { return !a.isEscapeDef(); });
                        if (args.length > 0) {
                            pushOp("(");
                            args.forEach(function (ee, i) {
                                if (i > 0)
                                    pushOp(",");
                                rec(ee, -1);
                            });
                            pushOp(")");
                        }
                    }
                }
                function rec(e, prio) {
                    if (e instanceof AST.Call)
                        call(e, prio);
                    else if (typeof e.getLiteral() === "number")
                        TDev.Util.numberToStringNoE(e.getLiteral()).split("").forEach(pushOp);
                    else
                        r.push(e);
                }
                rec(e0, -1);
                return r;
            }
            function staticPropRef(s, p) {
                return [AST.mkThing(s), AST.mkPropRef(p)];
            }
            function findDefaultCore(p) {
                var defl = p.getDefaultValue();
                if (!!defl)
                    return defl;
                var k = p.getKind();
                switch (k.getName()) {
                    case "Number": return [AST.mkOp("0")];
                    case "String": return [AST.mkLit("")];
                    case "Boolean": return [AST.mkLit(false)];
                    case "Color": return AST.proMode ? null : staticPropRef("colors", "random");
                }
                if (k.isAction) {
                    var ak = k;
                    var pp = ak.getOutParameters();
                    if (pp.length == 1) {
                        return [AST.mkFunOp(ak.getInParameters().map(function (p) { return p.getName(); }))].concat(findDefaultCore(pp[0]) || [AST.mkPlaceholder(pp[0])]);
                    }
                }
                return null;
            }
            function tokenize(toks) {
                return toks.collect(function (t) {
                    if (t instanceof AST.Literal)
                        return flatten(t);
                    else
                        return [t];
                });
            }
            Fixer.tokenize = tokenize;
            function findDefault(p, locals) {
                var r = findDefaultCore(p);
                if (!r) {
                    var numChoices = 0;
                    if (!AST.proMode)
                        TDev.Script.variables().forEach(function (g) {
                            if (g.getKind() == p.getKind()) {
                                numChoices++;
                                r = [AST.mkThing("data"), AST.mkPropRef(g.getName())];
                            }
                        });
                    locals.forEach(function (l) {
                        if (l.getKind() == p.getKind()) {
                            numChoices++;
                            r = [AST.mkThing(l.getName())];
                        }
                    });
                    if (AST.proMode && numChoices > 1)
                        r = null;
                }
                if (!r) {
                    r = [AST.mkPlaceholder(p)];
                }
                return tokenize(r);
            }
            Fixer.findDefault = findDefault;
            function getFix(eh) {
                if (!eh.hasFix || !eh.parsed)
                    return null;
                return flatten(eh.parsed);
            }
            Fixer.getFix = getFix;
        })(Fixer = AST.Fixer || (AST.Fixer = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var useAsync = false;
        var TsQuotingCtx = (function (_super) {
            __extends(TsQuotingCtx, _super);
            function TsQuotingCtx() {
                _super.apply(this, arguments);
            }
            TsQuotingCtx.prototype.unUnicode = function (s) {
                s = s.replace(/#/g, " sharp ");
                s = s.replace(/\+/g, " plus ");
                s = s.replace(/\s+([A-Za-z])/g, function (v, l) { return l.toUpperCase(); });
                s = s.replace(/[^a-zA-Z0-9]+/g, "_");
                if (s == "" || /^[0-9]/.test(s) || TsQuotingCtx.keywords.hasOwnProperty(s))
                    s = "_" + s;
                return s;
            };
            TsQuotingCtx.keywords = {
                "break": 1,
                "case": 1,
                "class": 1,
                "catch": 1,
                "const": 1,
                "continue": 1,
                "debugger": 1,
                "default": 1,
                "delete": 1,
                "do": 1,
                "else": 1,
                "export": 1,
                "extends": 1,
                "finally": 1,
                "for": 1,
                "function": 1,
                "if": 1,
                "import": 1,
                "in": 1,
                "instanceof": 1,
                "let": 1,
                "new": 1,
                "return": 1,
                "super": 1,
                "switch": 1,
                "this": 1,
                "throw": 1,
                "try": 1,
                "typeof": 1,
                "var": 1,
                "void": 1,
                "while": 1,
                "with": 1,
                "yield": 1,
                "enum": 1,
                "await": 1,
                "implements": 1,
                "package": 1,
                "protected": 1,
            };
            return TsQuotingCtx;
        })(AST.QuotingCtx);
        function stringLit(s) {
            if (s.length > 20 && /\n/.test(s)) {
                if (/^[01 \n]*$/.test(s))
                    s = "\n" + s.replace(/0/g, ".").replace(/1/g, "#") + "\n";
                return "`" + s.replace(/[\\`${}]/g, function (f) { return "\\" + f; }) + "`";
            }
            else
                return JSON.stringify(s);
        }
        var TsTokenWriter = (function (_super) {
            __extends(TsTokenWriter, _super);
            function TsTokenWriter() {
                _super.call(this);
                this.globalCtx = new TsQuotingCtx();
                this.highlight = 0;
                this.indentString = "    ";
            }
            TsTokenWriter.prototype.finalize = function (skipNL) {
                if (skipNL === void 0) { skipNL = false; }
                var ret = _super.prototype.finalize.call(this, skipNL);
                ret = ret.replace(/(\s+)\}\n\s*else/, function (a, b) { return b + "} else"; });
                return ret;
            };
            TsTokenWriter.prototype.getGlobalId = function (d, pref) {
                if (pref === void 0) { pref = ""; }
                var n = d.getName();
                if (d instanceof AST.RecordDef || (d instanceof AST.Action && d.isActionTypeDef())) {
                    n = n[0].toUpperCase() + n.slice(1);
                }
                else if (d instanceof AST.Action) {
                    var a = d;
                    if (useAsync && !a.isAtomic)
                        n += "Async";
                }
                return this.globalCtx.quote(pref + n, 0);
            };
            TsTokenWriter.prototype.globalId = function (d, pref) {
                if (pref === void 0) { pref = ""; }
                var quoted = this.getGlobalId(d, pref);
                return this.jsid(quoted);
            };
            TsTokenWriter.prototype.sep = function () {
                if (" ([<.".indexOf(this.lastChar) >= 0)
                    return this;
                return _super.prototype.sep.call(this);
            };
            TsTokenWriter.prototype.jsid = function (id) {
                if (!/^[a-zA-Z_]\w*$/.test(id))
                    TDev.Util.oops("bad id: " + id);
                return this.sep().write(id);
            };
            TsTokenWriter.prototype.kw = function (k) {
                return this.keyword(k);
            };
            TsTokenWriter.prototype.semiNL = function () {
                if (this.highlight)
                    this.sep().write("// ***");
                this.nl();
                return this;
            };
            TsTokenWriter.prototype.comment = function (s) {
                var _this = this;
                var inner = AST.MdDocs.formatText(s).trim();
                inner.split("\n").forEach(function (l) { return _this.op("//").space().write(l).nl(); });
                return this;
            };
            return TsTokenWriter;
        })(AST.TokenWriter);
        var AsyncFinder = (function (_super) {
            __extends(AsyncFinder, _super);
            function AsyncFinder() {
                _super.apply(this, arguments);
            }
            AsyncFinder.prototype.visitCall = function (c) {
                if (c.awaits())
                    this.lastAsync = c;
                _super.prototype.visitCall.call(this, c);
            };
            return AsyncFinder;
        })(AST.ExprVisitor);
        var ConverterPrep = (function (_super) {
            __extends(ConverterPrep, _super);
            function ConverterPrep(tw) {
                _super.call(this);
                this.tw = tw;
                this.numAwaits = 0;
            }
            ConverterPrep.prototype.visitAstNode = function (n) {
                delete n._converterValue;
                this.visitChildren(n);
            };
            ConverterPrep.prototype.visitInlineActions = function (s) {
                var pre = this.numAwaits;
                this.dispatch(s.expr);
                s._converterAwait = pre < this.numAwaits;
                s.normalActions().forEach(function (a) { return a.name._converterAction = a; });
                _super.prototype.visitStmt.call(this, s);
            };
            ConverterPrep.prototype.visitStmt = function (s) {
                var pre = this.numAwaits;
                _super.prototype.visitStmt.call(this, s);
                s._converterAwait = pre < this.numAwaits;
            };
            ConverterPrep.prototype.visitExprHolder = function (eh) {
                if (eh.isAwait)
                    this.numAwaits++;
                _super.prototype.visitExprHolder.call(this, eh);
            };
            ConverterPrep.prototype.visitThingRef = function (t) {
                var l = t.referencedLocal();
                if (l && typeof l._converterUses == "number")
                    l._converterUses++;
            };
            ConverterPrep.prototype.visitAction = function (a) {
                a.getOutParameters().forEach(function (op) {
                    op.local._converterUses = 0;
                });
                _super.prototype.visitAction.call(this, a);
            };
            ConverterPrep.prototype.visitDecl = function (d) {
                this.tw.getGlobalId(d);
                _super.prototype.visitDecl.call(this, d);
            };
            return ConverterPrep;
        })(AST.NodeVisitor);
        (function (SymbolKind) {
            SymbolKind[SymbolKind["None"] = 0] = "None";
            SymbolKind[SymbolKind["Method"] = 1] = "Method";
            SymbolKind[SymbolKind["Property"] = 2] = "Property";
            SymbolKind[SymbolKind["Function"] = 3] = "Function";
            SymbolKind[SymbolKind["Variable"] = 4] = "Variable";
            SymbolKind[SymbolKind["Module"] = 5] = "Module";
            SymbolKind[SymbolKind["Enum"] = 6] = "Enum";
            SymbolKind[SymbolKind["EnumMember"] = 7] = "EnumMember";
        })(AST.SymbolKind || (AST.SymbolKind = {}));
        var SymbolKind = AST.SymbolKind;
        function td2ts(options) {
            AST.reset();
            var errRes = null;
            var okRes = null;
            AST.loadScriptAsync(function (s) { return TDev.Promise.as(s == "" ? options.text : null); }).then(function (r) {
                okRes = r;
            }, function (err) {
                errRes = err;
            });
            if (errRes)
                throw errRes;
            var r = new TDev.AST.Converter(TDev.Script, options).run();
            r.tdres = okRes;
            okRes.errLibs = null;
            okRes.prevScript = null;
            return r;
        }
        AST.td2ts = td2ts;
        function testConverterAsync() {
            return TDev.Util.httpGetJsonAsync("http://localhost:4242/editor/local/apiinfo.json").then(function (json) {
                var r = new TDev.AST.Converter(TDev.Script, {
                    useExtensions: true,
                    apiInfo: json
                }).run();
                return r.text;
            });
        }
        AST.testConverterAsync = testConverterAsync;
        var Converter = (function (_super) {
            __extends(Converter, _super);
            function Converter(app, options) {
                var _this = this;
                if (options === void 0) { options = {}; }
                _super.call(this);
                this.app = app;
                this.options = options;
                this.tw = new TsTokenWriter();
                this.builtinCtx = new TsQuotingCtx();
                this.localCtx = new TsQuotingCtx();
                this.apis = {};
                this.allEnums = {};
                this.isReachable = true;
                if (this.options.apiInfo) {
                    Object.keys(this.options.apiInfo.byQName).forEach(function (k) {
                        if (k.indexOf(".") == -1)
                            _this.tw.globalCtx.reservedNames[k] = 1;
                    });
                }
            }
            Converter.prototype.run = function () {
                var _this = this;
                new ConverterPrep(this.tw).dispatch(this.app);
                this.dispatch(this.app);
                var keys = Object.keys(this.apis);
                keys.sort(function (a, b) { return _this.apis[a] - _this.apis[b]; });
                var newApis = {};
                keys.forEach(function (k) { return newApis[k] = _this.apis[k]; });
                var txt = (this.tw.finalize().trim() + "\n").replace(/\n\n+/g, "\n\n");
                return {
                    text: txt,
                    apis: newApis,
                };
            };
            Converter.prototype.renderSnippet = function (stmts) {
                var _this = this;
                this.tw.clear();
                stmts.forEach(function (s) { return _this.dispatch(s); });
                return this.tw.finalize();
            };
            Converter.prototype.renderSig = function (act) {
                this.tw.clear();
                this.printActionHeader(act);
                return this.tw.finalize();
            };
            Converter.prototype.localName = function (l) {
                if (l == this.thisLocal)
                    this.tw.kw("this");
                else
                    this.tw.jsid(this.localCtx.quote(l.getName(), l.nodeId));
                return this.tw;
            };
            Converter.prototype.type = function (t) {
                if (t.getRoot() == AST.api.core.Collection) {
                    this.type(t.getParameter(0));
                    this.tw.op0("[]");
                }
                else if (t.getRoot() == AST.api.core.Task) {
                    this.tw.write("Promise<");
                    this.type(t.getParameter(0));
                    this.tw.write(">");
                }
                else if (t.getRecord()) {
                    var parL = t.getRecord().parentLibrary();
                    if (parL && !parL.isThis())
                        this.tw.globalId(parL).op0(".");
                    this.tw.globalId(t.getRecord());
                }
                else if (t.parentLibrary()) {
                    var n = t.getName();
                    n = n[0].toUpperCase() + n.slice(1);
                    this.tw.jsid(this.builtinName(n));
                }
                else if (Converter.kindMap.hasOwnProperty(t.toString())) {
                    this.tw.kw(Converter.kindMap[t.toString()]);
                }
                else {
                    this.tw.id(this.localCtx.unUnicode(t.getRoot().toString()));
                    var len = t.getParameterCount();
                    if (len > 0) {
                        this.tw.write("<");
                        this.type(t.getParameter(0));
                        this.tw.write(">");
                    }
                }
                return this.tw;
            };
            Converter.prototype.localDef = function (l) {
                this.localName(l).op0(":");
                return this.type(l.getKind());
            };
            Converter.prototype.builtinName = function (n) {
                return this.builtinCtx.quote(n, 0);
            };
            Converter.prototype.visitAstNode = function (n) {
                this.visitChildren(n);
            };
            Converter.prototype.toRegex = function (e, flags) {
                if (flags === void 0) { flags = ""; }
                var l = e.getLiteral();
                if (l)
                    this.tw.write("/" + l.replace(/\\?\//g, "\\/") + "/" + flags);
                else {
                    this.tw.write("new RegExp(");
                    this.dispatch(e);
                    if (flags)
                        this.tw.write(", " + JSON.stringify(flags));
                    this.tw.write(")");
                }
            };
            Converter.prototype.bitop = function (p) {
                if (p.parentKind.getName() != "Bits")
                    return null;
                switch (p.getName().replace(/ u?int32$/, "")) {
                    case "or": return "|,4.1";
                    case "xor": return "^,4.2";
                    case "and": return "&,4.3";
                    case "shift left": return "<<,7";
                    case "shift right": return ">>>,7";
                }
                return null;
            };
            Converter.prototype.infixPri = function (e) {
                var p = e.getCalledProperty();
                if (!p)
                    return 0;
                if (p.getName() == "is invalid")
                    return 5;
                if (e instanceof AST.Call && e.funAction)
                    return 0.1;
                if (p.parentKind == AST.api.core.String) {
                    if (p.getName() == "equals" || p.getName() == "is empty")
                        return 5;
                    if (p == AST.api.core.StringConcatProp)
                        return 10;
                }
                else if (p.parentKind == AST.api.core.Boolean) {
                    if (p.getName() == "not") {
                        var a0 = e.args[0].getCalledProperty();
                        if (a0 && a0.getName() == "is invalid")
                            return 5;
                        if (a0 && a0.parentKind == AST.api.core.String && (a0.getName() == "is empty" || a0.getName() == "equals"))
                            return 5;
                        return 50;
                    }
                    else if (p.getName() == "equals") {
                        return 5;
                    }
                }
                else if (p.getName() == "mod" && p.parentKind.getName() == "Math") {
                    return 20;
                }
                else if (this.bitop(p)) {
                    return parseFloat(this.bitop(p).split(/,/)[1]);
                }
                else if (e instanceof AST.Call && e.awaits()) {
                    return 40;
                }
                return p.getInfixPriority() || 0;
            };
            Converter.prototype.visitCall = function (e) {
                if (e == this.currAsync) {
                    this.tw.jsid("_");
                    return;
                }
                if (useAsync && e.awaits()) {
                    this.tw.write("await").space();
                }
                this.visitCallInner(e);
            };
            Converter.prototype.propName = function (e) {
                var p = e.getCalledProperty();
                if (!p)
                    return null;
                return p.parentKind.getRoot().toString() + "->" + p.getName();
            };
            Converter.prototype.dumpJs = function (s) {
                var _this = this;
                this.tw.write("/*JS*/").nl();
                s.split("\n").forEach(function (l) {
                    l = l.replace(/(TDev\.Util|lib)\.userError\(/g, "throw new Error(");
                    _this.tw.write(l).nl();
                });
            };
            Converter.prototype.fixupArgs = function (e, nameOverride) {
                var _this = this;
                if (!e.args[0])
                    return;
                if (!nameOverride) {
                    var th = e.args[0].getThing();
                    if (!(th instanceof AST.SingletonDef))
                        return;
                    if (th.getKind() instanceof TDev.ThingSetKind)
                        return;
                }
                if (!this.options.apiInfo)
                    return;
                var p = e.getCalledProperty();
                var fullName = nameOverride || this.builtinName(e.args[0].getThing().getName()) + "." + this.builtinName(p.getName());
                var apiInfo = this.options.apiInfo.byQName[fullName];
                if (!apiInfo) {
                    this.tw.write("/*WARN: no api " + fullName + "*/");
                    return;
                }
                e.args.slice(1).forEach(function (a, i) {
                    var litVal = a.getLiteral();
                    if (!litVal || typeof litVal != "string")
                        return;
                    litVal = litVal.toLowerCase();
                    var pi = apiInfo.parameters[i];
                    if (!pi)
                        return;
                    var enumInfo = _this.options.apiInfo.byQName[pi.type];
                    if (enumInfo && enumInfo.kind == 6 /* Enum */) {
                        var members = TDev.Util.values(_this.options.apiInfo.byQName).filter(function (e) { return e.namespace == pi.type && (e.name.toLowerCase() == litVal || (e.attributes.block || "").toLowerCase() == litVal); });
                        if (members.length >= 1) {
                            a._converterValue = members[0].namespace + "." + members[0].name;
                            if (members.length > 1) {
                                a._converterValue += " /*WARN: more possible!*/";
                            }
                        }
                        else {
                            a._converterValue = pi.type + "." + a.getLiteral() + " /*WARN: not found*/";
                        }
                    }
                });
            };
            Converter.prototype.visitCallInner = function (e) {
                var _this = this;
                var p = e.getCalledProperty();
                var infixPri = this.infixPri(e);
                var pn = this.propName(e);
                if (infixPri == 40)
                    infixPri = 0;
                var params = function (pp) {
                    if (pp.peek() && pp.peek().isEscapeDef() && pp.peek().def.escapeDef.isEmpty)
                        pp.pop();
                    _this.pcommaSep(pp, function (p) { return _this.dispatch(p); });
                };
                if (p.parentKind == AST.api.core.Unknown && /^(return|break|continue)$/.test(p.getName())) {
                    this.tw.kw(p.getName());
                    if (!e.args[0].isPlaceholder()) {
                        this.tw.sep();
                        this.dispatch(e.args[0]);
                    }
                    this.isReachable = false;
                    return;
                }
                var realargs = e.args.slice(0);
                if (realargs[0] && (realargs[0].getThing() instanceof AST.SingletonDef || realargs[0].referencedLibrary()))
                    realargs.shift();
                var prefixName = Converter.prefixGlue[pn];
                var methodName = Converter.methodRepl[pn];
                if (!methodName && !prefixName && p.parentKind instanceof AST.LibraryRefKind && /micro:bit/.test(p.parentKind.getName())) {
                    var tmpname = this.builtinName(p.getName());
                    var elt = TDev.Util.values(this.options.apiInfo.byQName).filter(function (e) { return e.namespace && e.name == tmpname; })[0];
                    if (elt)
                        prefixName = elt.namespace + "." + elt.name;
                }
                if (!infixPri && !methodName && !/^Invalid->/.test(pn))
                    this.fixupArgs(e, prefixName);
                if (infixPri) {
                    if (p.getName() == "-" && e.args[0].getLiteral() === 0.0) {
                        this.tw.op0("-");
                        this.dispatch(e.args[1]);
                        return;
                    }
                    if (e.funAction) {
                        if (e.funAction.inParameters.length == 1) {
                            this.localName(e.funAction.inParameters[0]);
                        }
                        else {
                            this.pcommaSep(e.funAction.inParameters, function (p) { return _this.localName(p); });
                        }
                        this.tw.op("=>");
                        this.dispatch(e.args[1]);
                        return;
                    }
                    var doParen = function (e) {
                        if (_this.infixPri(e) && _this.infixPri(e) <= infixPri && e.getCalledProperty().getName() != p.getName()) {
                            _this.tw.op0("(");
                            _this.dispatch(e);
                            _this.tw.op0(")");
                        }
                        else
                            _this.dispatch(e);
                    };
                    if (p.getName() == "is invalid") {
                        doParen(e.args[0]);
                        this.tw.sep().write("== null");
                    }
                    else if (p.getName() == "async") {
                        this.tw.write("/* async */ ");
                        this.dispatch(e.args[1]);
                    }
                    else if (p.getName() == "is empty") {
                        var inner0 = e.args[0].getCalledProperty();
                        if (inner0 && inner0.getName() == "or empty") {
                            this.tw.op0("!");
                            this.tightExpr(e.args[0].args[1]);
                        }
                        else {
                            doParen(e.args[0]);
                            this.tw.sep().write("== \"\"");
                        }
                    }
                    else if (infixPri == 5 && p.getName() == "not") {
                        doParen(e.args[0].args[0]);
                        switch (e.args[0].getCalledProperty().getName()) {
                            case "is invalid":
                                this.tw.sep().write("!= null");
                                break;
                            case "is empty":
                                this.tw.sep().write("!= \"\"");
                                break;
                            case "equals":
                                this.tw.op("!=");
                                doParen(e.args[0].args[1]);
                                break;
                            default: TDev.Util.die();
                        }
                    }
                    else if (e.args.length == 1) {
                        this.printOp(p.getName());
                        doParen(e.args[0]);
                    }
                    else if (e._assignmentInfo && e._assignmentInfo.targets && e._assignmentInfo.targets.length > 1) {
                        this.tw.sep().op0("[");
                        this.commaSep(e._assignmentInfo.targets, function (p) { return _this.dispatch(p); });
                        this.tw.op0("] =").sep();
                        this.dispatch(e.args[1]);
                    }
                    else if (p == AST.api.core.AssignmentProp && e.args[0].getLiftedSetter()) {
                        this.visitCallInner(AST.mkFakeCall(AST.PropertyRef.mkProp(e.args[0].getLiftedSetter()), [e.args[0].args[0], e.args[1]]));
                    }
                    else {
                        var binopArgs = e.args;
                        if (binopArgs.length == 3)
                            binopArgs.shift();
                        doParen(binopArgs[0]);
                        var nn = p.getName();
                        if (nn == "equals")
                            nn = "==";
                        if (this.bitop(p))
                            nn = this.bitop(p).split(",")[0];
                        this.printOp(nn);
                        doParen(binopArgs[1]);
                    }
                }
                else if (prefixName) {
                    this.tw.write(prefixName);
                    params(realargs);
                }
                else if (methodName != null) {
                    this.tightExpr(realargs[0]);
                    realargs.shift();
                    if (Converter.methodRepl[pn] != "") {
                        this.tw.write("." + Converter.methodRepl[pn]);
                        params(realargs);
                    }
                }
                else if (e.referencedData()) {
                    this.tw.globalId(e.referencedData());
                }
                else if (e.referencedLibrary()) {
                    this.tw.globalId(e.referencedLibrary());
                }
                else if (e.referencedRecord()) {
                    this.tw.globalId(e.referencedRecord());
                }
                else if (e.referencedRecordField()) {
                    this.tightExpr(e.args[0]);
                    this.tw.op0(".");
                    this.simpleId(e.referencedRecordField().getName());
                }
                else if (e.calledAction() || e.calledExtensionAction()) {
                    var aa = e.calledExtensionAction() || e.calledAction();
                    var args = e.args.slice(0);
                    if (args[0].getKind() instanceof TDev.ThingSetKind) {
                        args.shift();
                    }
                    if (this.isExtension(aa) || aa.parent != this.app) {
                        this.tightExpr(args[0]);
                        args.shift();
                        this.tw.op0(".");
                    }
                    this.tw.globalId(aa);
                    params(args);
                }
                else if (pn == "App->javascript") {
                    this.dumpJs(e.args[2].getLiteral());
                }
                else if (pn == "App->javascript async") {
                    this.tw.write("new Promise(resume =>").beginBlock();
                    this.dumpJs(e.args[2].getLiteral());
                    this.tw.endBlock();
                    this.tw.op0(")");
                }
                else if (p.parentKind instanceof AST.RecordDefKind && p.getName() == "create") {
                    this.tw.write("new ");
                    this.type(e.getKind());
                    params([]);
                }
                else if (/^Invalid->/.test(pn) || (p.parentKind instanceof AST.RecordDefKind && p.getName() == "invalid")) {
                    this.tw.write("(null as ");
                    this.type(e.getKind());
                    this.tw.write(")");
                }
                else if (/^Json Builder->set (string|number|boolean|field|builder)$/.test(pn) || /->set at$/.test(pn)) {
                    this.tightExpr(e.args[0]);
                    this.tw.op0("[");
                    this.dispatch(e.args[1]);
                    this.tw.op0("] = ").sep();
                    this.dispatch(e.args[2]);
                }
                else if (/^Json (Builder|Object)->(string|number|boolean|field|remove field)$/.test(pn) || /->at$/.test(pn)) {
                    if (/remove/.test(pn))
                        this.tw.kw("delete");
                    this.tightExpr(e.args[0]);
                    this.tw.op0("[");
                    this.dispatch(e.args[1]);
                    this.tw.op0("]");
                }
                else if (pn == "String->to character code") {
                    var innerProp = e.args[0].getCalledProperty();
                    if (innerProp && innerProp.parentKind == AST.api.core.String && innerProp.getName() == "at") {
                        this.tightExpr(e.args[0].args[0]);
                        this.tw.write(".charCodeAt");
                        params([e.args[0].args[1]]);
                    }
                    else {
                        this.tightExpr(e.args[0]);
                        this.tw.write(".charCodeAt(0)");
                    }
                }
                else if (/^Web->json array$/.test(pn)) {
                    this.tw.write("[]");
                }
                else if (/^Web->json object$/.test(pn)) {
                    this.tw.write("{}");
                }
                else if (/^Json (Builder|Object)->serialize$/.test(pn)) {
                    this.tw.write("JSON.stringify");
                    params([e.args[0]]);
                }
                else if (/^Json (Builder|Object)->format$/.test(pn)) {
                    this.tw.write("JSON.stringify(");
                    this.dispatch(e.args[0]);
                    this.tw.write(", null,").sep();
                    this.dispatch(e.args[1]);
                    this.tw.write(")");
                }
                else if (/^Collection->remove at$/.test(pn)) {
                    this.tightExpr(e.args[0]);
                    this.tw.write(".splice(");
                    this.dispatch(e.args[1]);
                    this.tw.write(", 1)");
                }
                else if (/^Json (Builder|Object)->(to json|clone|to json builder)$/.test(pn)) {
                    if (/^Web->json(| array| object)$/.test(this.propName(e.args[0]))) {
                        this.dispatch(e.args[0]);
                    }
                    else {
                        this.tw.write("clone");
                        params([e.args[0]]);
                    }
                }
                else if (pn == "Web->create json builder") {
                    this.tw.op0("{}");
                }
                else if ((e.getKind().getRoot() == AST.api.core.Collection && e.args[0].getCalledProperty() && e.args[0].getCalledProperty().getName() == "Collection of") || /->create collection$/.test(pn) || /^Collections->.* collection$/.test(pn)) {
                    this.tw.op0("([] as ");
                    this.type(e.getKind());
                    this.tw.op0(")");
                }
                else if ((e.getKind().getRoot() == AST.api.core.Collection && e.args[0].getCalledProperty() && e.args[0].getCalledProperty().getName() == "map to")) {
                    this.tightExpr(e.args[0].args[0]);
                    this.tw.op0(".map<");
                    this.type(e.getKind().getParameter(0));
                    this.tw.op0(">");
                    params([e.args[1]]);
                }
                else if (/->count$/.test(pn)) {
                    this.tightExpr(e.args[0]);
                    this.tw.op0(".length");
                }
                else if (pn == "String->replace regex with converter") {
                    this.tw.write("td.replaceFn(");
                    this.dispatch(e.args[0]);
                    this.tw.op0(",").sep();
                    this.toRegex(e.args[1]);
                    this.tw.write("g,").sep();
                    this.dispatch(e.args[2]);
                    this.tw.op0(")");
                }
                else if (pn == "String->match") {
                    this.tw.op0("(");
                    this.toRegex(e.args[1]);
                    this.tw.write(".exec(");
                    this.dispatch(e.args[0]);
                    this.tw.op0(") || [])");
                }
                else if (pn == "String->is match regex") {
                    this.toRegex(e.args[1]);
                    this.tw.write(".test(");
                    this.dispatch(e.args[0]);
                    this.tw.op0(")");
                }
                else if (pn == "String->replace regex") {
                    this.tightExpr(e.args[0]);
                    this.tw.write(".replace(");
                    this.toRegex(e.args[1], "g");
                    this.tw.op0(",").sep();
                    this.dispatch(e.args[2]);
                    this.tw.op0(")");
                }
                else if (p.getName() == "\u25C8add") {
                    this.dispatch(e.args[0]);
                    this.tw.op("+=");
                    this.dispatch(e.args[1]);
                }
                else if (p.getName() == "\u25C8set") {
                    this.dispatch(e.args[0]);
                    this.tw.op("=");
                    this.dispatch(e.args[1]);
                }
                else if (p.parentKind.isAction && p.getName() == "run") {
                    this.tightExpr(e.args[0]);
                    params(e.args.slice(1));
                }
                else if (pn == "Web->json") {
                    if (e.args[1].getLiteral())
                        this.tw.op0("(").write(e.args[1].getLiteral()).op0(")");
                    else {
                        this.tw.write("JSON.parse(");
                        this.dispatch(e.args[1]);
                        this.tw.write(")");
                    }
                }
                else {
                    if (!/^App Logger->/.test(pn)) {
                        if (!this.apis.hasOwnProperty(pn))
                            this.apis[pn] = 0;
                        this.apis[pn]++;
                    }
                    this.tightExpr(e.args[0]);
                    this.tw.op0(".");
                    this.simpleId(p.getName());
                    params(e.args.slice(1));
                }
            };
            Converter.prototype.tightExpr = function (e) {
                if (e instanceof AST.ThingRef || (e instanceof AST.Call && this.infixPri(e) == 0) || e instanceof AST.Literal) {
                    this.dispatch(e);
                }
                else {
                    this.tw.op0("(");
                    this.dispatch(e);
                    this.tw.op0(")");
                }
            };
            Converter.prototype.visitExprHolder = function (eh) {
                if (eh.isPlaceholder())
                    this.tw.write("/* placeholder */");
                else
                    this.dispatch(eh.parsed);
            };
            Converter.prototype.printOp = function (s) {
                if (Converter.opmap.hasOwnProperty(s))
                    this.tw.op(Converter.opmap[s]);
                else
                    this.tw.op(s);
            };
            Converter.prototype.simpleId = function (n) {
                var x = this.localCtx.unUnicode(n);
                return this.tw.jsid(x);
            };
            Converter.prototype.visitPropertyRef = function (p) {
                this.tw.op0(".");
                this.simpleId(p.getText());
            };
            Converter.prototype.visitLiteral = function (l) {
                if (l._converterValue) {
                    this.tw.write(l._converterValue);
                    return;
                }
                if (l.data === undefined)
                    return;
                if (typeof l.data == "number")
                    this.tw.write(l.stringForm || l.data.toString());
                else if (typeof l.data == "string")
                    this.tw.write(stringLit(l.data));
                else if (typeof l.data == "boolean")
                    this.tw.kw(l.data ? "true" : "false");
                else
                    l.writeTo(this.tw);
            };
            Converter.prototype.inlineAction = function (a) {
                var _this = this;
                if (useAsync && !a.name.getKind().isAtomic())
                    this.tw.kw("async").space();
                this.pcommaSep(a.inParameters, function (p) { return _this.localDef(p); });
                this.tw.op("=>").beginBlock();
                a.outParameters.forEach(function (p) {
                    _this.tw.kw("let");
                    _this.localDef(p);
                    _this.tw.semiNL();
                });
                this.codeBlockInner(a.body.stmts);
                if (a.outParameters.length >= 1) {
                    this.tw.kw("return");
                    this.localName(a.outParameters[0]).semiNL();
                }
                this.tw.endBlock();
            };
            Converter.prototype.visitThingRef = function (t) {
                var _this = this;
                var d = t.def;
                if (d instanceof AST.LocalDef) {
                    var a = d._converterAction;
                    if (a) {
                        this.inlineAction(a);
                    }
                    else {
                        if (d.getKind() == AST.api.core.Unknown)
                            this.simpleId(d.getName());
                        else
                            this.localName(d);
                    }
                }
                else if (d instanceof AST.SingletonDef) {
                    this.simpleId(d.getName());
                }
                else if (t.isEscapeDef()) {
                    var e = d.escapeDef;
                    if (e.isEmpty) {
                        this.tw.op0("{}");
                        return;
                    }
                    this.tw.beginBlock();
                    var vals = e.optionalConstructor.optionalParameters();
                    vals.forEach(function (p, i) {
                        _this.simpleId(p.recordField.getName()).op0(":").sep();
                        if (p instanceof AST.OptionalParameter)
                            _this.dispatch(p.expr);
                        else
                            _this.inlineAction(p);
                        if (i < vals.length - 1)
                            _this.tw.op0(",");
                        _this.tw.nl();
                    });
                    this.tw.endBlock();
                }
                else
                    this.simpleId(d.getName());
            };
            Converter.prototype.visitAnyIf = function (i) {
                var _this = this;
                var tw = this.tw;
                if (false && i.isTopCommentedOut()) {
                    tw.op0("/*").nl();
                    this.codeBlockInner(i.rawThenBody.stmts);
                    tw.op0("*/").nl();
                    return;
                }
                if (!i.branches)
                    return;
                i.branches.forEach(function (b, k) {
                    if (!b.condition) {
                        if (!b.body.isBlockPlaceholder()) {
                            tw.keyword("else");
                            _this.dispatch(b.body);
                        }
                    }
                    else {
                        if (k > 0)
                            tw.keyword("else");
                        tw.keyword("if").sep().op0("(");
                        _this.dispatch(b.condition);
                        tw.op0(")");
                        _this.dispatch(b.body);
                    }
                    _this.isReachable = true;
                });
            };
            Converter.prototype.visitFor = function (f) {
                this.tw.kw("for (let").sep();
                this.localName(f.boundLocal).write(" = 0;").sep();
                this.localName(f.boundLocal).op("<");
                this.dispatch(f.upperBound);
                this.tw.op0(";").sep();
                this.localName(f.boundLocal).op0("++)");
                this.dispatch(f.body);
            };
            Converter.prototype.visitForeach = function (f) {
                this.tw.kw("for (let").sep();
                this.localName(f.boundLocal).write(" of").sep();
                this.dispatch(f.collection);
                this.tw.op0(")");
                TDev.Util.assert(f.conditions.stmts.length == 0);
                this.dispatch(f.body);
            };
            Converter.prototype.visitWhile = function (n) {
                var tw = this.tw;
                tw.keyword("while").sep().op0("(");
                this.dispatch(n.condition);
                tw.op0(")");
                this.dispatch(n.body);
            };
            Converter.prototype.visitInlineActions = function (i) {
                this.visitExprStmt(i);
            };
            Converter.prototype.visitExprStmt = function (es) {
                if (es.isVarDef())
                    this.tw.kw("let");
                this.dispatch(es.expr);
                this.tw.semiNL();
            };
            Converter.prototype.codeBlockInner = function (stmts) {
                var _this = this;
                stmts.forEach(function (s, i) {
                    if (s.isPlaceholder()) {
                        if (i > 0)
                            _this.tw.nl();
                    }
                    else {
                        _this.dispatch(s);
                    }
                });
            };
            Converter.prototype.visitCodeBlock = function (b) {
                this.tw.beginBlock();
                this.codeBlockInner(b.stmts);
                this.tw.endBlock();
                this.isReachable = true;
            };
            Converter.prototype.pcommaSep = function (l, f) {
                this.tw.op0("(");
                this.commaSep(l, f);
                this.tw.op0(")");
            };
            Converter.prototype.commaSep = function (l, f) {
                var _this = this;
                l.forEach(function (p, i) {
                    if (i > 0)
                        _this.tw.op0(",").sep();
                    f(p);
                });
            };
            Converter.prototype.isOwnExtension = function (a) {
                if (!this.options.useExtensions || !this.isExtension(a))
                    return false;
                var r = this.getFirstRecord(a);
                return (r && r.parent == this.app);
            };
            Converter.prototype.isExtension = function (a) {
                if (!this.options.useExtensions && a.parent == this.app)
                    return false;
                if (a.isActionTypeDef())
                    return false;
                var p0 = a.getInParameters()[0];
                if (p0 && /\?$/.test(p0.getName()))
                    return false;
                var r = this.getFirstRecord(a);
                if (!r) {
                    if (p0 && p0.local.getKind().parentLibrary() == a.parentLibrary())
                        return true;
                    return false;
                }
                if (r.parent != a.parent)
                    return false;
                return true;
            };
            Converter.prototype.getFirstRecord = function (a) {
                var p0 = a.getInParameters()[0];
                if (!p0)
                    return null;
                return p0.local.getKind().getRecord();
            };
            Converter.prototype.actionReturn = function (a) {
                var _this = this;
                if (useAsync && !a.isAtomic)
                    this.tw.kw("Promise<");
                var outp = a.getOutParameters();
                if (outp.length == 0)
                    this.tw.kw("void");
                else if (outp.length == 1)
                    this.type(outp[0].getKind());
                else {
                    this.tw.op0("[");
                    this.commaSep(outp, function (p) { return _this.type(p.local.getKind()); });
                    this.tw.op0("]");
                }
                if (useAsync && !a.isAtomic)
                    this.tw.op0(">");
            };
            Converter.prototype.printActionTypeDef = function (a) {
                var _this = this;
                this.tw.kw("export type");
                this.tw.globalId(a).op("=");
                this.pcommaSep(a.getInParameters(), function (p) { return _this.localDef(p.local); });
                this.tw.op("=>");
                this.actionReturn(a);
                this.tw.semiNL();
            };
            Converter.prototype.setupQuoting = function () {
                this.localCtx = new TsQuotingCtx();
                this.localCtx.reservedNames = this.tw.globalCtx.snapshotUsed();
                this.thisLocal = null;
            };
            Converter.prototype.printActionHeader = function (a) {
                var _this = this;
                if (a.isActionTypeDef()) {
                    this.printActionTypeDef(a);
                    return;
                }
                var isExtension = this.isOwnExtension(a);
                this.setupQuoting();
                var optsName = "";
                var optsLocal = null;
                var printP = function (p) {
                    if (/\?$/.test(p.getName())) {
                        optsLocal = p.local;
                        optsName = _this.localCtx.unUnicode(p.getName() + "0");
                        _this.tw.jsid(optsName).write(": ");
                        _this.tw.globalId(p.local.getKind().getRecord(), "I");
                        _this.tw.write(" = {}");
                    }
                    else
                        _this.localDef(p.local);
                };
                var stmts = a.body.stmts.slice(0);
                var annot = [];
                if (!/^example/.test(a.getName()) && stmts[0] instanceof AST.Comment) {
                    var paramHelp = {};
                    var helpLines = 0;
                    while (stmts[0] instanceof AST.Comment) {
                        var txt = stmts[0].text;
                        txt = txt.replace(/\{(\w+)(:[^{}]*)?\}/g, function (full, n, arg) {
                            if (!arg)
                                arg = ":";
                            arg = arg.slice(1);
                            var arg0 = arg.replace(/:.*/);
                            var argRest = arg.slice(arg0.length + 1);
                            switch (n) {
                                case "shim":
                                case "help":
                                case "weight":
                                    if (/\s/.test(arg))
                                        if (/"/.test(arg))
                                            arg = "'" + arg + "'";
                                        else
                                            arg = "\"" + arg + "\"";
                                    else
                                        arg = arg;
                                    annot.push(n + "=" + arg);
                                    break;
                                case "enum":
                                case "namespace":
                                case "action":
                                    break;
                                case "hints":
                                    paramHelp[arg0] = ", eg: " + argRest.replace(/,/g, ", ");
                                    break;
                                default:
                                    return full;
                            }
                            if (n == "shim" && !a.isAtomic)
                                annot.push("async");
                            return "";
                        });
                        txt = txt.trim();
                        if (txt) {
                            if (helpLines == 0)
                                this.tw.write("/**").nl();
                            this.tw.write(" * " + txt).nl();
                            helpLines++;
                        }
                        stmts.shift();
                    }
                    if (helpLines) {
                        a.getInParameters().forEach(function (p) {
                            _this.tw.write(" * @param ");
                            _this.localName(p.local);
                            _this.tw.write(" TODO" + (paramHelp[p.getName()] || "")).nl();
                        });
                        this.tw.write(" */").nl();
                    }
                    if (annot.length)
                        this.tw.write("//% " + annot.join(" ")).nl();
                    a.getParameters().forEach(function (p) {
                        if (p.enumMap) {
                            var thisEnum = "enum TODO {\n" + Object.keys(p.enumMap).map(function (k) { return "    //% enumval=" + p.enumMap[k] + "\n    " + _this.builtinName(k) + ",\n"; }).join("") + "}\n";
                            _this.allEnums[thisEnum] = 1;
                        }
                    });
                }
                if (isExtension) {
                    if (a.isPrivate)
                        this.tw.kw("private");
                    else
                        this.tw.kw("public");
                    if (useAsync && !a.isAtomic)
                        this.tw.kw("async");
                    this.tw.globalId(a);
                    this.pcommaSep(a.getInParameters().slice(1), printP);
                }
                else {
                    if (useAsync && !a.isAtomic)
                        this.tw.kw("async");
                    this.tw.kw("function");
                    this.tw.globalId(a);
                    this.pcommaSep(a.getInParameters(), printP);
                }
                if (a.getOutParameters().length > 0) {
                    this.tw.op(":");
                    this.actionReturn(a);
                }
                return { isExtension: isExtension, stmts: stmts, optsLocal: optsLocal, optsName: optsName };
            };
            Converter.prototype.visitAction = function (a) {
                var _this = this;
                var isMain = a.getInParameters().length == 0 && /^main/.test(a.getName());
                if (isMain) {
                    this.setupQuoting();
                    this.codeBlockInner(a.body.stmts);
                    this.tw.nl();
                    return;
                }
                var info = this.printActionHeader(a);
                var optsLocal = info.optsLocal;
                this.tw.beginBlock();
                if (info.isExtension) {
                    this.thisLocal = a.getInParameters()[0].local;
                }
                if (optsLocal) {
                    this.tw.kw("let").sep();
                    this.localName(optsLocal);
                    this.tw.write(" = new").sep();
                    this.type(optsLocal.getKind());
                    this.tw.write("(); ");
                    this.localName(optsLocal).write(".load(");
                    this.tw.jsid(info.optsName).op0(");").nl();
                }
                var hasOutP = !!a.getOutParameters().filter(function (p) { return p.local._converterUses > 0; })[0];
                if (hasOutP)
                    a.getOutParameters().forEach(function (p) {
                        _this.tw.kw("let");
                        _this.localDef(p.local);
                        _this.tw.semiNL();
                    });
                this.isReachable = true;
                this.codeBlockInner(info.stmts);
                if (!hasOutP || !this.isReachable) {
                }
                else if (a.getOutParameters().length == 1) {
                    this.tw.kw("return");
                    this.localName(a.getOutParameters()[0].local).semiNL();
                }
                else if (a.getOutParameters().length > 1) {
                    this.tw.kw("return ");
                    if (!a.isAtomic) {
                        this.tw.op0("<[");
                        this.commaSep(a.getOutParameters(), function (p) { return _this.type(p.local.getKind()); });
                        this.tw.op0("]>");
                    }
                    this.tw.op0("[");
                    this.commaSep(a.getOutParameters(), function (p) { return _this.localName(p.local); });
                    this.tw.op0("]").nl();
                }
                this.tw.endBlock();
                this.tw.nl();
            };
            Converter.prototype.defaultValue = function (k) {
                if (k == AST.api.core.String)
                    return '""';
                else if (k == AST.api.core.Number)
                    return '0';
                else if (k == AST.api.core.Boolean)
                    return 'false';
                else
                    return null;
            };
            Converter.prototype.visitGlobalDef = function (g) {
                if (g.getKind() == AST.api.core.Picture)
                    return;
                this.tw.kw("let");
                this.tw.globalId(g).op0(": ");
                this.type(g.getKind());
                this.tw.semiNL();
            };
            Converter.prototype.visitLibraryRef = function (l) {
            };
            Converter.prototype.visitRecordDef = function (r) {
                var _this = this;
                this.tw.kw("class").sep();
                this.tw.globalId(r).beginBlock();
                r.getFields().forEach(function (f) {
                    _this.tw.kw("public").sep();
                    _this.simpleId(f.getName());
                    _this.tw.op0(":").sep();
                    _this.type(f.dataKind);
                    _this.tw.semiNL();
                });
                var exts = this.app.actions().filter(function (a) { return _this.isOwnExtension(a) && _this.getFirstRecord(a) == r; });
                exts.forEach(function (e) { return _this.visitAction(e); });
                this.tw.endBlock();
                this.tw.nl();
            };
            Converter.prototype.visitApp = function (a) {
                var _this = this;
                var dump = function (lst) { return lst.forEach(function (t) { return _this.dispatch(t); }); };
                dump(a.libraries());
                this.tw.nl();
                dump(a.allActions().filter(function (a) { return a.isActionTypeDef(); }));
                this.tw.nl();
                dump(a.variables());
                this.tw.nl();
                dump(a.resources());
                this.tw.nl();
                dump(a.records());
                this.tw.nl();
                var normalActions = a.allActions().filter(function (a) { return !_this.isOwnExtension(a) && !a.isActionTypeDef(); });
                var byNs = TDev.Util.groupBy(normalActions, function (a) { return a.getNamespaces()[0] || ""; });
                Object.keys(byNs).forEach(function (ns) {
                    if (ns)
                        _this.tw.kw("namespace " + ns).beginBlock();
                    dump(byNs[ns]);
                    if (ns)
                        _this.tw.endBlock();
                });
                this.tw.write(Object.keys(this.allEnums).join("\n"));
            };
            Converter.prototype.visitComment = function (c) {
                var tt = c.text.trim();
                if (tt == "{highlight}")
                    this.tw.highlight++;
                else if (tt == "{/highlight}")
                    this.tw.highlight--;
                else
                    this.tw.comment(c.text);
            };
            Converter.prototype.visitStmt = function (s) {
                console.log("unhandled stmt: " + s.nodeType());
                _super.prototype.visitStmt.call(this, s);
            };
            Converter.kindMap = {
                "String": "string",
                "Number": "number",
                "Boolean": "boolean",
                "Nothing": "void",
                "DateTime": "Date",
                "Json Object": "{}",
                "Json Builder": "{}",
                "Buffer": "Buffer",
            };
            Converter.prefixGlue = {
                "App->log": "console.log",
                "Time->now": "new Date",
                "Json Builder->keys": "Object.keys",
                "Json Object->keys": "Object.keys",
                "String Map->keys": "Object.keys",
                "Contract->assert": "control.assert",
                "Bits->string to buffer": "new Buffer",
                "Bits->create buffer": "pins.createBuffer",
                "Time->sleep": "basic.sleep",
                "String->to number": "parseInt",
                "Web->decode url": "decodeURIComponent",
                "Web->decode uri component": "decodeURIComponent",
                "Web->encode uri component": "encodeURIComponent",
                "Web->encode url": "encodeURIComponent",
                "Math->clamp": "Math.clamp",
                "Math->abs": "Math.abs",
                "Math->sign": "Math.sign",
                "Math->pow": "Math.pow",
                "Math->sqrt": "Math.sqrt",
                "Math->min": "Math.min",
                "Math->max": "Math.max",
                "Math->round": "Math.round",
                "Math->floor": "Math.floor",
                "Math->random": "Math.random",
                "Math->random range": "Math.randomRange",
                "Math->random normalized": "Math.randomNormalized",
                "Json Builder->to string": "td.toString",
                "Json Object->to string": "td.toString",
                "Json Builder->to number": "td.toNumber",
                "Json Object->to number": "td.toNumber",
                "♻ micro:bit->plot image": "basic.showLeds",
                "♻ micro:bit->note": "music.noteFrequency",
                "♻ micro:bit music->note": "music.noteFrequency",
                "♻ micro:bit->ring": "music.ringTone",
                "♻ micro:bit->play note": "music.playTone",
                "♻ micro:bit music->play note": "music.playTone",
            };
            Converter.methodRepl = {
                "Buffer->concat": "concat",
                "Buffer->to string": "toString",
                "Number->to string": "toString",
                "String->replace": "replaceAll",
                "String->split": "split",
                "String->substring": "substr",
                "String->to upper case": "toUpperCase",
                "String->to lower case": "toLowerCase",
                "String->code at": "charCodeAt",
                "Json Builder->add": "push",
                "Json Builder->contains key": "hasOwnProperty",
                "Json Object->contains key": "hasOwnProperty",
                "Collection->add": "push",
                "Collection->where": "filter",
                "DateTime->milliseconds since epoch": "getTime",
                "Web Request->send": "sendAsync",
                "♻ micro:bit->show image": "showImage",
                "String->to json": "",
                "Number->to json": "",
                "Task->await": "",
            };
            Converter.opmap = {
                "not": "!",
                "and": "&&",
                "or": "||",
                "\u2225": "+",
                "=": "==",
                ":=": "=",
                "\u2260": "!=",
                "\u2264": "<=",
                "\u2265": ">=",
                "mod": "%",
            };
            return Converter;
        })(AST.NodeVisitor);
        AST.Converter = Converter;
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var MdDocs;
        (function (MdDocs) {
            var topicCore;
            var topicName;
            MdDocs.preexistingArtIds = {};
            var lastTopic;
            var currBox;
            function info() {
                return JSON.stringify({}, null, 1);
            }
            MdDocs.info = info;
            var macroMap = {
                "videoptr": "video",
                "section": "section",
                "breadcrumbtitle": "short",
                "parenttopic": "parent",
            };
            function formatText(s) {
                var warnS = "";
                function warn(m) {
                    if (topicName != lastTopic) {
                        console.log("*** " + topicName);
                        lastTopic = topicName;
                    }
                    warnS += "WARN: " + m + "\n";
                    console.log("WARN: " + m);
                }
                s = s.replace(/\t/g, " ");
                s = s.replace(/\[([^\n\[\]]*)\]\s*\(([\w\/\-]+)\)/g, function (f, name, lnk) {
                    if (!name)
                        name = lnk.replace(/.*\//, "");
                    lnk = lnk.replace(/^\/td/, "/js");
                    lnk = "/microbit" + lnk;
                    return "[" + name + "](" + lnk + ")";
                });
                s = s.replace(/\{([\/\w\*]+)(:([^{}]*))?\}/g, function (full, macro, dummy, arg) {
                    macro = macro.toLowerCase();
                    if (macro == "vimeo") {
                        macro = "videoptr";
                        arg = "vimeo/" + arg;
                    }
                    if (macro == "sig") {
                        var m = arg.split(/->/);
                        var act = null;
                        TDev.Script.librariesAndThis().forEach(function (l) {
                            if (l.getName() == m[0])
                                act = act || l.getPublicActions().filter(function (a) { return a.getName() == m[1]; })[0];
                        });
                        if (act && converter) {
                            return quoteCode(converter.renderSig(act));
                        }
                        else {
                            warn("cannot find lib action: " + arg);
                            return full;
                        }
                    }
                    else if (macro == "decl") {
                        var d = TDev.Script.things.filter(function (t) { return t.getName() == arg; })[0];
                        if (!d) {
                            warn("no such decl: " + arg);
                            return full;
                        }
                        else
                            return mkSnippet([d]);
                    }
                    else if (macro == "fullsig") {
                        warn("unsupported macro: " + macro);
                        return full;
                    }
                    else if (macro == "topic") {
                        topicName = arg;
                        topicCore = ("/" + arg).replace(/(\/(td|functions))+\//g, "/").replace(/\/(activity|quiz|quiz.answer(s|)|challenges|tutorial)$/, "");
                        if (!topicCore)
                            topicCore = topicName;
                        topicCore = topicCore.replace(/^\//, "").toLowerCase();
                        return "";
                    }
                    else if (macro == "box") {
                        if (!arg)
                            arg = "box";
                        var mm = /([^:]+):(.*)/.exec(arg);
                        var tp = mm ? mm[1] : arg;
                        var title = mm ? mm[2] : "";
                        currBox = null;
                        if (tp == "card")
                            return "## " + title;
                        else if (tp == "screen")
                            return "";
                        currBox = tp;
                        return "### ~" + tp + " " + title;
                    }
                    else if (macro == "hide") {
                        currBox = "hide";
                        return "### ~hide";
                    }
                    else if (macro == "/box" || macro == "/hide") {
                        if (currBox) {
                            currBox = null;
                            return "### ~";
                        }
                        return "";
                    }
                    else if (macroMap.hasOwnProperty(macro)) {
                        return "### @" + macroMap[macro] + " " + (arg || "") + "\n";
                    }
                    else if (macro == "pic" || macro == "pici") {
                        var args = arg.split(/:/);
                        var r0 = TDev.Script.resources().filter(function (r) { return TDev.MdComments.shrink(r.getName()) == TDev.MdComments.shrink(args[0]); })[0];
                        var artId = "";
                        if (r0) {
                            var mm = /([a-z]+)$/.exec(r0.url);
                            if (mm)
                                artId = mm[1];
                        }
                        if (!artId && /^[a-z]+$/.test(args[0])) {
                            artId = args[0];
                        }
                        if (!artId)
                            warn("missing picture: " + arg);
                        var preName = MdDocs.preexistingArtIds[artId];
                        if (!preName) {
                            warn("unknown picture: " + arg);
                            return "(picture " + args[0] + ")";
                        }
                        return "![](/static/mb/" + preName + ")";
                    }
                    else {
                        warnS += "MACRO: " + macro;
                        return full;
                    }
                });
                if (/^\* /.test(s))
                    return s + "\n" + warnS;
                return "\n" + s + "\n" + warnS + "\n";
            }
            MdDocs.formatText = formatText;
            function quoteCode(s) {
                return "\n```\n" + s.trim() + "\n```\n\n";
            }
            function mkSnippet(stmts) {
                if (!converter)
                    return "[" + stmts.length + " stmts]";
                return quoteCode(converter.renderSnippet(stmts));
            }
            function extractStmts(stmts) {
                var output = "";
                for (var i = 0; i < stmts.length;) {
                    var cmt = stmts[i].docText();
                    if (cmt != null) {
                        var m;
                        if ((m = /^\s*(\{code\}|````)\s*$/.exec(cmt)) != null) {
                            var j = i + 1;
                            var seenStmt = false;
                            while (j < stmts.length) {
                                if (/^\s*(\{\/code\}|````)\s*$/.test(stmts[j].docText()))
                                    break;
                                j++;
                            }
                            output += mkSnippet(stmts.slice(i + 1, j));
                            i = j + 1;
                        }
                        else {
                            output += formatText(cmt);
                            i++;
                        }
                    }
                    else {
                        var j = i;
                        while (j < stmts.length) {
                            if (stmts[j].docText() != null)
                                break;
                            j++;
                        }
                        output += mkSnippet(stmts.slice(i, j));
                        i = j;
                    }
                }
                return output;
            }
            var converter;
            function toMD(app) {
                converter = new AST.Converter(app);
                converter.run();
                var header = "# " + app.getName() + "\n\n" + app.getDescription() + "\n\n";
                var body = extractStmts(app.mainAction().body.stmts);
                return (header + body).replace(/\n\n+/g, "\n\n");
            }
            MdDocs.toMD = toMD;
        })(MdDocs = AST.MdDocs || (AST.MdDocs = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var ScriptCache;
    (function (ScriptCache) {
        function log(s) {
            TDev.Util.log("ScriptCache: " + s);
        }
        var getScriptCacheTableAsync = function () { return TDev.Storage.getTableAsync("ScriptCache"); };
        function scriptSource(text) {
            return function (id) {
                if (!id)
                    return TDev.Promise.as(text);
                else
                    return getScriptAsync(id);
            };
        }
        ScriptCache.scriptSource = scriptSource;
        function snapshotCacheAsync(storage) {
            return getScriptCacheTableAsync().then(function (table) { return table.getKeysAsync().then(function (keys) {
                keys = keys.filter(function (s) { return /^id-/.test(s); });
                return table.getItemsAsync(keys).then(function (v) {
                    storage.scriptCache = v;
                });
            }); });
        }
        ScriptCache.snapshotCacheAsync = snapshotCacheAsync;
        function restoreCacheAsync(storage) {
            if (!storage.scriptCache)
                return TDev.Promise.as();
            return getScriptCacheTableAsync().then(function (table) { return table.setItemsAsync(storage.scriptCache); });
        }
        ScriptCache.restoreCacheAsync = restoreCacheAsync;
        function forceUpdateId(id) {
            var libCache = TDev.shippedLibraryCache;
            return !libCache ? id : libCache.updates[id] || id;
        }
        ScriptCache.forceUpdateId = forceUpdateId;
        function forcedUpdate(id) {
            var libCache = TDev.shippedLibraryCache;
            if (!libCache)
                return null;
            if (libCache && libCache.updates.hasOwnProperty(id)) {
                id = libCache.updates[id];
                return { json: libCache.json[id], text: libCache.text[id] };
            }
            return null;
        }
        ScriptCache.forcedUpdate = forcedUpdate;
        function shippedLibrariesJson() {
            var libCache = TDev.shippedLibraryCache;
            return libCache ? libCache.json : undefined;
        }
        ScriptCache.shippedLibrariesJson = shippedLibrariesJson;
        function getScriptAsync(id) {
            if (!TDev.Util.check(!!id))
                return TDev.Promise.as("");
            var libCache = TDev.shippedLibraryCache;
            if (libCache && libCache.text.hasOwnProperty(id))
                return TDev.Promise.as(libCache.text[id]);
            return getScriptCacheTableAsync().then(function (table) { return table.getValueAsync("id-" + id); }).then(function (value) {
                if (typeof value === "string") {
                    log("cache hit: " + id);
                    return value;
                }
                log("cache miss: " + id);
                return TDev.Cloud.getScriptTextAsync(id).then(function (value) { return getScriptCacheTableAsync().then(function (table) {
                    if (!value)
                        return value;
                    var items = {};
                    items["id-" + id] = value;
                    return table.setItemsAsync(items).then(function () { return value; });
                }); }, function (err) {
                    if (err.status != 404) {
                        TDev.Util.reportError("getScriptAsync", err, false);
                        return null;
                    }
                    return "";
                });
            });
        }
        ScriptCache.getScriptAsync = getScriptAsync;
    })(ScriptCache = TDev.ScriptCache || (TDev.ScriptCache = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var World;
    (function (World) {
        function log(s) {
            TDev.Util.log("World: " + s);
        }
        World.log = log;
        World.getScriptMeta;
        World.sanitizeScriptTextForCloud;
        World.waitForUpdate = function (id) { return false; };
        World.disableMerge = true;
        World.newHeaderCallbackAsync = function (h, state) { return TDev.Promise.as(); };
        World.incomingHeaderAsync = function (guid) { return TDev.Promise.as(); };
        var currentUserInfo = null;
        var currentUserPromise = new TDev.PromiseInv();
        var localStorage = window.localStorage;
        var getIndexTablePromise = function () { return TDev.Storage.getTableAsync("Index"); };
        var getScriptsTablePromise = function () { return TDev.Storage.getTableAsync("Scripts"); };
        var getTracesTablePromise = function () { return TDev.Storage.getTableAsync("Traces"); };
        function getHeader(body) {
            var x = JSON.parse(JSON.stringify(body));
            delete x.script;
            return x;
        }
        function removeInstalledAsync(indexTable, scriptsTable, guid) {
            var headerItem = {};
            headerItem[guid] = undefined;
            var bodyItem = {};
            bodyItem[guid + "-script"] = undefined;
            bodyItem[guid + "-scriptState"] = undefined;
            bodyItem[guid + "-scriptVersionInCloud"] = undefined;
            return TDev.Promise.join([indexTable.setItemsAsync(headerItem), scriptsTable.setItemsAsync(bodyItem)]);
        }
        var pendingMetaItems = [];
        function setUnInstalledAsync(indexTable, scriptsTable, header) {
            return setInstalledAsync(indexTable, scriptsTable, uninstall(header), 0, 0, 0, 0);
        }
        function setInstalledAsync(indexTable, scriptsTable, header, script, editorState, scriptState, cloudScriptVersion) {
            var headerItem = {};
            if (script && !header.editor && (!header.meta || header.meta.comment === undefined)) {
                header.meta = World.getScriptMeta(script);
                if (TDev.Cloud.lite) {
                    pendingMetaItems.push({
                        guid: header.guid,
                        meta: header.meta
                    });
                }
            }
            if (header.editor && (!header.meta || !header.meta.name)) {
                TDev.Util.log("ERROR pre-condition not met for [setInstalledAsync]; bailing");
                return TDev.Promise.as();
            }
            if (header.meta)
                header.name = header.meta.name;
            headerItem[header.guid] = JSON.stringify(header);
            var bodyItem = {};
            if (script != null)
                bodyItem[header.guid + "-script"] = typeof script === "string" ? script : undefined;
            if (editorState != null)
                bodyItem[header.guid + "-editorState"] = typeof editorState === "string" ? editorState : undefined;
            if (scriptState !== null)
                bodyItem[header.guid + "-scriptState"] = typeof scriptState === "string" ? scriptState : undefined;
            if (cloudScriptVersion != null)
                bodyItem[header.guid + "-scriptVersionInCloud"] = typeof cloudScriptVersion === "string" ? cloudScriptVersion : undefined;
            log(header.guid + "/" + header.scriptId + ": " + header.name + " save with base " + header.scriptVersion.baseSnapshot);
            return TDev.Promise.join([indexTable.setItemsAsync(headerItem), scriptsTable.setItemsAsync(bodyItem)]);
        }
        function setCloudScriptVersionAsync(scriptsTable, guid, cloudScriptVersion) {
            var bodyItem = {};
            bodyItem[guid + "-scriptVersionInCloud"] = typeof cloudScriptVersion === "string" ? cloudScriptVersion : undefined;
            return scriptsTable.setItemsAsync(bodyItem);
        }
        function mergeJSON(base, local, server) {
            Object.keys(server).forEach(function (k) {
                if (server[k] && typeof server[k] === "object" && local[k] && typeof local[k] == "object")
                    local[k] = mergeJSON(base[k] || {}, local[k], server[k]);
                else if (!local.hasOwnProperty(k) || base[k] === local[k])
                    local[k] = server[k];
            });
            return local;
        }
        World.mergeJSON = mergeJSON;
        function mergeEditorStates(base, local, server) {
            return JSON.stringify(mergeJSON(JSON.parse(base || "{}"), JSON.parse(local || "{}"), JSON.parse(server || "{}")));
        }
        World.mergeScripts = function (base, local, server) { return local; };
        function getScriptBlobAsync(snapshotId) {
            return TDev.Util.httpGetJsonAsync(TDev.Cloud.config.workspaceUrl + snapshotId);
        }
        World.getScriptBlobAsync = getScriptBlobAsync;
        function downloadInstalledAsync(indexTable, scriptsTable, header) {
            log(header.guid + "/" + header.scriptId + ": " + header.name + " is newer");
            if (TDev.Cloud.lite) {
                var theirs;
                var baseVer;
                var currVer;
                var hd;
                var skipMsg = false;
                return getScriptBlobAsync(header.scriptVersion.baseSnapshot).then(function (v) { return theirs = v; }).then(function () { return World.incomingHeaderAsync(header.guid); }).then(function () { return indexTable.getValueAsync(header.guid); }).then(function (str) { return hd = str ? JSON.parse(str) : null; }).then(function () {
                    var touch = function () {
                        header.scriptVersion.instanceId = TDev.Cloud.getWorldId();
                        header.scriptVersion.time = getCurrentTime();
                        header.scriptVersion.version++;
                        header.status = "unpublished";
                    };
                    if (hd && hd.scriptVersion.instanceId != "cloud" && hd.scriptVersion.baseSnapshot && hd.scriptVersion.baseSnapshot != header.scriptVersion.baseSnapshot) {
                        if (World.disableMerge) {
                            touch();
                            skipMsg = true;
                            return { script: null, editorState: null };
                        }
                        log(header.guid + "/" + header.scriptId + ": " + header.name + " merging based on " + hd.scriptVersion.baseSnapshot);
                        return getScriptBlobAsync(hd.scriptVersion.baseSnapshot).then(function (r) {
                            baseVer = r;
                        }).then(function () { return World.incomingHeaderAsync(header.guid); }).then(function () { return scriptsTable.getItemsAsync([header.guid + "-script", header.guid + "-editorState"]); }).then(function (r) {
                            currVer = { script: r[header.guid + "-script"], editorState: r[header.guid + "-editorState"] };
                        }).then(function () {
                            if (header.editor) {
                                var ret = {
                                    script: currVer.script,
                                    editorState: currVer.editorState,
                                    extra: {
                                        theirs: {
                                            scriptText: theirs.script,
                                            editorState: theirs.editorState,
                                            baseSnapshot: header.scriptVersion.baseSnapshot,
                                            metadata: header.meta,
                                        },
                                        base: {
                                            scriptText: baseVer.script,
                                            editorState: baseVer.editorState,
                                            baseSnapshot: hd.scriptVersion.baseSnapshot,
                                            metadata: hd.meta,
                                        },
                                    }
                                };
                                var newVersion = header.scriptVersion.baseSnapshot;
                                header = hd;
                                header.pendingMerge = newVersion;
                                return ret;
                            }
                            else {
                                touch();
                                return {
                                    script: World.mergeScripts(baseVer.script, currVer.script, theirs.script),
                                    editorState: mergeEditorStates(baseVer.editorState, currVer.editorState, theirs.editorState),
                                };
                            }
                        });
                    }
                    else {
                        return theirs;
                    }
                }).then(function (resp) { return setInstalledAsync(indexTable, scriptsTable, header, resp.script, resp.editorState, null, JSON.stringify(resp.extra || {})); }).then(function () { return World.newHeaderCallbackAsync(header, skipMsg ? "skippedMerge" : "downloaded"); }).then(function () { return header.scriptVersion.instanceId == "cloud" ? TDev.Promise.as() : uploadInstalledAsync(indexTable, scriptsTable, header); });
            }
            return TDev.Cloud.getUserInstalledBodyAsync(header.guid).then(function (installedBodies) {
                var body = undefined;
                installedBodies.bodies.forEach(function (b) {
                    if (b.guid == header.guid)
                        body = b;
                });
                if (body) {
                    var cloudScriptVersion = JSON.stringify(header.scriptVersion);
                    if (body.status == "published")
                        return TDev.ScriptCache.getScriptAsync(body.scriptId).then(function (script) { return script == null ? TDev.Promise.as() : script == "" ? setUnInstalledAsync(indexTable, scriptsTable, getHeader(body)) : setInstalledAsync(indexTable, scriptsTable, getHeader(body), script, body.editorState, null, cloudScriptVersion); });
                    else if (body.script == "")
                        return setUnInstalledAsync(indexTable, scriptsTable, getHeader(body));
                    else
                        return setInstalledAsync(indexTable, scriptsTable, getHeader(body), body.script, body.editorState, null, cloudScriptVersion);
                }
                else
                    return removeInstalledAsync(indexTable, scriptsTable, header.guid);
            });
        }
        function publishInstalledAsync(indexTable, scriptsTable, header) {
            log(header.guid + "/" + header.scriptId + ": " + header.name + " is to be published");
            var hidden = header.publishAsHidden;
            return indexTable.getValueAsync(header.guid).then(function (resp) {
                header = JSON.parse(resp);
            }).then(function () { return TDev.Cloud.postUserInstalledPublishAsync(header.guid, hidden, JSON.stringify(header.scriptVersion), header.meta); }).then(function (installedBodies) {
                var body = undefined;
                installedBodies.bodies.forEach(function (b) {
                    if (b.guid == header.guid)
                        body = b;
                });
                if (!body)
                    return undefined;
                var cloudScriptVersion = JSON.stringify(header.scriptVersion);
                var hd = getHeader(body);
                return setInstalledAsync(indexTable, scriptsTable, hd, body.script || null, body.editorState || null, null, cloudScriptVersion).then(function () { return World.newHeaderCallbackAsync(hd, "published"); }).then(function () { return []; });
            }).then(function (r) { return r; }, function (e) {
                if (e.status == 400) {
                    TDev.ModalDialog.info("cannot publish", TDev.lf("Your script '{0}' cannot be published. Error message: {1:not available}", header.name, e.errorMessage));
                    getInstalledHeaderAsync(header.guid).then(function (header) {
                        if (header.status == "tobepublished") {
                            header.status = "unpublished";
                            return setInstalledAsync(indexTable, scriptsTable, header, null, null, null, null);
                        }
                        else
                            return TDev.Promise.as();
                    }).done();
                }
                throw e;
            });
        }
        function uploadInstalledAsync(indexTable, scriptsTable, header) {
            var conservativeVersion = JSON.stringify(header.scriptVersion);
            log(header.guid + "/" + header.scriptId + ": " + header.name + " is dirty, attempting to save version " + conservativeVersion);
            if (header.pendingMerge) {
                log(header.guid + "/" + header.scriptId + ": " + header.name + " is pending merge resolution, skipping");
                return TDev.Promise.as();
            }
            return TDev.Promise.join({
                script: scriptsTable.getValueAsync(header.guid + "-script"),
                editorState: scriptsTable.getValueAsync(header.guid + "-editorState")
            }).then(function (data) {
                var body = JSON.parse(JSON.stringify(header));
                if (!TDev.Cloud.lite && body.status == "published")
                    body.script = "";
                else if ((TDev.Cloud.lite && body.status == "published") || body.status == "unpublished" || body.status == "tobepublished") {
                    body.script = World.sanitizeScriptTextForCloud(data.script);
                    if (body.status == "tobepublished")
                        body.status = "unpublished";
                }
                else
                    body.script = undefined;
                body.editorState = data.editorState;
                if (TDev.Cloud.lite && World.disableMerge) {
                    body.scriptVersion.baseSnapshot = "*";
                }
                return TDev.Cloud.postUserInstalledAsync({ bodies: [body] }).then(function (resp) {
                    if (TDev.Cloud.lite && !resp.numErrors) {
                        var header = resp.headers[0];
                        if (!header.editor && body.script)
                            header.meta = World.getScriptMeta(body.script);
                        return getInstalledHeaderAsync(header.guid).then(function (h) {
                            var currentVersion = JSON.stringify(h.scriptVersion);
                            log("actually saving? version is now " + currentVersion);
                            if (currentVersion != conservativeVersion) {
                                h.scriptVersion.baseSnapshot = resp.headers[0].scriptVersion.baseSnapshot;
                                resp.retry = true;
                                return setInstalledAsync(indexTable, scriptsTable, h, null, null, null, null).then(function () { return resp; });
                            }
                            else {
                                return setInstalledAsync(indexTable, scriptsTable, header, null, null, null, null).then(function () { return resp; });
                            }
                        }).then(function (resp) { return World.newHeaderCallbackAsync(resp.headers[0], "uploaded").then(function () { return resp; }); });
                    }
                    return TDev.Promise.as(resp);
                });
            });
        }
        function recentUsesInstalledAsync(headers) {
            return TDev.Cloud.postUserInstalledAsync({ recentUses: headers.map(function (h) { return { guid: h.guid, recentUse: h.recentUse }; }) });
        }
        var syncVersion = undefined;
        var continuouslySyncVersion = undefined;
        var syncCount = 0;
        function cancelSync() {
            syncVersion = undefined;
        }
        World.cancelSync = cancelSync;
        function syncIsActive() {
            return !!syncVersion;
        }
        World.syncIsActive = syncIsActive;
        function cancelContinuouslySync() {
            if (continuouslySyncVersion) {
                continuouslySyncVersion = undefined;
                cancelSync();
            }
        }
        World.cancelContinuouslySync = cancelContinuouslySync;
        var updateCache = null;
        var addUpdates = {};
        World.onNewNotificationChanged = undefined;
        World._askEmail = false;
        World._askToEnableEmailNewsletter = false;
        World._askToEnableEmailNotifications = false;
        World._askToEnableNotifications = false;
        World._profileIndex = 0;
        World._profileCount = 0;
        function continuouslySyncAsync(m, onSyncedAsync) {
            if (onSyncedAsync === void 0) { onSyncedAsync = undefined; }
            if (continuouslySyncVersion)
                return TDev.Promise.as();
            return internalContinuouslySyncAsync(m, onSyncedAsync, continuouslySyncVersion = new Object());
        }
        World.continuouslySyncAsync = continuouslySyncAsync;
        function internalContinuouslySyncAsync(m, onSyncedAsync, myContinuouslySyncVersion) {
            var v = lastV;
            if (myContinuouslySyncVersion == continuouslySyncVersion && v)
                return syncAsync(false, v, m).then(function () {
                    var p = TDev.Promise.as();
                    if (myContinuouslySyncVersion == continuouslySyncVersion) {
                        if (onSyncedAsync && v != lastV)
                            p = p.then(function () { return onSyncedAsync(); });
                        p = p.then(function () { return TDev.Promise.delay(2000, function () { return internalContinuouslySyncAsync(m, onSyncedAsync, myContinuouslySyncVersion); }); });
                    }
                    return p;
                });
            else
                return TDev.Promise.as();
        }
        function getCurrentUserInfoAsync() {
            if (currentUserInfo)
                return TDev.Promise.as(currentUserInfo);
            else
                return currentUserPromise;
        }
        World.getCurrentUserInfoAsync = getCurrentUserInfoAsync;
        var lastV;
        function syncAsync(uploadRecentUses, v, m, onNotLoggedIn, onBadTime, onAskBeta, onAskSomething, onNoOtherAsk) {
            if (uploadRecentUses === void 0) { uploadRecentUses = true; }
            if (v === void 0) { v = undefined; }
            if (m === void 0) { m = false; }
            if (onNotLoggedIn === void 0) { onNotLoggedIn = undefined; }
            if (onBadTime === void 0) { onBadTime = undefined; }
            if (onAskBeta === void 0) { onAskBeta = undefined; }
            if (onAskSomething === void 0) { onAskSomething = undefined; }
            if (onNoOtherAsk === void 0) { onNoOtherAsk = undefined; }
            var totalCounter = TDev.RT.Perf.start("syncasync", true);
            var last = TDev.RT.Perf.start("startsync");
            function time(name) {
                if (!v)
                    TDev.RT.Perf.stop(last);
                last = TDev.RT.Perf.start(name);
            }
            if (syncCount > 0 && window.applicationCache.status == window.applicationCache.IDLE) {
                try {
                    window.applicationCache.update();
                }
                catch (e) {
                }
            }
            time("appcache");
            syncCount++;
            if (TDev.Cloud.isOffline()) {
                var message = TDev.lf("cannot sync - you appear to be offline");
                TDev.HTML.showProgressNotification(v ? undefined : message);
                return TDev.Promise.as(message);
            }
            time("isonline");
            var mySyncVersion = new Object();
            syncVersion = mySyncVersion;
            var canceled = TDev.Promise.wrapError("canceled");
            log("starting sync");
            localStorage.removeItem("editorScriptToSaveDirty");
            var pendingDownloads = 0;
            var pendingUploads = 0;
            var pendingPublishs = 0;
            var progress = function (deltaDownloads, deltaUploads, deltaPublishs) {
                if (syncVersion != mySyncVersion)
                    return;
                pendingDownloads += deltaDownloads;
                pendingUploads += deltaUploads;
                pendingPublishs += deltaPublishs;
                var a = [];
                if (pendingDownloads)
                    a.push(TDev.lf("{0} down", pendingDownloads));
                if (pendingUploads)
                    a.push(TDev.lf("{0} up", pendingUploads));
                if (pendingPublishs)
                    a.push(TDev.lf("{0} publish", pendingPublishs));
                var s = TDev.lf("syncing...");
                if (a.length > 0) {
                    s += " (" + a.join(", ") + ")";
                    TDev.HTML.showProgressNotification(s, false);
                }
            };
            progress(0, 0, 0);
            var tobepublished = [];
            var newerHeaders = [];
            var deletedHeaders = [];
            var uptodates = [];
            var dirtyHeaders = [];
            var askBeta = false;
            var askSomething = null;
            return (v ? TDev.Cloud.getUserInstalledLongAsync(v, m) : TDev.Cloud.getUserInstalledAsync()).then(function (installedHeaders) {
                if (syncVersion != mySyncVersion)
                    return canceled;
                return TDev.Promise.join({
                    installedHeaders: installedHeaders,
                    indexTable: getIndexTablePromise(),
                    scriptsTable: getScriptsTablePromise()
                });
            }, function (e) {
                if (e.status == 204 || false) {
                    mySyncVersion = new Object();
                    return canceled;
                }
                throw e;
            }).then(function (data) {
                time("opendb+user/installed");
                if (syncVersion != mySyncVersion)
                    return canceled;
                var user = data.installedHeaders.user;
                if (user) {
                    currentUserInfo = user;
                    if (currentUserPromise) {
                        currentUserPromise.success(user);
                        currentUserPromise = null;
                    }
                }
                var min = data.installedHeaders.minimum;
                lastV = data.installedHeaders.v;
                if (min && TDev.Cloud.currentReleaseId && min < TDev.Cloud.currentReleaseId) {
                    if (World.waitForUpdate(min)) {
                        syncVersion = new Object();
                        return;
                    }
                }
                if (World.onNewNotificationChanged)
                    World.onNewNotificationChanged(data.installedHeaders.newNotifications);
                if (TDev.Runtime.offerNotifications()) {
                    var notifications = data.installedHeaders.notifications;
                    if (TDev.Runtime.refreshNotifications)
                        TDev.Runtime.refreshNotifications(notifications);
                    World._askToEnableNotifications = !notifications;
                }
                World._askEmail = !data.installedHeaders.email;
                World._askToEnableEmailNewsletter = !data.installedHeaders.emailNewsletter;
                World._askToEnableEmailNotifications = !data.installedHeaders.emailNotifications;
                World._profileIndex = data.installedHeaders.profileIndex || 0;
                World._profileCount = data.installedHeaders.profileCount || 0;
                if (data.installedHeaders.blobcontainer)
                    TDev.Cloud.config.workspaceUrl = data.installedHeaders.blobcontainer;
                TDev.Random.addCloudEntropy(data.installedHeaders.random);
                if (!TDev.Cloud.lite && data.installedHeaders.time) {
                    var now = new Date().getTime();
                    var seconds = (now - data.installedHeaders.time * 1000) / 1000;
                    if (Math.abs(seconds) > 180) {
                        TDev.HTML.showProgressNotification(v ? undefined : "syncing canceled.");
                        syncVersion = undefined;
                        if (onBadTime)
                            onBadTime(seconds);
                        return;
                    }
                }
                if (data.installedHeaders.askBeta && World.switchToChannel)
                    askBeta = true;
                askSomething = data.installedHeaders.askSomething;
                updateCache = {};
                data.installedHeaders.headers.forEach(function (hd) {
                    if (hd.updateId && hd.scriptId != hd.updateId && hd.updateTime > hd.scriptTime)
                        updateCache[hd.scriptId] = hd.updateId;
                });
                localStorage["updateCacheForInstalled"] = JSON.stringify(updateCache);
                data.keys = data.indexTable.getKeysAsync();
                return TDev.Promise.join(data);
            }).then(function (data) {
                time("readdb1");
                if (syncVersion != mySyncVersion)
                    return canceled;
                data.items = data.indexTable.getItemsAsync(data.keys);
                if (!TDev.Cloud.lite)
                    data.scriptVersionsInCloudItems = data.scriptsTable.getItemsAsync(data.keys.map(function (guid) { return guid + "-scriptVersionInCloud"; }));
                return TDev.Promise.join(data);
            }).then(function (data) {
                time("readdb2");
                if (syncVersion != mySyncVersion)
                    return canceled;
                var recentUses = [];
                var newerOrDeletedGuids = {};
                data.installedHeaders.headers.forEach(function (header) {
                    var existingItem = data.items[header.guid];
                    var isNewer = true;
                    if (existingItem) {
                        var existingHeader = JSON.parse(existingItem);
                        if (TDev.Cloud.lite) {
                            isNewer = header.scriptVersion.baseSnapshot != existingHeader.scriptVersion.baseSnapshot && header.scriptVersion.baseSnapshot != existingHeader.pendingMerge;
                            if (existingHeader.status == "deleted")
                                isNewer = false;
                            if (!isNewer && existingHeader.scriptVersion.instanceId == "cloud" && header.status == "published" && existingHeader.status == "unpublished")
                                isNewer = true;
                        }
                        else
                            isNewer = TDev.Cloud.isVersionNewer(header.scriptVersion, existingHeader.scriptVersion);
                        if (header.recentUse < existingHeader.recentUse)
                            recentUses.push(existingHeader);
                    }
                    if (isNewer) {
                        newerOrDeletedGuids[header.guid] = true;
                        if (header.status === "deleted") {
                            if (existingItem)
                                deletedHeaders.push(header);
                        }
                        else {
                            newerHeaders.push(header);
                        }
                    }
                    else {
                        var cloudScriptVersion = JSON.stringify(header.scriptVersion);
                        var uptodate = TDev.Promise.as();
                        if (!TDev.Cloud.lite && data.scriptVersionsInCloudItems[header.guid + "-scriptVersionInCloud"] !== cloudScriptVersion)
                            uptodate = uptodate.then(function () { return setCloudScriptVersionAsync(data.scriptsTable, header.guid, cloudScriptVersion); });
                        if (header.recentUse > existingHeader.recentUse)
                            uptodate = uptodate.then(function () { return recentUseAsync(data.indexTable, header.guid, header.recentUse); });
                        uptodates.push(uptodate);
                    }
                });
                data.keys.forEach(function (key) {
                    var header = JSON.parse(data.items[key]);
                    if (newerOrDeletedGuids[header.guid])
                        return;
                    if (header.status === "tobepublished")
                        tobepublished.push(header);
                    var isDirty = true;
                    if (TDev.Cloud.lite) {
                        isDirty = header.scriptVersion.instanceId != "cloud";
                    }
                    else {
                        var s = data.scriptVersionsInCloudItems[key + "-scriptVersionInCloud"];
                        if (s) {
                            var cloudScriptVersion = JSON.parse(s);
                            if (!TDev.Cloud.isVersionNewer(header.scriptVersion, cloudScriptVersion))
                                isDirty = false;
                        }
                    }
                    if (isDirty)
                        dirtyHeaders.push(header);
                });
                log(recentUses.length + " items with newer recentUses");
                log(newerHeaders.length + " newer items to download, " + deletedHeaders.length + " deleted items");
                log(dirtyHeaders.length + " items to upload");
                progress(newerHeaders.length, dirtyHeaders.length, tobepublished.length);
                if (recentUses.length > 0 && uploadRecentUses)
                    data.recentUses = recentUsesInstalledAsync(recentUses);
                return TDev.Promise.join(data);
            }).then(function (data) {
                time("diff");
                pendingMetaItems = [];
                data.downloaded = TDev.Promise.thenEach(newerHeaders, function (h) {
                    if (syncVersion != mySyncVersion)
                        return canceled;
                    return downloadInstalledAsync(data.indexTable, data.scriptsTable, h).then(function () {
                        progress(-1, 0, 0);
                    });
                });
                data.removed = TDev.Promise.thenEach(deletedHeaders, function (h) {
                    if (syncVersion != mySyncVersion)
                        return canceled;
                    return removeInstalledAsync(data.indexTable, data.scriptsTable, h.guid);
                });
                data.uploaded = TDev.Promise.thenEach(dirtyHeaders, function (h) {
                    if (syncVersion != mySyncVersion)
                        return canceled;
                    return uploadInstalledAsync(data.indexTable, data.scriptsTable, h).then(function () {
                        progress(0, -1, 0);
                    });
                });
                data.uptodates = TDev.Promise.join(uptodates);
                return TDev.Promise.join(data);
            }).then(function (data) {
                time("download+upload");
                if (syncVersion != mySyncVersion)
                    return canceled;
                data.tobepublished = TDev.Promise.thenEach(tobepublished, function (header) { return publishInstalledAsync(data.indexTable, data.scriptsTable, header).then(function (result) {
                    progress(0, 0, -1);
                    if (!result)
                        TDev.ModalDialog.info(TDev.lf("publishing failed"), TDev.lf("There was a versioning mismatch between your local state and the cloud. Please check the content of the script you want to publish and then try again."));
                }); });
                data.progress = TDev.Cloud.postPendingProgressAsync();
                if (TDev.Cloud.lite && pendingMetaItems.length > 0) {
                    data.postmeta = TDev.Cloud.postUserInstalledAsync({ metas: pendingMetaItems });
                }
                return TDev.Promise.join(data);
            }).then(function () {
                time("publish");
                if (!v)
                    TDev.RT.Perf.stop(totalCounter);
                if (syncVersion != mySyncVersion)
                    return;
                syncVersion = undefined;
                TDev.HTML.showProgressNotification(v ? undefined : "syncing done", true, 0, 1000);
                if (askBeta && onAskBeta && !/localhost/.test(window.location.href))
                    onAskBeta();
                else if (askSomething && onAskSomething)
                    onAskSomething(askSomething);
                else if (onNoOtherAsk)
                    onNoOtherAsk();
                return undefined;
            }, function (e) {
                if (syncVersion != mySyncVersion)
                    return;
                syncVersion = undefined;
                var status = e.status;
                var errorMessage = e.errorMessage;
                if (!status)
                    Object.keys(e).forEach(function (k) {
                        var f = e[k];
                        if (!f)
                            return;
                        if (f.status)
                            status = f.status;
                        if (f.errorMessage)
                            errorMessage = f.errorMessage;
                        if (typeof f == "object")
                            Object.keys(f).forEach(function (l) {
                                var g = f[l];
                                if (!g)
                                    return;
                                if (g.status)
                                    status = g.status;
                                if (g.errorMessage)
                                    errorMessage = g.errorMessage;
                            });
                    });
                var info = "";
                if (status || errorMessage)
                    info = " (code " + status + (errorMessage ? (": " + errorMessage) : "") + ")";
                TDev.Util.log('nosync: ' + info);
                if (TDev.Util.navigatingAway) {
                    TDev.HTML.showProgressNotification(undefined);
                    return undefined;
                }
                else if (status == 442 && TDev.Cloud._migrate) {
                    TDev.Cloud._migrate();
                    return undefined;
                }
                else if (status == 400) {
                    var message = TDev.lf("Cloud precondition violated") + info;
                    TDev.HTML.showProgressNotification(message);
                    return message;
                }
                else if (status == 503) {
                    var message = TDev.lf("Did you post a lot recently? You must wait for one hour before you can post more.") + info;
                    TDev.HTML.showProgressNotification(message);
                    return message;
                }
                else if (status == 403) {
                    var message = status == 403 ? TDev.Cloud.hasAccessToken() ? onNotLoggedIn ? TDev.lf("cannot sync - your access token has expired and will renew automatically") + info : TDev.lf("cannot sync - your access token has expired") + info : TDev.lf("cannot sync - you are not signed in") + info : TDev.lf("cannot sync") + info;
                    TDev.HTML.showProgressNotification(message);
                    if (status == 403) {
                        if (!onNotLoggedIn)
                            TDev.Cloud.handlePostingError(e, TDev.lf("sync"));
                        else
                            TDev.Cloud.accessTokenExpired();
                    }
                    if (onNotLoggedIn)
                        onNotLoggedIn();
                    World.cancelContinuouslySync();
                    return message;
                }
                else if (!TDev.Cloud.isTouchDevelopOnline()) {
                    var message = TDev.lf("cannot sync - you are in offline mode");
                    TDev.HTML.showProgressNotification(v ? undefined : message);
                    return message;
                }
                else {
                    var message = TDev.lf("cannot sync - are you offline?") + info;
                    TDev.HTML.showProgressNotification(v ? undefined : message);
                    return message;
                }
            });
        }
        World.syncAsync = syncAsync;
        function saveAsync(guid, onNotLoggedIn, onBadTime) {
            if (onNotLoggedIn === void 0) { onNotLoggedIn = undefined; }
            if (onBadTime === void 0) { onBadTime = undefined; }
            if (!TDev.Cloud.getUserId() || TDev.Cloud.isOffline()) {
                TDev.Util.log('save skipped: not auth or offline');
                return TDev.Promise.as();
            }
            var mySyncVersion = new Object();
            syncVersion = mySyncVersion;
            var canceled = TDev.Promise.wrapError("canceled");
            log("starting save");
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
                header: getInstalledHeaderAsync(guid)
            }).then(function (data) {
                if (syncVersion != mySyncVersion)
                    return;
                return uploadInstalledAsync(data.indexTable, data.scriptsTable, data.header);
            }).then(function (result) {
                if (syncVersion != mySyncVersion)
                    return;
                syncVersion = undefined;
                TDev.HTML.showSaveNotification(result.numErrors ? TDev.lf("problems saving!") : TDev.lf("saved"));
                return result;
            }, function (e) {
                if (syncVersion != mySyncVersion)
                    return;
                syncVersion = undefined;
                var status = e.status;
                var errorMessage = e.errorMessage;
                var info = "";
                if (status || errorMessage)
                    info = " (code " + status + (errorMessage ? (": " + errorMessage) : "") + ")";
                if (status == 400)
                    throw new Error("Cloud precondition violated" + info);
                else if (status == 403 || (!TDev.Cloud.lite && TDev.Cloud.isOnline() && /localhost/.test(document.URL))) {
                    TDev.HTML.showSaveNotification(TDev.lf("could not save - you are not signed in ({0:500})", status));
                    if (status == 403)
                        TDev.Cloud.accessTokenExpired();
                    if (onNotLoggedIn)
                        onNotLoggedIn();
                }
                else
                    TDev.HTML.showSaveNotification(TDev.lf("cannot back up to cloud - you appear to be offline"));
            });
        }
        World.saveAsync = saveAsync;
        function uninstall(header) {
            header.scriptVersion = { instanceId: TDev.Cloud.getWorldId(), version: 2147483647, time: 253402300799, baseSnapshot: header.scriptVersion.baseSnapshot };
            header.status = "deleted";
            return header;
        }
        function uninstallAsync(guid) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            log("starting uninstall of " + guid);
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                data.items = data.indexTable.getItemsAsync([guid]);
                return TDev.Promise.join(data);
            }).then(function (data) {
                var h = data.items[guid];
                if (!h)
                    return undefined;
                var header = JSON.parse(h);
                return setUnInstalledAsync(data.indexTable, data.scriptsTable, header);
            });
        }
        World.uninstallAsync = uninstallAsync;
        function publishAsync(guid, hidden) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            log("starting publishing of " + guid);
            return TDev.Promise.join({
                indexTable: getIndexTablePromise()
            }).then(function (data) {
                data.items = data.indexTable.getItemsAsync([guid]);
                return TDev.Promise.join(data);
            }).then(function (data) {
                var h = data.items[guid];
                if (!h)
                    return undefined;
                var header = JSON.parse(h);
                if (header.status !== "unpublished")
                    return undefined;
                header.status = "tobepublished";
                header.publishAsHidden = hidden;
                var headerItem = {};
                headerItem[header.guid] = JSON.stringify(header);
                return data.indexTable.setItemsAsync(headerItem);
            });
        }
        World.publishAsync = publishAsync;
        function recentUseAsync(indexTable, guid, recentUse) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            return TDev.Promise.join({
                items: indexTable.getItemsAsync([guid])
            }).then(function (data) {
                var h = data.items[guid];
                if (!h)
                    return undefined;
                var header = JSON.parse(h);
                if (header.recentUse < recentUse)
                    header.recentUse = recentUse;
                var headerItem = {};
                headerItem[header.guid] = JSON.stringify(header);
                return indexTable.setItemsAsync(headerItem);
            });
        }
        World.recentUseAsync = recentUseAsync;
        function getCurrentTime() {
            return Math.floor(new Date().getTime() / 1000);
        }
        World.getCurrentTime = getCurrentTime;
        function stripHeaderForSave(hd) {
            return {
                cloudId: TDev.Cloud.config.cloudId,
                scriptId: hd.scriptId,
                userId: TDev.Cloud.isRestricted() ? undefined : hd.userId,
                status: hd.status,
                lastUse: hd.scriptVersion ? hd.scriptVersion.time : getCurrentTime(),
                editor: hd.editor || "touchdevelop",
                name: hd.meta.name,
                comment: hd.meta.comment,
            };
        }
        World.stripHeaderForSave = stripHeaderForSave;
        function installFromSaveAsync(hd, scriptText) {
            var tm = hd.lastUse || hd.recentUse || getCurrentTime();
            tm = TDev.Util.intBetween(1350000000, tm, getCurrentTime());
            if (!hd.meta)
                hd.meta = {};
            var name = hd.name || hd.meta.name || "no name";
            var comment = hd.comment || hd.meta.comment || "";
            var h = {
                status: hd.status === "published" ? "published" : "unpublished",
                scriptId: hd.scriptId || "",
                userId: hd.userId || (hd.scriptId ? "bogususerid" : ""),
                name: name,
                meta: {
                    name: name,
                    comment: comment,
                },
                scriptVersion: {
                    instanceId: TDev.Cloud.getWorldId(),
                    version: 0,
                    time: tm,
                    baseSnapshot: ""
                },
                guid: TDev.Util.guidGen(),
                editor: hd.editor == "touchdevelop" ? "" : hd.editor,
                recentUse: getCurrentTime(),
            };
            if (!/^\w{1,50}$/.test(h.editor))
                h.editor = "";
            if (!/^[a-z]{1,20}$/.test(h.scriptId)) {
                h.scriptId = "";
                h.userId = "";
            }
            if (h.userId && !/^[a-z]{1,20}$/.test(h.userId))
                h.userId = "bogususerid";
            if (!h.editor)
                h.meta = null;
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                return setInstalledAsync(data.indexTable, data.scriptsTable, h, scriptText, null, null, null).then(function () { return h; });
            });
        }
        World.installFromSaveAsync = installFromSaveAsync;
        function installAsync(status, scriptId, userId, stub) {
            var meta;
            if (stub.editorName == "touchdevelop") {
                meta = World.getScriptMeta(stub.scriptText);
                TDev.Util.assert(meta.name.trim() == stub.scriptName.trim());
                stub.editorName = "";
            }
            else {
                meta = {
                    localGuid: TDev.Util.guidGen(),
                    name: stub.scriptName,
                    comment: stub.scriptComment,
                };
            }
            var h = {
                status: status,
                scriptId: scriptId,
                userId: userId,
                meta: meta,
                name: meta.name,
                scriptVersion: { instanceId: TDev.Cloud.getWorldId(), version: 0, time: getCurrentTime(), baseSnapshot: "" },
                guid: meta.localGuid,
                editor: stub.editorName,
            };
            TDev.Util.assert(!!h.guid);
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                return setInstalledAsync(data.indexTable, data.scriptsTable, h, stub.scriptText, null, null, null).then(function () { return h; });
            });
        }
        function installPublishedAsync(scriptId, userId) {
            if (!TDev.Util.check(!!scriptId))
                return TDev.Promise.as(undefined);
            return getInstalledAsync().then(function (items) {
                var guids = Object.keys(items);
                var matchingGuids = guids.filter(function (guid) {
                    var item = items[guid];
                    return item.status == "published" && item.scriptId == scriptId;
                });
                if (matchingGuids.length > 0)
                    return items[matchingGuids[0]];
                return TDev.Promise.join({
                    text: TDev.ScriptCache.getScriptAsync(scriptId),
                    json: TDev.Browser.TheApiCacheMgr.getAsync(scriptId, true),
                }).then(function (data) {
                    var text = data.text;
                    var json = data.json;
                    if (!text) {
                        TDev.HTML.showErrorNotification("cannot get script /" + scriptId);
                        return new TDev.PromiseInv();
                    }
                    else {
                        return installAsync("published", scriptId, userId, {
                            scriptText: text,
                            editorName: json.editor || "touchdevelop",
                            scriptName: json.name,
                            scriptComment: json.description,
                        });
                    }
                });
            });
        }
        World.installPublishedAsync = installPublishedAsync;
        function installUnpublishedAsync(baseScriptId, baseUserId, stub) {
            return installAsync("unpublished", baseScriptId, baseUserId, stub);
        }
        World.installUnpublishedAsync = installUnpublishedAsync;
        function getInstalledAsync() {
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                data.keys = data.indexTable.getKeysAsync();
                return TDev.Promise.join(data);
            }).then(function (data) {
                return data.indexTable.getItemsAsync(data.keys).then(function (items) { return TDev.Promise.thenEach(items, function (v) { return JSON.parse(v); }); });
            });
        }
        World.getInstalledAsync = getInstalledAsync;
        function getInstalledHeaderAsync(guid) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            return getIndexTablePromise().then(function (indexTable) { return indexTable.getValueAsync(guid); }).then(function (s) { return s ? JSON.parse(s) : undefined; });
        }
        World.getInstalledHeaderAsync = getInstalledHeaderAsync;
        function getInstalledScriptAsync(guid) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            return getScriptsTablePromise().then(function (scriptsTable) { return scriptsTable.getValueAsync(guid + "-script"); });
        }
        World.getInstalledScriptAsync = getInstalledScriptAsync;
        function getInstalledEditorStateAsync(guid) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            return getScriptsTablePromise().then(function (scriptsTable) { return scriptsTable.getValueAsync(guid + "-editorState"); });
        }
        World.getInstalledEditorStateAsync = getInstalledEditorStateAsync;
        function getInstalledScriptVersionInCloud(guid) {
            if (!TDev.Util.check(!!guid))
                return TDev.Promise.as(undefined);
            return getScriptsTablePromise().then(function (scriptsTable) { return scriptsTable.getValueAsync(guid + "-scriptVersionInCloud"); });
        }
        World.getInstalledScriptVersionInCloud = getInstalledScriptVersionInCloud;
        function getAnyScriptAsync(guid) {
            if (/-/.test(guid))
                return getInstalledScriptAsync(guid);
            else
                return TDev.ScriptCache.getScriptAsync(guid);
        }
        World.getAnyScriptAsync = getAnyScriptAsync;
        function getInstalledScriptsAsync(guids) {
            return getScriptsTablePromise().then(function (scriptsTable) { return scriptsTable.getItemsAsync(guids.map(function (g) { return g + "-script"; })).then(function (map) {
                var r = {};
                guids.forEach(function (g) {
                    r[g] = map[g + "-script"];
                });
                return r;
            }); });
        }
        World.getInstalledScriptsAsync = getInstalledScriptsAsync;
        function getScriptRestoreAsync(guid) {
            var d = null;
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                d = data;
                return TDev.Promise.join([
                    data.indexTable.getValueAsync(guid),
                    data.scriptsTable.getItemsAsync([
                        guid + "-scriptVersionInCloud",
                        guid + "-editorState",
                        guid + "-script"
                    ])
                ]);
            }).then(function (resp) {
                var hd = {};
                hd[guid] = resp[0];
                var entries = resp[1];
                return function () { return TDev.Promise.join([d.indexTable.setItemsAsync(hd), d.scriptsTable.setItemsAsync(entries)]); };
            });
        }
        World.getScriptRestoreAsync = getScriptRestoreAsync;
        function setInstalledScriptAsync(header, script, editorState, scriptState, scriptVersionInCloud) {
            if (scriptState === void 0) { scriptState = null; }
            if (scriptVersionInCloud === void 0) { scriptVersionInCloud = null; }
            if (!TDev.Util.check(!!header))
                return TDev.Promise.as(undefined);
            log("setting " + header.guid);
            return TDev.Promise.join({
                indexTable: getIndexTablePromise(),
                scriptsTable: getScriptsTablePromise(),
            }).then(function (data) {
                return setInstalledAsync(data.indexTable, data.scriptsTable, header, script, editorState, scriptState, scriptVersionInCloud);
            });
        }
        World.setInstalledScriptAsync = setInstalledScriptAsync;
        function initUpdateCache() {
            if (!updateCache) {
                var s = localStorage["updateCacheForInstalled"];
                updateCache = s ? JSON.parse(s) : {};
            }
        }
        function rememberUpdate(id, update) {
            addUpdates[id] = update;
        }
        World.rememberUpdate = rememberUpdate;
        function updateFor(h) {
            initUpdateCache();
            if (h && h.status == "published")
                return updateCache[h.scriptId] || addUpdates[h.scriptId] || null;
            return null;
        }
        World.updateFor = updateFor;
        function updateAsync(guid) {
            var id = "";
            return getInstalledHeaderAsync(guid).then(function (h) {
                id = updateFor(h);
                if (!id)
                    return TDev.Promise.as();
                return TDev.ScriptCache.getScriptAsync(id);
            }).then(function (text) {
                if (!text)
                    return TDev.Promise.as();
                return getInstalledHeaderAsync(guid).then(function (h) {
                    if (h.status != "published")
                        return TDev.Promise.as();
                    h.status = "published";
                    h.scriptId = id;
                    h.meta = null;
                    return updateInstalledScriptAsync(h, text, null, true);
                });
            });
        }
        World.updateAsync = updateAsync;
        function updateInstalledScriptAsync(hd, script, state, background, scriptVersionInCloud) {
            if (background === void 0) { background = false; }
            if (scriptVersionInCloud === void 0) { scriptVersionInCloud = ""; }
            if (!background) {
                hd.status = "unpublished";
                hd.recentUse = getCurrentTime();
            }
            hd.scriptVersion.instanceId = TDev.Cloud.getWorldId();
            hd.scriptVersion.time = getCurrentTime();
            hd.scriptVersion.version++;
            if (!hd.editor)
                hd.meta = null;
            return World.setInstalledScriptAsync(hd, script, state, "", scriptVersionInCloud);
        }
        World.updateInstalledScriptAsync = updateInstalledScriptAsync;
        World.switchToChannel = function (ch) {
            if (ch == "beta")
                TDev.Util.navigateInWindow(TDev.Cloud.getServiceUrl() + "/app/beta?nocache=" + TDev.Util.guidGen());
            else
                TDev.Util.navigateInWindow(TDev.Cloud.getServiceUrl() + "/app/");
        };
    })(World = TDev.World || (TDev.World = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    TDev.onWallClose = null;
    var RuntimeHostBase = (function () {
        function RuntimeHostBase() {
            this.wallContainer = TDev.div('');
            this.backBtnDiv = TDev.div(null);
            this.scriptTitleDiv = TDev.div("scriptTitle");
            this.titleDiv = TDev.div("title");
            this.subtitleDiv = TDev.div("subtitle");
            this.titleContainer = TDev.div("wallTitleDiv");
            this.cloudSymbol = TDev.div("wallCloudSymbol");
            this.cloudStatus = TDev.div("wallCloudStatus");
            this.bgPictureContainer = TDev.div("wallBgPictureHorizontal");
            this.fullScreenContainer = TDev.div("wallFullScreenContainer");
            this.adContainer = TDev.div('wallAdContainer');
            this.wallWidth = 1000;
            this.wallHeight = 1000;
            this.wallOrientation = 0;
            this.wallVisible = false;
            this.copyrightHeight = 26;
            this.keyState = null;
            this.localProxyAsync = undefined;
            this.keyboard = undefined;
            this.cssSetup = false;
            this.cs_hasCloudState = false;
            this.cs_status = "";
            this.cs_type = "";
            this.cs_color = "#000000";
        }
        RuntimeHostBase.prototype.getWall = function () {
            return TDev.elt("theWall");
        };
        RuntimeHostBase.prototype.isHeadless = function () {
            return TDev.Browser.isHeadless || (this.currentRt && this.currentRt.headlessPluginMode);
        };
        RuntimeHostBase.prototype.fullWallHeight = function () {
            this.computeCopyrightHeight();
            return TDev.SizeMgr.windowHeight - this.copyrightHeight;
        };
        RuntimeHostBase.prototype.computeCopyrightHeight = function () {
            this.copyrightHeight = Math.round(TDev.SizeMgr.topFontSize * 0.7 * 1.66);
        };
        RuntimeHostBase.prototype.userWallHeight = function () {
            if (!this.currentRt.getCurrentPage().chromeVisible)
                return this.fullWallHeight();
            this.computeCopyrightHeight();
            return TDev.SizeMgr.windowHeight - 4 * TDev.SizeMgr.topFontSize - this.copyrightHeight;
        };
        RuntimeHostBase.prototype.fullWallWidth = function () {
            return TDev.SizeMgr.wallWindowWidth;
        };
        RuntimeHostBase.prototype.init = function (rt) {
            this.currentRt = rt;
        };
        RuntimeHostBase.prototype.liveMode = function () {
            return false;
        };
        RuntimeHostBase.prototype.dontWaitForEvents = function () {
            return false;
        };
        RuntimeHostBase.prototype.astOfAsync = function (id) {
            return TDev.Promise.as(undefined);
        };
        RuntimeHostBase.prototype.deploymentSettingsAsync = function (id) {
            return TDev.Promise.as(undefined);
        };
        RuntimeHostBase.prototype.pickScriptAsync = function (mode, message) {
            return TDev.Promise.as(undefined);
        };
        RuntimeHostBase.prototype.saveAstAsync = function (id, ast) {
            return TDev.Promise.as(undefined);
        };
        RuntimeHostBase.prototype.packageScriptAsync = function (id, options) {
            return TDev.Promise.as(undefined);
        };
        RuntimeHostBase.prototype.showBackButton = function () {
            if (TDev.Browser.notifyBackToHost)
                return this.currentRt.getCurrentPage().backButtonVisible;
            if (this.currentRt.getPageCount() == 1 && (TDev.Browser.isCompiledApp || TDev.SizeMgr.splitScreen))
                return false;
            if (!this.currentRt.isStopped())
                return this.currentRt.getCurrentPage().backButtonVisible;
            return true;
        };
        RuntimeHostBase.prototype.applyPageAttributes = function (wp) {
            this.titleDiv.setChildren(wp.title);
            this.subtitleDiv.setChildren(wp.subtitle);
            if (this.showBackButton())
                this.titleContainer.className = 'wallTitleDiv';
            else
                this.titleContainer.className = 'wallTitleDiv wallTitleDivFirst';
            var wall = TDev.elt("wallOverlay");
            wall.style.background = wp.bgColor;
            wall.style.color = wp.fgColor;
            this.updateCloudStateColor(wp.fgColor);
            var bgPic = this.bgPictureContainer;
            if (wp.bgVideo) {
                wp.bgVideo.style.width = '100%';
                wp.bgVideo.style.height = '100%';
                wp.bgVideo.style.overflow = 'hidden';
                wp.bgVideo.controls = false;
                bgPic.className = "wallBgPictureHorizontal";
                bgPic.setChildren(wp.bgVideo);
                wp.bgVideo.play();
            }
            else if (wp.bgPicture && wp.bgPictureWidth > 0 && wp.bgPictureHeight > 0) {
                var ww = wp.bgPictureWidth;
                var hh = wp.bgPictureHeight;
                var pic = wp.bgPicture;
                bgPic.setChildren(pic);
                var r = hh / ww;
                var sr = window.innerHeight / window.innerWidth;
                if (ww / hh < TDev.SizeMgr.wallWindowWidth / TDev.SizeMgr.windowHeight) {
                    pic.style.width = '100%';
                    var h = (100 * r / sr);
                    pic.style.height = h + '%';
                    bgPic.style.left = "0";
                    bgPic.style.top = (100 - h) / 2 + "%";
                    bgPic.className = "wallBgPictureHorizontal";
                }
                else {
                    var w = 100 / r * sr;
                    pic.style.width = w + '%';
                    pic.style.height = '100%';
                    bgPic.style.left = (100 - w) / 2 + "%";
                    bgPic.style.top = "0";
                    bgPic.className = "wallBgPictureVertical";
                }
            }
            else if (wp.bgPictureUrl) {
                bgPic.style.backgroundImage = TDev.HTML.cssImage(wp.bgPictureUrl);
                bgPic.style.backgroundSize = "cover";
                bgPic.style.width = '100%';
                bgPic.style.height = '100%';
                bgPic.className = 'wallBgPictureVertical';
            }
            else {
                bgPic.className = "";
                bgPic.style.width = '';
                bgPic.style.height = '';
                bgPic.style.backgroundImage = '';
                bgPic.style.backgroundSize = '';
                bgPic.setChildren([]);
            }
            var walkHtml = function (e) {
                if (!e)
                    return;
                if (e.getAttribute && e.getAttribute("fill")) {
                    e.setAttribute("fill", wp.fgColor);
                }
                if (e.className == "topMenu-button-frame")
                    e.style.borderColor = wp.fgColor;
                else if (e.className == "topMenu-button-desc" || e.className == "appBarSymbol")
                    e.style.color = wp.fgColor;
                TDev.Util.childNodes(e).forEach(walkHtml);
            };
            walkHtml(TDev.elt("wallBtns"));
            walkHtml(TDev.elt("wallFullScreenBtns"));
            walkHtml(TDev.elt("wallBottomBtns"));
        };
        RuntimeHostBase.prototype.setTransform3d = function (trans, origin, perspective) {
            var ch = this.fullScreenContainer.firstChild;
            if (ch)
                TDev.Util.setTransform(ch, trans, origin, perspective);
        };
        RuntimeHostBase.prototype.fullScreenElement = function () {
            if (this.isFullScreen())
                return this.fullScreenContainer.firstElementChild;
            return undefined;
        };
        RuntimeHostBase.prototype.setFullScreenElement = function (element) {
            this.fullScreenContainer.setChildren(element);
            if (element) {
                var wall = TDev.elt("wallOverlay");
                this.fullScreenContainer.style.position = "relative";
                this.fullScreenContainer.style.display = "block";
            }
            else {
                this.fullScreenContainer.style.display = "none";
                this.fullScreenContainer.innerHTML = "";
            }
            this.updateButtonsVisibility();
        };
        RuntimeHostBase.prototype.isFullScreen = function () {
            return this.fullScreenContainer.style.display != "none" && !!this.fullScreenContainer.firstChild;
        };
        RuntimeHostBase.prototype.copyrightElement = function () {
            var _this = this;
            if (TDev.Browser.isCompiledApp && !TDev.Browser.webRunner)
                return TDev.div(null);
            if (TDev.Browser.inEditor)
                return TDev.div(null);
            var copyrights = TDev.div("copyright-text copyright-info");
            var logo = TDev.div("copyright-text copyright-logo", TDev.SVG.getHorizLogo());
            var theNote = TDev.div("copyright-note", logo, copyrights);
            var aw = window;
            var userName = TDev.Util.htmlEscape(aw.userName);
            var userId = TDev.Util.htmlEscape(aw.userId);
            var appName = TDev.Util.htmlEscape(aw.webAppName);
            var betaFriendlyId = aw.betaFriendlyId;
            var shareLink = function () { return TDev.Browser.webRunner ? window.location.toString().replace(/#.*/, "") : _this.currentRt && _this.currentRt.currentScriptId ? TDev.Cloud.getServiceUrl() + "/" + _this.currentRt.currentScriptId : ""; };
            var author = TDev.Browser.inEditor ? "" : " by <b>" + userName + "</b>";
            var betaNote = betaFriendlyId ? ("<b>" + betaFriendlyId + "</b> ") : "";
            betaNote += "<b>" + appName + "</b>" + author;
            TDev.Browser.setInnerHTML(copyrights, "©&nbsp;&nbsp;" + "<span class='beta-underline'>privacy and cookies</span>&nbsp;&nbsp;" + "<span class='beta-underline'>legal</span>");
            var link = function (text, lnk) { return TDev.HTML.mkButton(text, function () {
                window.open(/:\/\//.test(lnk) ? lnk : TDev.Cloud.getServiceUrl() + lnk);
            }); };
            var popup = function () {
                var m = new TDev.ModalDialog();
                m.fullWhite();
                m.add(TDev.div("wall-dialog-header", TDev.Util.htmlUnescape(appName)));
                m.addHTML(TDev.lf("This web app was created {0} using Touch Develop.", author));
                m.addHTML(TDev.lf("The Touch Develop platform - Copyright © {0} Microsoft Corporation. All rights reserved.", new Date().getFullYear()));
                m.addHTML(TDev.lf("<b>DISCLAIMER:</b> This web app is not endorsed by Microsoft."));
                if (!TDev.Browser.inEditor)
                    m.add(TDev.div("wall-dialog-buttons", link("more by " + userName, "/" + userId), link("try touch develop", "")));
                m.add(TDev.div("wall-dialog-buttons", TDev.Cloud.config.legalButtons.map(function (b) { return link(b.name, b.url); })));
                m.show();
            };
            logo.withClick(popup);
            copyrights.withClick(popup);
            return theNote;
        };
        RuntimeHostBase.prototype.askSourceAccessAsync = function (source, description, secondchance, critical) {
            if (!TDev.RuntimeSettings.askSourceAccess)
                return TDev.Promise.as(true);
            var rt = this.currentRt;
            return rt.permissionsAsync().then(function (d) {
                var v = d[source];
                if (v === false && secondchance)
                    v = undefined;
                if (v != undefined) {
                    if (!v)
                        TDev.HTML.showProgressNotification("denied access to " + description);
                    return TDev.Promise.as(!!v);
                }
                return new TDev.Promise(function (onSuccess, onError, onProgress) {
                    var m = new TDev.ModalDialog();
                    var allow = false;
                    m.onDismiss = function () {
                        d[source] = allow;
                        rt.savePermissionsAsync(d).done(function () { return onSuccess(allow); });
                    };
                    var buttons;
                    m.add([
                        TDev.div("wall-dialog-header", TDev.lf("allow access to {0}?", source)),
                        TDev.div("wall-dialog-body", TDev.lf("This script wants to access {0}", description)),
                        buttons = TDev.div("wall-dialog-buttons", TDev.HTML.mkButton(TDev.lf("deny"), function () {
                            allow = false;
                            m.dismiss();
                        }), TDev.HTML.mkButton(TDev.lf("allow"), function () {
                            allow = true;
                            m.dismiss();
                        }))
                    ]);
                    if (critical) {
                        m.critical();
                        buttons.style.display = "none";
                        TDev.Util.setTimeout(5000, function () {
                            buttons.style.display = "block";
                        });
                    }
                    m.show();
                });
            });
        };
        RuntimeHostBase.prototype.updateButtonsVisibility = function () {
            if (this.isHeadless())
                return;
            var wp = this.currentRt.getCurrentPage();
            var element = this.fullScreenContainer.firstChild;
            var isStopped = this.currentRt.isStopped();
            this.titleContainer.style.display = (!wp.chromeVisible || element || TDev.SizeMgr.splitScreen) ? "none" : "block";
            this.backBtnDiv.style.display = this.showBackButton() ? "block" : "none";
            if (wp.chromeVisible)
                this.wallContainer.classList.remove('no-bar');
            else
                this.wallContainer.classList.add('no-bar');
            this.wallContainer.style.display = element ? "none" : "block";
            this.fullScreenBtnRow.style.display = (TDev.Browser.screenshots || element) ? "block" : "none";
            this.bottomBtnsDiv.style.display = (element || !this.bottomBtnsDiv.hasChildNodes()) ? "none" : "block";
            for (var i = 0; i < this.bottomBtnsDiv.children.length; ++i)
                this.bottomBtnsDiv.children[i].setFlag('disabled', isStopped);
        };
        RuntimeHostBase.prototype.applyWallStyle = function () {
            var w = this.getWall();
            w.className = "wallWithColumns";
            var h = TDev.SizeMgr.windowHeight;
            TDev.Util.setTransform(w, "none");
            TDev.Util.setupHDragToScroll(TDev.elt("wallContainer"));
            TDev.Util.resetDragToScroll(w);
            this.wallOrientation = 0;
            this.wallWidth = 18.5 * TDev.SizeMgr.topFontSize * 0.8;
            this.wallHeight = this.userWallHeight();
        };
        RuntimeHostBase.prototype.publishSizeUpdate = function () {
            if (this.currentRt) {
                var p = this.currentRt.getCurrentPage();
                if (p)
                    this.applyPageAttributes(p);
            }
            TDev.WallPage.applySizeUpdate(TDev.elt("wallOverlay"));
        };
        RuntimeHostBase.prototype.additionalButtons = function () {
            return [];
        };
        RuntimeHostBase.prototype.additionalFullScreenButtons = function () {
            return [];
        };
        RuntimeHostBase.prototype.notifyRunState = function () {
            this.updateButtonsVisibility();
        };
        RuntimeHostBase.prototype.notifyBreakpointHit = function (bp) {
        };
        RuntimeHostBase.prototype.notifyBreakpointContinue = function () {
        };
        RuntimeHostBase.prototype.notifyTutorial = function (cmd) {
        };
        RuntimeHostBase.prototype.agreeTermsOfUseAsync = function () {
            return TDev.Promise.as();
        };
        RuntimeHostBase.prototype.keyDown = function (e) {
            return this.keyboard.keyDown(e);
        };
        RuntimeHostBase.prototype.keyUp = function (e) {
            return this.keyboard.keyUp(e);
        };
        RuntimeHostBase.prototype.clearCss = function () {
            this.cssSetup = false;
            TDev.Util.childNodes(document.head).forEach(function (ch) {
                if (ch.getAttribute && ch.getAttribute("data-td-css"))
                    document.head.removeChild(ch);
            });
        };
        RuntimeHostBase.prototype.importCss = function (css) {
            this.cssSetup = true;
            if (css) {
                var fileref = document.createElement("style");
                fileref.appendChild(document.createTextNode(css));
                fileref.setAttribute("data-td-css", "yes");
                document.head.appendChild(fileref);
            }
        };
        RuntimeHostBase.prototype.showWall = function () {
            var _this = this;
            TDev.Ticker.dbg("showWall");
            var back = TDev.HTML.mkRoundButton("svg:back,currentColor", TDev.lf("back"), 288 /* wallBack */, function () { return _this.backBtnHandler(); });
            this.keyboard = new TDev.RT.RuntimeKeyboard(this.currentRt);
            this.clearCss();
            if (!TDev.SizeMgr.splitScreen) {
                var keyMgr = TDev.KeyboardMgr.instance;
                this.wallVisible = true;
                if (this.keyState == null)
                    this.keyState = keyMgr.saveState();
                keyMgr.btnShortcut(back, "Esc");
                keyMgr.register("*keydown*", function (e) { return _this.keyDown(e); });
                keyMgr.register("*keyup*", function (e) { return _this.keyUp(e); });
            }
            this.backBtnDiv = TDev.div("wallBack", back);
            this.scriptTitleDiv.setChildren([this.currentRt.compiled.scriptTitle]);
            this.cloudContainer = TDev.div("inlineBlock hidden", this.cloudSymbol, this.cloudStatus);
            this.cloudContainer.withClick(function () {
                if (_this.cs_hasCloudState)
                    TDev.RT.CloudData.sessionInfoAsync(_this.currentRt);
            });
            this.wallContainer = TDev.divId("wallContainer", "pane", TDev.divId("theWall", null), TDev.divId("theWallFloat", null));
            var wall = TDev.elt("wallOverlay");
            this.titleContainer.setChildren([this.scriptTitleDiv, this.titleDiv, this.subtitleDiv]);
            this.topBtnRow = TDev.divId("wallBtns", "wallBtnRow", this.backBtnDiv, this.titleContainer, this.cloudContainer, this.additionalButtons());
            this.fullScreenBtnRow = TDev.divId("wallFullScreenBtns", "", this.additionalFullScreenButtons());
            this.bottomBtnsDiv = TDev.divId("wallBottomBtns", "bottomButtons");
            var logoDiv;
            if (TDev.Cloud.config.companyLogoHorizontalUrl)
                logoDiv = TDev.div('wallUpperLogo', TDev.HTML.mkImg(TDev.Cloud.config.companyLogoHorizontalUrl));
            var legalDiv;
            if (this.currentRt && this.currentRt.compiled && this.currentRt.compiled.logoUrl)
                legalDiv = TDev.div('wallLogo', TDev.HTML.mkImg(this.currentRt.compiled.logoUrl));
            this.setFullScreenElement(null);
            this.bgPictureContainer.setChildren([]);
            wall.setChildren([
                this.bgPictureContainer,
                this.wallContainer,
                this.fullScreenContainer,
                this.topBtnRow,
                this.fullScreenBtnRow,
                this.bottomBtnsDiv,
                legalDiv,
                logoDiv
            ]);
            this.computeCopyrightHeight();
            this.wallContainer.style.bottom = this.copyrightHeight + "px";
            var copyright = this.copyrightElement();
            if (copyright) {
                wall.appendChild(copyright);
            }
            this.applyWallStyle();
            wall.style.display = "block";
            wall.style.opacity = "1";
            TDev.Util.showLeftPanel(wall);
            this.wallShown();
        };
        RuntimeHostBase.prototype.getFullScreenCanvas = function () {
            if (this.fullScreenContainer.style.display !== "none") {
                var el = this.fullScreenContainer.firstChild;
                while (el != null && !el.toDataURL)
                    el = el.firstChild;
                var fs = el;
                if (fs != null)
                    return fs;
            }
            return undefined;
        };
        RuntimeHostBase.prototype.toScreenshotCanvas = function () {
            var fs = this.getFullScreenCanvas();
            if (fs != null) {
                try {
                    var page = this.currentRt.getCurrentPage();
                    var bgColor = page.bgColor || 'white';
                    var bgPicture = page.bgPicture;
                    var canvas = document.createElement("canvas");
                    var w = fs.width;
                    var h = fs.height;
                    var f = 1;
                    if (h > w) {
                        if (h > 800)
                            f = 800 / h;
                    }
                    else {
                        if (w > 800)
                            f = 800 / w;
                    }
                    canvas.width = Math.floor(w * f);
                    canvas.height = Math.floor(h * f);
                    var ctx = canvas.getContext("2d");
                    ctx.save();
                    ctx.fillStyle = bgColor;
                    ctx.fillRect(0, 0, canvas.width, canvas.height);
                    if (bgPicture) {
                        var ww = page.bgPictureWidth;
                        var hh = page.bgPictureHeight;
                        var r = hh / ww;
                        var sr = canvas.height / canvas.width;
                        var left, top;
                        if (r > sr) {
                            hh = ww * sr;
                            left = 0;
                            top = (page.bgPictureHeight - hh) / 2;
                        }
                        else {
                            ww = hh / sr;
                            top = 0;
                            left = (page.bgPictureWidth - ww) / 2;
                        }
                        ctx.drawImage(bgPicture, left, top, ww, hh, 0, 0, canvas.width, canvas.height);
                    }
                    ctx.drawImage(fs, 0, 0, canvas.width, canvas.height);
                    ctx.restore();
                    return canvas;
                }
                catch (e) {
                }
            }
            return undefined;
        };
        RuntimeHostBase.prototype.otherwiseBack = function () {
        };
        RuntimeHostBase.prototype.backBtnHandler = function () {
            TDev.Ticker.dbg("history.back from RuntimeHostBase.backBtnHandler");
            if (TDev.Browser.notifyBackToHost && this.currentRt.getPageCount() == 1)
                TDev.Util.externalNotify("exit");
            else
                TDev.Util.goBack();
        };
        RuntimeHostBase.prototype.notifyPageButtonUpdate = function () {
            this.bottomBtnsDiv.removeAllChildren();
            var page = this.currentRt.getCurrentPage();
            for (var i = 0; i < page.buttons.length; i++) {
                var button = page.buttons[i];
                this.bottomBtnsDiv.appendChild(button.getElement());
            }
            if (page.buttons.length > 0) {
                this.bottomBtnsDiv.style.display = 'block';
                this.getWall().firstChild.style.paddingBottom = '6em';
            }
            else {
                this.bottomBtnsDiv.style.display = 'none';
                this.getWall().firstChild.style.paddingBottom = null;
            }
            this.notifyRunState();
        };
        RuntimeHostBase.prototype.notifyPagePush = function () {
            var _this = this;
            this.notifyPageButtonUpdate();
            if (this.currentRt.getPageCount() > 1) {
                var p = this.currentRt.getCurrentPage();
                if (!TDev.SizeMgr.splitScreen)
                    TDev.Screen.pushModalHash("page" + p.id, function () {
                        _this.currentRt.popPagesIncluding(p);
                    });
            }
        };
        RuntimeHostBase.prototype.notifyPagePop = function (p) {
            this.notifyPageButtonUpdate();
            if (!TDev.SizeMgr.splitScreen)
                TDev.Screen.popModalHash("page" + p.id);
        };
        RuntimeHostBase.prototype.notifyStopAsync = function () {
            TDev.Ticker.dbg("notifyStop");
            var p = this.currentRt.saveDataAsync();
            this.notifyRunState();
            if (!TDev.SizeMgr.splitScreen && this.backBtnDiv && this.backBtnDiv.firstChild)
                TDev.KeyboardMgr.instance.btnShortcut(this.backBtnDiv.firstChild, "Esc");
            return p;
        };
        RuntimeHostBase.prototype.updateCloudState = function (hasCloudState, type, status) {
            if (hasCloudState !== this.cs_hasCloudState || type !== this.cs_type || status !== this.cs_status) {
                if (!hasCloudState)
                    this.cloudSymbol.setChildren([]);
                else {
                    var svg = TDev.SVG.getCloudSymbol(this.cs_color, type, status === "connected", 1.5);
                    this.cloudSymbol.setChildren(svg);
                }
                this.cs_hasCloudState = hasCloudState;
                this.cs_type = type;
                if (this.cs_hasCloudState)
                    this.cloudContainer.classList.remove("hidden");
                else
                    this.cloudContainer.classList.add("hidden");
            }
            if (status !== this.cs_status) {
                this.cloudStatus.setChildren(status);
                this.cs_status = status;
            }
        };
        RuntimeHostBase.prototype.updateCloudStateColor = function (color) {
            if (this.cs_color != color) {
                if (!this.cs_hasCloudState)
                    this.cloudSymbol.setChildren([]);
                else {
                    var svg = TDev.SVG.getCloudSymbol(color, this.cs_type, this.cs_status === "connected", 1.5);
                    this.cloudSymbol.setChildren(svg);
                }
                this.cs_color = color;
            }
        };
        RuntimeHostBase.prototype.attachProfilingInfo = function (profile) {
        };
        RuntimeHostBase.prototype.attachCoverageInfo = function (profile, showCoverage) {
        };
        RuntimeHostBase.prototype.attachDebuggingInfo = function (runMap, stackTrace, errorMessage) {
        };
        RuntimeHostBase.prototype.canEditCode = function () {
            return false;
        };
        RuntimeHostBase.prototype.canDebugCode = function () {
            return false;
        };
        RuntimeHostBase.prototype.fixErrorIn = function (stableName, error) {
        };
        RuntimeHostBase.prototype.wallHidden = function () {
        };
        RuntimeHostBase.prototype.wallShown = function () {
        };
        RuntimeHostBase.prototype.hideWallAsync = function () {
            var _this = this;
            TDev.Ticker.dbg("hideWallAsync");
            if (this.keyState)
                TDev.KeyboardMgr.instance.loadState(this.keyState);
            if (!this.wallVisible) {
                return TDev.Promise.as();
            }
            this.clearCss();
            var wall = TDev.elt("wallOverlay");
            this.keyState = null;
            this.wallHidden();
            return TDev.Util.animAsync("fadeOut", 200, wall).then(function () {
                _this.wallVisible = false;
                wall.style.display = "none";
            });
        };
        RuntimeHostBase.prototype.goBack = function () {
            TDev.Ticker.dbg("history.back from RuntimeHostBase.goBack");
            TDev.Util.goBack();
        };
        RuntimeHostBase.prototype.notifyHideWall = function () {
            var _this = this;
            TDev.Ticker.dbg("notifyHideWall");
            this.hideWallAsync().done(function () {
                var f = TDev.onWallClose;
                if (!!f) {
                    TDev.onWallClose = null;
                    f();
                }
                _this.goBack();
            });
        };
        RuntimeHostBase.prototype.exceptionActions = function (e) {
            return null;
        };
        RuntimeHostBase.prototype.attachScriptStackTrace = function (bug) {
        };
        RuntimeHostBase.prototype.debugModeEnabled = function () {
            return false;
        };
        RuntimeHostBase.prototype.exceptionHandler = function (e) {
            var _this = this;
            TDev.Ticker.dbg("wallExceptionHandler");
            e.includeSource = true;
            var bug = TDev.Ticker.mkBugReport(e, "runtime error");
            var msg = bug.exceptionMessage;
            var runMap = this.currentRt.runMap;
            var stack = TDev.PackedStackTrace.buildFrom(this.currentRt.getStackTrace());
            TDev.RT.App.logException(e);
            var actions = this.exceptionActions(e) || {};
            var debugAction = actions.debug || TDev.Util.doNothing;
            var stackTraceAction = actions.stack || TDev.Util.doNothing;
            var cancelAction = TDev.Util.doNothing;
            var error = ((e.isUserError && (e.message || e.name)) || "") + "";
            function frown(d) {
                d.addFirst(TDev.div("floatingFrown", ":("));
            }
            if (this.canEditCode() && !!e.syntaxErrorDeclName) {
                this.fixErrorIn(e.syntaxErrorDeclName, error);
            }
            else if (!!e.isUserError) {
                this.attachDebuggingInfo(runMap, stack, msg);
                if (!this.canDebugCode())
                    stackTraceAction();
                else {
                    var dial = TDev.ModalDialog.buttons(TDev.lf("the script crashed"), TDev.lf("do you want do debug it?"), "", error, TDev.HTML.mkButton(TDev.lf("debug"), function () {
                        TDev.tick(472 /* crashDialogDebug */);
                        dial.dismiss();
                        debugAction();
                    }), TDev.HTML.mkButton(TDev.lf("see code"), function () {
                        dial.dismiss();
                        stackTraceAction();
                    }));
                    dial.fullYellow();
                    frown(dial);
                }
            }
            else {
                this.attachScriptStackTrace(bug);
                TDev.Util.sendErrorReport(bug);
                var jsinfo = TDev.dbg ? TDev.div("inlineBlock", TDev.HTML.mkButton(TDev.lf("js info (dbg)"), function () {
                    jsinfo.className = "";
                    var addInfo = bug.stackTrace ? bug.stackTrace : "(none available)";
                    TDev.Browser.setInnerHTML(jsinfo, TDev.Util.formatText(addInfo));
                })) : undefined;
                var dial = TDev.ModalDialog.buttons("Touch Develop crashed", this.canDebugCode() ? "do you want do debug the script?" : null, null, null, this.canDebugCode() ? TDev.HTML.mkButton(TDev.lf("debug"), function () {
                    dial.dismiss();
                    _this.attachDebuggingInfo(runMap, stack, msg);
                    debugAction();
                }) : null, jsinfo, TDev.HTML.mkButton(TDev.lf("cancel"), function () {
                    dial.dismiss();
                }));
                dial.fullYellow();
                frown(dial);
            }
        };
        return RuntimeHostBase;
    })();
    TDev.RuntimeHostBase = RuntimeHostBase;
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Embedded;
    (function (Embedded) {
        var Helpers;
        (function (Helpers) {
            Helpers.librarySymbol = "♻";
            var cppKeywords = {
                "alignas": null,
                "alignof": null,
                "and": null,
                "and_eq": null,
                "asm": null,
                "auto": null,
                "bitand": null,
                "bitor": null,
                "bool": null,
                "break": null,
                "case": null,
                "catch": null,
                "char": null,
                "char16_t": null,
                "char32_t": null,
                "class": null,
                "compl": null,
                "concept": null,
                "const": null,
                "constexpr": null,
                "const_cast": null,
                "continue": null,
                "decltype": null,
                "default": null,
                "delete": null,
                "do": null,
                "double": null,
                "dynamic_cast": null,
                "else": null,
                "enum": null,
                "explicit": null,
                "export": null,
                "extern": null,
                "false": null,
                "float": null,
                "for": null,
                "friend": null,
                "goto": null,
                "if": null,
                "inline": null,
                "int": null,
                "long": null,
                "mutable": null,
                "namespace": null,
                "new": null,
                "noexcept": null,
                "not": null,
                "not_eq": null,
                "nullptr": null,
                "operator": null,
                "or": null,
                "or_eq": null,
                "private": null,
                "protected": null,
                "public": null,
                "register": null,
                "reinterpret_cast": null,
                "requires": null,
                "return": null,
                "short": null,
                "signed": null,
                "sizeof": null,
                "static": null,
                "static_assert": null,
                "static_cast": null,
                "struct": null,
                "switch": null,
                "template": null,
                "this": null,
                "thread_local": null,
                "throw": null,
                "true": null,
                "try": null,
                "typedef": null,
                "typeid": null,
                "typename": null,
                "union": null,
                "unsigned": null,
                "using": null,
                "virtual": null,
                "void": null,
                "volatile": null,
                "wchar_t": null,
                "while": null,
                "xor": null,
                "xor_eq ": null,
            };
            var operatorTable = {
                "boolean::not": { prio: 3, right: false, op: "!" },
                "number::/": { prio: 5, right: true, op: "/" },
                "number::*": { prio: 5, right: false, op: "*" },
                "number::+": { prio: 6, right: false, op: "+" },
                "number::-": { prio: 6, right: true, op: "-" },
                "number::<": { prio: 8, right: false, op: "<" },
                "number::≤": { prio: 8, right: false, op: "<=" },
                "number::>": { prio: 8, right: false, op: ">" },
                "number::≥": { prio: 8, right: false, op: ">=" },
                "number::≠": { prio: 9, right: false, op: "!=" },
                "number::=": { prio: 9, right: false, op: "==" },
                "boolean::and": { prio: 13, right: false, op: "&&" },
                "boolean::or": { prio: 14, right: false, op: "||" },
            };
            function lookupOperator(op) {
                return operatorTable[op];
            }
            Helpers.lookupOperator = lookupOperator;
            function setPriority(e, p) {
                return {
                    usedNames: e.usedNames,
                    localNames: e.localNames,
                    globalNameMap: e.globalNameMap,
                    libName: e.libName,
                    priority: p,
                    indent: e.indent,
                    promotedIds: e.promotedIds,
                };
            }
            Helpers.setPriority = setPriority;
            function priority(e) {
                return e.priority;
            }
            Helpers.priority = priority;
            function resetPriority(e) {
                return setPriority(e, 16);
            }
            Helpers.resetPriority = resetPriority;
            function indent(e) {
                return {
                    usedNames: e.usedNames,
                    localNames: e.localNames,
                    globalNameMap: e.globalNameMap,
                    libName: e.libName,
                    priority: e.priority,
                    indent: e.indent + "  ",
                    promotedIds: e.promotedIds,
                };
            }
            Helpers.indent = indent;
            function markPromoted(e, id) {
                e.promotedIds[id] = true;
            }
            Helpers.markPromoted = markPromoted;
            function isPromoted(e, id) {
                return e.promotedIds[id];
            }
            Helpers.isPromoted = isPromoted;
            function emptyEnv(g, libName) {
                var usedNames = {};
                var m = libName ? g.libraries[libName] : g.program;
                Object.keys(m).forEach(function (tdIdent) {
                    var cppIdent = m[tdIdent];
                    usedNames[cppIdent] = true;
                });
                return {
                    usedNames: usedNames,
                    localNames: {},
                    globalNameMap: g,
                    libName: libName,
                    indent: "",
                    priority: 16,
                    promotedIds: {},
                };
            }
            Helpers.emptyEnv = emptyEnv;
            function currentMap(e) {
                return e.libName ? e.globalNameMap.libraries[e.libName] : e.globalNameMap.program;
            }
            Helpers.currentMap = currentMap;
            function mangle(name) {
                var candidate = name.replace(/\W/g, "_");
                if (candidate in cppKeywords)
                    candidate += "_";
                else if (candidate.match(/^\d/))
                    candidate = "_" + candidate;
                return candidate;
            }
            Helpers.mangle = mangle;
            function freshName(usedNames, name) {
                var i = 0;
                var suffix = "";
                while (mangle(name + suffix) in usedNames)
                    suffix = i++;
                return mangle(name + suffix);
            }
            Helpers.freshName = freshName;
            function resolveLocal(env, name, id) {
                if (id in env.localNames)
                    return env.localNames[id];
                var n = freshName(env.usedNames, name);
                env.usedNames[n] = true;
                env.localNames[id] = n;
                return n;
            }
            Helpers.resolveLocal = resolveLocal;
            function resolveLocalDef(env, d) {
                return resolveLocal(env, d.name, d.id);
            }
            Helpers.resolveLocalDef = resolveLocalDef;
            function resolveLocalRef(env, d) {
                return resolveLocal(env, d.name, d.localId);
            }
            Helpers.resolveLocalRef = resolveLocalRef;
            function resolveGlobalLN(env, l, n) {
                if (n in env.globalNameMap.libraries[l])
                    return env.globalNameMap.libraries[l][n];
                else
                    return mangle(n);
            }
            function resolveGlobalL(env, l, n) {
                return mangle(l) + "::" + resolveGlobalLN(env, l, n);
            }
            Helpers.resolveGlobalL = resolveGlobalL;
            function resolveGlobal(e, n) {
                var m = currentMap(e);
                if (n in m)
                    return m[n];
                else
                    return n;
            }
            Helpers.resolveGlobal = resolveGlobal;
            function shouldPromoteToRef(e, t, isByRef) {
                return typeof t == "string" && isByRef;
            }
            Helpers.shouldPromoteToRef = shouldPromoteToRef;
            function resolveStructuredTypeRef(libMap, t) {
                if (typeof t == "string") {
                    return {
                        lib: null,
                        user: false,
                        type: t,
                        args: []
                    };
                }
                else {
                    if (!(t.o || t.g))
                        throw new Error("Unsupported type reference");
                    return {
                        lib: t.l ? libMap[t.l] : "",
                        user: !!t.o,
                        type: t.o || t.g,
                        args: t.a && t.a.length ? t.a.map(function (x) { return resolveStructuredTypeRef(libMap, x); }) : []
                    };
                }
            }
            function resolveTypeRef(libMap, typeRef) {
                var s = typeRef;
                if (s.length && s[0] == "{")
                    return resolveStructuredTypeRef(libMap, JSON.parse(s));
                else
                    return resolveStructuredTypeRef(libMap, s);
            }
            Helpers.resolveTypeRef = resolveTypeRef;
            function defaultValueForType(libMap, t1) {
                var t = resolveTypeRef(libMap, t1);
                if (!t.lib && t.type == "Number")
                    return "0";
                else if (!t.lib && t.type == "Boolean")
                    return "false";
                else if (!t.lib && t.type == "Action")
                    return "NULL";
                else
                    return null;
            }
            Helpers.defaultValueForType = defaultValueForType;
            function toCppType(env, t) {
                var args = t.args.map(function (t) { return toCppType(env, t); });
                var n = t.lib ? resolveGlobalLN(env, t.lib, t.type) : resolveGlobal(env, t.type);
                var r = (t.lib ? mangle(t.lib) + "::" : "") + (t.user ? "user_types::" : "") + n + (args.length ? "<" + args.join(", ") + ">" : "");
                return r;
            }
            function mkType(env, libMap, type) {
                return toCppType(env, resolveTypeRef(libMap, type));
            }
            Helpers.mkType = mkType;
            function mkParam(env, libMap, p) {
                return mkType(env, libMap, p.type) + " " + resolveLocalDef(env, p);
            }
            Helpers.mkParam = mkParam;
            function mkSignature(env, libMap, name, inParams, outParams, isLambda) {
                if (isLambda === void 0) { isLambda = false; }
                if (outParams.length > 1)
                    throw new Error("Not supported (multiple return parameters)");
                var retType = outParams.length ? mkType(env, libMap, outParams[0].type) : "void";
                var args = "(" + inParams.map(function (p) { return mkParam(env, libMap, p); }).join(", ") + ")";
                if (isLambda)
                    return "[=] " + args + " mutable";
                else
                    return retType + " " + name + args;
            }
            Helpers.mkSignature = mkSignature;
            function findTypeDef(env, libMap, inParams, outParams) {
                if (!inParams.length && !outParams.length)
                    return "Action";
                else if (inParams.length == 1 && !outParams.length)
                    return "Action1<" + mkType(env, libMap, inParams[0].type) + ">";
                else
                    return mkSignature(env, libMap, "", inParams, outParams);
            }
            Helpers.findTypeDef = findTypeDef;
            function mkReturn(exprCode) {
                return "return " + exprCode + ";";
            }
            Helpers.mkReturn = mkReturn;
            function isLibrary(e) {
                if (e.nodeType == "singletonRef")
                    return e.libraryName;
                return (e.nodeType == "call" && e.args[0].nodeType == "singletonRef" && e.args[0].name == Helpers.librarySymbol && e.name || null);
            }
            Helpers.isLibrary = isLibrary;
            function isSingletonRef(e) {
                return (e.nodeType == "singletonRef" && e.name);
            }
            Helpers.isSingletonRef = isSingletonRef;
            function isRecordConstructor(name, args) {
                return (name == "create" && args.length == 1 && args[0].nodeType == "call" && args[0].parent == "records" && args[0].args.length == 1 && isSingletonRef(args[0].args[0]) == "records");
            }
            Helpers.isRecordConstructor = isRecordConstructor;
            function isEnumLiteral(e) {
                return (e.nodeType == "stringLiteral" && e.enumValue);
            }
            Helpers.isEnumLiteral = isEnumLiteral;
            function isScopedCall(e) {
                return (e.nodeType == "singletonRef" && e.name == "code" || null);
            }
            Helpers.isScopedCall = isScopedCall;
            function isShim(s) {
                var matches = s.match(/^{shim:([^}]*)}\s*$/);
                if (matches)
                    return matches[1];
                else
                    return null;
            }
            Helpers.isShim = isShim;
            function isShimBody(body) {
                var ret = null;
                body.forEach(function (s) {
                    var shim = s.nodeType == "comment" && isShim(s.text);
                    if (shim || shim === "")
                        ret = shim;
                });
                return ret;
            }
            Helpers.isShimBody = isShimBody;
            function isStringLiteral(x) {
                return x.nodeType == "stringLiteral" && x.value;
            }
            Helpers.isStringLiteral = isStringLiteral;
            function isInvalidRecord(name, args) {
                return (name == "invalid" && args.length == 1 && args[0].nodeType == "call" && args[0].parent == "records" && isSingletonRef(args[0].args[0]) == "records");
            }
            Helpers.isInvalidRecord = isInvalidRecord;
            function isInitialRecordAssignment(locals, expr) {
                return (locals.length == 1 && expr.nodeType == "call" && expr.name == ":=" && expr.args.length == 2 && expr.args[1].nodeType == "call" && isRecordConstructor(expr.args[1].name, expr.args[1].args) && expr.args[0].nodeType == "localRef" && expr.args[0].localId == locals[0].id);
            }
            Helpers.isInitialRecordAssignment = isInitialRecordAssignment;
            function willCompile(f) {
                return isShimBody(f.body) == null;
            }
            Helpers.willCompile = willCompile;
            function mkLibraryRef(x) {
                return {
                    nodeType: "call",
                    id: null,
                    args: [{
                        nodeType: "singletonRef",
                        id: null,
                        name: "♻",
                    }],
                    name: x,
                    parent: null,
                };
            }
            Helpers.mkLibraryRef = mkLibraryRef;
            function mkCodeRef() {
                return {
                    nodeType: "singletonRef",
                    id: null,
                    name: "code"
                };
            }
            Helpers.mkCodeRef = mkCodeRef;
        })(Helpers = Embedded.Helpers || (Embedded.Helpers = {}));
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Embedded;
    (function (Embedded) {
        var JsonAstVisitor = (function () {
            function JsonAstVisitor() {
            }
            JsonAstVisitor.prototype.visit = function (env, n) {
                switch (n.nodeType) {
                    case "numberLiteral":
                        return this.visitNumberLiteral(env, n.value);
                    case "booleanLiteral":
                        return this.visitBooleanLiteral(env, n.value);
                    case "stringLiteral":
                        return this.visitStringLiteral(env, n.value);
                    case "operator":
                        return this.visitOperator(env, n.op);
                    case "propertyRef":
                        var n9 = n;
                        return this.visitPropertyRef(env, n9.name, n9.parent);
                    case "call":
                        var n10 = n;
                        return this.visitCall(env, n10.name, n10.args, n10.typeArgs, n10.parent, n10.callType);
                    case "singletonRef":
                        return this.visitSingletonRef(env, n.name);
                    case "globalDef":
                        var n13 = n;
                        return this.visitGlobalDef(env, n13.name, n13.type, n13.comment);
                    case "localDef":
                        var n1 = n;
                        return this.visitLocalDef(env, n1.name, n1.id, n1.type, n1.isByRef);
                    case "localRef":
                        var n11 = n;
                        return this.visitLocalRef(env, n11.name, n11.localId);
                    case "exprHolder":
                        var n16 = n;
                        return this.visitExprHolder(env, n16.locals, n16.tree, n16.tokens);
                    case "exprStmt":
                        var ex = n;
                        var tr = ex.expr.tree;
                        switch (tr.nodeType) {
                            case "show":
                                var nshow = tr;
                                return this.visitShow(env, nshow.expr);
                            case "break":
                                return this.visitBreak(env);
                            case "continue":
                                return this.visitContinue(env);
                            case "return":
                                var nret = tr;
                                return this.visitReturn(env, nret.expr);
                            default:
                                return this.visitExprStmt(env, ex.expr);
                        }
                    case "inlineActions":
                        var n8 = n;
                        return this.visitInlineActions(env, n8.expr, n8.actions);
                    case "while":
                        var n3 = n;
                        return this.visitWhile(env, n3.condition, n3.body);
                    case "for":
                        var n4 = n;
                        return this.visitFor(env, n4.index, n4.bound, n4.body);
                    case "comment":
                        return this.visitComment(env, n.text);
                    case "if":
                        var n5 = n;
                        return this.visitIf(env, n5.condition, n5.thenBody, n5.elseBody, n5.isElseIf);
                    case "inlineAction":
                        var n6 = n;
                        return this.visitInlineAction(env, n6.reference, n6.inParameters, n6.outParameters, n6.body);
                    case "action":
                        var n7 = n;
                        return this.visitAction(env, n7.name, n7.id, n7.inParameters, n7.outParameters, n7.body, n7.isPrivate);
                    case "app":
                        return this.visitApp(env, n.decls);
                    case "library":
                        return this.visitLibrary(env, n.scriptName);
                    case "art":
                        var n12 = n;
                        return this.visitArt(env, n12.name, n12.type, n12.url, n12.comment);
                    case "data":
                        var n14 = n;
                        return this.visitData(env, n14.name, n14.type, n14.comment);
                    case "record":
                        var n15 = n;
                        return this.visitRecord(env, n15.name, n15.keys, n15.fields, n15.isExported);
                }
                throw new Error("Unsupported node: " + n.nodeType);
            };
            JsonAstVisitor.prototype.visitNumberLiteral = function (env, v) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitStringLiteral = function (env, v) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitBooleanLiteral = function (env, v) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitOperator = function (env, op) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitPropertyRef = function (env, name, parent) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitCall = function (env, name, args, typeArgs, parent, callType) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitSingletonRef = function (env, name) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitLocalDef = function (env, name, id, type, isByRef) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitLocalRef = function (env, name, id) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitExprHolder = function (env, locals, expr, tokens) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitExprStmt = function (env, expr) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitReturn = function (env, expr) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitShow = function (env, expr) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitBreak = function (env) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitContinue = function (env) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitInlineActions = function (env, expr, actions) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitWhile = function (env, cond, body) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitFor = function (env, index, bound, body) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitComment = function (env, c) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitIf = function (env, cond, thenBranch, elseBranch, isElseIf) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitInlineAction = function (env, reference, inParams, outParams, body) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitAction = function (env, name, id, inParams, outParams, body, isPrivate) {
                return this.visitDecl(env, name);
            };
            JsonAstVisitor.prototype.visitApp = function (env, decls) {
                throw new Error("Not implemented");
            };
            JsonAstVisitor.prototype.visitLibrary = function (env, name) {
                return this.visitDecl(env, name);
            };
            JsonAstVisitor.prototype.visitArt = function (env, name, type, url, comment) {
                return this.visitGlobalDef(env, name, type, comment);
            };
            JsonAstVisitor.prototype.visitData = function (env, name, type, comment) {
                return this.visitGlobalDef(env, name, type, comment);
            };
            JsonAstVisitor.prototype.visitGlobalDef = function (env, name, type, comment) {
                return this.visitDecl(env, name);
            };
            JsonAstVisitor.prototype.visitRecord = function (env, name, keys, fields, isExported) {
                return this.visitDecl(env, name);
            };
            JsonAstVisitor.prototype.visitDecl = function (env, name) {
                throw new Error("Not implemented");
            };
            return JsonAstVisitor;
        })();
        Embedded.JsonAstVisitor = JsonAstVisitor;
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var TDev;
(function (TDev) {
    var Embedded;
    (function (Embedded) {
        var H = Embedded.Helpers;
        function assert(x) {
            if (!x)
                throw new Error("Assert failure");
        }
        var Emitter = (function (_super) {
            __extends(Emitter, _super);
            function Emitter(libRef, libs, resolveMap) {
                _super.call(this);
                this.libRef = libRef;
                this.libs = libs;
                this.resolveMap = resolveMap;
                this.prototypes = "";
                this.code = "";
                this.prelude = "";
                this.tPrototypes = "";
                this.tCode = "";
                this.libraryMap = {};
                this.imageLiterals = [];
            }
            Emitter.prototype.visitMany = function (e, ss) {
                var _this = this;
                var code = [];
                ss.forEach(function (s) {
                    code.push(_this.visit(e, s));
                });
                return code.join("\n");
            };
            Emitter.prototype.visitComment = function (env, c) {
                return env.indent + "// " + c.replace("\n", "\n" + env.indent + "// ");
            };
            Emitter.prototype.visitBreak = function (env) {
                return env.indent + "break;";
            };
            Emitter.prototype.visitContinue = function (env) {
                return env.indent + "continue;";
            };
            Emitter.prototype.visitShow = function (env, expr) {
                return env.indent + "serial.print(" + this.visit(env, expr) + ");";
            };
            Emitter.prototype.visitReturn = function (env, expr) {
                return env.indent + H.mkReturn(this.visit(env, expr));
            };
            Emitter.prototype.visitExprStmt = function (env, expr) {
                return env.indent + this.visit(env, expr) + ";";
            };
            Emitter.prototype.visitInlineActions = function (env, expr, actions) {
                var _this = this;
                var map = {};
                expr.locals.forEach(function (l) {
                    map[l.id] = l.name;
                });
                var lambdas = actions.map(function (a) {
                    var n = H.resolveLocal(env, map[a.reference.id], a.reference.id);
                    return (env.indent + H.findTypeDef(env, _this.libraryMap, a.inParameters, a.outParameters) + " " + n + " = " + _this.visitAction(env, "", n, a.inParameters, a.outParameters, a.body, false, true) + ";\n");
                });
                return (lambdas.join("\n") + "\n" + env.indent + this.visit(env, expr.tree) + ";");
            };
            Emitter.prototype.visitExprHolder = function (env, locals, expr) {
                var _this = this;
                if (H.isInitialRecordAssignment(locals, expr))
                    return this.visit(env, locals[0]) + "(new " + H.mkType(env, this.libraryMap, locals[0].type) + "_)";
                var decls = locals.map(function (d) {
                    var decl = _this.visit(env, d);
                    var defaultValue = H.defaultValueForType(_this.libraryMap, d.type);
                    var initialValue = !H.isPromoted(env, d.id) && defaultValue ? " = " + defaultValue : "";
                    return decl + initialValue + ";";
                });
                return decls.join("\n" + env.indent) + (decls.length ? "\n" + env.indent : "") + this.visit(env, expr);
            };
            Emitter.prototype.visitLocalRef = function (env, name, id) {
                var prefix = H.isPromoted(env, id) ? "*" : "";
                return prefix + H.resolveLocal(env, name, id);
            };
            Emitter.prototype.visitLocalDef = function (env, name, id, type, isByRef) {
                var t = H.mkType(env, this.libraryMap, type);
                var l = H.resolveLocal(env, name, id);
                if (H.shouldPromoteToRef(env, type, isByRef)) {
                    H.markPromoted(env, id);
                    return "Ref<" + t + "> " + l;
                }
                else {
                    return t + " " + l;
                }
            };
            Emitter.prototype.visitStringLiteral = function (env, s) {
                return 'touch_develop::mk_string("' + s.replace(/["\\\n\r]/g, function (c) {
                    if (c == '"')
                        return '\\"';
                    if (c == '\\')
                        return '\\\\';
                    if (c == "\n")
                        return '\\n';
                    if (c == "\r")
                        return '\\r';
                }) + '")';
            };
            Emitter.prototype.visitNumberLiteral = function (env, n) {
                return n + "";
            };
            Emitter.prototype.visitBooleanLiteral = function (env, b) {
                return b + "";
            };
            Emitter.prototype.visitWhile = function (env, cond, body) {
                var condCode = this.visit(env, cond);
                var bodyCode = this.visitMany(H.indent(env), body);
                return env.indent + "while (" + condCode + ") {\n" + bodyCode + "\n" + env.indent + "}";
            };
            Emitter.prototype.visitFor = function (env, index, bound, body) {
                var indexCode = this.visit(env, index) + " = 0";
                var testCode = H.resolveLocalDef(env, index) + " < " + this.visit(env, bound);
                var incrCode = "++" + H.resolveLocalDef(env, index);
                var bodyCode = this.visitMany(H.indent(env), body);
                return (env.indent + "for (" + indexCode + "; " + testCode + "; " + incrCode + ") {\n" + bodyCode + "\n" + env.indent + "}");
            };
            Emitter.prototype.visitIf = function (env, cond, thenBranch, elseBranch, isElseIf) {
                var isIfFalse = cond.tree.nodeType == "booleanLiteral" && cond.tree.value === false;
                return [
                    env.indent,
                    isElseIf ? "else " : "",
                    "if (" + this.visit(env, cond) + "){\n",
                    isIfFalse ? "" : this.visitMany(H.indent(env), thenBranch) + "\n",
                    env.indent,
                    "}",
                    elseBranch ? " else {\n" : "",
                    elseBranch ? this.visitMany(H.indent(env), elseBranch) + "\n" : "",
                    elseBranch ? env.indent + "}" : ""
                ].join("");
            };
            Emitter.prototype.resolveCall = function (env, receiver, name) {
                if (!receiver)
                    return null;
                var scoped = H.isScopedCall(receiver);
                if (scoped)
                    return this.resolveCall(env, this.libRef, name);
                var n = H.isLibrary(receiver);
                if (n) {
                    var key = this.resolveMap[n] || n;
                    var lib = this.libs.filter(function (l) { return l.name == key; })[0];
                    var action = lib.decls.filter(function (d) { return d.name == name; })[0];
                    var s = H.isShimBody(action.body);
                    if (s != null) {
                        if (!s.length)
                            throw new Error("Library author: some (compiled) function is trying to call " + name + " " + "which is marked as {shim:}, i.e. for simulator purposes only.\n\n" + "Hint: break on exceptions in the debugger and walk up the call stack to " + "figure out which action it is.");
                        return s;
                    }
                    else if (n in this.resolveMap) {
                        return H.resolveGlobalL(env, this.resolveMap[n], name);
                    }
                    else {
                        return H.resolveGlobal(env, name);
                    }
                }
                return null;
            };
            Emitter.prototype.specialTreatment = function (e, f, actualArgs) {
                var _this = this;
                if (f == "micro_bit::createImage" || f == "micro_bit::showAnimation" || f == "micro_bit::showLeds" || f == "micro_bit::plotLeds") {
                    var x = H.isStringLiteral(actualArgs[0]);
                    if (x === "")
                        x = "0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n";
                    if (!x)
                        throw new Error("create image / show animation / plot image takes a string literal only");
                    var r = "literals::bitmap" + this.imageLiterals.length;
                    var otherArgs = actualArgs.splice(1).map(function (x) { return _this.visit(e, x); });
                    var code = f + "(" + r + "_w, " + r + "_h, " + r + (otherArgs.length ? ", " + otherArgs : "") + ")";
                    this.imageLiterals.push(x);
                    return code;
                }
                else {
                    return null;
                }
            };
            Emitter.prototype.safeGet = function (x, f) {
                return x + "->" + f;
            };
            Emitter.prototype.visitCall = function (env, name, args, typeArgs, parent, callType, typeArgument) {
                var _this = this;
                if (typeArgument === void 0) { typeArgument = null; }
                var mkCall = function (f, skipReceiver) {
                    var actualArgs = skipReceiver ? args.slice(1) : args;
                    var s = _this.specialTreatment(env, f, actualArgs);
                    if (s)
                        return s;
                    else {
                        var argsCode = actualArgs.map(function (a) {
                            var k = H.isEnumLiteral(a);
                            if (k)
                                return k + "";
                            else
                                return _this.visit(H.resetPriority(env), a);
                        });
                        var t = typeArgument ? "<" + typeArgument + ">" : "";
                        return f + t + "(" + argsCode.join(", ") + ")";
                    }
                };
                var mkWrap = function (prio) {
                    var needsParentheses = prio > H.priority(env);
                    var wrap = needsParentheses ? function (x) { return "(" + x + ")"; } : function (x) { return x; };
                    return wrap;
                };
                if (parent == "Unfinished Type") {
                    var newTypeArg = typeArgument || H.mkType(env, this.libraryMap, typeArgs[0]);
                    assert(args.length && args[0].nodeType == "call");
                    var call = args[0];
                    return this.visitCall(H.resetPriority(env), call.name, call.args, call.typeArgs, call.parent, call.callType, newTypeArg);
                }
                if (H.isRecordConstructor(name, args)) {
                    var struct_name = "user_types::" + H.resolveGlobal(env, parent) + "_";
                    return "ManagedType<" + struct_name + ">(new " + struct_name + "())";
                }
                if (H.isInvalidRecord(name, args))
                    return "ManagedType<user_types::" + H.resolveGlobal(env, args[0].name) + "_>()";
                if (name == "is invalid" && H.resolveTypeRef(this.libraryMap, parent).user) {
                    return mkWrap(9)(this.visit(H.setPriority(env, 9), args[0]) + ".get() == NULL");
                }
                if (name == "equals" && H.resolveTypeRef(this.libraryMap, parent).user)
                    return mkWrap(9)(this.visit(H.setPriority(env, 9), args[0]) + "==" + this.visit(H.setPriority(env, 9), args[1]));
                var resolvedName = this.resolveCall(H.resetPriority(env), args[0], name);
                if (resolvedName)
                    return mkCall(resolvedName, true);
                else if (name == ":=")
                    return this.visit(H.resetPriority(env), args[0]) + " = " + this.visit(H.resetPriority(env), args[1]);
                else if (args.length && H.isSingletonRef(args[0]) == "data")
                    return "globals::" + H.resolveGlobal(env, name);
                else if (callType == "extension") {
                    var t = H.resolveTypeRef(this.libraryMap, parent);
                    var prefixedName = t.lib ? this.resolveCall(H.resetPriority(env), H.mkLibraryRef(t.lib), name) : this.resolveCall(H.resetPriority(env), H.mkCodeRef(), name);
                    return mkCall(prefixedName, false);
                }
                else if (callType == "field")
                    return this.safeGet(this.visit(H.resetPriority(env), args[0]), H.mangle(name));
                else if (args.length && H.isSingletonRef(args[0]) == "♻")
                    return "";
                else if (args.length && H.isSingletonRef(args[0]))
                    return H.isSingletonRef(args[0]).toLowerCase() + "::" + mkCall(H.mangle(name).toLowerCase(), true);
                else {
                    var t = H.resolveTypeRef(this.libraryMap, parent);
                    var op = H.lookupOperator(t.type.toLowerCase() + "::" + name);
                    if (op) {
                        var wrap = mkWrap(op.prio);
                        var rightPriority = op.right ? op.prio - 1 : op.prio;
                        var leftPriority = op.prio;
                        if (args.length == 2)
                            return wrap(this.visit(H.setPriority(env, leftPriority), args[0]) + " " + op.op + " " + this.visit(H.setPriority(env, rightPriority), args[1]));
                        else {
                            assert(args.length == 1);
                            return wrap(op.op + this.visit(H.setPriority(env, leftPriority), args[0]));
                        }
                    }
                    else {
                        return mkCall(t.type.toLowerCase() + "::" + H.mangle(name), false);
                    }
                }
            };
            Emitter.prototype.visitSingletonRef = function (e, n) {
                if (n == "$skip")
                    return "";
                else
                    return "";
            };
            Emitter.prototype.visitGlobalDef = function (e, name, t, comment) {
                var s = H.isShim(comment);
                if (s !== null)
                    return null;
                var def = comment.match(/{default:([^}]+)}/);
                var x = def ? def[1] : H.defaultValueForType(this.libraryMap, t);
                return e.indent + H.mkType(e, this.libraryMap, t) + " " + H.resolveGlobal(e, name) + (x ? " = " + x : "") + ";";
            };
            Emitter.prototype.visitAction = function (env, name, id, inParams, outParams, body, isPrivate, isLambda) {
                if (isLambda === void 0) { isLambda = false; }
                if (outParams.length > 1)
                    throw new Error("Not supported (multiple return parameters)");
                var env2 = H.indent(env);
                var outParamInitialization = "";
                if (outParams.length > 0) {
                    var defaultValue = H.defaultValueForType(this.libraryMap, outParams[0].type);
                    var initialValue = defaultValue ? " = " + defaultValue : "";
                    outParamInitialization = env2.indent + this.visit(env2, outParams[0]) + initialValue + ";";
                }
                var bodyText = [
                    outParamInitialization,
                    this.visitMany(env2, body),
                    outParams.length ? env2.indent + H.mkReturn(H.resolveLocalDef(env, outParams[0])) : "",
                ].filter(function (x) { return x != ""; }).join("\n");
                var head = H.mkSignature(env, this.libraryMap, H.resolveGlobal(env, name), inParams, outParams, isLambda);
                return (isLambda ? "" : env.indent) + head + " {\n" + bodyText + "\n" + env.indent + "}";
            };
            Emitter.prototype.compileImageLiterals = function (e) {
                if (!this.imageLiterals.length)
                    return "";
                return e.indent + "namespace literals {\n" + this.imageLiterals.map(function (s, n) {
                    var x = 0;
                    var w = 0;
                    var h = 0;
                    var lit = "{ ";
                    for (var i = 0; i < s.length; ++i) {
                        switch (s[i]) {
                            case "0":
                            case "1":
                                lit += s[i] + ", ";
                                x++;
                                break;
                            case " ":
                                break;
                            case "\n":
                                if (w == 0)
                                    w = x;
                                else if (x != w)
                                    throw new Error("Malformed string literal");
                                x = 0;
                                h++;
                                break;
                            default:
                                throw new Error("Malformed string literal");
                        }
                    }
                    h++;
                    lit += "}";
                    var r = "bitmap" + n;
                    return e.indent + "  const int " + r + "_w = " + w + ";\n" + e.indent + "  const int " + r + "_h = " + h + ";\n" + e.indent + "  const uint8_t " + r + "[] = " + lit + ";\n";
                }).join("\n") + e.indent + "}\n\n";
            };
            Emitter.prototype.typeDecl = function (e, r) {
                var _this = this;
                var s = H.isShim(r.comment);
                if (s !== null)
                    return null;
                var n = H.resolveGlobal(e, r.name);
                var fields = r.fields.map(function (f) {
                    var t = H.mkType(e, _this.libraryMap, f.type);
                    return e.indent + "  " + t + " " + H.mangle(f.name) + ";";
                }).join("\n");
                return [
                    e.indent + "struct " + n + "_ {",
                    fields,
                    e.indent + "};",
                ].join("\n");
            };
            Emitter.prototype.typeStub = function (e, r) {
                var n = H.resolveGlobal(e, r.name);
                var s = H.isShim(r.comment);
                if (s === "")
                    return null;
                else if (s !== null)
                    return e.indent + "typedef " + s + " " + n + ";";
                else
                    return [
                        e.indent + "struct " + n + "_;",
                        e.indent + "typedef ManagedType<" + n + "_> " + n + ";",
                    ].join("\n");
            };
            Emitter.prototype.wrapNamespaceIf = function (e, s) {
                if (e.libName != null)
                    return (s.length ? "  namespace " + H.mangle(e.libName) + " {\n" + s + "\n  }" : "");
                else
                    return s;
            };
            Emitter.prototype.wrapNamespaceDecls = function (e, n, s) {
                return (s.length ? e.indent + "namespace " + n + " {\n" + s.join("\n") + "\n" + e.indent + "}" : "");
            };
            Emitter.prototype.visitApp = function (e, decls) {
                var _this = this;
                e = H.indent(e);
                if (e.libName)
                    e = H.indent(e);
                decls.forEach(function (x) {
                    if (x.nodeType == "library") {
                        var l = x;
                        _this.libraryMap[l.id] = l.name;
                    }
                });
                var typeStubs = decls.map(function (f) {
                    var e1 = H.indent(e);
                    if (f.nodeType == "record")
                        return _this.typeStub(e1, f);
                    else
                        return null;
                }).filter(function (x) { return x != null; });
                var typeStubsCode = this.wrapNamespaceDecls(e, "user_types", typeStubs);
                var typeDefs = decls.map(function (f) {
                    var e1 = H.indent(e);
                    if (f.nodeType == "record")
                        return _this.typeDecl(e1, f);
                    else
                        return null;
                }).filter(function (x) { return x != null; });
                var typeDefsCode = this.wrapNamespaceDecls(e, "user_types", typeDefs);
                var globals = decls.map(function (f) {
                    var e1 = H.indent(e);
                    if (f.nodeType == "data")
                        return _this.visit(e1, f);
                    else
                        return null;
                }).filter(function (x) { return x != null; });
                var globalsCode = this.wrapNamespaceDecls(e, "globals", globals);
                var forwardDeclarations = decls.map(function (f) {
                    if (f.nodeType == "action" && H.willCompile(f)) {
                        return e.indent + H.mkSignature(e, _this.libraryMap, H.resolveGlobal(e, f.name), f.inParameters, f.outParameters) + ";";
                    }
                    else {
                        return null;
                    }
                }).filter(function (x) { return x != null; });
                var userFunctions = decls.map(function (d) {
                    if (d.nodeType == "action" && H.willCompile(d)) {
                        return _this.visit(e, d);
                    }
                    else if (d.nodeType == "art" && d.name == "prelude.cpp") {
                        _this.prelude += d.value;
                    }
                    else {
                        return null;
                    }
                    return null;
                }).filter(function (x) { return x != null; });
                this.prototypes = this.wrapNamespaceIf(e, globalsCode + "\n" + forwardDeclarations.join("\n"));
                this.code = this.wrapNamespaceIf(e, this.compileImageLiterals(e) + userFunctions.join("\n"));
                this.tPrototypes = this.wrapNamespaceIf(e, typeStubsCode);
                this.tCode = this.wrapNamespaceIf(e, typeDefsCode);
                return null;
            };
            return Emitter;
        })(Embedded.JsonAstVisitor);
        Embedded.Emitter = Emitter;
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Embedded;
    (function (Embedded) {
        var H = Embedded.Helpers;
        function extend(e, x) {
            e.push(x);
        }
        function contains(e, x) {
            return e.indexOf(x) >= 0;
        }
        var Lifter = (function (_super) {
            __extends(Lifter, _super);
            function Lifter(env) {
                _super.call(this);
                this.env = env;
                this.as = [];
            }
            Lifter.prototype.visitMany = function (e, ss) {
                var _this = this;
                ss.forEach(function (x) { return _this.visit(e, x); });
            };
            Lifter.prototype.visit = function (env, e) {
                var _this = this;
                if (e.nodeType == "inlineActions") {
                    var e1 = e;
                    var lifted = [];
                    e1.actions.forEach(function (a) {
                        try {
                            _this.visit([], a);
                            _this.as.push(a);
                            lifted.push(a.reference.id);
                            var newName = H.resolveLocal(_this.env, a.reference.name, a.reference.id);
                            a.reference.name = newName;
                        }
                        catch (e) {
                        }
                    });
                    e1.actions = e1.actions.filter(function (a) { return lifted.indexOf(a.reference.id) < 0; });
                    e1.expr.locals = e1.expr.locals.filter(function (l) { return lifted.indexOf(l.id) < 0; });
                    if (e1.actions.length == 0)
                        e.nodeType = "exprStmt";
                }
                else {
                    _super.prototype.visit.call(this, env, e);
                }
            };
            Lifter.prototype.visitExpr = function (env, e) {
            };
            Lifter.prototype.visitExprStmt = function (env, expr) {
                this.visit(env, expr);
            };
            Lifter.prototype.visitExprHolder = function (env, locals, tree, tokens) {
                locals.forEach(function (x) { return extend(env, x.id); });
                tokens.forEach(function (x) {
                    if (x.nodeType == "localRef" && !contains(env, x.localId))
                        throw {};
                });
            };
            Lifter.prototype.visitContinue = function (env) {
            };
            Lifter.prototype.visitReturn = function (env) {
            };
            Lifter.prototype.visitBreak = function (env) {
            };
            Lifter.prototype.visitInlineActions = function (env, e, actions) {
                this.visit(env, e);
                this.visitMany(env, actions);
            };
            Lifter.prototype.visitInlineAction = function (env, r, i, o, body) {
                var e = [];
                i.forEach(function (x) { return extend(e, x.id); });
                o.forEach(function (x) { return extend(e, x.id); });
                this.visitMany(e, body);
            };
            Lifter.prototype.visitWhile = function (env, cond, body) {
                this.visitMany(env, body);
            };
            Lifter.prototype.visitIf = function (env, cond, thenBranch, elseBranch, isElseIf) {
                this.visitMany(env, thenBranch);
                this.visitMany(env, elseBranch || []);
            };
            Lifter.prototype.visitFor = function (env, index, bound, body) {
                extend(env, index.id);
                this.visitMany(env, body);
            };
            Lifter.prototype.visitComment = function (env, c) {
            };
            Lifter.prototype.visitAction = function (env, name, id, inParams, outParams, body, isPrivate) {
                if (H.isShimBody(body) == null) {
                    var e = [];
                    inParams.forEach(function (x) { return extend(e, x.id); });
                    outParams.forEach(function (x) { return extend(e, x.id); });
                    this.visitMany(e, body);
                }
            };
            Lifter.prototype.visitLibrary = function (env, name) {
            };
            Lifter.prototype.visitApp = function (e, decls) {
                this.visitMany(e, decls);
            };
            Lifter.prototype.visitGlobalDef = function (e, n, t) {
            };
            Lifter.prototype.visitRecord = function (e, n, k, f) {
            };
            return Lifter;
        })(Embedded.JsonAstVisitor);
        function lift(e, a) {
            var l = new Lifter(e);
            l.visit([], a);
            var lambdas = l.as.map(function (a) {
                var name = a.reference.name;
                var id = a.reference.id;
                return {
                    nodeType: "action",
                    id: id,
                    name: name,
                    inParameters: a.inParameters,
                    outParameters: a.outParameters,
                    isPrivate: false,
                    isOffline: false,
                    isQuery: false,
                    isTest: false,
                    isAsync: false,
                    description: "",
                    body: a.body
                };
            });
            Array.prototype.push.apply(a.decls, lambdas);
        }
        Embedded.lift = lift;
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Bytecode;
        (function (Bytecode) {
            var funcInfo;
            var hex;
            var jmpStartAddr;
            var jmpStartIdx;
            var bytecodeStartAddr;
            var bytecodeStartIdx;
            function swapBytes(str) {
                var r = "";
                for (var i = 0; i < str.length; i += 2)
                    r = str[i] + str[i + 1] + r;
                TDev.Util.assert(i == str.length);
                return r;
            }
            function userError(msg) {
                var e = new Error(msg);
                e.bitvmUserError = true;
                throw e;
            }
            function isSetupFor(extInfo) {
                return currentSetup == extInfo.sha;
            }
            Bytecode.isSetupFor = isSetupFor;
            function parseHexBytes(bytes) {
                bytes = bytes.replace(/^[\s:]/, "");
                if (!bytes)
                    return [];
                var m = /^([a-f0-9][a-f0-9])/i.exec(bytes);
                if (m)
                    return [parseInt(m[1], 16)].concat(parseHexBytes(bytes.slice(2)));
                else
                    TDev.Util.oops("bad bytes " + bytes);
            }
            var currentSetup = null;
            function setupFor(extInfo, bytecodeInfo) {
                if (isSetupFor(extInfo))
                    return;
                currentSetup = extInfo.sha;
                var jsinf = bytecodeInfo || TDev.bytecodeInfo;
                hex = jsinf.hex;
                var i = 0;
                var upperAddr = "0000";
                var lastAddr = 0;
                var lastIdx = 0;
                bytecodeStartAddr = 0;
                for (; i < hex.length; ++i) {
                    var m = /:02000004(....)/.exec(hex[i]);
                    if (m) {
                        upperAddr = m[1];
                    }
                    m = /^:..(....)00/.exec(hex[i]);
                    if (m) {
                        var newAddr = parseInt(upperAddr + m[1], 16);
                        if (!bytecodeStartAddr && newAddr >= 0x3C000) {
                            var bytes = parseHexBytes(hex[lastIdx]);
                            if (bytes[0] != 0x10) {
                                bytes.pop();
                                bytes[0] = 0x10;
                                while (bytes.length < 20)
                                    bytes.push(0x00);
                                hex[lastIdx] = hexBytes(bytes);
                            }
                            TDev.Util.assert((bytes[2] & 0xf) == 0);
                            bytecodeStartAddr = lastAddr + 16;
                            bytecodeStartIdx = lastIdx + 1;
                        }
                        lastIdx = i;
                        lastAddr = newAddr;
                    }
                    m = /^:10....000108010842424242010801083ED8E98D/.exec(hex[i]);
                    if (m) {
                        jmpStartAddr = lastAddr;
                        jmpStartIdx = i;
                    }
                }
                if (!jmpStartAddr)
                    TDev.Util.oops("No hex start");
                funcInfo = {};
                var funs = jsinf.functions.concat(extInfo.functions);
                var addEnum = function (enums) { return Object.keys(enums).forEach(function (k) {
                    funcInfo[k] = {
                        name: k,
                        type: "E",
                        args: 0,
                        value: enums[k]
                    };
                }); };
                addEnum(extInfo.enums);
                addEnum(jsinf.enums);
                for (var i = jmpStartIdx + 1; i < hex.length; ++i) {
                    var m = /^:10(....)00(.{16})/.exec(hex[i]);
                    if (!m)
                        continue;
                    var s = hex[i].slice(9);
                    while (s.length >= 8) {
                        var inf = funs.shift();
                        if (!inf)
                            return;
                        funcInfo[inf.name] = inf;
                        inf.value = parseInt(swapBytes(s.slice(0, 8)), 16) & 0xfffffffe;
                        TDev.Util.assert(!!inf.value);
                        s = s.slice(8);
                    }
                }
                TDev.Util.die();
            }
            Bytecode.setupFor = setupFor;
            function isRefKind(k) {
                TDev.Util.assert(k != null);
                TDev.Util.assert(k != AST.api.core.Unknown);
                var isSimple = k == AST.api.core.Number || k == AST.api.core.Boolean;
                return !isSimple;
            }
            function isRefExpr(e) {
                if (typeof e.getLiteral() == "string" && e.enumVal != null)
                    return false;
                if (typeof e.getLiteral() == "number")
                    return false;
                return isRefKind(e.getKind());
            }
            function lookupFunc(name) {
                if (/^uBit\./.test(name))
                    name = name.replace(/^uBit\./, "micro_bit::").replace(/\.(.)/g, function (x, y) { return y.toUpperCase(); });
                return funcInfo[name];
            }
            function lookupFunctionAddr(name) {
                var inf = lookupFunc(name);
                if (inf)
                    return inf.value - bytecodeStartAddr;
                return null;
            }
            Bytecode.lookupFunctionAddr = lookupFunctionAddr;
            function tohex(n) {
                if (n < 0 || n > 0xffff)
                    return ("0x" + n.toString(16)).toLowerCase();
                else
                    return ("0x" + ("000" + n.toString(16)).slice(-4)).toLowerCase();
            }
            Bytecode.tohex = tohex;
            var Location = (function () {
                function Location(index, def) {
                    if (def === void 0) { def = null; }
                    this.index = index;
                    this.def = def;
                    this.isarg = false;
                }
                Location.prototype.toString = function () {
                    var n = "";
                    if (this.def)
                        n += this.def.getName();
                    if (this.isarg)
                        n = "ARG " + n;
                    if (this.isRef())
                        n = "REF " + n;
                    if (this.isByRefLocal())
                        n = "BYREF " + n;
                    return "[" + n + "]";
                };
                Location.prototype.isRef = function () {
                    return this.def && isRefKind(this.def.getKind());
                };
                Location.prototype.refSuff = function () {
                    if (this.isRef())
                        return "Ref";
                    else
                        return "";
                };
                Location.prototype.isByRefLocal = function () {
                    return this.def instanceof AST.LocalDef && this.def.isByRef();
                };
                Location.prototype.emitStoreByRef = function (proc) {
                    TDev.Util.assert(this.def instanceof AST.LocalDef);
                    if (this.isByRefLocal()) {
                        this.emitLoadLocal(proc);
                        proc.emit("pop {r1}");
                        proc.emitCallRaw("bitvm::stloc" + (this.isRef() ? "Ref" : ""));
                    }
                    else {
                        this.emitStore(proc);
                    }
                };
                Location.prototype.asmref = function (proc) {
                    if (this.isarg) {
                        var idx = proc.args.length - this.index - 1;
                        return "[sp, args@" + idx + "] ; " + this.toString();
                    }
                    else {
                        var idx = this.index;
                        return "[sp, locals@" + idx + "] ; " + this.toString();
                    }
                };
                Location.prototype.emitStoreCore = function (proc) {
                    proc.emit("str r0, " + this.asmref(proc));
                };
                Location.prototype.emitStore = function (proc) {
                    if (this.isarg)
                        TDev.Util.oops("store for arg");
                    if (this.def instanceof AST.GlobalDef) {
                        proc.emitInt(this.index);
                        proc.emitCall("bitvm::stglb" + this.refSuff(), 0);
                    }
                    else {
                        TDev.Util.assert(!this.isByRefLocal());
                        if (this.isRef()) {
                            this.emitLoadCore(proc);
                            proc.emitCallRaw("bitvm::decr");
                        }
                        proc.emit("pop {r0}");
                        this.emitStoreCore(proc);
                    }
                };
                Location.prototype.emitLoadCore = function (proc) {
                    proc.emit("ldr r0, " + this.asmref(proc));
                };
                Location.prototype.emitLoadByRef = function (proc) {
                    if (this.isByRefLocal()) {
                        this.emitLoadLocal(proc);
                        proc.emitCallRaw("bitvm::ldloc" + this.refSuff());
                        proc.emit("push {r0}");
                    }
                    else
                        this.emitLoad(proc);
                };
                Location.prototype.emitLoadLocal = function (proc) {
                    if (this.isarg && proc.argsInR5) {
                        TDev.Util.assert(0 <= this.index && this.index < 32);
                        proc.emit("ldr r0, [r5, #4*" + this.index + "]");
                    }
                    else {
                        this.emitLoadCore(proc);
                    }
                };
                Location.prototype.emitLoad = function (proc, direct) {
                    if (direct === void 0) { direct = false; }
                    if (this.def instanceof AST.GlobalDef) {
                        proc.emitInt(this.index);
                        proc.emitCall("bitvm::ldglb" + this.refSuff(), 0);
                    }
                    else {
                        TDev.Util.assert(direct || !this.isByRefLocal());
                        this.emitLoadLocal(proc);
                        proc.emit("push {r0}");
                        if (this.isRef() || this.isByRefLocal()) {
                            proc.emitCallRaw("bitvm::incr");
                        }
                    }
                };
                Location.prototype.emitClrIfRef = function (proc) {
                    TDev.Util.assert(!(this.def instanceof AST.GlobalDef));
                    if (this.isarg && this.isByRefLocal())
                        return;
                    if (this.isRef() || this.isByRefLocal()) {
                        this.emitLoadCore(proc);
                        proc.emitCallRaw("bitvm::decr");
                    }
                };
                return Location;
            })();
            Bytecode.Location = Location;
            var Procedure = (function () {
                function Procedure() {
                    this.numArgs = 0;
                    this.hasReturn = false;
                    this.argsInR5 = false;
                    this.lblNo = 0;
                    this.prebody = "";
                    this.body = "";
                    this.locals = [];
                    this.args = [];
                }
                Procedure.prototype.toString = function () {
                    return this.prebody + this.body;
                };
                Procedure.prototype.mkLocal = function (def) {
                    if (def === void 0) { def = null; }
                    var l = new Location(this.locals.length, def);
                    this.locals.push(l);
                    return l;
                };
                Procedure.prototype.emitClrs = function (omit, inclArgs) {
                    var _this = this;
                    if (inclArgs === void 0) { inclArgs = false; }
                    var lst = this.locals;
                    if (inclArgs)
                        lst = lst.concat(this.args);
                    lst.forEach(function (p) {
                        if (p.def != omit)
                            p.emitClrIfRef(_this);
                    });
                };
                Procedure.prototype.emitCallRaw = function (name) {
                    this.emit("bl " + name + " ; (raw)");
                };
                Procedure.prototype.emitCall = function (name, mask) {
                    var inf = lookupFunc(name);
                    TDev.Util.assert(!!inf, "unimplemented function: " + name);
                    TDev.Util.assert(inf.args <= 4);
                    if (inf.args >= 4)
                        this.emit("pop {r3}");
                    if (inf.args >= 3)
                        this.emit("pop {r2}");
                    if (inf.args >= 2)
                        this.emit("pop {r1}");
                    if (inf.args >= 1)
                        this.emit("pop {r0}");
                    var reglist = [];
                    for (var i = 0; i < 4; ++i) {
                        if (mask & (1 << i))
                            reglist.push("r" + i);
                    }
                    var numMask = reglist.length;
                    if (inf.type == "F" && mask != 0) {
                        reglist.push("r7");
                        this.emit("@stackmark retval");
                    }
                    TDev.Util.assert((mask & ~0xf) == 0);
                    if (reglist.length > 0)
                        this.emit("push {" + reglist.join(",") + "}");
                    this.emit("bl " + name);
                    if (inf.type == "F") {
                        if (mask == 0)
                            this.emit("push {r0}");
                        else {
                            this.emit("str r0, [sp, retval@-1]");
                        }
                    }
                    else if (inf.type == "P") {
                    }
                    else
                        TDev.Util.oops("invalid call type " + inf.type);
                    while (numMask-- > 0) {
                        this.emitCall("bitvm::decr", 0);
                    }
                };
                Procedure.prototype.emitJmp = function (trg, name) {
                    if (name === void 0) { name = "JMP"; }
                    var lbl = "";
                    if (name == "JMPZ") {
                        lbl = this.mkLabel("jmpz");
                        this.emit("pop {r0}");
                        this.emit("cmp r0, #0");
                        this.emit("bne " + lbl);
                    }
                    else if (name == "JMPNZ") {
                        lbl = this.mkLabel("jmpnz");
                        this.emit("pop {r0}");
                        this.emit("cmp r0, #0");
                        this.emit("beq " + lbl);
                    }
                    else if (name == "JMP") {
                    }
                    else {
                        TDev.Util.oops("bad jmp");
                    }
                    this.emit("bb " + trg);
                    if (lbl)
                        this.emitLbl(lbl);
                };
                Procedure.prototype.mkLabel = function (root) {
                    return "." + root + "." + this.seqNo + "." + this.lblNo++;
                };
                Procedure.prototype.emitLbl = function (lbl) {
                    this.emit(lbl + ":");
                };
                Procedure.prototype.emit = function (name) {
                    this.body += asmline(name);
                };
                Procedure.prototype.emitMov = function (v) {
                    TDev.Util.assert(0 <= v && v <= 255);
                    this.emit("movs r0, #" + v);
                };
                Procedure.prototype.emitAdd = function (v) {
                    TDev.Util.assert(0 <= v && v <= 255);
                    this.emit("adds r0, #" + v);
                };
                Procedure.prototype.emitLdPtr = function (lbl, push) {
                    if (push === void 0) { push = false; }
                    TDev.Util.assert(!!lbl);
                    this.emit("movs r0, " + lbl + "@hi   ; ldptr " + lbl);
                    this.emit("lsls r0, r0, #8");
                    this.emit("adds r0, " + lbl + "@lo   ; endldptr");
                    if (push)
                        this.emit("push {r0}");
                };
                Procedure.prototype.emitInt = function (v, keepInR0) {
                    if (keepInR0 === void 0) { keepInR0 = false; }
                    TDev.Util.assert(v != null);
                    var n = Math.floor(v);
                    var isNeg = false;
                    if (n < 0) {
                        isNeg = true;
                        n = -n;
                    }
                    if (n <= 255) {
                        this.emitMov(n);
                    }
                    else if (n <= 0xffff) {
                        this.emitMov((n >> 8) & 0xff);
                        this.emit("lsls r0, r0, #8");
                        this.emitAdd(n & 0xff);
                    }
                    else {
                        this.emitMov((n >> 24) & 0xff);
                        this.emit("lsls r0, r0, #8");
                        this.emitAdd((n >> 16) & 0xff);
                        this.emit("lsls r0, r0, #8");
                        this.emitAdd((n >> 8) & 0xff);
                        this.emit("lsls r0, r0, #8");
                        this.emitAdd((n >> 0) & 0xff);
                    }
                    if (isNeg) {
                        this.emit("neg r0, r0");
                    }
                    if (!keepInR0)
                        this.emit("push {r0}");
                };
                Procedure.prototype.stackEmpty = function () {
                    this.emit("@stackempty locals");
                };
                Procedure.prototype.pushLocals = function () {
                    TDev.Util.assert(this.prebody == "");
                    this.prebody = this.body;
                    this.body = "";
                };
                Procedure.prototype.popLocals = function () {
                    var _this = this;
                    var suff = this.body;
                    this.body = this.prebody;
                    var len = this.locals.length;
                    if (len > 0)
                        this.emit("movs r0, #0");
                    this.locals.forEach(function (l) {
                        _this.emit("push {r0} ; loc");
                    });
                    this.emit("@stackmark locals");
                    this.body += suff;
                    TDev.Util.assert(0 <= len && len < 127);
                    if (len > 0)
                        this.emit("add sp, #4*" + len + " ; pop locals " + len);
                };
                return Procedure;
            })();
            Bytecode.Procedure = Procedure;
            function hexBytes(bytes) {
                var chk = 0;
                var r = ":";
                bytes.forEach(function (b) { return chk += b; });
                bytes.push((-chk) & 0xff);
                bytes.forEach(function (b) { return r += ("0" + b.toString(16)).slice(-2); });
                return r.toUpperCase();
            }
            var Binary = (function () {
                function Binary() {
                    this.procs = [];
                    this.globals = [];
                    this.csource = "";
                    this.strings = {};
                    this.stringsBody = "";
                    this.lblNo = 0;
                }
                Binary.prototype.isDataRecord = function (s) {
                    if (!s)
                        return false;
                    var m = /^:......(..)/.exec(s);
                    TDev.Util.assert(!!m);
                    return m[1] == "00";
                };
                Binary.prototype.patchHex = function (shortForm) {
                    var myhex = hex.slice(0, bytecodeStartIdx);
                    TDev.Util.assert(this.buf.length < 32000);
                    var ptr = 0;
                    function nextLine(buf, addr) {
                        var bytes = [0x10, (addr >> 8) & 0xff, addr & 0xff, 0];
                        for (var j = 0; j < 8; ++j) {
                            bytes.push((buf[ptr] || 0) & 0xff);
                            bytes.push((buf[ptr] || 0) >>> 8);
                            ptr++;
                        }
                        return bytes;
                    }
                    var hd = [0x4207, this.globals.length, bytecodeStartAddr & 0xffff, bytecodeStartAddr >>> 16];
                    var tmp = hexTemplateHash();
                    for (var i = 0; i < 4; ++i)
                        hd.push(parseInt(swapBytes(tmp.slice(i * 4, i * 4 + 4)), 16));
                    myhex[jmpStartIdx] = hexBytes(nextLine(hd, jmpStartAddr));
                    ptr = 0;
                    if (shortForm)
                        myhex = [];
                    var addr = bytecodeStartAddr;
                    var upper = (addr - 16) >> 16;
                    while (ptr < this.buf.length) {
                        if ((addr >> 16) != upper) {
                            upper = addr >> 16;
                            myhex.push(hexBytes([0x02, 0x00, 0x00, 0x04, upper >> 8, upper & 0xff]));
                        }
                        myhex.push(hexBytes(nextLine(this.buf, addr)));
                        addr += 16;
                    }
                    if (!shortForm)
                        hex.slice(bytecodeStartIdx).forEach(function (l) { return myhex.push(l); });
                    return myhex;
                };
                Binary.prototype.addProc = function (proc) {
                    this.procs.push(proc);
                    proc.seqNo = this.procs.length;
                    proc.label = "_" + (proc.action ? proc.action.getName().replace(/[^\w]/g, "") : "inline") + "_" + proc.seqNo;
                };
                Binary.prototype.stringLiteral = function (s) {
                    var r = "\"";
                    for (var i = 0; i < s.length; ++i) {
                        var c = s.charCodeAt(i) & 0xff;
                        var cc = String.fromCharCode(c);
                        if (cc == "\\" || cc == "\"")
                            r += "\\" + cc;
                        else if (cc == "\n")
                            r += "\\n";
                        else if (c <= 0xf)
                            r += "\\x0" + c.toString(16);
                        else if (c < 32 || c > 127)
                            r += "\\x" + c.toString(16);
                        else
                            r += cc;
                    }
                    return r + "\"";
                };
                Binary.prototype.emitLiteral = function (s) {
                    this.stringsBody += s + "\n";
                };
                Binary.prototype.emitString = function (s) {
                    if (this.strings.hasOwnProperty(s))
                        return this.strings[s];
                    var lbl = "_str" + this.lblNo++;
                    this.strings[s] = lbl;
                    this.emitLiteral(".balign 4");
                    this.emitLiteral(lbl + "meta: .short 0xffff, " + s.length);
                    this.emitLiteral(lbl + ": .string " + this.stringLiteral(s));
                    return lbl;
                };
                Binary.prototype.emit = function (s) {
                    this.csource += asmline(s);
                };
                Binary.prototype.serialize = function () {
                    var _this = this;
                    TDev.Util.assert(this.csource == "");
                    this.emit("; start");
                    this.emit(".hex 708E3B92C615A841C49866C975EE5197");
                    this.emit(".hex " + hexTemplateHash() + " ; hex template hash");
                    this.emit(".hex 0000000000000000 ; @SRCHASH@");
                    this.emit(".space 16 ; reserved");
                    this.procs.forEach(function (p) {
                        _this.csource += "\n" + p.body;
                    });
                    this.csource += this.stringsBody;
                    this.emit("_program_end:");
                };
                Binary.prototype.patchSrcHash = function () {
                    var srcSha = TDev.Random.sha256buffer(TDev.Util.stringToUint8Array(TDev.Util.toUTF8(this.csource)));
                    this.csource = this.csource.replace(/\n.*@SRCHASH@\n/, "\n    .hex " + srcSha.slice(0, 16).toUpperCase() + " ; program hash\n");
                };
                Binary.prototype.addSource = function (meta, blob) {
                    var metablob = TDev.Util.stringToUint8Array(TDev.Util.toUTF8(meta));
                    var totallen = metablob.length + blob.length;
                    if (totallen > 40000) {
                        return 0;
                    }
                    this.emit(".balign 16");
                    this.emit(".hex 41140E2FB82FA2BB");
                    this.emit(".short " + metablob.length);
                    this.emit(".short " + blob.length);
                    this.emit(".short 0");
                    this.emit(".short 0");
                    var str = "_stored_program: .string \"";
                    var addblob = function (b) {
                        for (var i = 0; i < b.length; ++i) {
                            var v = b[i] & 0xff;
                            if (v <= 0xf)
                                str += "\\x0" + v.toString(16);
                            else
                                str += "\\x" + v.toString(16);
                        }
                    };
                    addblob(metablob);
                    addblob(blob);
                    str += "\"";
                    this.emit(str);
                    return totallen + 16;
                };
                Binary.extractSource = function (hexfile) {
                    if (!hexfile)
                        return undefined;
                    var metaLen = 0;
                    var textLen = 0;
                    var toGo = 0;
                    var buf;
                    var ptr = 0;
                    hexfile.split(/\r?\n/).forEach(function (ln) {
                        var m = /^:10....0041140E2FB82FA2BB(....)(....)(....)(....)(..)/.exec(ln);
                        if (m) {
                            metaLen = parseInt(swapBytes(m[1]), 16);
                            textLen = parseInt(swapBytes(m[2]), 16);
                            toGo = metaLen + textLen;
                            buf = new Uint8Array(toGo);
                        }
                        else if (toGo > 0) {
                            m = /^:10....00(.*)(..)$/.exec(ln);
                            if (!m)
                                return;
                            var k = m[1];
                            while (toGo > 0 && k.length > 0) {
                                buf[ptr++] = parseInt(k[0] + k[1], 16);
                                k = k.slice(2);
                                toGo--;
                            }
                        }
                    });
                    if (!buf || !(toGo == 0 && ptr == buf.length)) {
                        return undefined;
                    }
                    var bufmeta = new Uint8Array(metaLen);
                    var buftext = new Uint8Array(textLen);
                    for (var i = 0; i < metaLen; ++i)
                        bufmeta[i] = buf[i];
                    for (var i = 0; i < textLen; ++i)
                        buftext[i] = buf[metaLen + i];
                    return {
                        meta: TDev.Util.fromUTF8Bytes(bufmeta),
                        text: buftext
                    };
                };
                Binary.prototype.assemble = function () {
                    var _this = this;
                    AST.Thumb.test();
                    var b = new AST.Thumb.Binary();
                    b.lookupExternalLabel = lookupFunctionAddr;
                    b.emit(this.csource);
                    this.csource = b.getSource(!/peepdbg=1/.test(document.URL));
                    if (b.errors.length > 0) {
                        var userErrors = "";
                        b.errors.forEach(function (e) {
                            var m = /^user(\d+)/.exec(e.scope);
                            if (m) {
                                var no = parseInt(m[1]);
                                var proc = _this.procs.filter(function (p) { return p.seqNo == no; })[0];
                                if (proc && proc.action)
                                    userErrors += TDev.lf("At function {0}:\n", proc.action.getName());
                                else
                                    userErrors += TDev.lf("At inline assembly:\n");
                                userErrors += e.message;
                            }
                        });
                        if (userErrors) {
                            TDev.ModalDialog.showText(userErrors, TDev.lf("errors in inline assembly"));
                        }
                        else {
                            throw new Error(b.errors[0].message);
                        }
                    }
                    else {
                        this.buf = b.buf;
                    }
                };
                return Binary;
            })();
            Bytecode.Binary = Binary;
            var ReachabilityVisitor = (function (_super) {
                __extends(ReachabilityVisitor, _super);
                function ReachabilityVisitor() {
                    _super.apply(this, arguments);
                    this.markShims = false;
                }
                ReachabilityVisitor.prototype.useAction = function (a) {
                    if (a.getShimName() != null) {
                        if (this.markShims || a._compilerInlineBody) {
                            a.visitorState = true;
                        }
                        return;
                    }
                    _super.prototype.useAction.call(this, a);
                };
                return ReachabilityVisitor;
            })(AST.PreCompiler);
            Bytecode.ReachabilityVisitor = ReachabilityVisitor;
            function computeReachableNodes(app, markShims) {
                if (markShims === void 0) { markShims = false; }
                var prev = TDev.Script;
                try {
                    TDev.Script = app;
                    var pre = new ReachabilityVisitor({});
                    pre.markShims = markShims;
                    pre.run(TDev.Script);
                }
                finally {
                    TDev.Script = prev;
                }
            }
            Bytecode.computeReachableNodes = computeReachableNodes;
            var Compiler = (function (_super) {
                __extends(Compiler, _super);
                function Compiler(app) {
                    _super.call(this);
                    this.app = app;
                    this.binary = new Binary();
                    this.numStmts = 1;
                    this.finals = [];
                }
                Compiler.prototype.shouldCompile = function (d) {
                    return d.visitorState === true;
                };
                Compiler.prototype.run = function () {
                    var _this = this;
                    setup();
                    if (AST.TypeChecker.tcApp(this.app) > 0) {
                        TDev.HTML.showProgressNotification(TDev.lf("Your script has errors! Just saving the source."));
                        return;
                    }
                    var prev = TDev.Script;
                    try {
                        TDev.Script = this.app;
                        computeReachableNodes(this.app);
                        this.app.librariesAndThis().forEach(function (l) {
                            if (l.isThis()) {
                                l.resolved.libraries().forEach(function (lr) { return lr.getPublicActions().forEach(function (la) {
                                    la._compilerInfo = la.template;
                                }); });
                            }
                            else {
                                var ress = TDev.Util.toDictionary(l.resolveClauses.stmts, function (r) { return r.formalLib.getName(); });
                                l.resolved.libraries().forEach(function (lr) {
                                    var acts = TDev.Util.toDictionary(ress[lr.getName()].actionBindings.stmts, function (a) { return a.formal.getName(); });
                                    lr.getPublicActions().forEach(function (la) {
                                        if (!acts[la.getName()])
                                            return;
                                        var act = acts[la.getName()].actual;
                                        if (act instanceof AST.LibraryRefAction && act.template)
                                            la._compilerInfo = act.template;
                                        else
                                            la._compilerInfo = act;
                                    });
                                });
                            }
                            _this.prepApp(l.resolved);
                        });
                        this.app.librariesAndThis().forEach(function (l) {
                            _this.compileApp(l.resolved);
                        });
                        while (this.finals.length > 0) {
                            var f = this.finals.shift();
                            f();
                        }
                    }
                    finally {
                        TDev.Script = prev;
                    }
                };
                Compiler.prototype.serialize = function (shortForm, metainfo, blob) {
                    var compiled = false;
                    shortForm = false;
                    if (this.binary.procs.length == 0) {
                        shortForm = true;
                    }
                    else {
                        this.binary.serialize();
                        compiled = true;
                    }
                    var lenSrc = 0;
                    if (metainfo != null && blob != null)
                        lenSrc = this.binary.addSource(metainfo, blob);
                    this.binary.patchSrcHash();
                    var sourceSaved = lenSrc > 0;
                    this.binary.assemble();
                    var res = {
                        data: null,
                        contentType: "application/x-microbit-hex",
                        csource: this.binary.csource,
                        sourceSaved: sourceSaved,
                        compiled: compiled,
                    };
                    if (!this.binary.buf)
                        return res;
                    var hex = this.binary.patchHex(shortForm).join("\r\n") + "\r\n";
                    res.data = hex;
                    return res;
                };
                Compiler.prototype.visitAstNode = function (n) {
                    this.visitChildren(n);
                };
                Compiler.prototype.handleAssignment = function (e) {
                    TDev.Util.assert(e._assignmentInfo.targets.length == 1);
                    var trg = e.args[0];
                    var src = e.args[1];
                    var refSuff = isRefKind(e.args[1].getKind()) ? "Ref" : "";
                    if (trg.referencedRecordField()) {
                        this.dispatch(trg.args[0]);
                        this.emitInt(this.fieldIndex(trg.referencedRecordField()));
                        this.dispatch(src);
                        this.proc.emitCall("bitvm::stfld" + refSuff, 0);
                    }
                    else if (trg.referencedData()) {
                        this.dispatch(src);
                        this.globalIndex(trg.referencedData()).emitStore(this.proc);
                    }
                    else if (trg.referencedLocal()) {
                        this.dispatch(src);
                        this.localIndex(trg.referencedLocal()).emitStoreByRef(this.proc);
                    }
                    else {
                        TDev.Util.oops("bad assignment: " + trg.nodeType());
                    }
                };
                Compiler.prototype.visitBreak = function (b) {
                    this.proc.emitJmp(b.topAffectedStmt._compilerBreakLabel);
                };
                Compiler.prototype.visitContinue = function (b) {
                    this.proc.emitJmp(b.topAffectedStmt._compilerContinueLabel);
                };
                Compiler.prototype.visitReturn = function (r) {
                    if (r.topRetLocal) {
                        this.dispatch(r.args[0]);
                        this.localIndex(r.topRetLocal).emitStore(this.proc);
                    }
                    this.proc.emitJmp(r.topAffectedStmt._compilerBreakLabel);
                };
                Compiler.prototype.getMask = function (args) {
                    TDev.Util.assert(args.length <= 8);
                    var m = 0;
                    args.forEach(function (a, i) {
                        if (isRefExpr(a))
                            m |= (1 << i);
                    });
                    return m;
                };
                Compiler.prototype.emitAsString = function (e) {
                    this.dispatch(e);
                    var kn = e.getKind().getName().toLowerCase();
                    if (kn == "string") {
                    }
                    else if (kn == "number" || kn == "boolean") {
                        this.proc.emitCall(kn + "::to_string", 0);
                    }
                    else {
                        TDev.Util.oops("don't know how to convert " + kn + " to string");
                    }
                };
                Compiler.prototype.emitImageLiteral = function (s) {
                    if (!s)
                        s = "0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n";
                    var x = 0;
                    var w = 0;
                    var h = 0;
                    var lit = "";
                    for (var i = 0; i < s.length; ++i) {
                        switch (s[i]) {
                            case "0":
                                lit += "0,";
                                x++;
                                break;
                            case "1":
                                lit += "1,";
                                x++;
                                break;
                            case " ": break;
                            case "\n":
                                if (w == 0)
                                    w = x;
                                else if (x != w)
                                    throw new Error("Malformed string literal");
                                x = 0;
                                h++;
                                break;
                            default:
                                throw new Error("Malformed string literal");
                        }
                    }
                    if (x > 0)
                        h++;
                    var lbl = "_img" + this.binary.lblNo++;
                    this.binary.emitLiteral(".balign 4");
                    this.binary.emitLiteral(lbl + ": .short 0xffff");
                    this.binary.emitLiteral("        .short " + w + ", " + h);
                    if (lit.length % 4 != 0)
                        lit += "42";
                    this.binary.emitLiteral("        .byte " + lit);
                    this.proc.emitLdPtr(lbl, true);
                };
                Compiler.prototype.handleActionCall = function (e) {
                    var _this = this;
                    var aa = e.calledExtensionAction() || e.calledAction();
                    var args = e.args.slice(0);
                    if (args[0].getKind() instanceof TDev.ThingSetKind || args[0].referencedLibrary() || (args[0] instanceof AST.ThingRef && args[0].namespaceLibraryName())) {
                        args.shift();
                    }
                    TDev.Util.assert(args.length == aa.getInParameters().length);
                    var a = aa._compilerInfo || aa;
                    TDev.Util.assert(args.length == a.getInParameters().length);
                    if (a != aa) {
                        var params = a.getParameters().slice(-a.getInParameters().length);
                        params.forEach(function (p) {
                            var sv = p.getStringValues();
                            if (!sv)
                                return;
                            var emap = sv.enumMap;
                            if (emap) {
                                var v = emap[args[0].getStringLiteral()];
                                TDev.Util.assert(v != null);
                                args[0].enumVal = v;
                            }
                        });
                    }
                    var shm = a.getShimName();
                    var hasret = !!aa.getOutParameters()[0];
                    if (shm == "TD_NOOP") {
                        TDev.Util.assert(!hasret);
                        return;
                    }
                    if (/^micro_bit::(createImage|createReadOnlyImage|showAnimation|showLeds|plotLeds)$/.test(shm)) {
                        TDev.Util.assert(args[0].getLiteral() != null);
                        this.emitImageLiteral(args[0].getLiteral());
                        args.shift();
                        args.forEach(function (a) { return _this.dispatch(a); });
                        args = [AST.mkLit(0)].concat(args);
                    }
                    else {
                        args.forEach(function (a) { return _this.dispatch(a); });
                    }
                    if (shm == "TD_ID") {
                        TDev.Util.assert(args.length == 1);
                        return;
                    }
                    if (shm != null) {
                        var mask = this.getMask(args);
                        var msg = "{shim:" + shm + "} from " + a.getName();
                        if (!shm)
                            userError("called " + msg + " (with empty {shim:}");
                        var inf = lookupFunc(shm);
                        if (a._compilerInlineBody) {
                            TDev.Util.assert(!inf);
                            funcInfo[shm] = {
                                name: shm,
                                type: hasret ? "F" : "P",
                                args: a.getInParameters().length,
                                idx: 0,
                                value: 0
                            };
                            try {
                                this.proc.emitCall(shm, mask);
                            }
                            finally {
                                delete funcInfo[shm];
                            }
                        }
                        else {
                            if (!inf)
                                userError("shim not found: " + msg);
                            if (!hasret) {
                                if (inf.type != "P")
                                    userError("expecting procedure for " + msg);
                            }
                            else {
                                if (inf.type != "F")
                                    userError("expecting function for " + msg);
                            }
                            if (args.length != inf.args)
                                userError("argument number mismatch: " + args.length + " vs " + inf.args + " in " + msg);
                            this.proc.emitCall(shm, mask);
                        }
                    }
                    else {
                        this.proc.emit("bl " + this.procIndex(a).label);
                        if (args.length > 0) {
                            var len = args.length;
                            TDev.Util.assert(0 <= len && len < 127);
                            this.proc.emit("add sp, #4*" + len);
                        }
                        if (hasret)
                            this.proc.emit("push {r0}");
                    }
                };
                Compiler.prototype.emitLazyOp = function (op, arg0, arg1) {
                    this.dispatch(arg0);
                    var lblEnd = this.proc.mkLabel("lazy");
                    if (op == "and") {
                        this.proc.emitJmp(lblEnd, "JMPZ");
                    }
                    else if (op == "or") {
                        this.proc.emitJmp(lblEnd, "JMPNZ");
                    }
                    else {
                        TDev.Util.die();
                    }
                    this.dispatch(arg1);
                    this.proc.emit("pop {r0}");
                    this.proc.emitLbl(lblEnd);
                    this.proc.emit("push {r0}");
                };
                Compiler.prototype.visitCall = function (e) {
                    var _this = this;
                    var p = e.getCalledProperty();
                    if (p == AST.api.core.AssignmentProp) {
                        this.handleAssignment(e);
                        return;
                    }
                    var emitCall = function (name, args) {
                        args.forEach(function (a) { return _this.dispatch(a); });
                        _this.proc.emitCall(name, _this.getMask(args));
                    };
                    var pkn = p.parentKind.getRoot().getName();
                    if (e.args.length == 1 && p.getName() == "is invalid") {
                        this.dispatch(e.args[0]);
                        this.proc.emitCall("bitvm::is_invalid", this.getMask(e.args));
                    }
                    else if (e.referencedData()) {
                        this.globalIndex(e.referencedData()).emitLoad(this.proc);
                    }
                    else if (e.referencedLibrary()) {
                        this.emitInt(0);
                    }
                    else if (e.calledAction() || e.calledExtensionAction()) {
                        this.handleActionCall(e);
                    }
                    else if (e.args[0] && e.args[0].referencedRecord()) {
                        var rrec = e.args[0].referencedRecord();
                        if (p.getName() == "create") {
                            this.emitInt(rrec._compilerInfo.refsize);
                            this.emitInt(rrec._compilerInfo.size);
                            this.proc.emitCall("record::mk", 0);
                        }
                        else if (p.getName() == "invalid") {
                            this.emitInt(0);
                        }
                        else {
                            TDev.Util.oops("unhandled record operation: " + p.getName());
                        }
                    }
                    else if (e.referencedRecordField()) {
                        this.dispatch(e.args[0]);
                        this.emitInt(this.fieldIndex(e.referencedRecordField()));
                        this.proc.emitCall("bitvm::ldfld" + (isRefKind(e.getKind()) ? "Ref" : ""), 0);
                    }
                    else if (p.parentKind instanceof AST.RecordEntryKind) {
                        if (p.getName() == "equals") {
                            emitCall("number::eq", e.args);
                        }
                        else {
                            TDev.Util.oops("unhandled entry record operation: " + p.getName());
                        }
                    }
                    else if (pkn == "Invalid") {
                        this.emitInt(0);
                    }
                    else if ((e.getKind().getRoot() == AST.api.core.Collection && e.args[0].getCalledProperty() && e.args[0].getCalledProperty().getName() == "Collection of")) {
                        var argK = e.getKind().getParameter(0);
                        if (argK == AST.api.core.String)
                            this.proc.emitInt(3);
                        else if (isRefKind(argK))
                            this.proc.emitInt(1);
                        else
                            this.proc.emitInt(0);
                        this.proc.emitCall("collection::mk", 0);
                    }
                    else if (p == AST.api.core.StringConcatProp) {
                        this.emitAsString(e.args[0]);
                        this.emitAsString(e.args[1]);
                        this.proc.emitCall("string::concat_op", 3);
                    }
                    else if (pkn == "Boolean" && /^(and|or)$/.test(p.getName())) {
                        TDev.Util.assert(e.args.length == 2);
                        this.emitLazyOp(p.getName(), e.args[0], e.args[1]);
                    }
                    else {
                        var args = e.args.slice(0);
                        if (args[0].getThing() instanceof AST.SingletonDef)
                            args.shift();
                        var nm = pkn.toLowerCase() + "::" + TDev.Embedded.Helpers.mangle(p.getName());
                        var inf = lookupFunc(nm);
                        if (!inf) {
                            nm = pkn.toLowerCase() + "::" + p.runtimeName();
                            inf = lookupFunc(nm);
                        }
                        if (nm == "contract::assert") {
                            TDev.Util.assert(typeof args[1].getLiteral() == "string");
                            this.dispatch(args[0]);
                            var lbl = this.binary.emitString(args[1].getLiteral());
                            this.proc.emitLdPtr(lbl, true);
                            this.proc.emitCall(nm, 0);
                            return;
                        }
                        if (inf) {
                            if (e.getKind() == AST.api.core.Nothing) {
                                TDev.Util.assert(inf.type == "P", "expecting procedure for " + nm);
                            }
                            else {
                                TDev.Util.assert(inf.type == "F", "expecting function for " + nm);
                            }
                            TDev.Util.assert(args.length == inf.args, "argument number mismatch: " + args.length + " vs " + inf.args);
                            emitCall(nm, args);
                        }
                        else {
                            TDev.Util.oops("function not found: " + nm);
                        }
                    }
                };
                Compiler.prototype.visitExprHolder = function (eh) {
                    var _this = this;
                    var ai = eh.assignmentInfo();
                    if (ai && ai.definedVars)
                        ai.definedVars.forEach(function (l) {
                            if (l.isByRef()) {
                                var li = _this.localIndex(l);
                                li.emitClrIfRef(_this.proc);
                                _this.proc.emitCallRaw("bitvm::mkloc" + li.refSuff());
                                li.emitStoreCore(_this.proc);
                            }
                        });
                    if (eh.isPlaceholder())
                        this.proc.emit("nop");
                    else
                        this.dispatch(eh.parsed);
                };
                Compiler.prototype.emitInt = function (v, keepInR0) {
                    if (keepInR0 === void 0) { keepInR0 = false; }
                    this.proc.emitInt(v, keepInR0);
                };
                Compiler.prototype.visitLiteral = function (l) {
                    if (l.data === undefined)
                        return;
                    if (typeof l.data == "number") {
                        this.emitInt(l.data);
                    }
                    else if (typeof l.data == "string") {
                        if (l.enumVal != null) {
                            if (/^-?\d+$/.test(l.enumVal)) {
                                this.emitInt(parseInt(l.enumVal));
                            }
                            else {
                                var inf = lookupFunc(l.enumVal);
                                if (!inf)
                                    userError(TDev.lf("unhandled enum value: {0}", l.enumVal));
                                if (inf.type == "E")
                                    this.proc.emitInt(inf.value);
                                else if (inf.type == "F" && inf.args == 0)
                                    this.proc.emitCall(l.enumVal, 0);
                                else
                                    userError(TDev.lf("not valid enum: {0}; is it procedure name?", l.enumVal));
                            }
                        }
                        else if (l.data == "") {
                            this.proc.emitCall("string::mkEmpty", 0);
                        }
                        else {
                            var lbl = this.binary.emitString(l.data);
                            this.proc.emitLdPtr(lbl + "meta", false);
                            this.proc.emitCallRaw("bitvm::stringData");
                            this.proc.emit("push {r0}");
                        }
                    }
                    else if (typeof l.data == "boolean") {
                        this.emitInt(l.data ? 1 : 0);
                    }
                    else {
                        TDev.Util.oops("invalid literal emit " + l.data);
                    }
                };
                Compiler.prototype.emitInlineAction = function (inl) {
                    var _this = this;
                    var inlproc = new Procedure();
                    inlproc.argsInR5 = true;
                    this.binary.addProc(inlproc);
                    var isRef = function (l) { return l.isByRef() || isRefKind(l.getKind()); };
                    var refs = inl.closure.filter(function (l) { return isRef(l); });
                    var flats = inl.closure.filter(function (l) { return !isRef(l); });
                    var caps = refs.concat(flats);
                    this.emitInt(refs.length);
                    this.emitInt(caps.length);
                    this.proc.emitLdPtr(inlproc.label, true);
                    this.proc.emitCall("action::mk", 0);
                    caps.forEach(function (l, i) {
                        _this.emitInt(i);
                        _this.localIndex(l).emitLoad(_this.proc, true);
                        _this.proc.emitCall("bitvm::stclo", 0);
                    });
                    this.finals.push(function () {
                        _this.proc = inlproc;
                        _this.proc.args = caps.map(function (p, i) {
                            var l = new Location(i, p);
                            l.isarg = true;
                            return l;
                        });
                        inl.allLocals.forEach(function (l) {
                            l._lastWriteLocation = null;
                            if (caps.indexOf(l) == -1)
                                _this.proc.mkLocal(l);
                        });
                        _this.proc.emit(".section code");
                        _this.proc.emit(".balign 4");
                        _this.proc.emitLbl(_this.proc.label);
                        _this.proc.emit(".short 0xffff, 0x0000   ; action literal");
                        _this.proc.emit("@stackmark inlfunc");
                        _this.proc.emit("push {r5, lr}");
                        _this.proc.emit("mov r5, r1");
                        _this.proc.pushLocals();
                        inl.inParameters.forEach(function (loc, i) {
                            TDev.Util.assert(i < 2);
                            var l = _this.localIndex(loc, true);
                            _this.proc.emit("push {r" + (i + 2) + "}");
                            l.emitStore(_this.proc);
                        });
                        var ret = _this.proc.mkLabel("inlret");
                        inl._compilerBreakLabel = ret;
                        _this.dispatch(inl.body);
                        _this.proc.emitLbl(ret);
                        _this.proc.emitClrs(null, false);
                        _this.proc.popLocals();
                        _this.proc.emit("pop {r5, pc}");
                        _this.proc.emit("@stackempty inlfunc");
                    });
                };
                Compiler.prototype.visitThingRef = function (t) {
                    var d = t.def;
                    if (d instanceof AST.LocalDef) {
                        if (d._lastWriteLocation instanceof AST.InlineAction) {
                            this.emitInlineAction(d._lastWriteLocation);
                        }
                        else {
                            this.localIndex(d).emitLoadByRef(this.proc);
                        }
                    }
                    else if (d instanceof AST.SingletonDef) {
                        this.emitInt(0);
                    }
                    else {
                        TDev.Util.oops("invalid thing: " + d ? d.nodeType() : "(null)");
                    }
                };
                Compiler.prototype.visitAnyIf = function (i) {
                    var _this = this;
                    if (i.isTopCommentedOut())
                        return;
                    if (!i.branches)
                        return;
                    var afterall = this.proc.mkLabel("afterif");
                    i.branches.forEach(function (b, k) {
                        if (!b.condition) {
                            _this.dispatch(b.body);
                        }
                        else {
                            _this.dispatch(b.condition);
                            var after = _this.proc.mkLabel("else");
                            _this.proc.emitJmp(after, "JMPZ");
                            _this.dispatch(b.body);
                            _this.proc.emitJmp(afterall);
                            _this.proc.emitLbl(after);
                        }
                    });
                    this.proc.emitLbl(afterall);
                };
                Compiler.prototype.globalIndex = function (l) {
                    return this.binary.globals.filter(function (n) { return n.def == l; })[0];
                };
                Compiler.prototype.fieldIndex = function (l) {
                    TDev.Util.assert(l._compilerInfo.idx != null);
                    return l._compilerInfo.idx;
                };
                Compiler.prototype.procIndex = function (a) {
                    return this.binary.procs.filter(function (n) { return n.action == a; })[0];
                };
                Compiler.prototype.localIndex = function (l, noargs) {
                    if (noargs === void 0) { noargs = false; }
                    return this.proc.locals.filter(function (n) { return n.def == l; })[0] || (noargs ? null : this.proc.args.filter(function (n) { return n.def == l; })[0]);
                };
                Compiler.prototype.visitFor = function (f) {
                    var upper = this.proc.mkLocal();
                    this.dispatch(f.upperBound);
                    upper.emitStore(this.proc);
                    var idx = this.localIndex(f.boundLocal);
                    this.proc.emitInt(0);
                    idx.emitStore(this.proc);
                    var top = this.proc.mkLabel("fortop");
                    this.proc.emitLbl(top);
                    var brk = this.proc.mkLabel("forbrk");
                    idx.emitLoad(this.proc);
                    upper.emitLoad(this.proc);
                    this.proc.emitCall("number::lt", 0);
                    this.proc.emitJmp(brk, "JMPZ");
                    var cont = this.proc.mkLabel("forcnt");
                    f._compilerBreakLabel = brk;
                    f._compilerContinueLabel = cont;
                    this.dispatch(f.body);
                    this.proc.emitLbl(cont);
                    idx.emitLoad(this.proc);
                    this.emitInt(1);
                    this.proc.emitCall("number::add", 0);
                    idx.emitStore(this.proc);
                    this.proc.stackEmpty();
                    this.proc.emitJmp(top);
                    this.proc.emitLbl(brk);
                };
                Compiler.prototype.visitForeach = function (f) {
                    TDev.Util.oops("foreach emit");
                };
                Compiler.prototype.visitWhile = function (n) {
                    var top = this.proc.mkLabel("whiletop");
                    this.proc.emitLbl(top);
                    var brk = this.proc.mkLabel("whilebrk");
                    this.dispatch(n.condition);
                    this.proc.emitJmp(brk, "JMPZ");
                    n._compilerBreakLabel = brk;
                    n._compilerContinueLabel = top;
                    this.dispatch(n.body);
                    this.proc.emitJmp(top);
                    this.proc.emitLbl(brk);
                };
                Compiler.prototype.visitInlineActions = function (i) {
                    i.normalActions().forEach(function (a) { return a.name._lastWriteLocation = a; });
                    this.visitExprStmt(i);
                };
                Compiler.prototype.visitExprStmt = function (es) {
                    if (es.isPlaceholder())
                        return;
                    this.dispatch(es.expr);
                    var k = es.expr.parsed.getKind();
                    if (k == AST.api.core.Nothing) {
                        this.proc.stackEmpty();
                    }
                    else {
                        if (isRefKind(k))
                            this.proc.emitCall("bitvm::decr", 0);
                        else
                            this.proc.emit("pop {r0}");
                        this.proc.stackEmpty();
                    }
                };
                Compiler.prototype.visitCodeBlock = function (b) {
                    var _this = this;
                    this.proc.stackEmpty();
                    b.stmts.forEach(function (s) {
                        _this.numStmts++;
                        _this.dispatch(s);
                        _this.proc.stackEmpty();
                    });
                };
                Compiler.prototype.visitAction = function (a) {
                    this.numStmts++;
                    this.proc = this.procIndex(a);
                    if (a.getShimName() != null) {
                        var body = AST.getEmbeddedLangaugeToken(a._compilerInlineBody);
                        TDev.Util.assert(body != null);
                        TDev.Util.assert(body.getStringLiteral() != null);
                        this.proc.emit(body.getStringLiteral());
                        this.proc.emit("@stackempty func");
                        this.proc.emit("@scope");
                        return;
                    }
                    var ret = this.proc.mkLabel("actret");
                    a._compilerBreakLabel = ret;
                    this.dispatch(a.body);
                    this.proc.emitLbl(ret);
                    this.proc.stackEmpty();
                    var retl = a.getOutParameters()[0];
                    this.proc.emitClrs(retl ? retl.local : null, true);
                    if (retl) {
                        var li = this.localIndex(retl.local);
                        TDev.Util.assert(!li.isByRefLocal());
                        li.emitLoadCore(this.proc);
                    }
                    this.proc.popLocals();
                    this.proc.emit("pop {pc}");
                    this.proc.emit("@stackempty func");
                };
                Compiler.prototype.visitGlobalDef = function (g) {
                    var x = new Location(this.binary.globals.length, g);
                    this.binary.globals.push(x);
                };
                Compiler.prototype.visitLibraryRef = function (l) {
                };
                Compiler.prototype.visitRecordDef = function (r) {
                    TDev.Util.assert(r.recordType == 1 /* Object */);
                    var refs = r.getFields().filter(function (f) { return isRefKind(f.dataKind); });
                    var flats = r.getFields().filter(function (f) { return !isRefKind(f.dataKind); });
                    r._compilerInfo = { size: refs.length + flats.length, refsize: refs.length };
                    refs.concat(flats).forEach(function (f, i) {
                        f._compilerInfo = { idx: i };
                    });
                };
                Compiler.prototype.prepAction = function (a) {
                    var _this = this;
                    var p = new Procedure();
                    this.proc = p;
                    p.action = a;
                    this.binary.addProc(p);
                    var shimname = a.getShimName();
                    if (shimname != null) {
                        TDev.Util.assert(!!a._compilerInlineBody);
                        this.proc.label = shimname;
                        this.proc.emit(".section code");
                        this.proc.emit(".balign 4");
                        this.proc.emitLbl(this.proc.label);
                        this.proc.emit("@scope user" + p.seqNo);
                        this.proc.emit("@stackmark func");
                        return;
                    }
                    var inparms = a.getInParameters().map(function (p) { return p.local; });
                    this.proc.args = inparms.map(function (p, i) {
                        var l = new Location(i, p);
                        l.isarg = true;
                        return l;
                    });
                    this.proc.emit(".section code");
                    this.proc.emitLbl(this.proc.label);
                    this.proc.emit("@stackmark func");
                    this.proc.emit("@stackmark args");
                    this.proc.emit("push {lr}");
                    this.proc.pushLocals();
                    var copyArgIntoLocal = function (loc) {
                        if (!loc)
                            return;
                        var idx = inparms.indexOf(loc);
                        if (idx >= 0) {
                            var curr = _this.localIndex(loc, true);
                            if (!curr) {
                                var l = _this.proc.mkLocal(loc);
                                if (loc.isByRef()) {
                                    _this.proc.emitCallRaw("bitvm::mkloc" + l.refSuff());
                                    l.emitStoreCore(_this.proc);
                                }
                                _this.proc.args[idx].emitLoadLocal(_this.proc);
                                _this.proc.emit("push {r0}");
                                l.emitStoreByRef(_this.proc);
                            }
                        }
                    };
                    AST.visitStmts(a.body, function (s) {
                        if (s instanceof AST.ExprStmt) {
                            var ai = s.expr.assignmentInfo();
                            if (ai) {
                                ai.targets.forEach(function (t) { return copyArgIntoLocal(t.referencedLocal()); });
                            }
                        }
                    });
                    a.allLocals.forEach(function (l) {
                        l._lastWriteLocation = null;
                        if (inparms.indexOf(l) == -1)
                            _this.proc.mkLocal(l);
                    });
                };
                Compiler.prototype.dump = function (lst) {
                    var _this = this;
                    lst.forEach(function (t) {
                        if (_this.shouldCompile(t))
                            _this.dispatch(t);
                    });
                };
                Compiler.prototype.prepApp = function (a) {
                    var _this = this;
                    this.actions(a).forEach(function (a) {
                        if (!_this.shouldCompile(a))
                            return;
                        _this.prepAction(a);
                    });
                    this.dump(a.libraries());
                    this.dump(a.variables());
                    this.dump(a.resources());
                    this.dump(a.records());
                };
                Compiler.prototype.actions = function (a) {
                    var res = a.allActions().filter(function (a) { return !a.isActionTypeDef(); });
                    AST.App.orderThings(res);
                    return res;
                };
                Compiler.prototype.compileApp = function (a) {
                    this.dump(this.actions(a));
                };
                Compiler.prototype.visitApp = function (a) {
                    TDev.Util.oops("");
                };
                Compiler.prototype.visitComment = function (c) {
                };
                Compiler.prototype.visitStmt = function (s) {
                    TDev.Util.oops("unhandled stmt: " + s.nodeType());
                };
                return Compiler;
            })(AST.NodeVisitor);
            Bytecode.Compiler = Compiler;
            function lintThumb(act, asm) {
                setup();
                var shimname = act.getShimName();
                var b = new AST.Thumb.Binary();
                if (/{shim:/.test(act.getDescription()))
                    b.pushError(TDev.lf("use {asm:{0}} with app->thumb, not {shim:{0}}", shimname));
                if (lookupFunc(shimname))
                    b.pushError(TDev.lf("{asm:{0}} already defined in runtime", shimname));
                if (!/^\w+$/.test(shimname))
                    b.pushError(TDev.lf("invalid characters in shim name: {asm:{0}}", shimname));
                if (act.getInParameters().length > 4)
                    b.pushError(TDev.lf("inline shims support only up to 4 arguments"));
                if (b.errors.length > 0)
                    return b.errors;
                var code = ".section code\n" + "@stackmark func\n" + shimname + ":\n" + "@scope user\n" + asm + "\n" + "@stackempty func\n" + "@scope\n";
                b.lookupExternalLabel = lookupFunctionAddr;
                b.throwOnError = false;
                b.inlineMode = true;
                b.emit(code);
                return b.errors;
            }
            AST.TypeChecker.lintThumb = lintThumb;
            function asmline(s) {
                if (!/(^\s)|(:$)/.test(s))
                    s = "    " + s;
                return s + "\n";
            }
            function hexTemplateHash() {
                var sha = currentSetup ? currentSetup.slice(0, 16) : "";
                while (sha.length < 16)
                    sha += "0";
                return sha.toUpperCase();
            }
            function emptyExtInfo() {
                return {
                    enums: {},
                    functions: [],
                    errors: "",
                    sha: "",
                    compileData: "",
                    hasExtension: false,
                };
            }
            function setup() {
                if (currentSetup == null)
                    setupFor(emptyExtInfo(), null);
            }
            function parseExpr(e) {
                e = e.trim();
                e = e.replace(/^\(/, "");
                e = e.replace(/\)$/, "");
                e = e.trim();
                if (/^-/.test(e) && parseExpr(e.slice(1)) != null)
                    return -parseExpr(e.slice(1));
                if (/^0x[0-9a-f]+$/i.exec(e))
                    return parseInt(e.slice(2), 16);
                if (/^0b[01]+$/i.exec(e))
                    return parseInt(e.slice(2), 2);
                if (/^0\d+$/i.exec(e))
                    return parseInt(e, 8);
                if (/^\d+$/i.exec(e))
                    return parseInt(e, 10);
                return null;
            }
            function getExtensionInfo(app) {
                var res = emptyExtInfo();
                var fileRepl = {};
                var pointersInc = "";
                var includesInc = "";
                var totalConfig = {
                    dependencies: {},
                    config: {},
                };
                var thisErrors = "";
                var err = function (s) { return thisErrors += "   " + s + "\n"; };
                var cfginc = "";
                function parseCpp(src) {
                    res.hasExtension = true;
                    var currNs = "";
                    src.split(/\r?\n/).forEach(function (ln) {
                        var m = /^\s*namespace\s+(\w+)/.exec(ln);
                        if (m) {
                            if (currNs)
                                err("more than one namespace declaration not supported");
                            currNs = m[1];
                            return;
                        }
                        m = /^\s*GLUE\s+(\w+)([\*\&]*\s+[\*\&]*)(\w+)\s*\(([^\(\)]*)\)\s*(;\s*$|\{|$)/.exec(ln);
                        if (m) {
                            if (!currNs)
                                err("missing namespace declaration before GLUE");
                            var retTp = (m[1] + m[2]).replace(/\s+/g, "");
                            var funName = m[3];
                            var args = m[4];
                            var numArgs = 0;
                            if (args.trim())
                                numArgs = args.replace(/[^,]/g, "").length + 1;
                            var fi = {
                                name: currNs + "::" + funName,
                                type: retTp == "void" ? "P" : "F",
                                args: numArgs,
                                value: null
                            };
                            res.functions.push(fi);
                            pointersInc += "(uint32_t)(void*)::" + fi.name + ",\n";
                            return;
                        }
                        if (/^\s*GLUE\s+/.test(ln)) {
                            err("invalid GLUE line: " + ln);
                            return;
                        }
                        ln = ln.replace(/\/\/.*/, "");
                        var isEnum = false;
                        m = /^\s*#define\s+(\w+)\s+(.*)/.exec(ln);
                        if (!m) {
                            m = /^\s*(\w+)\s*=\s*(.*)/.exec(ln);
                            isEnum = true;
                        }
                        if (m) {
                            var num = m[2];
                            num = num.replace(/\/\/.*/, "");
                            num = num.replace(/\/\*.*/, "");
                            num = num.trim();
                            if (isEnum)
                                num = num.replace(/,$/, "");
                            var val = parseExpr(num);
                            var nm = m[1];
                            if (isEnum)
                                nm = currNs + "::" + nm;
                            if (val != null) {
                                res.enums[nm] = val;
                                return;
                            }
                        }
                    });
                    if (!currNs)
                        err("missing namespace declaration");
                    includesInc += "#include \"" + currNs + ".cpp\"\n";
                    fileRepl["/generated/" + currNs + ".cpp"] = src;
                }
                function parseJson(src) {
                    var parsed = TDev.RT.JsonParser.parse(src, err);
                    if (!parsed)
                        return;
                    var json = parsed.value();
                    if (!json)
                        return;
                    res.hasExtension = true;
                    if (json.dependencies)
                        TDev.Util.jsonCopyFrom(totalConfig.dependencies, json.dependencies);
                    if (json.config)
                        Object.keys(json.config).forEach(function (k) {
                            if (!/^\w+$/.test(k))
                                err(TDev.lf("invalid config variable: {0}", k));
                            cfginc += "#undef " + k + "\n";
                            if (!/^\w+$/.test(json.config[k]))
                                err(TDev.lf("invalid config value: {0}: {1}", k, json.config[k]));
                            cfginc += "#define " + k + " " + json.config[k] + "\n";
                        });
                }
                function isUsed(a) {
                    if (a.visitorState)
                        return true;
                    var l = a;
                    if (l.template && l.template.visitorState)
                        return true;
                    return false;
                }
                if (app) {
                    computeReachableNodes(app, true);
                    app.librariesAndThis().forEach(function (l) {
                        if (!l.isThis() && !l.getPublicActions().some(isUsed)) {
                            TDev.Util.log("skip library " + l.getName());
                            return;
                        }
                        thisErrors = "";
                        l.resolved.resources().forEach(function (r) {
                            if (r.getName() != "glue.cpp" && r.getName() != "glue.json")
                                return;
                            var src = r.stringResourceValue();
                            if (src == null) {
                                err(TDev.lf("'{0}' isn't a string resource", r.getName()));
                                return;
                            }
                            if (r.getName() == "glue.cpp")
                                parseCpp(src);
                            else
                                parseJson(src);
                        });
                        if (thisErrors) {
                            res.errors += TDev.lf("Library {0}:\n", l.getName()) + thisErrors;
                        }
                    });
                }
                if (res.errors)
                    return res;
                if (cfginc)
                    fileRepl["/generated/extconfig.h"] = cfginc;
                fileRepl["/generated/extpointers.inc"] = pointersInc;
                fileRepl["/generated/extensions.inc"] = includesInc;
                var creq = {
                    config: "ws",
                    tag: TDev.Cloud.config.microbitGitTag,
                    replaceFiles: fileRepl,
                    dependencies: totalConfig.dependencies,
                };
                var reqData = TDev.Util.toUTF8(JSON.stringify(creq));
                res.sha = TDev.Random.sha256buffer(TDev.Util.stringToUint8Array(reqData));
                res.compileData = TDev.Util.base64Encode(reqData);
                return res;
            }
            Bytecode.getExtensionInfo = getExtensionInfo;
        })(Bytecode = AST.Bytecode || (AST.Bytecode = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var AST;
    (function (AST) {
        var Thumb;
        (function (Thumb) {
            var badNameError = emitErr("opcode name doesn't match", "<name>");
            var Instruction = (function () {
                function Instruction(format, opcode, mask) {
                    this.opcode = opcode;
                    this.mask = mask;
                    TDev.Util.assert((opcode & mask) == opcode);
                    this.code = format.replace(/\s+/g, " ");
                    this.friendlyFmt = format.replace(/\$\w+/g, function (m) {
                        if (encoders[m])
                            return encoders[m].pretty;
                        return m;
                    });
                    var words = tokenize(format);
                    this.name = words[0];
                    this.args = words.slice(1);
                }
                Instruction.prototype.emit = function (ln) {
                    var tokens = ln.words;
                    if (tokens[0] != this.name)
                        return badNameError;
                    var r = this.opcode;
                    var j = 1;
                    var stack = 0;
                    var numArgs = [];
                    for (var i = 0; i < this.args.length; ++i) {
                        var formal = this.args[i];
                        var actual = tokens[j++];
                        if (/^\$/.test(formal)) {
                            var enc = encoders[formal];
                            var v = null;
                            if (enc.isRegister) {
                                v = registerNo(actual);
                                if (v == null)
                                    return emitErr("expecting register name", actual);
                            }
                            else if (enc.isImmediate) {
                                actual = actual.replace(/^#/, "");
                                v = ln.bin.parseOneInt(actual);
                                if (v == null) {
                                    return emitErr("expecting number", actual);
                                }
                                else {
                                    if (this.opcode == 0xb000)
                                        stack = -(v / 4);
                                    else if (this.opcode == 0xb080)
                                        stack = (v / 4);
                                }
                            }
                            else if (enc.isRegList) {
                                if (actual != "{")
                                    return emitErr("expecting {", actual);
                                v = 0;
                                while (tokens[j] != "}") {
                                    actual = tokens[j++];
                                    if (!actual)
                                        return emitErr("expecting }", tokens[j - 2]);
                                    var no = registerNo(actual);
                                    if (no == null)
                                        return emitErr("expecting register name", actual);
                                    if (v & (1 << no))
                                        return emitErr("duplicate register name", actual);
                                    v |= (1 << no);
                                    if (this.opcode == 0xb400)
                                        stack++;
                                    else if (this.opcode == 0xbc00)
                                        stack--;
                                    if (tokens[j] == ",")
                                        j++;
                                }
                                actual = tokens[j++];
                            }
                            else if (enc.isLabel) {
                                actual = actual.replace(/^#/, "");
                                if (/^[+-]?\d+$/.test(actual)) {
                                    v = parseInt(actual, 10);
                                }
                                else {
                                    v = ln.bin.getRelativeLabel(actual);
                                    if (v == null) {
                                        if (ln.bin.finalEmit)
                                            return emitErr("unknown label", actual);
                                        else
                                            v = 8;
                                    }
                                }
                            }
                            else {
                                TDev.Util.die();
                            }
                            if (v == null)
                                return emitErr("didn't understand it", actual);
                            if (this.name == "bl" || this.name == "bb") {
                                if (tokens[j])
                                    return emitErr("trailing tokens", tokens[j]);
                                return this.emitBl(v, actual);
                            }
                            numArgs.push(v);
                            v = enc.encode(v);
                            if (v == null)
                                return emitErr("argument out of range or mis-aligned", actual);
                            TDev.Util.assert((r & v) == 0);
                            r |= v;
                        }
                        else if (formal == actual) {
                        }
                        else {
                            return emitErr("expecting " + formal, actual);
                        }
                    }
                    if (tokens[j])
                        return emitErr("trailing tokens", tokens[j]);
                    return {
                        stack: stack,
                        opcode: r,
                        numArgs: numArgs,
                    };
                };
                Instruction.prototype.emitBl = function (v, actual) {
                    if (v % 2)
                        return emitErr("uneven BL?", actual);
                    var off = v / 2;
                    TDev.Util.assert(off != null);
                    if ((off | 0) != off || !(-128 * 1024 <= off && off <= 128 * 1024))
                        return emitErr("jump out of range", actual);
                    var imm11 = off & 0x7ff;
                    var imm10 = (off >> 11) & 0x3ff;
                    return {
                        opcode: (off & 0xf0000000) ? (0xf400 | imm10) : (0xf000 | imm10),
                        opcode2: (0xf800 | imm11),
                        stack: 0,
                        numArgs: [v],
                    };
                };
                Instruction.prototype.toString = function () {
                    return this.friendlyFmt;
                };
                return Instruction;
            })();
            var Line = (function () {
                function Line(bin, text) {
                    this.bin = bin;
                    this.text = text;
                }
                Line.prototype.getOpExt = function () {
                    return this.instruction ? this.instruction.code : "";
                };
                Line.prototype.getOp = function () {
                    return this.instruction ? this.instruction.name : "";
                };
                Line.prototype.singleReg = function () {
                    TDev.Util.assert(this.getOp() == "push" || this.getOp() == "pop");
                    var k = 0;
                    var ret = -1;
                    var v = this.numArgs[0];
                    while (v > 0) {
                        if (v & 1) {
                            if (ret == -1)
                                ret = k;
                            else
                                ret = -2;
                        }
                        v >>= 1;
                        k++;
                    }
                    if (ret >= 0)
                        return ret;
                    else
                        return -1;
                };
                Line.prototype.preservesReg = function (n) {
                    if (this.getOpExt() == "movs $r5, $i0" && this.numArgs[0] != n)
                        return true;
                    return false;
                };
                Line.prototype.clobbersReg = function (n) {
                    if (this.getOp() == "pop" && this.numArgs[0] & (1 << n))
                        return true;
                    return false;
                };
                Line.prototype.update = function (s) {
                    this.bin.peepOps++;
                    s = s.replace(/^\s*/, "");
                    if (!s)
                        this.bin.peepDel++;
                    if (s)
                        s += "      ";
                    s = "    " + s;
                    this.text = s + "; WAS: " + this.text.trim();
                    this.instruction = null;
                    this.numArgs = null;
                    this.words = tokenize(s) || [];
                    if (this.words.length == 0)
                        this.type = "empty";
                };
                return Line;
            })();
            var Binary = (function () {
                function Binary() {
                    this.checkStack = true;
                    this.inlineMode = false;
                    this.currLineNo = 0;
                    this.scope = "";
                    this.errors = [];
                    this.labels = {};
                    this.stackpointers = {};
                    this.stack = 0;
                    this.peepOps = 0;
                    this.peepDel = 0;
                    this.stats = "";
                    this.throwOnError = false;
                    this.disablePeepHole = false;
                    this.currLine = new Line(this, "<start>");
                    this.currLine.lineNo = 0;
                }
                Binary.prototype.emitShort = function (op) {
                    TDev.Util.assert(0 <= op && op <= 0xffff);
                    this.buf.push(op);
                };
                Binary.prototype.location = function () {
                    return this.buf.length * 2;
                };
                Binary.prototype.parseOneInt = function (s) {
                    if (!s)
                        return null;
                    var mul = 1;
                    while (m = /^([^\*]*)\*(.*)$/.exec(s)) {
                        var tmp = this.parseOneInt(m[1]);
                        if (tmp == null)
                            return null;
                        mul *= tmp;
                        s = m[2];
                    }
                    if (/^-/.test(s)) {
                        mul *= -1;
                        s = s.slice(1);
                    }
                    var v = null;
                    var m = /^0x([a-f0-9]+)$/i.exec(s);
                    if (m)
                        v = parseInt(m[1], 16);
                    m = /^0b([01]+)$/i.exec(s);
                    if (m)
                        v = parseInt(m[1], 2);
                    m = /^(\d+)$/i.exec(s);
                    if (m)
                        v = parseInt(m[1], 10);
                    m = /^(\w+)@(-?\d+)$/.exec(s);
                    if (m) {
                        if (mul != 1)
                            this.directiveError(TDev.lf("multiplication not supported with saved stacks"));
                        if (this.stackpointers.hasOwnProperty(m[1]))
                            v = 4 * (this.stack - this.stackpointers[m[1]] + parseInt(m[2]));
                        else
                            this.directiveError(TDev.lf("saved stack not found"));
                    }
                    m = /^(.*)@(hi|lo)$/.exec(s);
                    if (m && this.looksLikeLabel(m[1])) {
                        v = this.lookupLabel(m[1], true);
                        if (v != null) {
                            v >>= 1;
                            if (0 <= v && v <= 0xffff) {
                                if (m[2] == "hi")
                                    v = (v >> 8) & 0xff;
                                else if (m[2] == "lo")
                                    v = v & 0xff;
                                else
                                    TDev.Util.die();
                            }
                            else {
                                this.directiveError(TDev.lf("@hi/lo out of range"));
                                v = null;
                            }
                        }
                    }
                    if (v == null && this.looksLikeLabel(s)) {
                        v = this.lookupLabel(s, true);
                        v += this.baseOffset;
                    }
                    if (v == null || isNaN(v))
                        return null;
                    return v * mul;
                };
                Binary.prototype.looksLikeLabel = function (name) {
                    if (/^(r\d|pc|sp|lr)$/i.test(name))
                        return false;
                    return /^[\.a-zA-Z_][\.\w+]*$/.test(name);
                };
                Binary.prototype.scopedName = function (name) {
                    if (name[0] == "." && this.scope)
                        return this.scope + "$" + name;
                    else
                        return name;
                };
                Binary.prototype.lookupLabel = function (name, direct) {
                    if (direct === void 0) { direct = false; }
                    var v = null;
                    var scoped = this.scopedName(name);
                    if (this.labels.hasOwnProperty(scoped))
                        v = this.labels[scoped];
                    else if (this.lookupExternalLabel)
                        v = this.lookupExternalLabel(name);
                    if (v == null && direct) {
                        if (this.finalEmit)
                            this.directiveError(TDev.lf("unknown label: {0}", name));
                        else
                            v = 42;
                    }
                    return v;
                };
                Binary.prototype.getRelativeLabel = function (s) {
                    var l = this.lookupLabel(s);
                    if (l == null)
                        return null;
                    return l - (this.location() + 4);
                };
                Binary.prototype.align = function (n) {
                    TDev.Util.assert(n == 2 || n == 4 || n == 8 || n == 16);
                    while (this.location() % n != 0)
                        this.emitShort(0);
                };
                Binary.prototype.pushError = function (msg, hints) {
                    if (hints === void 0) { hints = ""; }
                    var err = {
                        scope: this.scope,
                        message: TDev.lf("  -> Line {2} ('{1}'), error: {0}\n{3}", msg, this.currLine.text, this.currLine.lineNo, hints),
                        lineNo: this.currLine.lineNo,
                        line: this.currLine.text,
                        coremsg: msg,
                        hints: hints
                    };
                    this.errors.push(err);
                    if (this.throwOnError)
                        throw new Error(err.message);
                };
                Binary.prototype.directiveError = function (msg) {
                    this.pushError(msg);
                };
                Binary.prototype.emitString = function (l) {
                    function byteAt(s, i) {
                        return (s.charCodeAt(i) || 0) & 0xff;
                    }
                    var m = /^\s*([\w\.]+\s*:\s*)?.\w+\s+(".*")\s*$/.exec(l);
                    var s;
                    if (!m || null == (s = parseString(m[2]))) {
                        this.directiveError(TDev.lf("expecting string"));
                    }
                    else {
                        this.align(2);
                        for (var i = 0; i < s.length + 1; i += 2) {
                            this.emitShort((byteAt(s, i + 1) << 8) | byteAt(s, i));
                        }
                    }
                };
                Binary.prototype.parseNumber = function (words) {
                    var v = this.parseOneInt(words.shift());
                    if (v == null)
                        return null;
                    return v;
                };
                Binary.prototype.parseNumbers = function (words) {
                    words = words.slice(1);
                    var nums = [];
                    while (true) {
                        var n = this.parseNumber(words);
                        if (n == null) {
                            this.directiveError(TDev.lf("cannot parse number at '{0}'", words[0]));
                            break;
                        }
                        else
                            nums.push(n);
                        if (words[0] == ",") {
                            words.shift();
                            if (words[0] == null)
                                break;
                        }
                        else if (words[0] == null) {
                            break;
                        }
                        else {
                            this.directiveError(TDev.lf("expecting number, got '{0}'", words[0]));
                            break;
                        }
                    }
                    return nums;
                };
                Binary.prototype.emitSpace = function (words) {
                    var nums = this.parseNumbers(words);
                    if (nums.length == 1)
                        nums.push(0);
                    if (nums.length != 2)
                        this.directiveError(TDev.lf("expecting one or two numbers"));
                    else if (nums[0] % 2 != 0)
                        this.directiveError(TDev.lf("only even space supported"));
                    else {
                        var f = nums[1] & 0xff;
                        f = f | (f << 8);
                        for (var i = 0; i < nums[0]; i += 2)
                            this.emitShort(f);
                    }
                };
                Binary.prototype.emitBytes = function (words) {
                    var nums = this.parseNumbers(words);
                    if (nums.length % 2 != 0) {
                        this.directiveError(".bytes needs an even number of arguments");
                        nums.push(0);
                    }
                    for (var i = 0; i < nums.length; i += 2) {
                        var n0 = nums[i];
                        var n1 = nums[i + 1];
                        if (0 <= n0 && n1 <= 0xff && 0 <= n1 && n0 <= 0xff)
                            this.emitShort((n0 & 0xff) | ((n1 & 0xff) << 8));
                        else
                            this.directiveError(TDev.lf("expecting uint8"));
                    }
                };
                Binary.prototype.emitHex = function (words) {
                    var _this = this;
                    words.slice(1).forEach(function (w) {
                        if (w == ",")
                            return;
                        if (w.length % 4 != 0)
                            _this.directiveError(".hex needs an even number of bytes");
                        else if (!/^[a-f0-9]+$/i.test(w))
                            _this.directiveError(".hex needs a hex number");
                        else
                            for (var i = 0; i < w.length; i += 4) {
                                var n = parseInt(w.slice(i, i + 4), 16);
                                n = ((n & 0xff) << 8) | ((n >> 8) & 0xff);
                                _this.emitShort(n);
                            }
                    });
                };
                Binary.prototype.handleDirective = function (l) {
                    var _this = this;
                    var words = l.words;
                    var expectOne = function () {
                        if (words.length != 2)
                            _this.directiveError(TDev.lf("expecting one argument"));
                    };
                    var num0;
                    switch (words[0]) {
                        case ".ascii":
                        case ".asciz":
                        case ".string":
                            this.emitString(l.text);
                            break;
                        case ".align":
                            expectOne();
                            num0 = this.parseOneInt(words[1]);
                            if (num0 != null) {
                                if (num0 == 0)
                                    return;
                                if (num0 <= 4) {
                                    this.align(1 << num0);
                                }
                                else {
                                    this.directiveError(TDev.lf("expecting 1, 2, 3 or 4 (for 2, 4, 8, or 16 byte alignment)"));
                                }
                            }
                            else
                                this.directiveError(TDev.lf("expecting number"));
                            break;
                        case ".balign":
                            expectOne();
                            num0 = this.parseOneInt(words[1]);
                            if (num0 != null) {
                                if (num0 == 1)
                                    return;
                                if (num0 == 2 || num0 == 4 || num0 == 8 || num0 == 16) {
                                    this.align(num0);
                                }
                                else {
                                    this.directiveError(TDev.lf("expecting 2, 4, 8, or 16"));
                                }
                            }
                            else
                                this.directiveError(TDev.lf("expecting number"));
                            break;
                        case ".byte":
                            this.emitBytes(words);
                            break;
                        case ".hex":
                            this.emitHex(words);
                            break;
                        case ".hword":
                        case ".short":
                        case ".2bytes":
                            this.parseNumbers(words).forEach(function (n) {
                                if (-0x8000 <= n && n <= 0xffff)
                                    _this.emitShort(n & 0xffff);
                                else
                                    _this.directiveError(TDev.lf("expecting int16"));
                            });
                            break;
                        case ".word":
                        case ".4bytes":
                            this.parseNumbers(words).forEach(function (n) {
                                if (-0x80000000 <= n && n <= 0xffffffff) {
                                    _this.emitShort(n & 0xffff);
                                    _this.emitShort((n >> 16) & 0xffff);
                                }
                                else {
                                    _this.directiveError(TDev.lf("expecting int32"));
                                }
                            });
                            break;
                        case ".skip":
                        case ".space":
                            this.emitSpace(words);
                            break;
                        case "@stackmark":
                            expectOne();
                            this.stackpointers[words[1]] = this.stack;
                            break;
                        case "@stackempty":
                            if (this.stackpointers[words[1]] == null)
                                this.directiveError(TDev.lf("no such saved stack"));
                            else if (this.stackpointers[words[1]] != this.stack)
                                this.directiveError(TDev.lf("stack mismatch"));
                            break;
                        case "@scope":
                            this.scope = words[1] || "";
                            this.currLineNo = this.scope ? 0 : this.realCurrLineNo;
                            break;
                        case ".section":
                        case ".global":
                            this.stackpointers = {};
                            this.stack = 0;
                            break;
                        case ".file":
                        case ".text":
                        case ".cpu":
                        case ".fpu":
                        case ".eabi_attribute":
                        case ".code":
                        case ".thumb_func":
                        case ".type":
                            break;
                        case "@":
                            break;
                        default:
                            if (/^\.cfi_/.test(words[0])) {
                            }
                            else {
                                this.directiveError(TDev.lf("unknown directive"));
                            }
                            break;
                    }
                };
                Binary.prototype.handleInstruction = function (ln) {
                    var getIns = function (n) { return instructions.hasOwnProperty(n) ? instructions[n] : []; };
                    var ins = ln.instruction ? [ln.instruction] : getIns(ln.words[0]);
                    for (var i = 0; i < ins.length; ++i) {
                        var op = ins[i].emit(ln);
                        if (!op.error) {
                            this.stack += op.stack;
                            if (this.checkStack && this.stack < 0)
                                this.pushError(TDev.lf("stack underflow"));
                            this.emitShort(op.opcode);
                            if (op.opcode2 != null)
                                this.emitShort(op.opcode2);
                            ln.instruction = ins[i];
                            ln.numArgs = op.numArgs;
                            return;
                        }
                    }
                    var w0 = ln.words[0].toLowerCase().replace(/s$/, "").replace(/[^a-z]/g, "");
                    var hints = "";
                    var possibilities = getIns(w0).concat(getIns(w0 + "s"));
                    if (possibilities.length > 0) {
                        possibilities.forEach(function (i) {
                            var err = i.emit(ln);
                            hints += TDev.lf("   Maybe: {0} ({1} at '{2}')\n", i.toString(), err.error, err.errorAt);
                        });
                    }
                    this.pushError(TDev.lf("assembly error"), hints);
                };
                Binary.prototype.mkLine = function (tx) {
                    var l = new Line(this, tx);
                    l.scope = this.scope;
                    l.lineNo = this.currLineNo;
                    this.lines.push(l);
                    return l;
                };
                Binary.prototype.prepLines = function (text) {
                    var _this = this;
                    this.currLineNo = 0;
                    this.realCurrLineNo = 0;
                    this.lines = [];
                    text.split(/\r?\n/).forEach(function (tx) {
                        if (_this.errors.length > 10)
                            return;
                        _this.currLineNo++;
                        _this.realCurrLineNo++;
                        var l = _this.mkLine(tx);
                        var words = tokenize(l.text) || [];
                        l.words = words;
                        var m = /^([\.\w]+):$/.exec(words[0]);
                        if (m) {
                            l.type = "label";
                            l.text = m[1] + ":";
                            l.words = [m[1]];
                            if (words.length > 1) {
                                words.shift();
                                l = _this.mkLine(tx.replace(/^[^:]*:/, ""));
                                l.words = words;
                            }
                            else {
                                return;
                            }
                        }
                        if (/^[\.@]/.test(l.words[0])) {
                            l.type = "directive";
                            if (l.words[0] == "@scope")
                                _this.handleDirective(l);
                        }
                        else {
                            if (l.words.length == 0)
                                l.type = "empty";
                            else
                                l.type = "instruction";
                        }
                    });
                };
                Binary.prototype.iterLines = function () {
                    var _this = this;
                    this.stack = 0;
                    this.buf = [];
                    this.lines.forEach(function (l) {
                        if (_this.errors.length > 10)
                            return;
                        _this.currLine = l;
                        if (l.words.length == 0)
                            return;
                        if (l.type == "label") {
                            var lblname = _this.scopedName(l.words[0]);
                            if (_this.finalEmit) {
                                var curr = _this.labels[lblname];
                                if (curr == null)
                                    TDev.Util.die();
                                TDev.Util.assert(_this.errors.length > 0 || curr == _this.location());
                            }
                            else {
                                if (_this.labels.hasOwnProperty(lblname))
                                    _this.directiveError(TDev.lf("label redefinition"));
                                else if (_this.inlineMode && /^_/.test(lblname))
                                    _this.directiveError(TDev.lf("labels starting with '_' are reserved for the compiler"));
                                else
                                    _this.labels[lblname] = _this.location();
                            }
                        }
                        else if (l.type == "directive") {
                            _this.handleDirective(l);
                        }
                        else if (l.type == "instruction") {
                            _this.handleInstruction(l);
                        }
                        else if (l.type == "empty") {
                        }
                        else {
                            TDev.Util.die();
                        }
                    });
                };
                Binary.prototype.getSource = function (clean) {
                    var _this = this;
                    var lenTotal = this.buf ? this.buf.length * 2 : 0;
                    var lenThumb = this.labels["_program_end"] || lenTotal;
                    var res = TDev.Util.fmt("; thumb size: {0} bytes; src size {1} bytes\n", lenThumb, lenTotal - lenThumb) + TDev.Util.fmt("; assembly: {0} lines\n", this.lines.length) + this.stats + "\n\n";
                    var pastEnd = false;
                    this.lines.forEach(function (ln, i) {
                        if (pastEnd)
                            return;
                        if (ln.type == "label" && ln.words[0] == "_program_end")
                            pastEnd = true;
                        var text = ln.text;
                        if (clean) {
                            if (ln.words[0] == "@stackempty" && _this.lines[i - 1].text == ln.text)
                                return;
                            text = text.replace(/; WAS: .*/, "");
                            if (!text.trim())
                                return;
                        }
                        res += text + "\n";
                    });
                    return res;
                };
                Binary.prototype.peepHole = function () {
                    var lb11 = encoders["$lb11"];
                    var lb = encoders["$lb"];
                    var mylines = this.lines.filter(function (l) { return l.type != "empty"; });
                    for (var i = 0; i < mylines.length; ++i) {
                        var ln = mylines[i];
                        if (/^user/.test(ln.scope))
                            continue;
                        var lnNext = mylines[i + 1];
                        if (!lnNext)
                            continue;
                        var lnNext2 = mylines[i + 2];
                        if (ln.type == "instruction") {
                            var lnop = ln.getOp();
                            var isSkipBranch = false;
                            if (lnop == "bne" || lnop == "beq") {
                                if (lnNext.getOp() == "b" && ln.numArgs[0] == 0)
                                    isSkipBranch = true;
                                if (lnNext.getOp() == "bb" && ln.numArgs[0] == 2)
                                    isSkipBranch = true;
                            }
                            if (lnop == "bb" && lb11.encode(ln.numArgs[0]) != null) {
                                ln.update("b " + ln.words[1]);
                            }
                            else if (lnop == "bne" && isSkipBranch && lb.encode(lnNext.numArgs[0]) != null) {
                                ln.update("beq " + lnNext.words[1]);
                                lnNext.update("");
                            }
                            else if (lnop == "beq" && isSkipBranch && lb.encode(lnNext.numArgs[0]) != null) {
                                ln.update("bne " + lnNext.words[1]);
                                lnNext.update("");
                            }
                            else if (lnop == "push" && lnNext.getOp() == "pop" && ln.numArgs[0] == lnNext.numArgs[0]) {
                                TDev.Util.assert(ln.numArgs[0] > 0);
                                ln.update("");
                                lnNext.update("");
                            }
                            else if (lnop == "push" && lnNext.getOp() == "pop" && ln.words.length == 4 && lnNext.words.length == 4) {
                                TDev.Util.assert(ln.words[1] == "{");
                                ln.update("mov " + lnNext.words[2] + ", " + ln.words[2]);
                                lnNext.update("");
                            }
                            else if (lnNext2 && ln.getOpExt() == "movs $r5, $i0" && lnNext.getOpExt() == "mov $r0, $r1" && ln.numArgs[0] == lnNext.numArgs[1] && lnNext2.clobbersReg(ln.numArgs[0])) {
                                ln.update("movs r" + lnNext.numArgs[0] + ", #" + ln.numArgs[1]);
                                lnNext.update("");
                            }
                            else if (lnop == "pop" && ln.singleReg() >= 0 && lnNext.getOp() == "push" && ln.singleReg() == lnNext.singleReg()) {
                                ln.update("ldr r" + ln.singleReg() + ", [sp, #0]");
                                lnNext.update("");
                            }
                            else if (lnNext2 && lnop == "push" && ln.singleReg() >= 0 && lnNext.preservesReg(ln.singleReg()) && lnNext2.getOp() == "pop" && ln.singleReg() == lnNext2.singleReg()) {
                                ln.update("");
                                lnNext2.update("");
                            }
                        }
                    }
                };
                Binary.prototype.peepPass = function () {
                    if (this.disablePeepHole)
                        return;
                    this.peepOps = 0;
                    this.peepDel = 0;
                    this.peepHole();
                    this.throwOnError = true;
                    this.finalEmit = false;
                    this.labels = {};
                    this.iterLines();
                    TDev.Util.assert(!this.checkStack || this.stack == 0);
                    this.finalEmit = true;
                    this.iterLines();
                    this.stats += TDev.Util.fmt("; peep hole pass: {0} instructions removed and {1} updated\n", this.peepDel, this.peepOps - this.peepDel);
                };
                Binary.prototype.emit = function (text) {
                    init();
                    TDev.Util.assert(this.buf == null);
                    this.prepLines(text);
                    if (this.errors.length > 0)
                        return;
                    this.labels = {};
                    this.iterLines();
                    if (this.checkStack && this.stack != 0)
                        this.directiveError(TDev.lf("stack misaligned at the end of the file"));
                    if (this.errors.length > 0)
                        return;
                    this.finalEmit = true;
                    this.iterLines();
                    if (this.errors.length > 0)
                        return;
                    for (var i = 0; i < 5; ++i) {
                        this.peepPass();
                        if (this.peepOps == 0)
                            break;
                    }
                };
                return Binary;
            })();
            Thumb.Binary = Binary;
            function registerNo(actual) {
                if (!actual)
                    return null;
                actual = actual.toLowerCase();
                switch (actual) {
                    case "pc":
                        actual = "r15";
                        break;
                    case "lr":
                        actual = "r14";
                        break;
                    case "sp":
                        actual = "r13";
                        break;
                }
                var m = /^r(\d+)$/.exec(actual);
                if (m) {
                    var r = parseInt(m[1], 10);
                    if (0 <= r && r < 16)
                        return r;
                }
                return null;
            }
            var instructions;
            var encoders;
            function tokenize(line) {
                line = line.replace(/[\[\]\!\{\},]/g, function (m) { return " " + m + " "; });
                var words = line.split(/\s/).filter(function (s) { return !!s; });
                if (!words[0])
                    return null;
                if (/^;/.test(words[0]))
                    return null;
                for (var i = 1; i < words.length; ++i) {
                    if (/^;/.test(words[i]))
                        return words.slice(0, i);
                }
                return words;
            }
            function init() {
                if (instructions)
                    return;
                encoders = {};
                var addEnc = function (n, p, e) {
                    var ee = {
                        name: n,
                        pretty: p,
                        encode: e,
                        isRegister: /^\$r\d/.test(n),
                        isImmediate: /^\$i\d/.test(n),
                        isRegList: /^\$rl\d/.test(n),
                        isLabel: /^\$l[a-z]/.test(n),
                    };
                    encoders[n] = ee;
                    return ee;
                };
                var inrange = function (max, v, e) {
                    if (Math.floor(v) != v)
                        return null;
                    if (v < 0)
                        return null;
                    if (v > max)
                        return null;
                    return e;
                };
                addEnc("$r0", "R0-7", function (v) { return inrange(7, v, v); });
                addEnc("$r1", "R0-7", function (v) { return inrange(7, v, v << 3); });
                addEnc("$r2", "R0-15", function (v) { return inrange(15, v, (v & 7) | ((v & 8) << 4)); });
                addEnc("$r3", "R0-15", function (v) { return inrange(15, v, v << 3); });
                addEnc("$r4", "R0-7", function (v) { return inrange(7, v, v << 6); });
                addEnc("$r5", "R0-7", function (v) { return inrange(7, v, v << 8); });
                addEnc("$i0", "#0-255", function (v) { return inrange(255, v, v); });
                addEnc("$i1", "#0-1020", function (v) { return inrange(255, v / 4, v >> 2); });
                addEnc("$i2", "#0-510", function (v) { return inrange(127, v / 4, v >> 2); });
                addEnc("$i3", "#0-7", function (v) { return inrange(7, v, v << 6); });
                addEnc("$i4", "#0-31", function (v) { return inrange(31, v, v << 6); });
                addEnc("$i5", "#0-124", function (v) { return inrange(31, v / 4, (v >> 2) << 6); });
                addEnc("$i6", "#1-32", function (v) { return v == 0 ? null : v == 32 ? 0 : inrange(31, v, v << 6); });
                addEnc("$i7", "#0-62", function (v) { return inrange(31, v / 2, (v >> 1) << 6); });
                addEnc("$rl0", "{R0-7,...}", function (v) { return inrange(255, v, v); });
                addEnc("$rl1", "{LR,R0-7,...}", function (v) { return (v & 0x4000) ? inrange(255, (v & ~0x4000), 0x100 | (v & 0xff)) : inrange(255, v, v); });
                addEnc("$rl2", "{PC,R0-7,...}", function (v) { return (v & 0x8000) ? inrange(255, (v & ~0x8000), 0x100 | (v & 0xff)) : inrange(255, v, v); });
                var inrangeSigned = function (max, v, e) {
                    if (Math.floor(v) != v)
                        return null;
                    if (v < -(max + 1))
                        return null;
                    if (v > max)
                        return null;
                    var mask = (max << 1) | 1;
                    return e & mask;
                };
                addEnc("$la", "LABEL", function (v) { return inrange(255, v / 4, v >> 2); });
                addEnc("$lb", "LABEL", function (v) { return inrangeSigned(127, v / 2, v >> 1); });
                addEnc("$lb11", "LABEL", function (v) { return inrangeSigned(1023, v / 2, v >> 1); });
                instructions = {};
                var add = function (name, code, mask) {
                    var ins = new Instruction(name, code, mask);
                    if (!instructions.hasOwnProperty(ins.name))
                        instructions[ins.name] = [];
                    instructions[ins.name].push(ins);
                };
                add("adcs  $r0, $r1", 0x4140, 0xffc0);
                add("add   $r2, $r3", 0x4400, 0xff00);
                add("add   $r5, pc, $i1", 0xa000, 0xf800);
                add("add   $r5, sp, $i1", 0xa800, 0xf800);
                add("add   sp, $i2", 0xb000, 0xff80);
                add("adds  $r0, $r1, $i3", 0x1c00, 0xfe00);
                add("adds  $r0, $r1, $r4", 0x1800, 0xfe00);
                add("adds  $r5, $i0", 0x3000, 0xf800);
                add("adr   $r5, $la", 0xa000, 0xf800);
                add("ands  $r0, $r1", 0x4000, 0xffc0);
                add("asrs  $r0, $r1", 0x4100, 0xffc0);
                add("asrs  $r0, $r1, $i6", 0x1000, 0xf800);
                add("bics  $r0, $r1", 0x4380, 0xffc0);
                add("bkpt  $i0", 0xbe00, 0xff00);
                add("blx   $r3", 0x4780, 0xff87);
                add("bx    $r3", 0x4700, 0xff80);
                add("cmn   $r0, $r1", 0x42c0, 0xffc0);
                add("cmp   $r0, $r1", 0x4280, 0xffc0);
                add("cmp   $r2, $r3", 0x4500, 0xff00);
                add("cmp   $r5, $i0", 0x2800, 0xf800);
                add("eors  $r0, $r1", 0x4040, 0xffc0);
                add("ldmia $r5!, $rl0", 0xc800, 0xf800);
                add("ldmia $r5, $rl0", 0xc800, 0xf800);
                add("ldr   $r0, [$r1, $i5]", 0x6800, 0xf800);
                add("ldr   $r0, [$r1, $r4]", 0x5800, 0xfe00);
                add("ldr   $r5, [pc, $i1]", 0x4800, 0xf800);
                add("ldr   $r5, [sp, $i1]", 0x9800, 0xf800);
                add("ldrb  $r0, [$r1, $i4]", 0x7800, 0xf800);
                add("ldrb  $r0, [$r1, $r4]", 0x5c00, 0xfe00);
                add("ldrh  $r0, [$r1, $i7]", 0x8800, 0xf800);
                add("ldrh  $r0, [$r1, $r4]", 0x5a00, 0xfe00);
                add("ldrsb $r0, [$r1, $r4]", 0x5600, 0xfe00);
                add("ldrsh $r0, [$r1, $r4]", 0x5e00, 0xfe00);
                add("lsls  $r0, $r1", 0x4080, 0xffc0);
                add("lsls  $r0, $r1, $i4", 0x0000, 0xf800);
                add("lsrs  $r0, $r1", 0x40c0, 0xffc0);
                add("lsrs  $r0, $r1, $i6", 0x0800, 0xf800);
                add("mov   $r0, $r1", 0x4600, 0xffc0);
                add("movs  $r0, $r1", 0x0000, 0xffc0);
                add("movs  $r5, $i0", 0x2000, 0xf800);
                add("muls  $r0, $r1", 0x4340, 0xffc0);
                add("mvns  $r0, $r1", 0x43c0, 0xffc0);
                add("negs  $r0, $r1", 0x4240, 0xffc0);
                add("nop", 0x46c0, 0xffff);
                add("orrs  $r0, $r1", 0x4300, 0xffc0);
                add("pop   $rl2", 0xbc00, 0xfe00);
                add("push  $rl1", 0xb400, 0xfe00);
                add("rev   $r0, $r1", 0xba00, 0xffc0);
                add("rev16 $r0, $r1", 0xba40, 0xffc0);
                add("revsh $r0, $r1", 0xbac0, 0xffc0);
                add("rors  $r0, $r1", 0x41c0, 0xffc0);
                add("sbcs  $r0, $r1", 0x4180, 0xffc0);
                add("sev", 0xbf40, 0xffff);
                add("stmia $r5!, $rl0", 0xc000, 0xf800);
                add("str   $r0, [$r1, $i5]", 0x6000, 0xf800);
                add("str   $r0, [$r1, $r4]", 0x5000, 0xfe00);
                add("str   $r5, [sp, $i1]", 0x9000, 0xf800);
                add("strb  $r0, [$r1, $i4]", 0x7000, 0xf800);
                add("strb  $r0, [$r1, $r4]", 0x5400, 0xfe00);
                add("strh  $r0, [$r1, $i7]", 0x8000, 0xf800);
                add("strh  $r0, [$r1, $r4]", 0x5200, 0xfe00);
                add("sub   sp, $i2", 0xb080, 0xff80);
                add("subs  $r0, $r1, $i3", 0x1e00, 0xfe00);
                add("subs  $r0, $r1, $r4", 0x1a00, 0xfe00);
                add("subs  $r5, $i0", 0x3800, 0xf800);
                add("svc   $i0", 0xdf00, 0xff00);
                add("sxtb  $r0, $r1", 0xb240, 0xffc0);
                add("sxth  $r0, $r1", 0xb200, 0xffc0);
                add("tst   $r0, $r1", 0x4200, 0xffc0);
                add("udf   $i0", 0xde00, 0xff00);
                add("uxtb  $r0, $r1", 0xb2c0, 0xffc0);
                add("uxth  $r0, $r1", 0xb280, 0xffc0);
                add("wfe", 0xbf20, 0xffff);
                add("wfi", 0xbf30, 0xffff);
                add("yield", 0xbf10, 0xffff);
                add("cpsid i", 0xb672, 0xffff);
                add("cpsie i", 0xb662, 0xffff);
                add("beq   $lb", 0xd000, 0xff00);
                add("bne   $lb", 0xd100, 0xff00);
                add("bcs   $lb", 0xd200, 0xff00);
                add("bcc   $lb", 0xd300, 0xff00);
                add("bmi   $lb", 0xd400, 0xff00);
                add("bpl   $lb", 0xd500, 0xff00);
                add("bvs   $lb", 0xd600, 0xff00);
                add("bvc   $lb", 0xd700, 0xff00);
                add("bhi   $lb", 0xd800, 0xff00);
                add("bls   $lb", 0xd900, 0xff00);
                add("bge   $lb", 0xda00, 0xff00);
                add("blt   $lb", 0xdb00, 0xff00);
                add("bgt   $lb", 0xdc00, 0xff00);
                add("ble   $lb", 0xdd00, 0xff00);
                add("bhs   $lb", 0xd200, 0xff00);
                add("blo   $lb", 0xd300, 0xff00);
                add("b     $lb11", 0xe000, 0xf800);
                add("bal   $lb11", 0xe000, 0xf800);
                add("bl    $lb", 0xf000, 0xf800);
                add("bb    $lb", 0xe000, 0xf800);
            }
            function parseString(s) {
                var toks = AST.Lexer.tokenize(s);
                if (toks.length != 2 || toks[0].category != 3 /* String */ || toks[1].category != 7 /* EOF */)
                    return null;
                return toks[0].data;
            }
            function emitErr(msg, tok) {
                return {
                    stack: null,
                    opcode: null,
                    error: msg,
                    errorAt: tok
                };
            }
            function testOne(op, code) {
                var b = new Binary();
                b.checkStack = false;
                b.emit(op);
                TDev.Util.assert(b.buf[0] == code);
            }
            Thumb.testOne = testOne;
            function expectError(asm) {
                var b = new Binary();
                b.emit(asm);
                if (b.errors.length == 0) {
                    TDev.Util.oops("ASMTEST: expecting error for: " + asm);
                }
            }
            function tohex(n) {
                if (n < 0 || n > 0xffff)
                    return ("0x" + n.toString(16)).toLowerCase();
                else
                    return ("0x" + ("000" + n.toString(16)).slice(-4)).toLowerCase();
            }
            Thumb.tohex = tohex;
            function expect(disasm) {
                var exp = [];
                var asm = disasm.replace(/^([0-9a-fA-F]{4})\s/gm, function (w, n) {
                    exp.push(parseInt(n, 16));
                    return "";
                });
                var b = new Binary();
                b.throwOnError = true;
                b.disablePeepHole = true;
                b.emit(asm);
                if (b.errors.length > 0) {
                    console.log(b.errors[0].message);
                    TDev.Util.oops("ASMTEST: not expecting errors");
                }
                if (b.buf.length != exp.length)
                    TDev.Util.oops("ASMTEST: wrong buf len");
                for (var i = 0; i < exp.length; ++i) {
                    if (b.buf[i] != exp[i])
                        TDev.Util.oops("ASMTEST: wrong buf content, exp:" + tohex(exp[i]) + ", got: " + tohex(b.buf[i]));
                }
            }
            function test() {
                expectError("lsl r0, r0, #8");
                expectError("push {pc,lr}");
                expectError("push {r17}");
                expectError("mov r0, r1 foo");
                expectError("movs r14, #100");
                expectError("push {r0");
                expectError("push lr,r0}");
                expectError("pop {lr,r0}");
                expectError("b #+11");
                expectError("b #+102400");
                expectError("bne undefined_label");
                expectError(".foobar");
                expect("0200      lsls    r0, r0, #8\n" + "b500      push    {lr}\n" + "2064      movs    r0, #100        ; 0x64\n" + "b401      push    {r0}\n" + "bc08      pop     {r3}\n" + "b501      push    {r0, lr}\n" + "bd20      pop {r5, pc}\n" + "bc01      pop {r0}\n" + "4770      bx      lr\n" + "0000      .balign 4\n" + "e6c0      .word   -72000\n" + "fffe\n");
                expect("4291      cmp     r1, r2\n" + "d100      bne     l6\n" + "e000      b       l8\n" + "1840  l6: adds    r0, r0, r1\n" + "4718  l8: bx      r3\n");
                expect("          @stackmark base\n" + "b403      push    {r0, r1}\n" + "          @stackmark locals\n" + "9801      ldr     r0, [sp, locals@1]\n" + "b401      push    {r0}\n" + "9802      ldr     r0, [sp, locals@1]\n" + "bc01      pop     {r0}\n" + "          @stackempty locals\n" + "9901      ldr     r1, [sp, locals@1]\n" + "9102      str     r1, [sp, base@0]\n" + "          @stackempty locals\n" + "b002      add     sp, #8\n" + "          @stackempty base\n");
                expect("b090      sub sp, #4*16\n" + "b010      add sp, #4*16\n");
                expect("6261      .string \"abc\"\n" + "0063      \n");
                expect("6261      .string \"abcde\"\n" + "6463      \n" + "0065      \n");
                expect("3042      adds r0, 0x42\n" + "1c0d      adds r5, r1, #0\n" + "d100      bne #0\n" + "2800      cmp r0, #0\n" + "6b28      ldr r0, [r5, #48]\n" + "0200      lsls r0, r0, #8\n" + "2063      movs r0, 0x63\n" + "4240      negs r0, r0\n" + "46c0      nop\n" + "b500      push {lr}\n" + "b401      push {r0}\n" + "b402      push {r1}\n" + "b404      push {r2}\n" + "b408      push {r3}\n" + "b520      push {r5, lr}\n" + "bd00      pop {pc}\n" + "bc01      pop {r0}\n" + "bc02      pop {r1}\n" + "bc04      pop {r2}\n" + "bc08      pop {r3}\n" + "bd20      pop {r5, pc}\n" + "9003      str r0, [sp, #4*3]\n");
            }
            Thumb.test = test;
        })(Thumb = AST.Thumb || (AST.Thumb = {}));
    })(AST = TDev.AST || (TDev.AST = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var J = TDev.AST.Json;
    var Embedded;
    (function (Embedded) {
        var H = Embedded.Helpers;
        function parseScript(text) {
            return TDev.AST.loadScriptAsync(function (id) {
                if (id == "")
                    return TDev.Promise.as(text);
                else
                    return TDev.World.getAnyScriptAsync(id);
            }, "").then(function (resp) {
                var s = TDev.Script;
                TDev.Script = null;
                return TDev.Promise.as(s);
            });
        }
        Embedded.parseScript = parseScript;
        function makeOutMbedErrorMsg(json) {
            var errorMsg = "unknown error";
            if (json.mbedresponse) {
                if (json.messages) {
                    var messages = json.messages.filter(function (m) { return m.severity == "error" || m.type == "Error"; });
                    errorMsg = messages.map(function (m) { return m.message + "\n" + m.text; }).join("\n");
                }
                else if (json.mbedresponse.result) {
                    errorMsg = json.mbedresponse.result.exception;
                }
            }
            return errorMsg;
        }
        Embedded.makeOutMbedErrorMsg = makeOutMbedErrorMsg;
        ;
        function compile1(globalNameMap, libs, resolveMap, a) {
            try {
                var libRef = H.mkLibraryRef(a.name);
                var libName = a.isLibrary ? a.name : null;
                var env = H.emptyEnv(globalNameMap, libName);
                Embedded.lift(env, a);
                var e = new Embedded.Emitter(libRef, libs, resolveMap);
                e.visit(env, a);
                return e;
            }
            catch (e) {
                console.error("Compilation error", e);
                throw e;
            }
        }
        function buildResolveMap(libs) {
            var idToAbsoluteName = {};
            libs.map(function (l) {
                idToAbsoluteName[l.id] = l.name;
            });
            return libs.map(function (l) {
                var map = {};
                l.resolveClauses.map(function (r) {
                    map[r.name] = idToAbsoluteName[r.defaultLibId];
                });
                return map;
            });
        }
        var reservedNames = [
            "user_types",
            "globals",
            "create",
            "collection",
            "touch_develop",
            "ref",
            "ds1307",
            "string",
            "action",
            "math",
            "number",
            "boolean",
            "bits",
            "internal_main",
            "Number",
            "Boolean",
            "String",
            "ManagedString",
            "Collection",
            "Collection_of",
            "Ref",
            "TdError",
            "DalAdapter",
            "MicroBitPin",
        ];
        function compile(a) {
            var libraries = a.decls.filter(function (d) { return d.nodeType == "library"; });
            var resolveMap = buildResolveMap(libraries);
            var mainResolveMap = {};
            var textPromises = libraries.map(function (j, i) {
                var pubId = j.libIdentifier;
                return TDev.AST.loadScriptAsync(TDev.World.getAnyScriptAsync, pubId).then(function (resp) {
                    var s = TDev.Script;
                    TDev.Script = resp.prevScript;
                    var jApp = J.dump(s);
                    mainResolveMap[libraries[i].name] = jApp.name;
                    return TDev.Promise.as(jApp);
                });
            });
            textPromises.push(TDev.Promise.as(a));
            return TDev.Promise.join(textPromises).then(function (everything) {
                Object.keys(resolveMap).forEach(function (libName) {
                    var libMap = resolveMap[libName];
                    Object.keys(libMap).forEach(function (x) {
                        libMap[x] = mainResolveMap[libMap[x]];
                    });
                });
                resolveMap.push(mainResolveMap);
                var globalNameMap = {
                    libraries: {},
                    program: null,
                };
                everything.forEach(function (a) {
                    var tdToCpp = {};
                    var cppToTd = {};
                    everything.map(function (a) { return H.mangle(a.name); }).concat(reservedNames).forEach(function (x) { return cppToTd[x] = true; });
                    a.decls.forEach(function (d) {
                        var n = H.freshName(cppToTd, d.name);
                        cppToTd[n] = true;
                        tdToCpp[d.name] = n;
                    });
                    if (a.isLibrary)
                        globalNameMap.libraries[a.name] = tdToCpp;
                    else
                        globalNameMap.program = tdToCpp;
                });
                var compiled = everything.map(function (a, i) { return compile1(globalNameMap, everything, resolveMap[i], a); });
                return TDev.Promise.as(compiled.map(function (x) { return x.prelude; }).concat(["namespace touch_develop {"]).concat(compiled.map(function (x) { return x.tPrototypes; })).concat(compiled.map(function (x) { return x.tCode; })).concat(compiled.map(function (x) { return x.prototypes; })).concat(compiled.map(function (x) { return x.code; })).concat(["}"]).filter(function (x) { return x != ""; }).join("\n") + "\n" + (a.isLibrary ? "\nvoid app_main() {\n" + "  uBit.display.scroll(\"Error: trying to run a library\");\n" + "}\n" : "\nvoid app_main() {\n" + "  touch_develop::main();\n" + "}\n") + "\n\n// vim: sw=2 ts=2");
            });
        }
        Embedded.compile = compile;
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Hex;
    (function (Hex) {
        var getCacheTableAsync = function () { return TDev.Storage.getTableAsync("ArtCache"); };
        var maxItems = 5;
        function setValueAsync(t, k, v) {
            var st = {};
            st[k] = v;
            return t.setItemsAsync(st);
        }
        function storeHexInfoAsync(sha, entry) {
            var key = "hex-" + sha;
            return getCacheTableAsync().then(function (table) {
                var setPr = setValueAsync(table, key, entry);
                return table.getValueAsync("hex:keys").then(function (currKeys) {
                    if (!currKeys)
                        currKeys = "[]";
                    var lst = JSON.parse(currKeys);
                    lst.push(key);
                    if (lst.length > maxItems) {
                        lst = lst.slice(-maxItems);
                        setPr = setPr.then(function () { return table.getKeysAsync(); }).then(function (keys) {
                            var del = {};
                            keys.forEach(function (k) {
                                if (/^hex-/.test(k) && lst.indexOf(k) == -1) {
                                    TDev.Util.log("delete " + k);
                                    del[k] = null;
                                }
                            });
                            return table.setItemsAsync(del);
                        });
                    }
                    return setPr.then(function () { return setValueAsync(table, "hex:keys", JSON.stringify(lst)); });
                });
            });
        }
        function loadHexInfoAsync(sha) {
            var key = "hex-" + sha;
            return getCacheTableAsync().then(function (table) { return table.getValueAsync(key); });
        }
        var downloadCache = {};
        function downloadHexInfoAsync(extInfo) {
            if (downloadCache.hasOwnProperty(extInfo.sha))
                return downloadCache[extInfo.sha];
            return (downloadCache[extInfo.sha] = downloadHexInfoCoreAsync(extInfo));
        }
        function downloadHexInfoCoreAsync(extInfo) {
            var hexurl = TDev.Cloud.config.primaryCdnUrl + "/compile/" + extInfo.sha;
            return TDev.Util.httpGetTextAsync(hexurl + ".hex").then(function (text) { return text; }, function (e) { return TDev.Cloud.postPrivateApiAsync("compile/extension", { data: extInfo.compileData }).then(function (ret) {
                var r = new TDev.PromiseInv();
                var tryGet = function () { return TDev.Util.httpGetJsonAsync(ret.hex.replace(/\.hex/, ".json")).then(function (json) {
                    if (!json.success)
                        TDev.ModalDialog.showText(JSON.stringify(json, null, 1), TDev.lf("Compilation error"));
                    else
                        r.success(TDev.Util.httpGetTextAsync(hexurl + ".hex"));
                }, function (e) { return TDev.Util.setTimeout(1000, tryGet); }); };
                tryGet();
                return r;
            }); }).then(function (text) { return TDev.Util.httpGetJsonAsync(hexurl + "-metainfo.json").then(function (meta) {
                meta.hex = text.split(/\r?\n/);
                return meta;
            }); });
        }
        function getHexInfoAsync(extInfo) {
            if (!extInfo.sha)
                return TDev.Promise.as(null);
            if (TDev.AST.Bytecode.isSetupFor(extInfo))
                return TDev.Promise.as(null);
            if (TDev.Cloud.config.microbitGitTag == "local") {
                if (extInfo.hasExtension)
                    throw new Error("?microbit=local not allowed when compiling with extensions");
                if (!TDev.bytecodeInfo)
                    throw new Error("?microbit=local requires bytecode.js file");
                return TDev.Promise.as(TDev.bytecodeInfo);
            }
            TDev.Util.log("get hex info: " + extInfo.sha);
            return loadHexInfoAsync(extInfo.sha).then(function (res) {
                if (res) {
                    TDev.Util.log("get from world: " + res.length);
                    var meta = JSON.parse(res);
                    meta.hex = decompressHex(meta.hex);
                    return TDev.Promise.as(meta);
                }
                else {
                    if (TDev.Cloud.isOffline())
                        return TDev.Promise.as(null);
                    return downloadHexInfoAsync(extInfo).then(function (meta) {
                        var origHex = meta.hex;
                        meta.hex = compressHex(meta.hex);
                        var store = JSON.stringify(meta);
                        meta.hex = origHex;
                        return storeHexInfoAsync(extInfo.sha, store).then(function () { return meta; });
                    });
                }
            });
        }
        function preCacheEmptyExtensionAsync(fromEditor) {
            if (fromEditor === void 0) { fromEditor = false; }
            if (!TDev.Cloud.isRestricted())
                return TDev.Promise.as();
            var extInfo = TDev.AST.Bytecode.getExtensionInfo(null);
            if (extInfo.errors)
                throw new Error(extInfo.errors);
            return getHexInfoAsync(extInfo).then(function (meta) {
                if (meta && fromEditor)
                    TDev.AST.Bytecode.setupFor(extInfo, meta);
            });
        }
        Hex.preCacheEmptyExtensionAsync = preCacheEmptyExtensionAsync;
        function cliCompileAsync(app, scriptId) {
            if (scriptId === void 0) { scriptId = ""; }
            var guid = app.localGuid;
            var extInfo = TDev.AST.Bytecode.getExtensionInfo(app);
            if (extInfo.errors)
                throw new Error(extInfo.errors);
            var hd = {
                meta: {
                    name: app.getName(),
                    comment: app.getDescription(),
                },
                status: scriptId ? "published" : "unpublished",
                scriptId: scriptId,
            };
            return TDev.Promise.join([getHexInfoAsync(extInfo), compressSourceAsync(app.serialize(), hd)]).then(function (r) {
                TDev.AST.Bytecode.setupFor(extInfo, r[0]);
                var c = new TDev.AST.Bytecode.Compiler(app);
                c.run();
                var res = c.serialize(false, r[1][0], r[1][1]);
                if (!res.data)
                    throw new Error("no hex data");
                return res;
            });
        }
        Hex.cliCompileAsync = cliCompileAsync;
        function compressSourceAsync(text, hd) {
            var meta = JSON.stringify(TDev.World.stripHeaderForSave(hd));
            var lzma = window.LZMA;
            if (!lzma)
                return TDev.Promise.as([meta, TDev.Util.stringToUint8Array(TDev.Util.toUTF8(text))]);
            var newMeta = {
                compression: "LZMA",
                headerSize: meta.length,
                textSize: text.length,
                name: hd.name,
            };
            return TDev.lzmaCompressAsync(meta + text).then(function (cbuf) { return [JSON.stringify(newMeta), cbuf]; });
        }
        var firstTime = true;
        function compile(app, compilationStartTime, saveStateAsync, showSource, source, onCompiled) {
            var times = "";
            var startTime = TDev.Util.now();
            times += TDev.Util.fmt("; type check before compile {0}ms\n", startTime - compilationStartTime);
            var guid = app.localGuid;
            var st = saveStateAsync().then(function () { return TDev.Promise.join([source || TDev.World.getInstalledScriptAsync(guid), TDev.World.getInstalledHeaderAsync(guid)]); }).then(function (r) { return compressSourceAsync(r[0], r[1]); }).then(function (r) {
                var saveDone = TDev.Util.now();
                times += TDev.Util.fmt("; save time {0}ms\n", saveDone - startTime);
                return r;
            });
            var extensionStart = TDev.Util.now();
            var extInfo = TDev.AST.Bytecode.getExtensionInfo(app);
            if (extInfo.errors) {
                TDev.ModalDialog.info(TDev.lf("Errors compiling glue.cpp extensions"), extInfo.errors);
                return;
            }
            getHexInfoAsync(extInfo).done(function (meta) {
                TDev.AST.Bytecode.setupFor(extInfo, meta);
                var realCompileStartTime = TDev.Util.now();
                times += TDev.Util.fmt("; glue.cpp extesion handling {0}ms\n", realCompileStartTime - extensionStart);
                var c = new TDev.AST.Bytecode.Compiler(app);
                try {
                    c.run();
                }
                catch (e) {
                    if (e.bitvmUserError) {
                        TDev.ModalDialog.info(e.message, TDev.lf("If you're using any special library, please contact the author. Otherwise contact BBC micro:bit support."));
                    }
                    else {
                        if (app != TDev.Script)
                            e.bugAttachments = [app.serialize()];
                        TDev.Util.reportError("bitvm compile", e, false);
                        if (TDev.dbg)
                            TDev.ModalDialog.showText(e.stack);
                        else
                            TDev.HTML.showErrorNotification(TDev.lf("Oops, something happened! If this keeps happening, contact BBC micro:bit support."));
                    }
                    return;
                }
                var compileStop = TDev.Util.now();
                times += TDev.Util.fmt("; to assembly {0}ms\n", compileStop - realCompileStartTime);
                st.then(function (r) {
                    var asmStart = TDev.Util.now();
                    var res = c.serialize(!firstTime, r[0], r[1]);
                    times += TDev.Util.fmt("; assemble time {0}ms\n", TDev.Util.now() - asmStart);
                    if (showSource)
                        TDev.ModalDialog.showText(times + res.csource);
                    if (!res.sourceSaved) {
                        TDev.HTML.showWarningNotification("program compiled, but without the source; to save for later use the 'save' button");
                    }
                    firstTime = false;
                    if (res.data) {
                        var fn = TDev.Util.toFileName("microbit-" + app.getName(), 'script') + ".hex";
                        TDev.HTML.browserDownloadText(res.data, fn, res.contentType);
                        if (onCompiled)
                            onCompiled(fn, "data:" + res.contentType + ";base64," + TDev.Util.base64EncodeBytes(TDev.Util.stringToUint8Array(TDev.Util.toUTF8(res.data))));
                    }
                }).done(function () {
                }, function (e) {
                    TDev.Util.reportError("bitvm download", e, false);
                    if (TDev.dbg)
                        TDev.ModalDialog.showText(e.stack);
                    else
                        TDev.HTML.showErrorNotification(TDev.lf("Oops, something happened! If this keeps happening, contact BBC micro:bit support."));
                });
            });
        }
        Hex.compile = compile;
        function decompressHex(hex) {
            var outp = [];
            for (var i = 0; i < hex.length; i++) {
                var m = /^([@!])(....)$/.exec(hex[i]);
                if (!m) {
                    outp.push(hex[i]);
                    continue;
                }
                var addr = parseInt(m[2], 16);
                var nxt = hex[++i];
                var buf = "";
                if (m[1] == "@") {
                    buf = "";
                    var cnt = parseInt(nxt, 16);
                    while (cnt-- > 0) {
                        buf += "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
                    }
                }
                else {
                    buf = atob(nxt);
                }
                TDev.Util.assert(buf.length > 0);
                TDev.Util.assert(buf.length % 16 == 0);
                for (var j = 0; j < buf.length;) {
                    var bytes = [0x10, (addr >> 8) & 0xff, addr & 0xff, 0];
                    addr += 16;
                    for (var k = 0; k < 16; ++k) {
                        bytes.push(buf.charCodeAt(j++));
                    }
                    var chk = 0;
                    for (var k = 0; k < bytes.length; ++k)
                        chk += bytes[k];
                    bytes.push((-chk) & 0xff);
                    var r = ":";
                    for (var k = 0; k < bytes.length; ++k) {
                        var b = bytes[k] & 0xff;
                        if (b <= 0xf)
                            r += "0";
                        r += b.toString(16);
                    }
                    outp.push(r.toUpperCase());
                }
            }
            return outp;
        }
        function compressHex(hex) {
            var outp = [];
            for (var i = 0; i < hex.length; i += j) {
                var addr = -1;
                var outln = "";
                var j = 0;
                var zeroMode = false;
                while (j < 500) {
                    var m = /^:10(....)00(.{32})(..)$/.exec(hex[i + j]);
                    if (!m)
                        break;
                    var h = m[2];
                    var isZero = /^0+$/.test(h);
                    var newaddr = parseInt(m[1], 16);
                    if (addr == -1) {
                        zeroMode = isZero;
                        outp.push((zeroMode ? "@" : "!") + m[1]);
                        addr = newaddr - 16;
                    }
                    else {
                        if (isZero != zeroMode)
                            break;
                        if (addr + 16 != newaddr)
                            break;
                    }
                    if (!zeroMode)
                        outln += h;
                    addr = newaddr;
                    j++;
                }
                if (j == 0) {
                    outp.push(hex[i]);
                    j = 1;
                }
                else {
                    if (zeroMode) {
                        outp.push(j.toString(16));
                    }
                    else {
                        var bin = "";
                        for (var k = 0; k < outln.length; k += 2)
                            bin += String.fromCharCode(parseInt(outln.slice(k, k + 2), 16));
                        outp.push(btoa(bin));
                    }
                }
            }
            return outp;
        }
    })(Hex = TDev.Hex || (TDev.Hex = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var Embedded;
    (function (Embedded) {
        function packageApp(name, sources) {
            if (typeof (JSZip) === 'undefined')
                return undefined;
            var zip = new JSZip();
            var vscode = zip.folder(".vscode");
            vscode.file("tasks.json", JSON.stringify({
                "version": "0.1.0",
                "command": "yotta",
                "isShellCommand": true,
                "args": ["--target", "bbc-microbit-classic-gcc"],
                "tasks": [
                    {
                        "taskName": "build",
                        "args": [],
                        "isBuildCommand": true,
                        "problemMatcher": "$msCompile"
                    }
                ]
            }, null, "4"));
            zip.file("module.json", JSON.stringify({
                "name": TDev.Util.toFileName(name, "microbit-script"),
                "version": "0.0.0",
                "keywords": ["microbit"],
                "dependencies": {
                    "microbit-touchdevelop": "microsoft/microbit-touchdevelop#" + TDev.Cloud.config.microbitGitTag
                },
                "bin": "./source",
            }, null, 4));
            var source = zip.folder("source");
            Object.keys(sources).forEach(function (fn) { return source.file(fn, sources[fn]); });
            return "data:application/zip;base64," + zip.generate({ type: "base64" });
        }
        Embedded.packageApp = packageApp;
    })(Embedded = TDev.Embedded || (TDev.Embedded = {}));
})(TDev || (TDev = {}));
var TDev; TDev = TDev || {};
TDev.md_initApis = function md_initApis() {
   'use strict';
   var self;
   var multiplex;
   var mkKind = TDev.Kind.md_make;
   var mkProp = TDev.Property.md_make;
   var mkArg = TDev.PropertyParameter.md_make;
   var k_Nothing = mkKind(10000, 'Nothing', 'Represents no value of interest');
   k_Nothing.md_isData();

// Kind definitions
var k_Action = self = mkKind(0, "Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_TextAction = self = mkKind(0, "Text Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_NumberAction = self = mkKind(0, "Number Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_BooleanAction = self = mkKind(0, "Boolean Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_PositionAction = self = mkKind(0, "Position Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_SpriteAction = self = mkKind(0, "Sprite Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_SpriteSetAction = self = mkKind(0, "Sprite Set Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_VectorAction = self = mkKind(0, "Vector Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_WebResponseAction = self = mkKind(0, "Web Response Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_CollectionMessageAction = self = mkKind(0, "Collection Message Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_JsonAction = self = mkKind(0, "Json Action", "A place to hook up an action to execute in response to an event", 'action');
self.md_isData();
self.md_ctx("general");
self.md_isAction();
var k_Comparison = self = mkKind(0, "Comparison", "An atomic comparison action", 'action');
self.md_isData();
self.md_stem("cmp");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parametric("Elt");
var k_Predicate = self = mkKind(0, "Predicate", "An atomic predicate test", 'action');
self.md_isData();
self.md_stem("cmp");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parameterPrefixes("on");
self.md_parametric("Elt");
var k_AtomicAction = self = mkKind(0, "Atomic Action", "An atomic action with no arguments", 'action');
self.md_isData();
self.md_stem("op");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
var k_AtomicAction1 = self = mkKind(0, "Atomic Action1", "An atomic single argument action", 'action');
self.md_isData();
self.md_stem("op");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parameterPrefixes("taking");
self.md_parametric("T");
var k_Action1 = self = mkKind(0, "Action1", "A possibly non-atomic single argument action", 'action');
self.md_isData();
self.md_stem("op");
self.md_ctx("general");
self.md_isAction();
self.md_parameterPrefixes("taking");
self.md_parametric("T");
var k_NumberConverter = self = mkKind(0, "Number Converter", "An atomic conversion function to number", 'action');
self.md_isData();
self.md_stem("key");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parameterPrefixes("from");
self.md_parametric("Elt");
var k_StringConverter = self = mkKind(0, "String Converter", "An atomic conversion function to string", 'action');
self.md_isData();
self.md_stem("key");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parameterPrefixes("from");
self.md_parametric("Elt");
var k_Converter = self = mkKind(0, "Converter", "A generic atomic conversion function", 'action');
self.md_isData();
self.md_stem("cnv");
self.md_ctx("general");
self.md_isAction();
self.md_isAtomic();
self.md_parameterPrefixes("from", "to");
self.md_parametric("From", "To");
var k_AppLogger = self = mkKind(0, "App Logger", "A custom logger");
self.md_isData();
self.md_stem("logger");
var k_AppEnv = self = mkKind(0, "App Env", "Various properties of application environment");
self.md_isData();
var k_App = self = mkKind(0, "App", "Interact with the app runtime");
self.md_skill(3);
var k_Bazaar = self = mkKind(195, "Bazaar", "Browse and review scripts from the bazaar");
self.md_skill(3);
var k_Bits = self = mkKind(0, "Bits", "Arithmetic and bitwise operations on 32 bit integers");
self.md_skill(3);
var k_Board = self = mkKind(12146, "Board", "A board to build 2D games");
self.md_isData();
self.md_icon("gameboard");
self.md_ctx("general", "gckey", "enumerable");
var k_Obstacle = self = mkKind(0, "Obstacle", "An obstacle on a board");
self.md_isData();
self.md_ctx("general", "gckey");
var k_BoardBackgroundScene = self = mkKind(0, "Board Background Scene", "A scene contains layers of parralax backgrounds.");
self.md_isData();
self.md_stem("scene");
var k_BoardBackgroundLayer = self = mkKind(0, "Board Background Layer", "A background scene layer");
self.md_isData();
self.md_stem("layer");
var k_Boolean_ = self = mkKind(4321, "Boolean", "true or false");
self.md_isData();
self.md_stem("b");
self.md_icon("fa-check-square-o");
self.md_immutable();
self.md_isData();
self.md_builtin();
self.md_ctx("general", "indexkey", "cloudfield", "json");
self.md_robust();
var k_Box = self = mkKind(0, "Box", "Current box element in the page.");
self.md_skill(2);
var k_Dom = self = mkKind(0, "Dom", "Current html element in the page.");
self.md_betaOnly();
self.md_skill(2);
var k_Buffer = self = mkKind(0, "Buffer", "Contains binary data");
self.md_isData();
self.md_stem("buf");
var k_Camera = self = mkKind(33, "Camera", "The front or back camera");
self.md_isData();
self.md_walltap();
var k_CloudSession = self = mkKind(0, "Cloud Session", "A cloud data session");
self.md_isData();
self.md_ctx("general");
self.md_stem("session");
self.md_cap("cloudData");
self.md_serializable();
var k_CloudData = self = mkKind(0, "Cloud Data", "Cloud session management");
self.md_cap("cloudData");
self.md_skill(2);
var k_Collection = self = mkKind(0, "Collection", "A collection of objects", 'parametric');
self.md_isData();
self.md_stem("coll");
self.md_icon("fa-list-ol");
self.md_enumerable();
self.md_serializable();
self.md_ctx("general", "json");
self.md_parametric("T");
var k_Collections = self = mkKind(613, "Collections", "Create collections of items.");
self.md_robust();
self.md_skill(3);
var k_Color = self = mkKind(1267, "Color", "A argb color (alpha, red, green, blue)");
self.md_isData();
self.md_stem("c");
self.md_icon("color");
self.md_immutable();
self.md_ctx("general", "indexkey", "walltap", "cloudfield", "json");
self.md_serializable();
self.md_robust();
var k_Colors = self = mkKind(5532, "Colors", "New or built-in colors");
var k_Contact = self = mkKind(8, "Contact", "A contact");
self.md_isData();
self.md_walltap();
self.md_cap("contacts");
var k_Contract = self = mkKind(0, "Contract", "Correctness helpers");
self.md_skill(3);
var k_Create = self = mkKind(0, "Create", "Create collections of items.");
self.md_robust();
self.md_skill(2);
var k_DateTime = self = mkKind(1934, "DateTime", "A combination of date and time");
self.md_isData();
self.md_stem("dt");
self.md_immutable();
self.md_ctx("general", "indexkey", "cloudfield", "json");
self.md_serializable();
var k_Docs = self = mkKind(0, "Docs", "Doc rendering helpers");
var k_Document_ = self = mkKind(0, "Document", "A document resource");
self.md_isData();
self.md_stem("doc");
self.md_immutable();
var k_Editor = self = mkKind(0, "Editor", "An interface to TouchDevelop editor");
self.md_isData();
self.md_stem("editor");
self.md_ctx("general", "gckey");
var k_Enumerator = self = mkKind(0, "Enumerator", "An general enumerator");
self.md_isData();
self.md_ctx("none");
var k_EventBinding = self = mkKind(0, "Event Binding", "A handler attached to an event.");
self.md_isData();
self.md_stem("ev");
self.md_ctx("general");
var k_FormBuilder = self = mkKind(0, "Form Builder", "A builder to create HTML Form data");
self.md_isData();
self.md_stem("form");
var k_Invalid = self = mkKind(354, "Invalid", "Create invalid values");
self.md_skill(3);
var k_JsonBuilder = self = mkKind(0, "Json Builder", "A json data structure builder");
self.md_isData();
self.md_stem("jsb");
self.md_ctx("general", "enumerable", "json");
self.md_serializable();
var k_JsonObject = self = mkKind(858, "Json Object", "A json data structure.");
self.md_isData();
self.md_stem("js");
self.md_immutable();
self.md_ctx("general", "gckey", "enumerable", "cloudfield", "json");
self.md_serializable();
var k_Languages = self = mkKind(167, "Languages", "Translation, speech to text, ...");
self.md_skill(2);
var k_Link = self = mkKind(76, "Link", "A link to a video, image, email, phone number");
self.md_isData();
self.md_ctx("general", "gckey", "walltap", "cloudfield", "json");
self.md_serializable();
var k_Location_ = self = mkKind(167, "Location", "A geo coordinate (latitude, longitude, ...)");
self.md_isData();
self.md_stem("loc");
self.md_immutable();
self.md_ctx("general", "indexkey", "cloudfield", "json");
self.md_serializable();
var k_Locations = self = mkKind(257, "Locations", "Geo coordinates");
self.md_skill(3);
var k_MapPushpin = self = mkKind(0, "Map Pushpin", "A map pushpin");
self.md_isData();
self.md_stem("pushpin");
self.md_ctx("general", "gckey");
self.md_cap("maps");
var k_Map = self = mkKind(111, "Map", "A Bing map");
self.md_isData();
self.md_ctx("general", "gckey");
self.md_cap("maps");
var k_Maps = self = mkKind(66, "Maps", "Maps, location to address, address to location");
self.md_skill(3);
var k_Math_ = self = mkKind(4294, "Math", "Math goodness, abs, max, ...");
self.md_robust();
var k_Matrix = self = mkKind(0, "Matrix", "A 2D matrix of numbers");
self.md_isData();
self.md_stem("m");
self.md_enumerable();
self.md_serializable();
var k_Media = self = mkKind(2062, "Media", "Pictures and music...");
self.md_skill(2);
var k_Message = self = mkKind(77, "Message", "A post on a message board");
self.md_isData();
self.md_stem("msg");
self.md_ctx("general", "gckey", "walltap");
self.md_serializable();
var k_Number_ = self = mkKind(33205, "Number", "A number (possibly negative and/or fractional)");
self.md_isData();
self.md_stem("x");
self.md_icon("fa-calculator");
self.md_immutable();
self.md_isData();
self.md_builtin();
self.md_ctx("general", "indexkey", "cloudfield", "json");
self.md_robust();
self.md_idempotent();
var k_NumberMap = self = mkKind(2043, "Number Map", "A map of numbers to numbers");
self.md_isData();
self.md_stem("m");
self.md_enumerable();
self.md_serializable();
self.md_ctx("general", "json");
var k_OAuthResponse = self = mkKind(0, "OAuth Response", "OAuth 2.0 Access Token or Error as described in http://tools.ietf.org/html/rfc6749.");
self.md_isData();
self.md_stem("oauth res");
self.md_serializable();
self.md_ctx("general", "cloudfield", "json");
var k_Page = self = mkKind(47, "Page", "A page on a wall");
self.md_isData();
self.md_ctx("general", "gckey");
var k_PageButton = self = mkKind(307, "Page Button", "A page button on the wall");
self.md_isData();
self.md_ctx("general", "gckey", "walltap");
var k_Phone = self = mkKind(253, "Phone", "Phone numbers, vibrate, etc...");
self.md_skill(2);
var k_Picture = self = mkKind(3727, "Picture", "A picture");
self.md_isData();
self.md_stem("pic");
self.md_icon("fa-file-image-o");
self.md_walltap();
self.md_enumerable();
var k_Place = self = mkKind(37, "Place", "A named location");
self.md_isData();
self.md_ctx("general", "gckey", "walltap");
var k_Player = self = mkKind(610, "Player", "Play, stop or resume songs, ...");
self.md_skill(3);
var k_Ref = self = mkKind(0, "Ref", "A reference to a value", 'parametric');
self.md_isData();
self.md_stem("ref");
self.md_icon("fa-gift");
self.md_parametric("T");
var k_Senses = self = mkKind(430, "Senses", "Camera, location, microphone and other sensors");
var k_Gamepad_ = self = mkKind(0, "Gamepad", "A snapshot of the gamepad state");
self.md_isData();
self.md_immutable();
self.md_icon('fa-gamepad');
self.md_robust();
var k_ServerRequest = self = mkKind(0, "Server Request", "An incomming HTTP web request");
self.md_isData();
self.md_stem("request");
self.md_ctx("general", "gckey");
self.md_betaOnly();
var k_ServerResponse = self = mkKind(0, "Server Response", "An HTTP web response to be returned");
self.md_isData();
self.md_stem("resp");
self.md_ctx("general", "gckey");
self.md_betaOnly();
var k_Social = self = mkKind(119, "Social", "Emails, sms, contacts, calendar, ...");
self.md_skill(2);
var k_Song = self = mkKind(568, "Song", "A song");
self.md_isData();
self.md_icon("fa-headphones");
self.md_walltap();
var k_Sound = self = mkKind(287, "Sound", "A sound effect");
self.md_isData();
self.md_stem("snd");
self.md_icon("fa-headphones");
self.md_ctx("general", "gckey", "walltap");
var k_Spring = self = mkKind(0, "Spring", "A spring between two sprites.");
self.md_isData();
self.md_ctx("general", "gckey");
var k_Sprite = self = mkKind(16920, "Sprite", "A sprite");
self.md_isData();
self.md_icon("fa-rocket");
self.md_ctx("general", "gckey");
var k_SpriteAnimation = self = mkKind(0, "Sprite Animation", "A animation to animate sprite properties.");
self.md_isData();
self.md_stem("anim");
self.md_ctx("general");
var k_SpriteSet = self = mkKind(3475, "Sprite Set", "A collection of sprites");
self.md_isData();
self.md_stem("sprites");
self.md_icon("fa-list-ol");
self.md_ctx("general", "gckey", "enumerable");
var k_SpriteSheet = self = mkKind(0, "Sprite Sheet", "A sprite sheet which packs multiple frames in a single picture");
self.md_isData();
self.md_stem("sheet");
self.md_ctx("general");
var k_String_ = self = mkKind(12926, "String", "A piece of text");
self.md_isData();
self.md_stem("s");
self.md_icon("fa-file-text-o");
self.md_immutable();
self.md_isData();
self.md_builtin();
self.md_ctx("general", "indexkey", "cloudfield", "walltap", "enumerable", "json");
var k_StringMap = self = mkKind(856, "String Map", "A map from strings to strings");
self.md_isData();
self.md_stem("d");
self.md_enumerable();
self.md_serializable();
self.md_ctx("general", "json");
var k_Task = self = mkKind(0, "Task", "A task created with `async` keyword", 'parametric');
self.md_isData();
self.md_stem("task");
self.md_parametric("T");
var k_TextBox = self = mkKind(1029, "TextBox", "A text box");
self.md_isData();
self.md_stem("tb");
self.md_ctx("general", "gckey", "walltap");
var k_Time = self = mkKind(2528, "Time", "time and dates");
self.md_robust();
var k_Timer = self = mkKind(0, "Timer", "A timer");
self.md_isData();
self.md_icon("timer");
self.md_ctx("general", "gckey");
var k_Tutorial = self = mkKind(0, "Tutorial", "Support for interactive tutorials.");
self.md_skill(3);
var k_User = self = mkKind(0, "User", "A user account");
self.md_isData();
self.md_ctx("general", "indexkey", "cloudfield", "walltap", "json");
self.md_serializable();
self.md_icon("fa-user");
self.md_immutable();
self.md_isData();
self.md_ctx("general");
self.md_serializable();
var k_Vector3 = self = mkKind(1051, "Vector3", "A 3D vector");
self.md_isData();
self.md_stem("p");
self.md_immutable();
self.md_ctx("general", "indexkey", "walltap", "json");
self.md_serializable();
var k_Wall = self = mkKind(5098, "Wall", "Ask or display values on the wall...");
var k_WebEventSource = self = mkKind(0, "Web Event Source", "A Server-Sent-Events client");
self.md_isData();
self.md_stem("source");
var k_Web = self = mkKind(592, "Web", "Search and browse the web...");
self.md_skill(2);
var k_WebRequest = self = mkKind(60, "Web Request", "An HTTP web request");
self.md_isData();
self.md_stem("request");
self.md_ctx("general", "gckey");
var k_WebResponse = self = mkKind(40, "Web Response", "An HTTP web response");
self.md_isData();
self.md_stem("response");
self.md_ctx("general", "gckey");
var k_WebSocketMessage = self = mkKind(0, "Web Socket Message", "A web socket message");
self.md_isData();
self.md_stem("msg");
self.md_ctx("general");
var k_WebSocket_ = self = mkKind(0, "Web Socket", "A web socket");
self.md_isData();
self.md_stem("ws");
self.md_ctx("general");
var k_XmlObject = self = mkKind(176, "Xml Object", "An xml element or collection of elements");
self.md_isData();
self.md_stem("xml");
self.md_immutable();
self.md_ctx("general", "gckey", "enumerable");


// Property definitions

// properties of generic kinds
self = mkProp(0, k_Comparison, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Comparison, "run", "Run the inline action.", [mkArg("a", k_Comparison.getParameter(0)), mkArg("b", k_Comparison.getParameter(0))], k_Number_);
self = mkProp(0, k_Predicate, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Predicate, "run", "Run the inline action.", [mkArg("elt", k_Predicate.getParameter(0))], k_Boolean_);
self = mkProp(0, k_AtomicAction1, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_AtomicAction1, "run", "Run the inline action.", [mkArg("v", k_AtomicAction1.getParameter(0))], k_Nothing);
self = mkProp(0, k_Action1, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Action1, "run", "Run the inline action.", [mkArg("v", k_Action1.getParameter(0))], k_Nothing);
self = mkProp(0, k_NumberConverter, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_NumberConverter, "run", "Run the inline action.", [mkArg("elt", k_NumberConverter.getParameter(0))], k_Number_);
self = mkProp(0, k_StringConverter, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_StringConverter, "run", "Run the inline action.", [mkArg("elt", k_StringConverter.getParameter(0))], k_String_);
self = mkProp(0, k_Converter, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Converter, "run", "Run the inline action.", [mkArg("elt", k_Converter.getParameter(0))], k_Converter.getParameter(1));
self = mkProp(0, k_Collection, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Collection, "count", "Gets the number of objects.", [], k_Number_);
self = mkProp(0, k_Collection, "clear", "Removes all objects from the collection", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "add", "Adds an object", [mkArg("item", k_Collection.getParameter(0))], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "add many", "Adds many objects at once", [mkArg("items", k_Collection)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "index of", "Gets the index of the first occurrence of an object. Returns -1 if not found or start is out of range.", [mkArg("item", k_Collection.getParameter(0)), mkArg("start", k_Number_)], k_Number_);
self = mkProp(0, k_Collection, "at", "Gets the object at position index. Returns invalid if index is out of range", [mkArg("index", k_Number_)], k_Collection.getParameter(0));
self = mkProp(0, k_Collection, "contains", "Checks if the item is in the collection", [mkArg("item", k_Collection.getParameter(0))], k_Boolean_);
self = mkProp(0, k_Collection, "remove", "Removes the first occurence of an object. Returns true if removed.", [mkArg("item", k_Collection.getParameter(0))], k_Boolean_);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(0, k_Collection, "remove at", "Removes the object at position index.", [mkArg("index", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "reverse", "Reverses the order of objects in the collection", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "random", "Gets a random object from the collection. Returns invalid if the collection is empty.", [], k_Collection.getParameter(0));
self = mkProp(0, k_Collection, "set at", "Sets the object at position index. Does nothing if the index is out of range.", [mkArg("index", k_Number_), mkArg("item", k_Collection.getParameter(0))], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "insert at", "Inserts an object at position index. Does nothing if index is out of range.", [mkArg("index", k_Number_), mkArg("item", k_Collection.getParameter(0))], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Collection, "to json", "Exports a JSON representation of the contents.", [], k_JsonObject);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "from json", "Imports a JSON representation of the contents.", [mkArg("jobj", k_JsonObject)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self = mkProp(0, k_Collection, "where", "Returns a collections of elements that satisfy the filter `condition`", [mkArg("condition", k_Predicate.createInstance([k_Collection.getParameter(0)]))], k_Collection);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
multiplex = TDev.MultiplexRootProperty.md_make_kind();
multiplex.md_parametric("S");
self = TDev.MultiplexRootProperty.md_make_prop(multiplex, 0, k_Collection, "map to", "Applies `converter` on all elements of the input collection and returns a collection of results", [mkArg("converter", k_Converter.createInstance([k_Collection.getParameter(0), multiplex.getParameter(0)]))], k_Collection.createInstance([multiplex.getParameter(0)]));
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "sorted", "Returns a collection sorted using specified `comparison` function", [mkArg("comparison", k_Comparison.createInstance([k_Collection.getParameter(0)]))], k_Collection);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "ordered by", "Returns a collection sorted using specified comparison key", [mkArg("key", k_NumberConverter.createInstance([k_Collection.getParameter(0)]))], k_Collection);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "ordered by string", "Returns a collection sorted using specified comparison key", [mkArg("key", k_StringConverter.createInstance([k_Collection.getParameter(0)]))], k_Collection);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "take", "Returns a collection with the `count` first elements if any.", [mkArg("count", k_Number_)], k_Collection);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "slice", "Returns a slice of the collection starting at `start`, and ends at, but does not include, the `end`.", [mkArg("start", k_Number_), mkArg("end", k_Number_)], k_Collection);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collection, "first", "Gets the first element if any", [], k_Collection.getParameter(0));
self = mkProp(0, k_Collection, "last", "Gets the last element if any", [], k_Collection.getParameter(0));
self = mkProp(0, k_Collection, "post to wall", "Display all objects on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Collection, "pick entry", "Ask user to pick an entry from this collection", [mkArg("text", k_String_)], k_Collection.getParameter(0));
self.md_resumes();
self.md_uiAsync();
self = mkProp(0, k_Collection, "sum of", "Computes the sum of the key of the elements in the collection", [mkArg("key", k_NumberConverter.createInstance([k_Collection.getParameter(0)]))], k_Number_);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Collection, "max of", "Computes the maximum of the key of the elements in the collection", [mkArg("key", k_NumberConverter.createInstance([k_Collection.getParameter(0)]))], k_Number_);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Collection, "avg of", "Computes the average of the key of the elements in the collection", [mkArg("key", k_NumberConverter.createInstance([k_Collection.getParameter(0)]))], k_Number_);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Collection, "min of", "Computes the minimum of the key of the elements in the collection", [mkArg("key", k_NumberConverter.createInstance([k_Collection.getParameter(0)]))], k_Number_);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Collection, "min", "Computes the minimum of the values", [], k_Number_);
self.md_readsMutable();
self.md_onlyOn("Number");
self = mkProp(0, k_Collection, "max", "Computes the maximum of the values", [], k_Number_);
self.md_readsMutable();
self.md_onlyOn("Number");
self = mkProp(0, k_Collection, "sum", "Computes the sum of the values", [], k_Number_);
self.md_readsMutable();
self.md_onlyOn("Number");
self = mkProp(0, k_Collection, "avg", "Computes the average of the values", [], k_Number_);
self.md_readsMutable();
self.md_onlyOn("Number");
self = mkProp(0, k_Collection, "sort by date", "Sorts from the newest to oldest", [], k_Nothing);
self.md_writesMutable();
self.md_onlyOn("Message");
self = mkProp(0, k_Collection, "sort", "Sorts the strings in this collection", [], k_Nothing);
self.md_writesMutable();
self.md_onlyOn("Number", "String");
self = mkProp(0, k_Collection, "sort by distance", "Sorts the places by distance to the location", [mkArg("loc", k_Location_)], k_Nothing);
self.md_writesMutable();
self.md_onlyOn("Location", "Place");
self = mkProp(0, k_Collection, "join", "Concatenates the separator and items into a string", [mkArg("separator", k_String_)], k_String_);
self.md_readsMutable();
self.md_onlyOn("Number", "String");
self = mkProp(0, k_Collection, "continuation", "Gets the identifier of the next set of items (if any)", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Collection, "set continuation", "Sets the identifier of the next set of items", [mkArg("value", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Ref, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Ref, "◈get", "Get the current value of the reference", [], k_Ref.getParameter(0));
self.md_needsFrame();
self.md_jsName("_get");
self = mkProp(0, k_Ref, "◈confirmed", "Check if reference has been written to the storage/server", [], k_Boolean_);
self.md_needsFrame();
self.md_jsName("_confirmed");
self = mkProp(0, k_Ref, "◈set", "Set the value of the reference", [mkArg("t", k_Ref.getParameter(0))], k_Nothing);
self.md_needsFrame();
self.md_jsName("_set");
self = mkProp(0, k_Ref, "◈clear", "Set reference to invalid", [], k_Nothing);
self.md_needsFrame();
self.md_jsName("_clear");
self = mkProp(0, k_Ref, "◈ref", "Retrive the reference itself (useful on globals and fields)", [], k_Ref);
self.md_needsFrame();
self.md_jsName("_ref");
self = mkProp(0, k_Ref, "◈add", "Add specified value to given reference", [mkArg("v", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_onlyOn("Number");
self.md_jsName("_add");
self = mkProp(0, k_Ref, "◈test and set", "Set reference to `v` if it's currently non-empty", [mkArg("v", k_Ref.getParameter(0))], k_Nothing);
self.md_needsFrame();
self.md_onlyOn("String");
self.md_jsName("_test_and_set");
self = mkProp(0, k_Ref, "◈with notify", "Create a new ref, that invokes `on changed` whenever the update is performed through it", [mkArg("on changed", k_Action)], k_Ref);
self.md_needsFrame();
self.md_dbgOnly();
self.md_jsName("_with_notify");
self = mkProp(0, k_Task, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Task, "completed", "Check if the task is done yet", [], k_Boolean_);
self = mkProp(0, k_Task, "await", "Wait for the task to finish, and return any possible value", [], k_Task.getParameter(0));
self.md_resumes();
self.md_async();
self = mkProp(0, k_Task, "value", "Get the value of the task, which must have completed.", [], k_Task.getParameter(0));
self = mkProp(0, k_Task, "await at most", "Wait for the task to finish for at most `seconds`; returns invalid in case of timeout", [mkArg("seconds", k_Number_)], k_Task.getParameter(0));
self.md_resumes();
self.md_async();

// initialization of generic kinds
k_Comparison.initProperties();
k_Predicate.initProperties();
k_AtomicAction1.initProperties();
k_Action1.initProperties();
k_NumberConverter.initProperties();
k_StringConverter.initProperties();
k_Converter.initProperties();
k_Collection.initProperties();
k_Ref.initProperties();
k_Task.initProperties();
self = mkProp(0, k_Action, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Action, "run", "Run the inline action.", [], k_Nothing);
self = mkProp(0, k_TextAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_TextAction, "run", "Run the inline action.", [mkArg("text", k_String_)], k_Nothing);
self = mkProp(0, k_NumberAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_NumberAction, "run", "Run the inline action.", [mkArg("x", k_Number_)], k_Nothing);
self = mkProp(0, k_BooleanAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_BooleanAction, "run", "Run the inline action.", [mkArg("boolean", k_Boolean_)], k_Nothing);
self = mkProp(0, k_PositionAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_PositionAction, "run", "Run the inline action.", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self = mkProp(0, k_SpriteAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_SpriteAction, "run", "Run the inline action.", [mkArg("sprite", k_Sprite)], k_Nothing);
self = mkProp(0, k_SpriteSetAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_SpriteSetAction, "run", "Run the inline action.", [mkArg("sprites", k_SpriteSet)], k_Nothing);
self = mkProp(0, k_VectorAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_VectorAction, "run", "Run the inline action.", [mkArg("x", k_Number_), mkArg("y", k_Number_), mkArg("delta x", k_Number_), mkArg("delta y", k_Number_)], k_Nothing);
self = mkProp(0, k_WebResponseAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebResponseAction, "run", "Run the inline action.", [mkArg("response", k_WebResponse)], k_Nothing);
self = mkProp(0, k_CollectionMessageAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_CollectionMessageAction, "run", "Run the inline action.", [mkArg("msgs", k_Collection.createInstance([k_Message]))], k_Nothing);
self = mkProp(0, k_JsonAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_JsonAction, "run", "Run the inline action.", [mkArg("json", k_JsonObject)], k_Nothing);
self = mkProp(0, k_AtomicAction, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_AtomicAction, "run", "Run the inline action.", [], k_Nothing);
self = mkProp(0, k_AppLogger, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_AppLogger, "debug", "Logs a debug message", [mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_AppLogger, "info", "Logs an informational message", [mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_AppLogger, "warning", "Logs a warning message", [mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_AppLogger, "error", "Logs an error message", [mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_AppLogger, "log", "Logs a new message with optional metadata. The level follows the syslog convention.", [mkArg("level", k_String_), mkArg("message", k_String_), mkArg("meta", k_JsonObject)], k_Nothing);
self.md_needsFrame();
self.md_arg("level").md_deflStrings("info", "debug", "warning", "error");
self.md_arg("meta").md_deflExpr('invalid->json_object');
self = mkProp(0, k_AppLogger, "set verbosity", "Set minimum logging level for this logger (defaults to \"debug\").", [mkArg("level", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("level").md_deflStrings("info", "debug", "warning", "error");
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "verbosity", "Get the current logging level for this logger (defaults to \"debug\").", [], k_String_);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "set context user", "Get the userid attached to the current context, or empty.", [mkArg("userid", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "context user", "Get the userid attached to the current context, or empty.", [], k_String_);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "context id", "The unique id of current context, or empty if in global scope.", [], k_String_);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "context pause", "Stop counting time in all current contexts", [], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "context resume", "Start counting time again in all current contexts", [], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "logger duration", "How long the current logger has been executing for in milliseconds.", [], k_Number_);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "context duration", "How long the current context has been executing for in milliseconds.", [], k_Number_);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "tick", "Log a custom event tick in any registered performance logger.", [mkArg("id", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "custom tick", "Log a custom event tick, including specified meta information, in any registered performance logger.", [mkArg("id", k_String_), mkArg("meta", k_JsonObject)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "measure", "Log a measure in any registered performance logger.", [mkArg("id", k_String_), mkArg("value", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "new context", "Start new logging context when you're starting a new task (eg, handling a request)", [], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "start", "Starts a timed sub-logger. The task name is concatenated to the current logger category.", [mkArg("task", k_String_)], k_AppLogger);
self.md_betaOnly();
self = mkProp(0, k_AppLogger, "end", "Ends a time sub-logger and reports the time.", [], k_Nothing);
self.md_betaOnly();
self = mkProp(0, k_AppEnv, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_AppEnv, "temporary setting", "Retreives an in-memory editor setting", [mkArg("key", k_String_)], k_String_);
self.md_flow("SourceWeb");
self = mkProp(0, k_AppEnv, "set temporary setting", "Sets an in-memory editor setting. The setting is stored until the page is refreshed", [mkArg("key", k_String_), mkArg("value", k_String_)], k_Nothing);
self.md_flow("SinkWeb");
self = mkProp(0, k_AppEnv, "user agent", "Get the browser name and version", [], k_String_);
self = mkProp(0, k_AppEnv, "has shell", "Indicates if the `app->run_command` action can be used to run shell commands.", [], k_Boolean_);
self.md_betaOnly();
self = mkProp(0, k_AppEnv, "has host", "Indicates if the `app->host_exec` action can be used to run host commands.", [], k_Boolean_);
self.md_betaOnly();
self = mkProp(0, k_AppEnv, "runtime kind", "Where are we running from: \"editor\", \"website\", \"nodejs\", \"mobileapp\", \"plugin\"", [], k_String_);
self.md_needsFrame();
self = mkProp(0, k_AppEnv, "form factor", "Get device 'size': \"phone\", \"tablet\", or \"desktop\"", [], k_String_);
self = mkProp(0, k_AppEnv, "operating system", "Get current OS: \"windows\", \"osx\", \"linux\", \"wp\", \"ios\", \"android\", ...", [], k_String_);
self = mkProp(0, k_AppEnv, "backend url", "Return URL of the cloud backend service if any.", [], k_String_);
self.md_needsFrame();
self = mkProp(0, k_AppEnv, "initial url", "Initial URL used to launch the website; invalid when `->runtime kind` is \"editor\"", [], k_String_);
self = mkProp(0, k_App, "create logger", "Creates a specialized logger", [mkArg("category", k_String_)], k_AppLogger);
self = mkProp(0, k_App, "log", "Appends this message to the debug log.", [mkArg("message", k_String_)], k_Nothing);
self.md_oldName("time->log");
self = mkProp(0, k_App, "current handler", "Gets the binding of the current handler if any. This can be used to delete a handler from itself.", [], k_EventBinding);
self.md_needsFrame();
self = mkProp(0, k_App, "stop", "Stops the app.", [], k_Nothing);
self.md_resumes();
self = mkProp(0, k_App, "script id", "Gets the app script id if any; invalid if not available", [], k_String_);
self.md_needsFrame();
self = mkProp(0, k_App, "restart", "Restarts the app and pops a restart dialog", [mkArg("message", k_String_)], k_Nothing);
self.md_resumes();
self = mkProp(0, k_App, "fail if not", "Aborts the execution if the condition is false.", [mkArg("condition", k_Boolean_)], k_Nothing);
self.md_arg("condition").md_defl(true);
self = mkProp(0, k_App, "server setting", "When exported server-side, retreives the value of a setting stored on the server. If not optional, fails if missing. Returns invalid if missing.", [mkArg("key", k_String_), mkArg("optional", k_Boolean_)], k_String_);
self.md_needsFrame();
self = mkProp(0, k_App, "javascript", "When exported, run `script` instead of the body of the action", [mkArg("calling convention", k_String_), mkArg("script", k_String_)], k_Nothing);
self.md_arg("calling convention").md_defl("local");
self.md_arg("script").md_lang("js");
self = mkProp(0, k_App, "javascript async", "When exported, run `script` instead of the body of the action", [mkArg("calling convention", k_String_), mkArg("script", k_String_)], k_Nothing);
self.md_resumes();
self.md_async();
self.md_arg("calling convention").md_defl("local");
self.md_arg("script").md_lang("js");
self = mkProp(0, k_App, "import", "Imports a dependent package which may be versioned. Package managers may be Node.JS npm, Bower, Apache cordova, Python Pip and TouchDevelop plugins. ``bower`` and ``client`` imports are not available within the touchdevelop.com domain.", [mkArg("manager", k_String_), mkArg("module", k_String_), mkArg("version", k_String_)], k_Nothing);
self.md_arg("manager").md_deflStrings("npm", "cordova", "bower", "client", "touchdevelop", "pip");
self.md_arg("version").md_defl("*");
self.md_jsName("import_");
self = mkProp(0, k_App, "thumb", "When compiled to ARM Thumb, inline the body.", [mkArg("script", k_String_)], k_Nothing);
self.md_arg("script").md_lang("thumb");
self = mkProp(0, k_App, "server request", "Get the current incomming HTTP web request", [], k_ServerRequest);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_App, "server response", "Get the response corresponding to the current incomming HTTP web request", [], k_ServerResponse);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_App, "editor", "Get the Editor interface", [], k_Editor);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_App, "env", "Access various properties of application environment", [], k_AppEnv);
self.md_betaOnly();
self = mkProp(0, k_App, "reflect", "Return runtime information about functions and types defined in script and its libraries", [mkArg("what", k_String_)], k_JsonObject);
self.md_needsFrame();
self.md_betaOnly();
self.md_arg("what").md_deflStrings("actions");
self = mkProp(0, k_App, "run command", "Runs a shell command. This action is only available when the script is running from a local web server.", [mkArg("cmd", k_String_), mkArg("data", k_JsonObject)], k_JsonObject);
self.md_resumes();
self.md_arg("cmd").md_deflStrings("shell", "mkdir", "writeFile", "readFile", "readDir", "writeFiles", "pythonEnv", "socket", "seriallist");
self.md_cap("shell");
self.md_async();
self = mkProp(0, k_App, "show logs", "Shows a dialog with the logs", [mkArg("filter", k_String_)], k_Nothing);
self.md_resumes();
self.md_uiAsync();
self.md_betaOnly();
self = mkProp(0, k_App, "consume rendered comments", "Get HTML-rendered content of all comments 'executed' since last call", [], k_String_);
self.md_needsFrame();
self.md_dbgOnly();
self = mkProp(0, k_App, "host exec", "Invokes the host to execute a command described in the message and returns the response. There is no restriction on the format of the request and response. If not available or errored, returns invalid.", [mkArg("message", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_readsMutable();
self.md_betaOnly();
self = mkProp(0, k_App, "host subscribe", "Invokes the host to register an event listener described in the message.", [mkArg("message", k_String_), mkArg("handler", k_TextAction)], k_EventBinding);
self.md_resumes();
self.md_async();
self.md_readsMutable();
self.md_betaOnly();
self.md_ignoreReturnValue();
self = mkProp(0, k_App, "allow other events", "Allow execution of other events, before the current event finishes.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Bazaar, "user of", "Returns a user object for a specified user id", [mkArg("id", k_String_)], k_User);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(0, k_Bazaar, "current user", "Returns the user object of the current user", [], k_User);
self.md_resumes();
self.md_authAsync();
self = mkProp(17, k_Bazaar, "leaderboard score", "Gets the current score for the current script", [], k_Number_);
self.md_resumes();
self.md_async();
self.md_tandre();
self.md_hasPauseContinue();
self.md_readsMutable();
self = mkProp(105, k_Bazaar, "post leaderboard score", "Posts the current game score to the script leaderboard", [mkArg("score", k_Number_)], k_Nothing);
self.md_resumes();
self.md_async();
self.md_writesMutable();
self = mkProp(73, k_Bazaar, "post leaderboard to wall", "Posts the current game leaderboard to the wall", [], k_Nothing);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(0, k_Bazaar, "merge3", "three-way merge script texts. Debug only: for testing.", [mkArg("O", k_String_), mkArg("A", k_String_), mkArg("B", k_String_)], k_String_);
self.md_dbgOnly();
self = mkProp(0, k_Bazaar, "open", "Launches the bazaar.", [], k_Nothing);
self.md_obsolete();
self = mkProp(0, k_Bazaar, "open review", "Opens the review page for the current script", [], k_Nothing);
self.md_obsolete();
self = mkProp(0, k_Bazaar, "open leaderboard", "Opens the leaderboard for the current script", [], k_Nothing);
self.md_resumes();
self.md_obsolete();
self = mkProp(0, k_Bazaar, "script id", "Returns an identifier of either the top-level script or the current library", [mkArg("which", k_String_)], k_String_);
self.md_needsFrame();
self.md_arg("which").md_deflStrings("top", "current");
self = mkProp(0, k_Bazaar, "pick script", "Asks the user to pick a script and return its identifier", [mkArg("mode", k_String_), mkArg("message", k_String_)], k_String_);
self.md_resumes();
self.md_arg("mode").md_deflStrings("read", "write", "read-write");
self.md_uiAsync();
self = mkProp(0, k_Bazaar, "save ast", "Saves given Abstract Syntax Tree as a script", [mkArg("id", k_String_), mkArg("script", k_JsonObject)], k_Nothing);
self.md_resumes();
self.md_uiAsync();
self = mkProp(0, k_Bazaar, "ast of", "Returns the Abstract Syntax Tree JSON object for specified script", [mkArg("id", k_String_)], k_JsonObject);
self.md_resumes();
self.md_arg("id").md_deflExpr('bazaar->script_id("current")');
self.md_uiAsync();
self = mkProp(0, k_Bits, "add uint32", "Add two unsigned 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "subtract uint32", "Subtract two unsigned 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "multiply uint32", "Multiply two unsigned 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "add int32", "Add two signed 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "subtract int32", "Subtract two signed 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "multiply int32", "Multiply two signed 32 bit numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "and uint32", "Perform bitwise and (`&` in C)", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "or uint32", "Perform bitwise or (`|` in C)", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "and int32", "Perform bitwise and (`&` in C) on signed integers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "or int32", "Perform bitwise or (`|` in C) on signed integers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "xor uint32", "Perform bitwise exclusive or (`^` in C)", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "not uint32", "Perform bitwise negation (`~` in C)", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "shift left uint32", "Shift `x` by `bits` left (`<<` in C)", [mkArg("x", k_Number_), mkArg("bits", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "shift right uint32", "Shift `x` by `bits` right (`>>` in C, `>>>` in JavaScript)", [mkArg("x", k_Number_), mkArg("bits", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "rotate left uint32", "Rotate `x` by `bits` left (rotl)", [mkArg("x", k_Number_), mkArg("bits", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "rotate right uint32", "Rotate `x` by `bits` right (rotr)", [mkArg("x", k_Number_), mkArg("bits", k_Number_)], k_Number_);
self = mkProp(0, k_Bits, "create buffer", "Creates an empty binary buffer of `size` bytes", [mkArg("size", k_Number_)], k_Buffer);
self.md_arg("size").md_defl(32);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Bits, "string to buffer", "Decodes string into a binary buffer", [mkArg("s", k_String_), mkArg("encoding", k_String_)], k_Buffer);
self.md_arg("encoding").md_deflStrings("base64", "hex", "binary", "utf8", "utf16le");
self = mkProp(28, k_Board, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(942, k_Board, "height", "Gets the height in pixels", [], k_Number_);
self = mkProp(15, k_Board, "count", "Gets the sprite count", [], k_Number_);
self.md_readsMutable();
self = mkProp(1241, k_Board, "width", "Gets the width in pixels", [], k_Number_);
self = mkProp(666, k_Board, "touched", "True if board is touched", [], k_Boolean_);
self.md_tandre();
self = mkProp(92, k_Board, "touch start", "Last touch start point", [], k_Vector3);
self.md_tandre();
self = mkProp(144, k_Board, "touch current", "Current touch point", [], k_Vector3);
self.md_tandre();
self = mkProp(27, k_Board, "touch end", "Last touch end point", [], k_Vector3);
self.md_tandre();
self = mkProp(2, k_Board, "touch velocity", "Final touch velocity after touch ended", [], k_Vector3);
self.md_tandre();
self = mkProp(98, k_Board, "create boundary", "Create walls around the board at the given distance.", [mkArg("distance", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(699, k_Board, "create sprite set", "Create a new collection for sprites.", [], k_SpriteSet);
self = mkProp(0, k_Board, "frame timer", "gets the timer that fires for every display frame.", [], k_Timer);
self.md_needsFrame();
self = mkProp(0, k_Board, "add on every frame", "add an action that fires for every display frame.", [mkArg("body", k_Action)], k_EventBinding);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(0, k_Board, "on every frame", "add an action that fires for every display frame.", [mkArg("body", k_Action)], k_EventBinding);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(0, k_Board, "clear every frame timers", "Stops and clears all the `every frame` timers", [], k_Nothing);
self = mkProp(0, k_Board, "on tap", "set the handler that is invoked when the board is tapped", [mkArg("tapped", k_PositionAction)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_Board, "on swipe", "set the handler that is invoked when the board is swiped", [mkArg("swiped", k_VectorAction)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_Board, "on touch down", "set the handler that is invoked when the board is touched", [mkArg("touch down", k_PositionAction)], k_EventBinding);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(0, k_Board, "on touch up", "set the handler that is invoked when the board touch is released", [mkArg("touch up", k_PositionAction)], k_EventBinding);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(265, k_Board, "evolve", "Update positions of sprites on board.", [], k_Nothing);
self.md_timestamp();
self.md_writesMutable();
self = mkProp(0, k_Board, "equals", "Checks if the board is the same instance as the other board.", [mkArg("other board", k_Board)], k_Boolean_);
self = mkProp(0, k_Board, "background scene", "Gets the background scene", [], k_BoardBackgroundScene);
self.md_readsMutable();
self = mkProp(678, k_Board, "set background", "Sets the background color", [mkArg("color", k_Color)], k_Nothing);
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(10, k_Board, "set background camera", "Sets the background camera", [mkArg("camera", k_Camera)], k_Nothing);
self.md_writesMutable();
self.md_cap("camera");
self.md_arg("camera").md_deflExpr('senses->camera');
self = mkProp(164, k_Board, "set background picture", "Sets the background picture", [mkArg("picture", k_Picture)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self.md_embedsLink("Board", "Picture");
self = mkProp(30, k_Board, "set debug mode", "In debug mode, board displays speed and other info of sprites", [mkArg("debug", k_Boolean_)], k_Nothing);
self.md_arg("debug").md_defl(true);
self = mkProp(25, k_Board, "set friction", "Sets the default friction for sprites to a fraction of speed loss between 0 and 1", [mkArg("friction", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("friction").md_defl(0.01);
self = mkProp(1, k_Board, "is landscape", "Gets a value indicating if the board is designed to be viewed in landscape mode", [], k_Boolean_);
self = mkProp(98, k_Board, "set gravity", "Sets the uniform acceleration vector for objects on the board to pixels/sec^2", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("y").md_defl(200);
self = mkProp(96, k_Board, "at", "Gets the sprite indexed by i", [mkArg("i", k_Number_)], k_Sprite);
self.md_readsMutable();
self = mkProp(1342, k_Board, "update on wall", "Make updates visible.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(445, k_Board, "create ellipse", "Create a new ellipse sprite.", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Sprite);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(20);
self.md_arg("height").md_defl(20);
self.md_embedsLink("Board", "Sprite");
self = mkProp(698, k_Board, "create rectangle", "Create a new rectangle sprite.", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Sprite);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(20);
self.md_arg("height").md_defl(20);
self.md_embedsLink("Board", "Sprite");
self = mkProp(1926, k_Board, "create text", "Create a new text sprite.", [mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("font Size", k_Number_), mkArg("text", k_String_)], k_Sprite);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(40);
self.md_arg("font Size").md_defl(20);
self.md_embedsLink("Board", "Sprite");
self = mkProp(626, k_Board, "create picture", "Create a new picture sprite.", [mkArg("picture", k_Picture)], k_Sprite);
self.md_resumes();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_picAsync();
self.md_embedsLink("Board", "Sprite");
self.md_embedsLink("Sprite", "Picture");
self = mkProp(0, k_Board, "create sprite sheet", "Create a new sprite sheet.", [mkArg("picture", k_Picture)], k_SpriteSheet);
self.md_resumes();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_picAsync();
self.md_embedsLink("Board", "SpriteSheet");
self.md_embedsLink("SpriteSheet", "Picture");
self = mkProp(3, k_Board, "create anchor", "Create an anchor sprite.", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Sprite);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(20);
self.md_arg("height").md_defl(20);
self.md_embedsLink("Board", "Sprite");
self = mkProp(590, k_Board, "create obstacle", "Create a line obstacle with given start point, and given width and height. Elasticity is 0 for sticky, 1 for complete bounce.", [mkArg("x", k_Number_), mkArg("y", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("elasticity", k_Number_)], k_Obstacle);
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("elasticity").md_defl(1);
self = mkProp(11, k_Board, "create spring", "Create a spring between the two sprites.", [mkArg("sprite1", k_Sprite), mkArg("sprite2", k_Sprite), mkArg("stiffness", k_Number_)], k_Spring);
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("stiffness").md_defl(100);
self = mkProp(56, k_Board, "clear events", "Clear all queued events related to this board", [], k_Nothing);
self = mkProp(1, k_Board, "clear background camera", "Clears the background camera", [], k_Nothing);
self.md_cap("camera");
self = mkProp(5, k_Board, "clear background picture", "Clear the background picture", [], k_Nothing);
self = mkProp(1122, k_Board, "post to wall", "Shows the board on the wall.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Obstacle, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Obstacle, "on collision", "Attaches a handler where a sprite bounces on the obstacle", [mkArg("bounce", k_SpriteAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Obstacle, "set color", "Sets the obstacle color", [mkArg("color", k_Color)], k_Nothing);
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(0, k_Obstacle, "set thickness", "Sets the obstacle thickness", [mkArg("thickness", k_Number_)], k_Nothing);
self.md_arg("thickness").md_defl(3);
self = mkProp(0, k_Obstacle, "delete", "Delete the obstacle", [], k_Nothing);
self = mkProp(0, k_BoardBackgroundScene, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_BoardBackgroundScene, "view x", "Gets the view horizontal offset", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundScene, "set view x", "Sets the view horizontal offset", [mkArg("x", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundScene, "view y", "Gets the view vertical offset", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundScene, "set view y", "Sets the view vertical offset", [mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundScene, "create layer", "Creates a new layer on the scene. The distance determines the order of rendering and how fast the layer moves", [mkArg("distance", k_Number_), mkArg("pic", k_Picture)], k_BoardBackgroundLayer);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self.md_ignoreReturnValue();
self.md_embedsLink("BoardBackgroundScene", "BoardBackgroundLayer");
self = mkProp(0, k_BoardBackgroundScene, "count", "Gets the number of layers in the scene", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundScene, "at", "Gets the layer at the given index", [mkArg("index", k_Number_)], k_BoardBackgroundLayer);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundScene, "clear", "Removes all layers from scene and resets the viewport", [], k_Nothing);
self = mkProp(0, k_BoardBackgroundScene, "post to wall", "Displays the sprite sheet.", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_BoardBackgroundLayer, "picture", "Gets the picture associated to the layer.", [], k_Nothing);
self = mkProp(0, k_BoardBackgroundLayer, "distance", "Gets the layer distance", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "set distance", "Sets the layer distance", [mkArg("d", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundLayer, "align x", "Gets a value indicating how the picture aligns horizontally. The default is `left`.", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "set align x", "Sets a value indicating how the picture aligns horizontally. The default is `left`.", [mkArg("align", k_String_)], k_Nothing);
self.md_arg("align").md_deflStrings("right", "left", "center");
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundLayer, "align y", "Gets a value indicating how the picture aligns vertically. The default is `top`.", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "set align y", "Sets a value indicating how the picture aligns vertically. The default is `top`.", [mkArg("align", k_String_)], k_Nothing);
self.md_arg("align").md_deflStrings("bottom", "top", "center");
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundLayer, "repeat x", "Gets a value indicating if the background repeats horizontally", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "set repeat x", "Sets a value indicating if the background repeats horizontally", [mkArg("repeat", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_BoardBackgroundLayer, "repeat y", "Gets a value indicating if the background repeats horizontally", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_BoardBackgroundLayer, "set repeat y", "Sets a value indicating if the background repeats horizontally", [mkArg("repeat", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self = mkProp(12, k_Boolean_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(327, k_Boolean_, "equals", "Indicates that the two values are equal", [mkArg("right", k_Boolean_)], k_Boolean_);
self = mkProp(1511, k_Boolean_, "not", "Negates the boolean expression", [], k_Boolean_);
self.md_infixPriority(4);
self = mkProp(1411, k_Boolean_, "and", "Builds conjunction", [mkArg("right", k_Boolean_)], k_Boolean_);
self.md_infixPriority(3);
self = mkProp(1002, k_Boolean_, "or", "Builds disjunction", [mkArg("right", k_Boolean_)], k_Boolean_);
self.md_infixPriority(2);
self = mkProp(31, k_Boolean_, "to string", "Converts a boolean to a string", [], k_String_);
self = mkProp(18, k_Boolean_, "to number", "Converts true to 1 and false to 0", [], k_Number_);
self = mkProp(9, k_Boolean_, "post to wall", "Displays the value on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Boolean_, "to json", "Converts the value into a json data structure.", [], k_JsonObject);
self = mkProp(0, k_Box, "set foreground", "Sets the foreground color of elements.", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(0, k_Box, "set background", "Sets the background color.", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(0, k_Box, "add background picture", "Sets the background picture. The picture must be a resource or from the web. The size of the picture does not impact the size of the box.", [mkArg("pic", k_Picture), mkArg("position", k_String_), mkArg("size", k_String_), mkArg("repeat", k_String_), mkArg("attachment", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("position").md_deflStrings('center center', 'left top', 'left center', 'left bottom', 'right top', 'right center','right bottom','center top','center bottom');
self.md_arg("size").md_deflStrings('cover', 'contain', 'auto');
self.md_arg("repeat").md_deflStrings('no-repeat', 'repeat', 'repeat-x', 'repeat-y');
self.md_arg("attachment").md_deflStrings('scroll', 'fixed', 'local');
self = mkProp(0, k_Box, "use vertical layout", "Arrange boxes inside this box from top to bottom.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "use horizontal layout", "Arrange boxes inside this box from left to right.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "use overlay layout", "Arrange boxes inside this box as layers on top of each other.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set width", "Set the width of this box.", [mkArg("width", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set height", "Set the height of this box.", [mkArg("height", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set width range", "Set lower and upper limits on the width of this box.", [mkArg("min width", k_Number_), mkArg("max width", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set height range", "Set lower and upper limits on the height of this box.", [mkArg("min height", k_Number_), mkArg("max height", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set horizontal stretch", "Specify how to compute box width (0 = shrink to fit content, 1 = stretch to fit frame, , 0.5 = stretch to half width)", [mkArg("elasticity", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("elasticity").md_defl(1);
self = mkProp(0, k_Box, "set vertical stretch", "Specify how to compute box height (0 = shrink to fit content, 1 = stretch to fit frame, 0.5 = stretch to half height)", [mkArg("elasticity", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("elasticity").md_defl(1);
self = mkProp(0, k_Box, "set border", "Set the color and width of the border.", [mkArg("color", k_Color), mkArg("width", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("color").md_deflExpr('colors->foreground');
self.md_arg("width").md_defl(0.1);
self = mkProp(0, k_Box, "set border widths", "Set the width of each border.", [mkArg("top", k_Number_), mkArg("right", k_Number_), mkArg("bottom", k_Number_), mkArg("left", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set margins", "Set the margins of this box (to leave space around the outside of this box).", [mkArg("top", k_Number_), mkArg("right", k_Number_), mkArg("bottom", k_Number_), mkArg("left", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("left").md_defl(0.5);
self.md_arg("top").md_defl(0.5);
self = mkProp(0, k_Box, "set padding", "Set the padding of this box (to leave space around the contents of this box).", [mkArg("top", k_Number_), mkArg("right", k_Number_), mkArg("bottom", k_Number_), mkArg("left", k_Number_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "set horizontal alignment", "align (0,0)=center (1,0)=left, (0,1)=right, (1,1)=stretch", [mkArg("left", k_Number_), mkArg("right", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_obsolete();
self = mkProp(0, k_Box, "set vertical alignment", "align (0,0)=center (1,0)=top, (0,1)=bottom, (1,1)=stretch", [mkArg("top", k_Number_), mkArg("bottom", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_obsolete();
self = mkProp(0, k_Box, "set horizontal align", "Specify how to arrange the content of this box", [mkArg("arrange", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("arrange").md_defl("left");
self.md_arg("arrange").md_deflStrings("center", "left", "right", "justify", "spread");
self = mkProp(0, k_Box, "set vertical align", "Specify how to arrange the content of this box", [mkArg("arrange", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("arrange").md_defl("baseline");
self.md_arg("arrange").md_deflStrings("baseline", "top", "bottom", "center", "justify", "spread");
self = mkProp(0, k_Box, "set font size", "Set font size in this box and contained boxes.", [mkArg("font size", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("font size").md_defl(1);
self = mkProp(0, k_Box, "set font weight", "Set font weight in this box and contained boxes.", [mkArg("font weight", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("font weight").md_defl("bold");
self.md_arg("font weight").md_deflStrings("normal", "bold", "lighter", "bolder");
self = mkProp(0, k_Box, "set font family", "Set font family in this box and contained boxes.", [mkArg("family", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("family").md_defl("Default");
self.md_arg("family").md_deflStrings("Default", "Arial, Helvetica, sans-serif", "Courier New, Courier, monospace", "Georgia, serif", "Lucida Console, Monaco, monospace", "Lucida Sans Unicode, Lucida Grande, sans - serif", "Palatino Linotype, Book Antiqua, Palatino, serif", "Tahoma, Geneva, sans - serif", "Times New Roman, Times, serif", "Trebuchet MS, sans-serif", "Verdana, Geneva, sans-serif", "Comic Sans MS, cursive");
self.md_dbgOnly();
self = mkProp(0, k_Box, "set scrolling", "Specify whether to use scrollbars on overflow.", [mkArg("horizontal scrolling", k_Boolean_), mkArg("vertical scrolling", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self.md_arg("horizontal scrolling").md_defl(true);
self.md_arg("vertical scrolling").md_defl(true);
self = mkProp(0, k_Box, "on tapped", "Set what happens when the box is tapped.", [mkArg("handler", k_Action)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Box, "on text editing", "Set what happens whenever the text in the box is being edited.", [mkArg("handler", k_TextAction)], k_Nothing);
self.md_needsFrame();
self.md_obsolete();
self = mkProp(0, k_Box, "on text edited", "Set what happens when the user has finished editing the text in the box.", [mkArg("handler", k_TextAction)], k_Nothing);
self.md_needsFrame();
self.md_obsolete();
self = mkProp(0, k_Box, "edit text", "Display editable text.", [mkArg("text", k_String_), mkArg("multiline", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self.md_obsolete();
self.md_arg("text").md_defl("");
self.md_arg("multiline").md_defl(true);
self = mkProp(0, k_Box, "edit", "Display editable text, for the given content and change handler.", [mkArg("style", k_String_), mkArg("value", k_String_), mkArg("changehandler", k_TextAction)], k_Nothing);
self.md_needsFrame();
self.md_arg("style").md_defl("textline");
self.md_arg("style").md_deflStrings("textline", "textarea", "number", "password");
self = mkProp(0, k_Box, "edit ref", "Display editable text, bound to the given string reference.", [mkArg("style", k_String_), mkArg("ref", k_Ref.createInstance([k_String_]))], k_Nothing);
self.md_needsFrame();
self.md_arg("style").md_defl("textline");
self.md_arg("style").md_deflStrings("textline", "textarea", "number", "password");
self = mkProp(0, k_Box, "is init", "", [], k_Boolean_);
self.md_needsFrame();
self.md_hidden();
self = mkProp(0, k_Box, "page width", "Get the total width of the page.", [], k_Number_);
self.md_needsFrame();
self = mkProp(0, k_Box, "page height", "Get the total height of the page.", [], k_Number_);
self.md_needsFrame();
self = mkProp(0, k_Box, "pixels per em", "Get the number of pixels in an em", [], k_Number_);
self = mkProp(0, k_Box, "set text wrapping", "Set whether to break long lines, and specify what length is too short for breaking", [mkArg("wrap", k_Boolean_), mkArg("minimumwidth", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_arg("wrap").md_readsMutable();
self.md_arg("wrap").md_defl(true);
self.md_arg("minimumwidth").md_defl(15);
self = mkProp(0, k_Dom, "use css", "Use CSS for layout and import additional CSS stylesheets. Use string art resource to import urls.", [mkArg("stylesheet", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "set tag name", "Specify the tagname for this element", [mkArg("name", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "add css class", "Add a CSS class name to the current element.", [mkArg("name", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "set attribute", "Specify an attribute for the current element.", [mkArg("name", k_String_), mkArg("value", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "set style", "Specify a style attribute for the current element.", [mkArg("property", k_String_), mkArg("value", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "bind value with handler", "Bind editable text, by giving current text and change handler.", [mkArg("value", k_String_), mkArg("changehandler", k_TextAction)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "bind value to ref", "Bind editable text, using a string reference.", [mkArg("ref", k_Ref.createInstance([k_String_]))], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Dom, "add on click", "Set what happens when this element is clicked.", [mkArg("body", k_Action)], k_Nothing);
self.md_needsFrame();
self.md_betaOnly();
self = mkProp(0, k_Buffer, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Buffer, "read number", "Read a binary number at `offset`", [mkArg("offset", k_Number_), mkArg("format", k_String_), mkArg("endian", k_String_)], k_Number_);
self.md_arg("format").md_deflStrings("int8", "uint8", "int16", "uint16", "int32", "uint32");
self.md_arg("endian").md_deflStrings("le", "be");
self = mkProp(0, k_Buffer, "write number", "Write a binary number `value` at `offset`", [mkArg("value", k_Number_), mkArg("offset", k_Number_), mkArg("format", k_String_), mkArg("endian", k_String_)], k_Nothing);
self.md_arg("format").md_deflStrings("int8", "uint8", "int16", "uint16", "int32", "uint32");
self.md_arg("endian").md_deflStrings("le", "be");
self = mkProp(0, k_Buffer, "set", "Set byte at `index` to `value`", [mkArg("index", k_Number_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Buffer, "at", "Get byte at `index`", [mkArg("index", k_Number_)], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Buffer, "count", "Return the number of bytes in the buffer", [], k_Number_);
self.md_robust();
self = mkProp(0, k_Buffer, "sha256", "Return the SHA-256 hash of the buffer encoded as lowercase hex", [], k_String_);
self.md_betaOnly();
self = mkProp(0, k_Buffer, "concat", "Return a new buffer consiting of the current and `other` in sequence", [mkArg("other", k_Buffer)], k_Buffer);
self = mkProp(0, k_Buffer, "sub buffer", "Creates a read-write view of the current buffer.", [mkArg("start", k_Number_), mkArg("length", k_Number_)], k_Buffer);
self.md_writesMutable();
self = mkProp(0, k_Buffer, "fill random", "Fills the buffer with random values", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Buffer, "fill", "Sets all bytes in buffer to `value`", [mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Buffer, "copy from", "Copies all bytes from `source` to current buffer at `offset`", [mkArg("target offset", k_Number_), mkArg("source", k_Buffer)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Buffer, "clone", "Copies all bytes from `source` to current buffer at `offset`", [], k_Buffer);
self.md_readsMutable();
self = mkProp(0, k_Buffer, "to string", "Convert the buffer to a string", [mkArg("encoding", k_String_)], k_String_);
self.md_arg("encoding").md_deflStrings("base64", "hex", "binary", "utf8", "utf16le");
self.md_readsMutable();
self = mkProp(0, k_Camera, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(7, k_Camera, "height", "Gets the height of the camera image in pixels.", [], k_Number_);
self.md_stub("");
self = mkProp(0, k_Camera, "is front", "Indicates if this camera is in front of the phone; false if this is the primary (back) camera.", [], k_Boolean_);
self = mkProp(1, k_Camera, "width", "Gets the width of the camera image in pixels.", [], k_Number_);
self.md_stub("");
self = mkProp(7, k_Camera, "post to wall", "Displays the camera video stream in full screen.", [], k_Nothing);
self.md_needsFrame();
self.md_flow("SourceCamera");
self = mkProp(18, k_Camera, "preview", "Takes a low quality picture from the camera.", [], k_Picture);
self.md_resumes();
self.md_flow("SourceCamera");
self.md_uiAsync();
self = mkProp(0, k_CloudSession, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_CloudSession, "equals", "Checks if this cloud session is the same as another one", [mkArg("other", k_CloudSession)], k_Boolean_);
self = mkProp(12, k_CloudSession, "id", "Gets a string that uniquely identifies this cloud session; other users can connect by using this string.", [], k_String_);
self = mkProp(13, k_CloudSession, "title", "Gets a string that describes this cloud session", [], k_String_);
self = mkProp(11, k_CloudSession, "owner", "Gets information about the user that owns this session", [], k_User);
self = mkProp(0, k_CloudSession, "is owned", "Indicates if the current user owns this session", [], k_Boolean_);
self.md_needsFrame();
self = mkProp(10, k_CloudSession, "post to wall", "Displays the session description on the wall.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_CloudSession, "server info", "Query server about current state of this session. You must be the authenticated owner.", [], k_JsonObject);
self.md_resumes();
self.md_async();
self.md_dbgOnly();
self = mkProp(15, k_CloudData, "current session", "Gets the currently active session. When the script starts, this is always the just-me session.", [], k_CloudSession);
self.md_needsFrame();
self = mkProp(0, k_CloudData, "rebuild cache", "Clear the local cache of the current session (discarding unsynced changes) and get fresh data from server", [], k_CloudSession);
self.md_resumes();
self.md_dbgOnly();
self.md_async();
self = mkProp(0, k_CloudData, "clear all data", "Clear all data of the currently active session.", [], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self = mkProp(0, k_CloudData, "to json", "Export a JSON representation of all the cloud data", [], k_JsonObject);
self.md_needsFrame();
self.md_dbgOnly();
self = mkProp(0, k_CloudData, "from json", "Import a JSON representation of the cloud data", [mkArg("jobj", k_JsonObject)], k_Nothing);
self.md_needsFrame();
self.md_dbgOnly();
self.md_writesMutable();
self = mkProp(12, k_CloudData, "last session", "Deprecated: always equal to current session.", [], k_CloudSession);
self.md_needsFrame();
self.md_obsolete();
self = mkProp(14, k_CloudData, "just me session", "Gets the just-me session, in which cloud data is shared between devices by the same user.", [], k_CloudSession);
self.md_needsFrame();
self = mkProp(0, k_CloudData, "set token validator", "`validator(token)` should return user id (eg, `\"fb:123456\"`) or `\"\"` in case token is invalid", [mkArg("validator", k_StringConverter.createInstance([k_String_]))], k_Nothing);
self.md_needsFrame();
self.md_dbgOnly();
self.md_writesMutable();
self = mkProp(0, k_CloudData, "authenticate", "Authenticate against your deployed cloud library. Returns false if the authentication fails or the connection times out.", [mkArg("access token", k_String_)], k_Boolean_);
self.md_resumes();
self.md_dbgOnly();
self.md_uiAsync();
self.md_writesMutable();
self = mkProp(13, k_CloudData, "everyone session", "Gets the everyone-session, in which cloud data is shared by everyone running this script.", [], k_CloudSession);
self.md_needsFrame();
self = mkProp(0, k_CloudData, "wait for server", "Waits until the current server state has been received. Returns false if offline, or if time limit is exceeded.", [mkArg("timeout", k_Number_)], k_Boolean_);
self.md_resumes();
self.md_arg("timeout").md_deflExpr(30);
self.md_async();
self.md_writesMutable();
self = mkProp(11, k_CloudData, "create session", "Creates a new cloud session owned by the current user.", [mkArg("title", k_String_), mkArg("type", k_String_)], k_CloudSession);
self.md_resumes();
self.md_arg("type").md_defl("shareable");
self.md_arg("type").md_deflStrings("shareable", "private", "broadcast");
self.md_async();
self.md_writesMutable();
self = mkProp(10, k_CloudData, "session of", "Gets a session from a session id", [mkArg("id", k_String_), mkArg("title", k_String_)], k_CloudSession);
self.md_needsFrame();
self = mkProp(9, k_CloudData, "connection status", "Gets a string that describes the state of the cloud synchronization, and additional details if requested", [mkArg("include extra details", k_Boolean_)], k_String_);
self.md_needsFrame();
self = mkProp(0, k_CloudData, "participant number", "Returns the participant number within the current session, or -1 if not known yet. Participant numbers are assigned by the server on first connect, starting with 0.", [], k_Number_);
self.md_needsFrame();
self = mkProp(0, k_CloudData, "set sync enabled", "Enable or disable cloud synchronization for the current session", [mkArg("enable", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self = mkProp(0, k_CloudData, "is sync enabled", "Returns a boolean indicating whether cloud synchronization is enabled for the current session", [], k_Boolean_);
self.md_needsFrame();
self = mkProp(16, k_CloudData, "switch to session", "Connect to the given session. The user may be asked to confirm.", [mkArg("session", k_CloudSession)], k_Nothing);
self.md_resumes();
self.md_arg("session").md_deflExpr('cloud_data->everyone_session');
self.md_uiAsync();
self.md_writesMutable();
self = mkProp(17, k_CloudData, "switch sessions", "Asks the user to choose a session to switch to", [], k_Nothing);
self.md_resumes();
self.md_uiAsync();
self.md_writesMutable();
self = mkProp(0, k_Collections, "create user collection", "Creates an empty User collection", [], k_Collection.createInstance([k_User]));
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collections, "create date time collection", "Creates an empty DateTime collection", [], k_Collection.createInstance([k_DateTime]));
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collections, "create picture collection", "Creates an empty Picture collection", [], k_Collection.createInstance([k_Picture]));
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collections, "create sound collection", "Creates an empty Picture collection", [], k_Collection.createInstance([k_Sound]));
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Collections, "create action collection", "Creates an empty Action collection", [], k_Collection.createInstance([k_Action]));
self.md_arg("result").md_writesMutable();
self = mkProp(310, k_Collections, "create string collection", "Creates an empty string collection", [], k_Collection.createInstance([k_String_]));
self.md_arg("result").md_writesMutable();
self = mkProp(5, k_Collections, "create place collection", "Creates an empty place collection", [], k_Collection.createInstance([k_Place]));
self.md_arg("result").md_writesMutable();
self = mkProp(4, k_Collections, "create link collection", "Creates an empty link collection", [], k_Collection.createInstance([k_Link]));
self.md_arg("result").md_writesMutable();
self = mkProp(4, k_Collections, "create message collection", "Creates an empty message collection", [], k_Collection.createInstance([k_Message]));
self.md_arg("result").md_writesMutable();
self = mkProp(10, k_Collections, "create location collection", "Creates an empty location collection", [], k_Collection.createInstance([k_Location_]));
self.md_arg("result").md_writesMutable();
self = mkProp(111, k_Collections, "create number map", "Creates an empty number map", [], k_NumberMap);
self.md_arg("result").md_writesMutable();
self = mkProp(75, k_Collections, "create string map", "Creates an empty string map (case and culture sensitive)", [], k_StringMap);
self.md_arg("result").md_writesMutable();
self = mkProp(94, k_Collections, "create number collection", "Creates an empty number collection", [], k_Collection.createInstance([k_Number_]));
self.md_arg("result").md_writesMutable();
self = mkProp(7, k_Color, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(19, k_Color, "A", "Gets the normalized alpha value (0.0-1.0)", [], k_Number_);
self = mkProp(67, k_Color, "R", "Gets the normalized red value (0.0-1.0)", [], k_Number_);
self = mkProp(66, k_Color, "G", "Gets the normalized green value (0.0-1.0)", [], k_Number_);
self = mkProp(66, k_Color, "B", "Gets the normalized blue value (0.0-1.0)", [], k_Number_);
self = mkProp(152, k_Color, "equals", "Checks if the color is equal to the other", [mkArg("other", k_Color)], k_Boolean_);
self = mkProp(14, k_Color, "blend", "Composes a new color using alpha blending", [mkArg("other", k_Color)], k_Color);
self = mkProp(227, k_Color, "make transparent", "Creates a new color by changing the alpha channel from 0 (transparent) to 1 (opaque).", [mkArg("alpha", k_Number_)], k_Color);
self = mkProp(397, k_Color, "darken", "Makes a darker color by a delta between 0 and 1.", [mkArg("delta", k_Number_)], k_Color);
self.md_arg("delta").md_defl(0.1);
self = mkProp(158, k_Color, "lighten", "Makes a lighter color by a delta between 0 and 1.", [mkArg("delta", k_Number_)], k_Color);
self.md_arg("delta").md_defl(0.1);
self = mkProp(0, k_Color, "to html", "Convert color to HTML syntax (either #FF002A or rgba(255, 0, 42, 0.5) when A is non-1)", [], k_String_);
self = mkProp(49, k_Color, "hue", "Gets the hue component of the color.", [], k_Number_);
self = mkProp(16, k_Color, "saturation", "Gets the saturation component of the color.", [], k_Number_);
self = mkProp(21, k_Color, "brightness", "Gets the brightness component of the color.", [], k_Number_);
self = mkProp(8, k_Color, "post to wall", "Prints the value to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(519, k_Colors, "accent", "Gets the accent color in the current theme", [], k_Color);
self = mkProp(101, k_Colors, "subtle", "Gets the subtle color in the current theme (light gray)", [], k_Color);
self = mkProp(337, k_Colors, "chrome", "Gets the chrome color in the current theme (control background)", [], k_Color);
self = mkProp(257, k_Colors, "foreground", "Gets the foreground color in the current theme", [], k_Color);
self.md_needsFrame();
self = mkProp(186, k_Colors, "background", "Gets the background color in the current theme", [], k_Color);
self.md_needsFrame();
self = mkProp(46, k_Colors, "is light theme", "Indicates if the user is using a light theme in their phone", [], k_Boolean_);
self.md_needsFrame();
self = mkProp(109, k_Colors, "from rgb", "Creates a color from the red, green, blue channels (0.0-1.0 range)", [mkArg("red", k_Number_), mkArg("green", k_Number_), mkArg("blue", k_Number_)], k_Color);
self = mkProp(84, k_Colors, "from argb", "Creates a color from the alpha, red, green, blue channels (0.0-1.0 range)", [mkArg("alpha", k_Number_), mkArg("red", k_Number_), mkArg("green", k_Number_), mkArg("blue", k_Number_)], k_Color);
self = mkProp(0, k_Colors, "pink", "Gets the color that has the ARGB value of #FFFFCBDB", [], k_Color);
self = mkProp(653, k_Colors, "black", "Gets the color that has the ARGB value of #FF000000", [], k_Color);
self = mkProp(285, k_Colors, "blue", "Gets the color that has the ARGB value of #FF0000FF", [], k_Color);
self = mkProp(83, k_Colors, "brown", "Gets the color that has the ARGB value of #FFA52A2A", [], k_Color);
self = mkProp(68, k_Colors, "cyan", "Gets the color that has the ARGB value of #FF00FFFF", [], k_Color);
self = mkProp(187, k_Colors, "dark gray", "Gets the color that has the ARGB value of #FFA9A9A9", [], k_Color);
self = mkProp(176, k_Colors, "gray", "Gets the color that has the ARGB value of #FF808080", [], k_Color);
self = mkProp(325, k_Colors, "green", "Gets the color that has the ARGB value of #FF008000", [], k_Color);
self = mkProp(115, k_Colors, "light gray", "Gets the color that has the ARGB value of #FFD3D3D3", [], k_Color);
self = mkProp(57, k_Colors, "magenta", "Gets the color that has the ARGB value of #FFFF00FF", [], k_Color);
self = mkProp(214, k_Colors, "orange", "Gets the color that has the ARGB value of #FFFFA500", [], k_Color);
self = mkProp(46, k_Colors, "purple", "Gets the color that has the ARGB value of #FF800080", [], k_Color);
self = mkProp(462, k_Colors, "red", "Gets the color that has the ARGB value of #FFFF0000", [], k_Color);
self = mkProp(123, k_Colors, "transparent", "Gets the color that has the ARGB value of #00FFFFFF", [], k_Color);
self = mkProp(449, k_Colors, "white", "Gets the color that has the ARGB value of #FFFFFFFF", [], k_Color);
self = mkProp(84, k_Colors, "yellow", "Gets the color that has the ARGB value of #FFFFFF00", [], k_Color);
self = mkProp(81, k_Colors, "sepia", "Gets the color that has the ARGB value of #FF704214", [], k_Color);
self = mkProp(114, k_Colors, "linear gradient", "Computes an intermediate color", [mkArg("c1", k_Color), mkArg("c2", k_Color), mkArg("alpha", k_Number_)], k_Color);
self.md_arg("c1").md_deflExpr('colors->background');
self.md_arg("c2").md_deflExpr('colors->foreground');
self = mkProp(61, k_Colors, "rand", "Renamed to 'random'", [], k_Color);
self.md_hidden();
self.md_tandre();
self = mkProp(209, k_Colors, "random", "Picks a random color", [], k_Color);
self.md_tandre();
self = mkProp(0, k_Colors, "wheel", "Picks a color from a color wheel where the hue is between 0 and 1.", [mkArg("hue", k_Number_)], k_Color);
self = mkProp(92, k_Colors, "from hsb", "Creates a color from the hue, saturation, brightness channels (0.0-1.0 range)", [mkArg("hue", k_Number_), mkArg("saturation", k_Number_), mkArg("brightness", k_Number_)], k_Color);
self.md_arg("saturation").md_defl(1);
self.md_arg("brightness").md_defl(1);
self = mkProp(9, k_Colors, "from ahsb", "Creates a color from the alpha, hue, saturation, brightness channels (0.0-1.0 range)", [mkArg("alpha", k_Number_), mkArg("hue", k_Number_), mkArg("saturation", k_Number_), mkArg("brightness", k_Number_)], k_Color);
self.md_arg("alpha").md_defl(1);
self.md_arg("saturation").md_defl(1);
self.md_arg("brightness").md_defl(1);
self = mkProp(0, k_Contact, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Contact, "id", "Gets the user id if any", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set id", "Sets the user id", [mkArg("id", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_Contact, "name", "Gets the display name (not used when saving contact)", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "first name", "Gets the first name if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set first name", "Sets the first name", [mkArg("first name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "last name", "Gets the last name if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set last name", "Sets the last name", [mkArg("last name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "nick name", "Gets the nickname if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set nick name", "Sets the middle name", [mkArg("nick name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "middle name", "Gets the middle name if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set middle name", "Sets the middle name", [mkArg("middle name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "title", "Gets the name title if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set title", "Sets the title", [mkArg("title", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "suffix", "Gets the name suffix if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set suffix", "Sets the suffix", [mkArg("suffix", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "company", "Gets the company name if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set company", "Sets the company", [mkArg("company", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "job title", "Gets the job title at the company if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set job title", "Sets the job title", [mkArg("job title", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "office", "Gets the office location at the company if any.", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set office", "Sets the office location at the company", [mkArg("office", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "work address", "Gets the home address if any", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set work address", "Sets the work address", [mkArg("work address", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "home address", "Gets the work address if any", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set home address", "Sets the home address", [mkArg("home address", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "source", "Gets the source of this contact (phone, etc...)", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set source", "Sets the source", [mkArg("source", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "birthday", "Gets the birth date if any.", [], k_DateTime);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set birthday", "Sets the birthday", [mkArg("birthday", k_DateTime)], k_Nothing);
self.md_writesMutable();
self = mkProp(3, k_Contact, "picture", "Gets the picture of the contact if any.", [], k_Picture);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(0, k_Contact, "set picture", "Sets the picture", [mkArg("picture", k_Picture)], k_Nothing);
self.md_writesMutable();
self.md_arg("picture").md_readsMutable();
self = mkProp(0, k_Contact, "set Picture url", "Sets the picture url", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_Contact, "email", "Gets the work or personal email if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set email", "Sets the work or personal email", [mkArg("email", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "work email", "Gets the work email if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set work email", "Sets the work email", [mkArg("work email", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "personal email", "Gets the personal email if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set personal email", "Sets the personal email", [mkArg("personal email", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(2, k_Contact, "phone number", "Gets the cell or work or home phone number if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set phone number", "Sets the cell or work or home phone number if any", [mkArg("phone number", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "home phone", "Gets the home phone number if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set home phone", "Sets the home phone", [mkArg("home phone", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "work phone", "Gets the work phone number if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set work phone", "Sets the work phone", [mkArg("work phone", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "mobile phone", "Gets the cell phone number if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set mobile phone", "Sets the mobile phone", [mkArg("mobile phone", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Contact, "web site", "Gets the web site if any", [], k_Link);
self.md_readsMutable();
self = mkProp(0, k_Contact, "set web site", "Sets the web site", [mkArg("web site", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_Contact, "post to wall", "Posts the contact to the wall", [], k_Nothing);
self.md_needsFrame();
self.md_cap("none");
self = mkProp(0, k_Contract, "requires", "Specifies a precondition contract for the action; if the condition is false, execution fails. Does nothing for published scripts.", [mkArg("condition", k_Boolean_), mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Contract, "assert", "Checks for a condition; if the condition is false, execution fails. Does nothing for published scripts.", [mkArg("condition", k_Boolean_), mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
multiplex = TDev.MultiplexRootProperty.md_make_kind();
multiplex.md_parametric("T");
self = TDev.MultiplexRootProperty.md_make_prop(multiplex, 0, k_Create, "Collection of", "Creates an empty collection of arbitrary type", [], k_Collection.createInstance([multiplex.getParameter(0)]));
self.md_needsFrame();
self.md_arg("result").md_writesMutable();
multiplex = TDev.MultiplexRootProperty.md_make_kind();
multiplex.md_parametric("T");
self = TDev.MultiplexRootProperty.md_make_prop(multiplex, 0, k_Create, "Ref of", "Creates a `Ref of T` (single-field object), initialized to the default value of `T`", [], k_Ref.createInstance([multiplex.getParameter(0)]));
self.md_needsFrame();
self.md_arg("result").md_writesMutable();
self = mkProp(8, k_DateTime, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_DateTime, "to json", "Converts the value into a json data structure.", [], k_JsonObject);
self = mkProp(183, k_DateTime, "add days", "Returns a date that adds the specified number of days to the value of this instance.", [mkArg("days", k_Number_)], k_DateTime);
self.md_arg("days").md_defl(1);
self = mkProp(8, k_DateTime, "add hours", "Returns a date that adds the specified number of hours to the value of this instance.", [mkArg("hours", k_Number_)], k_DateTime);
self.md_arg("hours").md_defl(1);
self = mkProp(18, k_DateTime, "add minutes", "Returns a date that adds the specified number of minutes to the value of this instance.", [mkArg("minutes", k_Number_)], k_DateTime);
self.md_arg("minutes").md_defl(1);
self = mkProp(43, k_DateTime, "add seconds", "Returns a date that adds the specified number of seconds to the value of this instance.", [mkArg("seconds", k_Number_)], k_DateTime);
self.md_arg("seconds").md_defl(1);
self = mkProp(35, k_DateTime, "add milliseconds", "Returns a date that adds the specified number of milliseconds to the value of this instance.", [mkArg("milliseconds", k_Number_)], k_DateTime);
self.md_arg("milliseconds").md_defl(1);
self = mkProp(202, k_DateTime, "subtract", "Computes the difference between date-times in seconds", [mkArg("value", k_DateTime)], k_Number_);
self = mkProp(10, k_DateTime, "equals", "Compares dates for equality", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(0, k_DateTime, "not equals", "Compares dates for disequality", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(14, k_DateTime, "less or equals", "Compares dates for less or equal", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(5, k_DateTime, "less", "Compares dates for less", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(23, k_DateTime, "greater or equal", "Compares dates for greater or equal", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(90, k_DateTime, "greater", "Compares dates for greater", [mkArg("other", k_DateTime)], k_Boolean_);
self = mkProp(83, k_DateTime, "to string", "Converts a dates to a string", [], k_String_);
self = mkProp(9, k_DateTime, "date", "Gets the date", [], k_DateTime);
self = mkProp(0, k_DateTime, "milliseconds since epoch", "Gets the milliseconds elapsed since January 1, 1970 UTC; same as getTime() in JavaScript.", [], k_Number_);
self = mkProp(0, k_DateTime, "from now", "Converts into text that describes the elapsed time in a friendly way.", [], k_String_);
self = mkProp(402, k_DateTime, "day", "Gets the day of the month", [], k_Number_);
self = mkProp(179, k_DateTime, "hour", "Gets the hour", [], k_Number_);
self = mkProp(26, k_DateTime, "millisecond", "Gets the millisecond", [], k_Number_);
self = mkProp(178, k_DateTime, "minute", "Gets the minute", [], k_Number_);
self = mkProp(112, k_DateTime, "month", "Gets the month", [], k_Number_);
self = mkProp(114, k_DateTime, "second", "Gets the second", [], k_Number_);
self = mkProp(112, k_DateTime, "year", "Gets the year", [], k_Number_);
self = mkProp(19, k_DateTime, "week day", "Gets the day of the week (sunday = 0, monday = 1, ... saturday = 6)", [], k_Number_);
self = mkProp(7, k_DateTime, "year day", "Gets the day of the year between 1 and 366", [], k_Number_);
self = mkProp(0, k_DateTime, "add years", "Returns a date that adds the specified number of years to the value of this instance.", [mkArg("years", k_Number_)], k_DateTime);
self.md_stub();
self.md_arg("years").md_defl(1);
self = mkProp(0, k_DateTime, "add months", "Returns a date that adds the specified number of months to the value of this instance.", [mkArg("months", k_Number_)], k_DateTime);
self.md_stub();
self.md_arg("months").md_defl(1);
self = mkProp(27, k_DateTime, "to universal time", "Converts coordinated universal time", [], k_DateTime);
self = mkProp(5, k_DateTime, "to local time", "Converts to the local time", [], k_DateTime);
self.md_stub();
self = mkProp(22, k_DateTime, "post to wall", "Prints the date to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Docs, "bitmatrix", "Renders a bitmatrix", [mkArg("bits", k_String_)], k_Nothing);
self.md_docsOnly();
self.md_arg("bits").md_lang("bitmatrix");
self = mkProp(0, k_Document_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Document_, "docs render", "Shows a document link in the docs.", [mkArg("caption", k_String_)], k_Nothing);
self.md_docsOnly();
self = mkProp(0, k_Document_, "url", "Gets the web address for the document.", [], k_String_);
self = mkProp(0, k_Editor, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Editor, "progress", "Replace standard 'running plugin' message with something else", [mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Editor, "annotate ast", "Place a message on an AST node", [mkArg("id", k_String_), mkArg("category", k_String_), mkArg("message", k_String_)], k_Nothing);
self.md_arg("category").md_deflStrings("warning", "info", "error");
self = mkProp(0, k_Editor, "annotate caller", "Place a message on the first caller in the top-level script in the editor", [mkArg("category", k_String_), mkArg("message", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("category").md_deflStrings("warning", "info", "error");
self.md_betaOnly();
self = mkProp(0, k_Editor, "current script id", "The id of the script currently in the editor", [], k_String_);
self.md_needsFrame();
self = mkProp(0, k_Editor, "current script ast", "Returns the AST of the script currently in the editor", [], k_JsonObject);
self.md_resumes();
self.md_uiAsync();
self = mkProp(0, k_Editor, "tutorial step completed", "Signal that the current tutorial step is done.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Editor, "deployment settings", "Get (Azure) web site deployment settings.", [], k_JsonObject);
self.md_resumes();
self.md_async();
self = mkProp(0, k_Editor, "user token", "Authenticates the user for the given app name and returns the token if successful. The identity of the token is contructed with ``{app name} - {user id}``.", [mkArg("app name", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("editoronly");
self = mkProp(0, k_Editor, "package current script", "Compiles and packages the current script.", [mkArg("options", k_JsonObject)], k_JsonObject);
self.md_resumes();
self.md_async();
self.md_cap("editoronly");
self.md_dbgOnly();
self = mkProp(0, k_Enumerator, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Enumerator, "current", "Return current value", [], k_Nothing);
self.md_stub();
self = mkProp(0, k_Enumerator, "move next", "Advance enumerator and return true if there is another element.", [], k_Boolean_);
self.md_stub();
self = mkProp(0, k_EventBinding, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_EventBinding, "delete", "Detaches the handler from the event.", [], k_Nothing);
self = mkProp(0, k_FormBuilder, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_FormBuilder, "post to wall", "Displays the form to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_FormBuilder, "add text", "Adds a piece of text to the form using a custom type and/or file name.", [mkArg("name", k_String_), mkArg("content", k_String_), mkArg("mimetype", k_String_), mkArg("filename", k_String_)], k_Nothing);
self.md_arg("mimetype").md_deflStrings('text/html', 'text/plain');
self = mkProp(0, k_FormBuilder, "add buffer", "Adds a buffer as an attached file", [mkArg("name", k_String_), mkArg("buffer", k_Buffer), mkArg("filename", k_String_)], k_Nothing);
self = mkProp(0, k_FormBuilder, "add string as file", "Adds a buffer as an attached file", [mkArg("name", k_String_), mkArg("text", k_String_), mkArg("filename", k_String_)], k_Nothing);
self = mkProp(0, k_FormBuilder, "add string", "Adds a string value", [mkArg("name", k_String_), mkArg("value", k_String_)], k_Nothing);
self = mkProp(0, k_FormBuilder, "add number", "Adds a number value", [mkArg("name", k_String_), mkArg("value", k_Number_)], k_Nothing);
self = mkProp(0, k_FormBuilder, "add boolean", "Adds a boolean value", [mkArg("name", k_String_), mkArg("value", k_Boolean_)], k_Nothing);
self = mkProp(0, k_FormBuilder, "add picture", "Adds a picture", [mkArg("name", k_String_), mkArg("value", k_Picture), mkArg("picture Name", k_String_)], k_Nothing);
self.md_resumes();
self.md_picAsync();
self.md_arg("picture Name").md_defl("pic");
self = mkProp(86, k_Invalid, "number", "Creates an invalid Number instance", [], k_Number_);
self = mkProp(6, k_Invalid, "boolean", "Creates an invalid Boolean instance", [], k_Boolean_);
self = mkProp(26, k_Invalid, "string", "Creates an invalid String instance", [], k_String_);
self = mkProp(1, k_Invalid, "string collection", "Creates an invalid String Collection instance", [], k_Collection.createInstance([k_String_]));
self = mkProp(9, k_Invalid, "datetime", "Creates an invalid DateTime instance", [], k_DateTime);
self = mkProp(12, k_Invalid, "color", "Creates an invalid Color instance", [], k_Color);
self = mkProp(40, k_Invalid, "picture", "Creates an invalid Picture instance", [], k_Picture);
self = mkProp(13, k_Invalid, "song", "Creates an invalid Song instance", [], k_Song);
self = mkProp(1, k_Invalid, "location", "Creates an invalid Location instance", [], k_Location_);
self = mkProp(1, k_Invalid, "location collection", "Creates an invalid Location Collection instance", [], k_Collection.createInstance([k_Location_]));
self = mkProp(0, k_Invalid, "map", "Creates an invalid Map instance", [], k_Map);
self.md_cap("maps");
self = mkProp(5, k_Invalid, "sound", "Creates an invalid Sound instance", [], k_Sound);
self = mkProp(0, k_Invalid, "json object", "Creates an invalid Json Object instance", [], k_JsonObject);
self = mkProp(0, k_Invalid, "link", "Creates an invalid Link instance", [], k_Link);
self = mkProp(0, k_Invalid, "link collection", "Creates an invalid Link Collection instance", [], k_Collection.createInstance([k_Link]));
self = mkProp(13, k_Invalid, "vector3", "Creates an invalid Vector3 instance", [], k_Vector3);
self = mkProp(5, k_Invalid, "number map", "Creates an invalid Number Map instance", [], k_NumberMap);
self = mkProp(3, k_Invalid, "string map", "Creates an invalid String Map instance", [], k_StringMap);
self = mkProp(0, k_Invalid, "message", "Creates an invalid Message instance", [], k_Message);
self = mkProp(1, k_Invalid, "message collection", "Creates an invalid Message Collection instance", [], k_Collection.createInstance([k_Message]));
self = mkProp(57, k_Invalid, "board", "Creates an invalid Board instance", [], k_Board);
self = mkProp(21, k_Invalid, "sprite", "Creates an invalid Sprite instance", [], k_Sprite);
self = mkProp(0, k_Invalid, "sprite animation", "Creates an invalid Sprite Animation instance", [], k_SpriteAnimation);
self = mkProp(27, k_Invalid, "sprite set", "Creates an invalid Sprite Set instance", [], k_SpriteSet);
self = mkProp(5, k_Invalid, "xml object", "Creates an invalid Xml Object instance", [], k_XmlObject);
self = mkProp(0, k_Invalid, "place", "Creates an invalid Place instance", [], k_Place);
self = mkProp(0, k_Invalid, "place collection", "Creates an invalid Place Collection instance", [], k_Collection.createInstance([k_Place]));
self = mkProp(3, k_Invalid, "textbox", "Creates an invalid TextBox instance", [], k_TextBox);
self = mkProp(0, k_Invalid, "contact", "Creates an invalid Contact instance", [], k_Contact);
self = mkProp(0, k_Invalid, "contact collection", "Creates an invalid Contact Collection instance", [], k_Collection.createInstance([k_Contact]));
self = mkProp(0, k_Invalid, "camera", "Creates an invalid Camera instance", [], k_Camera);
self = mkProp(0, k_Invalid, "web request", "Creates an invalid Web Request instance", [], k_WebRequest);
self = mkProp(0, k_Invalid, "web response", "Creates an invalid Web Response instance", [], k_WebResponse);
self = mkProp(0, k_Invalid, "number collection", "Creates an invalid Number Collection instance", [], k_Collection.createInstance([k_Number_]));
self = mkProp(4, k_Invalid, "page", "Creates an invalid Page instance", [], k_Page);
self = mkProp(0, k_Invalid, "page button", "Creates an invalid Page Button instance", [], k_PageButton);
self = mkProp(0, k_Invalid, "page collection", "Creates an invalid Page Collection instance", [], k_Collection.createInstance([k_Page]));
self = mkProp(0, k_Invalid, "matrix", "Creates an invalid Matrix instance", [], k_Matrix);
self = mkProp(0, k_Invalid, "action", "Creates an invalid Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "text action", "Creates an invalid Text Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "position action", "Creates an invalid Position Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "vector action", "Creates an invalid Vector Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "webresponse action", "Creates an invalid WebResponse Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "sprite action", "Creates an invalid Sprite Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "sprite set action", "Creates an invalid Sprite Set Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "json builder", "Creates an invalid Json Builder instance", [], k_JsonBuilder);
self = mkProp(0, k_Invalid, "message collection action", "Creates an invalid Message Collection Action instance", [], k_Action);
self = mkProp(0, k_Invalid, "oauth response", "Creates an invalid OAuth Response instance", [], k_OAuthResponse);
self = mkProp(0, k_Invalid, "form builder", "Creates an invalid Form Builder instance", [], k_FormBuilder);
self = mkProp(0, k_Invalid, "user", "Creates an invalid User instance", [], k_User);
self = mkProp(0, k_Invalid, "gamepad", "Creates an invalid Gamepad instance", [], k_Gamepad_);
self = mkProp(0, k_JsonBuilder, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_JsonBuilder, "set field", "Sets the field value.", [mkArg("name", k_String_), mkArg("value", k_JsonObject)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "set builder", "Sets the field the the reference to JsonBuilder.", [mkArg("name", k_String_), mkArg("value", k_JsonBuilder)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "set string", "Sets the string value.", [mkArg("name", k_String_), mkArg("value", k_String_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "clone", "Creates a deep copy clone of the object", [], k_JsonBuilder);
self = mkProp(0, k_JsonBuilder, "set number", "Sets the number value.", [mkArg("name", k_String_), mkArg("value", k_Number_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "set boolean", "Sets the boolean value.", [mkArg("name", k_String_), mkArg("value", k_Boolean_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "set sound", "Sets the Sound value as a data uri.", [mkArg("name", k_String_), mkArg("snd", k_Sound)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "set picture", "Sets the Picture value as a data uri.", [mkArg("name", k_String_), mkArg("pic", k_Picture), mkArg("quality", k_Number_)], k_Nothing);
self.md_resumes();
self.md_picAsync();
self = mkProp(0, k_JsonBuilder, "set field null", "Sets the field value as null.", [mkArg("name", k_String_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add", "Adds a value to the array.", [mkArg("value", k_JsonObject)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add number", "Adds a number to the array.", [mkArg("value", k_Number_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add string", "Adds a string to the array.", [mkArg("value", k_String_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add boolean", "Adds a boolean to the array.", [mkArg("value", k_Boolean_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "copy from", "Copy all fields from given JSON object", [mkArg("value", k_JsonObject)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add builder", "Add a reference to JsonBuilder to the array.", [mkArg("value", k_JsonBuilder)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "clear", "Deletes all array elements from the current builder.", [], k_Nothing);
self = mkProp(0, k_JsonBuilder, "add null", "Adds a null value to the array.", [], k_Nothing);
self = mkProp(0, k_JsonBuilder, "to json", "Converts the builder into a json data structure", [], k_JsonObject);
self = mkProp(0, k_JsonBuilder, "count", "Gets the number of values", [], k_Number_);
self = mkProp(0, k_JsonBuilder, "at", "Gets the i-th json value", [mkArg("index", k_Number_)], k_JsonBuilder);
self = mkProp(0, k_JsonBuilder, "set at", "Sets the i-th json value", [mkArg("index", k_Number_), mkArg("v", k_JsonBuilder)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "remove at", "Removes the i-th json value", [mkArg("index", k_Number_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "remove field", "Deletes named field", [mkArg("name", k_String_)], k_Nothing);
self = mkProp(0, k_JsonBuilder, "boolean", "Gets a field value as a boolean", [mkArg("key", k_String_)], k_Boolean_);
self = mkProp(0, k_JsonBuilder, "contains key", "Indicates if the key exists", [mkArg("key", k_String_)], k_Boolean_);
self = mkProp(0, k_JsonBuilder, "time", "Gets the field value as a time", [mkArg("key", k_String_)], k_DateTime);
self = mkProp(0, k_JsonBuilder, "field", "Gets a value by name", [mkArg("key", k_String_)], k_JsonBuilder);
self = mkProp(0, k_JsonBuilder, "keys", "Gets the list of keys", [], k_Collection.createInstance([k_String_]));
self = mkProp(0, k_JsonBuilder, "kind", "Gets a json kind (string, number, object, array, boolean, null)", [], k_String_);
self = mkProp(0, k_JsonBuilder, "number", "Gets a field value as a number", [mkArg("key", k_String_)], k_Number_);
self = mkProp(0, k_JsonBuilder, "string", "Gets a field value as a string", [mkArg("key", k_String_)], k_String_);
self = mkProp(0, k_JsonBuilder, "post to wall", "Prints the value to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_JsonBuilder, "to boolean", "Converts to a boolean (type must be boolean)", [], k_Boolean_);
self = mkProp(0, k_JsonBuilder, "to number", "Converts to a number (type must be number)", [], k_Number_);
self = mkProp(0, k_JsonBuilder, "to string", "Converts to a string (type must be string)", [], k_String_);
self = mkProp(0, k_JsonBuilder, "to time", "Converts and parses to a date time (type must be string)", [], k_DateTime);
self = mkProp(0, k_JsonBuilder, "to collection", "Converts to a collection of JsonBuilders (type must be array)", [], k_Collection.createInstance([k_JsonBuilder]));
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_JsonBuilder, "serialize", "Stringify the current JSON object", [], k_String_);
self = mkProp(38, k_JsonObject, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_JsonObject, "clone", "Creates a deep copy clone of the object", [], k_JsonObject);
self = mkProp(39, k_JsonObject, "count", "Gets the number of values", [], k_Number_);
self = mkProp(109, k_JsonObject, "at", "Gets the i-th json value", [mkArg("index", k_Number_)], k_JsonObject);
self = mkProp(5, k_JsonObject, "boolean", "Gets a field value as a boolean", [mkArg("key", k_String_)], k_Boolean_);
self = mkProp(6, k_JsonObject, "contains key", "Indicates if the key exists", [mkArg("key", k_String_)], k_Boolean_);
self = mkProp(1, k_JsonObject, "time", "Gets the field value as a time", [mkArg("key", k_String_)], k_DateTime);
self = mkProp(308, k_JsonObject, "field", "Gets a value by name", [mkArg("key", k_String_)], k_JsonObject);
self = mkProp(70, k_JsonObject, "keys", "Gets the list of keys", [], k_Collection.createInstance([k_String_]));
self = mkProp(8, k_JsonObject, "kind", "Gets a json kind (string, number, object, array, boolean, null)", [], k_String_);
self = mkProp(21, k_JsonObject, "number", "Gets a field value as a number", [mkArg("key", k_String_)], k_Number_);
self = mkProp(135, k_JsonObject, "string", "Gets a field value as a string", [mkArg("key", k_String_)], k_String_);
self = mkProp(17, k_JsonObject, "post to wall", "Prints the value to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_JsonObject, "format", "Create a string formatted for easy readability", [mkArg("spaces", k_Number_)], k_String_);
self.md_arg("spaces").md_defl(2);
self = mkProp(5, k_JsonObject, "to boolean", "Converts to a boolean (type must be boolean)", [], k_Boolean_);
self = mkProp(38, k_JsonObject, "to number", "Converts to a number (type must be number)", [], k_Number_);
self = mkProp(56, k_JsonObject, "to string", "Converts to a string (type must be string)", [], k_String_);
self = mkProp(2, k_JsonObject, "to time", "Converts and parses to a date time (type must be string)", [], k_DateTime);
self = mkProp(0, k_JsonObject, "to collection", "Converts to a collection of JsonObjects (type must be array)", [], k_Collection.createInstance([k_JsonObject]));
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_JsonObject, "serialize", "Stringify the current JSON object", [], k_String_);
self = mkProp(0, k_JsonObject, "to json builder", "Copy current JSON object into a Json Builder so it can be modified", [], k_JsonBuilder);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(24, k_Languages, "current language", "Gets the current language code, to be used in the 'translate' method.", [], k_String_);
self = mkProp(3, k_Languages, "record text", "Converts the microphone dictation to text.", [], k_String_);
self.md_resumes();
self.md_uiAsync();
self.md_cap("speech");
self.md_flow("SourceMicrophone");
self = mkProp(28, k_Languages, "translate", "Translates some text between two languages using Bing. Empty source language to auto-detect.", [mkArg("source lang", k_String_), mkArg("target lang", k_String_), mkArg("text", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("translation");
self.md_flow("SinkSafe");
self.md_arg("target lang").md_defl("fr");
self.md_arg("text").md_defl("hello");
self = mkProp(3, k_Languages, "detect language", "Automatically detects the language of a given text using Bing.", [mkArg("text", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("translation");
self.md_flow("SinkSafe");
self = mkProp(94, k_Languages, "speak", "This api was renamed. Use `speak_text` instead.", [mkArg("lang", k_String_), mkArg("text", k_String_)], k_Sound);
self.md_cap("translation");
self.md_flow("SinkSafe");
self.md_obsolete();
self.md_arg("result").md_writesMutable();
self.md_arg("lang").md_defl("en");
self.md_arg("text").md_defl("");
self = mkProp(0, k_Languages, "speak text", "Speaks the text immediately using the text-to-speech engine on the device.", [mkArg("voice language", k_String_), mkArg("voice gender", k_String_), mkArg("text", k_String_)], k_Nothing);
self.md_resumes();
self.md_async();
self.md_cap("speech");
self.md_arg("voice language").md_defl("");
self.md_arg("voice gender").md_deflStrings("female", "male");
self.md_arg("text").md_defl("");
self.md_import("cordova", "org.apache.cordova.speech.speechsynthesis");
self = mkProp(0, k_Languages, "speak ssml", "Speaks the SSML markup immediately using the text-to-speech engine on the device.", [mkArg("ssml", k_XmlObject)], k_Nothing);
self.md_resumes();
self.md_async();
self.md_cap("speech");
self.md_import("cordova", "org.apache.cordova.speech.speechsynthesis");
self = mkProp(3, k_Link, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(4, k_Link, "name", "Gets the name if any", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Link, "set name", "Sets the name", [mkArg("name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(2, k_Link, "location", "Gets the location if any", [], k_Location_);
self.md_readsMutable();
self = mkProp(1, k_Link, "set location", "Sets the location", [mkArg("location", k_Location_)], k_Nothing);
self.md_writesMutable();
self = mkProp(10, k_Link, "address", "Gets the url", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Link, "to picture", "Gets a picture pointing to this address. Only applies to `image` link kinds.", [], k_Picture);
self.md_readsMutable();
self = mkProp(0, k_Link, "kind", "Gets the kind of asset - media, image, email, phone number, hyperlink, deep zoom link, radio", [], k_String_);
self = mkProp(1, k_Link, "share", "Shares the link (email, sms, facebook, social or '' to pick from a list)", [mkArg("network", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_readsMutable();
self.md_uiAsync();
self.md_arg("network").md_defl("social");
self = mkProp(55, k_Link, "post to wall", "Displays the link on the wall", [], k_Nothing);
self.md_needsFrame();
self.md_flow("SinkWeb");
self.md_readsMutable();
self = mkProp(17, k_Location_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(11, k_Location_, "to string", "Converts to a string lat,long", [], k_String_);
self = mkProp(29, k_Location_, "latitude", "Gets the latitude of the coordinate", [], k_Number_);
self = mkProp(29, k_Location_, "longitude", "Gets the longitude of the coordinate", [], k_Number_);
self = mkProp(7, k_Location_, "altitude", "Gets the altitude of the coordinate", [], k_Number_);
self = mkProp(10, k_Location_, "hor accuracy", "Gets the horizontal accuracy of the coordinate", [], k_Number_);
self = mkProp(10, k_Location_, "vert accuracy", "Gets the vertical accuracy of the coordinate", [], k_Number_);
self = mkProp(4, k_Location_, "speed", "Gets the speed of the coordinate", [], k_Number_);
self = mkProp(2, k_Location_, "course", "Gets the course of the coordinate", [], k_Number_);
self = mkProp(1, k_Location_, "equals", "Indicates if this instance is equal to the other", [mkArg("other", k_Location_)], k_Boolean_);
self = mkProp(1, k_Location_, "share", "Shares the location (email, sms, social or '' to pick from a list)", [mkArg("network", k_String_), mkArg("message", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_uiAsync();
self.md_arg("network").md_defl("social");
self.md_arg("network").md_deflStrings("", "email", "sms", "social");
self.md_arg("message").md_defl("Sent from TouchDevelop");
self = mkProp(33, k_Location_, "distance", "Calculates the distance in meters", [mkArg("other", k_Location_)], k_Number_);
self = mkProp(13, k_Location_, "post to wall", "Displays the location in a map using Bing.", [], k_Nothing);
self.md_needsFrame();
self.md_cap("maps");
self.md_flow("SinkSafe");
self = mkProp(19, k_Locations, "create location", "Creates a new geo coordinate location", [mkArg("latitude", k_Number_), mkArg("longitude", k_Number_)], k_Location_);
self = mkProp(4, k_Locations, "create location list", "Creates an empty list of locations", [], k_Collection.createInstance([k_Location_]));
self = mkProp(62, k_Locations, "describe location", "Looks for an address near a location using Bing.", [mkArg("location", k_Location_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("maps");
self.md_flow("SinkSafe");
self = mkProp(172, k_Locations, "search location", "Looks for the coordinate of an address using Bing.", [mkArg("address", k_String_), mkArg("postal code", k_String_), mkArg("city", k_String_), mkArg("country", k_String_)], k_Location_);
self.md_resumes();
self.md_async();
self.md_cap("maps");
self.md_flow("SinkSafe");
self = mkProp(0, k_MapPushpin, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_MapPushpin, "on tap", "Set the handler invoked when the pushpin is tapped", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_MapPushpin, "location", "Gets the pushpin geo location", [], k_Location_);
self.md_readsMutable();
self = mkProp(0, k_MapPushpin, "set location", "Sets the location of the pushpin", [mkArg("loc", k_Location_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_MapPushpin, "set visible", "Shows or hides the pushpin", [mkArg("visible", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Map, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Map, "zoom", "Gets the zoom level", [], k_Number_);
self.md_readsMutable();
self = mkProp(15, k_Map, "set zoom", "Sets the zoom level from 1 (earth) to 21 (street)", [mkArg("level", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("level").md_defl(12);
self = mkProp(0, k_Map, "center", "Gets the map center location", [], k_Location_);
self.md_readsMutable();
self = mkProp(19, k_Map, "set center", "Sets the map center location", [mkArg("center", k_Location_)], k_Nothing);
self.md_writesMutable();
self = mkProp(23, k_Map, "add text", "Adds a text pushpin on the map", [mkArg("location", k_Location_), mkArg("text", k_String_), mkArg("background", k_Color), mkArg("foreground", k_Color)], k_MapPushpin);
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_arg("foreground").md_deflExpr('colors->white');
self = mkProp(0, k_Map, "add link", "Adds a link pushpin on the map (ignored if the location if not set)", [mkArg("link", k_Link), mkArg("background", k_Color), mkArg("foreground", k_Color)], k_MapPushpin);
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_readsMutable();
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_arg("foreground").md_deflExpr('colors->white');
self.md_embedsLink("Map", "Link");
self = mkProp(0, k_Map, "add message", "Adds a message pushpin on the map (ignored if the location is not set)", [mkArg("msg", k_Message), mkArg("background", k_Color), mkArg("foreground", k_Color)], k_MapPushpin);
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_arg("foreground").md_deflExpr('colors->white');
self.md_embedsLink("Map", "Message");
self = mkProp(5, k_Map, "add picture", "Adds a picture pushpin on the map", [mkArg("location", k_Location_), mkArg("picture", k_Picture), mkArg("background", k_Color)], k_MapPushpin);
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_embedsLink("Map", "Picture");
self = mkProp(4, k_Map, "add place", "Adds a place pushpin on the map (ignored if the location is not set)", [mkArg("place", k_Place), mkArg("background", k_Color), mkArg("foreground", k_Color)], k_MapPushpin);
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_arg("foreground").md_deflExpr('colors->white');
self.md_embedsLink("Map", "Place");
self = mkProp(7, k_Map, "add line", "Adds a polyline that passes through various geocoordinates", [mkArg("locations", k_Collection.createInstance([k_Location_])), mkArg("color", k_Color), mkArg("thickness", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("locations").md_readsMutable();
self.md_arg("color").md_deflExpr('colors->accent');
self.md_arg("thickness").md_defl(6);
self = mkProp(0, k_Map, "fill region", "Fills a region with a color", [mkArg("locations", k_Collection.createInstance([k_Location_])), mkArg("fill", k_Color), mkArg("stroke", k_Color), mkArg("thickness", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("locations").md_readsMutable();
self.md_arg("fill").md_deflExpr('colors->background');
self.md_arg("stroke").md_deflExpr('colors->foreground');
self.md_arg("thickness").md_defl(6);
self = mkProp(1, k_Map, "clear", "Clears the lines, regions and pushpins", [], k_Nothing);
self.md_writesMutable();
self = mkProp(3, k_Map, "view pushpins", "Changes the current zoom and center so that all the pushpins are visible. This method has no effect if the map is not posted on a the wall yet.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(34, k_Map, "post to wall", "Displays the map in the wall using Bing.", [], k_Nothing);
self.md_needsFrame();
self.md_cap("maps");
self.md_flow("SinkSafe");
self.md_readsMutable();
self = mkProp(19, k_Maps, "create map", "Creates a Bing map. Use 'post to wall' to display it.", [], k_Map);
self.md_cap("maps");
self.md_arg("result").md_writesMutable();
self = mkProp(18, k_Maps, "create full map", "Creates a full screen Bing map. Use 'post to wall' to display it.", [], k_Map);
self.md_cap("maps");
self.md_arg("result").md_writesMutable();
self = mkProp(13, k_Maps, "directions", "Calculates the directions between two coordinates using Bing.", [mkArg("from", k_Location_), mkArg("to", k_Location_), mkArg("walking", k_Boolean_)], k_Collection.createInstance([k_Location_]));
self.md_resumes();
self.md_async();
self.md_cap("maps");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self.md_arg("from").md_deflExpr('senses->current_location');
self.md_arg("walking").md_defl(true);
self = mkProp(12, k_Maps, "open directions", "Shows the directions in the Bing map application. If search term is provided, location is ignored.Provide search term or location for start and end.", [mkArg("start search", k_String_), mkArg("start loc", k_Location_), mkArg("end search", k_String_), mkArg("end loc", k_Location_)], k_Nothing);
self.md_resumes();
self.md_arg("start search").md_defl("");
self.md_arg("start loc").md_deflExpr('senses->current_location');
self.md_arg("end search").md_defl("");
self.md_uiAsync();
self = mkProp(4, k_Maps, "open map", "Opens the Bing map application. zoom between 0 (close) and 1 (far).", [mkArg("center", k_Location_), mkArg("search", k_String_), mkArg("zoom", k_Number_)], k_Nothing);
self.md_resumes();
self.md_arg("center").md_deflExpr('senses->current_location');
self.md_arg("search").md_defl("");
self.md_arg("zoom").md_defl(0.6);
self.md_uiAsync();
self = mkProp(0, k_Math_, "map range", "Maps an integer value from one range to another. Does not contrain the value.", [mkArg("x", k_Number_), mkArg("in min", k_Number_), mkArg("in max", k_Number_), mkArg("out min", k_Number_), mkArg("out max", k_Number_)], k_Number_);
self.md_arg("result").md_writesMutable();
self.md_arg("in max").md_defl(1023);
self.md_arg("out max").md_defl(4);
self = mkProp(0, k_Math_, "create matrix", "Creates a matrix of zeros of a given size", [mkArg("rows", k_Number_), mkArg("columns", k_Number_)], k_Matrix);
self.md_arg("result").md_writesMutable();
self.md_arg("rows").md_defl(3);
self.md_arg("columns").md_defl(3);
self = mkProp(32, k_Math_, "ceiling", "Returns the smallest integral value greater than or equal to the specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(406, k_Math_, "floor", "Returns the largest integer less than or equal to the specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(135, k_Math_, "pow", "Returns a specified number raised to the specified power", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "random range", "Returns a random integral number between `min` and `max` included.", [mkArg("min", k_Number_), mkArg("max", k_Number_)], k_Number_);
self.md_tandre();
self.md_arg("min").md_defl(-100);
self.md_arg("max").md_defl(100);
self = mkProp(825, k_Math_, "random", "Returns a random integral number bounded between limit and 0, not including limit unless it is 0", [mkArg("limit", k_Number_)], k_Number_);
self.md_tandre();
self.md_arg("limit").md_defl(2);
self.md_oldName("rand");
self = mkProp(65, k_Math_, "random normalized", "Returns a random floating-point number x: 0 ≤ x < 1", [], k_Number_);
self.md_tandre();
self = mkProp(17, k_Math_, "rand norm", "Renamed to 'random normalized'", [], k_Number_);
self.md_hidden();
self.md_tandre();
self = mkProp(0, k_Math_, "div", "Returns the result of integer division of one number by another number", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(294, k_Math_, "mod", "Returns the modulus resulting from the division of one number by another number", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(318, k_Math_, "abs", "Returns the absolute value of a number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(17, k_Math_, "acos", "Returns the angle whose cosine is the specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(35, k_Math_, "asin", "Returns the angle whose sine is the specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(25, k_Math_, "atan", "Returns the angle whose tangent is the specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(35, k_Math_, "atan2", "Returns the angle whose tangent is the quotient of two specified numbers", [mkArg("y", k_Number_), mkArg("x", k_Number_)], k_Number_);
self = mkProp(252, k_Math_, "cos", "Returns the cosine of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "e", "Returns the natural logarithmic base, specified by the constant, e", [], k_Number_);
self = mkProp(75, k_Math_, "exp", "Returns e raised to the specified power", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(3, k_Math_, "log", "Returns the logarithm of a specified number in a specified base", [mkArg("x", k_Number_), mkArg("base", k_Number_)], k_Number_);
self = mkProp(102, k_Math_, "loge", "Returns the natural (base e) logarithm of a specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(19, k_Math_, "log10", "Returns the base 10 logarithm of a specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(72, k_Math_, "max", "Returns the larger of two numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(38, k_Math_, "min", "Returns the smaller of two numbers", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(187, k_Math_, "π", "Returns the Pi constant", [], k_Number_);
self.md_jsName("pi");
self = mkProp(0, k_Math_, "gravity", "Returns the gravity constant (9.80665)", [], k_Number_);
self = mkProp(212, k_Math_, "round", "Rounds a number to the nearest integral value", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(75, k_Math_, "sign", "Returns a value indicating the sign of a number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(246, k_Math_, "sin", "Returns the sine of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(248, k_Math_, "sqrt", "Returns the square root of a specified number", [mkArg("x", k_Number_)], k_Number_);
self = mkProp(30, k_Math_, "tan", "Returns the tangent of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(73, k_Math_, "deg to rad", "Converts degrees into radians", [mkArg("degrees", k_Number_)], k_Number_);
self = mkProp(19, k_Math_, "rad to deg", "Converts rad into degrees", [mkArg("radians", k_Number_)], k_Number_);
self = mkProp(3, k_Math_, "∞₊", "Returns the positive infinity", [], k_Number_);
self.md_jsName("pos_inf");
self = mkProp(0, k_Math_, "∞₋", "Returns the negative infinity", [], k_Number_);
self.md_jsName("neg_inf");
self = mkProp(19, k_Math_, "is ∞", "Indicates whether number evaluates to negative or positive infinity", [mkArg("x", k_Number_)], k_Boolean_);
self.md_jsName("is_inf");
self = mkProp(0, k_Math_, "is ∞₊", "Indicates whether number evaluates to positive infinity", [mkArg("x", k_Number_)], k_Boolean_);
self.md_jsName("is_pos_inf");
self = mkProp(0, k_Math_, "is ∞₋", "Indicates whether number evaluates to negative infinity", [mkArg("x", k_Number_)], k_Boolean_);
self.md_jsName("is_neg_inf");
self = mkProp(35, k_Math_, "is nan", "Indicates that value cannot be represented as a number, i.e. Not-a-Number. This usually happens when the number is the result of a division by zero.", [mkArg("x", k_Number_)], k_Boolean_);
self = mkProp(114, k_Math_, "round with precision", "Rounds a number to a specified number of fractional digits.", [mkArg("x", k_Number_), mkArg("digits", k_Number_)], k_Number_);
self.md_arg("digits").md_defl(2);
self = mkProp(0, k_Math_, "cosh", "Returns the hyperbolic cosine of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "sinh", "Returns the hyperbolic sine of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "tanh", "Returns the hyperbolic tangent of the specified angle (in radians)", [mkArg("angle", k_Number_)], k_Number_);
self = mkProp(54, k_Math_, "create number map", "Use Collections->create number map instead.", [], k_NumberMap);
self.md_hidden();
self.md_arg("result").md_writesMutable();
self = mkProp(101, k_Math_, "create vector3", "Creates a 3D vector", [mkArg("x", k_Number_), mkArg("y", k_Number_), mkArg("z", k_Number_)], k_Vector3);
self = mkProp(0, k_Math_, "ε", "Returns the machine epsilon, the smallest positive number greater than zero.", [], k_Number_);
self.md_jsName("epsilon");
self = mkProp(0, k_Math_, "clamp", "Clamps `value` between `min` and `max`", [mkArg("min", k_Number_), mkArg("max", k_Number_), mkArg("value", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "normalize", "Clamps `value` between 0 and 1.", [mkArg("value", k_Number_)], k_Number_);
self = mkProp(9, k_Math_, "ieee remainder", "Returns the remainder resulting from the division of a specified number by another specified number", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Number_);
self = mkProp(0, k_Math_, "range", "Return numbers between `start` and `start + length - 1` inclusively", [mkArg("start", k_Number_), mkArg("length", k_Number_)], k_Collection.createInstance([k_Number_]));
self = mkProp(0, k_Matrix, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Matrix, "count", "Gets the total number of elements", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "row count", "Gets the number of rows", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "column count", "Gets the number of columns", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "post to wall", "Displays the value of the array on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Matrix, "copy from", "Copies the content from ``other`` starting at position ``row`` and ``column``", [mkArg("row", k_Number_), mkArg("column", k_Number_), mkArg("other", k_Matrix)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Matrix, "at", "Gets the value at a given index. Elements are ordered line by line starting top left.", [mkArg("index", k_Number_)], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "set at", "Sets the value at a given index. Elements are ordered line by line starting top left.", [mkArg("index", k_Number_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Matrix, "item", "Gets the value at a given location. Returns invalid if outside of the array dimensions", [mkArg("row", k_Number_), mkArg("column", k_Number_)], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "set item", "Sets the value at a particular position. The matrix  will be expanded if the position falls outside the boundaries.", [mkArg("row", k_Number_), mkArg("column", k_Number_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Matrix, "clone", "Creates a deep copy of the matrix.", [], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "min", "Computes the minimum of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "max", "Computes the maximum of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "scale", "Returns a copy of the matrix scaled by factor.", [mkArg("factor", k_Number_)], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "negate", "Returns the matrix negated.", [], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "transpose", "Returns the transposed matrix.", [], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "add", "Returns a matrix resulting from adding this matrix to b. The size of both matrices must match.", [mkArg("b", k_Matrix)], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "subtract", "Returns a matrix resulting from subtracting b from this matrix. The size of both matrices must match.", [mkArg("b", k_Matrix)], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "multiply", "Returns a matrix resulting from multiply each element in the matrices. The size of both matrices must match.", [mkArg("b", k_Matrix)], k_Matrix);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "to string", "Gets the string representation of the matrix", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Matrix, "random", "Gets a random element. Returns invalid if the matrix is empty.", [], k_Number_);
self.md_tandre();
self.md_readsMutable();
self = mkProp(0, k_Matrix, "clear", "Sets all the element of the matrix to the value.", [mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Media, "tone", "Plays a monotone sine wave", [mkArg("frequency", k_Number_), mkArg("gain", k_Number_)], k_Nothing);
self.md_arg("gain").md_defl(1);
self.md_arg("frequency").md_defl(440);
self = mkProp(0, k_Media, "play note", "Plays a monotone note", [mkArg("frequency", k_Number_), mkArg("gain", k_Number_), mkArg("seconds", k_Number_)], k_Nothing);
self.md_resumes();
self.md_arg("gain").md_defl(1);
self.md_arg("frequency").md_defl(440);
self.md_arg("seconds").md_defl(1);
self.md_async();
self = mkProp(378, k_Media, "create picture", "Creates a new picture of the given size", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Picture);
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(480);
self.md_arg("height").md_defl(800);
self = mkProp(58, k_Media, "choose picture", "Chooses a picture from the media library", [], k_Picture);
self.md_resumes();
self.md_flow("SourcePicture");
self.md_uiAsync();
self.md_import("cordova", "cordova-plugin-camera");
self = mkProp(729, k_Media, "create board", "Creates a new game board", [mkArg("height", k_Number_)], k_Board);
self.md_needsFrame();
self.md_timestamp();
self.md_arg("result").md_writesMutable();
self.md_arg("height").md_defl(640);
self = mkProp(225, k_Media, "create full board", "Creates a new game board in portrait mode. On rotatable devices it will take the entire screen when posted.", [], k_Board);
self.md_needsFrame();
self.md_obsolete();
self.md_timestamp();
self.md_arg("result").md_writesMutable();
self = mkProp(46, k_Media, "create portrait board", "Creates a new game board in portrait mode. On rotatable devices it will take the entire screen when posted.", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Board);
self.md_needsFrame();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(480);
self.md_arg("height").md_defl(800);
self = mkProp(56, k_Media, "create landscape board", "Creates a new game board in landscape mode. On rotatable devices it will take the entire screen when posted.", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Board);
self.md_needsFrame();
self.md_arg("result").md_writesMutable();
self.md_arg("width").md_defl(800);
self.md_arg("height").md_defl(480);
self = mkProp(3, k_Media, "icon names", "Gets the list of built-in 48x48 icon names. You can see the icon list in the script settings.", [], k_Collection.createInstance([k_String_]));
self.md_hidden();
self.md_cap("editoronly");
self = mkProp(72, k_Media, "icon", "Gets a 48x48 icon picture. Use 'media->icon names' to retrieve the list of names available.", [mkArg("name", k_String_)], k_Picture);
self.md_hidden();
self.md_cap("editoronly");
self = mkProp(175, k_Media, "large icon", "Gets a 96x96 icon picture. Use 'media->icon names' to retrieve the list of names available.", [mkArg("name", k_String_)], k_Picture);
self.md_hidden();
self.md_cap("editoronly");
self = mkProp(0, k_Message, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(4, k_Message, "title", "Gets the title text", [], k_String_);
self.md_readsMutable();
self = mkProp(8, k_Message, "set title", "Sets the title text", [mkArg("title", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(4, k_Message, "message", "Gets the message text", [], k_String_);
self.md_readsMutable();
self = mkProp(1, k_Message, "set message", "Sets the message text", [mkArg("message", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Message, "id", "Gets the message identifier", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Message, "set id", "Sets the message identifier", [mkArg("value", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(2, k_Message, "from", "Gets the author", [], k_String_);
self.md_readsMutable();
self = mkProp(6, k_Message, "set from", "Sets the author", [mkArg("author", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(2, k_Message, "to", "Gets the recipient", [], k_String_);
self.md_readsMutable();
self = mkProp(4, k_Message, "set to", "Sets the recipient", [mkArg("author", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(2, k_Message, "picture link", "Gets a url to the picture", [], k_String_);
self.md_readsMutable();
self = mkProp(4, k_Message, "set picture link", "Sets the url to the picture", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(5, k_Message, "link", "Gets the link associated to the message", [], k_String_);
self.md_readsMutable();
self = mkProp(4, k_Message, "set link", "Sets the link associated to the message", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Message, "media link", "Gets a url to the media", [], k_String_);
self.md_readsMutable();
self = mkProp(1, k_Message, "set media link", "Sets the url to the media", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Message, "location", "Gets the geo coordinates", [], k_Location_);
self.md_readsMutable();
self = mkProp(1, k_Message, "set location", "Sets the geo coordinates", [mkArg("location", k_Location_)], k_Nothing);
self.md_writesMutable();
self = mkProp(4, k_Message, "time", "Gets the time", [], k_DateTime);
self.md_readsMutable();
self = mkProp(7, k_Message, "set time", "Sets the time", [mkArg("time", k_DateTime)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Message, "source", "Gets the source of this message (Facebook, Twitter, etc...)", [], k_String_);
self.md_readsMutable();
self = mkProp(6, k_Message, "set source", "Sets the source of this message", [mkArg("source", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(5, k_Message, "share", "Shares this message (email, sms, facebook, social or '' to pick from a list)", [mkArg("network", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_readsMutable();
self.md_arg("network").md_defl("social");
self.md_uiAsync();
self = mkProp(1, k_Message, "values", "Gets the additional values stored in the message", [], k_StringMap);
self.md_readsMutable();
self = mkProp(6, k_Message, "post to wall", "Posts the message to the wall", [], k_Nothing);
self.md_needsFrame();
self.md_flow("SinkWeb");
self.md_readsMutable();
self = mkProp(110, k_Number_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(1311, k_Number_, "to string", "Converts a number to a string", [], k_String_);
self = mkProp(57, k_Number_, "post to wall", "Prints the number to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(57, k_Number_, "to character", "Interprets a number as a unicode value and converts it to the single character string", [], k_String_);
self = mkProp(5, k_Number_, "to color", "Interprets the number as a ARGB (alpha, red, green, blue) color", [], k_Color);
self = mkProp(0, k_Number_, "to json", "Converts the value into a json data structure.", [], k_JsonObject);
self = mkProp(6862, k_Number_, "+", "Adds numbers", [mkArg("other", k_Number_)], k_Number_);
self.md_infixPriority(10);
self.md_inlineApply("+");
self.md_jsName("add");
self = mkProp(6795, k_Number_, "-", "Subtracts numbers", [mkArg("other", k_Number_)], k_Number_);
self.md_infixPriority(10);
self.md_inlineApply("-");
self.md_jsName("subtract");
self = mkProp(5659, k_Number_, "*", "Multiplies numbers", [mkArg("other", k_Number_)], k_Number_);
self.md_infixPriority(20);
self.md_inlineApply("*");
self.md_jsName("multiply");
self = mkProp(4062, k_Number_, "/", "Divides numbers", [mkArg("other", k_Number_)], k_Number_);
self.md_infixPriority(20);
self.md_inlineApply("/");
self.md_jsName("divide");
self = mkProp(3668, k_Number_, "=", "Compares numbers for equality", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply("===");
self.md_jsName("eq");
self = mkProp(354, k_Number_, "≠", "Compares numbers for disequality", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply("!==");
self.md_jsName("neq");
self = mkProp(420, k_Number_, "≤", "Compares numbers for less or equal", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply("<=");
self.md_jsName("le");
self = mkProp(1592, k_Number_, "<", "Compares numbers for less", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply("<");
self.md_jsName("lt");
self = mkProp(568, k_Number_, "≥", "Compares numbers for more or equal", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply(">=");
self.md_jsName("ge");
self = mkProp(1685, k_Number_, ">", "Compares numbers for more", [mkArg("other", k_Number_)], k_Boolean_);
self.md_infixPriority(5);
self.md_inlineApply(">");
self.md_jsName("gt");
self = mkProp(26, k_NumberMap, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(147, k_NumberMap, "count", "Gets the number of elements", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_NumberMap, "clear", "Clears the number map.", [], k_Nothing);
self = mkProp(5, k_NumberMap, "sum", "Computes the sum of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(3, k_NumberMap, "avg", "Computes the average of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(2, k_NumberMap, "slice", "Extracts the elements at indices between start (inclusive) and end (non-inclusive).", [mkArg("start", k_Number_), mkArg("end", k_Number_)], k_NumberMap);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(5, k_NumberMap, "min", "Computes the minimum of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(9, k_NumberMap, "max", "Computes the maximum of the values", [], k_Number_);
self.md_readsMutable();
self = mkProp(1017, k_NumberMap, "at", "Gets the element at index. Index may be any floating-point value.", [mkArg("index", k_Number_)], k_Number_);
self.md_readsMutable();
self = mkProp(792, k_NumberMap, "set at", "Sets the element at index. Index may be any floating-point value.", [mkArg("index", k_Number_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_NumberMap, "set many", "Sets many elements at once.", [mkArg("numbers", k_NumberMap)], k_Nothing);
self.md_writesMutable();
self.md_arg("numbers").md_readsMutable();
self = mkProp(0, k_NumberMap, "remove", "Removes the value at a given index", [mkArg("index", k_Number_)], k_Nothing);
self = mkProp(0, k_NumberMap, "update on wall", "Updates any display of this map", [], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_NumberMap, "to json", "Exports a JSON representation of the contents.", [], k_JsonObject);
self.md_readsMutable();
self = mkProp(0, k_NumberMap, "from json", "Imports a JSON representation of the contents.", [mkArg("jobj", k_JsonObject)], k_Nothing);
self.md_writesMutable();
self = mkProp(36, k_NumberMap, "post to wall", "Displays the map in a line chart; you need to call 'update on wall' later if you want changes to be reflected.", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_OAuthResponse, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_OAuthResponse, "access token", "The access token issued by the authorization server.", [], k_String_);
self = mkProp(0, k_OAuthResponse, "expires in", "(Optional) The lifetime in seconds of the access token.", [], k_Number_);
self = mkProp(0, k_OAuthResponse, "scope", "(Optional) Optional if identical to the scope requested by the client; otherwise, the scope of the access token as described by Section 3.3 of the OAuth 2.0 specification.", [], k_String_);
self = mkProp(0, k_OAuthResponse, "error", "A single ASCII [USASCII] error code.", [], k_String_);
self = mkProp(0, k_OAuthResponse, "error description", "(Optional) A human readable error code.", [], k_String_);
self = mkProp(0, k_OAuthResponse, "error uri", "(Optional) A URI identifying a human-readable web page with information about the error, used to provide the client developer with additional information about the error.", [], k_String_);
self = mkProp(0, k_OAuthResponse, "others", "(Optional) Additional key-value pairs not covered by the OAuth 2.0 specification.", [], k_StringMap);
self = mkProp(0, k_OAuthResponse, "is expiring", "(Optional) Indicates if the token might expire within the next seconds.", [mkArg("seconds", k_Number_)], k_Boolean_);
self.md_arg("seconds").md_defl(100);
self = mkProp(0, k_OAuthResponse, "is error", "Indicates if this response is an error.", [], k_Boolean_);
self = mkProp(0, k_OAuthResponse, "post to wall", "Displays the response.", [], k_Nothing);
self.md_needsFrame();
self = mkProp(4, k_Page, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Page, "on navigated from", "Sets a handler that runs when the page is popped.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(41, k_Page, "equals", "Gets a value indicating if the page is equal to the other", [mkArg("other", k_Page)], k_Boolean_);
self = mkProp(2, k_Page, "post to wall", "Does nothing.", [], k_Nothing);
self.md_hidden();
self = mkProp(0, k_PageButton, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(1, k_PageButton, "page", "Gets the page hosting this button", [], k_Page);
self = mkProp(9, k_PageButton, "equals", "Gets a value indicating if both instances are equal", [mkArg("page button", k_PageButton)], k_Boolean_);
self = mkProp(3, k_PageButton, "post to wall", "Pushes this button on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(122, k_PageButton, "icon", "Gets the icon name", [], k_String_);
self.md_readsMutable();
self = mkProp(172, k_PageButton, "text", "Gets the text", [], k_String_);
self.md_readsMutable();
self = mkProp(22, k_Phone, "dial phone number", "Starts a phone call", [mkArg("n", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_uiAsync();
self = mkProp(0, k_Phone, "save phone number", "Allows the user to save the phone number", [mkArg("phone number", k_String_)], k_Nothing);
self.md_cap("contacts");
self.md_flow("SinkContacts");
self = mkProp(0, k_Phone, "save contact", "Obsolete, use social->save contact instead", [mkArg("contact", k_Contact)], k_Nothing);
self.md_obsolete();
self.md_cap("contacts");
self.md_flow("SinkContacts");
self.md_uiAsync();
self = mkProp(208, k_Phone, "vibrate", "Vibrates the phone for ... seconds (0.02 minimum)", [mkArg("seconds", k_Number_)], k_Nothing);
self.md_arg("seconds").md_defl(0.1);
self.md_import("cordova", "cordova-plugin-vibration");
self = mkProp(4, k_Phone, "power source", "Indicates if the phone is on 'battery' or 'external' power source.", [], k_String_);
self.md_resumes();
self.md_quickAsync();
self = mkProp(124, k_Picture, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Picture, "count", "Gets the number of pixels", [], k_Number_);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(16, k_Picture, "date", "Gets the date time where the picture was taken; if any.", [], k_DateTime);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(171, k_Picture, "height", "Gets the height in pixels", [], k_Number_);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(0, k_Picture, "equals", "Checks if the picture is the same instance as the other picture. This action does not check that pixels are the same between two different pictures.", [mkArg("other picture", k_Picture)], k_Boolean_);
self = mkProp(16, k_Picture, "is panorama", "Indicates if the picture width is greater than its height", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(3, k_Picture, "location", "Gets the location where the picture was taken; if any.", [], k_Location_);
self.md_resumes();
self.md_flow("SourceGeoLocation");
self.md_readsMutable();
self.md_picAsync();
self = mkProp(206, k_Picture, "width", "Gets the width in pixels", [], k_Number_);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(44, k_Picture, "update on wall", "Refreshes the picture on the wall", [], k_Nothing);
self.md_readsMutable();
self = mkProp(4, k_Picture, "at", "Gets the pixel color at the given linear index", [mkArg("index", k_Number_)], k_Color);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(205, k_Picture, "blend", "Writes another picture at a given location. The opacity ranges from 0 (transparent) to 1 (opaque).", [mkArg("other", k_Picture), mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("angle", k_Number_), mkArg("opacity", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("other").md_readsMutable();
self.md_arg("opacity").md_defl(1);
self.md_picAsync();
self = mkProp(369, k_Picture, "clone", "Returns a copy of the image", [], k_Picture);
self.md_resumes();
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_picAsync();
self = mkProp(228, k_Picture, "fill rect", "Fills a rectangle with a given color", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(100);
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->accent');
self.md_picAsync();
self = mkProp(73, k_Picture, "pixel", "Gets the pixel color", [mkArg("left", k_Number_), mkArg("top", k_Number_)], k_Color);
self.md_resumes();
self.md_readsMutable();
self.md_picAsync();
self = mkProp(252, k_Picture, "resize", "Resizes the picture to the given size in pixels", [mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(-1);
self.md_picAsync();
self = mkProp(77, k_Picture, "save to library", "Saves the picture and returns the file name if successful.", [], k_String_);
self.md_resumes();
self.md_flow("SinkMedia");
self.md_readsMutable();
self.md_ignoreReturnValue();
self.md_async();
self = mkProp(72, k_Picture, "clear", "Clears the picture to a given color", [mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->transparent');
self.md_picAsync();
self = mkProp(0, k_Picture, "clear rect", "Clears a rectangle on a the picture to a given color", [mkArg("color", k_Color), mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->transparent');
self.md_arg("width").md_defl(10);
self.md_arg("height").md_defl(10);
self.md_picAsync();
self = mkProp(78, k_Picture, "colorize", "Recolors the picture with the background and foreground color, based on a color threshold between 0.0 and 1.0", [mkArg("background", k_Color), mkArg("foreground", k_Color), mkArg("threshold", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("background").md_deflExpr('colors->accent');
self.md_arg("foreground").md_deflExpr('colors->background');
self.md_arg("threshold").md_defl(0.65);
self.md_picAsync();
self = mkProp(0, k_Picture, "negative", "Inverts the colors in the picture", [], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(13, k_Picture, "desaturate", "Makes picture monochromatic (black and white)", [], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(19, k_Picture, "invert", "Inverts the red, blue and green channels", [], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(95, k_Picture, "tint", "Converts every pixel to gray and tints it with the given color.", [mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->sepia');
self.md_picAsync();
self = mkProp(16, k_Picture, "brightness", "Changes the brightness of the picture. factor in [-1, 1].", [mkArg("factor", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("factor").md_defl(0.05);
self.md_picAsync();
self = mkProp(15, k_Picture, "contrast", "Changes the contrast of the picture. factor in [-1, 1].", [mkArg("factor", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("factor").md_defl(0.05);
self.md_picAsync();
self = mkProp(129, k_Picture, "crop", "Crops a sub-image", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(161, k_Picture, "draw ellipse", "Draws an elliptic border with a given color", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("angle", k_Number_), mkArg("c", k_Color), mkArg("thickness", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(100);
self.md_arg("angle").md_defl(0);
self.md_arg("c").md_deflExpr('colors->accent');
self.md_arg("thickness").md_defl(3);
self.md_picAsync();
self = mkProp(187, k_Picture, "draw line", "Draws a line between two points", [mkArg("x1", k_Number_), mkArg("y1", k_Number_), mkArg("x2", k_Number_), mkArg("y2", k_Number_), mkArg("color", k_Color), mkArg("thickness", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->accent');
self.md_arg("thickness").md_defl(3);
self.md_picAsync();
self = mkProp(72, k_Picture, "draw rect", "Draws a rectangle border with a given color", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color), mkArg("thickness", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(100);
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->accent');
self.md_arg("thickness").md_defl(3);
self.md_picAsync();
self = mkProp(465, k_Picture, "draw text", "Draws some text border with a given color and font size", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("text", k_String_), mkArg("font size", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("font size").md_defl(16);
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->foreground');
self.md_picAsync();
self = mkProp(215, k_Picture, "fill ellipse", "Fills a ellipse with a given color", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(100);
self.md_arg("height").md_defl(100);
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->random');
self.md_picAsync();
self = mkProp(0, k_Picture, "draw path", "Draws a path with a given color.", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color), mkArg("thickness", k_Number_), mkArg("data", k_String_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->random');
self.md_picAsync();
self = mkProp(0, k_Picture, "fill path", "Fills a path with a given color.", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("angle", k_Number_), mkArg("color", k_Color), mkArg("data", k_String_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("angle").md_defl(0);
self.md_arg("color").md_deflExpr('colors->random');
self.md_picAsync();
self = mkProp(62, k_Picture, "set pixel", "Sets the pixel color at a given pixel", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("color", k_Color)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->accent');
self.md_picAsync();
self = mkProp(0, k_Picture, "to buffer", "Copy all pixels from the picture", [], k_Buffer);
self.md_resumes();
self.md_allocates();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(0, k_Picture, "write buffer", "Copy pixels from `buffer` to the picture", [mkArg("buffer", k_Buffer)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(4, k_Picture, "share", "Shares this message ('' to pick from a list)", [mkArg("where", k_String_), mkArg("message", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_readsMutable();
self.md_uiAsync();
self = mkProp(23, k_Picture, "flip horizontal", "Flips the picture horizontally", [], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(17, k_Picture, "flip vertical", "Flips the picture vertically", [], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(0, k_Picture, "to data uri", "Encodes the image into a data uri using the desired quality (1 best, 0 worst). If the quality value is 1, the image is encoded as PNG, otherwise JPEG.", [mkArg("quality", k_Number_)], k_String_);
self.md_resumes();
self.md_async();
self.md_readsMutable();
self.md_arg("quality").md_defl(0.85);
self.md_picAsync();
self = mkProp(0, k_Picture, "blend svg", "Writes an Scalable Vector Graphics (SVG) document at a given location. By default, this action uses the viewport size provided in the SVG document when width or height are negative.", [mkArg("markup", k_String_), mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("angle", k_Number_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_arg("width").md_defl(-1);
self.md_arg("height").md_defl(-1);
self.md_picAsync();
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(296, k_Picture, "post to wall", "Displays the image to the wall; you need to call 'update on wall' later if you want changes to be reflected.", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self.md_embedsLink("Wall", "Picture");
self = mkProp(0, k_Picture, "docs render", "Shows an art picture in the docs.", [mkArg("height", k_Number_), mkArg("caption", k_String_)], k_Nothing);
self.md_docsOnly();
self = mkProp(0, k_Picture, "readonly url", "Get the web address of an art resource; invalid if not available.", [], k_String_);
self = mkProp(0, k_Place, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(11, k_Place, "location", "Gets the location of the place", [], k_Location_);
self.md_readsMutable();
self = mkProp(1, k_Place, "set location", "Sets the location of the place", [mkArg("location", k_Location_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Place, "id", "Gets the identifier of this place", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Place, "set id", "Sets the identifier of this place", [mkArg("id", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(14, k_Place, "name", "Gets the name of the place", [], k_String_);
self.md_readsMutable();
self = mkProp(1, k_Place, "set name", "Sets the name of the place", [mkArg("name", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_Place, "picture link", "Gets a url to the picture", [], k_String_);
self.md_readsMutable();
self = mkProp(1, k_Place, "set picture link", "Sets the url to the picture", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Place, "link", "Gets the link associated to the message", [], k_String_);
self.md_readsMutable();
self = mkProp(1, k_Place, "set link", "Sets the link associated to the place", [mkArg("url", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Place, "category", "Gets the category of the place", [], k_String_);
self.md_readsMutable();
self = mkProp(5, k_Place, "set category", "Sets the category of the place", [mkArg("category", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Place, "source", "Gets the source of this place", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Place, "set source", "Sets the source of this place", [mkArg("source", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Place, "values", "Gets the additional values stored in the place", [], k_StringMap);
self.md_readsMutable();
self = mkProp(0, k_Place, "to string", "Converts to a string name,lat,long", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Place, "check in", "Checks into the place (supported for Facebook)", [], k_Nothing);
self.md_obsolete();
self.md_stub();
self.md_flow("SinkSharing");
self.md_readsMutable();
self = mkProp(2, k_Place, "post to wall", "Posts the place to the wall", [], k_Nothing);
self.md_needsFrame();
self.md_cap("maps", "network");
self.md_flow("SinkWeb");
self.md_readsMutable();
self = mkProp(157, k_Player, "active song", "Gets the active song if any", [], k_Song);
self.md_resumes();
self.md_quickAsync();
self.md_readsMutable();
self.md_embedsLink("Player", "Song");
self = mkProp(0, k_Player, "on active song changed", "Attaches a handler when the active song changes", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Player, "on player state changed", "Attaches a handler when the player state changes", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(41, k_Player, "pause", "Pauses the currently playing song", [], k_Nothing);
self.md_cap("musicandsounds");
self.md_writesMutable();
self = mkProp(25, k_Player, "play", "Plays a Song", [mkArg("song", k_Song)], k_Nothing);
self.md_cap("musicandsounds");
self.md_writesMutable();
self.md_arg("song").md_readsMutable();
self.md_arg("song").md_writesMutable();
self = mkProp(19, k_Player, "play position", "Gets the position in seconds whithin the active song", [], k_Number_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(44, k_Player, "resume", "Resumes a paused song", [], k_Nothing);
self.md_cap("musicandsounds");
self.md_writesMutable();
self = mkProp(35, k_Player, "stop", "Stops playing a song", [], k_Nothing);
self.md_cap("musicandsounds");
self.md_writesMutable();
self = mkProp(12, k_Player, "is muted", "Indicates if the player is muted", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(0, k_Player, "sound volume", "Gets the sound volume for sounds from 0 (silent) to 1 (current volume)", [], k_Number_);
self.md_stub();
self.md_cap("media");
self.md_readsMutable();
self = mkProp(0, k_Player, "set sound volume", "Sets the sound volume level from 0 (silent) to 1 (current volume)", [mkArg("x", k_Number_)], k_Nothing);
self.md_stub();
self.md_cap("media");
self = mkProp(6, k_Player, "is repeating", "Indicates if the player is repeating", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(15, k_Player, "set repeating", "Sets the repeating on and off", [mkArg("repeating", k_Boolean_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_quickAsync();
self.md_arg("repeating").md_defl(true);
self = mkProp(10, k_Player, "is shuffled", "Indicates if the player is shuffled", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(22, k_Player, "set shuffled", "Sets the shuffling on and off", [mkArg("shuffled", k_Boolean_)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_quickAsync();
self.md_arg("shuffled").md_defl(true);
self = mkProp(14, k_Player, "is stopped", "Indicates if the player is stopped", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(78, k_Player, "is playing", "Indicates if the player is playing a song", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(38, k_Player, "is paused", "Indicates if the player is paused", [], k_Boolean_);
self.md_resumes();
self.md_readsMutable();
self.md_quickAsync();
self = mkProp(0, k_Player, "volume", "Volume is no longer supported.", [], k_Number_);
self.md_obsolete();
self.md_readsMutable();
self = mkProp(0, k_Senses, "on shake", "Attaches a handler to the `shake` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(0, k_Senses, "on phone face up", "Attaches a handler to the `phone face up` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(0, k_Senses, "on phone face down", "Attaches a handler to the `phone face down` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(0, k_Senses, "on phone portrait", "Attaches a handler to the `phone portrait` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(0, k_Senses, "on phone landscape left", "Attaches a handler to the `phone landscape left` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(0, k_Senses, "on phone landscape right", "Attaches a handler to the `phone landscape right` event.", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_cap("accelerometer");
self = mkProp(19, k_Senses, "take camera picture", "Takes a picture and returns it. This picture does not contain the gps location.", [], k_Picture);
self.md_resumes();
self.md_flow("SourceCamera");
self.md_uiAsync();
self.md_import("cordova", "cordova-plugin-camera");
self = mkProp(40, k_Senses, "record microphone", "Records audio using the microphone", [], k_Sound);
self.md_resumes();
self.md_uiAsync();
self.md_cap("microphone");
self.md_flow("SourceMicrophone");
self = mkProp(5, k_Senses, "is device stable", "Indicates whether the device is 'stable' (no movement for about 0.5 seconds)", [], k_Boolean_);
self.md_resumes();
self.md_cap("accelerometer");
self.md_quickAsync();
self.md_tandre();
self = mkProp(2, k_Senses, "has accelerometer", "Indicates if an accelerometer is available.", [], k_Boolean_);
self = mkProp(5, k_Senses, "acceleration stable", "Gets filtered and temporally averaged accelerometer data using an arithmetic mean of the last 25 'optimally filtered' samples, so over 500ms at 50Hz on each axis, to virtually eliminate most sensor noise. This provides a very stable reading but it has also a very high latency and cannot be used for rapidly reacting UI.", [], k_Vector3);
self.md_resumes();
self.md_cap("accelerometer");
self.md_quickAsync();
self.md_tandre();
self = mkProp(17, k_Senses, "acceleration smooth", "Gets filtered accelerometer data using a 1 Hz first-order low-pass on each axis to eliminate the main sensor noise while providing a medium latency. This can be used for moderately reacting UI updates requiring a very smooth signal.", [], k_Vector3);
self.md_resumes();
self.md_cap("accelerometer");
self.md_quickAsync();
self.md_tandre();
self = mkProp(89, k_Senses, "acceleration quick", "Gets filtered accelerometer data using a combination of a low-pass and threshold triggered high-pass on each axis to eliminate the majority of the sensor low amplitude noise while trending very quickly to large offsets (not perfectly smooth signal in that case), providing a very low latency. This is ideal for quickly reacting UI updates.", [], k_Vector3);
self.md_resumes();
self.md_cap("accelerometer");
self.md_quickAsync();
self.md_tandre();
self.md_allowInRestricted();
self = mkProp(109, k_Senses, "current location", "Gets the current approximate phone location. The phone optimizes the accuracy for power, performance, and other cost considerations.", [], k_Location_);
self.md_resumes();
self.md_async();
self.md_cap("location");
self.md_flow("SourceGeoLocation");
self.md_tandre();
self = mkProp(39, k_Senses, "current location accurate", "Gets the current phone location with the most accuracy. This includes using services that might charge money, or consuming higher levels of battery power or connection bandwidth.", [], k_Location_);
self.md_resumes();
self.md_async();
self.md_cap("location");
self.md_flow("SourceGeoLocation");
self.md_tandre();
self = mkProp(40, k_Senses, "camera", "Gets the primary camera if available", [], k_Camera);
self.md_resumes();
self.md_cap("camera");
self.md_quickAsync();
self = mkProp(0, k_Senses, "front camera", "Gets the front facing camera if available", [], k_Camera);
self.md_resumes();
self.md_cap("camera");
self.md_quickAsync();
self = mkProp(2, k_Senses, "has front camera", "Test if the senses→front camera is invalid instead", [], k_Boolean_);
self.md_resumes();
self.md_obsolete();
self.md_cap("camera");
self.md_quickAsync();
self = mkProp(2, k_Senses, "has motion", "Test if the senses→motion is invalid instead.", [], k_Boolean_);
self.md_obsolete();
self.md_stub();
self.md_cap("motion");
self = mkProp(0, k_Senses, "orientation", "Gets the current orientation in degrees if available. (x,y,z) is also called (pitch, roll, yaw) or (alpha, beta, gamma).", [], k_Vector3);
self.md_resumes();
self.md_cap("orientation");
self.md_quickAsync();
self = mkProp(4, k_Senses, "has compass", "Test if the senses→heading is invalid instead", [], k_Boolean_);
self.md_obsolete();
self.md_cap("compass");
self = mkProp(26, k_Senses, "heading", "Gets the compass heading, in degrees, measured clockwise from the Earth’s geographic north.", [], k_Number_);
self.md_resumes();
self.md_cap("compass");
self.md_quickAsync();
self.md_tandre();
self.md_allowInRestricted();
self = mkProp(2, k_Senses, "has gyroscope", "Indicates if the gyroscope is available on the device", [], k_Boolean_);
self.md_hidden();
self.md_cap("gyroscope");
self = mkProp(0, k_Senses, "rotation speed", "Gets the gyroscope rotational velocity around each axis of the device, in degrees per second.", [], k_Vector3);
self.md_resumes();
self.md_cap("gyroscope");
self.md_quickAsync();
self.md_tandre();
self = mkProp(0, k_Senses, "battery level", "Gets the charge level of the battery between 0 (discharged) and 1 (fully charged). Returns invalid if this information is not available.", [], k_Number_);
self.md_resumes();
self.md_quickAsync();
self = mkProp(0, k_Senses, "is key pressed", "Indicates if the specified key is pressed.", [mkArg("key", k_String_)], k_Boolean_);
self.md_needsFrame();
self.md_arg("key").md_deflStrings('space', 'a', 'w', 's', 'd', 'enter', 'left', 'right', 'up', 'down');
self = mkProp(0, k_Senses, "on key pressed", "Attaches an event that triggers while the key is pressed. This event repeats while the key is down.", [mkArg("key", k_String_), mkArg("body", k_Action)], k_EventBinding);
self.md_needsFrame();
self.md_arg("key").md_deflStrings('space', 'a', 'w', 's', 'd', 'enter', 'left', 'right', 'up', 'down');
self.md_ignoreReturnValue();
self = mkProp(0, k_Senses, "gamepads", "Gets a snapshot of the gamepad states (if any connected to the browser). Empty if unsupported or no gamepad connected.", [], k_Collection.createInstance([k_Gamepad_]));
self = mkProp(0, k_Senses, "first gamepad", "Gets the first connected gamepad available", [], k_Gamepad_);
self = mkProp(0, k_Gamepad_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Gamepad_, "equals", "Indicates if the gamepad data are identical", [mkArg("other", k_Gamepad_)], k_Boolean_);
self = mkProp(0, k_Gamepad_, "post to wall", "Displays the state of the gamepad on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Gamepad_, "id", "Gets the gamepad identifier", [], k_String_);
self = mkProp(0, k_Gamepad_, "index", "Gets the player index", [], k_Number_);
self = mkProp(0, k_Gamepad_, "timestamp", "Gets the timestamp of this snapshot", [], k_Number_);
self = mkProp(0, k_Gamepad_, "is connected", "Indicates if the gamepad is still connected.", [], k_Boolean_);
self = mkProp(0, k_Gamepad_, "is button pressed", "Indicates if a button is pressed. Returns false if button missing.", [mkArg("name", k_String_)], k_Boolean_);
self.md_arg("name").md_deflStrings("a", "b", "x", "y", "left bumper", "right bumper", "left trigger", "right trigger", "back", "start", "left stick", "right stick", "up", "down", "left", "right", "home");
self = mkProp(0, k_Gamepad_, "button value", "Gets the pressed value of a button. Returns 0 if button missing.", [mkArg("name", k_String_)], k_Number_);
self.md_arg("name").md_deflStrings("a", "b", "x", "y", "left bumper", "right bumper", "left trigger", "right trigger", "back", "start", "left stick", "right stick", "up", "down", "left", "right", "home");
self = mkProp(0, k_Gamepad_, "axes", "Gets the `x` and `y` value of the selected axes.", [mkArg("name", k_String_)], k_Vector3);
self.md_arg("name").md_deflStrings('left stick', 'right stick');
self = mkProp(0, k_ServerRequest, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_ServerRequest, "response", "Gets the associated response", [], k_ServerResponse);
self = mkProp(0, k_ServerRequest, "content", "Reads the request body as a string", [], k_String_);
self = mkProp(0, k_ServerRequest, "content as buffer", "Reads the request body as a binary buffer", [], k_Buffer);
self = mkProp(0, k_ServerRequest, "content as json", "Reads the request body as a JSON tree", [], k_JsonObject);
self = mkProp(0, k_ServerRequest, "method", "Gets whether it was a 'get', 'post', 'put', 'delete', 'options', etc.", [], k_String_);
self = mkProp(0, k_ServerRequest, "url", "Gets the url of the request", [], k_String_);
self = mkProp(0, k_ServerRequest, "header", "Gets the value of a given header", [mkArg("name", k_String_)], k_String_);
self.md_readsMutable();
self = mkProp(0, k_ServerRequest, "query", "Gets the value of a given query string parameter", [mkArg("name", k_String_)], k_String_);
self.md_readsMutable();
self = mkProp(0, k_ServerRequest, "equals", "Indicates if both requests are the same instance.", [mkArg("other", k_ServerRequest)], k_Boolean_);
self = mkProp(0, k_ServerRequest, "post to wall", "Displays the request to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_ServerRequest, "header names", "Gets the names of the headers", [], k_Collection.createInstance([k_String_]));
self.md_readsMutable();
self = mkProp(0, k_ServerRequest, "query names", "Gets the names of the query string parameters", [], k_Collection.createInstance([k_String_]));
self.md_readsMutable();
self = mkProp(0, k_ServerRequest, "user", "Get the user who sent this request", [], k_User);
self.md_dbgOnly();
self = mkProp(0, k_ServerResponse, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_ServerResponse, "header", "Gets the value of a given header", [mkArg("name", k_String_)], k_String_);
self.md_readsMutable();
self = mkProp(0, k_ServerResponse, "set header", "Sets an HTTP header value. Empty string clears the value", [mkArg("name", k_String_), mkArg("value", k_String_)], k_Nothing);
self = mkProp(0, k_ServerResponse, "request", "Gets the request associated to this response", [], k_ServerRequest);
self = mkProp(0, k_ServerResponse, "status code", "Gets the HTTP Status code of the response (defaults to 200)", [], k_Number_);
self = mkProp(0, k_ServerResponse, "set status code", "Sets the HTTP Status code of the response (defaults to 200)", [mkArg("code", k_Number_)], k_Nothing);
self.md_arg("code").md_defl(403);
self = mkProp(0, k_ServerResponse, "equals", "Indicates if both responses are the same instance.", [mkArg("other", k_ServerResponse)], k_Boolean_);
self = mkProp(0, k_ServerResponse, "post to wall", "Displays the request to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_ServerResponse, "set content type", "Sets the 'Content-Type' HTTP header; call after `->set_content...`", [mkArg("type", k_String_)], k_Nothing);
self.md_arg("type").md_deflStrings('text/html', 'picture/jpeg', 'picture/png');
self = mkProp(0, k_ServerResponse, "set content", "Sets the content of the response", [mkArg("content", k_String_)], k_Nothing);
self = mkProp(0, k_ServerResponse, "set content as json", "Sets the content of the response as the JSON tree", [mkArg("json", k_JsonObject)], k_Nothing);
self = mkProp(0, k_ServerResponse, "set content as buffer", "Sets the content of the response as a binary buffer", [mkArg("bytes", k_Buffer)], k_Nothing);
self = mkProp(0, k_ServerResponse, "set content as xml", "Sets the content of the response as the XML tree", [mkArg("xml", k_XmlObject)], k_Nothing);
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(0, k_ServerResponse, "header names", "Gets the names of the headers", [], k_Collection.createInstance([k_String_]));
self.md_readsMutable();
self = mkProp(12, k_Social, "send email", "Opens the mail client", [mkArg("to", k_String_), mkArg("subject", k_String_), mkArg("body", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_uiAsync();
self = mkProp(0, k_Social, "save email", "Allows the user to save the email address (email)", [mkArg("email address", k_String_)], k_Nothing);
self.md_cap("contacts");
self.md_flow("SinkContacts");
self = mkProp(0, k_Social, "save contact", "Saves a new contact", [mkArg("contact", k_Contact)], k_Nothing);
self.md_cap("contacts");
self.md_flow("SinkContacts");
self = mkProp(25, k_Social, "send sms", "Opens the short message client (to, body)", [mkArg("to", k_String_), mkArg("body", k_String_)], k_Nothing);
self.md_resumes();
self.md_flow("SinkSharing");
self.md_uiAsync();
self = mkProp(0, k_Social, "link phone number", "Creates a link from a phone number", [mkArg("phone number", k_String_)], k_Link);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Social, "link email", "Creates a link from an email", [mkArg("email address", k_String_)], k_Link);
self.md_arg("result").md_writesMutable();
self = mkProp(10, k_Social, "create message", "Creates a message to share", [mkArg("message", k_String_)], k_Message);
self.md_arg("result").md_writesMutable();
self = mkProp(13, k_Social, "create place", "Creates a place", [mkArg("name", k_String_), mkArg("location", k_Location_)], k_Place);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Social, "create contact", "Creates a new contact", [mkArg("nickname", k_String_)], k_Contact);
self.md_arg("nickname").md_writesMutable();
self.md_arg("result").md_writesMutable();
self = mkProp(38, k_Song, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(61, k_Song, "artist", "Gets the name of the artist", [], k_String_);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(32, k_Song, "duration", "Gets the duration in seconds", [], k_Number_);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(11, k_Song, "genre", "Gets the genre of the song", [], k_String_);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(139, k_Song, "name", "Gets the name of the song", [], k_String_);
self = mkProp(5, k_Song, "play count", "Gets the play count", [], k_Number_);
self.md_resumes();
self.md_cachedAsync();
self.md_readsMutable();
self = mkProp(1, k_Song, "rating", "Gets the users rating. -1 if not rated.", [], k_Number_);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(13, k_Song, "track", "Gets the track number in the album", [], k_Number_);
self.md_resumes();
self.md_cachedAsync();
self = mkProp(87, k_Song, "play", "Plays the song.", [], k_Nothing);
self.md_cap("musicandsounds");
self = mkProp(0, k_Song, "protected", "Gets a value whether the song is DRM protected", [], k_Boolean_);
self.md_stub("");
self = mkProp(66, k_Song, "post to wall", "Displays the song on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(7, k_Sound, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Sound, "pan", "Gets the panning, ranging from -1.0 (full left) to 1.0 (full right).", [], k_Number_);
self.md_readsMutable();
self = mkProp(3, k_Sound, "set pan", "Sets the panning, ranging from -1.0 (full left) to 1.0 (full right).", [mkArg("pan", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sound, "pitch", "Gets the pitch adjustment, ranging from -1 (down one octave) to 1 (up one octave).", [], k_Number_);
self.md_readsMutable();
self = mkProp(3, k_Sound, "set pitch", "Sets the pitch adjustment, ranging from -1 (down one octave) to 1 (up one octave).", [mkArg("pitch", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sound, "volume", "Gets the volume from 0 (silent) to 1 (full volume)", [], k_Number_);
self.md_readsMutable();
self = mkProp(12, k_Sound, "set volume", "Sets the volume from 0 (silent) to 1 (full volume).", [mkArg("v", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(20, k_Sound, "duration", "Gets the duration in seconds.", [], k_Number_);
self.md_resumes();
self.md_cachedAsync();
self.md_readsMutable();
self = mkProp(0, k_Sound, "pause", "Not supported anymore", [], k_Nothing);
self.md_obsolete();
self.md_writesMutable();
self = mkProp(191, k_Sound, "play", "Plays the sound effect", [], k_Nothing);
self.md_resumes();
self.md_cap("musicandsounds");
self.md_quickAsync();
self.md_readsMutable();
self.md_import("cordova", "cordova-plugin-media");
self = mkProp(16, k_Sound, "play special", "Plays the song with different volume (0 to 1), pitch (-1 to 1) and pan (-1 to 1).", [mkArg("volume", k_Number_), mkArg("pitch", k_Number_), mkArg("pan", k_Number_)], k_Nothing);
self.md_resumes();
self.md_cap("musicandsounds");
self.md_quickAsync();
self.md_arg("volume").md_defl(1);
self.md_import("cordova", "cordova-plugin-media");
self = mkProp(26, k_Sound, "post to wall", "Displays a player on the wall", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Sound, "resume", "Not supported anymore", [], k_Nothing);
self.md_obsolete();
self.md_writesMutable();
self = mkProp(0, k_Sound, "state", "Not supported anymore", [], k_String_);
self.md_obsolete();
self.md_readsMutable();
self = mkProp(9, k_Sound, "stop", "Not supported anymore", [], k_Nothing);
self.md_obsolete();
self.md_writesMutable();
self = mkProp(0, k_Spring, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Spring, "set stiffness", "Sets the spring stiffness.", [mkArg("stiffness", k_Number_)], k_Nothing);
self = mkProp(0, k_Spring, "delete", "Deletes the spring", [], k_Nothing);
self = mkProp(63, k_Sprite, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Sprite, "friction", "Gets the fraction of speed loss between 0 and 1", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set shadow", "Sets the shadow information", [mkArg("blur", k_Number_), mkArg("color", k_Color), mkArg("x offset", k_Number_), mkArg("y offset", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("blur").md_defl(20);
self.md_arg("x offset").md_defl(5);
self.md_arg("y offset").md_defl(5);
self.md_arg("color").md_deflExpr('colors->gray');
self = mkProp(334, k_Sprite, "set friction", "Sets the friction to a fraction of speed loss between 0 and 1", [mkArg("friction", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "scale", "Gets the scaling applied when rendering the sprite. This scaling does not influence the bounding box.", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set scale", "Sets the scaling applied to the sprite on rendering. This scaling does not influence the bounding box.", [mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("value").md_defl(1);
self = mkProp(20, k_Sprite, "angular speed", "Gets the rotation speed in degrees/sec", [], k_Number_);
self.md_readsMutable();
self = mkProp(144, k_Sprite, "set angular speed", "Sets the rotation speed in degrees/sec", [mkArg("speed", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(405, k_Sprite, "height", "Gets the height in pixels", [], k_Number_);
self = mkProp(0, k_Sprite, "location", "Gets the geo location assigned to the sprite", [], k_Location_);
self.md_readsMutable();
self = mkProp(1, k_Sprite, "set location", "Sets the geo location of the sprite", [mkArg("location", k_Location_)], k_Nothing);
self.md_cap("motion");
self.md_flow("SourceGeoLocation");
self.md_writesMutable();
self = mkProp(70, k_Sprite, "angle", "Gets the angle of the sprite in degrees", [], k_Number_);
self.md_readsMutable();
self = mkProp(546, k_Sprite, "set angle", "Sets the angle of the sprite in degrees", [mkArg("angle", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(4, k_Sprite, "elasticity", "Gets the sprite elasticity as a fraction of speed preservation per bounce (0-1)", [], k_Number_);
self.md_readsMutable();
self = mkProp(41, k_Sprite, "set elasticity", "Sets the sprite elasticity as a fraction of speed preservation per bounce (0-1)", [mkArg("elasticity", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(138, k_Sprite, "speed x", "Gets the speed along x in pixels/sec", [], k_Number_);
self.md_readsMutable();
self = mkProp(166, k_Sprite, "set speed x", "Sets the x speed in pixels/sec", [mkArg("vx", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(120, k_Sprite, "speed y", "Gets the speed along y in pixels/sec", [], k_Number_);
self.md_readsMutable();
self = mkProp(143, k_Sprite, "set speed y", "Sets the y speed in pixels/sec", [mkArg("vy", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(394, k_Sprite, "width", "Gets the width in pixels", [], k_Number_);
self = mkProp(159, k_Sprite, "set height", "Sets the height in pixels", [mkArg("height", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(213, k_Sprite, "set width", "Sets the width in pixels", [mkArg("width", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "top", "Gets the top position in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set top", "Sets the top position in pixels", [mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "bottom", "Gets the bottom position in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set bottom", "Sets the bottom position in pixels", [mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "right", "Gets the right position in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set right", "Sets the right position in pixels", [mkArg("x", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "left", "Gets the left position in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set left", "Sets the left position in pixels", [mkArg("x", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(823, k_Sprite, "x", "Gets the center horizontal position of in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(468, k_Sprite, "set x", "Sets the center horizontal position in pixels", [mkArg("x", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(953, k_Sprite, "y", "Gets the y position in pixels", [], k_Number_);
self.md_readsMutable();
self = mkProp(529, k_Sprite, "set y", "Sets the y position in pixels", [mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(267, k_Sprite, "color", "Returns the sprite color.", [], k_Color);
self.md_readsMutable();
self = mkProp(2639, k_Sprite, "set color", "Sets the sprite color.", [mkArg("color", k_Color)], k_Nothing);
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(66, k_Sprite, "opacity", "Gets the opacity (between 0 transparent and 1 opaque)", [], k_Number_);
self = mkProp(273, k_Sprite, "set opacity", "Sets the sprite opacity (between 0 transparent and 1 opaque).", [mkArg("opacity", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "gradient", "Gets the property that enables or disables gradients", [], k_Boolean_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set gradient", "Sets gradient on or off", [mkArg("value", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "sheet", "Gets the associated sprite sheet", [], k_SpriteSheet);
self = mkProp(0, k_Sprite, "set font size", "Sets the font size in pixels of the sprite (for text sprites)", [mkArg("size", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("size").md_defl(20);
self = mkProp(0, k_Sprite, "font size", "Gets the font size in pixels (for text sprites)", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set text baseline", "Sets the current text baseline used when drawing text (for text sprites)", [mkArg("pos", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("pos").md_deflStrings("top", "alphabetic", "hanging", "middle", "ideographic", "bottom");
self.md_writesMutable();
self = mkProp(0, k_Sprite, "text baseline", "Gets the current text baseline (for text sprites)", [], k_String_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "fit text", "Fits the bounding box to the size of the text", [], k_Nothing);
self.md_writesMutable();
self = mkProp(116, k_Sprite, "text", "The text on a text sprite (if it is a text sprite)", [], k_String_);
self.md_readsMutable();
self = mkProp(1263, k_Sprite, "set text", "Updates text on a text sprite (if it is a text sprite)", [mkArg("text", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "background", "Gets the background color", [], k_Color);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "set background", "Sets the background color", [mkArg("c", k_Color)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "bubble", "Gets the bubble sprite if any", [], k_Sprite);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "set bubble", "Sets the bubble sprite", [mkArg("sprite", k_Sprite)], k_Nothing);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "say", "Displays a text bubble attached to the sprite and returns the bubble sprite.", [mkArg("text", k_String_)], k_Sprite);
self.md_ignoreReturnValue();
self = mkProp(7, k_Sprite, "mass", "Gets the mass", [], k_Number_);
self.md_readsMutable();
self = mkProp(6, k_Sprite, "set mass", "Sets the sprite mass.", [mkArg("mass", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "acceleration x", "Gets the acceleration along x in pixels/sec^2", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_Sprite, "acceleration y", "Gets the acceleration along y in pixels/sec^2", [], k_Number_);
self.md_readsMutable();
self = mkProp(3, k_Sprite, "set acceleration x", "Sets the x acceleration in pixels/sec^2", [mkArg("x", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(1, k_Sprite, "set acceleration y", "Sets the y acceleration in pixels/sec^2", [mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(3, k_Sprite, "set acceleration", "Sets the acceleration in pixels/sec^2", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "on tap", "Set the handler invoked when the sprite is tapped", [mkArg("tapped", k_PositionAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Sprite, "on swipe", "Set the handler invoked when the sprite is swiped", [mkArg("swiped", k_VectorAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Sprite, "on drag", "Set the handler invoked when the sprite is dragged", [mkArg("dragged", k_VectorAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Sprite, "on touch down", "Set the handler invoked when the sprite is touched initially", [mkArg("touch down", k_PositionAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Sprite, "on touch up", "Set the handler invoked when the sprite touch is released", [mkArg("touch up", k_PositionAction)], k_EventBinding);
self.md_ignoreReturnValue();
self = mkProp(0, k_Sprite, "on every frame", "Add an action that fires for every display frame", [mkArg("body", k_Action)], k_EventBinding);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(908, k_Sprite, "hide", "Hide sprite.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(117, k_Sprite, "is visible", "Returns true if sprite is not hidden", [], k_Boolean_);
self.md_readsMutable();
self = mkProp(245, k_Sprite, "move", "Moves sprite.", [mkArg("delta x", k_Number_), mkArg("delta y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(23, k_Sprite, "move towards", "Moves sprite towards other sprite.", [mkArg("other", k_Sprite), mkArg("fraction", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("other").md_readsMutable();
self.md_arg("fraction").md_defl(1);
self = mkProp(195, k_Sprite, "overlaps with", "Do the sprites overlap", [mkArg("other", k_Sprite)], k_Boolean_);
self.md_readsMutable();
self.md_arg("other").md_readsMutable();
self = mkProp(108, k_Sprite, "overlap with", "Returns the subset of sprites in the given set that overlap with sprite.", [mkArg("sprites", k_SpriteSet)], k_SpriteSet);
self.md_readsMutable();
self.md_arg("sprites").md_readsMutable();
self = mkProp(23, k_Sprite, "equals", "Are these the same sprite", [mkArg("other", k_Sprite)], k_Boolean_);
self.md_readsMutable();
self.md_arg("other").md_readsMutable();
self = mkProp(111, k_Sprite, "set picture", "Updates picture on a picture sprite (if it is a picture sprite)", [mkArg("pic", k_Picture)], k_Nothing);
self.md_resumes();
self.md_writesMutable();
self.md_picAsync();
self = mkProp(12, k_Sprite, "picture", "The picture on a picture sprite (if it is a picture sprite)", [], k_Picture);
self.md_readsMutable();
self = mkProp(3599, k_Sprite, "set pos", "Sets the position in pixels", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(258, k_Sprite, "set speed", "Sets the speed in pixels/sec", [mkArg("vx", k_Number_), mkArg("vy", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(473, k_Sprite, "show", "Show sprite.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(52, k_Sprite, "speed towards", "Sets sprite speed direction towards other sprite with given magnitude.", [mkArg("other", k_Sprite), mkArg("magnitude", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("other").md_readsMutable();
self = mkProp(19, k_Sprite, "set clip", "Sets the clipping area for an image sprite (if it is an image sprite)", [mkArg("left", k_Number_), mkArg("top", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("width").md_defl(48);
self.md_arg("height").md_defl(48);
self = mkProp(0, k_Sprite, "move clip", "Use `Sprite Sheet` instead.", [mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_obsolete();
self.md_arg("x").md_defl(48);
self = mkProp(331, k_Sprite, "delete", "Delete sprite.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "is deleted", "True if sprite is deleted.", [], k_Boolean_);
self.md_readsMutable();
self = mkProp(23, k_Sprite, "z index", "Gets the z-index of the sprite", [], k_Number_);
self.md_readsMutable();
self = mkProp(45, k_Sprite, "set z index", "Sets the z-index of the sprite", [mkArg("zindex", k_Number_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Sprite, "create animation", "Starts a new tween animation.", [], k_SpriteAnimation);
self = mkProp(0, k_SpriteAnimation, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_SpriteAnimation, "time scale", "Gets the current time scale factor", [], k_Number_);
self.md_readsMutable();
self = mkProp(0, k_SpriteAnimation, "set time scale", "Sets the current time scale factor", [mkArg("scale", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("scale").md_defl(1);
self = mkProp(0, k_SpriteAnimation, "move to", "Moves the sprite to a given location using separate easing for x and y", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("x", k_Number_), mkArg("y", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(1);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "text", "Changes the text of the sprite.", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("value", k_String_)], k_Nothing);
self.md_arg("duration").md_defl(1);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "color", "Changes the color of the sprite", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("c", k_Color)], k_Nothing);
self.md_arg("duration").md_defl(1);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "beat", "Creating a beating animation", [mkArg("duration", k_Number_), mkArg("cycle", k_Number_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.3);
self.md_arg("cycle").md_defl(2);
self.md_arg("value").md_defl(1.1);
self = mkProp(0, k_SpriteAnimation, "scale", "Scales the sprite", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("value").md_defl(1.2);
self.md_arg("easing").md_deflStrings('sine', 'linear', 'quadratic', 'cubic', 'expo');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "width", "Modifies the sprite width", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("value").md_defl(100);
self.md_arg("easing").md_deflStrings('sine', 'linear', 'quadratic', 'cubic', 'expo');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "height", "Modifies the sprite height", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("value", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("value").md_defl(100);
self.md_arg("easing").md_deflStrings('sine', 'linear', 'quadratic', 'cubic', 'expo');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "fork", "Starts a new animation and continues with the current animation", [], k_SpriteAnimation);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "wait", "Waits till the animation completes. This action will evolve the board if needed.", [], k_Nothing);
self.md_resumes();
self.md_async();
self = mkProp(0, k_SpriteAnimation, "wait for", "Waits for the other animation to complete before proceding.", [mkArg("animation", k_SpriteAnimation)], k_Nothing);
self = mkProp(0, k_SpriteAnimation, "stop", "Stops this animation", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "repeat", "Repeats the latest animation. Negative ``count`` makes infinite repetition. ``yoyo`` makes the animation repeat back and forth.", [mkArg("count", k_Number_), mkArg("yoyo", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self.md_arg("count").md_defl(2);
self = mkProp(0, k_SpriteAnimation, "on start", "Raised when the animation started playing", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "on stop", "Raised when the animation stopped playing", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "sleep", "Waits for a number of seconds", [mkArg("duration", k_Number_)], k_Nothing);
self.md_arg("duration").md_defl(1);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "fade in", "Fades in to fully opaque", [mkArg("duration", k_Number_), mkArg("easing", k_String_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self = mkProp(0, k_SpriteAnimation, "fade out", "Fades out to transparent", [mkArg("duration", k_Number_), mkArg("easing", k_String_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self = mkProp(0, k_SpriteAnimation, "fade", "Changes the opacity of the sprite", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("opacity", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self.md_arg("shape").md_deflStrings('inout', 'out', 'in');
self = mkProp(0, k_SpriteAnimation, "puff out", "Scales up and fades out an object", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("scale", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(0.5);
self.md_arg("scale").md_defl(1.5);
self.md_arg("easing").md_deflStrings('cubic', 'linear', 'quadratic', 'expo', 'sine');
self = mkProp(0, k_SpriteAnimation, "hide", "Hides the sprite", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "show", "shows the sprite", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "delete", "deletes the sprite", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "play sound", "play sound", [mkArg("sound", k_Sound)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteAnimation, "frame", "Sets a different frame from the sprite sheet", [mkArg("name", k_String_)], k_Nothing);
self = mkProp(0, k_SpriteAnimation, "play frames", "Starts playing an animation from the sprite sheet, if any", [mkArg("animation", k_String_)], k_Nothing);
self.md_writesMutable();
self.md_arg("animation").md_defl('all');
self = mkProp(0, k_SpriteAnimation, "turn to", "Rotates the sprite.", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("angle", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(1);
self.md_arg("easing").md_deflStrings('expo', 'linear', 'quadratic', 'cubic', 'sine');
self.md_arg("shape").md_deflStrings('in', 'out', 'inout');
self = mkProp(0, k_SpriteAnimation, "run", "Calls a user handler during the animation. ``handler`` receives a number from 0 to 1 during the tweeining.", [mkArg("duration", k_Number_), mkArg("easing", k_String_), mkArg("shape", k_String_), mkArg("handler", k_NumberAction)], k_Nothing);
self.md_writesMutable();
self.md_arg("duration").md_defl(1);
self.md_arg("easing").md_deflStrings('expo', 'linear', 'quadratic', 'cubic', 'sine');
self.md_arg("shape").md_deflStrings('in', 'out', 'inout');
self = mkProp(0, k_SpriteAnimation, "is active", "Gets a value indicating if the animation is still running", [], k_Boolean_);
self = mkProp(0, k_SpriteAnimation, "post to wall", "Describes the animation.", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(38, k_SpriteSet, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_SpriteSet, "clear", "Removes all sprites from the set.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(305, k_SpriteSet, "count", "Returns the number of sprites in the set", [], k_Number_);
self.md_readsMutable();
self = mkProp(1246, k_SpriteSet, "add", "Add sprite to set. Returns true if sprite was not already in set.", [mkArg("sprite", k_Sprite)], k_Boolean_);
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_embedsLink("Sprite Set", "Sprite");
self = mkProp(24, k_SpriteSet, "add from", "Add sprite to set and remove from old set. Returns true if sprite was in old set and not in new set.", [mkArg("old set", k_SpriteSet), mkArg("sprite", k_Sprite)], k_Boolean_);
self.md_writesMutable();
self.md_arg("old set").md_readsMutable();
self.md_arg("old set").md_writesMutable();
self.md_ignoreReturnValue();
self.md_embedsLink("Sprite Set", "Sprite");
self = mkProp(116, k_SpriteSet, "remove", "Remove sprite from set. Returns true if sprite was in set.", [mkArg("sprite", k_Sprite)], k_Boolean_);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(5, k_SpriteSet, "contains", "Returns true if sprite is in set.", [mkArg("sprite", k_Sprite)], k_Boolean_);
self.md_readsMutable();
self = mkProp(22, k_SpriteSet, "remove first", "Remove sprite that was added to set first.", [], k_Sprite);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(52, k_SpriteSet, "index of", "Returns index of sprite in this set or -1 if not in set.", [mkArg("sprite", k_Sprite)], k_Number_);
self.md_readsMutable();
self = mkProp(1667, k_SpriteSet, "at", "Return sprite at given index.", [mkArg("index", k_Number_)], k_Sprite);
self.md_readsMutable();
self = mkProp(0, k_SpriteSheet, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_SpriteSheet, "picture", "Gets the picture associated to this sprite sheet.", [], k_Picture);
self.md_readsMutable();
self = mkProp(0, k_SpriteSheet, "set frame", "Sets the current frame displayed by sprite", [mkArg("sprite", k_Sprite), mkArg("frame", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteSheet, "create sprite", "Creates a new sprite displaying the given frame.", [mkArg("frame", k_String_)], k_Sprite);
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_embedsLink("SpriteSheet", "Sprite");
self.md_embedsLink("Sprite", "Picture");
self = mkProp(0, k_SpriteSheet, "set frame grid", "Sets the frames as a rectangular grid. The tiles are numbered from top, left to bottom right starting at 0.", [mkArg("rows", k_Number_), mkArg("columns", k_Number_), mkArg("frame width", k_Number_), mkArg("frame height", k_Number_), mkArg("margin left", k_Number_), mkArg("margin top", k_Number_), mkArg("spacing", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("rows").md_defl(1);
self.md_arg("columns").md_defl(1);
self = mkProp(0, k_SpriteSheet, "add frame", "Defines a new frame in the sprite sheet", [mkArg("name", k_String_), mkArg("x", k_Number_), mkArg("y", k_Number_), mkArg("width", k_Number_), mkArg("height", k_Number_), mkArg("rotated", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_SpriteSheet, "add grid animation", "Defines an animation as a continuous sequence of frames. The frame index starts at `1`.", [mkArg("name", k_String_), mkArg("start", k_Number_), mkArg("count", k_Number_), mkArg("duration", k_Number_), mkArg("loops", k_Number_), mkArg("yoyo", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self.md_arg("loops").md_defl(1);
self.md_arg("start").md_defl(1);
self.md_arg("name").md_defl("all");
self = mkProp(0, k_SpriteSheet, "add animation", "Defines an animation as a custom sequence of frames.", [mkArg("name", k_String_), mkArg("frames", k_Collection.createInstance([k_String_])), mkArg("duration", k_Number_), mkArg("loops", k_Number_), mkArg("yoyo", k_Boolean_)], k_Nothing);
self.md_writesMutable();
self.md_arg("loops").md_defl(1);
self = mkProp(0, k_SpriteSheet, "post to wall", "Displays the sprite sheet.", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self.md_embedsLink("Wall", "Picture");
self = mkProp(182, k_String_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(409, k_String_, "split", "Returns a string collection that contains the substrings in this string that are delimited by elements of a specified string.", [mkArg("separator", k_String_)], k_Collection.createInstance([k_String_]));
self.md_arg("separator").md_defl(",");
self.md_arg("result").md_writesMutable();
self.md_robust();
self = mkProp(0, k_String_, "trim overflow", "Trims the string at the given length and adds ``...`` if necessary", [mkArg("lim", k_Number_)], k_String_);
self.md_arg("lim").md_defl(140);
self = mkProp(1438, k_String_, "post to wall", "Displays string on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(534, k_String_, "count", "Returns the number of characters", [], k_Number_);
self.md_robust();
self = mkProp(0, k_String_, "code at", "Gets the charecter unicode value at a given index. Returns NaN if out of bounds", [mkArg("index", k_Number_)], k_Number_);
self = mkProp(68, k_String_, "at", "Gets the character at a specified index. Returns invalid if out of bounds.", [mkArg("index", k_Number_)], k_String_);
self = mkProp(71, k_String_, "to lower case", "Returns a copy of this string converted to lowercase, using the casing rules of the current culture.", [], k_String_);
self.md_robust();
self = mkProp(79, k_String_, "to upper case", "Returns a copy of this string converted to uppercase, using the casing rules of the current culture.", [], k_String_);
self.md_robust();
self = mkProp(12, k_String_, "to unicode", "Use ``to_character_code`` instead", [], k_Number_);
self.md_hidden();
self = mkProp(0, k_String_, "to character code", "Converts the first character into the character code number (unicode)", [], k_Number_);
self = mkProp(2, k_String_, "compare", "Compares two pieces of text", [mkArg("other", k_String_)], k_Number_);
self.md_robust();
self = mkProp(406, k_String_, "concat", "Concatenates two pieces of text", [mkArg("other", k_String_)], k_String_);
self.md_robust();
self = mkProp(4627, k_String_, "∥", "Concatenates two pieces of text", [mkArg("other", k_String_)], k_String_);
self.md_infixPriority(6);
self.md_robust();
self.md_jsName("concat_op");
self = mkProp(281, k_String_, "contains", "Returns a value indicating if the second string is contained", [mkArg("value", k_String_)], k_Boolean_);
self.md_robust();
self.md_robust();
self = mkProp(3087, k_String_, "equals", "Checks if two strings are the same", [mkArg("other", k_String_)], k_Boolean_);
self.md_robust();
self = mkProp(45, k_String_, "ends with", "Determines whether the ending matches the specified string", [mkArg("value", k_String_)], k_Boolean_);
self.md_robust();
self = mkProp(155, k_String_, "index of", "Returns the index of the first occurence if found starting at a given position", [mkArg("value", k_String_), mkArg("start", k_Number_)], k_Number_);
self.md_robust();
self = mkProp(8, k_String_, "insert", "Inserts a string at a given position", [mkArg("start", k_Number_), mkArg("value", k_String_)], k_String_);
self = mkProp(265, k_String_, "is empty", "Indicates if the string is empty", [], k_Boolean_);
self.md_robust();
self = mkProp(23, k_String_, "is match regex", "Indicates if the string matches a regular expression", [mkArg("pattern", k_String_)], k_Boolean_);
self = mkProp(1, k_String_, "last index of", "Returns the index of the last occurence if found starting at a given position", [mkArg("value", k_String_), mkArg("start", k_Number_)], k_Number_);
self.md_robust();
self = mkProp(0, k_String_, "match", "Gets the groups from the matching the regex expression (pattern). Returns an empty collection if no matches.", [mkArg("pattern", k_String_)], k_Collection.createInstance([k_String_]));
self = mkProp(19, k_String_, "matches", "Gets the strings matching the regex expression (pattern)", [mkArg("pattern", k_String_)], k_Collection.createInstance([k_String_]));
self = mkProp(19, k_String_, "remove", "Returns the string with characters removed starting at a given index", [mkArg("start", k_Number_)], k_String_);
self.md_robust();
self = mkProp(208, k_String_, "replace", "Returns a given string with a replacement", [mkArg("old", k_String_), mkArg("new", k_String_)], k_String_);
self.md_robust();
self = mkProp(42, k_String_, "replace regex", "Replace every match of the regex according to the replacement string", [mkArg("pattern", k_String_), mkArg("replace", k_String_)], k_String_);
self = mkProp(0, k_String_, "replace regex with converter", "Run `replacer` on every match of the regex", [mkArg("pattern", k_String_), mkArg("replace", k_StringConverter.createInstance([k_Collection.createInstance([k_String_])]))], k_String_);
self.md_needsFrame();
self = mkProp(181, k_String_, "starts with", "Determines whether the beginning matches the specified string", [mkArg("value", k_String_)], k_Boolean_);
self = mkProp(419, k_String_, "substring", "Returns a substring given a start index and a length", [mkArg("start", k_Number_), mkArg("length", k_Number_)], k_String_);
self = mkProp(12, k_String_, "trim", "Removes all leading and trailing occurrences of a set of characters specified in a string from the current string.", [mkArg("chars", k_String_)], k_String_);
self.md_arg("chars").md_defl(" \t");
self.md_robust();
self = mkProp(32, k_String_, "trim start", "Removes all leading occurrences of a set of characters specified in a string from the current string.", [mkArg("chars", k_String_)], k_String_);
self.md_arg("chars").md_defl(" \t");
self.md_robust();
self = mkProp(6, k_String_, "trim end", "Removes all trailing occurrences of a set of characters specified in a string from the current string.", [mkArg("chars", k_String_)], k_String_);
self.md_arg("chars").md_defl(" \t");
self.md_robust();
self = mkProp(0, k_String_, "to time", "Parses the string as a time (12:30:12) and returns the number of seconds.", [], k_Number_);
self = mkProp(248, k_String_, "to number", "Parses the string as a number", [], k_Number_);
self = mkProp(2, k_String_, "to boolean", "Parses the string as a boolean", [], k_Boolean_);
self = mkProp(4, k_String_, "to location", "Parses the string as a geo coordinate.", [], k_Location_);
self = mkProp(9, k_String_, "share", "Shares the string (email, sms, facebook, social or '' to pick from a list)", [mkArg("network", k_String_)], k_Nothing);
self.md_resumes();
self.md_uiAsync();
self.md_flow("SinkSharing");
self.md_arg("network").md_defl("social");
self = mkProp(28, k_String_, "copy to clipboard", "Stores text in the clipboard", [], k_Nothing);
self.md_resumes();
self.md_flow("SinkClipboard");
self.md_uiAsync();
self = mkProp(2, k_String_, "to datetime", "Parses the string as a date and time.", [], k_DateTime);
self = mkProp(2, k_String_, "to color", "Parses the string as a color.", [], k_Color);
self = mkProp(0, k_String_, "to json", "Converts the value into a json data structure.", [], k_JsonObject);
self = mkProp(8, k_StringMap, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(70, k_StringMap, "count", "Gets the number of elements in the map", [], k_Number_);
self.md_readsMutable();
self = mkProp(48, k_StringMap, "keys", "Gets the keys in the map", [], k_Collection.createInstance([k_String_]));
self.md_readsMutable();
self = mkProp(241, k_StringMap, "at", "Gets the value at a given key; invalid if not found", [mkArg("key", k_String_)], k_String_);
self.md_readsMutable();
self = mkProp(472, k_StringMap, "set at", "Sets the value at a given key; invalid if not found", [mkArg("key", k_String_), mkArg("value", k_String_)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_StringMap, "to json", "Exports a JSON representation of the contents.", [], k_JsonObject);
self.md_readsMutable();
self = mkProp(0, k_StringMap, "from json", "Imports a JSON representation of the contents.", [mkArg("jobj", k_JsonObject)], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_StringMap, "clear", "Clears the values from the map", [], k_Nothing);
self = mkProp(5, k_StringMap, "set many", "Sets many elements at once.", [mkArg("strings", k_StringMap)], k_Nothing);
self.md_writesMutable();
self.md_arg("strings").md_readsMutable();
self = mkProp(6, k_StringMap, "remove", "Removes the value at a given key", [mkArg("key", k_String_)], k_Nothing);
self = mkProp(6, k_StringMap, "post to wall", "Displays the list of key,value pairs in a table", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(6, k_TextBox, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(138, k_TextBox, "text", "Gets the text", [], k_String_);
self.md_readsMutable();
self = mkProp(58, k_TextBox, "set text", "Sets the text", [mkArg("text", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self = mkProp(6, k_TextBox, "icon", "Gets the icon picture (max 173x173)", [], k_Picture);
self.md_readsMutable();
self = mkProp(29, k_TextBox, "set icon", "Sets the icon picture (max 96 x 96)", [mkArg("pic", k_Picture)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_embedsLink("TextBox", "Picture");
self = mkProp(0, k_TextBox, "font size", "Gets the font size", [], k_Number_);
self.md_readsMutable();
self = mkProp(4, k_TextBox, "set font size", "Sets the font size (small = 14, normal = 15, medium = 17, medium large = 19, large = 24, extra large = 32, extra extra large = 54, huge = 140", [mkArg("size", k_Number_)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("size").md_defl(19);
self = mkProp(1, k_TextBox, "background", "Gets the background color", [], k_Color);
self.md_readsMutable();
self = mkProp(163, k_TextBox, "set background", "Sets the background color", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->background');
self = mkProp(2, k_TextBox, "foreground", "Gets the foreground color", [], k_Color);
self.md_readsMutable();
self = mkProp(101, k_TextBox, "set foreground", "Sets the foreground color", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->foreground');
self = mkProp(0, k_TextBox, "border", "Gets the border color", [], k_Color);
self.md_readsMutable();
self = mkProp(20, k_TextBox, "set border", "Sets the border color", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("color").md_deflExpr('colors->foreground');
self = mkProp(501, k_TextBox, "post to wall", "Posts the textbox to the wall", [], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self = mkProp(0, k_Time, "on every frame", "Attaches a handler to run on every time frame, roughly every 20ms.", [mkArg("body", k_Action)], k_EventBinding);
self.md_needsFrame();
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(0, k_Time, "run after", "Starts a timer to run ``perform`` after ``seconds`` seconds.", [mkArg("seconds", k_Number_), mkArg("body", k_Action)], k_Timer);
self.md_needsFrame();
self.md_writesMutable();
self.md_ignoreReturnValue();
self.md_arg("seconds").md_defl(1);
self = mkProp(0, k_Time, "run every", "Starts a timer to run ``perform`` every ``seconds`` seconds.", [mkArg("seconds", k_Number_), mkArg("body", k_Action)], k_Timer);
self.md_needsFrame();
self.md_writesMutable();
self.md_arg("seconds").md_defl(1);
self.md_ignoreReturnValue();
self = mkProp(561, k_Time, "sleep", "Waits for a specified amount of seconds", [mkArg("seconds", k_Number_)], k_Nothing);
self.md_resumes();
self.md_arg("seconds").md_defl(1);
self.md_async();
self = mkProp(1392, k_Time, "now", "Gets the current time", [], k_DateTime);
self.md_needsFrame();
self.md_tandre();
self = mkProp(58, k_Time, "today", "Gets today's date without time", [], k_DateTime);
self.md_tandre();
self = mkProp(92, k_Time, "tomorrow", "Gets tomorrow's date without time", [], k_DateTime);
self.md_tandre();
self = mkProp(17, k_Time, "fail if not", "Use `app->fail_if_not` instead.", [mkArg("condition", k_Boolean_)], k_Nothing);
self.md_arg("condition").md_defl(true);
self.md_obsolete();
self = mkProp(108, k_Time, "stop", "Use `app->stop` instead.", [], k_Nothing);
self.md_resumes();
self.md_hidden();
self = mkProp(126, k_Time, "log", "Use `app->log` instead.", [mkArg("message", k_String_)], k_Nothing);
self.md_hidden();
self = mkProp(81, k_Time, "stop and close", "Use `app->stop` instead.", [], k_Nothing);
self.md_resumes();
self.md_hidden();
self = mkProp(93, k_Time, "create", "Creates a new date instance", [mkArg("year", k_Number_), mkArg("month", k_Number_), mkArg("day", k_Number_), mkArg("hour", k_Number_), mkArg("minute", k_Number_), mkArg("second", k_Number_)], k_DateTime);
self.md_arg("year").md_defl(2000);
self.md_arg("month").md_defl(1);
self.md_arg("day").md_defl(1);
self.md_arg("hour").md_defl(12);
self = mkProp(0, k_Timer, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_Timer, "clear", "Clears the handlers and pauses the timer", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Timer, "on trigger", "sets the action to perform when the timer fires", [mkArg("body", k_Action)], k_EventBinding);
self.md_writesMutable();
self.md_ignoreReturnValue();
self = mkProp(0, k_Timer, "is active", "is the timer active", [], k_Boolean_);
self = mkProp(0, k_Timer, "is interval", "is this an interval timer that fires regularly", [], k_Boolean_);
self = mkProp(0, k_Timer, "set interval", "set the regular interval in seconds at which this timer fires", [mkArg("seconds", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("seconds").md_defl(1);
self = mkProp(0, k_Timer, "set timeout", "set the time in seconds after which this timer fires once", [mkArg("seconds", k_Number_)], k_Nothing);
self.md_writesMutable();
self.md_arg("seconds").md_defl(1);
self = mkProp(0, k_Timer, "pause", "deactivates the timer", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Timer, "resume", "reactives the timer", [], k_Nothing);
self.md_writesMutable();
self = mkProp(0, k_Tutorial, "step completed", "Signal that the step is done.", [], k_Nothing);
self.md_needsFrame();
self.md_docsOnly();
self = mkProp(0, k_Tutorial, "show hint", "Show a suggestion to the user (eg., an error description)", [mkArg("message", k_String_)], k_Nothing);
self.md_resumes();
self.md_docsOnly();
self.md_dbgOnly();
self.md_uiAsync();
self = mkProp(0, k_User, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_User, "equals", "Gets a value idincating if the user is the same as the other.", [mkArg("other", k_User)], k_Boolean_);
self = mkProp(0, k_User, "id", "Gets a unique identifier for the user.", [], k_String_);
self = mkProp(0, k_User, "preload", "Download user-data if needed", [], k_Nothing);
self.md_resumes();
self.md_async();
self.md_cap("network");
self = mkProp(0, k_User, "name", "Gets the name of the user", [], k_String_);
self.md_resumes();
self.md_cachedAsync();
self.md_cap("network");
self = mkProp(0, k_User, "about", "Gets the about-me text of the user", [], k_String_);
self.md_resumes();
self.md_cachedAsync();
self.md_cap("network");
self = mkProp(0, k_User, "has picture", "Indicates if the user has a picture", [], k_Boolean_);
self.md_resumes();
self.md_cachedAsync();
self.md_cap("network");
self = mkProp(0, k_User, "settings", "Gets the user settings if accessible. Currently, only the current user. Supported fields are editormode, twitterhandle, githubuser, minecraftuser", [], k_JsonObject);
self.md_resumes();
self.md_cachedAsync();
self.md_cap("editorOnly", "network");
self = mkProp(0, k_User, "picture address", "Gets the url of the user picture where original is the unmodified user picture, square is 50x50, small has 50px width, normal has 100px width, large has roughly 200px width", [mkArg("which", k_String_)], k_String_);
self.md_resumes();
self.md_arg("which").md_deflStrings("original", "square", "small", "normal", "large");
self.md_cachedAsync();
self.md_cap("network");
self = mkProp(0, k_User, "picture", "Gets the user picture where original is the unmodified user picture, square is 50x50, small has 50px width, normal has 100px width, large has roughly 200px width", [mkArg("which", k_String_)], k_Picture);
self.md_resumes();
self.md_arg("which").md_deflStrings("original", "square", "small", "normal", "large");
self.md_cachedAsync();
self.md_cap("network");
self = mkProp(0, k_User, "post to wall", "Displays the link on the wall", [], k_Nothing);
self.md_needsFrame();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(7, k_Vector3, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(463, k_Vector3, "x", "Gets the x-component", [], k_Number_);
self = mkProp(426, k_Vector3, "y", "Gets the y-component", [], k_Number_);
self = mkProp(36, k_Vector3, "z", "Gets the z-component", [], k_Number_);
self = mkProp(11, k_Vector3, "length", "Gets the length of the vector", [], k_Number_);
self = mkProp(8, k_Vector3, "distance", "Gets the distance between the two vectors", [mkArg("other", k_Vector3)], k_Number_);
self = mkProp(1, k_Vector3, "negate", "Returns a vector pointing in the opposite direction", [], k_Vector3);
self = mkProp(0, k_Vector3, "normalize", "Returns a vector of one unit pointing in the same direction as the original vector", [], k_Vector3);
self = mkProp(9, k_Vector3, "add", "Adds a vector", [mkArg("other", k_Vector3)], k_Vector3);
self = mkProp(5, k_Vector3, "subtract", "Subtracts another vector", [mkArg("other", k_Vector3)], k_Vector3);
self = mkProp(0, k_Vector3, "multiply", "Multiplies component-wise with a vector", [mkArg("other", k_Vector3)], k_Vector3);
self = mkProp(72, k_Vector3, "scale", "Multiplies with a scaling factor", [mkArg("scalar", k_Number_)], k_Vector3);
self = mkProp(3, k_Vector3, "clamp", "Restricts the vector in the specified range", [mkArg("min", k_Vector3), mkArg("max", k_Vector3)], k_Vector3);
self = mkProp(0, k_Vector3, "cross", "Calculates the cross product with the other vector", [mkArg("other", k_Vector3)], k_Vector3);
self = mkProp(5, k_Vector3, "linear interpolation", "Linear interpolation between two vectors", [mkArg("other", k_Vector3), mkArg("amount", k_Number_)], k_Vector3);
self = mkProp(4, k_Vector3, "to string", "Turns the vector into a string", [], k_String_);
self = mkProp(1, k_Vector3, "post to wall", "Displays the vector on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(1481, k_Wall, "clear", "Clears the background, buttons and entries", [], k_Nothing);
self.md_needsFrame();
self = mkProp(13, k_Wall, "display search", "This action is not supported anymore.", [mkArg("on", k_Boolean_)], k_Nothing);
self.md_arg("on").md_defl(true);
self.md_obsolete();
self = mkProp(471, k_Wall, "prompt", "Prompts the user with a ok button", [mkArg("text", k_String_)], k_Nothing);
self.md_resumes();
self.md_tandre2();
self.md_uiAsync();
self = mkProp(306, k_Wall, "ask boolean", "Prompts the user with ok and cancel buttons", [mkArg("text", k_String_), mkArg("caption", k_String_)], k_Boolean_);
self.md_resumes();
self.md_tandre2();
self.md_uiAsync();
self = mkProp(231, k_Wall, "ask number", "Prompts the user to input a number", [mkArg("text", k_String_)], k_Number_);
self.md_resumes();
self.md_tandre2();
self.md_uiAsync();
self = mkProp(304, k_Wall, "ask string", "Prompts the user to input a string", [mkArg("text", k_String_)], k_String_);
self.md_resumes();
self.md_tandre2();
self.md_uiAsync();
self = mkProp(24, k_Wall, "screenshot", "Takes a screenshot of the wall.", [], k_Picture);
self.md_resumes();
self.md_flow("SourcePicture");
self.md_readsMutable();
self.md_arg("result").md_writesMutable();
self.md_quickAsync();
self = mkProp(425, k_Wall, "create text box", "Creates an updatable text box", [mkArg("text", k_String_), mkArg("font size", k_Number_)], k_TextBox);
self.md_arg("result").md_writesMutable();
self.md_arg("font size").md_defl(19);
self.md_embedsLink("Wall", "TextBox");
self = mkProp(144, k_Wall, "pick string", "Prompts the user to pick a string from a list. Returns the selected index.", [mkArg("text", k_String_), mkArg("caption", k_String_), mkArg("values", k_Collection.createInstance([k_String_]))], k_Number_);
self.md_resumes();
self.md_tandre2();
self.md_uiAsync();
self = mkProp(2, k_Wall, "pick time", "Prompts the user to pick a time. Returns a datetime whose time is set, the date is undefined.", [mkArg("text", k_String_), mkArg("caption", k_String_)], k_DateTime);
self.md_resumes();
self.md_tandre2();
self.md_arg("caption").md_defl("pick a time");
self.md_uiAsync();
self = mkProp(21, k_Wall, "pick date", "Prompts the user to pick a date. Returns a datetime whose date is set, the time is 12:00:00.", [mkArg("text", k_String_), mkArg("caption", k_String_)], k_DateTime);
self.md_resumes();
self.md_tandre2();
self.md_arg("caption").md_defl("pick a date");
self.md_uiAsync();
self = mkProp(49, k_Wall, "set foreground", "Sets the wall foreground color of elements.", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_arg("color").md_readsMutable();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(0, k_Wall, "clear background", "Clears the background color, picture and camera", [], k_Nothing);
self.md_needsFrame();
self = mkProp(172, k_Wall, "set background", "Sets the wall background color.", [mkArg("color", k_Color)], k_Nothing);
self.md_needsFrame();
self.md_arg("color").md_readsMutable();
self.md_arg("color").md_deflExpr('colors->random');
self = mkProp(0, k_Wall, "set page transition style", "Sets the animation for push/pop of pages.", [mkArg("style", k_String_)], k_Nothing);
self.md_needsFrame();
self.md_arg("style").md_deflStrings('slide', 'fade', 'none');
self.md_dbgOnly();
self = mkProp(64, k_Wall, "set background picture", "Sets the wall background picture. The picture will be resized and clipped to the screen background as needed.", [mkArg("picture", k_Picture)], k_Nothing);
self.md_resumes();
self.md_arg("picture").md_readsMutable();
self.md_picAsync();
self = mkProp(0, k_Wall, "set background camera", "Sets the wall background camera.", [mkArg("camera", k_Camera)], k_Nothing);
self.md_resumes();
self.md_cap("camera");
self.md_async();
self.md_arg("camera").md_readsMutable();
self.md_arg("camera").md_deflExpr('senses->camera');
self = mkProp(8, k_Wall, "set transform matrix", "Sets the 3x3 affine matrix transformation applied to the wall.", [mkArg("m11", k_Number_), mkArg("m12", k_Number_), mkArg("m21", k_Number_), mkArg("m22", k_Number_), mkArg("offsetx", k_Number_), mkArg("offsety", k_Number_)], k_Nothing);
self.md_stub();
self.md_cap("phone");
self.md_arg("m11").md_defl(1);
self.md_arg("m12").md_defl(0);
self.md_arg("m21").md_defl(0);
self.md_arg("m22").md_defl(1);
self.md_arg("offsetx").md_defl(0);
self.md_arg("offsety").md_defl(0);
self = mkProp(118, k_Wall, "set reversed", "Reverses the elements on the wall and inserts new ones at the bottom.", [mkArg("bottom", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self.md_arg("bottom").md_readsMutable();
self.md_arg("bottom").md_defl(true);
self = mkProp(0, k_Wall, "show title bar", "Indicates if the title and subtitle bar should be visible on a page.", [mkArg("visible", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_Wall, "show back button", "Indicates if the back button should be visible on the current page. The back button gets visible automatically when the app is paused or stopped in the editor.", [mkArg("visible", k_Boolean_)], k_Nothing);
self.md_needsFrame();
self = mkProp(225, k_Wall, "set title", "Sets the title of the wall.", [mkArg("text", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(136, k_Wall, "set subtitle", "Sets the subtitle of the wall.", [mkArg("text", k_String_)], k_Nothing);
self.md_needsFrame();
self = mkProp(2, k_Wall, "icon names", "Use button icon names instead.", [], k_Collection.createInstance([k_String_]));
self.md_obsolete();
self = mkProp(76, k_Wall, "clear buttons", "Clears the application bar buttons and hides the bar", [], k_Nothing);
self.md_needsFrame();
self = mkProp(367, k_Wall, "add button", "Add a new button. icon must be the name of a built-in icon, text must be non-empty.", [mkArg("icon", k_String_), mkArg("text", k_String_)], k_PageButton);
self.md_needsFrame();
self.md_arg("result").md_writesMutable();
self.md_arg("icon").md_defl("add");
self.md_arg("icon").md_deflStrings("back", "cancel", "check", "close", "delete", "download", "edit", "favs.addto", "favs", "feature.camera", "feature.email", "feature.search", "feature.settings", "feature.video", "folder", "minus", "new", "next", "questionmark", "refresh", "save", "share", "stop", "sync", "transport.ff", "transport.pause", "transport.play", "transport.rew", "upload");
self.md_embedsLink("Wall", "Page Button");
self.md_ignoreReturnValue();
self = mkProp(70, k_Wall, "current page", "Gets the current page displayed on the wall", [], k_Page);
self.md_needsFrame();
self = mkProp(204, k_Wall, "push new page", "Pushes an empty page on the wall.", [], k_Page);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(160, k_Wall, "pop page", "Pops the current page and restores the previous wall page. Returns false if already on the default page.", [], k_Boolean_);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(0, k_Wall, "pop page with transition", "Same as `wall->pop_page`, but lets you use specific animation.", [mkArg("style", k_String_)], k_Boolean_);
self.md_needsFrame();
self.md_ignoreReturnValue();
self.md_arg("style").md_deflStrings('slide down', 'slide up', 'slide right', 'fade', 'none');
self = mkProp(21, k_Wall, "pages", "Returns the current back stack of pages, starting from the current page to the bottom page.", [], k_Collection.createInstance([k_Page]));
self.md_needsFrame();
self = mkProp(4, k_Wall, "button icon names", "Gets the list of available page button names.", [], k_Collection.createInstance([k_String_]));
self = mkProp(0, k_Wall, "width", "Gets the width of the screen (in pixels).", [], k_Number_);
self.md_needsFrame();
self = mkProp(0, k_Wall, "height", "Gets the height of the screen (in pixels).", [], k_Number_);
self.md_needsFrame();
self = mkProp(0, k_WebEventSource, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebEventSource, "on message", "Sets an event to run when a message is received. Change name to receive custom events.", [mkArg("name", k_String_), mkArg("handler", k_TextAction)], k_EventBinding);
self.md_arg("name").md_defl('message');
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_WebEventSource, "state", "Gets the current connection state (`connecting`, `open`, `closed`)", [], k_String_);
self = mkProp(0, k_WebEventSource, "on open", "Sets an event to run when the event source is opened", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_WebEventSource, "on error", "Sets an event to run when an error occurs", [mkArg("body", k_Action)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_writesMutable();
self = mkProp(0, k_WebEventSource, "close", "Closes the EventSource. No further event will be raised.", [], k_Nothing);
self.md_writesMutable();
self = mkProp(3, k_Web, "search", "Searching the web using Bing", [mkArg("query", k_String_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "search nearby", "Searching the web near a location using Bing. Distance in meters, negative to ignore.", [mkArg("query", k_String_), mkArg("location", k_Location_), mkArg("distance", k_Number_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self.md_arg("location").md_deflExpr('senses->current_location');
self.md_arg("distance").md_defl(1000);
self = mkProp(9, k_Web, "search images", "Searching images using Bing", [mkArg("query", k_String_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "search images nearby", "Searching images near a location using Bing. Distance in meters, negative to ignore.", [mkArg("query", k_String_), mkArg("location", k_Location_), mkArg("distance", k_Number_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self.md_arg("location").md_deflExpr('senses->current_location');
self.md_arg("distance").md_defl(1000);
self = mkProp(0, k_Web, "search phone numbers", "Search phone numbers using Bing", [mkArg("query", k_String_)], k_Collection.createInstance([k_Link]));
self.md_obsolete();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "search phone numbers nearby", "Search phone numbers near a location using Bing. Distance in meters, negative to ignore.", [mkArg("query", k_String_), mkArg("location", k_Location_), mkArg("distance", k_Number_)], k_Collection.createInstance([k_Link]));
self.md_obsolete();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self.md_arg("location").md_deflExpr('senses->current_location');
self.md_arg("distance").md_defl(1000);
self = mkProp(0, k_Web, "search news", "Searching news using Bing", [mkArg("query", k_String_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "search news nearby", "Searching news near a location using Bing. Distance in meters, negative to ignore.", [mkArg("query", k_String_), mkArg("location", k_Location_), mkArg("distance", k_Number_)], k_Collection.createInstance([k_Link]));
self.md_resumes();
self.md_async();
self.md_cap("search");
self.md_flow("SinkSafe");
self.md_arg("result").md_writesMutable();
self.md_arg("location").md_deflExpr('senses->current_location');
self.md_arg("distance").md_defl(1000);
self = mkProp(43, k_Web, "is connected", "Indicates whether any network connection is available", [], k_Boolean_);
self = mkProp(35, k_Web, "connection type", "Gets the type of the network servicing Internet requests (unknown, none, ethernet, wifi, mobile)", [], k_String_);
self.md_resumes();
self.md_quickAsync();
self.md_import("cordova", "cordova-plugin-network-information");
self = mkProp(29, k_Web, "connection name", "Gets a name of the currently connected network servicing Internet requests. Empty string if no connection.", [], k_String_);
self.md_resumes();
self.md_quickAsync();
self = mkProp(66, k_Web, "open connection settings", "Opens a connection settings page (airplanemode, bluetooth, wifi, cellular)", [mkArg("page", k_String_)], k_Nothing);
self.md_resumes();
self.md_cap("phone");
self.md_uiAsync();
self.md_arg("page").md_defl("airplanemode");
self.md_arg("page").md_deflStrings("airplanemode", "bluetooth", "wifi", "cellular");
self = mkProp(29, k_Web, "browse", "Opens a web browser to a url", [mkArg("url", k_String_)], k_Nothing);
self.md_resumes();
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_uiAsync();
self = mkProp(0, k_Web, "redirect", "Redirects the browser to a url; only available when exporting", [mkArg("url", k_String_)], k_Nothing);
self.md_resumes();
self.md_betaOnly();
self.md_uiAsync();
self = mkProp(12, k_Web, "play media", "Plays an internet audio/video in full screen", [mkArg("url", k_String_)], k_Nothing);
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(3, k_Web, "link media", "Creates a link to an internet audio/video", [mkArg("url", k_String_)], k_Link);
self.md_arg("result").md_writesMutable();
self = mkProp(11, k_Web, "link image", "Creates a link to an internet image", [mkArg("url", k_String_)], k_Link);
self.md_arg("result").md_writesMutable();
self = mkProp(49, k_Web, "link url", "Creates a link to an internet page", [mkArg("name", k_String_), mkArg("url", k_String_)], k_Link);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "link deep zoom", "Creates a multi-scale image from an image url", [mkArg("url", k_String_)], k_Link);
self.md_obsolete();
self.md_arg("result").md_writesMutable();
self = mkProp(68, k_Web, "download", "Downloads the content of an internet page (http get)", [mkArg("url", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(23, k_Web, "download json", "Downloads a web service response as a JSON data structure (http get)", [mkArg("url", k_String_)], k_JsonObject);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(0, k_Web, "download xml", "Downloads a web service response as a XML data structure (http get)", [mkArg("url", k_String_)], k_XmlObject);
self.md_resumes();
self.md_cap("network");
self.md_async();
self.md_flow("SinkWeb");
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(4, k_Web, "download sound", "Downloads a WAV sound file from internet", [mkArg("url", k_String_)], k_Sound);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(4, k_Web, "download song", "Create a streamed song file from internet (download happens when playing)", [mkArg("url", k_String_), mkArg("name", k_String_)], k_Song);
self.md_cap("media", "network");
self.md_flow("SinkWeb");
self.md_arg("name").md_defl("a song");
self = mkProp(2, k_Web, "upload", "Uploads text to an internet page (http post)", [mkArg("url", k_String_), mkArg("body", k_String_)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(0, k_Web, "upload sound", "Uploads a sound to an internet page (http post). The sound must have been recorded from the microphone.", [mkArg("url", k_String_), mkArg("snd", k_Sound)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(3, k_Web, "upload picture", "Uploads a picture to an internet page (http post)", [mkArg("url", k_String_), mkArg("pic", k_Picture)], k_String_);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(53, k_Web, "download picture", "Downloads a picture from internet", [mkArg("url", k_String_)], k_Picture);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_arg("result").md_writesMutable();
self = mkProp(1, k_Web, "html decode", "Decodes a string that has been HTML-encoded", [mkArg("html", k_String_)], k_String_);
self = mkProp(0, k_Web, "html encode", "Converts a text string into an HTML-encoded string", [mkArg("text", k_String_)], k_String_);
self = mkProp(0, k_Web, "decode uri", "Decodes a URI component", [mkArg("url", k_String_)], k_String_);
self = mkProp(0, k_Web, "encode uri", "Encodes a uri component", [mkArg("text", k_String_)], k_String_);
self = mkProp(0, k_Web, "decode uri component", "Decodes a URI component", [mkArg("url", k_String_)], k_String_);
self = mkProp(0, k_Web, "encode uri component", "Encodes a uri component", [mkArg("text", k_String_)], k_String_);
self = mkProp(2, k_Web, "url decode", "Use `web->decode uri component` instead.", [mkArg("url", k_String_)], k_String_);
self.md_obsolete();
self = mkProp(23, k_Web, "url encode", "Use `web->encode uri component` instead.", [mkArg("text", k_String_)], k_String_);
self.md_obsolete();
self = mkProp(49, k_Web, "json", "Parses the string as a json object", [mkArg("value", k_String_)], k_JsonObject);
self.md_arg("value").md_lang("json");
self.md_arg("value").md_defl("{}");
self = mkProp(0, k_Web, "json object", "Returns an empty json object", [], k_JsonObject);
self = mkProp(0, k_Web, "json array", "Returns an empty json array", [], k_JsonObject);
self = mkProp(26, k_Web, "xml", "Parses the string as a xml element", [mkArg("value", k_String_)], k_XmlObject);
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(4, k_Web, "rss", "Obsolete. Use 'feed' instead.", [mkArg("value", k_String_)], k_Collection.createInstance([k_Message]));
self.md_obsolete();
self.md_arg("result").md_writesMutable();
self = mkProp(27, k_Web, "create request", "Creates a web request", [mkArg("url", k_String_)], k_WebRequest);
self = mkProp(0, k_Web, "open web socket", "Creates a web socket", [mkArg("url", k_String_)], k_WebSocket_);
self.md_resumes();
self.md_async();
self = mkProp(0, k_Web, "base64 decode", "Decodes a string that has been base64-encoded (assuming utf8 encoding)", [mkArg("text", k_String_)], k_String_);
self = mkProp(1, k_Web, "base64 encode", "Converts a string into an base64-encoded string (with utf8 encoding)", [mkArg("text", k_String_)], k_String_);
self = mkProp(13, k_Web, "feed", "Parses the newsfeed string (RSS 2.0 or Atom 1.0) into a message collection", [mkArg("value", k_String_)], k_Collection.createInstance([k_Message]));
self.md_arg("result").md_writesMutable();
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(0, k_Web, "create json builder", "Creates a json builder", [], k_JsonBuilder);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "csv", "Parses a Command Separated Values document into a JsonObject where the `headers` is a string array of column names; `records` is an array of rows where each row is itself an array of strings. The delimiter is inferred if not specified.", [mkArg("text", k_String_), mkArg("delimiter", k_String_)], k_JsonObject);
self.md_arg("delimiter").md_defl("\t");
self = mkProp(0, k_Web, "picture", "Creates a picture from a web address. The resulting picture cannot be modified, use clone if you want to change it.", [mkArg("url", k_String_)], k_Picture);
self = mkProp(0, k_Web, "oauth v2", "Authenticate with OAuth 2.0 and receives the access token or error. See [](/oauthv2) for more information on which Redirect URI to choose.", [mkArg("oauth url", k_String_)], k_OAuthResponse);
self.md_resumes();
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_uiAsync();
self = mkProp(0, k_Web, "create form builder", "Create a form builder", [], k_FormBuilder);
self.md_arg("result").md_writesMutable();
self = mkProp(0, k_Web, "post message to parent", "Posts a message to the parent window if any. The `target origin` must match the domain of the parent window, * is not accepted.", [mkArg("target origin", k_String_), mkArg("message", k_JsonObject)], k_Nothing);
self.md_needsFrame();
self.md_readsMutable();
self.md_arg("target origin").md_defl('https://www.touchdevelop.com');
self = mkProp(0, k_Web, "wait for message from parent", "Waits for the next message from the parent window in `origin`.", [mkArg("origin", k_String_)], k_JsonObject);
self.md_resumes();
self.md_async();
self = mkProp(0, k_Web, "on received message from parent", "Attaches code to run when a message is received. Only messages from the parent window and `origin` will be received.", [mkArg("origin", k_String_), mkArg("received", k_JsonAction)], k_EventBinding);
self.md_needsFrame();
self.md_ignoreReturnValue();
self = mkProp(0, k_Web, "create event source", "Opens an Server-Sent-Events client on the given URL. If not supported, returns invalid. The server must implement CORS to allow https://www.touchdevelop.com to receive messages.", [mkArg("url", k_String_)], k_WebEventSource);
self.md_needsFrame();
self = mkProp(0, k_Web, "oauth token from url", "Parses a OAuth v2.0 access token from a redirect uri as described in http://tools.ietf.org/html/rfc6749. Returns invalid if the url does not contain an OAuth token.", [mkArg("redirect url", k_String_)], k_OAuthResponse);
self = mkProp(0, k_Web, "oauth token from json", "Parses a OAuth v2.0 access token from a JSON payload as described in http://tools.ietf.org/html/rfc6749. Returns invalid if the payload is not an OAuth token.", [mkArg("response", k_JsonObject)], k_OAuthResponse);
self = mkProp(0, k_WebRequest, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebRequest, "show notifications", "Indicates if program notifications should be shown to the user. Default is true.", [mkArg("visible", k_Boolean_)], k_Nothing);
self = mkProp(0, k_WebRequest, "method", "Gets whether it was a 'get' or a 'post'.", [], k_String_);
self = mkProp(13, k_WebRequest, "set method", "Sets the method. Default value is 'get'.", [mkArg("method", k_String_)], k_Nothing);
self.md_arg("method").md_deflStrings("post", "put", "get", "delete");
self = mkProp(0, k_WebRequest, "url", "Gets the url of the request", [], k_String_);
self = mkProp(0, k_WebRequest, "set url", "Sets the url of the request. Must be a valid internet address.", [mkArg("url", k_String_)], k_Nothing);
self = mkProp(0, k_WebRequest, "header", "Gets the value of a given header", [mkArg("name", k_String_)], k_String_);
self.md_readsMutable();
self = mkProp(10, k_WebRequest, "set header", "Sets an HTML header value. Empty string clears the value", [mkArg("name", k_String_), mkArg("value", k_String_)], k_Nothing);
self = mkProp(0, k_WebRequest, "equals", "Indicates if both requests are the same instance.", [mkArg("other", k_WebRequest)], k_Boolean_);
self = mkProp(0, k_WebRequest, "set accept", "Sets the Accept header type ('text/xml' for xml, 'application/json' for json).", [mkArg("type", k_String_)], k_Nothing);
self.md_arg("type").md_deflStrings('application/json', 'text/xml');
self = mkProp(0, k_WebRequest, "post to wall", "Displays the request to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_WebRequest, "send async", "User ``send`` instead", [], k_Nothing);
self.md_needsFrame();
self.md_cap("network");
self.md_flow("SinkWeb");
self.md_hidden();
self = mkProp(0, k_WebRequest, "on response received", "Use ``send`` instead", [mkArg("handler", k_WebResponseAction)], k_EventBinding);
self.md_ignoreReturnValue();
self.md_hidden();
self = mkProp(29, k_WebRequest, "send", "Performs the request synchronously", [], k_WebResponse);
self.md_resumes();
self.md_async();
self.md_cap("network");
self.md_flow("SinkWeb");
self = mkProp(4, k_WebRequest, "set content", "Sets the content of a 'post' request", [mkArg("content", k_String_)], k_Nothing);
self = mkProp(4, k_WebRequest, "set content as json", "Sets the content of a 'post' request as the JSON tree", [mkArg("json", k_JsonObject)], k_Nothing);
self = mkProp(0, k_WebRequest, "set content as buffer", "Sets the content of a 'post' request as a binary buffer", [mkArg("bytes", k_Buffer)], k_Nothing);
self = mkProp(0, k_WebRequest, "set content as form", "Sets the content as multipart/form-data.", [mkArg("form", k_FormBuilder)], k_Nothing);
self = mkProp(0, k_WebRequest, "set content as picture", "Sets the content of a 'post' request as a JPEG encoded image. Quality from 0 (worse) to 1 (best).", [mkArg("pic", k_Picture), mkArg("quality", k_Number_)], k_Nothing);
self.md_resumes();
self.md_arg("quality").md_defl(0.85);
self.md_picAsync();
self = mkProp(0, k_WebRequest, "set content as xml", "Sets the content of a 'post' request as the XML tree", [mkArg("xml", k_XmlObject)], k_Nothing);
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(0, k_WebRequest, "set credentials", "Sets the name and password for basic authentication. Requires an HTTPS URL, empty string clears.", [mkArg("name", k_String_), mkArg("password", k_String_)], k_Nothing);
self = mkProp(0, k_WebRequest, "header names", "Gets the names of the headers", [], k_Collection.createInstance([k_String_]));
self.md_readsMutable();
self = mkProp(0, k_WebRequest, "set compress", "Compresses the request content with gzip and sets the Content-Encoding header", [mkArg("value", k_Boolean_)], k_Nothing);
self.md_arg("value").md_defl(true);
self.md_obsolete();
self = mkProp(0, k_WebResponse, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebResponse, "request", "Gets the request associated to this response", [], k_WebRequest);
self = mkProp(12, k_WebResponse, "status code", "Gets the HTTP Status code of the request if any", [], k_Number_);
self = mkProp(11, k_WebResponse, "content", "Reads the response body as a string", [], k_String_);
self = mkProp(0, k_WebResponse, "content as buffer", "Reads the response body as a Buffer.", [], k_Buffer);
self = mkProp(13, k_WebResponse, "content as json", "Reads the response body as a JSON tree", [], k_JsonObject);
self = mkProp(1, k_WebResponse, "content as picture", "Reads the response body as a picture", [], k_Picture);
self.md_resumes();
self.md_async();
self = mkProp(0, k_WebResponse, "content as sound", "Reads the response body as a wave sound", [], k_Sound);
self.md_stub();
self = mkProp(1, k_WebResponse, "content as xml", "Reads the response body as a XML tree", [], k_XmlObject);
self.md_import("npm", "xmldom", "0.1.*");
self = mkProp(2, k_WebResponse, "header", "Gets the value of a given header", [mkArg("name", k_String_)], k_String_);
self = mkProp(0, k_WebResponse, "header names", "Gets the names of the headers", [], k_Collection.createInstance([k_String_]));
self = mkProp(0, k_WebResponse, "post to wall", "Displays the response to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_WebSocketMessage, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebSocketMessage, "is error", "Indicates if this message is an error", [], k_Boolean_);
self = mkProp(0, k_WebSocketMessage, "error", "Gets the error if any.", [], k_String_);
self = mkProp(0, k_WebSocketMessage, "string", "Gets the message as a string", [], k_String_);
self = mkProp(0, k_WebSocketMessage, "json", "Gets the message as a Json payload", [], k_JsonObject);
self = mkProp(0, k_WebSocketMessage, "buffer", "Gets the message as a Buffer", [], k_Buffer);
self = mkProp(0, k_WebSocketMessage, "post to wall", "Displays the message on the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(0, k_WebSocket_, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(0, k_WebSocket_, "close", "Closes the socket", [], k_Nothing);
self = mkProp(0, k_WebSocket_, "ready state", "Gets the ready state of the web socket, \"connection\", \"closed\", \"closing\", \"open\"", [], k_String_);
self = mkProp(0, k_WebSocket_, "buffered amount", "The number of bytes of data that have been queued using calls to send() but not yet transmitted to the network. This value does not reset to zero when the connection is closed; if you keep calling send(), this will continue to climb.", [], k_Number_);
self = mkProp(0, k_WebSocket_, "receive", "Receives a message", [], k_WebSocketMessage);
self.md_resumes();
self.md_async();
self = mkProp(0, k_WebSocket_, "send", "Transmits string data to the server", [mkArg("msg", k_String_)], k_Nothing);
self = mkProp(0, k_WebSocket_, "send json", "Transmits JSON data to the server", [mkArg("json", k_JsonObject)], k_Nothing);
self = mkProp(0, k_WebSocket_, "send buffer", "Sends buffer data to the server", [mkArg("buf", k_Buffer)], k_Nothing);
self = mkProp(0, k_WebSocket_, "post to wall", "Displays the request to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(6, k_XmlObject, "is invalid", "Returns true if the current instance is useless", [], k_Boolean_);
self.md_runOnInvalid();
self.md_cap('none');
self = mkProp(3, k_XmlObject, "count", "Gets the number of child element", [], k_Number_);
self = mkProp(1, k_XmlObject, "is element", "Indicates if this instance is an element or a filtered collection", [], k_Boolean_);
self = mkProp(0, k_XmlObject, "name", "Gets the full name of this element", [], k_String_);
self = mkProp(38, k_XmlObject, "value", "Gets the concatenated text contents of this element", [], k_String_);
self = mkProp(15, k_XmlObject, "at", "Gets the i-th child element in the collection", [mkArg("index", k_Number_)], k_XmlObject);
self = mkProp(27, k_XmlObject, "attr", "Gets the value of the attribute", [mkArg("name", k_String_)], k_String_);
self = mkProp(0, k_XmlObject, "attr names", "Gets the list of attribute names", [], k_Collection.createInstance([k_String_]));
self = mkProp(65, k_XmlObject, "child", "Gets a first child element matching the fully qualified name", [mkArg("name", k_String_)], k_XmlObject);
self = mkProp(8, k_XmlObject, "children", "Gets a collection of child element matching the fully qualified name", [mkArg("name", k_String_)], k_XmlObject);
self = mkProp(1, k_XmlObject, "post to wall", "Display the xml content to the wall", [], k_Nothing);
self.md_needsFrame();
self = mkProp(12, k_XmlObject, "to string", "Gets an xml string", [], k_String_);
self = mkProp(0, k_XmlObject, "local name", "Gets the local name of this element", [], k_String_);
self = mkProp(0, k_XmlObject, "namespace", "Gets the namespace of this element", [], k_String_);
self = mkProp(0, k_XmlObject, "create name", "Creates a qualified full name from the namespace and local name", [mkArg("local name", k_String_), mkArg("namespace uri", k_String_)], k_String_);


// Help definitions
TDev.AST.Json.docs = "// The current version of this file can be retrieved by:\n// GET /api/language/webast\n\nmodule TDev.AST.Json\n{\n    // This module describes an AST for TouchDevelop scripts. The documentation\n    // is severely lacking, so the best way to figure things out is to write a\n    // TouchDevelop script, and type (in the console):\n    //\n    //   \"TDev.AST.Json.dump(TDev.Script)\"\n    //\n    // which will dump the currently-edited script in this representation. The\n    // converse operation is:\n    //\n    //   \"TDev.AST.Json.serialize(yourJsonAst)\"\n    //\n    // Beware: the composition of these two operations is *not* the\n    // identity. In particular, [dump] will resolve implicit optional arguments,\n    // while [serialize] expects them to be left out.\n\n    // These two interfaces are never used. Actually, whenever a field has type\n    // [JNodeRef], this is a lie, and its type is [string].\n    export interface JNodeRef { dummyNodeRef: number; }\n    export interface JTypeRef { dummyTypeRef: number; }\n\n    // the JTypeRef may be either a simple string, or if it starts with '{',\n    // it is JSON-encoded and conforms to one of these interfaces or is just a string (API type)\n    export interface JGenericTypeInstance extends JTypeRef {\n        g: string;\n        a?: JTypeRef[];\n    }\n    export interface JUserType extends JTypeRef {\n        o: string;\n    }\n    export interface JLibraryType extends JUserType {\n        l: JNodeRef;\n    }\n\n\n    /*abstract*/ export interface JNode\n    {\n        nodeType:string; // name of interface without leading J and with lower-case first letter\n        id:string; // do not depend on the particular format of these strings\n    }\n\n    /*abstract*/ export interface JDecl extends JNode\n    {\n        name: string;\n        unused?: boolean;\n    }\n\n    /*abstract*/ export interface JToken extends JNode { }\n    /*abstract*/ export interface JExpr extends JToken { }\n\n    // This corresponds to the [operator] syntactic class defined in the\n    // OOPSLA'15 submission. When adopting the \"hybrid AST\" point of view,\n    // an expression is decomposed as a series of tokens. The [JOperator]\n    // interface covers operators (assignment, comparison, boolean and\n    // arithmetic operators), but also *digits*.\n    //\n    // For instance, \"1 + 10 = 11\" will generate:\n    //   [JOperator 1; JOperator +; JOperator 0; JOperator =; JOperator 1; JOperator 1]\n    export interface JOperator extends JToken { op:string; }\n\n    // A reference to a \"property\", i.e. something defined for an object of that\n    // type. There is no good way of figuring out what should the [parent] be\n    // when generating such properties; probably the best way is to dump a\n    // TouchDevelop AST.\n    export interface JPropertyRef extends JToken\n    {\n        name:string;\n        parent: JTypeRef; // if used as token this is ignored when building\n                          // if used as JCall it's needed for operators\n        declId?: JNodeRef; // filled when the property is user-defined\n    }\n\n    export interface JStringLiteral extends JExpr {\n        value:string;\n        enumValue?:string;\n    }\n    export interface JBooleanLiteral extends JExpr { value:boolean; }\n\n    // A number literal is only used when adopting the \"tree\" view for\n    // expressions (see comment on [JExprHolder]).\n    export interface JNumberLiteral extends JExpr {\n        value:number;\n        // If parsing 'stringForm' yields 'value', 'stringForm' is used\n        // Otherwise stringified form of 'value' is used\n        stringForm?:string;\n    }\n\n    // when building expressions of these three types you can provide localId/type or name;\n    // if you provide both, name is ignored\n    export interface JLocalRef extends JExpr\n    {\n        name:string;\n        localId:JNodeRef;\n    }\n\n    export interface JPlaceholder extends JExpr\n    {\n        name:string;\n        type:JTypeRef;\n    }\n\n    // A singleton (probably) references one of the top-level categories such as\n    // libraries or data. When trying to call \"♻ l →  foo(x1, x2)\", one may\n    // understand that the following call takes place:\n    //   ♻ -> l -> foo(x1, x2)\n    // and the following AST is generated:\n    //   JCall { name: foo, parent: l, args: [\n    //     JCall { name: l, parent: ♻, args: [ JSingletonRef ♻ ] },\n    //     x1,\n    //     x2\n    //  ]}\n    // this is surprising, because when calling \"1 + 2\", we generate a call that\n    // has two arguments only.\n    export interface JSingletonRef extends JExpr\n    {\n        name:string;\n        // type is ignored when building\n        type:JTypeRef;\n        libraryName?:string; // if this is a reference to a namespace in a library, this gives the name of library\n    }\n\n    // It seems like TouchDevelop has an extra invariant that a [JCall] must\n    // *always* be wrapped in a [JExprHolder].\n    export interface JCall extends JPropertyRef, JExpr\n    {\n        args:JExpr[];\n        // If we are calling a *type* T on an expression (e.g. create ->\n        // Collection of -> T), then T will be in there.\n        typeArgs?: JTypeRef[];\n        // The field below, if present, determines without ambiguity the nature\n        // of the call.\n        // - extension (the new special syntax)\n        // - field (reading a record field)\n        // Other types of calls can be determined by careful inspection of the\n        // receiver. See the C++ code emitter.\n        callType?: string;\n    }\n\n    // Expressions can be represented in two different manners.\n    // - The first one is as a series of tokens. This would correspond to the\n    //   \"hybrid AST\" described in the OOPSLA'15 submission. In that\n    //   representation, the [tree] field is null and the [tokens] field\n    //   contains the list of tokens.\n    // - The second one is as an actual AST, with a proper tree structure. In\n    //   that case, the [tokens] field is null and [tree] must contain a proper\n    //   tree.\n    //\n    // TouchDevelop conflates variable binding and expressions. This means that\n    // every expression is flagged with the variables that are introduced at\n    // this stage. For instance, \"var x = 1\" will be translated as a\n    // [JExprHolder] where [locals] contains a [JLocalDef x], and either:\n    // - [tokens] is [JLocalRef x; JOperator :=; JOperator 1], or\n    // - [tree] is [JCall { name: \":=\", parent: \"Unknown\", args: [JLocalRef x, JNumberLiteral 1] }]\n    //\n    // This is not the traditional notion of binding! The variable's scope is\n    // not limited to the tokens, but rather extends until the end of the parent\n    // block.\n    export interface JExprHolder extends JNode\n    {\n        // if tokens is unset, will try to use tree\n        tokens:JToken[];\n        tree:JExpr;\n        locals:JLocalDef[]; // locals variables defined in this expression\n    }\n\n    /*abstract*/ export interface JStmt extends JNode\n    {\n        // this is available when using the short form\n        locals?: JLocalDef[];\n    }\n\n    export interface JComment extends JStmt { text: string; }\n    export interface JFor extends JStmt\n    {\n        index:JLocalDef;\n        bound:JExprHolder;\n        body:JStmt[];\n    }\n    export interface JForeach extends JStmt\n    {\n        iterator:JLocalDef;\n        collection:JExprHolder;\n        conditions:JCondition[];\n        body:JStmt[];\n    }\n    /*abstract*/ export interface JCondition extends JNode {\n        // this is available when using the short form\n        locals?: JLocalDef[];\n    }\n    export interface JWhere extends JCondition { condition: JExprHolder; }\n    export interface JWhile extends JStmt\n    {\n        condition:JExprHolder;\n        body:JStmt[];\n    }\n\n    export interface JContinue extends JStmt {}\n    export interface JBreak extends JStmt {}\n    export interface JReturn extends JExprStmt {}\n    export interface JShow extends JExprStmt {}\n\n    // Sequences of if / else if / else statements are not represented the usual\n    // way. That is, instead of having a structured AST:\n    //\n    // if\n    // |- condition1\n    // |- then-branch1 = ...\n    // |- else-branch = if\n    //                  |- condition2\n    //                  |- then-branch2\n    //                  |- else-branch2\n    //\n    // the TouchDevelop AST adopts the following (unusual) representation.\n    //\n    // if\n    // |- condition1\n    // |- then-branch1 = ...\n    // |- else-branch = null\n    // if\n    // |- condition2\n    // |- then-branch2\n    // |- else-branch2\n    // |- isElseIf = true\n    //\n    // This is NOT equivalent to the representation above (condition2 may\n    // subsume condition1), so the extra flag \"isElseIf\" is set and (I suppose)\n    // gets some special treatment when it comes to running / compiling the\n    // program.\n    export interface JIf extends JStmt\n    {\n        condition:JExprHolder;\n        thenBody:JStmt[];\n        elseBody:JStmt[];\n        isElseIf:boolean;\n    }\n\n    export interface JBoxed extends JStmt { body:JStmt[]; }\n    export interface JExprStmt extends JStmt { expr:JExprHolder; }\n    export interface JInlineActions extends JExprStmt { actions:JInlineAction[]; }\n    export interface JInlineAction extends JNode\n    {\n        reference:JLocalDef;\n        inParameters:JLocalDef[];\n        outParameters:JLocalDef[];\n        body:JStmt[];\n        locals?:JLocalDef[]; // this contains the reference in short mode; it never contains anything else\n        isImplicit:boolean;\n        isOptional:boolean;\n        allLocals: JLocalDef[];\n        capturedLocals: JLocalDef[];\n    }\n\n    export interface JOptionalParameter extends JNode\n    {\n        name:string;\n        declId:JNodeRef;\n        expr:JExprHolder;\n    }\n\n    /*abstract*/ export interface JActionBase extends JDecl\n    {\n        inParameters:JLocalDef[];\n        outParameters:JLocalDef[];\n        // note that events should be always treated as private, but for historical reasons this field can be true or false\n        isPrivate:boolean;\n        isOffline: boolean;\n        isQuery: boolean;\n        isTest: boolean;\n        isAsync:boolean;\n        description: string;\n    }\n\n    export interface JActionType extends JActionBase\n    {\n    }\n\n    export interface JAction extends JActionBase { body: JStmt[]; }\n    export interface JPage extends JActionBase\n    {\n        initBody:JStmt[];\n        displayBody:JStmt[];\n        initBodyId?:string;\n        displayBodyId?:string;\n        hasModelParameter?:boolean;\n    }\n    export interface JEvent extends JActionBase\n    {\n        // when building provide name or both eventName and eventVariableId (which take precedence over name)\n        eventName:string;\n        eventVariableId:JNodeRef;\n        body:JStmt[];\n    }\n\n    export interface JLibAction extends JActionBase\n    {\n        parentLibId:JNodeRef; // this can be empty - it means \"current script\"\n    }\n\n    export interface JLibAbstractType extends JDecl\n    {\n    }\n\n    export interface JLibActionType extends JActionBase\n    {\n    }\n\n\n    /*abstract*/ export interface JGlobalDef extends JDecl\n    {\n        comment:string;\n        type:JTypeRef;\n        isReadonly:boolean;\n        isTransient:boolean;\n        isCloudEnabled:boolean;\n    }\n\n    export interface JArt extends JGlobalDef {\n        url: string;\n        // If it's a string art, contains its value.\n        value: string;\n    }\n    export interface JData extends JGlobalDef { }\n\n    export interface JLibrary extends JDecl\n    {\n        libIdentifier: string;\n        libIsPublished: boolean;\n        scriptName: string; // name of the script to which the library resolves\n        exportedTypes: string; // space separated; obsolete, use exportedTypeDefs\n        exportedTypeDefs: JDecl[]; // JLibAbstractType or JLibActionType\n        exportedActions: JLibAction[];\n        resolveClauses: JResolveClause[];\n    }\n\n    /*abstract*/ export interface JBinding extends JNode\n    {\n        name:string; // name of the formal argument\n        isExplicit:boolean; // was it explicitly specified by the user\n        // implicit bindings are ignored when building expressions\n    }\n\n    export interface JTypeBinding extends JBinding { type:JTypeRef; }\n    export interface JActionBinding extends JBinding { actionId:JNodeRef; }\n\n    export interface JResolveClause extends JNode\n    {\n        name:string;\n        // points to a JLibrary (not publish-id);\n        // it may be null for binding to the current script\n        defaultLibId:JNodeRef;\n        withTypes: JTypeBinding[];\n        withActions: JActionBinding[];\n    }\n    export interface JRecord extends JDecl\n    {\n        comment: string;\n        category: string; // \"object\", \"table\", \"index\", or \"decorator\"\n        isCloudEnabled: boolean;\n        isCloudPartiallyEnabled: boolean;\n        isPersistent: boolean;\n        isExported: boolean;\n        keys: JRecordKey[];\n        fields: JRecordField[];\n    }\n\n    export interface JRecordField extends JNode\n    {\n        name:string;\n        type:JTypeRef;\n    }\n    export interface JRecordKey extends JRecordField {}\n\n    // local variable or a parameter\n    export interface JLocalDef extends JNode\n    {\n        name:string;\n        type:JTypeRef;\n        isByRef: boolean;\n    }\n\n    // Response to:\n    // GET /api/<script-id>/webast\n    export interface JApp extends JNode\n    {\n        // both versions are comma-separated list of tokens/features\n        textVersion: string;\n        jsonVersion: string;\n\n        name: string;\n        comment: string;\n        // The name and icon are only given here if they are explicitly specified by the user.\n        icon?: string; // name of the icon, e.g., \"Bolt\"\n        color?: string; // e.g., #ff00ff\n        // These two are always present. They are ignored when building new scripts.\n        autoIcon:string;\n        autoColor:string;\n\n        platform: string; // comma-separated\n        isLibrary: boolean;\n        useCppCompiler?: boolean;\n        showAd: boolean;\n        hasIds: boolean; // does it have stable, persistent ids for every stmt\n        rootId: string;\n        decls: JDecl[];\n        deletedDecls: JDecl[]; // these are present when a node was deleted but is still referenced from somewhere\n\n        libraryName?: string; // when used in reflection info\n        libraryId?: string; // when used in reflection info\n    }\n\n\n    //\n    // API description\n    //\n\n    export interface JPropertyParameter\n    {\n        name: string;\n        type: JTypeRef;\n        writesMutable?: boolean; // are fields of the object referenced by this paramter being written to\n        readsMutable?: boolean;  // .... read from\n        defaultValue?: JToken[];\n        stringValues?: string[]; // these show up in intelli buttons; they are usually all allowed values for a parameter\n    }\n\n    export interface JProperty\n    {\n        name: string;\n        help: string;\n        usage_count: number;       // this is used for syntax autocompletion priority\n        runOnInvalid?: boolean;       // should the property by run even if one of the arguments is 'invalid'\n        isHidden?: boolean;           // doesn't show in autocompletion\n        isAsync?: boolean;\n        isObsolete?: boolean;         // generates a warning\n        isDbgOnly?: boolean;          // an experimental feature; not visible in regular builds\n        isBetaOnly?: boolean;         // a feature in testing; visible in /app/beta\n        jsName: string;            // how is the property refered to from JavaScript\n        infixPriority?: number;    // when present, this is an infix operator with given priority\n                                   // higher number is higher priority; even assosiates left, odd - right\n        pausesInterpreter?: boolean;  // is this a potentially-async operation\n        usesStackFrame?: boolean;     // is the implementation passed IStackFrame object\n        missingWeb?: boolean;         // is the implementation missing from the general web version\n        capabilities?: string;     // comma-separated list of required platform capabilities (if any)\n        result: JPropertyParameter;\n        parameters: JPropertyParameter[];\n    }\n\n    export interface JTypeDef\n    {\n        name: string;\n        help: string;\n        icon: string;               // a name of the icon representing this type\n        isAction?: boolean;            // is it a function type; look for 'run' property for the signature\n        isData: boolean;               // false for singleton types\n        stemName: string;           // used when auto-naming variables of this type\n        jsName: string;            // how is the type refered to from JavaScript\n        isDbgOnly?: boolean;           // an experimental feature; not visible in regular builds\n        isBetaOnly?: boolean;          // a feature in testing; visible in /app/beta\n        isSerializable: boolean;       // do we support automatic serialization of this type\n        isBuiltin?: boolean;           // true for number, boolean, string; the JS calling convention is different for these\n        ctxLocal?: boolean;            // can it be used as local variable\n        ctxGlobal?: boolean;           // .... as global variable\n        ctxField?: boolean;            // .... as field of a record\n        ctxLocalKey?: boolean;         // .... as key in a local index\n        ctxGcKey?: boolean;            // can it have decorators\n        ctxCloudKey?: boolean;\n        ctxRowKey?: boolean;\n        ctxCloudField?: boolean;\n        ctxWallTap?: boolean;          // do global variables of this type get 'wall tap' events\n        ctxEnumerable?: boolean;       // can it be used with foreach construct\n        ctxJson?: boolean;             // can it be json exported/imported\n        properties: JProperty[];\n    }\n\n    // GET /api/language/apis\n    export interface JApis\n    {\n        textVersion:string;\n        jsonVersion: string;\n        types:JTypeDef[];\n    }\n\n/*\n\nThe short format\n~~~~~~~~~~~~~~~~\n\nThe main difference between the full JSON format and the short JSON format is\nrepresentation of `JExprHolder` nodes. Whenever the full JSON format says node\n`JBar` has a field `foo` of type `JExprHolder`, then in the short format `JBar`\nhas a field `foo` of type `string` and a field `locals` of type `JLocalDef[]`.\nAdditionally, the fields `index` in `JFor` and `iterator` in `JForeach` are\nabsent, and the loop-bound variable is instead stored as the first element of\n`locals`.\n\nThe string placed instead of the `JExprHolder` node can be turned into sequence\nof tokens using the following function:\n\n    export function shortToTokens(shortForm:string)\n    {\n        function uq(s:string) {\n            var r = \"\"\n            for (var i = 0; i < s.length; ++i) {\n                var c = s.charAt(i);\n                if (c == \"_\") {\n                    r += \" \";\n                } else if (c == \"/\") {\n                    r += String.fromCharCode(parseInt(s.slice(i + 1, i + 5), 16))\n                    i += 4\n                } else {\n                    r += c;\n                }\n            }\n            return r;\n        }\n\n        function oneToken(s:string) {\n            var v = s.slice(1)\n            switch (s[0]) {\n                case \",\": return { nodeType: \"operator\", op: v }\n                case \"#\": return { nodeType: \"propertyRef\", declId: v }\n                case \".\": return { nodeType: \"propertyRef\", name: uq(v) }\n                case \"'\": return { nodeType: \"stringLiteral\", value: uq(v) }\n                case \"F\":\n                case \"T\": return { nodeType: \"booleanLiteral\", value: (s[0] == \"T\") }\n                case \"$\": return { nodeType: \"localRef\", localId: v }\n                case \":\": return { nodeType: \"singletonRef\", name: uq(v) }\n                case \"?\":\n                    var cln = v.indexOf(':')\n                    if (cln > 0)\n                        return { nodeType: \"placeholder\", type: uq(v.slice(0, cln)), name: uq(v.slice(cln + 1)) }\n                    else\n                        return { nodeType: \"placeholder\", type: uq(v) }\n                default:\n                    throw new Error(\"wrong short form: \" + s)\n            }\n        }\n\n        if (!shortForm) return []; // handles \"\" and null; the code below is incorrect for \"\"\n\n        return shortForm.split(\" \").map(oneToken)\n    }\n\nIn other words, it's space separated sequence of strings, where the first\ncharacter denotes the kind of token and remaining characters are the payload.\nThe string is quoted by replacing spaces with underscores and all other\nnon-alphanumeric characters with unicode sequences preceeded by a slash (not\nbackslash to avoid double quoting in JSON).\n\n\n\nShort diff format\n~~~~~~~~~~~~~~~~~\n\nEvery object node in the short JSON format has a field named `id`. This is used\nwhen formulating diffs. The diff is set of updates to nodes of given ids. For\nevery id there is a set of `fieldName`, `value` pairs.\n\nFor example consider:\n\nA = {\n  \"id\": \"01\",\n  \"one\": \"one\",\n  \"two\": 2,\n  \"baz\": [\n    { \"id\": \"02\", \"enabled\": true },\n    { \"id\": \"03\", \"x\": 0 }\n  ]\n}\n\nB = {\n  \"id\": \"01\",\n  \"one\": \"seven\",\n  \"two\": 2,\n  \"baz\": [\n    { \"id\": \"02\", \"enabled\": true },\n    { \"id\": \"05\", \"y\": 7, \"z\": 13 }\n  ]\n}\n\ndiff(A, B) = {\n  // new node, assignment given for all fields\n  \"05\": { \"y\": 7, \"z\": 13 },\n  // updated node\n  \"01\": {\n    \"one\": \"seven\", // the field \"one\" is now \"seven\"\n    // the field \"two\" is not mentioned and thus unchanged\n    // the field \"baz\" now contains two nodes, ids of which are given\n    \"baz\": [ \"02\", \"05\" ]\n  },\n  // the node \"03\" is deleted\n  \"03\": null\n}\n\nThe JSON diff relies on the following properties of the short JSON format:\n\nFields of JNodes always contain either:\n  1. a JSON primitive value (string, boolean, integer, null), or\n  2. a sequence of JNodes\n\nEvery JNode has a unique 'id' field.\n\nThis is why JFor.bound and JForeach.collection fields are missing.  In the diff\nformat sequence of strings is always treated as a sequence of node ids.\n\nThe following function can be used to apply JSON diff:\n\n    function indexIds(obj:any)\n    {\n        var oldById:any = {}\n\n        function findIds(o:any) {\n            if (!o) return;\n            if (Array.isArray(o)) {\n                for (var i = 0; i < o.length; ++i)\n                    findIds(o[i])\n            } else if (typeof o === \"object\") {\n                if (!o.id) Util.oops(\"no id for \" + JSON.stringify(o))\n                if (oldById.hasOwnProperty(o.id)) Util.oops(\"duplicate id \" + o.id)\n                oldById[o.id] = o\n                var k = Object.keys(o)\n                for (var i = 0; i < k.length; ++i)\n                    findIds(o[k[i]])\n            }\n        }\n        findIds(obj)\n\n        return oldById\n    }\n\n    export function applyJsonDiff(base:any, diff:any)\n    {\n        var byId = indexIds(base)\n\n        var k = Object.keys(diff)\n        for (var i = 0; i < k.length; ++i) {\n            var id = k[i]\n            var upd = diff[id]\n            if (upd === undefined) continue;\n            var trg = byId[id]\n            if (upd === null) {\n                if (!trg) Util.oops(\"apply diff: no target id \" + id)\n                trg.__deleted = true;\n                continue;\n            }\n            if (!trg) {\n                byId[id] = trg = { id: id }\n            }\n            var kk = Object.keys(upd)\n            for (var j = 0; j < kk.length; ++j) {\n                var f = kk[j]\n                var v = upd[f]\n                if (Array.isArray(v) && typeof v[0] === \"string\")\n                    v = v.map(id => {\n                        var r = byId[id]\n                        if (!r) { r = byId[id] = { id: id } }\n                        return r\n                    })\n\n                Util.assert(f != \"nodeType\" || !trg[f])\n                trg[f] = v\n            }\n        }\n\n        var newIds = indexIds(base)\n        k = Object.keys(newIds)\n        for (var i = 0; i < k.length; ++i) {\n            var id = k[i]\n            if (newIds[k[i]].__deleted)\n                Util.oops(\"dangling id after diff \" + id)\n        }\n    }\n\n*/\n}\n";
TDev.webappHtml = "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <title></title>\n    <meta name=\"Description\" content=\"\"/>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0\"/>\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\" />\n    <meta name=\"format-detection\" content=\"telephone=no\">\n    <meta name=\"msapplication-tap-highlight\" content=\"no\"/>\n    <meta property=\"og:title\" content=\"\"/>\n    <meta property=\"og:site_name\" content=\"Touch Develop\"/>\n    <meta property=\"og:type\" content=\"game\" />\n    <meta property=\"og:description\" content=\"\" />\n    <meta property=\"og:image\" content=\"\" />\n    <meta property=\"og:url\" content=\"\" />\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n</head>\n<body id=\"root\">\n<style type=\"text/css\">\n    @import url(\"./default.css\");\n</style>\n<div id=\"loading\" style=\"width: 200px; margin: 150px auto 0 auto; text-align: center; color: #81e774; font-family: sans-serif; \">\n<div id=\"loadingDot\" style=\"font-size: 18px;margin-top:-10px\">we need JavaScript enabled</div>\n<div id='progressContainer' style='margin-top:20px;height:3px;width:200px; background:#eee;'>\n<div id='progressBar' style='height:3px; width:0px; background:#81e774'></div>\n</div>\n<div style=\"margin-top: 1em; font-size:12px;\" id=\"statusMsg\"></div>\n</div>\n<script type=\"text/javascript\">\nvar browsersUrl = \"browsers.html\";\nvar errorUrl = \"error.html\";\nvar mainJsName = \"./runtime.js\";\nvar userId = \"\";\nvar userName = \"\";\nvar webAppName = \"\";\nvar webAppGuid = \"\";\nvar webAppPublicationId = \"\";\nvar webAppImplicit = true;\nvar runtimeFlags = \"\";\nvar rootUrl = \"https://www.touchdevelop.com\";\nif (/debugLocal/.test(document.URL)) rootUrl = \"http://localhost:7777\";\nvar webRunner = true;\n(function() {\n  var e = document.getElementById(\"loadingDot\");\n  if (e) {\n    e.innerHTML = '';\n  }\n}());\n(function() {\n  var ratio = 0.97\n  var curr = 195 / (1 / (1 - ratio))\n  var sum = 0\n  function updatePbar() {\n    var pbar = document.getElementById(\"progressBar\");\n    if (!pbar) return;\n    sum += curr\n    curr *= ratio\n    pbar.style.width = sum + \"px\"\n    setTimeout(updatePbar, 200)\n  }\n  updatePbar();\n}());\nfunction statusMsg(m) {\n  if (/debugMsg/.test(document.URL)) {\n    var e = document.getElementById(\"statusMsg\");\n    if (e) e.innerHTML = m;\n  }\n}\n</script>\n<script src=\"./browser.js\" type=\"text/javascript\"></script>\n<script type=\"text/javascript\">\nTDev.Browser.check(true, \"Touch Develop\", \"https://www.touchdevelop.com/app/\");\n</script>\n<script src=\"precompiled.js?a=\" type=\"text/javascript\"></script>\n<script src=\"./runtime.js\" type=\"text/javascript\"></script>\n</body>\n</html>\n";

}
TDev.Util._languageData = function (lang) {
var keys = [
"   Maybe: {0} ({1} at '{2}')\n",
"  -> Line {2} ('{1}'), error: {0}\n{3}",
" -- a local variable",
" [class]",
" [hidden]",
" [override]",
" backward",
" forward",
" hours ",
" minutes ",
" of ",
" seconds ",
" sending changes",
" waiting for server",
"### full source code",
"'Javascripty' curly braces, all the tools, for experienced devs!",
"'atomic' function",
"'box' can only be accessed in page display code",
"'box' cannot be accessed in HTML layout mode",
"'else' of the preceding 'if' must be empty",
"'html' can only be accessed in HTML layout mode",
"'{0}' expects {1} here",
"'{0}' has unsupported signature",
"'{0}' is currently not implemented",
"'{0}' is obsolete and not implemented",
"'{0}' is obsolete and should not be used",
"'{0}' isn't a string resource",
"'{0}' returns a '{1}'; {2}",
"'{0}' returns {1} values; you can use 'store in var' button to save them to locals",
"(Optional) A URI identifying a human-readable web page with information about the error, used to provide the client developer with additional information about the error.",
"(Optional) A human readable error code.",
"(Optional) Additional key-value pairs not covered by the OAuth 2.0 specification.",
"(Optional) Indicates if the token might expire within the next seconds.",
"(Optional) Optional if identical to the scope requested by the client; otherwise, the scope of the access token as described by Section 3.3 of the OAuth 2.0 specification.",
"(Optional) The lifetime in seconds of the access token.",
"(please wait, it can take up to a minute)",
", got {0:a} instead",
", got {0}",
", size: {0} characters",
". Please read our ",
"... nothing to see here ...",
"... there's more ...",
"// comment",
"1. choose a document (.txt, .pptx, .pdf, .css, less than 8MB)",
"1. choose an MP3 sound (less than 1MB)",
"2. give it a name (minimum 4 characters)",
"3. describe it",
"4. publish",
":( Sorry, an error occured while translating this text.",
":( Sorry, we could not translate this.",
":( could not find any video source",
":( invalid in video information",
"; are you missing  → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'>Apache Cordova</a> let you build cross-platform mobile applications.",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'>generate the certificate</a>.",
"<b>DISCLAIMER:</b> This web app is not endorsed by Microsoft.",
"<b>how to run Touch Develop locally</b>",
"<b>this line is perfect!</b> let's move on",
"<h3>loading current settings...</h3>",
"<h3>no more tips!</h3>",
"<h3>welcome to Touch Develop</h3>",
"<h3>{0:q} requires sign&nbsp;in</h3>",
"<p>If you do not have an Azure subscription, go to <a href='https://account.windowsazure.com/Subscriptions' target='_blank'>Azure subscriptions</a> to get one.</p>",
"<p>Touch Develop lets you <b>create apps easily</b> from your phone, tablet or PC.</p>",
"<p>You can share your apps with others, so they can <b>run and edit</b> them on Windows Phone, iPad, iPhone, Android, PC, or Mac.</p>",
"<strong>feature in beta testing:</strong> the syntax and semantics is subject to change",
"<strong>required platform:</strong>",
"@hi/lo out of range",
"A 2D matrix of numbers",
"A 3D vector",
"A Bing map",
"A Minecraft Pi app.",
"A Minecraft app.",
"A Minecraft creeper app.",
"A Server-Sent-Events client",
"A animation to animate sprite properties.",
"A argb color (alpha, red, green, blue)",
"A background scene layer",
"A beginner friendly editor",
"A board to build 2D games",
"A builder to create HTML Form data",
"A cloud data session",
"A collection of objects",
"A collection of sprites",
"A color constant",
"A combination of date and time",
"A comment about your pull request was added.",
"A contact",
"A custom logger",
"A document",
"A document resource",
"A fully replicated {0} is saved in cloud storage, and fully cached on clients.",
"A generic atomic conversion function",
"A geo coordinate (latitude, longitude, ...)",
"A global variable",
"A group can be used to run a class or an event. Please do NOT include your school name within the group name.",
"A handler attached to an event.",
"A json data structure builder",
"A json data structure.",
"A link to a video, image, email, phone number",
"A local {0} is automatically saved to local storage, but never shared with other devices.",
"A map from strings to strings",
"A map of numbers to numbers",
"A map pushpin",
"A named location",
"A network error occurred. Your account settings could not be saved. Are you offline?",
"A number (possibly negative and/or fractional)",
"A number constant",
"A page button on the wall",
"A page on a wall",
"A partially replicated {0} is saved in cloud storage, and fully cached on clients.",
"A picture",
"A piece of text",
"A pixel art app.",
"A place to hook up an action to execute in response to an event",
"A possibly non-atomic single argument action",
"A post on a message board",
"A reference to a library script",
"A reference to a value",
"A replicated {0} is automatically saved in the cloud and shared between devices.",
"A scene contains layers of parralax backgrounds.",
"A separate window with the sign in dialog has opened, please sign in in that window.",
"A server-local {0} is saved in cloud storage, and never cached on clients.",
"A signature definition of an function",
"A single ASCII [USASCII] error code.",
"A snapshot of the gamepad state",
"A song",
"A sound",
"A sound effect",
"A spring between two sprites.",
"A sprite",
"A sprite sheet which packs multiple frames in a single picture",
"A structure of user-data",
"A table of user-defined rows",
"A task created with `async` keyword",
"A temporary {0} is local to the connection, and discarded when the connection ends.",
"A temporary {0} is not saved between runs.",
"A text box",
"A timer",
"A unique display name for your public profile (at least 8 characters)",
"A unit test",
"A user account",
"A user interface",
"A web socket",
"A web socket message",
"ADJ script",
"API config",
"API name",
"API not implemented",
"ARM logo",
"Aborts the execution if the condition is false.",
"Accelerometer",
"Access Denied: Your web browser and the web site prevent cross-origin resource sharing (CORS).",
"Access various properties of application environment",
"Add a CSS class name to the current element.",
"Add a new button. icon must be the name of a built-in icon, text must be non-empty.",
"Add a reference to JsonBuilder to the array.",
"Add an action that fires for every display frame",
"Add specified value to given reference",
"Add sprite to set and remove from old set. Returns true if sprite was in old set and not in new set.",
"Add sprite to set. Returns true if sprite was not already in set.",
"Add two signed 32 bit numbers",
"Add two unsigned 32 bit numbers",
"Adds a boolean value",
"Adds a number value",
"Adds a picture",
"Adds a picture pushpin on the map",
"Adds a piece of text to the form using a custom type and/or file name.",
"Adds a place pushpin on the map (ignored if the location is not set)",
"Adds a string value",
"Adds a text pushpin on the map",
"Adds a value to the array.",
"Adds a vector",
"Adds an object",
"Adds many objects at once",
"Adds numbers",
"Adds the value to the current life. Value can be negative.",
"Adds value to the current score. Value can be negative.",
"Adjust it {0}.",
"Advance enumerator and return true if there is another element.",
"After the script stops, browse the code to see collected information.",
"All my groups",
"All my scripts",
"All options turned on",
"Allow execution of other events, before the current event finishes.",
"Allows the user to save the email address (email)",
"Allows the user to save the phone number",
"An HTTP web request",
"An HTTP web response",
"An atomic action with no arguments",
"An empty app using pages and boxes.",
"An empty app using the scratch library.",
"An empty documentation page.",
"An empty interactive tutorial.",
"An empty script editor plugin.",
"An empty script, which doesn't do anything.",
"An general enumerator",
"An incomming HTTP web request",
"An indexed table of user-defined rows",
"An interface to TouchDevelop editor",
"An turtle app.",
"Applies `converter` on all elements of the input collection and returns a collection of results",
"Are you finished coding?",
"Are you sure you want to stop following the tutorial?",
"Arithmetic and bitwise operations on 32 bit integers",
"Art by this user:",
"Ask or display values on the wall...",
"Attach data to other objects",
"Boiler plate code to create a game.",
"Browse and review scripts from the bazaar",
"By dragging and placing blocks, you've created the following code.",
"Camera",
"Camera, location, microphone and other sensors",
"Can't see any window? Try tapping the button below to log in manually.",
"Change settings...",
"Change skill level!",
"Channels",
"Checks if the board is the same instance as the other board.",
"Checks if the color is equal to the other",
"Checks if two strings are the same",
"Chooses a picture from the media library",
"Clear all queued events related to this board",
"Clear the background picture",
"Clears the background camera",
"Cloud Data",
"Cloud session management",
"Code raised when a user interaction happens",
"Code that performs a specific task",
"Compares numbers for equality",
"Compares numbers for less",
"Compares numbers for less or equal",
"Compares numbers for more",
"Compares numbers for more or equal",
"Compass",
"Computes the average of the values",
"Computes the maximum of the key of the elements in the collection",
"Computes the maximum of the values",
"Computes the minimum of the values",
"Computes the sum of the values",
"Concatenates two pieces of text",
"Convert color to HTML syntax (either #FF002A or rgba(255, 0, 42, 0.5) when A is non-1)",
"Converts a number to a string",
"Converts and parses to a date time (type must be string)",
"Converts the value into a json data structure.",
"Converts to a boolean (type must be boolean)",
"Converts to a number (type must be number)",
"Converts to the local time",
"Copy current JSON object into a Json Builder so it can be modified",
"Cordova mobile app",
"Correctness helpers",
"Counts the number of rows",
"Create Code",
"Create Group",
"Create Script",
"Create a line obstacle with given start point, and given width and height. Elasticity is 0 for sticky, 1 for complete bounce.",
"Create a new collection for sprites.",
"Create a new ellipse sprite.",
"Create a new picture sprite.",
"Create a new rectangle sprite.",
"Create a new script",
"Create a new sprite sheet.",
"Create a new text sprite.",
"Create a spring between the two sprites.",
"Create an anchor sprite.",
"Create an invalid value of this object type",
"Create channel",
"Create collections of items.",
"Create invalid values",
"Create walls around the board at the given distance.",
"Create your own apps",
"Creates a color from the red, green, blue channels (0.0-1.0 range)",
"Creates a new color by changing the alpha channel from 0 (transparent) to 1 (opaque).",
"Creates a new empty game board and shows it on the screen.",
"Creates a new game board in landscape mode. On rotatable devices it will take the entire screen when posted.",
"Creates a new game board in portrait mode. On rotatable devices it will take the entire screen when posted.",
"Creates a new layer on the scene. The distance determines the order of rendering and how fast the layer moves",
"Creates a new sprite of width 100 with the given picture.",
"Creates an empty Picture collection",
"Creates an invalid Gamepad instance",
"Creates an invalid reference to an entry",
"Current box element in the page.",
"Current device",
"Current script: {0}",
"Current touch point",
"Detaches the handler from the event.",
"Displays string on the wall",
"Displays the image to the wall; you need to call 'update on wall' later if you want changes to be reflected.",
"Displays the link on the wall",
"Displays the request to the wall",
"Displays the sprite sheet.",
"Displays the state of the gamepad on the wall",
"Divides numbers",
"Do the sprites overlap",
"Do you want to receive informational Touch Develop-related newsletters, e.g. about new features and upcoming events?",
"Docs",
"Don't forget to scroll down and tap 'save' when you are done editing!",
"Drag and drop blocks, simplified interface, great for beginners!",
"Draws a line between two points",
"Draws some text border with a given color and font size",
"Edit code as text, more options, for aspiring app writers!",
"Emails, sms, contacts, calendar, ...",
"Enable or disable cloud synchronization for the current session",
"Enter a name",
"Enter a script name...",
"Enter some information about yourself",
"Enter the URL to your personal website (Example: http://www.northwindtraders.com)",
"Enter the invitation code",
"Enter your school affiliation, if any.",
"Events cannot have out parameters.",
"Everyone will be able to see your picture on the Internet forever. ",
"Expert",
"Exports a JSON representation of the contents.",
"Extensions",
"Facebook",
"Fills a ellipse with a given color",
"Fills a rectangle with a given color",
"Final touch velocity after touch ended",
"For published scripts, also look at the tab of the published script page to find anonymously collected crowd-sourced profile and coverage data.",
"Forums",
"From now on we won't show you the code to write. Follow the instructions and tap run when you think you are done.",
"Functions in the current script",
"Geo coordinates",
"Gets a field value as a boolean",
"Gets a field value as a number",
"Gets a field value as a string",
"Gets a json kind (string, number, object, array, boolean, null)",
"Gets a snapshot of the gamepad states (if any connected to the browser). Empty if unsupported or no gamepad connected.",
"Gets a url to the picture",
"Gets a value by name",
"Gets a value indicating if the background repeats horizontally",
"Gets a value indicating if the board is designed to be viewed in landscape mode",
"Gets a value whether the song is DRM protected",
"Gets the `x` and `y` value of the selected axes.",
"Gets the acceleration along y in pixels/sec^2",
"Gets the accent color in the current theme",
"Gets the background scene",
"Gets the center horizontal position of in pixels",
"Gets the chrome color in the current theme (control background)",
"Gets the color that has the ARGB value of #00FFFFFF",
"Gets the color that has the ARGB value of #FF000000",
"Gets the color that has the ARGB value of #FF0000FF",
"Gets the color that has the ARGB value of #FF008000",
"Gets the color that has the ARGB value of #FF00FFFF",
"Gets the color that has the ARGB value of #FF704214",
"Gets the color that has the ARGB value of #FF800080",
"Gets the color that has the ARGB value of #FF808080",
"Gets the color that has the ARGB value of #FFA52A2A",
"Gets the color that has the ARGB value of #FFA9A9A9",
"Gets the color that has the ARGB value of #FFD3D3D3",
"Gets the color that has the ARGB value of #FFFF0000",
"Gets the color that has the ARGB value of #FFFF00FF",
"Gets the color that has the ARGB value of #FFFFA500",
"Gets the color that has the ARGB value of #FFFFCBDB",
"Gets the color that has the ARGB value of #FFFFFF00",
"Gets the color that has the ARGB value of #FFFFFFFF",
"Gets the current connection state (`connecting`, `open`, `closed`)",
"Gets the current phone location with the most accuracy. This includes using services that might charge money, or consuming higher levels of battery power or connection bandwidth.",
"Gets the duration in seconds",
"Gets the field value as a time",
"Gets the first connected gamepad available",
"Gets the foreground color in the current theme",
"Gets the gamepad identifier",
"Gets the genre of the song",
"Gets the height in pixels",
"Gets the height of the camera image in pixels.",
"Gets the i-th json value",
"Gets the link associated to the message",
"Gets the list of keys",
"Gets the name of the artist",
"Gets the name of the song",
"Gets the names of the headers",
"Gets the normalized red value (0.0-1.0)",
"Gets the number of elements",
"Gets the number of values",
"Gets the player index",
"Gets the pressed value of a button. Returns 0 if button missing.",
"Gets the property that enables or disables gradients",
"Gets the sound volume for sounds from 0 (silent) to 1 (current volume)",
"Gets the sprite count",
"Gets the sprite indexed by i",
"Gets the text",
"Gets the timestamp of this snapshot",
"Gets the value of a given header",
"Gets the width in pixels",
"Gets the width of the camera image in pixels.",
"Gets the y position in pixels",
"Getting started",
"GitHub",
"Global variables in the current script",
"HTML5 web app",
"Help",
"Hide sprite.",
"Hides the timer.",
"Home",
"House rules",
"How did you discover Touch Develop?",
"If the page did not open, tap the 'open' button below, otherwise tap 'done'.",
"Import Code",
"Import a script from a file",
"Imports a JSON representation of the contents.",
"Imports a dependent package which may be versioned. Package managers may be Node.JS npm, Bower, Apache cordova, Python Pip and TouchDevelop plugins. ``bower`` and ``client`` imports are not available within the touchdevelop.com domain.",
"Imports the code from .hex files created for the BBC micro:bit or saved .jsz files. Hint: you can also drag and drop the files in the editor to import them!",
"In debug mode, board displays speed and other info of sprites",
"Indicates if a button is pressed. Returns false if button missing.",
"Indicates if program notifications should be shown to the user. Default is true.",
"Indicates if the gamepad data are identical",
"Indicates if the gamepad is still connected.",
"Indicates if the key exists",
"Indicates if the player is paused",
"Indicates if the player is stopped",
"Indicates if the string is empty",
"Insert '{0}' {1}",
"Interact with the app runtime",
"Items marked with * are required.",
"JSON data",
"Join Group",
"Last touch end point",
"Last touch start point",
"Libraries referenced by the current script",
"Library {0}:\n",
"Loading leaderboards...",
"Loading sessions...",
"Loading version info...",
"Make updates visible.",
"Makes a darker color by a delta between 0 and 1.",
"Makes a lighter color by a delta between 0 and 1.",
"Makes all the sprite bounce on thee border of the screen",
"Maps, location to address, address to location",
"Math goodness, abs, max, ...",
"Me",
"Microphone",
"Minecraft user",
"More",
"Motion",
"Moves sprite towards other sprite.",
"Multiplies numbers",
"Music and Sounds",
"My Groups",
"My Profile",
"My Scripts",
"NEW",
"NFC",
"Need some reason.",
"Network",
"New Scripts",
"New message from {0} in {1}",
"New or built-in colors",
"No can do",
"Objects, tables and indexes in the current script",
"On device '{0}', apply the following instructions.",
"Oops, could not get the leaderboards. Please check your internet connection.",
"Oops, the name is too short...",
"Oops, the picture name is too short...",
"Oops, the sound name is too short...",
"Oops, there was an error loading the picture.",
"Oops, we can't take a screenshot now",
"Oops, we can't take a screenshot now.",
"Oops, we could not get the scripts for this group. Please try again later.",
"Opens the leaderboard for the current script",
"Parses the string as a number",
"Partners",
"Phone numbers, vibrate, etc...",
"Picks a color from a color wheel where the hue is between 0 and 1.",
"Picks a random color",
"Pictures and music...",
"Pictures, sounds, etc. in the current script",
"Play, stop or resume songs, ...",
"Plays the song.",
"Please connect to internet to load the leaderboards.",
"Please go to the settings in the main hub to disable offline mode.",
"Please review our Privacy Statement.",
"Please wait...",
"Post a comment...",
"Prints the number to the wall",
"Prints the value to the wall",
"Privacy policy",
"Private actions do not get a run button. ",
"Prompts the user to input a number",
"Prompts the user to pick a string from a list. Returns the selected index.",
"Publish script",
"Publish your script, so that everyone can run it.",
"Publishing is subject to our ",
"Publishing script...",
"Raised when the animation started playing",
"Raised when the animation stopped playing",
"Reads the response body as a wave sound",
"Receive email notifications when other people review/take a screenshot of/comment on your scripts, or reply to one of your comments, or when events related to your subscriptions occur.",
"Remember: everyone will be able to see your script if you publish it, so make sure it doesn’t contain your passwords or personal information.",
"Removes the value from the current life. Value can be negative.",
"Reply...",
"Report/Delete",
"Resizes the picture to the given size in pixels",
"Returns a collection sorted using specified comparison key",
"Returns a copy of the image",
"Returns a copy of this string converted to lowercase, using the casing rules of the current culture.",
"Returns a copy of this string converted to uppercase, using the casing rules of the current culture.",
"Returns a date that adds the specified number of months to the value of this instance.",
"Returns a date that adds the specified number of years to the value of this instance.",
"Returns a random integral number between `min` and `max` included.",
"Returns a string collection that contains the substrings in this string that are delimited by elements of a specified string.",
"Returns a substring given a start index and a length",
"Returns the hyperbolic cosine of the specified angle (in radians)",
"Returns the number of characters",
"Returns the sine of the specified angle (in radians)",
"Returns the sprite color.",
"Returns true if sprite is not hidden",
"Returns true if the current instance is useless",
"Run the beta version of Touch Develop.",
"Run the inline action.",
"Runs a shell command. This action is only available when the script is running from a local web server.",
"Scales the sprite",
"Script Updates",
"Scripts by this user:",
"Search",
"Search and browse the web...",
"Search code...",
"Search everything",
"Search here...",
"Search phone numbers near a location using Bing. Distance in meters, negative to ignore.",
"Search phone numbers using Bing",
"Search...",
"Searching images using Bing",
"Searching news near a location using Bing. Distance in meters, negative to ignore.",
"Searching news using Bing",
"See More",
"Set what happens when the box is tapped.",
"Sets a value indicating if the background repeats horizontally",
"Sets gradient on or off",
"Sets the 3x3 affine matrix transformation applied to the wall.",
"Sets the angle of the sprite in degrees",
"Sets the background camera",
"Sets the background color",
"Sets the background color.",
"Sets the background picture",
"Sets the center horizontal position in pixels",
"Sets the current life points. Set as negative or zero to end the game.",
"Sets the default friction for sprites to a fraction of speed loss between 0 and 1",
"Sets the height in pixels",
"Sets the position in pixels",
"Sets the rotation speed in degrees/sec",
"Sets the sound volume level from 0 (silent) to 1 (current volume)",
"Sets the speed in pixels/sec",
"Sets the sprite color.",
"Sets the uniform acceleration vector for objects on the board to pixels/sec^2",
"Sets the url to the picture",
"Sets the wall background picture. The picture will be resized and clipped to the screen background as needed.",
"Sets the width in pixels",
"Sets the x speed in pixels/sec",
"Sets the y acceleration in pixels/sec^2",
"Sets the y position in pixels",
"Sets the y speed in pixels/sec",
"Sets the z-index of the sprite",
"Settings",
"Share it with this url:",
"Show errors in the editor if the script uses any APIs that prevent it from running on these platforms.",
"Shows the board on the wall.",
"Sign out",
"Skill level: {0}     ",
"Sorts from the newest to oldest",
"Sorts the places by distance to the location",
"Sorts the strings in this collection",
"Specify how to arrange the content of this box",
"Starts a new tween animation.",
"Stops and clears all the `every frame` timers",
"Stringify the current JSON object",
"Subtracts numbers",
"Support for interactive tutorials.",
"TD100: insert {0:a} here",
"TD101: cannot find '{0}'",
"TD109: cannot assign to this",
"TD111: cannot assign from {0} to {1}",
"TD112: i cannot find property '{0}' on {1}",
"TD115: excessive parameter(s) supplied to {0}",
"TD116: not enough parameters supplied to {0}",
"TD118: 'if' condition wants {1:a}",
"TD119: i need something to iterate on",
"TD121: cannot find type {0}",
"TD130: bound of 'for' wants {1:a}",
"TD144: it seems you're missing '{0}', try adding it",
"TD145: there seem to be an operator (like '+', '(' or ',') missing here",
"TD147: we didn't expect '{0}' here",
"TD150: cannot call the thing before '('",
"TD151: unclosed '('",
"TD152: unexpected ')'",
"TD154: the operator needs something after it",
"TD155: '{0}' cannot be assigned to a local variable",
"Teach Creative Coding!",
"Technology services by",
"Terms of use",
"The Touch Develop app has been updated.",
"The Touch Develop platform - Copyright © {0} Microsoft Corporation. All rights reserved.",
"The document url",
"The encoded screenshot is too big.",
"The front or back camera",
"The group has new owner",
"The user denied access to shell execution.",
"Thing",
"This command requires a local proxy.",
"This group is locked.",
"This group is open.",
"This script is current.",
"This script is missing the header.",
"This script is missing the source.",
"This script is using the following capabilities that might be missing on your current device: {0}",
"This script uses the following capabilities: ",
"This tab contains additional information about this script",
"This tutorial uses cloud data which is shared with other users.",
"To add page data, create a local var and tap 'promote to field'.",
"Touch Develop Local Shell",
"Touch Develop settings",
"Translation",
"Translation, speech to text, ...",
"Translations by Microsoft® Translator, tap to see original...",
"True if board is touched",
"Try tweaking your code until you get it right. If you get stuck, tap the tutorial bar.",
"Trying to reach server",
"Tutorial completed",
"Tutorials",
"Twitter",
"Type to search online...",
"Type to search...",
"TypeScript",
"Types, order, and number of event parameters cannot be edited.",
"UI widget",
"URL: {0}",
"Update positions of sprites on board.",
"Updates picture on a picture sprite (if it is a picture sprite)",
"Updates text on a text sprite (if it is a text sprite)",
"Upload Picture",
"Upload Sound",
"Users",
"We cannot run this script",
"We need more options",
"We will adapt the editor to your coding skill level. You can change your skill level later in the hub.",
"What is your level of programming knowledge?",
"What is your occupation?",
"What's new",
"Where in the world are you?",
"Writes another picture at a given location. The opacity ranges from 0 (transparent) to 1 (opaque).",
"You are online.",
"YouTube",
"YouTube video (https://youtu.be/...)",
"Your .hex will be uploaded onto your BBC micro:bit soon.",
"Your GitHub user.",
"Your Minecraft user.",
"Your art will appear here",
"Your browser does not allow Touch Develop to store data. This usually happens if run in Private Mode (Safari), in InPrivate mode (Internet Explorer) or your security settings prevent data storage. Sign in or change your browser settings to avoid loosing your work. All the changes not saved to the cloud will be lost when leaving this page.",
"Your channel will appear here",
"Your email address has not yet been verified. Please check your inbox.",
"Your full name",
"Your nickname is displayed on public pages. Make sure you do not enter your last name there.",
"Your script '{0}' cannot be published. Error message: {1:not available}",
"Your script has errors!",
"Your script will appear here",
"Your twitter handle, like @touchdevelop.",
"a few seconds ago",
"a function",
"a global variable",
"a minute ago",
"a page",
"about coverage",
"about insights",
"about profile",
"about you",
"abuse",
"abuse report",
"abuse reports",
"abuse review",
"access and use your location",
"access denied",
"access the {0} field",
"activity",
"add",
"add a new ...",
"add a publication note",
"add an action that fires for every display frame.",
"add comment",
"add comment for this field",
"add custom website",
"add function",
"add hearts",
"add input parameter",
"add line above",
"add line below",
"add new",
"add new tag",
"add optional",
"add output parameter",
"add to channel",
"add to inventory",
"add {0}",
"adding plugins",
"alien",
"all APIs",
"allow",
"amazing, astonishing, astounding, awe-inspiring, awesome, breathtaking, classic, cool, curious, distinct, exceptional, exclusive, extraordinary, fabulous, fantastic, glorious, great, ",
"an event handler",
"an function type definition",
"an hour ago",
"analyzing...",
"apply code",
"approvals",
"approve",
"approved",
"apps",
"are you sure?",
"art",
"art resource",
"assignment",
"authenticating...",
"author",
"author email",
"author web site",
"back",
"background",
"backspace",
"backspace this",
"bad key",
"ball",
"base",
"beginner",
"beginners",
"bell",
"binds to script:",
"blank",
"blank app",
"blank creeper",
"blank docs",
"blank game",
"blank minecraft",
"blank minecraft pi",
"blank pixel art",
"blank scratch",
"blank script plugin",
"blank turtle",
"blank tutorial",
"break in debugger",
"breakpoint",
"build",
"by time",
"by votes",
"call",
"call number",
"callback",
"cancel",
"cannot sync - you are not signed in",
"cat",
"change (back) to local",
"change contents",
"channels",
"checks if reference has not been set",
"choose .hex or .jsz files",
"choose a file",
"choose a picture",
"choose a picture (less than 1MB, smaller than 2048x2048)",
"choose a plugin",
"choose a wallpaper",
"choose group",
"choose library",
"choose new password",
"choose picture",
"choose your coding skill level",
"choose...",
"cleaning up browser data...",
"clear",
"clipboard",
"clone",
"cloud data",
"cloud sessions",
"code",
"code the goal line",
"coder",
"color #{0}",
"color: {0}",
"comment out",
"comments",
"compile",
"conditional",
"connected",
"connecting",
"console",
"continue",
"convert",
"copy",
"copy selection",
"coverage",
"create",
"create a new parameter",
"create channel",
"create code with...",
"create codes",
"creates an empty collection of entries",
"creates an empty collection of objects",
"creating script",
"current",
"current expression",
"customize the art!",
"cut",
"cut selection",
"database",
"debug",
"decimal dot",
"decorators",
"delete",
"delete local data and permissions",
"delete selection",
"demote to var",
"deny",
"description",
"description (helps search)",
"desert",
"details",
"did you want to use this value?",
"diff curr",
"diff prev",
"disable login",
"disabled",
"disconnect",
"dismiss",
"display value",
"displays the object on the wall",
"document name",
"document resource",
"dog",
"done",
"done!",
"edit",
"else if",
"email",
"email (private)",
"email and push notifications",
"email is not verified, {0}",
"enabled",
"enter a group name (required)",
"enter a number",
"enter invitation code",
"enter this code",
"errors",
"errors in plugin",
"events",
"everything",
"ex: ",
"example",
"excellent; great job; awesome; cool; you rock; well done; outstanding; you got it; right on",
"execute shell commands or manipulate files.",
"exit",
"expert",
"explosion",
"export",
"export a JSON representation of the contents",
"exported from this library",
"extend",
"extract",
"extract selection into function",
"extract to parameter",
"extract to var",
"find references",
"finished",
"fix it",
"follow tutorial in editor",
"for group",
"forks",
"function",
"function name",
"function types",
"function, variable, library, ...",
"gender",
"get my Hour of Code™ certificate",
"gets the timer that fires for every display frame.",
"github user",
"given ♥",
"global replace",
"global variable",
"global vars",
"go back",
"go back to coding! {0}★ to go",
"go back...",
"go to",
"go to list of things in your script",
"go to previous step",
"goal:",
"group",
"groups",
"hearts",
"help",
"here is your code",
"hide",
"history",
"hooray! your script is published",
"how found",
"i want it to run on",
"i'm finished with my Hour of Code™",
"icon art: {0}",
"if",
"if you are stuck, tap the goal line",
"image proxying",
"import can only be used from a script context",
"import code",
"import column values from a JSON object",
"import field values from a JSON object",
"imports",
"in a minute",
"in an hour",
"in this function",
"incredible, magical, marvellous, marvelous, mind-blowing, mind-boggling, miraculous, peculiar, phenomenal, rad, rockin', special, spectacular, startling, stunning, super-cool, ",
"initializing...",
"insert",
"insert comment",
"insert statement",
"insert {0}",
"insights",
"install {0}",
"installing and loading script",
"into local",
"island",
"issues",
"join a group",
"join group",
"jungle",
"just keep typing the search terms!",
"keep editing",
"known here as:",
"leaderboard",
"learn",
"learn about publishing",
"learn more",
"learn more about {0}",
"leave tutorial",
"let's change this",
"let's do it!",
"let's get started!",
"lib",
"libraries",
"library",
"library name",
"library reference",
"load more",
"load more replies",
"loading",
"loading art ...",
"loading comments for /{0}...",
"loading more...",
"loading replies...",
"loading script",
"loading tutorial",
"loading...",
"local",
"location",
"log",
"logical negation",
"logs",
"main",
"make call async",
"makers",
"manage data",
"maybe later",
"me",
"meow",
"minecraft",
"minecraft user",
"monster",
"moon",
"more",
"more ",
"more settings",
"move cursor",
"move left",
"move on to the next step",
"move the cursor left",
"move the cursor right",
"my art",
"my group",
"my groups",
"my script",
"my scripts",
"need a different name here",
"need a different string here",
"need a new field here",
"need a parameter",
"need to delete this",
"need to edit elsewhere",
"negation",
"new field/data",
"new function",
"new global var",
"new invitation code",
"new line",
"new local",
"new password:",
"new property",
"new stmt below",
"new variable",
"next page",
"next tutorials...",
"nickname",
"no",
"no art published by this user",
"no comments, tap to write some!",
"no forks, install, edit and re-publish script to create one!",
"no hearts. you can add one once you install the script!",
"no picture loaded yet",
"no previous email",
"no screenshots yet!",
"no tags, tap to add some!",
"no users in this group!",
"non-atomic",
"not today",
"notifications",
"now",
"now you can select a property of {0}; it doesn't do anything by itself",
"now you can select a property on it",
"number",
"number entry",
"objects",
"occupation",
"of an object",
"offline available",
"ok",
"ok, let's roll!",
"online",
"open",
"or tap to get help",
"others",
"overview",
"overwrite",
"pages",
"parameter name",
"parsing script text",
"password is reset",
"paste",
"pause",
"permissions",
"physics game starter",
"pick a script template...",
"picture",
"picture name",
"picture name (minimum 4 characters)",
"picture url",
"play again",
"please wait",
"please wait...",
"plugins",
"preview",
"print",
"privacy policy",
"private",
"private function",
"private profile",
"profile",
"programming knowledge",
"progress",
"promote to data",
"promote to field",
"public nickname",
"public profile",
"publish",
"publish as hidden",
"publish your script",
"published",
"pull changes",
"pull out to block level",
"pumpkin",
"re-run",
"read more...",
"read only",
"real name",
"real name (private)",
"receive email newsletters",
"receive email notifications",
"record name:",
"redeploying shell...",
"regular keypad",
"reloading script",
"remove",
"remove else",
"remove picture",
"remove white background (best for game sprites)",
"removing script...",
"rename",
"repeat n times",
"repeat on collection",
"repeat while",
"replace all in function",
"replace all in script",
"replace picture",
"replicated",
"replicated ",
"reply",
"report abuse",
"resume",
"revert to published version",
"rewind",
"rewind ",
"run",
"run main",
"run tests",
"run with instrumentation",
"save",
"saved",
"saving...",
"school",
"screens",
"screenshot",
"screenshot of {0}",
"script",
"script properties",
"scripts",
"search",
"search art",
"search art pictures",
"search here for {0}",
"search templates",
"searching...",
"see more options",
"select",
"select more",
"select that line",
"select type of this {0}",
"select {0}",
"serial",
"set local variable name",
"set name",
"set the handler that is invoked when the board is swiped",
"set the handler that is invoked when the board is tapped",
"set the handler that is invoked when the board is touched",
"set the handler that is invoked when the board touch is released",
"sets all fields to their default values",
"setting saved",
"settings",
"share",
"show",
"show how to complete this activity",
"show more options",
"showcase",
"sign in",
"sign in as:",
"sign in required",
"sign out",
"signing in...",
"signing out",
"simplify",
"skill level saved",
"skip iteration",
"skip this",
"social",
"sorry",
"sound",
"sound url",
"splash screen art: {0}",
"split",
"start beta testing",
"start over",
"starting script",
"starting...",
"stats",
"step in",
"step out",
"step over",
"still compiling, please wait...",
"stop",
"stop beta testing",
"stop function",
"stop loop",
"store in var",
"store the value in a variable",
"string",
"string resource",
"strip '{0}'",
"stuff you copied",
"subscribers",
"subscriptions",
"superior, supernatural, terrific, unbelievable, unearthly, unique, unprecedented, unusual, weird, wonderful, wondrous",
"surround with",
"sync",
"sync was disabled on purpose",
"syncing...",
"table",
"table of contents",
"tables",
"tag name {0} is not allowed",
"tag not allowed",
"tags",
"take picture",
"taker",
"tap (←) when done",
"tap [ok] when done",
"tap a checkmark to add (or remove) your 'vote' to an existing tag",
"tap here to move on to the next step",
"tap here when done",
"tap there",
"tap there for instructions",
"tap there to run your app",
"tap to change the color",
"tap to change the icon picture",
"tap to change the splash screen picture",
"tap to translate with Microsoft® Translator...",
"temporary",
"terms of use",
"test",
"test function",
"tests",
"tests if two references refer to the same object",
"the current function",
"the forums",
"the hub",
"the invitation code must be a number between 9 and 64 characters long",
"the script crashed",
"the shell and/or the file system. This script may be harmful for your computer. Do not allow this if you do not trust the source of this script.",
"this",
"this script is a library",
"this script is a web service",
"time and dates",
"to code",
"to continue",
"to global var",
"toggle breakpoint",
"top & new",
"touch develop",
"touch develop is in offline mode{0}",
"translate",
"translating tutorial...",
"translation",
"true or false",
"true?",
"try again!",
"turn into",
"tutorial progress",
"tutorial: ",
"tutorials",
"twitter handle",
"type: ",
"type: {0}",
"types",
"uncomment",
"under the hood (dbg): ",
"undo",
"undo fix",
"unhide",
"unicorn",
"uninstall",
"uninstall scripts",
"uninstalling...",
"unknown editor",
"unknown flag",
"unselect",
"unsubscribe",
"update",
"update them!",
"updating libraries",
"updating meta",
"updating picture...",
"updating script",
"updating your scripts",
"upload",
"upload picture",
"upload screenshot",
"upload sound",
"uploader",
"uploading documents",
"uploading pictures",
"url",
"url (e.g. http://localhost:4242):",
"use C++ compiler",
"users",
"value",
"variable",
"variable name",
"view as script",
"view/edit name, email, ...",
"vimeo video (https://vimeo.com/...)",
"wallpaper",
"we have a library '{0}' here; {1}",
"we have {0:a} here; did you want to do something with it?",
"we need a new field",
"we need a new table",
"we need a new {0}",
"we need different keypad",
"we need to a new variable",
"we need to edit another thing",
"we'll guide you step by step",
"web apps",
"web site key",
"web site name",
"web site url",
"website",
"website name",
"website url",
"which kind of event to add?",
"white",
"working hard",
"writing {0}",
"wrote",
"year of birth",
"yes",
"you can also search",
"you did it!",
"your best score: {0}",
"{0} ({1} line{1:s})",
"{0} day{0:s} ago",
"{0} down",
"{0} failed; we are now using offline mode;\n make sure your internet connection is working",
"{0} file{0:s} imported",
"{0} for this version",
"{0} hour{0:s} ago",
"{0} minute{0:s} ago",
"{0} month{0:s} ago",
"{0} of {1} done",
"{0} publish",
"{0} script{0:s} published",
"{0} second{0:s} ago",
"{0} up",
"{0} year{0:s} ago",
"{box:avatar:avatar}\n",
"© Copyright {0} {1}",
"● Sign in"
];

if (lang == "ar") { TDev.Util._setLanguageArray(keys, [0,0,
" --متغير محلي",
0,
" [hidden]",
0,0,0,0,0,
" من ",
0,
" إرسال التغييرات",
0,0,
"أقواس 'Javascripty' المتعرجة، كل الأدوات، للمطورين الخبراء!",
"دالة \"ذرية\"",
0,0,0,0,
"'{0}' يتوقع {1} هنا",
0,0,0,
"'{0}' قديم وينبغي عدم استخدامه",
0,
"'{0}' يقوم بإرجاع \\\"{1}\\\"؛ {2}",
0,0,0,0,0,0,0,0,
"، حصل على {0} في المقابل",
"، تم الحصول على {0}",
0,0,0,
"... هناك المزيد ...",
"// تعليقات",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>هذا السطر كامل!</b> دعنا نتابع العمل",
"<h3>تحميل الإعدادات الحالية...</h3>",
"<h3>لا مزيد من التلميحات!</h3>",
0,
"<h3>يتطلب {0:q} تسجيل الدخول</h3>",
0,0,0,0,0,0,0,0,0,
"تطبيق Minecraft Pi.",
"تطبيق Minecraft.",
"تطبيق زاحف في Minecraft.",
0,0,0,0,0,0,0,0,0,0,
"قيمة ثابتة للّون",
0,0,0,0,0,0,0,0,0,
"متغير عمومي",
0,0,0,0,0,0,0,0,0,0,0,
"الرقم (قد يكون سالبًا و/أو كسرًا)",
"قيمة ثابتة للعدد",
0,0,0,
"صورة",
"جزء من نص",
"تطبيق فن بكسل.",
0,0,0,
"مرجع إلى برنامج نصي لمكتبة",
0,0,0,0,0,0,0,0,0,
"صوت",
0,0,0,0,
"بنية بيانات المستخدم",
"جدول صفوف معرفة من قبل المستخدم",
0,0,0,0,0,
"اسم عرض فريد لملف التعريف العام لديك (8 أحرف على الأقل)",
0,0,
"واجهة مستخدم",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"إضافة إجراء يضفي جمالاً لكل إطار عرض",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"إضافة أرقام",
"يقوم بإزالة القيمة من الحياة الحالية.",
"إضافة قيمة إلى مجموع النقاط الحالي.",
0,0,
"بعد توقف البرنامج النصي، استعرض الرمز لمشاهدة المعلومات التي تم تجميعها.",
"كل مجموعاتي",
"كل برامجي النصية",
0,0,0,0,0,0,0,
"تطبيق فارغ يستخدم الصفحات والمربعات.",
"تطبيق فارغ يستخدم مكتبة الخدوش.",
"صفحة وثائق فارغة.",
"برنامج تعليمي تفاعلي فارغ.",
"مكوّن إضافي لمحرر برنامج نصي فارغ.",
"برنامج نصي فارغ، لا يقوم بأي إجراء.",
0,0,
"جدول مفهرس لصفوف معرفة من قبل المستخدم",
0,
"تطبيق سلحفاة.",
"يقوم بتطبيق `converter` على جميع عناصر مجموعة الإدخال ويقوم بإرجاع مجموعة نتائج",
0,
"هل تريد بالتأكيد إيقاف متابعة البرنامج التعليمي؟",
0,
"النشاط الفني بواسطة هذا المستخدم:",
"السؤال أو عرض القيم على الجدار...",
"إرفاق بيانات بالكائنات الأخرى",
"التعليمات البرمجية المتكررة لإنشاء لعبة.",
0,0,0,0,0,0,
"تغيير مستوى المهارة!",
0,
"للتحقق مما إذا كانت اللوحة تقع على نفس المسافة من اللوحة الأخرى.",
0,0,0,
"مسح كل الأحداث في قائمة الانتظار المرتبطة بهذه اللوحة",
"مسح صورة الخلفية",
"مسح كاميرا الخلفية",
0,0,
"رمز يتم إبرازه عندما يحدث تفاعل مستخدم",
"رمز يؤدي مهمة معينة",
"مقارنة الأرقام بأرقام مساوية",
"مقارنة الأرقام بأقل",
0,
"مقارنة الأرقام بأكثر",
0,0,0,0,0,0,0,
"سَلسلة جزأين من النص",
0,0,0,0,0,0,
"تحويل إلى الوقت المحلي",
0,0,0,0,0,
"إنشاء مجموعة",
"إنشاء برنامج نصي",
"إنشاء حاجز خط مع نقطة بدء محدد، وبعرض وارتفاع محددين. المرونة هي 0 للملصق، و1 للوثب الكامل.",
"إنشاء مجموعة جديدة لرسومات سبرايت.",
"إنشاء رسم سبرايت بيضاوي جديد.",
"إنشاء عرض ثنائي الأبعاد جديد لصورة.",
"إنشاء عرض ثنائي الأبعاد جديد لمستطيل.",
0,
"إنشاء ورقة عرض ثنائي الأبعاد جديدة.",
"إنشاء عرض ثنائي الأبعاد جديد لنص.",
"إنشاء عرض ثنائي الأبعاد بين عرضين ثنائيي الأبعاد.",
"إنشاء عرض ثنائي أبعاد لمرساة.",
"إنشاء قيمة غير صالحة لنوع الكائن هذا",
"إنشاء قناة",
"إنشاء مجموعات من العناصر.",
0,
"إنشاء جدران حول اللوحة على مسافة معينة.",
"إنشاء تطبيقاتك",
0,0,
"لإنشاء حد لعبة جديد فارغ وإظهاره على الشاشة.",
0,0,0,
"لإنشاء عرض ثنائي الأبعاد جديد بعرض يبلغ 100 مع صورة معينة.",
0,
"لإنشاء مثيل لوحة لعبة غير صالحة",
0,0,
"الجهاز الحالي",
0,
"نقطة اللمس الحالية",
"يفصل المعالج عن الحدث.",
0,
"يعرض الصورة على حائط، ستكون بحاجة إلى طلب \"التحديث على الحائط\" في وقت لاحق إذا كنت تريد أن تظهر التغييرات.",
0,0,0,
"لعرض حالة لوحة اللعبة على الحائط",
0,
"تنفيذ تداخل العرض ثنائي الأبعاد",
0,
"المستندات",
"لا تنس التمرير لأسفل ولمس \"حفظ\" عند الانتهاء من التحرير!",
"سحب وإفلات الكتل، واجهة مبسّطة، رائعة للمبتدئين!",
"رسم خط بين نقطتين",
"رسم بعض حدود النص بلون وحجم خط معين",
"تحرير التعليمة البرمجية كنص، مزيد من الخيارات، لكتاب التطبيقات الطموحين!",
0,0,
"إدخال اسم",
0,
"إدخال بعض المعلومات الخاصة بك",
"إدخال عنوان URL لموقع الويب الشخصي لديك (مثلاً: http://www.northwindtraders.com)",
"إدخال رمز الدعوة",
0,
"لا يمكن أن يكون للأحداث معلمات خارجية.",
"سيتمكن كل شخص من رؤية صورتك على الإنترنت للأبد. ",
0,0,
"ملحقات",
"Facebook",
"ملء قطع ناقص بلون معين",
"ملء مستطيل بلون معين",
"سرعة اللمس النهائية بعد إنهاء اللمس",
"بالنسبة للبرامج النصية المنشورة، انظر أيضا إلى علامة التبويب الخاصة بصفحة البرنامج النصي المنشور للبحث عن ملف التعريف وبيانات التغطية التي يتم تجميعها بواسطة العديد من المصادر.",
"منتديات",
"من الآن فصاعدًا، لن نعرض لك التعليمات البرمجية اللازم كتابتها. اتبع التعليمات واضغط على \"تشغيل\" عندما تعتقد أنك انتهيت.",
"الدوال في البرنامج النصي الحالي",
0,0,0,0,0,
"للحصول على لقطة شاشة لحالات لوحة اللعبة (إذا كان أي منها متصلاً بالمستعرض). فارغ إذا كان غير مدعوم أو لا توجد لوحة لعبة متصلة.",
0,0,0,
"للحصول على قيمة تشير إلى ما إذا كان اللوح قد صّمم ليتم عرضه في الوضع الأفقي",
"الحصول على قيمة توضح ما إذا كانت الأغنية محمية بموجب إدارة الحقوق الرقمية \"DRM\"",
"للحصول على قيمة س وص للمحاور المحددة.",
0,0,
"للحصول على مشهد الخلفية",
"الحصول على موضع التمركز الأفقي بالبكسل",
0,
"الحصول على لون له قيمة ARGB تبلغ #00FFFFFF",
"الحصول على لون له قيمة ARGB تبلغ #FF000000",
"الحصول على لون له قيمة ARGB تبلغ #FF0000FF",
"الحصول على لون له قيمة ARGB تبلغ #FF008000",
"الحصول على لون له قيمة ARGB تبلغ #FF00FFFF",
0,
"الحصول على لون له قيمة ARGB تبلغ #FF800080",
0,0,0,0,
"الحصول على لون له قيمة ARGB تبلغ #FFFF0000",
"الحصول على لون له قيمة ARGB تبلغ #FFFF00FF",
"الحصول على لون له قيمة ARGB تبلغ #FFFFA500",
0,
"الحصول على لون له قيمة ARGB تبلغ #FFFFFF00",
"الحصول على لون له قيمة ARGB تبلغ #FFFFFFFF",
0,0,0,0,
"للحصول على أول لوحة لعبة متصلة متوفرة",
0,
"للحصول على معرف لوحة اللعبة",
0,
"الحصول على الارتفاع بالبسكل",
"يحصل على الارتفاع الخاص بصورة الكاميرا بالبكسل.",
0,0,0,0,0,0,0,0,0,
"للحصول على فهرس اللاعبين",
"احصل على القيمة المضغوطة لزر. لإرجاع 0 إذا كان الزر مفقودًا.",
0,
"الحصول على مستوى الصوت للأصوات من 0 (صامت) إلى 1 (الصوت الحالي)",
"للحصول على عدد الصور ثنائية الأبعاد",
"للحصول على عرض ثنائي الأبعاد مفهرس حسب",
0,
"للحصول على الطابع الزمني للقطة الشاشة هذه",
0,
"الحصول على العرض بالبسكل",
"يحصل على العرض الخاص بصورة الكاميرا بالبكسل.",
"الحصول على الموضع ص بالبسكل",
"بدء الاستخدام",
0,
"المتغيرات العامة في البرنامج النصي الحالي",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"في وضع تصحيح الخطأ، تعرض اللوحة السرعة والمعلومات الأخرى للعروض ثنائية الأبعاد",
"للإشارة إلى ما إذا كان قد تم الضغط على زر أم لا. لإرجاع خطأ إذا كان الزر مفقودًا.",
0,
"للإشارة إلى ما إذا كانت بيانات لوحة اللعبة مطابقة أم لا",
"للإشارة إلى ما إذا كانت لوحة اللعبة لا تزال متصلة أم لا.",
0,0,0,0,
"إدراج \"{0}\" {1}",
"التفاعل مع وقت التشغيل",
"العناصر المعلَّمة بـ * مطلوبة.",
"بيانات JSON",
"انضم للمجموعة",
"نقطة نهاية اللمس الأخيرة",
"نقطة بداية اللمس الأخيرة",
0,0,0,0,0,
"جعل التحديثات مرئية.",
0,0,
"جعل رسم سبرايت يقفز بالكامل على حافة الشاشة",
0,
"روعة الرياضيات، القيمة المطلقة abs، الحد الأقصى max،...",
"Me",
0,
"مستخدم Minecraft",
0,0,
"نقل رسم سبرايت باتجاه رسم سبرايت آخر.",
"ضرب أرقام",
0,0,0,0,0,0,0,0,
"برامج نصية جديدة",
0,
"الألوان الجديدة أو المضمنة",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"يختار لون عشوائي",
0,0,0,0,0,0,
"يرجى مراجعة بيان الخصوصية الخاص بنا.",
0,
"نشر تعليق...",
0,0,0,
"إجراء خاص لا يشتمل على زر تشغيل.",
"لمطالبة المستخدم بإدخال رقم",
0,
"نشر البرنامج النصي",
"انشر البرنامج النصي الخاص بك، كي يتمكن الجميع من تشغيله.",
"النشر يخضع لـ \" الخاص بنا ",
"جارٍ نشر البرنامج النصي...",
"يتم الرفع عند بدء الرسم المتحرك في الحركة",
"يتم الرفع عند توقف الرسم المتحرك عن الحركة",
"يقرأ نص الاستجابة كموجة صوتية",
"يمكنك تلقي إعلامات البريد الإلكتروني عند مراجعة أشخاص آخرين/أخذهم لقطات شاشة من/التعليق على البرامج النصية الخاصة بك، أو الرد على أحد تعليقاتك أو عند وقوع أحداث متعلقة باشتراكاتك.",
"تذكر: سيتمكن الجميع من رؤية برنامجك النصي إذا قمت بنشره، لذا تأكد من أنه لا يحتوي على أي من كلمات المرور أو المعلومات الشخصية الخاصة بك.",
"يقوم بإزالة القيمة من مرة الحياة الحالية.",
"رد...",
"إبلاغ/حذف",
"تغيير حجم الصورة إلى الحجم المحدد بالبكسل",
0,
"إرجاع نسخة للصورة",
0,0,
"يقوم بإرجاع تاريخ يضيق عدد معينا من الأشهر لقيمة هذا المثيل.",
"يقوم بإرجاع تاريخ يضيق عدد معينا من الأعوام لقيمة هذا المثيل.",
"إرجاع رقم صحيح عشوائي بين \"الحد الأدنى\" و\"الحد الأقصى\" ويشملهما.",
0,0,0,0,0,0,0,
"إرجاع \"صواب\" إذا كان المثيل الحالي بدون استخدام",
0,0,0,0,
"تحديثات البرنامج النصي",
"البرامج النصية بواسطة هذا المستخدم:",
"بحث",
0,
"بحث عن الرمز...",
"بحث عن كل شيء",
"بحث هنا...",
0,0,
"بحث...",
0,0,0,
"مشاهدة المزيد",
0,0,
"تعيين تدرج الألوان على تشغيل أو إيقاف",
"يقوم بتعيين التحويل الخطي مع إضافة مصفوفة 3×3 المطبقة على الحائط.",
0,
"لتعيين كاميرا الخلفية",
"لتعيين لون الخلفية",
0,
"تعيين صورة الخلفية",
"تعيين موضع التمركز الأفقي بالبكسل",
"يقوم بتعيين نقاط الحياة الحالية.",
"لتعيين الجزء الافتراضي من العروض ثنائية الأبعاد لجزء فقد السرعة بين 0 و1",
"تعيين الارتفاع بالبسكل",
"تعيين الموضع بالبسكل",
0,
"تعيين مستوى الصوت للأصوات من 0 (صامت) إلى 1 (الصوت الحالي)",
"تعيين السرعة بالبكسل/الثواني",
"تعيين لون العرض ثنائي الأبعاد.",
"لتعيين موجّه التسارع الموحّد للكائنات على اللوحة بالبكسل/ثانية^2",
0,0,
"تعيين العرض بالبسكل",
"تعيين السرعة س بالبكسل/ث",
"تعيين تسارع ص بالبكسل/الثانية المربعة",
"تعيين الموضع ص بالبسكل",
"تعيين السرعة ص بالبكسل/ث",
0,
"إعدادات",
"شاركه باستخدام عنوان url هذا:",
"يظهر أخطاء في المحرر في حالة استخدام البرنامج النصي لأي واجهات برمجة تطبيقات (API) تمنع تشغيله على هذه الأنظمة الأساسية.",
"لإظهار اللوحة على الحائط.",
0,
"مستوى المهارة: {0}     ",
0,0,0,0,0,
"لإيقاف كل مؤقتات كل إطار ومسحها",
0,
"طرح أرقام",
0,
"TD100: إدراج {0} هنا",
"TD101: يتعذر البحث عن \\\"{0}\\\"",
"TD109: يتعذر التعيين إلى ذلك",
"TD111: يتعذر التعيين من {0} إلى {1}",
"TD112: لا يمكنني العثور على الخاصية \\\"{0}\\\" على {1}",
"TD115: معلمة (معلمات) زائدة متوفرة لـ {0}",
"TD116: لا توجد معلمات كافية إلى {0}",
"TD118: يريد الشرط \\\"إذا\\\" {1}",
"TD119: أحتاج إلى شيء ما لتكراره",
0,
"TD130: مرتبط بما يريده \\\"لـ\\\" {1}",
"TD144: يبدو أنك ليس لديك \\\"{0}\\\", حاول الإضافة",
"TD145: يبدو أنه يوجد عامل (مثل \\\"+\\\", أو \\\"(\\\"، أو \\\",\\\") مفقود هنا",
"TD147: لم نتوقع \\\"{0}\\\" هنا",
"TD150: يتعذر استدعاء الشيء قبل '('",
"TD151: مفتوح '('",
"TD152: \\\")\\\"\\\" غير متوقع",
"TD154: المحرر في حاجة إلى شيء بعده",
"TD155: '{0}' لا يمكن تعيينها إلى متغير محلي",
"تعليم الترميز الإبداعي!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"يستخدم هذا البرنامج النصي الإمكانات التالية: ",
0,
"هذا البرنامج التعليمي يستخدم بيانات السحابة التي تتم مشاركتها مع مستخدمين آخرين.",
"لإضافة بيانات الصفحة، قم بإنشاء متغير واضغط \\\"ترقية إلى الحقل\\\".",
0,0,0,0,
"ترجمة من قبل مترجم Microsoft ®، اضغط لرؤية الأصلي...",
"صحيح إذا تم لمس اللوحة",
"حاول تغيير التعليمة البرمجية وتبديلها حتى تحصل على التعليمة الصحيحة. إذا علقت، فاضغط على شريط البرامج التعليمية.",
0,0,
"برامج تعليمية",
"Twitter",
"اكتب للبحث على الإنترنت...",
"اكتب للبحث...",
0,
"يتعذر تحرير أنواع وترتيب ورقم معلمات الأحداث.",
"عنصر واجهة المستخدم الخاص بواجهة المستخدم",
0,
"تحديث مواضع العروض ثنائية الأبعاد على اللوحة.",
"تحديث الصورة على عرض ثنائي الأبعاد للصورة (إذا كانت عبارة عن عرض ثنائي الأبعاد للصورة)",
"لتحديث النص على عرض ثنائي الأبعاد للنص (إذا كانت عبارة عن عرض ثنائي الأبعاد للنص)",
"تحميل صورة",
"تحميل صوت",
"المستخدمون",
0,
"نحتاج إلى مزيد من الخيارات",
"سنجعل المحرر ملائمًا لمستوى مهارات الترميز لديك. يمكنك تغيير مستوى مهاراتك لاحقًا في الموزع.",
"ما مستوى معلوماتك البرمجية؟",
"ما مهنتك؟",
"الجديد",
"في أي مكان في العالم تقيم؟",
"يكتب صورة أخرى في مكان معين. يتراوح معدل الشفافية من 0 (شفاف) إلى 1 (معتم).",
0,
"YouTube",
0,0,
"مستخدم GitHub الخاص بك.",
"مستخدم Minecraft الخاصة بك.",
"العمل الفني الخاص بك يظهر هنا",
0,
"ستظهر قناتك هنا",
"لم يتم التحقق من صحة عنوان بريدك الإلكتروني حتى الآن. يرجى التحقق من علبة الوارد لديك.",
"اسمك بالكامل",
0,0,0,
"البرنامج النصي الخاص بك يظهر هنا",
"اسمك على twitter، مثل ‎@touchdevelop.",
"منذ بضع ثوانٍ",
"دالة أ",
"متغير عمومي",
"منذ دقيقة",
"صفحة",
"عن التغطية",
"عن الأفكار",
"عن ملف التعريف",
"عنك",
"إساءة استخدام",
0,
"تقارير الإساءة",
0,0,0,
"الوصول إلى الحقل {0}",
0,
"إضافة",
"إضافة جديد...",
0,
"إضافة إجراء يضفي جمالاً لكل إطار عرض.",
0,0,0,0,0,
"إضافة معلمة إدخال",
"إضافة سطر في الأعلى",
"إضافة سطر في الأسفل",
"إضافة جديد",
0,0,
"إضافة معلمة إخراج",
0,0,0,0,0,
"كل واجهات API",
"السماح",
"مذهل، مدهش، رائع، ملهم، جميل، خلاب، كلاسيكي، ظريف، لافت للنظر، مميز، استثنائي، حصري، غير عادي، خرافي، باهر، فخم، عظيم. ",
0,
"تعريف نوع دالة",
"منذ ساعة",
0,0,0,0,0,
"تطبيقات",
0,
"عمل فني",
"مورد العمل الفني",
"تعيين",
0,
"المؤلف",
0,0,
"الخلف",
0,
"مسافة للخلف",
"رجوع بذلك للخلف",
0,0,
"قاعدة",
"مبتدئ",
"المبتدئون",
0,
"يرتبط ببرنامج نصي:",
"فارغ",
"تطبيق فارغ",
"زاحف فارغ",
"مستندات فارغة",
"لعبة فارغة",
"لعبة minecraft فارغة",
"لعبة minecraft pi فارغة",
"فن بكسل فارغة",
"خدش فارغ",
"مكوّن إضافي لبرنامج نصي فارغ",
"سلحفاة فارغة",
0,
"إيقاف في مصحح الأخطاء",
"نقطة توقف",
0,0,0,0,0,0,
"إلغاء الأمر",
0,0,
"تغيير (رجوع) إلى محلي",
"تغيير المحتويات",
"قنوات",
"التحقق مما إذا كان المرجع لم يتم تعيينه",
0,0,0,
"اختر صورة (أقل من 1 ميجابايت، وأصغر من 2048×2048)",
0,0,0,0,0,0,
"اختيار مستوى مهارات الترميز لديك",
"اختيار...",
0,
"مسح",
"الحافظة",
"النسخة",
0,
"جلسات عمل سحابية",
"رمز",
"ترميز سطر الهدف",
"مبرمج",
"لون #{0}",
"اللون: {0}",
"تعليق",
"تعليقات",
0,
"شرطي",
"متصل",
0,0,
"متابعة",
0,
"نسخ",
"نسخ التحديد",
"تغطية",
"إنشاء",
"إنشاء معلمة جديدة",
0,0,0,0,
"إنشاء مجموعة كائنات فارغة",
"إنشاء برنامج نصي",
0,
"التعبير الحالي",
"تخصيص الفن!",
"قص",
"قص التحديد",
"قاعدة بيانات",
"تصحيح",
"نقطة عشرية",
"الديكور",
"حذف",
"حذف البيانات المحلية والأذونات",
"حذف التحديد",
"تخفيض إلى متغير",
"رفض",
"الوصف",
"الوصف (يساعد في البحث)",
0,
"تفاصيل",
"هل كنت تريد استخدام هذه القيمة؟",
"حالي مختلف",
"سابق مختلف",
0,0,0,
"استبعاد",
"عرض قيمة",
"عرض الكائن على الحائط",
0,0,0,
"تم",
"تم!",
"تحرير",
"آخر في حالة",
"البريد الإلكتروني",
0,
"البريد الإلكتروني والإعلامات",
0,0,0,0,
"أدخل رمز الدعوة",
"أدخل هذه التعليمة البرمجية",
"أخطاء",
0,
"الأحداث",
0,
"مثال: ",
0,
"ممتاز؛ عمل رائع؛ جميل؛ جيد؛ مبهر؛ متقن؛ استثنائي؛ مكتمل؛ صحيح",
0,
"إنهاء",
"خبير",
0,
"تصدير",
"تصدير تمثيل JSON للمحتويات",
"تم التصدير من هذه المكتبة",
"توسيع",
0,
"تحديد إضافي في الدالة",
0,
"استخراج إلى متغير",
"بحث عن مراجع",
"انتهى",
"الإصلاح",
"متابعة البرنامج التعليمي في المحرر",
"للمجموعة",
"روافع شوكية",
"الدالة",
"اسم الدالة",
"أنواع الدالة",
"الدالة، المتغير، المكتبة، ...",
"النوع الاجتماعي",
"الحصول على شهادة Hour of Code™ الخاصة بي",
"للحصول على المؤقت الذي يتم تشغيله لكل إطار عرض.",
"مستخدم github",
0,
"استبدال عمومي",
"متغير عمومي",
"متغيرات عمومية",
"رجوع للخلف",
"العودة إلى الترميز! {0}★ للانتقال",
"رجوع للخلف...",
"انتقال إلى",
0,
"انتقال إلى الخطوة السابقة",
"الهدف:",
"المجموعة",
"المجموعات",
"قلوب",
"تعليمات",
0,0,
"السجل",
"مرحى! تم نشر برنامج النصي",
"كيف عرفت",
"أريد التشغيل على",
"™انتهيتُ من ساعة البرمجة",
"قصاصة الرمز الفنية: {0}",
0,
"إذا علقت، فاضغط على سطر الهدف",
0,0,0,0,
"استيراد قيم الحقل من كائن JSON",
0,0,0,
"في هذه الدالة",
"مذهل، سحري، إعجازي، إعجازي، آخذ للعقول، مدهش للعقول، معجز، متميز، نادر، مثير للإعجاب، أسطوري، خاص، دراماتيكي، مروع، فاتن، رائع بشكل فائق، ",
0,
"إدراج",
"إدراج تعليق",
"إدراج عبارة",
"إدراج {0}",
"أفكار",
0,
"تثبيت البرنامج النصي وتحميله",
"إلى محلي",
0,
"المشكلات",
"الانضمام إلى مجموعة",
"انضمام إلى المجموعة",
0,
"واصل كتابة مصطلحات البحث!",
"واصل التحرير",
"معرفة هنا كـ:",
0,
"تعلّم",
"معرفة المزيد عن عملية النشر",
"معرفة المزيد",
"معرفة المزيد حول {0}",
"مغادرة البرنامج التعليمي",
"لنقم بتغيير ذلك",
"لنقم بذلك!",
"لنبدأ",
"مكتبة",
"مكتبات",
"مكتبة",
"اسم المكتبة",
"مرجع المكتبة",
"تحميل المزيد",
"تحميل المزيد من الردود",
"جارِ التحميل",
0,
"جارٍ تحميل التعليقات لـ /{0}...",
0,
"جارٍ تحميل الردود...",
"تحميل البرنامج النصي",
"تحميل البرنامج التعليمي",
"جارِ التحميل...",
"محلي",
"الموقع",
0,
"رفض منطقي",
"سجلات",
"رئيسي",
0,
"منشئون",
"إدارة البيانات",
"ربما في وقت لاحق",
"أنا",
0,0,
"مستخدم minecraft",
0,0,
"المزيد",
"المزيد ",
"مزيد من الإعدادات",
"تحريك المؤشر",
"تحريك لليسار",
"تابع إلى الخطوة التالية",
"تحريك المؤشر لليسار",
"تحريك المؤشر لليمين",
"العمل الفني الخاص بي",
0,0,0,
"برامجي النصية",
"بحاجة إلى اسم مختلف هنا",
"بحاجة إلى سلسلة مختلفة هنا",
"بحاجة إلى حقل جديد هنا",
"بحاجة إلى معلمة",
"بحاجة إلى حذف ذلك",
"بحاجة إلى التحرير في مكان آخر",
"رفض",
0,0,0,0,
"سطر جديد",
0,0,0,
"عبارة جديدة أدناه",
"متغير جديد",
0,
"البرامج التعليمية التالية...",
"اللقب",
0,
"لم يتم نشر أي فن بواسطة هذا المستخدم",
"لا توجد تعليقات، المس لكتابة شيء ما!",
"لا توجد تفرعات شوكية، قم بتثبيت البرنامج النصي وتحريره وإعادة نشره لإنشاء تفرع شوكي!",
"لا توجد قلوب. يمكنك إضافة واحد منها بمجرد تثبيت البرنامج النصي!",
"لم يتم تحميل أي صورة حتى الآن",
0,0,
"لا توجد علامات، المس لإضافة البعض!",
0,0,0,
"إعلامات",
0,
"يمكنك الآن تحديد خاصية {0}; لا يقوم بأي شيء بنفسه",
"يمكنك الآن تحديد خاصية عليه",
"الرقم",
"إدخال الرقم",
"الكائنات",
"المهنة",
"لكائن",
"متوفر دون اتصال",
"موافق",
"حسنًا لنبدأ!",
"متصل",
0,
"أو انقر للحصول على المساعدة",
"أخرى",
"نظرة عامة",
0,
"صفحات",
0,
"تحليل نص البرنامج النصي",
0,
"لصق",
"إيقاف مؤقت",
0,
"بادئ لعبة فيزياء",
"اختيار قالب برنامج نصي...",
"صورة",
"اسم الصورة",
"اسم الصورة (4 أحرف كحد أدنى)",
"عنوان url للصورة",
"اللعب مرة أخرى",
"يرجى الانتظار",
"يرجى الانتظار...",
"مكونات إضافية",
"معاينة",
"طباعة",
0,
"خاص",
"دالة خاصة",
"ملف تعريف خاص",
"ملف تعريف",
"المعلومات البرمجية",
0,
"ترقية لبيانات",
0,
"اللقب العام",
"ملف تعريف عام",
"نشر",
"نشر إصدار مخفي",
0,
"تم النشر",
"تغييرات السحب",
"سحب لمستوى الحظر",
0,
"إعادة تشغيل",
"قراءة المزيد...",
"قراءة فقط",
"الاسم الحقيقي",
0,
"تلقي رسائل إخبارية على البريد الإلكتروني",
"تلقي إعلامات البريد الإلكتروني",
"اسم السجل:",
0,
"لوحة مفاتيح عادية",
"إعادة تحميل البرنامج النصي",
"إزالة",
0,
"إزالة صورة",
"إزالة الخلفية البيضاء (الأفضل للعروض ثنائية الأبعاد في الألعاب)",
0,
"إعادة تسمية",
"تكرار على أوقات",
"تكرار على المجموعة",
"تكرار أثناء",
"استبدال الكل في الدالة",
"استبدال الكل في البرنامج النصي",
"استبدال صورة",
"نسخ",
"نسخ ",
0,
"إبلاغ عن إساءة استخدام",
0,
"عودة إلى الإصدار المنشور",
0,
"إرجاع ",
"تشغيل",
"تشغيل الرئيسي",
0,
"تشغيل من خلال الأدوات",
"حفظ",
"تم الحفظ",
"يتم الآن الحفظ...",
"المدرسة",
"شاشات",
"لقطة شاشة",
"لقطة شاشة لـ {0}",
"برنامج نصي",
"خصائص البرنامج النصي",
0,
"بحث",
"بحث في الفن",
"بحث في صور الفن",
"بحث هنا عن {0}",
"بحث في القوالب",
"جارِ البحث...",
"عرض المزيد من الخيارات",
"تحديد",
"تحديد المزيد",
"تحديد هذا السطر",
"تحديد نوع هذا {0}",
0,0,
"تعيين اسم متغير محلي",
"تعيين اسم",
"تعيين المعالج الذي يتم استدعاؤه عند تمرير اللوحة",
"تعيين المعالج الذي يتم استدعاؤه عند الضغط على اللوحة",
"تعيين المعالج الذي يتم استدعاؤه عند لمس اللوحة",
"تعيين المعالج الذي يتم استدعاؤه عند تحرير لمس اللوحة",
"تعيين كل الحقول على قيمها الافتراضية",
"تم حفظ الإعداد",
"إعدادات",
"مشاركة",
0,
"إظهار كيفية إكمال هذا النشاط",
"إظهار المزيد من الخيارات",
"عرض الحالة",
"تسجيل الدخول",
0,0,
"تسجيل الخروج",
"يتم الآن تسجيل الدخول...",
0,
"تبسيط",
"تم حفظ مستوى المهارة",
"تخطي التكرار",
0,
"مواقع التواصل الاجتماعي",
0,
"صوت",
0,
"قصاصة شاشة البدء: {0}",
"تقسيم",
0,
"البدء مرة أخرى",
"بدء البرنامج النصي",
"جارِ البدء...",
0,
"دخول",
"خروج",
"تخطي",
0,
"إيقاف",
0,
"إيقاف الدالة",
"إيقاف الحلقة",
"تخزين في متغير",
"تخزين القيمة في متغير",
"سلسلة",
0,
"شريط \\\"{0}\\\"",
0,0,
"اشتراكات",
"فائق، غير عادي، مرعب، لا يصدق، خارق للعادة، فريد، غير مسبوق، غير عادي، غريب، رائع، مدهش",
"إحاطة بـ",
0,0,
"جارٍ المزامنة...",
0,0,0,0,0,
"علامات",
0,0,
"اضغط على (←) عندما تنتهي",
"اضغط على [موافق] عندما تنتهي",
0,
"اضغط هنا للانتقال إلى الخطوة التالية",
"اضغط هنا عندما تنتهي",
"اضغط هناك",
"الضغط هناك للحصول على تعليمات",
"اضغط هناك لتشغيل تطبيقك",
"الضغط لتغيير اللون",
"اضغط لتغيير صورة الرمز",
"اضغط لتغيير شاشة البدء",
"اضغط للترجمة مع Microsoft ® مترجم...",
"مؤقت",
"terms of use",
"اختبار",
"دالة اختبار",
"اختبارات",
"اختبار ما إذا كان هناك مرجعان يشيران إلى نفس الكائن",
0,0,
"الموزع",
"يجب أن يكون رمز الدعوة رقمًا يتراوح طوله بين 9 و64 حرفًا",
"تعطل البرنامج النصي",
0,0,
"هذا البرنامج النصي عبارة عن مكتبة",
"هذا البرنامج النصي عبارة عن خدمة ويب",
0,
"إلى رمز",
"للمتابعة",
"لمتغير عمومي",
"تبديل نقطة التوقف",
"الأفضل والجديد",
0,0,
"ترجمة",
"ترجمة البرنامج التعليمي...",
0,0,0,
"حاول مرة أخرى!",
"تحويل إلى",
"تقدم البرنامج التعليمي",
"البرنامج التعليمي: ",
"برامج تعليمية",
"الاسم على twitter",
"النوع: ",
"النوع: {0}",
0,0,0,
"تراجع",
0,0,0,0,0,0,0,0,0,0,
"تحديث",
0,0,0,0,0,0,
"تحميل",
"تحميل الصورة",
"تحمين لقطة شاشة",
"تحميل صوت",
0,0,0,
"url عنوان",
0,0,0,0,0,
"اسم المتغير",
"عرض كبرنامج نصي",
"عرض/تحرير الاسم، البريد،...",
0,
"خلفية الشاشة",
"لدينا مكتبة \\\"{0}\\\" هنا; {1}",
"لدينا {0:a} هنا؛ هل كنت تريد أن تفعل به شيئًا ؟",
"نحتاج إلى حقل جديد",
"نحتاج إلى جدول جديد",
"نحتاج إلى الجديد من {0}",
"نحتاج للوحة مفاتيح مختلفة",
"نحتاج إلى متغير جديد",
"نحتاج لتحرير شيء آخر",
"سنقوم بتوجيهك خطوة بخطوة",
"تطبيقات ويب",
0,0,0,
"موقع الويب",
0,
"عنوان url الخاص بموقع الويب",
0,0,0,0,0,
"تاريخ الميلاد",
0,0,
"لقد قمت بذلك بنجاح!",
0,
"{0} ({1} سطر{1:s})",
"منذ {0} يوم{0:s}",
"{0} إلى أسفل",
0,0,0,
"منذ {0} عام{0:s}",
"منذ {0} دقيقة{0:s}",
"منذ {0} شهر{0:s}",
"تم الانتهاء من {0} من {1}",
"{0} نشر",
"تم نشر {0} برنامج نصي",
"منذ {0} ثانية{0:s}",
"{0} لأعلى",
"منذ {0} عام{0:s}"
]); return true; }

if (lang == "cy") { TDev.Util._setLanguageArray(keys, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Creu Cod",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Dechrau arni",
0,0,0,
"Cymorth",
0,0,
"Cartef",
"Rheolau",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Fy sgriptiau",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Partneriaid",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Polisi preifatrwydd",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Chwilio...",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Allgofnodi",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Telerau defnyddio",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"fy sgriptiau",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"polisi preifatrwydd",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"tap yno",
0,0,0,0,0,0,0,
"telerau defnyddio",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"© Hawlfraint {0} {1}",
"● Mewngofnodi"
]); return true; }

if (lang == "de") { TDev.Util._setLanguageArray(keys, [
"   Vielleicht: {0} ({1} bei '{2}')\n",
"  -> Zeile {2} ('{1}'), Fehler: {0}\n{3}",
" -- Lokale Variable",
" [Klasse]",
" [ausgeblendet]",
0,
" Rückwärts",
" Vorwärts",
" Stunden ",
" Minuten ",
" von ",
" Sekunden ",
" Änderungen werden gesendet...",
0,0,
"Geschweifte Javascript-Klammern und alle Tools für erfahrene Entwickler!",
"'Atomische' Funktion",
0,0,0,0,
"'{0}' erwartet {1} hier",
0,0,0,
"„{0}“ ist ein Hindernis und sollte nicht verwendet werden.",
0,
"'{0}' gibt '{1}' zurück; {2}",
0,0,0,0,0,0,0,0,
", stattdessen {0} abgerufen",
", {0} abgerufen",
0,0,0,
"... wir haben noch mehr ...",
"// Kommentar",
0,0,0,0,
"4. Veröffentlichen",
0,0,0,0,0,0,0,0,0,
"<b>Diese Zeile ist perfekt!</b> Weiter geht's",
"<h3>Aktuelle Einstellungen werden geladen...</h3>",
"<h3>Keine weiteren Tipps!</h3>",
0,
"<h3>Für die Nutzung von {0:q} ist die Anmeldung erforderlich.</h3>",
0,0,0,0,0,0,
"Eine 2D Nummernmatrix",
"Ein 3D Vektor",
"Eine Bing Karte",
"Eine Minecraft Pi-App.",
"Eine Minecraft-App.",
"Eine Minecraft Creeper-App.",
0,0,0,0,0,0,0,0,0,0,
"Eine Farbkonstante",
0,0,
"Eine Berührung",
0,
"Ein Dokument",
0,0,0,0,
"Eine globale Variable",
0,0,0,0,0,0,0,0,0,0,0,
"Eine Zahl (negative und/oder Bruchzahl möglich)",
"Eine Zahlenkonstante",
0,0,0,
"Ein Bild",
"Ein Stück Text",
"Eine Pixel-Art-App.",
0,0,0,
"Ein Verweis auf ein Bibliotheksskript",
0,0,0,0,0,0,0,0,
"Ein Lied",
"Ton",
0,0,0,0,
"Struktur mit Benutzerdaten",
"Eine Tabelle mit benutzerdefinierten Zeilen",
0,0,0,0,0,
"Ein eindeutiger Anzeigename für Ihr öffentliches Profil (mindestens 8 Zeichen)",
0,0,
"Eine Benutzeroberfläche",
0,0,
"ADJ-Skript",
0,0,0,0,0,0,0,0,0,0,0,
"Fügen Sie eine Aktion hinzu, die für jeden Anzeigeframe ausgelöst wird",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Addiert Zahlen",
0,
"Fügt dem Punktestand Werte hinzu.",
0,0,
"Nachdem das Skript beendet wird, durchsuchen Sie den Code, um die gesammelten Informationen anzuzeigen.",
"Alle meine Gruppen",
"Alle meine Skripts",
0,0,0,0,0,0,0,
"Eine leere App mit Seiten und Feldern.",
"Eine leere App, für die die Scratch-Bibliothek verwendet wird.",
"Eine leere Dokumentationsseite.",
"Ein leeres interaktives Lernprogramm.",
"Ein leeres Skript-Editor-Plug-In.",
"Ein leeres Skript ohne Funktion.",
0,0,
"Eine indizierte Tabelle mit benutzerdefinierten Zeilen",
0,
"Eine Schildkröten-App.",
"Wendet `Konverter` auf alle Elemente der Eingabesammlung an und gibt eine Sammlung von Ergebnissen zurück",
0,
"Möchtest du das Lernprogramm wirklich nicht weiter ausführen?",
0,
"Grafiken dieses Benutzers:",
0,
"Daten an andere Objekte anfügen",
"Codebaustein zum Erstellen eines Spiels.",
0,0,0,0,0,0,
"Qualifikationsstufe ändern",
0,
"Überprüft, ob das Board die gleiche Instanz wie das andere Board aufweist.",
0,0,0,
"Alle Ereignisse in Warteschlange für dieses Board löschen",
"Hintergrundbild löschen",
"Hintergrundkamera löschen",
0,0,
"Code, der bei einer Benutzerinteraktion ausgelöst wird",
"Code, der eine bestimmte Aufgabe durchführt",
"Vergleicht Zahlen auf Gleichheit",
"Vergleicht Zahlen auf weniger",
0,
"Vergleicht Zahlen auf mehr",
0,0,0,0,0,0,0,
"Verkettet zwei Textstücke",
0,0,0,0,0,0,
"Konvertiert zur lokalen Zeit",
0,0,0,0,0,
"Gruppe erstellen",
"Skript erstellen",
"Erstelle ein Linienhindernis mit vorgegebenem Startpunkt und einer Breite und Höhe. In Bezug auf die Elastizität steht 0 für Haften und 1 für vollständiges Abprallen.",
"Erstelle eine neue Sammlung für Sprites.",
"Erstelle ein neues ellipsenförmiges Sprite.",
"Neues Bildsprite erstellen.",
"Erstelle ein neues rechteckiges Sprite.",
0,
"Erstelle ein neues Spritesheet.",
"Erstellen Sie eine neue Text-Sprite.",
"Erstelle eine Spirale zwischen den beiden Sprites.",
"Erstelle ein Anker-Sprite.",
"Einen ungültigen Wert dieses Objekttyps erstellen",
"Kanal erstellen",
"Erstellen Sie Sammlungen von Gegenständen.",
0,
"Erstelle im gewünschten Abstand Wände um das Board.",
"Erstellen Sie Ihre eigenen Apps",
0,0,
"Erstellt ein neues, leeres Gameboard und zeigt es auf dem Bildschirm an.",
0,0,0,
"Erstellt auf der Grundlage eines Bilds ein neues Sprite mit der Breite 100.",
0,
"Erstellt eine ungültige Gamepad-Instanz",
0,0,
"Aktuelles Gerät",
0,
"Aktueller Berührungspunkt",
"Trennt den Handler vom Ereignis.",
0,
"Zeigt das Bild an der Wand an; Sie müssen später 'An der Wand aktualisieren' aufrufen, wenn Sie die Änderungen übernehmen möchten.",
0,0,0,
"Zeigt den Status des Gamepads auf der Wand an",
0,
"Überlappen die Sprites",
0,
"Dokumente",
"Vergessen Sie nicht, einen Bildlauf nach unten auszuführen und auf „Speichern“ zu tippen, wenn Sie mit der Bearbeitung fertig sind!",
"Blöcke per Drag & Drop einfügen und eine übersichtliche Oberfläche – hervorragend für Anfänger geeignet!",
"Zeichnet eine Linie zwischen zwei Punkten",
"Zeichnet einen Textrand mit einer angegebenen Farbe und Schriftgröße",
"Code als Text bearbeiten und mehr Optionen – optimal für angehende App-Entwickler!",
0,0,
"Namen eingeben",
0,
"Geben Sie Informationen über sich selbst ein.",
"Geben Sie die URL zu Ihrer persönlichen Website ein (Beispiel: http://www.northwindtraders.com).",
"Einladungscode eingeben",
0,
"Für Ereignisse können keine out-Parameter angegeben werden.",
"Jeder kann dein Bild immer im Internet sehen. ",
0,0,
"Erweiterungen",
"Facebook",
"Füllt eine Ellipse mit einer angegebenen Farbe",
"Füllt ein Rechteck mit einer angegebenen Farbe",
"Letzte Berührungsgeschwindigkeit nach Berührungsende",
"Achten Sie bei veröffentlichen Skripts auch auf die Registerkarte der Seite für veröffentlichte Skripts, um anonym gesammelte Crowdsourcing- und Deckungsdaten zu finden.",
"Foren",
"Ab jetzt wird der zu schreibende Code nicht mehr angezeigt. Folgen Sie den Anweisungen, und tippen Sie auf „Ausführen“, wenn Sie soweit sind.",
"Funktionen im aktuellen Skript",
0,0,0,0,0,
"Erstellt eine Momentaufnahme der Gamepad-Zustände (bei Verbindung mit dem Browser). Ist leer, wenn keine Unterstützung vorhanden oder kein Gamepad angeschlossen ist.",
0,0,0,
"Ruft einen Wert ab, der angibt, ob das Board für die Anzeige im Querformat ausgelegt ist",
"Ruft einen Wert ab, ob das Lied DRM-geschützt ist",
"Ruft den x- und y-Wert der ausgewählten Achsen ab.",
0,0,
"Dient zum Abrufen der Hintergrundszene",
"Ruft die mittlere horizontale Position in Pixeln ab",
0,
"Ruft die Farbe mit dem ARGB-Wert '#00FFFFFF' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FF000000' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FF0000FF' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FF008000' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FF00FFFF' ab.",
0,
"Ruft die Farbe mit dem ARGB-Wert '#FF800080' ab.",
0,0,0,0,
"Ruft die Farbe mit dem ARGB-Wert '#FFFF0000' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FFFF00FF' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FFFFA500' ab.",
0,
"Ruft die Farbe mit dem ARGB-Wert '#FFFFFF00' ab.",
"Ruft die Farbe mit dem ARGB-Wert '#FFFFFFFF' ab.",
0,0,0,0,
"Verwendet das erste verfügbare Gamepad, das angeschlossen wird",
0,
"Ruft den Gamepad-Bezeichner ab",
0,
"Ruft die Höhe in Pixeln ab",
"Ruft die Höhe des Kamerabilds in Pixeln ab.",
0,0,0,0,0,0,0,0,0,
"Ruft den Player-Index ab",
"Ruft den Wert für das Drücken einer Schaltfläche ab. Gibt 0 zurück, wenn die Schaltfläche fehlt.",
0,
"Ruft die Lautstärke für Töne von 0 (leise) bis 1 (aktuelle Lautstärke) ab",
"Ruft die Sprite-Anzahl ab",
"Sprite wird nach „i“ indiziert",
0,
"Ruft den Zeitstempel dieser Momentaufnahme ab",
0,
"Ruft die Breite in Pixeln ab",
"Ruft die Breite des Kamerabilds in Pixeln ab.",
"Ruft die y-Position in Pixeln ab",
"Erste Schritte",
0,
"Globale Variablen im aktuellen Skript",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Im Debugmodus zeigt das Board die Geschwindigkeit und andere Infos zu Sprites an.",
"Gibt an, ob eine Schaltfläche gedrückt wurde. Gibt „false“ zurück, wenn die Schaltfläche fehlt.",
0,
"Gibt an, ob die Gamepad-Daten identisch sind",
"Gibt an, ob das Gamepad noch angeschlossen ist.",
0,0,0,0,
"{1} '{0}' einfügen",
0,
"Mit einem Sternchen (*) markierte Elemente sind erforderlich.",
"JSON-Daten",
"Gruppe beitreten",
"Letzter Berührungsendpunkt",
"Letzter Berührungsstartpunkt",
0,0,0,0,0,
"Macht Updates sichtbar.",
0,0,
"Sorgt dafür, dass alle Sprites an den Bildschirmrändern abprallen",
0,
"Mathematische Funktionen, abs, max, ...",
"Me",
0,
"Minecraft-Benutzer",
0,0,
"Bewegt ein Sprite zu einem anderen Sprite.",
"Multipliziert Zahlen",
0,0,0,0,0,0,0,0,
"Neue Skripts",
0,
"Neue oder integrierte Farben",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Wählt willkürlich eine Farbe aus.",
"Bilder und Musik...",
0,0,0,0,0,
"Lesen Sie unsere Datenschutzbestimmungen.",
0,
"Kommentar posten...",
0,0,0,
"Private Aktionen haben keine Ausführungsschaltfläche. ",
"Fordert Benutzer zur Eingabe einer Zahl auf",
0,
"Skript veröffentlichen",
0,
"Eine Veröffentlichung unterliegt unseren ",
"Skript wird veröffentlicht...",
"Wird ausgelöst, wenn die Wiedergabe der Animation beginnt",
"Wird ausgelöst, wenn die Wiedergabe der Animation endet",
"Liest den Antworttext als einen Wavesound",
"Erhalten Sie E-Mail-Benachrichtigungen, wenn andere Benutzer Ihre Skripts anzeigen/kommentieren bzw. einen Screenshot Ihrer Skripts erstellen, auf einen Ihrer Kommentare antworten oder wenn Ereignisse in Zusammenhang mit Ihrem Abonnement auftreten.",
"Denken Sie daran: Jeder kann Ihr Skript sehen, wenn Sie es veröffentlichen. Stellen Sie daher sicher, dass es weder Ihre Kennwörter noch andere persönliche Informationen enthält.",
"Entfernt den Wert vom aktuellen Leben.",
"Antworten...",
"Melden/Löschen",
"Passt die Bildgröße an die angegebene Größe in Pixel an",
0,
"Gibt eine Kopie des Bilds zurück",
0,0,
"Gibt ein Datum zurück, das dem Wert dieser Instanz eine bestimmte Anzahl von Monaten hinzufügt.",
"Gibt ein Datum zurück, das dem Wert dieser Instanz eine bestimmte Anzahl von Jahren hinzufügt.",
"Gibt eine zufällige ganze Zahl im Bereich zwischen „min“ und „max“ aus.",
0,0,0,0,0,0,0,
"Gibt \"wahr\" zurück, wenn die aktuelle Instanz nutzlos ist",
0,0,0,0,
"Skript-Updates",
"Skripts von diesem Benutzer:",
0,0,
"Code suchen...",
"Durchsuchen",
"Hier suchen...",
0,0,
"Suchen...",
0,0,0,
"Mehr",
0,0,
"Schaltet den Farbverlauf ein oder aus.",
"Legt die affine 3x3-Matrixtransformation fest, die auf die Wand angewendet wird.",
0,
"Legt die Hintergrundkamera fest",
"Legt die Hintergrundfarbe fest.",
0,
"Legt das Hintergrundbild fest.",
"Legt die mittlere horizontale Position in Pixeln fest",
"Legt die aktuellen Lebenspunkte fest.",
"Legt die Standardreibung für Sprites auf einen Bruchteil des Geschwindigkeitsverlusts zwischen 0 und 1 fest",
"Legt die Höhe in Pixeln fest",
"Legt die Position in Pixeln fest",
0,
"Legt die Lautstärkestufe von 0 (leise) auf 1 (aktuelle Lautstärke) fest",
"Legt die Geschwindigkeit in Pixel/s fest.",
"Legt die Sprite-Farbe fest.",
"Legt den einheitlichen Beschleunigungsvektor für Objekte auf dem Board auf „Pixel/s^2“ fest",
0,0,
"Legt die Breite in Pixeln fest",
"Legt die Geschwindigkeit von \"x\" in Pixel/s fest",
"Legt die Beschleunigung von \"y\" in Pixel/s^2 fest",
"Legt die y-Position in Pixeln fest",
"Legt die Geschwindigkeit von \"y\" in Pixel/s fest",
0,
"Einstellungen",
"Du kannst es mit dieser URL teilen:",
"Fehler im Editor anzeigen, wenn das Skript APIs verwendet, die ein Ausführen auf diesen Plattformen verhindern.",
"Zeigt das Board auf der Wand an.",
0,
"Qualifikationsstufe: {0}     ",
0,0,0,0,0,
"Hält alle Frame-Timer an und löscht sie",
0,
"Subtrahiert Zahlen",
0,
"TD100: Hier {0} einfügen",
"TD101: '{0}' kann nicht gefunden werden",
"TD109: Zuweisen darauf nicht möglich",
"TD111: Zuweisen von {0} zu {1} nicht möglich",
"TD112: Ich kann die Eigenschaft '{0}' nicht auf {1} finden",
"TD115: Überzählige(r) Parameter an {0} übergeben",
"TD116: Nicht genügend Parameter für {0} angegeben",
"TD118: 'if'-Bedingung möchte {1}",
"TD119: Es ist etwas erforderlich, das durchlaufen werden kann.",
0,
"TD130: Gebundenes Element von 'for' möchte {1}",
"TD144: Scheinbar fehlt Ihnen '{0}'. Versuchen Sie das hinzuzufügen",
"TD145: Es scheint hier ein Operator (z. B. '+', '('or',') zu fehlen",
"TD147: Wir haben '{0}' hier nicht erwartet",
"TD150: Element vor '(' kann nicht abgerufen werden.",
"TD151: '(' nicht geschlossen",
"TD152: unerwartet ')'",
"TD154: Hinter dem Operator muss etwas stehen",
"TD155: '{0}' kann keiner lokalen Variable zugewiesen werden.",
"Unterrichten Sie Creative Coding!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Das Skript verwendet die folgenden Fähigkeiten: ",
0,
"Dieses Tutorial enthält Clouddaten, die mit anderen Benutzern geteilt werden.",
"Um Seitendaten hinzuzufügen, erstellen Sie eine lokale var, und tippen Sie auf 'Auf Feld hochstufen'-",
0,0,0,0,
"Übersetzungen von Microsoft® Translator. Tippen, um Original anzuzeigen...",
"Wahr bei Berührung des Boards",
"Ändern Sie den Code, bis er richtig ist. Wenn Sie nicht weiterkommen, tippen Sie auf die Tutorialleiste.",
0,0,
"Anleitungen",
"Twitter",
"Text eingeben, um online zu suchen...",
"Eingeben, um zu suchen...",
0,
"Die Typen, die Reihenfolge und die Anzahl der Ereignisparameter können nicht bearbeitet werden.",
"UI-Widget",
0,
"Aktualisiere die Positionen der Sprites im Board.",
"Aktualisiert das Bild auf einem Bildsprite (wenn es ein Bildsprite ist)",
"Aktualisiert Text auf Textsprite (wenn Textsprite)",
"Bild hochladen",
"Klang hochladen",
"Benutzer",
0,
"Mehr Optionen erforderlich",
"Der Editor wird gemäß Ihrer Qualifikationsstufe im Programmierbereich angepasst. Sie können Ihre Qualifikationsstufe später im Hub ändern.",
"Über welche Qualifikationsstufe verfügen Sie im Programmierbereich?",
"Was ist Ihr Beruf?",
"Was ist neu",
"Wo befinden Sie sich?",
"Schreibt ein anderes Bild an einem angegebenen Speicherort. Die Deckkraft reicht von 0 (transparent) bis 1 (opak).",
0,
"YouTube",
0,0,
"Ihr GitHub-Benutzer.",
"Ihr Minecraft-Benutzer",
"Ihre Kunst wird hier angezeigt",
0,
"Ihr Kanal wird hier angezeigt.",
"Ihre E-Mail-Adresse wurde noch nicht überprüft. Überprüfen Sie Ihren Posteingang.",
"Ihr vollständiger Name",
0,0,0,
"Ihr Skript wird hier angezeigt",
"Ihr Twitter-Name wie etwa „@touchdevelop“.",
"Vor einigen Sekunden",
"eine Funktion",
"Eine globale Variable",
"Vor einer Minute",
"Eine Seite",
"Über Deckung",
"Über Einblicke",
"Über Profile",
"Persönliche Infos",
"Missbrauch",
0,
"Missbrauchsmeldungen",
0,0,0,
"Auf Feld '{0}' zugreifen",
0,
"Hinzufügen",
"Neu hinzufügen ...",
0,
"Aktion hinzufügen, die für jeden Anzeigeframe ausgelöst wird.",
0,0,0,0,0,
"Eingabeparameter hinzufügen",
"Zeile oben hinzufügen",
"Zeilen unterhalb hinzufügen",
"Neu hinzufügen",
0,0,
"Ausgabeparameter hinzufügen",
0,0,0,0,0,
"Alle APIs",
"Zulassen",
"erstaunlich, verblüffend, beeindruckend, atemberaubend, eindrucksvoll, klassisch, toll, eigenartig, besonders, außergewöhnlich, exklusiv, ungewöhnlich, fabelhaft, fantastisch, herrlich, großartig, ",
0,
"Die Definition eines Funktionstyps",
"Vor einer Stunde",
0,0,0,0,0,
"Apps",
0,
"Kunst",
"Kunst-Ressource",
"Zuweisung",
0,
"Autor",
0,0,
"Zurück",
0,
"Rücktaste",
"Mit Rücktaste löschen",
0,0,
"Basis",
"Anfänger",
"Anfänger",
0,
"Bindung an Skript:",
"Leer",
"Leere App",
"Leerer Creeper",
"Leere Dokumente",
"Leeres Spiel",
"Leeres Minecraft",
"Leeres Minecraft Pi",
"Leere Pixel-Art",
"Leeres Scratch-Element",
"Leeres Skript-Plug-In",
"Leere Schildkröte",
"Leeres Lernprogramm",
"In Debugger unterbrechen",
"Haltepunkt",
0,0,0,0,0,0,
"Abbrechen",
0,0,
"Auf lokal (zurück) ändern",
"Inhalte ändern",
"Kanäle",
"Überprüft, ob kein Verweis festgelegt wurde.",
0,0,0,
"Bild auswählen (weniger als 1 MB, kleiner als 2048x2048)",
0,0,0,0,0,0,
"Qualifikationsstufe im Programmierbereich auswählen",
"Auswählen...",
0,
"Löschen",
"Zwischenablage",
"Klonen",
0,
"Cloud-Sitzungen",
"Code",
"Ziellinie codieren",
"Programmierer",
"Farbe #{0}",
"Farbe: {0}",
"Auskommentieren",
"Kommentare",
0,
"Bedingung",
"verbunden",
0,0,
"Fortsetzen",
0,
"Kopieren",
"Auswahl kopieren",
"Abdeckung",
"Erstellen",
"Einen neuen Parameter erstellen",
0,0,0,0,
"Erstellt eine leere Sammlung mit Objekten",
"Skript erstellen",
0,
"Aktueller Ausdruck",
"Passen Sie die Kunst an!",
"Ausschneiden",
"Auswahl ausschneiden",
"Datenbank",
"Debuggen",
"Dezimalzeichen",
0,
"Löschen",
"Lokale Daten und Berechtigungen löschen",
"Auswahl löschen",
"Auf var tiefer stufen",
"Verweigern",
"Beschreibung",
"Beschreibung (Hilfe für Suche)",
0,
"Details",
"Sollte dieser Wert verwendet werden?",
"Differenz (aktuell)",
"Differenz (vorher)",
0,0,0,
"Verwerfen",
"Anzeigewert",
"Zeigt das Objekt an der Wand an.",
0,0,0,
"fertig",
"Fertig",
"Bearbeiten",
"else if",
"E-Mail",
0,
"E-Mail- und Pushbenachrichtigungen",
0,0,0,0,
"Einladungscode eingeben",
"Diesen Code eingeben",
"Fehler",
0,
"Ereignisse",
0,
"ex: ",
0,
"Exzellent, Großartige Leistung, Erstaunlich, Cool, Sie sind der Hammer, Gut gemacht, Hervorragend, Sie haben es drauf, Genau richtig",
0,
"Beenden",
"Experte",
0,
"Exportieren",
"Eine JSON-Darstellung der Inhalte exportieren",
"aus dieser Bibliothek exportiert",
"Erweitern",
0,
"Auswahl in Funktion extrahieren",
0,
"Zur var extrahieren",
"Verweis suchen",
"Fertig",
"Reparieren Sie's",
"Der Anleitung im Editor folgen",
"Für Gruppe",
"Verzweigungen",
"Funktion",
"Funktionsname",
"Funktionsarten",
"Funktion, Variable, Bibliothek, ...",
"Geschlecht",
"Hour of Code™-Zertifikat erhalten",
"Ruft den Timer ab, der für jeden Anzeigeframe ausgelöst wird.",
"GitHub-Benutzer",
0,
"Globales Ersetzen",
"Globale Variable",
"Globale Variablen",
"Zurück",
"Zurück zum Codieren! noch {0}★",
"Zurück...",
"Wechseln zu",
"Zur Liste von Dingen im Skript wechseln",
"zum vorherigen Schritt",
"Ziel:",
"Gruppe",
0,
"Herzen",
"Hilfe",
0,0,
"Verlauf",
"Hurra, dein Skript wurde veröffentlicht!",
"Wie gefunden",
"Ausführen auf",
"Ich bin mit meiner Hour of Code™ fertig.",
"Symbolgrafik: {0}",
"if",
"Wenn Sie nicht weiterkommen, tippen Sie auf die Ziellinie.",
0,0,0,0,
"Feldwerte aus einem JSON-Objekt importieren",
0,0,0,0,
"unglaublich, magisch, wundervoll, wunderbar, überwältigend, umwerfend, seltsam, phänomenal, bombig, irre, speziell, spektakulär, aufsehenerregend, cool, spitze, ",
0,
"Einfügen ",
"Kommentar einfügen",
"Anweisung einfügen",
"{0} einfügen",
"Einblicke",
0,
"Installieren und Laden des Skripts",
"In lokales Element",
0,
"Probleme",
"Gruppe beitreten",
"Gruppe beitreten",
0,
"Geben Sie einfach weitere Suchbegriffe ein!",
"Bearbeiten Sie weiter",
"Hier bezeichnet als:",
0,
"Lernen",
"Informationen zum Veröffentlichen",
"Mehr erfahren",
"erfahren Sie mehr über {0}",
"Lernprogramm verlassen",
"Das ändern wir.",
"Legen wir los!",
"Los geht's!",
"lib",
"Bibliotheken",
"Bibliothek",
"Bibliothekname",
"Bibliotheksverweis",
"Mehr laden",
"Weitere Antworten laden",
"Wird geladen",
0,
"kommentare für {0} wird geladen...",
0,
"Antworten werden geladen...",
"Skript wird geladen.",
"Tutorial wird geladen",
"Wird geladen...",
"Lokal",
"Ort",
0,
"Logische Negation",
"Protokolle",
"Hauptfunktion",
0,
"Makers",
"Daten verwalten",
"Vielleicht später",
"ich",
0,0,
"Minecraft-Benutzer",
0,0,
"Weitere",
"Mehr ",
"Weitere Einstellungen",
"Cursor bewegen",
"Nach links bewegen",
"Gehe zum nächsten Schritt",
"Cursor nach links bewegen",
"Cursor nach rechts bewegen",
"Meine Kunst",
0,0,0,
"Meine Skripte",
"Anderer Name erforderlich",
"andere Zeichenfolge erforderlich",
"Hier ist ein neues Feld erforderlich.",
"Parameter erforderlich",
"Muss gelöscht werden",
"Muss an anderer Stelle bearbeitet werden",
"Negation",
0,0,0,0,
"Neue Zeile",
0,0,0,
"Neue stmt unterhalb",
"Neue Variable",
0,
"Weitere Anleitungen...",
"Spitzname",
0,
"Von diesem Benutzer wurde keine Kunst veröffentlicht.",
"Keine Kommentare, tippen, um welche zu schreiben!",
"Keine Verzweigungen, Skript installieren, bearbeiten und neu veröffentlichen, um eine zu erstellen!",
"Keine Herzen, Sie können eins hinzufügen, indem Sie das Skript installieren!",
"Noch kein Bild geladen",
0,0,
"Keine Tags, tippen, um welche hinzuzufügen!",
0,0,0,
"Benachrichtigungen",
0,
"Jetzt können Sie eine Eigenschaft von {0} auswählen, es tut selbst nichts",
"Jetzt können Sie eine Eigenschaft dafür auswählen",
"zahl",
"Zahleneingabe",
0,
"Beruf",
0,
"Offline verfügbar",
"OK",
"OK, los geht's!",
"Online",
0,
"oder tippen für Hilfe",
"Andere",
"Überblick",
0,
"Seiten",
0,
"Analyse des Skripttexts",
0,
"Einfügen",
"Anhalten",
0,
"Starthilfe für Physikspiel",
"Skriptvorlage auswählen...",
"Bild",
"Bildname",
"Bildname (mindestens 4 Zeichen)",
"Bild-URL",
"Neues Spiel",
0,
"Bitte warten...",
"Plug-Ins",
"Vorschau",
"Drucken",
0,
"Privat",
"private Funktion",
"Privates Profil",
"Profil",
"Programmierkenntnisse",
0,
"Auf Daten höherstufen",
0,
"Öffentlicher Spitzname",
"Öffentliches Profil",
"Veröffentlichen",
"Veröffentlichen als ausgeblendet",
0,
"Veröffentlicht",
"Änderungen",
"Herausziehen, um Stufe zu blockieren",
0,
"Erneut ausführen",
"lesen Sie mehr...",
"Schreibgeschützt",
"Richtiger Name",
0,
"E-Mail-Newsletter erhalten",
"E-Mail-Benachrichtigungen erhalten",
"Name aufzeichnen:",
0,
"Normales Tastenfeld",
"Skript wird neu geladen",
"Entfernen",
0,
"Bild entfernen",
"Weißen Hintergrund entfernen (optimal für Spielesprites)",
0,
"Umbenennen",
"n Mal wiederholen",
"Auf Sammlung wiederholen",
"wiederholen während",
"Funktion „Alle ersetzen“",
"Alle in Skript ersetzen",
"Bild ersetzen",
"Repliziert",
"Repliziert ",
0,
"Missbrauch melden",
0,
"Veröffentlichte Version wiederherstellen",
"Zurück",
"Zurück ",
"Ausführen",
"„main“ ausführen",
0,
"Mit Instrumentation ausführen",
"Speichern",
"gespeichert",
"Wird gespeichert...",
"Schule",
"Bildschirme",
"Screenshot",
"Screenshot von {0}",
"Skript",
"Skripteigenschaften",
0,
"Suchen",
"Kunst durchsuchen",
"Kunstbilder durchsuchen",
"Hier suchen nach {0}",
"Suchvorlagen",
"Wird gesucht...",
"Weitere Optionen",
"Auswählen",
"Mehr auswählen",
"Diese Zeile auswählen",
"Typ für {0} auswählen",
0,0,
"Name der lokalen Variablen festlegen",
"Name festlegen",
"Lege den Handler fest, der beim Wischen auf dem Board aufgerufen wird",
"Legen Sie den Handler, der beim Tippen auf das Brett aufgerufen wird, fest",
"Lege den Handler fest, der beim Berühren des Boards aufgerufen wird",
"Lege den Handler fest, der beim Loslassen des Boards aufgerufen wird",
"Legt alle Felder auf die Standardwerte fest.",
"Einstellung gespeichert",
"Einstellungen",
"Freigeben",
0,
"Zeigen, wie diese Aktion fertiggestellt wird",
"Weitere Optionen anzeigen",
"Schaufenster",
"Anmelden",
0,0,
"Abmelden",
"Anmelden...",
0,
"Vereinfachen",
"Qualifikationsstufe gespeichert",
"Iteration überspringen",
0,
"Soziales",
0,
"Klang",
0,
"Begrüßungsbildschirm-Grafik: {0}",
"Trennen",
0,
"Von vorn beginnen",
"Skript wird gestartet",
"Wird gestartet...",
0,
"Schrittweise ausführen",
"Schrittweise ausführen beenden",
"Überspringen",
0,
"Anhalten",
0,
"Funktion beenden",
"Schleife beenden",
"In var speichern",
"Speichern Sie den Wert in einer Variablen",
"Zeichenfolge",
0,
"Streifen '{0}'",
0,0,0,
"überragend, unnormal, grandios, sagenhaft, überirdisch, einzigartig, beispiellos, ausgefallen, eigenartig, herrlich, traumhaft",
"Umgeben mit",
0,0,
"synchronisieren von...",
0,0,0,0,0,
"Tags",
0,0,
"Tippen (←), wenn fertig",
"Anschließend auf [ok] tippen",
0,
"Hier tippen, um zum nächsten Schritt zu gelangen",
"Anschließend hier tippen",
"Dort tippen",
"Für Anweisungen hier tippen",
"Dort tippen, um die Anwendung auszuführen",
"Tippen, um die Farbe zu ändern",
"Tippen, um das Symbolbild zu ändern",
"Tippen, um das Begrüßungsbildschirm-Bild zu ändern",
"Tippen, um mit Microsoft® Translator zu übersetzen...",
"Temporär",
"terms of use",
"Test",
"Testfunktion",
"Tests",
"Überprüft, ob sich zwei Verweise auf dasselbe Objekt beziehen.",
0,0,
"Der Hub",
"Der Einladungscode muss eine Zahl mit 9 bis 64 Zeichen sein",
"Skript abgestürzt",
0,0,
"Dieses Skript ist eine Bibliothek",
"Dieses Skript ist ein Webdienst.",
0,
"Zum Codieren",
"Fortsetzen",
"Zur globalen var",
"Breakpoint umschalten",
"Beste & Neueste",
0,0,
"übersetzen",
"Tutorial wird übersetzt...",
0,0,0,
"Versuchen Sie es erneut.",
"Umwandeln",
"Fortschritt in der Anleitung",
"Anleitung: ",
"Tutorials",
"Twitter-Name",
"Typ:",
"Typ: {0}",
0,0,0,
"Rückgängig",
0,0,0,0,0,0,0,0,0,0,
"Update",
0,0,0,0,0,0,
"Hochladen",
"bild hochladen",
"Screenshot hochladen",
"Klang hochladen",
0,0,0,
"URL",
0,0,0,0,0,
"Variablenname",
"Als Skript anzeigen",
"Name, E-Mail anzeigen/bearbeiten ...",
0,
"Hintergrundbild",
"Wir haben hier '{0}' eine Bibliothek; {1}",
"Wir haben hier {0:a}. Wolltest du dieses Element für eine Aktion verwenden?",
"Neues Feld erforderlich",
"Neue Tabelle erforderlich",
"Wir brauchen einen neuen {0}",
"Wir benötigen ein anderes Tastenfeld",
"Neue Variable erforderlich",
"Wir müssen noch etwas anderes Ändern",
"Wir leiten Sie Schritt für Schritt weiter",
"Web-Apps",
0,0,0,
"Website",
0,
"Website-URL",
0,0,0,0,0,
"Geburtsjahr",
0,0,
"Sie haben es geschafft!",
0,
"{0} ({1} Zeile{1:s})",
"Vor {0} Tag{0:s}",
"{0} unten",
0,0,0,
"vor {0} Stunde{0:s}",
"Vor {0} Minute{0:s}",
"Vor {0} Monat{0:s}",
"{0} von {1} fertig",
"{0} veröffentlichen",
"Das Skript {0} wurde veröffentlicht",
"Vor {0} Sekunde{0:s}",
"{0} hochladen",
"Vor {0} Jahr{0:s}"
]); return true; }

if (lang == "en-GB") { TDev.Util._setLanguageArray(keys, [
"{0}PBA",
"  -> Line {2} ('{1}'), error: {0}\n{3}part",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Search...",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"a function",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"add",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"dismiss",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"goal:",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"insert {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"more",
0,0,0,0,0,0,0,0,0,0,0,
"my scripts",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"run",
0,0,0,0,0,0,0,0,0,0,
"script",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"tap there"
]); return true; }

if (lang == "es") { TDev.Util._setLanguageArray(keys, [0,
"  -> Línea {2} ('{1}'), error: {0}\n{3}",
" -- una variable local",
" [class]",
" [oculto]",
" [override]",
" atrás",
" adelante",
" horas ",
" minutos ",
" de ",
" segundos ",
" enviando cambios",
" esperando por el servidor",
"### código fuente completo",
"Las llaves de Javascript, todas las herramientas, para desarrolladores con experiencia",
"función 'atomic'",
"'box' solo se puede acceder desde la página de visualización del código",
"'box' no se puede acceder en el modo de diseño HTML",
0,
"'html' sólo se puede acceder en el modo de diseño HTML",
"'{0}' espera {1} aquí",
"'{0}' tiene una firma no soportada",
"'{0}' no está implementada",
"'{0}' es obsoleto y no está implementado",
"'{0}' obsoleto, no debería utilizarse",
0,
"'{0}' devuelve un '{1}'; {2}",
"'{0}' devuelve valores de {1}; puede utilizar el botón 'store in var' para guardar a los locales",
"(Opcional) Un URI que identifica una página con información sobre el error, usado para proporcionar información adicional sobre el error, al desarrollador del lado del cliente.",
"(Opcional) Un código de error legible.",
"(Opcional) Pares adicionales de clave y valor no cubiertos por la especificación OAuth 2.0.",
"(Opcional) Indica si el token puede caducar dentro de los próximos segundos.",
"(Opcional) Opcional si es idéntico al alcance solicitado por el cliente; de lo contrario, el alcance del token de acceso según lo descrito por la sección 3.3 de la especificación de OAuth 2.0.",
"(Opcional) La duración en segundos del token de acceso.",
"(por favor espere, puede tardar hasta un minuto)",
", en su lugar, se obtuvo {0}",
", obtuvo {0}",
", tamaño: {0} caracteres",
". Por favor, lea nuestra ",
"... nada que ver aquí...",
"... hay más ...",
"// comentario",
"1. elegir un documento (.txt, .pptx, .pdf, .css, de menos de 8MB)",
"1. escoja un sonido MP3 (menos de 1MB)",
"2. dar un nombre (mínimos 4 caracteres)",
"3. describir",
"4. publicar",
":( Lo sentimos, ha ocurrido un error al traducir este texto.",
":( Lo sentimos, no se ha podido traducir esto.",
":( no pudo encontrar alguna fuente de vídeo",
":( no válido en la información de vídeo",
"; ¿le falta → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'>Apache Cordova</a> le permite construir aplicaciones móviles multiplataforma.",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> generar el certificado</a>.",
"<b>Descargo de responsabilidad:</b> Esta aplicación web no está avalada por Microsoft.",
"<b>cómo ejecutar localmente Touch Develop</b>",
"<b>¡una línea perfecta!</b> sigamos",
"<h3>cargando configuraciones actuales...</h3>",
"<h3>no más consejos!</h3>",
"<h3>bienvenido a Touch Develop</h3>",
"<h3>{0:q} requiere estar logueado</h3>",
"<p>Si no tienes una suscripción Azure, ir a <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> suscripciones Azure</a> para conseguir una.</p>",
"<p>Touch Develop le permite<b>crear aplicaciones fácilmente</b>desde su teléfono, tablet o PC.</p>",
"<p>Puedes compartir tus aplicaciones con otros, para que puedan ser <b>ejecutadas y editadas</b> en Windows Phone, iPad, iPhone, Android, PC o Mac.</p>",
"<strong>función en beta:</strong> la sintaxis y la semántica está sujeta a cambios",
"<strong>plataforma requerida:</strong>",
"@hi/lo fuera de alcance",
"Una matriz 2D de números",
"Un vector 3D",
"Un mapa de Bing",
"Una aplicación Minecraft Pi.",
"Una aplicación de Minecraft.",
"Una aplicación Minecraft creeper.",
"Un cliente que envía eventos al servidor",
"Una animación para animar las propiedades del sprite.",
"Un color argb (alfa, rojo, verde, azul)",
"Una capa de la escena de fondo",
"Un editor amigable para principiantes",
"Un tablero para crear juegos 2D",
"Un constructor para crear formularios de datos en HTML",
"Una sesión de datos en la nube",
"Una colección de objetos",
"Una colección de sprites",
"Una constante de color",
"Una combinación de fecha y hora",
"Se agregó un comentario sobre su pull request.",
"Un contacto",
"Un logger personalizado",
"Un documento",
"Un recurso de documento",
"Un {0} completamente replicado se guarda en un almacenamiento en la nube y es completamente amacenado en memoria caché de los clientes.",
"Una función atómica y genérica de conversión",
"Una geo coordenada (latitud, longitud,...)",
"Una variable global",
"Un grupo puede utilizarse para ejecutar una clase o un evento. Por favor no incluya el nombre de su escuela en el nombre del grupo.",
"Un controlador conectado a un evento.",
"Un creador de estructura de datos json",
"Una estructura de datos json.",
"Un enlace a un video, imagen, correo electrónico, número de teléfono",
"Un {0} local es automáticamente guardado en almacenamiento local, pero nunca compartido con otros dispositivos.",
"Mapa de cadenas a cadenas",
"Un mapa de números a los números",
"Un marcador de mapa",
"Una ubicación con nombre",
"Se ha producido un error de red. Su configuración de cuenta no ha sido almacenada ¿Estás desconectado?",
"Un número (posiblemente negativo o fracción)",
"Una constante numérica",
"Un botón de página en el muro",
"Una página en un muro",
"Un {0} parcialmente replicada se guarda en la nube y completamente en memoria caché en los clientes.",
"Una imagen",
"Un fragmento de texto",
"Una aplicación de diseño infográfico.",
"Un lugar para conectar una acción para ejecutar en respuesta a un evento",
"Una acción posiblemente atómica con un único argumento",
"Un comentario en un muro de mensajes",
"Una referencia a un script de biblioteca",
"Una referencia a un valor",
"Un {0} replicada es automáticamente guardado en la nube y compartido entre los dispositivos.",
"Una escena que contiene fondos con capas de parralax.",
"Se ha abierto una ventana separada con el cuadro de acceso, por favor acceda desde esa ventana.",
"Un {0} local del servidor se guarda en la nube y nunca en caché en los clientes.",
"Una definición de la firma de una función",
"Un único códigode error ASCII [USASCII].",
"Una instantánea del estado de gamepad",
"Una canción",
"Un sonido",
"Un efecto de sonido",
"Un resorte entre dos sprites.",
"Un sprite",
"Una hoja de sprites que agrupa varios fotogramas en una sola imagen",
"Una estructura de datos de usuario",
"Una tabla con filas definidas por el usuario",
"Una tarea creada con la palabra clave 'async'",
"Un {0} temporal es local en la conexión y desechado cuando la conexión termina.",
"No se guarda un {0} temporal entre ejecuciones.",
"Un cuadro de texto",
"Un contador de tiempo",
"Un nombre único para mostrar en su perfil público (al menos 8 caracteres)",
"Una prueba de unidad",
"Una cuenta de usuario",
"Una interfaz de usuario",
"Un web socket",
"Un mensaje de web socket",
"Script ADJ",
"Configuración de API",
"Nombre de la API",
"API no implementado",
"logo ARM",
"Se aborta la ejecución si la condición es falsa.",
"Acelerómetro",
"Acceso denegado: El navegador web y el sitio web evitan compartir recursos de origen cruzado (CORS).",
"Acceder a diversas propiedades del entorno de aplicación",
"Agregar un nombre de clase CSS para el elemento actual.",
"Añadir un nuevo botón. El icono debe ser el nombre de un icono incorporado, el texto no debe estar vacío.",
"Agregue una referencia a JsonBuilder en la matriz.",
"Agregar una acción que se desencadene para cada fotograma de la pantalla",
"Añadir un valor especificado a la referencia dada",
0,0,
"Añadir dos números de 32 bits firmados",
"Añadir dos números sin firma de 32 bits",
"Agrega un valor booleano",
"Agrega un valor numérico",
"Agrega una imagen",
"Añade un marcador de imagen en el mapa",
"Agrega un trozo de texto al formulario con un nombre personalizado o archivo.",
"Añade un marcador de lugar en el mapa (ignorar si no se establece la ubicación)",
"Agrega un valor de cadena",
"Añade un marcador de texto en el mapa",
"Agrega un valor al array.",
"Añade un vector",
"Agregar un objeto",
"Agrega muchos objetos a la vez",
"Suma números",
0,
"Agrega valor a la puntuación actual.",
"Ajustar {0}.",
"Avanzar el enumerador y devuelva true si existe otro elemento.",
"Después que se detiene el script, explora el código para ver la información recopilada.",
"Todos mis grupos",
"Todos mis scripts",
"Todas las opciones encendidas",
"Permitir la ejecución de otros eventos, antes de que termine el evento actual.",
"Le permite al usuario guardar la dirección de correo electrónico (email)",
"Permite al usuario que guarde el número de teléfono",
"Una solicitud HTTP de web",
"Una respuesta HTTP de web",
"Una acción atómica sin argumentos",
"Una aplicación vacía usando páginas y casillas.",
"Una aplicación vacía usando la biblioteca temporal.",
"Una página de documentación vacía.",
"Un tutorial interactivo vacío.",
"Un complemento del editor de script vacío.",
"Un script vacío que no hace nada.",
"Un enumerador general",
"Una solicitud entrante HTTP de web",
"Una tabla indexada con filas definidas por el usuario",
"Una interfaz para el editor de TouchDevelop",
"Una aplicación de tortuga.",
"Aplica `converter` a todos los elementos de la colección de datos de entrada y devuelve una colección de resultados",
0,
"¿Está seguro de que quiere dejar de seguir el tutorial?",
0,
"Artículos por este usuario:",
"Pedir o mostrar los valores en la pared...",
"Adjuntar datos a otros objetos",
"Código repetitivo para crear un juego.",
0,0,
"Camara",
"Ubicación, micrófono, cámara y otros sensores",
0,
"Cambiar configuración...",
"¡Cambiar nivel de aptitud!",
"Canales",
"Verifica si el panel está en la misma instancia que el otro panel.",
0,0,0,
"Borrar todos los eventos en proceso relacionados con esta placa",
"Borrar la imagen de fondo",
"Borrar la cámara de fondo",
0,0,
"Código que aparece cuando se produce una interacción del usuario",
"Código que realiza una tarea específica",
"Compara números según igualdad",
"Compara números según menor",
0,
"Compara números según mayor",
0,0,0,0,0,0,0,
"Concatena dos fragmentos de texto",
0,0,0,0,0,0,
"Convierte a la hora local",
0,0,
"Ayudantes de corrección",
0,0,
"Crear grupo",
"Crear script",
"Crea un obstáculo de línea con un punto inicial dado o un ancho y un alto dados. La elasticidad es 0 para la adhesión y es 1 para un rebote completo.",
"Crea una nueva colección para los sprites.",
"Crea un nuevo sprite de elipsis.",
"Crear una imagen sprite nueva.",
"Crea un nuevo sprite de rectángulo.",
0,
"Crea una nueva hoja de sprite.",
"Crear un nuevo sprite de texto.",
"Crea un salto entre los dos sprites.",
"Crea un sprite delimitador.",
"Crear un valor no válido de este tipo de objeto",
"Crear canal",
"Crear colecciones de objetos.",
"Crear valores no válidos",
"Crea muros alrededor del tablero a una distancia dada.",
"Crea tus propias aplicaciones",
0,0,
"Crea un nuevo tablero de juego vacío y lo muestra en la pantalla.",
0,0,0,
"Crea un nuevo sprite de 100 de ancho con la imagen dada.",
0,
"Crea una instancia no válida del controlador para juegos",
0,
"Elemento actual de la caja en la página.",
"Dispositivo actual",
0,
"Punto táctil actual",
"Desasocia el controlador del evento.",
0,
"Muestra la imagen en el muro; debes llamar a 'actualizar en el muro' posteriormente si quieres que se vean reflejados los cambios.",
0,0,0,
"Muestra el estado del controlador para juegos en la pared",
"Divide números",
"¿Se solapan los sprites?",
0,
"Documentos",
"Recuerde desplazarse hacia abajo y presionar “guardar” al terminar la edición.",
"Arrastre y suelte bloques, interfaz simplificada, ¡perfecto para principiantes!",
"Dibuja una línea entre dos puntos",
"Dibuja borde de texto en un color y tamaño de fuente determinados",
"Edite el código como texto, más opciones, para quienes aspiran a ser escritores de aplicaciones.",
"Mensajes de correo electrónico, sms, contactos, calendario...",
0,
"Escribir un nombre",
0,
"Introduzca alguna información sobre usted",
"Introduzca la URL de su sitio web personal (ejemplo: http://www.northwindtraders.com)",
"Ingresar el código de invitación",
0,
"No se puede tener parámetros out en estos eventos.",
"Todos podrán ver la imagen en Internet por siempre. ",
0,0,
"Extensiones",
"Facebook",
"Rellena una elipse en un color determinado",
"Rellena un rectángulo en un color determinado",
"Velocidad táctil final después de haber finalizado la función táctil",
"Para los scripts publicados, consulta también la pestaña en la página del script publicado para buscar un perfil y cobertura recopilados por \\\"crowdsourcing\\\" de forma anónima",
"Foros",
"Ya no te mostraremos el código que tienes que ingresar. Sigue las instrucciones y toca Ejecutar cuando creas que hayas terminado.",
"Funciones definidas en el script actual",
0,0,0,0,0,
"Obtiene una instantánea de los estados del controlador para juegos (si alguno está conectado al navegador). Vacío si el controlador no es compatible o no hay ningún controlador para juegos conectado.",
0,0,0,
"Obtiene un valor que indica si la placa está diseñada para ser vista en el modo de panorama",
"Obtiene un valor que indica si la canción está protegida por DRM",
"Obtiene el valor x e y de los ejes seleccionados.",
0,0,
"Obtiene la escena de fondo",
"Obtiene la posición horizontal central en píxeles",
0,
"Obtiene el color que tiene el valor ARGB de #00FFFFFF",
"Obtiene el color que tiene el valor ARGB de #FF000000",
"Obtiene el color que tiene el valor ARGB de #FF0000FF",
"Obtiene el color que tiene el valor ARGB de #FF008000",
"Obtiene el color que tiene el valor ARGB de #FF00FFFF",
0,
"Obtiene el color que tiene el valor ARGB de #FF800080",
0,0,0,0,
"Obtiene el color que tiene el valor ARGB de #FFFF0000",
"Obtiene el color que tiene el valor ARGB de #FFFF00FF",
"Obtiene el color que tiene el valor ARGB de #FFFFA500",
0,
"Obtiene el color que tiene el valor ARGB de #FFFFFF00",
"Obtiene el color que tiene el valor ARGB de #FFFFFFFF",
0,0,0,0,
"Obtiene el primer controlador para juegos conectado disponible",
0,
"Obtiene el identificador del controlador para juegos",
0,
"Obtiene el alto en píxeles",
"Obtiene el alto de la imagen de la cámara en píxeles.",
0,0,0,0,0,0,0,0,0,
"Obtiene el índice del reproductor",
"Obtiene el valor presionado de un botón. Devuelve 0 si falta el botón.",
0,
"Obtiene el volumen del sonido para sonidos comprendidos de 0 (silencio) a 1 (volumen actual)",
"Obtiene la cantidad de sprites",
"Obtiene el sprite con índice i",
0,
"Obtiene la marca de tiempo de esta instantánea",
0,
"Obtiene el ancho en píxeles",
"Obtiene el ancho de la imagen de la cámara en píxeles.",
"Obtiene la posición de y en píxeles",
"Empezar",
0,
"Variables globales en el script actual",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"En el modo de depuración, el panel muestra la velocidad y otra información sobre los sprites",
"Indica si un botón se presiona. Devuelve false si falta el botón.",
0,
"Indica si los datos del controlador para juegos son idénticos",
"Indica si el controlador para juegos aún está conectado.",
0,0,0,0,
"Insertar '{0}' {1}",
"Interactuar con el tiempo de ejecución de la aplicación",
"Los elementos marcados con * son obligatorios.",
"Datos JSON",
"Unirse a un grupo",
"Último punto final táctil",
"Último punto inicial táctil",
0,0,0,0,0,
"Permite visualizar las actualizaciones.",
0,0,
"Hace que el sprite rebote en el borde la pantalla",
"Mapas, ubicación, dirección, dirección de ubicación",
"Aptitud de las matemáticas, abs, máx, ...",
"Me",
0,
"Usuario de Minecraft",
"Más",
"Movimiento",
"Mueve el sprite hacia otro sprite.",
"Multiplica números",
"Música y sonidos",
"Mis grupos",
"Mi perfil",
"Mis Scripts",
"NUEVO",
"NFC",
"Necesita alguna razón.",
"Red",
"Nuevos scripts",
"Nuevo mensaje de {0} en {1}",
"Colores nuevos o integrados",
"No puede hacer",
0,0,0,
"Vaya, el nombre es muy corto...",
"Vaya, el nombre de la foto es demasiado corto...",
"Vaya, el nombre del sonido es demasiado corto...",
"Vaya, hubo un error al cargar la imagen.",
"Vaya, no podemos tomar una captura de pantalla ahora",
"Vaya, no podemos tomar una captura de pantalla ahora.",
0,0,0,
"Socios",
"Números de teléfono, vibración, etc....",
0,
"Escoge un color aleatorio",
"Fotos y música...",
0,
"Reproducir, detener o reanudar canciones...",
0,0,0,
"Revise nuestra Declaración de privacidad.",
"espera...",
"Publicar un comentario...",
0,0,0,
"La acción privada no tiene un botón de ejecutar. ",
"Solicita al usuario que ingrese un número",
0,
"Publicar guión",
0,
"La publicación está sujeta a nuestras ",
"Publicar script...",
"Se elevó cuando la animación comenzó a mostrarse",
"Se elevó cuando la animación dejó de mostrarse",
"Lee el cuerpo de la respuesta como archivo de sonido",
"Recibir notificaciones de correo electrónico cuando otras personas revisen/tomen una captura de pantalla de sus scripts o respondan a uno de sus comentarios, o cuando ocurran eventos relacionados con sus suscripciones.",
"Recuerde: todos podrán ver el script si lo publica; por lo tanto, asegúrese de que no contenga las contraseñas o la información personal.",
"Quita el valor de la vida actual.",
"Responder...",
"Informar/eliminar",
"Cambia el tamaño de la imagen según el tamaño en píxeles especificado",
0,
"Devuelve una copia de la imagen",
0,0,
"Devuelve una fecha que agrega el número especificado de meses al valor de esta instancia.",
"Devuelve una fecha que agrega el número especificado de años al valor de esta instancia.",
"Devuelve un número integral aleatorio entre el \"mín.\" y el \"máx.\" incluidos.",
0,0,0,0,0,0,0,
"Devuelve TRUE si la instancia actual es inservible",
0,0,0,
"Escalas del sprite",
"Actualizaciones de script",
"Scripts por este usuario:",
"Buscar",
"Buscar y navegar por la web...",
"Buscar código...",
"Buscar todo",
"Buscar aquí...",
"Buscar números de teléfono cerca de un lugar usando Bing. Distancia en metros, negativas a ignorar.",
"Buscar números de teléfono con Bing",
"Buscar...",
"Buscar imágenes usando Bing",
"Buscar noticias cerca de un lugar usando Bing. Distancia en metros, negativas a ignorar.",
"Buscar noticias con Bing",
"Ver más",
0,0,
"Enciende o apaga la gradiente",
"Establece la transformación afín de matriz 3x3 que se aplica al muro.",
0,
"Establece la cámara de fondo",
"Establece el color de fondo",
"Establece el color de fondo.",
"Establece la imagen de fondo",
"Establece la posición horizontal central en píxeles",
"Fija los puntos de vida actuales.",
"Establece la fricción predeterminada para los sprites a una fracción de la pérdida de velocidad entre 0 y 1",
"Establece el alto en píxeles",
"Establece la posición en píxeles",
0,
"Establece el nivel del volumen del sonido de 0 (silencio) a 1 (volumen actual)",
"Establece la velocidad en píxeles/s",
"Establece el color del sprite.",
"Establece el vector de aceleración uniforme para los objetos en el panel a píxeles/seg.^2",
0,0,
"Establece el ancho en píxeles",
"Establece la velocidad de x en píxeles/seg",
"Establece la aceleración de y en píxeles/seg^2",
"Establece la posición de y en píxeles",
"Establece la velocidad de y en píxeles/seg",
0,
"Configuración",
"Comparátelo con esta url:",
"Mostrar errores en el editor si el script usa API que evitan que se ejecute en estas plataformas.",
"Muestra el panel en el muro.",
0,
"Nivel de aptitud: {0}     ",
0,0,0,0,0,
"Detiene y borra todos los temporizadores de fotogramas",
0,
"Resta números",
"Soporte para tutoriales interactivos.",
"TD100: insertar {0} aquí",
"TD101: no puede encontrar '{0}'",
"TD109: no se puede asignar a esto",
"TD111: no se puede asignar de {0} a {1}",
"TD112: no puedo encontrar la propiedad '{0}' en {1}",
"TD115: se han proporcionado demasiados parámetros a {0}",
"TD116: no se han suministrado suficientes parámetros a {0}",
"TD118: la condición 'if' pide {1}",
"TD119: necesito algo en qué iterar",
0,
"TD130: el enlace de 'for' pide {1}",
"TD144: parece que te falta '{0}', intenta añadirlo",
"TD145: parece que aquí falta un operador (como '+', '(' o ',')",
"TD147: no esperábamos ver a '{0}' aquí",
"TD150: no puede llamar a la cosa antes '('",
"TD151: sin cerrar '('",
"TD152: inesperado ')'",
"TD154: hay algo que tiene que ir detrás del operador",
"TD155: no se puede asignar '{0}' a una variable local",
"Dicte Creative Coding.",
"Servicios de tecnología de",
"Condiciones de Uso",
0,0,
"La url del documento",
"La imagen codificada es demasiado grande.",
"La cámara frontal o trasera",
"El grupo tiene nuevo dueño",
0,0,
"Este comando requiere un proxy local.",
"Este grupo está bloqueado.",
"Este grupo está abierto.",
"Este script es actual.",
"Este script le falta el encabezado.",
"Este script le falta la fuente.",
"Este script utiliza las siguientes capacidades que pueden faltar en tu dispositivo actual: {0}",
"Este script usa las siguientes capacidades: ",
0,
"Este tutorial usa datos en la nube que se comparten con otros usuarios.",
"Para agregar datos a la página, crea una variable local y pulsa 'promocionar a campo'.",
0,0,
"Traducción",
"Traducción, discurso al texto...",
"Traducciones hechas por Microsoft ® Translator, pulse para ver original...",
"True si se toca el panel",
"Intenta modificar el código hasta que sea correcto. Si te atascas, toca la barra del tutorial.",
"Tratando de llegar a servidor",
"Tutorial terminado",
"Tutoriales",
"Twitter",
"Escribir para buscar en línea...",
"Escribir para búsqueda...",
0,
"No se pueden editar los tipos, el orden y el número de parámetros del evento.",
"Widget de interfaz de usuario",
"URL: {0}",
"Actualiza las posiciones de sprites en el panel.",
"Actualiza la imagen como imagen sprite (si es una imagen sprite)",
"Actualiza el texto como sprite de texto (si se trata de un sprite de texto)",
"Cargar imagen",
"Cargar sonido",
"Usuarios",
"No podemos correr este script",
"Necesitamos más opciones",
"Adaptaremos el editor a su nivel de aptitud en codificación. Puede cambiar su nivel de aptitud más tarde en el concentrador.",
"¿Cuál es su nivel de conocimiento sobre programación?",
"¿A qué se dedica?",
"Novedades",
"¿En qué parte del mundo se encuentra?",
"Escribe otra imagen en una ubicación determinada. La opacidad tiene una gradación de 0 (transparente) a 1 (opaco).",
"Usted está en línea.",
"YouTube",
0,0,
"Su usuario de GitHub.",
"Su usuario Minecraft.",
"Tu arte aparecerá aquí",
0,
"Tu canal aparecerán aquí",
"Todavía no se ha verificado su dirección de correo electrónico. Revise su bandeja de entrada.",
"Su nombre completo",
"Su apodo aparece en páginas públicas. Asegúrese de que no introducir su apellido.",
"No se publicará tu script '{0}'. Mensaje de error: {1:not available}",
"El script contiene errores!",
"El script aparecerá aquí",
"Su usuario de Twitter, por ej. @touchdevelop.",
"hace unos segundos",
"una función",
"una variable global",
"hace un minuto",
"una página",
"acerca de la cobertura",
"acerca de la información detallada",
"acerca del perfil",
"sobre usted",
"abuso",
"reportes de abuso",
"informes de contenido inapropiado",
"informe de abuso",
"acceder y usar su ubicación",
"acceso denegado",
"acceder al campo {0}",
"actividad",
"añadir",
"agregar uno nuevo...",
"añadir una nota de publicación",
"agrega una acción que se desencadena para cada fotograma de la pantalla.",
"agregar comentario",
0,
"añadir sitio web personalizado",
"añadir función",
"añadir corazones",
"agregar parámetro de entrada",
"añadir línea arriba",
"añadir una línea debajo",
"agregar nuevo",
"añadir nueva etiqueta",
0,
"agregar parámetro de salida",
"añadir al canal",
"añadir al inventario",
"añadir {0}",
"agregando plugins",
0,
"todas las API",
"permitir",
"increíble, asombroso, alucinante, impresionante, formidable, impactante, clásico, guay, curioso, distinto, excepcional, exclusivo, extraordinario, fabuloso, fantástico, glorioso, genial, ",
0,
"definición de un tipo de función",
"hace una hora",
"analizando...",
"aplicar código",
"aprobados",
"aprobar",
"aprobado",
"aplicaciones",
"¿Estás seguro/a?",
"arte",
"recursos de arte",
"asignación",
"autenticando...",
"autor",
"correo electrónico del autor",
"sitio web del autor",
"atrás",
"fondo",
"retroceso",
"borra esto",
"tecla mala",
0,
"base",
"principiante",
"principiantes",
0,
"está vinculado al script:",
"en blanco",
"aplicación en blanco",
"creeper en blanco",
"documentos en blanco",
"juego en blanco",
"minecraft en blanco",
"minecraft pi en blanco",
"diseño infográfico en blanco",
"borrador en blanco",
"complemento de script en blanco",
"tortuga en blanco",
"tutorial en blanco",
"pausa en el depurador",
"punto de interrupción",
"construir",
"por tiempo",
"por votos",
"llamar",
"llamar a número",
"devolución de llamada",
"cancelar",
0,0,
"cambiar (de nuevo) a local",
"cambiar contenidos",
"canales",
"comprueba si la referencia no se ha establecido",
0,0,0,
"elegir una imagen (menor que 1 MB, más pequeña que 2048 x 2048)",
0,0,0,0,0,0,
"seleccione su nivel de aptitud en codificación",
"elegir...",
0,
"borrar",
"portapapeles",
"clon",
0,
"sesiones en la nube",
"código",
"codifica la línea de meta",
"codificador",
"color #{0}",
"color: {0}",
"sacar comentario",
"comentarios",
0,
"condicional",
"conectado",
0,0,
"continuar",
0,
"copiar",
"copiar selección",
"cobertura",
"crear",
"crear un nuevo parámetro",
0,0,0,0,
"crea una colección vacía de objetos",
"creando el script",
0,
"expresión actual",
"¡personaliza el arte!",
"cortar",
"cortar selección",
"base de datos",
"depurar",
"punto decimal",
0,
"eliminar",
"eliminar datos locales y permisos",
"eliminar selección",
"bajar a variable",
"denegar",
"descripción",
"descripción (búsqueda de ayuda)",
0,
"detalles",
"¿Querías usar este valor?",
"dif. act.",
"dif. ant.",
0,0,0,
"descartar",
"mostrar valor",
"muestra el objeto en el muro",
"nombre del documento",
"recurso del documento",
"perro",
"hecho",
"¡listo!",
"editar",
"otra cosa si",
"correo electrónico",
0,
"correo electrónico y notificaciones push",
0,
"habilitado",
"introduzca un nombre de grupo (requerido)",
0,
"ingresar el código de invitación",
"ingresa este código",
"errores",
"errores en el plugin",
"eventos",
"todo",
"ej.: ",
0,
"muy bien; buen trabajo; fantástico, guay; molas; bien hecho; sobresaliente; lo has pillado; genial",
0,
"salir",
"experto",
0,
"exportar",
"exportar una representación JSON de los contenidos",
"exportado desde esta biblioteca",
"ampliar",
0,
"extraer la selección en la función",
0,
"extraer a variable",
"encontrar referencias",
"finalizado",
"arréglalo",
"seguir tutorial en el editor",
"para el grupo",
"tenedores",
"función",
"nombre de la función",
"tipos de funciones",
"función, variable, biblioteca, ...",
"sexo",
"Obtener mi certificado Hora del Código™",
"obtiene el temporizador de se desencadena para cada fotograma de la pantalla.",
"usuario de github",
0,
"sustitución global",
"variable global",
"variables globales",
"volver",
"¡regresar a la codificación! {0}★ para ir",
"volver...",
"ir a",
"ve a la lista de cosas de tu guion",
"ir al paso anterior",
"meta:",
"grupo",
0,
"corazones",
"ayuda",
0,0,
"historial",
"¡Bravo!, se publicó tu guión",
"como encontró",
"quiero ejecutarla en",
"He terminado mi Hora del Código™",
"imagen del ícono: {0}",
0,
"si estás atascado, toca la línea de meta",
0,0,0,0,
"importar valores de los campos desde un objeto JSON",
0,0,0,0,
"increíble, mágico, maravilloso, sorprendente, alucinante, milagroso, peculiar, fenomenal, molón, especial, espectacular, inesperado, chocante, super guay, ",
0,
"insertar",
"insertar comentario",
"insertar instrucción",
"insertar {0}",
"información detallada",
0,
"instalando y cargando script",
"en local",
0,
"problemas",
"unirse a un grupo",
"unirse a un grupo",
0,
"¡siga escribiendo los términos de búsqueda!",
"seguir editando",
"se conoce aquí como:",
0,
"aprender",
"obtener información sobre la publicación",
"más información",
"más información acerca de {0}",
"salir del tutorial",
"cambiemos esto",
"¡Vamos!",
"¡empecemos!",
"bib",
"bibliotecas",
"biblioteca",
"nombre de la biblioteca",
"referencia de la biblioteca",
"cargar más",
"cargar más respuestas",
"cargando",
0,
"cargando comentarios de /{0}...",
0,
"cargando respuestas...",
"cargando guion",
"cargando tutorial",
"cargando...",
"local",
"ubicación",
0,
"negación lógica",
"registros",
"principal",
0,
"creadores",
"administrar datos",
"quizás más tarde",
"yo",
0,0,
"usuario de minecraft",
0,0,
"más",
"más ",
"más configuraciones",
"mover cursor",
"mover a la izquierda",
"ve al siguiente paso",
"mover el cursor a la izquierda",
"mover el cursor a la derecha",
"mi arte",
0,0,0,
"mis scripts",
"se necesita un nombre diferente aquí",
"aquí se necesita una cadena diferente",
"aquí se necesita un campo diferente",
"se necesita un parámetro",
"tienes que borrar esto",
"tienes que hacer modificaciones en otro sitio",
"negativo",
0,0,0,0,
"nueva línea",
0,0,0,
"nueva instrucción debajo",
"nueva variable",
0,
"siguientes tutoriales...",
"sobrenombre",
0,
"este usuario no tiene ningún arte publicado",
"sin comentarios, pulsa para escribirlos",
"¡no hay tenedores, instala, edita y vuelve a publicar tu script para crear uno!",
"no hay corazones. ¡podrás agregar uno cuando instales el script!",
"todavía no se cargaron imágenes",
0,0,
"sin etiquetas, pulsa para añadirlas",
0,0,0,
"notificaciones",
0,
"ya puedes seleccionar una propiedad de {0}; por sí misma no hace nada",
"ahora puedes seleccionar una propiedad en él",
"número",
"entrada numérica",
0,
"ocupación",
0,
"disponible sin conexión",
"aceptar",
"juguemos entonces",
"en línea",
0,
"o toca para obtener ayuda",
"otros",
"información general",
0,
"páginas",
0,
"análisis del texto del script",
0,
"pegar",
"pausar",
0,
"inicio del juego de física",
"elige una plantilla de script...",
"imagen",
"nombre de la imagen",
"nombre de la imagen (de 4 caracteres como mínimo)",
"url de la imagen",
"volver a jugar",
0,
"espera...",
"complementos",
"vista previa",
"imprimir",
0,
"privado",
"función privada",
"perfil privado",
"perfil",
"conocimiento sobre programación",
0,
"promocionar a datos",
0,
"sobrenombre público",
"perfil público",
"publicar",
"publicar como oculto",
0,
"publicado",
"extraer cambios",
"sacar a nivel de bloque",
0,
"volver a ejecutar",
"leer mas...",
"solo lectura",
"nombre real",
0,
"recibir boletín de correo electrónico",
"recibir notificaciones de correo electrónico",
"registrar nombre:",
0,
"teclado numérico normal",
"volviendo a cargar script",
"eliminar",
0,
"eliminar imagen",
"quitar el fondo blanco (es mejor para los sprites del juego)",
0,
"cambiar nombre",
"repetir n veces",
"repetir en la colección",
"repetir mientras",
"sustituir todo en la función",
"sustituir todo en el script",
"sustituir imagen",
"replicado",
"replicado ",
0,
"denunciar abuso",
0,
"revertir a versión publicada",
0,
"retroceder ",
"ejecutar",
"ejecute principal",
0,
"ejecutar con instrumentación",
"guardar",
"guardado",
"guardando...",
"estudios",
"pantallas",
"captura de pantalla",
"captura de pantalla de {0}",
"script",
"propiedades del script",
0,
"buscar",
"buscar arte",
"buscar imágenes de arte",
"buscar aquí para {0}",
"buscar plantillas",
"buscando...",
"ver más opciones",
"seleccionar",
"seleccionar más",
"selecciona esa línea",
"seleccionar el {0}",
0,0,
"establecer el nombre de la variable local",
"establecer nombre",
"establecer el controlador que se invoca cuando se desliza el panel",
"establecer el controlador que se invoca cuando se pulsa el panel",
"establecer el controlador que se invoca cuando se toca el panel",
"establecer el controlador que se invoca cuando se libera la capacidad táctil del panel",
"establece todos los campos a sus valores predeterminados",
"configuración guardada",
"configuración",
"compartir",
0,
"mostrar cómo completar esta actividad",
"mostrar más opciones",
"presentar",
"iniciar sesión",
0,0,
"cerrar sesión",
"iniciando sesión...",
0,
"simplificar",
"nivel de aptitud guardado",
"saltar iteración",
0,
"social",
0,
"sonido",
0,
"imagen de la pantalla de presentación: {0}",
"dividir",
0,
"volver a empezar",
"iniciando script",
"iniciando...",
0,
"dentro",
"fuera",
"encima",
0,
"detener",
0,
"función detener",
"detener bucle",
"guardar en variable",
"guardar el valor en una variable",
"cadena",
0,
"tira '{0}'",
0,0,0,
"superior, sobrenatural, estupendo, inaudito, sobrenatural, único, sin precedentes, inusual, raro, extraño, fuera de lo común",
"alrededor de",
0,0,
"sincronización de...",
0,0,0,0,0,
"etiquetas",
0,0,
"toca (←) cuando termines",
"toca [ok] cuando termines",
0,
"toca aquí para ir al siguiente paso",
"pulsar aquí cuando termine",
"pulsa aquí",
"pulsar aquí para obtener instrucciones",
"pulsa aquí para ejecutar la aplicación",
"pulsa para cambiar el color",
"tocar para cambiar la imagen del icono",
"tocar para cambiar la imagen de la pantalla de presentación",
"pulsar para traducir con el traductor de Microsoft®...",
"temporal",
"terms of use",
"probar",
"función de prueba",
"pruebas",
"prueba si dos referencias aluden al mismo objeto",
0,0,
"el hub",
"el código de invitación debe ser un número entre 9 y 64 caracteres de largo",
"el script se bloqueó",
0,0,
"este script es una biblioteca",
"este script es un servicio web",
"hora y fecha",
"a código",
"para continuar",
"para variable global",
"alternar punto de interrupción",
"más destacado y nuevo",
0,0,
"traducir",
"traduciendo tutorial...",
0,0,0,
"volver a intentarlo",
"convertir en",
"progreso del tutorial",
"tutorial: ",
"tutoriales",
"usuario de Twitter",
"tipo:",
"tipo: {0}",
0,0,0,
"deshacer",
0,0,0,0,0,0,0,0,0,0,
"actualizar",
0,0,0,0,0,0,
"cargar",
"cargar imagen",
"Cargar captura de pantalla",
"cargar sonido",
0,0,0,
"url",
0,0,0,0,0,
"nombre de la variable",
"ver como script",
"ver/editar nombre, correo electrónico, ...",
0,
"fondo de pantalla",
"tenemos una biblioteca '{0}' aquí; {1}",
"Aquí tenemos un {0:a}; ¿quería hacer algo con él?",
"necesitamos un nuevo campo",
"necesitamos una nueva tabla",
"necesitamos un nuevo {0}",
"necesitamos un teclado numérico diferente",
"necesitamos una nueva variable",
"tenemos que editar otra cosa",
"te guiaremos paso a paso",
"aplicaciones web",
0,0,0,
"sitio web",
0,
"url del sitio web",
0,0,0,0,0,
"año de nacimiento",
0,0,
"¡Lo has conseguido!",
0,
"{0} ({1} línea{1:s})",
"hace {0} día{0:s}",
0,
"{0} falló; ahora estamos en modo offline;\n asegúrate de que tu conexión a internet funcione",
"archivo {0} de {0:s} importados",
"{0} para esta versión",
"hace {0} hora{0:s}",
"hace {0} minuto{0:s}",
"hace {0} mes{0:s}",
"{0} de {1} terminado",
"{0} publicar",
"{0} script{0:s} publicado{0:s}",
"hace {0} segundo{0:s}",
"{0} arriba",
"hace  {0:s}años {0}"
]); return true; }

if (lang == "es-ES") { TDev.Util._setLanguageArray(keys, [0,
"  -> Línea {2} ('{1}'), error: {0}\n{3}",
" -- una variable local",
" [class]",
" [oculto]",
" [override]",
" atrás",
" adelante",
" horas ",
" minutos ",
" de ",
" segundos ",
" enviando cambios",
" esperando por el servidor",
"### código fuente completo",
"Las llaves de Javascript, todas las herramientas, para desarrolladores con experiencia",
"función 'atomic'",
"'box' solo se puede acceder desde la página de visualización del código",
"'box' no se puede acceder en el modo de diseño HTML",
0,
"'html' sólo se puede acceder en el modo de diseño HTML",
"'{0}' espera {1} aquí",
"'{0}' tiene una firma no soportada",
"'{0}' no está implementada",
"'{0}' es obsoleto y no está implementado",
"'{0}' obsoleto, no debería utilizarse",
0,
"'{0}' devuelve un '{1}'; {2}",
"'{0}' devuelve valores de {1}; puede utilizar el botón 'store in var' para guardar a los locales",
"(Opcional) Un URI que identifica una página con información sobre el error, usado para proporcionar información adicional sobre el error, al desarrollador del lado del cliente.",
"(Opcional) Un código de error legible.",
"(Opcional) Pares adicionales de clave y valor no cubiertos por la especificación OAuth 2.0.",
"(Opcional) Indica si el token puede caducar dentro de los próximos segundos.",
"(Opcional) Opcional si es idéntico al alcance solicitado por el cliente; de lo contrario, el alcance del token de acceso según lo descrito por la sección 3.3 de la especificación de OAuth 2.0.",
"(Opcional) La duración en segundos del token de acceso.",
"(por favor espere, puede tardar hasta un minuto)",
", en su lugar, se obtuvo {0}",
", obtuvo {0}",
", tamaño: {0} caracteres",
". Por favor, lea nuestra ",
"... nada que ver aquí...",
"... hay más ...",
"// comentario",
"1. elegir un documento (.txt, .pptx, .pdf, .css, de menos de 8MB)",
"1. escoja un sonido MP3 (menos de 1MB)",
"2. dar un nombre (mínimos 4 caracteres)",
"3. describir",
"4. publicar",
":( Lo sentimos, ha ocurrido un error al traducir este texto.",
":( Lo sentimos, no se ha podido traducir esto.",
":( no pudo encontrar alguna fuente de vídeo",
":( no válido en la información de vídeo",
"; ¿le falta → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'>Apache Cordova</a> le permite construir aplicaciones móviles multiplataforma.",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> generar el certificado</a>.",
"<b>Descargo de responsabilidad:</b> Esta aplicación web no está avalada por Microsoft.",
"<b>cómo ejecutar localmente Touch Develop</b>",
"<b>¡una línea perfecta!</b> sigamos",
"<h3>cargando configuraciones actuales...</h3>",
"<h3>no más consejos!</h3>",
"<h3>bienvenido a Touch Develop</h3>",
"<h3>{0:q} requiere estar logueado</h3>",
"<p>Si no tienes una suscripción Azure, ir a <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> suscripciones Azure</a> para conseguir una.</p>",
"<p>Touch Develop le permite<b>crear aplicaciones fácilmente</b>desde su teléfono, tablet o PC.</p>",
"<p>Puedes compartir tus aplicaciones con otros, para que puedan ser <b>ejecutadas y editadas</b> en Windows Phone, iPad, iPhone, Android, PC o Mac.</p>",
"<strong>función en beta:</strong> la sintaxis y la semántica está sujeta a cambios",
"<strong>plataforma requerida:</strong>",
"@hi/lo fuera de alcance",
"Una matriz 2D de números",
"Un vector 3D",
"Un mapa de Bing",
"Una aplicación Minecraft Pi.",
"Una aplicación de Minecraft.",
"Una aplicación Minecraft creeper.",
"Un cliente que envía eventos al servidor",
"Una animación para animar las propiedades del sprite.",
"Un color argb (alfa, rojo, verde, azul)",
"Una capa de la escena de fondo",
"Un editor amigable para principiantes",
"Un tablero para crear juegos 2D",
"Un constructor para crear formularios de datos en HTML",
"Una sesión de datos en la nube",
"Una colección de objetos",
"Una colección de sprites",
"Una constante de color",
"Una combinación de fecha y hora",
"Se agregó un comentario sobre su pull request.",
"Un contacto",
"Un logger personalizado",
"Un documento",
"Un recurso de documento",
"Un {0} completamente replicado se guarda en un almacenamiento en la nube y es completamente amacenado en memoria caché de los clientes.",
"Una función atómica y genérica de conversión",
"Una geo coordenada (latitud, longitud,...)",
"Una variable global",
"Un grupo puede utilizarse para ejecutar una clase o un evento. Por favor no incluya el nombre de su escuela en el nombre del grupo.",
"Un controlador conectado a un evento.",
"Un creador de estructura de datos json",
"Una estructura de datos json.",
"Un enlace a un video, imagen, correo electrónico, número de teléfono",
"Un {0} local es automáticamente guardado en almacenamiento local, pero nunca compartido con otros dispositivos.",
"Mapa de cadenas a cadenas",
"Un mapa de números a los números",
"Un marcador de mapa",
"Una ubicación con nombre",
"Se ha producido un error de red. Su configuración de cuenta no ha sido almacenada ¿Estás desconectado?",
"Un número (posiblemente negativo o fracción)",
"Una constante numérica",
"Un botón de página en el muro",
"Una página en un muro",
"Un {0} parcialmente replicada se guarda en la nube y completamente en memoria caché en los clientes.",
"Una imagen",
"Un fragmento de texto",
"Una aplicación de diseño infográfico.",
"Un lugar para conectar una acción para ejecutar en respuesta a un evento",
"Una acción posiblemente atómica con un único argumento",
"Un comentario en un muro de mensajes",
"Una referencia a un script de biblioteca",
"Una referencia a un valor",
"Un {0} replicada es automáticamente guardado en la nube y compartido entre los dispositivos.",
"Una escena que contiene fondos con capas de parralax.",
"Se ha abierto una ventana separada con el cuadro de acceso, por favor acceda desde esa ventana.",
"Un {0} local del servidor se guarda en la nube y nunca en caché en los clientes.",
"Una definición de la firma de una función",
"Un único códigode error ASCII [USASCII].",
"Una instantánea del estado de gamepad",
"Una canción",
"Un sonido",
"Un efecto de sonido",
"Un resorte entre dos sprites.",
"Un sprite",
"Una hoja de sprites que agrupa varios fotogramas en una sola imagen",
"Una estructura de datos de usuario",
"Una tabla con filas definidas por el usuario",
"Una tarea creada con la palabra clave 'async'",
"Un {0} temporal es local en la conexión y desechado cuando la conexión termina.",
"No se guarda un {0} temporal entre ejecuciones.",
"Un cuadro de texto",
"Un contador de tiempo",
"Un nombre único para mostrar en su perfil público (al menos 8 caracteres)",
"Una prueba de unidad",
"Una cuenta de usuario",
"Una interfaz de usuario",
"Un web socket",
"Un mensaje de web socket",
"Script ADJ",
"Configuración de API",
"Nombre de la API",
"API no implementado",
"logo ARM",
"Se aborta la ejecución si la condición es falsa.",
"Acelerómetro",
"Acceso denegado: El navegador web y el sitio web evitan compartir recursos de origen cruzado (CORS).",
"Acceder a diversas propiedades del entorno de aplicación",
"Agregar un nombre de clase CSS para el elemento actual.",
"Añadir un nuevo botón. El icono debe ser el nombre de un icono incorporado, el texto no debe estar vacío.",
"Agregue una referencia a JsonBuilder en la matriz.",
"Agregar una acción que se desencadene para cada fotograma de la pantalla",
"Añadir un valor especificado a la referencia dada",
0,0,
"Añadir dos números de 32 bits firmados",
"Añadir dos números sin firma de 32 bits",
"Agrega un valor booleano",
"Agrega un valor numérico",
"Agrega una imagen",
"Añade un marcador de imagen en el mapa",
"Agrega un trozo de texto al formulario con un nombre personalizado o archivo.",
"Añade un marcador de lugar en el mapa (ignorar si no se establece la ubicación)",
"Agrega un valor de cadena",
"Añade un marcador de texto en el mapa",
"Agrega un valor al array.",
"Añade un vector",
"Agregar un objeto",
"Agrega muchos objetos a la vez",
"Suma números",
0,
"Agrega valor a la puntuación actual.",
"Ajustar {0}.",
"Avanzar el enumerador y devuelva true si existe otro elemento.",
"Después que se detiene el script, explora el código para ver la información recopilada.",
"Todos mis grupos",
"Todos mis scripts",
"Todas las opciones encendidas",
"Permitir la ejecución de otros eventos, antes de que termine el evento actual.",
"Le permite al usuario guardar la dirección de correo electrónico (email)",
"Permite al usuario que guarde el número de teléfono",
"Una solicitud HTTP de web",
"Una respuesta HTTP de web",
"Una acción atómica sin argumentos",
"Una aplicación vacía usando páginas y casillas.",
"Una aplicación vacía usando la biblioteca temporal.",
"Una página de documentación vacía.",
"Un tutorial interactivo vacío.",
"Un complemento del editor de script vacío.",
"Un script vacío que no hace nada.",
"Un enumerador general",
"Una solicitud entrante HTTP de web",
"Una tabla indexada con filas definidas por el usuario",
"Una interfaz para el editor de TouchDevelop",
"Una aplicación de tortuga.",
"Aplica `converter` a todos los elementos de la colección de datos de entrada y devuelve una colección de resultados",
0,
"¿Está seguro de que quiere dejar de seguir el tutorial?",
0,
"Artículos por este usuario:",
"Pedir o mostrar los valores en la pared...",
"Adjuntar datos a otros objetos",
"Código repetitivo para crear un juego.",
0,0,
"Camara",
"Ubicación, micrófono, cámara y otros sensores",
0,
"Cambiar configuración...",
"¡Cambiar nivel de aptitud!",
"Canales",
"Verifica si el panel está en la misma instancia que el otro panel.",
0,0,0,
"Borrar todos los eventos en proceso relacionados con esta placa",
"Borrar la imagen de fondo",
"Borrar la cámara de fondo",
0,0,
"Código que aparece cuando se produce una interacción del usuario",
"Código que realiza una tarea específica",
"Compara números según igualdad",
"Compara números según menor",
0,
"Compara números según mayor",
0,0,0,0,0,0,0,
"Concatena dos fragmentos de texto",
0,0,0,0,0,0,
"Convierte a la hora local",
0,0,
"Ayudantes de corrección",
0,0,
"Crear grupo",
"Crear script",
"Crea un obstáculo de línea con un punto inicial dado o un ancho y un alto dados. La elasticidad es 0 para la adhesión y es 1 para un rebote completo.",
"Crea una nueva colección para los sprites.",
"Crea un nuevo sprite de elipsis.",
"Crear una imagen sprite nueva.",
"Crea un nuevo sprite de rectángulo.",
0,
"Crea una nueva hoja de sprite.",
"Crear un nuevo sprite de texto.",
"Crea un salto entre los dos sprites.",
"Crea un sprite delimitador.",
"Crear un valor no válido de este tipo de objeto",
"Crear canal",
"Crear colecciones de objetos.",
"Crear valores no válidos",
"Crea muros alrededor del tablero a una distancia dada.",
"Crea tus propias aplicaciones",
0,0,
"Crea un nuevo tablero de juego vacío y lo muestra en la pantalla.",
0,0,0,
"Crea un nuevo sprite de 100 de ancho con la imagen dada.",
0,
"Crea una instancia no válida del controlador para juegos",
0,
"Elemento actual de la caja en la página.",
"Dispositivo actual",
0,
"Punto táctil actual",
"Desasocia el controlador del evento.",
0,
"Muestra la imagen en el muro; debes llamar a 'actualizar en el muro' posteriormente si quieres que se vean reflejados los cambios.",
0,0,0,
"Muestra el estado del controlador para juegos en la pared",
"Divide números",
"¿Se solapan los sprites?",
0,
"Documentos",
"Recuerde desplazarse hacia abajo y presionar “guardar” al terminar la edición.",
"Arrastre y suelte bloques, interfaz simplificada, ¡perfecto para principiantes!",
"Dibuja una línea entre dos puntos",
"Dibuja borde de texto en un color y tamaño de fuente determinados",
"Edite el código como texto, más opciones, para quienes aspiran a ser escritores de aplicaciones.",
"Mensajes de correo electrónico, sms, contactos, calendario...",
0,
"Escribir un nombre",
0,
"Introduzca alguna información sobre usted",
"Introduzca la URL de su sitio web personal (ejemplo: http://www.northwindtraders.com)",
"Ingresar el código de invitación",
0,
"No se puede tener parámetros out en estos eventos.",
"Todos podrán ver la imagen en Internet por siempre. ",
0,0,
"Extensiones",
"Facebook",
"Rellena una elipse en un color determinado",
"Rellena un rectángulo en un color determinado",
"Velocidad táctil final después de haber finalizado la función táctil",
"Para los scripts publicados, consulta también la pestaña en la página del script publicado para buscar un perfil y cobertura recopilados por \\\"crowdsourcing\\\" de forma anónima",
"Foros",
"Ya no te mostraremos el código que tienes que ingresar. Sigue las instrucciones y toca Ejecutar cuando creas que hayas terminado.",
"Funciones definidas en el script actual",
0,0,0,0,0,
"Obtiene una instantánea de los estados del controlador para juegos (si alguno está conectado al navegador). Vacío si el controlador no es compatible o no hay ningún controlador para juegos conectado.",
0,0,0,
"Obtiene un valor que indica si la placa está diseñada para ser vista en el modo de panorama",
"Obtiene un valor que indica si la canción está protegida por DRM",
"Obtiene el valor x e y de los ejes seleccionados.",
0,0,
"Obtiene la escena de fondo",
"Obtiene la posición horizontal central en píxeles",
0,
"Obtiene el color que tiene el valor ARGB de #00FFFFFF",
"Obtiene el color que tiene el valor ARGB de #FF000000",
"Obtiene el color que tiene el valor ARGB de #FF0000FF",
"Obtiene el color que tiene el valor ARGB de #FF008000",
"Obtiene el color que tiene el valor ARGB de #FF00FFFF",
0,
"Obtiene el color que tiene el valor ARGB de #FF800080",
0,0,0,0,
"Obtiene el color que tiene el valor ARGB de #FFFF0000",
"Obtiene el color que tiene el valor ARGB de #FFFF00FF",
"Obtiene el color que tiene el valor ARGB de #FFFFA500",
0,
"Obtiene el color que tiene el valor ARGB de #FFFFFF00",
"Obtiene el color que tiene el valor ARGB de #FFFFFFFF",
0,0,0,0,
"Obtiene el primer controlador para juegos conectado disponible",
0,
"Obtiene el identificador del controlador para juegos",
0,
"Obtiene el alto en píxeles",
"Obtiene el alto de la imagen de la cámara en píxeles.",
0,0,0,0,0,0,0,0,0,
"Obtiene el índice del reproductor",
"Obtiene el valor presionado de un botón. Devuelve 0 si falta el botón.",
0,
"Obtiene el volumen del sonido para sonidos comprendidos de 0 (silencio) a 1 (volumen actual)",
"Obtiene la cantidad de sprites",
"Obtiene el sprite con índice i",
0,
"Obtiene la marca de tiempo de esta instantánea",
0,
"Obtiene el ancho en píxeles",
"Obtiene el ancho de la imagen de la cámara en píxeles.",
"Obtiene la posición de y en píxeles",
"Empezar",
0,
"Variables globales en el script actual",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"En el modo de depuración, el panel muestra la velocidad y otra información sobre los sprites",
"Indica si un botón se presiona. Devuelve false si falta el botón.",
0,
"Indica si los datos del controlador para juegos son idénticos",
"Indica si el controlador para juegos aún está conectado.",
0,0,0,0,
"Insertar '{0}' {1}",
"Interactuar con el tiempo de ejecución de la aplicación",
"Los elementos marcados con * son obligatorios.",
"Datos JSON",
"Unirse a un grupo",
"Último punto final táctil",
"Último punto inicial táctil",
0,0,0,0,0,
"Permite visualizar las actualizaciones.",
0,0,
"Hace que el sprite rebote en el borde la pantalla",
"Mapas, ubicación, dirección, dirección de ubicación",
"Aptitud de las matemáticas, abs, máx, ...",
"Me",
0,
"Usuario de Minecraft",
"Más",
"Movimiento",
"Mueve el sprite hacia otro sprite.",
"Multiplica números",
"Música y sonidos",
"Mis grupos",
"Mi perfil",
"Mis Scripts",
"NUEVO",
"NFC",
"Necesita alguna razón.",
"Red",
"Nuevos scripts",
"Nuevo mensaje de {0} en {1}",
"Colores nuevos o integrados",
"No puede hacer",
0,0,0,
"Vaya, el nombre es muy corto...",
"Vaya, el nombre de la foto es demasiado corto...",
"Vaya, el nombre del sonido es demasiado corto...",
"Vaya, hubo un error al cargar la imagen.",
"Vaya, no podemos tomar una captura de pantalla ahora",
"Vaya, no podemos tomar una captura de pantalla ahora.",
0,0,0,
"Socios",
"Números de teléfono, vibración, etc....",
0,
"Escoge un color aleatorio",
"Fotos y música...",
0,
"Reproducir, detener o reanudar canciones...",
0,0,0,
"Revise nuestra Declaración de privacidad.",
"espera...",
"Publicar un comentario...",
0,0,0,
"La acción privada no tiene un botón de ejecutar. ",
"Solicita al usuario que ingrese un número",
0,
"Publicar guión",
0,
"La publicación está sujeta a nuestras ",
"Publicar script...",
"Se elevó cuando la animación comenzó a mostrarse",
"Se elevó cuando la animación dejó de mostrarse",
"Lee el cuerpo de la respuesta como archivo de sonido",
"Recibir notificaciones de correo electrónico cuando otras personas revisen/tomen una captura de pantalla de sus scripts o respondan a uno de sus comentarios, o cuando ocurran eventos relacionados con sus suscripciones.",
"Recuerde: todos podrán ver el script si lo publica; por lo tanto, asegúrese de que no contenga las contraseñas o la información personal.",
"Quita el valor de la vida actual.",
"Responder...",
"Informar/eliminar",
"Cambia el tamaño de la imagen según el tamaño en píxeles especificado",
0,
"Devuelve una copia de la imagen",
0,0,
"Devuelve una fecha que agrega el número especificado de meses al valor de esta instancia.",
"Devuelve una fecha que agrega el número especificado de años al valor de esta instancia.",
"Devuelve un número integral aleatorio entre el \"mín.\" y el \"máx.\" incluidos.",
0,0,0,0,0,0,0,
"Devuelve TRUE si la instancia actual es inservible",
0,0,0,
"Escalas del sprite",
"Actualizaciones de script",
"Scripts por este usuario:",
"Buscar",
"Buscar y navegar por la web...",
"Buscar código...",
"Buscar todo",
"Buscar aquí...",
"Buscar números de teléfono cerca de un lugar usando Bing. Distancia en metros, negativas a ignorar.",
"Buscar números de teléfono con Bing",
"Buscar...",
"Buscar imágenes usando Bing",
"Buscar noticias cerca de un lugar usando Bing. Distancia en metros, negativas a ignorar.",
"Buscar noticias con Bing",
"Ver más",
0,0,
"Enciende o apaga la gradiente",
"Establece la transformación afín de matriz 3x3 que se aplica al muro.",
0,
"Establece la cámara de fondo",
"Establece el color de fondo",
"Establece el color de fondo.",
"Establece la imagen de fondo",
"Establece la posición horizontal central en píxeles",
"Fija los puntos de vida actuales.",
"Establece la fricción predeterminada para los sprites a una fracción de la pérdida de velocidad entre 0 y 1",
"Establece el alto en píxeles",
"Establece la posición en píxeles",
0,
"Establece el nivel del volumen del sonido de 0 (silencio) a 1 (volumen actual)",
"Establece la velocidad en píxeles/s",
"Establece el color del sprite.",
"Establece el vector de aceleración uniforme para los objetos en el panel a píxeles/seg.^2",
0,0,
"Establece el ancho en píxeles",
"Establece la velocidad de x en píxeles/seg",
"Establece la aceleración de y en píxeles/seg^2",
"Establece la posición de y en píxeles",
"Establece la velocidad de y en píxeles/seg",
0,
"Configuración",
"Comparátelo con esta url:",
"Mostrar errores en el editor si el script usa API que evitan que se ejecute en estas plataformas.",
"Muestra el panel en el muro.",
0,
"Nivel de aptitud: {0}     ",
0,0,0,0,0,
"Detiene y borra todos los temporizadores de fotogramas",
0,
"Resta números",
"Soporte para tutoriales interactivos.",
"TD100: insertar {0} aquí",
"TD101: no puede encontrar '{0}'",
"TD109: no se puede asignar a esto",
"TD111: no se puede asignar de {0} a {1}",
"TD112: no puedo encontrar la propiedad '{0}' en {1}",
"TD115: se han proporcionado demasiados parámetros a {0}",
"TD116: no se han suministrado suficientes parámetros a {0}",
"TD118: la condición 'if' pide {1}",
"TD119: necesito algo en qué iterar",
0,
"TD130: el enlace de 'for' pide {1}",
"TD144: parece que te falta '{0}', intenta añadirlo",
"TD145: parece que aquí falta un operador (como '+', '(' o ',')",
"TD147: no esperábamos ver a '{0}' aquí",
"TD150: no puede llamar a la cosa antes '('",
"TD151: sin cerrar '('",
"TD152: inesperado ')'",
"TD154: hay algo que tiene que ir detrás del operador",
"TD155: no se puede asignar '{0}' a una variable local",
"Dicte Creative Coding.",
"Servicios de tecnología de",
"Condiciones de Uso",
0,0,
"La url del documento",
"La imagen codificada es demasiado grande.",
"La cámara frontal o trasera",
"El grupo tiene nuevo dueño",
0,0,
"Este comando requiere un proxy local.",
"Este grupo está bloqueado.",
"Este grupo está abierto.",
"Este script es actual.",
"Este script le falta el encabezado.",
"Este script le falta la fuente.",
"Este script utiliza las siguientes capacidades que pueden faltar en tu dispositivo actual: {0}",
"Este script usa las siguientes capacidades: ",
0,
"Este tutorial usa datos en la nube que se comparten con otros usuarios.",
"Para agregar datos a la página, crea una variable local y pulsa 'promocionar a campo'.",
0,0,
"Traducción",
"Traducción, discurso al texto...",
"Traducciones hechas por Microsoft ® Translator, pulse para ver original...",
"True si se toca el panel",
"Intenta modificar el código hasta que sea correcto. Si te atascas, toca la barra del tutorial.",
"Tratando de llegar a servidor",
"Tutorial terminado",
"Tutoriales",
"Twitter",
"Escribir para buscar en línea...",
"Escribir para búsqueda...",
0,
"No se pueden editar los tipos, el orden y el número de parámetros del evento.",
"Widget de interfaz de usuario",
"URL: {0}",
"Actualiza las posiciones de sprites en el panel.",
"Actualiza la imagen como imagen sprite (si es una imagen sprite)",
"Actualiza el texto como sprite de texto (si se trata de un sprite de texto)",
"Cargar imagen",
"Cargar sonido",
"Usuarios",
"No podemos correr este script",
"Necesitamos más opciones",
"Adaptaremos el editor a su nivel de aptitud en codificación. Puede cambiar su nivel de aptitud más tarde en el concentrador.",
"¿Cuál es su nivel de conocimiento sobre programación?",
"¿A qué se dedica?",
"Novedades",
"¿En qué parte del mundo se encuentra?",
"Escribe otra imagen en una ubicación determinada. La opacidad tiene una gradación de 0 (transparente) a 1 (opaco).",
"Usted está en línea.",
"YouTube",
0,0,
"Su usuario de GitHub.",
"Su usuario Minecraft.",
"Tu arte aparecerá aquí",
0,
"Tu canal aparecerán aquí",
"Todavía no se ha verificado su dirección de correo electrónico. Revise su bandeja de entrada.",
"Su nombre completo",
"Su apodo aparece en páginas públicas. Asegúrese de que no introducir su apellido.",
"No se publicará tu script '{0}'. Mensaje de error: {1:not available}",
"El script contiene errores!",
"El script aparecerá aquí",
"Su usuario de Twitter, por ej. @touchdevelop.",
"hace unos segundos",
"una función",
"una variable global",
"hace un minuto",
"una página",
"acerca de la cobertura",
"acerca de la información detallada",
"acerca del perfil",
"sobre usted",
"abuso",
"reportes de abuso",
"informes de contenido inapropiado",
"informe de abuso",
"acceder y usar su ubicación",
"acceso denegado",
"acceder al campo {0}",
"actividad",
"añadir",
"agregar uno nuevo...",
"añadir una nota de publicación",
"agrega una acción que se desencadena para cada fotograma de la pantalla.",
"agregar comentario",
0,
"añadir sitio web personalizado",
"añadir función",
"añadir corazones",
"agregar parámetro de entrada",
"añadir línea arriba",
"añadir una línea debajo",
"agregar nuevo",
"añadir nueva etiqueta",
0,
"agregar parámetro de salida",
"añadir al canal",
"añadir al inventario",
"añadir {0}",
"agregando plugins",
0,
"todas las API",
"permitir",
"increíble, asombroso, alucinante, impresionante, formidable, impactante, clásico, guay, curioso, distinto, excepcional, exclusivo, extraordinario, fabuloso, fantástico, glorioso, genial, ",
0,
"definición de un tipo de función",
"hace una hora",
"analizando...",
"aplicar código",
"aprobados",
"aprobar",
"aprobado",
"aplicaciones",
"¿Estás seguro/a?",
"arte",
"recursos de arte",
"asignación",
"autenticando...",
"autor",
"correo electrónico del autor",
"sitio web del autor",
"atrás",
"fondo",
"retroceso",
"borra esto",
"tecla mala",
0,
"base",
"principiante",
"principiantes",
0,
"está vinculado al script:",
"en blanco",
"aplicación en blanco",
"creeper en blanco",
"documentos en blanco",
"juego en blanco",
"minecraft en blanco",
"minecraft pi en blanco",
"diseño infográfico en blanco",
"borrador en blanco",
"complemento de script en blanco",
"tortuga en blanco",
"tutorial en blanco",
"pausa en el depurador",
"punto de interrupción",
"construir",
"por tiempo",
"por votos",
"llamar",
"llamar a número",
"devolución de llamada",
"cancelar",
0,0,
"cambiar (de nuevo) a local",
"cambiar contenidos",
"canales",
"comprueba si la referencia no se ha establecido",
0,0,0,
"elegir una imagen (menor que 1 MB, más pequeña que 2048 x 2048)",
0,0,0,0,0,0,
"seleccione su nivel de aptitud en codificación",
"elegir...",
0,
"borrar",
"portapapeles",
"clon",
0,
"sesiones en la nube",
"código",
"codifica la línea de meta",
"codificador",
"color #{0}",
"color: {0}",
"sacar comentario",
"comentarios",
0,
"condicional",
"conectado",
0,0,
"continuar",
0,
"copiar",
"copiar selección",
"cobertura",
"crear",
"crear un nuevo parámetro",
0,0,0,0,
"crea una colección vacía de objetos",
"creando el script",
0,
"expresión actual",
"¡personaliza el arte!",
"cortar",
"cortar selección",
"base de datos",
"depurar",
"punto decimal",
0,
"eliminar",
"eliminar datos locales y permisos",
"eliminar selección",
"bajar a variable",
"denegar",
"descripción",
"descripción (búsqueda de ayuda)",
0,
"detalles",
"¿Querías usar este valor?",
"dif. act.",
"dif. ant.",
0,0,0,
"descartar",
"mostrar valor",
"muestra el objeto en el muro",
"nombre del documento",
"recurso del documento",
"perro",
"hecho",
"¡listo!",
"editar",
"otra cosa si",
"correo electrónico",
0,
"correo electrónico y notificaciones push",
0,
"habilitado",
"introduzca un nombre de grupo (requerido)",
0,
"ingresar el código de invitación",
"ingresa este código",
"errores",
"errores en el plugin",
"eventos",
"todo",
"ej.: ",
0,
"muy bien; buen trabajo; fantástico, guay; molas; bien hecho; sobresaliente; lo has pillado; genial",
0,
"salir",
"experto",
0,
"exportar",
"exportar una representación JSON de los contenidos",
"exportado desde esta biblioteca",
"ampliar",
0,
"extraer la selección en la función",
0,
"extraer a variable",
"encontrar referencias",
"finalizado",
"arréglalo",
"seguir tutorial en el editor",
"para el grupo",
"tenedores",
"función",
"nombre de la función",
"tipos de funciones",
"función, variable, biblioteca, ...",
"sexo",
"Obtener mi certificado Hora del Código™",
"obtiene el temporizador de se desencadena para cada fotograma de la pantalla.",
"usuario de github",
0,
"sustitución global",
"variable global",
"variables globales",
"volver",
"¡regresar a la codificación! {0}★ para ir",
"volver...",
"ir a",
"ve a la lista de cosas de tu guion",
"ir al paso anterior",
"meta:",
"grupo",
0,
"corazones",
"ayuda",
0,0,
"historial",
"¡Bravo!, se publicó tu guión",
"como encontró",
"quiero ejecutarla en",
"He terminado mi Hora del Código™",
"imagen del ícono: {0}",
0,
"si estás atascado, toca la línea de meta",
0,0,0,0,
"importar valores de los campos desde un objeto JSON",
0,0,0,0,
"increíble, mágico, maravilloso, sorprendente, alucinante, milagroso, peculiar, fenomenal, molón, especial, espectacular, inesperado, chocante, super guay, ",
0,
"insertar",
"insertar comentario",
"insertar instrucción",
"insertar {0}",
"información detallada",
0,
"instalando y cargando script",
"en local",
0,
"problemas",
"unirse a un grupo",
"unirse a un grupo",
0,
"¡siga escribiendo los términos de búsqueda!",
"seguir editando",
"se conoce aquí como:",
0,
"aprender",
"obtener información sobre la publicación",
"más información",
"más información acerca de {0}",
"salir del tutorial",
"cambiemos esto",
"¡Vamos!",
"¡empecemos!",
"bib",
"bibliotecas",
"biblioteca",
"nombre de la biblioteca",
"referencia de la biblioteca",
"cargar más",
"cargar más respuestas",
"cargando",
0,
"cargando comentarios de /{0}...",
0,
"cargando respuestas...",
"cargando guion",
"cargando tutorial",
"cargando...",
"local",
"ubicación",
0,
"negación lógica",
"registros",
"principal",
0,
"creadores",
"administrar datos",
"quizás más tarde",
"yo",
0,0,
"usuario de minecraft",
0,0,
"más",
"más ",
"más configuraciones",
"mover cursor",
"mover a la izquierda",
"ve al siguiente paso",
"mover el cursor a la izquierda",
"mover el cursor a la derecha",
"mi arte",
0,0,0,
"mis scripts",
"se necesita un nombre diferente aquí",
"aquí se necesita una cadena diferente",
"aquí se necesita un campo diferente",
"se necesita un parámetro",
"tienes que borrar esto",
"tienes que hacer modificaciones en otro sitio",
"negativo",
0,0,0,0,
"nueva línea",
0,0,0,
"nueva instrucción debajo",
"nueva variable",
0,
"siguientes tutoriales...",
"sobrenombre",
0,
"este usuario no tiene ningún arte publicado",
"sin comentarios, pulsa para escribirlos",
"¡no hay tenedores, instala, edita y vuelve a publicar tu script para crear uno!",
"no hay corazones. ¡podrás agregar uno cuando instales el script!",
"todavía no se cargaron imágenes",
0,0,
"sin etiquetas, pulsa para añadirlas",
0,0,0,
"notificaciones",
0,
"ya puedes seleccionar una propiedad de {0}; por sí misma no hace nada",
"ahora puedes seleccionar una propiedad en él",
"número",
"entrada numérica",
0,
"ocupación",
0,
"disponible sin conexión",
"aceptar",
"juguemos entonces",
"en línea",
0,
"o toca para obtener ayuda",
"otros",
"información general",
0,
"páginas",
0,
"análisis del texto del script",
0,
"pegar",
"pausar",
0,
"inicio del juego de física",
"elige una plantilla de script...",
"imagen",
"nombre de la imagen",
"nombre de la imagen (de 4 caracteres como mínimo)",
"url de la imagen",
"volver a jugar",
0,
"espera...",
"complementos",
"vista previa",
"imprimir",
0,
"privado",
"función privada",
"perfil privado",
"perfil",
"conocimiento sobre programación",
0,
"promocionar a datos",
0,
"sobrenombre público",
"perfil público",
"publicar",
"publicar como oculto",
0,
"publicado",
"extraer cambios",
"sacar a nivel de bloque",
0,
"volver a ejecutar",
"leer mas...",
"solo lectura",
"nombre real",
0,
"recibir boletín de correo electrónico",
"recibir notificaciones de correo electrónico",
"registrar nombre:",
0,
"teclado numérico normal",
"volviendo a cargar script",
"eliminar",
0,
"eliminar imagen",
"quitar el fondo blanco (es mejor para los sprites del juego)",
0,
"cambiar nombre",
"repetir n veces",
"repetir en la colección",
"repetir mientras",
"sustituir todo en la función",
"sustituir todo en el script",
"sustituir imagen",
"replicado",
"replicado ",
0,
"denunciar abuso",
0,
"revertir a versión publicada",
0,
"retroceder ",
"ejecutar",
"ejecute principal",
0,
"ejecutar con instrumentación",
"guardar",
"guardado",
"guardando...",
"estudios",
"pantallas",
"captura de pantalla",
"captura de pantalla de {0}",
"script",
"propiedades del script",
0,
"buscar",
"buscar arte",
"buscar imágenes de arte",
"buscar aquí para {0}",
"buscar plantillas",
"buscando...",
"ver más opciones",
"seleccionar",
"seleccionar más",
"selecciona esa línea",
"seleccionar el {0}",
0,0,
"establecer el nombre de la variable local",
"establecer nombre",
"establecer el controlador que se invoca cuando se desliza el panel",
"establecer el controlador que se invoca cuando se pulsa el panel",
"establecer el controlador que se invoca cuando se toca el panel",
"establecer el controlador que se invoca cuando se libera la capacidad táctil del panel",
"establece todos los campos a sus valores predeterminados",
"configuración guardada",
"configuración",
"compartir",
0,
"mostrar cómo completar esta actividad",
"mostrar más opciones",
"presentar",
"iniciar sesión",
0,0,
"cerrar sesión",
"iniciando sesión...",
0,
"simplificar",
"nivel de aptitud guardado",
"saltar iteración",
0,
"social",
0,
"sonido",
0,
"imagen de la pantalla de presentación: {0}",
"dividir",
0,
"volver a empezar",
"iniciando script",
"iniciando...",
0,
"dentro",
"fuera",
"encima",
0,
"detener",
0,
"función detener",
"detener bucle",
"guardar en variable",
"guardar el valor en una variable",
"cadena",
0,
"tira '{0}'",
0,0,0,
"superior, sobrenatural, estupendo, inaudito, sobrenatural, único, sin precedentes, inusual, raro, extraño, fuera de lo común",
"alrededor de",
0,0,
"sincronización de...",
0,0,0,0,0,
"etiquetas",
0,0,
"toca (←) cuando termines",
"toca [ok] cuando termines",
0,
"toca aquí para ir al siguiente paso",
"pulsar aquí cuando termine",
"pulsa aquí",
"pulsar aquí para obtener instrucciones",
"pulsa aquí para ejecutar la aplicación",
"pulsa para cambiar el color",
"tocar para cambiar la imagen del icono",
"tocar para cambiar la imagen de la pantalla de presentación",
"pulsar para traducir con el traductor de Microsoft®...",
"temporal",
"terms of use",
"probar",
"función de prueba",
"pruebas",
"prueba si dos referencias aluden al mismo objeto",
0,0,
"el hub",
"el código de invitación debe ser un número entre 9 y 64 caracteres de largo",
"el script se bloqueó",
0,0,
"este script es una biblioteca",
"este script es un servicio web",
"hora y fecha",
"a código",
"para continuar",
"para variable global",
"alternar punto de interrupción",
"más destacado y nuevo",
0,0,
"traducir",
"traduciendo tutorial...",
0,0,0,
"volver a intentarlo",
"convertir en",
"progreso del tutorial",
"tutorial: ",
"tutoriales",
"usuario de Twitter",
"tipo:",
"tipo: {0}",
0,0,0,
"deshacer",
0,0,0,0,0,0,0,0,0,0,
"actualizar",
0,0,0,0,0,0,
"cargar",
"cargar imagen",
"Cargar captura de pantalla",
"cargar sonido",
0,0,0,
"url",
0,0,0,0,0,
"nombre de la variable",
"ver como script",
"ver/editar nombre, correo electrónico, ...",
0,
"fondo de pantalla",
"tenemos una biblioteca '{0}' aquí; {1}",
"Aquí tenemos un {0:a}; ¿quería hacer algo con él?",
"necesitamos un nuevo campo",
"necesitamos una nueva tabla",
"necesitamos un nuevo {0}",
"necesitamos un teclado numérico diferente",
"necesitamos una nueva variable",
"tenemos que editar otra cosa",
"te guiaremos paso a paso",
"aplicaciones web",
0,0,0,
"sitio web",
0,
"url del sitio web",
0,0,0,0,0,
"año de nacimiento",
0,0,
"¡Lo has conseguido!",
0,
"{0} ({1} línea{1:s})",
"hace {0} día{0:s}",
0,
"{0} falló; ahora estamos en modo offline;\n asegúrate de que tu conexión a internet funcione",
"archivo {0} de {0:s} importados",
"{0} para esta versión",
"hace {0} hora{0:s}",
"hace {0} minuto{0:s}",
"hace {0} mes{0:s}",
"{0} de {1} terminado",
"{0} publicar",
"{0} script{0:s} publicado{0:s}",
"hace {0} segundo{0:s}",
"{0} arriba",
"hace  {0:s}años {0}"
]); return true; }

if (lang == "fi") { TDev.Util._setLanguageArray(keys, [0,0,
" --paikallinen muuttuja",
0,0,0,0,0,0,0,0,0,0,0,0,
"'Javascriptin aaltosulkeet, kaikki työkalut, kokeneille kehittäjille!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", mutta siinä on {0:a}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>tämä rivi on täydellinen!</b> jatketaan",
"<h3>ladataan nykyisiä asetuksia...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Julkisen profiilisi yksilöllinen näyttönimi (vähintään 8 merkkiä)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Kasvattavaa nykyistä pistemäärää.",
0,0,0,0,
"Kaikki skriptini",
0,0,0,0,0,0,0,
"Sivuja ja ruutuja käyttävä tyhjä sovellus.",
"Scratch-kirjastoa käyttävä tyhjä sovellus.",
0,0,0,0,0,0,0,0,
"Kilpikonnasovellus.",
0,0,0,0,
"Tämän käyttäjän kuvat/äänet:",
0,0,
"Koodipohja pelin luomiseen.",
0,0,0,0,0,0,
"Vaihda taitotaso!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Luo koodi",
0,
"Luo skripti",
0,0,0,
"Luo uusi kuvahahmo.",
0,
"Luo uusi skripti",
0,0,0,0,0,
"Luo kanava",
0,0,0,
"Luo omia sovelluksia",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Osuvatko hahmot päällekkäin",
"Haluatko saada TouchDevelop-sovellukseen liittyviä uutiskirjeitä esimerkiksi uusista ominaisuuksista ja tulevista tapahtumista.",
"Asiakirjat",
"Muista siirtyä alaspäin ja napauttaa ”save”, kun et enää tee muutoksia!",
"Vedä ja pudota lohkoja, yksinkertaistettu käyttöliittymä, hyvä vaihtoehto vasta-alkajille!",
0,0,
"Muokkaa koodia tekstinä, lisää toimintoja, haasteita kaipaaville kirjoittajille!",
0,0,0,0,
"Anna joitakin tietoja itsestäsi",
"Anna oman verkkosivustosi URL-osoite (esimerkki:\nhttp://www.northwindtraders.com)",
0,
"Määritä mahdollinen suhteesi kouluun.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Hakee korkeuden kuvapisteinä",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Hakee y-sijainnin kuvapisteinä",
"Aloitus",
0,
"Nykyisen komentosarjan yleiset muuttujat",
0,
"Ohje",
0,0,0,0,
"Miten löysit TouchDevelop-ohjelman?",
0,
"Tuo koodi",
"Tuo skripti tiedostosta",
0,0,0,0,0,0,0,0,0,0,0,0,
"Lisää '{0}' {1}",
0,
"Tähdellä (*) merkityt kohdat ovat pakollisia. ",
0,0,0,0,0,0,0,0,0,0,0,0,
"Saa kaikki pelihahmot ponnahtelemaan näytön reunoista",
0,0,
"Minä",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Lue tietosuojatietomme.",
0,0,0,0,0,0,0,0,0,
"Julkaise skriptisi niin, että kaikki voivat suorittaa sen.",
0,0,0,0,0,
"Vastaanota sähköposti-ilmoituksia, kun muut henkilöt tarkastelevat tai kommentoivat skriptejäsi tai ottavat niistä näyttökuvan tai vastaavat kommentteihisi tai kun ilmenee tilauksiisi liittyviä tapahtumia.",
0,
"Poistaa arvon nykyisestä elämästä.",
0,
"Ilmoita/poista",
0,0,0,0,0,0,0,
"Palauttaa sattumanvaraisen kokonaisluvun ”min”- ja ”max”-arvojen väliltä raja-arvot mukaan lukien.",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Tämän käyttäjän skriptit:",
0,0,
"Hae koodia...",
"Hae kaikki",
"Hae tästä...",
0,0,
"Hae...",
0,0,0,
"Näytä lisää",
0,0,0,0,0,0,0,0,
"Asettaa taustakuvan",
0,
"Asettaa nykyiset elämät.",
0,0,
"Asettaa sijainnin kuvapisteinä",
0,0,0,0,0,0,0,
"Asettaa leveyden kuvapisteinä",
"Asettaa nopeuden x kuvapisteinä/s",
"Asettaa y-kiihtyvyyden kuvapisteinä/s^2",
0,
"Asettaa y-nopeuden kuvapisteinä/s",
0,
"Asetukset",
0,0,0,0,
"Taitotaso: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: if-ehto edellyttää {1:a}",
0,0,0,0,0,0,0,0,0,0,0,
"Opeta luovaa koodausta!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Microsoft® Translator -käännös. Napauta, niin näet alkuperäisen...",
0,0,0,0,
"Opetusohjelmat",
0,0,0,0,0,
"käyttöliittymän pienoissovellus",
0,0,0,0,0,0,0,0,0,
"Muutamme editoria ohjelmoinnin taitotasosi mukaan. Voit vaihtaa taitotasosi myöhemmin keskuksessa.",
"Mikä on ohjelmointitaitojesi taso?",
"Mikä on ammattisi?",
"Uudet ominaisuudet ",
"Missä oikein olet?",
0,0,0,0,0,
"GitHub-käyttäjäsi.",
"Minecraft-käyttäjäsi.",
0,0,
"Kanavasi näkyy tässä",
"Sähköpostiosoitettasi ei ole vahvistettu. Katso Saapuneet-kansiotasi.",
"Koko nimesi",
0,0,0,
"Skriptisi näkyy tässä",
"Twitter-käyttäjänimesi, kuten @touchdevelop.",
"muutama sekunti sitten",
"funktio",
"yleinen muuttuja",
"minuutti sitten",
0,0,0,0,
"tietoja sinusta",
0,0,
"ilmoitukset väärinkäytöstä",
0,0,0,0,0,
"lisää",
0,0,0,0,0,0,0,0,0,0,
"lisätä rivi alapuolelle",
"lisää uusi",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"tunti sitten",
0,0,0,0,0,0,0,
"kuva/ääni",
0,
"tehtävä",
0,0,0,0,0,0,
"askelpalautin",
"poista tämä askelpalauttimella",
0,0,0,
"aloittelija",
"vasta-alkajat",
0,0,0,
"tyhjä sovellus",
0,0,
"tyhjä peli",
0,0,0,
"tyhjä scratch",
0,
"tyhjä kilpikonna",
0,0,0,0,0,0,0,0,0,
"peruuta",
0,0,0,0,
"kanavat",
0,0,0,0,0,0,0,0,0,0,0,
"valitse ohjelmoinnin taitotasosi",
0,0,0,0,
"kloonaa",
0,0,
"koodi",
0,
"koodaaja",
0,0,0,0,0,
"ehtolause",
0,0,0,0,0,
"kopioi",
0,0,
"luo",
0,
"luo kanava",
0,0,0,0,
"luodaan skriptiä",
0,0,
"mukauta kuvitusta!",
"leikkaa",
0,0,0,
"desimaalipiste",
0,0,0,0,0,0,0,0,0,
"tiedot",
0,0,0,0,0,0,
"hylkää",
"näyttöarvo",
0,0,0,0,0,0,
"muokkaa",
0,
"sähköposti",
"sähköposti (yksityinen)",
"sähköposti- ja palveluilmoitukset",
"sähköpostia ei voi tarkistaa, {0}",
0,0,0,0,0,0,0,0,0,
"esim.: ",
0,
"loistavaa; hyvin tehty; mahtavaa; upeaa; sinä olet paras; hyvää työtä; erinomaista; juuri niin; niin sitä pitää",
0,0,
"asiantuntija",
0,0,0,0,0,0,0,0,0,0,
"valmis",
0,
"seuraa opetusohjelmaa editorissa",
0,0,
"funktio",
0,0,
"funktio, muuttuja, kirjasto...",
"sukupuoli",
"hae Hour of Code™ -todistus",
0,
"github-käyttäjä",
0,0,0,
"yleiset muuttujat",
0,
"palaa koodaukseen! {0}★ ja palaa",
0,0,0,
"palaa edelliseen vaiheeseen",
"tavoite:",
0,0,0,
"ohje",
0,0,
"historia",
0,
"miten löytynyt",
0,
"olen saanut oman Hour of Code™ -osuuteni tehtyä",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"lisää",
"lisää kommentti",
"lisää lause",
"lisää {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"opettele",
0,0,0,0,
"muutetaan tätä",
"aloitetaan!",
"käynnistys!",
0,
"kirjastot",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"sijainti",
0,
"looginen negaatio",
0,0,0,0,0,0,0,0,0,
"minecraft-käyttäjä",
0,0,
"lisää",
"lisää ",
"lisää asetuksia",
"siirrä kohdistinta",
0,0,
"siirrä kohdistinta vasemmalle",
"siirrä kohdistinta oikealle",
0,0,0,0,
"omat skriptit",
0,0,0,0,0,0,
"negaatio",
0,0,0,0,0,0,0,0,0,
"uusi muuttuja",
0,
"seuraavat opetusohjelmat...",
"lempinimi",
0,0,0,0,0,0,
"ei aiempaa sähköpostia",
0,0,0,0,0,
"ilmoitukset",
0,0,0,0,0,0,
"ammatti",
0,0,0,0,0,0,0,0,
"yleiskatsaus",
0,0,0,
"jäsennetään skriptin tekstiä",
0,
"liitä",
"tauko",
0,0,
"valitse skriptimalli...",
"kuva",
0,0,0,
"pelaa uudelleen",
0,
"odota...",
0,0,0,0,
"yksityinen",
0,
"yksityinen profiili",
0,
"ohjelmointitaidot",
0,0,0,
"julkinen lempinimi",
"julkinen profiili",
"publish",
0,0,0,0,0,0,0,
"lue lisää...",
0,
"oikea nimi",
"oikea nimi (yksityinen)",
"vastaanota sähköpostitiedotteita",
"vastaanota sähköposti-ilmoitukset",
0,0,0,0,
"poista",
0,
"poista kuva",
0,0,0,
"toista n kertaa",
0,
"toista kunnes",
0,0,0,0,0,0,0,0,0,
"siirrä taaksepäin",
"siirrä taaksepäin ",
"suorita",
"suorita main-osio",
0,0,
"tallenna",
0,
"tallennetaan...",
"koulu",
0,0,0,
"skripti",
"skriptin ominaisuudet",
0,0,
"hae kuvaa/ääntä",
0,
"hae täältä {0}",
"hae malleja",
0,0,
"valitse",
0,
"valitse kyseinen rivi",
0,0,0,0,
"aseta nimi",
0,0,0,0,0,0,0,0,0,0,
"näytä lisää vaihtoehtoja",
"esittely",
0,0,0,
"kirjaudu ulos",
"kirjaudutaan sisään...",
0,0,0,
"keskeytä toisto",
0,0,0,0,0,0,
"jaa",
0,0,0,0,0,0,0,0,0,0,0,
"keskeytä funktio",
"keskeytä silmukka",
0,
"tallenna arvo muuttujaan",
"merkkijono",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"napauta tätä",
0,
"napauta tätä, kun haluat suorittaa sovelluksen",
0,0,0,0,0,
"käyttöehdot",
0,0,0,0,0,0,
"keskus",
0,0,0,0,0,0,0,0,
"jatka",
"yleisiin muuttuj",
0,0,0,0,0,0,0,0,0,
"yritä uudelleen!",
"muunna muotoon",
"opetusohjelman eteneminen",
"opetusohjelma: ",
"opetusohjelmat",
"twitter-käyttäjänimi",
"tyyppi: ",
"tyyppi: {0}",
0,0,0,
"kumoa",
0,0,0,
"poista asennus",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"näytä/muokkaa: nimi, sähköposti, ...",
0,
"taustakuva",
0,
"tässä on {0:a}; halusitko tehdä sille jotakin?",
0,0,0,0,0,0,
"opastamme sinua vaihe vaiheelta",
0,0,0,0,
"verkkosivusto",
0,
"verkkosivuston URL-osoite",
0,0,0,0,0,
"syntymävuosi",
0,0,0,0,0,
"{0} päivää sitten",
0,0,0,0,0,
"{0} minuuttia sitten",
"{0} kuukautta sitten",
0,0,0,
"{0} sekuntia sitten",
0,
"{0} vuotta sitten",
0,0,
"● Kirjaudu sisään"
]); return true; }

if (lang == "fr") { TDev.Util._setLanguageArray(keys, [0,0,
" -- une variable locale",
" [class]",
" [masqué]",
" [override]",
0,0,
" heures ",
" minutes ",
" de ",
" secondes ",
" envoi des modifications",
" en attente du serveur",
"### code source complet",
"Accolades Javascript, tous les outils, pour les développeurs avertis !",
"fonction 'atomic'",
0,0,0,0,
"'{0}' attend {1} ici",
0,0,0,
"« {0} » est obsolète et ne doit pas être utilisé",
0,
"'{0}' renvoie un '{1}' ; {2}",
0,0,0,0,0,0,0,0,
", devienne {0:a} à la place",
", a obtenu {0}",
0,0,0,
"... il y a plus ...",
"// commentaire",
0,0,0,0,
"4. publier",
0,0,0,0,0,0,0,
"<b>Avertissement :</b> Cette application web n'est pas approuvée par Microsoft.",
0,
"<b>Cette ligne est parfaite !</b> Poursuivons.",
"<h3>chargement des paramètres actuels...</h3>",
"<h3>plus d'indices!</h3>",
0,
"<h3>{0:q} nécessite de se connecter</h3>",
0,0,
"<p>Vous pouvez partager vos applications avec d'autres, afin qu'ils puissent <b>exécuter et modifier</b> sur Windows Phone, iPad, iPhone, Android, PC ou Mac.</p>",
0,0,0,0,0,0,
"Application Minecraft Pi.",
"Application Minecraft.",
"Application Minecraft Creeper.",
0,0,
"Une couleur argb (alpha, rouge, vert, bleu)",
0,0,0,0,0,
"Une collection d'objets",
0,
"Une constante (couleur)",
"Une combinaison de date et d'heure",
0,
"Un contact",
0,
"Un document",
0,0,0,0,
"Une variable globale",
0,0,0,0,0,0,0,0,0,0,0,
"Nombre (éventuellement négatif et/ou décimal)",
"Une constante (chiffre)",
0,0,0,
"Une image",
"Extrait de texte",
"Application Pixel Art.",
"Un endroit pour accrocher une action à exécuter en réponse à un événement",
0,0,
"Une référence à un script bibliothèque",
0,0,0,0,0,0,0,0,0,
"Son",
0,0,0,0,
"Structure de données utilisateur",
"Une table de lignes définies par l'utilisateur",
0,0,0,
"Une zone de texte",
"Une minuterie",
"Nom complet unique pour votre profil public (au moins 8 caractères)",
0,
"Un compte utilisateur",
"Une interface utilisateur",
0,0,
"Script de ADJ",
"Configuration de l'API",
0,0,0,0,
"Accéléromètre",
0,0,0,0,0,
"Ajouter une action qui se déclenche pour chaque image affichée",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Ajoute un objet",
"Ajoute plusieurs objets à la fois",
"Ajoute des nombres",
0,
"Ajoute une valeur au score actuel.",
0,0,
"Après que le script s'arrête, parcourir le code pour voir les informations collectées.",
"Tous mes groupes",
"Tous mes scripts",
"Toutes les options sont activées",
0,0,
"Autorise l'utilisateur à enregistrer le numéro de téléphone",
0,0,0,
"Application vide utilisant des pages et des zones.",
"Application vide utilisant la bibliothèque Scratch.",
"Page de documentation vierge.",
"Didacticiel interactif vide.",
"Plug-in d’éditeur de script vide.",
"Un script vide, qui ne fait rien.",
0,0,
"Une table indexée de lignes définies par l'utilisateur",
0,
"Application Turtle.",
"Applique 'converter' à tous les éléments de la collection d'entrée et retourne une collection de résultats",
"Avez-vous fini de coder?",
"Voulez-vous vraiment arrêter le didacticiel ?",
"Opérations arithmétiques et opérations de bits sur les entiers de 32 bits",
"Image de cet utilisateur :",
"Demander ou afficher des valeurs sur le mur...",
"Attacher les données à d’autres objets",
"Code réutilisable pour créer un jeu.",
"Parcourir et examiner les scripts du bazar",
0,0,
"Caméra, micro, localisation et autres capteurs",
0,0,
"Changer le niveau de compétence!",
"Chaînes",
"Vérifie si le tableau est la même instance que l’autre tableau.",
"Vérifie si la couleur est égale à l'autre",
"Vérifie si deux textes sont identiques",
"Choisit une image de la Médiathèque",
"Effacer tous les événements en attente pour ce tableau",
"Effacer l’image d’arrière-plan",
"Effacer la caméra d’arrière-plan",
"Données du Cloud",
"Gestion de session du cloud",
"Code évoqué lors d'une interaction de utilisateur",
"Code qui effectue une tâche spécifique",
"Compare les nombres égaux",
"Compare les nombres inférieurs",
"Compare les nombres inférieurs ou égaux",
"Compare les chiffres pour en savoir plus",
"Compare les nombres supérieurs ou égaux",
0,
"Calcule la moyenne",
0,
"Calcule le maximum des valeurs",
"Calcule le minimum des valeurs",
"Calcule la somme",
"Concaténer deux morceaux de texte",
0,
"Convertit un nombre en texte",
"Convertit en une date (type doit être ``string``)",
"Convertit la valeur en une structure de données JSON.",
"Convertit en une valeur booléenne (type doit être ``boolean``)",
"Convertit un nombre (type doit être number)",
"Convertit en heure locale",
0,0,
"Aides pour l'exactitude",
0,0,
"Créer un groupe",
"Créez un Script",
"Créez un obstacle ligne avec le point de départ et les dimensions (largeur/hauteur) spécifiés. L’élasticité est 0 pour aucun rebond et 1 pour un rebond complet.",
"Créer une nouvelle collection de ``sprites``.",
"Créer un sprite d’ellipse.",
"Créez un nouveau sprite d’image.",
"Créer un nouveau \"sprite\" rectangle.",
0,
"Créez une feuille de sprites.",
"Créer un nouveau sprite de texte.",
"Créez un sprite entre les deux sprites.",
"Créez un sprite d’ancrage.",
"Créer une valeur non valide sur ce type d’objet",
"Créer une chaîne",
"Créer une collection d'éléments.",
"Créer des valeurs non valides",
"Créez des murs autour du tableau à la distance spécifiée.",
"Créez vos propres applications",
0,
"Crée une nouvelle couleur en changeant le canal alpha de 0 (transparent) à 1 (opaque).",
"Crée un tableau de jeu vide et l’affiche à l’écran.",
0,0,0,
"Crée un sprite de 100 de largeur avec l’image spécifiée.",
"Crée une collection de Picture vide",
"Crée une instance du tableau de bord non valide",
0,
"Élément 'box' courant dans la page.",
"périphérique actuel",
0,
"Point tactile actuel",
"Détache le gestionnaire de l'événement.",
"Affiche le texte à l'écran",
"Affiche l'image sur le mur ; vous devez activer la fonction 'update on wall' si vous voulez que les changements apparaissent.",
"Affiche le lien sur le mur",
"Affiche la requête à l'écran",
"Affiche la ``sprite sheet``.",
"Affiche l’état du tableau de bord sur le mur",
"Divise des nombres",
"Les lutins se chevauchent-ils",
0,
"Docs",
"N’oubliez pas de faire défiler vers le bas et d’appuyer sur « Enregistrer » quand vous avez terminé vos modifications !",
"Blocs à déplacer, interface simplifiée, parfait pour les débutants !",
"Dessine une ligne entre deux points",
"Trace la bordure d'un texte avec une couleur et taille de police spécifiques",
"Code à modifier en texte, options supplémentaires, pour les apprentis développeurs d’applications !",
"E-mails, sms, contacts, calendrier, ...",
0,
"Entrez un nom",
"Entrez un nom pour le script...",
"Entrez des informations vous concernant",
"Entrez l’URL de votre site web personnel (exemple : http://www.northwindtraders.com)",
"Entrez le code d’invitation",
0,
"Les événements ne peuvent pas avoir de paramètres out.",
"Tout le monde pourra voir votre image sur Internet. ",
0,
"Exporte une représentation JSON du contenu.",
"Extensions",
"Facebook",
"Remplit une ellipse avec une couleur donnée",
"Remplit un rectangle avec une couleur donnée",
"Vitesse tactile finale après l’arrêt de l’action tactile",
"Pour les scripts publiés, regardez également sur l'onglet de la page de script publié pour trouver des données de couverture et de profil enrichies par les utilisateurs de façon anonyme.",
"Forums",
"A partir de maintenant, on ne vous montrera plus le code à insérer. Suivez les instructions et tapez \"exécuter\" quand vous avez finit.",
"Fonctions contenues dans le script actuel",
"Coordonnées géographique",
"Obtient une valeur de champ comme un type boolean",
"Obtient une valeur du champ sous forme de nombre",
"Obtient une valeur de champ sous forme de chaîne",
"Obtient a sorte de json (``string``, ``number``, ``object``, ``array``, ``boolean``, ``null``)",
"Obtient un instantané des états du tableau de bord (si connecté au navigateur). Vide en l’absence d’un tableau de bord pris en charge ou connecté.",
"Obtient un url vers l'image",
"Obtient une valeur par nom",
"Obtient une valeur indiquant si le fond se répète horizontalement",
"Obtient une valeur qui indique si le tableau peut être affiché en mode paysage",
"Permet d'obtenir une valeur si la chanson est protégée par la gestion des droits numériques DRM",
"Obtient les valeurs x et y des axes sélectionnés.",
"Obtient l'accélération le long de y en ``pixels/s^2``",
"Obtient la couleur d'accent dans le thème actuel",
"Obtient le décor d’arrière-plan",
"Permet d'obtenir la position centrée horizontalement en pixels",
"Obtient la couleur de chrome dans le thème actuel (arrière-plan de contrôle)",
"Obtient la couleur qui a la valeur ARVB de #00FFFFFF",
"Obtient la couleur qui a la valeur ARVB de #FF000000",
"Obtient la couleur qui a la valeur ARVB de #FF0000FF",
"Obtient la couleur qui a la valeur ARVB de #FF008000",
"Obtient la couleur qui a la valeur ARVB de #FF00FFFF",
0,
"Obtient la couleur qui a la valeur ARVB de #FF800080",
0,0,0,0,
"Obtient la couleur qui a la valeur ARVB de #FFFF0000",
"Obtient la couleur qui a la valeur ARVB de #FFFF00FF",
"Obtient la couleur qui a la valeur ARVB de #FFFFA500",
0,
"Obtient la couleur qui a la valeur ARVB de #FFFFFF00",
"Obtient la couleur qui a la valeur ARVB de #FFFFFFFF",
0,0,
"Obtient la durée en secondes",
"Obtient la valeur du champ sous forme de temps",
"Obtient le premier tableau de bord connecté disponible",
"Obtient la couleur de premier plan dans le thème actuel",
"Obtient l’identificateur du tableau de bord",
"Obtient le genre de la chanson",
"Obtient la hauteur en pixels",
"Permet d'obtenir la hauteur de l'image de la caméra en pixels.",
"Renvoie la i-ème valeur json",
"Obtient le lien associé au message",
"Obtient la liste des clés",
"Obtient le nom de l'artiste",
"Obtient le nom de la chanson",
"Obtient les noms des \"headers\"",
"Récupère la valeur normalisée de rouge (0.0-1.0)",
"Obtient le nombre d'éléments",
"Obtient le nombre de valeurs",
"Obtient l’index du lecteur",
"Obtient la valeur d’un bouton appuyé. Retourne 0 s’il n’y a pas de bouton.",
0,
"Permet d'obtenir le volume sonore pour des sons allant de 0 (silencieux) à 1 (volume actuel)",
"Obtient le nombre de sprites",
"Obtient le sprite d’index i",
"Obtient le texte",
"Obtient l’horodatage de cet instantané",
"Obtient la valeur d'un \"header\" donné",
"Obtient la largeur en pixels",
"Permet d'obtenir la largeur de l'image de la caméra en pixels.",
"Obtient la position y en pixels",
"Mise en route",
0,
"Variables globales contenues dans le script actuel",
0,0,
"Cacher le sprite.",
0,0,0,0,0,0,0,
"Importe une représentation JSON du contenu.",
0,0,
"En mode de débogage, affiche les vitesse et autres infos de \"sprites\"",
"Indique si un bouton est appuyé. Retourne false s’il n’y a pas de bouton.",
0,
"Indique si les données du tableau de bord sont identiques",
"Indique si le tableau de bord est encore connecté.",
"Indique si la clé existe",
"Indique si le lecteur est en mode pause",
"Indique si le lecteur est arrêté",
"Indique si le texte est vide",
"Insérer '{0}' {1}",
"Interagissent avec le runtime de l'application",
"Les éléments marqués d’un * sont obligatoires.",
"données JSON",
"Joindre un groupe",
"Dernier point tactile de fin",
"Dernier point tactile de départ",
0,0,0,0,0,
"Affichez les mises à jour.",
"Crée une couleur plus foncée suivant un delta compris entre 0 et 1.",
"Crée une couleur plus claire suivant un delta compris entre 0 et 1.",
"Fait rebondir tous les sprites sur le bord de l’écran",
"Cartes, localisation d'adresse, adresse de l'emplacement",
"Les maths dans toute leur splendeur : abs, max, etc, ...",
"Me",
0,
"Utilisateur Minecraft",
"Plus",
0,
"Déplace un sprite vers un autre.",
"Multiplie des nombres",
0,0,0,0,0,0,0,0,
"Nouveaux Scripts",
0,
"Couleurs nouvelles ou intégrées",
0,0,0,0,0,0,0,0,0,0,0,0,
"Convertit le texte en nombre",
0,
"Numéros de téléphone, vibrer, etc...",
"Sélectionne une couleur d'une roue de couleur où la teinte est comprise entre 0 et 1.",
"Sélectionne une couleur au hasard",
"Images et musique...",
0,
"Jouer, arrêter ou reprendre les chansons...",
"Joue la chanson.",
0,0,
"Veuillez lire notre Déclaration de confidentialité.",
"veuillez patienter...",
"Publier un commentaire...",
"Imprime le nombre sur le mur",
"Imprime le contenu du \"wall\"",
0,
"Une action privée n’a pas de bouton d’exécution. ",
"Invite l'utilisateur à entrer un nombre",
0,
"Script de publication",
0,
"La publication est soumise à nos ",
"Publication du script en cours...",
"Se déclenche au démarrage de la lecture de l’animation",
"Se déclenche à l’arrêt de la lecture de l’animation",
"Lit la réponse comme un son Wave",
"Recevez des notifications par e-mail quand des personnes consultent ou commentent vos scripts, quand elles en font une capture instantanée, quand elles répondent à l'un de vos commentaires ou encore quand des événements concernant vos abonnements se produisent.",
"Rappel : Votre script est visible par tous dès sa publication. Veillez à ce qu’il ne contienne aucun mot de passe ni aucune information personnelle.",
"Supprime la valeur de la vie en cours.",
"Répondre...",
"Rapporter/Supprimer",
"Redimensionne l'image à la taille donnée en pixels",
"Retourne une collection triée à l'aide de la clé de comparaison",
"Renvoie une copie de l'image",
0,0,
"Renvoie une date qui ajoute le nombre spécifié de mois à la valeur de cette instance.",
"Renvoie une date qui ajoute le nombre spécifié d'années à la valeur de cette instance.",
"Retourne un nombre entier aléatoire entre `min` et `max` inclus.",
"Retourne une collection de chaînes qui contient les sous-chaînes de cette chaîne qui sont délimitées par les éléments d'une chaîne spécifiée.",
"Retourne une sous-chaîne à partir d'un index de début et d'une longueur",
0,
"Renvoie le nombre de caractères",
0,
"Retourne la couleur du \"sprite\".",
0,
"Renvoie true si cette instance est inutile",
0,
"Exécuter l'action incluse.",
0,0,
"Mises à jour des scripts",
"Scripts de cet utilisateur :",
0,
"Rechercher et naviguer le web...",
"Chercher un code...",
"Tout rechercher",
"Chercher ici...",
0,0,
"Rechercher...",
0,0,0,
"Voir Plus",
0,
"Définit une valeur indiquant si le fond se répète horizontalement",
"Active ou désactive le dégradé",
"Définit la transformation affine de matrice 3x3 appliquée au mur.",
"Spécifie l'angle du \"sprite\" en degrés",
"Définit la caméra d’arrière-plan",
"Spécifie la couleur d'arrière-plan",
"Définit la couleur d’arrière-plan.",
"Définit l’image d’arrière-plan",
"Spécifie la position centrée horizontalement en pixels",
"Définit les points de vie actuels.",
"Définit la friction par défaut pour les sprites à une fraction de la perte de vitesse entre 0 et 1",
"Spécifie la hauteur en pixels",
"Spécifie la position en pixels",
"Spécifie la vitesse de rotation en degrés/sec",
"Définit le niveau du volume sonore de 0 (silencieux) à 1 (volume actuel)",
"Spécifie la vitesse en pixels/sec",
"Spécifie la couleur du sprite.",
"Définit le vecteur d’accélération constant pour les objets du tableau à pixels/sec^2",
"Spécifie l'url de l'image",
"Définit l'image d'arrière-plan du mur. L'image sera redimensionnée et découpée sur le fond d'écran au besoin.",
"Spécifie la largeur en pixels",
"Spécifie la vitesse x en pixels/sec",
"Spécifie l'accélération y en pixels/s^2",
"Spécifie la position y en pixels",
"Définit la vitesse y en pixels/sec",
"Spécifie l'index-z du sprite",
"Paramètres",
"Partagez-le avec cette URL :",
"Afficher les erreurs dans l'éditeur si le script utilise une interface API qui empêche l'exécution sur ces plateformes.",
"Affiche le tableau sur le mur.",
0,
"Niveau de compétence : {0}     ",
"Trie du plus récent au plus ancien",
"Trie les lieux par la distance et l'emplacement",
"Trie cette collection",
"Spécifie comment organiser le contenu de cette boîte",
"Commence une nouvelle animation.",
"Arrête et efface les minuteurs de chaque image",
"Convertit l'object JSON en texte",
"Soustrait des nombres",
"Support pour des didacticiels interactifs.",
"TD100: insérez un {0:a} ici",
"TD101: impossible de trouver '{0}'",
"TD109: impossible d'attribuer à celui-ci",
"TD111: impossible d'attribuer de {0} à {1}",
"TD112: je ne peux pas trouver la propriété '{0}' sur {1}",
"TD115: trop de paramètres fournis à {0}",
"TD116: nombre insuffisant de paramètres fournis à {0}",
"TD118: la condition 'if' veut {1:a}",
"TD119 : j’ai besoin d’un élément sur lequel itérer",
0,
"TD130: limite de 'for' veut {1:a}",
"TD144: il semble qu'il vous manque '{0}', essayez de l'ajouter",
"TD145: il semble qu'il manque un opérateur (comme '+' ou ',')",
"TD147: on ne s'attend pas à '{0}' ici",
"TD150: impossible d’appeler l’élément avant '('",
"TD151: TD151 : '(' non fermée",
"TD152: inattendu ')'",
"TD154: l'opérateur doit être suivi de quelque chose",
"TD155: '{0}' ne peut pas être attribué à une variable locale",
"Enseignez Creative Coding !",
0,0,0,0,0,0,0,0,0,
"Chose",
0,0,0,0,0,0,0,
"Ce script utilise les fonctionnalités suivantes : ",
0,
"Ce didacticiel utilise des données du cloud qui sont partagées avec d'autres utilisateurs.",
"Pour ajouter des données de page, créez une variable locale et appuyez sur 'promote to field'.",
0,0,0,
"Traduction, dictation, ...",
"Traductions fournies par \\\"Microsoft®Translator\\\", cliquez pour voir l'original...",
"True si le tableau est touché",
"Essayez de changer votre code. If vous êtes bloqué, tapez sur le menu du tutoriel.",
0,0,
"Didacticiels",
"Twitter",
"Faire une recherche en ligne...",
"Tapez pour rechercher...",
0,
"Les types, l’ordre et le nombre de paramètres d’événement ne peuvent pas être modifiés.",
"Widget de UI",
0,
"Mettez à jour les emplacements des sprites sur le tableau.",
"Met à jour une image sur une image de lutin (le cas échéant)",
"Mises à jour du texte sur un sprite de texte",
"Charger une image",
"Charger un son",
"Utilisateurs",
0,
"Nous avons besoin de plus d'options",
"Nous adapterons l’éditeur à votre niveau de compétence en code. Vous pouvez changer votre niveau de compétence plus tard dans le hub.",
"Quel est le niveau de vos connaissances en programmation ?",
"Quelle est votre profession ?",
"Nouveautés",
"Où habitez-vous ?",
"Dessine une autre image à un endroit donné. La gamme de l'opacité va de 0 (transparent) à 1 (opaque).",
0,
"YouTube",
0,0,
"Votre utilisateur GitHub.",
"Votre utilisateur Minecraft.",
"Votre art apparaîtra ici",
0,
"Votre chaîne apparaîtra ici",
"Votre adresse e-mail n'a pas encore été vérifiée. Consultez votre boîte de réception.",
"Votre nom complet",
0,0,0,
"Votre script apparaîtra ici",
"Votre pseudo twitter, tel que @touchdevelop.",
"il y a quelques secondes",
"une fonction",
"une variable globale",
"il y a une minute",
"une page",
"à propos de la couverture",
"à propos des aperçus",
"à propos du profil",
"informations personnelles",
"abus",
0,
"rapports d’abus",
0,0,0,
"accéder au champ {0}",
0,
"ajouter",
"ajouter un nouvel élément...",
0,
"ajouter une action qui se déclenche pour chaque image de l'animation",
0,
"ajouter un commentaire pour ce champ",
0,0,0,
"ajouter le paramètre d'entrée",
"ajouter une ligne ci-dessus",
"ajouter une ligne ci-dessous",
"ajouter nouvelle",
0,
"ajouter une option",
"ajouter le paramètre de sortie",
0,0,
"ajouter {0}",
0,0,
"toutes les APIs",
"autoriser",
"extraordinaire, étonnant, stupéfiant, imposant, impressionnant, à couper le souffle, classique, super, curieux, différent, exceptionnel, incomparable, splendide, fabuleux, fantastique, magnifique, géant, ",
0,
"une définition de type de fonction",
"il y a une heure",
0,0,0,0,0,
"applications",
0,
"art",
"ressource d'art",
"devoir",
0,
"auteur",
0,0,
"précédent",
0,
"retour arrière",
"effacez ceci",
0,0,
"base",
"débutant",
"débutants",
0,
"liée au script :",
"vide",
"application vide",
"creeper vide",
"documents vierges",
"jeu vide",
"minecraft vide",
"minecraft pi vide",
"pixel art vide",
"scratch vide",
"plug-in de script vide",
"turtle vide",
"didacticiel vide",
"interrompre le débogueur",
"point d'arrêt",
0,0,0,0,0,0,
"annuler",
"ne peut pas synchroniser - vous n'êtes pas connecté",
0,
"revenir en local",
"modifiez le contenu",
"chaînes",
"vérifie si la référence n’a pas été définie",
0,0,0,
"choisissez une image (taille inférieure à 1 Mo et à 2048 x 2048)",
0,0,0,0,0,0,
"choisir votre niveau de compétence en code",
"choisir...",
0,
"effacer",
"presse-papiers",
"clone",
0,
"sessions Cloud",
"code",
"codez la ligne d'objectif",
"développeur",
"couleur n°{0}",
"couleur : {0}",
"placer en commentaire",
"commentaires",
"compiler",
"conditionnel",
"connecté",
0,0,
"continuer",
0,
"copier",
"coller la sélection",
"couverture",
"créer",
"créer un nouveau paramètre",
0,0,0,0,
"crée une collection d’objets vide",
"création d'un script",
"actuel",
"expression courante",
"personnaliser l’image clipart",
"couper",
"couper la sélection",
"base de données",
"déboguer",
"point décimal",
"décorateurs",
"supprimer",
"supprimer les données locales et les autorisations",
"supprimer la sélection",
"rétrograder en variable",
"refuser",
"description",
"description (facilite la recherche)",
0,
"détails",
"vouliez-vous utiliser cette valeur ?",
"diff. actuelle",
"diff. préc",
0,0,0,
"annuler",
"afficher la valeur",
"affiche l’objet sur le mur",
0,0,0,
"terminée",
"terminé !",
"modifier",
"else if",
"e-mail",
0,
"e-mail et notifications push",
0,0,0,
"entrez un numéro",
"entrer le code d’invitation",
"entrez ce code",
"erreurs",
0,
"événements",
0,
"ex. : ",
0,
"excellent ; bon travail ; magnifique ; super ; vous êtes fabuleux ; très bien ; incroyable ; vous avez réussi ; parfait",
0,
"sortir",
"expert",
0,
"exporter",
"exporter une représentation JSON du contenu",
"exporté de cette bibliothèque",
"étendre",
0,
"extraire la sélection et l’ajouter dans la fonction",
"extrait au paramètre",
"extraire en var",
"trouver des références",
"terminé",
"corrigez-le",
"suivre le didacticiel dans l'éditeur",
"pour le groupe",
"bifurcations",
"fonction",
"nom de la fonction",
"types de fonction",
"fonction, variable, bibliothèque, etc.",
"homme/femme",
"obtenir mon certificat Heure de Code™",
"obtient le minuteur qui se déclenche pour chaque image affichée.",
"utilisateur github",
"♥ donné",
"remplacement global",
"variable globale",
"variables globales",
"retour",
"retournez au code ! encore {0} ★",
"retour...",
"aller à",
"accédez à liste de choses dans votre script",
"revenir à l’étape précédente",
"objectif :",
"groupe",
"groupes",
"coeurs",
"aide",
0,0,
"histoire",
"super, le script est publié",
"comment nous avez-vous trouvés",
"je veux l'exécuter sur",
"j'ai terminé ma session Heure de Code™",
"image d’icône : {0}",
"si",
"si vous êtes bloqué, appuyez sur la ligne d'objectif",
0,0,0,0,
"importer des valeurs de champ à partir d’un objet JSON",
0,0,0,
"dans cette fonction",
"incroyable, magique, merveilleux, époustouflant, ahurissant, particulier, phénoménal, génial, rock and roll, spécial, spectaculaire, surprenant, éblouissant, super-génial, ",
0,
"insérer",
"insérer commentaire",
"insérer une instruction",
"insérer {0}",
"aperçus",
0,
"installation et chargement de script",
"en locale",
0,
"problèmes",
"joindre un groupe",
"joindre un groupe",
0,
"continuez simplement à taper les termes de recherche !",
"continuer à modifier",
"dénommée ici :",
0,
"apprendre",
"en savoir plus sur la publication",
"en savoir plus",
"en savoir plus sur {0}",
"quitter le didacticiel",
"modifier",
"c'est parti !",
"c'est parti !",
"lib",
"bibliothèques",
"bibliothèque",
"nom de la bibliothèque",
"référence de la bibliothèque",
"charger plus",
"charger plus de réponses",
"chargement en cours",
"téléchargement des ressources en cours...",
"chargement de commentaires pour /{0}...",
"téléchargement en cours...",
"chargement des réponses...",
"chargement du script",
"chargement du didacticiel",
"téléchargement en cours...",
"local",
"lieu de résidence",
0,
"négation logique",
"journaux",
"principal",
0,
"fabricants",
"gestion des données",
"peut-être plus tard",
"moi",
0,0,
"utilisateur minecraft",
0,0,
"plus",
"plus ",
"plus de paramètres",
"déplacer curseur",
"aller à gauche",
"passe à l’étape suivante",
"déplacer le curseur à gauche",
"déplacer le curseur vers la droite",
"mon art",
0,0,0,
"mes scripts",
"besoin d'un autre nom ici",
"une chaîne différente est attendue ici",
"nouveau champ nécessaire ici",
"un paramètre est nécessaire",
"nécessité de supprimer ce",
"besoin d'éditer ailleurs",
"négation",
0,0,0,0,
"nouvelle ligne",
0,0,0,
"nouveau stmt ci-dessous",
"nouvelle variable",
0,
"didacticiels suivants...",
"surnom",
"non",
"aucune image clipart publiée par cet utilisateur",
"pas de commentaires, appuyez pour en écrire !",
"aucune bifurcation, installez, modifiez et republiez le script pour en créer une !",
"aucun cœur. vous pouvez en ajouter un après que vous avez installé le script !",
"aucune image téléchargée",
0,0,
"aucune balise, appuyez pour en ajouter !",
0,0,0,
"notifications",
0,
"vous pouvez désormais sélectionner une propriété de {0} ; elle ne fait rien par elle-même",
"vous pouvez sélectionner une propriété là-dessus",
"nombre",
"entrée de numéro",
"objets",
"profession",
"d'un objet",
"disponible hors ligne",
"oK",
"ok, c'est compris!",
"en ligne",
0,
"ou appuyez pour obtenir de l'aide",
"autres",
"vue d'ensemble",
0,
"pages",
0,
"analyse du texte de script",
0,
"coller",
"pause",
0,
"kit de démarrage jeu de physique",
"sélectionnez un modèle de script...",
"image",
"nom de l’image",
"nom de l’image (4 caractères au minimum)",
"url de l’image",
"rejouer",
0,
"veuillez patienter...",
"plugins",
"aperçu",
"imprimer",
0,
"privé",
"fonction privée",
"profil privé",
"profil",
"connaissances en programmation",
"progression",
"promouvoir comme données",
"promouvoir en champ",
"surnom public",
"profil public",
"publier",
"publier sous la forme masquée",
"publier votre script",
"publiée ",
"extraire les modifications",
"extraire au block supérieur",
0,
"ré-exécuter",
"lire la suite...",
"lecture seule",
"vrai nom",
0,
"recevoir les newsletters par e-mail",
"recevoir des notifications par e-mail",
"nom de l'enregistrement :",
0,
"clavier habituel",
"rechargement du script",
"supprimer",
0,
"supprimer l’image",
"supprimer l’arrière-plan blanc (recommandé pour les sprites de jeu)",
0,
"renommer",
"répéter n fois",
"répéter sur la collection",
"répéter pendant",
"remplacer tout dans la fonction",
"remplacer tout dans le script",
"remplacer l'image",
"répliqué",
"répliqué ",
0,
"signaler un abus",
"continuer",
"revenir à la version publiée",
"revenir en arrière",
"revenir en arrière ",
"exécuter",
"exécuter main",
"exécuter les tests",
"exécuter avec instrumentation",
"enregistrer",
"enregistré",
"enregistrement...",
"établissement scolaire",
"écrans",
"capture d'écran",
"capture d’écran de {0}",
"script",
"propriétés du script",
"scripts",
"recherche",
"rechercher des images clipart",
"rechercher des images artistiques",
"rechercher ici pour {0}",
"rechercher des modèles",
"recherche en cours...",
"afficher plus d’options",
"sélectionner",
"sélectionner plusieurs",
"sélectionner cette ligne",
"Sélectionnez le type de ce {0}",
0,0,
"spécifiez le nom de la variable locale",
"spécifier le nom",
"définir le gestionnaire appelé lors d’un balayage sur le tableau",
"définissez le gestionnaire qui est invoqué en appuyant sur le tableau",
"définir le gestionnaire appelé quand le tableau est touché",
"définir le gestionnaire appelé quand le tableau n’est plus touché",
"définit tous les champs à leurs valeurs par défaut",
"paramètre enregistré",
"paramètres",
"partager",
0,
"indiquer comment terminer cette activité",
"afficher plus d’options",
"vitrine",
"connexion",
0,0,
"déconnexion",
"connexion...",
0,
"simplifier",
"niveau de compétence enregistré",
"ignorer l’itération",
0,
"social",
0,
"son",
0,
"image d’écran de démarrage : {0}",
"partager",
0,
"recommencer",
"démarrage du script",
"début...",
0,
"entrer",
"sortir",
"passer par-dessus",
0,
"arrêter",
0,
"arrêter la fonction",
"arrêter la boucle",
"stocker dans variable",
"stocker la valeur dans une variable",
"chaîne",
0,
"bande de « {0} »",
0,0,0,
"supérieur, surnaturel, énorme, hallucinant, étrange, unique, inédit, original, bizarre, remarquable, fascinant",
"entourer de",
0,0,
"la synchronisation...",
0,0,0,0,0,
"tags",
0,0,
"appuyez sur (←) quand vous avez terminé",
"appuie sur [ok] quand tu as terminé",
0,
"appuie ici pour passer à l’étape suivante",
"appuyez ici quand vous avez terminé",
"appuyez ici",
"appuyez ici pour obtenir des instructions",
"appuyez ici pour exécuter votre application",
"appuyez pour changer la couleur",
"appuyez pour changer l’image d’icône",
"appuyez pour changer l’image d’écran de démarrage",
"appuyez pour traduire avec \\\"Microsoft® Translator...\\\"",
"temporaire",
"terms of use",
"test",
"fonction de test",
"tests",
"teste si deux références renvoient vers le même objet",
0,0,
"le hub",
"le code d’invitation doit être un nombre composé de 9 à 64 caractères",
"échec du script",
0,0,
"ce script est une bibliothèque",
"ce script est un service web",
"dates",
"vers code",
"pour continuer",
"convertir en variable globale",
"basculer vers le point de rupture",
"top & nouveau",
0,0,
"traduire",
"traduction du didacticiel...",
0,0,0,
"réessayez!",
"transformer en",
"avancement du didacticiel",
"didacticiel : ",
"didacticiels",
"pseudo twitter",
"type : ",
"type : {0}",
0,0,0,
"annuler",
0,0,0,0,0,0,0,0,0,0,
"mettre à jour",
0,0,0,0,0,0,
"télécharger",
"charger une image",
"télécharger une capture d'écran",
"charger un son",
0,0,0,
"url",
0,0,
"utilisateurs",
0,0,
"nom de la variable",
"voir comme un script",
"afficher/modifier le nom, l’adresse e-mail...",
0,
"papier peint",
"nous avons une bibliothèque {0} ici ; {1}",
"Ici, nous avons {0:a} ; vouliez-vous vous en servir ?",
"nous avons besoin d'un nouveau champ",
"nous avons besoin d'une nouvelle table",
"nous avons besoin d'un nouveau {0}",
"nous avons besoin d'un autre clavier",
"nous avons besoin d'une nouvelle variable",
"nous devons encore faire une modification",
"nous allons vous guider pas à pas",
"applications web",
0,0,0,
"site web",
0,
"URL du site web",
0,0,0,0,0,
"année de naissance",
"oui",
0,
"vous avez réussi !",
"votre meilleur score : {0}",
"{0} ({1} ligne{1:s})",
"il y a {0} jour{0:s}",
"{0} vers le bas",
0,0,0,
"il y a {0} heure{0:s}",
"il y a {0} minute{0:s}",
"il y a {0} mois{0:s}",
"{0} sur {1} effectué",
"{0} publiés",
"{0} script publié{0:s}",
"il y a {0} seconde{0:s}",
"{0} vers le haut",
"il y a {0} années{0:s}"
]); return true; }

if (lang == "he") { TDev.Util._setLanguageArray(keys, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"חיפוש...",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"עוד",
0,0,0,0,0,0,0,0,0,0,0,
"הסקריפטים שלי",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"הקש שם"
]); return true; }

if (lang == "hi") { TDev.Util._setLanguageArray(keys, [0,0,
" -- स्‍थानीय वेरिएबल",
0,0,0,0,0,0,0,0,0,0,0,0,
"'Javascripty' curly braces, सभी टूल, अनुभवी डेवलपरों के लिए!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", उसके बजाय {0:a} आ गया",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>यह पंक्ति एकदम ठीक है!</b> आगे बढ़ते हैं",
"<h3>वर्तमान सेटिंग लोड हो रही है...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"आपकी सार्वजनिक प्रोफाइल के लिए विशिष्‍ट प्रदर्शित नाम (कम से कम 8 अक्षर)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"मौजूदा स्कोर में मान जोड़ता है।",
0,0,0,0,
"मेरी सभी स्क्रिप्‍ट",
0,0,0,0,0,0,0,
"पृष्ठों और बॉक्स का इस्तेमाल कर रहा रिक्त ऐप",
"स्क्रैच लाइब्रेरी का इस्तेमाल कर रहा एक रिक्त ऐप",
0,0,0,0,0,0,0,0,
"एक turtle ऐप।",
0,0,0,0,
"इस उपयोगकर्ता की आर्ट:",
0,0,
"गेम बनाने के लिए बॉयलर प्लेट कोड।",
0,0,0,0,0,0,
"कौशल का स्‍तर बदलें!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"कोड बनाएँ",
0,
"स्क्रिप्‍ट बनाएं",
0,0,0,
"नई तस्‍वीर वाली स्प्राइट बनाएं।",
0,
"नई स्क्रिप्ट बनाएँ",
0,0,0,0,0,
"चैनल बनाएँ",
0,0,0,
"स्‍वयं अपनी ऐप्‍स बनाएं",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
" स्प्राइट ओवरलैप करें",
"क्‍या आप जानकारीपरक Touch Develop-संबंधी न्‍यूजलेटर प्राप्‍त करना चाहते हैं, जैसे नई सुविधाओं और भावी कार्यक्रमों के बारे में जानकारी?",
"डॉक्स",
"संपादन करने के बाद नीचे स्‍क्रॉल करने और 'सहेजें' पर टैप करना ना भूलें!",
"ड्रैग एंड ड्रॉप ब्‍लॉक, सरलीकृत इंटरफेस, शुरुआत करने वालों के लिए सर्वोत्‍तम!",
0,0,
"कोड को पाठ के रूप में संपादित करें, भावी ऐप निर्माताओं के लिए, अधिक विकल्‍प!",
0,0,0,0,
"अपने बारे में कुछ जानकारी प्रविष्‍ट करें",
"अपनी व्‍यक्तिगत वेबसाइट का URL प्रविष्‍ट करें (उदाहरण: http://www.northwindtraders.com)",
0,
"अपनी स्‍कूल संबद्धता प्रविष्‍ट करें, यदि कोई है।",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"लम्बाई पिक्सेल में मिलती है",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Y स्थिति पिक्सेल में मिलती है",
"प्रारंभ करना",
0,
"मौजूदा स्क्रिप्ट में ग्लोबल वेरिएबल",
0,
"सहायता",
0,0,0,0,
"आपको Touch Develop के बारे में कैसे पता चला?",
0,
"कोड आयात करें",
"फ़ाइल से स्क्रिप्ट आयात करें",
0,0,0,0,0,0,0,0,0,0,0,0,
"'{0}' {1} प्रविष्‍ट करें",
0,
"* द्वारा चिह्नित आइटम आवश्‍यक हैं।",
0,0,0,0,0,0,0,0,0,0,0,0,
"सभी स्प्राइट को स्क्रीन की सीमा पर उछालता है",
0,0,
"मैं",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"कृपया हमारा निजता वक्‍तव्‍य देखें।",
0,0,0,0,0,0,0,0,0,
"अपनी स्क्रिप्ट पब्लिश करें, ताकि हर कोई इसे रन कर सके",
0,0,0,0,0,
"अन्‍य लोगों द्वारा आपकी किसी स्क्रिप्‍ट की समीक्षा करने/उसका स्‍क्रीनशॉट लेने/उस पर टिप्‍पणी करने, या आपकी किसी टिप्‍पणी पर जवाब देने, या आपकी सदस्‍य संबंधी आयोजन होने पर ईमेल से सूचना प्राप्‍त करें।",
0,
"मौजूदा जीवन से मान निकालता है।",
0,
"रिपोर्ट करें/हटाएँ",
0,0,0,0,0,0,0,
"“min” और “max” के बीच यादृच्छिक अभिन्न संख्या देता है जिसमें ये दोनों शामिल हैं।",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"इस उपयोगकर्ता की स्क्रिप्‍ट:",
0,0,
"कोड खोजें...",
"सब कुछ खोजें",
"यहां खोजें...",
0,0,
"खोजें…",
0,0,0,
"और देखें",
0,0,0,0,0,0,0,0,
"बैकग्राउंड पिक्‍चर सेट करता है",
0,
"मौजूदा जीवन पाइंट सेट करें।",
0,0,
"पिक्‍सेल में स्थिति निर्धारित करता है",
0,0,0,0,0,0,0,
"पिक्सेल में चौड़ाई सेट करता है",
"x स्‍पीड को पिक्सेल/ सेकंड में सेट करता है",
"y acceleration को पिक्सेल/ सेकंड^2 में सेट करता है",
0,
"y स्‍पीड को पिक्‍सेल/ सेकंड में सेट करता है",
0,
"सेटिंग्स",
0,0,0,0,
"कौशल का स्‍तर: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: 'if' कन्डीशन को {1:a} चाहिए,",
0,0,0,0,0,0,0,0,0,0,0,
"क्रिएटिव कोडिंग सिखाएँ!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Microsoft® Translator द्वारा अनुवाद, मूल देखने के लिए टैप करें...",
0,0,0,0,
"ट्यूटोरियल",
0,0,0,0,0,
"UI विजेट",
0,0,0,0,0,0,0,0,0,
"हम एडिटर को आपकी कोडिंग के कौशल स्‍तर के अनुकूल बना देंगे। आप बाद में अपना कौशल स्तर हब में बदल सकते हैं।",
"आपके प्रोग्रामिंग ज्ञान का स्‍तर क्‍या है?",
"आपका पेशा क्‍या है?",
"नया क्या है",
"आप इस दुनिया में कहां रहते हैं?",
0,0,0,0,0,
"आपका GitHub उपयोगकर्ता।",
"आपका Minecraft उपयोगकर्ता।",
0,0,
"आपका चैनल यहाँ दिखाई देगा",
"आपका ईमेल पता अभी तक सत्‍यापित नहीं हुआ है। कृपया अपना इनबॉक्‍स चेक करें।",
"आपका पूरा नाम",
0,0,0,
"आपकी स्क्रिप्‍ट यहां नजर आएगी",
"आपका ट्विटर हैंडल, जैसे @touchdevelop।",
"कुछ सेकंड पहले",
"फंक्‍शन",
"वैश्विक वेरिएबल",
"एक मिनट पहले",
0,0,0,0,
"आपके बारे में",
0,0,
"दुरुपयोग की रिपोर्ट",
0,0,0,0,0,
"जोड़ें",
0,0,0,0,0,0,0,0,0,0,
"नीचे पंक्ति जोड़ें",
"नया जोड़ें",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"एक घंटे पहले",
0,0,0,0,0,0,0,
"कला",
0,
"कार्यभार",
0,0,0,0,0,0,
"बैकस्‍पेस",
"इसे बैकस्पेस करें",
0,0,0,
"बिगिनर",
"शुरुआत करने वाले",
0,0,0,
"रिक्त ऐप",
0,0,
"रिक्त गेम",
0,0,0,
"रिक्त स्क्रैच",
0,
"रिक्त turtle",
0,0,0,0,0,0,0,0,0,
"रद्द करें",
0,0,0,0,
"चैनल",
0,0,0,0,0,0,0,0,0,0,0,
"अपने कोडिंग कौशल का स्‍तर चुनें",
0,0,0,0,
"क्‍लोन",
0,0,
"कोड",
0,
"कोडर",
0,0,0,0,0,
"कंडीशनल",
0,0,0,0,0,
"कॉपी करें",
0,0,
"बनाएँ",
0,
"चैनल बनाएँ",
0,0,0,0,
"स्क्रिप्‍ट तैयार हो रही है",
0,0,
"कला को अनुकूलित करें!",
"कट करें",
0,0,0,
"दशमलव बिंदु",
0,0,0,0,0,0,0,0,0,
"विवरण",
0,0,0,0,0,0,
"खारिज करें",
"प्रदर्शित मान",
0,0,0,0,0,0,
"संपादन करें",
0,
"ईमेल",
"ई-मेल (निजी)",
"ईमेल और पुश नोटिफिकेशन",
"ईमेल सत्यापित नहीं हुई, {0}",
0,0,0,0,0,0,0,0,0,
"उदा.: ",
0,
"शानदार; अच्‍छा प्रदर्शन; अद्भुत; बहुत बढ़ि‍या; छा गए; बहुत अच्‍छे; उत्‍कृष्‍ट; बिल्‍कुल; हां",
0,0,
"विशेषज्ञ",
0,0,0,0,0,0,0,0,0,0,
"पूरा हुआ",
0,
"एडिटर में ट्यूटोरियल का पालन करें",
0,0,
"फ़ंक्शन",
0,0,
"फंक्‍शन, वेरिएबल, लाइब्रेरी, ...",
"लिंग",
"मेरा Hour of Code™ सर्टिफिकेट प्राप्त करें",
0,
"github उपयोगकर्ता",
0,0,0,
"वैश्विक वेरिएबल",
0,
"कोडिंग पर वापस जाएं! {0}★ बाकी",
0,0,0,
"पिछले कदम पर जाएं",
"लक्ष्‍य:",
0,0,0,
"सहायता",
0,0,
"इतिहास",
0,
"कैसे मिला",
0,
"मैंने Hour of Code™ को पूरा कर लिया",
0,0,0,0,0,
"कोड आयात करें",
0,0,0,0,0,0,0,0,0,
"टिप्पणी सम्मिलित करें",
"स्टेटमेंट प्रविष्ट करें",
"{0} प्रविष्‍ट करें",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"सीखें",
0,0,0,0,
"आइए इसे बदलें",
"आइए, इसे क्रियान्वित करें!",
"आइए शुरूआत करते हैं!",
0,
"लाइब्रेरी",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"स्‍थान",
0,
"तार्किक निषेध",
0,0,0,0,0,0,
"मैं",
0,0,
"minecraft उपयोगकर्ता",
0,0,
"अधिक",
"और ",
"अधिक सेटिंग्‍स",
"कर्सर को सरकाएं",
0,0,
"कर्सर को बांये ले जाएं",
"कर्सर दायें ले जाएं",
0,0,0,0,
"मेरी स्क्रिप्‍ट",
0,0,0,0,0,0,
"निषेध",
0,0,0,0,0,0,0,0,0,
"नया वेरिएबल",
0,
"अगले ट्यूटोरियल...",
"उपनाम",
0,0,0,0,0,0,
"कोई पिछली ईमेल नहीं है",
0,0,0,0,0,
"सूचनाएं",
0,0,0,0,0,0,
"पेशा",
0,0,0,0,0,0,0,0,
"रूपरेखा",
0,0,0,
"स्क्रिप्‍ट का टेक्‍स्‍ट पार्स हो रहा है",
0,
"पेस्‍ट करें",
"पॉज़ करें",
0,0,
"स्क्रिप्ट टेम्प्लेट लें...",
"तस्‍वीर",
0,0,0,
"फिर खेलें",
0,
"कृपया प्रतीक्षा करें...",
0,0,0,0,
"निजी",
0,
"निजी प्रोफाइल",
0,
"प्रोग्रामिंग ज्ञान",
0,0,0,
"सार्वजनिक उपनाम",
"सार्वजनिक प्रोफाइल",
"पब्लिश करें",
0,0,0,0,0,0,0,
"और पढ़ें",
0,
"वास्‍तविक नाम",
"वास्तविक नाम (निजी)",
"ईमेल न्‍यूजलेटर प्राप्‍त करें",
"ईमेल सूचनाएं प्राप्‍त करें",
0,0,0,0,
"हटाएं",
0,
"तस्‍वीर हटाएं",
0,0,0,
"n बार दोहराएं",
0,
"तक दोहराएं",
0,0,0,0,0,0,0,0,0,
"पीछे करें",
"पीछे करें ",
"रन करें",
"मुख्‍य को रन करें",
0,0,
"सहेजें",
0,
"सहेज रहा है...",
"स्‍कूल",
0,0,0,
"स्क्रिप्ट",
"स्क्रिप्‍ट के गुण",
0,0,
"कला खोजें",
0,
"{0} के लिए यहां खोजें",
"टेम्प्लेट की खोज करें",
0,0,
"चयन करें",
0,
"उस पंक्ति को चुनें",
0,0,0,0,
"नाम सेट करें",
0,0,0,0,0,0,0,0,0,0,
"और विकल्प दिखायें",
"शोकेस",
"साइन इन",
0,0,
"साइन आउट",
"प्रवेश हो रहा है...",
0,0,0,
"पुनरावृत्ति छोड़ें",
0,0,0,0,0,0,
"विभाजित करें",
0,0,0,0,0,0,0,0,0,0,0,
"रोकने का फ़ंक्शन",
"रोकने का लूप",
0,
"इस मान को वेरिएबल में भंडारित करें",
"स्ट्रिंग",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"वहाँ टैप करें",
0,
"अपनी ऐप को रन करने के लिए यहां क्लिक करें",
0,0,0,0,0,
"उपयोग की शर्तें",
0,0,0,0,0,0,
"हब",
0,0,0,0,0,0,0,0,
"जारी रखने के लिए",
"वैश्विक वेरिएबल के लिए",
0,0,0,0,0,0,0,0,0,
"फिर कोशिश करें!",
"में बदलें",
"ट्यूटोरियल की प्रगति",
"ट्यूटोरियल: ",
"ट्यूटोरियल",
"ट्विटर हैंडल",
"टाइप करें: ",
"टाइप करें: {0}",
0,0,0,
"पूर्ववत करें",
0,0,0,
"स्‍थापना रद्द करें",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"नाम, ईमेल देखें/संपादित करें ...",
0,
"वॉलपेपर",
0,
"हमारे पास यहाँ {0:a} है; क्या आप इसके साथ कुछ करना चाहते थे?",
0,0,0,0,0,0,
"हम आपका चरण-दर-चरण मार्गदर्शन करेंगे",
0,0,0,0,
"वेबसाइट",
0,
"वेबसाइट का यूआरएल",
0,0,0,0,0,
"जन्‍म वर्ष",
0,0,0,0,0,
"{0} दिन पहले",
0,0,0,0,0,
"{0} मिनट पहले",
"{0} महीने पहले",
0,0,0,
"{0} सेकंड पहले",
0,
"{0} साल पहले",
0,0,
"● साइन इन"
]); return true; }

if (lang == "id") { TDev.Util._setLanguageArray(keys, [0,0,
" -- variabel lokal",
0,0,0,0,0,0,0,0,0,0,0,0,
"Kurung kurawal Javascript, semua alat bantu, untuk pengembang berpengalaman!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", namun mendapatkan {0:a}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>baris ini sempurna!</b> ayo lanjut",
"<h3>memuat pengaturan saat ini...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Nama tampilan unik untuk profil publik Anda (minimal 8 karakter)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Menambahkan nilai ke skor saat ini.",
0,0,0,0,
"Semua skrip saya",
0,0,0,0,0,0,0,
"Aplikasi kosong yang menggunakan halaman dan kotak.",
"Aplikasi kosong yang menggunakan perpustakaan awal.",
0,0,0,0,0,0,0,0,
"Aplikasi kura-kura.",
0,0,0,0,
"Seni dari pengguna ini:",
0,0,
"Kode pelat nama untuk membuat game.",
0,0,0,0,0,0,
"Ubah tingkat keahlian!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Buat Kode",
0,
"Buat Skrip",
0,0,0,
"Buat sprite gambar baru.",
0,
"Buat skrip baru",
0,0,0,0,0,
"Buat saluran",
0,0,0,
"Buat aplikasi sendiri",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Apakah sprite tumpang tindih",
"Anda ingin menerima buletin informasi terkait ToucDevelop, misalnya tentang fitur baru dan acara mendatang?",
"Dok",
"Jangan lupa gulir ke bawah, lalu ketuk 'simpan' bila Anda selesai mengedit!",
"Tarik dan simpan blok, antarmuka sederhana, cocok untuk pemula!",
0,0,
"Edit kode sebagai teks, pilihan selengkapnya, untuk calon penulis aplikasi!",
0,0,0,0,
"Masukkan beberapa informasi tentang diri Anda!",
"Masukkan URL ke situs web pribadi Anda (Misalnya: http://www.northwindtraders.com)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Mendapatkan tinggi dalam piksel",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Mendapatkan posisi y dalam piksel",
"Memulai",
0,
"Variabel global dalam skrip saat ini",
0,
"Bantuan",
0,0,0,0,
"Bagaimana Anda menemukan TouchDevelop?",
0,
"Impor Kode",
"Impor skrip dari file",
0,0,0,0,0,0,0,0,0,0,0,0,
"Masukkan '{0}' {1}",
0,
"Item yang ditandai * adalah wajib.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Membuat semua sprite memantul dari batas layar",
0,0,
"Saya",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Tinjau Pernyataan Privasi kami.",
0,0,0,0,0,0,0,0,0,
"Publikasikan skrip, agar setiap orang dapat menjalankannya.",
0,0,0,0,0,
"Terima pemberitahuan email saat orang lain meninjau/mengambil screenshot dari/mengomentari skrip Anda, atau membalas salah satu komentar Anda, atau saat kejadian terkait langganan Anda muncul.",
0,
"Menghapus nilai dari nyawa saat ini.",
0,
"Laporkan/Hapus",
0,0,0,0,0,0,0,
"Menghasilkan angka integral acak antara \"min\" dan \"max\" yang disertakan.",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Skrip dari pengguna ini:",
0,0,
"Cari kode...",
"Cari semua hal",
"Cari di sini...",
0,0,
"Cari…",
0,0,0,
"Lihat Lainnya",
0,0,0,0,0,0,0,0,
"Tetapkan gambar latar belakang",
0,
"Menetapkan poin nyawa saat ini.",
0,0,
"Menetapkan posisi dalam piksel",
0,0,0,0,0,0,0,
"Menetapkan lebar dalam piksel",
"Menetapkan kecepatan x dalam piksel/detik",
"Menetapkan percepatan y dalam piksel/detik^2",
0,
"Menetapkan kecepatan y dalam piksel/detik",
0,
"Pengaturan",
0,0,0,0,
"Tingkat keahlian: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: kondisi 'if' menginginkan {1:a}",
0,0,0,0,0,0,0,0,0,0,0,
"Ajarkan Pengkodean Kreatif!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Terjemahan oleh Microsoft® Translator, ketuk untuk melihat yang asli...",
0,0,0,0,
"Tutorial",
0,0,0,0,0,
"widget UI",
0,0,0,0,0,0,0,0,0,
"Kami akan menyesuaikan editor dengan tingkat keahlian pengkodean Anda! Anda selanjutnya dapat mengubah tingkat keahlian di hub.",
"Apa tingkat pengetahuan pemrograman Anda?",
"Apa pekerjaan Anda?",
"Yang baru",
"Di mana lokasi Anda?",
0,0,0,0,0,
"pengguna GitHub Anda.",
"Pengguna Minecraft Anda.",
0,0,
"Saluran kamu akan ditampilkan di sini",
"Alamat email Anda belum diverifikasi. Periksa kotak masuk Anda.",
"Nama lengkap Anda",
0,0,0,
"Skrip kamu akan ditampilkan di sini",
"Handle twitter Anda, seperti @touchdevelop.",
"beberapa detik yang lalu",
"fungsi",
"variabel global",
"menit yang lalu",
0,0,0,0,
"tentang Anda",
0,0,
"laporan penyalahgunaan",
0,0,0,0,0,
"tambah",
0,0,0,0,0,0,0,0,0,0,
"tambah baris di bawah ini",
"tambah baru",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"satu jam yang lalu",
0,0,0,0,0,0,0,
"seni",
0,
"penugasan",
0,0,0,0,0,0,
"backspace",
"hapus ini",
0,0,0,
"pemula",
"pemula",
0,0,0,
"blank app",
0,0,
"game kosong",
0,0,0,
"blank scratch",
0,
"blank turtle",
0,0,0,0,0,0,0,0,0,
"batal",
0,0,0,0,
"saluran",
0,0,0,0,0,0,0,0,0,0,0,
"pilih tingkat keahlian pengkodean Anda",
0,0,0,0,
"kloning",
0,0,
"kode",
0,
"coder",
0,0,0,0,0,
"kondisional",
0,0,0,0,0,
"salin",
0,0,
"buat",
0,
"buat saluran",
0,0,0,0,
"membuat skrip",
0,0,
"sesuaikan art!",
"potong",
0,0,0,
"dot desimal",
0,0,0,0,0,0,0,0,0,
"detail",
0,0,0,0,0,0,
"tutup",
"tampilkan nilai",
0,0,0,0,0,0,
"edit",
0,
"email",
"email (pribadi)",
"pemberitahuan email dan push",
"email belum diverifikasi, {0}",
0,0,0,0,0,0,0,0,0,
"mis.: ",
0,
"sangat baik; kerja bagus; menggagumkan; keren; kamu hebat; bagus; luar biasa; kamu berhasil; tepat sekali",
0,0,
"ahli",
0,0,0,0,0,0,0,0,0,0,
"selesai",
0,
"ikuti tutorial dalam editor",
0,0,
"fungsi",
0,0,
"fungsi, variabel, perpustakaan,...",
"jenis kelamin",
"dapatkan sertifikat Hour of Code™",
0,
"pengguna github",
0,0,0,
"variabel global",
0,
"kembali ke pengkodean! {0}★ tersisa",
0,0,0,
"lanjut ke langkah berikutnya",
"sasaran:",
0,0,0,
"bantuan",
0,0,
"riwayat",
0,
"cara menemukan",
0,
"saya selesai dengan Hour of Code™",
0,0,0,0,0,
"impor kode",
0,0,0,0,0,0,0,0,
"sisipkan",
"masukkan komentar",
"masukkan pernyataan",
"masukkan {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"pelajari",
0,0,0,0,
"mari kita mengubahnya",
"ayo lakukan!",
"ayo mulai!",
0,
"perpustakaan",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"lokasi",
0,
"negasi logika",
0,0,0,0,0,0,0,0,0,
"pengguna minecraft",
0,0,
"lainnya",
"lebih ",
"pengaturan selengkapnya",
"pindahkan kursor",
0,0,
"gerakkan kursor ke kiri",
"gerakkan kursor ke kanan",
0,0,0,0,
"skrip saya",
0,0,0,0,0,0,
"negasi",
0,0,0,0,0,0,0,0,0,
"variabel baru",
0,
"tutorial berikutnya...",
"nama panggilan",
0,0,0,0,0,0,
"tidak ada email sebelumnya",
0,0,0,0,0,
"pemberitahuan",
0,0,0,0,0,0,
"pekerjaan",
0,0,0,0,0,0,0,0,
"ikhtisar",
0,0,0,
"menguraikan teks skrip",
0,
"tempel",
"jeda",
0,0,
"pilih template skrip...",
"gambar",
0,0,0,
"main lagi",
0,
"tunggu...",
0,0,0,0,
"pribadi",
0,
"profil pribadi",
0,
"pengetahuan pemrograman",
0,0,0,
"nama panggilan publik",
"profil publik",
"publikasikan",
0,0,0,0,0,0,0,
"baca selengkapnya...",
0,
"nama asli",
"nama asli (pribadi)",
"terima buletin email",
"terima pemberitahuan email",
0,0,0,0,
"hapus",
0,
"hapus gambar",
0,0,0,
"ulang n kali",
0,
"ulang sewaktu",
0,0,0,0,0,0,0,0,0,
"mundur",
"mundur ",
"jalankan",
"jalankan utama",
0,0,
"simpan",
0,
"menyimpan...",
"sekolah",
0,0,0,
"skrip",
"properti skrip",
0,0,
"cari seni",
0,
"cari {0} di sini",
"template pencarian",
0,0,
"pilih",
0,
"pilih baris tersebut",
0,0,0,0,
"tetapkan nama",
0,0,0,0,0,0,0,0,0,0,
"tampilkan pilihan lainnya",
"tampilkan",
0,0,0,
"sign out",
0,0,0,0,
"lewati iterasi",
0,0,0,0,0,0,
"bagi",
0,0,0,0,0,0,0,0,0,0,0,
"hentikan fungsi",
"hentikan loop",
0,
"simpan nilai dalam variabel",
"string",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ketuk di sana",
0,
"ketuk di sana untuk menjalankan aplikasi",
0,0,0,0,0,
"syarat penggunaan",
0,0,0,0,0,0,
"hub",
0,0,0,0,0,0,0,0,
"untuk melanjutkan",
"ke var global",
0,0,0,0,0,0,0,0,0,
"coba lagi!",
"berubah menjadi",
"kemajuan tutorial",
"tutorial: ",
"tutorial",
"handle twitter",
"tipe: ",
"tipe: {0}",
0,0,0,
"batalkan",
0,0,0,
"hapus instalan",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"lihat/edit nama, email, ...",
0,
"wallpaper",
0,
"kita punya {0:a} di sini; ada yang ingin kamu lakukan dengannya?",
0,0,0,0,0,0,
"kami akan memandu Anda langkah demi langkah",
0,0,0,0,
"situs web",
0,
"url situs web",
0,0,0,0,0,
"tahun kelahiran",
0,0,0,0,0,
"{0} hari yang lalu",
0,0,0,0,0,
"{0} menit yang lalu",
"{0} bulan yang lalu",
0,0,0,
"{0} detik yang lalu",
0,
"{0} tahun yang lalu",
0,0,
"● Sign in"
]); return true; }

if (lang == "it") { TDev.Util._setLanguageArray(keys, [0,0,
" -- una variabile locale",
0,0,0,0,0,0,0,0,0,0,0,0,
"Parentesi graffe in stile Javascript e tutti gli strumenti per sviluppatori esperti.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", non uno {0:a}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>la riga è perfetta.</b> Procediamo",
"<h3>caricamento impostazioni correnti...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Un nome visualizzazione univoco per il tuo profilo pubblico (almeno 8 caratteri)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Aggiunge valore al punteggio corrente.",
0,0,0,0,
"Tutti i miei script",
0,0,0,0,0,0,0,
"Un’app vuota che usa pagine e caselle.",
"Un’app vuota che usa la libreria scratch.",
0,0,0,0,0,0,0,0,
"Un’app turtle.",
0,0,0,0,
"Disegni di questi utenti:",
0,0,
"Codice standard per creare un gioco.",
0,0,0,0,0,0,
"Modifica livello di competenza.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Crea codice",
0,
"Crea script",
0,0,0,
"Crea un nuovo sprite immagine.",
0,
"Crea un nuovo script",
0,0,0,0,0,
"Crea canale",
0,0,0,
"Crea le tue app",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Esegui sovrapposizione sprite",
"Vuoi ricevere newsletter informative su TouchDevelop, ad esempio, su nuove funzionalità e sugli eventi in programma?",
"Documenti",
"Non dimenticare di scorrere verso il basso e toccare \"salva\" al termine dell'operazione di modifica.",
"Possibilità di trascinare i blocchi e interfaccia semplificata, ideali per i principianti.",
0,0,
"Possibilità di modificare il codice come testo e opzioni aggiuntive per aspiranti programmatori di app.",
0,0,0,0,
"Inserisci alcune informazioni personali",
"Inserisci l'URL del tuo sito Web (esempio: http://www.northwindtraders.com)",
0,
"Indica l'affiliazione scolastica, se disponibile.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Visualizza l'altezza in pixel",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Visualizza la posizione y in pixel",
"Introduzione",
0,
"Variabili globali nello sprite corrente",
0,
"Guida",
0,0,0,0,
"Come hai scoperto TouchDevelop?",
0,
"Importa codice",
"Importa script da un file",
0,0,0,0,0,0,0,0,0,0,0,0,
"Inserisci '{0}' {1}",
0,
"Gli elementi contrassegnati da * sono obbligatori.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Consente a tutti gli sprite di rimbalzare sul bordo dello schermo",
0,0,
"Io",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Consulta la nostra Informativa sulla privacy.",
0,0,0,0,0,0,0,0,0,
"Pubblica lo script e consenti ad altri di usarlo.",
0,0,0,0,0,
"Ricevi notifiche via e-mail quando altri utenti rivedono/scattano uno screenshot/commentano i tuoi script o rispondono a uno dei tuoi commenti oppure quando si verificano eventi correlati ai tuoi abbonamenti.",
0,
"Rimuove il valore dalla vita corrente.",
0,
"Segnala/Elimina",
0,0,0,0,0,0,0,
"Restituisce un numero intero casuale tra \"min\" e \"max\".",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Script di questo utente:",
0,0,
"Cerca codice...",
"Cerca tutto",
"Cerca qui...",
0,0,
"Cerca...",
0,0,0,
"Visualizza altro",
0,0,0,0,0,0,0,0,
"Imposta l'immagine di sfondo",
0,
"Imposta i punti per la vita corrente.",
0,0,
"Imposta la posizione in pixel",
0,0,0,0,0,0,0,
"Imposta la larghezza in pixel",
"Imposta x speed in pixel/sec",
"Imposta y acceleration in pixel/sec^2",
0,
"Imposta y speed in pixel/sec",
0,
"Impostazioni",
0,0,0,0,
"Livello di competenza: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: la condizione \"if\" richiede un valore {1:a}",
0,0,0,0,0,0,0,0,0,0,0,
"Insegna la scrittura di codice creativa!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Traduzioni di Microsoft® Translator. Tocca per visualizzare la versione originale...",
0,0,0,0,
"Tutorial",
0,0,0,0,0,
"widget UI",
0,0,0,0,0,0,0,0,0,
"Adatteremo l'editor in base al tuo livello di competenza. Puoi modificare il tuo livello di competenza successivamente nell'hub.",
"Qual è il tuo livello di conoscenze relative alla programmazione?",
"Qual è la tua occupazione?",
"Novità",
"Dove vivi?",
0,0,0,0,0,
"Il tuo utente GitHub.",
"Il tuo utente Minecraft.",
0,0,
"Il tuo canale viene visualizzato qui",
"Il tuo indirizzo e-mail non è stato ancora verificato. Controlla la Posta in arrivo.",
"Nome completo",
0,0,0,
"Il tuo script viene visualizzato qui",
"Il tuo pseudonimo Twitter, ad esempio @touchdevelop.",
"alcuni secondi fa",
"una funzione",
"una variabile globale",
"un minuto fa",
0,0,0,0,
"informazioni personali",
0,0,
"segnalazioni abusi",
0,0,0,0,0,
"aggiungi",
0,0,0,0,0,0,0,0,0,0,
"aggiungi riga in basso",
"aggiungi nuovo",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"un'ora fa",
0,0,0,0,0,0,0,
"disegno",
0,
"assegnazione",
0,0,0,0,0,0,
"backspace",
"premi qui il tasto backspace",
0,0,0,
"principiante",
"principianti",
0,0,0,
"modello di app",
0,0,
"gioco vuoto",
0,0,0,
"modello di scratch",
0,
"modello di turtle",
0,0,0,0,0,0,0,0,0,
"annulla",
0,0,0,0,
"canali",
0,0,0,0,0,0,0,0,0,0,0,
"scegli il tuo livello di competenze di programmazione",
0,0,0,0,
"duplica",
0,0,
"codice",
0,
"programmatore",
0,0,0,0,0,
"istruzione condizionale",
0,0,0,0,0,
"copia",
0,0,
"crea",
0,0,0,0,0,0,
"creazione script",
0,0,
"personalizza il disegno.",
"taglia",
0,0,0,
"punto decimale",
0,0,0,0,0,0,0,0,0,
"dettagli",
0,0,0,0,0,0,
"ignora",
"visualizza valore",
0,0,0,0,0,0,
"modifica",
0,
"e-mail",
"e-mail (privata)",
"e-mail e notifiche push",
"e-mail non verificata; {0}",
0,0,0,0,0,0,0,0,0,
"esempio: ",
0,
"eccellente; ottimo lavoro; grandioso; grande; sei forte; ottimo;\neccezionale; esatto; giusto",
0,0,
"esperto",
0,0,0,0,0,0,0,0,0,0,
"fine",
0,
"segui il tutorial nell'editor",
0,0,
"funzione",
0,0,
"biblioteca, variabile, funzione,...",
"sesso",
"visualizza il mio certificato Hour of Code™",
0,
"utente github",
0,0,0,
"variab. globali",
0,
"torna alla scrittura di codice. {0}★ per andare",
0,0,0,
"vai al passaggio precedente",
"obiettivo:",
0,0,0,
"guida",
0,0,
"cronologia",
0,
"come ci hai trovato",
0,
"ho terminato Hour of Code™",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"inserisci commento",
"inserisci istruzione",
"inserisci {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"apprendi",
0,0,0,0,
"modifichiamolo",
"facciamolo!",
"Iniziamo!",
0,
"raccolte",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"percorso",
0,
"negazione locale",
0,0,0,0,0,0,0,0,0,
"utente minecraft",
0,0,
"altro",
"altro ",
"altre impostazioni",
"sposta il cursore",
0,0,
"muovi il cursore a sinistra",
"muovi il cursore a destra",
0,0,0,0,
"i miei script",
0,0,0,0,0,0,
"negazione",
0,0,0,0,0,0,0,0,0,
"nuova variabile",
0,
"prossimi tutorial...",
"nickname",
0,0,0,0,0,0,
"nessuna e-mail precedente",
0,0,0,0,0,
"notifiche",
0,0,0,0,0,0,
"occupazione",
0,0,0,0,0,0,0,0,
"panoramica",
0,0,0,
"analisi testo script",
0,
"incolla",
"pausa",
0,0,
"scegli un modello di script...",
"immagine",
0,0,0,
"gioca di nuovo",
0,
"attendi...",
0,0,0,0,
"privato",
0,
"profilo privato",
0,
"competenze di programmazione",
0,0,0,
"nickname pubblico",
"profilo pubblico",
"pubblica",
0,0,0,0,0,0,0,
"leggi altro...",
0,
"nome reale",
"nome vero (privato)",
"ricevi le newsletter via e-mail",
"ricevi notifiche via e-mail",
0,0,0,0,
"elimina",
0,
"elimina immagine",
0,0,0,
"ripeti n volte",
0,
"ripeti mentre",
0,0,0,0,0,0,0,0,0,
"indietro",
"indietro ",
"esegui",
"esegui principale",
0,0,
"salva",
0,
"salvataggio in corso...",
"scuola",
0,0,0,
"script",
"proprietà script",
0,0,
"cerca disegno",
0,
"cerca {0} da qui",
"cerca modelli",
0,0,
"seleziona",
0,
"seleziona la riga",
0,0,0,0,
"imposta nome",
0,0,0,0,0,0,0,0,0,0,
"mostra più opzioni",
"presentazione",
0,0,0,
"esci",
"accesso in corso...",
0,0,0,
"salta iterazione",
0,0,0,0,0,0,
"dividi",
0,0,0,0,0,0,0,0,0,0,0,
"arresta funzione",
"arresta loop",
0,
"archivia il valore nella variabile",
"stringa",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Tocca là",
0,
"tocca là per eseguire l'app",
0,0,0,0,0,
"condizioni per l'utilizzo",
0,0,0,0,0,0,
"l'hub",
0,0,0,0,0,0,0,0,
"per continuare",
"alla variabile glob",
0,0,0,0,0,0,0,0,0,
"riprova!",
"trasforma",
"avanzamento tutorial",
"tutorial: ",
"tutorial",
"pseudonimo Twitter",
"digita: ",
"digita: {0}",
0,0,0,
"annulla",
0,0,0,
"disinstalla",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"visualizza/modifica nome, e-mail, ...",
0,
"sfondo",
0,
"qui c'è uno {0:a}. Volevi usarlo?",
0,0,0,0,0,0,
"ti guideremo passo dopo passo",
0,0,0,0,
"sito Web",
0,
"url sito Web",
0,0,0,0,0,
"anno di nascita",
0,0,0,0,0,
"{0} giorni fa",
0,0,0,0,0,
"{0} minuti fa",
"{0} mesi fa",
0,0,0,
"{0} secondi fa",
0,
"{0} anni fa",
0,0,
"● Accedi"
]); return true; }

if (lang == "ja") { TDev.Util._setLanguageArray(keys, [0,0,
" -- ローカル変数",
0,
" [非表示]",
0,0,0,0,
" 分 ",
" / ",
" 秒 ",
" 変更の送信",
0,0,
"経験豊富な開発者のために、Javascript の中かっこやあらゆるツールも用意されています!",
"'アトミック' 関数",
0,0,0,0,
"'{0}' はここで {1} を予期しています",
0,0,0,
"'{0}' は古い形式であり、使用しないでください",
0,
"'{0}' は '{1}' を返します。{2}",
0,0,0,0,0,0,0,0,
"、代わりに得られたのは {0}",
"、{0} を取得",
0,0,0,
"... さらに...",
"// コメント",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>この行は完成しました。</b> 先へ進みましょう",
"<h3>現在の設定を読み込んでいます…</h3>",
"<h3>他にヒントはありません!</h3>",
0,
"<h3>{0:q} にはサインインが必要です</h3>",
0,0,0,0,0,0,
" 2Dマトリクス（数列）",
"3D ベクトル",
0,
"Minecraft Pi アプリ。",
"Minecraft アプリ。",
"Minecraft クリーパー アプリ。",
0,0,0,0,0,0,0,0,0,0,
"カラー定数",
0,0,0,0,0,0,0,0,0,
"グローバル変数",
0,0,0,0,0,0,0,0,0,0,0,
"数値 (負 / 小数の場合もある)",
"数値定数",
0,0,0,
"画像",
"一連のテキスト",
"ピクセル アート アプリ。",
0,0,0,
"ライブラリ スクリプトの参照",
0,0,0,0,0,0,0,0,0,
"サウンド",
"効果音",
0,0,0,
"ユーザー データの構造",
"ユーザー定義行から成るテーブル",
0,0,0,
"テキストボックス",
"タイマー",
"パブリック プロフィールの一意の表示名 (8 文字以上)",
0,
"ユーザーアカウント",
"ユーザー インターフェイス",
0,0,
"ADJ スクリプト",
0,0,0,0,0,
"加速度センサ",
0,0,0,0,0,
"表示フレームごとに起動されるアクションの追加",
0,0,0,0,0,0,0,
"画像を追加",
0,0,0,0,0,0,
"ベクターを追加",
"オブジェクトを追加",
0,
"数値の加算",
0,
"現在のスコアに値を加算します。",
0,0,
"スクリプトの停止後、コードを参照して、収集された情報を確認してください。",
"すべてのマイ グループ",
"すべてのマイ スクリプト",
0,0,0,0,0,0,0,
"ページとボックスを使用する空白のアプリ。",
"検索ライブラリを使用する空白のアプリ。",
"空白のドキュメント ページ。",
"空白の対話型チュートリアル。",
"空白のスクリプト エディター プラグイン。",
"空白のスクリプト。これは何も行いません。",
0,0,
"ユーザー定義行から成るインデックス付きテーブル",
0,
"カメのアプリ。",
"入力コレクションのすべての要素に対して `converter` を適用し、結果から成るコレクションを返します",
0,
"チュートリアルに従うことを本当に停止しますか?",
0,
"このユーザーによるアート:",
0,
"他のオブジェクトにデータを添付します",
"ゲームを作成するための反復して使用するコード。",
0,0,
"カメラ",
0,0,0,
"スキル レベルの変更",
"チャンネル",
"ボードが他のボードと同じインスタンスであるかどうかを確認します。",
0,0,0,
"このボードに関連するキューに登録済みのすべてのイベントを消去",
"背景画像を消去",
"背景カメラを消去",
0,0,
"ユーザー操作が発生したときに呼び出されるコード",
"特定のタスクを実行するコード",
"数値が等しいかどうかの比較",
"数値が小さいかどうかの比較",
0,
"数値が大きいかどうかの比較",
0,0,0,0,0,0,0,
"2 つのテキスト要素を連結",
0,0,0,0,0,0,
"ローカル時刻に変換",
0,0,0,0,0,
"グループの作成",
"スクリプトの作成",
"指定された開始ポイント、指定された幅と高さで障害物の線を作成します。粘着する場合の弾力性は 0、完全なバウンスの場合は 1 です。",
"スプライトの新しいコレクションを作成します。",
"新しい楕円形のスプライトを作成。",
"新しい画像スプライトを作成します。",
"新しい四角形のスプライトを作成します。",
0,
"新しいスプライト シートを作成します。",
"新しいテキスト スプライトを作成します。",
"2 つのスプライトの間にスプリングを作成します。",
"anchor スプライトを作成します。",
"このオブジェクト タイプの無効な値を作成します",
"チャンネルを作成します",
0,0,
"指定された距離でボードの周囲にウォールを作成します。",
"アプリの作成",
0,0,
"新しい空白のゲーム ボードを作成して、画面上に表示します。",
0,0,0,
"指定された画像に幅 100 の新しいスプライトを作成します。",
0,
"無効なゲームパッド インスタンスを作成します",
0,0,
"現在のデバイス",
0,
"現在のタッチ ポイント",
"イベントからのハンドラーのデタッチ",
0,
"ウォールに画像を表示します。変更を反映するには、'update on wall' (ウォールで変更) を後で呼び出す必要があります。",
0,0,0,
"ウォールにゲームパッドの状態を表示します",
0,
"スプライトを重ね合わせますか",
0,
"文書",
"編集が終わったら、下にスクロールして、[保存] をタップしてください!",
"ブロックのドラッグ アンド ドロップ、簡略化されたインターフェイスによって、初心者でも簡単に操作できます!",
"2 つの店の間に 1 本の直線を描きます",
"指定したカラーとフォント サイズでテキスト境界を描画します",
"テキストとしてコードを編集できることやその他のオプションは、コーディング初心者にとって心強い味方です!",
0,0,
"名前の入力",
0,
"お客様の情報を入力してください",
"お客様の Web サイト URL を入力してください (例: http://www.northwindtraders.com)",
"招待コードを入力します",
0,
"イベントにアウト パラメーターを含めることはできません。",
"誰でもインターネット上で永久に写真を見ることができます。 ",
0,0,
"エクステンション",
"Facebook",
"特定の色で楕円を塗りつぶし",
"特定の色で長方形を塗りつぶし",
"タッチの修了後の最終タッチ速度",
"公開されているスクリプトについては、公開されているスクリプト ページに対応するタブも参照し、匿名で収集されたクラウドベースのプロファイルとカバレッジ データを確認してください。",
"フォーラム",
"今後は、作成する行を表示しません。指示に従って、完了したと思ったときに [実行] をタップします。",
"現在のスクリプトの関数",
0,0,0,0,0,
"ゲームパッドの状態のスナップショットを取得します (ブラウザーに接続している場合)。ゲームパッドがサポートされていないか、接続されていない場合は空白です。",
0,0,0,
"ボードが横長に表示されるように設計されているかどうかを示す値を取得します。",
"歌が DRM で保護されているかどうかを表す値を取得します",
"選択された軸の x と y の値を取得します。",
0,0,
"背景シーンを取得",
"水平方向の中心位置をピクセル単位で取得",
0,
"ARGB 値が #00FFFFFF の色を取得",
"ARGB 値が #FF000000 の色を取得",
"ARGB 値が #FF0000FF の色を取得",
"ARGB 値が #FF008000 の色を取得",
"ARGB 値が #FF00FFFF の色を取得",
0,
"ARGB 値が #FF800080 の色を取得",
0,0,0,0,
"ARGB 値が #FFFF0000 の色を取得",
"ARGB 値が #FFFF00FF の色を取得",
"ARGB 値が #FFFFA500 の色を取得",
0,
"ARGB 値が #FFFFFF00 の色を取得",
"ARGB 値が #FFFFFFFF の色を取得",
0,0,0,0,
"最初に接続されたゲームパッドを使用できます",
0,
"ゲームパッドの識別子を取得します",
0,
"高さをピクセル単位で取得",
"カメラ画像の高さをピクセル単位で取得します。",
0,0,0,0,0,0,0,0,0,
"プレイヤーのインデックスを取得します",
"押されたボタンの値を取得します。ボタンが不明な場合は 0 を返します。",
0,
"サウンドに関するサウンド ボリュームを 0 (無音) から 1 (現在のボリューム) の範囲で取得します",
"スプライト数を取得",
"i によってインデックスが付けられたスプライトを取得",
0,
"このスナップショットのタイムスタンプを取得します",
0,
"幅をピクセル単位で取得",
"カメラ画像の幅をピクセル単位で取得します。",
"y 位置をピクセル単位で取得",
"作業の開始",
0,
"現在のスクリプト内のグローバル変数",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"デバッグ モードでは、ボードに速度およびスプライトのその他の情報が表示されます",
"ボタンが押されているかどうかを示します。ボタンが不明な場合は false を返します。",
0,
"ゲームパッド データが一致しているかどうかを示します。",
"ゲームパッドがまだ接続されてかどうかを示します。",
0,0,0,0,
"'{0}' {1} の挿入",
0,
"* が付いている項目は必須です。",
"JSON データ",
"グループに参加",
"最後のタッチの終了ポイント",
"最後のタッチの開始ポイント",
0,0,0,0,0,
"更新を表示します。",
0,0,
"すべてのスプライトが画面の 3 つの境界で跳ね返るようにします。",
0,
"長所、特殊性、最大値などを計算します。",
"Me",
0,
"Minecraft ユーザー",
0,0,
"スプライトを他のスプライトに向けて移動します。",
"数値の乗算",
0,0,0,0,0,0,0,0,
"新しいスクリプト",
0,
"新しい色または組み込みの色",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ランダム カラーを選択します",
0,0,0,0,0,0,
"プライバシーに関する声明を確認してください。",
"お待ち下さい...",
"コメントを投稿します...",
0,0,0,
"プライベート アクションでは [実行] ボタンが表示されません。 ",
"ユーザーに数値を入力するように指示します",
0,
"スクリプトの公開",
0,
"公開は、当社の ",
"スクリプトを公開しています…",
"アニメーションの再生が開始されたときに上昇します",
"アニメーションの再生が停止されたときに上昇します",
"広告本文をウェーブ サウンドとして読み上げ",
"他の人があなたのスクリプトをレビューしたり、スクリーンショットを作成したり、コメントした場合や、あなたのコメントに返信した場合、あるいはあなたのサブスクリプションに関するイベントが発生した場合に、電子メールで通知を受け取ります。",
"覚えておいてください: スクリプトを公開すると、全員が見られるようになるため、パスワードや個人情報が含まれていないことを確認してください。",
"現在のライフから値を減らします。",
"返信...",
"レポート/削除",
"ピクセル単位で指定したサイズに合わせて画像をサイズ変更",
0,
"画像のコピーを返します",
0,0,
"このインスタンスの値に対して指定した月数を加算したのに相当する日付を返します。",
"このインスタンスの値に対して指定した年数を加算したのに相当する日付を返します。",
"「min」と「max」の間に含まれるランダムな整数を返します。",
0,0,0,0,0,0,0,
"現在のインスタンスが不要な場合は true を返す",
0,0,0,0,
"スクリプトの更新",
"このユーザーによるスクリプト:",
0,0,
"コードの検索...",
"すべてを検索",
"ここで検索...",
0,0,
"検索...",
0,0,0,
"詳細の表示",
0,0,
"勾配をオンまたはオフに設定",
"ウォールに対して適用される 3x3 のアフィン行列の転換を設定します。",
0,
"背景カメラを設定します",
"背景色を設定します",
"背景色を設定します。",
"背景の画像を設定します",
"水平方向の中心位置をピクセル単位で設定",
"現在のライフ ポイント、つまり残機を設定します。",
"スプライトの既定の摩擦を、0～1 の速度低下の摩擦に設定します",
"高さをピクセル単位で設定",
"位置をピクセル単位で設定",
0,
"サウンド ボリューム レベルを 0 (無音) から 1 (現在のボリューム) の範囲で設定します",
"速度をピクセル/秒で設定",
"スプライトの色を設定します。",
"ボード上のオブジェクトの均一の加速ベクトルをピクセル/秒^2 に設定します",
0,0,
"幅をピクセル単位で設定",
"x 方向の速度をピクセル/秒で設定",
"y 方向の加速度をピクセル/秒^2 で設定",
"y 位置をピクセル単位で設定",
"y 方向の速度をピクセル/秒で設定",
0,
"設定",
"この URL で共有します:",
"これらのプラットフォームで実行できない API をスクリプトで使用している場合は、エディターでエラーを表示します。",
"ボードをウォールに表示します。",
0,
"スキル レベル:{0}     ",
0,0,0,0,0,
"フレームごとのすべてのタイマーを停止して消去",
0,
"数値の減算",
0,
"TD100: {0} をここに挿入",
"TD101: '{0}' が見つかりません",
"TD109: これに割り当てることはできません",
"TD111: {0} から {1} に割り当てることはできません",
"TD112: プロパティ '{0}' が {1} で見つかりません",
"TD115: {0} に対して指定したパラメーターが多すぎます",
"TD116: {0} に対して十分なパラメーターが指定されていません",
"TD118: 'if' 条件で要求されているのは {1}",
"何かを繰り返す必要があります",
0,
"TD130: 'for' に結合された条件で要求されているのは {1}",
"TD144: '{0}' が欠落しているようです。追加してみてください",
"TD145: ここで演算子 ('+'、'('、',' など) が欠落しているようです",
"TD147: ここで '{0}' は予期されていませんでした",
"TD150: '(' の前に何かを呼び出すことはできません",
"TD151: 閉じられていない '('",
"TD152: 予期しない ')'",
"TD154: この後、オペレーターはいずれかを実行する必要があります",
"TD155: '{0}' をローカル変数に割り当てることはできません",
"Creative Coding を指導してください!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"このスクリプトでは次の機能を使用: ",
0,
"このチュートリアルでは、他のユーザーと共有するクラウド データを使用します。",
"ページ データを追加するには、ローカル変数を作成し、'promote to field' (フィールドに昇格) をタップします。",
0,0,0,0,
"Microsoft® Translator による翻訳。タップすると、原文が表示されます...",
"ボードがタッチされている場合は true",
"目的の結果が得られるまで、コードを変更してみてください。行き詰まったら、チュートリアル バーをタップしてください。",
0,0,
"チュートリアル",
"Twitter",
"入力してオンラインで検索...",
"入力して検索...",
"TypeScript",
"イベントパラメーターのタイプ、順序、および数を編集することはできません。",
"UI ウィジェット",
"URL: {0}",
"ボード上のスプライトの位置を更新します。",
"画像スプライト (これが画像スプライトである場合) を画像で更新",
"テキスト スプライトのテキストを更新 (これがテキスト スプライトである場合)",
"画像のアップロード",
"サウンドのアップロード",
"ユーザー",
0,
"その他のオプションが必要です",
"コーディング スキル レベルに合わせたディターを採用しています。ハブで後からスキル レベルを変更できます。",
"プログラムに関する知識はどの程度のレベルですか?",
"あなたのご職業は?",
"新機能",
"どこにお住まいですか?",
"指定した場所に別の画像を書き込みます。透明度の範囲は 0 (透過) から 1 (不透明) です。",
0,
"YouTube",
"YouTube ビデオ (https://youtu.be/...)",
0,
"自分の GitHub ユーザー名。",
"自分の Minecraft ユーザー名。",
"制作したアートはここに表示されます",
0,
"チャンネルがここに表示されます",
"電子メールが確認されていません。受信トレイをチェックしてください。",
"フル ネーム",
0,0,0,
"制作したスクリプトはここに表示されます",
"Twitter のハンドル名 (例: @touchdevelop)",
"数秒前",
"関数",
"グローバル変数",
"1 分前",
"ページ",
"カバレッジについて",
"洞察について",
"プロファイルについて",
"自分について",
"不正使用",
0,
"不正使用を報告",
0,0,0,
"{0} フィールドにアクセスします",
0,
"追加",
"新規追加…",
0,
"表示フレームごとに起動されるアクションを追加します。",
"コメントを追加",
0,
"カスタムWebサイトを追加",
"関数を追加",
0,
"入力パラメーターの追加",
"下の行を追加",
"次の行を追加",
"新しい",
0,0,
"出力パラメーターの追加",
"チャンネルに追加",
0,0,0,0,
"すべての API",
"許可",
"すばらしい, 目を見張る, 仰天するような, 恐怖すら感じる, 恐ろしい, はらはらする, 最高水準の, クールな, 不思議な, 格別な, 例外的な, 上級の, 非凡な, 信じがたい, すてきな, 名誉ある, 偉大な, ",
0,
"関数の種類の定義",
"1 時間前",
0,0,0,0,0,
"アプリ",
0,
"アート",
"アート リソース",
"課題",
0,
"制作者",
0,0,
"戻る",
0,
"バックスペース",
"ここでバックスペース",
0,0,
"基数",
"初心者",
"初心者",
0,
"スクリプトにバインドされます:",
"空白",
"空白のアプリ",
"空白のクリーパー",
"空白のドキュメント",
"空白のゲーム",
"空白の Minecraft",
"空白の Minecraft Pi",
"空白のピクセル アート",
"空白のスクラッチ",
"空白のスクリプト プラグイン。",
"空白のカメ",
"空白のチュートリアル。",
"デバッガーでブレーク",
"ブレークポイント",
0,0,0,0,0,0,
"キャンセル",
0,0,
"ローカルに変更 (戻す)",
"内容の変更",
"チャンネル",
"参照が設定されているかどうかを確認します",
0,
"ファイルを選択",
"画像を選択",
"画像を選択 (1MB、2048x2048 未満)",
"プラグインを選択",
"壁紙を選択",
"グループを選択",
"ライブラリを選択",
"新しいパスワードを選択",
"画像を選択",
"コーディングのスキル レベルを選んでください",
"選択します...",
0,
"クリア",
"クリップボード",
"クローン",
"クラウドデータ",
"クラウド セッション",
"コード",
"目標の行をコーディング",
"コーダー",
"カラー #{0}",
"カラー: {0}",
"コメント アウト",
"コメント",
0,
"条件付き",
"接続済み",
0,
"コンソール",
"続行",
0,
"コピー",
"選択内容のコピー",
"カバレッジ",
"作成",
"新規パラメーターの作成",
0,0,0,0,
"オブジェクトの空のコレクションを作成します",
"スクリプトの作成",
0,
"現在の式",
"アートをカスタマイズします。",
"切り取り",
"選択内容の切り取り",
"データベース",
"デバッグ",
"小数点",
"デコレータ",
"削除",
"ローカルのデータとアクセス許可の削除",
"選択内容の削除",
"変数に降格",
"拒否",
"説明",
"説明 (ヘルプの検索)",
0,
"詳細",
"この値を使用しましたか?",
"diff curr",
"diff prev",
0,0,0,
"クリア",
"値を表示",
"オブジェクトをウォールに表示します",
0,0,0,
"完了しました",
"完了しました。",
"編集",
"else if",
"電子メール",
0,
"電子メールとプッシュ通知",
0,0,0,0,
"招待コードを入力",
"このコードを入力",
"エラー",
0,
"イベント",
"すべて",
"例: ",
"例",
"最高; 優れた成果; 完璧; クール; 感動的; 良好な出来; 抜群; 上出来; 適切",
0,
"終了",
"エキスパート",
0,
"エクスポート",
"コンテンツの JSON 表現をエクスポートします",
"このライブラリからエクスポート済み",
"拡張",
0,
"選択内容の関数への抽出",
0,
"変数に抽出",
"参照の検索",
"完了",
"これを修正します",
"エディター内のチュートリアルに従ってください",
"グループ",
"フォーク",
"関数",
"関数名",
"関数タイプ",
"関数、変数、ライブラリなどを追加します...",
"性別",
"Hour of Code™ 認定証の取得",
"表示フレームごとに起動されるタイマーを取得します。",
"GitHub ユーザー",
0,
"一括置換",
"グローバル変数",
"グローバル変数",
"戻る",
"コーディングに戻ります!残り {0}★",
"戻る...",
"移動",
"スクリプト内の項目のリストに移動",
"前の手順に移動",
"目標:",
"グループ",
0,
"心臓部",
"ヘルプ",
0,0,
"履歴",
"これでスクリプトが公開されました",
"見つけた方法",
"次のものに対して実行",
"Hour of Code™ を使用した作業が完了しました",
"アイコン アート: {0}",
0,
"行き詰まったら、目標の行をタップ",
0,0,0,0,
"JSON オブジェクトからフィールド値をインポートします",
0,0,0,0,
"途方もない, 魔法でも見ているような, 驚くべき, 本当とも思えないほど, 幻覚でも起こしそうな, 肝をつぶすような, 奇跡の, 独特の, 珍しい, 格好良い, 揺り動かす, 特殊な, 華々しい, あっと言わせる, 立派な, とてもクールな, ",
0,
"挿入",
"コメントの挿入",
"ステートメントの挿入",
"{0} の挿入",
"洞察",
0,
"スクリプトをインストールして読み込んでいます",
"ローカルに",
0,
"課題",
"グループに参加",
"グループに参加",
0,
"検索語句の入力を続けます!",
"編集の続行",
"次のように認識されました:",
0,
"詳細",
"公開について学習する",
"詳細情報",
"{0} を詳細します。",
"チュートリアルから離れる",
"これを変更しましょう",
"実行しましょう。",
"作業を開始しましょう。",
"lib",
"ライブラリ",
"ライブラリ",
"ライブラリ名",
"ライブラリ参照",
"さらに読み込み",
"さらに返信を読み込み",
"読み込み中",
0,
"/{0} に対するコメントを読み込んでいます...",
0,
"返信を読み込んでいます...",
"スクリプトの読み込み中",
"チュートリアルの読み込み",
"読み込み中...",
"ローカル",
"場所",
0,
"論理否定",
"ログ",
"メイン",
0,
"マーカー",
"データの管理",
"後で実行することもできます",
"自分",
0,
"minecraft",
"Minecraft ユーザー",
"モンスター",
0,
"詳細",
"その他? ",
"その他の設定",
"カーソルの移動",
"左に移動",
"次のステップに移動",
"カーソルを左に移動",
"カーソルを右に移動",
"マイ アート",
0,0,0,
"マイ スクリプト",
"ここに別の名前が必要",
"ここに別の文字列が必要",
"ここに新しいフィールドが必要",
"パラメーターが必要",
"これを削除する必要があります",
"どこかを編集する必要があります",
"否定",
"新しいフィールド/データ",
"新しい関数",
"新しいグローバル変数",
"新しい招待コード",
"新しい行",
"新しいローカル",
"新しいパスワード:",
"新しいプロパティ",
"新しいステートメントを下に",
"新しい変数",
"次のページ",
"次のチュートリアル...",
"ニックネーム",
"いいえ",
"このユーザーからアートは発行されていません",
"コメントはありません。タップして何かコードを記述します。",
"スクリプトを作成するために、スクリプトのフォーク (分岐)、インストール、編集、再発行なし",
"ハートがありません。スクリプトをインストールした後、ハートを追加できます。",
"まだどの画像も読み込まれていません",
0,0,
"タグはありません。タップして何かコードを追加します。",
0,0,0,
"通知",
0,
"{0} のプロパティを選択できます。これは単独では何も実行しません",
"現在、これに対するプロパティを選択できます",
"数値",
"数値エントリ",
0,
"職業",
0,
"オフラインで使用可能",
"OK",
"行きましょう！",
"オンライン",
0,
"またはタップしてヘルプを表示",
"その他",
"概要",
0,
"ページ",
0,
"スクリプトのテキストを解析",
0,
"貼り付け",
"一時停止",
0,
"物理的なゲーム スターター",
"スクリプトのテンプレートを選択…",
"画像",
"画像の名前",
"画像の名前 (4 文字以上)",
"画像の URL",
"もう一度プレイする",
0,
"お待ちください...",
"プラグイン",
"プレビュー",
"出力",
"プライバシーポリシー",
"プライベート",
"プライベート関数",
"プライベート プロフィール",
"プロファイル",
"プログラムに関する知識",
0,
"データに昇格",
0,
"パブリック ニックネーム",
"パブリック プロフィール",
"公開",
"非表示として公開",
0,
"公開者",
"変更の取得",
"ブロック レベルまで引き上げる",
0,
"再実行",
"詳細...",
"読み取り専用",
"本名",
0,
"電子メールのニュースレターを受信",
"電子メールの通知を受信",
"名前の記録:",
0,
"通常のキーパッド",
"スクリプトの再読み込み",
"削除",
0,
"画像を削除",
"白の背景を削除 (ゲーム スプライトに最適)",
0,
"名前の変更",
"n 回反復処理",
"コレクションの反復処理",
"少しの間反復処理",
"関数内ですべてを置換",
"スクリプト内ですべてを置換",
"アートの置換",
"レプリケート済み",
"レプリケート済み ",
0,
"不正使用を報告",
0,
"公開されているバージョンに戻す",
"巻き戻し",
"巻き戻し ",
"実行",
"main を実行",
0,
"インストルメンテーションを使用して実行",
"保存",
"保存済み",
"保存しています…",
"学校",
"スクリーン",
"スクリーンショット",
"{0} のスクリーンショット",
"スクリプト",
"スクリプトのプロパティ",
"スクリプト",
"検索",
"アートの検索",
"アート画像の検索",
"ここで {0} を検索",
"テンプレートの検索",
"検索中...",
"その他のオプションを表示",
"選択",
"他を選択",
"行の選択",
"この {0} のタイプを選択します ",
0,0,
"ローカル変数の名前を設定",
"名前の設定",
"ボードがスワイプされたときに起動されるハンドラーを設定",
"ボードがタップされたときに起動されるハンドラーを設定",
"ボードがタッチされたときに起動されるハンドラーを設定",
"ボードのタッチが解放されたときに起動されるハンドラーを設定",
"すべてのフィールドを既定値に設定します",
"保存された設定",
"設定",
"共有",
0,
"このアクティビティを完了させる方法を表示します",
"その他のオプションを表示",
"ショーケース",
"サインインしています",
0,0,
"サインアウト",
"サインインしています…",
0,
"簡略化",
"保存されたスキル レベル",
"繰り返しをスキップ",
0,
"ソーシャル",
0,
"サウンド",
0,
"スプラッシュ画面アート: {0}",
"分割",
0,
"最初からやり直し",
"スクリプトを開始",
"開始中...",
0,
"ステップ イン",
"ステップ アウト",
"ステップ オーバー",
0,
"停止して",
0,
"関数を停止",
"ループを停止",
"変数に格納",
"値を変数に格納します",
"文字列",
0,
"'{0}' を取り除く",
0,0,0,
"上等の, 超自然の, 最高の, 信じられない, この世のものとも思えない, 唯一の, 空前の, まれな, 奇妙な, 驚嘆すべき, 不思議なほど",
"囲む",
0,0,
"同期しています...",
0,0,0,0,0,
"タグ",
0,0,
"完了したら (←) をタップ",
"完了したら、[OK] をタップ",
0,
"ヒーローをタップすると次のステップに移動",
"完了したら、ここをタップ",
"ここをタップします",
"説明を表示するには、ここをタップします",
"ここをタップして開発中のアプリを実行します",
"タップしてカラーを変更",
"タップしてアイコン画像を変更",
"タップしてスプラッシュ画面の画像を変更",
"タップすると、Microsoft® Translator で翻訳されます...",
"一時的",
"terms of use",
"テスト",
"テスト関数",
"テスト",
"同じオブジェクトを参照する 2 つの参照をテストします",
0,0,
"ハブ",
"招待コードは 9～64 文字の数値にする必要があります",
"スプライトがクラッシュしました",
0,0,
"このスクリプトはライブラリです",
"このスクリプトは Web サービスです",
0,
"コードに",
"続行",
"グローバル変数に",
"ブレークポイントのトグル",
"トップと新機能",
0,0,
"翻訳",
"チュートリアルの翻訳...",
0,0,0,
"再挑戦!",
"次のものに変化",
"チュートリアルの進行状況",
"チュートリアル: ",
"チュートリアル",
"Twitter のハンドル名",
"タイプ: ",
"タイプ: {0}",
0,0,0,
"元に戻す",
0,0,0,
"アンインストール",
0,
"アンインストール中...",
0,0,0,0,
"更新",
0,0,0,0,0,0,
"アップロード",
"画像のアップロード",
"スクリーンショットのアップロード",
0,
"アップローダー",
0,0,
"URL",
"url (例: http://localhost:4242):",
0,
"ユーザー",
"値",
"変数",
"変数名",
"スクリプトとして表示",
"名前、電子メールを表示/編集しています…",
"vimeo ビデオ (https://vimeo.com/...)",
"壁紙",
"ライブラリ '{0}' がここにあります。 {1}",
"ここに {0:a} があります。これで何かを実行しようと思いましたか?",
"新しいフィールドが必要",
"新しい表が必要",
"新規が必要 {0}",
"別のキーパッドが必要です",
"新しい変数が必要",
"別のものを編集する必要があります",
"手順を追って説明します",
"Web アプリ",
0,0,
"WebサイトのURL",
"Web サイト",
"Webサイト名",
"Web サイトの URL",
0,0,0,0,0,
"生年",
"はい",
0,
"作業が完了しました。",
0,
"{0} ({1} 行{1:s})",
"{0} 日{0:s} 前",
"{0} ダウン",
0,0,0,
"{0} 時間{0:s} 前",
"{0} 分{0:s} 前",
"{0} か月{0:s} 前",
"{0} / {1} 完了",
"{0} 個を公開します",
"{0} 個のスクリプトが公開されました",
"{0} 秒{0:s} 前",
"{0} 個をアップロードします",
"{0} 年{0:s} 前",
0,0,
"● ログイン"
]); return true; }

if (lang == "ko") { TDev.Util._setLanguageArray(keys, [0,0,
" -- 지역 변수",
0,
" [숨김]",
0,0,0,0,0,
" / ",
0,
" 변경 내용을 보내는 중",
0,0,
"Javascripty의 중괄호, 모든 도구는 숙련된 개발자를 위한 것입니다!",
"'원자성' 함수",
0,0,0,0,
"'{0}'에 {1} 필요",
0,0,0,
"'{0}'은(는) 사용되지 않으므로 사용하면 안 됩니다.",
0,
"'{0}'이(가) '{1}' 반환, {2}",
0,0,0,0,0,0,0,0,
", 대신 {0} 받음",
", {0} 받음",
0,0,0,
"... 더 많은 결과가 있습니다. ...",
"// 설명",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>이 줄은 완벽합니다.</b> 넘어가세요.",
"<h3>현재 설정을 로드하는 중...</h3>",
"<h3>팁이 더 이상 없음!</h3>",
0,
"<h3>{0:q}에는 로그인이 필요함</h3>",
0,0,0,0,0,0,0,0,0,
"Minecraft Pi 앱.",
"Minecraft 앱.",
"Minecraft creeper 앱.",
0,0,0,0,0,0,0,0,0,0,
"색 상수",
0,0,0,0,0,0,0,0,0,
"전역 변수",
0,0,0,0,0,0,0,0,0,0,0,
"숫자(음수 또는 분수)",
"숫자 상수",
0,0,0,
"그림",
"텍스트",
"pixel art 앱.",
0,0,0,
"라이브러리 스크립트에 대한 참조",
0,0,0,0,0,0,0,0,0,
"사운드",
0,0,0,0,
"사용자 데이터 구조",
"사용자 정의 행의 테이블",
0,0,0,0,0,
"공개 프로필의 고유한 표시 이름(8자 이상)",
0,0,
"사용자 인터페이스",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"모든 디스플레이 프레임에 대해 실행되는 작업 추가",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"더하기",
0,
"현재 점수에 값을 추가합니다.",
0,0,
"스크립트 중지 후 코드를 찾아 수집된 정보를 보세요.",
"모든 내 그룹",
"모든 내 스크립트",
0,0,0,0,0,0,0,
"페이지 및 상자를 사용하는 비어 있는 앱.",
"scratch 라이브러리를 사용하는 비어 있는 앱.",
"비어 있는 문서 페이지.",
"비어 있는 대화형 자습서.",
"비어 있는 스크립트 편집기 플러그인.",
"아무런 작업도 수행하지 않는 비어 있는 스크립트.",
0,0,
"사용자 정의 행의 인덱싱된 테이블",
0,
"turtle 앱.",
"입력 컬렉션의 모든 요소에 `변환기` 적용 및 결과 컬렉션 반환",
0,
"다음 자습서를 중지하시겠습니까?",
0,
"이 사용자가 만든 아트:",
0,
"다른 개체에 데이터 첨부",
"게임을 만들기 위한 상용구 코드.",
0,0,0,0,0,0,
"기술 수준 변경!",
0,
"보드가 다른 보드와 동일한 인스턴스인지 확인합니다.",
0,0,0,
"이 보드와 관련된 큐의 모든 이벤트 지우기",
"배경 그림 지우기",
"배경 카메라 지우기",
0,0,
"사용자 상호 작업 발생 시 실행된 코드",
"특정 작업을 수행하는 코드",
"등호",
"어느 숫자가 더 작은지 비교",
0,
"부등호(보다 큼)",
0,0,0,0,0,0,0,
"두 텍스트 연결",
0,0,0,0,0,0,
"로컬 시간으로 변환",
0,0,0,0,0,
"그룹 만들기",
"스크립트 만들기",
"지정된 시작 지점, 너비 및 높이를 사용하여 라인 장애물을 만듭니다. 탄력성은 달라붙는 경우 0, 완전히 튕기는 경우 1입니다.",
"스프라이트용 새 컬렉션을 만듭니다.",
"새 원 스프라이트 만들기.",
"새 그림 스프라이트를 만드세요.",
"새 직사각형 스프라이트를 만듭니다.",
0,
"새 스프라이트 시트를 만듭니다.",
"새 텍스트 스프라이트를 만드십시오.",
"두 스프라이트 사이에 스프링을 만듭니다.",
"앵커 스프라이트를 만듭니다.",
"이 개체 유형의 잘못된 값 생성",
"채널 만들기",
0,0,
"지정된 거리에 보드를 둘러싼 벽을 만듭니다.",
"자신만의 앱 만들기",
0,0,
"빈 게임 보드를 새로 만들어 화면에 표시합니다.",
0,0,0,
"지정된 그림으로 너비100의 새 스프라이트를 만듭니다.",
0,
"유효하지 않은 게임패드 인스턴스 만들기",
0,0,
"현재 장치",
0,
"현재 터치 지점",
"이벤트에서 처리기를 분리합니다.",
0,
"담벼락에 이미지를 표시합니다. 변경 내용을 적용하려면 나중에 '담벼락에서 업데이트'를 호출해야 합니다.",
0,0,0,
"담벼락에 게임패드의 상태를 표시",
0,
"스프라이트 겹치기 수행",
0,
"문서",
"편집을 완료하면 아래로 스크롤하여 '저장'을 탭해야 합니다.",
"초보자에게 안성맞춤인 끌어서 놓기 블록, 간편해진 인터페이스!",
"두 점 사이 선 그리기",
"지정된 색과 글꼴 크기로 텍스트 테두리 그리기",
"예비 앱 개발자를 위한 텍스트로 코드 편집 기능 및 추가 옵션!",
0,0,
"이름 입력",
0,
"본인에 대한 정보를 입력하세요.",
"개인 웹 사이트의 URL(예: http://www.northwindtraders.com)을 입력하세요.",
"초대 코드 입력",
0,
"이벤트에는 Out 매개 변수가 있을 수 없습니다.",
"인터넷에서 모든 사람이 영구적으로 귀하의 그림을 볼 수 있게 됩니다. ",
0,0,
"확장",
"Facebook",
"지정된 색으로 타원 채우기",
"지정된 색으로 사각형 채우기",
"터치 종료 후의 최종 터치 속도",
"게시된 스크립트의 경우 게시된 스크립트 페이지의 탭을 보고 익명으로 수집된 크라우드 제공 프로필과 검사 데이터를 찾아보세요.",
"포럼",
"지금부터는 작성할 코드가 표시되지 않습니다. 지침에 따라 진행하고, 완료된 것 같으면 실행을 탭합니다.",
"현재 스크립트의 함수",
0,0,0,0,0,
"게임패드 상태 스냅샷을 가져옵니다(브라우저에 연결된 경우). 지원되지 않거나 연결된 게임패드가 없는 경우 비어 있습니다.",
0,0,0,
"보드가 가로 모드로 표시되도록 디자인되었는지 여부를 나타내는 값을 가져옵니다.",
"DRM에 의해 보호되는 곡인지 여부에 대한 값 가져오기",
"선택한 축의 x 및 y 값을 가져옵니다.",
0,0,
"배경 장면 가져오기",
"가로 가운데 위치 구하기(픽셀)",
0,
"ARGB 값이 #00FFFFFF인 색 가져오기",
"ARGB 값이 #FF000000인 색 가져오기",
"ARGB 값이 #FF0000FF인 색 가져오기",
"ARGB 값이 #FF008000인 색 가져오기",
"ARGB 값이 #FF00FFFF인 색 가져오기",
0,
"ARGB 값이 #FF800080인 색 가져오기",
0,0,0,0,
"ARGB 값이 #FFFF0000인 색 가져오기",
"ARGB 값이 #FFFF00FF인 색 가져오기",
"ARGB 값이 #FFFFA500인 색 가져오기",
0,
"ARGB 값이 #FFFFFF00인 색 가져오기",
"ARGB 값이 #FFFFFFFF인 색 가져오기",
0,0,0,0,
"사용 가능한 첫 번째 연결된 게임패드 가져오기",
0,
"게임패드 식별자 가져오기",
0,
"높이 구하기(픽셀)",
"카메라 이미지의 높이(픽셀)를 구합니다.",
0,0,0,0,0,0,0,0,0,
"플레이어 인덱스 가져오기",
"단추의 누름 값을 가져옵니다. 단추가 없는 경우 0을 반환합니다.",
0,
"0(무음)에서 1(현재 볼륨)까지 사운드 볼륨 가져오기",
"스프라이트 수 가져오기",
"i로 인덱싱된 스프라이트 가져오기",
0,
"이 스냅샷의 타임스탬프 가져오기",
0,
"너비 구하기(픽셀)",
"카메라 이미지의 너비(픽셀)를 구합니다.",
"y 위치 구하기(픽셀)",
"시작하기",
0,
"현재 스크립트의 전역 변수",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"디버그 모드에서 보드에는 속도와 기타 스프라이트 정보가 표시됨",
"단추를 눌렀는지 여부를 나타냅니다. 단추가 없는 경우 false를 반환합니다.",
0,
"게임패드 데이터가 동일한지 여부를 나타냄",
"게임패드가 아직 연결되어 있는지 여부를 나타냅니다.",
0,0,0,0,
"'{0}' {1} 삽입",
0,
"*로 표시된 항목은 필수 항목입니다.",
"JSON 데이터",
"그룹 참가",
"마지막 터치 종료 지점",
"마지막 터치 시작 지점",
0,0,0,0,0,
"업데이트를 보이도록 합니다.",
0,0,
"모든 스프라이트가 화면 끝에 닿으면 튀어오르도록 설정",
0,
"수학 공식, abs, max, ...",
"Me",
0,
"Minecraft 사용자",
0,0,
"스프라이트를 다른 스프라이트 방향으로 이동합니다.",
"곱하기",
0,0,0,0,0,0,0,0,
"새 스크립트",
0,
"새 또는 기본 제공 색",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"임의의 색 선택",
0,0,0,0,0,0,
"개인정보취급방침을 검토하세요.",
0,
"설명 게시...",
0,0,0,
"개인적으로 수행한 작업에는 run 단추가 표시되지 않습니다. ",
"사용자가 숫자를 입력하도록 표시",
0,
"스크립트 게시",
0,
"게시에 다음 적용됨 ",
"스크립트를 게시하는 중…",
"애니메이션 재생이 시작되면 실행됨",
"애니메이션 재생이 중지되면 실행됨",
"웨이브 사운드로 응답 본문 읽기",
"다른 사람이 스크립트를 검토하거나 스크립트의 스크린샷을 찍거나 이에 대해 댓글을 다는 경우, 사용자의 댓글에 답글이 게재되는 경우, 또는 사용자 구독 관련 이벤트가 발생할 경우 전자 메일 알림이 수신됩니다.",
"주의: 스크립트를 게시하면 모든 사람이 볼 수 있으므로 암호나 개인 정보가 포함되어 잇지 않은지 확인하세요.",
"현재 수명에서 값을 제거합니다.",
"회신...",
"보고/삭제",
"지정된 크기(픽셀)로 그림 크기 조정",
0,
"이미지의 복사본 반환",
0,0,
"이 인스턴스의 값에 지정된 개월 수를 추가하는 날짜를 반환합니다.",
"이 인스턴스의 값에 지정된 연도 수를 추가하는 날짜를 반환합니다.",
"\"min\"에서 \"max\"까지의 정수 난수를 반환합니다.",
0,0,0,0,0,0,0,
"현재 인스턴스가 소용 없을 경우 true 반환",
0,0,0,0,
"스크립트 업데이트",
"이 사용자가 작성한 스크립트:",
0,0,
"코드 검색...",
"모두 검색",
"여기 검색...",
0,0,
"검색...",
0,0,0,
"더 보기",
0,0,
"그라데이션 설정/해제",
"담벼락에 적용되는 3x3 행렬 유사 변환을 설정합니다.",
0,
"배경 카메라 설정",
"배경 색 설정",
"배경 색 설정.",
"배경 그림 설정",
"가로 가운데 위치 설정(픽셀)",
"현재 수명 점수를 설정합니다.",
"스프라이트의 기본 마찰을 0과 1 사이의 속도 손실 분수로 설정",
"높이 설정(픽셀)",
"위치 설정(픽셀)",
0,
"0(무음)에서 1(현재 볼륨)까지 사운드 볼륨 수준 설정",
"픽셀/초 단위로 속도 설정",
"스프라이트 색을 설정합니다.",
"보드의 개체에 대한 등가속도 벡터를 픽셀/초^2로 설정",
0,0,
"너비 설정(픽셀)",
"x 위치 설정(픽셀/초)",
"y 가속화 설정(픽셀/초)^2",
"y 위치 설정(픽셀)",
"y 위치 설정(픽셀/초)",
0,
"설정",
"이 url과 함께 공유:",
"이러한 플랫폼에서 실행되지 못하게 하는 API가 스크립트에 사용되는 경우 편집기에 오류를 표시합니다.",
"담벼락에 보드를 표시합니다.",
0,
"기술 수준: {0}     ",
0,0,0,0,0,
"모든 프레임 타이머 중지 및 지우기",
0,
"빼기",
0,
"TD100: 여기에 {0} 삽입",
"TD101: '{0}'을(를) 찾을 수 없음",
"TD109: 이 항목에 할당할 수 없음",
"TD111: {0}에서 {1}에 할당할 수 없음",
"TD112: {1}에서 속성 '{0}'을(를) 찾을 수 없음",
"TD115: {0}에 과도한 매개 변수 제공됨",
"TD116: {0}에 매개 변수가 충분히 제공되지 않음",
"TD118: 'if' 조건에 {1} 필요",
"TD119: 반복할 대상이 필요합니다.",
0,
"TD130: 'for'의 경계에 {1} 필요",
"TD144: '{0}'이(가) 누락된 것 같음, 추가 필요",
"TD145: 연산자('+', '(', ',' 등)가 누락된 것 같음",
"TD147: 여기에 '{0}' 필요 없음",
"TD150: '(' 앞의 항목을 호출할 수 없음",
"TD151: 닫히지 않은 '('",
"TD152: 예기치 않음 ')'",
"TD154: 연산자 다음 항목 필요",
"TD155: '{0}'은(는) 로컬 변수에 할당할 수 없음",
"Creative Coding을 지도하세요!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"이 스크립트는 다음 기능을 사용함: ",
0,
"이 자습서에서 사용하는 클라우드 데이터는 다른 사용자와 공유됩니다.",
"페이지 데이터를 추가하려면 로컬 변수를 만들고 '필드로 수준 올리기'를 탭하세요.",
0,0,0,0,
"Microsoft® Translator의 번역, 원본을 보려면 탭...",
"보드가 터치된 경우 true",
"올바르게 실행될 때까지 코드를 다듬어 봅니다. 진행이 중단되는 경우 자습서 막대를 탭합니다.",
0,0,
"자습서",
"Twitter",
"온라인 검색 내용 입력...",
"검색 내용 입력...",
0,
"이벤트 매개 변수의 유형, 순서 및 번호는 편집할 수 없습니다.",
"UI 위젯",
0,
"보드의 스프라이트 위치를 업데이트합니다.",
"그림 스프라이트의 그림 업데이트(그림 스프라이트인 경우)",
"텍스트 스프라이트의 텍스트 업데이트(텍스트 스프라이트인 경우)",
"그림 업로드",
"사운드 업로드",
"사용자",
0,
"추가 옵션이 필요함",
"편집기를 코딩 기술 수준에 맞춥니다. 나중에 허브에서 기술 수준을 변경할 수 있습니다.",
"프로그래밍 지식 수준은 어떻게 됩니까?",
"직업은 무엇입니까?",
"새로운 기능",
"현재 위치한 세계",
"지정된 위치에 다른 그림을 작성합니다. 불투명도 범위는 0(투명)에서 1(불투명)입니다.",
0,
"YouTube",
0,0,
"GitHub 사용자입니다.",
"Minecraft 사용자입니다.",
"아트가 여기 표시됨",
0,
"채널이 여기 표시됨",
"전자 메일 주소가 확인되지 않습니다. 받은 편지함을 확인하세요.",
"전체 이름",
0,0,0,
"스크립트가 여기 표시됨",
"@touchdevelop과 같은 Twitter handle.",
"몇 초 전",
"함수",
"전역 변수",
"1분 전",
"페이지",
"검사 정보",
"통찰력 정보",
"프로필 정보",
"내 정보",
"신고",
0,
"신고서",
0,0,0,
"{0} 필드에 액세스",
0,
"추가",
"새로 추가...",
0,
"모든 디스플레이 프레임에 대해 실행되는 작업을 추가합니다.",
0,0,0,0,0,
"입력 매개 변수 추가",
"위에 줄 추가",
"아래에 줄 추가",
"새로 추가",
0,0,
"출력 매개 변수 추가",
0,0,0,0,0,
"모든 API",
"허용",
"놀라운, 눈부신, 뜻밖의, 장엄한, 근사한, 숨막히는, 클래식, 멋진, 호기심을 일으키는, 명확한, 특별한, 예외적인, 대단한, 굉장한, 멋진, 훌륭한, 대단한, ",
0,
"함수 유형 정의",
"1시간 전",
0,0,0,0,0,
"앱",
0,
"아트",
"아트 리소스",
"과제",
0,
"만든 이",
0,0,
"뒤로",
0,
"백스페이스",
"이 항목 지우기",
0,0,
"기본",
"초보자",
"초보자",
0,
"스크립트에 바인딩:",
"비어 있음",
"비어 있는 앱",
"비어 있는 creeper",
"비어 있는 문서",
"비어 있는 게임",
"비어 있는 minecraft",
"비어 있는 minecraft pi",
"비어 있는 pixel art",
"비어 있는 scratch",
"비어 있는 스크립트 플러그인",
"비어 있는 turtle",
"비어 있는 자습서",
"중단하고 디버거 실행",
"중단점",
0,0,0,0,0,0,
"취소",
0,0,
"로컬로 다시 변경",
"콘텐츠 변경",
"채널",
"참조가 설정되지 않았는지 확인",
0,0,0,
"그림 선택(1MB 미만, 2048x2048보다 작음)",
0,0,0,0,0,0,
"코딩 기술 수준 선택",
"선택...",
0,
"지우기",
"클립보드",
"클론",
0,
"클라우드 세션",
"코드",
"골 라인 코딩",
"코더",
"색 #{0}",
"색: {0}",
"주석 처리",
"설명",
0,
"조건부",
"연결됨",
0,0,
"계속",
0,
"복사",
"선택 항목 복사",
"검사",
"만들기",
"새 매개 변수 만들기",
0,0,0,0,
"빈 개체 컬렉션 생성",
"스크립트 만들기",
0,
"현재 식",
"아트를 사용자 지정하십시오.",
"잘라내기",
"선택 항목 잘라내기",
"데이터베이스",
"디버그",
"소수점",
0,
"삭제",
"로컬 데이터 및 사용 권한 삭제",
"선택 항목 삭제",
"변수로 수준 내리기",
"거부",
"설명",
"설명(검색에 도움이 됨)",
0,
"세부 정보",
"사용하려던 것이 이 값인가요?",
"현재 차이",
"이전 차이",
0,0,0,
"취소",
"값 표시",
"담벼락에 개체 표시",
0,0,0,
"완료",
"완료했습니다.",
"편집",
"else if",
"전자 메일",
0,
"전자 메일 및 푸시 알림",
0,0,0,0,
"초대 코드 입력",
"이 코드 입력",
"오류",
0,
"이벤트",
0,
"예: ",
0,
"우수, 훌륭함, 멋짐, 감동, 보기 좋음, 잘함, 뛰어남, 해냄, 옳음",
0,
"종료",
"전문가",
0,
"내보내기",
"콘텐츠의 JSON 표현 내보내기",
"이 라이브러리에서 내보냄",
"확장",
0,
"선택 항목을 함수로 추출",
0,
"변수로 추출",
"참조 찾기",
"종료됨",
"수정",
"편집기에서 자습서 추적",
"그룹용",
"분기",
"함수",
"함수 이름",
"함수 유형",
"함수, 변수, 라이브러리, ...",
"성",
"내 Hour of Code™ 인증서 받기",
"모든 디스플레이 프레임에 대해 실행되는 타이머를 가져옵니다.",
"GitHub 사용자",
0,
"전체 바꾸기",
"전역 변수",
"전역 변수",
"뒤로 이동",
"코딩으로 돌아가기! 이동할 {0}★",
"뒤로 이동...",
"이동",
"스크립트의 항목 목록으로 이동",
"이전 단계로 이동",
"목표:",
"그룹",
0,
"하트",
"도움말",
0,0,
"기록",
"축하합니다! 스크립트가 게시되었습니다.",
"찾은 방법",
"다음에 실행",
"내 Hour of Code™ 마침",
"아이콘 아트: {0}",
0,
"진행이 중단되는 경우 골 라인 탭",
0,0,0,0,
"JSON 개체에서 필드 값 가져오기",
0,0,0,0,
"엄청난, 신기한, 놀랄 만한, 감동적인, 믿어지지 않는, 기적적인, 독특한, 경이적인, 끝내주는, 마음을 뒤흔드는, 특별한, 눈부신, 깜짝 놀라게 하는, 엄청난, 아주 멋진, ",
0,
"삽입",
"설명 삽입",
"문 삽입",
"{0} 삽입",
"통찰력",
0,
"스크립트를 설치 및 로드하는 중",
"로컬로",
0,
"문제",
"그룹 참가",
"그룹 참가",
0,
"검색어를 계속 입력하세요!",
"계속 편집",
"이곳의 알려진 이름:",
0,
"알아보기",
"게시에 대해 알아보기",
"자세히 알아보기",
"{0}에 대해 자세히 알아보기",
"자습서에서 나가기",
"이것을 바꿔 보겠습니다.",
"시작!",
"시작!",
"lib",
"라이브러리",
"라이브러리",
"라이브러리 이름",
"라이브러리 참조",
"더 로드",
"추가 회신 로드",
"로드 중",
0,
"/{0}에 대한 설명 로드 중...",
0,
"회신 로드 중...",
"스크립트 로드 중",
"자습서를 로드하는 중",
"로드 중...",
"로컬",
"위치",
0,
"논리 부정",
"로그",
"주",
0,
"메이커",
"데이터 관리",
"나중에",
"나",
0,0,
"minecraft 사용자",
0,0,
"기타",
"기타 ",
"추가 설정",
"커서 이동",
"왼쪽으로 이동",
"다음 단계로 이동",
"왼쪽으로 커서 이동",
"오른쪽으로 커서 이동",
"내 아트",
0,0,0,
"내 스크립트",
"여기에는 다른 이름이 필요함",
"여기에는 다른 문자열이 필요함",
"여기에 새 필드가 필요합니다",
"매개 변수 필요",
"삭제 필요",
"다른 곳에서 편집 필요",
"부정",
0,0,0,0,
"줄 추가",
0,0,0,
"아래 문 추가",
"새 변수",
0,
"다음 자습서...",
"애칭",
0,
"이 사용자가 게시한 아트 없음",
"설명 없음, 몇 가지를 기록하려면 탭!",
"분기가 없습니다. 스크립트를 설치, 편집 및 다시 게시하여 하나 만드십시오.",
"하트가 없습니다. 스크립트를 설치하면 하나 추가할 수 있습니다.",
"업로드된 그림 없음",
0,0,
"태그 없음, 몇 가지를 추가하려면 탭!",
0,0,0,
"알림",
0,
"이제 {0}의 속성을 선택할 수 있지만 그 자체는 아무 것도 하지 않음",
"이제 속성을 선택할 수 있습니다.",
"숫자",
"숫자 항목",
0,
"직업",
0,
"오프라인으로 사용 가능",
"확인",
"그럼 시작해 봅시다.",
"온라인",
0,
"또는 탭하여 도움말 확인",
"다른 사람",
"개요",
0,
"페이지",
0,
"스크립트 텍스트 구문 분석 중",
0,
"붙여넣기",
"일시 정지",
0,
"물리 게임 스타터",
"스크립트 템플릿 선택…",
"그림",
"그림 이름",
"그림 이름(최소 4자)",
"그림 url",
"다시 플레이",
0,
"잠시 기다려 주세요.",
"플러그 인",
"미리 보기",
"인쇄",
0,
"비공개",
"개인 함수",
"비공개 프로필",
"프로필",
"프로그래밍 지식",
0,
"데이터로 수준 올리기",
0,
"공개 애칭",
"공개 프로필",
"게시",
"숨김 항목으로 게시",
0,
"게시됨",
"변경 내용 받음",
"블록 수준으로 끌어내기",
0,
"다시 실행",
"자세히 읽기...",
"읽기 전용",
"실명",
0,
"전자 메일 뉴스레터 수신",
"전자 메일 알림 수신",
"레코드 이름:",
0,
"일반 키보드",
"스크립트를 다시 로드하는 중",
"제거",
0,
"그림 제거",
"흰색 배경 제거(게임 스프라이트에 최적)",
0,
"이름 바꾸기",
"n번 반복",
"컬렉션에서 반복",
"반복",
"함수에서 모두 바꾸기",
"스크립트에서 모두 바꾸기",
"그림 바꾸기",
"복제됨",
"복제됨 ",
0,
"신고",
0,
"게시된 버전으로 되돌리기",
0,
"되감기 ",
"실행",
"기본 실행",
0,
"계측으로 실행",
"저장",
"저장됨",
"저장하는 중...",
"학교",
"화면",
"스크린 샷",
"{0}의 스크린 샷",
"스크립트",
"스크립트 속성",
0,
"검색",
"아트 검색",
"아트 그림 검색",
"여기에서 {0} 검색",
"템플릿 검색",
"검색 중...",
"옵션 더 보기",
"선택",
"더 선택",
"이 줄 선택",
"이 {0}의 유형 선택",
0,0,
"로컬 변수 이름 설정",
"이름 설정",
"보드를 살짝 밀 때 호출되는 처리기 설정",
"보드를 탭할 때 호출되는 처리기 설정",
"보드를 터치할 때 호출되는 처리기 설정",
"보드를 터치했다가 뗄 때 호출되는 처리기 설정",
"모든 필드를 기본값으로 설정",
"설정 저장됨",
"설정",
"공유",
0,
"이 작업을 수행하는 방법 표시",
"추가 옵션 표시",
"소개",
"로그인",
0,0,
"로그아웃",
"로그인하는 중...",
0,
"단순화",
"기술 수준 저장됨",
"반복 건너뛰기",
0,
"소셜",
0,
"사운드",
0,
"시작 화면 아트: {0}",
"분할",
0,
"다시 시작",
"스크립트 시작 중",
"시작하는 중...",
0,
"한 단계씩 코드 실행",
"프로시저 나가기",
"프로시저 단위 실행",
0,
"중지",
0,
"함수 중지",
"반복 중지",
"변수에 저장",
"변수에 값 저장",
"문자열",
0,
"'{0}' 스트립",
0,0,0,
"우수한, 초자연적인, 빼어난, 믿기 어려운, 비현실적인, 독특한, 전례가 없는, 유별난, 기묘한, 이상한, 불가사의한",
"둘러싸기",
0,0,
"동기화 중...",
0,0,0,0,0,
"태그",
0,0,
"완료되면 (←) 탭",
"완료되면 [ok] 를 탭하세요.",
0,
"다음 단계로 이동하려면 여기를 탭하세요",
"완료되면 여기를 탭",
"여기 탭",
"여기를 탭하여 지침 보기",
"앱을 실행하려면 거기 탭",
"탭하여 색 변경",
"아이콘 그림을 변경하려면 탭",
"시작 화면 그림을 변경하려면 탭",
"Microsoft® Translator로 번역하려면 탭...",
"임시",
"terms of use",
"테스트",
"테스트 함수",
"테스트",
"두 참조가 동일한 개체를 참조하는지 테스트",
0,0,
"허브",
"초대 코드는 9~64자 사이의 숫자여야 함",
"스크립트가 충돌함",
0,0,
"이 스크립트는 라이브러리임",
"이 스크립트는 웹 서비스임",
0,
"코드에",
"계속하려면",
"전역 변수로",
"중단점 설정/해제",
"인기 및 최신",
0,0,
"번역",
"자습서를 번역하는 중...",
0,0,0,
"다시 시도하세요!",
"다음으로 변환",
"자습서 진행률",
"자습서: ",
"자습서",
"Twitter handle",
"유형: ",
"유형: {0}",
0,0,0,
"실행 취소",
0,0,0,0,0,0,0,0,0,0,
"업데이트",
0,0,0,0,0,0,
"업로드",
"사진 업로드",
"스크린 샷 업로드",
"소리 업로드",
0,0,0,
"url",
0,0,0,0,0,
"변수 이름",
"스크립트로 보기",
"이름, 전자 메일 등 보기/편집 ",
0,
"배경 화면",
"여기에 라이브러리 '{0}' 있음, {1}",
"여기에 {0:a}이(가) 있습니다. 이를 통해 작업을 수행하려 하셨습니까?",
"새 필드가 필요함",
"새 테이블이 필요함",
"새 항목이 필요함 {0}",
"다른 키보드 필요",
"새 변수가 필요함",
"다른 사항을 편집해야 함",
"단계별 안내",
"웹 앱",
0,0,0,
"웹 사이트",
0,
"웹 사이트 URL",
0,0,0,0,0,
"출생 연도",
0,0,
"해냈습니다.",
0,
"{0} ({1} 줄{1:s})",
"{0}일{0:s} 전",
0,0,0,0,
"{0}시간{0:s} 전",
"{0}분{0:s} 전",
"{0}개월{0:s} 전",
"{0}/{1} 완료",
"{0} 게시",
"{0} 스크립트가 게시됨",
"{0}초{0:s} 전",
"{0} 위로",
"{0}년{0:s} 전"
]); return true; }

if (lang == "nl") { TDev.Util._setLanguageArray(keys, [
"   Misschien {0} ({1} bij '{2}')\n",
"  Lijn {2} ('{1}'), fout: {0}\n{3}",
" -- een lokale variabele",
" [class]",
" [verborgen]",
" [override]",
" achterwaarts",
" voorwaarts",
" uren ",
" minuten ",
" van ",
" seconden ",
" wijzigingen worden doorgestuurd",
" wachten op de server",
"### volledige broncode",
"'Javascript'-accolades, alle hulpmiddelen, voor ervaren ontwerpers!",
"'atomaire' functie",
"'box' kan alleen geopend worden in de code bekijken pagina",
"'box' kan niet geopend worden in de HTML layout modus",
"'else' van de voorafgaande 'if' moet leeg zijn",
"'html' kan alleen geopend worden in de HTML layout modus",
"'{0}' verwacht {1} hier",
"'{0}' heeft een niet-ondersteunde handtekening",
"'{0}' is momenteel niet geïmplementeerd",
"'{0}' is verouderd en niet geïmplementeerd",
"'{0}' is verouderd en mag niet worden gebruikt",
"'{0}' is geen string bron",
"'{0}' retourneert een '{1}'; {2}",
"'{0}' geeft {1} waarden terug; u kunt de 'bewaren in var' knop gebruiken om hen lokaal op te slaan",
"(Optioneel) Een URI identificeerd een menselijke leesbare webpagina met information over de fout, gebruikt om de client-ontwikkelaar met extra informatie over de fout te verschaffen.",
"(Optioneel) Een menselijk leesbare foutcode.",
0,0,0,0,0,
", kreeg in plaats daarvan {0}",
", kreeg {0}",
0,0,0,
"... er is meer ...",
"// opmerking",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>deze regel is perfect!</b> laten we verdergaan",
"<h3>bezig met laden van huidige instellingen...</h3>",
"<h3>geen tips meer!</h3>",
0,
"<h3>{0:q} vereist aanmelding</h3>",
0,0,0,0,0,0,0,0,0,
"Een Minecraft Pi-app.",
"Een Minecraft-app.",
"Een Minecraft creeper-app.",
0,0,0,0,0,0,0,0,0,0,
"Een kleurconstante",
0,0,0,0,0,0,0,0,0,
"Een globale variabele",
0,0,0,0,0,0,0,0,0,0,0,
"Een aantal (mogelijk negatieve en/of gedeeltelijke)",
"Een getalconstante",
0,0,0,
"Een afbeelding",
"Een stuk tekst",
"Een pixel art-app.",
0,0,0,
"Een verwijzing naar een bibliotheekscript",
0,0,0,0,0,0,0,0,0,
"Een geluid",
0,0,0,0,
"Een structuur van gebruikersgegevens",
"Een tabel met door de gebruiker ingestelde rijen",
0,0,0,0,0,
"Een unieke weergavenaam voor uw openbare profiel (minimaal 8 tekens)",
0,0,
"Een gebruikersinterface",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Voeg een actie toe die wordt uitgevoerd voor elk weergavebeeld",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Telt getallen op",
0,
"Voegt een waarde toe aan de huidige score.",
0,0,
"Doorzoek nadat het script stopt de code om verzamelde informatie weer te geven.",
"Al mijn groepen",
"Al mijn scripts",
0,0,0,0,0,0,0,
"Een lege app die gebruikmaakt van pagina’s en kaders.",
"Een lege app die gebruikmaakt van de scratch-bibliotheek.",
"Een lege documentatie-pagina.",
"Een lege interactieve tutorial.",
"Een lege plug-in voor scriptbewerking.",
"Een leeg script, dat niks doet.",
0,0,
"Een geïndexeerde tabel met door de gebruiker ingestelde rijen",
0,
"Een turtle app.",
"Past 'omzetter' toe op alle elementen van de inputverzameling en retourneert een verzameling resultaten",
0,
"Weet je zeker dat je de tutorial niet meer wilt volgen?",
0,
"Activiteit van deze gebruiker:",
0,
"Bevestig gegevens aan andere objecten",
"Standaardcode om een game te maken.",
0,0,0,0,0,0,
"Niveau wijzigen!",
0,
"Controleert of het bord op dezelfde instantie is als het andere bord.",
0,0,0,
"Verwijder alle geplande events die aan dit bord zijn gerelateerd",
"Verwijder de achtergrondafbeelding",
"Verwijder de achtergrondcamera",
0,0,
"Code doorgegeven in geval van interactie met gebruiker",
"Code die een specifieke taak uitvoert",
"Vergelijkt getallen voor gelijkheid",
"Vergelijkt getallen voor minder",
0,
"Vergelijkt getallen voor meer",
0,0,0,0,0,0,0,
"Koppelt twee stukken tekst aaneen",
0,0,0,0,0,0,
"Zet om naar de lokale tijd",
0,0,0,0,0,
"Groep maken",
"Script maken",
"Een lijn-obstakel met bepaald startpunt en bepaalde breedte en hoogte maken. Elasticiteit is 0 voor plakkerig, 1 voor compleet stuiteren.",
"Maak een nieuwe verzameling voor sprites.",
"Een nieuwe ovaalsprite maken.",
"Een nieuwe afbeeldingssprite maken.",
"Een nieuwe rechthoeksprite maken.",
0,
"Een nieuwe spritesheet maken.",
"Een nieuwe tekstsprite maken.",
"Een spring tussen de twee sprites maken.",
"Een anchor-sprite maken.",
"Een ongeldige waarde van dit objecttype maken",
"Kanaal maken",
0,0,
"Muren rond het bord op de bepaalde afstand maken.",
"Maak je eigen apps",
0,0,
"Maakt een nieuw leeg spelbord en laat het zien op het scherm.",
0,0,0,
"Creëert een nieuwe sprite met een breedte van 100 met de bepaalde afbeelding.",
0,
"Maakt een ongeldige Gamepad-instantie",
0,0,
"Huidig apparaat",
0,
"Huidige aanraakpunt",
"Koppelt de handler los van de gebeurtenis.",
0,
"Geeft de afbeelding op de wand weer; je moet later 'bijwerken op wand' gebruiken als je wilt dat de veranderingen worden weergegeven.",
0,0,0,
"Geeft de status van de gamepad weer op de muur",
0,
"Overlappen de sprites elkaar",
0,
"Documenten",
"Vergeet niet om naar beneden te bladeren en op “Opslaan” te tikken als u klaar bent met bewerken!",
"Blokken verslepen en plaatsen, vereenvoudigde interface, perfect voor beginners!",
"Tekent een lijn tussen twee punten",
"Tekent een tekstrand met een gegeven kleur en fontgrootte",
"Code als tekst bewerken, meer opties, voor aankomende app-schrijvers!",
0,0,
"Voer een naam in",
0,
"Voer informatie over uzelf in.",
"Voer de URL naar uw persoonlijke website in (bijvoorbeeld: http://www.northwindtraders.com)",
"Vul de uitnodigingscode in",
0,
"Gebeurtenissen kunnen geen out parameters hebben.",
"Iedereen zal voor altijd je afbeelding kunnen zien op internet. ",
0,0,
"Uitbreidingen",
"Facebook",
"Vult een ovaal met een gegeven kleur",
"Vult een rechthoek met een gegeven kleur",
"Uiteindelijke aanraaksnelheid na stoppen aanraken",
"Bekijk bij gepubliceerde scripts ook de tab van de gepubliceerde scriptpagina om anoniem verzamelde crowd-sourced profiel- en dekkingsgegevens te zoeken.",
"Forums",
"Vanaf nu laten we de code niet meer zien. Volg de instructies en tik uitvoeren als je denkt dat je klaar bent.",
"Functies in het huidige script",
0,0,0,0,0,
"Maakt een snapshot van de status van het gamepad (indien aangesloten op de browser). Leeg wanneer het niet wordt ondersteund of er geen gamepad verbonden is.",
0,0,0,
"Krijgt een waarde die aangeeft of het bord is ontworpen om in landschapsmodus te worden weergegeven",
"Haalt een waarde op die aangeeft of het lied door DRM is beschermd",
"Haalt de x- en y-waarde van de geselecteerde assen op.",
0,0,
"Krijgt de achtergrondscène",
"Haalt de centrale horizontale positie in pixels op",
0,
"Haalt de kleur op met ARGB-waarde #00FFFFFF",
"Haalt de kleur op met ARGB-waarde #FF000000",
"Haalt de kleur op met ARGB-waarde #FF0000FF",
"Haalt de kleur op met ARGB-waarde #FF008000",
"Haalt de kleur op met ARGB-waarde #FF00FFFF",
0,
"Haalt de kleur op met ARGB-waarde #FF800080",
0,0,0,0,
"Haalt de kleur op met ARGB-waarde #FFFF0000",
"Haalt de kleur op met ARGB-waarde #FFFF00FF",
"Haalt de kleur op met ARGB-waarde #FFFFA500",
0,
"Haalt de kleur op met ARGB-waarde #FFFFFF00",
"Haalt de kleur op met ARGB-waarde #FFFFFFFF",
0,0,0,0,
"Neemt het eerste beschikbare aangesloten gamepad",
0,
"Haalt de identificatie van de gamepad op",
0,
"Haalt de hoogte in pixels op",
"Haalt de hoogte van het camerabeeld in pixels op.",
0,0,0,0,0,0,0,0,0,
"Haalt de spelerindex op",
"Haal de ingedrukt-status van een knop op. Levert 0 op als de knop ontbreekt.",
0,
"Haalt het geluidsvolume op voor geluiden van 0 (stil) tot 1 (huidig volume)",
"Krijgt de sprite-count",
"Sorteert de sprites op i",
0,
"Geeft het tijdstempel van dit snapshot",
0,
"Haalt de breedte in pixels op",
"Haalt de breedte van het camerabeeld in pixels op.",
"Haalt de y-positie in pixels op",
"Aan de slag",
0,
"Globale variabelen in het huidige script",
0,0,0,0,0,0,0,
"Als de pagina niet opende, tik dan op de 'open' knop beneden of tik 'klaar'.",
0,0,0,0,0,
"In de probleemoplossingsmodus geeft het bord de snelheid en andere info over sprites weer",
"Geeft aan of een knop wordt ingedrukt Levert false op als de knop ontbreekt.",
0,
"Geeft aan of de gamepadgegevens identiek zijn",
"Geeft aan of de gamepad nog verbonden is.",
0,0,0,0,
"'{0}' {1} invoegen",
0,
"Onderdelen gemarkeerd met * zijn verplicht.",
"JSON-gegevens",
"Aanmelden bij groep",
"Eindpunt laatste aanraking",
"Startpunt laatste aanraking",
0,0,0,0,0,
"not yet translated",
0,0,
"Laat alle sprites stuiteren op drie randen van het scherm",
0,
"Wiskunde, abs, max,...",
"Me",
0,
"Minecraft-gebruiker",
0,0,
"Verplaatst een sprite naar een andere sprite.",
"Vermenigvuldigt getallen",
0,0,0,0,0,0,0,0,
"Nieuwe scripts",
0,
"Nieuwe of ingebouwde kleuren",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Kiest een willekeurige kleur",
0,0,0,0,0,0,
"Lees onze Privacyverklaring.",
0,
"Een opmerking posten...",
0,0,0,
"Privé acties krijgen geen 'run' knop. ",
"Vraagt de gebruiker om een waarde in te voeren",
0,
"Script publiceren",
0,
"Publicatie is onderhevig aan onze ",
"Script publiceren...",
"Wordt doorgegeven als de animatie begint te spelen",
"Word doorgegeven als de animatie stopt met spelen",
"Leest het responslichaam als een geluidsgolf",
"Ontvang e-mailmeldingen als anderen je scripts bekijken/daar een schermafbeelding van maken/daar opmerkingen over hebben, of een van je opmerkingen beantwoorden, of als gebeurtenissen plaatsvinden die betrekking hebben op je abonnementen.",
"Vergeet niet dat iedereen uw script kan zien als u het publiceert, dus zorg ervoor dat het niet uw wachtwoord of persoonlijke gegevens bevat.",
"Verwijdert de waarde voor het huidige leven.",
"Beantwoorden...",
"Rapport/verwijder",
"Past de afbeelding aan de opgegeven grootte in pixels aan",
0,
"Retourneert een kopie van de afbeelding",
0,0,
"Retourneert een datum die het opgegeven aantal maanden optelt bij de waarde van dit geval.",
"Retourneert een datum die het opgegeven aantal jaren optelt bij de waarde van dit geval.",
"Retourneert een willekeurig geheel getal tussen ‘min’ en ‘max’.",
0,0,0,0,0,0,0,
"Retourneert waar als het huidige geval nutteloos is",
0,0,0,0,
"Scriptupdates",
"Scripts van deze gebruiker:",
0,0,
"Code zoeken...",
"Alles doorzoeken",
"Hier zoeken...",
0,0,
"Zoek...",
0,0,0,
"Meer info",
"Definieer wat er gebeurd als op de box wordt getikt",
0,
"Schakelt kleurovergang in of uit",
"Stelt de 3x3 affiene matrixtransformatie in die op de wand is toegepast.",
0,
"Stelt de achtergrondcamera in",
"Stelt de achtergrondkleur in",
"Stelt de achtergrondkleur in.",
"Stelt de achtergrondafbeelding in",
"Stelt de centrale horizontale positie in pixels in",
"Hiermee wordt het aantal levens ingesteld.",
"Stel de standaard frictie voor sprites in op een fractie van snelheidsverlies tussen 0 en 1",
"Stelt de hoogte in pixels in",
"Stelt de positie in pixels in",
0,
"Stelt het volumeniveau in van 0 (stil) op 1 (huidig volume)",
"Stelt de snelheid in pixels/sec in",
"Stelt de kleur van de sprite in.",
"Stel de algemene acceleratievector voor objecten op het bord in op pixels/sec^2",
0,0,
"Stelt de breedte in pixels in",
"Stelt de x-snelheid in pixels/sec in",
"Stelt de y-versnelling in pixels/sec^2 in",
"Stelt de y-positie in pixels in",
"Stelt de y-snelheid in pixels/sec in",
0,
"Instellingen",
"Deel het met deze url:",
"Geeft fouten weer in de editor als het script API's gebruikt die voorkomen dat de app op deze platformen kan worden uitgevoerd.",
"Geeft het bord op de muur weer.",
0,
"Vaardigheidsniveau: {0}     ",
0,0,0,0,0,
"Stopt en verwijdert alle every frame timers",
0,
"Trekt getallen af",
0,
"TD100: hier {0} invoegen",
"TD101: kan '{0}' niet vinden",
"TD109: kan niet toewijzen aan deze",
"TD111: kan niet toewijzen van {0} aan {1}",
"TD112: ik kan eigenschap '{0}' op {1} niet vinden",
"TD115: excessieve parameter(s) geleverd aan {0}",
"TD116: niet genoeg parameters geleverd aan {0}",
"TD118: 'als'-voorwaarde wil {1}",
"TD119: Ik heb iets nodig om te doorlopen",
0,
"TD130: limiet van 'voor' wil {1}",
"TD144: het lijkt erop dat '{0}' ontbreekt, probeer deze toe te voegen",
"TD145: er lijkt hier een operator (zoals '+', '(' of ',') te ontbreken",
"TD147: we hadden '{0}' hier niet verwacht",
"TD150: kan het ding voor ' (' niet aanroepen",
"TD151: ongesloten ' ('",
"TD152: onverwachte ')'",
"TD154: er moet iets na de operator komen",
"TD155: '{0}' kan niet worden toegewezen aan een lokale variabele",
"Doceer creatief coderen!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Dit script gebruikt de volgende mogelijkheden: ",
0,
"Deze tutorial gebruikt gegevens in de cloud die gedeeld worden met andere gebruikers.",
"Maak een lokale var en tik op 'bevorderen naar veld' om paginagegevens toe te voegen.",
0,0,0,0,
"Vertalingen door Microsoft ® vertaler, tik om het origineel te zien...",
"Waar als bord aangeraakt is",
"Probeer de code aan te passen tot deze goed is. Tik op de lesbalk als je vastzit.",
0,0,
"Tutorials",
"Twitter",
"Typ om online te zoeken...",
"Typ om te zoeken...",
0,
"Het type, de volgorde en het aantal gebeurtenisparameters kunnen niet bewerkt worden.",
"UI widget",
0,
"Posities van sprites op bord bijwerken.",
"Werkt afbeelding op een afbeeldingssprite bij (als het een afbeeldingssprite is)",
"Werkt tekst op een sprite bij (als het een tekstsprite is)",
"Afbeelding uploaden",
"Geluid uploaden",
"Gebruikers",
0,
"We hebben meer opties nodig",
"We passen de editor aan uw coderingsniveau aan. U kunt uw ervaringsniveau later in de hub wijzigen.",
"Wat is het niveau van uw programmeerkennis?",
"Wat is uw beroep?",
"Wat is er nieuw",
"Waar ter wereld bent u?",
"Schrijft nog een afbeelding op een gegeven locatie. De opaciteit loopt uiteen van 0 (transparant) tot 1 (ondoorzichtig).",
0,
"YouTube",
0,0,
"Uw GitHub-gebruiker.",
"Uw Minecraft-gebruiker.",
"Uw kunst verschijnt hier",
0,
"Uw kanaal verschijnt hier",
"Uw e-mailadres is nog niet geverifieerd. Controleer uw postvak.",
"Uw volledige naam",
0,0,0,
"Jouw script verschijnt hier",
"Uw twitter-gebruikersnaam, zoals @touchdevelop.",
"een paar seconden geleden",
"een functie",
"een globale variabele",
"een minuut geleden",
"een pagina",
"over dekking",
"over inzichten",
"over profiel",
"over u",
"misbruik",
0,
"meldingen van misbruik",
0,0,0,
"toegang tot het veld {0}",
0,
"toevoegen",
"een nieuwe toevoegen...",
0,
"voeg een actie toe die wordt uitgevoerd voor elk weergavebeeld.",
0,0,0,0,0,
"invoerparameter toevoegen",
"voeg hierboven een regel toe",
"voeg hieronder een regel toe",
"nieuwe toevoegen",
"voeg een nieuwe tag toe",
0,
"uitvoerparameter toevoegen",
0,0,0,0,0,
"alle API's\n",
"toestaan",
"verbazingwekkend, verbijsterend, ongelofelijk, ontzagwekkend, gaaf, adembenemend, klassiek, gaaf, curieus, apart, uitzonderlijk, exclusief, buitengewoon, fabuleus, fantastisch, glorieus, geweldig, ",
0,
"definitie voor een functietype",
"een uur geleden",
0,0,0,0,0,
"apps",
0,
"kunst",
"kunst resource",
"opdracht",
0,
"auteur",
0,0,
"terug",
0,
"backspace",
"verwijder deze met backspace",
0,0,
"basis",
"beginner",
"beginners",
0,
"verbindt aan script:",
"leeg",
"lege app",
"lege creeper",
"lege docs",
"lege game",
"lege minecraft",
"lege minecraft pi",
"lege pixel art",
"lege scratch",
"leeg script plug-in",
"lege turtle",
"lege tutorial",
"stop in debugger",
"onderbrekingspunt",
0,0,0,0,0,0,
"annuleren",
0,0,
"(terug) veranderen naar lokaal",
"inhoud veranderen",
"kanalen",
"controleert of verwijzing niet werd ingesteld",
0,0,0,
"kies een foto (minder dan 1 MB, kleiner dan 2048x2048)",
0,0,0,0,0,0,
"kies uw vaardigheidsniveau voor coderen",
"kiezen...",
0,
"wissen",
"klembord",
"klonen",
0,
"cloud-sessies",
"code",
"codeer de doellijn",
"programmeur",
"kleur #{0}",
"kleur: {0}",
"commentaar uit",
"opmerkingen",
0,
"voorwaardelijk",
"verbonden",
0,0,
"doorgaan",
0,
"kopie",
"kopieer selectie",
"dekking",
"creëren",
"een nieuwe parameter maken",
0,0,0,0,
"maakt een lege verzameling van objecten",
"script maken",
0,
"huidige expressie",
"pas de afbeeldingen aan!",
"knippen",
"selectie knippen",
"database",
"debuggen",
"decimale punt",
0,
"verwijderen",
"lokale gegevens en machtigingen verwijderen",
"selectie verwijderen",
"terugzetten naar var",
"afwijzen",
"beschrijving",
"beschrijving (helpt bij zoeken)",
0,
"details",
"wilde je deze waarde gebruiken?",
"huid wijz",
"vor wijz",
0,0,0,
"negeren",
"waarde weergeven",
"geeft het object op de wand weer",
0,0,0,0,
"klaar!",
"bewerken",
"anders als",
"e-mail",
0,
"e-mail- en push-meldingen",
0,0,0,0,
"vul uitnodigingscode in",
"voer deze code in",
"fouten",
0,
"evenementen",
0,
"ex: ",
0,
"uitstekend; goed gedaan; fantastisch; vet; jij bent geweldig; super; grandioos; het is je gelukt; perfect",
0,
"afsluiten",
"expert",
0,
"exporteren",
"een JSON-representatie van de inhoud exporteren",
"geëxporteerd van deze bibliotheek",
"uitbreiden",
0,
"selectie uitpakken naar functie",
0,
"overnemen naar var",
"verwijzingen zoeken",
"afgelopen",
"repareer het",
"tutorial in editor volgen",
"voor groep",
"splitsingen",
"functie",
"naam functie",
"soorten functie",
"functie, variabele, bibliotheek, ...",
"geslacht",
"mij Uur Code™-certificaat ontvangen",
"neemt de timer die wordt uitgevoerd voor elk weergavebeeld.",
"github-gebruiker",
0,
"globaal vervangen",
"globale variabele",
"globale vars",
"terug",
"programmeer verder! nog {0}★ te gaan",
"terug...",
"ga naar",
"ga naar een lijst met zaken in je script",
"ga naar de vorige stap",
"doel:",
"groep",
"groepen",
"harten",
"help",
0,
"verbergen",
"geschiedenis",
"hoera! Je script wordt gepubliceerd",
"hoe gevonden",
"ik wil het uitvoeren op",
"ik ben klaar met mijn Uur Code™",
"pictogramkunst: {0}",
"als",
"Tik op de doellijn als je vastzit",
0,0,0,0,
"veldwaarden van een JSON-object importeren",
0,0,0,0,
"onvoorstelbaar, magisch, schitterend, onthutsend, verbijsterend, miraculeus, vreemd, fenomenaal, stoer, speciaal, spectaculair, opzienbarend, magnifiek, supergaaf ",
0,
"invoegen",
"opmerking invoegen",
"propositie invoegen",
"{0} invoegen",
"inzichten",
0,
"script installeren en laden",
"naar lokaal",
0,
"problemen",
"aanmelden bij een groep",
"aanmelden bij groep",
0,
"blijf de zoektermen gewoon intypen!",
"doorgaan met bewerken",
"hier bekend als:",
0,
"leren",
"meer informatie over publiceren",
"meer leren",
"meer weten over {0}",
"tutorial verlaten",
"laten we dit veranderen",
"aan de slag!",
"laten we beginnen!",
"lib",
"bibliotheken",
"bibliotheek",
"naam bibliotheek",
"bibliotheekreferentie",
"meer laden",
"laden van meer antwoorden",
"laden",
0,
"opmerkingen voor /{0} worden geladen...",
0,
"antwoorden worden geladen...",
"script wordt geladen",
"tutorial laden",
"laden...",
"lokaal",
"locatie",
0,
"logische negatie",
"logboeken",
"main",
0,
"makers",
"gegevens beheren",
"misschien later",
"ik",
0,0,
"minecraft-gebruiker",
0,0,
"meer",
"meer ",
"meer instellingen",
"cursor verplaatsen",
"ga naar links",
"verder met de volgende stap",
"verplaats de cursor naar links",
"verplaats de cursor naar rechts",
"mijn kunst",
0,0,0,
"mijn scripts",
"hier is een andere naam nodig",
"hier is een andere tekenreeks nodig",
"nieuw veld nodig hier",
"parameter nodig",
"moet dit verwijderen",
"bewerken op ander punt nodig",
"ontkenning",
0,0,0,0,
"nieuwe regel",
0,0,0,
"nieuwe stmt hieronder",
"nieuwe variabele",
0,
"volgende tutorials...",
"bijnaam",
0,
"geen afbeeldingen gepubliceerd door deze gebruiker",
"geen commentaar, tik om iets te schrijven!",
"geen vorken. Installeer, bewerk en publiceer script opnieuw om er één te maken!",
"geen harten. Je kunt er één toevoegen nadat je het script hebt geïnstalleerd!",
"nog geen afbeelding geladen",
0,0,
"geen codes, tik om er enkele toe te voegen!",
0,0,0,
"meldingen",
0,
"nu kun je een eigenschap selecteren van {0}; op zichzelf doet het niets",
"nu kun je er een eigenschap voor selecteren",
"aantal",
"getalinvoer",
0,
"beroep",
"van een object",
"offline beschikbaar",
"oké",
"ok, aan de slag!",
"online",
0,
"of tik voor hulp",
"anderen",
"overzicht",
0,
"pagina 's",
0,
"scripttekst wordt geparseerd",
0,
"plakken",
"pauzeren",
0,
"natuurkundegame starter",
"kies een scriptsjabloon...",
"afbeelding",
"naam foto",
"naam foto (minimaal 4 tekens)",
"afbeeldings-url",
"speel opnieuw",
0,
"een ogenblik geduld...",
"plugins",
"voorbeeld",
"afdrukken",
0,
"privé",
"persoonlijke functie",
"privéprofiel",
"profiel",
"programmeerkennis",
0,
"verhogen naar data",
"promoveren naar veld",
"openbare bijnaam",
"openbaar profiel",
"publiceren",
"verborgen publiceren",
0,
"gepubliceerd",
"haal wijzigingen op",
"trek uit niveau blokkeren",
0,
"opnieuw uitvoeren",
"lees meer...",
"alleen lezen",
"echte naam",
0,
"e-mailnieuwsbrieven ontvangen",
"e-mailmeldingen ontvangen",
"naam record:",
0,
"gewoon toetsenpaneel",
"script opnieuw laden",
"verwijderen",
"verwijderen anders",
"afbeelding verwijderen",
"verwijder witte achtergrond (beste voor gamesprites)",
0,
"naam wijzigen",
"n keer herhalen",
"herhaal op collectie",
"herhalen zolang",
"alle vervangen in functie",
"alle vervangen in script",
"afbeelding vervangen",
"herhaald",
"herhaald ",
0,
"misbruik melden",
"hervatten",
"terugkeren naar gepubliceerde versie",
"terugspoelen",
"terugspoelen ",
"uitvoeren",
"hoofdprogramma uitvoeren",
0,
"uitvoeren met instrumentatie",
"opslaan",
"opgeslagen",
"bezig met opslaan...",
"school",
"schermen",
"schermafbeelding",
"schermafbeelding van {0}",
"script",
"eigenschappen van script",
0,
"zoeken",
"afbeeldingen doorzoeken",
"kunstafbeeldingen doorzoeken",
"hier zoeken naar {0}",
"zoek sjablonen",
"zoeken...",
"bekijk meer opties",
"selecteer",
"meer selecteren",
"selecteer deze regel",
"selecteer type van deze {0}",
0,0,
"instellen naam lokale variabele",
"naam instellen",
"stel de handler in die wordt opgeroepen wanneer over het bord wordt geveegd",
"stel de handler in die wordt uitgelokt wanneer op het bord wordt getikt",
"stel de handler in die wordt opgeroepen wanneer het bord wordt aangeraakt",
"stel de handler in die wordt opgeroepen wanneer op het bord wordt getikt",
"stelt alle velden in op hun standaardwaarden",
"instelling opgeslagen",
"instellingen",
"delen",
0,
"laat zien hoe je deze activiteit kunt afronden",
"meer opties tonen",
"tentoonstellen",
"aanmelden",
0,0,
"afmelden",
"bezig met aanmelden...",
0,
"vereenvoudigen",
"ervaringsniveau opgeslagen",
"iteratie overslaan",
0,
"sociaal",
0,
"geluid",
0,
"welkomstschermkunst: {0}",
"splitsen",
0,
"begin opnieuw",
"script starten",
"beginnen...",
0,
"instappen",
"uitstappen",
"eroverheen stappen",
0,
"stop",
0,
"functie stoppen",
"lus stoppen",
"opslaan in var",
"sla de waarde op in een variabele",
"tekenreeks",
0,
"strip '{0}'",
0,0,0,
"superieur, bovennatuurlijk, ontzagwekkend, ongelofelijk, buitenaards goed, uniek, ongekend, ongebruikelijk, vreemd, schitterend, prachtig, wonderbaarlijk",
"omringen met",
0,0,
"synchroniseert...",
0,0,0,0,0,
"tags",
0,0,
"tik op (←) als je klaar bent",
"tik [ok] wanneer je klaar bent",
"tik een checkmark om je 'vote' aan een bestaande 'tag' toe te voegen",
"tik hier om verder te gaan met de volgende stap",
"tik hier als je klaar bent",
"tik daar",
"tik daar voor instructies",
"tik daar om de app uit te voeren",
"tik om de kleur te veranderen",
"tik om het pictogram te veranderen",
"tik om de welkomstschermafbeelding te veranderen",
"tik hier om te vertalen met Microsoft ® vertaler...",
"tijdelijk",
"terms of use",
"test",
"testfunctie",
"proeven",
"controleert of twee verwijzingen verwijzen naar hetzelfde object",
0,0,
"de hub",
"de uitnodigingscode moet een nummer zijn tussen 9 en 64 tekens lang",
"het script is gecrashed",
0,0,
"dit script is een bibliotheek",
"dit script is een webdienst",
0,
"naar code",
"doorgaan",
"naar globale var",
"onderbrekingspunt",
"beste en nieuw",
0,0,
"vertalen",
"tutorial vertalen...",
0,0,0,
"probeer opnieuw!",
"veranderen in",
"voortgang tutorial",
"tutorial: ",
"tutorials",
"twitter-gebruikersnaam",
"type: ",
"type: {0}",
0,0,0,
"ongedaan maken",
0,0,0,0,0,0,0,0,0,0,
"bijwerken",
0,0,0,0,0,0,
"uploaden",
"afbeelding uploaden",
"schermafbeelding uploaden",
"geluid uploaden",
0,0,0,
"url",
0,0,0,0,0,
"naam variabele",
"weergeven als script",
"bekijk/bewerk naam, e-mail, ...",
0,
"achtergrond",
"we hebben een bibliotheek '{0}' hier; {1}",
"dit is een {0:a}; wilde je daar iets mee doen?",
"we hebben een nieuw veld nodig",
"we hebben een nieuwe tabel nodig",
"we hebben een nieuwe nodig {0}",
"we hebben een ander toetsenpaneel nodig",
"we hebben een nieuwe variabele nodig",
"we moeten ook nog iets anders bewerken",
"we begeleiden je stap voor stap",
"webapps",
0,0,0,
"website",
0,
"website url",
0,0,0,0,0,
"geboortejaar",
0,0,
"Het is je gelukt!",
0,
"{0} ({1} regel{1:s})",
"{0} dag {0:s} geleden",
0,0,0,0,
"{0} uur {0:s} geleden",
"{0} minuten {0:s} geleden",
"{0} maand {0:s} geleden",
"{0} van {1} gereed",
"{0} publiceren",
"{0} script gepubliceerd",
"{0} seconden{0:s} geleden",
"{0} omhoog",
"{0} jaar {0:s} geleden"
]); return true; }

if (lang == "pl") { TDev.Util._setLanguageArray(keys, [
"   Może: {0} ({1} w '{2}')\n",
"  -> Linia {2} ('{1}'), błąd: {0}\n{3}",
" -- zmienna lokalna",
0,0,0,
" do tyłu",
" do przodu",
" godzin ",
" minut ",
" z ",
" sekundy ",
" wysyłanie zmian",
0,0,
"'Zastosowanie nawiasów klamrowych podobnie jak w JavaScript, wszystkie narzędzia niezbędne doświadczonym programistom!",
0,0,0,0,0,
"'{0}' oczekuje {1} tutaj",
0,0,0,
"„{0}” to element przestarzały i nie należy go używać",
0,
"'{0}' zwraca '{1}'; {2}",
0,0,0,0,0,0,0,0,
", a dostaliśmy {0}",
", mamy {0}",
0,0,0,0,
"// komentarz",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>ten wiersz jest doskonały!</b> przejdźmy dalej",
"<h3>ładowanie bieżących ustawień…</h3>",
"<h3>koniec podpowiedzi!</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Kolor argb (alfa, czerwony, zielony, niebieski)",
0,0,0,0,0,0,0,
"Stała koloru",
0,0,0,0,0,0,0,0,0,
"Zmienna globalna",
0,0,0,0,0,0,0,0,0,0,0,0,
"Stała liczba",
0,0,0,
"Obraz",
0,0,
"Miejsce aby podpiąć akcję, żeby wykonać ją w odpowiedzi na zdarzenie",
0,0,
"Odwołanie do skryptu z biblioteki",
0,0,0,0,0,0,0,0,
"Piosenka",
"Dźwięk",
"Efekt dźwiękowy",
0,0,0,0,
"Tabela wierszy zdefiniowanych przez użytkownika",
0,0,0,0,
"Zegar",
"Unikatowa nazwa wyświetlana Twojego profilu publicznego (co najmniej 8 znaków)",
0,0,
"Interfejs użytkownika",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Dodaj akcję, która zadziała dla każdej wyświetlanej klatki",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Dodaje liczby",
0,
"Dodaje wartość do bieżącego wyniku.",
0,0,
"Po zatrzymaniu skryptu przejrzyj kod i zapoznaj się z zebranymi informacjami.",
0,
"Wszystkie moje skrypty",
0,0,0,0,0,0,0,0,0,0,0,0,
"Pusty skrypt, który nic nie robi.",
0,0,
"Indeksowana tabela wierszy zdefiniowanych przez użytkownika",
0,0,
"Aplikuje `converter` na wszystkich elementach kolekcji wejściowej i zwraca kolekcję wyników",
0,0,
"Operacje arytmetyczne i logiczne na 32-bitowych liczbach całkowitych",
"Zasoby artystyczne tego użytkownika:",
"Wprowadź lub wyświetl wartości na ścianie...",
0,
"Stelarz do stworzenia gry.",
"Przeglądaj i recenzuj skrypty z bazaru",
0,0,
"Aparat fotograficzny, lokalizacja, mikrofon i inne czujniki",
0,0,
"Zmień poziom umiejętności!",
0,0,0,0,0,0,0,0,0,
"Zarządzanie sesjami w chmurze",
"Kod zgłaszany po interakcji z użytkownikiem",
"Kod wykonujący określone zadanie",
"Porównuje liczby",
"Sprawdza, która liczba jest mniejsza",
0,
"Sprawdza, która liczba jest większa",
0,0,0,0,0,0,0,
"Łączy dwa fragmenty tekstu",
0,0,0,0,0,0,
"Konwertuje na czas lokalny",
0,0,
"Funkcje pomocnicze dla poprawności",
0,
"Utwórz kod",
"Utwórz grupę",
"Utwórz skrypt",
0,0,0,
"Utwórz nowy obrazek złożony.",
0,
"Utwórz nowy skrypt",
0,0,0,0,0,
"Utwórz kanał",
"Tworzy kolekcję przedmiotów.",
"Tworzenie nieprawidłowych wartości",
0,
"Stwórz własne aplikacje",
0,0,0,0,0,0,0,0,0,0,
"Bieżące pudełko na stronie.",
"Bieżące urządzenie",
0,0,
"Odłącza program obsługi od zdarzenia.",
"Wyświetla napis na ścianie",
"Wyświetla zdjęcia na tablicy; trzeba będzie wywołać polecenie „update on wall” później, jeśli chcesz zobaczyć zmiany.",
0,0,0,0,
"Dzielenie liczb",
"Nałóż na siebie obrazki",
"Czy chcesz otrzymywać biuletyny informacyjne związane z Touch Develop, np. poświęcone nowym funkcjom i nadchodzącym wydarzeniom?",
"Dokumenty",
"Nie zapomnij przewinąć w dół i nacisnąć przycisku „zapisz” po zakończeniu edycji!",
"Przeciąganie i upuszczanie bloków, uproszczony interfejs, doskonałe narzędzie dla początkujących!",
"Rysuje linię między dwoma punktami",
"Rysuje niektóre obramowania tekstowe za pomocą zadanego koloru i rozmiaru czcionki",
"Edytowanie kodu w formie tekstu i więcej opcji dla początkujących programistów!",
"E-maile, sms, kontakty, kalendarz...",
0,0,0,
"Wpisz informacje o sobie",
"Wpisz adres URL własnej witryny internetowej (na przykład: http://www.northwindtraders.com)",
0,
"Opisz swoje powiązanie ze szkołą, jeśli takie masz.",
0,0,0,0,0,
"Facebook",
"Wypełnia elipsę zadanym kolorem",
"Wypełnia prostokąt zadanym kolorem",
0,
"W przypadku opublikowanych skryptów poszukaj także na karcie strony opublikowanego skryptu anonimowo zebranych profili społecznościowych i danych o pokryciu.",
"Fora",
"Od teraz nie pokażemy Ci kodu do wpisania. Postępuj zgodnie z instrukcjami i gdy jesteś gotowy uruchom program.",
0,
"Współrzędne geograficzne",
0,0,0,0,0,0,0,0,0,
"Pobiera wartość, określającą czy utwór jest chroniony prawami DRM",
0,0,0,0,
"Pobiera wyśrodkowane położenie poziome w pikselach",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Pobiera wysokość w pikselach",
"Pobiera wysokość obrazu z aparatu w pikselach.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Pobiera głośność dźwięku od 0 (cicho) do 1 (bieżąca głośność)",
0,0,0,0,0,
"Pobiera szerokość w pikselach",
"Pobiera szerokość obrazu z aparatu w pikselach.",
"Pobiera położenie y w pikselach",
"Pierwsze kroki",
0,
"Globalne zmienne w bieżącym skrypcie",
0,0,0,0,0,0,
"Skąd wiesz o Touch Develop?",
0,
"Importuj kod",
"Importuj skrypt z pliku",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Interakcja z bibliotekami uruchomieniowymi",
"Elementy oznaczone symbolem * są wymagane.",
0,
"Dołącz do grupy",
0,0,0,0,0,0,0,0,0,0,
"Sprawia, że wszystkie sprite'y odbijają się od krawędzi ekranu",
"Mapy, z lokalizacji do adresu i odwrotnie",
0,
"Ja",
0,0,0,0,0,
"Mnoży liczby",
0,0,0,0,0,0,0,0,
"Nowe skrypty",
0,
"Nowe lub wbudowane kolory",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Numery telefonów, wibracja, itp...",
0,
"Wybiera losowy kolor",
"Zdjęcia i muzyka...",
0,
"Zagraj, zatrzymaj lub wznów piosenki..",
0,0,0,
"Zapoznaj się z naszymi Zasadami zachowania poufności informacji.",
"Proszę czekać...",
0,0,0,0,0,0,0,0,0,
"Publikowanie wymaga ",
0,0,0,
"Odczytuje treść odpowiedzi jako falę dźwiękową",
"Możesz otrzymywać powiadomienia e-mail informujące o przeglądaniu/komentowaniu Twoich skryptów przez innych użytkowników, robieniu przez nich zrzutów ekranu z Twoimi skryptami, przesłaniem odpowiedzi na Twoje komentarze lub też wydarzeniach dotyczących Twoich subskrypcji.",
0,
"Odejmuje wartość od bieżącego życia.",
"Odpowiedz...",
"Zgłoś/usuń",
"Zmienia rozmiar obrazu do zadanego rozmiaru w pikselach",
0,
"Zwraca kopię obrazu",
0,0,
"Zwraca datę, która dodaje do wartości tego wystąpienia określoną liczbę miesięcy.",
"Zwraca datę, która dodaje do wartości tego wystąpienia określoną liczbę lat.",
"Zwraca losową liczbę całkowitą pomiędzy podanymi wartościami \"min\" i \"max\".",
0,0,0,0,0,
"Zwraca kolor duszka.",
0,
"Zwraca wartość true, jeśli bieżąca instancja jest bezużyteczna",
0,
"Uruchomia akcję inline.",
0,0,
"Aktualizacje skryptów",
"Skrypty tego użytkownika:",
0,
"Wyszukiwanie i przeglądanie stron internetowych...",
"Szukaj w kodzie...",
"Szukaj wszędzie",
"Szukaj tutaj...",
0,0,
"Szukaj...",
0,0,0,
"Zobacz więcej",
0,0,0,
"Ustawia afiniczne przekształcenie macierzy 3x3 stosowane do tablicy.",
0,0,0,0,
"Ustawia obraz tła",
"Ustawia wyśrodkowane położenie poziome w pikselach",
"Ustawia aktualne punkty życia.",
0,
"Ustawia wysokość w pikselach",
"Ustawia położenie w pikselach",
0,
"Ustawia głośność dźwięku od 0 (cicho) do 1 (bieżąca głośność)",
0,0,0,0,0,
"Ustawia szerokość w pikselach",
"Ustawia prędkość x w pikselach/s",
"Ustawia przyspieszenie y w pikselach/s^2",
"Ustawia położenie y w pikselach",
"Ustawia prędkość y w pikselach/s",
0,
"Ustawienia",
0,
"Pokaż błędy w edytorze, jeśli skrypt używa interfejsu API, który uniemożliwia uruchomienie go na tych platformach.",
0,0,
"Poziom umiejętności:{0}     ",
0,0,0,0,0,0,0,
"Odejmuje liczby",
"Wsparcie dla interaktywnych samouczków.",
"TD100: wstaw tutaj {0}",
"TD101: nie mogę znaleźć '{0}'",
"TD109: nie można wykonać przypisania do tego elementu",
"TD111: nie można wykonać przypisania z {0} do {1}",
"TD112: nie można znaleźć właściwości '{0}' w {1}",
"TD115: nadmierne parametry dostarczone do {0}",
"TD116: za mało parametrów dla {0}",
"TD118: warunek 'if' potrzebuje {1}",
0,0,
"TD130: granica 'for' potrzebuje {1}",
"TD144: chyba brakuje tutaj '{0}', spróbuj to dodać",
"TD145: chyba brakuje tutaj operatora (np. '+', '(' lub',')",
"TD147: nie oczekiwaliśmy tutaj '{0}'",
0,0,
"TD152: nieoczekiwane ')'",
"TD154: coś musi być po operatorze",
0,
"Ucz Kreatywnego Programowania!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Ten skrypt używa następujących funkcji: ",
0,0,
"Aby dodać dane strony, utwórz zmienną lokalną i kliknij 'promuj do pola'.",
0,0,0,
"tłumaczenia, mowa do tekstu...",
"Tłumaczenia Microsoft® Translator; dotknij, aby zobaczyć wersję oryginalną...",
0,
"Zmieniaj kod, aż pojawi się znak powodzenia. Jeśli utkniesz, kliknij na pasku samouczka.",
0,0,
"Samouczki",
"Twitter",
0,
"Wpisz, aby wyszukać...",
0,0,
"widżet UI",
0,0,
"Aktualizuje zdjęcia na obrazku (jeśli jest obrazek z wielu zdjęć)",
0,
"Wrzuć Zdjęcie",
"Wrzuć Dźwięk",
"Użytkownicy",
0,0,
"Dostosujemy edytor do Twojego poziomu umiejętności kodowania. Poziom umiejętności możesz później zmienić w Centrum.",
"Jak dobra jest Twoja znajomość programowania?",
"Jaki zawód wykonujesz?",
"Nowości",
"W jakim miejscu świata się znajdujesz?",
"Zapisuje inny obraz w danej lokalizacji. Przezroczystość może mieć wartość od 0 (przezroczyste) do 1 (nieprzezroczyste).",
0,
"YouTube",
0,0,
"Twoja nazwa użytkownika w serwisie GitHub.",
"Twoja nazwa użytkownika w portalu Minecraft.",
"Zasoby artystyczne pojawią się tutaj",
0,
"Twój kanał pojawi się tutaj",
"Twój adres e-mail nie został jeszcze zweryfikowany. Sprawdź skrzynkę odbiorczą.",
"Twoje pełne imię i nazwisko",
0,0,0,
"Twój skrypt pojawi się tutaj",
"Twoja nazwa użytkownika na Twitterze, na przykład @touchdevelop.",
"kilka sekund temu",
"funkcja",
"zmienna globalna",
"minutę temu",
"strona",
"o pokryciu",
"o wnioskach",
"o profilu",
"o tobie",
0,0,
"zgłoszenia nadużyć",
0,0,0,0,0,
"dodaj",
0,0,0,0,0,0,0,0,
"dodaj parametr wejściowy",
0,
"dodaj wiersz poniżej",
"dodaj nowe",
0,0,
"dodaj parametr wyjściowy",
0,0,0,0,0,0,0,
"niesamowity, zadziwiający, zdumiewający, inspirujący, klasyczny, fajny, ciekawy, wyjątkowy, ekskluzywny, nadzwyczajny, wspaniały, fantastyczny, wielki, ",
0,0,
"godzinę temu",
0,0,0,0,0,0,0,
"sztuka",
"zasoby artystyczne",
"przypisanie",
0,
"autor",
0,0,
"wstecz",
0,
"backspace",
"usuńmy to",
0,0,
"baza",
"początkujący",
0,0,0,
"pusty",
0,0,0,
"pusta gra",
0,0,0,0,0,0,0,
"zatrzymaj się w debugerze",
"punkt przerwania",
0,0,0,0,0,0,
"anuluj",
0,0,
"zmień (ponownie) na lokalną",
0,
"kanały",
0,0,0,0,0,0,0,0,0,0,0,
"wybierz poziom swoich umiejętności kodowania",
0,0,
"wyczyść",
0,
"klonuj",
0,
"sesje chmurowe",
"kod",
0,
"programista",
"kolor nr{0}",
0,0,
"komentarze",
0,
"instrukcja warunkowa",
0,0,0,
"kontynuuj",
0,
"kopiuj",
0,
"pokrycie",
"utwórz",
"utwórz nowy parametr",
0,0,0,0,0,
"tworzenie skryptu",
0,
"aktualne wyrażenie",
"dostosuj grafikę!",
"wytnij",
0,0,
"debuguj",
"kropka dziesiętna",
0,
"usuń",
"usuń lokalne dane i uprawnienia",
0,
"zdegraduj do zmiennej",
0,
"opis",
0,0,
"szczegóły",
0,0,0,0,0,0,
"odrzuć",
"wyświetl wartość",
0,0,0,0,0,
"gotowe!",
"edytuj",
"else if",
"e-mail",
"e-mail (prywatny)",
"powiadomienia e-mail i push",
"niezweryfikowany adres e-mail, {0}",
0,0,0,0,0,0,0,
"wydarzenia",
0,
"eks: ",
0,
"doskonale; świetna robota; niesamowite; spoko; brawo; wybitnie; dokładnie tak",
0,
"wyjście",
"ekspert",
0,0,0,0,
"rozszerz",
0,0,0,
"wyodrębnij do var",
"znajdź odniesienia",
"ukończone",
"napraw",
"obserwuj samouczek w edytorze",
0,
"rozwidlenia",
"funkcja",
0,0,
"funkcja, zmienna, biblioteka, ...",
"płeć",
"pobierz swój certyfikat Godzinka z kodem™",
0,
"nazwa użytkownika w serwisie github",
0,
"globalne zastąpienie",
"zmienna globalna",
"globalne zm.",
0,
"wróć do kodowania! jeszcze {0}★",
0,
"idź do",
0,
"aby wrócić do poprzedniego kroku",
"cel:",
0,0,
"serca",
"pomoc",
0,
"ukryj",
"historia",
0,
"skąd o nas wiesz",
"chcę to uruchomić",
"moja godzina Godzinka z kodem™ jest skończona",
0,0,0,0,0,0,0,0,0,0,0,0,
"magiczny, wspaniały, cudowny, osobliwy, fenomenalny, specjalny, spektakularny, zaskakujący, wspaniały, super-fajny, ",
0,0,
"wstaw komentarz",
"wstaw instrukcję",
"wstaw {0}",
"wgląd",
0,0,
"do lokalnej",
0,
"problemy",
0,0,0,0,
"nadal edytuj",
0,0,
"uczymy się",
0,
"dowiedz się więcej",
0,0,0,
"do dzieła!",
"zaczynajmy!",
"bib",
"biblioteki",
"biblioteka",
0,0,
"załaduj więcej",
0,0,0,0,0,0,0,0,
"ładowanie...",
0,
"lokalizacja",
0,
"negacja logiczna",
"dzienniki",
0,0,0,
"zarządzaj danymi",
"może później",
0,0,0,
"nazwa użytkownika w portalu minecraft",
0,0,
"więcej",
"więcej ",
"więcej ustawień",
"rusz kursor",
"przesuń w lewo",
0,
"przesuń kursor w lewo",
"przesuń kursor w prawo",
"moja sztuka",
0,0,0,
"moje skrypty",
0,0,0,0,
"trzeba to usunąć",
"trzeba edytować coś jeszcze",
"zaprzeczenie",
0,0,0,0,
"nowa linia",
0,0,0,
"nowa instrukcja poniżej",
"nowa zmienna",
0,
"następne samouczki...",
"nick",
0,
"brak grafik opublikowanych przez tego użytkownika",
"brak komentarzy, kliknij, aby jakieś napisać!",
"brak skryptu rozgałęzienia, instalacji, edycji lub ponownej publikacji do utworzenia!",
"nie ma serc. możesz jedno dodać po zainstalowaniu skryptu!",
"nie załadowano obrazów",
"brak poprzedniego adresu e-mail",
0,
"brak tagów, kliknij, aby jakieś dodać!",
0,0,0,
"powiadomienia",
0,
"teraz możesz wybrać właściwość {0}; samo z siebie to nic nie zrobi",
"teraz możesz wybrać właściwość",
0,
"wpisywanie liczb",
0,
"zawód",
0,
"dostępne offline",
0,
"ok, startujemy!",
"online",
0,0,0,
"ogólne",
0,
"strony",
0,
"analizowanie tekstu skryptu",
0,
"wklej",
"pauza",
0,0,0,
"obraz",
0,0,0,
"zagraj ponownie",
0,
"czekaj...",
"wtyczki",
"podgląd",
"drukuj",
0,
"prywatne",
0,
"profil prywatny",
"profil",
"znajomość programowania",
0,0,0,
"nick publiczny",
"profil publiczny",
"publikuj",
0,0,0,
"ściągnij zmiany",
"wyciągnij na poziom bloku",
0,
"uruchom od nowa",
0,
"tylko do odczytu",
"prawdziwe imię i nazwisko",
"prawdziwe imię (prywatne)",
"otrzymywanie biuletynu e-mail",
"otrzymywanie powiadomień e-mail",
"nazwa rekordu:",
0,
"zwykła klawiatura",
0,
"usuń",
0,
"usuń obrazek",
0,0,
"zmień nazwę",
"powtórz n razy",
"iteruj po kolekcji",
"powtórz klauzulę while",
0,
"zastąp wszystko w skrypcie",
"zamień obraz",
0,0,0,
"zgłoś nadużycie",
0,
"przywróć opublikowaną wersję",
0,
"cofnij ",
"uruchom",
"uruchom główny",
0,
"uruchom z instrumentacją",
"zapisz",
0,
"zapisywanie...",
"szkoła",
"ekrany",
"zrzut ekranu",
0,
"skrypt",
"właściwości skryptu",
0,0,
"szukaj grafiki",
"szukaj grafik",
"szukaj tutaj {0}",
0,
"wyszukiwanie...",
0,
"wybierz",
"wybierz więcej",
"wybierz ten wiersz",
0,0,0,
"ustaw nazwę zmiennej lokalnej",
"ustaw nazwę",
0,
"ustaw program obsługi wywoływany po kliknięciu tablicy",
0,0,0,0,
"ustawienia",
"udostępnij",
0,
"pokaż, jak przeprowadzić tę czynność",
0,
"wybrane",
"zaloguj",
0,0,
"wyloguj",
"logowanie...",
0,
"uprość",
0,
"zatrzymaj iterację",
0,
"społecznościowo",
0,
"dźwięk",
0,0,
"przedziel",
0,
"zacznij od nowa",
0,
"trwa rozpoczynanie...",
0,
"wejdź w",
"wyjdź",
"przejdź nad",
0,
"stop",
0,
"zatrzymaj funkcję",
"zatrzymaj pętlę",
"zapisz w var",
"przechowaj wartość w zmiennej",
"napis",
0,
"odpakuj '{0}'",
0,0,0,
"nadprzyrodzony, niewiarygodny, nieziemski, unikatowy, bezprecedensowy, dziwny",
0,0,0,0,0,0,0,0,0,
"tagi",
0,0,0,0,0,0,0,
"kliknij tutaj",
"kliknij tutaj, aby uzyskać instrukcje",
"kliknij tutaj, aby uruchomić aplikację",
"kliknij, aby zmienić kolor",
0,0,0,0,
"warunki użytkowania",
"test",
0,
"testy",
0,0,0,
"hub",
0,0,0,0,
"ten skrypt jest biblioteką",
0,
"czas i daty",
"do kodu",
"aby kontynuować",
"na zmienną globalną",
"przełącz punkt przerwania",
"najlepsze & nowe",
0,0,0,0,0,0,0,
"spróbuj jeszcze raz!",
"przekształć na",
"postęp przerabiania samouczka",
"samouczek: ",
"samouczki",
"nazwa użytkownika na twitterze",
"typ: ",
"typ: {0}",
0,0,0,
"cofnij",
0,0,0,
"odinstaluj",
0,0,0,0,0,0,
"aktualizacja",
0,0,0,0,0,0,
"załaduj",
0,
"załaduj zrzut ekranu",
0,0,0,0,
"url",
0,0,0,0,0,0,
"wyświetl jako skrypt",
"wyświetl/edytuj nazwę, e-mail, ...",
0,
"tapeta",
"'{0}' to biblioteka; {1}",
"mamy tutaj {0:a}; chcesz coś z nim zrobić?",
0,0,0,
"potrzebujemy innej klawiatury",
0,
"trzeba jeszcze coś zmienić",
"poprowadzimy Cię krok po kroku",
0,0,0,0,
"witryna internetowa",
0,
"adres url witryny internetowej",
0,0,0,0,0,
"rok urodzenia",
0,0,
"udało się!",
0,
"{0} ({1} linia{1:s})",
"Dni temu: {0} {0:s}",
0,0,0,0,
"Godzin temu: {0} {0:s}",
"{0} min{0:s} temu",
"{0} mies.{0:s} temu",
0,0,0,
"{0} s{0:s} temu",
0,
"Lat temu {0} {0:s}",
0,0,
"● Zaloguj"
]); return true; }

if (lang == "pt") { TDev.Util._setLanguageArray(keys, [
"   Talvez: {0} ({1} em '{2}')\n",
"  -> Linha {2} ('{1}'), erro: {0}",
" -- uma variável local",
" [class]",
" [oculto]",
" [override]",
" para trás",
" para frente",
" horas ",
" minutos ",
" de ",
" segundos ",
" enviando alterações",
" a aguardar pelo servidor",
"### código fonte completo",
"Chaves como em JavaScript, todas as ferramentas, para desenvolvedores experientes!",
"função “atômica”",
"só pode aceder-se à 'box' na página de exibição do código",
"não pode aceder-se à 'box' em modo de layout HTML",
0,
"só se pode aceder ao 'html' em modo de layout HTML",
"'{0}' espera {1} aqui",
"'{0}' tem uma assinatura não suportada",
"'{0}' não está implementada",
"'{0}' é obsoleto e não está implementado",
"'{0}' é obsoleto e não deve ser usado",
0,
"'{0}' retorna um '{1}'; {2}",
"'{0}' devolve valores de {1}; pode usar o botão 'store em var' para os guardar em locais",
0,0,0,0,0,0,0,
", em vez disso, obteve {0}",
", obteve {0}",
0,0,0,
"... há mais...",
"// comentário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>esta linha está perfeita!</b> vamos continuar",
"<h3>carregando configurações atuais...</h3>",
"<h3>sem mais dicas!</h3>",
0,
"<h3>{0:q} exige conexão</h3>",
0,0,0,0,0,0,0,0,0,
"Um aplicativo de pi do Minecraft.",
"Um aplicativo Minecraft.",
"Um aplicativo de creeper do Minecraft.",
0,0,0,0,0,0,0,0,0,0,
"Uma cor constante",
0,0,0,0,0,0,0,0,0,
"Uma variável global",
0,0,0,0,0,0,0,0,0,0,0,
"Um número (possivelmente negativo e/ou fração)",
"Um número constante",
0,0,0,
"Uma imagem",
"Um trecho de texto",
"Um aplicativo de pixel art.",
0,0,0,
"Uma referência a um script de biblioteca",
0,0,0,0,0,0,0,0,0,
"Um som",
0,0,0,0,
"Uma estrutura de dados do usuário",
"Uma tabela de linhas definidas pelo usuário",
0,0,0,0,
"Um temporizador",
"Um nome exclusivo de exibição para seu perfil público (pelo menos 8 caracteres)",
0,0,
"Uma interface do usuário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adicionar uma ação que é disparada para cada quadro de exibição",
0,
"Adicione o sprite para definir e remover do conjunto de velho. Retorna true se a sprite foi no antigo conjunto e não no conjunto de novo.",
"Adicione o sprite para definir. Retorna true se o sprite já não estava no conjunto.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adiciona números",
0,
"Agrega valor à pontuação atual.",
0,
"Avança o enumerador e retornar true se há um outro elemento.",
"Após a interrupção do script, procure o código para ver as informações coletadas.",
"Todos os meus grupos",
"Todos os meus scripts",
0,0,0,0,0,0,0,
"Um aplicativo em branco usando páginas e caixas.",
"Um aplicativo em branco que usa a biblioteca de rascunhos.",
"Uma página de documentação vazia.",
"Um tutorial interativo vazio.",
"Um plugin de editor script vazio.",
"Um script em branco, que não faz nada.",
0,0,
"Uma tabela indexada de linhas definidas pelo usuário",
0,
"Um aplicativo de tartaruga.",
"Aplica `conversor` a todos os elementos da coleção de entradas e retorna uma coleção de resultados",
0,
"Tem certeza de que deseja parar de seguir o tutorial?",
"Operações aritméticas e bit a bit em inteiros de 32 bits",
"Arte desse usuário:",
"Perguntar ou exibir valores na tela...",
"Anexe dados a outros objetos",
"Código de texto clichê para criar um jogo.",
0,0,0,0,0,0,
"Alterar o nível de habilidade!",
"canais",
"Verifica que o quadro é a mesma instância do outro quadro.",
0,0,0,
"Limpe todos os eventos em fila relacionados com esse quadro",
"Limpar a imagem do plano de fundo",
"Limpar a câmera do plano de fundo",
0,0,
"Código gerado quando ocorre uma interação do usuário",
"Código que executa uma tarefa específica",
"Compara números para igualdade",
"Compara números para menos",
0,
"Compara números para mais",
0,0,0,0,
"Calcula o máximo dos valores",
"Calcula o mínimo dos valores",
0,
"Concatena dois trechos de texto",
0,0,0,
"Converte o valor em uma estrutura de dados json.",
0,0,
"Converte na hora local",
0,0,
"Ajudantes de correção",
0,
"Criar o código",
"Criar Grupo",
"Criar Script",
"Criar um obstáculo de linha com certo ponto de início, de certa largura e altura. Elasticidade é 0 para grudento e 1 para rebatimento completo.",
"Crie uma nova coleção de sprites.",
"Criar um novo sprite de elipse.",
"Crie uma nova forma de imagem.",
"Criar um novo sprite de retângulo.",
"Criar um novo script",
0,0,0,
"Cria um sprite âncora.",
"Crie um valor inválido deste tipo de objeto",
"Criar canal",
0,
"Criar valores inválidos",
"Cria paredes em torno do quadro a uma dada distância.",
"Criar seus próprios aplicativos",
0,0,
"Cria um quadro de jogo vazio e mostra-o na tela.",
"Cria um novo jogo de tabuleiro no modo paisagem. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria um novo jogo de tabuleiro no modo retrato. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria uma nova camada na cena. A distância determina a ordem de renderização e quão rápido a camada se move",
"Cria um novo sprite de largura 100 com a imagem fornecida.",
0,
"Cria uma instância de gamepad inválida",
0,0,
"Dispositivo atual",
0,
"Ponto de toque atual",
"Desvincula o manipulador do evento.",
0,
"Exibe a imagem na parede; você precisará chamar 'atualização na parede' mais tarde se quiser que as alterações sejam refletidas.",
0,0,0,
"Exibe o estado do gamepad no mural",
"Divide números",
"Fazer com que as formas se sobreponham",
0,
"Documentos",
"Não se esqueça de rolar para baixo na tela e tocar em 'salvar' quando terminar de editar!",
"Arrastar e soltar blocos, interface simplificada, ótimo para iniciantes!",
"Traça uma linha entre dois pontos",
"Desenha alguma borda de texto com uma determinada cor e tamanho de fonte",
"Edite código como texto, mais opções, para aspirantes a criadores de aplicativos!",
0,
"Habilitar ou desabilitar a sincronização da nuvem para a sessão atual do",
"Insira um nome",
0,
"Insira algumas informações sobre você",
"Insira o URL de seu website pessoal (Exemplo: http://www.northwindtraders.com)",
"Insira o código de convite",
0,
"Os eventos não podem ter parâmetros.",
"Todos podem ver sua foto na Internet para sempre. ",
0,0,
"Extensões",
"Facebook",
"Preenche uma elipse com uma determinada cor",
"Preenche um retângulo com uma determinada cor",
"Velocidade de toque final após o fim do toque",
"Para scripts publicados, veja também a guia da página de scripts publicados para encontrar dados de cobertura e perfis coletados de forma anônima.",
"Fóruns",
"A partir de agora, não mostraremos mais o código a ser escrito. Siga as instruções e toque em executar quando achar que terminou.",
"Funções no script atual",
0,0,0,0,0,
"Obtém uma captura de tela dos estados do gamepad (se conectado ao navegador). Vazio se não tiver suporte ou nenhum gamepad for conectado.",
0,0,0,
"Obtenha um valor indicando se o quadro é projetado para ser exibido em modo paisagem",
"Obterá um valor se a música for protegida por DRM",
"Obtém o valor x e y dos eixos selecionados.",
0,0,
"Obtém a cena do plano de fundo",
"Obtém a posição horizontal do centro em pixels",
0,
"Obtém a cor com valor ARGB igual a #00FFFFFF",
"Obtém a cor com valor ARGB igual a #FF000000",
"Obtém a cor com valor ARGB igual a #FF0000FF",
"Obtém a cor com valor ARGB igual a #FF008000",
"Obtém a cor com valor ARGB igual a #FF00FFFF",
0,
"Obtém a cor com valor ARGB igual a #FF800080",
0,0,0,0,
"Obtém a cor com valor ARGB igual a #FFFF0000",
"Obtém a cor com valor ARGB igual a #FFFF00FF",
"Obtém a cor com valor ARGB igual a #FFFFA500",
0,
"Obtém a cor com valor ARGB igual a #FFFFFF00",
"Obtém a cor com valor ARGB igual a #FFFFFFFF",
0,0,0,0,
"Obtém o primeiro gamepad conectado disponível",
0,
"Obtém o identificador do gamepad",
0,
"Obtém a altura em pixels",
"Obtém a altura da imagem da câmera em pixels.",
0,0,0,0,0,0,0,
"Obtém o número de elementos",
0,
"Obtém o índice do jogador",
"Obtém o valor pressionado de um botão. Retorna 0 se o botão não for encontrado.",
"Obtém a propriedade que habilita ou desabilita a gradientes",
"Obtém o volume para sons de 0 (silencioso) a 1 (volume atual)",
"Obtém a contagem de sprites",
"Faz o sprite ser indexado por i",
0,
"Obtém a data/hora dessa captura de tela",
0,
"Obtém a largura em pixels",
"Obtém a largura da imagem da câmera em pixels.",
"Obtém a posição y em pixels",
"Introdução",
0,
"Variáveis globais no script atual",
0,0,0,0,0,0,0,0,
"Código de importação",
"Importar um script de um arquivo",
"Importa uma representação JSON do conteúdo.",
"Importa um pacote de dependente que pode ser versionado. Gerenciadores de pacotes podem ser node. js npm, Bower, Apache cordova, Python Pip e plugins TouchDevelop. importações ' bower ' e ' cliente ' não estão disponíveis dentro do domínio touchdevelop.com.",
"Importações, o código de arquivos hex criado para o BBC micro: bit ou .jsz arquivos salvos. Dica: você também pode arrastar e soltar os arquivos no editor para importá-los!",
"No modo debug, o quadro exibe a velocidade e outras informações de sprites",
"Indica se o botão é pressionado. Retorna falso se o botão não for encontrado.",
"Indica se as notificações do programa devem ser mostradas ao usuário. Padrão é true.",
"Indica se os dados do gamepad são idênticos",
"Indica se o gamepad ainda está conectado.",
0,0,0,0,
"Inserir '{0}' {1}",
0,
"Itens marcados com * são obrigatórios.",
"dados JSON",
"Ingressar no grupo",
"Último ponto final de toque",
"Último ponto inicial de toque",
0,0,0,0,0,
"Torna as atualizações visíveis.",
0,0,
"Faz com que todos os sprites saltem na borda da tela",
"Mapas, localização de endereço, endereço de localização",
"Bom em matemática, abs, máx, ...",
"Me",
0,
"Usuário Minecraft",
0,0,
"Move o sprite em direção a outro.",
"Multiplica números",
0,0,0,0,0,0,0,0,
"Novos Scripts",
0,
"Cores novas ou inseridas",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Números de telefone, vibrar, etc...",
0,
"Escolhe uma cor aleatória",
0,0,0,0,0,
"Por favor, vá para as configurações no cubo principal para desativar o modo off-line.",
"Examine nossa Declaração de Privacidade",
0,
"Publicação de um comentário...",
0,0,0,
"Ação privada não tem um botão run. ",
"Solicita que o usuário forneça um número",
"Solicita ao usuário para escolher uma seqüência de caracteres de uma lista. Retorna o índice selecionado.",
"Publicar script",
0,
"A publicação está sujeita aos nossos ",
"Publicando script...",
"Aumentado quando a animação começou a tocar",
"Aumentado quando a animação parou a tocar",
"Lê o corpo de resposta como som wave",
"Receba notificações quando outras pessoas avaliam/tiram uma captura de tela/comentam seus scripts, ou respondem um de seus comentários, ou quando ocorrem eventos relacionados às suas assinaturas.",
"Lembre-se: todos poderão ver o seu script se você publicá-lo; certifique-se de que ele não contém senhas ou informações pessoais.",
"Remove o valor da vida atual.",
"Responder...",
"Relatar/Excluir",
"Redimensiona a imagem de acordo com o tamanho fornecido em pixels",
0,
"Retorna uma cópia da imagem",
"Retorna uma cópia dessa seqüência de caracteres convertido para minúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma cópia dessa seqüência de caracteres convertidos em maiúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma data que adiciona o número especificado de meses ao valor dessa instância.",
"Retorna uma data que adiciona o número especificado de anos ao valor dessa instância.",
"Retorna que um número aleatório integral entre 'min' e 'max' incluído.",
0,0,0,0,0,0,
"Retorna true se o sprite não está oculto",
"Retorna verdadeiro se a instância atual é inútil",
0,
"Execute a ação de inline.",
0,0,
"Atualizações de script",
"Scripts desse usuário:",
0,
"Pesquisar e navegar na web...",
"Pesquisar código...",
"Pesquisar tudo",
"Pesquisar aqui...",
0,0,
"Pesquisar...",
0,0,0,
"Ver Mais",
0,0,
"Ativa ou desativa o set gradient",
"Define a transformação de matriz offline 3x3 aplicada à parede.",
0,
"Define a câmera de fundo",
"Define a cor de fundo",
"Define a cor de fundo.",
"Define a imagem de fundo",
"Define a posição horizontal do centro em pixels",
"Define os pontos da vida atual.",
"Define a resistência dos sprites como uma fração da perda de velocidade entre 0 e 1",
"Define a altura em pixels",
"Define a posição em pixels",
0,
"Define o nível de volume para sons de 0 (silencioso) a 1 (volume atual)",
"Define a velocidade em pixels/segundos",
"Define a cor do sprite.",
"Define o vetor de aceleração uniforme para objetos no quadro como pixels/sec^2",
0,0,
"Define a largura em pixels",
"Define a velocidade x em pixels/s",
"Define a aceleração y em pixels/s^2",
"Define a posição y em pixels",
"Define a velocidade y em pixels/s",
0,
"Configurações",
"Compartilhe-o com essa url:",
"Mostrar erros no editor se o script usar APIs que impeçam sua execução nessas plataformas.",
"Mostra o quadro no mural.",
0,
"Nível de habilidade: {0}     ",
0,0,0,0,0,
"Para e limpa todos timers de cada quadro",
0,
"Subtrai números",
0,
"TD100: inserir {0} aqui",
"TD101: não é possível encontrar '{0}'",
"TD109: não é possível fazer essa atribuição",
"TD111: não é possível atribuir de {0} a {1}",
"TD112: não consigo encontrar a propriedade '{0}' em {1}",
"TD115: parâmetro(s) excessivo(s) fornecido(s) para {0}",
"TD116: não foram fornecidos parâmetros suficientes para {0}",
"TD118: condição 'se' quer {1}",
"TD119: preciso de algo para interagir",
0,
"TD130: associado de 'para' quer {1}",
"TD144: parece que está faltando '{0}', tente adicioná-lo",
"TD145: parece que está faltando um operador (como '+', '(' ou ',') aqui",
"TD147: não esperávamos '{0}' aqui",
"TD150: não pode chamar antes de '('",
"TD151: unclosed ' ('",
"TD152: inesperado ')'",
"TD154: o operador precisa de alguma coisa após isso",
"TD155: '{0}' não pode ser atribuída a uma variável local",
"Ensine o Creative Coding!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Este script usa os seguintes recursos: ",
0,
"Este tutorial usa dados de nuvem compartilhados com outros usuários.",
"Para adicionar dados de página, crie uma variável local e toque em 'promover para campo'.",
0,0,0,
"Tradução, fala em texto,...",
"Traduções por Microsoft ® Translator, toque para ver o original...",
"Verdadeiro, se o quadro for tocado",
"Tente ajustar seu código até funcionar. Se tiver dificuldade, toque na barra do tutorial.",
0,0,
"Tutoriais",
"Twitter",
"Digite para pesquisar online...",
"Digite para pesquisar...",
0,
"Tipos, ordem e número de parâmetros de evento não podem ser editados.",
"Widget de interface do usuário",
0,
"Atualize as posições dos sprites no quadro.",
"Atualiza a imagem em uma forma de imagem (se não for uma forma de imagem)",
"Atualiza o texto em um sprite de texto (se for um sprite de texto)",
"Carregar imagens",
"Carregar som",
"Usuários",
0,
"Precisamos de mais opções",
"Adaptaremos o editor ao seu nível de habilidade em codificação. Você poderá alterar seu nível de habilidade posteriormente no hub.",
"Qual seu nível de conhecimento de programação?",
"Qual é a sua ocupação?",
"O que há de novo",
"Onde você está?",
"Grava outra imagem em um determinado local. A opacidade varia de 0 (transparente) a 1 (opaco).",
0,
"YouTube",
0,0,
"Seu usuário GitHub.",
"Seu usuário Minecraft.",
"Sua arte aparecerá aqui",
0,
"Seu canal aparecerá aqui",
"Seu endereço de email ainda não foi verificado Verifique sua caixa de entrada.",
"Seu nome completo",
0,0,0,
"Seu script aparecerá aqui",
"Seu handle do twitter, como @touchdevelop.",
"alguns segundos atrás",
"uma função",
"uma variável global",
"um minuto atrás",
"uma página",
"sobre cobertura",
"sobre percepções",
"sobre perfil",
"sobre você",
"abuso",
0,
"relatar abusos",
0,0,0,
"acesse o campo {0}",
0,
"adicionar",
"adicionar um novo...",
0,
"adicionar uma ação que é disparada para cada quadro de exibição.",
0,0,0,0,0,
"adicionar parâmetro de entradas",
"adicionar linha acima",
"adicionar linha abaixo",
"adicionar novo",
0,0,
"adicionar parâmetro de saídas",
0,0,0,0,0,
"todas as APIs",
"permitir",
"excelente, surpreendente, impressionante, espantoso, fenomenal, de tirar o fôlego, clássico, legal, curioso, diferente, excepcional, exclusivo, extraordinário, fabuloso, fantástico, esplêndido, ótimo, ",
0,
"uma definição de tipo de função",
"uma hora atrás",
0,0,0,0,0,
"aplicativos",
0,
"arte",
"recurso de arte",
"atribuição",
0,
"autor",
0,0,
"voltar",
0,
"backspace",
"usar backspace nisto",
0,0,
"base",
"iniciante",
"iniciantes",
0,
"vincula ao script:",
"em branco",
"aplicativo em branco",
"creeper em branco",
"documentos em branco",
"jogo em branco",
"minecraft em branco",
"minecraft pi em branco",
"pixel art em branco",
"rascunho em branco",
"plugin de script em branco",
"tartaruga em branco",
"tutorial em branco",
"quebrar no depurador",
"ponto de interrupção",
0,0,0,0,0,0,
"cancelar",
0,0,
"alterar (voltar) para local",
"alterar conteúdos",
0,
"verifica se a referência não foi definida",
0,0,0,
"escolha uma imagem (menos que 1 MB, menor que 2048x2048)",
0,0,0,0,0,0,
"escolha seu nível de habilidade em codificação",
"escolha...",
0,
"limpar",
"área de transferência",
"clonar",
0,
"sessões de nuvem",
"código",
"codifique a linha de objetivo",
"codificador",
"cor nº{0}",
"cor: {0}",
"comentado",
"comentários",
0,
"condicional",
"conectado",
0,0,
"continuar",
0,
"copiar",
"copiar seleção",
"cobertura",
"criar",
"criar um novo parâmetro",
0,
"crie código de com...",
"criar códigos",
0,
"cria uma coleção vazia de objetos",
"criação de script",
0,
"expressão atual",
"personalize a arte!",
"recortar",
"cortar seleção",
"banco de dados",
"depurar",
"ponto decimal",
0,
"excluir",
"excluir dados locais e permissões",
"excluir seleção",
"rebaixar para var",
"negar",
"descrição",
"descrição (ajuda a pesquisa)",
0,
"detalhes",
"você queria usar este valor?",
"diff curr",
"diff prev",
"desativar o login",
"desativado",
0,
"ignorar",
"valor de exibição",
"exibe o objeto na rede",
0,0,0,
"pronto",
"pronto!",
"editar",
"e se",
"email",
0,
"email e notificações por push",
0,0,0,0,
"insira o código de convite",
"insira este código",
"erros",
0,
"eventos",
0,
"ex: ",
0,
"excelente; ótimo trabalho; incrível; legal; você é demais; bom trabalho; extraordinário; você conseguiu; é isso aí",
0,
"saída",
"especialista",
0,
"exportar",
"exportar uma representação JSON dos conteúdos",
"exportado desta biblioteca",
"estender",
0,
"extrair seleção em função",
0,
"extrair para var",
"encontrar referências",
"concluído",
"corrigir",
"seguir tutorial no editor",
"para o grupo",
"bifurcações",
"função",
"nome da função",
"tipos de função",
"função, variável, biblioteca...",
"gênero",
"obter meu certificado da Hora do Código™",
"obtém o timer que dispara para cada quadro de exibição.",
"usuário github",
"dado ♥",
"substituição global",
"variável global",
"variáveis globais",
"voltar",
"voltar para a codificação! {0}★ para ir",
"voltar...",
"ir para",
"ir para a lista de coisas em seu script",
"ir para a etapa anterior",
"objetivo:",
"grupo",
"grupos",
"corações",
"ajuda",
0,0,
"histórico",
"Viva! Seu script está publicado",
"como encontrou",
"quero que seja executado em",
"terminei com meu Hora do Código™",
"arte do ícone: {0}",
0,
"se tiver dificuldade, toque na linha de objetivo",
0,
"importação somente pode ser usada em um contexto de roteiro",
"código de importação",
0,
"importar valores de campo de um objeto JSON",
"importações",
0,0,0,
"incrível, mágico, maravilhoso, maravilhoso, alucinante, estarrecedor, milagroso, peculiar, fenomenal, radical, formidável, especial, espetacular, vistoso, deslumbrante, superlegal, ",
0,
"inserir",
"inserir comentário",
"inserir instrução",
"inserir {0}",
"percepções",
0,
"instalando e carregando o script",
"no local",
0,
"questões",
"ingressar em um grupo",
"ingressar no grupo",
"selva",
"basta digitar os termos de pesquisa!",
"continuar editando",
"conhecido aqui como:",
0,
"aprender",
"saiba mais sobre publicação",
"saber mais",
"saiba mais sobre {0}",
"deixar tutorial",
"vamos mudar isso",
"vamos fazer isso!",
"vamos começar!",
"lib",
"bibliotecas",
"biblioteca",
"nome da biblioteca",
"referência de biblioteca",
"carregar mais",
"carregar mais respostas",
"carregando",
0,
"carregando comentários para /{0}...",
0,
"carregando respostas...",
"carregando o script",
"​carregando tutorial​",
"carregando...",
"local",
"local",
0,
"negação lógica",
"logs",
"principal",
0,
"makers",
"gerenciar dados",
"talvez mais tarde",
"eu",
0,0,
"usuário minecraft",
0,0,
"mais",
"mais ",
"mais configurações",
"mover cursor",
"mover para a esquerda",
"passe para a próxima etapa",
"mova o cursor para esquerda",
"mova o cursor para a direita",
"minha arte",
0,0,0,
"meus scripts",
"um nome diferente é necessário aqui",
"necessário uma string diferente aqui",
"um novo campo aqui é necessário",
"precisa de um parâmetro",
"é necessário excluir isso",
"é necessário editar em algum outro local",
"negação",
0,0,0,0,
"nova linha",
0,0,0,
"novo stmt abaixo",
"nova variável",
0,
"próximos tutoriais...",
"apelido",
0,
"nenhuma arte publicada por este usuário",
"nenhum comentário; toque para escrever algum!",
"nenhum script de bifurcações, instalação, edição e nova publicação para criar um!",
"nenhum coração. Você pode adicionar um desde que instale um script!",
"nenhuma imagem carregada ainda",
0,0,
"nenhuma marca; toque para adicionar alguma!",
0,0,0,
"notificações",
0,
"agora você pode selecionar uma propriedade de {0}; ele não faz nada sozinho",
"agora você pode selecionar uma propriedade nele",
"número",
"entrada de número",
0,
"ocupação",
"de um objeto",
"offline disponível",
"ok",
"ok, vamos lá!",
"online",
0,
"ou toque para obter ajuda",
"outros",
"visão geral",
0,
"páginas",
0,
"analisando o texto do script",
0,
"colar",
"pausar",
0,
"iniciador do jogo de física",
"escolha um modelo de script...",
"imagem",
"nome da imagem",
"nome da imagem (mínimo de 4 caracteres)",
"url da imagem",
"jogue novamente",
0,
"aguarde...",
"plugins",
"visualizar",
"imprimir",
0,
"privado",
"função privada",
"perfil privado",
"perfil",
"conhecimento de programação",
0,
"promover para dados",
"promover a campo",
"apelido público",
"perfil público",
"publicar",
"publicar como oculto",
0,
"publicado",
"extrair alterações",
"extrair para nível de bloco",
0,
"executar novamente",
"leia mais...",
"somente leitura",
"nome real",
0,
"receber boletins de notícias por email",
"receber notificações por email",
"registrar nome:",
0,
"teclado normal",
"recarregando script​",
"remover",
0,
"remover imagem",
"remove fundo branco (bom para sprites de jogos)",
0,
"renomear",
"repetir n vezes",
"repetir na coleção",
"repetir enquanto",
"substituir tudo na função",
"substituir tudo no script",
"substituir imagem",
"replicado",
"replicado ",
0,
"denunciar abuso",
0,
"reverter para versão publicada",
0,
"retroceder ",
"executar",
"executar principal",
0,
"executar com instrumentação",
"salvar",
"salvo",
"salvando...",
"escola",
"telas",
"captura de tela",
"captura de tela de {0}",
"script",
"propriedades do script",
0,
"pesquisar",
"pesquisar arte",
"pesquisar imagens de arte",
"pesquisar {0} aqui",
"pesquisar modelos",
"pesquisando...",
"ver mais opções",
"selecionar",
"selecionar mais",
"selecionar essa linha",
"selecione o tipo deste {0}",
0,0,
"definir nome da variável local",
"definir nome",
"definir o manipulador que é invocado quando o quadro é deslizado",
"definir o manipulador que é invocado quando o painel é tocado",
"definir o manipulador que é invocado quando o quadro é tocado",
"definir o manipulador que é invocado quando o quadro é solto",
"define todos os campos para os valores padrão",
"configuração salva",
"configurações",
"compartilhar",
0,
"mostrar como completar esta atividade",
"mostrar mais opções",
"demonstração",
"entrar",
0,0,
"sair",
"entrando...",
0,
"simplificar",
"nível de habilidade salvo",
"ignorar a iteração",
0,
"social",
0,
"som",
0,
"arte da tela inicial: {0}",
"dividir",
0,
"começar novamente",
"iniciando o script",
"iniciando...",
0,
"entrar",
"sair",
"transpor",
0,
"parar",
0,
"parar função",
"parar loop",
"store in var",
"armazenar o valor em uma variável",
"cadeia de caracteres",
0,
"faixa '{0}'",
0,0,0,
"superior, supernatural, tremendo, inacreditável, sobrenatural, único, sem precedente, incomum, estranho, magnífico, notável",
"cercar com",
0,
"sincronização foi desativada de propósito",
"sincronizando...",
0,0,0,0,0,
"tags",
0,0,
"toque (←) quando terminar",
"toque em [ok] ao concluir",
0,
"toque aqui para passar a próxima etapa",
"toque aqui quando concluir",
"toque aqui",
"toque lá para obter instruções",
"toque aqui para executar seu aplicativo",
"tocar para alterar a cor",
"toque para mudar a imagem do ícone",
"toque para mudar a imagem da tela inicial",
"toque para traduzir com o Microsoft® Translator...",
"temporário",
"terms of use",
"teste",
"testar função",
"testes",
"testa se duas referências estão relacionadas a um mesmo objeto",
0,0,
"o hub",
"o código de convite deve ser um número com extensão entre 9 e 64 caracteres",
"pane no script",
0,0,
"este script é uma biblioteca",
"este script é um serviço Web",
"tempo e datas",
"para código",
"para continuar",
"para var global",
"ativar/desativar ponto de interrupção",
"Novidades principais",
0,0,
"traduzir",
"​traduzindo tutorial​...",
0,0,0,
"tente novamente!",
"transformar em",
"progresso do tutorial",
"tutorial: ",
"tutoriais",
"handle do twitter",
"tipo: ",
"tipo: {0}",
0,0,0,
"desfazer",
0,0,0,0,0,0,0,
"bandeira desconhecida",
0,0,
"atualização",
0,0,0,0,0,0,
"carregar",
"carregar imagens",
"carregar screenshot",
"carregar som",
0,0,0,
"url",
0,0,0,0,0,
"nome da variável",
"exibir como script",
"exibir/editar nome, e-mail...",
0,
"papel de parede",
"temos uma biblioteca '{0}' aqui; {1}",
"temos {0:a} aqui; você queria fazer algo com isso?",
"precisamos de um novo campo",
"precisamos de uma nova tabela",
"precisamos de um novo {0}",
"precisamos de um teclado diferente",
"precisamos de uma nova variável",
"precisamos editar outro item",
"orientaremos você passo a passo",
"aplicativos web",
0,0,0,
"website",
0,
"url do website",
0,0,0,0,0,
"ano de nascimento",
0,0,
"você conseguiu!",
0,
"{0} ({1} linha{1:s})",
"{0} dia{0:s} atrás",
0,0,0,0,
"{0} hora{0:s} atrás",
"{0} minuto{0:s} atrás",
"{0} mês{0:s} atrás",
"{0} de {1} concluído",
"{0} publicado",
"{0} script publicado",
"{0} segundo{0:s} atrás",
"mais {0}",
"{0} ano{0:s} atrás"
]); return true; }

if (lang == "pt-BR") { TDev.Util._setLanguageArray(keys, [
"   Talvez: {0} ({1} em '{2}')\n",
"  -> Linha {2} ('{1}'), erro: {0}",
" -- uma variável local",
" [class]",
" [oculto]",
" [override]",
" para trás",
" para frente",
" horas ",
" minutos ",
" de ",
" segundos ",
" enviando alterações",
" a aguardar pelo servidor",
"### código fonte completo",
"Chaves como em JavaScript, todas as ferramentas, para desenvolvedores experientes!",
"função “atômica”",
"só pode aceder-se à 'box' na página de exibição do código",
"não pode aceder-se à 'box' em modo de layout HTML",
0,
"só se pode aceder ao 'html' em modo de layout HTML",
"'{0}' espera {1} aqui",
"'{0}' tem uma assinatura não suportada",
"'{0}' não está implementada",
"'{0}' é obsoleto e não está implementado",
"'{0}' é obsoleto e não deve ser usado",
0,
"'{0}' retorna um '{1}'; {2}",
"'{0}' devolve valores de {1}; pode usar o botão 'store em var' para os guardar em locais",
0,0,0,0,0,0,0,
", em vez disso, obteve {0}",
", obteve {0}",
0,0,0,
"... há mais...",
"// comentário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>esta linha está perfeita!</b> vamos continuar",
"<h3>carregando configurações atuais...</h3>",
"<h3>sem mais dicas!</h3>",
0,
"<h3>{0:q} exige conexão</h3>",
0,0,0,0,0,0,0,0,0,
"Um aplicativo de pi do Minecraft.",
"Um aplicativo Minecraft.",
"Um aplicativo de creeper do Minecraft.",
0,0,0,0,0,0,0,0,0,0,
"Uma cor constante",
0,0,0,0,0,0,0,0,0,
"Uma variável global",
0,0,0,0,0,0,0,0,0,0,0,
"Um número (possivelmente negativo e/ou fração)",
"Um número constante",
0,0,0,
"Uma imagem",
"Um trecho de texto",
"Um aplicativo de pixel art.",
0,0,0,
"Uma referência a um script de biblioteca",
0,0,0,0,0,0,0,0,0,
"Um som",
0,0,0,0,
"Uma estrutura de dados do usuário",
"Uma tabela de linhas definidas pelo usuário",
0,0,0,0,
"Um temporizador",
"Um nome exclusivo de exibição para seu perfil público (pelo menos 8 caracteres)",
0,0,
"Uma interface do usuário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adicionar uma ação que é disparada para cada quadro de exibição",
0,
"Adicione o sprite para definir e remover do conjunto de velho. Retorna true se a sprite foi no antigo conjunto e não no conjunto de novo.",
"Adicione o sprite para definir. Retorna true se o sprite já não estava no conjunto.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adiciona números",
0,
"Agrega valor à pontuação atual.",
0,
"Avança o enumerador e retornar true se há um outro elemento.",
"Após a interrupção do script, procure o código para ver as informações coletadas.",
"Todos os meus grupos",
"Todos os meus scripts",
0,0,0,0,0,0,0,
"Um aplicativo em branco usando páginas e caixas.",
"Um aplicativo em branco que usa a biblioteca de rascunhos.",
"Uma página de documentação vazia.",
"Um tutorial interativo vazio.",
"Um plugin de editor script vazio.",
"Um script em branco, que não faz nada.",
0,0,
"Uma tabela indexada de linhas definidas pelo usuário",
0,
"Um aplicativo de tartaruga.",
"Aplica `conversor` a todos os elementos da coleção de entradas e retorna uma coleção de resultados",
0,
"Tem certeza de que deseja parar de seguir o tutorial?",
"Operações aritméticas e bit a bit em inteiros de 32 bits",
"Arte desse usuário:",
"Perguntar ou exibir valores na tela...",
"Anexe dados a outros objetos",
"Código de texto clichê para criar um jogo.",
0,0,0,0,0,0,
"Alterar o nível de habilidade!",
"canais",
"Verifica que o quadro é a mesma instância do outro quadro.",
0,0,0,
"Limpe todos os eventos em fila relacionados com esse quadro",
"Limpar a imagem do plano de fundo",
"Limpar a câmera do plano de fundo",
0,0,
"Código gerado quando ocorre uma interação do usuário",
"Código que executa uma tarefa específica",
"Compara números para igualdade",
"Compara números para menos",
0,
"Compara números para mais",
0,0,0,0,
"Calcula o máximo dos valores",
"Calcula o mínimo dos valores",
0,
"Concatena dois trechos de texto",
0,0,0,
"Converte o valor em uma estrutura de dados json.",
0,0,
"Converte na hora local",
0,0,
"Ajudantes de correção",
0,
"Criar o código",
"Criar Grupo",
"Criar Script",
"Criar um obstáculo de linha com certo ponto de início, de certa largura e altura. Elasticidade é 0 para grudento e 1 para rebatimento completo.",
"Crie uma nova coleção de sprites.",
"Criar um novo sprite de elipse.",
"Crie uma nova forma de imagem.",
"Criar um novo sprite de retângulo.",
"Criar um novo script",
0,0,0,
"Cria um sprite âncora.",
"Crie um valor inválido deste tipo de objeto",
"Criar canal",
0,
"Criar valores inválidos",
"Cria paredes em torno do quadro a uma dada distância.",
"Criar seus próprios aplicativos",
0,0,
"Cria um quadro de jogo vazio e mostra-o na tela.",
"Cria um novo jogo de tabuleiro no modo paisagem. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria um novo jogo de tabuleiro no modo retrato. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria uma nova camada na cena. A distância determina a ordem de renderização e quão rápido a camada se move",
"Cria um novo sprite de largura 100 com a imagem fornecida.",
0,
"Cria uma instância de gamepad inválida",
0,0,
"Dispositivo atual",
0,
"Ponto de toque atual",
"Desvincula o manipulador do evento.",
0,
"Exibe a imagem na parede; você precisará chamar 'atualização na parede' mais tarde se quiser que as alterações sejam refletidas.",
0,0,0,
"Exibe o estado do gamepad no mural",
"Divide números",
"Fazer com que as formas se sobreponham",
0,
"Documentos",
"Não se esqueça de rolar para baixo na tela e tocar em 'salvar' quando terminar de editar!",
"Arrastar e soltar blocos, interface simplificada, ótimo para iniciantes!",
"Traça uma linha entre dois pontos",
"Desenha alguma borda de texto com uma determinada cor e tamanho de fonte",
"Edite código como texto, mais opções, para aspirantes a criadores de aplicativos!",
0,
"Habilitar ou desabilitar a sincronização da nuvem para a sessão atual do",
"Insira um nome",
0,
"Insira algumas informações sobre você",
"Insira o URL de seu website pessoal (Exemplo: http://www.northwindtraders.com)",
"Insira o código de convite",
0,
"Os eventos não podem ter parâmetros.",
"Todos podem ver sua foto na Internet para sempre. ",
0,0,
"Extensões",
"Facebook",
"Preenche uma elipse com uma determinada cor",
"Preenche um retângulo com uma determinada cor",
"Velocidade de toque final após o fim do toque",
"Para scripts publicados, veja também a guia da página de scripts publicados para encontrar dados de cobertura e perfis coletados de forma anônima.",
"Fóruns",
"A partir de agora, não mostraremos mais o código a ser escrito. Siga as instruções e toque em executar quando achar que terminou.",
"Funções no script atual",
0,0,0,0,0,
"Obtém uma captura de tela dos estados do gamepad (se conectado ao navegador). Vazio se não tiver suporte ou nenhum gamepad for conectado.",
0,0,0,
"Obtenha um valor indicando se o quadro é projetado para ser exibido em modo paisagem",
"Obterá um valor se a música for protegida por DRM",
"Obtém o valor x e y dos eixos selecionados.",
0,0,
"Obtém a cena do plano de fundo",
"Obtém a posição horizontal do centro em pixels",
0,
"Obtém a cor com valor ARGB igual a #00FFFFFF",
"Obtém a cor com valor ARGB igual a #FF000000",
"Obtém a cor com valor ARGB igual a #FF0000FF",
"Obtém a cor com valor ARGB igual a #FF008000",
"Obtém a cor com valor ARGB igual a #FF00FFFF",
0,
"Obtém a cor com valor ARGB igual a #FF800080",
0,0,0,0,
"Obtém a cor com valor ARGB igual a #FFFF0000",
"Obtém a cor com valor ARGB igual a #FFFF00FF",
"Obtém a cor com valor ARGB igual a #FFFFA500",
0,
"Obtém a cor com valor ARGB igual a #FFFFFF00",
"Obtém a cor com valor ARGB igual a #FFFFFFFF",
0,0,0,0,
"Obtém o primeiro gamepad conectado disponível",
0,
"Obtém o identificador do gamepad",
0,
"Obtém a altura em pixels",
"Obtém a altura da imagem da câmera em pixels.",
0,0,0,0,0,0,0,
"Obtém o número de elementos",
0,
"Obtém o índice do jogador",
"Obtém o valor pressionado de um botão. Retorna 0 se o botão não for encontrado.",
"Obtém a propriedade que habilita ou desabilita a gradientes",
"Obtém o volume para sons de 0 (silencioso) a 1 (volume atual)",
"Obtém a contagem de sprites",
"Faz o sprite ser indexado por i",
0,
"Obtém a data/hora dessa captura de tela",
0,
"Obtém a largura em pixels",
"Obtém a largura da imagem da câmera em pixels.",
"Obtém a posição y em pixels",
"Introdução",
0,
"Variáveis globais no script atual",
0,0,0,0,0,0,0,0,
"Código de importação",
"Importar um script de um arquivo",
"Importa uma representação JSON do conteúdo.",
"Importa um pacote de dependente que pode ser versionado. Gerenciadores de pacotes podem ser node. js npm, Bower, Apache cordova, Python Pip e plugins TouchDevelop. importações ' bower ' e ' cliente ' não estão disponíveis dentro do domínio touchdevelop.com.",
"Importações, o código de arquivos hex criado para o BBC micro: bit ou .jsz arquivos salvos. Dica: você também pode arrastar e soltar os arquivos no editor para importá-los!",
"No modo debug, o quadro exibe a velocidade e outras informações de sprites",
"Indica se o botão é pressionado. Retorna falso se o botão não for encontrado.",
"Indica se as notificações do programa devem ser mostradas ao usuário. Padrão é true.",
"Indica se os dados do gamepad são idênticos",
"Indica se o gamepad ainda está conectado.",
0,0,0,0,
"Inserir '{0}' {1}",
0,
"Itens marcados com * são obrigatórios.",
"dados JSON",
"Ingressar no grupo",
"Último ponto final de toque",
"Último ponto inicial de toque",
0,0,0,0,0,
"Torna as atualizações visíveis.",
0,0,
"Faz com que todos os sprites saltem na borda da tela",
"Mapas, localização de endereço, endereço de localização",
"Bom em matemática, abs, máx, ...",
"Me",
0,
"Usuário Minecraft",
0,0,
"Move o sprite em direção a outro.",
"Multiplica números",
0,0,0,0,0,0,0,0,
"Novos Scripts",
0,
"Cores novas ou inseridas",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Números de telefone, vibrar, etc...",
0,
"Escolhe uma cor aleatória",
0,0,0,0,0,
"Por favor, vá para as configurações no cubo principal para desativar o modo off-line.",
"Examine nossa Declaração de Privacidade",
0,
"Publicação de um comentário...",
0,0,0,
"Ação privada não tem um botão run. ",
"Solicita que o usuário forneça um número",
"Solicita ao usuário para escolher uma seqüência de caracteres de uma lista. Retorna o índice selecionado.",
"Publicar script",
0,
"A publicação está sujeita aos nossos ",
"Publicando script...",
"Aumentado quando a animação começou a tocar",
"Aumentado quando a animação parou a tocar",
"Lê o corpo de resposta como som wave",
"Receba notificações quando outras pessoas avaliam/tiram uma captura de tela/comentam seus scripts, ou respondem um de seus comentários, ou quando ocorrem eventos relacionados às suas assinaturas.",
"Lembre-se: todos poderão ver o seu script se você publicá-lo; certifique-se de que ele não contém senhas ou informações pessoais.",
"Remove o valor da vida atual.",
"Responder...",
"Relatar/Excluir",
"Redimensiona a imagem de acordo com o tamanho fornecido em pixels",
0,
"Retorna uma cópia da imagem",
"Retorna uma cópia dessa seqüência de caracteres convertido para minúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma cópia dessa seqüência de caracteres convertidos em maiúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma data que adiciona o número especificado de meses ao valor dessa instância.",
"Retorna uma data que adiciona o número especificado de anos ao valor dessa instância.",
"Retorna que um número aleatório integral entre 'min' e 'max' incluído.",
0,0,0,0,0,0,
"Retorna true se o sprite não está oculto",
"Retorna verdadeiro se a instância atual é inútil",
0,
"Execute a ação de inline.",
0,0,
"Atualizações de script",
"Scripts desse usuário:",
0,
"Pesquisar e navegar na web...",
"Pesquisar código...",
"Pesquisar tudo",
"Pesquisar aqui...",
0,0,
"Pesquisar...",
0,0,0,
"Ver Mais",
0,0,
"Ativa ou desativa o set gradient",
"Define a transformação de matriz offline 3x3 aplicada à parede.",
0,
"Define a câmera de fundo",
"Define a cor de fundo",
"Define a cor de fundo.",
"Define a imagem de fundo",
"Define a posição horizontal do centro em pixels",
"Define os pontos da vida atual.",
"Define a resistência dos sprites como uma fração da perda de velocidade entre 0 e 1",
"Define a altura em pixels",
"Define a posição em pixels",
0,
"Define o nível de volume para sons de 0 (silencioso) a 1 (volume atual)",
"Define a velocidade em pixels/segundos",
"Define a cor do sprite.",
"Define o vetor de aceleração uniforme para objetos no quadro como pixels/sec^2",
0,0,
"Define a largura em pixels",
"Define a velocidade x em pixels/s",
"Define a aceleração y em pixels/s^2",
"Define a posição y em pixels",
"Define a velocidade y em pixels/s",
0,
"Configurações",
"Compartilhe-o com essa url:",
"Mostrar erros no editor se o script usar APIs que impeçam sua execução nessas plataformas.",
"Mostra o quadro no mural.",
0,
"Nível de habilidade: {0}     ",
0,0,0,0,0,
"Para e limpa todos timers de cada quadro",
0,
"Subtrai números",
0,
"TD100: inserir {0} aqui",
"TD101: não é possível encontrar '{0}'",
"TD109: não é possível fazer essa atribuição",
"TD111: não é possível atribuir de {0} a {1}",
"TD112: não consigo encontrar a propriedade '{0}' em {1}",
"TD115: parâmetro(s) excessivo(s) fornecido(s) para {0}",
"TD116: não foram fornecidos parâmetros suficientes para {0}",
"TD118: condição 'se' quer {1}",
"TD119: preciso de algo para interagir",
0,
"TD130: associado de 'para' quer {1}",
"TD144: parece que está faltando '{0}', tente adicioná-lo",
"TD145: parece que está faltando um operador (como '+', '(' ou ',') aqui",
"TD147: não esperávamos '{0}' aqui",
"TD150: não pode chamar antes de '('",
"TD151: unclosed ' ('",
"TD152: inesperado ')'",
"TD154: o operador precisa de alguma coisa após isso",
"TD155: '{0}' não pode ser atribuída a uma variável local",
"Ensine o Creative Coding!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Este script usa os seguintes recursos: ",
0,
"Este tutorial usa dados de nuvem compartilhados com outros usuários.",
"Para adicionar dados de página, crie uma variável local e toque em 'promover para campo'.",
0,0,0,
"Tradução, fala em texto,...",
"Traduções por Microsoft ® Translator, toque para ver o original...",
"Verdadeiro, se o quadro for tocado",
"Tente ajustar seu código até funcionar. Se tiver dificuldade, toque na barra do tutorial.",
0,0,
"Tutoriais",
"Twitter",
"Digite para pesquisar online...",
"Digite para pesquisar...",
0,
"Tipos, ordem e número de parâmetros de evento não podem ser editados.",
"Widget de interface do usuário",
0,
"Atualize as posições dos sprites no quadro.",
"Atualiza a imagem em uma forma de imagem (se não for uma forma de imagem)",
"Atualiza o texto em um sprite de texto (se for um sprite de texto)",
"Carregar imagens",
"Carregar som",
"Usuários",
0,
"Precisamos de mais opções",
"Adaptaremos o editor ao seu nível de habilidade em codificação. Você poderá alterar seu nível de habilidade posteriormente no hub.",
"Qual seu nível de conhecimento de programação?",
"Qual é a sua ocupação?",
"O que há de novo",
"Onde você está?",
"Grava outra imagem em um determinado local. A opacidade varia de 0 (transparente) a 1 (opaco).",
0,
"YouTube",
0,0,
"Seu usuário GitHub.",
"Seu usuário Minecraft.",
"Sua arte aparecerá aqui",
0,
"Seu canal aparecerá aqui",
"Seu endereço de email ainda não foi verificado Verifique sua caixa de entrada.",
"Seu nome completo",
0,0,0,
"Seu script aparecerá aqui",
"Seu handle do twitter, como @touchdevelop.",
"alguns segundos atrás",
"uma função",
"uma variável global",
"um minuto atrás",
"uma página",
"sobre cobertura",
"sobre percepções",
"sobre perfil",
"sobre você",
"abuso",
0,
"relatar abusos",
0,0,0,
"acesse o campo {0}",
0,
"adicionar",
"adicionar um novo...",
0,
"adicionar uma ação que é disparada para cada quadro de exibição.",
0,0,0,0,0,
"adicionar parâmetro de entradas",
"adicionar linha acima",
"adicionar linha abaixo",
"adicionar novo",
0,0,
"adicionar parâmetro de saídas",
0,0,0,0,0,
"todas as APIs",
"permitir",
"excelente, surpreendente, impressionante, espantoso, fenomenal, de tirar o fôlego, clássico, legal, curioso, diferente, excepcional, exclusivo, extraordinário, fabuloso, fantástico, esplêndido, ótimo, ",
0,
"uma definição de tipo de função",
"uma hora atrás",
0,0,0,0,0,
"aplicativos",
0,
"arte",
"recurso de arte",
"atribuição",
0,
"autor",
0,0,
"voltar",
0,
"backspace",
"usar backspace nisto",
0,0,
"base",
"iniciante",
"iniciantes",
0,
"vincula ao script:",
"em branco",
"aplicativo em branco",
"creeper em branco",
"documentos em branco",
"jogo em branco",
"minecraft em branco",
"minecraft pi em branco",
"pixel art em branco",
"rascunho em branco",
"plugin de script em branco",
"tartaruga em branco",
"tutorial em branco",
"quebrar no depurador",
"ponto de interrupção",
0,0,0,0,0,0,
"cancelar",
0,0,
"alterar (voltar) para local",
"alterar conteúdos",
0,
"verifica se a referência não foi definida",
0,0,0,
"escolha uma imagem (menos que 1 MB, menor que 2048x2048)",
0,0,0,0,0,0,
"escolha seu nível de habilidade em codificação",
"escolha...",
0,
"limpar",
"área de transferência",
"clonar",
0,
"sessões de nuvem",
"código",
"codifique a linha de objetivo",
"codificador",
"cor nº{0}",
"cor: {0}",
"comentado",
"comentários",
0,
"condicional",
"conectado",
0,0,
"continuar",
0,
"copiar",
"copiar seleção",
"cobertura",
"criar",
"criar um novo parâmetro",
0,
"crie código de com...",
"criar códigos",
0,
"cria uma coleção vazia de objetos",
"criação de script",
0,
"expressão atual",
"personalize a arte!",
"recortar",
"cortar seleção",
"banco de dados",
"depurar",
"ponto decimal",
0,
"excluir",
"excluir dados locais e permissões",
"excluir seleção",
"rebaixar para var",
"negar",
"descrição",
"descrição (ajuda a pesquisa)",
0,
"detalhes",
"você queria usar este valor?",
"diff curr",
"diff prev",
"desativar o login",
"desativado",
0,
"ignorar",
"valor de exibição",
"exibe o objeto na rede",
0,0,0,
"pronto",
"pronto!",
"editar",
"e se",
"email",
0,
"email e notificações por push",
0,0,0,0,
"insira o código de convite",
"insira este código",
"erros",
0,
"eventos",
0,
"ex: ",
0,
"excelente; ótimo trabalho; incrível; legal; você é demais; bom trabalho; extraordinário; você conseguiu; é isso aí",
0,
"saída",
"especialista",
0,
"exportar",
"exportar uma representação JSON dos conteúdos",
"exportado desta biblioteca",
"estender",
0,
"extrair seleção em função",
0,
"extrair para var",
"encontrar referências",
"concluído",
"corrigir",
"seguir tutorial no editor",
"para o grupo",
"bifurcações",
"função",
"nome da função",
"tipos de função",
"função, variável, biblioteca...",
"gênero",
"obter meu certificado da Hora do Código™",
"obtém o timer que dispara para cada quadro de exibição.",
"usuário github",
"dado ♥",
"substituição global",
"variável global",
"variáveis globais",
"voltar",
"voltar para a codificação! {0}★ para ir",
"voltar...",
"ir para",
"ir para a lista de coisas em seu script",
"ir para a etapa anterior",
"objetivo:",
"grupo",
"grupos",
"corações",
"ajuda",
0,0,
"histórico",
"Viva! Seu script está publicado",
"como encontrou",
"quero que seja executado em",
"terminei com meu Hora do Código™",
"arte do ícone: {0}",
0,
"se tiver dificuldade, toque na linha de objetivo",
0,
"importação somente pode ser usada em um contexto de roteiro",
"código de importação",
0,
"importar valores de campo de um objeto JSON",
"importações",
0,0,0,
"incrível, mágico, maravilhoso, maravilhoso, alucinante, estarrecedor, milagroso, peculiar, fenomenal, radical, formidável, especial, espetacular, vistoso, deslumbrante, superlegal, ",
0,
"inserir",
"inserir comentário",
"inserir instrução",
"inserir {0}",
"percepções",
0,
"instalando e carregando o script",
"no local",
0,
"questões",
"ingressar em um grupo",
"ingressar no grupo",
"selva",
"basta digitar os termos de pesquisa!",
"continuar editando",
"conhecido aqui como:",
0,
"aprender",
"saiba mais sobre publicação",
"saber mais",
"saiba mais sobre {0}",
"deixar tutorial",
"vamos mudar isso",
"vamos fazer isso!",
"vamos começar!",
"lib",
"bibliotecas",
"biblioteca",
"nome da biblioteca",
"referência de biblioteca",
"carregar mais",
"carregar mais respostas",
"carregando",
0,
"carregando comentários para /{0}...",
0,
"carregando respostas...",
"carregando o script",
"​carregando tutorial​",
"carregando...",
"local",
"local",
0,
"negação lógica",
"logs",
"principal",
0,
"makers",
"gerenciar dados",
"talvez mais tarde",
"eu",
0,0,
"usuário minecraft",
0,0,
"mais",
"mais ",
"mais configurações",
"mover cursor",
"mover para a esquerda",
"passe para a próxima etapa",
"mova o cursor para esquerda",
"mova o cursor para a direita",
"minha arte",
0,0,0,
"meus scripts",
"um nome diferente é necessário aqui",
"necessário uma string diferente aqui",
"um novo campo aqui é necessário",
"precisa de um parâmetro",
"é necessário excluir isso",
"é necessário editar em algum outro local",
"negação",
0,0,0,0,
"nova linha",
0,0,0,
"novo stmt abaixo",
"nova variável",
0,
"próximos tutoriais...",
"apelido",
0,
"nenhuma arte publicada por este usuário",
"nenhum comentário; toque para escrever algum!",
"nenhum script de bifurcações, instalação, edição e nova publicação para criar um!",
"nenhum coração. Você pode adicionar um desde que instale um script!",
"nenhuma imagem carregada ainda",
0,0,
"nenhuma marca; toque para adicionar alguma!",
0,0,0,
"notificações",
0,
"agora você pode selecionar uma propriedade de {0}; ele não faz nada sozinho",
"agora você pode selecionar uma propriedade nele",
"número",
"entrada de número",
0,
"ocupação",
"de um objeto",
"offline disponível",
"ok",
"ok, vamos lá!",
"online",
0,
"ou toque para obter ajuda",
"outros",
"visão geral",
0,
"páginas",
0,
"analisando o texto do script",
0,
"colar",
"pausar",
0,
"iniciador do jogo de física",
"escolha um modelo de script...",
"imagem",
"nome da imagem",
"nome da imagem (mínimo de 4 caracteres)",
"url da imagem",
"jogue novamente",
0,
"aguarde...",
"plugins",
"visualizar",
"imprimir",
0,
"privado",
"função privada",
"perfil privado",
"perfil",
"conhecimento de programação",
0,
"promover para dados",
"promover a campo",
"apelido público",
"perfil público",
"publicar",
"publicar como oculto",
0,
"publicado",
"extrair alterações",
"extrair para nível de bloco",
0,
"executar novamente",
"leia mais...",
"somente leitura",
"nome real",
0,
"receber boletins de notícias por email",
"receber notificações por email",
"registrar nome:",
0,
"teclado normal",
"recarregando script​",
"remover",
0,
"remover imagem",
"remove fundo branco (bom para sprites de jogos)",
0,
"renomear",
"repetir n vezes",
"repetir na coleção",
"repetir enquanto",
"substituir tudo na função",
"substituir tudo no script",
"substituir imagem",
"replicado",
"replicado ",
0,
"denunciar abuso",
0,
"reverter para versão publicada",
0,
"retroceder ",
"executar",
"executar principal",
0,
"executar com instrumentação",
"salvar",
"salvo",
"salvando...",
"escola",
"telas",
"captura de tela",
"captura de tela de {0}",
"script",
"propriedades do script",
0,
"pesquisar",
"pesquisar arte",
"pesquisar imagens de arte",
"pesquisar {0} aqui",
"pesquisar modelos",
"pesquisando...",
"ver mais opções",
"selecionar",
"selecionar mais",
"selecionar essa linha",
"selecione o tipo deste {0}",
0,0,
"definir nome da variável local",
"definir nome",
"definir o manipulador que é invocado quando o quadro é deslizado",
"definir o manipulador que é invocado quando o painel é tocado",
"definir o manipulador que é invocado quando o quadro é tocado",
"definir o manipulador que é invocado quando o quadro é solto",
"define todos os campos para os valores padrão",
"configuração salva",
"configurações",
"compartilhar",
0,
"mostrar como completar esta atividade",
"mostrar mais opções",
"demonstração",
"entrar",
0,0,
"sair",
"entrando...",
0,
"simplificar",
"nível de habilidade salvo",
"ignorar a iteração",
0,
"social",
0,
"som",
0,
"arte da tela inicial: {0}",
"dividir",
0,
"começar novamente",
"iniciando o script",
"iniciando...",
0,
"entrar",
"sair",
"transpor",
0,
"parar",
0,
"parar função",
"parar loop",
"store in var",
"armazenar o valor em uma variável",
"cadeia de caracteres",
0,
"faixa '{0}'",
0,0,0,
"superior, supernatural, tremendo, inacreditável, sobrenatural, único, sem precedente, incomum, estranho, magnífico, notável",
"cercar com",
0,
"sincronização foi desativada de propósito",
"sincronizando...",
0,0,0,0,0,
"tags",
0,0,
"toque (←) quando terminar",
"toque em [ok] ao concluir",
0,
"toque aqui para passar a próxima etapa",
"toque aqui quando concluir",
"toque aqui",
"toque lá para obter instruções",
"toque aqui para executar seu aplicativo",
"tocar para alterar a cor",
"toque para mudar a imagem do ícone",
"toque para mudar a imagem da tela inicial",
"toque para traduzir com o Microsoft® Translator...",
"temporário",
"terms of use",
"teste",
"testar função",
"testes",
"testa se duas referências estão relacionadas a um mesmo objeto",
0,0,
"o hub",
"o código de convite deve ser um número com extensão entre 9 e 64 caracteres",
"pane no script",
0,0,
"este script é uma biblioteca",
"este script é um serviço Web",
"tempo e datas",
"para código",
"para continuar",
"para var global",
"ativar/desativar ponto de interrupção",
"Novidades principais",
0,0,
"traduzir",
"​traduzindo tutorial​...",
0,0,0,
"tente novamente!",
"transformar em",
"progresso do tutorial",
"tutorial: ",
"tutoriais",
"handle do twitter",
"tipo: ",
"tipo: {0}",
0,0,0,
"desfazer",
0,0,0,0,0,0,0,
"bandeira desconhecida",
0,0,
"atualização",
0,0,0,0,0,0,
"carregar",
"carregar imagens",
"carregar screenshot",
"carregar som",
0,0,0,
"url",
0,0,0,0,0,
"nome da variável",
"exibir como script",
"exibir/editar nome, e-mail...",
0,
"papel de parede",
"temos uma biblioteca '{0}' aqui; {1}",
"temos {0:a} aqui; você queria fazer algo com isso?",
"precisamos de um novo campo",
"precisamos de uma nova tabela",
"precisamos de um novo {0}",
"precisamos de um teclado diferente",
"precisamos de uma nova variável",
"precisamos editar outro item",
"orientaremos você passo a passo",
"aplicativos web",
0,0,0,
"website",
0,
"url do website",
0,0,0,0,0,
"ano de nascimento",
0,0,
"você conseguiu!",
0,
"{0} ({1} linha{1:s})",
"{0} dia{0:s} atrás",
0,0,0,0,
"{0} hora{0:s} atrás",
"{0} minuto{0:s} atrás",
"{0} mês{0:s} atrás",
"{0} de {1} concluído",
"{0} publicado",
"{0} script publicado",
"{0} segundo{0:s} atrás",
"mais {0}",
"{0} ano{0:s} atrás"
]); return true; }

if (lang == "pt-PT") { TDev.Util._setLanguageArray(keys, [
"   Talvez: {0} ({1} em '{2}')\n",
"  -> Linha {2} ('{1}'), erro: {0}",
" -- uma variável local",
" [class]",
" [oculto]",
" [override]",
" para trás",
" para frente",
" horas ",
" minutos ",
" de ",
" segundos ",
" enviando alterações",
" a aguardar pelo servidor",
"### código fonte completo",
"Chaves como em JavaScript, todas as ferramentas, para desenvolvedores experientes!",
"função “atômica”",
"só pode aceder-se à 'box' na página de exibição do código",
"não pode aceder-se à 'box' em modo de layout HTML",
0,
"só se pode aceder ao 'html' em modo de layout HTML",
"'{0}' espera {1} aqui",
"'{0}' tem uma assinatura não suportada",
"'{0}' não está implementada",
"'{0}' é obsoleto e não está implementado",
"'{0}' é obsoleto e não deve ser usado",
0,
"'{0}' retorna um '{1}'; {2}",
"'{0}' devolve valores de {1}; pode usar o botão 'store em var' para os guardar em locais",
0,0,0,0,0,0,0,
", em vez disso, obteve {0}",
", obteve {0}",
0,0,0,
"... há mais...",
"// comentário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>esta linha está perfeita!</b> vamos continuar",
"<h3>carregando configurações atuais...</h3>",
"<h3>sem mais dicas!</h3>",
0,
"<h3>{0:q} exige conexão</h3>",
0,0,0,0,0,0,0,0,0,
"Um aplicativo de pi do Minecraft.",
"Um aplicativo Minecraft.",
"Um aplicativo de creeper do Minecraft.",
0,0,0,0,0,0,0,0,0,0,
"Uma cor constante",
0,0,0,0,0,0,0,0,0,
"Uma variável global",
0,0,0,0,0,0,0,0,0,0,0,
"Um número (possivelmente negativo e/ou fração)",
"Um número constante",
0,0,0,
"Uma imagem",
"Um trecho de texto",
"Um aplicativo de pixel art.",
0,0,0,
"Uma referência a um script de biblioteca",
0,0,0,0,0,0,0,0,0,
"Um som",
0,0,0,0,
"Uma estrutura de dados do usuário",
"Uma tabela de linhas definidas pelo usuário",
0,0,0,0,
"Um temporizador",
"Um nome exclusivo de exibição para seu perfil público (pelo menos 8 caracteres)",
0,0,
"Uma interface do usuário",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adicionar uma ação que é disparada para cada quadro de exibição",
0,
"Adicione o sprite para definir e remover do conjunto de velho. Retorna true se a sprite foi no antigo conjunto e não no conjunto de novo.",
"Adicione o sprite para definir. Retorna true se o sprite já não estava no conjunto.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Adiciona números",
0,
"Agrega valor à pontuação atual.",
0,
"Avança o enumerador e retornar true se há um outro elemento.",
"Após a interrupção do script, procure o código para ver as informações coletadas.",
"Todos os meus grupos",
"Todos os meus scripts",
0,0,0,0,0,0,0,
"Um aplicativo em branco usando páginas e caixas.",
"Um aplicativo em branco que usa a biblioteca de rascunhos.",
"Uma página de documentação vazia.",
"Um tutorial interativo vazio.",
"Um plugin de editor script vazio.",
"Um script em branco, que não faz nada.",
0,0,
"Uma tabela indexada de linhas definidas pelo usuário",
0,
"Um aplicativo de tartaruga.",
"Aplica `conversor` a todos os elementos da coleção de entradas e retorna uma coleção de resultados",
0,
"Tem certeza de que deseja parar de seguir o tutorial?",
"Operações aritméticas e bit a bit em inteiros de 32 bits",
"Arte desse usuário:",
"Perguntar ou exibir valores na tela...",
"Anexe dados a outros objetos",
"Código de texto clichê para criar um jogo.",
0,0,0,0,0,0,
"Alterar o nível de habilidade!",
"canais",
"Verifica que o quadro é a mesma instância do outro quadro.",
0,0,0,
"Limpe todos os eventos em fila relacionados com esse quadro",
"Limpar a imagem do plano de fundo",
"Limpar a câmera do plano de fundo",
0,0,
"Código gerado quando ocorre uma interação do usuário",
"Código que executa uma tarefa específica",
"Compara números para igualdade",
"Compara números para menos",
0,
"Compara números para mais",
0,0,0,0,
"Calcula o máximo dos valores",
"Calcula o mínimo dos valores",
0,
"Concatena dois trechos de texto",
0,0,0,
"Converte o valor em uma estrutura de dados json.",
0,0,
"Converte na hora local",
0,0,
"Ajudantes de correção",
0,
"Criar o código",
"Criar Grupo",
"Criar Script",
"Criar um obstáculo de linha com certo ponto de início, de certa largura e altura. Elasticidade é 0 para grudento e 1 para rebatimento completo.",
"Crie uma nova coleção de sprites.",
"Criar um novo sprite de elipse.",
"Crie uma nova forma de imagem.",
"Criar um novo sprite de retângulo.",
"Criar um novo script",
0,0,0,
"Cria um sprite âncora.",
"Crie um valor inválido deste tipo de objeto",
"Criar canal",
0,
"Criar valores inválidos",
"Cria paredes em torno do quadro a uma dada distância.",
"Criar seus próprios aplicativos",
0,0,
"Cria um quadro de jogo vazio e mostra-o na tela.",
"Cria um novo jogo de tabuleiro no modo paisagem. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria um novo jogo de tabuleiro no modo retrato. Em dispositivos rotativos tomará a tela inteira quando Postado.",
"Cria uma nova camada na cena. A distância determina a ordem de renderização e quão rápido a camada se move",
"Cria um novo sprite de largura 100 com a imagem fornecida.",
0,
"Cria uma instância de gamepad inválida",
0,0,
"Dispositivo atual",
0,
"Ponto de toque atual",
"Desvincula o manipulador do evento.",
0,
"Exibe a imagem na parede; você precisará chamar 'atualização na parede' mais tarde se quiser que as alterações sejam refletidas.",
0,0,0,
"Exibe o estado do gamepad no mural",
"Divide números",
"Fazer com que as formas se sobreponham",
0,
"Documentos",
"Não se esqueça de rolar para baixo na tela e tocar em 'salvar' quando terminar de editar!",
"Arrastar e soltar blocos, interface simplificada, ótimo para iniciantes!",
"Traça uma linha entre dois pontos",
"Desenha alguma borda de texto com uma determinada cor e tamanho de fonte",
"Edite código como texto, mais opções, para aspirantes a criadores de aplicativos!",
0,
"Habilitar ou desabilitar a sincronização da nuvem para a sessão atual do",
"Insira um nome",
0,
"Insira algumas informações sobre você",
"Insira o URL de seu website pessoal (Exemplo: http://www.northwindtraders.com)",
"Insira o código de convite",
0,
"Os eventos não podem ter parâmetros.",
"Todos podem ver sua foto na Internet para sempre. ",
0,0,
"Extensões",
"Facebook",
"Preenche uma elipse com uma determinada cor",
"Preenche um retângulo com uma determinada cor",
"Velocidade de toque final após o fim do toque",
"Para scripts publicados, veja também a guia da página de scripts publicados para encontrar dados de cobertura e perfis coletados de forma anônima.",
"Fóruns",
"A partir de agora, não mostraremos mais o código a ser escrito. Siga as instruções e toque em executar quando achar que terminou.",
"Funções no script atual",
0,0,0,0,0,
"Obtém uma captura de tela dos estados do gamepad (se conectado ao navegador). Vazio se não tiver suporte ou nenhum gamepad for conectado.",
0,0,0,
"Obtenha um valor indicando se o quadro é projetado para ser exibido em modo paisagem",
"Obterá um valor se a música for protegida por DRM",
"Obtém o valor x e y dos eixos selecionados.",
0,0,
"Obtém a cena do plano de fundo",
"Obtém a posição horizontal do centro em pixels",
0,
"Obtém a cor com valor ARGB igual a #00FFFFFF",
"Obtém a cor com valor ARGB igual a #FF000000",
"Obtém a cor com valor ARGB igual a #FF0000FF",
"Obtém a cor com valor ARGB igual a #FF008000",
"Obtém a cor com valor ARGB igual a #FF00FFFF",
0,
"Obtém a cor com valor ARGB igual a #FF800080",
0,0,0,0,
"Obtém a cor com valor ARGB igual a #FFFF0000",
"Obtém a cor com valor ARGB igual a #FFFF00FF",
"Obtém a cor com valor ARGB igual a #FFFFA500",
0,
"Obtém a cor com valor ARGB igual a #FFFFFF00",
"Obtém a cor com valor ARGB igual a #FFFFFFFF",
0,0,0,0,
"Obtém o primeiro gamepad conectado disponível",
0,
"Obtém o identificador do gamepad",
0,
"Obtém a altura em pixels",
"Obtém a altura da imagem da câmera em pixels.",
0,0,0,0,0,0,0,
"Obtém o número de elementos",
0,
"Obtém o índice do jogador",
"Obtém o valor pressionado de um botão. Retorna 0 se o botão não for encontrado.",
"Obtém a propriedade que habilita ou desabilita a gradientes",
"Obtém o volume para sons de 0 (silencioso) a 1 (volume atual)",
"Obtém a contagem de sprites",
"Faz o sprite ser indexado por i",
0,
"Obtém a data/hora dessa captura de tela",
0,
"Obtém a largura em pixels",
"Obtém a largura da imagem da câmera em pixels.",
"Obtém a posição y em pixels",
"Introdução",
0,
"Variáveis globais no script atual",
0,0,0,0,0,0,0,0,
"Código de importação",
"Importar um script de um arquivo",
"Importa uma representação JSON do conteúdo.",
"Importa um pacote de dependente que pode ser versionado. Gerenciadores de pacotes podem ser node. js npm, Bower, Apache cordova, Python Pip e plugins TouchDevelop. importações ' bower ' e ' cliente ' não estão disponíveis dentro do domínio touchdevelop.com.",
"Importações, o código de arquivos hex criado para o BBC micro: bit ou .jsz arquivos salvos. Dica: você também pode arrastar e soltar os arquivos no editor para importá-los!",
"No modo debug, o quadro exibe a velocidade e outras informações de sprites",
"Indica se o botão é pressionado. Retorna falso se o botão não for encontrado.",
"Indica se as notificações do programa devem ser mostradas ao usuário. Padrão é true.",
"Indica se os dados do gamepad são idênticos",
"Indica se o gamepad ainda está conectado.",
0,0,0,0,
"Inserir '{0}' {1}",
0,
"Itens marcados com * são obrigatórios.",
"dados JSON",
"Ingressar no grupo",
"Último ponto final de toque",
"Último ponto inicial de toque",
0,0,0,0,0,
"Torna as atualizações visíveis.",
0,0,
"Faz com que todos os sprites saltem na borda da tela",
"Mapas, localização de endereço, endereço de localização",
"Bom em matemática, abs, máx, ...",
"Me",
0,
"Usuário Minecraft",
0,0,
"Move o sprite em direção a outro.",
"Multiplica números",
0,0,0,0,0,0,0,0,
"Novos Scripts",
0,
"Cores novas ou inseridas",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Números de telefone, vibrar, etc...",
0,
"Escolhe uma cor aleatória",
0,0,0,0,0,
"Por favor, vá para as configurações no cubo principal para desativar o modo off-line.",
"Examine nossa Declaração de Privacidade",
0,
"Publicação de um comentário...",
0,0,0,
"Ação privada não tem um botão run. ",
"Solicita que o usuário forneça um número",
"Solicita ao usuário para escolher uma seqüência de caracteres de uma lista. Retorna o índice selecionado.",
"Publicar script",
0,
"A publicação está sujeita aos nossos ",
"Publicando script...",
"Aumentado quando a animação começou a tocar",
"Aumentado quando a animação parou a tocar",
"Lê o corpo de resposta como som wave",
"Receba notificações quando outras pessoas avaliam/tiram uma captura de tela/comentam seus scripts, ou respondem um de seus comentários, ou quando ocorrem eventos relacionados às suas assinaturas.",
"Lembre-se: todos poderão ver o seu script se você publicá-lo; certifique-se de que ele não contém senhas ou informações pessoais.",
"Remove o valor da vida atual.",
"Responder...",
"Relatar/Excluir",
"Redimensiona a imagem de acordo com o tamanho fornecido em pixels",
0,
"Retorna uma cópia da imagem",
"Retorna uma cópia dessa seqüência de caracteres convertido para minúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma cópia dessa seqüência de caracteres convertidos em maiúsculas, usando as regras capitalização da cultura atual.",
"Retorna uma data que adiciona o número especificado de meses ao valor dessa instância.",
"Retorna uma data que adiciona o número especificado de anos ao valor dessa instância.",
"Retorna que um número aleatório integral entre 'min' e 'max' incluído.",
0,0,0,0,0,0,
"Retorna true se o sprite não está oculto",
"Retorna verdadeiro se a instância atual é inútil",
0,
"Execute a ação de inline.",
0,0,
"Atualizações de script",
"Scripts desse usuário:",
0,
"Pesquisar e navegar na web...",
"Pesquisar código...",
"Pesquisar tudo",
"Pesquisar aqui...",
0,0,
"Pesquisar...",
0,0,0,
"Ver Mais",
0,0,
"Ativa ou desativa o set gradient",
"Define a transformação de matriz offline 3x3 aplicada à parede.",
0,
"Define a câmera de fundo",
"Define a cor de fundo",
"Define a cor de fundo.",
"Define a imagem de fundo",
"Define a posição horizontal do centro em pixels",
"Define os pontos da vida atual.",
"Define a resistência dos sprites como uma fração da perda de velocidade entre 0 e 1",
"Define a altura em pixels",
"Define a posição em pixels",
0,
"Define o nível de volume para sons de 0 (silencioso) a 1 (volume atual)",
"Define a velocidade em pixels/segundos",
"Define a cor do sprite.",
"Define o vetor de aceleração uniforme para objetos no quadro como pixels/sec^2",
0,0,
"Define a largura em pixels",
"Define a velocidade x em pixels/s",
"Define a aceleração y em pixels/s^2",
"Define a posição y em pixels",
"Define a velocidade y em pixels/s",
0,
"Configurações",
"Compartilhe-o com essa url:",
"Mostrar erros no editor se o script usar APIs que impeçam sua execução nessas plataformas.",
"Mostra o quadro no mural.",
0,
"Nível de habilidade: {0}     ",
0,0,0,0,0,
"Para e limpa todos timers de cada quadro",
0,
"Subtrai números",
0,
"TD100: inserir {0} aqui",
"TD101: não é possível encontrar '{0}'",
"TD109: não é possível fazer essa atribuição",
"TD111: não é possível atribuir de {0} a {1}",
"TD112: não consigo encontrar a propriedade '{0}' em {1}",
"TD115: parâmetro(s) excessivo(s) fornecido(s) para {0}",
"TD116: não foram fornecidos parâmetros suficientes para {0}",
"TD118: condição 'se' quer {1}",
"TD119: preciso de algo para interagir",
0,
"TD130: associado de 'para' quer {1}",
"TD144: parece que está faltando '{0}', tente adicioná-lo",
"TD145: parece que está faltando um operador (como '+', '(' ou ',') aqui",
"TD147: não esperávamos '{0}' aqui",
"TD150: não pode chamar antes de '('",
"TD151: unclosed ' ('",
"TD152: inesperado ')'",
"TD154: o operador precisa de alguma coisa após isso",
"TD155: '{0}' não pode ser atribuída a uma variável local",
"Ensine o Creative Coding!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Este script usa os seguintes recursos: ",
0,
"Este tutorial usa dados de nuvem compartilhados com outros usuários.",
"Para adicionar dados de página, crie uma variável local e toque em 'promover para campo'.",
0,0,0,
"Tradução, fala em texto,...",
"Traduções por Microsoft ® Translator, toque para ver o original...",
"Verdadeiro, se o quadro for tocado",
"Tente ajustar seu código até funcionar. Se tiver dificuldade, toque na barra do tutorial.",
0,0,
"Tutoriais",
"Twitter",
"Digite para pesquisar online...",
"Digite para pesquisar...",
0,
"Tipos, ordem e número de parâmetros de evento não podem ser editados.",
"Widget de interface do usuário",
0,
"Atualize as posições dos sprites no quadro.",
"Atualiza a imagem em uma forma de imagem (se não for uma forma de imagem)",
"Atualiza o texto em um sprite de texto (se for um sprite de texto)",
"Carregar imagens",
"Carregar som",
"Usuários",
0,
"Precisamos de mais opções",
"Adaptaremos o editor ao seu nível de habilidade em codificação. Você poderá alterar seu nível de habilidade posteriormente no hub.",
"Qual seu nível de conhecimento de programação?",
"Qual é a sua ocupação?",
"O que há de novo",
"Onde você está?",
"Grava outra imagem em um determinado local. A opacidade varia de 0 (transparente) a 1 (opaco).",
0,
"YouTube",
0,0,
"Seu usuário GitHub.",
"Seu usuário Minecraft.",
"Sua arte aparecerá aqui",
0,
"Seu canal aparecerá aqui",
"Seu endereço de email ainda não foi verificado Verifique sua caixa de entrada.",
"Seu nome completo",
0,0,0,
"Seu script aparecerá aqui",
"Seu handle do twitter, como @touchdevelop.",
"alguns segundos atrás",
"uma função",
"uma variável global",
"um minuto atrás",
"uma página",
"sobre cobertura",
"sobre percepções",
"sobre perfil",
"sobre você",
"abuso",
0,
"relatar abusos",
0,0,0,
"acesse o campo {0}",
0,
"adicionar",
"adicionar um novo...",
0,
"adicionar uma ação que é disparada para cada quadro de exibição.",
0,0,0,0,0,
"adicionar parâmetro de entradas",
"adicionar linha acima",
"adicionar linha abaixo",
"adicionar novo",
0,0,
"adicionar parâmetro de saídas",
0,0,0,0,0,
"todas as APIs",
"permitir",
"excelente, surpreendente, impressionante, espantoso, fenomenal, de tirar o fôlego, clássico, legal, curioso, diferente, excepcional, exclusivo, extraordinário, fabuloso, fantástico, esplêndido, ótimo, ",
0,
"uma definição de tipo de função",
"uma hora atrás",
0,0,0,0,0,
"aplicativos",
0,
"arte",
"recurso de arte",
"atribuição",
0,
"autor",
0,0,
"voltar",
0,
"backspace",
"usar backspace nisto",
0,0,
"base",
"iniciante",
"iniciantes",
0,
"vincula ao script:",
"em branco",
"aplicativo em branco",
"creeper em branco",
"documentos em branco",
"jogo em branco",
"minecraft em branco",
"minecraft pi em branco",
"pixel art em branco",
"rascunho em branco",
"plugin de script em branco",
"tartaruga em branco",
"tutorial em branco",
"quebrar no depurador",
"ponto de interrupção",
0,0,0,0,0,0,
"cancelar",
0,0,
"alterar (voltar) para local",
"alterar conteúdos",
0,
"verifica se a referência não foi definida",
0,0,0,
"escolha uma imagem (menos que 1 MB, menor que 2048x2048)",
0,0,0,0,0,0,
"escolha seu nível de habilidade em codificação",
"escolha...",
0,
"limpar",
"área de transferência",
"clonar",
0,
"sessões de nuvem",
"código",
"codifique a linha de objetivo",
"codificador",
"cor nº{0}",
"cor: {0}",
"comentado",
"comentários",
0,
"condicional",
"conectado",
0,0,
"continuar",
0,
"copiar",
"copiar seleção",
"cobertura",
"criar",
"criar um novo parâmetro",
0,
"crie código de com...",
"criar códigos",
0,
"cria uma coleção vazia de objetos",
"criação de script",
0,
"expressão atual",
"personalize a arte!",
"recortar",
"cortar seleção",
"banco de dados",
"depurar",
"ponto decimal",
0,
"excluir",
"excluir dados locais e permissões",
"excluir seleção",
"rebaixar para var",
"negar",
"descrição",
"descrição (ajuda a pesquisa)",
0,
"detalhes",
"você queria usar este valor?",
"diff curr",
"diff prev",
"desativar o login",
"desativado",
0,
"ignorar",
"valor de exibição",
"exibe o objeto na rede",
0,0,0,
"pronto",
"pronto!",
"editar",
"e se",
"email",
0,
"email e notificações por push",
0,0,0,0,
"insira o código de convite",
"insira este código",
"erros",
0,
"eventos",
0,
"ex: ",
0,
"excelente; ótimo trabalho; incrível; legal; você é demais; bom trabalho; extraordinário; você conseguiu; é isso aí",
0,
"saída",
"especialista",
0,
"exportar",
"exportar uma representação JSON dos conteúdos",
"exportado desta biblioteca",
"estender",
0,
"extrair seleção em função",
0,
"extrair para var",
"encontrar referências",
"concluído",
"corrigir",
"seguir tutorial no editor",
"para o grupo",
"bifurcações",
"função",
"nome da função",
"tipos de função",
"função, variável, biblioteca...",
"gênero",
"obter meu certificado da Hora do Código™",
"obtém o timer que dispara para cada quadro de exibição.",
"usuário github",
"dado ♥",
"substituição global",
"variável global",
"variáveis globais",
"voltar",
"voltar para a codificação! {0}★ para ir",
"voltar...",
"ir para",
"ir para a lista de coisas em seu script",
"ir para a etapa anterior",
"objetivo:",
"grupo",
"grupos",
"corações",
"ajuda",
0,0,
"histórico",
"Viva! Seu script está publicado",
"como encontrou",
"quero que seja executado em",
"terminei com meu Hora do Código™",
"arte do ícone: {0}",
0,
"se tiver dificuldade, toque na linha de objetivo",
0,
"importação somente pode ser usada em um contexto de roteiro",
"código de importação",
0,
"importar valores de campo de um objeto JSON",
"importações",
0,0,0,
"incrível, mágico, maravilhoso, maravilhoso, alucinante, estarrecedor, milagroso, peculiar, fenomenal, radical, formidável, especial, espetacular, vistoso, deslumbrante, superlegal, ",
0,
"inserir",
"inserir comentário",
"inserir instrução",
"inserir {0}",
"percepções",
0,
"instalando e carregando o script",
"no local",
0,
"questões",
"ingressar em um grupo",
"ingressar no grupo",
"selva",
"basta digitar os termos de pesquisa!",
"continuar editando",
"conhecido aqui como:",
0,
"aprender",
"saiba mais sobre publicação",
"saber mais",
"saiba mais sobre {0}",
"deixar tutorial",
"vamos mudar isso",
"vamos fazer isso!",
"vamos começar!",
"lib",
"bibliotecas",
"biblioteca",
"nome da biblioteca",
"referência de biblioteca",
"carregar mais",
"carregar mais respostas",
"carregando",
0,
"carregando comentários para /{0}...",
0,
"carregando respostas...",
"carregando o script",
"​carregando tutorial​",
"carregando...",
"local",
"local",
0,
"negação lógica",
"logs",
"principal",
0,
"makers",
"gerenciar dados",
"talvez mais tarde",
"eu",
0,0,
"usuário minecraft",
0,0,
"mais",
"mais ",
"mais configurações",
"mover cursor",
"mover para a esquerda",
"passe para a próxima etapa",
"mova o cursor para esquerda",
"mova o cursor para a direita",
"minha arte",
0,0,0,
"meus scripts",
"um nome diferente é necessário aqui",
"necessário uma string diferente aqui",
"um novo campo aqui é necessário",
"precisa de um parâmetro",
"é necessário excluir isso",
"é necessário editar em algum outro local",
"negação",
0,0,0,0,
"nova linha",
0,0,0,
"novo stmt abaixo",
"nova variável",
0,
"próximos tutoriais...",
"apelido",
0,
"nenhuma arte publicada por este usuário",
"nenhum comentário; toque para escrever algum!",
"nenhum script de bifurcações, instalação, edição e nova publicação para criar um!",
"nenhum coração. Você pode adicionar um desde que instale um script!",
"nenhuma imagem carregada ainda",
0,0,
"nenhuma marca; toque para adicionar alguma!",
0,0,0,
"notificações",
0,
"agora você pode selecionar uma propriedade de {0}; ele não faz nada sozinho",
"agora você pode selecionar uma propriedade nele",
"número",
"entrada de número",
0,
"ocupação",
"de um objeto",
"offline disponível",
"ok",
"ok, vamos lá!",
"online",
0,
"ou toque para obter ajuda",
"outros",
"visão geral",
0,
"páginas",
0,
"analisando o texto do script",
0,
"colar",
"pausar",
0,
"iniciador do jogo de física",
"escolha um modelo de script...",
"imagem",
"nome da imagem",
"nome da imagem (mínimo de 4 caracteres)",
"url da imagem",
"jogue novamente",
0,
"aguarde...",
"plugins",
"visualizar",
"imprimir",
0,
"privado",
"função privada",
"perfil privado",
"perfil",
"conhecimento de programação",
0,
"promover para dados",
"promover a campo",
"apelido público",
"perfil público",
"publicar",
"publicar como oculto",
0,
"publicado",
"extrair alterações",
"extrair para nível de bloco",
0,
"executar novamente",
"leia mais...",
"somente leitura",
"nome real",
0,
"receber boletins de notícias por email",
"receber notificações por email",
"registrar nome:",
0,
"teclado normal",
"recarregando script​",
"remover",
0,
"remover imagem",
"remove fundo branco (bom para sprites de jogos)",
0,
"renomear",
"repetir n vezes",
"repetir na coleção",
"repetir enquanto",
"substituir tudo na função",
"substituir tudo no script",
"substituir imagem",
"replicado",
"replicado ",
0,
"denunciar abuso",
0,
"reverter para versão publicada",
0,
"retroceder ",
"executar",
"executar principal",
0,
"executar com instrumentação",
"salvar",
"salvo",
"salvando...",
"escola",
"telas",
"captura de tela",
"captura de tela de {0}",
"script",
"propriedades do script",
0,
"pesquisar",
"pesquisar arte",
"pesquisar imagens de arte",
"pesquisar {0} aqui",
"pesquisar modelos",
"pesquisando...",
"ver mais opções",
"selecionar",
"selecionar mais",
"selecionar essa linha",
"selecione o tipo deste {0}",
0,0,
"definir nome da variável local",
"definir nome",
"definir o manipulador que é invocado quando o quadro é deslizado",
"definir o manipulador que é invocado quando o painel é tocado",
"definir o manipulador que é invocado quando o quadro é tocado",
"definir o manipulador que é invocado quando o quadro é solto",
"define todos os campos para os valores padrão",
"configuração salva",
"configurações",
"compartilhar",
0,
"mostrar como completar esta atividade",
"mostrar mais opções",
"demonstração",
"entrar",
0,0,
"sair",
"entrando...",
0,
"simplificar",
"nível de habilidade salvo",
"ignorar a iteração",
0,
"social",
0,
"som",
0,
"arte da tela inicial: {0}",
"dividir",
0,
"começar novamente",
"iniciando o script",
"iniciando...",
0,
"entrar",
"sair",
"transpor",
0,
"parar",
0,
"parar função",
"parar loop",
"store in var",
"armazenar o valor em uma variável",
"cadeia de caracteres",
0,
"faixa '{0}'",
0,0,0,
"superior, supernatural, tremendo, inacreditável, sobrenatural, único, sem precedente, incomum, estranho, magnífico, notável",
"cercar com",
0,
"sincronização foi desativada de propósito",
"sincronizando...",
0,0,0,0,0,
"tags",
0,0,
"toque (←) quando terminar",
"toque em [ok] ao concluir",
0,
"toque aqui para passar a próxima etapa",
"toque aqui quando concluir",
"toque aqui",
"toque lá para obter instruções",
"toque aqui para executar seu aplicativo",
"tocar para alterar a cor",
"toque para mudar a imagem do ícone",
"toque para mudar a imagem da tela inicial",
"toque para traduzir com o Microsoft® Translator...",
"temporário",
"terms of use",
"teste",
"testar função",
"testes",
"testa se duas referências estão relacionadas a um mesmo objeto",
0,0,
"o hub",
"o código de convite deve ser um número com extensão entre 9 e 64 caracteres",
"pane no script",
0,0,
"este script é uma biblioteca",
"este script é um serviço Web",
"tempo e datas",
"para código",
"para continuar",
"para var global",
"ativar/desativar ponto de interrupção",
"Novidades principais",
0,0,
"traduzir",
"​traduzindo tutorial​...",
0,0,0,
"tente novamente!",
"transformar em",
"progresso do tutorial",
"tutorial: ",
"tutoriais",
"handle do twitter",
"tipo: ",
"tipo: {0}",
0,0,0,
"desfazer",
0,0,0,0,0,0,0,
"bandeira desconhecida",
0,0,
"atualização",
0,0,0,0,0,0,
"carregar",
"carregar imagens",
"carregar screenshot",
"carregar som",
0,0,0,
"url",
0,0,0,0,0,
"nome da variável",
"exibir como script",
"exibir/editar nome, e-mail...",
0,
"papel de parede",
"temos uma biblioteca '{0}' aqui; {1}",
"temos {0:a} aqui; você queria fazer algo com isso?",
"precisamos de um novo campo",
"precisamos de uma nova tabela",
"precisamos de um novo {0}",
"precisamos de um teclado diferente",
"precisamos de uma nova variável",
"precisamos editar outro item",
"orientaremos você passo a passo",
"aplicativos web",
0,0,0,
"website",
0,
"url do website",
0,0,0,0,0,
"ano de nascimento",
0,0,
"você conseguiu!",
0,
"{0} ({1} linha{1:s})",
"{0} dia{0:s} atrás",
0,0,0,0,
"{0} hora{0:s} atrás",
"{0} minuto{0:s} atrás",
"{0} mês{0:s} atrás",
"{0} de {1} concluído",
"{0} publicado",
"{0} script publicado",
"{0} segundo{0:s} atrás",
"mais {0}",
"{0} ano{0:s} atrás"
]); return true; }

if (lang == "ru") { TDev.Util._setLanguageArray(keys, [
"   Возможно: {0} ({1} в '{2}')\n",
"  -> Строка{2} ('{1}'), ошибка: {0}\n{3}",
" -- локальная переменная",
" [class]",
" [скрытый]",
" [override]",
" назад",
" вперёд",
" часов ",
" минут ",
" из ",
" секунд ",
" отправление изменений",
" ожидание ответа от сервера",
"### полный исходный код",
"Фигурные скобки как в JavaScript, весь набор инструментов, для опытных разработчиков!",
"'атомарная' функция",
"'блок' доступен только в коде интерфейса страницы",
"'блок' недоступен в режиме HTML разметки",
"'else' предшествующего 'if' должен быть пустым",
"'html' доступен только в режиме HTML разметки",
"\"{0}\" ожидает {1} здесь",
0,
"'{0}' на данный момент не реализован",
"'{0}' является устаревшим и не поддерживается",
"'{0}' устарел, использовать его не следует",
"'{0}' не является строковым ресурсом",
"\"{0}\" возвращает \"{1}\"; {2}",
"'{0}' возвращает значения {1}; вы можете 'сохранить в переменную', чтобы сохранить как локальную переменную",
0,
"(Необязательно) Удобочитаемый код ошибки.",
"(Необязательно) Дополнительные пары \"ключ-значение\", неохваченные в спецификации OAuth 2.0.",
"(Необязательно) Указывает, если срок действия маркера может истечь в ближайшие секунды.",
"(Необязательно) Необязательно, если идентично области, запрошенной клиентом; в противном случае, область маркера доступа, в соответствии с описанием в разделе 3.3 спецификации OAuth 2.0.",
"(Необязательно) Время жизни в секундах маркера доступа.",
"(Пожалуйста, подождите, это может занять около минуты)",
", вместо этого получено {0}",
", получено {0}",
", размер: {0} символов",
". Прочитайте наше ",
"... здесь ничего нет ...",
"... здесь есть ещё ...",
"//комментарий",
"1. выберите документ (.txt, .pptx, .pdf, .css, менее 8 мб)",
"1. выберите звуковой файл MP3 (менее 1 мб)",
"2. задайте имя файла (минимум 4 символа)",
"3. введите описание",
"4. опубликуйте",
":( К сожалению, при переводе текста произошла ошибка.",
":( К сожалению, мы не можем перевести это.",
":( Не могу найти источник видео",
0,0,
"<a href='http://cordova.apache.org/' target='_blank'> Apache Cordova</a> позволяет создавать кроссплатформенные мобильные приложения.",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> создать сертификат</a>.",
0,
"<b>как запустить Touch Develop локально</b>",
"<b>эта строка идеальна!</b> давайте двигаться дальше",
"<h3>загрузка текущих параметров...</h3>",
"<h3>подсказок больше нет!</h3>",
"<h3>добро пожаловать в Touch Develop</h3>",
0,
"<p>Если у вас нет подписки Azure, перейдите на страницу <a href='https://account.windowsazure.com/Subscriptions' target='_blank'>Подписки Azure</a>, для получения.</p>",
"<p>Touch Develop позволяет <b>легко создавать приложения</b> на смартфоне, планшете или компьютере.</p>",
"<p>Вы можете делиться вашими приложениями с другими, чтоб они могли <b>запустить и редактировать</b> их на Windows Phone, iPad, iPhone, Android, PC или Mac.</p>",
"<strong>функция в бета-тестировании:</strong> синтаксис и семантика могут быть изменены",
"<strong>необходимая платформа:</strong>",
0,
"Двумерная матрица чисел",
"Трёхмерный вектор",
"Карта Bing",
"Приложение для Minecraft Pi.",
"Приложение для Minecraft.",
0,0,0,
"Argb цвет (альфа, красный, зеленый, синий)",
0,0,
"Панель для создания 2D-игр",
0,0,0,0,
"Константа цвета",
0,0,
"Контакт",
0,
"Документ",
0,0,0,0,
"Глобальная переменная",
0,0,0,0,0,0,0,0,0,0,0,0,
"Константа числа",
0,0,0,
"Изображение",
0,0,
"Место для подключения действие для выполнения в ответ на событие",
0,0,
"Ссылка на скрипт библиотеки",
0,0,0,0,0,0,0,0,
"Песня",
"Звук",
"Звуковой эффект",
0,0,0,0,
"Таблица заданных пользователем строк",
0,0,0,0,0,
"Уникальное отображаемое имя для вашего общедоступного профиля (не менее 8 знаков)",
"Модульный тест",
0,
"Пользовательский интерфейс",
0,0,
"ADJ сценарий",
0,0,0,0,0,
"Акселерометр",
0,0,0,0,0,
"Добавьте действие, которое вызывается для каждого кадра отображаемого изображения",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Складывает числа",
0,
"Добавляет очки в текущий результат.",
0,0,
"После остановки скрипта просмотрите код, чтобы увидеть собранную информацию.",
"Все мои группы",
"Все мои сценарии",
0,0,0,0,0,0,0,0,
"Пустое приложение с использованием вспомогательной библиотеки.",
0,
"Пустой интерактивный урок.",
0,
"Пустой сценарий, который ничего не делает.",
0,0,
"Индексированная таблица заданных пользователем строк",
0,
"Приложение черепаха.",
"Применяет преобразователь ко всем элементам входной коллекции и возвращает коллекцию результатов",
0,0,0,
"Медиаобъекты этого пользователя:",
"Прочтите или отобразите значения на стене...",
0,
"Шаблонный код для создания игры.",
0,0,0,0,0,0,
"Изменить уровень мастерства!",
0,0,0,0,0,0,0,0,0,0,
"Код, который порождается при взаимодействии с пользователем",
"Код, который выполняет определенную задачу",
"Сравнивает числа (равенство)",
"Сравнивает числа (определяет меньшее из них)",
0,
"Сравнивает числа (определяет большее из них)",
0,0,0,0,0,0,0,
"Соединяет две части текста",
0,0,0,0,0,0,
"Преобразует время в местное",
0,
"Мобильное приложение Cordova",
0,
"Подсчитывает количество строк",
"Создать код",
"Создать группу",
"Создать скрипт",
0,0,0,
"Создать новый спрайт изображения.",
0,
"Создать скрипт",
0,0,0,0,0,
"Создать канал",
"Создание коллекций элементов.",
0,0,
"Создание собственных приложений",
0,0,0,0,0,0,0,0,0,
"Создает недопустимую ссылку на запись",
0,
"Текущее устройство",
"Текущий скрипт: {0}",
0,
"Отключает обработчик от события.",
0,
"Отображает изображение на стене; необходимо вызвать позже команду \"обновить на стене\", если вы хотите увидеть изменения.",
0,0,0,0,
"Делит числа",
"Сделайте наложение спрайтов",
"Вы хотите получать информационные бюллетени о TouchDevelop, например о новых функциях и предстоящих мероприятиях?",
"Документы",
"После внесения изменений не забудьте выполнить прокрутку вниз и щелкнуть элемент \"Сохранить\"!",
"Перетаскиваемые блоки и упрощенный интерфейс в помощь начинающим!",
"Рисует линию между двумя точками.",
"Рисует рамку с определенным цветом и размером шрифта",
"Редактирование кода как текста и большой набор возможностей для амбициозных программистов!",
0,0,
"Введите имя",
"Введите имя сценария...",
"Введите некоторые сведения о себе",
"Введите URL-адрес своего личного веб-сайта (например,\nhttp://www.northwindtraders.com)",
0,
"Укажите, к какой школе вы относитесь (если такая имеется).",
0,0,0,0,
"Расширения",
"Facebook",
"Заполняет эллипс определенным цветом",
"Заполняет прямоугольник определенным цветом",
0,
"При использовании опубликованных скриптов также откройте вкладку страницы для таких скриптов, чтобы найти анонимно собранные данные покрытия и профиля для краудсорсинга.",
"Форумы",
0,
"Функции в текущем сценарии",
0,0,0,0,0,0,0,0,0,0,
"Получает значение, которое указывает на то, защищена ли песня с помощью DRM",
0,0,0,0,
"Получает горизонтальное положение по центру в пикселях",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Получает высоту в пикселях",
"Получает высоту изображения с камеры в пикселях.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Получает громкость звука, значения — от 0 (без звука) до 1 (текущая громкость)",
0,0,0,0,0,
"Получает ширину в пикселях",
"Получает ширину изображения с камеры в пикселях.",
"Получает положение y в пикселях",
"Приступая к работе",
0,
"Глобальные переменные в текущем скрипте",
"Веб-приложение HTML5",
0,0,
"Скрывает таймер.",
0,0,
"Как вы узнали о TouchDevelop",
0,
"Импортировать код",
"Импортировать скрипт из файла",
0,0,0,0,0,0,0,0,0,0,0,0,
"Вставить '{0}' {1}",
"Взаимодействовать с исполняющей средой приложенеия",
"Элементы, помеченные звездочкой (*), являются обязательными. ",
"Данные JSON",
"Присоединиться к группе",
0,0,
"Библиотеки, на которые ссылается текущий сценарий",
"Библиотека {0}:\n",
"Загрузка таблицы рекордов...",
"Загрузка сессий...",
"Загрузка данных о версии...",
0,0,0,
"Заставляет все спрайты отскакивать от границ экрана",
0,0,
"Я",
0,0,
"Подробнее",
0,0,
"Умножает числа",
0,0,0,0,0,0,0,0,
"Новые скрипты",
0,
"Новые или встроенные цвета",
0,
"Объекты, таблицы и индексы в текущем сценарии",
0,
"Ой, не удалось получить таблицу рекордов. Проверьте ваше интернет-соединение.",
0,0,0,
"Ой, произошла ошибка при загрузке картинки.",
0,0,0,
"Открывает таблицу рекордов для текущего скрипта",
0,
"Партнёры",
0,0,
"Выбирает случайный цвет",
"Картинки и музыка...",
"Картинки, звуки и т.д. в текущем сценарии",
0,0,
"Подключитесь к интернету, чтобы загрузить таблицу рекордов.",
0,
"Прочитайте наше заявление о конфиденциальности.",
0,
"Опубликовать комментарий...",
0,0,
"Политика конфиденциальности",
0,0,0,0,0,
"Публикация регулируется нашими ",
0,0,0,
"Читает текст ответа со звуком WAVE",
"Получайте уведомления, когда другие люди просматривают или комментируют ваши скрипты, делают их снимки экрана или отвечают на один из ваших комментариев, а также в случае проведения мероприятий, связанных с вашей подпиской.",
0,
"Вычитает значение из имеющихся баллов шкалы здоровья.",
"Ответ...",
"Сообщить/Удалить",
"Изменяет размер изображения на определенный размер в пикселях",
0,
"Возвращает копию изображения",
0,0,
"Возвращает дату, которая прибавляет указанное количество месяцев к значению этого экземпляра.",
"Возвращает дату, которая прибавляет указанное количество лет к значению этого экземпляра.",
"Возвращает случайное целое число между значениями min и max включительно.",
0,0,0,0,0,0,0,
"Возвращает значение \"истина\", если текущий экземпляр является бесполезным",
"Запустить бета-версию Touch Develop.",
"Запуск встроенных действий.",
"Выполняет команду оболочки. Это действие доступно только в том случае, когда скрипт запускается на локальном веб-сервере.",
0,
"Обновления скриптов",
"Скрипты этого пользователя:",
0,0,
"Поиск в коде...",
"Поиск везде",
"Искать здесь...",
0,0,
"Поиск...",
0,0,0,
"Больше",
0,0,0,
"Задает аффинное преобразование с матричным представлением 3x3, которое применяется к стене.",
0,0,0,0,
"Задает фоновое изображение",
"Устанавливает горизонтальное положение по центру в пикселях",
"Задает количество баллов шкалы здоровья.",
0,
"Устанавливает высоту в пикселях",
"Устанавливает положение в пикселях",
0,
"Устанавливает громкость звука, значения — от 0 (без звука) до 1 (текущая громкость)",
0,0,0,0,0,
"Устанавливает ширину в пикселях",
"Устанавливает скорость x в пикселях/с",
"Устанавливает ускорение y в пикселях/с^2",
"Устанавливает положение y в пикселях",
"Устанавливает скорость y в пикселях/с",
0,
"Параметры",
0,
"В редакторе будут отображаться ошибки, если в скрипте используются API, которые не дают ему выполняться на этих платформах.",
0,0,
"Уровень навыка:{0}     ",
0,0,0,0,0,0,0,
"Вычитает числа",
0,
"TD100: вставить {0} сюда",
"TD101: не удается найти \"{0}\"",
"TD109: невозможно присвоить такое значение",
"TD111: невозможно присвоить значение от {0} до {1}",
"TD112: не удается найти свойство \"{0}\" в {1}",
"TD115: для {0} указаны лишние параметры",
"TD116: для {0} указано недостаточно параметров",
"TD118: для условия \"если\" нужно указать {1}",
0,
"TD121: не удается найти тип {0}",
"TD130: связанный с \"для\" элемент требует указать {1}",
"TD144: кажется, что вы пропустили элемент \"{0}\", попробуйте добавить его",
"TD145: кажется, здесь не хватает оператора (например, \"+\", \"(\" или \",\")",
"TD147: элемент \"{0}\" не ожидался здесь",
"TD150: не удается вызвать часть перед ' ('",
"TD151: отсутствует закрывающая ' ('",
"TD152: непредвиденный знак \")\"",
"TD154: после оператора нужно указать еще что-то",
"TD155: '{0}' не может быть назначен локальной переменной",
"Научите других креативному программированию!",
"Технологии предоставляются",
"Условия использования",
"Приложение Touch Develop обновлено.",
"Платформа Touch Develop - Copyright © {0} Корпорация Майкрософт. Все права защищены.",
"URL-адрес документа",
0,0,0,
"Пользователь отказал в доступе выполнению командной оболочки.",
"Вещь",
0,0,0,0,0,0,0,
"В этом скрипте используются следующие возможности: ",
"Эта вкладка содержит дополнительные сведения об этом сценарии",
0,
"Чтобы добавить страничные данные, создайте локальную переменную и нажмите \"повысить уровень до поля\".",
"Локальная коммандная оболочка Touch Develop",
"Настройки Touch Develop",
0,0,
"Перевод Microsoft® Переводчика, нажмите, чтобы увидеть оригинал...",
0,0,0,
"Урок завершён",
"Учебники",
"Twitter",
0,
"Ввести поисковой запрос...",
0,0,
"Мини-приложение пользовательского интерфейса",
0,0,
"Обновляет изображение на его спрайте (если это спрайт изображения)",
0,
"Загрузить изображение",
"Загрузить звук",
"Пользователи",
0,0,
"Мы адаптируем редактор под уровень навыка, если позднее вы измените его в Центре.",
"Каков ваш уровень знаний о программировании?",
"Каков ваш род занятий?",
"Новые возможности",
"В какой части мира вы находитесь?",
"Записывает еще одно изображение в определенном расположении. Для прозрачности устанавливаются значения от 0 (прозрачное изображение) до 1 (непрозрачное изображение).",
0,
"YouTube",
0,
"Файл .hex скоро будет загружен на ваш BBC micro:bit.",
"Ваш пользователь GitHub.",
"Ваш пользователь Minecraft.",
"Ваши медиа-объекты появятся здесь",
"Браузер не позволяет Touch Develop сохранять данные. Это обычно происходит когда браузер запущен в режиме инкогнито, или параметры безопасности запрещают сохранять данные в хранилище. Войдите или измените параметры безопасности браузера, чтобы сохранить вашу работу. Все изменения, не сохранённые в облаке, будут утеряны при закрытии этой страницы.",
"Ваш канал появится здесь",
"Ваш адрес электронной почты еще не подтвержден. Проверьте папку входящих сообщений.",
"Ваше полное имя",
0,0,0,
"Ваш скрипт появится здесь",
"Ваш дескриптор twitter, например @touchdevelop.",
"несколько секунд назад",
"функция",
"глобальная переменная",
"минуту назад",
"страница",
"о покрытии",
"об аналитических данных",
"о профиле",
"сведения о вас",
"злоупотребление",
0,
"сообщения о нарушениях",
0,0,0,
"доступ к полю {0}",
0,
"добавить",
0,0,0,
"добавить комментарий",
"добавить комментарий для этого поля",
0,0,0,
"Добавить параметр ввода",
"добавить строку выше",
"добавить строку ниже",
"Добавить",
0,0,
"Добавить параметр вывода",
0,0,
"добавить {0}",
0,
"чужой",
0,0,
"абсурдно, удивительно, потрясающе, великолепно, волшебно, восхитительно, впечатляюще, головокружительно, замечательно, захватывающе, зрелищно, изумительно, исключительно, классика, колоссально, непревзойденно, ",
"обработчик событий",
0,
"час назад",
"анализ...",
0,0,0,0,
"приложения",
0,
"медиа-объекты",
"медиа-объект",
"назначение",
0,
"автор",
0,0,
"назад",
"фон",
"backspace",
"удалить это клавишей backspace",
0,
"мяч",
"база",
"новичок",
"начинающие",
"колокольчик",
0,
"пустой",
"пустое приложение",
0,0,
"пустая игра",
0,0,
"пустой пиксель арт",
0,0,0,
"пустой урок",
"переключиться в отладчик",
"точка останова",
0,0,0,0,0,0,
"отмена",
0,
"кошка",
"изменить на локальный",
"изменить содержимое",
"каналы",
0,
"выберите файлы .hex или .jsz",
0,0,0,0,0,0,0,0,0,
"Выберите уровень навыка программирования",
0,
"очистка данных браузера...",
"очистить",
"буфер обмена",
"клонировать",
0,
"облачные сеансы",
"код",
0,
"программист",
"цвет №{0}",
"цвет: {0}",
"комментарий",
"комментарии",
0,
"условное",
0,
"подключение",
"консоль",
"продолжить",
"конвертировать",
"копировать",
"скопировать выделенное",
"покрытие",
"создать",
"создать новый параметр",
0,0,0,
"создает пустую коллекцию записей",
"создает пустую коллекцию объектов",
"Создание скрипта",
"текущий",
"текущее выражение",
"Наделите рисунки индивидуальностью!",
"вырезать",
"вырезать выделенное",
"база данных",
"отладка",
"десятичная точка",
0,
"удалить",
"удалить локальные данные и разрешения",
"удалить выделенное",
"понизить уровень до переменной",
0,
"описание",
0,
"пустыня",
"Сведения",
0,0,0,0,0,
"отсоедините",
"отменить",
"отображаемое значение",
"отображает объект на стене",
0,0,
"собака",
0,
"Готово!",
"редактировать",
"иначе если",
"электронная почта",
"адрес эл. почты (не отображается)",
"электронная почта и push-уведомления",
"адрес эл. почты не подтвержден, {0}",
0,0,
"введите число",
0,0,
"ошибки",
0,
"события",
0,
"пример: ",
0,
"отлично; отличная работа; превосходно; классно; вы отлично справляетесь; молодец; выдающийся результат; у вас получилось; в точку",
"выполняет команды оболочки или управляет файлами.",
"выход",
"эксперт",
"взрыв",
"экспорт",
0,
"экспортированно из этой библиотеки",
"расширить",
"извлечь",
0,
"извлечение параметров",
"извлечь в переменную",
"найти ссылки",
"завершено",
"исправить",
"следовать учебнику в редакторе",
0,
"вилки",
"функция",
"имя функции",
0,
"функция, переменная, библиотека,…",
"пол",
"Получить сертификат «Час кода»™",
0,
"пользователь github",
0,
"глобальная замена",
"глобальная переменная",
"глобальные переменные",
0,
"вернитесь к написанию кода! {0}★ для перехода",
0,
"перейти",
"перейти к списку вещей в вашем скрипте",
"перейти к предыдущему шагу",
"цель:",
"группа",
"группы",
"сердечки",
"справка",
"вот ваш код",
"скрыть",
"журнал",
0,
"как найдено",
"хочу, чтобы это запускалось на",
"я подтверждаю прохождение курса Час Кода™",
0,
"если",
0,
"проксирование изображения",
0,0,
"импорт значений столбца из объекта JSON",
0,0,0,0,
"в этой функции",
"любопытно, завораживающе, на грани фантастики, невероятно, незабываемо, необыкновенно, необычайно, необычно, отлично, ошеломляюще, поразительно, потрясающе, превосходно, пугающе, ",
"инициализация...",
0,
"вставить комментарий",
"вставить оператор",
"вставить {0}",
"аналитические данные",
0,
"Установка и загрузка скрипта",
"в локальный",
"остров",
"Проблемы",
0,0,
"джунгли",
0,
"Редактировать еще",
0,
"таблица рекордов",
"обучение",
0,
"подробнее",
"узнайте больше о {0}",
0,
"давайте изменим это",
"приступим!",
"давайте приступим!",
"библиотека",
"библиотеки",
"библиотека",
"имя библиотеки",
0,
"загрузить еще",
"загрузить больше ответов",
0,0,
"загрузка комментариев для {0}...",
0,0,
"загрузка скрипта",
0,
"загрузка...",
0,
"расположение",
"журнал",
"логическое отрицание",
"журналы",
0,
"сделать вызов асинхронного",
0,
"управление данными",
"возможно, позже",
"я",
"мяу",
0,
"пользователь minecraft",
0,
"луна",
"больше",
"вперед ",
"дополнительные параметры",
"переместить курсор",
"переместиться влево",
0,
"переместить курсор влево",
"переместить курсор вправо",
"мои медиа-объекты",
"моя группа",
"мои группы",
"мой скрипт",
"мои скрипты",
0,0,0,0,
"нужно удалить это",
"необходимо отредактировать в другом месте",
"отрицание",
0,0,0,0,
"новая строка",
0,0,
"новое свойство",
"новый stmt ниже",
"новая переменная",
"следующая страница",
"Следующий курс...",
"псевдоним",
"нет",
"Данный пользователь не публиковал картинки",
"нет комментариев, нажмите, чтобы их оставить!",
"Ветвления отсутствуют: чтобы создать ветвление, установите, отредактируйте и заново опубликуйте скрипт.",
"Сердец нет. Установите скрипт и добавьте их сами!",
"изображение еще не загружено",
"нет предыдущего адреса",
"пока скриншотов нет!",
"нет тегов, нажмите, чтобы их добавить!",
"в группе нет пользователей!",
"неатомарная",
"не сегодня",
"уведомления",
"сейчас",
"теперь вы можете выбрать свойство элемента {0}; сам по себе этот элемент ничего не делает",
"теперь вы можете выбрать свойство в этом",
0,
"ввод чисел",
"объекты",
"род занятий",
"объекта",
"автономный режим доступен",
"хорошо",
0,
"в сети",
"открыть",
"или нажмите, чтобы получить помощь",
"другие",
"обзор",
"перезаписать",
"страницы",
"имя параметра",
"анализ текста скрипта",
"пароль был сброшен",
"вставить",
"приостановить",
"разрешения",
0,
"выберите шаблон скрипта...",
"рисунок",
0,0,0,
"играть еще раз",
0,
"подождите...",
"подключаемые модули",
"предварительный просмотр",
"печать",
"политика конфиденциальности",
"частный",
0,
"Частный профиль",
"профиль",
"знания о программировании",
"прогресс",
0,0,
"общедоступный псевдоним",
"общедоступный профиль",
"опубликовать",
0,0,0,
"перетащить изменения",
"перенести на уровень блоков",
"тыква",
"повторный запуск",
"подробнее...",
"только чтение",
"настоящее имя",
"реальное имя (не отображается)",
"получение бюллетеней по электронной почте",
"получение уведомлений по электронной почте",
"имя записи:",
"повторное развертывание командной оболочки...",
"обычная дополнительная клавиатура",
0,
"удалить",
0,
"удалить рисунок",
0,
"удаление скрипта...",
"переименовать",
"повторить n раз",
"повторять на коллекции",
"повторять во время",
0,
"заменить все в скрипте",
"Заменить изображение",
0,0,
"ответить",
"сообщить о нарушении",
"продолжить",
"вернуться к опубликованной версии",
0,
"назад ",
"запустить",
"запустить главный блок",
"запустить тесты",
"запуск с инструментированием",
"сохранить",
0,
"Сохранение",
"школа",
"экраны",
"скриншоты",
"скриншот {0}",
"скрипт",
"свойства скрипта",
"скрипты",
"поиск",
"Поиск картинок",
"поиск в изображениях из числа медиа-объектов",
"искать {0} здесь",
"поиск шаблона",
"поиск...",
"посмотреть другие варианты",
"выбрать",
"выбрать дополнительные элементы",
"выберите эту строку",
0,
"выберите {0}",
"последовательный",
"установить имя локальной переменной",
"установить имя",
0,
"установите обработчик, который вызывается при касании доски",
0,0,0,0,
"параметры",
"поделиться",
"показать",
"показать, как нужно завершить это действие",
"показать дополнительные параметры",
"витрина",
0,
"войти как:",
"требуется вход",
"выход",
"выполняется вход...",
"выход",
"упростить",
"уровень навыков сохранён",
"пропустить итерацию",
"пропустить",
"социальные",
"извините",
"звук",
"url-адрес звука",
0,
"разделить",
"начать бета-тестирование",
"начать заново",
0,
"запуск...",
"статистика",
"шаг с заходом",
"шаг с выходом",
"шаг с обходом",
"компиляция продолжается, пожалуйста, подождите...",
"остановить",
"выйти из бета-тестирования",
"остановить функцию",
"остановить цикл",
"сохранить в переменной",
"сохранить значение в переменной",
"строка",
"строковый ресурс",
"полоса \"{0}\"",
"скопированное",
"подписчики",
"подписки",
"сверхъестественно, сногсшибательно, уникально, удивительно, умопомрачительно, уникально, фантастически, феноменально, чудесно, эксклюзивно",
"окружить",
"синхронизировать",
0,
"синхронизация...",
"таблица",
"содержание",
"таблицы",
"тег {0} не разршён",
"этот тег не разрешён",
"теги",
"сделать снимок",
"получатель",
"нажмите (←), когда закончите",
0,0,0,0,
"нажмите здесь",
"нажмите здесь, чтобы получить инструкции",
"нажмите здесь для запуска приложения",
"нажмите, чтобы изменить цвет",
0,
"нажмите, чтобы изменить изображение экрана заставки",
"нажмите, чтобы перевести Microsoft® Переводчиком...",
0,
"условия использования",
"тест",
"функция теста",
"тесты",
0,
"текущая функция",
"форум",
"главный экран",
0,
"скрипт сломался",
"командная оболочка и/или файловая система. Этот скрипт может нанести вред вашему компьютеру. Не разрешайте, если не доверяете источнику.",
"этот",
"этот скрипт является библиотекой",
0,
"время и даты",
"в код",
"чтобы продолжить",
"до глобальной переменной",
"переключить точку останова",
"наиболее популярные и новые",
"touch develop",
"touch develop в автономном режиме{0}",
"перевести",
"перевод урока...",
0,
"истина или ложь",
"истина?",
"попробуйте еще раз!",
"преобразовать в",
"Прохождение курса",
"учебник: ",
"учебники",
"дескриптор twitter",
"тип: ",
"введите: {0}",
"типы",
"раскомментировать",
"под капотом (dbg): ",
"отменить",
"отменить исправление",
"отобразить",
"единорог",
"Удалить",
"удалить скрипты",
"удаление...",
"неизвестный редактор",
0,
"снять выделение",
"отписаться",
"обновить",
"обновить их!",
"обновление библиотек",
"обновление метаданных",
"обновление изображения...",
"обновление скрипта",
"обновление скриптов",
"загрузить",
"загрузить картинку",
"загрузить снимок экрана",
"загрузить звук",
0,
"загрузка документов",
"загрузка изображений",
"url-адрес",
0,
"использовать компилятор C++",
"пользователи",
0,
"переменная",
"имя переменной",
"посмотреть как скрипт",
"просмотреть/изменить имя, электронную почту, ...",
0,
"обои",
"здесь есть библиотека \"{0}\"; {1}",
"здесь находится {0:a}; вы хотели что-то с ним сделать?",
0,0,
"нам нужна новая {0}",
"нужна другая дополнительная клавиатура",
0,
"нам необходимо отредактировать еще кое-что",
"мы будем сопровождать вас на всех этапах",
"веб-приложения",
"ключ веб-сайта",
"имя веб-сайта",
"адрес веб-сайта",
"веб-сайт",
"имя веб-сайта",
"URL-адрес веб-сайта",
"какой тип события добавить?",
"белый",
"усердно работает",
"пишет {0}",
"написал",
"год рождения",
"да",
"вы также можете искать",
"вам удалось это!",
"ваш лучший результат: {0}",
"{0} (линий: {1})",
"Дней назад: {0}",
"{0} вниз",
0,0,0,
"Часов назад: {0}",
"Минут назад: {0}",
"Месяцев назад: {0}",
0,0,0,
"Секунд назад: {0}",
"{0} вверх",
"Лет назад: {0}",
"{box:avatar:avatar}\n",
0,
"● Войти"
]); return true; }

if (lang == "sv") { TDev.Util._setLanguageArray(keys, [0,0,
" -- en lokal variabel",
0,0,0,0,0,0,0,0,0,0,0,0,
"JavaScript-klammerparenteser, alla verktygen, för erfarna utvecklare!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", men fick en {0:a}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>den här raden är perfekt!</b> vi fortsätter",
"<h3>laddar aktuella inställningar...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Ett unikt visningsnamn för din offentliga profil (minst 8 tecken)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Lägger till värde till aktuellt poängvärde.",
0,0,0,0,
"Alla mina skript",
0,0,0,0,0,0,0,
"En tom app använder sidor och rutor.",
"En tom app som använder scratch-biblioteket.",
0,0,0,0,0,0,0,0,
"En sköldpaddeapp.",
0,0,0,0,
"Den här användarens konst:",
0,0,
"Standardkod för att skapa ett spel",
0,0,0,0,0,0,
"Ändra kunskapsnivå!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Skapa kod",
0,
"Skapa skript",
0,0,0,
"Skapa en ny bildsprite.",
0,
"Skapa ett nytt skript",
0,0,0,0,0,
"Skapa kanal",
0,0,0,
"Skapa egna appar",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Överlappar spriterna",
"Vill du få informativa nyhetsbrev om TouchDevelop, t.ex. om nya funktioner och kommande evenemang?",
"Dokument",
"Glöm inte att trycka på ”spara” längst ned när du har redigerat klart!",
"Dra och släpp block, förenklat användargränssnitt, perfekt för nybörjare!",
0,0,
"Redigera kod som text, fler alternativ, för aspirerande apputvecklare!",
0,0,0,0,
"Ange information om dig själv",
"Ange adressen till din personliga webbplats (till exempel: http://www.northwindtraders.com)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Anger höjden i pixlar",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Anger y-positionen i pixlar",
"Komma igång",
0,
"Globala variabler från aktuellt liv",
0,0,0,0,0,0,
"Hur upptäckte du TouchDevelop?",
0,
"Importera kod",
"Importera ett skript från en fil",
0,0,0,0,0,0,0,0,0,0,0,0,
"Infoga '{0}' {1}",
0,
"Objekt markerade med * måste anges.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Får en sprite att studsa på skärmens kant",
0,0,
"Mig",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Läs igenom vårt sekretessmeddelande.",
0,0,0,0,0,0,0,0,0,
"Publicera ditt skript så att alla kan köra det.",
0,0,0,0,0,
"Ta emot e-postmeddelanden när andra granskar/tar en skärmdump av/kommenterar dina skript eller svarar på någon av dina kommenterar eller när någonting kopplat till din prenumeration inträffar.",
0,
"Tar bort värde från aktuellt liv.",
0,
"Rapportera/Ta bort",
0,0,0,0,0,0,0,
"Returnerar ett slumpmässigt inbyggt nummer mellan ”min” och ”max”.",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Den här användarens skript:",
0,0,
"Sök kod ...",
"Sök i allt",
"Sök här...",
0,0,
"Sök...",
0,0,0,
"Se mer",
0,0,0,0,0,0,0,0,
"Ställer in bakgrundsbilden",
0,
"Anger aktuella livpoäng.",
0,0,
"Anger positionen i pixlar",
0,0,0,0,0,0,0,
"Anger bredden i pixlar",
"Anger x-hastigheten i pixlar/sek",
"Anger y-accelerationen i pixlar/sek^2",
0,
"Anger y-hastigheten i pixlar/sek",
0,
"Inställningar",
0,0,0,0,
"Kunskapsnivå: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: ”if-villkor” vill ha ett {1:a} uttryck",
0,0,0,0,0,0,0,0,0,0,0,
"Lär ut kreativ kodning!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Översättning av Microsoft® Translator, tryck för att se originaltext ...",
0,0,0,0,
"Lektioner",
0,0,0,0,0,
"UI-widget",
0,0,0,0,0,0,0,0,0,
"Vi anpassar redigeraren efter din kunskapsnivå. Du kan ändra kunskapsnivå i hubben senare.",
"På vilken nivå ligger dina programmeringskunskaper?",
"Vad har du för sysselsättning?",
"Senaste nytt",
"Var i världen befinner du dig?",
0,0,0,0,0,
"Din GitHub-användare.",
"Din Minecraft-användare.",
0,0,
"Din kanal visas här",
"Din e-postadress har inte bekräftats än. Kontrollera din inbox.",
"Ditt fullständiga namn",
0,0,0,
"Ditt skript visas här",
"Ditt twitternamn, t.ex. @touchdevelop.",
"några sekunder sedan",
"en funktion",
"en global variabel",
"1 minut sedan",
0,0,0,0,
"om dig",
0,0,
"rapporter om missbruk",
0,0,0,0,0,
"lägg till",
0,0,0,0,0,0,0,0,0,0,
"lägg till rad under",
"lägg till ny",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"1 timme sedan",
0,0,0,0,0,0,0,
"konst",
0,
"uppgift",
0,0,0,0,0,0,
"backsteg",
"ta bort det här",
0,0,0,
"nybörjare",
"nybörjare",
0,0,0,
"tom app",
0,0,
"tomt spel",
0,0,0,
"tom scratch",
0,
"tom sköldpadda",
0,0,0,0,0,0,0,0,0,
"avbryt",
0,0,0,0,
"kanaler",
0,0,0,0,0,0,0,0,0,0,0,
"välj kunskapsnivå",
0,0,0,0,
"klona",
0,0,
"kod",
0,
"kodare",
0,0,0,0,0,
"villkor",
0,0,0,0,0,
"kopiera",
0,0,
"skapa",
0,0,0,0,0,0,
"skapar skript",
0,0,
"anpassa konsten!",
"klipp ut",
0,0,0,
"decimaltecken",
0,0,0,0,0,0,0,0,0,
"information",
0,0,0,0,0,0,
"stäng",
"visa värde",
0,0,0,0,0,0,
"redigera",
0,
"e-post",
"e-post (privat)",
"e-post och push-meddelanden",
"ej verifierad e-postadress, {0}",
0,0,0,0,0,0,0,0,0,
"till exempel: ",
0,
"utmärkt; bra jobbat; fantastiskt; coolt; du är grym; bra gjort; toppen; exakt så; precis",
0,0,
"expert",
0,0,0,0,0,0,0,0,0,0,
"klar",
0,
"följ lektionen i redigeraren",
0,0,
"funktion",
0,0,
"funktion, variabel, bibliotek...",
"kön",
"hämta mitt Hour of Code™-certifikat",
0,
"github-användare",
0,0,0,
"globala variabler",
0,
"tillbaka till kodning! {0}★ kvar",
0,0,0,
"gå tillbaka till föregående steg",
"mål:",
0,0,0,
"hjälp",
0,0,
"historik",
0,
"hur hittade",
0,
"jag är klar med min Hour of Code™",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"infoga kommentar",
"infoga påstående",
"infoga {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"lär",
0,0,0,0,
"det här ska vi ändra på",
"nu kör vi!",
"nu kör vi igång!",
0,
"bibliotek",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"plats",
0,
"logisk negation",
0,0,0,0,0,0,0,0,0,
"minecraft-användare",
0,0,
"mer",
"mer ",
"fler inställningar",
"flytta markör",
0,0,
"flytta markören åt vänster",
"flytta markören åt höger",
0,0,0,0,
"mina skript",
0,0,0,0,0,0,
"negation",
0,0,0,0,0,0,0,0,0,
"ny variabel",
0,
"nästa självstudie ...",
"användarnamn",
0,0,0,0,0,0,
"ingen tidigare e-postadress",
0,0,0,0,0,
"meddelanden",
0,0,0,0,0,0,
"sysselsättning",
0,0,0,0,0,0,0,0,
"översikt",
0,0,0,
"tolkar skripttext",
0,
"klistra in",
"pausa",
0,0,
"välj en skriptmall...",
"bild",
0,0,0,
"spela igen",
0,
"vänta ...",
0,0,0,0,
"privat",
0,
"privat profil",
0,
"programmeringskunskaper",
0,0,0,
"offentligt användarnamn",
"offentlig bild",
"publicera",
0,0,0,0,0,0,0,
"se mer ...",
0,
"riktigt namn",
"riktigt namn (privat)",
"ta emot nyhetsbrev via e-post",
"ta emot e-postmeddelanden",
0,0,0,0,
"ta bort",
0,
"ta bort bild",
0,0,0,
"upprepa n gånger",
0,
"upprepa medan",
0,0,0,0,0,0,0,0,0,
"spola tillbaka",
"spola tillbaka ",
"kör",
"kör huvudsaklig",
0,0,
"spara",
0,
"sparar...",
"skola",
0,0,0,
"skript",
"skriptegenskaper",
0,0,
"sök efter konst",
0,
"sök efter {0} här",
"sök mallar",
0,0,
"markera",
0,
"tryck på den linjen",
0,0,0,0,
"ange namn",
0,0,0,0,0,0,0,0,0,0,
"visa fler alternativ",
"showcase",
0,0,0,
"logga ut",
0,0,0,0,
"hoppa över upprepning",
0,0,0,0,0,0,
"dela",
0,0,0,0,0,0,0,0,0,0,0,
"stoppfunktion",
"stoppslinga",
0,
"lagra värdet i en variabel",
"sträng",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"tryck här",
0,
"tryck här för att köra din app",
0,0,0,0,0,
"användarvillkor",
0,0,0,0,0,0,
"hubben",
0,0,0,0,0,0,0,0,
"för att fortsätta",
"till global var",
0,0,0,0,0,0,0,0,0,
"försök igen!",
"gör till",
"lektionsförlopp",
"lektion: ",
"lektioner",
"twitternamn",
"skriv: ",
"skriv: {0}",
0,0,0,
"ångra",
0,0,0,
"avinstallera",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"visa/redigera namn, e-post, ...",
0,
"bakgrund",
0,
"här har vi en {0:a}, vill du göra något med den?",
0,0,0,0,0,0,
"vi kommer att guida dig steg för steg",
0,0,0,0,
"webbplats",
0,
"webbadress",
0,0,0,0,0,
"födelseår",
0,0,0,0,0,
"{0} dagar sedan",
0,0,0,0,0,
"{0} minuter sedan",
"{0} månader sedan",
0,0,0,
"{0} sekunder sedan",
0,
"{0} år sedan",
0,0,
"● Logga in"
]); return true; }

if (lang == "sv-SE") { TDev.Util._setLanguageArray(keys, [0,0,
" -- en lokal variabel",
0,0,0,0,0,0,0,0,0,0,0,0,
"JavaScript-klammerparenteser, alla verktygen, för erfarna utvecklare!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", men fick en {0:a}",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>den här raden är perfekt!</b> vi fortsätter",
"<h3>laddar aktuella inställningar...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Ett unikt visningsnamn för din offentliga profil (minst 8 tecken)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Lägger till värde till aktuellt poängvärde.",
0,0,0,0,
"Alla mina skript",
0,0,0,0,0,0,0,
"En tom app använder sidor och rutor.",
"En tom app som använder scratch-biblioteket.",
0,0,0,0,0,0,0,0,
"En sköldpaddeapp.",
0,0,0,0,
"Den här användarens konst:",
0,0,
"Standardkod för att skapa ett spel",
0,0,0,0,0,0,
"Ändra kunskapsnivå!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Skapa kod",
0,
"Skapa skript",
0,0,0,
"Skapa en ny bildsprite.",
0,
"Skapa ett nytt skript",
0,0,0,0,0,
"Skapa kanal",
0,0,0,
"Skapa egna appar",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Överlappar spriterna",
"Vill du få informativa nyhetsbrev om TouchDevelop, t.ex. om nya funktioner och kommande evenemang?",
"Dokument",
"Glöm inte att trycka på ”spara” längst ned när du har redigerat klart!",
"Dra och släpp block, förenklat användargränssnitt, perfekt för nybörjare!",
0,0,
"Redigera kod som text, fler alternativ, för aspirerande apputvecklare!",
0,0,0,0,
"Ange information om dig själv",
"Ange adressen till din personliga webbplats (till exempel: http://www.northwindtraders.com)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Anger höjden i pixlar",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Anger y-positionen i pixlar",
"Komma igång",
0,
"Globala variabler från aktuellt liv",
0,0,0,0,0,0,
"Hur upptäckte du TouchDevelop?",
0,
"Importera kod",
"Importera ett skript från en fil",
0,0,0,0,0,0,0,0,0,0,0,0,
"Infoga '{0}' {1}",
0,
"Objekt markerade med * måste anges.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Får en sprite att studsa på skärmens kant",
0,0,
"Mig",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Läs igenom vårt sekretessmeddelande.",
0,0,0,0,0,0,0,0,0,
"Publicera ditt skript så att alla kan köra det.",
0,0,0,0,0,
"Ta emot e-postmeddelanden när andra granskar/tar en skärmdump av/kommenterar dina skript eller svarar på någon av dina kommenterar eller när någonting kopplat till din prenumeration inträffar.",
0,
"Tar bort värde från aktuellt liv.",
0,
"Rapportera/Ta bort",
0,0,0,0,0,0,0,
"Returnerar ett slumpmässigt inbyggt nummer mellan ”min” och ”max”.",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Den här användarens skript:",
0,0,
"Sök kod ...",
"Sök i allt",
"Sök här...",
0,0,
"Sök...",
0,0,0,
"Se mer",
0,0,0,0,0,0,0,0,
"Ställer in bakgrundsbilden",
0,
"Anger aktuella livpoäng.",
0,0,
"Anger positionen i pixlar",
0,0,0,0,0,0,0,
"Anger bredden i pixlar",
"Anger x-hastigheten i pixlar/sek",
"Anger y-accelerationen i pixlar/sek^2",
0,
"Anger y-hastigheten i pixlar/sek",
0,
"Inställningar",
0,0,0,0,
"Kunskapsnivå: {0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: ”if-villkor” vill ha ett {1:a} uttryck",
0,0,0,0,0,0,0,0,0,0,0,
"Lär ut kreativ kodning!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Översättning av Microsoft® Translator, tryck för att se originaltext ...",
0,0,0,0,
"Lektioner",
0,0,0,0,0,
"UI-widget",
0,0,0,0,0,0,0,0,0,
"Vi anpassar redigeraren efter din kunskapsnivå. Du kan ändra kunskapsnivå i hubben senare.",
"På vilken nivå ligger dina programmeringskunskaper?",
"Vad har du för sysselsättning?",
"Senaste nytt",
"Var i världen befinner du dig?",
0,0,0,0,0,
"Din GitHub-användare.",
"Din Minecraft-användare.",
0,0,
"Din kanal visas här",
"Din e-postadress har inte bekräftats än. Kontrollera din inbox.",
"Ditt fullständiga namn",
0,0,0,
"Ditt skript visas här",
"Ditt twitternamn, t.ex. @touchdevelop.",
"några sekunder sedan",
"en funktion",
"en global variabel",
"1 minut sedan",
0,0,0,0,
"om dig",
0,0,
"rapporter om missbruk",
0,0,0,0,0,
"lägg till",
0,0,0,0,0,0,0,0,0,0,
"lägg till rad under",
"lägg till ny",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"1 timme sedan",
0,0,0,0,0,0,0,
"konst",
0,
"uppgift",
0,0,0,0,0,0,
"backsteg",
"ta bort det här",
0,0,0,
"nybörjare",
"nybörjare",
0,0,0,
"tom app",
0,0,
"tomt spel",
0,0,0,
"tom scratch",
0,
"tom sköldpadda",
0,0,0,0,0,0,0,0,0,
"avbryt",
0,0,0,0,
"kanaler",
0,0,0,0,0,0,0,0,0,0,0,
"välj kunskapsnivå",
0,0,0,0,
"klona",
0,0,
"kod",
0,
"kodare",
0,0,0,0,0,
"villkor",
0,0,0,0,0,
"kopiera",
0,0,
"skapa",
0,0,0,0,0,0,
"skapar skript",
0,0,
"anpassa konsten!",
"klipp ut",
0,0,0,
"decimaltecken",
0,0,0,0,0,0,0,0,0,
"information",
0,0,0,0,0,0,
"stäng",
"visa värde",
0,0,0,0,0,0,
"redigera",
0,
"e-post",
"e-post (privat)",
"e-post och push-meddelanden",
"ej verifierad e-postadress, {0}",
0,0,0,0,0,0,0,0,0,
"till exempel: ",
0,
"utmärkt; bra jobbat; fantastiskt; coolt; du är grym; bra gjort; toppen; exakt så; precis",
0,0,
"expert",
0,0,0,0,0,0,0,0,0,0,
"klar",
0,
"följ lektionen i redigeraren",
0,0,
"funktion",
0,0,
"funktion, variabel, bibliotek...",
"kön",
"hämta mitt Hour of Code™-certifikat",
0,
"github-användare",
0,0,0,
"globala variabler",
0,
"tillbaka till kodning! {0}★ kvar",
0,0,0,
"gå tillbaka till föregående steg",
"mål:",
0,0,0,
"hjälp",
0,0,
"historik",
0,
"hur hittade",
0,
"jag är klar med min Hour of Code™",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"infoga kommentar",
"infoga påstående",
"infoga {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"lär",
0,0,0,0,
"det här ska vi ändra på",
"nu kör vi!",
"nu kör vi igång!",
0,
"bibliotek",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"plats",
0,
"logisk negation",
0,0,0,0,0,0,0,0,0,
"minecraft-användare",
0,0,
"mer",
"mer ",
"fler inställningar",
"flytta markör",
0,0,
"flytta markören åt vänster",
"flytta markören åt höger",
0,0,0,0,
"mina skript",
0,0,0,0,0,0,
"negation",
0,0,0,0,0,0,0,0,0,
"ny variabel",
0,
"nästa självstudie ...",
"användarnamn",
0,0,0,0,0,0,
"ingen tidigare e-postadress",
0,0,0,0,0,
"meddelanden",
0,0,0,0,0,0,
"sysselsättning",
0,0,0,0,0,0,0,0,
"översikt",
0,0,0,
"tolkar skripttext",
0,
"klistra in",
"pausa",
0,0,
"välj en skriptmall...",
"bild",
0,0,0,
"spela igen",
0,
"vänta ...",
0,0,0,0,
"privat",
0,
"privat profil",
0,
"programmeringskunskaper",
0,0,0,
"offentligt användarnamn",
"offentlig bild",
"publicera",
0,0,0,0,0,0,0,
"se mer ...",
0,
"riktigt namn",
"riktigt namn (privat)",
"ta emot nyhetsbrev via e-post",
"ta emot e-postmeddelanden",
0,0,0,0,
"ta bort",
0,
"ta bort bild",
0,0,0,
"upprepa n gånger",
0,
"upprepa medan",
0,0,0,0,0,0,0,0,0,
"spola tillbaka",
"spola tillbaka ",
"kör",
"kör huvudsaklig",
0,0,
"spara",
0,
"sparar...",
"skola",
0,0,0,
"skript",
"skriptegenskaper",
0,0,
"sök efter konst",
0,
"sök efter {0} här",
"sök mallar",
0,0,
"markera",
0,
"tryck på den linjen",
0,0,0,0,
"ange namn",
0,0,0,0,0,0,0,0,0,0,
"visa fler alternativ",
"showcase",
0,0,0,
"logga ut",
0,0,0,0,
"hoppa över upprepning",
0,0,0,0,0,0,
"dela",
0,0,0,0,0,0,0,0,0,0,0,
"stoppfunktion",
"stoppslinga",
0,
"lagra värdet i en variabel",
"sträng",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"tryck här",
0,
"tryck här för att köra din app",
0,0,0,0,0,
"användarvillkor",
0,0,0,0,0,0,
"hubben",
0,0,0,0,0,0,0,0,
"för att fortsätta",
"till global var",
0,0,0,0,0,0,0,0,0,
"försök igen!",
"gör till",
"lektionsförlopp",
"lektion: ",
"lektioner",
"twitternamn",
"skriv: ",
"skriv: {0}",
0,0,0,
"ångra",
0,0,0,
"avinstallera",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"visa/redigera namn, e-post, ...",
0,
"bakgrund",
0,
"här har vi en {0:a}, vill du göra något med den?",
0,0,0,0,0,0,
"vi kommer att guida dig steg för steg",
0,0,0,0,
"webbplats",
0,
"webbadress",
0,0,0,0,0,
"födelseår",
0,0,0,0,0,
"{0} dagar sedan",
0,0,0,0,0,
"{0} minuter sedan",
"{0} månader sedan",
0,0,0,
"{0} sekunder sedan",
0,
"{0} år sedan",
0,0,
"● Logga in"
]); return true; }

if (lang == "th") { TDev.Util._setLanguageArray(keys, [0,0,
" -- ตัวแปรภายใน",
0,0,0,0,0,0,0,0,0,0,0,0,
"'วงเล็บปีกกาของ Javascripty' เครื่องมือทั้งหมด สำหรับนักพัฒนาผู้มีประสบการณ์",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"แต่ได้รับ {0:a} แทน",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>บรรทัดนี้สมบูรณ์แล้ว!</b> ไปต่อบรรทัดอื่นเลย",
"<h3>กำลังโหลดการตั้งค่าปัจจุบัน...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ชื่อที่แสดงที่ไม่ซ้ำกันสำหรับโพรไฟล์สาธารณะของคุณ (อย่างน้อย 8 อักขระ)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"เพิ่มค่าลงในคะแนนปัจจุบัน",
0,0,0,0,
"สคริปต์ของฉันทั้งหมด",
0,0,0,0,0,0,0,
"แอปว่างเปล่าที่ใช้หน้าและกล่อง",
"แอปว่างเปล่าที่ใช้ไลบรารี Scratch",
0,0,0,0,0,0,0,0,
"แอปเต่า",
0,0,0,0,
"งานศิลป์โดยผู้ใช้รายนี้:",
0,0,
"โค้ด Boilerplate ในการสร้างเกม",
0,0,0,0,0,0,
"เปลี่ยนระดับทักษะ!",
"ช่อง",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"สร้างโค้ด",
0,
"สร้างสคริปต์",
0,0,0,
"สร้างสไปรท์รูปภาพใหม่",
0,
"สร้างสคริปต์ใหม่",
0,0,0,0,0,
"สร้างช่อง",
0,0,0,
"สร้างแอปของคุณเอง",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ทำ Sprite ให้ทับซ้อนกัน",
"คุณต้องการรับจดหมายข่าวข้อมูลเกี่ยวกับ TouchDevelop เช่น เกี่ยวกับคุณลักษณะใหม่และกิจกรรมที่จะมีขึ้นหรือไม่",
"เอกสาร",
"อย่าลืมเลื่อนลงและแตะ \"บันทึก\" เมื่อคุณแก้ไขเสร็จแล้ว!",
"ลากและวางบล็อก อินเทอร์เฟซประยุกต์ ยอดเยี่ยมสำหรับผู้เริ่มต้น",
0,0,
"แก้ไขโค้ดในแบบข้อความ ตัวเลือกมากขึ้น สำหรับผู้เขียนแอปหัวก้าวหน้า!",
0,0,0,0,
"ใส่ข้อมูลบางอย่างเกี่ยวกับตัวคุณ",
"ใส่ URL ไปยังเว็บไซต์ส่วนตัวของคุณ (ตัวอย่างเช่น:\nhttp://www.northwindtraders.com)",
0,
"ใส่สังกัดของโรงเรียนคุณ (หากมี).",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"รับความกว้างเป็นพิกเซล",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"รับตำแหน่ง y เป็นพิกเซล",
"เริ่มต้นกันเลย",
0,
"ตัวแปรส่วนกลางในสคริปต์ปัจจุบัน",
0,
"ช่วยเหลือ",
0,0,0,0,
"คุณค้นพบ TouchDevelop ได้อย่างไร",
0,
"อิมพอร์ตโค้ด",
"อิมพอร์ตสคริปต์จากไฟล์",
0,0,0,0,0,0,0,0,0,0,0,0,
"แทรก '{0}' {1}",
0,
"รายการที่ทำเครื่องหมาย * เป็นรายการที่ต้องระบุ ",
0,0,0,0,0,0,0,0,0,0,0,0,
"ทำให้สไปรท์ทั้งหมดกระเด้งบนขอบของหน้าจอ",
0,0,
"ฉัน",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ตรวจสอบคำชี้แจงสิทธิส่วนบุคคลของเรา.",
0,0,0,0,0,0,0,0,0,
"เผยแพร่สคริปต์ของคุณเพื่อให้ทุกคนนำไปใช้งานได้",
0,0,0,0,0,
"รับการแจ้งเตือนทางอีเมลเมื่อมีคนอื่นมารีวิว/บันทึกภาพหน้าจอ/แสดงข้อคิดเห็นบนสคริปต์ของคุณ หรือตอบกลับข้อคิดเห็นใดข้อคิดเห็นหนึ่งของคุณ หรือเมื่อมีกิจกรรมที่เกี่ยวข้องกับการสมัครใช้งานของคุณ ",
0,
"นำค่าออกจากชีวิตปัจจุบัน",
0,
"รายงาน/ลบ",
0,0,0,0,0,0,0,
"แสดงจำนวนเต็มแบบสุ่มระหว่าง “min” และ “max” ที่รวมอยู่ด้วย",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"สคริปต์โดยผู้ใช้รายนี้:",
0,0,
"ค้นหาโค้ด…",
"ค้นหาทุกอย่าง",
"ค้นหาที่นี่…",
0,0,
"ค้นหา…",
0,0,0,
"ดูเพิ่มเติม",
0,0,0,0,0,0,0,0,
"กำหนดรูปภาพพื้นหลัง",
0,
"กำหนดจุดชีวิตปัจจุบัน",
0,0,
"กำหนดตำแหน่งในพิกเซล",
0,0,0,0,0,0,0,
"กำหนดความกว้างเป็นพิกเซล",
"กำหนดความเร็ว x เป็นพิกเซล/วินาที",
"กำหนด y ในความเร่งเป็นพิกเซล/วินาที^2",
0,
"กำหนดความเร็ว y เป็นพิกเซล/วินาที",
0,0,0,0,0,0,
"ระดับทักษะ:{0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: เงื่อนไข \"ถ้า\" ต้องการ {1:a}",
0,0,0,0,0,0,0,0,0,0,0,
"สอน Creative Coding!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"แปลโดยนักแปลของ Microsoft® แตะเพื่อดูต้นฉบับ...",
0,0,0,0,
"บทช่วยสอน",
0,0,0,0,0,
"วิดเจ็ต UI",
0,0,0,0,0,0,0,0,0,
"เราจะปรับตัวแก้ไขในการเขียนโค้ดของคุณเพื่อเปลี่ยนระดับทักษะในฮับหลังจากนั้น",
"ระดับความรู้ในการเขียนโปรแกรมของคุณอยู่ในระดับใด?",
"คุณประกอบอาชีพใด",
"มีอะไรใหม่",
"คุณอยู่ที่ใด",
0,0,0,0,0,
"ผู้ใช้ GitHub ของคุณ.",
"ผู้ใช้ Minecraft ของคุณ",
0,0,
"ช่องของคุณจะปรากฏที่นี่",
"ที่อยู่อีเมลยังไม่ได้รับการยืนยัน โปรดตรวจสอบกล่องขาเข้าของคุณ.",
"ชื่อเต็มของคุณ",
0,0,0,
"สคริปต์ของคุณจะปรากฏที่นี่",
"ตัวจัดการ Twitter ของคุณ เช่น @touchdevelop.",
"สองสามวินาทีที่ผ่านมา",
"ฟังก์ชัน",
"ตัวแปรส่วนกลาง",
"1 นาทีที่ผ่านมา",
0,0,0,0,
"เกี่ยวกับคุณ",
0,0,
"การแจ้งการใช้งานในทางที่ผิด",
0,0,0,0,0,
"เพิ่ม",
0,0,0,0,0,0,0,0,0,0,
"เพิ่มบรรทัดด้านล่าง",
"เพิ่มใหม่",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"1 ชั่วโมงที่ผ่านมา",
0,0,0,0,0,0,0,
"งานศิลป์",
0,
"การกำหนด",
0,0,0,0,0,0,
"แป้นถอยหลัง",
"Backspace สิ่งนี้",
0,0,0,
"ผู้เริ่มต้น",
"ผู้เริ่มต้น",
0,0,0,
"แอปเปล่า",
0,0,
"เกมว่าง",
0,0,0,
"Scratch เปล่า",
0,
"เต่าเปล่า",
0,0,0,0,0,0,0,0,0,
"ยกเลิก",
0,0,0,0,
"ช่อง",
0,0,0,0,0,0,0,0,0,0,0,
"เลือกระดับทักษะการเขียนโค้ดของคุณ",
0,0,0,0,
"ลอกแบบ",
0,0,
"โค้ด",
0,
"ตัวเข้ารหัส",
0,0,0,0,0,
"เป็นเงื่อนไข  ",
0,0,0,0,0,
"คัดลอก ",
0,0,
"สร้าง",
0,
"สร้างช่อง",
0,0,0,0,
"กำลังสร้างสคริปต์ ",
0,0,
"กำหนดงานศิลป์เอง",
"ตัด",
0,0,0,
"จุดทศนิยม",
0,0,0,0,0,0,0,0,0,
"รายละเอียด",
0,0,0,0,0,0,
"ยกเลิก ",
"แสดงค่า",
0,0,0,0,0,0,
"แก้ไข",
0,
"อีเมล",
"อีเมล (ส่วนตัว)",
"อีเมลและการแจ้งเตือนแบบพุช",
"อีเมลไม่ได้รับการยืนยัน {0}",
0,0,0,0,0,0,0,0,0,
"ตัวอย่าง: ",
0,
"ยอดเยี่ยม; ดีมาก; สุดยอด; เลิศมาก; คุณเจ๋ง; ทำได้ดี; เลิศมาก; คุณทำได้; เป๊ะเลย",
0,0,
"ผู้เชี่ยวชาญ",
0,0,0,0,0,0,0,0,0,0,
"เสร็จสิ้น",
0,
"ทำตามบทช่วยสอนในตัวแก้ไข",
0,0,
"ฟังก์ชัน",
0,0,
"ฟังก์ชัน ตัวแปร ไลบรารี…",
"เพศ",
"รับประกาศนียบัตร Hour of Code™ ของฉัน",
0,
"ผู้ใช้ GitHub",
0,0,0,
"ตัวแปรส่วนกลาง",
0,
"กลับไปที่การเขียนโค้ด {0}★ เพื่อไป",
0,0,0,
"ไปที่ขั้นตอนก่อนหน้านี้",
"เป้าหมาย:",
0,0,0,
"ช่วยเหลือ",
0,0,
"ประวัติ",
0,
"พบได้อย่างไร",
0,
"ฉันเข้ารับการแนะแนว Hour of Code™ เสร็จสิ้นแล้ว",
0,0,0,0,0,
"อิมพอร์ตโค้ด",
0,0,0,0,0,0,0,0,0,
"แทรกเอกสาร",
"แทรกคำสั่ง",
"แทรก {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"เรียนรู้",
0,0,0,0,
"ลองเปลี่ยนสิ่งนี้กัน",
"เริ่มกันเถอะ!",
"มาเริ่มกันเถอะ!",
0,
"ไลบรารี",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ที่ตั้ง",
0,
"ค่าลบตรรกะ",
0,0,0,0,0,0,0,0,0,
"ผู้ใช้ Minecraft ",
0,0,
"เพิ่มเติม",
"มากกว่า ",
"การตั้งค่าเพิ่มเติม",
"ย้ายเคอร์เซอร์ ",
0,0,
"เลื่อนเคอร์เซอร์ไปทางซ้าย",
"เลื่อนเคอร์เซอร์ไปทางขวา",
0,0,0,0,
"สคริปต์ของฉัน",
0,0,0,0,0,0,
"ค่าลบ",
0,0,0,0,0,0,0,0,0,
"ตัวแปรใหม่",
0,
"บทช่วยสอนถัดไป...",
"ชื่อเล่น",
0,0,0,0,0,0,
"ไม่มีอีเมลก่อนหน้านี้",
0,0,0,0,0,
"การแจ้งเตือน",
0,0,0,0,0,0,
"อาชีพ",
0,0,0,0,0,0,0,0,
"ภาพรวม",
0,0,0,
"กำลังแยกวิเคราะห์ข้อความสคริปต์",
0,
"วาง",
"หยุดชั่วคราว",
0,0,
"เลือกเทมเพลตสคริปต์...",
"รูปภาพ",
0,0,0,
"เล่นอีกครั้ง",
0,
"โปรดรอ...",
0,0,0,0,
"ส่วนตัว",
0,
"โพรไฟล์ส่วนตัว",
0,
"ความรู้ในการเขียนโปรแกรม",
0,0,0,
"ชื่อเล่นสาธารณะ ",
"โพรไฟล์สาธารณะ",
"เผยแพร่",
0,0,0,0,0,0,0,
"อ่านเพิ่มเติม…",
0,
"ชื่อจริง",
"ชื่อเต็ม (ส่วนตัว)",
"รับจดหมายข่าวทางอีเมล",
"รับการแจ้งเตือนทางอีเมล",
0,0,0,0,
"นำออก",
0,
"นำรูปภาพออก",
0,0,0,
"ทำซ้ำ n ครั้ง",
0,
"ทำซ้ำขณะ",
0,0,0,0,0,0,0,0,0,
"กรอกลับ",
"กรอกลับ ",
"เรียกใช้",
"เรียกใช้ส่วนหลัก",
0,0,
"บันทึก",
0,
"กำลังบันทึก…",
"โรงเรียน",
0,0,0,
"สคริปต์",
"คุณสมบัติของสคริปต์",
0,0,
"ค้นหางานศิลป์",
0,
"ค้นหา {0} ที่นี่",
"ค้นหาเทมเพลต",
0,0,
"เลือก",
0,
"เลือกบรรทัดนั้น",
0,0,0,0,
"กำหนดชื่อ",
0,0,0,0,0,0,
"การตั้งค่า",
0,0,0,
"แสดงตัวเลือกเพิ่มเติม",
"ผลงาน",
0,0,0,
"ลงชื่อออกจากระบบ",
"กำลังลงชื่อเข้าใช้…",
0,0,0,
"ข้ามการทำซ้ำ",
0,0,0,0,0,0,
"แยก",
0,0,0,0,0,0,0,0,0,0,0,
"หยุดการทำงาน",
"หยุดลูป",
0,
"เก็บค่าในตัวแปร",
"สตริง",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"แตะตรงนั้น",
0,
"แตะที่นั่นเพื่อเรียกใช้แอปของคุณ",
0,0,0,0,0,
"ข้อกำหนดการใช้งาน",
0,0,0,0,0,0,
"ฮับ",
0,0,0,0,0,0,0,0,
"ทำต่อ",
"ไปยังตัวแปรส่วนกลาง",
0,0,0,0,0,0,0,0,0,
"ลองอีกครั้ง!",
"เปลี่ยนเป็น",
"ความคืบหน้าในบทช่วยสอน",
"บทช่วยสอน: ",
"บทช่วยสอน",
"Twitter Handle",
"ประเภท: ",
"ประเภท: {0}",
0,0,0,
"ยกเลิก",
0,0,0,
"ถอนการติดตั้ง",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ดู/แก้ไขชื่อ, อีเมล, …",
0,
"รูปพื้นหลัง",
0,
"เรามี {0:a} ที่นี่ คุณต้องการใช้สไปรท์ทำอะไรไหม",
0,0,0,0,0,0,
"เราจะแนะนำคุณทีละขั้นตอน",
0,0,0,0,
"เว็บไซต์",
0,
"URL เว็บไซต์",
0,0,0,0,0,
"ปีเกิด",
0,0,0,0,0,
"{0} วันที่ผ่านมา",
0,0,0,0,0,
"{0} นาทีที่ผ่านมา",
"{0} เดือนที่ผ่านมา",
0,0,0,
"{0} วินาทีที่ผ่านมา",
0,
"{0} ปีที่ผ่านมา",
0,0,
"●ลงชื่อเข้าใช้"
]); return true; }

if (lang == "tr") { TDev.Util._setLanguageArray(keys, [
"   Belki: {0} ('{1}',{2}) ",
"  Satır {2} ('{1}'), hata->: {0}{3}",
" bir yerel değişken",
" [class]",
" [hidden]",
" [override]",
" arkaya",
" ileri",
" saat ",
" dakika ",
" in ",
" saniye ",
" değişiklikler gönderiliyor",
" sunucunun yanıt vermesi bekleniyor",
"### tam kaynak kodu",
"Tecrübeli geliştiriciler için Javascript’in küme parantezi ve tüm araçları!",
"'atomic' fonksiyon",
"'box' sadece sayfanın görüntü kodundan erişilebilir",
"'box' a HTML düzenleme modunda erişilemez",
0,
"'html' ye sadece HTML düzenleme modunda erişilebilir",
"'{0}' burada {1} bekleniyor",
"'{0}' desteklenmeyen bir imza içeriyor",
"'{0}' şimdilik eklenmedi",
"'{0}' eski ve eklenmedi",
"'{0}' kullanımdan kalkmıştır ve kullanılmamalıdır",
0,
"'{0}' bir '{1}'; {2}ye dönüşür",
0,0,0,0,0,0,0,0,
", bunun yerine {0} var",
", {0} var",
", boyut: {0} karakter",
". Lütfen okuyun ",
"... burada bakacak bir şey yok ...",
"... dahası da var ...",
"// yorum",
0,
"1. 1 MB tan daha az bir MP3 sesi seçin",
"2. En az 4 karakterli bir isim belirleyin",
"3. açıkla",
"4. yayımla",
":( Üzgünüz, bu metin çevrilirken bir hata oluştu.",
":( Üzgünüz, bu metni çevirmek olanaksız.",
":( Herhangi bir video kaynağı bulunamadı",
":( Video bilgileri geçersiz",
";  → ◈ref eksik mi?",
0,0,0,0,
"<b>bu satır mükemmel!</b> devam edelim",
"<h3>mevcut ayarlar yükleniyor...</h3>",
0,0,0,0,0,0,0,0,0,0,0,
"Bir Bing haritası",
0,0,
"Minecraft Creeper uygulaması.",
0,0,0,
"Arka plan sahne katmanı",
0,0,0,0,0,0,
"Sabit bir renk",
0,0,0,0,0,0,0,0,0,
"Genel bir değişken",
0,0,0,0,0,0,0,0,0,0,0,0,
"Sabit bir sayı",
0,0,0,
"Bir resim",
0,0,0,0,0,
"Bir kütüphane komut dosyasına referans",
0,0,0,0,0,0,0,0,
"Bir şarkı",
"Bir ses",
"Ses efekti",
0,0,0,0,
"Bir kullanıcı tanımlı satırlar tablosu",
0,0,0,0,0,
"Herkese açık profiliniz için daha önce hiç kullanılmayan bir ad (en az 8 karakterden oluşan)",
0,0,
"Bir kullanıcı arayüzü",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Her bir ekran çerçevesi için etkinleşen bir eylem ekleyin",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Sayılar ekler",
0,
"Mevcut puana değer ekler.",
0,0,
"Komut dosyası durduktan sonra, toplanan bilgileri görmek için koda göz atın.",
0,
"Tüm komut dosyalarım",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Kullanıcı tanımlı satırların bir dizinli tablosu",
0,0,
"Giriş koleksiyonunun tüm öğelerinde `dönüştürücü` uygular ve sonuçların koleksiyonunu getirir",
0,0,0,
"Bu kullanıcı tarafından yapılan görsel:",
0,0,
"Oyun oluşturmak için kod şablonu.",
0,0,0,0,0,0,
"Beceri düzeyini değiştir!",
0,0,0,0,0,0,0,0,0,0,
"Kullanıcı etkileşimi gerçekleştiğinde kod çalışır",
"Belirli bir görevi yerine getiren kod",
"Eşitlik için sayıları karşılaştırır",
"Daha azı için sayıları karşılaştırır",
0,
"Daha fazlası için sayıları karşılaştırır",
0,0,0,0,0,0,0,
"Metnin iki parçasını birleştirir",
0,0,0,0,0,0,
"Yerel saate dönüştürür",
0,0,0,0,
"Kod Oluştur",
"Grup Oluştur",
"Komut Dosyası Oluştur",
0,0,0,
"Yeni bir hareketli resim oluştur.",
0,
"Yeni bir komut dosyası oluşturun",
0,0,0,0,0,
"Kanal oluşturun",
0,0,0,
"Kendi uygulamalarınızı oluşturun",
0,0,0,0,0,0,0,0,0,0,0,
"Geçerli cihaz",
0,0,
"İşleyiciyi etkinlikten ayırır.",
0,
"Görüntüyü duvara getirir; daha sonra değişikliklerin yansıtılmasını isterseniz 'duvarda güncelle' öğesini seçmelisiniz.",
0,0,0,0,0,
"Hareketli görüntüleri üst üste bindir",
"Yeni özellikler ve gelecek etkinlikler vb. konularda TouchDevelop ile ilgili bilgilendirme amaçlı bültenleri almak istiyor musunuz?",
"Belgeler",
"Düzenleme işlemini bitirdikten sonra aşağıya inip “kaydet” öğesine tıklamayı unutmayın!",
"Acemiler için mükemmel sürükle ve bırak bloklar, kolaylaştırılmış arayüz!",
"İki nokta arasında bir çizgi çizer",
"Belirlenmiş bir renk ve yazı tipi boyutu ile metin çizer",
"Can atan uygulama yazıcıları için kodu metin olarak ve daha değişik seçeneklerde düzenleme!",
0,0,0,0,
"Kendiniz hakkında bir şeyler yazın",
"Kişisel web sitenizin URL’ini girin (Örnek: http://www.northwindtraders.com)",
0,
"Varsa okulla olan ilişiğinizi girin.",
0,0,0,0,0,
"Facebook",
"Elipsi belirlenmiş bir renk ile doldurur",
"Dikdörtgeni belirlenmiş renk ile doldurur",
0,
"Yayınlanan komut dosyaları için, anonim olarak toplanan kitle kaynaklı profil ve kapsam verilerini bulmak için yayınlanan komut dosyası sayfasının sekmesine de bakın.",
"Forumlar",
0,0,0,0,0,0,0,0,0,0,0,0,
"Şarkının DRM korumalı olup olmadığına göre bir değer alır",
0,0,0,0,
"Pikseldeki merkez yatay pozisyonunu alır",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Pikseldeki yüksekliği alır",
"Kamera görüntüsünün yüksekliğini piksel olarak alır.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Sesler için ses yüksekliğini 0 (sessiz) ile 1 (geçerli ses) arasında alır",
0,0,0,0,0,
"Pikseldeki genişliği alır",
"Kamera görüntüsünün genişliğini piksel olarak alır.",
"Pikseldeki y konumunu alır",
"Başlarken",
0,
"Mevcut komut dosyasındaki genel değişkenler",
0,
"Yardım",
0,0,0,0,
"TouchDevelop’u nasıl keşfettiniz?",
0,
"Kodu İçe Aktar",
"Komut dosyasını bir dosyadan içe aktarın",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"* ile işaretlenen yerlerin doldurulması gerekmektedir.",
0,
"Gruba Katıl",
0,0,0,0,0,0,0,0,0,0,
"Tüm hareketli simgelerin, ekranın kenarına çarpıp geri dönmelerini sağlar",
0,0,
"Ben",
0,0,0,0,0,
"Sayıları çarpar",
0,0,0,0,0,0,0,0,
"Yeni Komut Dosyaları",
0,
"Yeni veya mevcut renkler",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Lütfen Gizlilik Bildirimimizi inceleyin.",
0,0,0,0,0,0,0,0,0,0,
"Yayınlama kullanım koşullarımıza ",
0,0,0,
"Yanıt gövdesini bir ses dalgası olarak okur",
"Diğer kişiler tarafından komut dosyanız incelendiğinde/komut dosyanızın ekran görüntüsü alındığında/hakkında yorum yapıldığında veya yorumlarınızdan birisine cevap verildiğinde ya da üyeliğinizle ilgili bir durum olduğunda e-posta bildirimleri alın.",
0,
"Değeri geçerli candan kaldırır.",
"Yanıtla...",
"Bildir/Sil",
"Belirlenmiş piksel boyutuna resmi yeniden boyutlandırır",
0,
"Görüntünün bir kopyasını getirir",
0,0,
"Bu örneğin değerine göre belirtilen ayların sayısını ekleyen bir tarihe döner.",
"Bu örneğin değerine göre belirtilen yılların sayısını ekleyen bir tarihe döner.",
"Mevcut \"min.\" ve \"maks.\" değerler arasında rastgele bir tamsayıyı seçer.",
0,0,0,0,0,0,0,
"Geçerli örnek işe yaramaz ise doğru döner",
0,0,0,0,
"Komut Dosyası Güncellemeleri",
"Bu kullanıcı tarafından oluşturulan komut dosyaları",
0,0,
"Kod ara...",
"Her şeyi ara",
"Burada ara...",
0,0,
"Ara...",
0,0,0,
"Daha Fazla Bilgi Edinin",
0,0,0,
"Duvara uygulanan afin matris dönüşümünü 3x3 olarak ayarlar.",
0,0,0,0,
"Arka plan resmini ayarla",
"Pikseldeki merkez yatay pozisyonunu belirler",
"Geçerli can puanlarını ayarlar.",
0,
"Pikseldeki yüksekliği belirler",
"Pikseldeki konumu belirler",
0,
"Sesler için ses yüksekliği seviyesini 0 (sessiz) ile 1 (geçerli ses) arasında ayarlar",
0,0,0,0,0,
"Pikseldeki genişliği belirler",
"Pikselde/saniyede x hızını belirler",
"Pikselde/saniyede^2 y hızlanmasını belirler",
"Pikseldeki y konumunu belirler",
"Pikselde/saniyede y hızını belirler",
0,
"Ayarlar",
0,
"Komut dosyası, bu platformlar üzerinde çalışmasını önleyen API'ler kullanıyorsa, hataları düzenleyicide göster.",
0,0,
"Beceri düzeyi: {0}     ",
0,0,0,0,0,0,0,
"Sayıları çıkarır",
0,
"TD100: buraya {0} ekle",
"TD101: '{0}' bulunamadı",
"TD109: buna atanamıyor",
"TD111: {0} kaynağından {1} hedefine atanamıyor",
"TD112: '{0}' özelliğini {1} öğesinde bulamadım",
"TD115: {0} öğesine sağlanan aşırı parametre(ler)",
"TD116: {0} öğesine sağlanan yeterli parametre yok",
"TD118: 'eğer' koşulu {1} istiyor",
0,0,
"TD130: isteklere 'bağlı' {1}",
"TD144: görünüşe göre '{0}' öğesini atladınız, eklemeyi deneyin",
"TD145: görünüşe göre burada bir işleç ('+', '(' veya ',' gibi) eksik",
"TD147: '{0}' öğesini burada beklemiyorduk",
0,
"TD151: kapatılmamış ' ('",
"TD152: beklenmeyen ')'",
"TD154: ardından işlece bir şey gerekir",
0,
"Yaratıcı Kodlama Dersi Verin!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Bu komut dosyası aşağıdaki özellikleri kullanır: ",
0,0,
"Sayfa verileri eklemek için, yerel bir değişken oluşturun ve 'alana yükselt' seçeneğine dokunun.",
0,0,0,0,
"Microsoft ® çevirmen tarafından çeviriler dokunun orijinal görmek için...",
0,0,0,0,
"Öğreticiler",
"Twitter",
0,
"Aramak için yazın...",
0,0,
"UI widget",
0,0,
"Hareketli resimdeki resmi günceller (hareketli resim ise)",
0,
"Resim Yükle",
"Ses Yükle",
"Kullanıcılar",
0,0,
"Düzenleyiciyi kodlama beceri düzeyinize göre uyarlayacağız. Daha sonra hub’dan beceri düzeyinizi değiştirebilirsiniz.",
"Programlama bilgisi düzeyiniz nedir?",
"Mesleğiniz nedir?",
"Yenilikler",
"Dünyanın hangi ülkesindesiniz?",
"Belirlenmiş bir konumda başka bir resim yazar. Opaklık aralığı 0 (saydam) ile 1 (opak) arasında değişir.",
0,
"YouTube",
0,0,
"GitHub kullanıcınız.",
"Minecraft kullanıcınız.",
"Görseliniz burada görüntülenecek",
0,
"Kanalınız burada görüntülenecek",
"E-posta adresiniz henüz onaylanmadı. Lütfen gelen kutunuzu kontrol edin.",
"Tam adınız",
0,0,0,
"Komut dosyanız burada görüntülenecek",
"Twitter tanıtıcınız, @touchdevelop gibi.",
"birkaç saniye önce",
"bir işlev",
"genel bir değişken",
"bir dakika önce",
"bir sayfa",
"kapsam hakkında",
"öngörüler hakkında",
"profil hakkında",
"hakkınızda",
0,0,
"uygunsuz kullanım raporları",
0,0,0,0,0,
"ekle",
0,0,0,0,0,0,0,0,
"giriş parametresi ekle",
0,
"aşağıya satır ekle",
"yeni ekle",
0,0,
"çıkış parametresi ekle",
0,0,0,0,0,0,0,
"inanılmaz, şaşırtıcı, hayret verici, büyüleyici, müthiş, nefes kesici, klasik, havalı, ilginç, farklı, özel, seçkin, sıra dışı, mükemmel, etkileyici, olağanüstü, harika, ",
0,0,
"bir saat önce",
0,0,0,0,0,0,0,
"görsel",
"görsel kaynağı",
"görevlendirme",
0,
"yazar",
0,0,
"geri",
0,
"sil",
"bunu sil",
0,0,
"taban",
"acemi",
0,0,0,0,0,0,0,
"boş oyun",
0,0,0,0,0,0,0,
"hata ayıklamayı ara ver",
"kesme noktası",
0,0,0,0,0,0,
"iptal",
0,0,
"yerele (geri) değiştir",
0,
"kanallar",
0,0,0,0,0,0,0,0,0,0,0,
"kod bilgisi beceri düzeyinizi girin",
0,0,
"temizle",
0,
"kopyala",
0,
"bulut oturumları",
"kod",
0,
"kodlayıcı",
"renk #{0}",
0,0,
"yorumlar",
0,
"koşullu",
0,0,0,
"devam",
0,
"kopyala",
0,
"kapsam",
"oluştur",
"yeni bir parametre oluştur",
"kanal oluşturun",
0,0,0,0,
"betik oluşturma",
0,
"varsayılan ifade",
"görselleri özelleştirin!",
"kes",
0,0,
"hata ayıkla",
"ondalık nokta",
0,
"sil",
"yerel verileri ve izinleri sil",
0,
"değişkene indirge",
0,
"açıklama",
0,0,
"ayrıntılar",
0,0,0,0,0,0,
"reddet",
"değeri göster",
0,0,0,0,0,
"bitti!",
"düzenle",
"veya",
"e-posta",
"e-posta (gizli)",
"e-posta ve anında iletme bildirimleri",
"e-posta adresi doğrulanmadı, {0}",
0,0,0,0,0,0,0,
"etkinlikler",
0,
"örn: ",
0,
"mükemmel; harika iş; müthiş; havalı; süpersin; aferin; olağanüstü; başardın; tam isabet",
0,
"çıkış",
"uzman",
0,0,0,0,
"uzat",
0,0,0,
"değişkene çıkar",
"referans bul",
"bitti",
"düzelt",
"düzenleyicide öğreticiyi takip edin",
0,
"çatallar",
"fonksiyon",
0,0,
"fonksiyon, değişken, kütüphane,...",
"cinsiyet",
"Kodlama Saati™ sertifikamı al",
0,
"github kullanıcısı",
0,
"genel değiştirme",
"genel değişken",
"genel değişkenler",
0,
"kodlama için geri dönün! Gitmek için {0} ★",
0,
"git",
"komut listesi gidin",
"bir önceki adıma gidin",
"hedef:",
0,
"gruplar",
"kalpler",
"yardım",
0,
"gizle",
"geçmiş",
0,
"nasıl bulunduğu",
"çalıştırmak istiyorum",
"Kodlama Saati™ ile işim bitti",
0,0,0,0,0,0,0,0,0,0,0,0,
"akıl almaz, sihirli, nefis, harikulade, akıllara durgunluk veren, parmak ısırtan, mucizevi, acayip, fevkalade, radikal, göz kamaştırıcı, ayrıcalıklı, dikkat çekici, çok şaşırtıcı, çarpıcı, enfes, ",
0,0,
"yorum ekle",
"ifade ekle",
"{0} ekle",
"öngörüler",
0,0,
"yerele",
0,
"sorunlar",
0,0,0,0,
"düzenlemeye devam et",
0,0,
"öğren",
0,
"daha fazla bilgi edinin",
0,0,0,
"haydi yapalım!",
"haydi başlayalım!",
"kitaplık",
"kitaplıklar",
"kitaplık",
0,0,
"daha fazla yükle",
0,0,0,0,0,0,0,0,
"yükleniyor...",
0,
"konum",
0,
"mantıksal olumsuzlama",
"günlükler",
0,0,0,
"verileri yönet",
"belki daha sonra",
0,0,0,
"minecraft kullanıcısı",
0,0,
"daha fazla",
"daha fazla ",
"daha fazla ayar",
"imleci taşı",
"sola taşı",
0,
"imleci sola taşı",
"imleci sağa taşı",
"görsellerim",
0,0,0,
"komut dosyalarım",
0,0,0,0,
"bunun silinmesi gerekiyor",
"başka bir yerde düzenlemek gerekiyor",
"olumsuzlama",
0,0,0,0,
"yeni satır",
0,0,0,
"aşağıda yeni stmt",
"yeni değişken",
0,
"sonraki öğreticiler...",
"takma ad",
0,
"bu kullanıcı tarafından yayımlanan görsel yok",
"yorum yok, yazmak için dokunun!",
"çatal yok; oluşturmak için betiği yükleyin, düzenleyin ve yeniden yayımlayın!",
"kalp yok. betiği yükledikten sonra bir adet ekleyebilirsiniz!",
"henüz hiçbir resim yüklenmedi",
"önceden kayıtlı e-posta adresi yok",
0,
"yorum yok, eklemek için dokunun!",
0,0,0,
"bildirimler",
0,
"şimdi {0} öğesinin bir özelliğini seçebilirsiniz; kendisi tek başına bir şey yapmaz",
"şimdi bir özelliğini seçebilirsiniz",
0,
"sayı girişi",
0,
"meslek",
0,
"çevrimdışı kullanılabilir",
0,0,
"çevrimiçi",
0,0,0,
"genel bakış",
0,
"sayfalar",
0,
"komut dosyası metni çözümleniyor",
0,
"yapıştır",
"duraklat",
0,0,0,
"resim",
0,0,0,
"yeniden oyna",
0,
"lütfen bekleyin...",
"eklentiler",
"önizleme",
"yazdır",
0,
"özel",
0,
"özel profil",
"profil",
"programlama bilgisi",
0,0,0,
"herkesin görebildiği takma ad",
"herkesin görebildiği profil",
"yayınla",
0,0,0,
"değişiklikleri çek",
"seviyeyi engellemek için çek",
0,
"yeniden çalıştır",
"daha fazla...",
"salt okunur",
"gerçek ad",
"gerçek ad (gizli)",
"e-posta bültenleri al",
"e-posta bildirimleri alın",
"kayıt adı:",
0,
"normal tuş takımı",
0,
"kaldır",
0,
"resmi kaldır",
0,0,
"yeniden adlandır",
"n kez tekrar et",
"koleksiyon üzerinde tekrarla",
"tekrarlama aralığı",
0,
"komut dosyasında tümünü değiştir",
"resmi değiştir",
0,0,0,
"uygunsuz kullanımı bildir",
"özgeçmiş",
"yayınlanmış sürüme geri dön",
0,
"geri sar ",
"çalıştır",
"ana çalıştırmak",
0,
"araç ile çalıştır",
"kaydet",
0,
"kaydediliyor...",
"okul",
"ekranlar",
"ekran görüntüleri",
0,
"komut dosyası",
"komut dosyası özellikleri",
0,0,
"görselleri ara",
"sanat resimlerini ara",
"{0} öğesini burada ara",
0,
"aranıyor...",
0,
"seç",
"daha fazla seç",
"bu satırı seçin",
0,0,0,
"yerel değişken adını ayarla",
"ad belirle",
0,
"panoya dokunulduğunda çağrılan işleyiciyi ayarlayın",
0,0,0,0,
"ayarlar",
"paylaş",
0,
"bu aktivitenin nasıl tamamlandığını göster",
0,
"vitrin",
0,0,0,
"oturumu kapat",
"oturum açılıyor...",
0,
"basitleştir",
0,
"yinelemeyi atla",
0,
"sosyal",
0,
"ses",
0,0,
"böl",
0,
"baştan başla",
0,
"başlıyor...",
0,
"içeri gir",
"dışarı çık",
"adımlama",
0,
"dur",
0,
"işlevi durdur",
"döngüyü durdur",
"değişkene depola",
"değeri bir değişkende depola",
"dizi",
0,
"'{0}' şeridi",
0,0,0,
"üstün, doğaüstü, korkunç, inanılmaz, esrarengiz, benzersiz, eşi görülmemiş, tuhaf, garip, mükemmel, şahane",
0,0,0,0,0,0,0,0,0,
"etiketler",
0,0,0,0,0,0,0,
"buraya dokunun",
"yönergeler için buraya dokunun",
"uygulamanızı çalıştırmak için buraya dokunun",
"rengi değiştirmek için dokunun",
0,0,
"microsoft ® çevirmen ile çevirmek için dokunun...",
0,
"hakkındaki bilgilerimizi okuyun",
"dene",
0,
"denemeler",
0,0,0,
"merkez",
0,0,0,0,
"bu komut dosyası bir kütüphanedir",
0,0,
"koduna",
"devam et",
"genel değişkene",
"kesim noktasını değiştir",
"popüler ve yeni",
0,0,
"çevir",
0,0,0,0,
"yeniden dene!",
"dönüştür",
"öğretici ilerleme durumu",
"öğreticiler: ",
"öğreticiler",
"twitter tanıtıcısı",
"tür: ",
"tür: {0}",
0,0,0,
"geri al",
0,0,0,
"kaldır",
0,0,0,0,0,0,
"güncelle",
0,0,0,0,0,0,
"yükle",
0,
"ekran görüntüsü yükle",
0,0,0,0,
"url",
0,0,0,0,0,0,
"komut dosyası olarak görüntüle",
"adı, e-postayı görüntüle/düzenle",
0,
"duvar kağıdı",
"burada bir kütüphanemiz '{0}' var; {1}",
"burada bir {0:a} var; bununla bir şey mi yapmak istemiştiniz?",
0,0,0,
"farklı bir tuş takımına ihtiyacımız var",
0,
"başka bir şeyi düzenlememiz gerekiyor",
"size adım adım rehberlik edeceğiz",
0,0,0,0,
"web sitesi",
0,
"web sitesinin url’i",
0,0,0,0,0,
"doğum tarihi",
0,0,
"başardınız!",
0,
"{0} ({1} çizgi{1:s})",
"{0} gün{0:s} önce",
0,0,0,0,
"{0} saat{0:s} önce",
"{0} dakika{0:s} önce",
"{0} ay{0:s} önce",
0,0,0,
"{0} saniye{0:s} önce",
0,
"{0} yıl{0:s} önce",
0,0,
"● Oturum aç"
]); return true; }

if (lang == "uk") { TDev.Util._setLanguageArray(keys, [0,0,0,0,
" [прихований]",
0,0,0,0,0,
" з ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
", замість цього отримано {0}",
", отримано {0}",
0,0,0,0,
"// коментар",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<strong>функція перебуває в бета-тестуванні:</strong> синтаксис та семантика може змінюватися",
0,0,0,0,
"Карта Bing",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Документ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Пісня",
"Звук",
0,0,0,0,0,0,0,0,0,
"Текстове поле",
"Таймер",
0,0,0,0,0,0,
"ADJ скрипт",
"Конфігурація API",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Після зупинки скрипта перегляньте код, щоб бачити зібрану інформацію.",
"Всі мої групи",
"Всі мої сценарії",
0,0,0,0,0,
"Всі мої скрипти",
0,0,0,0,0,0,0,0,0,0,0,0,
"Застосовує перетворювач до всіх елементів вхідний колекції і повертає колекцію результатів",
0,0,0,0,
"Прочитайте або покажіть значення на стіні...",
0,0,0,
"Перетягуючи та розташовуючи блоки, ви створили наступний код.",
"Камера",
0,
"Не бачите вікон? Спробуйте торкнутися кнопки нижче, щоб увійти в систему вручну.",
0,0,0,0,0,0,0,0,0,0,
"Дані в Хмарі",
0,0,0,0,0,0,0,0,
"Компас",
0,
"Обчислює максимум ключа елементів у колекції",
0,0,0,
"З'єднує дві частини тексту",
"Перетворення кольору в HTML синтаксис (#FF002A або rgba(255, 0, 42, 0.5) коли A не-1)",
0,0,0,0,0,0,
"Скопіювати поточний JSON-об'єкт в Json Builder для подальших змін",
0,0,0,0,
"Створити групу",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Створення власних додатків",
"Створює колір із червоного, зеленого та синього каналів (діапазон 0.0-1.0)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Експерт",
0,
"Розширення",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Отримує колір, що має ARGB значення #00FFFFFF",
"Отримує колір, що має ARGB значення #FF000000",
"Отримує колір, що має ARGB значення #FF0000FF",
"Отримує колір, що має ARGB значення #FF008000",
"Отримує колір, що має ARGB значення #FF00FFFF",
"Отримує колір, що має ARGB значення #FF704214",
"Отримує колір, що має ARGB значення #FF800080",
"Отримує колір, що має ARGB значення #FF808080",
"Отримує колір, що має ARGB значення #FFA52A2A",
"Отримує колір, що має ARGB значення #FFA9A9A9",
"Отримує колір, що має ARGB значення #FFD3D3D3",
"Отримує колір, що має ARGB значення #FFFF0000",
"Отримує колір, що має ARGB значення #FFFF00FF",
"Отримує колір, що має ARGB значення #FFFFA500",
"Отримує колір, що має ARGB значення #FFFFCBDB",
"Отримує колір, що має ARGB значення #FFFFFF00",
"Отримує колір, що має ARGB значення #FFFFFFFF",
"Отримує стан поточного підключення (`підключення`, `відкрито`, `закрито`)",
"Отримує поточне місцерозташування телефону з найбільшою точністю. Включає використання послуг, що можуть спричинити використання додаткових коштів або споживання більшого заряду батареї чи збільшити використання мобільних даних.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"GitHub",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Мікрофон",
0,0,0,0,0,0,
"Мої групи",
"Мій профіль",
"Мої скрипти",
0,0,0,
"Мережа",
0,0,0,0,0,
"На пристрої '{0}', застосовуються наступні інструкції.",
0,0,0,0,0,0,0,
"На жаль, не вдалося отримати скрипти для цієї групи. Будь ласка, спробуйте пізніше.",
0,0,
"Партнери",
0,0,0,0,0,0,0,
"Підключіться до інтернету для перегляду списку лідерів.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Повертає гіперболічний косинус зазначеного кута (в радіанах)",
0,
"Повертає синус зазначеного кута (в радіанах)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Пошук...",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Twitter",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Що нового",
0,0,0,
"YouTube",
0,0,0,0,0,
"Ваш браузер не підтримує Touch Develop для зберігання даних. Зазвичай це трапляється коли ви перебуваєте в режимі конфіденційності (Safari), режимі InPrivate (Internet Explorer) або ваші налаштування безпеки запобігають зберіганню даних. Увійдіть у звичайний режим або змініть налаштування браузера, щоб не втратити результати своєї роботи. Усі зміни не збережені в хмарі будуть втрачені після виходу з цієї сторінки.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"про вас",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"backspace",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"буфер обміну",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"історія",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"через хвилину",
"через годину",
0,0,0,0,0,0,0,0,
"встановити {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"детальніше",
0,0,0,0,0,0,
"бібліотеки",
"бібліотека",
0,0,0,0,
"завантаження",
0,0,0,0,0,0,
"завантаження...",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"права доступу",
0,0,
"картинка",
0,0,0,0,0,0,
"плагіни",
"попередній перегляд",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"лише для читання",
"справжнє ім'я",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"збереження...",
0,0,
"скріншот",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"увійти",
0,0,0,0,
"вихід",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"синхронізація...",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"торкніться тут",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"форуми",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"переклад",
0,0,
"спробуйте ще раз!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"змінна",
0,0,0,0,
"шпалери",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"вебсайт"
]); return true; }

if (lang == "vi") { TDev.Util._setLanguageArray(keys, [0,0,
" -- một biến cục bộ",
0,0,0,0,0,0,0,0,0,0,0,0,
"Dấu ngoặc nhọn Javascript, tất cả công cụ, cho lập trình viên có kinh nghiệm!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"nhận hình {0:a} thay thế",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"<b>dòng này tốt rồi!</b> tiếp thôi nào",
"<h3>đang tải thiết lập hiện tại...</h3>",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Một tên hiển thị duy nhất cho hồ sơ công khai của bạn (ít nhất 8 kí tự)",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Thêm giá trị cho điểm số hiện tại.",
0,0,0,0,
"Tất cả tập lệnh của tôi",
0,0,0,0,0,0,0,
"Một ứng dụng trống sử dụng các trang và hộp.",
"Một ứng dụng trống sử dụng thư viện scratch.",
0,0,0,0,0,0,0,0,
"Một ứng dụng rùa.",
0,0,0,0,
"Hình ảnh nghệ thuật tạo bởi người dùng này:",
0,0,
"Mã boiler plate để tạo trò chơi.",
0,0,0,0,0,0,
"Thay đổi cấp độ kỹ năng!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Tạo Mã",
0,
"Tạo Tập lệnh",
0,0,0,
"Tạo sprite hình ảnh mới.",
0,
"Tạo tập lệnh mới",
0,0,0,0,0,
"Tạo kênh",
0,0,0,
"Tạo ứng dụng riêng của bạn",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Các hình sprit có chồng lắp không",
"Bạn có muốn nhận bản tin với các thông tin về TouchDevelop, ví dụ như các tính năng mới và các sự kiện sắp diễn ra hay không?",
"Tài liệu",
"Đừng quên cuộn xuống và bấm \"save\" khi bạn đã sửa xong!",
"Kéo và thả các khối, giao diện giản lược, thích hợp cho người mới bắt đầu!",
0,0,
"Chỉnh sửa mã ở dạng văn bản, thêm tùy chọn, cho những nhà phát triển ứng dụng đầy khao khát!",
0,0,0,0,
"Nhập vài thông tin về bản thân bạn",
"Nhập địa chỉ URL đến trang web cá nhân của bạn (Ví dụ:\nhttp://www.northwindtraders.com)",
0,
"Nhập trường học liên kết của bạn, nếu có.",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Thiết lập chiều cao theo pixel",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Thiết lập vị trí y theo pixel",
"Đang bắt đầu",
0,
"Biến toàn cục trong kịch bản hiện tại",
0,
"Trợ giúp",
0,0,0,0,
"Bạn biết đến TouchDevelop như thế nào?",
0,
"Nhập Mã",
"Nhập một tập lệnh từ một tập tin",
0,0,0,0,0,0,0,0,0,0,0,0,
"Chèn '{0}' {1}",
0,
"Các mục có dấu * là bắt buộc.",
0,0,0,0,0,0,0,0,0,0,0,0,
"Làm cho tất cả sprite văng ra khi chạm viền màn hình",
0,0,
"Tôi",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Vui lòng xem xét Tuyên bố Bảo mật của chúng tôi.",
0,0,0,0,0,0,0,0,0,
"Xuất bản tập lệnh của bạn để mọi người có thể sử dụng.",
0,0,0,0,0,
"Nhận thông báo email khi người khác xem lại/chụp ảnh màn hình/bình luận về tập lệnh của bạn, hoặc trả lời một trong các bình luận của bạn, hoặc khi xảy ra các sự kiện liên quan đến tài khoản của bạn.",
0,
"Loại bỏ các giá trị từ mạng hiện tại.",
0,
"Báo cáo/Xóa",
0,0,0,0,0,0,0,
"Trả về một số nguyên ngẫu nhiên giữa \"min\" và \"max\" đã được bao gồm.",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"Các tập lệnh tạo bởi người dùng này:",
0,0,
"Tìm kiếm mã...",
"Tìm kiếm mọi thứ",
"Tìm kiếm ở đây...",
0,0,
"Tìm kiếm...",
0,0,0,
"Xem Thêm",
0,0,0,0,0,0,0,0,
"Thiết lập hình nền",
0,
"Thiết lập số mạng hiện tại.",
0,0,
"Thiết lập vị trí theo pixel",
0,0,0,0,0,0,0,
"Thiết lập chiều rộng theo pixel",
"Thiết lập tốc độ x theo pixel/giây",
"Thiết lập gia tốc y theo pixel/giây^2",
0,
"Thiết lập tốc độ y theo pixel/giây",
0,
"Thiết lập",
0,0,0,0,
"Cấp kĩ năng:{0}     ",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"TD118: điều kiện ‘if’muốn có {1:a}",
0,0,0,0,0,0,0,0,0,0,0,
"Dạy Lập Trình Sáng Tạo!",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"Bản dịch của Microsoft® Translator, nhấn để xem bản gốc...",
0,0,0,0,
"Hướng dẫn",
0,0,0,0,0,
"Tiện ích UI",
0,0,0,0,0,0,0,0,0,
"Chúng tôi sẽ điều chỉnh trình biên tập theo cấp độ kỹ năng lập trình của bạn. Bạn có thể thay đổi cấp độ kỹ năng sau tại trung tâm.",
"Trình độ kiến thức lập trình của bạn ở mức nào?",
"Nghề nghiệp của bạn là gì?",
"Có gì mới",
"Bạn đang ở đâu trên thế giới?",
0,0,0,0,0,
"Người dùng GitHub của bạn.",
"Người dùng Minecraft của bạn.",
0,0,
"Kênh của bạn sẽ xuất hiện ở đây",
"Địa chỉ email chưa được xác nhận. Vui lòng kiểm tra hộp thư.",
"Tên đầy đủ của bạn",
0,0,0,
"Tập lệnh của bạn sẽ xuất hiện ở đây",
"Khóa twitter của bạn, như @touchdevelop.",
"cách đây vài giây",
"một hàm",
"một biến toàn cục",
"cách đây một phút",
0,0,0,0,
"về bạn",
0,0,
"báo cáo lạm dụng",
0,0,0,0,0,
"thêm",
0,0,0,0,0,0,0,0,0,0,
"thêm dòng bên dưới",
"thêm mới",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"cách đây một giờ",
0,0,0,0,0,0,0,
"hình ảnh nghệ thuật",
0,
"gán",
0,0,0,0,0,0,
"phím lùi",
"xóa lùi mục này",
0,0,0,
"nhập môn",
"người mới bắt đầu",
0,0,0,
"ứng dụng trống",
0,0,
"trò chơi trống",
0,0,0,
"Scratch trống",
0,
"rùa trống",
0,0,0,0,0,0,0,0,0,
"hủy bỏ",
0,0,0,0,
"kênh",
0,0,0,0,0,0,0,0,0,0,0,
"chọn cấp độ kỹ năng lập trình của bạn",
0,0,0,0,
"nhân bản",
0,0,
"mã",
0,
"lập trình viên",
0,0,0,0,0,
"điều kiện",
0,0,0,0,0,
"sao chép",
0,0,
"tạo",
0,
"tạo kênh",
0,0,0,0,
"đang tạo tập lệnh",
0,0,
"tùy chỉnh hình ảnh nghệ thuật!",
"cắt",
0,0,0,
"chấm thập phân",
0,0,0,0,0,0,0,0,0,
"chi tiết",
0,0,0,0,0,0,
"hủy bỏ",
"hiển thị giá trị",
0,0,0,0,0,0,
"sửa",
0,
"email",
"email (riêng tư)",
"email và thông báo đẩy",
"email chưa được xác nhận, {0}",
0,0,0,0,0,0,0,0,0,
"ví dụ: ",
0,
"xuất sắc; làm tốt lắm; tuyệt vời; hay lắm; bạn tuyệt lắm; giỏi lắm; quá giỏi; bạn hiểu ý tôi rồi đấy; bạn đã hoàn thành xong; được",
0,0,
"chuyên gia",
0,0,0,0,0,0,0,0,0,0,
"hoàn tất",
0,
"làm theo hướng dẫn trong trình biên tập",
0,0,
"chức năng",
0,0,
"chức năng, biến, thư viện, ...",
"giới tính",
"nhận chứng chỉ Hour of Code™ của tôi",
0,
"người dùng github",
0,0,0,
"biến toàn cục",
0,
"quay lại lập trình tiếp! còn {0}★",
0,0,0,
"đi đến bước trước đó",
"mục tiêu:",
0,0,0,
"trợ giúp",
0,0,
"lịch sử",
0,
"biết đến như thế nào",
0,
"tôi đã hoàn tất khóa Hour of Code™ của tôi",
0,0,0,0,0,
"nhập mã",
0,0,0,0,0,0,0,0,0,
"chèn bình luận",
"chèn lệnh",
"chèn {0}",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"học",
0,0,0,0,
"hãy thay đổi mục này",
"bắt đầu nào!",
"hãy bắt đầu thôi!",
0,
"thư viện",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"địa điểm",
0,
"phủ định tính logic",
0,0,0,0,0,0,0,0,0,
"người dùng minecraft",
0,0,
"thêm",
"thêm ",
"thêm thiết lập",
"di chuyển con trỏ",
0,0,
"di chuyển con trỏ sang trái",
"di chuyển con trỏ sang phải",
0,0,0,0,
"tập lệnh của tôi",
0,0,0,0,0,0,
"phủ định",
0,0,0,0,0,0,0,0,0,
"biến mới",
0,
"bài hướng dẫn kế tiếp...",
"biệt danh",
0,0,0,0,0,0,
"không có email trước đây",
0,0,0,0,0,
"thông báo",
0,0,0,0,0,0,
"nghề nghiệp",
0,0,0,0,0,0,0,0,
"tổng quan",
0,0,0,
"phân tích cú pháp văn bản tập lệnh",
0,
"dán",
"tạm dừng",
0,0,
"chọn một mẫu kịch bản...",
"hình ảnh",
0,0,0,
"chơi lại",
0,
"vui lòng chờ...",
0,0,0,0,
"riêng tư",
0,
"hồ sơ riêng tư",
0,
"kiến thức lập trình",
0,0,0,
"biệt danh công khai",
"hồ sơ công khai",
"xuất bản",
0,0,0,0,0,0,0,
"đọc thêm...",
0,
"tên thật",
"tên thật (riêng tư)",
"nhận bản tin email",
"nhận thông báo email",
0,0,0,0,
"xóa",
0,
"xóa ảnh",
0,0,0,
"lặp lại n lần",
0,
"lặp lại khi",
0,0,0,0,0,0,0,0,0,
"tua lại",
"tua lại ",
"chạy",
"run main",
0,0,
"lưu",
0,
"đang lưu...",
"trường",
0,0,0,
"tập lệnh",
"thuộc tính tập lệnh",
0,0,
"tìm kiếm hình ảnh nghệ thuật",
0,
"tìm {0} ở đây",
"tìm kiếm các mẫu",
0,0,
"chọn",
0,
"chọn dòng đó",
0,0,0,0,
"thiết lập tên",
0,0,0,0,0,0,0,0,0,0,
"hiển thị thêm tùy chọn",
"trưng bày",
0,0,0,
"đăng xuất",
0,0,0,0,
"bỏ qua lặp lại",
0,0,0,0,0,0,
"tách",
0,0,0,0,0,0,0,0,0,0,0,
"ngừng chức năng",
"ngừng vòng lặp",
0,
"lưu giá trị trong một biến",
"chuỗi",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"bấm vào đây",
0,
"bấm vào đây để chạy ứng dụng của bạn",
0,0,0,0,0,
"điều khoản sử dụng",
0,0,0,0,0,0,
"trung tâm",
0,0,0,0,0,0,0,0,
"để tiếp tục",
"đến biến toàn cục",
0,0,0,0,0,0,0,0,0,
"thử lại!",
"chuyển thành",
"tiến trình hướng dẫn",
"hướng dẫn: ",
"hướng dẫn",
"khóa twitter",
"loại: ",
"loại: {0}",
0,0,0,
"hoàn tác",
0,0,0,
"gỡ cài đặt",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"xem/sửa tên, email, ...",
0,
"hình nền",
0,
"chúng ta có một hình {0:a} ở đây; bạn có muốn làm gì với nó không?",
0,0,0,0,0,0,
"chúng tôi sẽ hướng dẫn bạn từng bước",
0,0,0,0,
"trang web",
0,
"địa chỉ url trang web",
0,0,0,0,0,
"năm sinh",
0,0,0,0,0,
"{0} ngày trước",
0,0,0,0,0,
"{0} phút trước",
"Cách đây {0} tháng",
0,0,0,
"{0} giây trước",
0,
"Cách đây {0} năm",
0,0,
"● Đăng nhập"
]); return true; }

if (lang == "zh") { TDev.Util._setLanguageArray(keys, [
"   Maybe: {0} ({1} at '{2}')\n",
"  -> Line {2} ('{1}'), error: {0}\n{3}",
" — — 局部变量",
" [class]",
" [隐藏]",
" [override]",
" 返回",
" 前进",
" 小时 ",
" 分钟 ",
" 的 ",
" 秒 ",
" 发送更改",
" 等待服务器",
"# # # 完整源代码",
"Javascripty 花括号，以及所有工具，适合于有经验的开发人员!",
"“atomic”函数",
"'盒子' 只能在页面显示代码中访问",
"'盒子' 无法访问在 HTML 布局模式中",
"'else' 的前面的 'if' 必须是空的",
"'html' 只能访问 HTML 布局模式",
"“{0}”认为此处应为 {1}",
"'{0}' 包含不支持的签名",
"'{0}' 当前未执行",
"'{0}' 已过期且不能实现",
"“{0}”已弃用，不应使用。",
"'{0}' 不是一个字符串资源",
"“{0}”返回“{1}”；{2}",
"'{0}' 返回 {1} 的值; 你可以使用 '储存在var' 按钮来将它们保存到本地",
"(可选) 与信息有关的错误，用来提供有关错误的额外信息的客户端开发者确定人类可读的 web 页的 URI。",
"(可选) 人类可读的错误代码。",
"(可选)未涵盖的 OAuth 2.0 规范的附加键值对。",
"(可选) 指示是否令牌可能在下一秒内已过期。",
"(可选)可选，如果相同范围由客户端请求;否则，访问令牌的范围如 OAuth 2.0 规范第 3.3 节所述。",
"(可选) 以秒为单位的访问令牌生存期。",
"(请等一等，它会占用至多一分钟)",
"，而获得了 {0:a}",
"，获得了 {0}",
"大小: {0} 字符",
". 请阅读我们 ",
"...... 这儿没什么可看...",
"... 有更多...",
"// 注释",
"1.选择一个文档 (.txt、.pptx，.pdf、.css，小于 8 Mb)",
"1. 选择 MP3 声音 (小于 1 MB)",
"2. 给它一个名称 (最低 4 个字符)",
"3. 描述它",
"4. 发布",
":(抱歉，这个文本翻译时出错。",
":(对不起，我们不能翻译此。",
":(找不到任何视频源",
":(无效的视频信息",
"; 是否缺少 → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'> Apache Cordova</a> 让您构建跨平台的移动应用程序。",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> 生成的证书</a>.",
"<b>免责声明:</b>这个 web 应用程序不是由微软认可的。",
"<b>如何本地运行本程序</b>",
"<b>此行正确无误！</b>我们继续吧",
"<h3>正在加载当前设置...</h3>",
"<h3>没有更多的提示!</h3>",
"<h3>欢迎来到Touch Develop</h3>",
"<h3>{0:q} 需要签到</h3>",
"<p>如果你没有Azure订阅，去 <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> Azure订阅</a> 获取.</p>",
"<p>Touch Develop使您可以 <b>轻松地创建应用程序</b> 来自您的手机、 平板电脑或 PC。</p>",
"<p>你可以与他人分享您的应用程序，因此他们可以 <b>运行和编辑</b> 他们在 Windows Phone、 iPad、 iPhone、 Android、 PC 或 mac上。</p>",
"<strong>beta 测试中的新功能:</strong> 的语法和语义的更改",
"<strong>所需的平台:</strong>",
"超出范围，@hi/lo",
"数字 2D 矩阵",
"一个三维向量",
"Bing 地图",
"Minecraft Pi 应用。",
"Minecraft 应用。",
"Minecraft 爬虫应用。",
"服务器发送事件的客户端",
"对sprite属性进行动画处理的动画",
"Argb 颜色 (alpha、 红色、 绿色、 蓝色)",
"背景场景图层",
"一个初学者友好编辑器",
"打造2D 游戏的开发板",
"创建 HTML 表单数据的生成器",
"云计算数据会议",
"对象集",
"Sprites集",
"颜色常量",
"日期和时间的组合",
"添加了有关您拉请求的注释。",
"联系人",
"自定义记录器",
"文档",
"文档资源",
0,0,0,
"全局变量",
0,0,0,0,0,0,0,0,0,0,0,
"数値 (負 / 小数の場合もある)",
"数字常量",
0,0,0,
"图片",
"一段文本",
"像素画应用。",
0,0,0,
"对库脚本的引用",
0,0,0,0,0,0,0,0,0,
"声效",
0,0,0,0,
"用户数据结构",
"包含用户定义行的表",
0,0,0,0,0,
"您公开信息的唯一显示名称（至少 8 个字符）",
0,0,
"用户界面",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"添加对每一显示帧触发的动作",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"增加数字",
0,
"给当前分数添加值。",
0,0,
"在脚本停止后，浏览代码以查看收集到的信息。",
"我的所有组",
"我的所有脚本",
0,0,0,0,0,0,0,
"使用页面和方框的空白应用。",
"使用图片素材库的空白应用。",
"空白文档页。",
"空白交互式教程。",
"空白脚本编辑器插件。",
"不执行任何操作的空白脚本。",
0,0,
"包含用户定义行的索引表",
0,
"乌龟应用。",
"对输入集合的所有元素应用“转换器”并返回结果集",
0,
"你确定你想停止下面的教程吗？",
0,
"由此用户绘制：",
0,
"向其他对象附加数据",
"用于创建游戏的样板文件代码。",
0,0,0,
"相机、 位置、 麦克风和其他传感器",
0,0,
"更改技能等级！",
0,
"检查该板是否和另一板的距离相同。",
0,0,0,
"清除与此板有关的所有排队事件",
"清除背景图片",
"清除背景相机",
0,0,
"用户交流时分享的代码",
"执行特定任务的代码",
"比较数字是否相等",
"比较数字以确定更小值",
0,
"比较数字以确定更大值",
0,0,0,0,0,0,0,
"连接两段文本",
0,0,0,0,0,0,
"转换为本地时间",
0,0,0,0,0,
"创建组",
"创建脚本",
"用给定的起点、宽度和高度创建一个线障碍。粘性的弹性为 0，1 为完全反弹。",
"新建画面集合。",
"新建椭圆画面。",
"新建图片画面。",
"创建一个新的长方形精灵。",
0,
"创建新的精灵表单。",
"创建新的文本画面。",
"在两个精灵之间创建一个跳板。",
"创建一个锚精灵。",
"创建此对象类型的无效值",
"创建通道",
0,
"创建无效的值",
"在给定的距离处创建板的四周。",
"创建自己的应用",
0,0,
"创建新的空白游戏板并使之在屏幕上显示。",
0,0,0,
"用给定图片创建宽度为 100 的新精灵。",
0,
"创建无效的游戏手柄实例",
0,0,
"当前设备",
0,
"当前触点",
"从事件中分离处理程序。",
0,
"将图像显示到展示墙上；稍后如果您希望所做更改生效，则需要调用“展示墙更新”。",
0,0,0,
"显示墙上游戏手柄的状态",
0,
"子画面是否重叠",
0,
"文档",
"完成编辑后，不要忘记向下滚动，然后点击“保存”！",
"拖放功能块，界面简单，适合于初学者！",
"在两点之间画一条线",
"用给定颜色和字号绘制一些文本边框",
"将代码编辑为文本，以及其他更多选项，适合于应用程序编写爱好者！",
0,0,
"输入名称",
0,
"请输入有关您的个人信息",
"请输入您个人网站的 URL（例如：http://www.northwindtraders.com）",
"输入邀请码",
0,
"事件不能有输出参数。",
"每个人将能够用于在 Internet 上看到你的图片。 ",
0,0,
"扩展",
"Facebook",
"用给定颜色填充椭圆",
"用给定颜色填充矩形",
"接触结束后的最终接触速度",
"对于已发布的脚本，还可查看已发布脚本页上的选项卡，查找匿名收集的众多个人资料和覆盖率数据。",
"论坛",
"从现在开始，我们不会向您显示要编写的代码。按照指示进行操作，如果您认为已完成，请单击运行。",
"当前脚本中的函数",
0,0,0,0,0,
"获取游戏手柄的状态快照（如果连接到浏览器）。如果不支持或未连接游戏手柄则为空。",
0,0,0,
"获取值，该值表示该板是否被设计为在景观模式中查看",
"获取歌曲是否受 DRM 保护的信息",
"获得所选定轴线的 x 和 y 值。",
0,0,
"获取背景场景",
"获取水平居中位置(单位: 像素)",
0,
"获取 ARGB 值为 #00FFFFFF 的颜色",
"获取 ARGB 值为 #FF000000 的颜色",
"获取 ARGB 值为 #FF0000FF 的颜色",
"获取 ARGB 值为 #FF008000 的颜色",
"获取 ARGB 值为 #FF00FFFF 的颜色",
0,
"获取 ARGB 值为 #FF800080 的颜色",
0,0,0,0,
"获取 ARGB 值为 #FFFF0000 的颜色",
"获取 ARGB 值为 #FFFF00FF 的颜色",
"获取 ARGB 值为 #FFFFA500 的颜色",
0,
"获取 ARGB 值为 #FFFFFF00 的颜色",
"获取 ARGB 值为 #FFFFFFFF 的颜色",
0,0,0,0,
"获得可用的第一个连接的游戏手柄",
0,
"获得游戏手柄标识符",
0,
"获取高度(单位: 像素)",
"获取相机图像的高度(单位: 像素)。",
0,0,0,0,0,0,0,0,0,
"获得玩家索引",
"获得按钮的按下值。如果按钮缺失则返回 0。",
0,
"获取从 0 (静音)到 1 (当前音量)的音量",
"获得精灵数目",
"获取由 i 索引的精灵",
0,
"获得这次快照的时间戳",
0,
"获取宽度(单位: 像素)",
"获取相机图像的宽度(单位: 像素)。",
"获取 y 轴位置(单位: 像素)",
"快速入门",
0,
"当前脚本中的全局变量",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"在调试模式，游戏板显示精灵的速度和其他信息",
"表示按钮是否被按下。如果按钮缺失则返回 false。",
0,
"表示游戏手柄数据是否相同",
"表示游戏手柄是否仍被连接。",
0,0,0,0,
"插入“{0}”{1}",
0,
"标记 * 的项为必填项。",
"JSON 数据",
"加入组",
"最后接触终点",
"最后接触起点",
0,0,0,0,0,
"使更新可见。",
0,0,
"确保所有画面都在屏幕的边界上弹起",
0,
"数学擅长程度，绝对值，最大值",
"Me",
0,
"Minecraft 用户",
"更多",
0,
"将画面向其他画面移动。",
"乘以数字",
0,0,0,0,0,0,0,0,
"新脚本",
0,
"新颜色或内置颜色",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"电话号码、 振动、 等...",
0,
"选取随机颜色",
"图片和音乐......",
0,0,0,0,0,
"请查看我们的隐私声明。",
0,
"发表评论...",
0,0,0,
"隐藏动作不会得到运行按钮。 ",
"提示用户输入一个数字",
0,
"发布脚本",
0,
"发布须遵守我们的 ",
"发布脚本...",
"在动画开始播放时引发",
"在动画停止播放时引发",
"以声波形式读取响应体",
"其他人查看您的推文或截取推文截图时；或者对推文发表评论或对你的评论进行回复时；或者发生与您的订阅相关的事件时，您会收到电子邮件通知。",
"请记住：发布脚本后，所有人都会看到您的脚本，所以请确保其中不包含您的密码或个人信息。",
"减少当前的生命值。",
"回复...",
"报告/删除",
"将图片调整为给定大小(单位: 像素)",
0,
"返回图像副本",
0,0,
"返回向此实例的值中添加指定月数的日期。",
"返回向此实例的值中添加指定年数的日期。",
"返回一个介于“最小值”和“最大值”（包括这两个值）之间的随机整数。",
0,0,0,0,0,0,0,
"如果当前实例无效，则返回 true",
0,0,0,0,
"脚本更新",
"由此用户编写：",
0,
"搜索和浏览互联网......",
"搜索代码...",
"搜索所有内容",
"在此搜索...",
0,0,
"搜索...",
0,0,0,
"查看更多",
0,0,
"将梯度设为开或关",
"设置应用于展示墙的 3x3 仿射矩阵转换。",
0,
"设置背景相机",
"设置背景色",
"设置背景色。",
"设置背景图片",
"设定水平居中位置(单位: 像素)",
"设置当前的生命值。",
"设定精灵 0 和 1 之间速度损失部分的默认摩擦",
"设置高度(单位: 像素)",
"设定位置(单位: 像素)",
0,
"获取从 0 (静音)到 1 (当前音量)的音量级别",
"设置速度（单位：像素/秒）",
"设置画面颜色。",
"设置游戏板上物体的均匀加速度矢量为像素/秒^2",
0,0,
"设置宽度(单位: 像素)",
"设置 x 轴速度(单位: 像素/秒)",
"设置 y 轴加速度(单位: 像素/秒^2)",
"设定 y 轴位置(单位: 像素)",
"设置 y 轴速度(单位: 像素/秒)",
0,
"设置",
"使用这个 URL 共享：",
"如果该脚本使用任何阻止它在这些平台上运行的 API，会在编辑器中显示错误。",
"显示墙上的板。",
0,
"技能等级：{0}     ",
0,0,0,0,0,
"停止并清除所有事件帧计时器",
0,
"减去数字",
0,
"TD100: 在此插入 {0:a}",
"TD101: ：无法找到“{0}”",
"TD109: 无法分配至此",
"TD111: 无法从 {0} 分配至 {1}",
"TD112: 找不到 {1} 的属性“{0}”",
"TD115: ：向 {0} 提供的参数过多",
"TD116: 没有向 {0} 提供足够参数",
"TD118: ：“if”条件需要 {1:a}",
"TD119: i 需要迭代对象",
0,
"TD130: “for”的边界需要 {1:a}",
"TD144: 好像缺了“{0}”，请补上",
"TD145: 此处好像缺一个运算符(如“+”、“(”或“，”)",
"TD147: 此处不应出现“{0}”",
"TD150: 无法调用“(”之前的东西",
"TD151: 未关闭的“(”",
"TD152: 意外的“)”",
"TD154: 运算符后不能为空",
"TD155: “{0}”无法分配到本地变量",
"讲授 Creative Coding！",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"此脚本使用以下功能: ",
0,
"本教程使用云数据，这些数据可与其他用户共享。",
"要添加页数据，请创建一个本地变量，然后点击“升级为字段”。",
0,0,0,0,
"Microsoft® Translator 进行的翻译，点击以查看原文...",
"如果接触到游戏板则为真",
"尝试调整代码，直到调整正确。如果卡住了，请点击教程栏。",
0,0,
"教程",
"Twitter",
"输入内容进行在线搜索...",
"键入以搜索...",
0,
"无法编辑事件参数的类型、顺序和数量。",
"UI 小组件",
0,
"更新板上精灵的位置。",
"更新子画面上的图片(如果是子画面)",
"更新文本精灵上的文本（如果是文本精灵）",
"上传图片",
"上传声音",
"用户",
0,
"我们需要更多选项",
"我们会让编辑器适应您的技能水平。您可以稍后在中心更改您的技能水平。",
"您的编程知识是什么水平？",
"您的职业是什么？",
"新增内容",
"您到底在哪里？",
"在给定位置写入另一张图片。 不透明度范围介于 0 (透明)和 1 (不透明)之间。",
0,
"YouTube",
0,0,
"您的 GitHub 用户。",
"您的 Minecraft 用户。",
"您的图形将在此处显示",
0,
"您的通道将在此处显示",
"您的电子邮件地址尚未验证。请检查您的收件箱。",
"您的全名",
0,0,0,
"您的脚本将显示在此处",
"你的 Twitter 帐号，例如 @touchdevelop。",
"几秒以前",
"函数",
"全局变量",
"一分钟以前",
"页",
"关于覆盖率",
"关于见解",
"关于个人资料",
"关于您",
"滥用",
0,
"滥用报告",
0,0,0,
"访问 {0} 字段",
0,
"添加",
"新增...",
0,
"为每一个显示帧添加一个动作。",
0,0,0,0,0,
"添加输入参数",
"在上面添加行",
"在下面添加行",
"新增",
0,0,
"添加输出参数",
0,0,0,0,0,
"所有 API",
"允许",
"惊人的、惊异的、惊骇的、令人敬畏的、可怕的、惊险的、一流的、酷、好奇的、独特的、特殊的、独一无二的、特别的、令人难以置信的、神奇的、令人愉快的、出色的 ",
0,
"函数类型定义",
"一小时以前",
0,0,0,0,0,
"应用",
0,
"图稿",
"图稿资源",
"任务",
0,
"作者",
0,0,
"返回",
0,
"退格",
"使用退格键删除",
0,0,
"基准版本",
"初学者",
"初学者",
0,
"绑定到脚本：",
"空白",
"空白应用",
"空白爬行者",
"空白文档",
"空白游戏",
"空白 Minecraft",
"空白 Minecraft pi",
"空白像素画",
"空白图片素材",
"空白脚本插件",
"空白乌龟",
"空白教程",
"调试器中断",
"断点",
0,0,0,0,0,0,
"取消",
0,0,
"改(回)到本地",
"更改内容",
"通道",
"检查是否已设置引用",
0,0,0,
"选择图片（1MB 以下，少于 2048x2048）",
0,0,0,0,0,0,
"选择您的编码技能水平",
"选择...",
0,
"清除",
"剪贴板",
"克隆",
0,
"云会话",
"代码",
"为终点线编码",
"编码员",
"颜色 #{0}",
"颜色： {0}",
"注释",
"注释",
0,
"条件",
"已连接",
0,0,
"继续",
0,
"复制",
"复制选定内容",
"覆盖率",
"创建",
"创建新参数",
0,0,0,0,
"创建空的对象集合",
"正在创建脚本",
0,
"当前表达式",
"自定义图片！",
"剪切",
"裁剪选定内容",
"数据库",
"调试",
"小数点",
0,
"删除",
"删除本地数据和权限",
"删除选定内容",
"降级到 var",
"拒绝",
"描述",
"描述（有助于搜索）",
0,
"详细信息",
"您是否想要使用此值？",
"diff curr",
"diff prev",
0,0,0,
"返回",
"显示值",
"在留言板上显示对象",
0,0,0,
"完成",
"完成！",
"编辑",
"else if",
"电子邮件",
0,
"电子邮件和推送通知",
0,0,0,0,
"输入邀请码",
"输入此代码",
"错误",
0,
"事件",
0,
"ex： ",
0,
"优秀；非常好；很棒；很酷；很牛；做得好；不错；做得对；正确",
0,
"退出",
"专家",
0,
"导出",
"导出内容的 JSON 表示",
"已从此库导出",
"扩展",
0,
"提取选定内容到函数",
0,
"提取到变量",
"查找引用",
"已完成",
"修复",
"在编辑器中按教程操作",
"针对小组",
"派生",
"函数",
"函数名称",
"函数类型",
"函数、变量、库...",
"性别",
"获取“是编程一小时™”证书",
"获取每个显示帧的计时器。",
"github 用户",
0,
"全局替换",
"全局变量",
"全局变量",
"返回",
"返回编码！{0}★ 待执行",
"返回...",
"转到",
"转至您的脚本中的事项列表",
"转到上一步",
"目标：",
"小组",
"团体",
"红心",
"帮助",
0,0,
"历史记录",
"万岁！你的脚本已成功发布",
"如何发现",
"我希望它运行的位置",
"我已完成 Hour of Code™",
"图标画： {0}",
0,
"如果卡住了，请点击终点线",
0,0,0,0,
"从 JSON 对象导入字段值",
0,0,0,0,
"惊人的、不可思议的、绝妙的、非凡的、令人兴奋的、令人难以置信的、神奇的、奇特的、杰出的、出色的、疯狂的、特别的、壮观的、令人吃惊的、令人惊叹的、超酷 ",
0,
"插入",
"插入注释",
"插入语句",
"插入 {0}",
"见解",
0,
"安装和加载脚本",
"到本地",
0,
"问题",
"加入小组",
"加入组",
0,
"只需继续输入搜索项！",
"继续编辑",
"知道这里：",
0,
"了解",
"了解有关发布的信息",
"了解更多",
"了解有关 {0} 的更多信息",
"离开教程",
"让我们改动一下",
"我们去做吧！",
"我们开始吧！",
"库",
"库",
"库",
"库名称",
"库参考",
"加载更多",
"加载更多回复",
"正在加载",
0,
"正在加载 /{0} 的注释...",
0,
"正在加载回复...",
"正在加载脚本",
"正在加载教程",
"正在加载...",
"本地",
"位置",
0,
"逻辑求反",
"日志",
"重点",
0,
"制造者",
"管理数据",
"以后再说",
"我",
0,0,
"minecraft 用户",
0,0,
"更多",
"更多 ",
"更多设置",
"移动光标",
"向左移动",
"进入下一步",
"将光标向左移动",
"将光标向右移动",
"我的图稿",
0,0,0,
"我的脚本",
"此处需要不同的名称",
"这里需要不同的字符串",
"此处需要一个新字段",
"需要参数",
"需要删除",
"需要在其他位置进行编辑",
"求反",
0,0,0,0,
"换行",
0,0,0,
"在下面添加新语句",
"新变量",
0,
"后续教程...",
"昵称",
0,
"该用户没有发布图片",
"无评论，点击以发表评论!",
"无叉子，请安装、编辑和重新发布脚本以创建一个！",
"没有红心。可以在安装脚本后添加一个！",
"尚未上载任何图片",
0,0,
"无标记，点击以填写标记!",
0,0,0,
"通知",
0,
"现在您可以选择 {0} 的一个属性；但它本身不执行任何操作",
"现在可以选择它的一个属性",
"数値",
"数字输入",
0,
"职业",
0,
"可脱机使用",
"确定",
"好的，我们来掷骰子吧！",
"联机",
0,
"或者点击获得帮助",
"其他",
"概述",
0,
"页",
0,
"解析脚本文本",
0,
"粘贴",
"暂停",
0,
"物理游戏入门",
"选取一个脚本模板...",
"图片",
"图片名称",
"图片名称（最少 4 个字符）",
"图片 URL",
"再玩一次",
"请稍等",
"请稍等...",
"插件",
"预览",
"打印",
0,
"私有",
"私有函数",
"个人资料",
"个人资料",
"编程知识",
0,
"升级为数据",
0,
"公开昵称",
"公开信息",
"发布",
"发布为隐藏项目",
0,
"已发布",
"拉进更改",
"退出到块级别",
0,
"重新运行",
"阅读更多...",
"只读",
"实际名称",
0,
"收到电子邮件通讯",
"接收电子邮件通知",
"记录名称：",
0,
"常规键盘",
"正在重新加载脚本",
"删除",
0,
"删除图片",
"删除白色背景（最适合游戏精灵）",
0,
"重命名",
"重复 n 次",
"对集合重复",
"重复条件",
"替换函数中的所有项",
"在脚本中替换全部",
"替换图片",
"已复制",
"已复制 ",
0,
"报告滥用",
0,
"还原到已发布版本",
"后退",
"后退 ",
"运行",
"运行主项",
0,
"带检测运行",
"保存",
"已保存",
"正在保存…",
"学校",
"屏幕",
"屏幕截图",
"{0} 的屏幕截图",
"脚本",
"脚本属性",
0,0,
"搜索图片",
"搜索图片",
"在此搜索 {0}",
"搜索模板",
"正在搜索...",
"参见更多选项",
"选择",
"选择更多",
"选择此行",
"请选择此 {0} 类型",
0,0,
"设置本地变量名称",
"设置名称",
"设定游戏板被击打时调用的处理程序",
"设置点击该板时调用的处理程序",
"设定游戏板被接触时调用的处理程序",
"设定游戏板触屏被放开时调用的处理程序",
"将所有字段设置为默认值",
"保存设置",
"设置",
"共享",
0,
"演示如何完成该活动",
"显示更多选项",
"展示",
"登录",
0,0,
"登出",
"正在登录...",
0,
"简化",
"保存的技能水平",
"跳过迭代",
0,
"社交",
0,
"声音",
0,
"splash screen 画： {0}",
"拆分",
0,
"重新开始",
"开始脚本",
"正在开始...",
0,
"单步进入",
"单步跳出",
"单步跳过",
0,
"停止",
0,
"停止函数",
"停止循环",
"存储在变量中",
"将值存储在变量中",
"字符串",
0,
"条带“{0}”",
0,0,0,
"出众的、不可思议的、令人恐怖的、令人难以置信的、神奇的、独一无二的、前所未有的、不寻常的、怪异的、美好的、奇妙的",
"包围",
0,0,
"正在同步...",
0,0,0,0,0,
"标记",
0,0,
"完成后点击（←）",
"完成后点击 [确定]",
0,
"点击此处可进入下一步",
"完成后点击这里",
"点击这里",
"点击此处获取说明",
"点击这里运行应用",
"点击以更改颜色",
"轻敲以改变图标画",
"轻敲以改变 splash screen 图片",
"点击以使用 Microsoft® Translator 进行翻译...",
"临时",
"terms of use",
"测试",
"测试函数",
"测试",
"测试两个引用是否指向同一对象",
0,0,
"中心",
"邀请码的长度必须在 9 到 64 个字符之间",
"崩溃的脚本",
0,0,
"此脚本是一个库",
"此脚本是一项 Web 服务",
0,
"到代码",
"继续",
"到全局变量",
"切换断点",
"最新内容",
0,0,
"翻译",
"正在翻译教程...",
0,0,0,
"再试一次！",
"变为",
"教程进度",
"教程： ",
"教程",
"Twitter 帐户",
"类型： ",
"类型：{0}",
0,0,0,
"撤消",
0,0,0,0,0,0,0,0,0,0,
"更新",
0,0,0,0,0,0,
"上载",
"上传图片",
"上载屏幕截图",
"上传声音",
0,0,0,
"URL",
0,0,0,0,0,
"变量名称",
"以脚本形式查看",
"查看/编辑姓名、电子邮件…",
0,
"壁纸",
"此处有一个库“{0}”；{1}",
"此处为{0:a}；是否要对其执行操作？",
"我们需要一个新字段",
"我们需要一个新表",
"我们需要一个新的 {0}",
"我们需要不同的键盘",
"我们需要一个新变量",
"我们需要编辑另一项内容",
"我们将逐步引导您完成",
"网络应用",
0,0,0,
"网站",
0,
"网站 URL",
0,0,0,0,0,
"出生年份",
0,0,
"您已完成任务!",
0,
"{0} ({1} 行{1:s})",
"{0} 天以前",
"{0} 下",
0,0,0,
"{0} 小时以前",
"{0} 分钟以前",
"{0} 个月以前",
"{0} 个(共 {1} 个)已完成",
"发布 {0} 个",
"已发布 {0} 个脚本",
"{0} 秒以前",
"上升 {0} 个",
"{0} 年以前"
]); return true; }

if (lang == "zh-CN") { TDev.Util._setLanguageArray(keys, [
"   Maybe: {0} ({1} at '{2}')\n",
"  -> Line {2} ('{1}'), error: {0}\n{3}",
" — — 局部变量",
" [class]",
" [隐藏]",
" [override]",
" 返回",
" 前进",
" 小时 ",
" 分钟 ",
" 的 ",
" 秒 ",
" 发送更改",
" 等待服务器",
"# # # 完整源代码",
"Javascripty 花括号，以及所有工具，适合于有经验的开发人员!",
"“atomic”函数",
"'盒子' 只能在页面显示代码中访问",
"'盒子' 无法访问在 HTML 布局模式中",
"'else' 的前面的 'if' 必须是空的",
"'html' 只能访问 HTML 布局模式",
"“{0}”认为此处应为 {1}",
"'{0}' 包含不支持的签名",
"'{0}' 当前未执行",
"'{0}' 已过期且不能实现",
"“{0}”已弃用，不应使用。",
"'{0}' 不是一个字符串资源",
"“{0}”返回“{1}”；{2}",
"'{0}' 返回 {1} 的值; 你可以使用 '储存在var' 按钮来将它们保存到本地",
"(可选) 与信息有关的错误，用来提供有关错误的额外信息的客户端开发者确定人类可读的 web 页的 URI。",
"(可选) 人类可读的错误代码。",
"(可选)未涵盖的 OAuth 2.0 规范的附加键值对。",
"(可选) 指示是否令牌可能在下一秒内已过期。",
"(可选)可选，如果相同范围由客户端请求;否则，访问令牌的范围如 OAuth 2.0 规范第 3.3 节所述。",
"(可选) 以秒为单位的访问令牌生存期。",
"(请等一等，它会占用至多一分钟)",
"，而获得了 {0:a}",
"，获得了 {0}",
"大小: {0} 字符",
". 请阅读我们 ",
"...... 这儿没什么可看...",
"... 有更多...",
"// 注释",
"1.选择一个文档 (.txt、.pptx，.pdf、.css，小于 8 Mb)",
"1. 选择 MP3 声音 (小于 1 MB)",
"2. 给它一个名称 (最低 4 个字符)",
"3. 描述它",
"4. 发布",
":(抱歉，这个文本翻译时出错。",
":(对不起，我们不能翻译此。",
":(找不到任何视频源",
":(无效的视频信息",
"; 是否缺少 → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'> Apache Cordova</a> 让您构建跨平台的移动应用程序。",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> 生成的证书</a>.",
"<b>免责声明:</b>这个 web 应用程序不是由微软认可的。",
"<b>如何本地运行本程序</b>",
"<b>此行正确无误！</b>我们继续吧",
"<h3>正在加载当前设置...</h3>",
"<h3>没有更多的提示!</h3>",
"<h3>欢迎来到Touch Develop</h3>",
"<h3>{0:q} 需要签到</h3>",
"<p>如果你没有Azure订阅，去 <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> Azure订阅</a> 获取.</p>",
"<p>Touch Develop使您可以 <b>轻松地创建应用程序</b> 来自您的手机、 平板电脑或 PC。</p>",
"<p>你可以与他人分享您的应用程序，因此他们可以 <b>运行和编辑</b> 他们在 Windows Phone、 iPad、 iPhone、 Android、 PC 或 mac上。</p>",
"<strong>beta 测试中的新功能:</strong> 的语法和语义的更改",
"<strong>所需的平台:</strong>",
"超出范围，@hi/lo",
"数字 2D 矩阵",
"一个三维向量",
"Bing 地图",
"Minecraft Pi 应用。",
"Minecraft 应用。",
"Minecraft 爬虫应用。",
"服务器发送事件的客户端",
"对sprite属性进行动画处理的动画",
"Argb 颜色 (alpha、 红色、 绿色、 蓝色)",
"背景场景图层",
"一个初学者友好编辑器",
"打造2D 游戏的开发板",
"创建 HTML 表单数据的生成器",
"云计算数据会议",
"对象集",
"Sprites集",
"颜色常量",
"日期和时间的组合",
"添加了有关您拉请求的注释。",
"联系人",
"自定义记录器",
"文档",
"文档资源",
0,0,0,
"全局变量",
0,0,0,0,0,0,0,0,0,0,0,
"数値 (負 / 小数の場合もある)",
"数字常量",
0,0,0,
"图片",
"一段文本",
"像素画应用。",
0,0,0,
"对库脚本的引用",
0,0,0,0,0,0,0,0,0,
"声效",
0,0,0,0,
"用户数据结构",
"包含用户定义行的表",
0,0,0,0,0,
"您公开信息的唯一显示名称（至少 8 个字符）",
0,0,
"用户界面",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"添加对每一显示帧触发的动作",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"增加数字",
0,
"给当前分数添加值。",
0,0,
"在脚本停止后，浏览代码以查看收集到的信息。",
"我的所有组",
"我的所有脚本",
0,0,0,0,0,0,0,
"使用页面和方框的空白应用。",
"使用图片素材库的空白应用。",
"空白文档页。",
"空白交互式教程。",
"空白脚本编辑器插件。",
"不执行任何操作的空白脚本。",
0,0,
"包含用户定义行的索引表",
0,
"乌龟应用。",
"对输入集合的所有元素应用“转换器”并返回结果集",
0,
"你确定你想停止下面的教程吗？",
0,
"由此用户绘制：",
0,
"向其他对象附加数据",
"用于创建游戏的样板文件代码。",
0,0,0,
"相机、 位置、 麦克风和其他传感器",
0,0,
"更改技能等级！",
0,
"检查该板是否和另一板的距离相同。",
0,0,0,
"清除与此板有关的所有排队事件",
"清除背景图片",
"清除背景相机",
0,0,
"用户交流时分享的代码",
"执行特定任务的代码",
"比较数字是否相等",
"比较数字以确定更小值",
0,
"比较数字以确定更大值",
0,0,0,0,0,0,0,
"连接两段文本",
0,0,0,0,0,0,
"转换为本地时间",
0,0,0,0,0,
"创建组",
"创建脚本",
"用给定的起点、宽度和高度创建一个线障碍。粘性的弹性为 0，1 为完全反弹。",
"新建画面集合。",
"新建椭圆画面。",
"新建图片画面。",
"创建一个新的长方形精灵。",
0,
"创建新的精灵表单。",
"创建新的文本画面。",
"在两个精灵之间创建一个跳板。",
"创建一个锚精灵。",
"创建此对象类型的无效值",
"创建通道",
0,
"创建无效的值",
"在给定的距离处创建板的四周。",
"创建自己的应用",
0,0,
"创建新的空白游戏板并使之在屏幕上显示。",
0,0,0,
"用给定图片创建宽度为 100 的新精灵。",
0,
"创建无效的游戏手柄实例",
0,0,
"当前设备",
0,
"当前触点",
"从事件中分离处理程序。",
0,
"将图像显示到展示墙上；稍后如果您希望所做更改生效，则需要调用“展示墙更新”。",
0,0,0,
"显示墙上游戏手柄的状态",
0,
"子画面是否重叠",
0,
"文档",
"完成编辑后，不要忘记向下滚动，然后点击“保存”！",
"拖放功能块，界面简单，适合于初学者！",
"在两点之间画一条线",
"用给定颜色和字号绘制一些文本边框",
"将代码编辑为文本，以及其他更多选项，适合于应用程序编写爱好者！",
0,0,
"输入名称",
0,
"请输入有关您的个人信息",
"请输入您个人网站的 URL（例如：http://www.northwindtraders.com）",
"输入邀请码",
0,
"事件不能有输出参数。",
"每个人将能够用于在 Internet 上看到你的图片。 ",
0,0,
"扩展",
"Facebook",
"用给定颜色填充椭圆",
"用给定颜色填充矩形",
"接触结束后的最终接触速度",
"对于已发布的脚本，还可查看已发布脚本页上的选项卡，查找匿名收集的众多个人资料和覆盖率数据。",
"论坛",
"从现在开始，我们不会向您显示要编写的代码。按照指示进行操作，如果您认为已完成，请单击运行。",
"当前脚本中的函数",
0,0,0,0,0,
"获取游戏手柄的状态快照（如果连接到浏览器）。如果不支持或未连接游戏手柄则为空。",
0,0,0,
"获取值，该值表示该板是否被设计为在景观模式中查看",
"获取歌曲是否受 DRM 保护的信息",
"获得所选定轴线的 x 和 y 值。",
0,0,
"获取背景场景",
"获取水平居中位置(单位: 像素)",
0,
"获取 ARGB 值为 #00FFFFFF 的颜色",
"获取 ARGB 值为 #FF000000 的颜色",
"获取 ARGB 值为 #FF0000FF 的颜色",
"获取 ARGB 值为 #FF008000 的颜色",
"获取 ARGB 值为 #FF00FFFF 的颜色",
0,
"获取 ARGB 值为 #FF800080 的颜色",
0,0,0,0,
"获取 ARGB 值为 #FFFF0000 的颜色",
"获取 ARGB 值为 #FFFF00FF 的颜色",
"获取 ARGB 值为 #FFFFA500 的颜色",
0,
"获取 ARGB 值为 #FFFFFF00 的颜色",
"获取 ARGB 值为 #FFFFFFFF 的颜色",
0,0,0,0,
"获得可用的第一个连接的游戏手柄",
0,
"获得游戏手柄标识符",
0,
"获取高度(单位: 像素)",
"获取相机图像的高度(单位: 像素)。",
0,0,0,0,0,0,0,0,0,
"获得玩家索引",
"获得按钮的按下值。如果按钮缺失则返回 0。",
0,
"获取从 0 (静音)到 1 (当前音量)的音量",
"获得精灵数目",
"获取由 i 索引的精灵",
0,
"获得这次快照的时间戳",
0,
"获取宽度(单位: 像素)",
"获取相机图像的宽度(单位: 像素)。",
"获取 y 轴位置(单位: 像素)",
"快速入门",
0,
"当前脚本中的全局变量",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"在调试模式，游戏板显示精灵的速度和其他信息",
"表示按钮是否被按下。如果按钮缺失则返回 false。",
0,
"表示游戏手柄数据是否相同",
"表示游戏手柄是否仍被连接。",
0,0,0,0,
"插入“{0}”{1}",
0,
"标记 * 的项为必填项。",
"JSON 数据",
"加入组",
"最后接触终点",
"最后接触起点",
0,0,0,0,0,
"使更新可见。",
0,0,
"确保所有画面都在屏幕的边界上弹起",
0,
"数学擅长程度，绝对值，最大值",
"Me",
0,
"Minecraft 用户",
"更多",
0,
"将画面向其他画面移动。",
"乘以数字",
0,0,0,0,0,0,0,0,
"新脚本",
0,
"新颜色或内置颜色",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"电话号码、 振动、 等...",
0,
"选取随机颜色",
"图片和音乐......",
0,0,0,0,0,
"请查看我们的隐私声明。",
0,
"发表评论...",
0,0,0,
"隐藏动作不会得到运行按钮。 ",
"提示用户输入一个数字",
0,
"发布脚本",
0,
"发布须遵守我们的 ",
"发布脚本...",
"在动画开始播放时引发",
"在动画停止播放时引发",
"以声波形式读取响应体",
"其他人查看您的推文或截取推文截图时；或者对推文发表评论或对你的评论进行回复时；或者发生与您的订阅相关的事件时，您会收到电子邮件通知。",
"请记住：发布脚本后，所有人都会看到您的脚本，所以请确保其中不包含您的密码或个人信息。",
"减少当前的生命值。",
"回复...",
"报告/删除",
"将图片调整为给定大小(单位: 像素)",
0,
"返回图像副本",
0,0,
"返回向此实例的值中添加指定月数的日期。",
"返回向此实例的值中添加指定年数的日期。",
"返回一个介于“最小值”和“最大值”（包括这两个值）之间的随机整数。",
0,0,0,0,0,0,0,
"如果当前实例无效，则返回 true",
0,0,0,0,
"脚本更新",
"由此用户编写：",
0,
"搜索和浏览互联网......",
"搜索代码...",
"搜索所有内容",
"在此搜索...",
0,0,
"搜索...",
0,0,0,
"查看更多",
0,0,
"将梯度设为开或关",
"设置应用于展示墙的 3x3 仿射矩阵转换。",
0,
"设置背景相机",
"设置背景色",
"设置背景色。",
"设置背景图片",
"设定水平居中位置(单位: 像素)",
"设置当前的生命值。",
"设定精灵 0 和 1 之间速度损失部分的默认摩擦",
"设置高度(单位: 像素)",
"设定位置(单位: 像素)",
0,
"获取从 0 (静音)到 1 (当前音量)的音量级别",
"设置速度（单位：像素/秒）",
"设置画面颜色。",
"设置游戏板上物体的均匀加速度矢量为像素/秒^2",
0,0,
"设置宽度(单位: 像素)",
"设置 x 轴速度(单位: 像素/秒)",
"设置 y 轴加速度(单位: 像素/秒^2)",
"设定 y 轴位置(单位: 像素)",
"设置 y 轴速度(单位: 像素/秒)",
0,
"设置",
"使用这个 URL 共享：",
"如果该脚本使用任何阻止它在这些平台上运行的 API，会在编辑器中显示错误。",
"显示墙上的板。",
0,
"技能等级：{0}     ",
0,0,0,0,0,
"停止并清除所有事件帧计时器",
0,
"减去数字",
0,
"TD100: 在此插入 {0:a}",
"TD101: ：无法找到“{0}”",
"TD109: 无法分配至此",
"TD111: 无法从 {0} 分配至 {1}",
"TD112: 找不到 {1} 的属性“{0}”",
"TD115: ：向 {0} 提供的参数过多",
"TD116: 没有向 {0} 提供足够参数",
"TD118: ：“if”条件需要 {1:a}",
"TD119: i 需要迭代对象",
0,
"TD130: “for”的边界需要 {1:a}",
"TD144: 好像缺了“{0}”，请补上",
"TD145: 此处好像缺一个运算符(如“+”、“(”或“，”)",
"TD147: 此处不应出现“{0}”",
"TD150: 无法调用“(”之前的东西",
"TD151: 未关闭的“(”",
"TD152: 意外的“)”",
"TD154: 运算符后不能为空",
"TD155: “{0}”无法分配到本地变量",
"讲授 Creative Coding！",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"此脚本使用以下功能: ",
0,
"本教程使用云数据，这些数据可与其他用户共享。",
"要添加页数据，请创建一个本地变量，然后点击“升级为字段”。",
0,0,0,0,
"Microsoft® Translator 进行的翻译，点击以查看原文...",
"如果接触到游戏板则为真",
"尝试调整代码，直到调整正确。如果卡住了，请点击教程栏。",
0,0,
"教程",
"Twitter",
"输入内容进行在线搜索...",
"键入以搜索...",
0,
"无法编辑事件参数的类型、顺序和数量。",
"UI 小组件",
0,
"更新板上精灵的位置。",
"更新子画面上的图片(如果是子画面)",
"更新文本精灵上的文本（如果是文本精灵）",
"上传图片",
"上传声音",
"用户",
0,
"我们需要更多选项",
"我们会让编辑器适应您的技能水平。您可以稍后在中心更改您的技能水平。",
"您的编程知识是什么水平？",
"您的职业是什么？",
"新增内容",
"您到底在哪里？",
"在给定位置写入另一张图片。 不透明度范围介于 0 (透明)和 1 (不透明)之间。",
0,
"YouTube",
0,0,
"您的 GitHub 用户。",
"您的 Minecraft 用户。",
"您的图形将在此处显示",
0,
"您的通道将在此处显示",
"您的电子邮件地址尚未验证。请检查您的收件箱。",
"您的全名",
0,0,0,
"您的脚本将显示在此处",
"你的 Twitter 帐号，例如 @touchdevelop。",
"几秒以前",
"函数",
"全局变量",
"一分钟以前",
"页",
"关于覆盖率",
"关于见解",
"关于个人资料",
"关于您",
"滥用",
0,
"滥用报告",
0,0,0,
"访问 {0} 字段",
0,
"添加",
"新增...",
0,
"为每一个显示帧添加一个动作。",
0,0,0,0,0,
"添加输入参数",
"在上面添加行",
"在下面添加行",
"新增",
0,0,
"添加输出参数",
0,0,0,0,0,
"所有 API",
"允许",
"惊人的、惊异的、惊骇的、令人敬畏的、可怕的、惊险的、一流的、酷、好奇的、独特的、特殊的、独一无二的、特别的、令人难以置信的、神奇的、令人愉快的、出色的 ",
0,
"函数类型定义",
"一小时以前",
0,0,0,0,0,
"应用",
0,
"图稿",
"图稿资源",
"任务",
0,
"作者",
0,0,
"返回",
0,
"退格",
"使用退格键删除",
0,0,
"基准版本",
"初学者",
"初学者",
0,
"绑定到脚本：",
"空白",
"空白应用",
"空白爬行者",
"空白文档",
"空白游戏",
"空白 Minecraft",
"空白 Minecraft pi",
"空白像素画",
"空白图片素材",
"空白脚本插件",
"空白乌龟",
"空白教程",
"调试器中断",
"断点",
0,0,0,0,0,0,
"取消",
0,0,
"改(回)到本地",
"更改内容",
"通道",
"检查是否已设置引用",
0,0,0,
"选择图片（1MB 以下，少于 2048x2048）",
0,0,0,0,0,0,
"选择您的编码技能水平",
"选择...",
0,
"清除",
"剪贴板",
"克隆",
0,
"云会话",
"代码",
"为终点线编码",
"编码员",
"颜色 #{0}",
"颜色： {0}",
"注释",
"注释",
0,
"条件",
"已连接",
0,0,
"继续",
0,
"复制",
"复制选定内容",
"覆盖率",
"创建",
"创建新参数",
0,0,0,0,
"创建空的对象集合",
"正在创建脚本",
0,
"当前表达式",
"自定义图片！",
"剪切",
"裁剪选定内容",
"数据库",
"调试",
"小数点",
0,
"删除",
"删除本地数据和权限",
"删除选定内容",
"降级到 var",
"拒绝",
"描述",
"描述（有助于搜索）",
0,
"详细信息",
"您是否想要使用此值？",
"diff curr",
"diff prev",
0,0,0,
"返回",
"显示值",
"在留言板上显示对象",
0,0,0,
"完成",
"完成！",
"编辑",
"else if",
"电子邮件",
0,
"电子邮件和推送通知",
0,0,0,0,
"输入邀请码",
"输入此代码",
"错误",
0,
"事件",
0,
"ex： ",
0,
"优秀；非常好；很棒；很酷；很牛；做得好；不错；做得对；正确",
0,
"退出",
"专家",
0,
"导出",
"导出内容的 JSON 表示",
"已从此库导出",
"扩展",
0,
"提取选定内容到函数",
0,
"提取到变量",
"查找引用",
"已完成",
"修复",
"在编辑器中按教程操作",
"针对小组",
"派生",
"函数",
"函数名称",
"函数类型",
"函数、变量、库...",
"性别",
"获取“是编程一小时™”证书",
"获取每个显示帧的计时器。",
"github 用户",
0,
"全局替换",
"全局变量",
"全局变量",
"返回",
"返回编码！{0}★ 待执行",
"返回...",
"转到",
"转至您的脚本中的事项列表",
"转到上一步",
"目标：",
"小组",
"团体",
"红心",
"帮助",
0,0,
"历史记录",
"万岁！你的脚本已成功发布",
"如何发现",
"我希望它运行的位置",
"我已完成 Hour of Code™",
"图标画： {0}",
0,
"如果卡住了，请点击终点线",
0,0,0,0,
"从 JSON 对象导入字段值",
0,0,0,0,
"惊人的、不可思议的、绝妙的、非凡的、令人兴奋的、令人难以置信的、神奇的、奇特的、杰出的、出色的、疯狂的、特别的、壮观的、令人吃惊的、令人惊叹的、超酷 ",
0,
"插入",
"插入注释",
"插入语句",
"插入 {0}",
"见解",
0,
"安装和加载脚本",
"到本地",
0,
"问题",
"加入小组",
"加入组",
0,
"只需继续输入搜索项！",
"继续编辑",
"知道这里：",
0,
"了解",
"了解有关发布的信息",
"了解更多",
"了解有关 {0} 的更多信息",
"离开教程",
"让我们改动一下",
"我们去做吧！",
"我们开始吧！",
"库",
"库",
"库",
"库名称",
"库参考",
"加载更多",
"加载更多回复",
"正在加载",
0,
"正在加载 /{0} 的注释...",
0,
"正在加载回复...",
"正在加载脚本",
"正在加载教程",
"正在加载...",
"本地",
"位置",
0,
"逻辑求反",
"日志",
"重点",
0,
"制造者",
"管理数据",
"以后再说",
"我",
0,0,
"minecraft 用户",
0,0,
"更多",
"更多 ",
"更多设置",
"移动光标",
"向左移动",
"进入下一步",
"将光标向左移动",
"将光标向右移动",
"我的图稿",
0,0,0,
"我的脚本",
"此处需要不同的名称",
"这里需要不同的字符串",
"此处需要一个新字段",
"需要参数",
"需要删除",
"需要在其他位置进行编辑",
"求反",
0,0,0,0,
"换行",
0,0,0,
"在下面添加新语句",
"新变量",
0,
"后续教程...",
"昵称",
0,
"该用户没有发布图片",
"无评论，点击以发表评论!",
"无叉子，请安装、编辑和重新发布脚本以创建一个！",
"没有红心。可以在安装脚本后添加一个！",
"尚未上载任何图片",
0,0,
"无标记，点击以填写标记!",
0,0,0,
"通知",
0,
"现在您可以选择 {0} 的一个属性；但它本身不执行任何操作",
"现在可以选择它的一个属性",
"数値",
"数字输入",
0,
"职业",
0,
"可脱机使用",
"确定",
"好的，我们来掷骰子吧！",
"联机",
0,
"或者点击获得帮助",
"其他",
"概述",
0,
"页",
0,
"解析脚本文本",
0,
"粘贴",
"暂停",
0,
"物理游戏入门",
"选取一个脚本模板...",
"图片",
"图片名称",
"图片名称（最少 4 个字符）",
"图片 URL",
"再玩一次",
"请稍等",
"请稍等...",
"插件",
"预览",
"打印",
0,
"私有",
"私有函数",
"个人资料",
"个人资料",
"编程知识",
0,
"升级为数据",
0,
"公开昵称",
"公开信息",
"发布",
"发布为隐藏项目",
0,
"已发布",
"拉进更改",
"退出到块级别",
0,
"重新运行",
"阅读更多...",
"只读",
"实际名称",
0,
"收到电子邮件通讯",
"接收电子邮件通知",
"记录名称：",
0,
"常规键盘",
"正在重新加载脚本",
"删除",
0,
"删除图片",
"删除白色背景（最适合游戏精灵）",
0,
"重命名",
"重复 n 次",
"对集合重复",
"重复条件",
"替换函数中的所有项",
"在脚本中替换全部",
"替换图片",
"已复制",
"已复制 ",
0,
"报告滥用",
0,
"还原到已发布版本",
"后退",
"后退 ",
"运行",
"运行主项",
0,
"带检测运行",
"保存",
"已保存",
"正在保存…",
"学校",
"屏幕",
"屏幕截图",
"{0} 的屏幕截图",
"脚本",
"脚本属性",
0,0,
"搜索图片",
"搜索图片",
"在此搜索 {0}",
"搜索模板",
"正在搜索...",
"参见更多选项",
"选择",
"选择更多",
"选择此行",
"请选择此 {0} 类型",
0,0,
"设置本地变量名称",
"设置名称",
"设定游戏板被击打时调用的处理程序",
"设置点击该板时调用的处理程序",
"设定游戏板被接触时调用的处理程序",
"设定游戏板触屏被放开时调用的处理程序",
"将所有字段设置为默认值",
"保存设置",
"设置",
"共享",
0,
"演示如何完成该活动",
"显示更多选项",
"展示",
"登录",
0,0,
"登出",
"正在登录...",
0,
"简化",
"保存的技能水平",
"跳过迭代",
0,
"社交",
0,
"声音",
0,
"splash screen 画： {0}",
"拆分",
0,
"重新开始",
"开始脚本",
"正在开始...",
0,
"单步进入",
"单步跳出",
"单步跳过",
0,
"停止",
0,
"停止函数",
"停止循环",
"存储在变量中",
"将值存储在变量中",
"字符串",
0,
"条带“{0}”",
0,0,0,
"出众的、不可思议的、令人恐怖的、令人难以置信的、神奇的、独一无二的、前所未有的、不寻常的、怪异的、美好的、奇妙的",
"包围",
0,0,
"正在同步...",
0,0,0,0,0,
"标记",
0,0,
"完成后点击（←）",
"完成后点击 [确定]",
0,
"点击此处可进入下一步",
"完成后点击这里",
"点击这里",
"点击此处获取说明",
"点击这里运行应用",
"点击以更改颜色",
"轻敲以改变图标画",
"轻敲以改变 splash screen 图片",
"点击以使用 Microsoft® Translator 进行翻译...",
"临时",
"terms of use",
"测试",
"测试函数",
"测试",
"测试两个引用是否指向同一对象",
0,0,
"中心",
"邀请码的长度必须在 9 到 64 个字符之间",
"崩溃的脚本",
0,0,
"此脚本是一个库",
"此脚本是一项 Web 服务",
0,
"到代码",
"继续",
"到全局变量",
"切换断点",
"最新内容",
0,0,
"翻译",
"正在翻译教程...",
0,0,0,
"再试一次！",
"变为",
"教程进度",
"教程： ",
"教程",
"Twitter 帐户",
"类型： ",
"类型：{0}",
0,0,0,
"撤消",
0,0,0,0,0,0,0,0,0,0,
"更新",
0,0,0,0,0,0,
"上载",
"上传图片",
"上载屏幕截图",
"上传声音",
0,0,0,
"URL",
0,0,0,0,0,
"变量名称",
"以脚本形式查看",
"查看/编辑姓名、电子邮件…",
0,
"壁纸",
"此处有一个库“{0}”；{1}",
"此处为{0:a}；是否要对其执行操作？",
"我们需要一个新字段",
"我们需要一个新表",
"我们需要一个新的 {0}",
"我们需要不同的键盘",
"我们需要一个新变量",
"我们需要编辑另一项内容",
"我们将逐步引导您完成",
"网络应用",
0,0,0,
"网站",
0,
"网站 URL",
0,0,0,0,0,
"出生年份",
0,0,
"您已完成任务!",
0,
"{0} ({1} 行{1:s})",
"{0} 天以前",
"{0} 下",
0,0,0,
"{0} 小时以前",
"{0} 分钟以前",
"{0} 个月以前",
"{0} 个(共 {1} 个)已完成",
"发布 {0} 个",
"已发布 {0} 个脚本",
"{0} 秒以前",
"上升 {0} 个",
"{0} 年以前"
]); return true; }

if (lang == "zh-HK") { TDev.Util._setLanguageArray(keys, [
"   Maybe: {0} ({1} at '{2}')\n",
"  -> Line {2} ('{1}'), error: {0}\n{3}",
" — — 局部变量",
" [class]",
" [隐藏]",
" [override]",
" 返回",
" 前进",
" 小时 ",
" 分钟 ",
" 的 ",
" 秒 ",
" 发送更改",
" 等待服务器",
"# # # 完整源代码",
"Javascripty 花括号，以及所有工具，适合于有经验的开发人员!",
"“atomic”函数",
"'盒子' 只能在页面显示代码中访问",
"'盒子' 无法访问在 HTML 布局模式中",
"'else' 的前面的 'if' 必须是空的",
"'html' 只能访问 HTML 布局模式",
"“{0}”认为此处应为 {1}",
"'{0}' 包含不支持的签名",
"'{0}' 当前未执行",
"'{0}' 已过期且不能实现",
"“{0}”已弃用，不应使用。",
"'{0}' 不是一个字符串资源",
"“{0}”返回“{1}”；{2}",
"'{0}' 返回 {1} 的值; 你可以使用 '储存在var' 按钮来将它们保存到本地",
"(可选) 与信息有关的错误，用来提供有关错误的额外信息的客户端开发者确定人类可读的 web 页的 URI。",
"(可选) 人类可读的错误代码。",
"(可选)未涵盖的 OAuth 2.0 规范的附加键值对。",
"(可选) 指示是否令牌可能在下一秒内已过期。",
"(可选)可选，如果相同范围由客户端请求;否则，访问令牌的范围如 OAuth 2.0 规范第 3.3 节所述。",
"(可选) 以秒为单位的访问令牌生存期。",
"(请等一等，它会占用至多一分钟)",
"，而获得了 {0:a}",
"，获得了 {0}",
"大小: {0} 字符",
". 请阅读我们 ",
"...... 这儿没什么可看...",
"... 有更多...",
"// 注释",
"1.选择一个文档 (.txt、.pptx，.pdf、.css，小于 8 Mb)",
"1. 选择 MP3 声音 (小于 1 MB)",
"2. 给它一个名称 (最低 4 个字符)",
"3. 描述它",
"4. 发布",
":(抱歉，这个文本翻译时出错。",
":(对不起，我们不能翻译此。",
":(找不到任何视频源",
":(无效的视频信息",
"; 是否缺少 → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'> Apache Cordova</a> 让您构建跨平台的移动应用程序。",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> 生成的证书</a>.",
"<b>免责声明:</b>这个 web 应用程序不是由微软认可的。",
"<b>如何本地运行本程序</b>",
"<b>此行正确无误！</b>我们继续吧",
"<h3>正在加载当前设置...</h3>",
"<h3>没有更多的提示!</h3>",
"<h3>欢迎来到Touch Develop</h3>",
"<h3>{0:q} 需要签到</h3>",
"<p>如果你没有Azure订阅，去 <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> Azure订阅</a> 获取.</p>",
"<p>Touch Develop使您可以 <b>轻松地创建应用程序</b> 来自您的手机、 平板电脑或 PC。</p>",
"<p>你可以与他人分享您的应用程序，因此他们可以 <b>运行和编辑</b> 他们在 Windows Phone、 iPad、 iPhone、 Android、 PC 或 mac上。</p>",
"<strong>beta 测试中的新功能:</strong> 的语法和语义的更改",
"<strong>所需的平台:</strong>",
"超出范围，@hi/lo",
"数字 2D 矩阵",
"一个三维向量",
"Bing 地图",
"Minecraft Pi 应用。",
"Minecraft 应用。",
"Minecraft 爬虫应用。",
"服务器发送事件的客户端",
"对sprite属性进行动画处理的动画",
"Argb 颜色 (alpha、 红色、 绿色、 蓝色)",
"背景场景图层",
"一个初学者友好编辑器",
"打造2D 游戏的开发板",
"创建 HTML 表单数据的生成器",
"云计算数据会议",
"对象集",
"Sprites集",
"颜色常量",
"日期和时间的组合",
"添加了有关您拉请求的注释。",
"联系人",
"自定义记录器",
"文档",
"文档资源",
0,0,0,
"全局变量",
0,0,0,0,0,0,0,0,0,0,0,
"数値 (負 / 小数の場合もある)",
"数字常量",
0,0,0,
"图片",
"一段文本",
"像素画应用。",
0,0,0,
"对库脚本的引用",
0,0,0,0,0,0,0,0,0,
"声效",
0,0,0,0,
"用户数据结构",
"包含用户定义行的表",
0,0,0,0,0,
"您公开信息的唯一显示名称（至少 8 个字符）",
0,0,
"用户界面",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"添加对每一显示帧触发的动作",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"增加数字",
0,
"给当前分数添加值。",
0,0,
"在脚本停止后，浏览代码以查看收集到的信息。",
"我的所有组",
"我的所有脚本",
0,0,0,0,0,0,0,
"使用页面和方框的空白应用。",
"使用图片素材库的空白应用。",
"空白文档页。",
"空白交互式教程。",
"空白脚本编辑器插件。",
"不执行任何操作的空白脚本。",
0,0,
"包含用户定义行的索引表",
0,
"乌龟应用。",
"对输入集合的所有元素应用“转换器”并返回结果集",
0,
"你确定你想停止下面的教程吗？",
0,
"由此用户绘制：",
0,
"向其他对象附加数据",
"用于创建游戏的样板文件代码。",
0,0,0,
"相机、 位置、 麦克风和其他传感器",
0,0,
"更改技能等级！",
0,
"检查该板是否和另一板的距离相同。",
0,0,0,
"清除与此板有关的所有排队事件",
"清除背景图片",
"清除背景相机",
0,0,
"用户交流时分享的代码",
"执行特定任务的代码",
"比较数字是否相等",
"比较数字以确定更小值",
0,
"比较数字以确定更大值",
0,0,0,0,0,0,0,
"连接两段文本",
0,0,0,0,0,0,
"转换为本地时间",
0,0,0,0,0,
"创建组",
"创建脚本",
"用给定的起点、宽度和高度创建一个线障碍。粘性的弹性为 0，1 为完全反弹。",
"新建画面集合。",
"新建椭圆画面。",
"新建图片画面。",
"创建一个新的长方形精灵。",
0,
"创建新的精灵表单。",
"创建新的文本画面。",
"在两个精灵之间创建一个跳板。",
"创建一个锚精灵。",
"创建此对象类型的无效值",
"创建通道",
0,
"创建无效的值",
"在给定的距离处创建板的四周。",
"创建自己的应用",
0,0,
"创建新的空白游戏板并使之在屏幕上显示。",
0,0,0,
"用给定图片创建宽度为 100 的新精灵。",
0,
"创建无效的游戏手柄实例",
0,0,
"当前设备",
0,
"当前触点",
"从事件中分离处理程序。",
0,
"将图像显示到展示墙上；稍后如果您希望所做更改生效，则需要调用“展示墙更新”。",
0,0,0,
"显示墙上游戏手柄的状态",
0,
"子画面是否重叠",
0,
"文档",
"完成编辑后，不要忘记向下滚动，然后点击“保存”！",
"拖放功能块，界面简单，适合于初学者！",
"在两点之间画一条线",
"用给定颜色和字号绘制一些文本边框",
"将代码编辑为文本，以及其他更多选项，适合于应用程序编写爱好者！",
0,0,
"输入名称",
0,
"请输入有关您的个人信息",
"请输入您个人网站的 URL（例如：http://www.northwindtraders.com）",
"输入邀请码",
0,
"事件不能有输出参数。",
"每个人将能够用于在 Internet 上看到你的图片。 ",
0,0,
"扩展",
"Facebook",
"用给定颜色填充椭圆",
"用给定颜色填充矩形",
"接触结束后的最终接触速度",
"对于已发布的脚本，还可查看已发布脚本页上的选项卡，查找匿名收集的众多个人资料和覆盖率数据。",
"论坛",
"从现在开始，我们不会向您显示要编写的代码。按照指示进行操作，如果您认为已完成，请单击运行。",
"当前脚本中的函数",
0,0,0,0,0,
"获取游戏手柄的状态快照（如果连接到浏览器）。如果不支持或未连接游戏手柄则为空。",
0,0,0,
"获取值，该值表示该板是否被设计为在景观模式中查看",
"获取歌曲是否受 DRM 保护的信息",
"获得所选定轴线的 x 和 y 值。",
0,0,
"获取背景场景",
"获取水平居中位置(单位: 像素)",
0,
"获取 ARGB 值为 #00FFFFFF 的颜色",
"获取 ARGB 值为 #FF000000 的颜色",
"获取 ARGB 值为 #FF0000FF 的颜色",
"获取 ARGB 值为 #FF008000 的颜色",
"获取 ARGB 值为 #FF00FFFF 的颜色",
0,
"获取 ARGB 值为 #FF800080 的颜色",
0,0,0,0,
"获取 ARGB 值为 #FFFF0000 的颜色",
"获取 ARGB 值为 #FFFF00FF 的颜色",
"获取 ARGB 值为 #FFFFA500 的颜色",
0,
"获取 ARGB 值为 #FFFFFF00 的颜色",
"获取 ARGB 值为 #FFFFFFFF 的颜色",
0,0,0,0,
"获得可用的第一个连接的游戏手柄",
0,
"获得游戏手柄标识符",
0,
"获取高度(单位: 像素)",
"获取相机图像的高度(单位: 像素)。",
0,0,0,0,0,0,0,0,0,
"获得玩家索引",
"获得按钮的按下值。如果按钮缺失则返回 0。",
0,
"获取从 0 (静音)到 1 (当前音量)的音量",
"获得精灵数目",
"获取由 i 索引的精灵",
0,
"获得这次快照的时间戳",
0,
"获取宽度(单位: 像素)",
"获取相机图像的宽度(单位: 像素)。",
"获取 y 轴位置(单位: 像素)",
"快速入门",
0,
"当前脚本中的全局变量",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"在调试模式，游戏板显示精灵的速度和其他信息",
"表示按钮是否被按下。如果按钮缺失则返回 false。",
0,
"表示游戏手柄数据是否相同",
"表示游戏手柄是否仍被连接。",
0,0,0,0,
"插入“{0}”{1}",
0,
"标记 * 的项为必填项。",
"JSON 数据",
"加入组",
"最后接触终点",
"最后接触起点",
0,0,0,0,0,
"使更新可见。",
0,0,
"确保所有画面都在屏幕的边界上弹起",
0,
"数学擅长程度，绝对值，最大值",
"Me",
0,
"Minecraft 用户",
"更多",
0,
"将画面向其他画面移动。",
"乘以数字",
0,0,0,0,0,0,0,0,
"新脚本",
0,
"新颜色或内置颜色",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"电话号码、 振动、 等...",
0,
"选取随机颜色",
"图片和音乐......",
0,0,0,0,0,
"请查看我们的隐私声明。",
0,
"发表评论...",
0,0,0,
"隐藏动作不会得到运行按钮。 ",
"提示用户输入一个数字",
0,
"发布脚本",
0,
"发布须遵守我们的 ",
"发布脚本...",
"在动画开始播放时引发",
"在动画停止播放时引发",
"以声波形式读取响应体",
"其他人查看您的推文或截取推文截图时；或者对推文发表评论或对你的评论进行回复时；或者发生与您的订阅相关的事件时，您会收到电子邮件通知。",
"请记住：发布脚本后，所有人都会看到您的脚本，所以请确保其中不包含您的密码或个人信息。",
"减少当前的生命值。",
"回复...",
"报告/删除",
"将图片调整为给定大小(单位: 像素)",
0,
"返回图像副本",
0,0,
"返回向此实例的值中添加指定月数的日期。",
"返回向此实例的值中添加指定年数的日期。",
"返回一个介于“最小值”和“最大值”（包括这两个值）之间的随机整数。",
0,0,0,0,0,0,0,
"如果当前实例无效，则返回 true",
0,0,0,0,
"脚本更新",
"由此用户编写：",
0,
"搜索和浏览互联网......",
"搜索代码...",
"搜索所有内容",
"在此搜索...",
0,0,
"搜索...",
0,0,0,
"查看更多",
0,0,
"将梯度设为开或关",
"设置应用于展示墙的 3x3 仿射矩阵转换。",
0,
"设置背景相机",
"设置背景色",
"设置背景色。",
"设置背景图片",
"设定水平居中位置(单位: 像素)",
"设置当前的生命值。",
"设定精灵 0 和 1 之间速度损失部分的默认摩擦",
"设置高度(单位: 像素)",
"设定位置(单位: 像素)",
0,
"获取从 0 (静音)到 1 (当前音量)的音量级别",
"设置速度（单位：像素/秒）",
"设置画面颜色。",
"设置游戏板上物体的均匀加速度矢量为像素/秒^2",
0,0,
"设置宽度(单位: 像素)",
"设置 x 轴速度(单位: 像素/秒)",
"设置 y 轴加速度(单位: 像素/秒^2)",
"设定 y 轴位置(单位: 像素)",
"设置 y 轴速度(单位: 像素/秒)",
0,
"设置",
"使用这个 URL 共享：",
"如果该脚本使用任何阻止它在这些平台上运行的 API，会在编辑器中显示错误。",
"显示墙上的板。",
0,
"技能等级：{0}     ",
0,0,0,0,0,
"停止并清除所有事件帧计时器",
0,
"减去数字",
0,
"TD100: 在此插入 {0:a}",
"TD101: ：无法找到“{0}”",
"TD109: 无法分配至此",
"TD111: 无法从 {0} 分配至 {1}",
"TD112: 找不到 {1} 的属性“{0}”",
"TD115: ：向 {0} 提供的参数过多",
"TD116: 没有向 {0} 提供足够参数",
"TD118: ：“if”条件需要 {1:a}",
"TD119: i 需要迭代对象",
0,
"TD130: “for”的边界需要 {1:a}",
"TD144: 好像缺了“{0}”，请补上",
"TD145: 此处好像缺一个运算符(如“+”、“(”或“，”)",
"TD147: 此处不应出现“{0}”",
"TD150: 无法调用“(”之前的东西",
"TD151: 未关闭的“(”",
"TD152: 意外的“)”",
"TD154: 运算符后不能为空",
"TD155: “{0}”无法分配到本地变量",
"讲授 Creative Coding！",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"此脚本使用以下功能: ",
0,
"本教程使用云数据，这些数据可与其他用户共享。",
"要添加页数据，请创建一个本地变量，然后点击“升级为字段”。",
0,0,0,0,
"Microsoft® Translator 进行的翻译，点击以查看原文...",
"如果接触到游戏板则为真",
"尝试调整代码，直到调整正确。如果卡住了，请点击教程栏。",
0,0,
"教程",
"Twitter",
"输入内容进行在线搜索...",
"键入以搜索...",
0,
"无法编辑事件参数的类型、顺序和数量。",
"UI 小组件",
0,
"更新板上精灵的位置。",
"更新子画面上的图片(如果是子画面)",
"更新文本精灵上的文本（如果是文本精灵）",
"上传图片",
"上传声音",
"用户",
0,
"我们需要更多选项",
"我们会让编辑器适应您的技能水平。您可以稍后在中心更改您的技能水平。",
"您的编程知识是什么水平？",
"您的职业是什么？",
"新增内容",
"您到底在哪里？",
"在给定位置写入另一张图片。 不透明度范围介于 0 (透明)和 1 (不透明)之间。",
0,
"YouTube",
0,0,
"您的 GitHub 用户。",
"您的 Minecraft 用户。",
"您的图形将在此处显示",
0,
"您的通道将在此处显示",
"您的电子邮件地址尚未验证。请检查您的收件箱。",
"您的全名",
0,0,0,
"您的脚本将显示在此处",
"你的 Twitter 帐号，例如 @touchdevelop。",
"几秒以前",
"函数",
"全局变量",
"一分钟以前",
"页",
"关于覆盖率",
"关于见解",
"关于个人资料",
"关于您",
"滥用",
0,
"滥用报告",
0,0,0,
"访问 {0} 字段",
0,
"添加",
"新增...",
0,
"为每一个显示帧添加一个动作。",
0,0,0,0,0,
"添加输入参数",
"在上面添加行",
"在下面添加行",
"新增",
0,0,
"添加输出参数",
0,0,0,0,0,
"所有 API",
"允许",
"惊人的、惊异的、惊骇的、令人敬畏的、可怕的、惊险的、一流的、酷、好奇的、独特的、特殊的、独一无二的、特别的、令人难以置信的、神奇的、令人愉快的、出色的 ",
0,
"函数类型定义",
"一小时以前",
0,0,0,0,0,
"应用",
0,
"图稿",
"图稿资源",
"任务",
0,
"作者",
0,0,
"返回",
0,
"退格",
"使用退格键删除",
0,0,
"基准版本",
"初学者",
"初学者",
0,
"绑定到脚本：",
"空白",
"空白应用",
"空白爬行者",
"空白文档",
"空白游戏",
"空白 Minecraft",
"空白 Minecraft pi",
"空白像素画",
"空白图片素材",
"空白脚本插件",
"空白乌龟",
"空白教程",
"调试器中断",
"断点",
0,0,0,0,0,0,
"取消",
0,0,
"改(回)到本地",
"更改内容",
"通道",
"检查是否已设置引用",
0,0,0,
"选择图片（1MB 以下，少于 2048x2048）",
0,0,0,0,0,0,
"选择您的编码技能水平",
"选择...",
0,
"清除",
"剪贴板",
"克隆",
0,
"云会话",
"代码",
"为终点线编码",
"编码员",
"颜色 #{0}",
"颜色： {0}",
"注释",
"注释",
0,
"条件",
"已连接",
0,0,
"继续",
0,
"复制",
"复制选定内容",
"覆盖率",
"创建",
"创建新参数",
0,0,0,0,
"创建空的对象集合",
"正在创建脚本",
0,
"当前表达式",
"自定义图片！",
"剪切",
"裁剪选定内容",
"数据库",
"调试",
"小数点",
0,
"删除",
"删除本地数据和权限",
"删除选定内容",
"降级到 var",
"拒绝",
"描述",
"描述（有助于搜索）",
0,
"详细信息",
"您是否想要使用此值？",
"diff curr",
"diff prev",
0,0,0,
"返回",
"显示值",
"在留言板上显示对象",
0,0,0,
"完成",
"完成！",
"编辑",
"else if",
"电子邮件",
0,
"电子邮件和推送通知",
0,0,0,0,
"输入邀请码",
"输入此代码",
"错误",
0,
"事件",
0,
"ex： ",
0,
"优秀；非常好；很棒；很酷；很牛；做得好；不错；做得对；正确",
0,
"退出",
"专家",
0,
"导出",
"导出内容的 JSON 表示",
"已从此库导出",
"扩展",
0,
"提取选定内容到函数",
0,
"提取到变量",
"查找引用",
"已完成",
"修复",
"在编辑器中按教程操作",
"针对小组",
"派生",
"函数",
"函数名称",
"函数类型",
"函数、变量、库...",
"性别",
"获取“是编程一小时™”证书",
"获取每个显示帧的计时器。",
"github 用户",
0,
"全局替换",
"全局变量",
"全局变量",
"返回",
"返回编码！{0}★ 待执行",
"返回...",
"转到",
"转至您的脚本中的事项列表",
"转到上一步",
"目标：",
"小组",
"团体",
"红心",
"帮助",
0,0,
"历史记录",
"万岁！你的脚本已成功发布",
"如何发现",
"我希望它运行的位置",
"我已完成 Hour of Code™",
"图标画： {0}",
0,
"如果卡住了，请点击终点线",
0,0,0,0,
"从 JSON 对象导入字段值",
0,0,0,0,
"惊人的、不可思议的、绝妙的、非凡的、令人兴奋的、令人难以置信的、神奇的、奇特的、杰出的、出色的、疯狂的、特别的、壮观的、令人吃惊的、令人惊叹的、超酷 ",
0,
"插入",
"插入注释",
"插入语句",
"插入 {0}",
"见解",
0,
"安装和加载脚本",
"到本地",
0,
"问题",
"加入小组",
"加入组",
0,
"只需继续输入搜索项！",
"继续编辑",
"知道这里：",
0,
"了解",
"了解有关发布的信息",
"了解更多",
"了解有关 {0} 的更多信息",
"离开教程",
"让我们改动一下",
"我们去做吧！",
"我们开始吧！",
"库",
"库",
"库",
"库名称",
"库参考",
"加载更多",
"加载更多回复",
"正在加载",
0,
"正在加载 /{0} 的注释...",
0,
"正在加载回复...",
"正在加载脚本",
"正在加载教程",
"正在加载...",
"本地",
"位置",
0,
"逻辑求反",
"日志",
"重点",
0,
"制造者",
"管理数据",
"以后再说",
"我",
0,0,
"minecraft 用户",
0,0,
"更多",
"更多 ",
"更多设置",
"移动光标",
"向左移动",
"进入下一步",
"将光标向左移动",
"将光标向右移动",
"我的图稿",
0,0,0,
"我的脚本",
"此处需要不同的名称",
"这里需要不同的字符串",
"此处需要一个新字段",
"需要参数",
"需要删除",
"需要在其他位置进行编辑",
"求反",
0,0,0,0,
"换行",
0,0,0,
"在下面添加新语句",
"新变量",
0,
"后续教程...",
"昵称",
0,
"该用户没有发布图片",
"无评论，点击以发表评论!",
"无叉子，请安装、编辑和重新发布脚本以创建一个！",
"没有红心。可以在安装脚本后添加一个！",
"尚未上载任何图片",
0,0,
"无标记，点击以填写标记!",
0,0,0,
"通知",
0,
"现在您可以选择 {0} 的一个属性；但它本身不执行任何操作",
"现在可以选择它的一个属性",
"数値",
"数字输入",
0,
"职业",
0,
"可脱机使用",
"确定",
"好的，我们来掷骰子吧！",
"联机",
0,
"或者点击获得帮助",
"其他",
"概述",
0,
"页",
0,
"解析脚本文本",
0,
"粘贴",
"暂停",
0,
"物理游戏入门",
"选取一个脚本模板...",
"图片",
"图片名称",
"图片名称（最少 4 个字符）",
"图片 URL",
"再玩一次",
"请稍等",
"请稍等...",
"插件",
"预览",
"打印",
0,
"私有",
"私有函数",
"个人资料",
"个人资料",
"编程知识",
0,
"升级为数据",
0,
"公开昵称",
"公开信息",
"发布",
"发布为隐藏项目",
0,
"已发布",
"拉进更改",
"退出到块级别",
0,
"重新运行",
"阅读更多...",
"只读",
"实际名称",
0,
"收到电子邮件通讯",
"接收电子邮件通知",
"记录名称：",
0,
"常规键盘",
"正在重新加载脚本",
"删除",
0,
"删除图片",
"删除白色背景（最适合游戏精灵）",
0,
"重命名",
"重复 n 次",
"对集合重复",
"重复条件",
"替换函数中的所有项",
"在脚本中替换全部",
"替换图片",
"已复制",
"已复制 ",
0,
"报告滥用",
0,
"还原到已发布版本",
"后退",
"后退 ",
"运行",
"运行主项",
0,
"带检测运行",
"保存",
"已保存",
"正在保存…",
"学校",
"屏幕",
"屏幕截图",
"{0} 的屏幕截图",
"脚本",
"脚本属性",
0,0,
"搜索图片",
"搜索图片",
"在此搜索 {0}",
"搜索模板",
"正在搜索...",
"参见更多选项",
"选择",
"选择更多",
"选择此行",
"请选择此 {0} 类型",
0,0,
"设置本地变量名称",
"设置名称",
"设定游戏板被击打时调用的处理程序",
"设置点击该板时调用的处理程序",
"设定游戏板被接触时调用的处理程序",
"设定游戏板触屏被放开时调用的处理程序",
"将所有字段设置为默认值",
"保存设置",
"设置",
"共享",
0,
"演示如何完成该活动",
"显示更多选项",
"展示",
"登录",
0,0,
"登出",
"正在登录...",
0,
"简化",
"保存的技能水平",
"跳过迭代",
0,
"社交",
0,
"声音",
0,
"splash screen 画： {0}",
"拆分",
0,
"重新开始",
"开始脚本",
"正在开始...",
0,
"单步进入",
"单步跳出",
"单步跳过",
0,
"停止",
0,
"停止函数",
"停止循环",
"存储在变量中",
"将值存储在变量中",
"字符串",
0,
"条带“{0}”",
0,0,0,
"出众的、不可思议的、令人恐怖的、令人难以置信的、神奇的、独一无二的、前所未有的、不寻常的、怪异的、美好的、奇妙的",
"包围",
0,0,
"正在同步...",
0,0,0,0,0,
"标记",
0,0,
"完成后点击（←）",
"完成后点击 [确定]",
0,
"点击此处可进入下一步",
"完成后点击这里",
"点击这里",
"点击此处获取说明",
"点击这里运行应用",
"点击以更改颜色",
"轻敲以改变图标画",
"轻敲以改变 splash screen 图片",
"点击以使用 Microsoft® Translator 进行翻译...",
"临时",
"terms of use",
"测试",
"测试函数",
"测试",
"测试两个引用是否指向同一对象",
0,0,
"中心",
"邀请码的长度必须在 9 到 64 个字符之间",
"崩溃的脚本",
0,0,
"此脚本是一个库",
"此脚本是一项 Web 服务",
0,
"到代码",
"继续",
"到全局变量",
"切换断点",
"最新内容",
0,0,
"翻译",
"正在翻译教程...",
0,0,0,
"再试一次！",
"变为",
"教程进度",
"教程： ",
"教程",
"Twitter 帐户",
"类型： ",
"类型：{0}",
0,0,0,
"撤消",
0,0,0,0,0,0,0,0,0,0,
"更新",
0,0,0,0,0,0,
"上载",
"上传图片",
"上载屏幕截图",
"上传声音",
0,0,0,
"URL",
0,0,0,0,0,
"变量名称",
"以脚本形式查看",
"查看/编辑姓名、电子邮件…",
0,
"壁纸",
"此处有一个库“{0}”；{1}",
"此处为{0:a}；是否要对其执行操作？",
"我们需要一个新字段",
"我们需要一个新表",
"我们需要一个新的 {0}",
"我们需要不同的键盘",
"我们需要一个新变量",
"我们需要编辑另一项内容",
"我们将逐步引导您完成",
"网络应用",
0,0,0,
"网站",
0,
"网站 URL",
0,0,0,0,0,
"出生年份",
0,0,
"您已完成任务!",
0,
"{0} ({1} 行{1:s})",
"{0} 天以前",
"{0} 下",
0,0,0,
"{0} 小时以前",
"{0} 分钟以前",
"{0} 个月以前",
"{0} 个(共 {1} 个)已完成",
"发布 {0} 个",
"已发布 {0} 个脚本",
"{0} 秒以前",
"上升 {0} 个",
"{0} 年以前"
]); return true; }

if (lang == "zh-TW") { TDev.Util._setLanguageArray(keys, [
"   Maybe: {0} ({1} at '{2}')\n",
"  -> Line {2} ('{1}'), error: {0}\n{3}",
" — — 局部变量",
" [class]",
" [隐藏]",
" [override]",
" 返回",
" 前进",
" 小时 ",
" 分钟 ",
" 的 ",
" 秒 ",
" 发送更改",
" 等待服务器",
"# # # 完整源代码",
"Javascripty 花括号，以及所有工具，适合于有经验的开发人员!",
"“atomic”函数",
"'盒子' 只能在页面显示代码中访问",
"'盒子' 无法访问在 HTML 布局模式中",
"'else' 的前面的 'if' 必须是空的",
"'html' 只能访问 HTML 布局模式",
"“{0}”认为此处应为 {1}",
"'{0}' 包含不支持的签名",
"'{0}' 当前未执行",
"'{0}' 已过期且不能实现",
"“{0}”已弃用，不应使用。",
"'{0}' 不是一个字符串资源",
"“{0}”返回“{1}”；{2}",
"'{0}' 返回 {1} 的值; 你可以使用 '储存在var' 按钮来将它们保存到本地",
"(可选) 与信息有关的错误，用来提供有关错误的额外信息的客户端开发者确定人类可读的 web 页的 URI。",
"(可选) 人类可读的错误代码。",
"(可选)未涵盖的 OAuth 2.0 规范的附加键值对。",
"(可选) 指示是否令牌可能在下一秒内已过期。",
"(可选)可选，如果相同范围由客户端请求;否则，访问令牌的范围如 OAuth 2.0 规范第 3.3 节所述。",
"(可选) 以秒为单位的访问令牌生存期。",
"(请等一等，它会占用至多一分钟)",
"，而获得了 {0:a}",
"，获得了 {0}",
"大小: {0} 字符",
". 请阅读我们 ",
"...... 这儿没什么可看...",
"... 有更多...",
"// 注释",
"1.选择一个文档 (.txt、.pptx，.pdf、.css，小于 8 Mb)",
"1. 选择 MP3 声音 (小于 1 MB)",
"2. 给它一个名称 (最低 4 个字符)",
"3. 描述它",
"4. 发布",
":(抱歉，这个文本翻译时出错。",
":(对不起，我们不能翻译此。",
":(找不到任何视频源",
":(无效的视频信息",
"; 是否缺少 → ◈ref?",
"<a href='http://cordova.apache.org/' target='_blank'> Apache Cordova</a> 让您构建跨平台的移动应用程序。",
"<a href='http://go.microsoft.com/fwlink/?LinkId=254432' target='_blank'> 生成的证书</a>.",
"<b>免责声明:</b>这个 web 应用程序不是由微软认可的。",
"<b>如何本地运行本程序</b>",
"<b>此行正确无误！</b>我们继续吧",
"<h3>正在加载当前设置...</h3>",
"<h3>没有更多的提示!</h3>",
"<h3>欢迎来到Touch Develop</h3>",
"<h3>{0:q} 需要签到</h3>",
"<p>如果你没有Azure订阅，去 <a href='https://account.windowsazure.com/Subscriptions' target='_blank'> Azure订阅</a> 获取.</p>",
"<p>Touch Develop使您可以 <b>轻松地创建应用程序</b> 来自您的手机、 平板电脑或 PC。</p>",
"<p>你可以与他人分享您的应用程序，因此他们可以 <b>运行和编辑</b> 他们在 Windows Phone、 iPad、 iPhone、 Android、 PC 或 mac上。</p>",
"<strong>beta 测试中的新功能:</strong> 的语法和语义的更改",
"<strong>所需的平台:</strong>",
"超出范围，@hi/lo",
"数字 2D 矩阵",
"一个三维向量",
"Bing 地图",
"Minecraft Pi 应用。",
"Minecraft 应用。",
"Minecraft 爬虫应用。",
"服务器发送事件的客户端",
"对sprite属性进行动画处理的动画",
"Argb 颜色 (alpha、 红色、 绿色、 蓝色)",
"背景场景图层",
"一个初学者友好编辑器",
"打造2D 游戏的开发板",
"创建 HTML 表单数据的生成器",
"云计算数据会议",
"对象集",
"Sprites集",
"颜色常量",
"日期和时间的组合",
"添加了有关您拉请求的注释。",
"联系人",
"自定义记录器",
"文档",
"文档资源",
0,0,0,
"全局变量",
0,0,0,0,0,0,0,0,0,0,0,
"数値 (負 / 小数の場合もある)",
"数字常量",
0,0,0,
"图片",
"一段文本",
"像素画应用。",
0,0,0,
"对库脚本的引用",
0,0,0,0,0,0,0,0,0,
"声效",
0,0,0,0,
"用户数据结构",
"包含用户定义行的表",
0,0,0,0,0,
"您公开信息的唯一显示名称（至少 8 个字符）",
0,0,
"用户界面",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"添加对每一显示帧触发的动作",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"增加数字",
0,
"给当前分数添加值。",
0,0,
"在脚本停止后，浏览代码以查看收集到的信息。",
"我的所有组",
"我的所有脚本",
0,0,0,0,0,0,0,
"使用页面和方框的空白应用。",
"使用图片素材库的空白应用。",
"空白文档页。",
"空白交互式教程。",
"空白脚本编辑器插件。",
"不执行任何操作的空白脚本。",
0,0,
"包含用户定义行的索引表",
0,
"乌龟应用。",
"对输入集合的所有元素应用“转换器”并返回结果集",
0,
"你确定你想停止下面的教程吗？",
0,
"由此用户绘制：",
0,
"向其他对象附加数据",
"用于创建游戏的样板文件代码。",
0,0,0,
"相机、 位置、 麦克风和其他传感器",
0,0,
"更改技能等级！",
0,
"检查该板是否和另一板的距离相同。",
0,0,0,
"清除与此板有关的所有排队事件",
"清除背景图片",
"清除背景相机",
0,0,
"用户交流时分享的代码",
"执行特定任务的代码",
"比较数字是否相等",
"比较数字以确定更小值",
0,
"比较数字以确定更大值",
0,0,0,0,0,0,0,
"连接两段文本",
0,0,0,0,0,0,
"转换为本地时间",
0,0,0,0,0,
"创建组",
"创建脚本",
"用给定的起点、宽度和高度创建一个线障碍。粘性的弹性为 0，1 为完全反弹。",
"新建画面集合。",
"新建椭圆画面。",
"新建图片画面。",
"创建一个新的长方形精灵。",
0,
"创建新的精灵表单。",
"创建新的文本画面。",
"在两个精灵之间创建一个跳板。",
"创建一个锚精灵。",
"创建此对象类型的无效值",
"创建通道",
0,
"创建无效的值",
"在给定的距离处创建板的四周。",
"创建自己的应用",
0,0,
"创建新的空白游戏板并使之在屏幕上显示。",
0,0,0,
"用给定图片创建宽度为 100 的新精灵。",
0,
"创建无效的游戏手柄实例",
0,0,
"当前设备",
0,
"当前触点",
"从事件中分离处理程序。",
0,
"将图像显示到展示墙上；稍后如果您希望所做更改生效，则需要调用“展示墙更新”。",
0,0,0,
"显示墙上游戏手柄的状态",
0,
"子画面是否重叠",
0,
"文档",
"完成编辑后，不要忘记向下滚动，然后点击“保存”！",
"拖放功能块，界面简单，适合于初学者！",
"在两点之间画一条线",
"用给定颜色和字号绘制一些文本边框",
"将代码编辑为文本，以及其他更多选项，适合于应用程序编写爱好者！",
0,0,
"输入名称",
0,
"请输入有关您的个人信息",
"请输入您个人网站的 URL（例如：http://www.northwindtraders.com）",
"输入邀请码",
0,
"事件不能有输出参数。",
"每个人将能够用于在 Internet 上看到你的图片。 ",
0,0,
"扩展",
"Facebook",
"用给定颜色填充椭圆",
"用给定颜色填充矩形",
"接触结束后的最终接触速度",
"对于已发布的脚本，还可查看已发布脚本页上的选项卡，查找匿名收集的众多个人资料和覆盖率数据。",
"论坛",
"从现在开始，我们不会向您显示要编写的代码。按照指示进行操作，如果您认为已完成，请单击运行。",
"当前脚本中的函数",
0,0,0,0,0,
"获取游戏手柄的状态快照（如果连接到浏览器）。如果不支持或未连接游戏手柄则为空。",
0,0,0,
"获取值，该值表示该板是否被设计为在景观模式中查看",
"获取歌曲是否受 DRM 保护的信息",
"获得所选定轴线的 x 和 y 值。",
0,0,
"获取背景场景",
"获取水平居中位置(单位: 像素)",
0,
"获取 ARGB 值为 #00FFFFFF 的颜色",
"获取 ARGB 值为 #FF000000 的颜色",
"获取 ARGB 值为 #FF0000FF 的颜色",
"获取 ARGB 值为 #FF008000 的颜色",
"获取 ARGB 值为 #FF00FFFF 的颜色",
0,
"获取 ARGB 值为 #FF800080 的颜色",
0,0,0,0,
"获取 ARGB 值为 #FFFF0000 的颜色",
"获取 ARGB 值为 #FFFF00FF 的颜色",
"获取 ARGB 值为 #FFFFA500 的颜色",
0,
"获取 ARGB 值为 #FFFFFF00 的颜色",
"获取 ARGB 值为 #FFFFFFFF 的颜色",
0,0,0,0,
"获得可用的第一个连接的游戏手柄",
0,
"获得游戏手柄标识符",
0,
"获取高度(单位: 像素)",
"获取相机图像的高度(单位: 像素)。",
0,0,0,0,0,0,0,0,0,
"获得玩家索引",
"获得按钮的按下值。如果按钮缺失则返回 0。",
0,
"获取从 0 (静音)到 1 (当前音量)的音量",
"获得精灵数目",
"获取由 i 索引的精灵",
0,
"获得这次快照的时间戳",
0,
"获取宽度(单位: 像素)",
"获取相机图像的宽度(单位: 像素)。",
"获取 y 轴位置(单位: 像素)",
"快速入门",
0,
"当前脚本中的全局变量",
0,0,0,0,0,0,0,0,0,0,0,0,0,
"在调试模式，游戏板显示精灵的速度和其他信息",
"表示按钮是否被按下。如果按钮缺失则返回 false。",
0,
"表示游戏手柄数据是否相同",
"表示游戏手柄是否仍被连接。",
0,0,0,0,
"插入“{0}”{1}",
0,
"标记 * 的项为必填项。",
"JSON 数据",
"加入组",
"最后接触终点",
"最后接触起点",
0,0,0,0,0,
"使更新可见。",
0,0,
"确保所有画面都在屏幕的边界上弹起",
0,
"数学擅长程度，绝对值，最大值",
"Me",
0,
"Minecraft 用户",
"更多",
0,
"将画面向其他画面移动。",
"乘以数字",
0,0,0,0,0,0,0,0,
"新脚本",
0,
"新颜色或内置颜色",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"电话号码、 振动、 等...",
0,
"选取随机颜色",
"图片和音乐......",
0,0,0,0,0,
"请查看我们的隐私声明。",
0,
"发表评论...",
0,0,0,
"隐藏动作不会得到运行按钮。 ",
"提示用户输入一个数字",
0,
"发布脚本",
0,
"发布须遵守我们的 ",
"发布脚本...",
"在动画开始播放时引发",
"在动画停止播放时引发",
"以声波形式读取响应体",
"其他人查看您的推文或截取推文截图时；或者对推文发表评论或对你的评论进行回复时；或者发生与您的订阅相关的事件时，您会收到电子邮件通知。",
"请记住：发布脚本后，所有人都会看到您的脚本，所以请确保其中不包含您的密码或个人信息。",
"减少当前的生命值。",
"回复...",
"报告/删除",
"将图片调整为给定大小(单位: 像素)",
0,
"返回图像副本",
0,0,
"返回向此实例的值中添加指定月数的日期。",
"返回向此实例的值中添加指定年数的日期。",
"返回一个介于“最小值”和“最大值”（包括这两个值）之间的随机整数。",
0,0,0,0,0,0,0,
"如果当前实例无效，则返回 true",
0,0,0,0,
"脚本更新",
"由此用户编写：",
0,
"搜索和浏览互联网......",
"搜索代码...",
"搜索所有内容",
"在此搜索...",
0,0,
"搜索...",
0,0,0,
"查看更多",
0,0,
"将梯度设为开或关",
"设置应用于展示墙的 3x3 仿射矩阵转换。",
0,
"设置背景相机",
"设置背景色",
"设置背景色。",
"设置背景图片",
"设定水平居中位置(单位: 像素)",
"设置当前的生命值。",
"设定精灵 0 和 1 之间速度损失部分的默认摩擦",
"设置高度(单位: 像素)",
"设定位置(单位: 像素)",
0,
"获取从 0 (静音)到 1 (当前音量)的音量级别",
"设置速度（单位：像素/秒）",
"设置画面颜色。",
"设置游戏板上物体的均匀加速度矢量为像素/秒^2",
0,0,
"设置宽度(单位: 像素)",
"设置 x 轴速度(单位: 像素/秒)",
"设置 y 轴加速度(单位: 像素/秒^2)",
"设定 y 轴位置(单位: 像素)",
"设置 y 轴速度(单位: 像素/秒)",
0,
"设置",
"使用这个 URL 共享：",
"如果该脚本使用任何阻止它在这些平台上运行的 API，会在编辑器中显示错误。",
"显示墙上的板。",
0,
"技能等级：{0}     ",
0,0,0,0,0,
"停止并清除所有事件帧计时器",
0,
"减去数字",
0,
"TD100: 在此插入 {0:a}",
"TD101: ：无法找到“{0}”",
"TD109: 无法分配至此",
"TD111: 无法从 {0} 分配至 {1}",
"TD112: 找不到 {1} 的属性“{0}”",
"TD115: ：向 {0} 提供的参数过多",
"TD116: 没有向 {0} 提供足够参数",
"TD118: ：“if”条件需要 {1:a}",
"TD119: i 需要迭代对象",
0,
"TD130: “for”的边界需要 {1:a}",
"TD144: 好像缺了“{0}”，请补上",
"TD145: 此处好像缺一个运算符(如“+”、“(”或“，”)",
"TD147: 此处不应出现“{0}”",
"TD150: 无法调用“(”之前的东西",
"TD151: 未关闭的“(”",
"TD152: 意外的“)”",
"TD154: 运算符后不能为空",
"TD155: “{0}”无法分配到本地变量",
"讲授 Creative Coding！",
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"此脚本使用以下功能: ",
0,
"本教程使用云数据，这些数据可与其他用户共享。",
"要添加页数据，请创建一个本地变量，然后点击“升级为字段”。",
0,0,0,0,
"Microsoft® Translator 进行的翻译，点击以查看原文...",
"如果接触到游戏板则为真",
"尝试调整代码，直到调整正确。如果卡住了，请点击教程栏。",
0,0,
"教程",
"Twitter",
"输入内容进行在线搜索...",
"键入以搜索...",
0,
"无法编辑事件参数的类型、顺序和数量。",
"UI 小组件",
0,
"更新板上精灵的位置。",
"更新子画面上的图片(如果是子画面)",
"更新文本精灵上的文本（如果是文本精灵）",
"上传图片",
"上传声音",
"用户",
0,
"我们需要更多选项",
"我们会让编辑器适应您的技能水平。您可以稍后在中心更改您的技能水平。",
"您的编程知识是什么水平？",
"您的职业是什么？",
"新增内容",
"您到底在哪里？",
"在给定位置写入另一张图片。 不透明度范围介于 0 (透明)和 1 (不透明)之间。",
0,
"YouTube",
0,0,
"您的 GitHub 用户。",
"您的 Minecraft 用户。",
"您的图形将在此处显示",
0,
"您的通道将在此处显示",
"您的电子邮件地址尚未验证。请检查您的收件箱。",
"您的全名",
0,0,0,
"您的脚本将显示在此处",
"你的 Twitter 帐号，例如 @touchdevelop。",
"几秒以前",
"函数",
"全局变量",
"一分钟以前",
"页",
"关于覆盖率",
"关于见解",
"关于个人资料",
"关于您",
"滥用",
0,
"滥用报告",
0,0,0,
"访问 {0} 字段",
0,
"添加",
"新增...",
0,
"为每一个显示帧添加一个动作。",
0,0,0,0,0,
"添加输入参数",
"在上面添加行",
"在下面添加行",
"新增",
0,0,
"添加输出参数",
0,0,0,0,0,
"所有 API",
"允许",
"惊人的、惊异的、惊骇的、令人敬畏的、可怕的、惊险的、一流的、酷、好奇的、独特的、特殊的、独一无二的、特别的、令人难以置信的、神奇的、令人愉快的、出色的 ",
0,
"函数类型定义",
"一小时以前",
0,0,0,0,0,
"应用",
0,
"图稿",
"图稿资源",
"任务",
0,
"作者",
0,0,
"返回",
0,
"退格",
"使用退格键删除",
0,0,
"基准版本",
"初学者",
"初学者",
0,
"绑定到脚本：",
"空白",
"空白应用",
"空白爬行者",
"空白文档",
"空白游戏",
"空白 Minecraft",
"空白 Minecraft pi",
"空白像素画",
"空白图片素材",
"空白脚本插件",
"空白乌龟",
"空白教程",
"调试器中断",
"断点",
0,0,0,0,0,0,
"取消",
0,0,
"改(回)到本地",
"更改内容",
"通道",
"检查是否已设置引用",
0,0,0,
"选择图片（1MB 以下，少于 2048x2048）",
0,0,0,0,0,0,
"选择您的编码技能水平",
"选择...",
0,
"清除",
"剪贴板",
"克隆",
0,
"云会话",
"代码",
"为终点线编码",
"编码员",
"颜色 #{0}",
"颜色： {0}",
"注释",
"注释",
0,
"条件",
"已连接",
0,0,
"继续",
0,
"复制",
"复制选定内容",
"覆盖率",
"创建",
"创建新参数",
0,0,0,0,
"创建空的对象集合",
"正在创建脚本",
0,
"当前表达式",
"自定义图片！",
"剪切",
"裁剪选定内容",
"数据库",
"调试",
"小数点",
0,
"删除",
"删除本地数据和权限",
"删除选定内容",
"降级到 var",
"拒绝",
"描述",
"描述（有助于搜索）",
0,
"详细信息",
"您是否想要使用此值？",
"diff curr",
"diff prev",
0,0,0,
"返回",
"显示值",
"在留言板上显示对象",
0,0,0,
"完成",
"完成！",
"编辑",
"else if",
"电子邮件",
0,
"电子邮件和推送通知",
0,0,0,0,
"输入邀请码",
"输入此代码",
"错误",
0,
"事件",
0,
"ex： ",
0,
"优秀；非常好；很棒；很酷；很牛；做得好；不错；做得对；正确",
0,
"退出",
"专家",
0,
"导出",
"导出内容的 JSON 表示",
"已从此库导出",
"扩展",
0,
"提取选定内容到函数",
0,
"提取到变量",
"查找引用",
"已完成",
"修复",
"在编辑器中按教程操作",
"针对小组",
"派生",
"函数",
"函数名称",
"函数类型",
"函数、变量、库...",
"性别",
"获取“是编程一小时™”证书",
"获取每个显示帧的计时器。",
"github 用户",
0,
"全局替换",
"全局变量",
"全局变量",
"返回",
"返回编码！{0}★ 待执行",
"返回...",
"转到",
"转至您的脚本中的事项列表",
"转到上一步",
"目标：",
"小组",
"团体",
"红心",
"帮助",
0,0,
"历史记录",
"万岁！你的脚本已成功发布",
"如何发现",
"我希望它运行的位置",
"我已完成 Hour of Code™",
"图标画： {0}",
0,
"如果卡住了，请点击终点线",
0,0,0,0,
"从 JSON 对象导入字段值",
0,0,0,0,
"惊人的、不可思议的、绝妙的、非凡的、令人兴奋的、令人难以置信的、神奇的、奇特的、杰出的、出色的、疯狂的、特别的、壮观的、令人吃惊的、令人惊叹的、超酷 ",
0,
"插入",
"插入注释",
"插入语句",
"插入 {0}",
"见解",
0,
"安装和加载脚本",
"到本地",
0,
"问题",
"加入小组",
"加入组",
0,
"只需继续输入搜索项！",
"继续编辑",
"知道这里：",
0,
"了解",
"了解有关发布的信息",
"了解更多",
"了解有关 {0} 的更多信息",
"离开教程",
"让我们改动一下",
"我们去做吧！",
"我们开始吧！",
"库",
"库",
"库",
"库名称",
"库参考",
"加载更多",
"加载更多回复",
"正在加载",
0,
"正在加载 /{0} 的注释...",
0,
"正在加载回复...",
"正在加载脚本",
"正在加载教程",
"正在加载...",
"本地",
"位置",
0,
"逻辑求反",
"日志",
"重点",
0,
"制造者",
"管理数据",
"以后再说",
"我",
0,0,
"minecraft 用户",
0,0,
"更多",
"更多 ",
"更多设置",
"移动光标",
"向左移动",
"进入下一步",
"将光标向左移动",
"将光标向右移动",
"我的图稿",
0,0,0,
"我的脚本",
"此处需要不同的名称",
"这里需要不同的字符串",
"此处需要一个新字段",
"需要参数",
"需要删除",
"需要在其他位置进行编辑",
"求反",
0,0,0,0,
"换行",
0,0,0,
"在下面添加新语句",
"新变量",
0,
"后续教程...",
"昵称",
0,
"该用户没有发布图片",
"无评论，点击以发表评论!",
"无叉子，请安装、编辑和重新发布脚本以创建一个！",
"没有红心。可以在安装脚本后添加一个！",
"尚未上载任何图片",
0,0,
"无标记，点击以填写标记!",
0,0,0,
"通知",
0,
"现在您可以选择 {0} 的一个属性；但它本身不执行任何操作",
"现在可以选择它的一个属性",
"数値",
"数字输入",
0,
"职业",
0,
"可脱机使用",
"确定",
"好的，我们来掷骰子吧！",
"联机",
0,
"或者点击获得帮助",
"其他",
"概述",
0,
"页",
0,
"解析脚本文本",
0,
"粘贴",
"暂停",
0,
"物理游戏入门",
"选取一个脚本模板...",
"图片",
"图片名称",
"图片名称（最少 4 个字符）",
"图片 URL",
"再玩一次",
"请稍等",
"请稍等...",
"插件",
"预览",
"打印",
0,
"私有",
"私有函数",
"个人资料",
"个人资料",
"编程知识",
0,
"升级为数据",
0,
"公开昵称",
"公开信息",
"发布",
"发布为隐藏项目",
0,
"已发布",
"拉进更改",
"退出到块级别",
0,
"重新运行",
"阅读更多...",
"只读",
"实际名称",
0,
"收到电子邮件通讯",
"接收电子邮件通知",
"记录名称：",
0,
"常规键盘",
"正在重新加载脚本",
"删除",
0,
"删除图片",
"删除白色背景（最适合游戏精灵）",
0,
"重命名",
"重复 n 次",
"对集合重复",
"重复条件",
"替换函数中的所有项",
"在脚本中替换全部",
"替换图片",
"已复制",
"已复制 ",
0,
"报告滥用",
0,
"还原到已发布版本",
"后退",
"后退 ",
"运行",
"运行主项",
0,
"带检测运行",
"保存",
"已保存",
"正在保存…",
"学校",
"屏幕",
"屏幕截图",
"{0} 的屏幕截图",
"脚本",
"脚本属性",
0,0,
"搜索图片",
"搜索图片",
"在此搜索 {0}",
"搜索模板",
"正在搜索...",
"参见更多选项",
"选择",
"选择更多",
"选择此行",
"请选择此 {0} 类型",
0,0,
"设置本地变量名称",
"设置名称",
"设定游戏板被击打时调用的处理程序",
"设置点击该板时调用的处理程序",
"设定游戏板被接触时调用的处理程序",
"设定游戏板触屏被放开时调用的处理程序",
"将所有字段设置为默认值",
"保存设置",
"设置",
"共享",
0,
"演示如何完成该活动",
"显示更多选项",
"展示",
"登录",
0,0,
"登出",
"正在登录...",
0,
"简化",
"保存的技能水平",
"跳过迭代",
0,
"社交",
0,
"声音",
0,
"splash screen 画： {0}",
"拆分",
0,
"重新开始",
"开始脚本",
"正在开始...",
0,
"单步进入",
"单步跳出",
"单步跳过",
0,
"停止",
0,
"停止函数",
"停止循环",
"存储在变量中",
"将值存储在变量中",
"字符串",
0,
"条带“{0}”",
0,0,0,
"出众的、不可思议的、令人恐怖的、令人难以置信的、神奇的、独一无二的、前所未有的、不寻常的、怪异的、美好的、奇妙的",
"包围",
0,0,
"正在同步...",
0,0,0,0,0,
"标记",
0,0,
"完成后点击（←）",
"完成后点击 [确定]",
0,
"点击此处可进入下一步",
"完成后点击这里",
"点击这里",
"点击此处获取说明",
"点击这里运行应用",
"点击以更改颜色",
"轻敲以改变图标画",
"轻敲以改变 splash screen 图片",
"点击以使用 Microsoft® Translator 进行翻译...",
"临时",
"terms of use",
"测试",
"测试函数",
"测试",
"测试两个引用是否指向同一对象",
0,0,
"中心",
"邀请码的长度必须在 9 到 64 个字符之间",
"崩溃的脚本",
0,0,
"此脚本是一个库",
"此脚本是一项 Web 服务",
0,
"到代码",
"继续",
"到全局变量",
"切换断点",
"最新内容",
0,0,
"翻译",
"正在翻译教程...",
0,0,0,
"再试一次！",
"变为",
"教程进度",
"教程： ",
"教程",
"Twitter 帐户",
"类型： ",
"类型：{0}",
0,0,0,
"撤消",
0,0,0,0,0,0,0,0,0,0,
"更新",
0,0,0,0,0,0,
"上载",
"上传图片",
"上载屏幕截图",
"上传声音",
0,0,0,
"URL",
0,0,0,0,0,
"变量名称",
"以脚本形式查看",
"查看/编辑姓名、电子邮件…",
0,
"壁纸",
"此处有一个库“{0}”；{1}",
"此处为{0:a}；是否要对其执行操作？",
"我们需要一个新字段",
"我们需要一个新表",
"我们需要一个新的 {0}",
"我们需要不同的键盘",
"我们需要一个新变量",
"我们需要编辑另一项内容",
"我们将逐步引导您完成",
"网络应用",
0,0,0,
"网站",
0,
"网站 URL",
0,0,0,0,0,
"出生年份",
0,0,
"您已完成任务!",
0,
"{0} ({1} 行{1:s})",
"{0} 天以前",
"{0} 下",
0,0,0,
"{0} 小时以前",
"{0} 分钟以前",
"{0} 个月以前",
"{0} 个(共 {1} 个)已完成",
"发布 {0} 个",
"已发布 {0} 个脚本",
"{0} 秒以前",
"上升 {0} 个",
"{0} 年以前"
]); return true; }


    return false;
}

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Node;
        (function (Node) {
            if (typeof require === "undefined") {
                window.require = function (name) {
                    return {};
                };
            }
            var fs = require("fs");
            var crypto = require("crypto");
            var querystring = require("querystring");
            var url = require("url");
            var util = require("util");
            var http = require("http");
            var https = require("https");
            var zlib = require("zlib");
            var path = require("path");
            var domain = require("domain");
            var net = require("net");
            var Buffer;
            var webSocketModule;
            function setupGlobalAgent() {
                var maxSock = 15;
                var Agent = http.Agent;
                var AgentSSL = https.Agent;
                function buildAgent(self) {
                    self.removeAllListeners('free');
                    self.on('free', function (socket, host, port) {
                        var name = host + ':' + port;
                        if (self.requests[name] && self.requests[name].length) {
                            self.requests[name].shift().onSocket(socket);
                        }
                        else {
                            var onIdleError = function () {
                                socket.destroy();
                            };
                            socket._onIdleError = onIdleError;
                            socket.on('error', onIdleError);
                        }
                    });
                    self.addRequestNoreuse = self.addRequest;
                    self.addRequest = function (req, host, port) {
                        var name = host + ':' + port;
                        var socks = this.sockets[name];
                        if (socks) {
                            for (var i = 0; i < socks.length; ++i) {
                                var idleSocket = socks[i];
                                if (idleSocket._onIdleError) {
                                    idleSocket.removeListener('error', idleSocket._onIdleError);
                                    delete idleSocket._onIdleError;
                                    req._reusedSocket = true;
                                    req.onSocket(idleSocket);
                                    return;
                                }
                            }
                        }
                        this.addRequestNoreuse(req, host, port);
                    };
                }
                function ReuseAgent(options) {
                    Agent.call(this, options);
                    buildAgent(this);
                }
                util.inherits(ReuseAgent, Agent);
                function ReuseAgentSSL(options) {
                    AgentSSL.call(this, options);
                    buildAgent(this);
                }
                util.inherits(ReuseAgentSSL, AgentSSL);
                if (/^v0\.10/.test(process.version))
                    Node.mkAgent = function (p) { return p == "https:" ? new ReuseAgentSSL({ maxSockets: maxSock }) : new ReuseAgent({ maxSockets: maxSock }); };
                else
                    Node.mkAgent = function (p) { return p == "https:" ? new AgentSSL({ maxSockets: maxSock, keepAlive: true }) : new Agent({ maxSockets: maxSock, keepAlive: true }); };
                Node.httpAgent = http.globalAgent = Node.mkAgent("http:");
                Node.httpsAgent = https.globalAgent = Node.mkAgent("https:");
            }
            Node.httpAgent, Node.httpsAgent;
            Node.mkAgent;
            Node.logInfo = function (s) { return TDev.Util.log(s); };
            Node.logError = function (s) { return TDev.Util.log(s); };
            Node.handleError = function (err) {
                if (err.rtProtectHandled)
                    return;
                if (host)
                    host.exceptionHandler(err);
                else
                    RT.App.logException(err);
            };
            var FsTable = (function () {
                function FsTable(tableName) {
                    this.tableName = tableName;
                    this.cache = {};
                    this.numWrites = 0;
                    this.path = "data/" + this.tableName + "/";
                    if (!fs.existsSync("data"))
                        fs.mkdirSync("data");
                    if (!fs.existsSync(this.path))
                        fs.mkdirSync(this.path);
                }
                FsTable.prototype.encode = function (s) {
                    return s.replace(/[^a-z0-9\-]/g, function (c) { return "_" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4); });
                };
                FsTable.prototype.decode = function (s) {
                    return s.toLowerCase().replace(/_([0-9a-f]{4})/g, function (a, b) { return String.fromCharCode(parseInt(b, 16)); });
                };
                FsTable.prototype.getValueAsync = function (key) {
                    var _this = this;
                    if (this.cache.hasOwnProperty(key))
                        return TDev.Promise.as(this.cache[key]);
                    var prevWrites = this.numWrites;
                    var r = new TDev.PromiseInv();
                    fs.readFile(this.path + this.encode(key), "utf8", function (err, data) {
                        if (err)
                            r.success(undefined);
                        else {
                            if (data.length < 256 && _this.numWrites == prevWrites)
                                _this.cache[key] = data;
                            r.success(data);
                        }
                    });
                    return r;
                };
                FsTable.prototype.getItemsAsync = function (keys) {
                    var _this = this;
                    var items = {};
                    var promises = keys.map(function (k) { return _this.getValueAsync(k).then(function (v) { return items[k] = v; }); });
                    return TDev.Promise.join(promises).then(function (v) { return items; });
                };
                FsTable.prototype.getKeysAsync = function () {
                    var _this = this;
                    var r = new TDev.PromiseInv();
                    fs.readdir(this.path, function (err, files) {
                        if (err)
                            r.error(err);
                        else
                            r.success(files.map(function (s) { return _this.decode(s); }));
                    });
                    return r;
                };
                FsTable.prototype.setItemAsync = function (key, val) {
                    var _this = this;
                    var r = new TDev.PromiseInv();
                    var temp = this.path + TDev.Random.uniqueId();
                    fs.writeFile(temp, val, function (err) {
                        if (err)
                            r.error(err);
                        else
                            fs.rename(temp, _this.path + _this.encode(key), function (err) {
                                if (err)
                                    r.error(err);
                                else {
                                    if (val.length < 256)
                                        _this.cache[key] = val;
                                    else
                                        delete _this.cache[key];
                                    _this.numWrites++;
                                    r.success(null);
                                }
                            });
                    });
                    return r;
                };
                FsTable.prototype.setItemsAsync = function (items) {
                    var _this = this;
                    var keys = Object.keys(items);
                    if (keys.length == 1)
                        return this.setItemAsync(keys[0], items[keys[0]]);
                    else
                        return TDev.Promise.join(Object.keys(items).map(function (k) { return _this.setItemAsync(k, items[k]); })).then(function (v) { return null; });
                };
                return FsTable;
            })();
            var TheNodeRuntime = (function (_super) {
                __extends(TheNodeRuntime, _super);
                function TheNodeRuntime(nodeHost, wsServer) {
                    _super.call(this, new TDev.Revisions.Sessions(wsServer));
                    this.nodeHost = nodeHost;
                    this.wsServer = wsServer;
                    this.routes = {};
                    this.restInits = [];
                    this.mainActionRef = null;
                    this.nodeModules = {};
                }
                TheNodeRuntime.prototype.initPageStack = function () {
                };
                TheNodeRuntime.prototype.getUserId = function () {
                    var req = this.getRestRequest();
                    if (req && req._user)
                        return req._user.id();
                    return null;
                };
                TheNodeRuntime.prototype.postBoxedText = function (s) {
                    TDev.Util.log("WALL: " + s);
                    return undefined;
                };
                TheNodeRuntime.prototype.postBoxedTextWithTap = function (s, rtV) {
                    return this.postBoxedText(s);
                };
                TheNodeRuntime.prototype.dispatchServerRequest = function (req, promise) {
                    var _this = this;
                    var path = unescape(req._api_path.replace(/\+/g, "%20"));
                    var path0 = path;
                    TDev.Util.log("path: {0}", path);
                    while (true) {
                        path = path.replace(/\/+$/, "");
                        if (this.routes.hasOwnProperty(path))
                            break;
                        if (path == "") {
                            return TDev.Promise.wrapError(new Error("No such API: " + path0));
                        }
                        path = path.replace(/[^\/]+$/, "");
                    }
                    var fn = this.routes[path];
                    req._api_path = path;
                    this.queueAsyncStd(function (rt, args) {
                        req.startHandle();
                        var bot = new TDev.StackBottom(_this);
                        var lc = fn(bot);
                        lc.needsPicker = true;
                        var f = lc.invoke(lc, TDev.Runtime.pumpEvents);
                        f.serverRequest = req;
                        req._stackframe = f;
                        return _this.enter(f);
                    });
                    return TDev.Promise.as(promise);
                };
                TheNodeRuntime.prototype.queueAsyncStd = function (cb) {
                    var _this = this;
                    this.queueEventCallback(function (rt, args) {
                        _this.queueAsyncEvent(function () { return cb(rt, args); });
                    });
                };
                TheNodeRuntime.prototype.queueAsync = function (cb) {
                    var _this = this;
                    this.queueAsyncStd(function (rt, args) {
                        cb();
                        var bot = new TDev.StackBottom(_this);
                        _this.current = bot;
                        return TDev.Runtime.pumpEvents;
                    });
                };
                TheNodeRuntime.prototype.queueActionCall = function (service, action, params, socket) {
                    var _this = this;
                    var promise = new TDev.PromiseInv();
                    var url = service + "/" + action;
                    var req = {
                        method: "WS",
                        url: url,
                        socket: socket,
                        _stackframe: undefined
                    };
                    var fn = this.routes[service + "/" + action];
                    var ev = new RT.Event_();
                    ev.addHandler(new RT.PseudoAction(function (rt, args) {
                        _this.queueAsyncEvent(function () {
                            var bot = new TDev.StackBottom(_this);
                            var lc = fn(bot);
                            lc.needsPicker = true;
                            var f = lc.invoke(lc, TDev.Runtime.pumpEvents);
                            f.serverRequest = req;
                            req._stackframe = f;
                            return _this.enter(f);
                        });
                    }));
                    this.queueLocalEvent(ev);
                    return promise;
                };
                TheNodeRuntime.prototype.addRestRoute = function (name, fn) {
                    this.routes[name] = fn;
                };
                TheNodeRuntime.prototype.addRestInit = function (fn) {
                    this.restInits.push(fn);
                };
                TheNodeRuntime.prototype.setMainAction = function (fn) {
                    this.mainActionRef = fn;
                };
                TheNodeRuntime.prototype.hasInits = function () {
                    return this.restInits.length > 0;
                };
                TheNodeRuntime.prototype.queueInits = function () {
                    var _this = this;
                    var queue = function (fn) {
                        var lifted = function (bot, retAddr) {
                            var lc = fn(bot);
                            return lc.invoke(lc, retAddr);
                        };
                        var ev = new RT.Event_();
                        ev.addHandler(lifted);
                        _this.queueLocalEvent(ev);
                    };
                    if (this.hasInits())
                        this.restInits.forEach(queue);
                    else if (this.mainActionRef)
                        queue(this.mainActionRef);
                };
                TheNodeRuntime.prototype.handleException = function (e, s) {
                    if (e.rtProtectHandled)
                        return;
                    if (!e.tdStackFrame)
                        e.tdStackFrame = s;
                    var handled = this.quietlyHandleError(e);
                    if (!handled)
                        this.host.exceptionHandler(e);
                    e.rtProtectHandled = true;
                    this.restartAfterException();
                };
                TheNodeRuntime.prototype.setCors = function (resp) {
                    resp.setHeader('Access-Control-Allow-Origin', "*");
                    resp.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST');
                    resp.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
                    resp.setHeader('Access-Control-Expose-Headers', 'ErrorMessage');
                };
                TheNodeRuntime.prototype.handleRpc = function (req, resp) {
                    var _this = this;
                    req.tdResponse = resp;
                    req.tdQueryString = querystring.parse(req.url.replace(/^[^\?]*\??/, ""));
                    var sr = RT.ServerRequest.mk(req);
                    sr._api_path = req.url.replace(/^\/-tdevrpc-\//, "");
                    if (sr._api_path == "-internal-/ping") {
                        error(resp, 200, { v: req.tdQueryString['v'] || "", now: Date.now() });
                        return;
                    }
                    this.setCors(resp);
                    if (req.method == "OPTIONS") {
                        resp.writeHead(200);
                        resp.end();
                        return;
                    }
                    var clientUserId = "";
                    var rt = this;
                    if (rt.authValidator) {
                        var m = /^\s*Bearer\s+(.+)/.exec(req.headers['authorization']);
                        if (m) {
                            var token = m[1];
                            rt.wrapFromHandler(function () {
                                clientUserId = rt.runUserAction(rt.authValidator, [token]);
                                if (clientUserId && !/:/.test(clientUserId))
                                    TDev.Util.userError("user id returned from validator has to have a namespace (eg., fb:123456)");
                            });
                            if (!clientUserId) {
                                TDev.Util.log("invalid authorization attempt, " + token);
                                error(resp, 403);
                                return;
                            }
                            else {
                                TDev.Util.log("authorized as " + clientUserId);
                                sr._user = RT.User.mk(clientUserId);
                            }
                        }
                    }
                    if (sr._api_path == "-internal-/me") {
                        if (!clientUserId) {
                            error(resp, 403);
                        }
                        else {
                            error(resp, 200, { userid: clientUserId });
                        }
                        return;
                    }
                    sr.recvContentAsync().done(function () { return _this.dispatchServerRequest(sr); });
                };
                TheNodeRuntime.prototype.augmentException = function (e) {
                    var d = process.domain;
                    if (typeof e == "object" && !e.tdStackFrame && d && d.tdStackFrame) {
                        e.tdStackFrame = d.tdStackFrame;
                    }
                    _super.prototype.augmentException.call(this, e);
                };
                TheNodeRuntime.prototype.runInlineJavascript = function (f) {
                    var _this = this;
                    var frame = this.current;
                    var d = domain.create();
                    d.tdStackFrame = frame;
                    d.on("error", function (err) {
                        _this.handleException(err, frame);
                    });
                    var exn = null;
                    d.enter();
                    try {
                        f();
                    }
                    catch (e) {
                        e.tdStackFrame = frame;
                        exn = e;
                    }
                    d.exit();
                    if (exn)
                        throw exn;
                };
                return TheNodeRuntime;
            })(TDev.Runtime);
            Node.TheNodeRuntime = TheNodeRuntime;
            var RunnerHost = (function (_super) {
                __extends(RunnerHost, _super);
                function RunnerHost(wsServer) {
                    _super.call(this);
                    this.isServer = true;
                    this.currentRt = new TheNodeRuntime(this, wsServer);
                    this.localProxyAsync = TDev.LocalShell.localProxyHandler();
                    RT.App.log('node runtime initialized');
                }
                RunnerHost.prototype.respondToCrash = function (bug) {
                    var req = this.currentRt.getRestRequest();
                    if (!req)
                        return;
                    try {
                        var resp = req.getNodeRequest().tdResponse;
                        resp.writeHead(500);
                        resp.end("Whoops, " + bug.exceptionMessage);
                    }
                    catch (e) {
                        var ses = this.currentRt.sessions.CurrentSession;
                        ses.abortCurrentTransaction(bug);
                    }
                };
                RunnerHost.prototype.log = function (s) {
                    RT.App.log(s);
                };
                RunnerHost.prototype.fillCrashInfo = function (crash) {
                    var req = this.currentRt.getRestRequest();
                    crash.url = req ? req.url() : null;
                };
                return RunnerHost;
            })(TDev.HeadlessHost);
            Node.RunnerHost = RunnerHost;
            var host;
            function httpRequestStreamAsync(url_, method, body, contentType) {
                if (method === void 0) { method = "GET"; }
                if (body === void 0) { body = undefined; }
                if (contentType === void 0) { contentType = null; }
                var parsed = url.parse(url_);
                parsed.method = method.toUpperCase();
                var req;
                if (parsed.protocol == "http:") {
                    req = http.request(parsed);
                }
                else if (parsed.protocol == "https:") {
                    req = https.request(parsed);
                }
                else {
                    TDev.Util.oops("unknown node.js protocol " + parsed.protocol + " in " + url_);
                }
                var ret = new TDev.PromiseInv();
                var headers = contentType || {};
                if (typeof headers == "string")
                    headers = { "Content-Type": headers };
                Object.keys(headers).forEach(function (k) { return req.setHeader(k, headers[k]); });
                req.on("error", function (err) {
                    err.socketUrl = url_;
                    ret.error(err);
                });
                req.on("response", function (res) {
                    if (res.statusCode == 200) {
                        if (/gzip/.test(res.headers['content-encoding'])) {
                            var g = zlib.createUnzip(undefined);
                            res.pipe(g);
                        }
                        else {
                            g = res;
                        }
                        ret.success(g);
                    }
                    else {
                        ret.error(new Error("bad status code " + res.statusCode + " for " + url_));
                    }
                });
                if (body !== undefined)
                    req.end(body, "utf8");
                else
                    req.end();
                return ret;
            }
            Node.httpRequestStreamAsync = httpRequestStreamAsync;
            function httpRequestAsync(url_, method, body, contentType) {
                if (method === void 0) { method = "GET"; }
                if (body === void 0) { body = undefined; }
                if (contentType === void 0) { contentType = null; }
                return httpRequestStreamAsync(url_, method, body, contentType).then(function (g) {
                    if (g.setEncoding)
                        g.setEncoding('utf8');
                    var ret = new TDev.PromiseInv();
                    var d = "";
                    g.on('data', function (c) {
                        d += c;
                    });
                    g.on('end', function () {
                        ret.success(d);
                    });
                    return ret;
                });
            }
            function webRequestAsync(r) {
                var parsed = url.parse(r.url());
                parsed.method = r.method().toUpperCase();
                var j = r.serializeForProxy();
                parsed.headers = {};
                j.headers.forEach(function (h) { return parsed.headers[h.name] = h.value; });
                if (j.credentials)
                    parsed.auth = j.credentials.name + ":" + j.credentials.password;
                var data;
                if (typeof j.contentText == "string")
                    data = new Buffer(j.contentText, "utf8");
                else if (typeof j.content == "string")
                    data = new Buffer(j.content, "base64");
                else
                    data = new Buffer("", "binary");
                if (data.length > 0)
                    parsed.headers['content-length'] = data.length;
                if (!parsed.headers['connection'])
                    parsed.headers['connection'] = 'keep-alive';
                var req;
                if (parsed.protocol == "http:") {
                    parsed.agent = Node.httpAgent;
                    req = http.request(parsed);
                }
                else if (parsed.protocol == "https:") {
                    parsed.agent = Node.httpsAgent;
                    req = https.request(parsed);
                }
                else {
                    TDev.Util.userError("unknown request protocol " + parsed.protocol + " in " + r.url());
                }
                var ret = new TDev.PromiseInv();
                req.on("error", function (err) {
                    RT.App.log("Web request error: " + err + " for " + r.url());
                    err.socketUrl = r.url();
                    ret.error(err);
                });
                req.on("response", function (res) {
                    var stream = res;
                    var encoding = (res.headers['content-encoding'] || "").toLowerCase();
                    if (encoding == "gzip")
                        stream = stream.pipe(zlib.createGunzip());
                    else if (encoding == "deflate")
                        stream = stream.pipe(zlib.createInflate());
                    var buffers = [];
                    stream.on('data', function (b) {
                        buffers.push(b);
                    });
                    stream.on('end', function () {
                        var buf = Buffer.concat(buffers);
                        var content = r.proxyResponseType() == "text" ? buf.toString("utf8") : buf.toString("binary");
                        var wresp = RT.WebResponse.mkProxy(r, {
                            code: res.statusCode,
                            headers: Object.keys(res.headers).map(function (h) {
                                return { name: h, value: res.headers[h] };
                            }),
                            forceText: true,
                            contentText: content,
                            binaryContent: buf
                        });
                        ret.success(wresp);
                    });
                });
                if (data.length == 0)
                    req.end();
                else
                    req.end(data);
                return ret;
            }
            function setup() {
                if (!TDev.Browser.isNodeJS)
                    return;
                Buffer = global.Buffer;
                TDev.Browser.canIndexedDB = false;
                TDev.Storage.getTableAsync = function (name) { return TDev.Promise.as(new FsTable(name)); };
                TDev.Storage.clearPreAsync = function () { return TDev.Promise.as(); };
                TDev.Util.httpRequestAsync = httpRequestAsync;
                RT.WebRequest.prototype.sendAsync = function () {
                    return webRequestAsync(this);
                };
                TDev.Util.perfNow = function () {
                    var t = process.hrtime();
                    return t[0] * 1e3 + t[1] * 1e-6;
                };
                TDev.Ticker.disable();
                TDev.Util.initGenericExtensions();
                TDev.RT.RTValue.initApis();
                global.btoa = function (str) { return new Buffer(str, "binary").toString("base64"); };
                global.atob = function (str) { return new Buffer(str, "base64").toString("binary"); };
                window = {};
                window.removeEventListener = function () {
                };
                window.setTimeout = setTimeout;
                window.rootUrl = "https://www.touchdevelop.com";
                var ls = {};
                window.localStorage = ls;
                window.localStorage['local_proxy'] = process.env['TD_SERVER'] + '/-tdevmgmt-/' + process.env['TD_DEPLOYMENT_KEY'];
                ls.getItem = function (s) { return ls[s]; };
                ls.setItem = function (s, v) { return ls[s] = v + ""; };
                ls.removeItem = function (s) { return delete ls[s]; };
                global.navigator = {};
                window.navigator = navigator;
                navigator.userAgent = "NodeJS " + process.version;
                if (process.env['TD_CLIENT_CONFIG']) {
                    var obj = JSON.parse(process.env['TD_CLIENT_CONFIG']);
                    Object.keys(obj).forEach(function (k) { return TDev.Cloud.config[k] = obj[k]; });
                }
                TDev.Util.logSz = 3000;
                setupGlobalAgent();
                TDev.Promise.errorHandler = function (ctx, err) {
                    var outer = process.domain;
                    if (outer)
                        outer.emit('error', err);
                    else
                        Node.handleError(err);
                    return new TDev.PromiseInv();
                };
                TDev.Cloud.getUserId = function () {
                    var rt = TDev.Runtime.theRuntime;
                    if (!rt)
                        return undefined;
                    var req = rt.getRestRequest();
                    if (!req)
                        return undefined;
                    var user = req.user();
                    if (user)
                        return user.id();
                };
                TDev.Cloud.authenticateAsync = function (activity, redirect, dontRedirect) {
                    if (redirect === void 0) { redirect = false; }
                    if (dontRedirect === void 0) { dontRedirect = false; }
                    return TDev.Promise.as(!!TDev.Cloud.getUserId());
                };
                try {
                    var xmldom = require('xmldom');
                    if (xmldom) {
                        global.DOMParser = xmldom.DOMParser;
                        global.XMLSerializer = xmldom.XMLSerializer;
                    }
                }
                catch (e) {
                }
                TDev.Random.strongEntropySource = function (buf) {
                    var b2 = crypto.randomBytes(buf.length);
                    for (var i = 0; i < buf.length; ++i)
                        b2[i] = buf[i];
                };
                TDev.RT.App.server_setting = function (key, optional, s) {
                    var setting = process.env[key];
                    if (!optional && setting == undefined)
                        TDev.Util.userError('missing environment variable ' + key, s.pc);
                    return setting;
                };
                TDev.RT.Web.proxy = function (url) { return url; };
                RT.App.runTransports = function (id, run) {
                    RT.App.transports.forEach(function (transport) {
                        var d = transport.domain;
                        if (!d) {
                            transport.domain = d = domain.create();
                            d.on("error", function (err) {
                                RT.App.transportFailed(transport, id, err);
                            });
                        }
                        d.enter();
                        try {
                            run(transport);
                        }
                        catch (err) {
                            RT.App.transportFailed(transport, id, err);
                        }
                        d.exit();
                    });
                };
                var origConnect = net.Socket.prototype.connect;
                net.Socket.prototype.connect = function (options) {
                    if (options && typeof options.host == "string")
                        this.tdHost = options.host;
                    return origConnect.apply(this, arguments);
                };
                var origDestroy = net.Socket.prototype._destroy;
                net.Socket.prototype._destroy = function (exn) {
                    if (typeof exn == "object" && (this.tdHost || this.tdUnrefed)) {
                        if (!exn.tdMeta)
                            exn.tdMeta = {};
                        exn.tdMeta.socketHost = this.tdHost;
                        exn.tdMeta.unrefed = this.tdUnrefed;
                        if (this.tdUnrefed && exn.code == 'ECONNRESET') {
                            TDev.Util.log("ignoring ECONNRESET on " + this.tdHost);
                            exn.rtProtectHandled = true;
                            exn.tdSkipReporting = true;
                        }
                    }
                    return origDestroy.apply(this, arguments);
                };
                var origRef = net.Socket.prototype.ref;
                net.Socket.prototype.ref = function () {
                    this.tdUnrefed = false;
                    return origRef.apply(this, arguments);
                };
                var origUnref = net.Socket.prototype.unref;
                net.Socket.prototype.unref = function () {
                    this.tdUnrefed = true;
                    return origUnref.apply(this, arguments);
                };
                RT.ServerResponse.toUtfBuffer = function (s) { return new Buffer(s, "utf8"); };
                TDev.RT.Buffer.prototype.toNodeBuffer = function () {
                    if (Buffer.isBuffer(this.buffer))
                        return this.buffer;
                    var r = new Buffer(this.count());
                    var b = this.buffer;
                    for (var i = 0; i < r.length; ++i)
                        r[i] = b[i];
                    return r;
                };
                TDev.RT.Buffer.fromNodeBuffer = function (buf) { return TDev.RT.Buffer.fromTypedArray(buf); };
                process.on('uncaughtException', Node.handleError);
            }
            Node.setup = setup;
            function getRuntimeInfoAsync(which) {
                var needed = TDev.Util.toDictionary(which.split(/,/), function (s) { return s; });
                if (needed["tdlog"]) {
                    var msgs = TDev.Util.getLogMsgs();
                    msgs.reverse();
                }
                var r = {
                    applog: needed["applog"] ? RT.App.logs() : undefined,
                    tdlog: msgs,
                    crashes: needed["crashes"] ? (host ? host.crashes : []) : undefined,
                };
                return TDev.Promise.as(r);
            }
            Node.isShuttingDown = false;
            var httpActions = {
                info: function (args, req, resp) { return getRuntimeInfoAsync(args[0] || "").done(function (r) { return resp.send(200, r); }); },
                ready: function (args, req, resp) { return resp.send(200, { ready: true }); },
                shutdown: function (args, req, resp) {
                    Node.isShuttingDown = true;
                    resp.send(201, {});
                },
            };
            function specialHttpRequest(req, resp) {
                resp.send = function (code, msg) {
                    if (typeof msg == "string")
                        msg = { message: msg };
                    var buf = new Buffer(JSON.stringify(msg), "utf8");
                    TDev.Util.log("worker request buffer len=" + buf.length + " code " + code);
                    resp.writeHead(code, {
                        'content-length': buf.length,
                        'content-type': 'application/json'
                    });
                    resp.end(buf);
                };
                var key = process.env['TD_DEPLOYMENT_KEY'];
                if (!key) {
                    resp.send(500, "key not setup");
                    return;
                }
                var words = req.url.replace(/^\//, "").split(/\//);
                if (words[0] != "-tdevmgmt-")
                    resp.send(404, "only /-tdevmgmt-/ supported");
                else if (words[1] != key)
                    resp.send(403, "wrong key");
                else if (httpActions.hasOwnProperty(words[2])) {
                    TDev.Util.log("worker request, " + words[2]);
                    httpActions[words[2]](words.slice(3), req, resp);
                }
                else
                    resp.send(404, "no such API " + words[2]);
            }
            function error(resp, code, data) {
                resp.writeHead(code);
                if (typeof data == "object")
                    data = JSON.stringify(data);
                if (data)
                    resp.end(data);
                else
                    resp.end();
            }
            function getMime(filename) {
                var ext = path.extname(filename).slice(1);
                switch (ext) {
                    case "txt": return "text/plain";
                    case "html":
                    case "htm": return "text/html";
                    case "css": return "text/css";
                    case "ts": return "text/plain";
                    case "js": return "application/javascript";
                    case "jpg":
                    case "jpeg": return "image/jpeg";
                    case "png": return "image/png";
                    case "ico": return "image/x-icon";
                    case "manifest": return "text/cache-manifest";
                    case "json": return "application/json";
                    case "svg": return "image/svg+xml";
                    default: return "application/octet-stream";
                }
            }
            function serveStaticFile(req, resp) {
                var m = /\/app\/([^?]*)/.exec(req.url);
                var p = m[1] || "index.html";
                var pp = path.normalize("/static/" + p).replace(/\\/g, "/");
                if (/^\/static\//.test(pp)) {
                    pp = "." + pp;
                    fs.exists(pp, function (yes) {
                        if (!yes)
                            error(resp, 404);
                        else {
                            var inp = fs.createReadStream(pp);
                            var mime = getMime(pp);
                            if (/^(text\/|application\/(json|javascript)|image\/svg)/.test(mime)) {
                                var gzip = zlib.createGzip();
                                resp.writeHead(200, {
                                    "Content-Encoding": "gzip",
                                    "Content-Type": mime,
                                });
                                inp.pipe(gzip).pipe(resp);
                            }
                            else {
                                resp.writeHead(200, {
                                    "Content-Type": mime,
                                });
                                inp.pipe(resp);
                            }
                        }
                    });
                }
                else
                    error(resp, 403);
            }
            function handleHttpRequest(req, resp) {
                if (/^\/-tdevmgmt-\//.test(req.url))
                    specialHttpRequest(req, resp);
                else {
                    var rt = TDev.Runtime.theRuntime;
                    if (rt.compiled.autoRouting) {
                        if (/^\/-tdevrpc-\//.test(req.url)) {
                            rt.handleRpc(req, resp);
                        }
                        else {
                            if (/^\/(app)?(\?|$)/.test(req.url)) {
                                resp.writeHead(302, { "Location": "/app/" });
                                resp.end();
                            }
                            else if (/^\/app\//.test(req.url)) {
                                serveStaticFile(req, resp);
                            }
                            else {
                                if (rt.requestHandler)
                                    rt.requestHandler(req, resp);
                                else
                                    error(resp, 404, "Generic routing not setup");
                            }
                        }
                    }
                    else {
                        if (rt.requestHandler)
                            rt.requestHandler(req, resp);
                        else
                            error(resp, 404, "Neither generic nor regular routing setup");
                    }
                }
            }
            Node.handleHttpRequest = handleHttpRequest;
            function startServerAsync() {
                var ret = new TDev.PromiseInv();
                var port = process.env.PORT || 4242;
                var app = http.createServer();
                app.on("upgrade", function (req, sock, body) {
                    var rt = TDev.Runtime.theRuntime;
                    if (rt.wsServer && rt.wsServer.isReal())
                        rt.wsServer.upgradeCallback(req, sock, body);
                    else
                        sock.end();
                });
                app.on("request", handleHttpRequest);
                app.on("listening", function () {
                    ret.success(app);
                });
                TDev.Util.log("listening on " + port + " from pid " + process.pid);
                app.listen(port);
                return ret;
            }
            Node.startServerAsync = startServerAsync;
            function runMainAsync() {
                if (require.resolve("faye-websocket"))
                    webSocketModule = require("faye-websocket");
                var wsServer = new TDev.WebSocketServerWrapper(webSocketModule);
                host = new RunnerHost(wsServer);
                var rt = host.currentRt;
                TDev.Runtime.theRuntime = rt;
                var initProm = new TDev.PromiseInv();
                rt.initPromise = initProm;
                host.initFromPrecompiled();
                host.currentGuid = rt.compiled.scriptGuid;
                TDev.Util.log("initializing data");
                TDev.Browser.localProxy = true;
                return rt.initDataAsync().then(function () {
                    TDev.Util.log("starting server script");
                    rt.setState(3 /* AtAwait */, "start server");
                    var autoStart = rt.hasInits() || rt.compiled.autoRouting;
                    rt.queueInits();
                    rt.queueAsyncStd(function () {
                        if (autoStart)
                            initProm.success(startServerAsync());
                        else {
                            TDev.Util.log("main finished");
                            initProm.success(null);
                        }
                    });
                    return initProm;
                });
            }
            Node.runMainAsync = runMainAsync;
        })(Node = RT.Node || (RT.Node = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));
var TDev;
(function (TDev) {
    var RT;
    (function (RT) {
        var Node;
        (function (Node) {
            Node.storeOAuthHTML = "<!DOCTYPE html>\n" + "<html>\n" + "<head>\n" + "    <meta charset='utf-8' />\n" + "    <meta http-equiv='X-UA-Compatible' content='IE=edge' /> \n" + "    <meta name='viewport' content='width=320, initial-scale=1, maximum-scale=1, user-scalable=0'/>\n" + "    <title>Authorization finished</title>\n" + "</head>\n" + "<body id='root'>\n" + "  <div style='font-size: 14px; color:#444; font-family: sans-serif; line-height: 1.5em; width: 310px; margin: 2em auto;'>\n" + "    <h1>authorization finished</h1>\n" + "    <p>\n" + "        You can close this page. \n" + "        The web app should resume in a different tab or window.\n" + "    </p>\n" + "  </div>\n" + "  <script type='text/javascript'>\n" + "     var a = window.localStorage['oauth_redirect'];\n" + "     var b = [];\n" + "     var now = new Date().getTime();\n" + "     if (a)\n" + "         JSON.parse(a).forEach(function (e) {\n" + "             if (now - e.time < 10 * 60 * 1000) b.push(e); // remove anything older than 10 minutes\n" + "         });        \n" + "     b.push({redirect_url: window.location.href, time: now, user_id: 'web-app' });\n" + "     window.localStorage.setItem('oauth_redirect', JSON.stringify(b));\n" + "     if (window.opener) window.opener.postMessage(b, document.URL.replace(/(.*:\\/\\/[^\\/]+).*/, function(a,b){return b}));\n" + "     setTimeout(window.close, 3000);\n" + "  </script>\n" + "</body>\n" + "</html>\n";
        })(Node = RT.Node || (RT.Node = {}));
    })(RT = TDev.RT || (TDev.RT = {}));
})(TDev || (TDev = {}));

var TDev; if(!TDev) TDev = {}; TDev.shippedLibraryCache = {
 "updates": {
  "lohjia": "lohjia",
  "dwiebl": "lohjia",
  "bwulwg": "lohjia",
  "rsnhdj": "lohjia",
  "boouiv": "lohjia",
  "xlxslt": "lohjia",
  "vflqes": "lohjia",
  "rknjae": "lohjia",
  "fdbsiw": "lohjia",
  "blijwl": "lohjia",
  "bzpicf": "lohjia",
  "lptrek": "lohjia",
  "ljivpr": "lohjia",
  "njwiab": "lohjia",
  "jcyhqq": "jcyhqq",
  "fvpcct": "jcyhqq",
  "pwjcnz": "jcyhqq",
  "tummov": "jcyhqq",
  "xczaux": "xczaux",
  "btierw": "xczaux",
  "njcjlk": "xczaux",
  "xbpfet": "xbpfet",
  "tjamyj": "xbpfet",
  "rbmtqn": "xbpfet",
  "paoixe": "xbpfet",
  "rfsnox": "xbpfet",
  "hvmmzk": "xbpfet",
  "fxyeei": "xbpfet",
  "lmqwsm": "xbpfet",
  "tyqrcx": "xbpfet",
  "rpnbfg": "xbpfet",
  "ruxplx": "xbpfet",
  "hjxfxm": "xbpfet",
  "blwvrs": "xbpfet",
  "bfdyuk": "xbpfet",
  "hajssc": "xbpfet",
  "lvpfqe": "xbpfet",
  "vzkdcc": "xbpfet",
  "dnfbfj": "xbpfet",
  "xyelfe": "xyelfe",
  "dceiba": "dceiba",
  "jowara": "jowara",
  "jwzrac": "jowara",
  "jinlsg": "jowara",
  "xuozdw": "jowara",
  "vnkwrm": "jowara",
  "xvdxqj": "jowara",
  "ljvbcu": "jowara",
  "tzpnpk": "jowara",
  "tbvqzm": "jowara",
  "pyudxk": "jowara",
  "llxdhr": "jowara",
  "rlsdex": "jowara",
  "jasfim": "jowara",
  "trbrqq": "jowara",
  "tnwmgs": "jowara",
  "nufgti": "jowara",
  "vgbplz": "jowara",
  "zfbkbb": "jowara",
  "vldvpc": "jowara",
  "dhkqum": "jowara",
  "nbpjbl": "jowara",
  "fdrhpb": "jowara",
  "fyydkk": "jowara",
  "nmhibf": "jowara",
  "vrhiwz": "jowara",
  "dotmbn": "jowara",
  "pluhts": "jowara",
  "phzafk": "jowara",
  "txmcff": "jowara",
  "rmeurh": "jowara",
  "hfkfrj": "jowara",
  "zzhwln": "jowara",
  "ziynpv": "jowara",
  "ttnzbx": "jowara",
  "dsuacd": "jowara",
  "basduc": "jowara",
  "halxyt": "jowara",
  "vimisk": "jowara",
  "lirsmq": "jowara",
  "jrvnlu": "jowara",
  "zkpmfe": "jowara",
  "fkinwi": "jowara",
  "fiimud": "jowara",
  "zivklh": "jowara",
  "xhrblh": "jowara",
  "tdloqa": "jowara",
  "dfaiyr": "jowara",
  "hrvbin": "jowara",
  "jztbbx": "jztbbx",
  "vkmzfe": "jztbbx",
  "lpyqwl": "jztbbx",
  "lyhgks": "jztbbx",
  "lhnrxc": "jztbbx",
  "rqusix": "jztbbx",
  "vjbufd": "jztbbx",
  "dlxfsa": "jztbbx",
  "dxihyl": "jztbbx",
  "hsxfze": "jztbbx",
  "xnkmqj": "jztbbx",
  "joggzb": "jztbbx",
  "hgcivb": "jztbbx",
  "jfhfbf": "jztbbx",
  "pvldqm": "jztbbx",
  "lmztcr": "jztbbx",
  "fnsquv": "jztbbx",
  "tgpxru": "tgpxru",
  "lnyirj": "tgpxru",
  "xpccdk": "tgpxru",
  "tmfxah": "tgpxru",
  "tulxtd": "tgpxru",
  "leviat": "tgpxru",
  "xrsbct": "tgpxru",
  "dgzalb": "tgpxru",
  "ntnaek": "tgpxru",
  "fqycyb": "tgpxru",
  "vmodll": "tgpxru",
  "nzngii": "tgpxru",
  "zppitt": "tgpxru",
  "vdtdmk": "tgpxru",
  "drdxps": "tgpxru",
  "nfleak": "tgpxru",
  "dsgmns": "tgpxru",
  "rgzzbv": "tgpxru",
  "bacckw": "tgpxru",
  "phdnud": "tgpxru",
  "hdrpdj": "tgpxru",
  "trcsiq": "tgpxru",
  "vtxxzt": "tgpxru",
  "xpccen": "tgpxru",
  "lbfjuu": "tgpxru",
  "bmjsup": "tgpxru",
  "rwbwnc": "rwbwnc",
  "xgqnpl": "rwbwnc",
  "flwhyo": "rwbwnc",
  "lkqbjr": "rwbwnc",
  "zhslvl": "rwbwnc",
  "zibjkk": "rwbwnc",
  "ryudev": "rwbwnc",
  "rwkysy": "rwbwnc",
  "btfsgu": "rwbwnc",
  "fhvcir": "rwbwnc",
  "ticpeu": "rwbwnc",
  "vunhaj": "rwbwnc",
  "bfxgzp": "rwbwnc",
  "ppbtkr": "rwbwnc",
  "tamxmb": "rwbwnc",
  "pyfuaj": "rwbwnc",
  "vlgowe": "rwbwnc",
  "vxryfu": "rwbwnc",
  "hnmzma": "rwbwnc",
  "lwagkt": "rwbwnc",
  "vlsqtp": "rwbwnc",
  "tkqhxs": "rwbwnc",
  "ddbdlp": "rwbwnc",
  "vbpllw": "rwbwnc",
  "hgdnlk": "rwbwnc",
  "xdbgfd": "rwbwnc",
  "hisopu": "rwbwnc",
  "hpsbjr": "rwbwnc",
  "rdnlgg": "rwbwnc",
  "dtanwz": "rwbwnc",
  "vqneem": "rwbwnc",
  "hfslhg": "rwbwnc",
  "ndqert": "rwbwnc",
  "fxfuvk": "rwbwnc",
  "jljdtt": "rwbwnc",
  "dlfyfr": "rwbwnc",
  "ldaqbf": "rwbwnc",
  "bicvwk": "rwbwnc",
  "peixmc": "rwbwnc",
  "jspgcp": "rwbwnc",
  "dhzjxl": "rwbwnc",
  "bvfteo": "rwbwnc",
  "zspnrz": "rwbwnc",
  "pmlwzq": "rwbwnc",
  "hehjco": "rwbwnc",
  "zgzyag": "rwbwnc",
  "vdxsnb": "rwbwnc",
  "rhzcbr": "rwbwnc",
  "bugxan": "rwbwnc",
  "paskjp": "rwbwnc",
  "huubfm": "rwbwnc",
  "jxjbju": "rwbwnc",
  "djjdpb": "rwbwnc",
  "fsdvro": "rwbwnc",
  "pzngyn": "pzngyn",
  "xmyfcx": "pzngyn",
  "rwhibw": "pzngyn",
  "rfvakj": "pzngyn",
  "xgnqyf": "pzngyn",
  "zbiwoq": "pzngyn",
  "tjwpnx": "tjwpnx",
  "pnmapm": "tjwpnx",
  "fkoswh": "tjwpnx",
  "pkfjzi": "tjwpnx",
  "ntijaa": "tjwpnx",
  "dsgklp": "tjwpnx",
  "hxknul": "tjwpnx",
  "xtdqur": "tjwpnx",
  "zkvycu": "tjwpnx",
  "fdcdke": "tjwpnx",
  "timemq": "tjwpnx",
  "jatkdh": "tjwpnx",
  "fflebn": "tjwpnx",
  "hibawm": "tjwpnx",
  "fmmavb": "tjwpnx",
  "fzypmq": "tjwpnx",
  "bhbvya": "tjwpnx",
  "zlkons": "tjwpnx",
  "fhjdxt": "tjwpnx",
  "fccpcn": "tjwpnx",
  "lfpakg": "tjwpnx",
  "zjinpw": "tjwpnx",
  "nlnzga": "tjwpnx",
  "lxtzxx": "tjwpnx",
  "fapdpb": "tjwpnx",
  "zfxkuh": "tjwpnx",
  "lzjlpd": "tjwpnx",
  "djwhxu": "tjwpnx",
  "bhylxt": "tjwpnx",
  "fgtlwv": "tjwpnx",
  "tefjnz": "tjwpnx",
  "bszmrk": "tjwpnx",
  "ryglta": "tjwpnx",
  "ditrnm": "tjwpnx",
  "vsiztm": "tjwpnx",
  "lkuyum": "tjwpnx",
  "dqkxtp": "tjwpnx",
  "ffetnp": "tjwpnx",
  "vaivlc": "tjwpnx",
  "plehpx": "tjwpnx",
  "bqtorq": "tjwpnx",
  "jpexjh": "tjwpnx",
  "vehemv": "tjwpnx",
  "hswbld": "tjwpnx",
  "dbkrwh": "tjwpnx",
  "bglpha": "tjwpnx",
  "lyusma": "tjwpnx",
  "bltbdc": "tjwpnx",
  "njxqsg": "njxqsg",
  "jzzrnq": "njxqsg",
  "tmizmw": "njxqsg",
  "howjlb": "njxqsg",
  "ndodyk": "njxqsg",
  "bnkbfq": "njxqsg",
  "pndnla": "njxqsg",
  "nqjlbg": "njxqsg",
  "rpfsmn": "njxqsg",
  "xgzgcy": "njxqsg",
  "vyzssw": "njxqsg",
  "fdlnnr": "njxqsg",
  "ltvhod": "njxqsg",
  "nrplbi": "njxqsg",
  "tashnb": "njxqsg",
  "xsurev": "njxqsg",
  "tuzezw": "njxqsg",
  "hqqryq": "njxqsg",
  "bzhcxd": "njxqsg",
  "xytpsi": "njxqsg",
  "thflqk": "njxqsg",
  "pocsyb": "njxqsg",
  "jpvoxj": "njxqsg",
  "xzsvex": "njxqsg",
  "jvkxya": "njxqsg",
  "nhgcyh": "njxqsg",
  "fafqqy": "njxqsg",
  "vldxsb": "njxqsg",
  "nvzoiu": "njxqsg",
  "ruqbfc": "njxqsg",
  "ftjozd": "njxqsg",
  "jquahl": "njxqsg",
  "zuurkm": "njxqsg",
  "zdcxqn": "njxqsg",
  "fqstta": "njxqsg",
  "xessad": "njxqsg",
  "lagzvz": "njxqsg",
  "raqojy": "njxqsg",
  "dfjodw": "njxqsg",
  "rveqvu": "njxqsg",
  "tjojku": "njxqsg",
  "znmsng": "njxqsg",
  "rvjljs": "njxqsg",
  "dtyvzo": "njxqsg",
  "vgruia": "njxqsg",
  "ldjskk": "njxqsg",
  "jcsoox": "njxqsg",
  "jsxbyn": "njxqsg",
  "nwmsfn": "njxqsg",
  "jinley": "njxqsg",
  "phkxrv": "njxqsg",
  "tqvaau": "njxqsg",
  "regzxg": "njxqsg",
  "pvucub": "njxqsg",
  "zjwfbi": "njxqsg",
  "fsrbza": "njxqsg",
  "fudpsy": "njxqsg",
  "hbpcym": "njxqsg",
  "dpwlkf": "njxqsg",
  "byelqo": "njxqsg",
  "tzmpvf": "njxqsg",
  "nrrcvw": "njxqsg",
  "bendhe": "njxqsg",
  "hdkwlu": "njxqsg",
  "rbgelh": "njxqsg",
  "vsuixj": "njxqsg",
  "hlgbao": "njxqsg",
  "fktqmg": "njxqsg",
  "bwfzww": "njxqsg",
  "flzcsl": "njxqsg",
  "jppknl": "njxqsg",
  "tentup": "njxqsg",
  "brajid": "njxqsg",
  "zeousb": "njxqsg",
  "rtssjg": "njxqsg",
  "pjxtzs": "njxqsg",
  "hzduee": "njxqsg",
  "dtwvpv": "njxqsg",
  "zecodr": "njxqsg",
  "xhvlgz": "njxqsg",
  "rfgvru": "njxqsg",
  "jcvnou": "njxqsg",
  "jnjqgc": "njxqsg",
  "faxnop": "njxqsg",
  "tmoluc": "njxqsg",
  "rwqgyd": "njxqsg",
  "hmuejp": "njxqsg",
  "rgyfae": "njxqsg",
  "nnkxto": "njxqsg",
  "hcmylp": "njxqsg",
  "duwejj": "njxqsg",
  "nedhlt": "njxqsg",
  "xftcfs": "njxqsg",
  "boihcn": "njxqsg",
  "vsplbm": "njxqsg",
  "ljqwee": "njxqsg",
  "jpccms": "njxqsg",
  "hrcqgn": "njxqsg",
  "vtrnrd": "njxqsg",
  "djexui": "njxqsg",
  "pqhjfc": "njxqsg",
  "bgmljr": "njxqsg",
  "bsxkwc": "njxqsg",
  "fnxamc": "njxqsg",
  "traifc": "njxqsg",
  "rlohpi": "njxqsg",
  "zmjejw": "njxqsg",
  "fgaiot": "njxqsg",
  "prvwsn": "njxqsg",
  "lqzmez": "njxqsg",
  "dokibj": "njxqsg",
  "vzzjsk": "njxqsg",
  "dqiavj": "njxqsg",
  "ptrzio": "njxqsg",
  "bcdsst": "njxqsg",
  "hgwcjq": "njxqsg",
  "fdbive": "njxqsg",
  "brinah": "njxqsg",
  "vlwuan": "njxqsg",
  "vewajo": "njxqsg",
  "fxrjny": "njxqsg",
  "xyvvhp": "njxqsg",
  "vmcpue": "njxqsg",
  "xjopei": "njxqsg",
  "dyniji": "njxqsg",
  "hckrfj": "njxqsg",
  "fgnmcb": "njxqsg",
  "txssad": "njxqsg",
  "jqldsq": "njxqsg",
  "nvokyb": "njxqsg",
  "jxjghw": "njxqsg",
  "hojdue": "njxqsg",
  "tnlqvy": "njxqsg",
  "beusln": "njxqsg",
  "lifutj": "njxqsg",
  "tmxgdk": "njxqsg",
  "fgvarw": "njxqsg",
  "xqypse": "njxqsg",
  "fcjaqm": "njxqsg",
  "vmqhsx": "njxqsg",
  "rvuque": "njxqsg",
  "hbmvrk": "njxqsg",
  "zuoapq": "njxqsg",
  "zmisat": "njxqsg",
  "drzcuf": "njxqsg",
  "vunagm": "njxqsg",
  "vcxfed": "njxqsg",
  "hetgnc": "njxqsg",
  "zbbqsq": "njxqsg",
  "fjgkli": "njxqsg",
  "fogzaw": "njxqsg",
  "vdybeo": "njxqsg",
  "fyyzri": "njxqsg",
  "lfuzog": "njxqsg",
  "bmobqs": "njxqsg",
  "lwrheb": "njxqsg",
  "bcivhd": "njxqsg",
  "fnunlw": "njxqsg",
  "hizses": "njxqsg",
  "nvswhh": "njxqsg",
  "hjzirz": "njxqsg",
  "fgqhyx": "njxqsg",
  "flzyau": "njxqsg",
  "jybhqz": "njxqsg",
  "bztzhj": "njxqsg",
  "hweebz": "njxqsg",
  "bkzaks": "njxqsg",
  "pheygq": "njxqsg",
  "hwpbmu": "njxqsg",
  "jxyceh": "njxqsg",
  "vdehwm": "njxqsg",
  "dpgrqt": "njxqsg",
  "xyyzhw": "njxqsg",
  "vxwcfp": "njxqsg",
  "zvvdnj": "njxqsg",
  "vxmesj": "njxqsg",
  "horjze": "njxqsg",
  "leoluh": "njxqsg",
  "jyyjzs": "njxqsg",
  "fqpgbl": "njxqsg",
  "peyjwx": "njxqsg",
  "fgfzbe": "njxqsg",
  "nnlrki": "njxqsg",
  "fexjlb": "njxqsg",
  "jaajrz": "njxqsg",
  "xwpigo": "njxqsg",
  "jiggzv": "njxqsg",
  "bqwzul": "njxqsg",
  "zfcylw": "njxqsg",
  "xcisdq": "njxqsg",
  "pfthxp": "njxqsg",
  "fvsnwu": "njxqsg",
  "ndhari": "njxqsg",
  "tyjtop": "njxqsg",
  "lvlboe": "njxqsg",
  "nmuxic": "njxqsg",
  "hxorqw": "njxqsg",
  "rzahie": "njxqsg",
  "beyybb": "njxqsg",
  "xqjkcp": "njxqsg",
  "juwyve": "njxqsg",
  "fqgedq": "njxqsg",
  "puijzs": "njxqsg",
  "rvhexm": "njxqsg",
  "renlro": "njxqsg",
  "zyqdvs": "njxqsg",
  "llqofi": "njxqsg",
  "vzxkfl": "njxqsg",
  "dtseqv": "njxqsg",
  "pemxpm": "njxqsg",
  "haapxp": "njxqsg",
  "zdasxv": "njxqsg",
  "trcljw": "njxqsg",
  "rednoe": "njxqsg",
  "labrqc": "njxqsg",
  "xkptia": "njxqsg",
  "vnnfxr": "njxqsg",
  "fgluyw": "njxqsg",
  "dtuita": "njxqsg",
  "vgdxqe": "njxqsg",
  "tobmaz": "njxqsg",
  "vszjdo": "njxqsg",
  "lxdokl": "njxqsg",
  "nkmjxh": "njxqsg",
  "bsltzc": "njxqsg",
  "doancw": "njxqsg",
  "lhdndq": "njxqsg",
  "tuplyq": "njxqsg",
  "zlwlyy": "njxqsg",
  "hbjzjt": "njxqsg",
  "pigzcc": "njxqsg",
  "rgwsxk": "njxqsg",
  "jqsszw": "njxqsg",
  "rwekce": "njxqsg",
  "pjlkva": "njxqsg",
  "baokpp": "njxqsg",
  "dgqzfl": "njxqsg",
  "lfjdoz": "njxqsg",
  "hqypue": "njxqsg",
  "jylsgx": "njxqsg",
  "dakqdg": "njxqsg",
  "nntbxo": "njxqsg",
  "ntjddv": "njxqsg",
  "rraqlk": "njxqsg",
  "fxeiws": "njxqsg",
  "xyrszg": "njxqsg",
  "vyftnw": "njxqsg",
  "fjktig": "njxqsg",
  "zfndvp": "njxqsg",
  "xnkwii": "njxqsg",
  "vskciw": "njxqsg",
  "blwjqd": "njxqsg",
  "vzvhqq": "njxqsg",
  "vvqjhc": "njxqsg",
  "telcei": "njxqsg",
  "vyebqv": "njxqsg",
  "hhkrab": "njxqsg",
  "jzgvsu": "njxqsg",
  "lukghe": "njxqsg",
  "tmgkjt": "njxqsg",
  "llyxpt": "njxqsg",
  "ndyhzm": "njxqsg",
  "vmnwsl": "njxqsg",
  "tqpbol": "njxqsg",
  "tpwoso": "njxqsg",
  "vlwphm": "njxqsg",
  "zkruva": "njxqsg",
  "flbpqk": "njxqsg",
  "beddew": "njxqsg",
  "tylnad": "njxqsg",
  "rpffea": "njxqsg",
  "hmvlxa": "njxqsg",
  "jodxyn": "njxqsg",
  "lgepxr": "njxqsg",
  "pfapdx": "njxqsg",
  "rexsxe": "njxqsg",
  "xuvjpz": "njxqsg",
  "tmjidg": "njxqsg",
  "pyseel": "njxqsg",
  "xbirbd": "njxqsg",
  "jkoykz": "njxqsg",
  "hkanrj": "njxqsg",
  "zcgowp": "njxqsg",
  "demugb": "njxqsg",
  "biymbi": "njxqsg",
  "xafywk": "njxqsg",
  "tthoxe": "njxqsg",
  "zpwjcc": "njxqsg",
  "lnjzri": "njxqsg",
  "jlvqyk": "njxqsg",
  "dtycws": "njxqsg",
  "xycdix": "njxqsg",
  "balqjq": "njxqsg",
  "hdzraa": "njxqsg",
  "ttltbw": "njxqsg",
  "fpfygq": "njxqsg",
  "znnral": "njxqsg",
  "zgggrx": "njxqsg",
  "lwhfye": "njxqsg",
  "rxlihk": "njxqsg",
  "dgnyim": "njxqsg",
  "jbsujg": "njxqsg",
  "vbqdlt": "njxqsg",
  "byhlao": "njxqsg",
  "tsyixa": "njxqsg",
  "bpmeqv": "njxqsg",
  "plhzfl": "njxqsg",
  "lsdizt": "njxqsg",
  "tzemng": "njxqsg",
  "rintdk": "njxqsg",
  "lwrlzo": "njxqsg",
  "vrxypn": "njxqsg",
  "zpjmqx": "njxqsg",
  "vuzioa": "njxqsg",
  "bakbbw": "njxqsg",
  "ncxxul": "njxqsg",
  "rhyemy": "njxqsg",
  "ficzlp": "njxqsg",
  "xulltg": "njxqsg",
  "tfpnjn": "njxqsg",
  "lhdroh": "njxqsg",
  "hveqib": "njxqsg",
  "hlclot": "njxqsg",
  "javxjs": "njxqsg",
  "pjlnya": "njxqsg",
  "nujmdz": "njxqsg",
  "hnfaau": "njxqsg",
  "rvjatm": "njxqsg",
  "drljsg": "njxqsg",
  "fbzlkj": "njxqsg",
  "hiqwys": "njxqsg",
  "byjuwx": "njxqsg",
  "vrmqnm": "njxqsg",
  "xnwrou": "njxqsg",
  "xaerpi": "njxqsg",
  "jeidnq": "njxqsg",
  "nnlltw": "njxqsg",
  "xfhchy": "njxqsg",
  "dzrqao": "njxqsg",
  "lppvfg": "njxqsg",
  "petakh": "njxqsg",
  "taaotd": "njxqsg",
  "rllwts": "njxqsg",
  "jlddeg": "njxqsg",
  "hgzzla": "njxqsg",
  "paulra": "njxqsg",
  "bwdbve": "njxqsg",
  "totsim": "njxqsg",
  "jtpmeh": "njxqsg",
  "fzaonu": "njxqsg",
  "fldvox": "njxqsg",
  "dhhzzl": "njxqsg"
 },
 "ids": [
  "nmhibf",
  "vxwcfp",
  "ldaqbf",
  "vzkdcc",
  "fdbsiw",
  "xnkmqj",
  "drdxps",
  "zbiwoq",
  "lyusma",
  "xczaux",
  "dceiba",
  "pwjcnz",
  "xyelfe"
 ],
 "json": {
  "lohjia": {
   "kind": "script",
   "id": "lohjia",
   "time": 1448588234,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit serial",
   "description": "A #microbit library to print messages to the serial port.",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "dwiebl",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "njwiab",
   "updateid": "lohjia",
   "updatetime": 1448588234,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "17bf73c6e41c65bb6428c3cd67b5dcf0",
   "updateroot": "njwiab",
   "unmoderated": false,
   "noexternallinks": false,
   "lastpointer": "ptr-usercontent-njwiab"
  },
  "jcyhqq": {
   "kind": "script",
   "id": "jcyhqq",
   "time": 1449171821,
   "userid": "xcih",
   "username": "Peli",
   "name": "flashing heart tutorial",
   "description": "control images with variables. #microbit #docs #tutorials #stepByStep",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "pwjcnz",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "fpildn",
   "updateid": "jcyhqq",
   "updatetime": 1449171821,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "",
   "meta": {
    "vimeo": "134118118",
    "videoptr": "td/videos/flashing-heart-0"
   },
   "raw": "",
   "scripthash": "0c4a5a7145bd2b106da08427b9a29622",
   "updateroot": "tummov",
   "unmoderated": false,
   "noexternallinks": false
  },
  "xczaux": {
   "kind": "script",
   "id": "xczaux",
   "time": 1432920327,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "blank blocks",
   "description": "",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "btierw",
   "icon": "",
   "iconbackground": "#FF7518",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "tnbqbf",
   "updateid": "xczaux",
   "updatetime": 1432920327,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "blockly",
   "meta": {},
   "raw": "",
   "scripthash": "1e86cd3ff643e0574f4fe80aca77926b",
   "updateroot": "xczaux",
   "unmoderated": false,
   "noexternallinks": false
  },
  "xbpfet": {
   "kind": "script",
   "id": "xbpfet",
   "time": 1454053350,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit sprites",
   "description": "",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "tjamyj",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "tcvvyucjxj",
   "updateid": "xbpfet",
   "updatetime": 1454053350,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "3be3a16b7688e17178917eebfce7f3c8",
   "updateroot": "dnfbfj",
   "unmoderated": false,
   "noexternallinks": false
  },
  "xyelfe": {
   "kind": "script",
   "id": "xyelfe",
   "time": 1457372439,
   "userid": "dvin",
   "username": "Michał (MS)",
   "name": "blank script",
   "description": "A MicroPython script",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "",
   "icon": "",
   "iconbackground": "#FF7518",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "xyelfe",
   "updateid": "xyelfe",
   "updatetime": 1457372439,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "python",
   "meta": {},
   "raw": "",
   "scripthash": "5456ac9ffb2d7281c254ab884a89c875",
   "updateroot": "xyelfe",
   "unmoderated": false,
   "noexternallinks": false
  },
  "dceiba": {
   "kind": "script",
   "id": "dceiba",
   "time": 1432920385,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "blink blocks",
   "description": "",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "tnbqbf",
   "icon": "",
   "iconbackground": "#FF7518",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "tnbqbf",
   "updateid": "dceiba",
   "updatetime": 1432920385,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "blockly",
   "meta": {},
   "raw": "",
   "scripthash": "ec6dcd9c87814c7dd2d3e8146f17c425",
   "updateroot": "dceiba",
   "unmoderated": false,
   "noexternallinks": false
  },
  "jowara": {
   "kind": "script",
   "id": "jowara",
   "time": 1454603025,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "ADJ script",
   "description": "",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "jwzrac",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "lzfptf",
   "updateid": "jowara",
   "updatetime": 1454603025,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "3a3542c19dbb32d92f0ac219410017a1",
   "updateroot": "hrvbin",
   "unmoderated": false,
   "noexternallinks": false
  },
  "jztbbx": {
   "kind": "script",
   "id": "jztbbx",
   "time": 1445017494,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit senses",
   "description": "A #microbit library that exposes orientation and movement events.",
   "positivereviews": 3,
   "subscribers": 0,
   "comments": 0,
   "baseid": "vkmzfe",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 3,
   "screenshots": 0,
   "rootid": "rjpqoh",
   "updateid": "jztbbx",
   "updatetime": 1445017494,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "9f6891a522efc4f9b846d88580c62325",
   "updateroot": "fnsquv",
   "unmoderated": false,
   "noexternallinks": false,
   "lastpointer": "ptr-usercontent-fnsquv"
  },
  "tgpxru": {
   "kind": "script",
   "id": "tgpxru",
   "time": 1454390980,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit screen",
   "description": "Specialized functions to control the screen #microbit",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "lnyirj",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "bmjsup",
   "updateid": "tgpxru",
   "updatetime": 1454390980,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "6c0c4e2688c7c59a50be7ed5e4e63c12",
   "updateroot": "bmjsup",
   "unmoderated": false,
   "noexternallinks": false,
   "lastpointer": "ptr-usercontent-bmjsup"
  },
  "rwbwnc": {
   "kind": "script",
   "id": "rwbwnc",
   "time": 1454053504,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit game",
   "description": "A #microbit game library.",
   "positivereviews": 3,
   "subscribers": 0,
   "comments": 0,
   "baseid": "xgqnpl",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 3,
   "screenshots": 0,
   "rootid": "fsdvro",
   "updateid": "rwbwnc",
   "updatetime": 1454053504,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "32f9ed1e51d5aea14c6c8d6c465d76c1",
   "updateroot": "fsdvro",
   "unmoderated": false,
   "noexternallinks": false
  },
  "pzngyn": {
   "kind": "script",
   "id": "pzngyn",
   "time": 1453051899,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit music",
   "description": "The music namespace #music",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "xmyfcx",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "zbiwoq",
   "updateid": "pzngyn",
   "updatetime": 1453051899,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "5b4a7e1865a017a7b77c9ed93a1898d6",
   "updateroot": "zbiwoq",
   "unmoderated": false,
   "noexternallinks": false
  },
  "tjwpnx": {
   "kind": "script",
   "id": "tjwpnx",
   "time": 1454603082,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit profile",
   "description": "The list of #microbit supported APIs.",
   "positivereviews": 0,
   "subscribers": 0,
   "comments": 0,
   "baseid": "pnmapm",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 0,
   "screenshots": 0,
   "rootid": "bltbdc",
   "updateid": "tjwpnx",
   "updatetime": 1454603082,
   "ishidden": false,
   "islibrary": false,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "f0c08f9c7b2996f1fc7dd4fbbd8328b5",
   "updateroot": "dqkxtp",
   "unmoderated": false,
   "noexternallinks": false
  },
  "njxqsg": {
   "kind": "script",
   "id": "njxqsg",
   "time": 1459789955,
   "userid": "nzle",
   "username": "Microsoft Touch Develop",
   "name": "micro:bit",
   "description": "The BBC micro:bit device api. #microbit",
   "positivereviews": 10,
   "subscribers": 0,
   "comments": 0,
   "baseid": "jzzrnq",
   "icon": "emptycircle",
   "iconbackground": "#0095ff",
   "cumulativepositivereviews": 10,
   "screenshots": 0,
   "rootid": "bpxuxa",
   "updateid": "njxqsg",
   "updatetime": 1459789955,
   "ishidden": false,
   "islibrary": true,
   "mergeids": [],
   "editor": "",
   "meta": {},
   "raw": "",
   "scripthash": "3757f1ee5345491069d429102ca82718",
   "updateroot": "hmvlxa",
   "unmoderated": false,
   "noexternallinks": false
  }
 },
 "text": {
  "jowara": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"ADJ script\";\nmeta rootId \"om6XYqUcsjDK0npYjNyzn3BW\";\nmeta hasIds \"yes\";\nmeta splitScreen \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n#sCBCojzbqNfj6sRA\naction main() {\n  #xP1meKgKx2EeA03s skip;\n}\n#SVXVucr3dRK4J6Y7 meta import micro\\u003abit {\n  pub \"xgzgcy\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `sync` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` set_pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Number)\n    action `sync` pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Number)\n    action `sync` set_display_mode(mode: String)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` light_level() returns(light: Number)\n    action `sync` is_ble_required() returns(r: Boolean)\n    action `sync` signal_strength() returns(strength: Number)\n    action `sync` on_signal_strength_changed(body: Action)\n  }\n}\n#Alu1GJCl0XiyaFNn meta import micro\\u003abit_screen {\n  pub \"tgpxru\"\n  usage {\n    action `sync` toggle(x: Number, y: Number)\n    action `sync` plot_all()\n    action `sync` toggle_all()\n    action `async` fade_in(ms: Number)\n    action `async` fade_out(ms: Number)\n    action `sync` screenshot() returns(img: ♻ micro\\u003abit → Image)\n    action `sync` plot_bar_graph(value: Number, high: Number)\n  }\n  #Msmo63osSl8VOt4V resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#x2LHHGswL451jMCn meta import micro\\u003abit_game {\n  pub \"rwbwnc\"\n  usage {\n    action `sync` score() returns(score: Number)\n    action `sync` set_score(value: Number)\n    action `sync` life() returns(life: Number)\n    action `async` set_life(value: Number)\n    action `sync` add_score(points: Number)\n    action `async` add_life(lives: Number)\n    action `async` start_countdown(ms: Number)\n    action `async` game_over()\n    action `async` current_time() returns(ms: Number)\n    action `async` remove_life(life: Number)\n    action `async` level_up()\n    action `async` level() returns(lv: Number)\n    action `async` start_stopwatch()\n    action `sync` is_running() returns(running: Boolean)\n    action `async` show_score()\n    action `sync` is_game_over() returns(over: Boolean)\n  }\n  #uTSBhGGRoLDgCI2N resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#xk593tAL91e8H2C4 meta import micro\\u003abit_senses {\n  pub \"jztbbx\"\n  usage {\n    action `sync` on_screen_up(body: Action)\n    action `sync` on_screen_down(body: Action)\n    action `sync` on_shake(body: Action)\n    action `sync` on_logo_up(body: Action)\n    action `sync` on_logo_down(body: Action)\n  }\n  #BbNcU7atbNNbBQmr resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#F7U0eegUWemWOHIj meta import micro\\u003abit_sprites {\n  pub \"xbpfet\"\n  usage {\n    type Led_Sprite\n    action `async` create_sprite(x: Number, y: Number) returns(r: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` move(@this: ♻ micro\\u003abit_sprites → Led_Sprite, leds: Number)\n    action `sync` go_to(@this: ♻ micro\\u003abit_sprites → Led_Sprite, x: Number, y: Number)\n    action `sync` if_on_edge\\u002c_bounce(@this: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` turn_right(@this: ♻ micro\\u003abit_sprites → Led_Sprite, degrees: Number)\n    action `sync` turn_left(@this: ♻ micro\\u003abit_sprites → Led_Sprite, degrees: Number)\n    action `sync` set_direction(@this: ♻ micro\\u003abit_sprites → Led_Sprite, degrees: Number)\n    action `sync` x(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Number)\n    action `sync` y(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Number)\n    action `sync` direction(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Number)\n    action `sync` set_x(@this: ♻ micro\\u003abit_sprites → Led_Sprite, x: Number)\n    action `sync` set_y(@this: ♻ micro\\u003abit_sprites → Led_Sprite, y: Number)\n    action `sync` change_y_by(@this: ♻ micro\\u003abit_sprites → Led_Sprite, y: Number)\n    action `sync` change_x_by(@this: ♻ micro\\u003abit_sprites → Led_Sprite, x: Number)\n    action `sync` is_touching(@this: ♻ micro\\u003abit_sprites → Led_Sprite, other: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Boolean)\n    action `sync` is_touching_edge(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Boolean)\n    action `sync` on(@this: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` off(@this: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` set_brightness(@this: ♻ micro\\u003abit_sprites → Led_Sprite, brightness: Number)\n    action `sync` brightness(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Number)\n    action `sync` change_brightness_by(@this: ♻ micro\\u003abit_sprites → Led_Sprite, value: Number)\n    action `sync` change_direction_by(@this: ♻ micro\\u003abit_sprites → Led_Sprite, angle: Number)\n    action `sync` invalid_sprite() returns(r: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` delete(sprite: ♻ micro\\u003abit_sprites → Led_Sprite)\n    action `sync` set_blink(sprite: ♻ micro\\u003abit_sprites → Led_Sprite, ms: Number)\n    action `sync` change_blink_by(@this: ♻ micro\\u003abit_sprites → Led_Sprite, ms: Number)\n    action `sync` blink(@this: ♻ micro\\u003abit_sprites → Led_Sprite) returns(r: Number)\n  }\n  #kOOTnWpb6q3mwRs3 resolve micro\\u003abit_game = ♻ micro\\u003abit_game with {\n  }\n  #yf5JlXsz20jG8d7Y resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#dXUNy3TCtcUuQHgo meta import micro\\u003abit_music {\n  pub \"pzngyn\"\n  usage {\n    action `sync` tempo() returns(bpm: Number)\n    action `async` change_tempo_by(bpm: Number)\n    action `async` set_tempo(bpm: Number)\n    action `sync` beat() returns(ms: Number)\n  }\n  #Q0tEe5dsulVXEC8U resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n",
  "njxqsg": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit\";\nmeta icon \"Command\";\nmeta color \"#ff008000\";\nmeta rootId \"iYo5o9pL2tCMNDztgDDztVLg\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// The BBC micro:bit device api. #microbit\n#init\naction \\_libinit() {\n  #oCEOjqaW4CH7lS4r // Initialize the library\n  #aCYMP4THhnQkBd4N // {shim:}\n  #x3z5eK4ybVcTCWJh if data→board→is_invalid then {\n    #diswbwoJ0rRtyUbA data→logger := app→create_logger(\"simulator\");\n    #YKJMortE5mXaazK7 data→event_queues := collections→create_string_map;\n    #JjsD2sJPrJ6vUU5w data→counters := web→create_json_builder;\n    #dSJI8h1ZUeMsbz21 data→compass_heading_value := invalid→number;\n    #BamJivB3cALMYQoQ data→start_time := time→now;\n    #pJfHUw7KRZ5r6xTq data→board := media→create_portrait_board(612, 498 + 100);\n    #tGJciuV0e2iZndkr wall→set_background(colors→transparent);\n    #xHZJdg4oIJlrN7cX data→picture := media→create_picture(612, 498);\n    #mes9Z70SlnN52zQT data→padding := 27;\n    #q8k7EFimR0fMv4GZ data→left := 205;\n    #xjbIl53FS2hhHDRL data→@top := 156;\n    #xHQWCYdhMT39OHlO data→bkg := data→board→create_picture(data→picture);\n    #tduKnQa7ilnDwAR8 data→bkg→width := data→board→width;\n    #Y4hGkvffxjBnxeqh data→bkg→left := 0;\n    #biiwiRxx6lfA2TSm data→bkg→@top := 0;\n    #xYFT5Uzzo7KE5Kr1 code→create_buttons;\n    #CT4ZDKfwZOw9wE2M data→finger := data→board→create_ellipse(20, 20);\n    #JoeW2bsnEkDyWSyt data→finger→set_opacity(0);\n    #mEta1VHYHeLZUHiH data→back_leds := data→board→create_sprite_set;\n    #xWKGWdrq4hPuEt6s data→leds := data→board→create_sprite_set;\n    #SfZi0Q4PST9W8C6f $led_opacity := 1;\n    #md36WuHm2WM6OUim $led_w := 10;\n    #wL4ZbsjEBlcHVdT4 $led_offset := 48;\n    #czF5GDH9tIShJiHQ $led_h := 20;\n    #eOl4yTJgCvJGnDPC for 0 ≤ i < 5 do {\n      #xu2j46v9YsXKI68O $led_top := $i * $led_offset + data→@top;\n      #VtKgwueOnr9ToKNo for 0 ≤ j < 5 do {\n        #xbwb4ptsRLHB8U2X $led_left := $j * $led_offset + data→left;\n        #pjVTyTlf5kQ4qA6G $back_led := data→board→create_rectangle($led_w, $led_h);\n        #cuWZqw3O5y2yXQb5 $led := data→board→create_rectangle($led_w + 8, $led_h + 8);\n        #m96ZgbF29ABbEmoL $back_led→left := $led_left;\n        #xGiwGuU71Tu9FgU5 $back_led→@top := $led_top;\n        #QjqcjX5p0pAvotrx $led→x := $back_led→x;\n        #avXCJDNsL2TCMLfU $led→y := $back_led→y;\n        #WPrSA3bt4MdkOVEE $led→color := colors→transparent;\n        #GCX2ykJxlYVUyoYt $led→set_opacity($led_opacity);\n        #g49uDAC8FfRzMF9O $led→set_shadow(10, colors→red, 0, 0);\n        #LZwZ7CQdOe5bMLP7 code→led_index_anim($back_led, $j, $i);\n        #N1DKQdDMWiPq5R3f data→back_leds→add($back_led);\n        #IwDQ2EgCXYvDIWQD data→leds→add($led);\n      }\n    }\n    #xN44GIpThDd2JQn5 code→init_theme;\n    #QIjvtSonf6Bx38tP code→init_eyes;\n    #auzjzpClkNJY94I3 code→init_axis;\n    #BlWLf7LrHMucdyNB code→init_pins;\n    #xVIOjGStCgdLjic6 code→update_axis;\n    #qLoyPDrDUdeG77Vv code→set_theme(\"\");\n    #ByFADaJmirytJ02b code→background_animation;\n    #xmVrpXc8aqbE3dq6 `async` code→animation_worker;\n    #pNdJy7kyaeqKZhfS data→board→on_every_frame;\n    #xbsS9F4HXWsdVT8s where `implicit` \\_body\\_() {\n      #WF6Md7jUVLVAe3m4 code→update_board;\n    }\n    #MYgk7IsTxvU17LkN data→board→post_to_wall;\n  }\n  meta sync;\n}\n#example\naction example() {\n  #unS88qlSD4KUIFo3 // {topic:td/micro-bit-api}\n  #Nn25gD1f1VnaefC5 // {shim:}\n  #WtyCgbH9W8rsFzbE // This library lets you control your **BBC micro:bit**. [read more...](/td/contents).\n  meta private;\n}\n#board\nvar board : Board {\n  // {shim:}\n  transient = true;\n}\n#starttime\nvar start_time : DateTime {\n  // {shim:}\n  transient = true;\n}\n#pTYFKJ2dSVmrISHGn2Cvx1ak\nvar leds : Sprite_Set {\n  // {shim:}\n  transient = true;\n}\n#delay\naction pause(#s4T6Z7saqVl4e7GI ms: Number) {\n  #xw0ceQXmgnW2YLkd // Pause for the specified time in milliseconds\n  #tkri0MjL1YpQLUMc // {help:functions/pause}\n  #aY6hM3Nf9YqDfRgi // {namespace:basic}\n  #oug4zW7u9u8tBZ1B // {weight:88}\n  #AEJQ04Cx4VKx2Rpc // {hints:ms:100,200,500,1000,2000}\n  #IwA49hY0PNZDrAK9 // {shim:micro_bit::pause}\n  #u4DOIK9VQzUgYTrN $ms := math→round($ms);\n  #tRxpGJplhnETomzN if $ms < 0 then {\n    #FsfEfBx8OfPv4xyo code→warning(\"ms should be a greater than or equal to 0\");\n    #YNPa4d34bFB8by52 `return` ;\n  }\n  #GQyW248xhuAJWQPB if `not` data→before_pause→is_invalid then {\n    #oTDD8uv0Dx2hvZqB data→before_pause→run;\n  }\n  #xgfVUH6efvOMy24z app→allow_other_events;\n  #R9tJwE1rZG7RwmLw time→sleep(math→max(1, $ms) / 1000);\n}\n#v8iiJ26rxKIMp44uFEIBfxCW\naction set_led_state(#AfRF8uNgO84DQCu3 x: Number, #MRql0kRW2QFozyIw y: Number, #k48W7K4Qx24WBKJY state: Number) {\n  #xztCKIZ3qGbn4IBK // Sets the LED color\n  #iv3jy8xz84h7sofY // {shim:}\n  #atk33Oey3ER4dzFQ // {hints:state:1,0}\n  #anevNAi4IdyNVhyu $x := math→round($x);\n  #x0qMudFm7xUQCgA4 $y := math→round($y);\n  #so9bs46bW4iXY0SR if $x < 0 `or` $x > 4 then {\n    #xea4WpawOvddatsC code→warning(\"x should be between 0 and 4.\");\n    #x4lxI0KQibRnJrdF `return` ;\n  }\n  else { #xI4iq6zmeb1WSESU if $y < 0 `or` $y > 4 then {\n    #wrr9Pq2Vl4NflTyC code→warning(\"y should be between 0 and 4.\");\n    #hGoYfUVVWx50GxJh `return` ;\n  }\n  else { } } \n  #w44RwY4hgpRIgpHZ $led := data→leds→at(code→index($x, $y));\n  #oj4yNDnGGTQFvFOa code→set_led_color($state, $led);\n  #JtzjlP7mB1bd2Ogn code→update_board;\n  meta private;\n  meta sync;\n}\n#AVn5dHoZz4zk1U2cqDlwGBFI\naction test_board() {\n  #lxgHqHNb4A6nnQOR // {shim:}\n  #z60YvOdiDDDJUrSK code→\\_libinit;\n  #xggqn1uH0YmirAs0 data→board→set_debug_mode(true);\n  #xbs7leriwIgIYW84 code→set_led_state(0, 0, 1);\n  #H2rlrr32Nr1cTRzG contract→assert(code→led_state(0, 0) = 1, \"\");\n  #pE0Lk2GcSwtMu6vO code→set_led_state(1, 1, 1);\n  #HRSkXl2cW0BeOvz4 contract→assert(code→led_state(1, 1) = 1, \"\");\n  #UuPVu5lhnJc26H43 code→set_led_state(2, 3, 1);\n  #q47JRBjbG423RGP7 contract→assert(code→led_state(2, 3) = 1, \"\");\n  meta private;\n  meta test;\n}\n#xbFe3E4xlaPVKqyQgLDbw44R\naction create_A_button() {\n  #xb4n7opYqhj4K5RQ // {shim:}\n  #fsNdOyLEOVKbaNzO data→button_a_inner := code→create_circle(45, 229);\n  #i0mbEct0JsGmR2IX data→button_a_inner→set_color(colors→black);\n  #hxuBSjFJoTGcKkyF data→button_a_inner→set_gradient(false);\n  #x0bngB2zwD5YNqhc data→button_a := code→create_circle(data→button_a_inner→x, data→button_a_inner→y);\n  #xeJ9fLqaRwHysI6H data→button_a→opacity := 0;\n  #QUMDCVZwMje402BB data→button_a→width := 112;\n  #xgxl4xE59t5HUcsH data→button_a→height := 112;\n  #Dvbapa4O529H2fs1 data→button_a→x := data→button_a_inner→x;\n  #jI0c4WdUI8QVWBHC data→button_a→y := data→button_a_inner→y;\n  #byJDE43aA5Kg6F5t data→button_a→on_touch_down($touch_down);\n  #xRnGBKk3PwrPrVq7 where touch_down(x: Number, y: Number) {\n    #Etn5CjWrVyWerIAv data→button_a_inner→set_color(colors→orange);\n  }\n  #spYCmKzaeQetcXJf data→button_a→on_touch_up($touch_up);\n  #hBkQn82nWTIgqurc where touch_up(x: Number, y: Number) {\n    #w8V7Xy22Sy1uDnD0 data→button_a_inner→set_color(colors→black);\n  }\n  meta private;\n  meta sync;\n}\n#rIjgEVDnXyYKKGW2z0G19vjb\naction create_circle(#dY8pewFJbnj6hliB left: Number, #NzrnBsCre4NFCIwk @top: Number) returns(#dyBo2jl2fIsGiYIo sp: Sprite) {\n  #Yba134pj3lkXWPx4 // {shim:}\n  #iBBRg3iUUQVTsPKF $sp := data→board→create_ellipse(42, 42);\n  #xLLim4SK6XqTBI1W $sp→left := $left;\n  #A4vAaBWwpyS1U0Xm $sp→@top := $@top;\n  #mPWpygJUPRH61jT2 $sp→set_color(colors→transparent);\n  #x4n4AmYHSf7bLueZ $sp→friction := 1;\n  meta private;\n  meta sync;\n}\n#sa4Hw2IQQ6yKVRcp\nvar led_on_color : Color {\n  // {shim:}\n  transient = true;\n}\n#sQ4pRVTHKnMu9DYy\nvar button_a : Sprite {\n  // {shim:}\n  transient = true;\n}\n#oUAhsVC3wJ704APn\nvar button_b : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xcaCrKgyeje9xop6\nvar led_off_color : Color {\n  // {shim:}\n  transient = true;\n}\n#eJrkaFqwHMniAE60\naction clear_screen() {\n  #m6PiKdvQQQ7NBgLu // Turn off all LEDs\n  #ZG9A5FPHHkO4uHN5 // {help:functions/clear-screen}\n  #Lc4GU4SQEeDXJcAp // {namespace:basic}\n  #WwZ9Imwcdzf4H2Db // {weight:79}\n  #IsinvyLebNu1rsu9 // {shim:micro_bit::clearScreen}\n  #yVSc2bJhsH0utE1x foreach led in data→leds\n  do {\n    #Tgb6koDUxsIrk8ua $led→set_color(data→led_off_color);\n  }\n  #e4hu5CQWn3R63uYt code→update_board;\n  meta sync;\n}\n#xdRC0FfCUbSXMbmh\naction update_board() {\n  #j4oi2p366aTw6QKa // {shim:}\n  #BoBb0C4wRa7gItQD data→board→evolve;\n  #MROJQrS4v1wSkgL7 code→update_compass;\n  #dEb8PV520FV1duTv code→update_acceleration;\n  #Qs6wzz1w9RgDe3yH data→board→update_on_wall;\n  meta private;\n  meta sync;\n}\n#rVt0ZcmX6UHbaXhI\nvar finger : Sprite {\n  // {shim:}\n  transient = true;\n}\n#T8E8znSXqQ2mBFaZ\naction set_led_color(#By9YA6QxMYHWVuPB state: Number, #w3io4YAswOq422Cs led: Sprite) {\n  #WNlyDe90AUFRSu16 // {shim:}\n  #xUaGp05mSO8ORKZ4 if $state = 0 then {\n    #w00c6FcHfazKsYrb $led→set_color(data→led_off_color);\n  }\n  else {\n    #TJGybBt6wykGbktJ $led→set_color(data→led_on_color);\n    #W39jTBnHFjSBib2V if data→\\_greyscale then {\n      #wL9uIv4tefOsQPiY $led→set_opacity(1 / 10 + 9 / 10 * math→log($state, 2) / 7);\n    }\n  }\n  meta private;\n  meta sync;\n}\n#BJ2LCyxTdQTyJIp4\naction led_state(#N5nd2zYg8ab9fj4E x: Number, #DrKMD4313XKAT7bj y: Number) returns(#zaJYN2jOBvU1HSRr state: Number) {\n  #xw3iEm0w54TEtrgm // Gets the state of a LED\n  #x823TnD4vMJUBvzI // {shim:}\n  #OJ67jtmj97vZUbUW $x := math→round($x);\n  #yMqGU0KTaz37h4lD $y := math→round($y);\n  #PItiVZIbypFvB4Ry if $x < 0 `or` $x > 4 then {\n    #uGUPj25ME43D7Bo3 code→warning(\"x should be between 0 and 4.\");\n    #k8Pjmch1K7qB7lzo `return` 0;\n  }\n  else { #G9RGmjhlZCHYpXo3 if $y < 0 `or` $y > 4 then {\n    #KQulE9FjsIO1jweV code→warning(\"y should be between 0 and 4.\");\n    #E2bQYfvtLS9MGdfx `return` 0;\n  }\n  else { } } \n  #Rs4DiTpY2Z4oV7sm $sprite := data→leds→at(code→index($x, $y));\n  #GrRbVE3LBFdiTxiy if `not` $sprite→is_invalid `and` $sprite→color→equals(data→led_on_color) then {\n    #z54A0XeDMLRIfIif `return` 1;\n  }\n  else {\n    #xNajv7Lgj9sPexQ4 `return` 0;\n  }\n  meta private;\n  meta sync;\n}\n#XJovYmLSOmKdCJPA\naction require_range(#pmedvcwuHbLnWC7W x: Number) returns(#xjG1JKjh2SbYBHt1 x2: Number) {\n  #Q1hQnkMVTzFmkD7E // {shim:}\n  #vF5Zkqpoz3eLR6Fs $x := math→floor($x);\n  #uaSKzCviakcz2Hgh contract→requires($x ≥ 0 `and` $x < 5, \"``x`` must be between 0 and 4 included\");\n  #xUUHEmAdLLlWhbNc $x2 := $x;\n  meta private;\n  meta sync;\n}\n#xVWGu871324FOHjb\naction bit(#qNb6K0K0Rv5gyH5O state: Number, #lJdGRw37BIcyWKtc x: Number) returns(#xI3h98FdRMqtr7rx state_i: Number) {\n  #EUfj2oPVG1MdKp8J // {shim:}\n  #xT7rsPKc3oufTSE8 $state_i := bits→and_uint32($state, bits→shift_left_uint32(1, $x));\n  #xLlmHK36SxZRh1xe if $state_i ≠ 0 then {\n    #ncgTXBzRhH2qcGob $state_i := 1;\n  }\n  meta private;\n  meta sync;\n}\n#BdGhpbmca\ntable Image {\n  // {shim:MicroBitImage}\n  type = \"Object\";\n  persistent = false;\n  fields {\n    #yczPr24geBgMxLbS leds : Matrix\n  }\n}\n#IGYgeBIpT62o9thr\naction sprite_from(#xSkDv46XVEoGCGdp x: Number, #A4TskwCTJk6qsg62 y: Number, #DgwwO2tgSkt14x23 width: Number, #xNwk4F0E4PVfaaQv height: Number) returns(#e7LIwNU1P7sj5r4t sprite: * Image) {\n  #xTkMUmuLHn6rCvcN // Extracts a new sprite from the current LED state.\n  #lEJq90PR2XwX4LWH // {shim:}\n  #GIZkJPyuoHVyLQvL $x := code→require_range($x);\n  #LJ7RyTPUzHmKq7qg $y := code→require_range($y);\n  #Px1qblV2PJdaSpFP $width := math→floor($width);\n  #IkJaTkTmG91scVxN contract→requires($x + $width < 5, \"too many columns\");\n  #UX437qD2aXfAs2K2 $height := math→floor($height);\n  #VugnBMqCdmloPdUn contract→requires($y + $height < 5, \"too many rows\");\n  #dIVCKXtu2IlpAMVY $sprite := code→create_sprite($width, $height);\n  #x2875Vxpg3Bp2PqA for 0 ≤ i < $width do {\n    #KrB4HHn2Lv0THbbV $xi := $x + $i;\n    #Jbzw3CsmimDDyrg8 for 0 ≤ j < $height do {\n      #PIqy1dJJsLGtH4vv $yj := $y + $j;\n      #AZUiEPzXmo0wB0mK $sprite→leds→set_at(code→index($xi, $yj), code→led_state($xi, $yj));\n    }\n  }\n  meta private;\n}\n#UfF7JOuScQfe5nnQ\naction index(#yuxV96yMNc6bUq72 x: Number, #UeWExLbJKOvZm7Lo y: Number) returns(#WZy6fjZAdBtmlvO9 index: Number) {\n  #F7qzqMCjZAg84ncU // {shim:}\n  #jHDElY6pSQg45hPr $index := $x + 5 * $y;\n  meta private;\n  meta sync;\n}\n#xrG3VA1cfC2J48fe\naction create_image_from_string(#WpbiG7M8pO8744cQ text: String) returns(#h937aDHP8dI2uUxT sprite: * Image) {\n  #btZDtCFCtf5qJCze // Create an image from the given text\n  #wW4iJXbwjNxZIFU6 // {shim:}\n  #rFXxMBc9LkwafeIX // {hints:text:hello}\n  #WPj3cOy0MJ59WIY5 code→init_font;\n  #xtzzE0XUUIsjAUc8 $sprite := code→create_sprite(6 * $text→count - 1, 5);\n  #P1KIVstMFDXRwF3I $k := 0;\n  #ocKg9CThqYfc08nJ for 0 ≤ i < $text→count do {\n    #x6Yzz0Oxk4szoFpC $char_code := $text→at($i)→to_unicode;\n    #xrcZN3qkfpggQLbu $char_start := ($char_code - 32) * 5;\n    #scugRD8oRG3wf9PP $w := data→font→width;\n    #w24as3aqIizfCySm if $char_start < 0 `or` $char_start + 5 > data→font→width then {\n      #je2HGup30lVVeYSw $char_code := \" \" →to_unicode;\n      #vOjWWAPcpHUFOaZ7 $char_start := ($char_code - 32) * 5;\n    }\n    #tckFmsMLGvfO2Wt2 data→font→copy($char_start, 5, $sprite, $k);\n    #htKxdnjIIL6Dj32s $k := $k + 5;\n    #rSWCxQVjgak3yHrl if $i < $text→count - 1 then {\n      #xNb8Xf2rGMryC3t4 $k := $k + 1;\n    }\n  }\n  meta private;\n  meta sync;\n}\n#A1geJUVrAOpqBzMO\naction create_sprite(#NXMvo2FCreUM57C8 width: Number, #T4IqbKqxeaWzGfu2 height: Number) returns(#gJCl5tgT9aZygOzM sprite: * Image) {\n  #SetwMqs402272zX2 // {shim:}\n  #dICN6N9VCIvsD3kb contract→requires($width > 0 `and` $height > 0, \"sprite must be at least 1x1\");\n  #SavRXQCZKe8RHaT5 $sprite := records→Image→create;\n  #OS3K5fEIA4Rny0hF $sprite→leds := math→create_matrix($width, $height);\n  meta private;\n  meta sync;\n}\n#EgRqP2ucVXW1es2k\nvar chars\\u002ejson : Json_Object {\n  is\\_resource = true;\n  url = \"data:text/plain;base64,eyIwIjpbNiwxMSwxNSwxMyw2XSwiMSI6WzIsNiwyLDIsMl0sIjIiOlsxNCwxLDYsOCwxNV0sIjMiOlsxNCwxLDYsMSwxNF0sIjQiOlsyLDYsMTAsMTUsMl0sIjUiOlsxNSw4LDE0LDEsMTRdLCI2IjpbNiw4LDE0LDksNl0sIjciOlsxNSwxLDIsNCw4XSwiOCI6WzYsOSw2LDksNl0sIjkiOls2LDksMTUsMSw2XSwiICI6WzAsMCwwLDAsMF0sIiEiOls0LDQsNCwwLDRdLCJcIiI6WzEsMiwwLDAsMF0sIiMiOls2LDE1LDYsMTUsNl0sIiQiOls3LDEwLDYsNSwxNF0sIiUiOls3LDE0LDQsNywxNF0sIiYiOlsyLDUsNiwxMCw1XSwiJyI6WzAsMTAsMCwwLDBdLCIoIjpbNCw4LDgsOCw0XSwiKSI6WzQsMiwyLDIsNF0sIioiOlswLDYsMTUsNiwwXSwiKyI6WzAsMiw3LDIsMF0sIiwiOlswLDAsMCwyLDRdLCItIjpbMCwwLDAsMTUsMF0sIi4iOlswLDAsMCwwLDRdLCIvIjpbMSwxLDIsNCw4XSwiOiI6WzAsNCwwLDQsMF0sIjsiOlswLDQsMCw0LDhdLCI8IjpbMiw0LDgsNCwyXSwiPSI6WzAsMTUsMCwxNSwwXSwiPiI6WzQsMiwxLDIsNF0sIj8iOls2LDksMiwwLDJdLCJAIjpbNiwxMywxMSw4LDZdLCJBIjpbNCwxMCwxNCwxMCwxMF0sIkIiOlsxNCw5LDE0LDksMTRdLCJDIjpbNiw5LDgsOSw2XSwiRCI6WzE0LDksOSw5LDE0XSwiRSI6WzE1LDgsMTQsOCwxNV0sIkYiOlsxNSw4LDE0LDgsOF0sIkciOls2LDgsMTEsOSw2XSwiSCI6WzksOSwxNSw5LDldLCJJIjpbMTQsNCw0LDQsMTRdLCJKIjpbMSwxLDEsOSw2XSwiSyI6WzksMTAsMTIsMTAsOV0sIkwiOls4LDgsOCw4LDE1XSwiTSI6WzksMTUsMTUsOSw5XSwiTiI6WzksMTMsMTUsMTEsOV0sIk8iOls2LDksOSw5LDZdLCJQIjpbMTQsOSwxNCw4LDhdLCJRIjpbNiw5LDksMTEsN10sIlIiOlsxNCw5LDE0LDEwLDldLCJTIjpbNyw4LDYsMSwxNF0sIlQiOlsxNCw0LDQsNCw0XSwiVSI6WzksOSw5LDksNl0sIlYiOls5LDksOSw2LDZdLCJXIjpbOSw5LDE1LDE1LDldLCJYIjpbOSw5LDYsOSw5XSwiWSI6WzksNSwyLDIsMl0sIloiOlsxNSwyLDQsOCwxNV0sIlsiOlsxNCw4LDgsOCwxNF0sIlxcIjpbOCw4LDQsMiwxXSwiXSI6WzcsMSwxLDEsN10sIl4iOls0LDEwLDAsMCwwXSwiXyI6WzAsMCwwLDAsMTVdLCJgIjpbNCwyLDAsMCwwXSwiYSI6WzAsNSwxMSwxMSw1XSwiYiI6WzgsOCwxNCw5LDE0XSwiYyI6WzAsNyw4LDgsN10sImQiOlsxLDEsNyw5LDddLCJlIjpbMCw2LDE1LDgsN10sImYiOlszLDQsMTQsNCw0XSwiZyI6WzcsOSw3LDEsN10sImgiOls4LDgsMTQsOSw5XSwiaSI6WzAsMiwwLDIsMl0sImoiOlsxLDAsMSwxLDZdLCJrIjpbOCwxMCwxMiwxMCw5XSwibCI6WzEyLDQsNCw0LDE0XSwibSI6WzAsOSwxNSwxNSw5XSwibiI6WzAsMTQsOSw5LDldLCJvIjpbMCw2LDksOSw2XSwicCI6WzAsMTQsOSwxNCw4XSwicSI6WzAsNiw5LDcsMV0sInIiOlswLDExLDEyLDgsOF0sInMiOlswLDcsNCwyLDE0XSwidCI6WzQsMTQsNCw0LDNdLCJ1IjpbMCw5LDksOSw2XSwidiI6WzAsOSw5LDYsNl0sInciOlswLDksMTUsMTUsNl0sIngiOlswLDksNiw2LDldLCJ5IjpbMCw5LDcsMSw2XSwieiI6WzAsMTUsMiw0LDE1XSwieyI6WzYsNCwxMiw0LDZdLCJ8IjpbNCw0LDAsNCw0XSwifSI6WzEyLDQsNiw0LDEyXSwifiI6WzAsMCw1LDEwLDBdfQ==\";\n  transient = true;\n}\n#FBCYO1ysYzVS3rEJ\naction test_scroll_string() {\n  #vY9MA7hWCXU1Ra23 // {shim:}\n  #eho3QrBxWsMAix4R code→\\_libinit;\n  #xSaLaPGzEk8WaSd1 code→show_string(\"\", 100);\n  #mPN9ztLMk7UbME0e code→pause(1000);\n  #PYmqDeoYaFBfJT8x code→show_string(\"A\", 100);\n  #gb29N4yYNoQOfoaW code→pause(1000);\n  #a4p4CD0Rz14TmzwM code→show_string(\"0123\", 100);\n  #xGyJN7Jgvwq9ZB4s code→pause(1000);\n  #xSjakVYLu7gd1QHM $sprite := code→create_image_from_string(\"Hello\");\n  #VKpTa6fxINbbXVz5 $sprite→scroll_image( - 5, 200);\n  #eyb8bNW9ffSO6O2G $sprite→scroll_image(5, 200);\n  #bwM4Tq2dxt2mOHIW $sprite→scroll_image(1, 200);\n  #ZYxNc8AOTZbdOJ1n $sprite→scroll_image( - 1, 200);\n  meta private;\n  meta test;\n}\n#Zm96IqdgVrI2iCjB\naction width(#mNqXeR0Venxmv0uf @this: * Image) returns(#xY2xXA2sFDmKE4PQ w: Number) {\n  #DPngUzxZ3HlrXHyv // Gets the width in columns\n  #ulYlLiq3yUhayh1l // {help:functions/width}\n  #gFXMVYYVHx5aY7Ts // {namespace:image}\n  #x2eHyTJVIamAaq45 // {shim:micro_bit::getImageWidth}\n  #z66k2w22K7InEnyV $w := $@this→leds→row_count;\n  meta sync;\n}\n#rZT5E9pMud033e54\naction height(#lwwRe2IKIaJ2btEs @this: * Image) returns(#oV9jdReQ85HMKiON h: Number) {\n  #gL2f9kgRHinswu2z // Gets the height in rows\n  #x6JI6jqwN4h4M2jY // {shim:}\n  #HWsux5YjWGEpumtE $h := $@this→leds→column_count;\n  meta private;\n  meta sync;\n}\n#D944KGlI2CeHG0gq\nvar board_color : Color {\n  // {shim:}\n  transient = true;\n}\n#H1uQDGTSbSLoJlFF\naction scroll_image(#dVF1wUlpKx2pPtHa @this: * Image, #Fr2rDLarbEiIzfHm x_offset_per_step: Number, #gPjfa2RSvx3dAN3H interval: Number) {\n  #xGQ520j5fXArwqWl // Scrolls sprite through the screen. If sprite has width <= 5, does not scroll, otherwise, shifts the image by one column every ``interval`` milliseconds.\n  #iT7MH9Kd29dafjMN // {help:functions/scroll-image}\n  #GkJdERhnRveIvkAV // {namespace:image}\n  #u06IOFGf80LHWg3W // {weight:68}\n  #xtyyk9lLDfqJLWpL // {hints:x offset per step:5,1}\n  #kK2O5fLxOlBFvjHG // {hints:interval:400,100}\n  #UrNHQ26Tc7HxFp1p // {shim:micro_bit::scrollImage}\n  #xtlglkDAp2Q1OJUh $anim_id := data→current_animation;\n  #Jysm4Pd4lszqgxXV $x_offset_per_step := math→round($x_offset_per_step);\n  #Hv8BBJJLK4ATmTYK code→queue_animation_and_wait;\n  #lyweMkPTU58Kbmtp where `implicit` \\_body\\_() {\n    #xluG50TZnkrViJjL if $x_offset_per_step > 0 then {\n      #xMcTw7gf2Fz9FwZ8 $dx := math→max(1, $x_offset_per_step);\n      #CXEE00t44mfWLUIC $x := 0;\n      #GwuUOeH3zqRBqEQ1 while $x + 4 < $@this→width do {\n        #x5vjJ5zSuf1rqKnV $@this→render_image($x);\n        #OwLsXGKEmYf3u4Gj code→pause($interval);\n        #PHeDA80GctvZmtme if data→current_animation ≠ $anim_id then {\n          #ietA2urgnfVpp2ss `return` ;\n        }\n        #wDxlPdR9HkBH4PHv $x := $x + $dx;\n      }\n    }\n    else {\n      #xQMEmAD35uksb3qz $dx := math→min( - 1, $x_offset_per_step);\n      #JkulbmMt5UmnsSIB $x := $@this→width - 5;\n      #ujNFlLWKwHnNk5rJ while $x ≥ 0 do {\n        #Gp42FT0fV8jwrcE4 $@this→render_image($x);\n        #d4IJlY2NIltFZZiE code→pause($interval);\n        #uLdovnfNVFKKXuXO if data→current_animation ≠ $anim_id then {\n          #yJCgIFUX2A0x3Os4 `return` ;\n        }\n        #xgrTFzGv8MLnnysv $x := $x + $dx;\n      }\n    }\n  }\n}\n#j6How14prTjVLiKJ\naction button_is_pressed(#dwrDe5YG33oG3MHB name: String) returns(#RdtB26hD1lA5OO8J pressed: Boolean) {\n  #xDfRt2S0C1CkPSHd // Get the button state (pressed or not) for ``A`` and ``B``.\n  #dmv7pPfdUX3Nii67 // {help:functions/button-is-pressed}\n  #RVFWVBfCjLPg2uRU // {namespace:input}\n  #yTzqdrDfKTub5zSp // {weight:59}\n  #xROirQwDWqY9ZgYL // {enum:name:A=MICROBIT_ID_BUTTON_A,B=MICROBIT_ID_BUTTON_B}\n  #QFNxD51gqBGenDQ6 // {shim:micro_bit::isButtonPressed}\n  #ntxF2QNxLArWB2V5 $name := $name→trim(\" \\t\")→to_lower_case;\n  #nA1Wp5PR401L45J9 if data→board→touched then {\n    #Tg9Z2s4GUdfgvcf8 $target := code→button_from_id($name);\n    #YTVfEiLMEHSyTaYY $p := data→board→touch_current;\n    #tq26Gcbvm0zenWR0 data→finger→set_pos($p→x, $p→y);\n    #PhXWkNR6epuZNkBa if data→finger→overlaps_with($target) then {\n      #IKV9abE47o0mPXbn `return` true;\n    }\n    else { #xvwUV2et9kypbYOc if $name→equals(\"a\") `or` $name→equals(\"b\") then {\n      #wM0dFQyl00dy9W8y $target := code→button_from_id(\"a+b\");\n      #Sg4UFkSp2RJWNX7P if data→finger→overlaps_with($target) then {\n        #VhRVWWt2X81ZkFV0 `return` true;\n      }\n    }\n    else { } } \n  }\n  #rujS852B1Sx8Gh1f if $name→equals(\"a\") `and` (senses→is_key_pressed(\"a\") `or` senses→is_key_pressed(\"left\")) then {\n    #eNt8xKqeXVB6CgMS `return` true;\n  }\n  else { #en3kBi1aD9t9e4lG if $name→equals(\"b\") `and` (senses→is_key_pressed(\"b\") `or` senses→is_key_pressed(\"d\") `or` senses→is_key_pressed(\"right\")) then {\n    #FclRZcdq6c4gnFaI `return` true;\n  }\n  else { } } \n  #o4B6c8hDkCKfcqbP `return` false;\n  meta sync;\n}\n#YKkpIRxYCYj6luNy\naction plot(#xr21JhTVxIw6N8eD x: Number, #mr8Hkd8kLjqzu8IZ y: Number) {\n  #C4ZSSnemxpZWIiOE // Turn on the specified LED using ``x``, ``y`` coordinates (``x`` is horizontal, ``y`` is vertical)\n  #oO7LJ2kRt1FlICbW // {help:functions/plot}\n  #PTHzXQhcnHkdu9e2 // {namespace:led}\n  #oVRf0YOvIGx9J1i9 // {weight:78}\n  #Oko244Xjtl3XaFOw // {hints:x:0,1,2,3,4}\n  #xEIQtXe6fw4kg5FH // {hints:y:0,1,2,3,4}\n  #tPQEuS6Gmqc7l6oB // {shim:micro_bit::plot}\n  #r35AgHxwXK1n29pb code→set_led_state($x, $y, 1);\n  meta sync;\n}\n#f02nNkUzv6b6aPHB\naction point(#PGRW6DJGVEVi5wFW x: Number, #JS5Z305cxyrTyxH2 y: Number) returns(#u0fXIVDG4WzrfN7B on: Boolean) {\n  #WPM6kMiDO4MFbj6F // Get the on/off state of the specified LED using ``x, y`` coordinates.\n  #cYimilnL8Y3meMHz // {help:functions/point}\n  #uLmwV8jgK3a2Fequ // {namespace:led}\n  #hferw4vyJzoT524J // {weight:76}\n  #fc2JgYLVULK0v7iN // {hints:x:0,1,2,3,4}\n  #MF2t9k2UiqFfh4Cm // {hints:y:0,1,2,3,4}\n  #ugAQOqPTl7WVJCXs // {shim:micro_bit::point}\n  #rJpqUyeFN9Z27674 `return` code→led_state($x, $y) > 0;\n  meta sync;\n}\n#xX8BI6pQozHWIVZF\naction show_string(#EEchsFBax4g4Pk4y text: String, #xhQbPcu59cxTmgPb interval: Number) {\n  #TC2ipxc1vXR9hICR // Display text on the display, one character at a time, and shift by one column each ``interval`` milliseconds. If the string fits on the screen (i.e. is one letter), does not scroll.\n  #IFE4Aw9tdA4X617h // {help:functions/show-string}\n  #lO7UShx1xNCN5Zk3 // {namespace:basic}\n  #bAlRv4X18pWxONAI // {weight:87}\n  #Scfwz74tte2bvoT1 // {hints:interval:150,100,200,-100}\n  #kf4HddkY4wQUaUAU // {shim:micro_bit::scrollString}\n  #DMmxTOrCif13ztvx $interval := math→round($interval);\n  #N4KPZT9PpUDTn9R1 if $text→is_empty then {\n    #yIHTm1wXSp2w8fes code→queue_animation_and_wait;\n    #GcGnNDNYH7xeg0od where `implicit` \\_body\\_() {\n      #YB68tFgWoN2PlJYA code→clear_screen;\n      #YvZOGJUcPcBXex8I code→pause($interval * 5);\n    }\n  }\n  else { #Qv7UTtB9F3o4pkvl if $text→count = 1 then {\n    #YeGT0NEaIr4ew2Wd code→queue_animation_and_wait;\n    #x4NHkwmJbhbUpSeh where `implicit` \\_body\\_() {\n      #jQ3KH7NUrCa547Rj $sprite := code→create_image_from_string($text);\n      #y26xiE0eE4lGwFIH $sprite→show_image(0);\n      #TxqzE2nAu66dxqXK code→pause($interval * 5);\n    }\n  }\n  else {\n    #yCPOXhiQN5kj94eK if `not` $text→starts_with(\" \") then {\n      #ijFFFXMfycO3t4zT $text := \" \" →concat($text);\n    }\n    #mq4ZR5VqItlUQ6Ky if `not` $text→ends_with(\" \") then {\n      #flvuXQ4pm95KpIM4 $text := $text→concat(\" \");\n    }\n    #VED492aakcpq3QUQ $sprite := code→create_image_from_string($text);\n    #D4qMsHOTTZizH0aw $sprite→scroll_image(1, $interval);\n  }\n  } \n}\n#VQSvphGIva2j2eg4\naction unplot(#O7M8Vy1IbaXhzvLo x: Number, #GhmbCx46is3dXy3V y: Number) {\n  #x5dqUP1tUHNDDO3f // Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical)\n  #xHyH4CKLbyg4Z46P // {help:functions/unplot}\n  #xFBaTe43eGHuX7jq // {namespace:led}\n  #OI57h7faeHyfUDJb // {weight:77}\n  #qbCl2JQDXjhkn4EY // {hints:x:0,1,2,3,4}\n  #bSncxBMLCswRbQ32 // {hints:y:0,1,2,3,4}\n  #ogXFG41ygqbXVmwT // {shim:micro_bit::unPlot}\n  #x742H6HoaE2M3kHZ code→set_led_state($x, $y, 0);\n  meta sync;\n}\n#O675B3CiRNXztplX\naction on_button_pressed(#M03fUuuX2m9eRu7n name: String, #LzMsXwEMSCmDzfWI body: Action) {\n  #K1FqW47X5j2qSM4S // Do something when a button (``A``, ``B`` or both ``A+B``) is pressed\n  #qpJP52P9EiGj7TmZ // {help:functions/on-button-pressed}\n  #LlzvO4Vhe7GjhJdh // {namespace:input}\n  #bb2jhwAjjludGu2o // {weight:58}\n  #fm3i5OlTIzr9FGuU // {enum:name:A=MICROBIT_ID_BUTTON_A,B=MICROBIT_ID_BUTTON_B,A+B=MICROBIT_ID_BUTTON_AB}\n  #KwFDbs7Kr12Y7FTP // {shim:micro_bit::onButtonPressed}\n  #OzSnTzWiKXQk0HlQ $evid := \"on button pressed \" ∥ $name;\n  #FMX7Dy8may7mfc7j code→notify_event_registration($evid);\n  #h2x2L30VBbMGVNED $btn := code→button_from_id($name);\n  #xOIGjOLy2Zmt99MW code→clear_button_handler($name);\n  #F5Y2ciTtYo87uZSG $ev := $btn→on_touch_down($touch_up);\n  #j0K6jsuWQ4V0EcaI where touch_up(x: Number, y: Number) {\n    #zvnW22u4MgaK24ge code→queue_event($body, $evid);\n  }\n  #hijH5eY42toXLOFF code→store_button_handler($name, $ev);\n  meta sync;\n}\n#Xf05xdIQbCZ19OFL\naction show_image(#x4Os5UgJK1k1DyDo @this: * Image, #WCEICn0SBZ7AnvYq x_offset: Number) {\n  #ZRFi6tDU9uTL4BAg // Shows an frame from the image at offset ``x offset``.\n  #CSX0am9r0KxyCfal // {help:functions/show-image}\n  #xo16JkWN0uUFScS2 // {namespace:image}\n  #ffde8HnYsd4thcGC // {namespace:led}\n  #s0MpoKh2adnhmM8z // {weight:69}\n  #RfVXECzwY1YjIfSF // {hints:x offset:0,5,10}\n  #UN2qrX2ZL1nyHdhU // {shim:micro_bit::showImage}\n  #AqfPdUQhQ8tq2B7e code→render_image($@this, $x_offset);\n}\n#gszRC4JNYzCIA8xJ\naction compass_heading() returns(#zcZKxlXZbsmdRJqQ degrees: Number) {\n  #xWohtN6AzrOdY6So // Get the current compass compass heading in degrees.\n  #ncq2Y4nDXRMWihmD // {help:functions/compass-heading}\n  #xELObR81CTxHPD2w // {namespace:input}\n  #m4jqzA8etiVBViTO // {weight:56}\n  #x2ui0y5T5xOVIJqE // {shim:micro_bit::compassHeading}\n  #r5T8xUyjlMatcURv if data→compass_arrow→is_invalid then {\n    #znZ4XizKuZgheSQa code→create_compass;\n  }\n  #xPo09mCqoceFQEYn $h := data→compass_heading_value;\n  #x8XQ4UchqvBIyyls if $h→is_invalid then {\n    #wRS57ygpIbvVyPSm $h := senses→heading;\n    #qErFwnuTtYjZ4nLa if $h→is_invalid then {\n      #hHLRZosDB3Q2AvMU $h := 0;\n    }\n  }\n  #T884bHCaSqLpYr2s `return` math→round($h);\n  meta sync;\n}\n#W2sYA4QxOtQbam5R\naction acceleration(#xFFtxqCX93owGiup dimension: String) returns(#x6aaLDiJe51GV4oq millig: Number) {\n  #sgNx1oCFIRqwLC6n // Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024)\n  #DoP0wrdqmS24eYbg // {help:functions/acceleration}\n  #lYmOu5jwgh9COs0W // {namespace:input}\n  #lmLkxkGRFp62YJly // {weight:57}\n  #LydMcPZr1SYTRbIt // {enum:dimension:x=0,y=1,z=2,strength=3}\n  #x2JSA5b4r4dcAO9P // {shim:micro_bit::getAcceleration}\n  #T4Ks27Pca5wQIBTz if data→acc_title→is_invalid then {\n    #a5RQGCAqswXV6Eiq data→acc_title := data→board→create_text(100, 40, 20, \"acceleration:\");\n    #xhS5Chpszr4Peq29 data→acc_title→fit_text;\n    #OO8NswAECGRtUDCO data→acc_title→color := colors→black;\n    #gV3Nm9rI8rv9WFSB data→acc_title→y := data→board→height - 80;\n    #ugQ4877rJLld9R1t data→acc_title→left := 200;\n    #xWsWgWWKrNZ8rzNs data→acceleration_x_text := data→board→create_text(100, 40, 20, \"x: -000\");\n    #q95IkSqEY2H4xCc6 data→acceleration_x_text→fit_text;\n    #xtbi4k3NDjlGfYi4 data→acceleration_x_text→text := \"\";\n    #zudWOEtdnOldj5Vt data→acceleration_x_text→y := data→board→height - 58;\n    #YaOi4wx0w2L2bRrd data→acceleration_x_text→left := 200;\n    #ydbSLoThXq28afSs data→acceleration_y_text := data→board→create_text(100, 40, 20, \"y: -000\");\n    #mm44LAERXjEwcw45 data→acceleration_y_text→fit_text;\n    #BMozg2TG88gKqWS5 data→acceleration_y_text→text := \"\";\n    #lVXLNglfbI6mlkMj data→acceleration_y_text→y := data→board→height - 36;\n    #GKJFyWtx7U9Bwkih data→acceleration_y_text→left := 200;\n    #Ij8VSPlCh9cUHLtL data→acceleration_z_text := data→board→create_text(100, 40, 20, \"z: -000\");\n    #xW6jBmKGvurjowgm data→acceleration_z_text→fit_text;\n    #uRhNDZQxzf60QioK data→acceleration_z_text→text := \"\";\n    #RaMet5qas3S6DyL2 data→acceleration_z_text→y := data→board→height - 14;\n    #xADu072x9Zk92VEH data→acceleration_z_text→left := 200;\n  }\n  #HQMGQT9aJ2NkNqVV $p := senses→acceleration_quick;\n  #x51K0wrwuxa2aoXN if $dimension→equals(\"x\") then {\n    #nEUa5R0jRvgiO3B5 data→acceleration_x_text→color := colors→black;\n    #R6D1BOSBvoJOofLE $millig := math→round($p→x * 1024);\n  }\n  else { #hpsliRC29yxAgj7q if $dimension→equals(\"y\") then {\n    #SYSYbYCqENPZIto2 data→acceleration_y_text→color := colors→black;\n    #o4OHeiSP0U04H5Oi $millig := math→round($p→y * 1024);\n  }\n  else {\n    #V2j2C7I62xgo9cWz data→acceleration_z_text→color := colors→black;\n    #opsthjH4KZ60PzoB $millig := math→round($p→z * 1024);\n  }\n  } \n  meta sync;\n}\n#itddg6di2mtKdWUA\naction digital_write_pin(#kihCn9i6hirgp2CN name: String, #SKnQ2VHVowJuQj03 value: Number) {\n  #fqLCfHZvhkkbdEsl // Set a pin or connector value to either 0 or 1.\n  #x8IX3LaoPHuSPP1k // {help:functions/digital-write-pin}\n  #QvcKHCKm4bLp2av4 // {namespace:pins}\n  #p48bRe3Fk04cqci0 // {weight:48}\n  #hf52W4GpWNOvCu3I // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2,P3=uBit.io.P3,P4=uBit.io.P4,P5=uBit.io.P5,P6=uBit.io.P6,P7=uBit.io.P7,P8=uBit.io.P8,P9=uBit.io.P9,P10=uBit.io.P10,P11=uBit.io.P11,P12=uBit.io.P12,P13=uBit.io.P13,P14=uBit.io.P14,P15=uBit.io.P15,P16=uBit.io.P16,P19=uBit.io.P19,P20=uBit.io.P20}\n  #xm4nD5CwJqCSj9nK // {shim:micro_bit::digitalWritePin}\n  meta sync;\n}\n#xqTDv45uY4g5Elo4\naction digital_read_pin(#w0yR0K9R0Vc1fl1w name: String) returns(#YJovAyKaUYf7fdeN value: Number) {\n  #bZe0bFUC7DkD6n1D // Read the specified pin or connector as either 0 or 1\n  #dmS3OiTqd3Gl4lDI // {help:functions/digital-read-pin}\n  #BnyFEXR5wKKdhtR5 // {namespace:pins}\n  #h1y7ij55abn1ywo2 // {weight:49}\n  #xXyGXmuQJNZlU61v // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2,P3=uBit.io.P3,P4=uBit.io.P4,P5=uBit.io.P5,P6=uBit.io.P6,P7=uBit.io.P7,P8=uBit.io.P8,P9=uBit.io.P9,P10=uBit.io.P10,P11=uBit.io.P11,P12=uBit.io.P12,P13=uBit.io.P13,P14=uBit.io.P14,P15=uBit.io.P15,P16=uBit.io.P16,P19=uBit.io.P19,P20=uBit.io.P20}\n  #KeelVlaOy290uC3r // {shim:micro_bit::digitalReadPin}\n  #YQtrwltmovQDIOC4 $pin := code→pin_by_name($name);\n  #Ko563vnmhZrsGquz if `not` $pin→is_invalid `and` $pin→mass - 1 > 0 then {\n    #xMThD47Dxan2pEwh `return` 1;\n  }\n  else {\n    #JIo9xOYMSEWhMsDF `return` 0;\n  }\n  meta sync;\n}\n#IMZk4sIic3bl2IqV\naction analog_read_pin(#MbbuFwADdbqnJ4Vx name: String) returns(#NMqOBEeeGloyin4x value: Number) {\n  #xbV7xMVLeyDT0M4e // Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n  #xah2vLBRZf3FqQzb // {help:functions/analog-read-pin}\n  #xsg9Er2mxpPh27XU // {namespace:pins}\n  #n6fzrbe7G44K3Hb9 // {weight:47}\n  #x60f9nanAtGqf58c // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2,P3=uBit.io.P3,P4=uBit.io.P4,P10=uBit.io.P10}\n  #KbSL0ZGyQSVvXAE4 // {shim:micro_bit::analogReadPin}\n  #xYp4xr8kW2d84h5C $p := code→pin_by_name($name);\n  #x4ki5CnUbrxJQS5O `return` $p→mass - 1;\n  meta sync;\n}\n#HV4Q7fi2POmCkKXI\naction analog_write_pin(#Ij91JuDakdZUgyo4 name: String, #CeWgWOcwgRe0D5op value: Number) {\n  #eDN1oz2oyUfdvk48 // Set the connector value as analog. Value must be comprised between 0 and 1023.\n  #kTJK4kSvEWdiaeOC // {help:functions/analog-write-pin}\n  #b4oneIlT9h82g7S4 // {namespace:pins}\n  #M12kgf6X8FWgiE4P // {weight:46}\n  #RE8jT20OKbkM5oUQ // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2,P3=uBit.io.P3,P4=uBit.io.P4,P10=uBit.io.P10}\n  #RXZASxwspuxN3AMn // {hints:value:1023,0}\n  #AY2QBjk4JghxAoSU // {shim:micro_bit::analogWritePin}\n  #NhjrLchqhj38jvVW $value := math→round($value);\n  #VoXahNiX4SWBg3rH if $value < 0 `or` $value > 1023 then {\n    #rv064Y14no7Xfrs6 code→warning(\"value should be between 0 and 1023.\");\n  }\n  meta sync;\n}\n#FOUJKwAjjQYg4Z01\naction create_image(#xkJvjGlZhyZHdmXg leds: String) returns(#d56UY1ORndlIMO5Z img: * Image) {\n  #xubRNFj0V14GVLwA // Create an image from a string of 0s and 1s\n  #lnGJt7NO5XSCYPCy // {help:functions/create-image}\n  #L3GzUd2cQeVret60 // {namespace:image}\n  #M8Rx5C74XOlneYTn // {weight:67}\n  #jwMX2SPoQ4OZPjFE // {language:leds:bitmatrix}\n  #uCb1uN0qGPIcavMf // {shim:micro_bit::createImage}\n  #ssLFHuIGAuT7O22r $img := code→parse_image($leds);\n  meta sync;\n}\n#xyrtyZ1z9MfBqH74\naction test_scroll_frames() {\n  #VgklC7f31Qls4an6 // {shim:}\n  #gyNJ4o0Keyf2wQO7 $sprite := code→create_image(\"1 1 1 1 1 1 0 0 0 0\\n0 0 0 0 0 1 0 1 0 0\\n0 1 1 1 0 1 0 1 0 1\\n0 0 0 0 0 1 0 1 0 0\\n0 0 1 0 0 1 0 0 0 0\");\n  #Nnmh4QLzVUWiEDS4 $sprite→scroll_image(5, 1000);\n  meta private;\n  meta test;\n}\n#x6MHp7ZQosljXBmh\naction button_from_id(#eWMyP2eed08EGj4i name: String) returns(#zZfqvpXF2TdNNjHB btn: Sprite) {\n  #zYsdQ2fdRAyiMMz6 // {shim:}\n  #xWip9UlKCrWerh1O $btn := invalid→sprite;\n  #HaglGnKeAYSISmWn $name := $name→trim(\" \\t\")→to_lower_case;\n  #IqwO4RKwUHTnlHCE if $name→equals(\"a\") then {\n    #ym1Bm5lxgGWMsD13 `return` data→button_a;\n  }\n  else { #dbL1RrfP7iYQnrPS if $name→equals(\"b\") then {\n    #jIZBLoeBLvpv87DZ `return` data→button_b;\n  }\n  else {\n    #K8Hk416DRp2f8rBC `return` data→button_a\\u002bb;\n  }\n  } \n  meta private;\n  meta sync;\n}\n#j57JbuVLhpRqJgbE\naction brightness() returns(#BZntGnCXsZYfxF2X brightness: Number) {\n  #xThf61EiGzXmaQVh // Get the screen brightness from 0 (off) to 255 (full bright).\n  #VrdakCnATFjtHjF2 // {help:functions/brightness}\n  #QNhPnnSYegd96QKN // {namespace:led}\n  #xQl2lvnN0kK3Npk0 // {weight:75}\n  #ffmCdknGe2J5ReU5 // {shim:micro_bit::getBrightness}\n  #Y872aj2BcDz0OMq2 $sprite := data→leds→at(0);\n  #xw0Ia9fgB02ZhIYE $x := $sprite→opacity;\n  #x3An1b9z2xip0Gn9 `return` math→floor($x * 255);\n  meta sync;\n}\n#Twa3ce2bugWhfW5Y\naction set_brightness(#kQeLgaV0YyWLTlCU value: Number) {\n  #j2osE1iAluAsBgjv // Set the screen brightness from 0 (off) to 255 (full bright).\n  #x1oLl7Js4DF5vUEd // {help:functions/set-brightness}\n  #r0hfweCAmAfJleDQ // {namespace:led}\n  #GTVh8j2PgD5ThcRO // {weight:74}\n  #f7pgqybG2Xda88Bm // {hints:value:255,50,30,10,0}\n  #xqY7TLQ2N0x8G9Yv // {shim:micro_bit::setBrightness}\n  #Vw0rhEfqksjuLmTz $value := math→round($value);\n  #j4S5fdOn2dZJ1v9c if $value < 0 `or` $value > 255 then {\n    #ARlErhDNjWUNk008 code→warning(\"value should be between 0 and 255.\");\n    #lVvkWmOH3yaOkd6P `return` ;\n  }\n  #w1r41Dx8m1rxeJey $opacity := $value / 255;\n  #MB3OiAEWMZ7wvrZH foreach sprite in data→leds\n  do {\n    #u4R2mHlwhMSXKBTj $sprite→set_opacity($opacity);\n  }\n  meta sync;\n}\n#amts8p71bcrUxkz1\naction test_main() {\n  #xyiiPHS90ToCvNsw // {shim:}\n  #xWzTyxr4F353Sjnb for 0 ≤ i < 5 do {\n    #xfa5QOwui5DgOLIp for 0 ≤ j < 5 do {\n      #CIb4JiIp4VnOBWLz code→plot($i, $j);\n    }\n  }\n  #ap6UE2At48Euv4sK code→set_brightness(0);\n  #ZOaTPEpAJrW2mnS7 code→pause(1000);\n  #xXe1OlzRTbkfj9Nm code→set_brightness(100);\n  #xUMgLebswWRJzs1J code→pause(1000);\n  #jNQcDqEmnENrFh42 code→set_brightness(50);\n  #HiVvh4TiFo0Epu2m code→pause(1000);\n  #gP2D5I1dvKO6fP23 while true do {\n    #Xt41f42aNzuj5nuU code→show_animation(\"0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\n0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0\\n1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0\\n0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0\\n0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\", 400);\n  }\n  meta private;\n  meta test;\n}\n#SqFERoUjMO52Yumn\naction show_animation(#LyDDqLjSvn1Mm4Xg leds: String, #C8902m9EtYbNj0u2 interval: Number) {\n  #i6Ya8Ok0jXfIWDwx // Shows a sequence of LED screens as an animation with an ``interval`` delay between each frame\n  #IMLoWk7aPkY2iqZ1 // {help:functions/show-animation}\n  #n2TGAB2Ool7dvNeM // {namespace:basic}\n  #x9issdCQmgXJGFgm // {language:leds:bitmatrix}\n  #xGPHI0rWxwi7n4s6 // {hints:interval:400,300,500,600}\n  #PnCSsOeThMMBAVXy // {shim:micro_bit::showAnimation}\n  #Ruz1jL2FF4H8oDpB $interval := math→round($interval);\n  #acZvOWOMmtBi8EK8 $img := code→parse_image($leds);\n  #vveYnNG2g6NXdP5g $img→scroll_image(5, $interval);\n}\n#SNaX2qGs1EJq6FCk\nvar led_indexes : Sprite_Set {\n  // {shim:}\n  transient = true;\n}\n#YEEItevulMc5K8Y2\naction update_axis() {\n  #xPVzjwLZvZBJ1x54 // {shim:}\n  #dkkLIU2fisYJPDgs for 0 ≤ i < 5 do {\n    #L6R7REP2RTV1ScG3 $sprite := data→led_indexes→at($i);\n    #x05FmmbOP9lsYovE $sprite→x := 211 + $i * 48;\n    #UkRsH3J4KCopUW6L $sprite→@bottom := 138;\n  }\n  #x9NcX2IPJTEr0YWB for 0 ≤ j < 5 do {\n    #GkDVBnIsjWst55Xl $sprite := data→led_indexes→at(5 + $j);\n    #xscN82XsBQ0HyOK0 $sprite→right := 180;\n    #ARG4f5kv6L542Vrc $sprite→y := 165 + $j * 48;\n  }\n  #XTCqT7R96r4UdteD data→led_x_index_legend→@bottom := 120;\n  #xDJRmybQdn3KETdh data→led_x_index_legend→left := 398;\n  #SjZ8WZmGZlQWutzs data→led_y_index_legend→left := 157;\n  #s2Hk7HlUFJH93vtY data→led_y_index_legend→@top := 347;\n  meta private;\n  meta sync;\n}\n#xaPlYNe5tmsCPc2x\naction running_time() returns(#gweptbT46k6jE8Lw now: Number) {\n  #jT8dmGMOR5HrvMA2 // Gets the number of milliseconds elapsed since power on.\n  #wgPDaZahSf78v2p8 // {help:functions/running-time}\n  #aSsocNV70Kl3gcq5 // {namespace:input}\n  #Tu7WFLYb2Qoht2MC // {shim:micro_bit::getCurrentTime}\n  #z2i5g6cse2ex2Lcf $seconds := time→now→subtract(data→start_time);\n  #VRUr0JWDsoqvcfjD $ms := math→round($seconds * 1000.0);\n  #h4YOt8m3rm6vNTWU `return` $ms;\n  meta sync;\n}\n#xOO43E2NIkwrkXxd\naction show_number(#arqB8R393DWmG4yx value: Number, #xwSeYvwN5k4Kt277 interval: Number) {\n  #f4ANMXr8KMpT2G8n // Scroll a number on the screen and shift by one column every ``interval`` milliseconds. If the number fits on the screen (i.e. is a single digit), does not scroll.\n  #carGbAdhyB3bdddY // {help:functions/show-number}\n  #xMbTyq6JVNUTdcS9 // {namespace:basic}\n  #BXU1lVjllXSyR2ie // {weight:89}\n  #OuyYvK30y62ROGkM // {hints:interval:150,100,200,-100}\n  #dxD9lszdBNwzGAUk // {shim:micro_bit::scrollNumber}\n  #x5tg98AeJkbUQbiv $value := math→round($value);\n  #C3O0Rmqfj0wV31Uh $interval := math→round($interval);\n  #oIZAtpmgCfqgmA3B code→show_string($value→to_string, $interval);\n}\n#QY3E6cU6eBZ2OJSF\nvar prelude\\u002ecpp : String {\n  is\\_resource = true;\n  url = \"data:text/plain;base64,I2luY2x1ZGUgIk1pY3JvQml0VG91Y2hEZXZlbG9wLmgi\";\n  transient = true;\n}\n#G1Hz2h0zbwEBMp8r\naction parse_image(#x0HNlskTjdSJeH7D leds: String) returns(#xysJj47ftGjOcxII img: * Image) {\n  #QCBfLADs0uy227pF // {shim:}\n  #ThhId49geuiERw0b if $leds→is_empty then {\n    #zMq8tYbUScrWhnVh `return` code→create_sprite(5, 5);\n  }\n  #oob6dV9UWsHDaLfX $coll := $leds→replace(\"\\n\", \" \")→split(\" \");\n  #Mtf8A3quiblg1vce $rows := $leds→split(\"\\n\")→count;\n  #jXV4K5hN3HnyKe4H if $rows ≠ 5 then {\n    #zt8c282yV7aLQUxE // create empty image\n    #ciffAzoM4UqzmFDZ `return` code→create_sprite(5, 5);\n  }\n  #tcARpGMvK8xwXtqj contract→assert($rows = 5, \"\");\n  #YKBULFF4pHgepPU0 $frames := $coll→count / ($rows * $rows);\n  #vQR4hrlzcnNZSZ4W $img := code→create_sprite($rows * $frames, $rows);\n  #HLRmLq08LpAB4okw $k := 0;\n  #Y31WIkDlikmi6Enb for 0 ≤ i < $rows do {\n    #xuoRzFEt1jKUNb07 for 0 ≤ j < $frames * $rows do {\n      #qS2DEgnlZI2rzI6E $bit := $coll→at($k);\n      #BF25h8Q5DS7t75Ol $img→leds→set_item($j, $i, $bit→to_number * 255);\n      #aH1dE2Wf26cTcJPy $k := $k + 1;\n    }\n  }\n  meta private;\n  meta sync;\n}\n#UtnSCSPxXT40kUae\naction create_buttons() {\n  #NhHdk2ZIg12mfIYm // {shim:}\n  #HPSfi8YXpzMd424M code→create_A_button();\n  #h5cYiVMZiqGPQpHd code→create_B_button();\n  #qATt6iPL4iFDhhLM code→create_A\\u002bB_button();\n  meta private;\n  meta sync;\n}\n#ykpAyylV4sU5Im4Z\naction test_print_text() {\n  #xNfHTwPX2YSGu0Ec // {shim:}\n  #XYfFtFoX41cu3orG code→\\_libinit;\n  #U38gBCeZHv0VcHP2 code→show_string(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\", 120);\n  #wh2snLHufOKmIF0L code→show_string(\"abcdefghijklmnopqrstuvwxyz\", 120);\n  #LCp56xZb2hT4h2LC code→show_string(\"£\", 100);\n  #xs64irnHsnCW82vb code→show_string(\"£££\", 100);\n  #sEboYWEAbegqYbMZ code→show_string(\"0123456789\", 100);\n  meta private;\n  meta test;\n}\n#GNCSnnlE2fFVnKGK\naction test_buttons() {\n  #W2mFTHLBePxLBlHZ // {shim:}\n  #E5YEE67bsbTys0jb code→\\_libinit;\n  #xm6Flc2jfLQMGfFQ code→on_button_pressed(\"A\");\n  #gS4N82WpF6tkuelR where `implicit` \\_body\\_() {\n    #ON7phOtrAHh9Jejz code→show_string(\"A\", 100);\n  }\n  #gmr7aY7MXcYsbncb code→on_button_pressed(\"B\");\n  #Rp8qiY1vzviZ2kWq where `implicit` \\_body\\_() {\n    #Wf7Z3Bn5plHJ78I1 code→show_string(\"B\", 100);\n  }\n  #NO9PrQ5LFZfQfagg code→on_button_pressed(\"A+B\");\n  #POC91PYG4214TJp0 where `implicit` \\_body\\_() {\n    #xYIv0xzaNMKmq0z3 code→show_string(\"A+B\", 150);\n  }\n  meta private;\n  meta test;\n}\n#xoBb197IePtkqyhM\nvar count : Number {\n  // {shim:}\n  transient = true;\n}\n#VHsIMy7uJfZzPoMX\naction set_pixel(#P0GQI7mqQZLddWdU @this: * Image, #E5qctGDlXgeNbS9G x: Number, #reArL0ANylbd8RZg y: Number, #cjLlFOO9xgu09YmX value: Boolean) {\n  #xOswNPjjGMm1sUfm // Set a pixel state at position ``(x,y)``\n  #InGkIRcHpl4IXVQK // {help:functions/set-pixel}\n  #zIS2o2dBpWF9RDx8 // {namespace:image}\n  #l8YA4111fgihgo2H $b := 0;\n  #mOmRFng7uyfg3XLR if $value then {\n    #ET2Fj3fuKjgQ93Hh $b := 255;\n  }\n  #fYNF76FqaZnZ4tL1 $@this→set_pixel_brightness($x, $y, $b);\n  meta sync;\n}\n#xNKMIAKQZ2XYQAqe\naction pixel(#TVxswFwyZs0INV5W @this: * Image, #QLIezAtdKSgv2ohr x: Number, #yMN5fgUMFfzObabg y: Number) returns(#BGQ1D2Ag9wHaQCLC state: Boolean) {\n  #rJhKHlNK4kKD4ezD // Get the pixel state at position ``(x,y)``\n  #JuPT9jZBFV6JJwj8 // {help:functions/pixel}\n  #xwxPjJYSo2B5Vkkq // {namespace:image}\n  #JTtgaUATi8Oo7he4 // {hints:x:0,1,2,3,4}\n  #Itieq6wpbGiz7w6r // {hints:y:0,1,2,3,4}\n  #KUGL4al4LBtoR7uX `return` $@this→pixel_brightness($x, $y) > 0;\n  meta sync;\n}\n#aqdR2AyKfGIWjWKX\naction clear(#TcdNAKsIbu986dqh img: * Image) {\n  #HyVQr9pzr4lAWRAX // Clears all the pixels in the image\n  #Vo18UEQT4sDp4o21 // {help:functions/clear}\n  #cupoiXR5e4GmsVYr // {namespace:image}\n  #xW1Iq3aG39sLTugT // {shim:micro_bit::clearImage}\n  #K4ZFXN4ytxFTfH2s for 0 ≤ i < $img→leds→count do {\n    #kA4W7IWpYB4o2624 $img→leds→set_at($i, 0);\n  }\n  meta sync;\n}\n#xq3rVK5p1wAVqxhU\nvar button_a\\u002bb : Sprite {\n  // {shim:}\n  transient = true;\n}\n#Ms9O2l7vxlDJVrtZ\nvar compass_arrow : Sprite {\n  // {shim:}\n  transient = true;\n}\n#dv4l34Vyg1pMFJgt\naction create_compass() {\n  #ZZtsSd44QAQ2UWxn // {shim:}\n  #xAlkfPeoWDvYa4Ix data→compass_text := data→board→create_text(100, 40, 20, \"359°\");\n  #VQG2dir1qpnkppWG data→compass_text→fit_text;\n  #qsbHlfR2wqbqLObO data→compass_text→y := data→board→height - 80;\n  #TXLyGWO4oXkQ202f data→compass_text→left := 30;\n  #uksFN3lypHUnVGUv data→compass_text→color := colors→black;\n  #UrsppZ77d3E3glgs $pic := media→create_picture(100, 100);\n  #BfAgyhEWuRzF042T $pic→fill_ellipse(0, 0, 100, 100, 0, \"#989898\" →to_color);\n  #pFWjh4kboAdRfglW $pic→fill_path(0, 0, 0, colors→white, \"M 50 0 L 60 70 L 50 65 L 40 70 Z\");\n  #xQl6MSp9TWUBTMEl data→compass_arrow := data→board→create_picture($pic);\n  #Slbh4hBK115AyrsX data→compass_arrow→width := 80;\n  #JMHYz83jCwfR2BiG data→compass_arrow→left := 60;\n  #ea8auwV1sLWF3At4 data→compass_arrow→y := data→board→height - 48;\n  #TLghe1aK8X4Y0P2L data→compass_heading_value := invalid→number;\n  #xP4D15cRYTcP3EEq data→compass_arrow→on_touch_down($touch_down);\n  #PGl4eapBlwlN5FSH where touch_down(x: Number, y: Number) {\n    #i4clvVN4ppe22bFC code→read_compass_arrow($y, $x);\n  }\n  #zO37ABILHahWBLkf data→compass_arrow→on_drag($dragged);\n  #qt3STQH7aH6YY1w8 where dragged(x: Number, y: Number, delta_x: Number, delta_y: Number) {\n    #ZHM1jr4hFYuNOCEN code→read_compass_arrow($y, $x);\n  }\n  meta private;\n  meta sync;\n}\n#JiZO327G3fL0SZGF\nvar compass_text : Sprite {\n  // {shim:}\n  transient = true;\n}\n#z8UAvCstrXYppXV7\nvar compass_heading_value : Number {\n  // {shim:}\n  transient = true;\n}\n#Hv7ujfF0nVCz8sx5\naction read_compass_arrow(#OHGqICBfnbz4QhvP y: Number, #xRbEEfKhc3Yxm43U x: Number) {\n  #ZD0GSuKo2Clfn6zQ // {shim:}\n  #g22ewR3VZal24Vqg $angle := math→rad_to_deg(math→atan2($y - data→compass_arrow→y, $x - data→compass_arrow→x) + math→\\u03c0 / 2);\n  #xnty57tqtklkEP8u if $angle < 0 then {\n    #SGb40PfCmS1yrV7d $angle := $angle + 360;\n  }\n  #pvXAKVWysSrTMdcR data→compass_heading_value := $angle;\n  meta private;\n  meta sync;\n}\n#FLON3QSP0fwDIZC4\naction test_compass() {\n  #MW4yaiY9wynUWlMR // {shim:}\n  #PPW482lSAJyUQ9ri code→\\_libinit;\n  #xAE8v7KmRMicbljm code→calibrate;\n  #FsMBbmufaJix02xe $degrees := code→compass_heading;\n  #xse7eRxbWddqX6nL $millig := code→acceleration(\"x\");\n  #tlXXCrB6Djt9HGiJ data→board→set_debug_mode(true);\n  meta private;\n  meta test;\n}\n#xzhTBaRFA7w2suUl\naction test_button_a\\u002bb() {\n  #b4aW2uElgK2cbabi // {shim:}\n  #VozcHml4ANVDRCzV code→\\_libinit;\n  #ntNRRFZ3bcxc6HtO code→on_button_pressed(\"A+B\");\n  #I444JVhpwg64uUp3 where `implicit` \\_body\\_() {\n    #ayHPmOCSVMv8QTqa code→show_string(\"good\", 100);\n  }\n  meta private;\n  meta test;\n}\n#trpRg6yTXKX8M8cY\nvar acceleration_x_text : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xj4QxpGx2XVt6SIa\nvar acceleration_y_text : Sprite {\n  // {shim:}\n  transient = true;\n}\n#PM0d2btuj5TMrQKD\nvar acceleration_z_text : Sprite {\n  // {shim:}\n  transient = true;\n}\n#D7945sGiSVeFOiz0\naction mg_to_string(#xVpQut6zF7b3yH2y g: Number) returns(#Wac7i7TRPpbskC9b mg2: String) {\n  #xrwjNX0PVUwch4D3 // {shim:}\n  #GB9LrYmhIg6CxRoh $mg := math→round($g * 1000)→to_string;\n  #Hd2xoPM6C0l4kyj2 `return` $mg;\n  meta private;\n  meta sync;\n}\n#I0wd2ww0cWi61IbW\naction test_accelerometer() {\n  #tdPH2SckDQFP0AHb // {shim:}\n  #c0W2EHJjeOCb9SP7 code→\\_libinit;\n  #x4TQZaZGf4vYeOAp data→board→set_debug_mode(true);\n  #j7MfPADEGw5Pi5im while true do {\n    #xnxjKVT2qERsVvmc $x := code→acceleration(\"x\");\n    #A5yEcY6mbAfb6TPA $y := code→acceleration(\"y\");\n    #xxSBeHns1qEX4s5O $z := code→acceleration(\"z\");\n    #i8PmYalgHlZL9oim $pitch := code→rotation(\"pitch\");\n    #fWfo2WcvU0qLKUYo $angle := code→rotation(\"roll\");\n    #B3OVJ2E408AL9uqx code→pause(100);\n  }\n  meta private;\n  meta test;\n}\n#db4usuIXbJkUwwL3\nvar bkg : Sprite {\n  // {shim:}\n  transient = true;\n}\n#UxZtwFWDOl2eBWHS\nvar acc_title : Sprite {\n  // {shim:}\n  transient = true;\n}\n#NB71vR2acuoxOzhF\naction update_compass() {\n  #GUKjAqnGheX4V0Fo // {shim:}\n  #ngsZsBasKScY4T5V if `not` data→compass_arrow→is_invalid then {\n    #zZbyXaPFEJrI4vnn $degrees := code→compass_heading;\n    #fP6woTbM4WvDhu5z if data→compass_heading_value→is_invalid then {\n      #SVWo2h2OTKLTN9Zu data→compass_arrow→angle := - $degrees;\n    }\n    else {\n      #jtGD4e2BPt7sPQ2f data→compass_arrow→angle := $degrees;\n    }\n    #xmqom9DO2N4UCxUo data→compass_text→text := $degrees ∥ \"°\";\n    #xye0othn81opwsR6 data→compass_text→fit_text;\n    #BoQ8NUUvE6oK18RC data→compass_text→left := 30;\n  }\n  meta private;\n  meta sync;\n}\n#Duo2QkiHEzLUwbPP\naction update_acceleration() {\n  #xYTnumJe8pmdMnOj // {shim:}\n  #T5H4jq33oZ2P97M2 if `not` data→acceleration_x_text→is_invalid `or` `not` data→acceleration_y_text→is_invalid `or` `not` data→acceleration_z_text→is_invalid then {\n    #Y4gIGmGYXPYUSSnc $p := senses→acceleration_quick;\n    #oonnY6sWxw0tq6ag if `not` data→acceleration_x_text→is_invalid then {\n      #xld1RvlF3fr7fUpj data→acceleration_x_text→text := \"x: \" ∥ code→mg_to_string($p→x);\n      #bLiTgPxiTV1D6D73 data→acceleration_x_text→fit_text;\n      #cob34YxVwT4lSg5N data→acceleration_x_text→left := 200;\n    }\n    #xE54GZuni6hnc2LU if `not` data→acceleration_y_text→is_invalid then {\n      #CK4RRChJoo5LTaD4 data→acceleration_y_text→text := \"y: \" ∥ code→mg_to_string($p→y);\n      #xtH0Dr43TgaKViYo data→acceleration_y_text→fit_text;\n      #x6204VDd8dJKb7bj data→acceleration_y_text→left := 200;\n    }\n    #xgm4X9sFTILN4PkS if `not` data→acceleration_z_text→is_invalid then {\n      #rKo1iSU2MLyJrjiu data→acceleration_z_text→text := \"z: \" ∥ code→mg_to_string($p→z);\n      #xdR4vtWBQlLAqFj8 data→acceleration_z_text→fit_text;\n      #X477zJbexlWyCpOd data→acceleration_z_text→left := 200;\n    }\n  }\n  meta private;\n  meta sync;\n}\n#eVKtTh73RfddrPbU\naction in_background(#x67Zj4FKKV2jt3w9 body: Action) {\n  #JS61XiP3XLxBGcSJ // Schedules code that run in the background.\n  #xOGy2Csz0dMRNvwY // {help:functions/in-background}\n  #xeIeSmXBocppJ249 // {namespace:control}\n  #tpcIQODlauXc4x94 // {shim:micro_bit::runInBackground}\n  #H9LSVq6QNak6kS1E if $body→is_invalid then {\n    #DcDY2ImNUd2qaRhd `return` ;\n  }\n  #M0p9EJ9u34sADrAp app→allow_other_events;\n  #xK0Ei4Ey5Aa6ktal `async` $body→run;\n  meta sync;\n}\n#z6mgAgBseIwhSA9q\nvar pins : Sprite_Set {\n  // {shim:}\n  transient = true;\n}\n#S4AaF6H9Bir1YG2B\naction init_pins() {\n  #xvHUpiQyRqSw08j4 // {shim:}\n  #x48sTDN6eBa0xXyy if data→pins→is_invalid then {\n    #xVyNflPdb6lsKBCK data→pins := data→board→create_sprite_set;\n    #FNXCkGWZPHZHdFMp $color := colors→blue;\n    #bEGdJ995axSAPUnk $coll := create→Collection_of→Number;\n    #OBYzjLeMGZGSwlRp $coll→add(25);\n    #PJgCYPHIzLXbTs1X $coll→add(145);\n    #XUScfAJ414uNtG3o $coll→add(280);\n    #FLd4X2wW20GtInS2 for 0 ≤ i < $coll→count do {\n      #bCVbJpfp40lEL102 $left := $coll→at($i);\n      #Afqsons4pseBNxj0 $pin := code→create_pin($color, $left);\n      #xIgLaDCrGz1xSf4r data→pins→add($pin);\n    }\n  }\n  meta private;\n  meta sync;\n}\n#A9xZmVQH2nPrrN8o\naction pin_by_name(#pznPOV8prsiYdNhL name: String) returns(#QC9UtfUA0ZQiyxvN sprite2: Sprite) {\n  #YLwrAONQnaRmH9mk // {shim:}\n  #ololoiFjuAzCfyDe $index := $name→trim(\"pP\\t\")→to_number;\n  #j0yR5tWcQjVZyB1T $sprite := data→pins→at($index);\n  #qz6N2BmKUFCpxz4N if `not` $sprite→is_invalid then {\n    #xGr49fRupLhPmlEq $sprite→show;\n  }\n  #aZHYIJGu0HFUl4SU `return` $sprite;\n  meta private;\n  meta sync;\n}\n#RtVnuDAS2Tqp1LSg\naction update_pin(#xLFmUabqhUFi0ZiP sprite: Sprite) {\n  #OLMKJMgxATEpHRHu // {shim:}\n  #oa5bznMuZaSILcw4 if $sprite→mass - 1 ≤ 0 then {\n    #xzLXU96Zk9wUo7bD $sprite→set_color(colors→transparent);\n  }\n  else {\n    #ZMq4rk7QkaT2NOsD $sprite→set_color(colors→green);\n  }\n  #v6NNVvhZ2YzYJw2D data→board→update_on_wall;\n  meta private;\n  meta sync;\n}\n#hEU77nyoMCRSSAqa\naction test_pins() {\n  #xynDU3S3kjEYy18D // {shim:}\n  #rK2IutWay0PFVvqq code→\\_libinit;\n  #t829Xv42HzfA2nAG code→digital_write_pin(\"P0\", 1);\n  #INTK9O6xrjxHkJ9g code→digital_write_pin(\"P1\", 1);\n  #aeUtxvIe4YYta4Nz code→digital_write_pin(\"P2\", 1);\n  #opMdOZDBv2MTyBXq code→digital_write_pin(\"P8\", 1);\n  #TVwRJDzgrpIJuTZ2 code→digital_write_pin(\"P12\", 1);\n  #s6YLWaYNLlbaI6bq code→digital_write_pin(\"P16\", 1);\n  #IUhZptHB34mvrxW2 $value2 := code→digital_read_pin(\"P0\");\n  #hPJl24rmbFWsf4a3 $value := code→digital_read_pin(\"P1\");\n  #NVG04rX4uPRfEh2d $value3 := code→digital_read_pin(\"P2\");\n  #MKOvVDJ6dfcQo0u1 $value4 := code→digital_read_pin(\"P8\");\n  #xVOeb35l5ezwAQqx $value5 := code→digital_read_pin(\"P12\");\n  #x6tsh2LJoLcSYHih $value6 := code→digital_read_pin(\"P16\");\n  #RU4iMpCdo1kUigzr code→analog_write_pin(\"P1\", 1000);\n  #HbZSxLTByep2h4qZ code→pause(1000);\n  #hpOIzAtXk5fN5c5M while true do {\n    #IDR9JN8Q2N13Bumo code→digital_write_pin(\"P0\", 0);\n    #xnKEa428MreHgCNq code→pause(1000);\n    #xKnTarBirfEP9bL5 code→digital_write_pin(\"P0\", 1);\n    #ieC6KUFGlIGc2sCf code→pause(1000);\n  }\n  meta private;\n  meta test;\n}\n#x871W29FACCUQhgl\naction create_pin(#xwnvtwXoIoa22y4Z color: Color, #IVU23UfeIRgACC6Q left: Number) returns(#m3RyCzsn2DCgDD7W pin2: Sprite) {\n  #Aq6gfS2XnSqEO42R // {shim:}\n  #Px6ORF6xlL3ssrZ0 $pin := data→board→create_rectangle(50, 108);\n  #xUih2I3DqrfQGQC2 $pin→set_color($color);\n  #bVSo2lipkr25Ga2P $pin→@bottom := data→bkg→@bottom - 5;\n  #xDtMKVUu2fjw8gEH $pin→mass := 1;\n  #uOBdkNKC5tgxgMmu $pin→set_friction(1);\n  #qCCZl1zpt7Jc32cS $pin→hide;\n  #IRReqhZX8YsLhC44 $pin→left := $left;\n  #xgbiNSJLlb6Ct3Xf $pin→on_touch_down($touch_down);\n  #dnm1P3MFrEzgk7ZV where touch_down(x: Number, y: Number) {\n    #gQ2vyq2Jd7fOV7g6 $pin→mass := 1024;\n    #ELw1bdG72zYVtFzz code→update_pin($pin);\n  }\n  #x5e0KdFm44Im64AZ $pin→on_touch_up($touch_up);\n  #n0fTpU4XnqkfP4qT where touch_up(x: Number, y: Number) {\n    #hn3r2pa6wYAY4u8w $pin→mass := 1;\n    #nvk6QNLw1m6DrV9M code→update_pin($pin);\n  }\n  #zUDQyhCWpFFvbmjL code→update_pin($pin);\n  #wemNuUcwH4xjwwNw `return` $pin;\n  meta private;\n  meta sync;\n}\n#tYt6bUhy3Nm9mpAR\naction test_plot_unplot() {\n  #xXot6id59vwJvRh2 // {shim:}\n  #xtZorNV3Gqgbg1S0 code→\\_libinit;\n  #xQdOxnawNQbuLBIm for 0 ≤ k < 2 do {\n    #PihMnuz9A57aOBax for 0 ≤ i < 5 do {\n      #xY5ZW4seHSQm14te for 0 ≤ j < 5 do {\n        #xk8RVw6DDoorZhsL $b := code→point($i, $j);\n        #aBSVSfZkN77ha2X4 if $b then {\n          #lytsEo6NBz3VlT47 code→unplot($i, $j);\n        }\n        else {\n          #vGAQtJ9z5CBiW5U9 code→plot($i, $j);\n        }\n        #puQuMFzF3KMG1e4q code→pause(500);\n      }\n    }\n  }\n  meta private;\n  meta test;\n}\n#xCn8l4L2PfqCeiNR\naction calibrate() {\n  #a592ki5YrzeI6a2X // Obsolete, compass calibration is automatic.\n  #jvwA9fcOAMuHgvd3 // {help:functions/calibrate}\n  #K69mm2lCHD9ANu8u // {namespace:input}\n  #xodr3UlxL4wpG04K // {weight:0}\n  #ZJoAB7BFrtoAg633 // {shim:TD_NOOP}\n}\n#OsMsC0czXS2YrjdU\naction forever(#xYRk46PsjFkdlEOm body: Action) {\n  #a1ZdSLsAwD6Rv0FM // Repeats the code forever in the background. On each iteration, allows other codes to run.\n  #Xa3HrwxE9W3Z3Erw // {help:functions/forever}\n  #Bo8g50yakYNCYSa1 // {namespace:basic}\n  #x4L41J1h0VUQZ1s2 // {weight:55}\n  #fJ2PtEUzMS9ydxsM // {shim:micro_bit::forever}\n  #xxnWmxDbWPRikigP $c := code→tick(\"forever\");\n  #xCLA2qrMQhTjL6yy if $c > 10 then {\n    #XSOwmzMlmmLIQMlN code→warning(\"You are creating a lot of `forever` loops!\");\n  }\n  #Pj4YeL1fWpHS4Rqe code→in_background;\n  #DzqAW6AtT7qsGylm where `implicit` \\_body\\_() {\n    #VewPBkQpxjnPzsoN while true do {\n      #xxjM7mD3FQ3G0HYN $body→run;\n      #q2kJK2U1MbTh4d4L code→pause(20);\n    }\n  }\n  meta sync;\n}\n#x2UhK7IwofqmWDW2\nvar background_scene : Picture {\n  is\\_resource = true;\n  url = \"https://microbit0.blob.core.windows.net/pub/prcwhomc\";\n  transient = true;\n}\n#gqSUQusGllAt4X3R\naction init_axis() {\n  #QkvjQqSfn5L41Ph4 // {shim:}\n  #q7cMCQpYupmXc3oS data→led_indexes := data→board→create_sprite_set;\n  #x36Llp6v7tD4OgDD for 0 ≤ l < 2 do {\n    #xPsYPYIXtbJBJDDl for 0 ≤ k < 5 do {\n      #WVBiy4HYa9LPzM9f $index := data→board→create_text(100, 40, 16, $k→to_string);\n      #GP3ccJkbFZoGfIOo $index→fit_text;\n      #bZpgALZp1Y7Pqvwq $index→set_color(colors→white);\n      #rJHNHPvhK2CuW6K5 data→led_indexes→add($index);\n    }\n  }\n  #xZvCdCFHs2yBG1WD data→led_x_index_legend := data→board→create_text(100, 40, 20, \"X\");\n  #kWxcFIVT5naWzvWl data→led_x_index_legend→fit_text;\n  #xryAhH2rPFt7CGEu data→led_x_index_legend→set_color(colors→white);\n  #Swmd5OgE0kLUq6vI data→led_y_index_legend := data→board→create_text(100, 40, 20, \"Y\");\n  #toIFKA5P9IJU4fyF data→led_y_index_legend→fit_text;\n  #v88nKL6Mx0ObDSQb data→led_y_index_legend→set_color(colors→white);\n  meta private;\n  meta sync;\n}\n#gbl636zYs8BjKywu\naction background_animation() {\n  #cXcKTdQsmOf72PyZ // {shim:}\n  #sbOu1sddCBbbzLto $anim_style := math→random(2);\n  #zWd8PXsYN214PuSi if $anim_style = 0 then {\n    #xOUvhBkpwLPAJKQE for 0 ≤ x < 5 do {\n      #XztMutk0HQK5N4bE for 0 ≤ y < 5 do {\n        #V0LLzNL1lk6N8oiG code→rotate_pixel($x, $y, ($x + $y) / 11);\n      }\n    }\n  }\n  else { #N8Fm2yynpg44tcFN if $anim_style = 1 then {\n    #WFnJlsyfcMVWjUdA for 0 ≤ x < 5 do {\n      #O0vgqGWuikN0Igzt for 0 ≤ y < 5 do {\n        #oqHsWxXgwop5m3UQ code→rotate_pixel($y, $x, (8 - $x - $y) / 11);\n      }\n    }\n  }\n  else { } } \n  #W55d2CMIzJ17AYTx time→run_after(20 + math→random(20));\n  #l3mxxkPpmOIFL0MI where `implicit` \\_body\\_() {\n    #hPG2SGmZ0v82ge2v code→background_animation;\n  }\n  meta private;\n  meta sync;\n}\n#xY4SKFl04lUKP0Tz\nvar back_leds : Sprite_Set {\n  // {shim:}\n  transient = true;\n}\n#s4TpycEQnK9omxJE\naction rotate_pixel(#xQ6b7K01ABZHGoIM x: Number, #LByh34Z47Y1t7STj y: Number, #xXPwmL1c4yZhN70E delay: Number) {\n  #hDHLiXE2IoG2LAIC // {shim:}\n  #ZhRYM1cp26cnzoZ1 $index := code→index($x, $y);\n  #Z4jTOPX6Hf1TWJsy $back_led := data→back_leds→at($index);\n  #f9URVMJG14plLGON $led := data→leds→at($index);\n  #Axwwjnz8AnLRT1zD $anim := $led→create_animation;\n  #BXSGIclwP5UQZVWn $anim→sleep($delay);\n  #T1txW266DHqoj2VL $anim→turn_to(0.7, \"expo\", \"inout\", 360);\n  #JmbebaijvsuwQhiZ $anim := $back_led→create_animation;\n  #NqByltxb37T2IH33 $anim→sleep($delay);\n  #NwwgANo3MHaQnz5l $anim→turn_to(0.7, \"expo\", \"inout\", 360);\n  meta private;\n  meta sync;\n}\n#Y42hygGODxnJXaRw\naction led_index_anim(#QVFm7dBCUmhXNZ2d back_led: Sprite, #x2kGm9JYaUim4lt7 j: Number, #L5TjxqpH6tKGkOTd i: Number) {\n  #mZsj4T6J4M2uKZuV // {shim:}\n  #bU0sdnTBX02bATEy $back_led→on_tap($tapped);\n  #QGyzuuvKa9ITgnVd where tapped(x: Number, y: Number) {\n    #x4h4i0Xr2uWxRBvm $anim2 := $back_led→create_animation;\n    #xsMdEt8ccoRpbNYI $anim2→beat(0.3, 3, 1.2);\n    #s6iFPhs6n9jPEG7J $hint := data→board→create_text(100, 40, 22, \"x=\" ∥ $j ∥ \", y=\" ∥ $i);\n    #D6b4Qvjr06KgKv45 $hint→fit_text;\n    #gJIdoRKO7jwnlbzz $hint→set_text_baseline(\"bottom\");\n    #qx3Y9mRjHEwbnF6m $hint→@bottom := $back_led→y;\n    #zGixTQ9Kuk2m6Whe $hint→left := $back_led→x;\n    #FTPPf6p4gUiFcxxb $anim := $hint→create_animation;\n    #DyAb59RCz24FZLtG $anim→fade_in(0.5, \"cubic\");\n    #lOOqrViiBQ4e4jku $anim→sleep(.5);\n    #XJ5iEvyaoe36o2rc $anim→puff_out(0.5, \"cubic\", 1.5);\n    #DoyEH0iisHSMcqKe $anim→delete;\n  }\n  meta private;\n  meta sync;\n}\n#xB22l4bTEuykprY5\nvar current_animation : Number {\n  // {shim:}\n  transient = true;\n}\n#IhVzhAZz2OeYSRgl\naction test_multi_scroll() {\n  #B6N0Ow6kWjo3o2k4 // {shim:}\n  #jwlm0IOR4ZnMvote code→\\_libinit;\n  #vvz4qs78fnml39OQ code→on_button_pressed(\"A\");\n  #LFV6TOZvYxsiDM0g where `implicit` \\_body\\_() {\n    #VEQJMbAIvN5XNwiw code→show_string(\"ABC\", 100);\n  }\n  #dH24BpCdIjxC0udR code→on_button_pressed(\"B\");\n  #xGRNMYqr5Oobo6Iv where `implicit` \\_body\\_() {\n    #xdthtZf2mEoAmQO3 code→show_leds(\"0 0 0 0 0\\n0 1 1 1 0\\n0 1 0 1 0\\n0 1 1 1 0\\n0 0 0 0 0\", 400);\n  }\n  meta private;\n  meta test;\n}\n#cEmz3y3ohmdp6AXY\naction init_eyes() {\n  #xufwLhiDE0bQWtRU // {shim:}\n  #bjkoPxbCzJ4pL2uK data→eye_y := 86;\n  #NkEaRwjz7rWxJKQK data→eye_left := 276;\n  #v783038Eh682f2OC data→eye_right := 324;\n  #eiAcEwONRspI5U37 data→left_eye := data→board→create_ellipse(13, 13);\n  #kvrBgQVgS7G0K2jA data→left_eye→color := colors→blue;\n  #Xl8q5Ud55nALw4Qz data→left_eye→left := data→eye_left;\n  #NEMjm8SQ7r0P45jG data→left_eye→@top := data→eye_y;\n  #pshgYorYc1f0W1RK data→left_eye→set_friction(1);\n  #R6QEKy3rQdbXOaX1 data→right_eye := data→board→create_ellipse(13, 13);\n  #cOqnG6djBmo9cbBW data→right_eye→color := data→left_eye→color;\n  #GZdwztrKXD2QRxAJ data→right_eye→left := data→eye_right;\n  #k85veqcrDilOuwDt data→right_eye→@top := data→eye_y;\n  #HRun2WhRntsb626o data→right_eye→set_friction(1);\n  #xvDkOawcF4uscx4W time→run_after(5);\n  #fO2SW4IL13o44Bv6 where `implicit` \\_body\\_() {\n    #B3LDJWeGHtW8E4MP code→background_eye_animation;\n  }\n  meta private;\n  meta sync;\n}\n#O8kw8lSdWvW7wrc8\nvar left_eye : Sprite {\n  // {shim:}\n  transient = true;\n}\n#PRwAVo3AkO2aHbCQ\nvar right_eye : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xhHLX6h5QdTnhalv\nvar eye_left : Number {\n  // {shim:}\n  transient = true;\n}\n#HWT93EnmgbqC9YKH\nvar eye_y : Number {\n  // {shim:}\n  transient = true;\n}\n#x4DvJKIPIgQ0E92R\nvar eye_right : Number {\n  // {shim:}\n  transient = true;\n}\n#qMsgTIJWIq1mQwZd\naction background_eye_animation() {\n  #H6xmVCztL24M7rH5 // {shim:}\n  #Yp9i79aYpUQDzMh3 $anim := data→right_eye→create_animation;\n  #yODxrazNsQmAFCaS $anim→turn_to(1, \"cubic\", \"inout\", - 360);\n  #cxDUduuWUiSMNJ7P $anim := data→left_eye→create_animation;\n  #bgGZqI1SAwMsPhxz $anim→turn_to(1, \"cubic\", \"inout\", - 360);\n  #WVY3japNIXYmFVbI time→run_after(20 + math→random(20));\n  #iOueH51c9marewEa where `implicit` \\_body\\_() {\n    #yItKPwNOdgar5Drt code→background_eye_animation;\n  }\n  meta private;\n  meta sync;\n}\n#kaq96iZh93dUdQ0Z\naction test_forever() {\n  #gIoxApIo64EHyPn8 // {shim:}\n  #ltm6kY4KiWLUR5jc code→\\_libinit;\n  #ZdeN0qz5MQzjBkkP code→forever;\n  #xPjmmLzsEKaNVoWr where `implicit` \\_body\\_() {\n    #qNI9KS2fM6Fo1pP4 skip;\n  }\n  meta private;\n  meta test;\n}\n#WuJjn92QznNVUE3Z\nvar font_chars : String {\n  is\\_resource = true;\n  url = \"data:text/plain;base64,ezB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDgsIDB4OCwgMHg4LCAweDAsIDB4OCwgMHhhLCAweDRhLCAweDQwLCAweDAsIDB4MCwgMHhhLCAweDVmLCAweGVhLCAweDVmLCAweGVhLCAweGUsIDB4ZDksIDB4MmUsIDB4ZDMsIDB4NmUsIDB4MTksIDB4MzIsIDB4NDQsIDB4ODksIDB4MzMsIDB4YywgMHg5MiwgMHg0YywgMHg5MiwgMHg0ZCwgMHg4LCAweDgsIDB4MCwgMHgwLCAweDAsIDB4NCwgMHg4OCwgMHg4LCAweDgsIDB4NCwgMHg4LCAweDQsIDB4ODQsIDB4ODQsIDB4ODgsIDB4MCwgMHhhLCAweDQ0LCAweDhhLCAweDQwLCAweDAsIDB4NCwgMHg4ZSwgMHhjNCwgMHg4MCwgMHgwLCAweDAsIDB4MCwgMHg0LCAweDg4LCAweDAsIDB4MCwgMHhlLCAweGMwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4OCwgMHgwLCAweDEsIDB4MjIsIDB4NDQsIDB4ODgsIDB4MTAsIDB4YywgMHg5MiwgMHg1MiwgMHg1MiwgMHg0YywgMHg0LCAweDhjLCAweDg0LCAweDg0LCAweDhlLCAweDFjLCAweDgyLCAweDRjLCAweDkwLCAweDFlLCAweDFlLCAweGMyLCAweDQ0LCAweDkyLCAweDRjLCAweDYsIDB4Y2EsIDB4NTIsIDB4NWYsIDB4ZTIsIDB4MWYsIDB4ZjAsIDB4MWUsIDB4YzEsIDB4M2UsIDB4MiwgMHg0NCwgMHg4ZSwgMHhkMSwgMHgyZSwgMHgxZiwgMHhlMiwgMHg0NCwgMHg4OCwgMHgxMCwgMHhlLCAweGQxLCAweDJlLCAweGQxLCAweDJlLCAweGUsIDB4ZDEsIDB4MmUsIDB4YzQsIDB4ODgsIDB4MCwgMHg4LCAweDAsIDB4OCwgMHgwLCAweDAsIDB4NCwgMHg4MCwgMHg0LCAweDg4LCAweDIsIDB4NDQsIDB4ODgsIDB4NCwgMHg4MiwgMHgwLCAweGUsIDB4YzAsIDB4ZSwgMHhjMCwgMHg4LCAweDQsIDB4ODIsIDB4NDQsIDB4ODgsIDB4ZSwgMHhkMSwgMHgyNiwgMHhjMCwgMHg0LCAweGUsIDB4ZDEsIDB4MzUsIDB4YjMsIDB4NmMsIDB4YywgMHg5MiwgMHg1ZSwgMHhkMiwgMHg1MiwgMHgxYywgMHg5MiwgMHg1YywgMHg5MiwgMHg1YywgMHhlLCAweGQwLCAweDEwLCAweDEwLCAweGUsIDB4MWMsIDB4OTIsIDB4NTIsIDB4NTIsIDB4NWMsIDB4MWUsIDB4ZDAsIDB4MWMsIDB4OTAsIDB4MWUsIDB4MWUsIDB4ZDAsIDB4MWMsIDB4OTAsIDB4MTAsIDB4ZSwgMHhkMCwgMHgxMywgMHg3MSwgMHgyZSwgMHgxMiwgMHg1MiwgMHg1ZSwgMHhkMiwgMHg1MiwgMHgxYywgMHg4OCwgMHg4LCAweDgsIDB4MWMsIDB4MWYsIDB4ZTIsIDB4NDIsIDB4NTIsIDB4NGMsIDB4MTIsIDB4NTQsIDB4OTgsIDB4MTQsIDB4OTIsIDB4MTAsIDB4MTAsIDB4MTAsIDB4MTAsIDB4MWUsIDB4MTEsIDB4M2IsIDB4NzUsIDB4YjEsIDB4MzEsIDB4MTEsIDB4MzksIDB4MzUsIDB4YjMsIDB4NzEsIDB4YywgMHg5MiwgMHg1MiwgMHg1MiwgMHg0YywgMHgxYywgMHg5MiwgMHg1YywgMHg5MCwgMHgxMCwgMHhjLCAweDkyLCAweDUyLCAweDRjLCAweDg2LCAweDFjLCAweDkyLCAweDVjLCAweDkyLCAweDUxLCAweGUsIDB4ZDAsIDB4YywgMHg4MiwgMHg1YywgMHgxZiwgMHhlNCwgMHg4NCwgMHg4NCwgMHg4NCwgMHgxMiwgMHg1MiwgMHg1MiwgMHg1MiwgMHg0YywgMHgxMSwgMHgzMSwgMHgzMSwgMHgyYSwgMHg0NCwgMHgxMSwgMHgzMSwgMHgzNSwgMHhiYiwgMHg3MSwgMHgxMiwgMHg1MiwgMHg0YywgMHg5MiwgMHg1MiwgMHgxMSwgMHgyYSwgMHg0NCwgMHg4NCwgMHg4NCwgMHgxZSwgMHhjNCwgMHg4OCwgMHgxMCwgMHgxZSwgMHhlLCAweGM4LCAweDgsIDB4OCwgMHhlLCAweDEwLCAweDgsIDB4NCwgMHg4MiwgMHg0MSwgMHhlLCAweGMyLCAweDQyLCAweDQyLCAweDRlLCAweDQsIDB4OGEsIDB4NDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MWYsIDB4OCwgMHg0LCAweDgwLCAweDAsIDB4MCwgMHgwLCAweGUsIDB4ZDIsIDB4NTIsIDB4NGYsIDB4MTAsIDB4MTAsIDB4MWMsIDB4OTIsIDB4NWMsIDB4MCwgMHhlLCAweGQwLCAweDEwLCAweGUsIDB4MiwgMHg0MiwgMHg0ZSwgMHhkMiwgMHg0ZSwgMHhjLCAweDkyLCAweDVjLCAweDkwLCAweGUsIDB4NiwgMHhjOCwgMHgxYywgMHg4OCwgMHg4LCAweGUsIDB4ZDIsIDB4NGUsIDB4YzIsIDB4NGMsIDB4MTAsIDB4MTAsIDB4MWMsIDB4OTIsIDB4NTIsIDB4OCwgMHgwLCAweDgsIDB4OCwgMHg4LCAweDIsIDB4NDAsIDB4MiwgMHg0MiwgMHg0YywgMHgxMCwgMHgxNCwgMHg5OCwgMHgxNCwgMHg5MiwgMHg4LCAweDgsIDB4OCwgMHg4LCAweDYsIDB4MCwgMHgxYiwgMHg3NSwgMHhiMSwgMHgzMSwgMHgwLCAweDFjLCAweDkyLCAweDUyLCAweDUyLCAweDAsIDB4YywgMHg5MiwgMHg1MiwgMHg0YywgMHgwLCAweDFjLCAweDkyLCAweDVjLCAweDkwLCAweDAsIDB4ZSwgMHhkMiwgMHg0ZSwgMHhjMiwgMHgwLCAweGUsIDB4ZDAsIDB4MTAsIDB4MTAsIDB4MCwgMHg2LCAweGM4LCAweDQsIDB4OTgsIDB4OCwgMHg4LCAweGUsIDB4YzgsIDB4NywgMHgwLCAweDEyLCAweDUyLCAweDUyLCAweDRmLCAweDAsIDB4MTEsIDB4MzEsIDB4MmEsIDB4NDQsIDB4MCwgMHgxMSwgMHgzMSwgMHgzNSwgMHhiYiwgMHgwLCAweDEyLCAweDRjLCAweDhjLCAweDkyLCAweDAsIDB4MTEsIDB4MmEsIDB4NDQsIDB4OTgsIDB4MCwgMHgxZSwgMHhjNCwgMHg4OCwgMHgxZSwgMHg2LCAweGM0LCAweDhjLCAweDg0LCAweDg2LCAweDgsIDB4OCwgMHg4LCAweDgsIDB4OCwgMHgxOCwgMHg4LCAweGMsIDB4ODgsIDB4MTgsIDB4MCwgMHgwLCAweGMsIDB4ODMsIDB4NjB9\";\n  transient = true;\n}\n#PMFLUE1q1CuJ4ghz\naction init_font() {\n  #b0vtErRVv2lKiwyD // {shim:}\n  #so2fife4MqLt1Dln if data→font→is_invalid then {\n    #hRTF6gnQkpgcVI0F $font_rows := art→font_chars→trim(\"{}\")→split(\",\")→map_to→Number($converter);\n    #gnhl2igarTz8w2X1 where converter(elt: String) returns (result: Number) {\n      #NZd95tR0pei7srD9 $x := $elt→to_number;\n      #bjwdIjRW58xl4ZgI contract→assert( `not` $x→is_invalid, $elt);\n      #VE234B61ItgkKgVL `return` $x;\n    }\n    #GXwn4PKhSZinH5Jl $nb := $font_rows→count;\n    #bcE3hNwJudeu449H contract→assert(math→mod($nb, 5) = 0, \"invalid font data\");\n    #ws1lTcfPCXYdibgp $n := $nb / 5;\n    #FNuWAd8Sjya04cTv data→font := code→create_sprite($nb, 5);\n    #xvsY0LHtmGPgd3TL for 0 ≤ c < $n do {\n      #NHblt5yTsRCX4KY1 for 0 ≤ row < 5 do {\n        #Krg7mRods3Dl3k2y $char := $font_rows→at($c * 5 + $row);\n        #PWFqQxwKPwt6h2Wd for 0 ≤ col < 5 do {\n          #NOwv6OryF0clX7lo if bits→and_uint32($char, bits→shift_left_uint32(1, $col)) ≠ 0 then {\n            #Cx4707D9Ly7f7wl3 data→font→leds→set_item($c * 5 + 4 - $col, $row, 255);\n          }\n        }\n      }\n    }\n  }\n  meta private;\n  meta sync;\n}\n#lXqPrHVzWaoZMhQU\nvar font : * Image {\n  // {shim:}\n  transient = true;\n}\n#kn3pxm1GvYlNa2FM\naction copy(#xDSPvIZLimSE2MgA src: * Image, #x3OdCZm4sg12zaMQ x_src_index: Number, #W2oZZTGMGJa7NNyS length: Number, #we1A4KgB1twL5dAS target: * Image, #SMzdIeBXlWN3rk9Z x_target_index: Number) {\n  #xVS27yM2iLbckrF4 // {shim:}\n  #itHlEE9vAYKoLLwH contract→requires($x_target_index ≥ 0 `and` $x_target_index + $length ≤ $target→leds→row_count, \"\");\n  #xSw5Z2RjNt6KkO1O contract→requires($x_src_index ≥ 0 `and` $x_src_index + $length ≤ $src→leds→row_count, \"\");\n  #YLi1rzwGdt51yvgW for 0 ≤ x < $length do {\n    #wOepVxKUEXepB4JQ for 0 ≤ y < 5 do {\n      #byEw4wKZ8D34CjTA $value := $src→leds→item($x_src_index + $x, $y);\n      #xgoui2MU0NwSX63I $target→leds→set_item($x_target_index + $x, $y, $value);\n    }\n  }\n  meta private;\n  meta sync;\n}\n#GBVlNX6jjV0ZeEsK\naction test_show_image() {\n  #vT52tges4o3Y4sKH // {shim:}\n  #tJWkRScB87ES2vh5 code→\\_libinit;\n  #B3ht5L7s2p9R2mUJ code→create_image(\"\");\n  #xaDxNVhBCfNUzkgF $img := code→create_image(\"1 0 0 0 0\\n0 1 0 0 0\\n0 0 1 0 0\\n0 0 0 1 0\\n0 0 0 0 1\");\n  #QVb2KOULf0Nlfuhv $img→show_image(0);\n  #UVUpjEQQ4dp7wzHj $img→show_image( - 2);\n  #F9pi4aSzEu9kjmyZ $img→show_image(2);\n  meta private;\n  meta test;\n}\n#Clf38zxkZIrobSlk\naction on_before_pause(#xk8GIyGNr2wlsynF body: Action) {\n  #tzjretiGNHu9Jbzz // **Simulator only!** Registers an event to run before pause.\n  #nAL0A4jjuTPWjd0J // {shim:}\n  #xjnRGo2GMH2Qy3Fi // {weight:0}\n  #xbU8a1LTxptE5w5M data→before_pause := $body;\n  meta private;\n  meta sync;\n}\n#lPJG6os6F3M65GjY\nvar before_pause : Action {\n  // {shim:}\n  transient = true;\n}\n#CCgTYpjWRTwnp9VZ\nvar doc : Document {\n  is\\_resource = true;\n  transient = true;\n}\n#xuFJQyZVR24l4lZD\naction pin_is_pressed(#PqStokDT5lOf1jxR name: String) returns(#tEhrD6EfDVOcSbFI pressed: Boolean) {\n  #azmYPGjkodVTzZEW // Get the pin state (pressed or not). Requires to hold the ground to close the circuit.\n  #vBhRQqSJZf4WYIle // {help:functions/pin-is-pressed}\n  #yiahMKDpg9PMqNVd // {namespace:input}\n  #x8XLiwKMO5Evc4TB // {weight:58}\n  #HNt4QiENW2fWc4fU // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2}\n  #QRFOhtCMkFfrBa2r // {shim:micro_bit::isPinTouched}\n  #SShWUIP3VYby3fRd code→init_pins;\n  #WsVEccEOZ0aG95J8 $name := $name→trim(\" \\t\")→to_lower_case;\n  #Ta2Yaf4GHnPo1g9S if data→board→touched then {\n    #xo2G8eJDCmsq4gT4 $target := code→pin_by_name($name);\n    #GtVffND0qQpD2Uky $p := data→board→touch_current;\n    #x3Gr77Zk0mZawflE data→finger→set_pos($p→x, $p→y);\n    #xB28uqAlbJAhYFzu if data→finger→overlaps_with($target) then {\n      #Ws3G9qMFZIAcnvDZ `return` true;\n    }\n  }\n  #adGG0ohDxSfXMItY if $name→equals(\"p0\") `and` senses→is_key_pressed(\"0\") then {\n    #b741DDwiWIafJlj6 `return` true;\n  }\n  else { #xN11da8I4Uh5uCI0 if $name→equals(\"p1\") `and` senses→is_key_pressed(\"1\") then {\n    #MwC8h4HyPUYqG0xK `return` true;\n  }\n  else { #KyslP3kLRnPWaw2f if $name→equals(\"p2\") `and` senses→is_key_pressed(\"2\") then {\n    #HvlIx1YVevH1jKxa `return` true;\n  }\n  else { } } } \n  #rE7lIBNdOOjEf4VE `return` false;\n  meta sync;\n}\n#J3NOIEutRnzUY4bD\naction on_pin_pressed(#xSs4Svf30EPMhoVj name: String, #BxKLhpiGqRcDwB1h body: Action) {\n  #kReLjZqoQYm1X75l // Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed.\n  #jHDQ6E4HWmRlwyxo // {help:functions/on-pin-pressed}\n  #yj4K6E3sCCK1V32N // {namespace:input}\n  #UZIoGA4CKSwhMxlf // {weight:57}\n  #OgqWJNwCulcyJT7l // {enum:name:P0=MICROBIT_ID_IO_P0,P1=MICROBIT_ID_IO_P1,P2=MICROBIT_ID_IO_P2}\n  #xZ0ArWZwbu4SBuBn // {shim:micro_bit::onPinPressed}\n  #jDgDoJLo4kvbVPvk $evid := \"on pin pressed \" ∥ $name;\n  #nPpJQoCs8nAIigcE code→notify_event_registration($evid);\n  #AC4jsXJ71LfQp2kk code→clear_pin_handler($name);\n  #h5fUFp7OQ9fEwJRv $btn := code→pin_by_name($name);\n  #g7K6590eu6r59eIv $ev := $btn→on_touch_up($touch_up);\n  #xSk8PXoFQvpiueOt where touch_up(x: Number, y: Number) {\n    #NbkK6P2y62Y9tOIt code→queue_event($body, $evid);\n  }\n  #P1GQOzd8c8e0hPJt code→store_pin_handler($name, $ev);\n  meta sync;\n}\n#pqc71fRJDE9AyREy\nvar led_x_index_legend : Sprite {\n  // {shim:}\n  transient = true;\n}\n#VTpQmE9c2z7zHZvZ\nvar led_y_index_legend : Sprite {\n  // {shim:}\n  transient = true;\n}\n#x6wCsmeEKLVxXaL2\naction test_pin_pressed() {\n  #YbjZ28PiH7cboofJ // {shim:}\n  #xrTaGQCG4tQ7BuaQ code→\\_libinit;\n  #uk4llAEL60uunwoN code→on_pin_pressed(\"P0\");\n  #xOX7XEk48KmshvAM where `implicit` \\_body\\_() {\n    #K9SewNiqXXHAAr9I code→show_number(0, 150);\n  }\n  #vMbUCvZwCzUVIPCj code→on_pin_pressed(\"P1\");\n  #ZNMMtevlmkH4UeG4 where `implicit` \\_body\\_() {\n    #xd8cEg1eTi89m63q code→show_number(1, 150);\n  }\n  #M792rT11iDEw20Qp code→on_pin_pressed(\"P2\");\n  #V3NF8Cc4SsoAbwjt where `implicit` \\_body\\_() {\n    #SkiHZpgB4MGkk3M6 code→show_number(2, 150);\n  }\n  meta private;\n  meta test;\n}\n#xfEzD2r0WjZppPTL\naction test_devices() {\n  #xM2V2HK64vD5CCP6 // {shim:}\n  #SF8Y7AzLVf79J9Hv code→\\_libinit;\n  #cTuQbNGhz19mZ9t8 code→on_notified(\"incoming call\");\n  #GyS1jjevaGOtFn7t where `implicit` \\_body\\_() {\n    #qV2L159TGxJqtFWY code→show_string(\"call\", 150);\n  }\n  #fDLKJmiUUW69SvE1 code→on_notified(\"display on\");\n  #xJ0TOWIoWn36b1L2 where `implicit` \\_body\\_() {\n    #x3DQ6nvE2f4Rqd2h code→show_string(\"on\", 150);\n  }\n  #pzhqPTIc6apYk7pA code→on_notified(\"display off\");\n  #tIPIEP27KGu6QXrc where `implicit` \\_body\\_() {\n    #oPQrc25PShs2hY12 code→show_string(\"off\", 150);\n  }\n  #TN6fi4j2zlOS6ZZN code→on_notified(\"incoming message\");\n  #xovkFszj0eJqEcde where `implicit` \\_body\\_() {\n    #jJR01sQvfk3C30u4 code→show_string(\"msg\", 150);\n  }\n  #xlty8np4b3hGTffF code→on_notified(\"orientation landscape\");\n  #n0VbKITZgs222bFS where `implicit` \\_body\\_() {\n    #z2ehI01nRsXB7Jri code→show_string(\"landscape\", 150);\n  }\n  #xo2CAyPVq82gihJv code→on_notified(\"orientation portrait\");\n  #ANNOwYn5M8CNBLsx where `implicit` \\_body\\_() {\n    #w3RcKVkf5ZwT0Yoy code→show_string(\"portrait\", 150);\n  }\n  #SP0ycUjbfsOKsd6J code→on_notified(\"shaken\");\n  #yRyJSh232waGLyFz where `implicit` \\_body\\_() {\n    #nQjSnZdNP45rtSYC code→show_string(\"shaken\", 150);\n  }\n  #xYsvR3f5jJsVfu8P code→tell_remote_control_to(\"play\");\n  #VXZ2fZLriKdH5o25 code→pause(1000);\n  #VHKRZyj11yrItaeA code→tell_remote_control_to(\"pause\");\n  #iuTCLYFn24YBEBAV code→pause(1000);\n  #NFjU8XLb5qH4qi0s code→tell_remote_control_to(\"stop\");\n  #oizDycRjQI2sU0fO code→pause(1000);\n  #x6tXtLrOjbyLj71J code→tell_remote_control_to(\"next track\");\n  #AaGU8mHo0WmDNVGm code→pause(1000);\n  #x9ptNjJbOEhQzr2G code→tell_remote_control_to(\"previous track\");\n  #hM89M5NlZSA5aZes code→pause(1000);\n  #m2qkS2n4QlIgr8rU code→tell_remote_control_to(\"forward\");\n  #gH1nNlcw62Yd6tF5 code→pause(1000);\n  #YC9iNYuSkosLnOiS code→tell_remote_control_to(\"rewind\");\n  #xmbSINcx1jnrao3s code→pause(1000);\n  #S4fvdbVeCn1mU7N5 code→tell_remote_control_to(\"volume up\");\n  #xpPB2ugK28IXwA4W code→pause(1000);\n  #c6mF6g3EZsN9kyMH code→tell_remote_control_to(\"volume down\");\n  #yr5uOJyqn6aV8Ge0 code→pause(1000);\n  #yb0esPi6Iy51trEl code→tell_camera_to(\"launch photo mode\");\n  #NzJXZ4xVLRd4Ejyg code→pause(1000);\n  #hCY4GTQ592HR6MDS code→tell_camera_to(\"launch video mode\");\n  #w00LIesoogGZI3SX code→pause(1000);\n  #q7dc4Ems5bX8bUjw code→tell_camera_to(\"start video capture\");\n  #w1XPyVxyf4I43cxv code→pause(1000);\n  #Ig5RtNNeoA2RR4Vp code→tell_camera_to(\"stop video capture\");\n  #VTD5jpdXtP0RSz4w code→pause(1000);\n  #xbMlLP406gUHPHdg code→tell_camera_to(\"stop photo mode\");\n  #x7UpsxVmiuAKf2O2 code→pause(1000);\n  #mji2VTG8pklTAlZT code→tell_camera_to(\"stop video mode\");\n  #xzqQy9QuYzBSFcU4 code→pause(1000);\n  #osyLpvx7y5Rqez47 code→raise_alert_to(\"display toast\");\n  #xgMtYE2VyuuK0SUh code→pause(1000);\n  #vplr1SUmLrtoEKw1 code→raise_alert_to(\"ring alarm\");\n  #mLMYnQoFZOYU4bBv code→pause(1000);\n  #Ti16hcwPzBwmNNj8 code→raise_alert_to(\"ring alarm 2\");\n  #nrJs9EsvqT9kFj7T code→pause(1000);\n  #abtVG7M5AmVIebxk code→raise_alert_to(\"ring alarm 2\");\n  #CuUOhQyH7q1POsMW code→pause(1000);\n  #wM3rylf47Mzw2D1I code→raise_alert_to(\"ring alarm 3\");\n  #hpxVivTxxOSR8Pqr code→pause(1000);\n  #c15239nr9VsPiIo9 code→raise_alert_to(\"ring alarm 4\");\n  #xI4HNzsLpPpgty82 code→pause(1000);\n  #N76wkVa5Gu9l3vAc code→raise_alert_to(\"ring alarm 5\");\n  #rS2fSXiqIn63Nape code→pause(1000);\n  #AXiIgG5uqhZfftXK code→raise_alert_to(\"ring alarm 6\");\n  #dnOMZGp6VT48T3g9 code→pause(1000);\n  #lQfV8k1SdXdWnQyy code→raise_alert_to(\"find my phone\");\n  #u4p6kOo9s73HoGoD code→pause(1000);\n  #r4nWD2K8jmaMjfI0 code→raise_alert_to(\"play ringtone\");\n  #KzEts7e3LbwEb2bL code→pause(1000);\n  #Llmpr8UCY4YttCbj code→raise_alert_to(\"play sound\");\n  #TKfJJ60q6Z52Y2Zs code→pause(1000);\n  #NmGpttcHIFb2l2NP code→raise_alert_to(\"vibrate\");\n  meta private;\n  meta test;\n}\n#FsXN4qs00Niar2I3\naction tell_camera_to(#p3kEX3EqeufdJmG1 @event: String) {\n  #wY3y0ASAfRrgGtG2 // Sends a ``camera`` command to the parent device.\n  #T9jxpLbgaFQwkQy8 // {namespace:devices}\n  #w2wLNoci3MafdcN6 // {weight:19}\n  #eeF0Fl9hopb7V9WB // {help:functions/tell-camera-to}\n  #Iqur1M60Xd5273Xa // {shim:micro_bit::devices::camera}\n  #gQP8w2Pvp4ygp502 // {enum:event:take photo=MES_CAMERA_EVT_TAKE_PHOTO,start video capture=MES_CAMERA_EVT_START_VIDEO_CAPTURE,stop video capture=MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,toggle front-rear=MES_CAMERA_EVT_TOGGLE_FRONT_REAR,launch photo mode=MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,launch video mode=MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,stop photo mode=MES_CAMERA_EVT_STOP_PHOTO_MODE,stop video mode=MES_CAMERA_EVT_STOP_VIDEO_MODE}\n  #yDtIYowWcPuh4mNt code→show_ble_event_notification(\"camera\", $@event);\n  meta sync;\n}\n#CzqRWuR2SyiUNdAg\naction raise_alert_to(#pHqCn0ZWIdyNQSVu @event: String) {\n  #vUmqTLUCj4fjFygl // Sends an ``alert`` command to the parent device.\n  #etLJqyeZ8q3eRTtj // {namespace:devices}\n  #gv2Lztj0odNeIJvt // {weight:18}\n  #ZCcDnTF7ZiSNaNNA // {help:functions/raise-alert-to}\n  #oq6L8Lgvq4qKxsZb // {shim:micro_bit::devices::alert}\n  #gEJkfOlRyGq3Cq72 // {enum:event:display toast=MES_ALERT_EVT_DISPLAY_TOAST,vibrate=MES_ALERT_EVT_VIBRATE,play sound=MES_ALERT_EVT_PLAY_SOUND,play ringtone=MES_ALERT_EVT_PLAY_RINGTONE,find my phone=MES_ALERT_EVT_FIND_MY_PHONE,ring alarm=MES_ALERT_EVT_ALARM1,ring alarm 2=MES_ALERT_EVT_ALARM2,ring alarm 3=MES_ALERT_EVT_ALARM3,ring alarm 4=MES_ALERT_EVT_ALARM4,ring alarm 5=MES_ALERT_EVT_ALARM5,ring alarm 6=MES_ALERT_EVT_ALARM6}\n  #feboFmM8Q6SZnWuH code→show_ble_event_notification(\"alert\", $@event);\n  meta sync;\n}\n#DFpXK66KYosuH2qD\naction create_A\\u002bB_button() {\n  #oqndQEOZsX7D7VuV // {shim:}\n  #Q7HJhFDhF31D1CyH data→button_a\\u002bb_inner := code→create_circle(525, 532);\n  #AezoGLweK6YLo95L // {help:functions/on-logo-up}\n  #jOo9NfJ7oRgpQ8Y4 data→button_a\\u002bb_inner→set_color(colors→black);\n  #nyeqaqfbg2o1utr4 data→button_a\\u002bb_inner→set_gradient(false);\n  #Z8fAqSYlCuXG6dtB data→button_a\\u002bb := code→create_circle(data→button_a\\u002bb_inner→x, data→button_a\\u002bb_inner→y);\n  #qL8vzC4Ua3ivvgm6 data→button_a\\u002bb→opacity := 0;\n  #pgsgfJbTVcGs9ULn data→button_a\\u002bb→width := 84;\n  #QWB0KqvVxcoyhy7H data→button_a\\u002bb→height := 84;\n  #Ktr2xDEXBGgQzQ6q data→button_a\\u002bb→x := data→button_a\\u002bb_inner→x;\n  #jMQz8inx0Hu43J4J data→button_a\\u002bb→y := data→button_a\\u002bb_inner→y;\n  #zS6N4kaRn2wel37F data→button_a\\u002bb→on_touch_down($touch_down);\n  #PJA6VUPCxlzWw0Nv where touch_down(x: Number, y: Number) {\n    #a2abvjq67X2J8yEU data→button_a\\u002bb_inner→set_color(colors→orange);\n    #R67xt5S6i2Tg17ti data→button_a_inner→set_color(colors→orange);\n    #tPC2aVNQVkohUc32 data→button_b_inner→set_color(colors→orange);\n  }\n  #HPkfFmXxktWAAMgq data→button_a\\u002bb→on_touch_up($touch_up);\n  #xWF6IyOF9X9GA09M where touch_up(x: Number, y: Number) {\n    #x3diqaUUBItAgH4p data→button_a\\u002bb_inner→set_color(colors→black);\n    #VWrTjWQVsOX82B1C data→button_a_inner→set_color(colors→black);\n    #mbfRvtByD8SP9Ard data→button_b_inner→set_color(colors→black);\n  }\n  #xrF43zP5h8mPVPIH $a\\u002bb_text := data→board→create_text(100, 40, 20, \"A+B\");\n  #OjSlLvcGgdRux2nI $a\\u002bb_text→set_color(colors→black);\n  #zds87sWwxUvSi4Kc $a\\u002bb_text→fit_text;\n  #MQQ53MhcsvV8Y81c $a\\u002bb_text→x := data→button_a\\u002bb→x;\n  #bs4gmywDvvLuEtqt $a\\u002bb_text→@bottom := data→button_a\\u002bb→@top + 10;\n  meta private;\n  meta sync;\n}\n#w7xLLit7W5biNqRL\naction create_B_button() {\n  #CDDoGfAZ7oqJpEWi // {shim:}\n  #Hxnhl22NTBAKVXpI data→button_b_inner := code→create_circle(525, 229);\n  #OJJgFsj90lBLVD6Y data→button_b_inner→set_color(colors→black);\n  #gtC6KmnU2Z5hTgIN data→button_b_inner→set_gradient(false);\n  #xPpbA1GFc7ufOgwp data→button_b := code→create_circle(data→button_b_inner→x, data→button_b_inner→y);\n  #xVcUpX8PlDVShy0U data→button_b→opacity := 0;\n  #myD38vc5KVYqxJjy data→button_b→width := 112;\n  #nk4Ah7b8Pz5Fxyaa data→button_b→height := 112;\n  #dnWpTTRMAGH5LR7K data→button_b→x := data→button_b_inner→x;\n  #xJ8biFwM65yBGrz4 data→button_b→y := data→button_b_inner→y;\n  #W8ipqb8qzv6DDJ9Z data→button_b→on_touch_down($touch_down);\n  #bZFBsmfIhtPST9HV where touch_down(x: Number, y: Number) {\n    #YiPXtiy40dPPjGdZ data→button_b_inner→set_color(colors→orange);\n  }\n  #Qrm9tjgmXuwskqsV data→button_b→on_touch_up($touch_up);\n  #IsiFhvitsyr3BwTC where touch_up(x: Number, y: Number) {\n    #kecNwKPdnS1ycmCt data→button_b_inner→set_color(colors→black);\n  }\n  meta private;\n  meta sync;\n}\n#h2y3t2CTwSZ5po2P\nvar button_b_inner : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xBES128hctdLOPWp\nvar button_a_inner : Sprite {\n  // {shim:}\n  transient = true;\n}\n#Bv2s8Hio3iAdQCss\nvar button_a\\u002bb_inner : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xrHM168gvIqFDWL4\naction on_notified(#ja99pvTLEWszGU6R @event: String, #u92yApOZzhWqx4x9 body: Action) {\n  #x3KDXHT4kdAt87Pj // Registers code to run when the device notifies about a particular event.\n  #e13mHRXUDt9X8SUj // {shim:micro_bit::onDeviceInfo}\n  #mc3m4mu0EMkFqfIo // {namespace:devices}\n  #x4sPBtRE9IMDXiSl // {enum:event:incoming call=MES_DEVICE_INCOMING_CALL,incoming message=MES_DEVICE_INCOMING_MESSAGE,orientation landscape=MES_DEVICE_ORIENTATION_LANDSCAPE,orientation portrait=MES_DEVICE_ORIENTATION_PORTRAIT,shaken=MES_DEVICE_GESTURE_DEVICE_SHAKEN,display off=MES_DEVICE_DISPLAY_OFF,display on=MES_DEVICE_DISPLAY_ON}\n  #m2Y4FjpJXWArRpT0 // {help:functions/on-notified}\n  #Bux3nIa98lMeKv4u code→notify_event_registration(\"on notified \" ∥ $@event);\n  #MDbRckoe8yhfH0Uw code→pairing_warning;\n  meta sync;\n}\n#xPty4Z96gEpPmXcC\nvar counters : Json_Builder {\n  // {shim:}\n  transient = true;\n}\n#uEOBEDRjLlEAJaV2\naction tick(#j2GGfLeDOHbsXZjl evid: String) returns(#xpE0YoFiEwnltNko c2: Number) {\n  #MeueTVmAKDsL2X3a // {shim:}\n  #nYuZwihGP24HOD9e $c := data→counters→number($evid);\n  #xCTFs2GTH5YoqiBt if $c→is_invalid then {\n    #YkiKdcxa0RNOk1Dd $c := 0;\n  }\n  #EKI3rwRF5c4S12YH $c := $c + 1;\n  #XDi6TARievQiaslS data→counters→set_number($evid, $c);\n  #M4BkiNLAQCyBMo2M `return` $c;\n  meta private;\n  meta sync;\n}\n#Mv24F812mJ3GfnmU\naction notify_event_registration(#g02jGBBa2sA62OQi evid: String) {\n  #HgJ7hFDs0h0KhMo0 // Used by library authors to notify an event.\n  #p4kX3FVGjvu2Bf44 // {shim:TD_NOOP}\n  #WV4LEgRBjvrM2NyD // {weight:0}\n  #xK4U2ElyXeq4kVxN // {namespace:simulator}\n  #JDNtwbXSOeQxOX3c // {action:libsonly}\n  #U3QSq4Bys0HpYoiD $c := code→tick($evid);\n  #CSLMchaNHEeAo9ZX if $c > 10 then {\n    #xGRcYnuDXDMpcEgQ code→warning(\"You register this event a lot. Move it out of the loop maybe?\");\n  }\n  meta sync;\n}\n#iyYckFFAkzncX0z5\naction test_image_partial_paste() {\n  #gGEVbkFZvwn26omq // {shim:}\n  #qNYSv82a9bufwSar code→\\_libinit;\n  #rUN44T7OGT1zz25f code→create_image(\"0 0 0 0 1\\n0 0 0 1 0\\n0 0 1 0 0\\n0 1 0 0 0\\n1 0 0 0 0\")→show_image(0);\n  #Z32wXINdisyPQwFl code→create_image(\"0 0 0 0 0\\n0 0 1 0 0\\n0 0 1 0 0\\n0 0 0 0 0\\n0 0 0 0 0\")→show_image(2);\n  meta private;\n  meta test;\n}\n#pbQ4mX9LsuvB6479\naction test_detect_event_over_registration() {\n  #XmLqRuU4B4mC44vY // {shim:}\n  #RP24GvJESSabTi3j code→\\_libinit;\n  #x8Rtk54oilx28eN2 code→forever;\n  #SDv3nIkUp4301pPy where `implicit` \\_body\\_() {\n    #wXqb2VYzBamFs9y0 code→on_button_pressed(\"A\");\n    #AFrJ39ft1kIpgu4T where `implicit` \\_body\\_() {\n      #iNCIkVU2vCCUxYqg skip;\n    }\n  }\n  meta private;\n  meta test;\n}\n#glHgGKBHAxnk24z2\naction render_image(#KkzO6pqnOT2H4Nbl @this: * Image, #WFXxzfGSmEcaecgL x_offset: Number) {\n  #wJjDZaded1juM16b // {shim:}\n  #xoCK7Hf5VvJd2IIu $cols := math→min(5, $@this→width - $x_offset);\n  #xIjtuyBD6lHvitS8 for 0 ≤ x < $cols do {\n    #cBTue49vRLx322bI for 0 ≤ y < 5 do {\n      #i4GeKthAALnRpGP4 $led := data→leds→at(code→index($x, $y));\n      #P2v15gj3plesHPMl $xi := $x + $x_offset;\n      #JwjqylYbr2MC3BU4 $state := 0;\n      #Xfykmd4KAfBDk2zI if $xi ≥ 0 `and` $xi < $@this→width then {\n        #pWDKJ02kXicPr2an $state := $@this→leds→item($xi, $y);\n      }\n      #zqePS9acv24oQAAv code→set_led_color($state, $led);\n    }\n  }\n  #Fk0NFFrO2Dmk9ebf code→update_board;\n  meta private;\n  meta sync;\n}\n#bjedWwYaJ5lL7RnB\nvar button_a_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#IJL62FT2o6Z3qp0h\nvar button_b_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#qHCHrugZxRO2nVNu\nvar button_a\\u002bb_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#V5epTckafYYQBUwI\naction clear_button_handler(#AP7KUiO86hEZMr3q name: String) {\n  #gVuKg3MqAoiA4KVd // {shim:}\n  #NducJY2YsouJ1sB4 $name := $name→trim(\" \\t\")→to_lower_case;\n  #ixzLqm9v9QnFaHCh if $name→equals(\"a\") `and` `not` data→button_a_handler→is_invalid then {\n    #n6oYNxkCTIM5W6gF data→button_a_handler→delete;\n    #xTH6y6KQyzUnfRMR data→button_a_handler→\\u25c8clear;\n  }\n  else { #dRbB4VOJ1mMUXJDY if $name→equals(\"b\") `and` `not` data→button_b_handler→is_invalid then {\n    #HGRHgdbJG1cj4P92 data→button_b_handler→delete;\n    #uJC4FJWjigU8QwyP data→button_b_handler→\\u25c8clear;\n  }\n  else { #DzKJuB7YBFPZWdo2 if $name→equals(\"a+b\") `and` `not` data→button_a\\u002bb_handler→is_invalid then {\n    #U99rMPfGl8rRBhMO data→button_a\\u002bb_handler→delete;\n    #NNQICBa0FzI7RLML data→button_a\\u002bb_handler→\\u25c8clear;\n  }\n  else { } } } \n  meta private;\n  meta sync;\n}\n#xIuuGWOiw4U0Z9E6\naction store_button_handler(#g5uKm1gGabuH7KEZ name: String, #xJnSEX7WxPHkhSK9 ev: Event_Binding) {\n  #ASAbZc9j0bH7hBmb // {shim:}\n  #Ccq6Wak9K4PcvMqn $name := $name→trim(\" \\t\")→to_lower_case;\n  #Z1idpGSDuTaD2SSS if $name→equals(\"a\") then {\n    #J2yZk3X9x4MJfzt2 data→button_a_handler := $ev;\n  }\n  else { #lFO5umVrdo8N5w8X if $name→equals(\"b\") then {\n    #fnPL4RqMQzhCa7MH data→button_b_handler := $ev;\n  }\n  else {\n    #bLLkTrQExLjukL2V data→button_a\\u002bb_handler := $ev;\n  }\n  } \n  meta private;\n  meta sync;\n}\n#w9lZwJwDJADMNaZY\naction test_forever_register() {\n  #AmcV6THL0zdDxQzd // {shim:}\n  #Dm8UnLZUSyFqCxQX code→\\_libinit;\n  #SJAOh2GVk4zGZC44 code→forever;\n  #xqAh9AiRPBjVq6zh where `implicit` \\_body\\_() {\n    #GCK4VF02k25NXDM1 code→on_button_pressed(\"A\");\n    #twPwQi6XciXsdKjV where `implicit` \\_body\\_() {\n      #xGqyp2mdNkIqsTei code→show_number(math→random(10), 150);\n      #Gjbrkpxz5Tx3vyYN code→pause(1000);\n    }\n  }\n  meta private;\n  meta test;\n}\n#M0RCMbzlj2nj2BI7\naction test_pixel() {\n  #BLv6aL7UZr2cqEfT // {shim:}\n  #chGi9E55itfMAUs2 code→\\_libinit;\n  #SGt5eFaUBCizckCO $img := code→create_image(\"0 1 0 0 0 1 1 1 1 1\\n0 1 0 0 0 0 0 0 0 1\\n0 1 0 0 0 0 0 0 0 1\\n0 1 0 0 0 0 0 0 0 1\\n0 1 0 0 0 0 0 0 0 1\");\n  #rsIi4z5FSvXfEUbY $img→set_pixel(8, 0, false);\n  #T5DS5wjBwJlWRDyx $img→scroll_image(1, 400);\n  #xRajHiRTS3WVG9eQ // grey scale\n  #x6EPsTOBC5Stwv2i code→set_display_mode(\"greyscale\");\n  #YxThP9Zpstv3c0GU for 0 ≤ j < 5 do {\n    #ctiRFQOKYtpl58Rb $img→set_pixel_brightness(9, $j, math→pow(2, $j));\n  }\n  #v7M3MZfrjb3ul0Hz $img→plot_image(5);\n  meta private;\n  meta test;\n}\n#dZXKhO253wRyy8ss\naction test_font() {\n  #x20Hxqj4AQlvhYrW // {shim:}\n  #RBMl9hru9FSnsMFJ code→\\_libinit;\n  #a4OniIrwDB2fZ6dL $s := \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n  #tNdflz42yjWVg2UE code→show_string($s, 150);\n  meta private;\n  meta test;\n}\n#XbUu3qU1GclXjcRC\naction add_button(#xbqiUfNdjVfd4IMd text: String, #xJ3n1woMhZjnYNMw @action: Action) {\n  #USGmD7z2Nxm3G1td // Adds a button to the simulator.\n  #xReX55Ndxhgd8Uwr // {shim:TD_NOOP}\n  #gzUEASG6jJjnjORe // {weight:0}\n  #sz5shPxAJMrHPGcv // {namespace:simulator}\n  #jurR2bpFoTez7gQd // {action:libsonly}\n  #Q7KxeKWW1ylQ4sof if data→button_extra→is_invalid then {\n    #xWU42PbYiXq0h2cU code→create_extra_button($text→to_upper_case, $@action);\n  }\n  meta sync;\n}\n#QofbsqCZ4V5hSSrX\naction create_extra_button(#mncq4kd55AAXrAl3 text: String, #xGKSnvw1vCIbFYyj @action: Action) {\n  #jiT2zrVOmtzOZRYr // {shim:}\n  #HqdXAvEWpftML4hA data→button_extra_inner := code→create_circle(412, 532);\n  #gPk3T8UBTWjSz8zn data→button_extra_inner→set_color(colors→black);\n  #nxreVM8UIUMg1VXW data→button_extra_inner→set_gradient(false);\n  #JGtXNV2yHEji6Ayn data→button_extra := code→create_circle(data→button_extra_inner→x, data→button_extra_inner→y);\n  #b4DhmqP47SNxK8OP data→button_extra→opacity := 0;\n  #SCO4V6exNc28sn95 data→button_extra→width := 84;\n  #LxUwVuZCSl3qrgQ3 data→button_extra→height := 84;\n  #xqljf58UOeHk2y2P data→button_extra→x := data→button_extra_inner→x;\n  #xzo2t6FZjFtPhcKY data→button_extra→y := data→button_extra_inner→y;\n  #pH0k8Ne3XCu2mscE data→button_extra→on_touch_down($touch_down);\n  #ePOpGNP0Ap24XGBk where touch_down(x: Number, y: Number) {\n    #gNN8eW7NKIACfyvx data→button_extra_inner→set_color(colors→orange);\n    #xWdiZFKt6469IQNI $@action→run;\n  }\n  #mFclEPh38W3L4nnR data→button_extra→on_touch_up($touch_up);\n  #xKbGq1XMVS7PZIF9 where touch_up(x: Number, y: Number) {\n    #BMGWQpXAUNqygWVm data→button_extra_inner→set_color(colors→black);\n  }\n  #cYszk5cTaxeH5lMn $btn_text := data→board→create_text(100, 40, 20, $text);\n  #pkRVEwItpfnOPHpL $btn_text→set_color(colors→black);\n  #xhVuttTeTSZXMEca $btn_text→fit_text;\n  #KuRLFeiYpX8ibIt4 $btn_text→x := data→button_extra→x;\n  #zIBuDWJcjBM32Yp4 $btn_text→@bottom := data→button_extra→@top + 10;\n  meta private;\n  meta sync;\n}\n#jKmZy7vMlzUPALmn\nvar button_extra_inner : Sprite {\n  // {shim:}\n  transient = true;\n}\n#cXnqrj241SpxUMwF\nvar button_extra : Sprite {\n  // {shim:}\n  transient = true;\n}\n#VIbUURZHhKQK2SyZ\naction reset() {\n  #xvUvNkHFq7GZFMhL // Resets the BBC micro:bit.\n  #lHHGwpOT14CKYow4 // {weight:1}\n  #bcD9ZyddSMemVKZU // {namespace:control}\n  #O4TGFHEORPMYt8Sp // {shim:uBit.reset}\n  #InYaIalKOaSAg5nh // {help:functions/reset}\n  #bn3n2t5DLBeqS63D app→restart(\"\");\n  meta sync;\n}\n#YEzwn1KNBHbFPNUs\naction test_reset() {\n  #S2osQorpwX0Xn5kn // {shim:}\n  #GSnZiIZY6ZZfqTYY code→\\_libinit;\n  #IPnXPhzZKv8j2H2j code→show_string(\"A\", 150);\n  #ZFn2kKadUEmlY4Wk code→reset;\n  meta private;\n  meta test;\n}\n#TpQcQgKdAFw5Pqho\naction test_show_number() {\n  #lkVsRQg2Y57CbEHt // {shim:}\n  #xlVV048e6Gv5qT80 code→\\_libinit;\n  #pJFrIdojNwmiVXeG code→show_number(0, 150);\n  #sOilRBUMeGHbS5iq code→show_number(1, 150);\n  #XiW64jN2AhkgUI8q code→show_number(2, 150);\n  meta private;\n  meta test;\n}\n#jFmD5xkFyWwpGTFt\naction test_plot_leds() {\n  #uv2qjBz92QKG6jb4 // {shim:}\n  #xWC0vpIb0g6zkauY code→\\_libinit;\n  #HAPp3WJOXLG3Hd5l code→plot_leds(\"0 0 0 0 0\\n0 1 0 1 0\\n0 0 1 0 0\\n0 0 0 1 0\\n1 0 0 0 0\");\n  #kBUen1jy0k4wINSh code→pause(1000);\n  #xekvRRnvmhQHiMBK code→plot_leds(\"0 0 0 0 1\\n0 1 0 1 0\\n0 0 1 0 0\\n0 0 0 1 0\\n0 0 0 0 0\");\n  #xzmqbCGIOoCg2MsE code→pause(1000);\n  #xFXsetNa4Qhcgcja $img := code→create_image(\"0 0 0 0 0 0 0 0 0 0\\n0 0 1 0 0 0 0 0 0 0\\n0 1 1 1 0 0 0 1 0 0\\n0 0 1 0 0 0 0 0 0 0\\n0 0 0 0 0 0 0 0 0 0\");\n  #x7RQ0L8v7jnJDs4P $img→plot_frame(1);\n  #fL5VgMaVovLc2kVR code→pause(1000);\n  #BwpLTSufIn4ypBn1 code→show_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n0 0 1 1 0\\n0 0 0 0 0\\n0 0 0 0 0\", 400);\n  #ibZy2FI2FCKOxqoF code→show_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n0 1 1 1 0\\n0 0 0 0 0\\n0 0 0 0 0\", 400);\n  #YncCIVFUM28UddtK code→show_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n1 1 1 1 1\\n0 0 0 0 0\\n0 0 0 0 0\", 800);\n  meta private;\n  meta test;\n}\n#Z6Z2iGq64Ec1fuTh\naction warning(#dJIbhLazNunQ2Pqc message: String) {\n  #tzFPXXJ2C0Ha4ERR // Warns the user about a potential usage issue with the current code.\n  #wTj93HfGOCA1RRHP // {shim:TD_NOOP}\n  #xn2tBmso4Kss6D00 // {namespace:simulator}\n  #xOgOSqT4yi1RgSdZ // {weight:0}\n  #keritj886fLnv3fw // {action:libsonly}\n  #ukJpRgVrsYCsFdrj $editor := app→editor;\n  #gwhUA7MFzDe9jIUB if `not` $editor→is_invalid `and` `not` $message→is_invalid `and` `not` $message→is_empty then {\n    #xyn4eh9QnXz4pLxl $editor→annotate_caller(\"warning\", $message);\n  }\n  meta sync;\n}\n#tPLU5ZwYXNcXCDk3\naction analog_set_period(#x0BXJqvN5uf5JIh2 pin: String, #amJYJbzMJzlrlol3 micros: Number) {\n  #D3DLwyTrT2wKkoVN // Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.\n  #fUdLXCrX4rNeuilQ // If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.\n  #DbpdkxM4nUP2sVga // {shim:micro_bit::setAnalogPeriodUs}\n  #xyHbQm9j2k6iXq4P // {namespace:pins}\n  #OBcAFCK2Q2DfudpZ // {help:functions/analog-set-period}\n  #PAYMs0BDD8RbLR3B // {weight:10}\n  #SqhPms4IXETastFm // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2}\n  #Xh232b04YquKwayo // {hints:micros:20000}\n  meta sync;\n}\n#AuigaLeUb4929mNA\naction analog_set_pitch_pin(#xpU1U000JWEY2Boq name: String) {\n  #xj4o22Omk1EIaC9O // Sets the pin used when using `pins->analog pitch`.\n  #p3pMqgSnQxlKKpTd // {shim:micro_bit::enablePitch}\n  #YOZY4h2Snemy2Ssv // {namespace:pins}\n  #ksrlzJbUsmtEkaBH // {help:functions/analog-set-pitch}\n  #xQhxWqWeqz22iboM // {weight:12}\n  #vKrvmC4KbTx4UrT9 // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2}\n  #WHQMX8TGwNk4rHSx data→pitch_pin := $name;\n  meta sync;\n}\n#gEmhFkaGb62VAwjT\naction analog_pitch(#xicUA6rVANK5Hpya frequency: Number, #EOcY1jATp3Ldw16o ms: Number) {\n  #xFJhXD0ijs00YMjd // Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.\n  #SuwCvUifdY38to4S // {shim:micro_bit::pitch}\n  #Mh0Oeb4E8cK3WWWW // {namespace:pins}\n  #xGfz4I04h2bsO91l // {help:functions/analog-pitch}\n  #xEGCJ6YyP3Gaw9ug // {weight:14}\n  #Nv7yTShmVzRRmckP // {hints:frequency:440}\n  #lyVvmxzXMSk4YDmd // {hints:ms:500}\n  #fx1pQM2jYhWeMW8F if data→pitch_pin→is_invalid `or` data→pitch_pin→is_empty then {\n    #bqUsIek5pKDTe6Pe code→warning(\"pitch pin not set\");\n    #ifW5htAtZseohisz `return` ;\n  }\n  #wunHmKjgrpZ9byII if $frequency ≤ 0 then {\n    #xXcOYe7q4TdBfOsz media→tone(0, 1);\n    #H9Y66i52F23oOeSD `return` ;\n  }\n  #qvLwajJDb3fREXyj if $ms ≤ 0 then {\n    #xHlePNztv5JpESZp media→tone($frequency, 1);\n  }\n  else {\n    #xbFhJ20GSASivmak $secs := $ms / 1000;\n    #c9RnAE2uzKh6Cqax media→play_note($frequency, 1, $secs);\n    #Bdrwg0EArm46eHAx time→sleep($secs);\n  }\n}\n#KgNK732SuRLWRKOO\nvar pitch_pin : String {\n  // {shim:}\n  transient = true;\n}\n#f01xEP7flwdYeYJq\naction test_pitch() {\n  #YTd12LqhKZ4TaZc2 // {shim:}\n  #seC2W2nEHKYskZWx code→\\_libinit;\n  #ZIUeBcsS2CnLOyAX code→analog_set_pitch_pin(\"P0\");\n  #HgqlbD1gvQviXx8z for 0 ≤ i < 10 do {\n    #U0MwRtD11cCn27TG code→analog_pitch(400 + $i * 100, 1000);\n  }\n  #dDCdl0EzpaRtSQeM code→pause(1000);\n  #xFHA2N0ccuekrNB6 code→analog_write_pin(\"P0\", 512);\n  #AgpJ3he45LX41vYs for 0 ≤ j < 10 do {\n    #VA5aDXkUjZHNPhD9 code→analog_set_period(\"P0\", 5000 - $j * 100);\n    #zq5NuKyDLAFXhWKl code→pause(500);\n  }\n  meta private;\n  meta test;\n}\n#Homv4VKEXNUbTAb4\naction plot_frame(#xYYuLhKmEWIzIX1x @this: * Image, #AJWLlSJwoTdXgT9i index: Number) {\n  #fCfOCntjWE4DNymC // Draws the ``index``-th frame of the image on the screen.\n  #xasY934N29G7WBjg // {help:functions/plot-frame}\n  #wQpnycOYR16SMb15 // {namespace:image}\n  #OFsNMj5vqD4C4rm4 // {weight:65}\n  #uM7fnoqbHXxpqA12 $@this→show_image(5 * $index);\n}\n#x07I9YOUT6XAu5Ky\naction show_leds(#Agy1tNVQeIcg2pFD leds: String, #H23Wq0aPH08LnwS6 ms: Number) {\n  #a1ZU6jET0rFURbW6 // Draws an image on the LED screen and pauses for the given milliseconds.\n  #rah4E4gr6b4ZXnki // {help:functions/show-leds}\n  #q2YahTUs7lFN2x05 // {weight:95}\n  #x8YEphMMwGJeCtZ4 // {namespace:basic}\n  #M7D8GVVyvj4k5vxo // {language:leds:bitframe}\n  #DGgSDJzlKoPX3ljp // {hints:ms:400,1000}\n  #WkpvN4lkB72SdNex // {shim:micro_bit::showLeds}\n  #xxOvJbn2Cq3yEODu $img := code→parse_image($leds);\n  #KrQe1YwMxdRhx6GZ $img→show_image(0);\n  #cvrrG22FPWn6MsSk code→pause($ms);\n}\n#t4AKY0PCv6CBzZ12\naction play_tone(#zExdWNZANFRC5nyu frequency: Number, #Ulhn7NcyJhmRukqz ms: Number) {\n  #RQfvAHuFsy3gBARR // Plays a tone through pin ``P0`` for the given duration.\n  #cyajATGMs74bzPW7 // {help:functions/play-tone}\n  #xQkMwqu2Oa6nrGiE // {namespace:music}\n  #ZTzyTPXsUFIyRaeU // {weight:90}\n  #dIQ0LIbfqHjwOyCO // {hints:frequency:440}\n  #xa04A5Hpj2lPJQ2M // {hints:ms:1000}\n  #L4roLQqOhkhZifAC code→analog_set_pitch_pin(\"P0\");\n  #DGH7JMwHU0ka6VR6 code→analog_pitch($frequency, $ms);\n}\n#q80UeIEQE4foqp5T\naction test_music() {\n  #ADNnaMD8sbQ092vx // {shim:}\n  #cnnl5nwTO8MNlzG2 code→\\_libinit;\n  #bt7ZIZfVg1aOLLEt code→play_tone(440, 1000);\n  #wBYXZY7x529yWQG4 code→play_tone(480, 1000);\n  #nq42JFfrOqGl2QKO code→play_tone(520, 1000);\n  #Cybr2QXkXV2ir6l6 code→pause(2000);\n  #qQ8ZNMWIJJXtutNM code→play_tone(code→note_frequency(\"C\"), 1000);\n  #mneI19aKf1ds9SjX code→play_tone(code→note_frequency(\"D\"), 1000);\n  #xbL5os2MHu5S7uYp code→play_tone(code→note_frequency(\"E\"), 1000);\n  #PVLpMp4WMqlphpIr code→play_tone(code→note_frequency(\"F\"), 1000);\n  #xZjE4yULP8q68zot code→play_tone(code→note_frequency(\"G\"), 1000);\n  #tupQgO33hsOHShvY code→play_tone(code→note_frequency(\"A\"), 1000);\n  #MPE7BMMK24O3cpKc code→play_tone(code→note_frequency(\"B\"), 1000);\n  meta private;\n  meta test;\n}\n#sOGTRmXpnMKLLTtr\naction note_frequency(#G5aP8OToIirHnSrm name: String) returns(#icSfcpgaQI61R31i frequency: Number) {\n  #MBVL4W7GtZth7c8Q // Gets the frequency of a note.\n  #yhvDBEaWWEbLTw4a // {enum:name:C=262,C#=277,D=294,Eb=311,E=330,F=349,F#=370,G=392,G#=415,A=440,Bb=466,B=494,C3=131,C#3=139,D3=147,Eb3=156,E3=165,F3=175,F#3=185,G3=196,G#3=208,A3=220,Bb3=233,B3=247,C4=262,C#4=277,D4=294,Eb4=311,E4=330,F4=349,F#4=370,G4=392,G#4=415,A4=440,Bb4=466,B4=494,C5=523,C#5=555,D5=587,Eb5=622,E5=659,F5=698,F#5=740,G5=784,G#5=831,A5=880,Bb5=932,B5=989}\n  #CEuFbUNDPjFBgtrO // {shim:TD_ID}\n  #xhQC7C2c52WDwr8z // {namespace:music}\n  #iXmcRdXDoHI3JVod // {weight:40}\n  #x3L2s27YTHChFBvT // {help:functions/note-frequency}\n  #cY7oVDRa2q52ktSU $f := art→notetable\\u002esjon→number($name→to_upper_case→trim(\" \\t\"));\n  #fxhp0PqdX2BUGW4N if `not` $f→is_invalid then {\n    #x0GIA0PDAM9yE8tE `return` $f;\n  }\n  else {\n    #STVoohtLA3YlXWin code→warning(\"Sorry, we don\\'t know about this note.\");\n    #SaL0iE3iTWdYkP1k `return` 0;\n  }\n  meta sync;\n}\n#z4gSyUfMQnLVFUce\nvar notetable\\u002esjon : Json_Object {\n  // {shim:}\n  is\\_resource = true;\n  url = \"data:text/plain;base64,ewogICAgIkMiOjI2MiwKICAgICJDIyI6Mjc3LAogICAgIkQiOjI5NCwKICAgICJFQiI6MzExLAogICAgIkUiOjMzMCwKICAgICJGIjozNDksCiAgICAiRiMiOjM3MCwKICAgICJHIjozOTIsCiAgICAiRyMiOjQxNSwKICAgICJBIjo0NDAsCiAgICAiQkIiOjQ2NiwKICAgICJCIjo0OTQsCiAgICAKICAgICJDMyI6MTMxLAogICAgIkMjMyI6MTM5LAogICAgIkQzIjoxNDcsCiAgICAiRUIzIjoxNTYsCiAgICAiRTMiOjE2NSwKICAgICJGMyI6MTc1LAogICAgIkYjMyI6MTg1LAogICAgIkczIjoxOTYsCiAgICAiRyMzIjoyMDgsCiAgICAiQTMiOjIyMCwKICAgICJCQjMiOjIzMywKICAgICJCMyI6MjQ3LAogICAgCiAgICAiQzQiOjI2MiwKICAgICJDIzQiOjI3NywKICAgICJENCI6Mjk0LAogICAgIkVCNCI6MzExLAogICAgIkU0IjozMzAsCiAgICAiRjQiOjM0OSwKICAgICJGIzQiOjM3MCwKICAgICJHNCI6MzkyLAogICAgIkcjNCI6NDE1LAogICAgIkE0Ijo0NDAsCiAgICAiQkI0Ijo0NjYsCiAgICAiQjQiOjQ5NCwKICAgIAogICAgIkM1Ijo1MjMsCiAgICAiQyM1Ijo1NTUsCiAgICAiRDUiOjU4NywKICAgICJFQjUiOjYyMiwKICAgICJFNSI6NjU5LAogICAgIkY1Ijo2OTgsCiAgICAiRiM1Ijo3NDAsCiAgICAiRzUiOjc4NCwKICAgICJHIzUiOjgzMSwKICAgICJBNSI6ODgwLAogICAgIkJCNSI6OTMyLAogICAgIkI1Ijo5ODkKfQ==\";\n  transient = true;\n}\n#xUYxOeKj6LoMvF7P\naction plot_leds(#WQt3HgKnNR1dkKwC leds: String) {\n  #jJiF4GeW3y5L8ZvJ // Draws an image on the LED screen.\n  #xeTbykuSWaF0nr9g // {help:functions/plot-leds}\n  #w9yQC2gSVG43NHs2 // {weight:80}\n  #C2NdzXO4YdWRnaEW // {namespace:basic}\n  #xCxDF5VU01h01Yh6 // {language:leds:bitframe}\n  #BA24IxYmXqkPDxLQ // {shim:micro_bit::plotLeds}\n  #cs0dZUvcOoT2Tbj4 $img := code→parse_image($leds);\n  #dfutR56803BeCdLx code→render_image($img, 0);\n  meta sync;\n}\n#CMiSgO7T4A4heu2z\naction plot_image(#OrAkEEB8qLoT4Mzd @this: * Image, #HXxAUi2ymf5FqRzN x_offset: Number) {\n  #c8b4vsUEisjXLh2u // Plots a frame from the image at offset ``x offset``.\n  #rVAalBbYMFEqtpEC // {help:functions/plot-image}\n  #L9R3IVcl2KNAEQL2 // {namespace:image}\n  #HThvzxSJtOTHengS // {namespace:led}\n  #xhU09kichmIGxHZV // {weight:69}\n  #Kl4zmpg9HVwUey6O // {hints:x offset:0,5,10}\n  #VfYDTi9V6fB4yWKi // {shim:micro_bit::plotImage}\n  #M8USzI3sH1AvswWQ code→render_image($@this, $x_offset);\n  meta sync;\n}\n#veAWzsaQ3mAeSOvA\naction set_theme(#cJ3VYThrkFH2nnon name: String) {\n  #x5CwjchVbMRh3uoA // {shim:}\n  #f2xg2qfKJ7v1Lq5x if $name→is_empty then {\n    #SLALoF6RT42i7Ejp // fetch theme from settings\n    #l3lhYG6Iq5hifmUk $default_theme := app→env→temporary_setting(\"bbc micro:bit theme\");\n    #xwWysIAEYBf7i4gW if $default_theme→is_invalid then {\n      #H4LeHpMBwx4OkSKf $default_theme := \"red\";\n    }\n    #uH4b8fL22EjTKz0h $name := $default_theme;\n  }\n  #e4B1ZURot54YEGiY data→current_theme := $name;\n  #e4Zsrvf4HUVvvwhd app→env→set_temporary_setting(\"bbc micro:bit theme\", $name);\n  #p5briRb9oTIasn8h data→led_off_color := colors→transparent;\n  #a2k5eTy9hRQcxe46 data→board_color := colors→from_rgb(0.85, 0.95, 0.85);\n  #qyDWsRI4ytHtFd8g $leds_background := colors→black;\n  #evzUYi83YPBOBMlr $markup := art→board\\u002esvg;\n  #HFTjMO2guOv7Rm2w if data→current_theme→equals(\"blue\") then {\n    #e1DeXSmMGEeWOuR8 data→led_on_color := colors→blue;\n    #thMgho7JD3MYX4td data→back_led_color := \"#aaa\" →to_color;\n    #waG9f7vlgr57D4RL data→left_eye→color := \"#273EE2\" →to_color;\n  }\n  else {\n    #fu62b3psxXKSTvpr $s := art→boardcolors\\u002ejson→at(math→random(art→boardcolors\\u002ejson→count))→to_string;\n    #E12o9ZhEzBrBdaxR $markup := $markup→replace(\"#273EE2\", $s)→replace(\"#D4AF37\", \"#989898\")→replace(\"#F9F9F9\", \"#000\");\n    #NAj8gc9TnnnW95KJ data→led_on_color := \"#ff7f7f\" →to_color;\n    #PDctHCuC00kxArHt data→back_led_color := \"#202020\" →to_color;\n    #HzF84IyeFuNZEN0S data→left_eye→color := $s→to_color;\n  }\n  #o0Sg6ZIdqIY2MrO7 data→right_eye→color := data→left_eye→color;\n  #DflzlS5FVtxTtiv3 data→picture→blend_svg($markup, 0, 0, 612, 498, 0);\n  #y83CLwRPgvZv68BM for 0 ≤ i < data→back_leds→count do {\n    #j0NqowF1gJYZbFxY $sprite := data→back_leds→at($i);\n    #uUA4sC8H8ziHanbz $sprite→set_color(data→back_led_color);\n  }\n  #xLIqmgbYCB5fxAPi for 0 ≤ j < data→leds→count do {\n    #gxG2ZfmOxSI7272S $sp := data→leds→at($j);\n    #xCqSX9GgsvwAdse6 if `not` $sp→color→equals(colors→transparent) then {\n      #KKuXMjFU6exhXzyG $sp→color := data→led_on_color;\n    }\n  }\n  meta private;\n  meta sync;\n}\n#CIQ4veOCB3b54xEF\nvar back_led_color : Color {\n  // {shim:}\n  transient = true;\n}\n#pKuVW9VLAsoLATs1\nvar current_theme : String {\n  // {shim:}\n  transient = true;\n}\n#ZcRIUJagQtw2kOc3\naction init_theme() {\n  #xG4G6cfMaEbWqlM9 // {shim:}\n  #EkEHXeeTIhNElM4z data→theme_button_inner := code→create_circle(data→board→width - 64, 54);\n  #gvxgpbcF2Vh2n8p5 data→theme_button_inner→set_color(colors→white);\n  #GFgmQ44OMr4dNwq4 data→theme_button := code→create_circle(data→theme_button_inner→x, data→theme_button_inner→y);\n  #Z29h69s2yrXbBYqT data→theme_button→opacity := 0;\n  #xAwSmgeMsxy2mo2m data→theme_button→width := 112;\n  #GbVT219kzML5zCRs data→theme_button→height := 112;\n  #c0AwY5ROsgtG2Knd data→theme_button→x := data→theme_button_inner→x;\n  #sQR4SSgpdHIVYt3Q data→theme_button→y := data→theme_button_inner→y;\n  #B2CwAWAZnJLS03hT data→theme_button_text := data→board→create_text(100, 40, 20, \"THEME\");\n  #D3Q0VYJTEsOeCSSW data→theme_button_text→set_color(colors→white);\n  #xmkTU26RbeIFb2Jc data→theme_button_text→fit_text;\n  #e4SNFryMf0J07YJC data→theme_button_text→x := data→theme_button_inner→x;\n  #tgvI4UL0HsxskMLH data→theme_button_text→y := data→theme_button_inner→y - 34;\n  #LzHTvRzGmrVF5uqf data→theme_button→on_touch_down($touch_down);\n  #j2kGPOFC3VpxGuvH where touch_down(x: Number, y: Number) {\n    #zUofeW9VI4OAw6vA if data→current_theme→equals(\"red\") then {\n      #KyZyX0ozrSc7lt7e code→set_theme(\"blue\");\n    }\n    else {\n      #ihyfyE1odrtrY2mB code→set_theme(\"red\");\n    }\n    #Ekmnrj2o99FWFUDY code→update_board;\n  }\n  meta private;\n  meta sync;\n}\n#xdhVzgfGv2tKJXiC\nvar theme_button_inner : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xzT4DM36ZVg22KDW\nvar padding : Number {\n  // {shim:}\n  transient = true;\n}\n#IumTSFIHhbwxn3H4\nvar left : Number {\n  // {shim:}\n  transient = true;\n}\n#ySs9JtsfD489KWqC\nvar @top : Number {\n  // {shim:}\n  transient = true;\n}\n#R4ySKAi8lAt3lPo4\nvar picture : Picture {\n  // {shim:}\n  transient = true;\n}\n#kgAKd05Qka2tkxaX\nvar theme_button_text : Sprite {\n  // {shim:}\n  transient = true;\n}\n#xxmFVVtdBqvw9AQy\naction temperature() returns(#xBZ4CpbFL4CvRApl temp: Number) {\n  #iJmxeqmb8usTYoBE // Gets the temperature in Celsius degrees (°C).\n  #xbkpE9efBEU3vReG // {weight:70}\n  #trqBmVFo8y4PREFi // {help:functions/temperature}\n  #ettU9cm9h4KGIsTs // {namespace:input}\n  #fokjMzX103zh4OIf // {shim:uBit.thermometer.getTemperature}\n  #w2zqRCAFyOt1oUWQ `return` 21;\n  meta sync;\n}\n#Vl55kdKb5D1kgSyk\naction stop_animation() {\n  #ATIWVp4tTwDxB4Bp // Cancels the current animation and clears other pending animations.\n  #d4LAQbEUe7uRZJAS // {namespace:led}\n  #Ix2qKgTtbnPMed6L // {weight:10}\n  #xbNtuxocqqClsImw // {shim:uBit.display.stopAnimation}\n  #PNe2ZX3bc32uAfMh // {help:functions/stop-animation}\n  #BDAdp8kwFZFXSYHu data→current_animation := data→current_animation + 1;\n  #gQ12sQ2hZdAouv1m records→Animation_table→clear;\n  meta sync;\n}\n#BVGhpbmcgdGFibGUa\ntable Animation {\n  // {shim:}\n  type = \"Table\";\n  persistent = false;\n  fields {\n    #e2tjt3wkHvRy11YN fn : Action\n  }\n}\n#zhNkP3CWz74bNvt9\naction animation_worker() {\n  #Cymc1fF7P43K4gho // {shim:}\n  #twUDLvYsbqiIiLNp while true do {\n    #Z12yqFGgOP8zzrgk $anim := records→Animation_table→row_at(0);\n    #TCtfj65FNI3BQu5k if `not` $anim→is_invalid then {\n      #x42IFPmOy8OMd94D $anim→fn→run;\n      #xwyIlpRntu8n4vEo $anim→delete_row;\n    }\n    else {\n      #xZksFGo4EkNM0dh8 records→Animation_table→wait_for_update;\n    }\n  }\n  meta private;\n}\n#bMFwG1RBnkCrq3IP\naction queue_animation_and_wait(#lZbLVMHV26CI2Azb body: Action) {\n  #pSk1SAXTgEkwXI52 // {shim:}\n  #y91tnga0ipumHs77 $anim := records→Animation_table→add_row;\n  #W4ekNcG32RwDFN64 $anim→fn := $body;\n  #VyXEejIbvlKT85x0 while true do {\n    #r2yPaxh1j83WPSQq if $anim→is_deleted then {\n      #lZZj1cN4JVqKGeD3 `break` ;\n    }\n    #x64FBWkpzD1lr3ys records→Animation_table→wait_for_update;\n  }\n  meta private;\n}\n#xfKBe2N4OpGoOMjI\naction test_animations() {\n  #C28AVJ2OeeVO9UJB // {shim:}\n  #NAatOLGkWDaNdLSJ code→\\_libinit;\n  #xM8mK0o47XZ2xL4w code→on_button_pressed(\"A\");\n  #Ec9RhvIua6hxfiau where `implicit` \\_body\\_() {\n    #xxDjfJsq8yJ2hJZg code→show_string(\"A\", 150);\n  }\n  #dkWr85kOaggITn84 code→on_button_pressed(\"B\");\n  #Ujf724J59Y9Agp4u where `implicit` \\_body\\_() {\n    #fkIWDo3j3WYiNeTE code→show_string(\"B\", 150);\n  }\n  meta private;\n  meta test;\n}\n#vtW004u24giFHFCF\naction show_frame(#so5UArm5bvzzbO7Q img: * Image, #wbgk1lJLlqXDa2l4 frame: Number) {\n  #ul6aa2q9FEngpuGm // Shows a particular frame of the image strip.\n  #FO4MMEEFSc9G0nTb // {namespace:image}\n  #gCr4tw5bcjlK72W2 // {weight:70}\n  #xA18S6STfkQQmHSO // {help:functions/show-frame}\n  #RqxUSeIfDyXF0l5K $img→show_image($frame * 5);\n}\n#jK3Ut2qwQC0bZ07k\ntable Event_Bus {\n  // {shim:}\n  type = \"Table\";\n  persistent = false;\n  fields {\n    #kng9nuProLg6HpFo fn : Action\n    #lz2qarlZRUAVl0SD name : String\n  }\n}\n#xQHQZkhjqzpE4CRi\naction event_bus_worker(#VnWE2Q9sB2A5uIXD name: String) {\n  #xDyM0UomTSCQXKSV // {shim:}\n  #HakK0IQSqWKY8zju while true do {\n    #B2MyaPSqynIjfXO5 code→pause(1);\n    #Zg9hZK25Zv1Ub2Ym $ev := code→first_event($name);\n    #lN4KZZuuN9p2paSM if `not` $ev→is_invalid then {\n      #qUZz8iwjSjiyyavq $ev→fn→run;\n      #E7aHvwM2U423dBK6 $ev→delete_row;\n    }\n    else {\n      #P594Nj69PCQ9z45m records→Event_Bus_table→wait_for_update;\n    }\n  }\n  meta private;\n}\n#uBLXg1puXSO4QzoW\naction queue_event(#ErQcVVIPwKO622FK body: Action, #x6jst5KZQ5V4sFOr name: String) {\n  #TvMY9sg6cL0LP4R4 // Queues an event to be executed in its own queue. **simulator only**.\n  #G4HX55fpvnZloONU // {namespace:simulator}\n  #uUvNaoO65YqMtQTe // {action:libsonly}\n  #x6pUJ4oEgynKekYO // {shim:TD_NOOP}\n  #NpFfWiYSSrNXvvQY $c := records→Event_Bus_table→count;\n  #xv0tUVTZQbNE3PW4 if $c < 10 then {\n    #mbqwhgLr24hPftS9 $ev := records→Event_Bus_table→add_row;\n    #Guj24KBD912FcSYv $ev→name := $name;\n    #OvyZqeICJJ2sQbR4 $ev→fn := $body;\n    #J6B4LYyWUMTT4MXF data→logger→debug(\"queued \" ∥ $name);\n    #N8pNCkiRuu6GYHAN if data→event_queues→at($name)→is_invalid then {\n      #xSpLhvkqOzz2Y2Xp data→event_queues→set_at($name, \"on\");\n      #Dcn5h1NYD742two9 `async` code→event_bus_worker($name);\n      #VtF252bO2GPFA1zp data→logger→debug(\"started queue for \" ∥ $name);\n    }\n  }\n  else {\n    #SzvR3GyWF2k4aEW8 data→logger→debug(\"skipped event \" ∥ $name ∥ \", bus full\");\n  }\n  meta sync;\n}\n#HHvqKQqbQ5Uea74Z\nvar board\\u002esvg : String {\n  is\\_resource = true;\n  url = \"data:text/plain;base64, \";\n  transient = true;\n}\n#IP7MQddaWIMSii2f\nvar logger : App_Logger {\n  // {shim:}\n  transient = true;\n}\n#z4JpVqUVYFEt242M\nvar event_queues : String_Map {\n  // {shim:}\n  transient = true;\n}\n#BqrPmRC6jDYCukGD\naction first_event(#D42Ig553PhKq4i1h name: String) returns(#LvCIVEn5SGoFsUQw r: * Event_Bus) {\n  #S54lpFtjKjUHFKzi // {shim:}\n  #RZNIuj3lqoN3XBHs $j := 0;\n  #xl2YfZUIVs2bxDTW $n := records→Event_Bus_table→count;\n  #XSmtWmzT9PIeyS4f while $j < $n do {\n    #xyeEq0ZyXsc8jJee $ev := records→Event_Bus_table→row_at($j);\n    #YLmFnqeqCx4SCqaW if $ev→name→equals($name) then {\n      #BfAUYnBpcCUv9d6a `return` $ev;\n    }\n    #Q1dlEH79JUnTh4LX $j := $j + 1;\n  }\n  #wIXRC18Oi3Crpzb5 `return` records→Event_Bus_table→invalid;\n  meta private;\n  meta sync;\n}\n#shg2hAnCU7F4s74Y\naction test_play_note() {\n  #xzttSnRTTwvwFA7J // {shim:}\n  #x4AIYBST31am9VdY code→ring_tone(440);\n  #THJySqP27cAgQsaj code→pause(1000);\n  #TblGf0VF1CPJ6kMi code→ring_tone(540);\n  #pJWEI0OhM2WjvsmY code→pause(1000);\n  #aRlrDs9lN5SjbIzI code→ring_tone(0);\n  #rTSs47awcQhuxF68 code→pause(1000);\n  #izbzXfqhmfDGfk1T code→ring_tone(440);\n  meta private;\n  meta test;\n}\n#xSM8dUbL7z4962Uq\naction ring_tone(#x6LSvAzKrDJ17xu5 frequency: Number) {\n  #xPhZkakRDj6rdLie // Plays a tone through pin ``P0``.\n  #Io3qQ3JyDbVd2NVV // {help:functions/ring-tone}\n  #Tt9V48fB99uH7oPY // {namespace:music}\n  #YGzmuem9F35GsbhE // {weight:80}\n  #tXZFp05e4tJHLACS // {hints:frequency:440}\n  #N722EwENmgCNUdCs code→analog_set_pitch_pin(\"P0\");\n  #nW42CNnggdII8dc4 code→analog_pitch($frequency, 0);\n}\n#zeiPSQvHNIer2uac\naction test_warning() {\n  #SSMfX6t5fWn7h04x // {shim:}\n  #rGaI9w2nf60bKxEH code→\\_libinit;\n  #mTHHt30PoPagapRP code→forever;\n  #xJiPHVjqVziSJqle where `implicit` \\_body\\_() {\n    #UcbyY25lqLaSlf0N code→on_pin_pressed(\"P2\");\n    #mSBzWIUK9D6gMShm where `implicit` \\_body\\_() {\n      #g6O52rAigBwHjrn4 code→show_string(\"sw\", 150);\n      #cv1jrjdAaBfrfJVt code→pause(500);\n    }\n  }\n  meta private;\n  meta test;\n}\n#tHOUdkl60T7Q7Doi\naction store_pin_handler(#foZZksEULlhDtfjB name: String, #xocE8Y4sHKsI4ZmX ev: Event_Binding) {\n  #sb2HOtfOByaJVTUA // {shim:}\n  #xjhOTngE9qyaAYrE $name := $name→trim(\" \\t\")→to_lower_case;\n  #aboKExhvnNmkj2pM if $name→equals(\"p0\") then {\n    #fp2oW4xMNIzM14oj data→p0_handler := $ev;\n  }\n  else { #t9YxAAvsTwP7gRjc if $name→equals(\"p1\") then {\n    #iEpu6Gr4k7YxwZyZ data→p1_handler := $ev;\n  }\n  else { #y4mYXzm4vv0qIW7V if $name→equals(\"p2\") then {\n    #g4ZFv85AuknPhpvC data→p2_handler := $ev;\n  }\n  else { } } } \n  meta private;\n  meta sync;\n}\n#tnIOjiWz0KJW0Jw4\nvar p0_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#wHKaWOUBRGyTzDER\nvar p1_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#P545BoMFP6juxgJ8\nvar p2_handler : Event_Binding {\n  // {shim:}\n  transient = true;\n}\n#FUIrUzLVkX1B0F8a\naction clear_pin_handler(#RSL4xscVGqj094dJ name: String) {\n  #C4gtDdQMQ8juyxA6 // {shim:}\n  #kfqPf0I2193RDPpB $name := $name→trim(\" \\t\")→to_lower_case;\n  #xIRL2SG5Y3slm0gb if $name→equals(\"p0\") `and` `not` data→p0_handler→is_invalid then {\n    #Z3z522H4zGPvuo6V data→p0_handler→delete;\n    #R4urnW9bw1szDdEg data→p0_handler→\\u25c8clear;\n  }\n  else { #oGnSVGLrssTCQmWp if $name→equals(\"p1\") `and` `not` data→p1_handler→is_invalid then {\n    #hXmS2sdX47s6nMDd data→p1_handler→delete;\n    #ssTjCqfie22HWaLa data→p1_handler→\\u25c8clear;\n  }\n  else { #d2xeKSkVSETaiyf1 if $name→equals(\"p2\") `and` `not` data→p2_handler→is_invalid then {\n    #XOFHbVTvwysTjcM0 data→p2_handler→delete;\n    #TgkAqrWwi7OEyrkK data→p2_handler→\\u25c8clear;\n  }\n  else { } } } \n  meta private;\n  meta sync;\n}\n#jIsIcIMs28T2k3d1\naction show_ble_event_notification(#iWT7LqrE1qPWy3nn family: String, #m26PlHeE0cZD3K3d msg: String) {\n  #xw5ZOUW8EPnesEjC // {shim:}\n  #xBsth8WKFROreEm2 code→\\_libinit;\n  #VHYJDnaGvLgvy0IS code→pairing_warning;\n  #lHoodQfdcB4tjgLt data→ble_required := true;\n  #xGdYFwSAjkS6aGY3 $sprite := data→board→create_text(100, 40, 24, $family→concat(\"\\n\")→concat($msg));\n  #FYwPad2E8AYpRN4N $sprite→set_color(colors→white);\n  #x4iM24484ozaNTeT $sprite→fit_text;\n  #MGAALd5sucnheK34 $sprite→set_text_baseline(\"top\");\n  #xFqNWnjtZC3yheXG $sprite→set_shadow(20, colors→white, 5, 5);\n  #QtVpY5jaqI0b24vT $sprite→speed_y := math→random_range( - 50, 10);\n  #tDWv6PeAjgT9jDRp $sprite→acceleration_y := math→random_range(100, 150);\n  #PA5DC8rDbWD8HJvR $sprite→speed_x := math→random_range(20, 30);\n  #eYo2fK83t5tPyZbI $sprite→left := 10;\n  #x25Duph4hxkI6ShK $sprite→@top := 0;\n  #IeqEh6CZBPBArsjt $anim := $sprite→create_animation;\n  #G4m04OrWzinA52eZ $anim→fade_in(0.5, \"cubic\");\n  #DfAyWezJ686P96Mc $anim→sleep(0.5);\n  #I7N2JTZXffLH62QE $anim→puff_out(0.5, \"cubic\", 1.5);\n  #CS4koD4KOBTpR4d2 $anim→delete;\n  meta private;\n  meta sync;\n}\n#fJ4pOnEOqU3eUD2k\naction tell_remote_control_to(#ct4m4Kjn25Ui4zdx @event: String) {\n  #xBtYsIZTUHfWmXCq // Sends a ``remote control`` command to the parent device.\n  #pUWFx7Xrhvhdfd36 // {namespace:devices}\n  #znsH3tl5GMatL1uD // {weight:20}\n  #tYPnukasH2fTz7ef // {help:functions/tell-remote-control-to}\n  #K8Z19s2gUUoEo7hY // {shim:micro_bit::devices::remote_control}\n  #KA5hsujGsAGoxW2v // {enum:event:play=MES_REMOTE_CONTROL_EVT_PLAY,pause=MES_REMOTE_CONTROL_EVT_PAUSE,stop=MES_REMOTE_CONTROL_EVT_STOP,next track=MES_REMOTE_CONTROL_EVT_NEXTTRACK,previous track=MES_REMOTE_CONTROL_EVT_PREVTRACK,forward=MES_REMOTE_CONTROL_EVT_FORWARD,rewind=MES_REMOTE_CONTROL_EVT_REWIND,volume up=MES_REMOTE_CONTROL_EVT_VOLUMEUP,volume down=MES_REMOTE_CONTROL_EVT_VOLUMEDOWN}\n  #DWxu9anbEMzicq8T code→show_ble_event_notification(\"remote control\", $@event);\n  meta sync;\n}\n#x4q8jp37FZ2yFjtH\naction map(#xDrpNVDYcOP4xPyM value: Number, #W7lLKHDJCBcfFWfx from_low: Number, #x51HWkuNwWc6CfRu from_high: Number, #UphF5VHccbBSprcV to_low: Number, #iODWbk9drmgB2ZBV to_high: Number) returns(#XiujfWmMGuAZueU8 r: Number) {\n  #MA0gRjAwdRLlCae7 // Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc.\n  #EUpjXk4q9Jn56eQe // {hints:from high:1023}\n  #zfwaGjKO4DVlsVTO // {hints:to high:4}\n  #Tft9hSpV4N3FKVO6 // {help:functions/map}\n  #xCn7AaB8RuB8qFVD // {namespace:pins}\n  #dnQlRSL4btf2ExhK // {weight:40}\n  #uc5IndedDZWZMEwV `return` ($value - $from_low) * ($to_high - $to_low) / ($from_high - $from_low) + $to_low;\n  meta sync;\n}\n#g4a4jkTOoyzp82wv\naction pairing_warning() {\n  #XaJUgiqPPsF9LCfB // {shim:}\n  #ONnRJZP4a5MRHgD4 code→warning(\"pair your micro:bit with another device to use this function\");\n  meta private;\n  meta sync;\n}\n#qPUtJwJ0TqvMC1KG\naction magnetic_force(#LsEFJSIvP0IbVrDx dimension: String) returns(#xHQcYMA6Plgw9L7T millig: Number) {\n  #hPENJP4Mk8DofQRm // Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.\n  #s3Bnnawgp2VmtUO8 // {help:functions/magnetic-force}\n  #xCTDjLY5GkeF3sgN // {namespace:input}\n  #BgprL13WBVpXrK9A // {weight:43}\n  #b4JHQry9Zdd486VW // {enum:dimension:x=0,y=1,z=2,strength=3}\n  #xF4wa42ef8c5X8lA // {shim:micro_bit::getMagneticForce}\n  #havM3pnn4dudJ5gg `return` 0;\n  meta sync;\n}\n#w0az5rdjy9wEVnUV\naction test_magnetic_force() {\n  #ZWuupOD9Su55M1MQ // {shim:}\n  #wsYSu1daVvpWUeD3 code→\\_libinit;\n  #SKnaR2nInQodK0CN while true do {\n    #yOEhUqmj5wpjX6RM $x := code→magnetic_force(\"x\");\n    #RMNgHytGLoye4r3z $y := code→magnetic_force(\"y\");\n    #yr82TE9I7LBUzNcE $z := code→magnetic_force(\"z\");\n    #qvqzBO2R24y8D4I5 code→pause(100);\n  }\n  meta private;\n  meta test;\n}\n#CdzvoNQyYRK48OLL\naction servo_write_pin(#xAG1wlRgYVj9GlRk name: String, #gpDCTuJQs7tEJaYB value: Number) {\n  #D4Do6hAmoqG30qwT // Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n  #xRCcrcV8V4YBSRY4 // {help:functions/servo-write-pin}\n  #qzuvM5DmpVW5HnJV // {namespace:pins}\n  #xU4azu812RcdtEK0 // {weight:44}\n  #VAh8yBEk4isWMrPv // {enum:name:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2}\n  #wb072FQSt0oUGTlW // {hints:value:180,90,0}\n  #Q5yrXRxd5OEeNIp4 // {shim:micro_bit::servoWritePin}\n  #r4JhdsGC9rWeysJv $value := math→round($value);\n  #PeRqtR86b2tatBWd if $value < 0 `or` $value > 180 then {\n    #R2SdD6mbOatEAbJ0 code→warning(\"value should be between 0 and 180.\");\n  }\n  meta sync;\n}\n#xyjXPoUGVDbuKVxy\naction servo_set_pulse(#xrp9JurOyqwzOHfl pin: String, #PW24fYn4zEb79S8Z micros: Number) {\n  #zRdYAgRkve7OQ4L9 // Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds.\n  #oSEIW9PKLCCG0hGx // {shim:micro_bit::setServoPulseUs}\n  #ZNqFhWfv389w4Kvb // {namespace:pins}\n  #IapMTP9dyJt46KX1 // {help:functions/serial-set-pulse}\n  #FPbnv4WqMjILi26F // {weight:10}\n  #dwQoy54QUKSce2jg // {enum:pin:P0=uBit.io.P0,P1=uBit.io.P1,P2=uBit.io.P2}\n  #xWd9YrYWLq2zwBJL // {hints:micros:1000,1500,2000}\n  meta sync;\n}\n#xOZj6EkeH5NrwuKz\naction rest(#Dlu4AkS2aw2W3kKC ms: Number) {\n  #x2FWDwNcak3HMLNZ // Rests (plays nothing) for a specified time through pin ``P0``.\n  #aqMT5z6Ff8QcKE7I // {help:functions/rest}\n  #Emu6nWDM2AFw0d5k // {namespace:music}\n  #xvpxHK76Ioc6P2jg // {weight:79}\n  #N9j25wl9kDg2FJ0c // {hints:millis:1000}\n  #NNgmNw93MRVEDJPH code→play_tone(0, $ms);\n}\n#UiGQIc1iIkMh2d64\naction rotation(#Hc1jGwhjaC7IKMYj kind: String) returns(#nybXv9g8UNYUVvLO angle: Number) {\n  #KUv392v682F9nzAO // The pitch of the device, rotation along the ``x-axis``, in degrees.\n  #uy3Q4O9JgrSbAgzY // {help:/functions/rotation}\n  #nIWWg8S2EfseNqBN // {namespace:input}\n  #H8M557Nv0mthwxR5 // {weight:60}\n  #exd1NQ4dHpmAW4Is // {enum:kind:pitch=0,roll=1}\n  #A2S02DdTu68XAkS6 // {shim:micro_bit::getRotation}\n  #KHSKxqHusXKmJ96h $x := code→acceleration(\"y\");\n  #TDpGRYYu4wknG2QD $y := - code→acceleration(\"x\");\n  #xlIUa0mMjRnw4KZc $z := - code→acceleration(\"z\");\n  #JcE4C83Mbv504yDN $roll := math→atan2($y, $z);\n  #xrDZacJbVkUJq4vB // See https://github.com/lancaster-university/microbit-dal/blob/master/source/MicroBitAccelerometer.cpp\n  #aqZTKjLnrx3auGYS if $kind→equals(\"roll\") then {\n    #VGYsdlr44neknh2p `return` math→floor(math→rad_to_deg($roll));\n  }\n  else {\n    #C8bMftDsn2hjvQ5q $pitch := math→atan( - $x / ($y * math→sin($roll) + $z * math→cos($roll)));\n    #uqPa5krZh97byvdt `return` math→floor(math→rad_to_deg($pitch));\n  }\n}\n#ko8AY4P56uQxR3Lx\naction note(#Y4tRTwLYNsq0niNH name: String) returns(#Shffo9ayK8aw62UV frequency: Number) {\n  #x2rK4VyqeesyxDoG // This function is obsolete. Please use ``music->note frequency`` instead.\n  #j07ppvwZ0wXrU4MB // {enum:name:C=262,C#=277,D=294,Eb=311,E=330,F=349,F#=370,G=392,G#=415,A=440,Bb=466,B=494,C3=131,C#3=139,D3=147,Eb3=156,E3=165,F3=175,F#3=185,G3=196,G#3=208,A3=220,Bb3=233,B3=247,C4=262,C#4=277,D4=294,Eb4=311,E4=330,F4=349,F#4=370,G4=392,G#4=415,A4=440,Bb4=466,B4=494,C5=523,C#5=555,D5=587,Eb5=622,E5=659,F5=698,F#5=740,G5=784,G#5=831,A5=880,Bb5=932,B5=989}\n  #rBsuxzJQpYkPcNvY // {shim:TD_ID}\n  #x2imSmluVwjKgKJq // {namespace:music}\n  #R8VYGr4Htc42XPG2 // {weight:0}\n  #vZCz3CeHwrqlLi2V // {help:functions/note-frequency}\n  #C4Nk1CulhgpB34fw $f := art→notetable\\u002esjon→number($name→to_upper_case→trim(\" \\t\"));\n  #xM27VD6UJfPYh0hy if `not` $f→is_invalid then {\n    #xYh72XsEjmWTjxm6 `return` $f;\n  }\n  else {\n    #vpeBlf9Hrij34fp2 code→warning(\"Sorry, we don\\'t know about this note.\");\n    #IMF8844p2G43Esg8 `return` 0;\n  }\n  meta sync;\n}\n#oQBH3ZAjr5l30Gy1\naction test_rotation() {\n  #LypAVSbUH5nm9UNJ // {shim:}\n  #hdpW2ZEMMT5A8CGv code→\\_libinit;\n  #f3AX3jZEtzwHQqsE code→forever;\n  #W2leacY4H1Hw8aVT where `implicit` \\_body\\_() {\n    #xGDUqeP40Y1Av5kr $angle := code→rotation(\"roll\");\n    #tblBtCn20WaO4kss code→show_number($angle, 150);\n  }\n  meta private;\n  meta test;\n}\n#xOyhkiuukKoXsSf3\naction set_pixel_brightness(#MXRjgwVpEVBRFqeR @this: * Image, #lV45czXkvrdYIaFe x: Number, #VziHcAryoNtz2N0K y: Number, #FGY5E61J6hOffs9e value: Number) {\n  #xjJS62ADi09BoR8h // Set a pixel state at position ``(x,y)``\n  #gY4qfnINky41OVAC // {help:functions/set-pixel}\n  #b2ukvr2YqvGXd6We // {namespace:image}\n  #nWnpK22Wo0dDCaec // {shim:micro_bit::setImagePixel}\n  #RuFHoZWWNJ7nwFbf $x := math→floor($x);\n  #lULDn4tozSW2Swy5 $y := math→floor($y);\n  #cAZh6VFQFZ4HCzP1 if $x < 0 `or` $x ≥ $@this→leds→row_count then {\n    #xAfMmCVOUHZpho4h code→warning(\"x should be between 0 and \" →concat(($@this→leds→row_count - 1)→to_string));\n    #x2K2FAWG4d6E2s5I `return` ;\n  }\n  else { #mrBUjDL4OsPrtTvk if $y < 0 `or` $y ≥ $@this→leds→column_count then {\n    #HbOQG7UJVWq2B1kb code→warning(\"y should be between 0 and \" →concat(($@this→leds→column_count - 1)→to_string));\n    #oIipripGXsEtvKys `return` ;\n  }\n  else { } } \n  #xLygH81fjmSis6kt $@this→leds→set_item($x, $y, $value);\n  meta sync;\n}\n#ZHNC7Mxlv12jRmo6\naction pixel_brightness(#uAEF3o8d5wYosjdT @this: * Image, #S7i6zQSOqBnuNhu5 x: Number, #q9VHqzfRTnI9XDDn y: Number) returns(#FECK2kiFRCeWmF5l state: Number) {\n  #ZAYbbyQljcBromJm // Get the pixel state at position ``(x,y)``\n  #s1qXnDy7759gbelE // {help:functions/pixel}\n  #xg27bIuNvP0nRcPO // {namespace:image}\n  #DWYzPeCDN4GNxa2l // {hints:x:0,1,2,3,4}\n  #cRWiaeT8TKShGdR7 // {hints:y:0,1,2,3,4}\n  #BjJ8orBlo6iJ0NrJ // {shim:micro_bit::getImagePixel}\n  #r3TTpBg0VX2b6DHN $x := math→round($x);\n  #dfZYFPmXS7GKLohf $y := math→round($y);\n  #ti4xQsZ8cO2NCsd4 if $x < 0 `or` $x ≥ $@this→leds→row_count then {\n    #fnFG55i42XiJcdrv code→warning(\"x should be between 0 and \" →concat(($@this→leds→row_count - 1)→to_string));\n    #g27fXMxF9GIeePsv `return` 0;\n  }\n  else { #JUUkH61WF1tcL28p if $y < 0 `or` $y ≥ $@this→leds→column_count then {\n    #HMKmCc6B0h2Q4cz2 code→warning(\"y should be between 0 and \" →concat(($@this→leds→column_count - 1)→to_string));\n    #R11nLsD2zpYlRGFb `return` 0;\n  }\n  else { } } \n  #ma6H9dmbM5CRZvzn `return` $@this→leds→item($x, $y);\n  meta sync;\n}\n#add7T3y7MNatnGny\naction set_display_mode(#WTg2PtS86SYIQDt0 mode: String) {\n  #E35ZI91OTJ2kyT6g // Sets the display mode between black and white and greyscale for rendering LEDs.\n  #b56Xmqi0Ckx0Hz4B // {enum:mode:back and white=0,greyscale=1}\n  #jhKTS5UHC8Rltnka // {shim:micro_bit::setDisplayMode}\n  #SVF4C6g4vgbWIOis // {namespace:led}\n  #jycAgxiKjEkoBwJs // {weight:1}\n  #zCgiDN8quFSVnDaT // {help:/functions/set-display-mode}\n  #awhSb2rKqSuvmbXC data→\\_greyscale := $mode→equals(\"greyscale\");\n  meta sync;\n}\n#hjjZvF3ZOHXgRyFu\nvar \\_greyscale : Boolean {\n  transient = true;\n}\n#g0ss4j1eLk5ynyUt\naction play_note(#bHaFCNEEJaK991Yo frequency: Number, #TcObkTO93uKAovfA ms: Number) {\n  #xgZagGizmoldZ7s1 // This function is obsolete. Please use ``music->play tone`` instead.\n  #xLfJimnAWhsIU1wq // {help:functions/play-tone}\n  #R0wMYnIMaWgjqZan // {namespace:music}\n  #VfhIF1cNxbzbYO2J // {weight:0}\n  #fc2nyHYoM4jaKZJl // {hints:frequency:440}\n  #Neq372aA2RIBI0lX // {hints:ms:1000}\n  #xoBbd94UdCwRCF99 code→play_tone($frequency, $ms);\n}\n#ZCnPMPq5QSyyJy6i\naction light_level() returns(#GXD5twYeWvP3BPyt light: Number) {\n  #WV0iSATx7aji44xQ // Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright. In the simulator, the ``acceleration y`` is used to emulate this value.\n  #xikatVrpE6xh0BTn // {help:functions/light-level}\n  #rjeg4imR7dmRWMEJ // {namespace:input}\n  #xi0fmPgjARvr6Z9r // {weight:55}\n  #vYVhQXlLmZu5Mva8 // {shim:micro_bit::lightLevel}\n  #akAqI31dd4qWYn7N `return` math→clamp(0, 255, math→abs(code→acceleration(\"y\") / 2)) - 255;\n  meta sync;\n}\n#v82mkjS2I5pZXQeU\naction is_ble_required() returns(#zvaiE3bc26qZJe0m r: Boolean) {\n  #ndD8Jzfci1As2Qku // Returns a value indicating if any BLE function has been used so far. **simulator only**\n  #Zg2S3ZOPKDzRoqjl // {namespace:simulator}\n  #blWfIptmUrfDF24o // {action:libsonly}\n  #x429y8Nylcc5yo1k `return` data→ble_required;\n  meta sync;\n}\n#Si7IjGa9nv451k3d\nvar ble_required : Boolean {\n  transient = true;\n}\n#qhRPOv27q7FwkCnd\naction signal_strength() returns(#pjNiV2VnbNOLOrtS strength: Number) {\n  #xT2ELzQbRIFqjn4W // Returns the last signal strength reported by the paired device.\n  #BQe7g7kLBH1JXry2 // {help:functions/signal-strength}\n  #LvClLSskMFcoNgOo // {namespace:devices}\n  #nqacunRHChfkRx2G // {weight:40}\n  #xHPfdExQ4TqV8mdt // {shim:micro_bit::signalStrength}\n  #kSpK0NglrvAg93Vz data→ble_required := true;\n  #z4nSUBqBKe6WaUJY `return` 0;\n  meta sync;\n}\n#u9XE1xZdVNsJL8sJ\naction on_signal_strength_changed(#cuYkQZekjFUGjAi4 body: Action) {\n  #RUTzQqkWAkkLT07I // Registers code to run when the device notifies about a change of signal strength.\n  #iYAREqvtJxpxvOH0 // {shim:micro_bit::onSignalStrengthChanged}\n  #UceJa459XHIqYGpt // {namespace:devices}\n  #xmRckxNtld14XWCK // {help:functions/on-signal-strength-changed}\n  #Csvsk6MK3WAipXGZ code→notify_event_registration(\"on string strength changed\");\n  #t84fDrl4Mq6am32n code→pairing_warning;\n  meta sync;\n}\n#od0z0OKRNOBHKno4\nvar namespacedocs\\u002ejson : Json_Object {\n  // {shim:}\n  is\\_resource = true;\n  url = \"data:text/plain;base64,ewogICAgImJhc2ljIjogIkRpc3BsYXkgc3RyaW5nLCBudW1iZXJzLCBpbWFnZXMgb24gdGhlIHNjcmVlbiBhbmQgYmFzaWMgbG9vcHMuIiwKICAgICJpbnB1dCI6ICJBY2Nlc3MgdG8gc2Vuc29yIGFuZCBldmVudHMuIiwKICAgICJsZWQiOiAiVHVybiBvbiBhbmQgb2ZmIExFRHMgb24gdGhlIHNjcmVlbi4iLAogICAgImNvbnRyb2wiOiAiUmVwZWF0IGNvZGUgd2l0aCB2YXJpb3VzIGxvb3BzLiIsCiAgICAibG9naWMiOiAiSWYgc3RhdGVtZW50IGFuZCBib29sZWFuIG9wZXJhdG9ycy4iLAogICAgIm11c2ljIjogIlBsYXkgdG9uZXMgb24gdGhlIHBpbnMuIiwKICAgICJwaW5zIjogIkludGVyYWN0IHdpdGggZWxlY3Rvcm5pYyBzZW5zb3JzIGFuZCBtb3RvcnMgdGhyb3VnIHRoZSBwaW5zLiIsCiAgICAicmFkaW8iOiAiQnJvYWRjYXN0ZWQgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIG1pY3JvOmJpdHMuIiwKICAgICJnYW1lIjogIlNwcml0ZXMgYW5kIGdhbWUgYW5pbWF0aW9ucyIsCiAgICAiZGV2aWNlcyI6ICJDb250cm9sIHBhaXJlZCBkZXZpY2VzIHN1Y2ggYXMgcGhvbmVzIG9yIHRhYmxldHMgb3ZlciBCbHVldG9vdGguIgp9\";\n  transient = true;\n}\n#xYboMgkbvJoQX7sC\naction test_simulator() {\n  #u48cZt3DgE4wCB4Y // {shim:}\n  #Rl7A4R4pnG5P27KE code→\\_libinit;\n  #zfAUVfu4BJ1DcIiz data→board→set_debug_mode(true);\n  #RzutKKtsqnxrwC65 code→forever;\n  #vRZvHqSS2hxQZ66I where `implicit` \\_body\\_() {\n    #qcsH21SkO2PAgOTL code→acceleration(\"x\");\n    #xhGcRD9sid5iFVrZ code→acceleration(\"y\");\n    #o4AExlgMkXXOP8GA code→acceleration(\"z\");\n    #LRctI025VatmeOCr code→acceleration(\"strength\");\n    #KV0405Bp8kY5Q0WX code→compass_heading;\n    #zmws2q49NZq7htip code→temperature;\n    #TwCxJBJlwOBGSdMS code→light_level;\n    #jCWPzJVSnmUVX3HY code→magnetic_force(\"x\");\n  }\n  meta private;\n  meta test;\n}\n#GmOcDyC1h7Te2171\nvar theme_button : Sprite {\n  // {shim:}\n  transient = true;\n}\n#ptr6LKVPwprLEIih\naction on_gamepad_button(#D3QUCj7BfHCBhap4 name: String, #xI9Zgf22rh0WuyDZ body: Action) {\n  #ec8bEwDIIWvoXaAQ // Register code to run when the micro:bit receives a command from the paired gamepad.\n  #DNz3nPXpQNLBRxS2 // {help:functions/on-gamepad-button}\n  #E9BV9SOyuTlksOp9 // {namespace:devices}\n  #T48grEOAY1B4H1ph // {weight:40}\n  #WZzx5JA2s7ssD9tE // {enum:name:A down=MES_DPAD_BUTTON_A_DOWN,A up=MES_DPAD_BUTTON_A_UP,B down=MES_DPAD_BUTTON_B_DOWN,B up=MES_DPAD_BUTTON_B_UP,C down=MES_DPAD_BUTTON_C_DOWN,C up=MES_DPAD_BUTTON_C_UP,D down=MES_DPAD_BUTTON_D_DOWN,D up=MES_DPAD_BUTTON_D_UP,1 up=MES_DPAD_BUTTON_1_DOWN,1 down=MES_DPAD_BUTTON_1_UP,2 down=MES_DPAD_BUTTON_2_DOWN,2 up=MES_DPAD_BUTTON_2_UP,3 down=MES_DPAD_BUTTON_3_DOWN,3 up=MES_DPAD_BUTTON_3_UP,4 down=MES_DPAD_BUTTON_4_DOWN,4 up=MES_DPAD_BUTTON_4_UP}\n  #yUSp4coqF0Z782rL // {shim:micro_bit::onGamepadButton}\n  #huR2efoZWTsLGE6k $evid := \"on gamepad button \" ∥ $name;\n  #NIoxxw4REvwe9Fac code→notify_event_registration($evid);\n  #FVzCwPmbtYNq7UzA code→pairing_warning;\n  meta private;\n  meta sync;\n}\n#dYquo5vKBlFTf010\nvar boardcolors\\u002ejson : Json_Object {\n  // {shim:}\n  is\\_resource = true;\n  url = \"data:text/plain;base64,WwoiIzNBRENGRSIsCiIjRkZENDNBIiwKIiMzQUZGQjMiLAoiI0ZGM0E1NCIKXQ==\";\n  transient = true;\n}\n",
  "rwbwnc": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit game\";\nmeta rootId \"Ba3NfsJb7QfMsuiMUrQ4HLjN\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta splitScreen \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// A #microbit game library.\n#FICjbNZc86cUSakA meta import micro\\u003abit {\n  pub \"thflqk\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `async` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` set_pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Number)\n    action `sync` pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Number)\n    action `sync` set_display_mode(mode: String)\n  }\n}\n#GSTBzUmgzKqh572M\nvar \\_score : Number {\n  transient = true;\n}\n#dBVZeGqsEXhS7NAa\nvar \\_life : Number {\n  transient = true;\n}\n#BAJJhCO4wcEnkvZS\naction score() returns(#ZdGkas4VGdp7KpAk score: Number) {\n  #JKrysLLsVXnU2lZd // Gets the current score\n  #bagjbfBxWixI920m // {namespace:game}\n  #b4OrVIn3auNNVlZc // {weight:10}\n  #gQUXqxZiVTUJH10u // {help:td/game-library}\n  #fLeWes41L5KcTL21 code→init;\n  #dZpwDtBRDC0AuC6K `return` data→\\_score;\n  meta sync;\n}\n#lJ7P9FLSUXiK1qfR\naction set_score(#Oj3vV76xynFUnJ6u value: Number) {\n  #VyQVy7NKpR21Y6op // Sets the current score value\n  #xAB4O7rLX45TrPs0 // {namespace:game}\n  #CpMhV2T2818lBBP4 // {weight:10}\n  #Hb1inJ8c2GnMbVTi // {help:td/game-library}\n  #QG6TE4UiTqrXI4uR code→init;\n  #sjsRgFn54B4GS3gW data→\\_score := math→max(0, $value);\n  meta sync;\n}\n#ct21RxcGord4ZUHK\naction life() returns(#xwvNDXyE5xUJo2w4 life: Number) {\n  #IyJ0579xbWjJurUv // Gets the current life\n  #xaYElyBY73cVSzfc // {namespace:game}\n  #qOfD7vEMcAwTXJCF // {weight:10}\n  #WThSysHUIV4s2PBM // {help:td/game-library}\n  #YWqh1YEfgdNxl82n code→init;\n  #S2tbXAXUHi1iQN22 `return` data→\\_life;\n  meta sync;\n}\n#yQOnar7sIXqp6pis\naction set_life(#A4tOr2LyOrUR2M3f value: Number) {\n  #bQC50q5J4Nv6DxLr // Sets the current life value\n  #xZpUVw9ridjn2EO4 // {hints:value:1,3}\n  #xwe4HAi2BtgQsN0O // {namespace:game}\n  #yMug18SrGqhAT3Bn // {weight:10}\n  #x9P3dC6Iwu2mm5gt // {help:td/game-library}\n  #ynbh4KZHrAcYV2DF code→init;\n  #vQP7JOwXyUTcrKDe data→\\_life := math→max(0, $value);\n  #az2zGYGvRNAVlCiN if data→\\_life ≤ 0 then {\n    #xXtO1gUMmxwZYolc code→game_over;\n  }\n}\n#sCf9vmLsvG8WaSm3\naction init() {\n  #w0iiw6oWxgjcSpvJ if `not` data→\\_init then {\n    #OEkjPQmmhwrJW0Oh data→\\_score := 0;\n    #xiVPvMphLY51NRS8 data→\\_life := 3;\n    #bwqxqjuqihyb94gx data→\\_level := 1;\n    #Lf6evmVl2EvvT5p2 data→\\_init := true;\n  }\n  meta private;\n  meta sync;\n}\n#phR5OQxcOdM4coX9\naction add_score(#upNGyw2apMaUcvQC points: Number) {\n  #tL87Dx4B01r4P1Jc // Adds points to the current score\n  #qxWdMPrkQWGmHqQp // {hints:points:1}\n  #mwAslp0sFgo3kxVy // {namespace:game}\n  #CjU5W9YaAbTDuPXe // {weight:10}\n  #zuiUmYhuZxbAIleZ // {help:td/game-library}\n  #x7PPOGU8dlENtc4w code→init;\n  #kQUTLhhhFULjGZ4O code→set_score(data→\\_score + $points);\n  #vZtX1RcjDdWohAtr control[lib micro\\u003abit] →in_background;\n  #xTmfOuxYEEZU8RZo where `implicit` \\_body\\_() {\n    #EmMB4oUWOSOSrs2Q led[lib micro\\u003abit] →stop_animation;\n    #TpoevJbyuENBzDRz basic[lib micro\\u003abit] →show_animation(\"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0\\n0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0\\n0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\n0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0\\n0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0\", 20);\n  }\n  meta sync;\n}\n#ROPTygCiIFymgxcF\naction add_life(#Idxc4r0G1Vbjq8Ax lives: Number) {\n  #NDQv2bhltDPIfVSi // Adds life points to the current life\n  #gZW4aOWlH3lkAdJ2 // {hints:lives:1}\n  #piZkQFwDxd24sMMZ // {namespace:game}\n  #uTWomM4YiSXvjNFc // {weight:10}\n  #gMxH43bPNY6lkYOk // {help:td/game-library}\n  #XZF4u0yOUgyUQRl2 code→init;\n  #UCNjMauTD6c4fyeX code→set_life(data→\\_life + $lives);\n}\n#eHS28n1RPy4vJt9h\naction start_countdown(#k15bqhzwFzH4Y3yU ms: Number) {\n  #BCtRANWiE67zR26q // Starts a game countdown timer\n  #AZiqP23JFfbITIOx // {hints:ms:10000,30000}\n  #C2ARUWzUgFTvOtlU // {namespace:game}\n  #xOEHlgzZy2hhHBBs // {weight:11}\n  #XhFLKLF40CAqHQDO // {help:td/game-library}\n  #sx4X6t87BpsDX2Rt code→init;\n  #aKdshGPo1iqAXgyG if code→check_start then {\n    #YA72wUp4JSnzvoSL basic[lib micro\\u003abit] →show_animation(\"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\", 400);\n    #A7XSXMDEmg5AdGAY data→\\_countdown_pause := math→max(500, $ms);\n    #FnAKYESYclPZ0cIR data→\\_start_time := - 1;\n    #v7EAWZzZFfFzIfTV data→\\_end_time := input[lib micro\\u003abit] →running_time + data→\\_countdown_pause;\n    #j1x6jSbo8PWqhcAB control[lib micro\\u003abit] →in_background;\n    #PfU9olXIFgS5aAwm where `implicit` \\_body\\_() {\n      #lvm9ZUpGlRoNoJSm basic[lib micro\\u003abit] →pause(data→\\_countdown_pause);\n      #Asl8YY54VpNM20l7 code→game_over;\n    }\n  }\n}\n#Zo54Nk7IINBtKKmo\nvar \\_start_time : Number {\n  transient = true;\n}\n#xlqvNMlD5yvfwaqU\nvar \\_end_time : Number {\n  transient = true;\n}\n#qsSRH3fC1L812M5G\naction game_over() {\n  #zL9SS6wzl1a4SmPu // Displays a game over animation.\n  #xEMronZSgyqejFrR // {namespace:game}\n  #iSDqv1rmu8dvkXDc // {weight:10}\n  #zVP4yHOI14OXGY5q // {help:td/game-library}\n  #Kx2cMn3rxMJadRgc if `not` data→\\_is_game_over then {\n    #xNEpLy8Dw9bOe19L data→\\_is_game_over := true;\n    #PHqtjWicyXXr3VHk code→unplug_events;\n    #Guoq4pVnwlRVXTiW led[lib micro\\u003abit] →stop_animation;\n    #XkFnkf3J2op1RUmQ led[lib micro\\u003abit] →set_brightness(255);\n    #qnqiNm6WirsquFMr led[lib micro\\u003abit] →set_display_mode(\"back and white\");\n    #DQ2Ufby7NHShBjEc while true do {\n      #oeKwkJj5snJoUEnm for 0 ≤ i < 8 do {\n        #qN0fKrhol7iI1zpn basic[lib micro\\u003abit] →clear_screen;\n        #puFgaW4Ecm7oLMUb basic[lib micro\\u003abit] →pause(100);\n        #xxi2pN9JNMVicahP basic[lib micro\\u003abit] →show_leds(\"1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\", 300);\n      }\n      #fYNBElDJt4VLUcV3 basic[lib micro\\u003abit] →show_animation(\"1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0\\n1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\n1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\n1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\n1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0\", 100);\n      #XKk2kW9RyjOsqmB1 for 0 ≤ j < 3 do {\n        #bwOlN7eGtv4fFmR6 basic[lib micro\\u003abit] →show_string(\" GAMEOVER \", 100);\n        #PZAWQZkkKMCO3f8F code→show_score;\n      }\n    }\n  }\n  else {\n    #n67cH9pIKxKFcdQ6 // already in game over mode in another fiber\n    #YJW4X4vqAVwdgZoD while true do {\n      #wYMn2vN7Y4h0bBFe basic[lib micro\\u003abit] →pause(10000);\n    }\n  }\n}\n#PdPR9cpJ2YKm2EYO\naction current_time() returns(#fsGwyKm0OLECbz4I ms: Number) {\n  #t5loUEw8UND4YmVQ // Gets the remaining time (since `start countdown`) or current time (since the device started or `start stopwatch`) in milliseconds.\n  #HeGc1Wr68Owk4cqu // {namespace:game}\n  #ioUuv9a7O60p0za8 // {weight:10}\n  #xgITZAJSJ1TVmJ9V // {help:td/game-library}\n  #aBET7rQnCPNQDPF4 code→init;\n  #q3rk2BW2LPvS91gF if data→\\_end_time > 0 then {\n    #eRrmAEc5C7Xt9JLP `return` math→max(0, data→\\_end_time - @\\u267b→micro\\u003abit→running_time);\n  }\n  else {\n    #dVJIN2dJFI6DfRF7 `return` input[lib micro\\u003abit] →running_time - data→\\_start_time;\n  }\n}\n#zklIHAKeSYRvJ7r5\naction remove_life(#wSxIkWFhDMvo9sOL life: Number) {\n  #zrsjRb9maA6M2BdC // Removes some life\n  #yWb3H15TlF1klDBI // {hints:life:1}\n  #x8aXtKa8b6T5VVww // {namespace:game}\n  #V6pwIi2V2K411YlU // {weight:10}\n  #j6t4SWxNJyZalsQ6 // {help:td/game-library}\n  #DokzagqHlchXTHmB code→set_life(data→\\_life - $life);\n  #xRYStStywBAPdax9 control[lib micro\\u003abit] →in_background;\n  #DtJ9rlrZWMIkx4xF where `implicit` \\_body\\_() {\n    #UvYuL7St3J40m5LQ led[lib micro\\u003abit] →stop_animation;\n    #XqehW2sAtG2xOYXE basic[lib micro\\u003abit] →show_animation(\"1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0\\n0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0\\n0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0\\n0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0\\n1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0\", 40);\n  }\n}\n#xsC75ma2TcxelNNG\nvar \\_is_game_over : Boolean {\n  transient = true;\n}\n#WoKtgesh2cZNfH2O\naction example() {\n  #QZZ2q1Vwz31xKT2A // This library makes it easy to create games with the  **BBC micro:bit**. [read more...](/td/game-library)\n  #xR3atML1XGN9lD1x // {topic:td/game}\n  #PYH5iWxI1IpjTa14 // {shim:}\n  meta private;\n}\n#vskFru7NgUXuZQaD\nvar \\_init : Boolean {\n  transient = true;\n}\n#i94uG229AdaGNx9C\nvar \\_countdown_pause : Number {\n  transient = true;\n}\n#gvgfanokCXXEpdXq\nvar \\_level : Number {\n  transient = true;\n}\n#xXS4d4K3tOHj4Jz7\naction level_up() {\n  #mlrJjFz25TdU2Qh2 // Increments the level and display a message.\n  #er18r7cjQCAzM1D2 // {namespace:game}\n  #ypIUOtUf7Dz1Ieng // {weight:10}\n  #wA1EjK6AQ9iPKEOh // {help:td/game-library}\n  #yDIMepChMEyFFv40 code→init;\n  #D4nHKjh53QC7yfsA data→\\_level := data→\\_level + 1;\n  #X6J8Jattms0PGdqt basic[lib micro\\u003abit] →show_string(\"LEVEL:\", 150);\n  #bmP28eYirxu2XvYe basic[lib micro\\u003abit] →show_number(data→\\_level, 150);\n}\n#XWIbW8F1TScZL6cH\naction level() returns(#BC2jHGgo22ON4Kdh lv: Number) {\n  #xgA22Q228ASNJkyl // Gets the current level\n  #FFqz0ecwtCtHQz1L // {namespace:game}\n  #M7Srh1TOB67gbJyC // {weight:10}\n  #v4vjzUaWjGBt98Tk // {help:td/game-library}\n  #x90u5Et4JvN5DwBj code→init;\n  #YNymvto12wVZjj7j `return` data→\\_level;\n}\n#xHLzsLHCUz2swJ7b\naction test_countdown() {\n  #HAVtIrGlPwag4rAe // {shim:}\n  #kCedIlBZ3zmvWtbH code→start_countdown(10000);\n  #dQ94gDwnV0JrWJ2x code→start_countdown(10000);\n  #L8tu7FS9v4O757r0 code→start_stopwatch;\n  meta private;\n  meta test;\n}\n#xtK4SuOp3S4NKf12\naction start_stopwatch() {\n  #UZaRv27LnL4oW8iD // Starts a stopwatch timer. `current time` will return the elapsed time.\n  #Ju4jzjvapc9RBIj2 // {namespace:game}\n  #icJgELixmfxl4ba3 // {weight:10}\n  #hva2wqo5aSnLcGoN // {help:td/game-library}\n  #FKbJxgbol0zH7hgT code→init;\n  #YHJWhIU4xlM5la8E data→\\_start_time := input[lib micro\\u003abit] →running_time;\n  #BpI9FVu4sEUXkm6r data→\\_end_time := - 1;\n}\n#xbKGS6NntocOrXMR\naction check_start() returns(#XlAMLwecZHyukwDA ok: Boolean) {\n  #cR2pNxoFmQT2z3Ar // returns false if game can't start\n  #fzxbNRsp2d4270rr if data→\\_countdown_pause > 0 `or` data→\\_start_time > 0 then {\n    #b76aTH8FMfHSvLzv `return` false;\n  }\n  else {\n    #ncC4pDPrtHFuFAZB `return` true;\n  }\n  meta private;\n}\n#ft2hIFocJsyLl7tl\naction test_countdown_current_time() {\n  #xUlb4fRTV5vy3fkr // {shim:}\n  #xHQD2251jM3XG2fp code→start_countdown(10000);\n  #xcxMHQHk2BykUG5q basic[lib micro\\u003abit] →pause(2000);\n  #znGGGrzotJyKqdWr basic[lib micro\\u003abit] →show_number(code→current_time, 150);\n  meta private;\n  meta test;\n}\n#YlRO2i8CApxNgUmT\naction test_current_time() {\n  #rSxmAE8htbXr8tPx // {shim:}\n  #nccSpY6Jx5nZuWLN code→start_stopwatch;\n  #JfguRXzmxjTW32v8 basic[lib micro\\u003abit] →pause(2000);\n  #x7knzGldoCwiQPaI basic[lib micro\\u003abit] →show_number(code→current_time, 150);\n  meta private;\n  meta test;\n}\n#pdSjcArPD4cvm6e6\naction test_gameover() {\n  #V3yLiuoWmbtsJ9Vx // {shim:}\n  #IaOdIeGxJPutmQwh code→set_score(100);\n  #JdKoXbfP2JAMokMf code→game_over;\n  meta private;\n  meta test;\n}\n#HFDx8tOEHyqGnvB4\naction unplug_events() {\n  #DqyMp24hlCKZ1iIU input[lib micro\\u003abit] →on_button_pressed(\"A\");\n  #xWJ2aInU0Y3DkXlw where `implicit` \\_body\\_() {\n    #Ty4DROMeSR45jk3H skip;\n  }\n  #x4WFXrH3DNTNwBkP input[lib micro\\u003abit] →on_button_pressed(\"B\");\n  #PfVz8A4RssRinAOM where `implicit` \\_body\\_() {\n    #oF6jBmYja3JxvnuC skip;\n  }\n  #E22Y5LHsxIs0Wnu5 input[lib micro\\u003abit] →on_button_pressed(\"A+B\");\n  #kV4iKdgWcqEmvTpi where `implicit` \\_body\\_() {\n    #wV0IUBnCRTmnKjvY control[lib micro\\u003abit] →reset;\n  }\n  meta private;\n  meta sync;\n}\n#sqTPeilZldQhVOCC\nvar \\_game_id : Number {\n  transient = true;\n}\n#pd6yzHOHLSOW4g1S\naction is_running() returns(#cw0Wu3beI6dUUnNH running: Boolean) {\n  #JT3Ts6q2D3ITZ3su // Gets a value indicating if the game is still running. Returns `false` if game over.\n  #hn1FvwLqvB0pL70n // {namespace:game}\n  #WVIg0Y2jJTD8Dj20 // {weight:10}\n  #HCRfiRSgAkdGdCW0 // {help:td/game-library}\n  #D70pd8XtiL4KQjAN `return` `not` data→\\_is_game_over;\n  meta sync;\n}\n#HyuErwY6aQym2GfB\naction show_score() {\n  #kg8B9WUteEZeeAjj // Displays the score on the screen.\n  #H8sRcoDkF2w8hCPt // {namespace:game}\n  #GhugUWVAz1SpufdN // {help:td/game-library}\n  #b4aCyOUHZ2tbnTQS // {weight:60}\n  #ZHOR0vX2feQxQuYO code→init;\n  #vgr9oxsK2Bw4HRY3 basic[lib micro\\u003abit] →show_string(\" SCORE \", 100);\n  #kBGIK1yQHgc1Qva4 basic[lib micro\\u003abit] →show_number(data→\\_score, 150);\n  #oKd4MsDD4AJGSbZN basic[lib micro\\u003abit] →show_string(\" \", 150);\n}\n#jeyL4tq7ItXRn0Wc\naction test_score() {\n  #hwRjsGVuU3oaoev1 // {shim:}\n  #lWM0K14zhXLm1Jwa code→add_score(1);\n  #xbIjXaeYnn91h0Gd code→add_score(1);\n  #ItJdwS5hlCAd7FSn code→add_score(1);\n  #ZUqE4xmrbyn4GjFZ code→show_score;\n  meta private;\n  meta test;\n}\n#dwHWlvnQ2iMQzo7I\naction is_game_over() returns(#x32ZhBoC55aPFdsW over: Boolean) {\n  #j2k4LBl4jXqOt9sp // Indicates if the game is display the game over sequence.\n  #JerSvQ3nm3EA1FsL // {namespace:game}\n  #x4RgK65eS6RtgjPc // {help:/functions/game-library}\n  #IsnY41mRsPoBXboe `return` data→\\_is_game_over;\n  meta sync;\n}\n",
  "xbpfet": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit sprites\";\nmeta rootId \"IrNJbTSBupAi6m6b0w7EHBVL\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta splitScreen \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n#YTCiBQqlEqAR6hEl\naction example() {\n  #OKmzT6pzf1C5mDmh // This library simple sprites for the  **BBC micro:bit** screen. [read more...](/td/sprites-library)\n  #xPbBQ4T5AZXIhcZ6 // {shim:}\n  meta private;\n}\n#BVGhpbmca\ntable Led_Sprite {\n  type = \"Object\";\n  persistent = false;\n  fields {\n    #iTImxC9YFcZqpWTT \\_x : Number\n    #sdXbuHxH9qCkC7qR \\_y : Number\n    #eTU9ge4joHCJTqwK \\_dir : Number\n    #CLRbdVAs4KoUqa4G \\_brightness : Number\n    #j4ZDeRimsQwonSek \\_blink : Number\n  }\n}\n#xbp2Y1F2yQjR1gEi\naction create_sprite(#KBVVgM8SyXDGuONt x: Number, #x1FLGt14bvabwz2I y: Number) returns(#ceYntRMw503qHIJo r: * Led_Sprite) {\n  #xMO3FUwzkNbdsVIL // Creates a new LED sprite pointing to the right.\n  #fZmCBJA8WJytdrrV // {hints:x:2}\n  #s8v5SPF4SgfsrprQ // {hints:y:2}\n  #ZLBODN0J98gjeOPM // {namespace:game}\n  #VJD4bKmxGOmnA4ZM // {weight:60}\n  #rfMC44aRImQUneP7 // {action:ignoreReturn}\n  #f2n8VK6qGoYNLbc9 code→init;\n  #cV1EFfm7xnOZnGv1 $p := records→Led_Sprite→create;\n  #gwBghdrsqah3tSYk $p→\\_x := math→clamp(0, 4, $x);\n  #I7ebVJnUT5Tah5Co $p→\\_y := math→clamp(0, 4, $y);\n  #N19lcNu2xirQysAJ $p→\\_dir := 90;\n  #xf8sKvf6jZohgpgS $p→\\_brightness := 255;\n  #FPHV1E3o5428zsUn data→sprites→add($p);\n  #ynsPu0nLmLOO9sHQ code→plot;\n  #oTUYBv5veHYOjR2U `return` $p;\n}\n#n03pjtVWhETO1iAd\nvar img : ♻ micro\\u003abit → Image {\n  transient = true;\n}\n#YXLJL2PruAqFVTws\naction init() {\n  #ORPuncsI5B4zWKsC if data→img→is_invalid then {\n    #xW1383xeJNO22s2z data→img := image[lib micro\\u003abit] →create_image(\"0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\");\n    #RhS9YdgJ5X2DrEy1 data→sprites := create→Collection_of→\\u2339Led_Sprite;\n    #SaBsOzam1nmkE90K led[lib micro\\u003abit] →set_display_mode(\"greyscale\");\n    #mLM9Xvcp2MUURJ2o basic[lib micro\\u003abit] →forever;\n    #f8294LK1k6meNU80 where `implicit` \\_body\\_() {\n      #WkUDkEISz4deLXyq basic[lib micro\\u003abit] →pause(30);\n      #C2A2hbqvfB4G49S2 code→plot;\n      #MIM8NVr4S1JzyKS4 if game[lib micro\\u003abit_game] →is_game_over then {\n        #vdr7cTGcwj9nFbuE basic[lib micro\\u003abit] →pause(600);\n      }\n    }\n  }\n  meta private;\n  meta sync;\n}\n#xIV6UQzyvfSv2Km0\nvar sprites : Collection[ * Led_Sprite] {\n  transient = true;\n}\n#mFH9LyIh4pa2Goe8\naction plot() {\n  #zMVFcsyhZHmabHaV // Plots the current sprites on the screen\n  #Ly2t4y22wIqGBVJ4 if game[lib micro\\u003abit_game] →is_game_over then {\n    #U44b0BkVL4cQWrH2 `return` ;\n  }\n  #OZV0I9V2oA2dv7zh $now := input[lib micro\\u003abit] →running_time;\n  #Q5smeV7QsSwvEXau data→img→clear;\n  #sUh5ANmEJC9YzA6C for 0 ≤ i < data→sprites→count do {\n    #cngEXkIoZe8PB6iQ $ps := data→sprites→at($i);\n    #xvfBtyPgxfnWShil if $ps→\\_brightness > 0 then {\n      #zpiTrj2PTmpmArwG $r := 0;\n      #Wo7d24Z1wBHCNlEM if $ps→\\_blink > 0 then {\n        #eOh4Cz98WEQhStbQ $r := math→mod($now / $ps→\\_blink, 2);\n      }\n      #xYX47qOm5Ljyl8vf if $r = 0 then {\n        #vsryWRdItzY5w8Gf data→img→set_pixel_brightness($ps→\\_x, $ps→\\_y, data→img→pixel_brightness($ps→\\_x, $ps→\\_y) + $ps→\\_brightness);\n      }\n    }\n  }\n  #xMy88FrS4AY8GpKp data→img→plot_image(0);\n  meta private;\n  meta sync;\n}\n#Ii223cRjT2ZfXMMv\naction move(#qvj22Zhu8Eo5aUG6 @this: * Led_Sprite, #f3DRVSobQuPZvt4O leds: Number) {\n  #xQHiOcGzhHb0Tx9t // Move a certain number of LEDs\n  #Ia0a2avS87ozapuc if $@this→\\_dir = 0 then {\n    #xguNWSh6ozJhLDZm $@this→\\_y := $@this→\\_y - $leds;\n  }\n  else { #xkZp4VKKT4vlygml if $@this→\\_dir = 45 then {\n    #BwF3Tum2fGAxOmhE $@this→\\_x := $@this→\\_x + $leds;\n    #WDUbDm4yNHaoKmvW $@this→\\_y := $@this→\\_y - $leds;\n  }\n  else { #fvsPfw4Q4C6D2L5Y if $@this→\\_dir = 90 then {\n    #OAatiV4yZX34Lif9 $@this→\\_x := $@this→\\_x + $leds;\n  }\n  else { #To0PQ7s6rn3KGnK4 if $@this→\\_dir = 135 then {\n    #hqnjllANuxMphiv2 $@this→\\_x := $@this→\\_x + $leds;\n    #xbrE4lOrDfgmt8HE $@this→\\_y := $@this→\\_y + $leds;\n  }\n  else { #UPLmWeTmHs3pWX1i if $@this→\\_dir = 180 then {\n    #qpgQOY1wHfUd2VSE $@this→\\_y := $@this→\\_y + $leds;\n  }\n  else { #Dm3TvL4C2BDNYlpJ if $@this→\\_dir = - 45 then {\n    #xLloUv2wDidasof7 $@this→\\_x := $@this→\\_x - $leds;\n    #Q4eMk8ku2tzRTWmV $@this→\\_y := $@this→\\_y - $leds;\n  }\n  else { #TkGM1qH4v7YjA3Dj if $@this→\\_dir = - 90 then {\n    #wiV8WWkDvoYq47YZ $@this→\\_x := $@this→\\_x - $leds;\n  }\n  else {\n    #N5FS3aoL5x6Q8bg3 $@this→\\_x := $@this→\\_x - $leds;\n    #xkUwKZMYcfPxvNu6 $@this→\\_y := $@this→\\_y + $leds;\n  }\n  } } } } } } \n  #hm8FZefbky33Z4HE $@this→\\_x := math→clamp(0, 4, $@this→\\_x);\n  #O4Eu78c4LTWcTZtE $@this→\\_y := math→clamp(0, 4, $@this→\\_y);\n  #x0H7hR67xz4euAeC code→plot;\n  meta sync;\n}\n#wquesHkwuYKkrRep\naction go_to(#abaqqKrsGOA41iFy @this: * Led_Sprite, #xcASpLlpX5koamEQ x: Number, #AEe12g4I9h5PTaxW y: Number) {\n  #I4EOQGLe35sjOJk6 // Go to this position on the screen\n  #PIpmUdNyvDkdBwrQ $@this→\\_x := $x;\n  #fEF0IYx9kgSeOHkb $@this→\\_y := $y;\n  #xWLn0kyHeQnWluNB $@this→\\_x := math→clamp(0, 4, $@this→\\_x);\n  #dtM7s4cG1zxXT7le $@this→\\_y := math→clamp(0, 4, $@this→\\_y);\n  #Cs4ula7JmM0HSolU code→plot;\n  meta sync;\n}\n#EnFD76PbssiLD7vv\naction if_on_edge\\u002c_bounce(#HV4x3j8JF159462w @this: * Led_Sprite) {\n  #mW2b4erDcZw45S3d // If touching the edge of the stage, then bounce away.\n  #WJvOYi3J0oQUfX7r if $@this→\\_dir = 0 `and` $@this→\\_y = 0 then {\n    #ki7G5jxaq4oECrOa $@this→\\_dir := 180;\n  }\n  else { #Cqb5nUza82plXe5W if $@this→\\_dir = 45 `and` ($@this→\\_x = 4 `or` $@this→\\_y = 0) then {\n    #xTNRwJttNNDMS4jH if $@this→\\_x = 0 `and` $@this→\\_y = 0 then {\n      #wNpbzp4QzSOBV6Uw $@this→\\_dir := - 135;\n    }\n    else { #QIHjBGVMm3O7jKbg if $@this→\\_y = 0 then {\n      #G4NfDqmzft2pZa0u $@this→\\_dir := 135;\n    }\n    else {\n      #xv4hQ8ImkIWqbf40 $@this→\\_dir := - 45;\n    }\n    } \n  }\n  else { #eKc44OZTHanPb4ou if $@this→\\_dir = 90 `and` $@this→\\_x = 4 then {\n    #mhlBDRbCxrRN2GJh $@this→\\_dir := - 90;\n  }\n  else { #y6QrCxoz5uQ2s6Xe if $@this→\\_dir = 135 `and` ($@this→\\_x = 4 `or` $@this→\\_y = 4) then {\n    #xP7I1EvwXEbwBqmq if $@this→x = 4 `and` $@this→y = 4 then {\n      #Msc2p75THd3we4FC $@this→\\_dir := - 45;\n    }\n    else { #xSXuex4eRZT5v1LQ if $@this→\\_y = 4 then {\n      #E22lLCJn4ecoqZ29 $@this→\\_dir := 45;\n    }\n    else {\n      #OoLMy4bQlVjRfZeE $@this→\\_dir := - 135;\n    }\n    } \n  }\n  else { #KO0B13gTd4WyOTav if $@this→\\_dir = 180 `and` $@this→\\_y = 4 then {\n    #HYmYAypV2ZRjwxjR $@this→\\_dir := 0;\n  }\n  else { #TC5SNjX4AmPPzgIq if $@this→\\_dir = - 45 `and` ($@this→\\_x = 0 `or` $@this→\\_y = 0) then {\n    #bte4O4gurLB2v8Ai if $@this→x = 0 `and` $@this→y = 0 then {\n      #x7iP8m2Y9zQkHyHh $@this→\\_dir := 135;\n    }\n    else { #wNngfLmvyionXaDP if $@this→\\_y = 0 then {\n      #DjbzNtzG2PEVhOVc $@this→\\_dir := - 135;\n    }\n    else {\n      #Q3IgxEngGQNS1Y5t $@this→\\_dir := 45;\n    }\n    } \n  }\n  else { #xXlWXaP45766gsVk if $@this→\\_dir = - 90 `and` $@this→\\_x = 0 then {\n    #xpKOVFoZAzm3xyS1 $@this→\\_dir := 90;\n  }\n  else { #I0kQuCXxWELaGOYh if $@this→\\_dir = - 135 `and` ($@this→\\_x = 0 `or` $@this→\\_y = 4) then {\n    #xJ7N9Y3ZVXv8g7oI if $@this→\\_x = 0 `and` $@this→\\_y = 4 then {\n      #LmufIcTbWtVXHSLJ $@this→\\_dir := 45;\n    }\n    else { #hkg4w2uDjtmf2ogC if $@this→\\_y = 4 then {\n      #l2OvXKlH3du5wfxz $@this→\\_dir := - 45;\n    }\n    else {\n      #xYQkGx2fAmR7kY90 $@this→\\_dir := 135;\n    }\n    } \n  }\n  else { } } } } } } } } \n  #Hwo8pD4s5eRV2By5 code→plot;\n  meta sync;\n}\n#Qbs2pH7Z7ul3N272\naction turn_right(#WQo2rhrkQWxkzPrA @this: * Led_Sprite, #TBC5hHn9AJYGofW7 degrees: Number) {\n  #xLjBzHVtkZc5wTsM // Turn to the right (clockwise)\n  #Dy8wBzFcytw4i4WD // {hints:degrees:45,90,135,180}\n  #STogS6X5S10pdm5j $@this→set_direction($@this→\\_dir + $degrees);\n  meta sync;\n}\n#nhl5mQt24x0S6udm\naction turn_left(#AkNxX24d83P2lJb4 @this: * Led_Sprite, #xaEEUGTEPf0CLnfJ degrees: Number) {\n  #q2Uw4nTyC4yxAhUV // Turn to the left (counter-clockwise)\n  #h2IwxNSyzoIrBCPo // {hints:degrees:45,90,135,180}\n  #aCF4f3u2PTKdbCBW $@this→turn_right( - $degrees);\n  meta sync;\n}\n#FCflZPrXxubdYEHq\naction set_direction(#W6XOHR7W7H5Uhce5 @this: * Led_Sprite, #GlUGqspXS7qUZZkh degrees: Number) {\n  #rkSAHKmBYqJ6uZYF // Set the direction of the current sprite, rounded to the nearest multiple of 45\n  #xLskSxLQcPhG5Eh8 // {hints:degrees:0,45,90,135,180,-45,-90,-135}\n  #Rkf7OLg8OLcS1BQd $@this→\\_dir := math→mod($degrees / 45, 8) * 45;\n  #nCQbePGChgTQ2hm7 if $@this→\\_dir ≤ - 180 then {\n    #xD2OY2tbKkgc4QFj $@this→\\_dir := $@this→\\_dir + 360;\n  }\n  else { #xxcX416s0eXg2Jb4 if $@this→\\_dir > 180 then {\n    #YUQrsgErLV0isSaw $@this→\\_dir := $@this→\\_dir - 360;\n  }\n  else { } } \n  #op5k2N9fbXY8HEWU code→plot;\n  meta sync;\n}\n#NSHCEK6bQ8swNBmM\naction x(#xgToVMvrrAswoUeH @this: * Led_Sprite) returns(#xXVHwibH1jpjLEIs r: Number) {\n  #O7hb0e8vT223tnC9 // Reports the ``x`` position of a sprite on the LED screen\n  #u9TO3yP69u3yQHq2 // {action:ignoreReturn}\n  #lbdc1f64posFgGUT `return` $@this→\\_x;\n  meta sync;\n}\n#JDrz7o89TGTxeK2w\naction y(#rnfi71evZY42LLnW @this: * Led_Sprite) returns(#j7qseMNIfdD5bZk2 r: Number) {\n  #OL72oZm0MjSHeGPi // Reports the ``y`` position of a sprite on the LED screen\n  #JChevy7MIzqvI44L // {action:ignoreReturn}\n  #XyGKpV2bxAm2MSb3 `return` $@this→\\_y;\n  meta sync;\n}\n#xSFJWYkhHm25gCC6\naction direction(#qmTmS7h27Sd6jvdE @this: * Led_Sprite) returns(#GMfjMqXduoLFMgVJ r: Number) {\n  #oqasR6pvP2QH5Yit // Reports the current direction of a sprite\n  #e1J4Gl2GjYDo4AhP // {action:ignoreReturn}\n  #qKryag4qEHbjmkOS `return` $@this→\\_dir;\n  meta sync;\n}\n#xd5Cnqhvdot8v0I2\naction set_x(#YRkB4B07f1TFpmc5 @this: * Led_Sprite, #IwppOWKsNf246cvq x: Number) {\n  #xtgkapSjxReCIzks // Set the ``x`` position of a sprite\n  #xBmG31Tos70NHkfZ $@this→go_to($x, $@this→\\_y);\n  meta sync;\n}\n#cjf3G44aBhLdgBM4\naction set_y(#xe00Eqd2Sye76CcK @this: * Led_Sprite, #xUIp4QMLCBopDvKT y: Number) {\n  #rt34m9v71RciQ1LM // Set the ``y`` position of a sprite\n  #xz0cSa4iDTY741jP $@this→go_to($@this→\\_x, $y);\n  meta sync;\n}\n#xCdoxKQ2PYO4sDeW\naction change_y_by(#GtmKdo2M0rB6Xoxp @this: * Led_Sprite, #xnOmlrhOk7cRHCIg y: Number) {\n  #nMbLdUu2E6HK3aod // Changes the ``y`` position by the given amount\n  #kq22RIc81QnunNP4 // {hints:y:1}\n  #xaWt7GUOc2SDslvK $@this→go_to($@this→\\_x, $@this→\\_y + $y);\n  meta sync;\n}\n#vaus553SVioo4jJr\naction change_x_by(#BNyURA3lrR445XJ2 @this: * Led_Sprite, #GC5f2Y5myMXFJMuk x: Number) {\n  #Wa4DXXQfls07wwqI // Changes the ``x`` position by the given amount\n  #ky1UesBkqQza1YpA // {hints:x:1}\n  #TE7whTqcF6AjYWvK $@this→go_to($@this→\\_x + $x, $@this→\\_y);\n  meta sync;\n}\n#NH3Z2IrvU21LuPGM\naction is_touching(#NB942NQl923gi02T @this: * Led_Sprite, #UZ597zOwyA6568TK other: * Led_Sprite) returns(#zHEcCNsDmXzhUt9V r: Boolean) {\n  #w2haKF4w9cxEBYkc // Reports true if sprite is touching specified sprite\n  #EHJ2YBpvJAzd0Uqp // {action:ignoreReturn}\n  #bAQMgnnEUZqDGLyC `return` $@this→\\_x = $other→\\_x `and` $@this→\\_y = $other→\\_y;\n  meta sync;\n}\n#xD4uhANlxBIGS7OU\naction is_touching_edge(#xvVZ9ABfZXXspLlY @this: * Led_Sprite) returns(#K8ObBSXJ5ECbUdjN r: Boolean) {\n  #IvjKKKDIP3iKSHqb // Reports true if sprite is touching an edge\n  #zOe9JEEGfZjkRXVN // {action:ignoreReturn}\n  #B25GiX6KizWzqnHH `return` $@this→\\_x = 0 `or` $@this→\\_x = 4 `or` $@this→\\_y = 0 `or` $@this→\\_y = 4;\n  meta sync;\n}\n#bkOzd2UzwbDSbLgu\naction on(#rj7tjF50krHRwt6J @this: * Led_Sprite) {\n  #ydvX567DaEZLqO7K // Turns on the sprite (on by default)\n  #lJ22kxYhvlqhft3U $@this→set_brightness(255);\n  meta sync;\n}\n#u9iUpHzn26Cdfona\naction off(#e0lGhx7xf1e7IUCX @this: * Led_Sprite) {\n  #Xb7Yx3vYM4ShEFUe // Turns off the sprite (on by default)\n  #REB5VhZtw3YUYSxh $@this→set_brightness(0);\n  meta sync;\n}\n#DJ445YFffVfKDqHs\naction set_brightness(#ylG8SOIydgxxfeSy @this: * Led_Sprite, #DQWYvEEkEzaPMwlC brightness: Number) {\n  #CYsmrKQxad2dO63G // Set the ``brightness`` of a sprite\n  #FLAXXGWNwLg24o2J // {hints:brightness:255,0,127}\n  #lGQZxBxH4pi0khw3 $@this→\\_brightness := math→clamp(0, 255, $brightness);\n  #bGzkRMdTHUH0BhYx code→plot;\n  meta sync;\n}\n#MMokZ8utTeSrEPEE\naction brightness(#x7Z3c9xE3t1SbCOb @this: * Led_Sprite) returns(#xUzQbOrOfDuvpEGp r: Number) {\n  #Sz7DkrDPcD4YpGJG // Reports the ``brightness` of a sprite on the LED screen\n  #FNuHpZoWtcvzcx0R // {action:ignoreReturn}\n  #Xb1aqKrgPqLtjVoj `return` $@this→brightness;\n  meta sync;\n}\n#CflgTntqHhWbxHlW\naction change_brightness_by(#YOnjOM5Dijox14bO @this: * Led_Sprite, #XChQ7dKtgcDBImGc value: Number) {\n  #QS0H5xTlm0sn0Unq // Changes the ``y`` position by the given amount\n  #O1QaAEjifPnQ8azU // {hints:value:25}\n  #Jk6fyOIwYdZoztd0 $@this→set_brightness($@this→\\_brightness + $value);\n  meta sync;\n}\n#fe4BUMNMHkLIbNKa\naction change_direction_by(#x32MjNr12ofz2JYc @this: * Led_Sprite, #xuoTqBS6Ikir95JL angle: Number) {\n  #VNIvix2ffUeRNdMx // Changes the ``direction`` position by the given amount by turning right\n  #zPHNWOxwhGlBgO69 // {hints:angle:45,90,-45,-90}\n  #l2PLkh6uahGZEzIi $@this→turn_right($angle);\n  meta sync;\n}\n#Xwzo4y2iATnX72lA\naction invalid_sprite() returns(#nr31Nq023HjQjvBc r: * Led_Sprite) {\n  #XWx7JR2mUvBQxhzD // Gets an invalid sprite; used to initialize locals.\n  #D04g2GnOmaLZtnRb // {weight:0}\n  #xja2b4gPwHB2dcd6 // {namespace:game}\n  #cxvKf4e0N6UEtGPL // {action:ignoreReturn}\n  #Naa3i2uT6RXc9lKZ `return` records→Led_Sprite→invalid;\n  meta sync;\n}\n#xUwWUO2jFGIlKOtq\naction delete(#TqK6aquLm37xVsNH sprite: * Led_Sprite) {\n  #bH7rJ8stE4vJr6ZV // Deletes the sprite from the game engine. All further operation of the sprite will not have any effect.\n  #KaYmbOrkjZ4CS4df data→sprites→remove($sprite);\n  meta sync;\n}\n#hi6X8Z2yYBVyLkWz\naction test_pong() {\n  #i8JqKk4Qc1tXPvFb // {shim:}\n  #s2X9VygZOY29nARC $paddle := code→create_sprite(0, 2);\n  #NBrpqVUuuENIGkHh $paddle→set_blink(100);\n  #pYCFQ2QktMJs93Qx $paddle→set_brightness(8);\n  #li2Xx982HOn3o2VB $ball := code→create_sprite(4, 1);\n  #vb0CkZtaWnHnk1XU $ball→set_direction( - 45);\n  #T5sAL25TVftlfVcf input[lib micro\\u003abit] →on_button_pressed(\"A\");\n  #Xc0cWs4EfXhPU1Xi where `implicit` \\_body\\_() {\n    #OrYN2UYJXGDZbVBr $paddle→change_y_by( - 1);\n  }\n  #AXHWyd3kTYsJElLr input[lib micro\\u003abit] →on_button_pressed(\"B\");\n  #xregKwVEF7FuAUjf where `implicit` \\_body\\_() {\n    #cwZAbLXRz4aW5rkZ $paddle→change_y_by(1);\n  }\n  #xdRq7JGUl6BOhWsK basic[lib micro\\u003abit] →forever;\n  #EqqnOIfFy9hTWQkt where `implicit` \\_body\\_() {\n    #O31nNQcgm3V9q3at basic[lib micro\\u003abit] →pause(500);\n    #xNa4DdNTY3Rp2wZM $ball→move(1);\n    #OszsjBEfq4VxjnS4 if $ball→x = 0 then {\n      #tv2doKCLd8JeZj3b if $paddle→y ≠ $ball→y then {\n        #vfKYjiha0E346q6D control[lib micro\\u003abit] →reset;\n      }\n    }\n    #RQqLvxZWJGUf2vau $ball→if_on_edge\\u002c_bounce;\n    #NexnUUAILkC5kxqt if $ball→x = 0 then {\n      #xc1sfBAq2ujFBfj2 $ball→change_x_by(1);\n    }\n  }\n  meta private;\n  meta test;\n}\n#UxwYpEnnSWg0DNxW\naction set_blink(#aKrr34Wgo3kkbwZp sprite: * Led_Sprite, #hqkyJK2pO17MsVDC ms: Number) {\n  #IwFtTdIGBNUXLH5Y // Sets the blink duration interval in millisecond.\n  #x9O466bk8ufa2Yio // {hints:ms:100,50,200}\n  #xg2e74XGOsfxy48l $sprite→\\_blink := math→clamp(0, 10000, $ms);\n  meta sync;\n}\n#vjw2ol9RXAfcugGH\naction change_blink_by(#tiHtDdJLNoz1vvYz @this: * Led_Sprite, #xYGs397pRbQfSJYL ms: Number) {\n  #x7mcAB7o2E4JTjLx // Changes the ``blink`` duration by the given amount of millisecons\n  #xRtxfoag4GzP4P5w // {hints:ms:10}\n  #H16162bYai4of4DQ $@this→set_blink($@this→\\_blink + $ms);\n  meta sync;\n}\n#zIjNoKzrTHYAVS9A\naction blink(#xfOf8pD0DexU1uz2 @this: * Led_Sprite) returns(#xTF5bE4QTqBPBl8X r: Number) {\n  #fasvxj1L7NBocnta // Reports the ``blink`` duration of a sprite\n  #PlrHp3HKOnu50Qzg // {action:ignoreReturn}\n  #m4hy2L2dtnFC00Pk `return` $@this→\\_blink;\n  meta sync;\n}\n#x0npij8XjopQavcK meta import micro\\u003abit_game {\n  pub \"xgqnpl\"\n  usage {\n    action `sync` score() returns(score: Number)\n    action `sync` set_score(value: Number)\n    action `sync` life() returns(life: Number)\n    action `async` set_life(value: Number)\n    action `sync` add_score(points: Number)\n    action `async` add_life(lives: Number)\n    action `async` start_countdown(ms: Number)\n    action `async` game_over()\n    action `async` current_time() returns(ms: Number)\n    action `async` remove_life(life: Number)\n    action `async` level_up()\n    action `async` level() returns(lv: Number)\n    action `async` start_stopwatch()\n    action `sync` is_running() returns(running: Boolean)\n    action `async` show_score()\n    action `sync` is_game_over() returns(over: Boolean)\n  }\n  #zC5J5ehItETvjAK0 resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#awExHfjoQJnV2nR1 meta import micro\\u003abit {\n  pub \"thflqk\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `async` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` set_pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Number)\n    action `sync` pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Number)\n    action `sync` set_display_mode(mode: String)\n  }\n}\n",
  "lohjia": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit serial\";\nmeta rootId \"J14qS9W69xfJRs1Wg6l4bL8j\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// A #microbit library to print messages to the serial port.\n#Jb2ciAJpCpybcXGj\naction write_line(#viL9JhCNnO3GFckc text: String) {\n  #qd8bnGggS2t7YSVF // Prints a line of text to the serial\n  #Ht90vVwzb9x642mt // {namespace:serial}\n  #R4f2PuqLYHK2Gtcr code→write_string($text);\n  #giwZfV8Lt049ksV2 code→write_string(\"\\r\\n\");\n  meta sync;\n}\n#KayLKTp6ax4o8wIi meta import micro\\u003abit {\n  pub \"jnjqgc\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` remote_control(@event: String)\n    action `sync` camera(@event: String)\n    action `sync` audio_recorder(@event: String)\n    action `sync` alert(@event: String)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n  }\n}\n#AABkMop1Z4RJQfcY\naction example() {\n  #vIxCYZlAfMloWGOR // This library provides functionalities to read and write data to the serial port.\n  #obJL2omLuN5vNWGX // * print a line of text (the new line character is added automatially)\n  #xfS6oh3qhUuVm3ee code→write_line(\"hello\");\n  #USJSQxggyA9b7Xk5 // * print a piece of text\n  #DJAddA2AQVd3x44R code→write_string(\"world\");\n  #ZGvSLSTMY2eH7BGS // * print a number.\n  #CPTexj2njchbeTaq code→write_number(5);\n  #FoTvRhTUX9cuCH4G // * write a key-value pair formatted as ``key: value``.\n  #xNrXN2N2zI6RANiH code→write_value(\"temp\", 5);\n  #gnakx4J3bNeA6l5y // * read a line of text from Serial\n  #xMVREMMWm4TP690d $msg := code→read_string;\n  meta private;\n}\n#pvd0wLlxZ7vuecCJ\naction write_number(#k2kI6XM6EpaLIU35 value: Number) {\n  #UPZWaaK4FPhqLQv5 // Prints a numeric value to the serial\n  #ABpnPKKwPATyuC4K // {namespace:serial}\n  #xyMeH7KZaUtgWna4 code→write_string($value→to_string);\n  meta sync;\n}\n#hGNQralaeJZymMYt\naction read_string() returns(#mR5YbOZ9oVeKJhbt msg: String) {\n  #Of7tDy94qf27pF8n // Reads a line of text from the serial port.\n  #xjcz6ZTqNS4rrHiN // {namespace:serial}\n  #rndC9WsJA7TzRqJw // {shim:uBit.serial.readString}\n  #xUvA7hlR41fO4O3S $msg := \"\";\n  meta sync;\n}\n#RihJksfYn4XsFVvo\naction write_string(#xCSsMIN55sl47uJy text: String) {\n  #gQl2sBm102NFdm2r // Sends a piece of text through Serial connection.\n  #xaRZMDD1PnoAssMk // {namespace:serial}\n  #E2GfoM3vov7PqeyA // {shim:uBit.serial.sendString}\n  #MZsKH7uN4oOrAkYD if data→logger→is_invalid then {\n    #xI2Zu2L2Lb9tvgAS data→logger := app→create_logger(\"simulator\");\n    #E2SUJPexCTkCqWoA data→buffer := \"\";\n  }\n  #dxqLroF89D9FBaiI data→buffer := data→buffer ∥ $text;\n  #z7tR5L7oMAlwH4gu $i := data→buffer→index_of(\"\\n\", 0);\n  #LS2Xmww1aZuQammy while $i > - 1 do {\n    #x4eGXbX2v6z0SE5y data→logger→info(data→buffer→substring(0, $i - 1));\n    #esc5CnL0W2BjsgA5 data→buffer := data→buffer→substring($i + 1, data→buffer→count - $i);\n    #EWO0d4UsugWoDRjW $i := data→buffer→index_of(\"\\n\", 0);\n  }\n  meta sync;\n}\n#ofbblREfGQlVQeKu\naction write_image(#gyH7VhnFqZTOycIl img: ♻ micro\\u003abit → Image) {\n  #xO6AG2n8p2M0iRM9 // Sends an image through Serial connection in CSV format.\n  #i9igu656RRwxytVx // {namespace:serial}\n  #sx5zVhpQfuMHxxmC // {shim:uBit.serial.sendImage}\n  #dfiCwNN06R38ZYRQ code→write_string(\"write image\");\n  meta sync;\n}\n#x4YEGlXH9CPn24qF\naction write_screen() {\n  #W6GWMYLuhTKpZfVd // Sends the current pixel values, byte-per-pixel, over serial.\n  #MaKPhWXTpJB2NNWZ // {namespace:serial}\n  #ejsGWhn5BXXX8fl4 // {shim:uBit.serial.sendDisplayState}\n  #AA2MkYF4heyXTuSP code→write_string(\"write screen\");\n  meta sync;\n}\n#x6Hp3T5XixrKOXp4\naction read_screen() {\n  #xkl7dNT5Lc785ZVZ // Reads the screen from serial.\n  #ApoeWPHDMVNc7MjB // {namespace:serial}\n  #tZxNxHtIuaSuvjo0 // {shim:uBit.serial.readDisplayState}\n  #eUUa4Y2jh2Gby4Ls app→log(\"serial: read screen\");\n  meta sync;\n}\n#xBHnPm4TuXZ1XJba\naction read_image() returns(#i9cIYIjnk4B1camX img: ♻ micro\\u003abit → Image) {\n  #HKBSShuS3IHZZKK3 // Reads a 5x5 image from the serial port.\n  #xvg6N07oMKfwiZHk // {namespace:serial}\n  #xKaSva7IbKCilyF8 // {hints:columns:5,10,15}\n  #t3L7RQAYTB4ch4Fj // {shim:uBit.serial.readImage}\n  #xbuEE8By6wuVCMZn $img := image[lib micro\\u003abit] →create_image(\"\");\n  meta sync;\n}\n#zPbJPfnPazeARtdv\naction write_value(#OgjzGItCA4ZJ4BzL name: String, #Vles4eqMyGBPIrfR value: Number) {\n  #VS9lEdypH2IAyWO6 // Writes a ``name: value`` pair line to the serial.\n  #x9jpo8ecP95VZ6PJ // {namespace:serial}\n  #tIIbV2VmG3JI2Q1Z // {weight:80}\n  #gj2gRu3mQINbNkri code→write_string($name);\n  #eYR5noToKqFF6E94 code→write_string(\": \");\n  #Zf7NNdlvoPDrwtMy code→write_number($value);\n  #byMfp2eAi2r7tJ1O code→write_line(\"\");\n  meta sync;\n}\n#kyNCj4TkYFS3fVSb\nvar buffer : String {\n  // {shim:}\n  transient = true;\n}\n#ObzPYQYVl4tjVK9D\nvar logger : App_Logger {\n  // {shim:}\n  transient = true;\n}\n#WnPrTNC3u44ZZOn6\naction test() {\n  #AeRsf2ESRnySmzle // {shim:}\n  #AMj8TxEWtoGWsERs code→write_string(\"abc\");\n  #TK2ZMRUQ2TOXpOa2 code→write_line(\"line\");\n  #pMkSlVs4iOUkZXf1 code→write_line(\"line 2\");\n  #x6rU5ty6bc2OoaN7 for 0 ≤ i < 100 do {\n    #bGiqKsnmXiwKPH2z code→write_value(\"x\", $i * $i);\n  }\n  meta private;\n  meta test;\n}\n",
  "jztbbx": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit senses\";\nmeta rootId \"zm342lGQufsImTJsY2Mjd6OL\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// A #microbit library that exposes orientation and movement events.\n#xwOq4wuI8tUXxrHj\naction on_screen_up(#Zm23L35zAoZ5xaUM body: Action) {\n  #MpPu5BNli80ud2U6 // Attaches code to run when the screen is facing up.\n  #xhao1j41emG2VOxP // {namespace:input}\n  #WdKqPeQdt8TOCgKu // {help:functions/on-screen-up}\n  #E4B0WT3YTg0B26mq simulator[lib micro\\u003abit] →notify_event_registration(\"on screen up\");\n  #yb4F8TjWZB4lGJFg data→screen_up := $body;\n  #Y83at3q2DuxfruwD code→init;\n  meta sync;\n}\n#PrS2fWPpYL7FC6Wo meta import micro\\u003abit {\n  pub \"vzzjsk\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` remote_control(@event: String)\n    action `sync` camera(@event: String)\n    action `sync` audio_recorder(@event: String)\n    action `sync` alert(@event: String)\n    action `sync` plot_image(leds: String)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n  }\n}\n#cW5Eaba6g2xa58TR\naction on_screen_down(#KMHPPFLh79ILxEsC body: Action) {\n  #AMcAx2XgzUwf2TMM // Attaches code to run when the screen is facing down.\n  #jQPXP4X2PHIs9Muo // {namespace:input}\n  #ZdcCAkOLyBzyIBOy // {help:functions/on-screen-down}\n  #xdc4HMUwupE74u9V simulator[lib micro\\u003abit] →notify_event_registration(\"on screen down\");\n  #xTg7g7WPbHijTQqB data→screen_down := $body;\n  #Yc1eBaxVszGtkaPn code→init;\n  meta sync;\n}\n#t6BUCc8WlaifMQw2\nvar screen_state : Number {\n  transient = true;\n}\n#Yasq36DXnLkbHctP\naction detect() {\n  #SGGUvEQILsE9YGty // Detects if the orientation has changed and raises events if available.\n  #xB6p3z7B2SjlkiiU $accx := @\\u267b→micro\\u003abit→acceleration(\"x\");\n  #mS3ZTk4J0zBlNh4V $accy := @\\u267b→micro\\u003abit→acceleration(\"y\");\n  #tFPDfT34L7ESBdo0 $accz := @\\u267b→micro\\u003abit→acceleration(\"z\");\n  #iX3VlP2YLy1uy2XF // screen state: 0 = unknown, 1 = down, 2 = up, 3 = logo up, 4 = logo down\n  #E4BWU7aQLnOxMhWf code→detect_screen($accx, $accy, $accz);\n  #xrAqAGomTzw8jL2g code→detect_shake($accx, $accy, $accz);\n  meta private;\n}\n#bMJX2o4cp6UbgrWH\nvar screen_up : Action {\n  transient = true;\n}\n#aJTalpc0eYQrv7QQ\nvar screen_down : Action {\n  transient = true;\n}\n#eVHP6bRFyulckN6X\naction example() {\n  #aW2IRmUTax7OLDG2 // A library that exposes orientation and movement events. [read more...](/td/contents).\n  meta private;\n}\n#lhwojBx1CnMGhLPB\naction init() {\n  #xHJIJAFfGrSx2zlD if `not` data→\\_init then {\n    #hA5Iq3c70pT8TcD5 data→\\_init := true;\n    #xyqvAivXibKxY0RO control[lib micro\\u003abit] →in_background;\n    #MoqZci0II5zqP364 where `implicit` \\_body\\_() {\n      #xbWJI6pgYPHpwWiw while true do {\n        #xwonR7KDZ1XgHpL9 code→detect;\n        #UAhoHSTIEevYn5rp basic[lib micro\\u003abit] →pause(80);\n      }\n    }\n  }\n  meta private;\n  meta sync;\n}\n#xdoNy11ziwtWZlCo\naction on_shake(#iQzuA2ozltGMgcTU body: Action) {\n  #JTf89RIRRrxO9SnG // Attaches code to run when the device is shaken.\n  #x4x2vPoD9qOIvh7q // {namespace:input}\n  #KmZcvSqByA57L44B // {help:functions/on-shake}\n  #KExN3jsE0DMuPqLE simulator[lib micro\\u003abit] →notify_event_registration(\"on shake\");\n  #YUaLdMsVvnyHMnXG simulator[lib micro\\u003abit] →add_button(\"shake\", $body);\n  #kZT3dnZQyxuZq166 data→last_shake := input[lib micro\\u003abit] →running_time;\n  #xbZpVSJVwAeD6GRE data→shake := $body;\n  #x7QP0YR4O6RXtmXl code→init;\n  meta sync;\n}\n#chN4AnXG7yhK2AXu\nvar shake : Action {\n  transient = true;\n}\n#l5nnEGrJBtPBD6uu\nvar last_shake : Number {\n  transient = true;\n}\n#q3bSEBO2AnZaW4dr\naction on_logo_up(#V7xeUvewokw5LxJn body: Action) {\n  #xDMX0HWkSWDtE0Tq // Attaches code to run when the logo is oriented upwards and the board is vertical.\n  #zUK2prvTnaAoT7md // {namespace:input}\n  #Gyr2W2ZXOCkfIMXd // {help:functions/on-logo-up}\n  #EdHSaeQmax51CBmq simulator[lib micro\\u003abit] →notify_event_registration(\"on logo up\");\n  #MaBgsJCEaDfkBf64 data→logo_up := $body;\n  #fwMBTN84PCeAj72Q code→init;\n  meta sync;\n}\n#S2o2JJdwYJhisAXp\nvar logo_up : Action {\n  transient = true;\n}\n#xUVten7m0vVmyA4R\nvar \\_init : Boolean {\n  transient = true;\n}\n#joy4eey9DDzC8HR2\naction detect_shake(#tHRDEldGJ4ue8ool accx: Number, #JLClk08tfyKwJmGH accy: Number, #CLOKXkFToen6qwJ9 accz: Number) {\n  #xtI6yHh4BtZCqR3Q if `not` data→shake→is_invalid then {\n    #HtnSKlCS2Xu9pWz1 $now := @\\u267b→micro\\u003abit→running_time;\n    #BthNMTUVySeX0Nyo $ming := 180 * 180;\n    #T4iDX31OZHOlEJd8 $debunk := 1500;\n    #xSGwMi25c0coQQts if $now - data→last_shake > $debunk then {\n      #fnMxF6aP4yeF6GUy $\\u007c\\u007ca\\u007c\\u007c\\u005e2 := $accx / 10 * $accx / 10 + $accy / 10 * $accy / 10 + $accz / 10 * $accz / 10;\n      #x2pNcYJa9kVrZzQ2 if $\\u007c\\u007ca\\u007c\\u007c\\u005e2 > $ming then {\n        #IIwfoyiSwpLzFvvP data→last_shake := $now;\n        #xPHE9AGXfXGi4lrD data→shake→run;\n      }\n    }\n  }\n  meta private;\n}\n#GVBYI3VMRbqoNfnB\naction detect_screen(#HjxZTbKfdDrNgiSW accx: Number, #ryLNBYcAXIyw99pb accy: Number, #Wk0emOygMMselU76 accz: Number) {\n  #OnPPZzfv2DrkD51t $is_flat := math→abs($accx) + math→abs($accy) < 500;\n  #KTztF0grpXNSfDmp $is_vertical := math→abs($accx) + math→abs($accz) < 500;\n  #x4JdPKoQnVxk29jj if $accz > 500 `and` $is_flat then {\n    #UkMmR3drUtXAuLxj if data→screen_state ≠ 1 then {\n      #Cj9au3agUL3VTXpO data→screen_state := 1;\n      #dBOsHPiFM8ZsQIT7 code→run(data→screen_down);\n    }\n  }\n  else { #ONuoM34BWCyrmusn if $accz < - 500 `and` $is_flat then {\n    #P8bC9epU8M9PMthm if data→screen_state ≠ 2 then {\n      #LAkfBQP2OPSE9wG4 data→screen_state := 2;\n      #YFtNJxzp3xOetkxg code→run(data→screen_up);\n    }\n  }\n  else { #NQ8roiFE5R3evNyA if $accy > 500 `and` $is_vertical then {\n    #wKAufKYGbc4Bf4f2 if data→screen_state ≠ 3 then {\n      #PTYU9inhX4ypWy4k data→screen_state := 3;\n      #zHl0rsD21pWm0B2V code→run(data→logo_up);\n    }\n  }\n  else { #xqOU4XCzSA95y1lP if $accy < - 500 `and` $is_vertical then {\n    #HQn4YeL20sul4fRk if data→screen_state ≠ 4 then {\n      #dzddbU1SCv7f9Iip data→screen_state := 4;\n      #Tdpys1iOeS6bIp4E code→run(data→logo_down);\n    }\n  }\n  else {\n    #W8JvPbZlWjgyyW8c // // other state, reset state engine\n    #ow9eps4LUTwKFv2O data→screen_state := 0;\n  }\n  } } } \n  meta private;\n}\n#q6oYfrMSlJuMnKCb\naction on_logo_down(#JBP7dSSZZ5CW05l5 body: Action) {\n  #xzt2NAugK2mmviuz // Attaches code to run when the logo is oriented downwards and the board is vertical.\n  #AafRbGbssZIrx4wW // {namespace:input}\n  #x7OLuFYYKkdCQ2fL // {help:functions/on-logo-down}\n  #Y0VL8QH6mDTxdO2h simulator[lib micro\\u003abit] →notify_event_registration(\"on logo down\");\n  #xU60Xk2Bqg5VlOWx data→logo_down := $body;\n  #f27pU1IPNnF4rxZK code→init;\n  meta sync;\n}\n#x4S5FO3oacwG7q6C\nvar logo_down : Action {\n  transient = true;\n}\n#xKtZXebPhpGkz5MM\naction run(#AiTi5d6ioX2KIbLl f: Action) {\n  #ghdujUmazcH7hXMr if `not` $f→is_invalid then {\n    #fZONblMHRCsaFKLv $f→run;\n  }\n  meta private;\n}\n",
  "tgpxru": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit screen\";\nmeta rootId \"V5599nbmoYZQw1w33khHVtMh\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta splitScreen \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// Specialized functions to control the screen #microbit\n#mExzaWj10ZHeHz4P meta import micro\\u003abit {\n  pub \"tuzezw\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `async` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` set_pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Number)\n    action `sync` pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Number)\n    action `sync` set_display_mode(mode: String)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` light_level() returns(light: Number)\n  }\n}\n#ljbL9TDyViQp60st\naction toggle(#VUPjYYFrhOWw74RY x: Number, #nnwwBs7Gvq4QOFhz y: Number) {\n  #xv1X4QIgYlNaMo2l // Toggles a particular pixel\n  #QLttuQ85laW9BGaZ // {namespace:led}\n  #x2e61yB2AlBJwsM5 // {help:functions/toggle}\n  #FgmFzMhIDa7kfWlW if @\\u267b→micro\\u003abit→point($x, $y) then {\n    #JI1NCFlqtrqCyEod @\\u267b→micro\\u003abit→unplot($x, $y);\n  }\n  else {\n    #fr9fcMhf84RFYCe9 @\\u267b→micro\\u003abit→plot($x, $y);\n  }\n  meta sync;\n}\n#x3aHYXZCFqQM4N5z\naction plot_all() {\n  #Kf7bsANqYZRuDX8A // Turns all LEDS on\n  #xfEAxWsrYpI8LsrE // {namespace:led}\n  #xeNqHFR4dPLWb9Gl // {help:functions/plot-all}\n  #XTQai3Nb2nzgE04T for 0 ≤ i < 5 do {\n    #sZ4AYvycaWDrPWQR for 0 ≤ j < 5 do {\n      #zK0BvwMjXrxYI5u5 led[lib micro\\u003abit] →plot($i, $j);\n    }\n  }\n  meta sync;\n}\n#vsHySw7q1f2qmubh\naction example() {\n  #xQ2zrKasHUhouu4h // Some useful helpers to handle the LED screen. [read more...](/td/contents)\n  meta private;\n}\n#jwEvxEXkWvhLQCaf\naction toggle_all() {\n  #VYZ0MOonSM7SZ4SO // Inverts the current LED display\n  #g0PQAlQ9DWRcDJT2 // {namespace:led}\n  #XteinmSV9nf35axp // {help:functions/toggle-all}\n  #LOVe1FvXIuQSpOdt for 0 ≤ i < 5 do {\n    #AYxwUImNsW2NTTew for 0 ≤ j < 5 do {\n      #xy1D6qKToA7LgBRZ code→toggle($i, $j);\n    }\n  }\n  meta sync;\n}\n#gFU1OsaYQ427Dy3x\naction fade_in(#NkDJQP4M8hf8ByOK ms: Number) {\n  #sbtvSbGxGQsyil0Z // Fades in the screen display.\n  #YZm7yA5dpchXMk25 // {namespace:led}\n  #pWluOjC4UFxfEwYh // {hints:ms:700,2000}\n  #xCnB7Oisl6i2Ej4M // {help:functions/fade-in}\n  #wjhIzkepLWuKwtcO if $ms < 20 then {\n    #xobsfoi3mQdcjO4f @\\u267b→micro\\u003abit→set_brightness(255);\n    #dyWd0Vf8y8oZY3rB `return` ;\n  }\n  #YqgDyN4nF1eYtrSV $dt := 50;\n  #a920O1mg2GuXQTdD $brightness := @\\u267b→micro\\u003abit→brightness;\n  #Q3yIM4g0fv6TytSC $start := @\\u267b→micro\\u003abit→running_time;\n  #Ru1viKxwftkHaSoQ $elapsed := 0;\n  #CLECm1gEDweUCejD while $elapsed < $ms do {\n    #bFUPUsryN4Z6mxac @\\u267b→micro\\u003abit→set_brightness($brightness + (255 - $brightness) * $elapsed / $ms);\n    #xm08jhWovN4w1CmZ @\\u267b→micro\\u003abit→pause($dt);\n    #evfXW0XSgZavco0w $elapsed := @\\u267b→micro\\u003abit→running_time - $start;\n  }\n  #xKQmhSBAvZrHDYSB @\\u267b→micro\\u003abit→set_brightness(255);\n}\n#x7QNRVcyyxuTqIfa\naction fade_out(#xx2JQS02XjfYMxJH ms: Number) {\n  #WHFGHq4tuyIIqh45 // Fades out the screen brightness.\n  #VQyMxftJmAQHvQRZ // {namespace:led}\n  #nzAVXXGFATNIDOmL // {hints:ms:700,2000}\n  #OcEhk39lQe4D6COp // {help:functions/fade-out}\n  #sK5afunPQhe58NjZ if $ms < 20 then {\n    #x1qzvgufpPMfMBeo @\\u267b→micro\\u003abit→set_brightness(0);\n    #OioXNl3u7319hz8B `return` ;\n  }\n  #x71hff5Cad3PEqM5 $brightness := @\\u267b→micro\\u003abit→brightness;\n  #OjIQYJFPlSls9mPg $dt := 50;\n  #pwHkHlg81w7LJQdF $start := @\\u267b→micro\\u003abit→running_time;\n  #Zkzghv82gIfqZg8A $elapsed := 0;\n  #JjDiXM24mWUDhxDI while $elapsed < $ms do {\n    #yQM8M8NLZgZujKEu @\\u267b→micro\\u003abit→set_brightness($brightness - $brightness * $elapsed / $ms);\n    #cmBIrPftfbuXykXz @\\u267b→micro\\u003abit→pause($dt);\n    #xU5b9vdOhBdVPfZX $elapsed := @\\u267b→micro\\u003abit→running_time - $start;\n  }\n  #Ff2KRjXjWXdADj8r @\\u267b→micro\\u003abit→set_brightness(0);\n}\n#ruZ2GUlDTR5PTZhd\naction test_fade() {\n  #mHo56GPjrBIBbrXn // {shim:}\n  #xuX2QaesZ3fv68zC @\\u267b→micro\\u003abit→plot(2, 2);\n  #UGqmIER3apEDwBvY while true do {\n    #kkkohXu3WnU1V4lc code→fade_out(700);\n    #UD2rxEyf4vHJh1nV code→fade_in(700);\n  }\n  meta private;\n  meta test;\n}\n#JzsKhABDnEUitS2i\naction screenshot() returns(#xqf63n34DRJFpmqH img: ♻ micro\\u003abit → Image) {\n  #F9xzUugwJ3pSz2Jl // Takes a screenshot of the LED screen and returns an image.\n  #y2Nlin4tWBVdqYY1 // {namespace:led}\n  #Hzg49aPDJ5V4z35P // {shim:uBit.display.screenShot}\n  #XTef15xe4sxw76s2 // {help:functions/screenshot}\n  #ku7MF9fWJoUuVkyq $img := image[lib micro\\u003abit] →create_image(\"\");\n  #oUq2AzKEBn6NX5zt for 0 ≤ i < 5 do {\n    #xv5N8Sypi9Neisg7 for 0 ≤ j < 5 do {\n      #xb55AcpSLBkazRcr if led[lib micro\\u003abit] →point($i, $j) then {\n        #xBwclcbBPNTlPuR4 $img→set_pixel($i, $j, true);\n      }\n    }\n  }\n  meta sync;\n}\n#ovd9A8N30ut1go7D\naction plot_bar_graph(#hpG4t1C3SqiqVFVZ value: Number, #ZCK5n2unSOxU42XY high: Number) {\n  #zOTs2HbFZSsGIcZt // Displays a vertical bar graph based on the ``value`` and ``high`` value.\n  #xlNlnrVrytCbk5TQ // {hints:high:1023}\n  #qS76fFIpRiOAJ9r7 // {namespace:led}\n  #PfHFzO6Dk5aRnuIz // {help:/functions/plot-bar-graph}\n  #xIIhHcSXRfTjjsGE // {weight:20}\n  #xMI934nNAoZ2D22k $v := pins[lib micro\\u003abit] →map(math→abs($value), 0, $high, 0, 5);\n  #xVN6w2AP5InoeHt3 if $v ≤ 0 then {\n    #JQAjkd892SfAZVaM basic[lib micro\\u003abit] →plot_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n0 0 1 0 0\");\n  }\n  else { #Min3hDu7yaW5CsLL if $v = 1 then {\n    #Kipc7xzzcvftlk7v basic[lib micro\\u003abit] →plot_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n1 1 1 1 1\");\n  }\n  else { #xz3ssI2E8u04Qu26 if $v = 2 then {\n    #xFr4ltnLkVIMInA4 basic[lib micro\\u003abit] →plot_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n0 0 0 0 0\\n1 1 1 1 1\\n1 1 1 1 1\");\n  }\n  else { #q8IuhLmS4sGFPO55 if $v = 3 then {\n    #x7wL822ySG1ZdJOi basic[lib micro\\u003abit] →plot_leds(\"0 0 0 0 0\\n0 0 0 0 0\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\");\n  }\n  else { #Gseh3zz4Rb8tB8JN if $v = 4 then {\n    #OGxguFRTl11Db823 basic[lib micro\\u003abit] →plot_leds(\"0 0 0 0 0\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\");\n  }\n  else {\n    #mlCNyfGnvQhrFhHW basic[lib micro\\u003abit] →plot_leds(\"1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\\n1 1 1 1 1\");\n  }\n  } } } } \n  meta sync;\n}\n#YzC6hAtAqg8JGJmu\naction test_bargraph() {\n  #ontCmUQv3BUJaI49 // {shim:}\n  #wvK4U1Vp0BRBgQTq while true do {\n    #x2dlLTWbHX2S134E $millig := input[lib micro\\u003abit] →acceleration(\"x\");\n    #xJUYwGoxp4Xoqezo code→plot_bar_graph($millig, 1023);\n    #YfuOoWp0VBU2DzXK basic[lib micro\\u003abit] →pause(100);\n  }\n  meta private;\n  meta test;\n}\n",
  "pzngyn": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit music\";\nmeta rootId \"zcZxuG7jlicmbnRC8t33m4Dy\";\nmeta isLibrary \"yes\";\nmeta hasIds \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// The music namespace #music\n#zYqnzT4hhd1sS9v5\naction tempo() returns(#CCovj83aLPTgGAt8 bpm: Number) {\n  #ueqedJC4g7ssLd5h // Returns the tempo in beats per minute. Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.\n  #NCyRjHyFCpsvUpgi // {namespace:music}\n  #Wwx0VF4pDf4tWbsx // {help:/functions/tempo}\n  #n5fWBFaxGoZn6a59 code→init;\n  #vvGXAa6I2U4YBHIg `return` data→beats_per_minute;\n  meta sync;\n}\n#r0rxopDDamerRRAb meta import micro\\u003abit {\n  pub \"nvzoiu\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `async` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n  }\n}\n#kbBPLS46tSc5UOmQ\nvar beats_per_minute : Number {\n  transient = true;\n}\n#O6C1DkeyUnBA2l2C\naction change_tempo_by(#lsfxpXD2FhXQxNGk bpm: Number) {\n  #aqr1yNGtOahiiS2R // Change the tempo by the specified amount\n  #gMMNZPis7E1V40q2 // {hints:bpm:20}\n  #fb1CjjSTrsgDAAe6 // {namespace:music}\n  #eIVK0pUebdvQ1PGh // {help:/functions/tempo}\n  #UniNu8bLkhBkzmrU code→init;\n  #TF63Rbt1L4Asccr7 code→set_tempo(data→beats_per_minute + $bpm);\n}\n#SpEP5yVzmHkAcJGN\naction set_tempo(#RCUKT2icKMepsL3y bpm: Number) {\n  #n3ai84JWePfIRLXL // Sets the tempo to the specified amount\n  #k9gfHliR4ZsJDHFl // {hints:bpm:20}\n  #bI6a1Z3412AeIhCW // {namespace:music}\n  #z94g44g2YR0CR5Vw // {help:/functions/tempo}\n  #xktYXztr5YSoG1yX code→init;\n  #hQgb0VsrX4z2v6Fn if $bpm > 0 then {\n    #xf5KgzllgkClaTp8 data→beats_per_minute := math→max(1, $bpm);\n  }\n}\n#G7S48gzm3ze1gc4v\naction beat() returns(#hoFA5AiMYyzd23g3 ms: Number) {\n  #xH2OnLBAgNzAOUQ3 // Returns the duration of a beat in milli-seconds\n  #Sv6x7jD1FTiy8ocP // {namespace:music}\n  #PAeXs8UzPlBGhlLC // {help:/functions/beat}\n  #l0rdN6YLCsWTq7Bc // {weight:20}\n  #xNDIQQ29ooZVioJS code→init;\n  #zTcTGCwspFfZ6VaA `return` 60000 / data→beats_per_minute;\n  meta sync;\n}\n#HVvqA47Svm2C8JMG\naction init() {\n  #Kd2J2Q8MiYpFm2Dm if data→beats_per_minute ≤ 0 then {\n    #wnFL1JNUeq88d3d9 data→beats_per_minute := 120;\n  }\n  meta private;\n  meta sync;\n}\n",
  "tjwpnx": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"micro:bit profile\";\nmeta rootId \"jNYxMIKZwmM1Tt2iLWl9Hvzs\";\nmeta hasIds \"yes\";\nmeta splitScreen \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// The list of #microbit supported APIs.\n#Lfh62trBUHiPyt65\naction main() {\n  #EHiM59bhD8SdJNdc // namespace order\n  #lYPvYSUJurXkntc3 basic[lib micro\\u003abit];\n  #y6kj0BBUYlWuwy6W led[lib micro\\u003abit];\n  #xPTTNHFnhdSz2dhl input[lib micro\\u003abit];\n  #D2z4dybkpmvwZyDo math;\n  #xVSeqKOnHOk6JFR2 music[lib micro\\u003abit];\n  #w9qtFNmNqcWH4xF9 game[lib micro\\u003abit_game];\n  #SNTTZp3SXz6JkWWX pins[lib micro\\u003abit];\n  #bD2m5z3BbloyYsFN devices[lib micro\\u003abit];\n  #FbxqDG6K9icP69Mq control[lib micro\\u003abit];\n  #jpHdDKNpGylh7PAD image[lib micro\\u003abit];\n  #xSn8t2IaNKG1wYPa bits;\n  #iBKCrFATYjJq1exg create;\n  #v2bLbE0rFvUVnt41 serial[lib micro\\u003abit_serial];\n  #SMxCdKRKLGsg2glO events[lib micro\\u003abit];\n  #ia5OhbXZnpECRsED // booleans\n  #IPjPGMDLDgCFYFQv $b := true;\n  #q2bFfxkeThFXBFk0 $b := false;\n  #xYMADcXfW3PqDTYO $b := $b `and` `not` $b `or` $b;\n  #y1h3f5k4zS2ow98i // numbers\n  #xuOJjbFpvOVe734G $x := 0;\n  #vRUKtRasZ3LLaLDi $x := $x + 1 - 1 * 1 / 1;\n  #qw2442wniqeMcATr $s2 := $x→to_character;\n  #GNVgb4Rv3z5MGD9M // convert to string\n  #AVZpO4XznZddsl4x $xs := $x→to_string;\n  #Ml4FF82JwXfw4oXh skip;\n  #iMtrXvO0vVbnrSif // math ops\n  #xN6L0k61CSKHhTpv $b2 := $x > $x `and` $x ≥ $x `and` $x < $x `and` $x ≤ $x `and` $x = $x `and` $x ≠ $x;\n  #xLpMe46s4AjhANFf // math functions\n  #ArcdgH4N2HCRJjQO $x := math→min(0, 0);\n  #xrAT2doldLWgGTnF $x := math→max(0, 0);\n  #F4V5YLK9ABuOOLG4 $x := math→abs(0);\n  #hdoPGaOZxi28TjVi $x := math→pow(0, 0);\n  #pjD21RoeFLPeOdEh $x := math→random(2);\n  #rMg0HgI1Y6mkhv2j $x := math→clamp(0, 2, 0);\n  #xlsQ3acfdGfr6ggj $x := math→mod(0, 0);\n  #q2P2GRUN1jiY15yW $x := math→sign(0);\n  #xS4hZqehw24D7Sog // bit operators\n  #RJOMUzeBx8e5vo2b bits→or_uint32(0, 0);\n  #oswTMG9LvJf67wT4 bits→and_uint32(0, 0);\n  #r4thhhgbQDaxi5NI bits→xor_uint32(0, 0);\n  #xRhlQ45wNJee42FE bits→shift_left_uint32(0, 0);\n  #xW2Iwc06EUjqWuXg bits→shift_right_uint32(0, 0);\n  #xR78521qrK4Itxq1 bits→rotate_right_uint32(0, 0);\n  #xmjdteXTzTUSF2JG bits→rotate_left_uint32(0, 0);\n  #wKD5XdCaANiSDZS7 // objects\n  #UQtoYBY1CERVcw9K $thing := records→Thing→create;\n  #LeDrah2RsZKT1pB7 $s4 := $thing→f;\n  #yatKuQljTswa4YV1 $thing→f := $s4;\n  #PeQnpqn1X99KPYqa $thing→is_invalid;\n  #gAKBi40RzKRzwv22 $thing→equals($thing);\n  #JEnNA1g0abp21gJ8 records→Thing→invalid;\n  #dwjKGUdJ0JXzBEr2 // collections\n  #x2fBIBqppWPrRtwg $coll := create→Collection_of→Number;\n  #V1jUmLAnDR9hfTzZ $coll→add(0);\n  #xpdMBA8WUOeoGVhf $coll→count;\n  #xUi2uGW4ugoFPgaw $coll→at(0);\n  #x3WYxOTBUpSyFXSF $coll→remove_at(0);\n  #y3yaErW59Cfbjc5a $coll→set_at(0, 0);\n  #UF5AYoLREb5jnAMW $coll→index_of(0, 0);\n  #IJSRaF7fXjhBwNMN $coll→remove(0);\n  #rdrL8PN4Uw9v26OU // strings\n  #mRe27YLotG80DdYr $s := \"test\";\n  #xRlJY4QhO4Fq4hJ8 $x2 := $s→to_character_code;\n  #SUvyxQSIw3TY3vW2 $s := $s→concat($s);\n  #xqD7p2y1I1qY6XLV $s := $s ∥ $s;\n  #WimJjEuFBoOizCqp $s := $s→substring(0, 0);\n  #fm7Y4HNaSi7jG2v3 $b := $s→equals(\"other\");\n  #xuAIL5NdAZ1KtF5N $sc := $s→count;\n  #gTeb4Xd82bliP9Gm $s3 := $s→at(0);\n  #LOpKfIPlDMsVUP2W $x3 := $s→to_number;\n  #sFNR99MXq2qcNn6A // actions: see run actions: see run actions: see run\n  #GItB3zzQlGKLva8E // language\n  #xWOrqmm28D1CwUqw if false then {\n    #umPuRv6PUVDM7goa skip;\n  }\n  else { #xIklxic0fgwN21vq if false then {\n    #XvFU71wc3Jdh9ooK `return` ;\n  }\n  else { } } \n  #QUxDFwGdBho6So46 while true do {\n    #xqbiIUoiP2fqU19Z skip;\n  }\n  #xTXiWXDOypaCgzx2 for 0 ≤ i < 10 do {\n    #V7R2z1u1veJzGB88 `break` ;\n  }\n  #xZ1ELRun4mad1PW7 // function calls\n  #x3bFUlCOYCfYKcWI if $x < 0 then {\n    #ZjV6o09yGjKJeC5l code→main;\n  }\n  #k4PTDaIFHqcXFso3 data→x := 0;\n  #FBCl2AsiYBT2BkKd // microbit apis\n  #lY4IxiRSVHUv1prz data→img := @\\u267b→micro\\u003abit→create_image(\"\");\n}\n#Wc1pO4N99lJnJtZj\nvar x : Number {\n  transient = true;\n}\n#NdBhY6y4JCp6AVvX\naction do_stuff(#xoRhpqBWrHKQ1wbj p: Number) returns(#uPnKPMlUDYKjtTpH r: Number) {\n  #R3v0NLKiT3NZzVqb `return` 1;\n}\n#Ebw62Hb2wL0dFNZw\naction run(#X6GWR42GD1IO8W95 p: Action) {\n  #tvk7682eRC1Qgml0 $b := $p→is_invalid;\n  #xJH443yIol2Lq8Ex $p→run;\n}\n#x0V58dtFBOlyU9Fk\nvar @action : Action {\n  transient = true;\n}\n#QGy8p7ggwOnDXD4z\nvar img : ♻ micro\\u003abit → Image {\n  transient = true;\n}\n#xvqxk1q4qCZk22MO meta import micro\\u003abit_screen {\n  pub \"tgpxru\"\n  usage {\n    action `sync` toggle(x: Number, y: Number)\n    action `sync` plot_all()\n    action `sync` toggle_all()\n    action `async` fade_in(ms: Number)\n    action `async` fade_out(ms: Number)\n    action `sync` screenshot() returns(img: ♻ micro\\u003abit → Image)\n    action `sync` plot_bar_graph(value: Number, high: Number)\n  }\n  #OE9022wXGJBOumFg resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#P952wWx2TsBNbUPl meta import micro\\u003abit_senses {\n  pub \"jztbbx\"\n  usage {\n    action `sync` on_screen_up(body: Action)\n    action `sync` on_screen_down(body: Action)\n    action `sync` on_shake(body: Action)\n    action `sync` on_logo_up(body: Action)\n    action `sync` on_logo_down(body: Action)\n  }\n  #xtFHv49Gg2zXwu3M resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#nxBsrWkksKmQnONy meta import micro\\u003abit_game {\n  pub \"rwbwnc\"\n  usage {\n    action `sync` score() returns(score: Number)\n    action `sync` set_score(value: Number)\n    action `sync` life() returns(life: Number)\n    action `async` set_life(value: Number)\n    action `sync` add_score(points: Number)\n    action `async` add_life(lives: Number)\n    action `async` start_countdown(ms: Number)\n    action `async` game_over()\n    action `async` current_time() returns(ms: Number)\n    action `async` remove_life(life: Number)\n    action `async` level_up()\n    action `async` level() returns(lv: Number)\n    action `async` start_stopwatch()\n    action `sync` is_running() returns(running: Boolean)\n    action `async` show_score()\n    action `sync` is_game_over() returns(over: Boolean)\n  }\n  #iFGAT33WIPN92bpo resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#BVGhpbmca\ntable Thing {\n  type = \"Object\";\n  persistent = false;\n  fields {\n    #G6G2a0flquLAXiyj f : String\n  }\n}\n#DGIsFkv2N6nOcw2l meta import micro\\u003abit_serial {\n  pub \"lohjia\"\n  usage {\n    action `sync` write_line(text: String)\n    action `sync` write_number(value: Number)\n    action `sync` read_string() returns(msg: String)\n    action `sync` write_string(text: String)\n    action `sync` write_image(img: ♻ micro\\u003abit → Image)\n    action `sync` write_screen()\n    action `sync` read_screen()\n    action `sync` read_image() returns(img: ♻ micro\\u003abit → Image)\n    action `sync` write_value(name: String, value: Number)\n  }\n  #pGGACFQC2GSgng2H resolve micro\\u003abit = ♻ micro\\u003abit with {\n  }\n}\n#BD280UyphFhv6ijW meta import micro\\u003abit {\n  pub \"xgzgcy\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` tell_camera_to(@event: String)\n    action `sync` raise_alert_to(@event: String)\n    action `sync` on_notified(@event: String, body: Action)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_tone(frequency: Number, ms: Number)\n    action `sync` note_frequency(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n    action `sync` queue_event(body: Action, name: String)\n    action `async` ring_tone(frequency: Number)\n    action `sync` tell_remote_control_to(@event: String)\n    action `sync` map(value: Number, from_low: Number, from_high: Number, to_low: Number, to_high: Number) returns(r: Number)\n    action `sync` magnetic_force(dimension: String) returns(millig: Number)\n    action `sync` servo_write_pin(name: String, value: Number)\n    action `sync` servo_set_pulse(pin: String, micros: Number)\n    action `async` rest(ms: Number)\n    action `async` rotation(kind: String) returns(angle: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` set_pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Number)\n    action `sync` pixel_brightness(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Number)\n    action `sync` set_display_mode(mode: String)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` light_level() returns(light: Number)\n    action `sync` is_ble_required() returns(r: Boolean)\n    action `sync` signal_strength() returns(strength: Number)\n    action `sync` on_signal_strength_changed(body: Action)\n  }\n}\n",
  "xczaux": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"></xml>\n",
  "dceiba": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n  <block type=\"device_forever\" id=\"1\" x=\"22\" y=\"16\">\n    <statement name=\"HANDLER\">\n      <block type=\"device_plot\" id=\"2\" inline=\"true\">\n        <value name=\"x\">\n          <block type=\"math_number\" id=\"3\">\n            <field name=\"NUM\">0</field>\n          </block>\n        </value>\n        <value name=\"y\">\n          <block type=\"math_number\" id=\"4\">\n            <field name=\"NUM\">0</field>\n          </block>\n        </value>\n        <next>\n          <block type=\"device_pause\" id=\"5\" inline=\"true\">\n            <value name=\"pause\">\n              <block type=\"math_number\" id=\"6\">\n                <field name=\"NUM\">200</field>\n              </block>\n            </value>\n            <next>\n              <block type=\"device_clear_display\" id=\"7\">\n                <next>\n                  <block type=\"device_pause\" id=\"8\" inline=\"true\">\n                    <value name=\"pause\">\n                      <block type=\"math_number\" id=\"9\">\n                        <field name=\"NUM\">100</field>\n                      </block>\n                    </value>\n                  </block>\n                </next>\n              </block>\n            </next>\n          </block>\n        </next>\n      </block>\n    </statement>\n  </block>\n</xml>\n",
  "jcyhqq": "meta version \"v2.2,js,ctx,refs,localcloud,unicodemodel,allasync,upperplex\";\nmeta name \"flashing heart tutorial\";\nmeta rootId \"xJRCBH3YIz4bMjLLSt5QrX5U\";\nmeta hasIds \"yes\";\nmeta platform \"current\";\nmeta parentIds \"\";\n// control images with variables. #microbit #docs #tutorials #stepByStep\n#xkPpDa5IUqmg0Bd4\naction \\u00230_main() {\n  #xMZvXjdlMZuY7Gh2 // {box:avatar:avatar}\n  #TXbKj0n88SBT3ZHf // Let's begin by creating a **forever** loop so that the heart can continuously flash.\n  #CBojua4OheEvSsyS // {stcode}\n  #ZV0rfKH4IuiF3zOj // {/box}\n  #iZkyEfHTeHpYToEd basic[lib micro\\u003abit] →forever;\n  #hb1ScsYK7CtQY9OP where `implicit` \\_body\\_() {\n    #EzH5zRoLqL44TUmF // {box:avatar:avatar}\n    #jyAdrhhmtT4QzZZo // Now let's plot and display a heart image on the BBC micro:bit.\n    #xTUlIt18NLalsjIr // {stcode}\n    #K4vgzySzJftYLZpC // {/box}\n    #y4ytMLcGIthzjN1o basic[lib micro\\u003abit] →show_leds(\"0 1 0 1 0\\n1 1 1 1 1\\n1 1 1 1 1\\n0 1 1 1 0\\n0 0 1 0 0\", 400);\n    #at2Say7Gx8U2BYGv // {stcmd:run}\n    #MlJGHtZzGZjhJihV // {box:avatar:avatar}\n    #xP8t2A5p1B2evsLe // We need to pause for a little bit before clearing the screen or else the heart disappears immediately.\n    #yKM2h4ak62gaL9pC // {stcode}\n    #ZmWcEfydvWI4hGyG // {/box}\n    #zXZvzZp0XgYYaFrD basic[lib micro\\u003abit] →pause(500);\n    #XUfrbYD8sr3fKWw1 // {box:avatar:avatar}\n    #qco45OxAC5HxnC4v // Now we can clear the screen.\n    #h2ebe2tRVqF4neZS // {stcode}\n    #bObnG5tr7OOOOatS // {/box}\n    #x5Ki4UC3eCnl7l2C basic[lib micro\\u003abit] →clear_screen;\n    #IDViNSdGTOnRj9j7 // {box:avatar:avatar}\n    #z3WVR7UxQH8jY1TK // Again, we need to pause, this time before showing the image again.\n    #LN2StgzgB42hq3kR // {stcode}\n    #TCEAlSxTntoHyJEP // {/box}\n    #bg0wqIA3xh2krx02 basic[lib micro\\u003abit] →pause(500);\n  }\n  #sL2YLOSW5pT00Ai6 // {stcmd:compile}\n}\n#T6l6bj8oRmkmUB2v meta import micro\\u003abit {\n  pub \"xhvlgz\"\n  usage {\n    type Image\n    action `sync` \\_libinit()\n    action `async` pause(ms: Number)\n    action `sync` clear_screen()\n    action `sync` width(@this: ♻ micro\\u003abit → Image) returns(w: Number)\n    action `async` scroll_image(@this: ♻ micro\\u003abit → Image, x_offset_per_step: Number, interval: Number)\n    action `sync` button_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` plot(x: Number, y: Number)\n    action `sync` point(x: Number, y: Number) returns(on: Boolean)\n    action `async` show_string(text: String, interval: Number)\n    action `sync` unplot(x: Number, y: Number)\n    action `sync` on_button_pressed(name: String, body: Action)\n    action `async` show_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` compass_heading() returns(degrees: Number)\n    action `sync` acceleration(dimension: String) returns(millig: Number)\n    action `sync` digital_write_pin(name: String, value: Number)\n    action `sync` digital_read_pin(name: String) returns(value: Number)\n    action `sync` analog_read_pin(name: String) returns(value: Number)\n    action `sync` analog_write_pin(name: String, value: Number)\n    action `sync` create_image(leds: String) returns(img: ♻ micro\\u003abit → Image)\n    action `sync` brightness() returns(brightness: Number)\n    action `sync` set_brightness(value: Number)\n    action `async` show_animation(leds: String, interval: Number)\n    action `sync` running_time() returns(now: Number)\n    action `async` show_number(value: Number, interval: Number)\n    action `sync` set_pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number, value: Boolean)\n    action `sync` pixel(@this: ♻ micro\\u003abit → Image, x: Number, y: Number) returns(state: Boolean)\n    action `sync` clear(img: ♻ micro\\u003abit → Image)\n    action `sync` in_background(body: Action)\n    action `async` calibrate()\n    action `sync` forever(body: Action)\n    action `sync` pin_is_pressed(name: String) returns(pressed: Boolean)\n    action `sync` on_pin_pressed(name: String, body: Action)\n    action `sync` remote_control(@event: String)\n    action `sync` camera(@event: String)\n    action `sync` audio_recorder(@event: String)\n    action `sync` alert(@event: String)\n    action `sync` notify_event_registration(evid: String)\n    action `sync` add_button(text: String, @action: Action)\n    action `sync` reset()\n    action `sync` warning(message: String)\n    action `sync` analog_set_period(pin: String, micros: Number)\n    action `sync` analog_set_pitch_pin(name: String)\n    action `async` analog_pitch(frequency: Number, ms: Number)\n    action `async` plot_frame(@this: ♻ micro\\u003abit → Image, index: Number)\n    action `async` show_leds(leds: String, ms: Number)\n    action `async` play_note(frequency: Number, ms: Number)\n    action `sync` note(name: String) returns(frequency: Number)\n    action `sync` plot_leds(leds: String)\n    action `sync` plot_image(@this: ♻ micro\\u003abit → Image, x_offset: Number)\n    action `sync` temperature() returns(temp: Number)\n    action `sync` stop_animation()\n    action `async` show_frame(img: ♻ micro\\u003abit → Image, frame: Number)\n  }\n}\n#La2qRKrLbx4LxKmX\nvar heart : ♻ micro\\u003abit → Image {\n  transient = true;\n}\n#x4334a31V1ZL6vj2\naction main() {\n  #BmrvZRXOS4UrAj3l // {topic:td/lessons/flashing-heart/tutorial}\n  #xNXZYjYB26M2UR9a // {template:empty}\n  #xCHA3gKFfilgUMTF // {templatename:ADJ script}\n  #DPm4qTiKKiAoe50f // {widgets:}\n  #wUr6BCeteY5gewoV // {box:avatar:boothing}\n  #xVT2NZpWJlOxhD2j // {videoptr:td/videos/flashing-heart-0}\n  #xP342IFDvLzjwRal // Welcome! This tutorial will teach how to control images with variables. Let's get started!\n  #xgIGusXyGCBXRcP4 // {/box}\n}\n#xEYX48iEHbsTFSwp\nvar imageEditor : Picture {\n  is\\_resource = true;\n  url = \"https://microbit0.blob.core.windows.net/pub/twiswpxf\";\n  transient = true;\n}\n#xofTBUKer21CfPXD\nvar boothing : Picture {\n  is\\_resource = true;\n  url = \"https://microbit0.blob.core.windows.net/pub/vflboela\";\n  transient = true;\n}\n#Aftcl64H2g55Hyhu\nvar avatar : Picture {\n  is\\_resource = true;\n  url = \"https://microbit0.blob.core.windows.net/pub/lqakekjj\";\n  transient = true;\n}\n",
  "xyelfe": "# Add your Python code here. E.g.\nfrom microbit import *\n\n\nwhile True:\n    display.scroll('Hello, World!')\n    display.show(Image.HEART)\n    sleep(2000)\n"
 }
}
TDev.Browser.detect();

if (typeof module != "undefined" && module.exports) {
    module.exports = TDev;
    TDev.RT.Node.setup();
} else {
    TDev.Ticker.disable()
    TDev.Util.initGenericExtensions();
    TDev.RT.RTValue.initApis();
}

TDev.AST.Lexer.init();
TDev.api.initFrom();

if (typeof window != "undefined" && window.tdAfterLoadCallback) {
    var f = window.tdAfterLoadCallback;
    delete window.tdAfterLoadCallback;
    f(TDev);
}
