diff --git a/appengine/README.txt b/appengine/README.txt index 2d6d8342e..7bf4c48f6 100644 --- a/appengine/README.txt +++ b/appengine/README.txt @@ -18,7 +18,6 @@ blockly/ |- storage.py |- closure-library/ (Optional) `- static/ - |- apps/ |- blocks/ |- core/ |- demos/ diff --git a/appengine/app.yaml b/appengine/app.yaml index 90fbd00a2..84a0a6e61 100644 --- a/appengine/app.yaml +++ b/appengine/app.yaml @@ -10,44 +10,12 @@ handlers: - url: /blockly/.* static_files: redirect.html upload: redirect.html -# Code, Maze and Turtle moved from demos to apps on 29 Dec 2012. +# Code, Maze and Turtle moved from demos on 29 Dec 2012. - url: /static/demos/(code|maze|turtle)/.* static_files: redirect.html upload: redirect.html -# Vietnamese apps moved from vn to vi on 9 Jun 2012. -- url: /static/apps/.+/vn\.html - static_files: redirect.html - upload: redirect.html -# Code moved to index.html on 7 Aug 2013. -- url: /static/apps/code/code\.html - static_files: redirect.html - upload: redirect.html -# Code became language-agnostic on 20 Jul 2013. -- url: /static/apps/code/(de|en|hu|vi|zh_tw)\.html - static_files: redirect.html - upload: redirect.html -# Puzzle moved to Blockly Games on 15 Oct 2014. -- url: /static/apps/puzzle/.* - static_files: redirect.html - upload: redirect.html -# Maze moved to Blockly Games on 10 Nov 2014. -- url: /static/apps/maze/.* - static_files: redirect.html - upload: redirect.html -# Turtle moved to Blockly Games on 10 Nov 2014. -- url: /static/apps/turtle/.* - static_files: redirect.html - upload: redirect.html -# Graph moved from apps to demos on 10 Nov 2014. -- url: /static/apps/graph/.* - static_files: redirect.html - upload: redirect.html -# Plane moved from apps to demos on 13 Nov 2014. -- url: /static/apps/plane/.* - static_files: redirect.html - upload: redirect.html -# Block Factory moved from apps to demos on 16 Oct 2014. -- url: /static/apps/blockfactory/.* +# Apps was disbanded on 20 Nov 2014. +- url: /static/apps/.* static_files: redirect.html upload: redirect.html diff --git a/appengine/redirect.html b/appengine/redirect.html index e1b92efd1..55e083544 100644 --- a/appengine/redirect.html +++ b/appengine/redirect.html @@ -23,7 +23,6 @@ if (loc.match('/apps/code/code.html')) { // Code moved to index.html on 7 Aug 2013. loc = loc.replace('/code.html', '/index.html'); } else if (loc.match('/apps/code/zh_tw.html')) { - // Code became language-agnostic on 20 Jul 2013. // zh-tw was changed to zh-hans on 25 Nov 2013. loc = loc.replace('/zh_tw.html', '/index.html?lang=zh-hans'); } else if (loc.match('/apps/code/index.html')) { @@ -57,16 +56,8 @@ if (loc.match('/apps/puzzle/')) { } else if (loc.match('/apps/turtle/')) { // Turtle moved to Blockly Games on 10 Nov 2014. loc = 'https://blockly-games.appspot.com/turtle'; -} - -if (loc.match('/apps/graph/')) { - // Graph moved from apps to demos on 10 Nov 2014. - loc = loc.replace('/apps/', '/demos/'); -} else if (loc.match('/apps/plane/')) { - // Graph moved from apps to demos on 10 Nov 2014. - loc = loc.replace('/apps/', '/demos/'); -} else if (loc.match('/apps/blockfactory/')) { - // Block Factory moved from apps to demos on 16 Oct 2014. +} else if (loc.match('/apps/')) { + // Remaining apps moved to demos on 20 Nov 2014. loc = loc.replace('/apps/', '/demos/'); } diff --git a/apps/_soy/COPYING b/apps/_soy/COPYING deleted file mode 100644 index d64569567..000000000 --- a/apps/_soy/COPYING +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/apps/_soy/README b/apps/_soy/README deleted file mode 100644 index e3447f2d8..000000000 --- a/apps/_soy/README +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -Contents: - -+ SoyToJsSrcCompiler.jar - Executable jar that compiles template files into JavaScript files. - -+ SoyMsgExtractor.jar - Executable jar that extracts messages from template files into XLF files. - -+ soyutils.js - Helper utilities required by all JavaScript code that SoyToJsSrcCompiler - generates. Equivalent functionality to soyutils_usegoog.js, but this - version does not need Closure Library. - - -Instructions: - -+ A simple Hello World for JavaScript: - http://code.google.com/closure/templates/docs/helloworld_js.html - -+ Complete documentation: - http://code.google.com/closure/templates/ - -+ Closure Templates project on Google Code: - http://code.google.com/p/closure-templates/ - - -Notes: - -+ Closure Templates requires Java 6 or higher: - http://www.java.com/ diff --git a/apps/_soy/SoyMsgExtractor.jar b/apps/_soy/SoyMsgExtractor.jar deleted file mode 100644 index d7d261984..000000000 Binary files a/apps/_soy/SoyMsgExtractor.jar and /dev/null differ diff --git a/apps/_soy/SoyToJsSrcCompiler.jar b/apps/_soy/SoyToJsSrcCompiler.jar deleted file mode 100644 index 540a0702a..000000000 Binary files a/apps/_soy/SoyToJsSrcCompiler.jar and /dev/null differ diff --git a/apps/_soy/soyutils.js b/apps/_soy/soyutils.js deleted file mode 100644 index bde8e4133..000000000 --- a/apps/_soy/soyutils.js +++ /dev/null @@ -1,2767 +0,0 @@ -/* - * Copyright 2008 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview - * Utility functions and classes for Soy. - * - *

- * The top portion of this file contains utilities for Soy users:

- * - *

- * The bottom portion of this file contains utilities that should only be called - * by Soy-generated JS code. Please do not use these functions directly from - * your hand-writen code. Their names all start with '$$'. - * - * @author Garrett Boyer - * @author Mike Samuel - * @author Kai Huang - * @author Aharon Lanin - */ - - -// COPIED FROM nogoog_shim.js - -// Create closure namespaces. -var goog = goog || {}; - - -goog.DEBUG = false; - - -goog.inherits = function(childCtor, parentCtor) { - /** @constructor */ - function tempCtor() {} - tempCtor.prototype = parentCtor.prototype; - childCtor.superClass_ = parentCtor.prototype; - childCtor.prototype = new tempCtor(); - childCtor.prototype.constructor = childCtor; -}; - - -// Just enough browser detection for this file. -if (!goog.userAgent) { - goog.userAgent = (function() { - var userAgent = ""; - if ("undefined" !== typeof navigator && navigator - && "string" == typeof navigator.userAgent) { - userAgent = navigator.userAgent; - } - var isOpera = userAgent.indexOf('Opera') == 0; - return { - jscript: { - /** - * @type {boolean} - */ - HAS_JSCRIPT: 'ScriptEngine' in this - }, - /** - * @type {boolean} - */ - OPERA: isOpera, - /** - * @type {boolean} - */ - IE: !isOpera && userAgent.indexOf('MSIE') != -1, - /** - * @type {boolean} - */ - WEBKIT: !isOpera && userAgent.indexOf('WebKit') != -1 - }; - })(); -} - -if (!goog.asserts) { - goog.asserts = { - /** - * @param {*} condition Condition to check. - */ - assert: function (condition) { - if (!condition) { - throw Error('Assertion error'); - } - }, - /** - * @param {...*} var_args - */ - fail: function (var_args) {} - }; -} - - -// Stub out the document wrapper used by renderAs*. -if (!goog.dom) { - goog.dom = {}; - /** - * @param {Document=} d - * @constructor - */ - goog.dom.DomHelper = function(d) { - this.document_ = d || document; - }; - /** - * @return {!Document} - */ - goog.dom.DomHelper.prototype.getDocument = function() { - return this.document_; - }; - /** - * Creates a new element. - * @param {string} name Tag name. - * @return {!Element} - */ - goog.dom.DomHelper.prototype.createElement = function(name) { - return this.document_.createElement(name); - }; - /** - * Creates a new document fragment. - * @return {!DocumentFragment} - */ - goog.dom.DomHelper.prototype.createDocumentFragment = function() { - return this.document_.createDocumentFragment(); - }; -} - - -if (!goog.format) { - goog.format = { - insertWordBreaks: function(str, maxCharsBetweenWordBreaks) { - str = String(str); - - var resultArr = []; - var resultArrLen = 0; - - // These variables keep track of important state inside str. - var isInTag = false; // whether we're inside an HTML tag - var isMaybeInEntity = false; // whether we might be inside an HTML entity - var numCharsWithoutBreak = 0; // number of chars since last word break - var flushIndex = 0; // index of first char not yet flushed to resultArr - - for (var i = 0, n = str.length; i < n; ++i) { - var charCode = str.charCodeAt(i); - - // If hit maxCharsBetweenWordBreaks, and not space next, then add . - if (numCharsWithoutBreak >= maxCharsBetweenWordBreaks && - // space - charCode != 32) { - resultArr[resultArrLen++] = str.substring(flushIndex, i); - flushIndex = i; - resultArr[resultArrLen++] = goog.format.WORD_BREAK; - numCharsWithoutBreak = 0; - } - - if (isInTag) { - // If inside an HTML tag and we see '>', it's the end of the tag. - if (charCode == 62) { - isInTag = false; - } - - } else if (isMaybeInEntity) { - switch (charCode) { - // Inside an entity, a ';' is the end of the entity. - // The entity that just ended counts as one char, so increment - // numCharsWithoutBreak. - case 59: // ';' - isMaybeInEntity = false; - ++numCharsWithoutBreak; - break; - // If maybe inside an entity and we see '<', we weren't actually in - // an entity. But now we're inside and HTML tag. - case 60: // '<' - isMaybeInEntity = false; - isInTag = true; - break; - // If maybe inside an entity and we see ' ', we weren't actually in - // an entity. Just correct the state and reset the - // numCharsWithoutBreak since we just saw a space. - case 32: // ' ' - isMaybeInEntity = false; - numCharsWithoutBreak = 0; - break; - } - - } else { // !isInTag && !isInEntity - switch (charCode) { - // When not within a tag or an entity and we see '<', we're now - // inside an HTML tag. - case 60: // '<' - isInTag = true; - break; - // When not within a tag or an entity and we see '&', we might be - // inside an entity. - case 38: // '&' - isMaybeInEntity = true; - break; - // When we see a space, reset the numCharsWithoutBreak count. - case 32: // ' ' - numCharsWithoutBreak = 0; - break; - // When we see a non-space, increment the numCharsWithoutBreak. - default: - ++numCharsWithoutBreak; - break; - } - } - } - - // Flush the remaining chars at the end of the string. - resultArr[resultArrLen++] = str.substring(flushIndex); - - return resultArr.join(''); - }, - /** - * String inserted as a word break by insertWordBreaks(). Safari requires - * , Opera needs the 'shy' entity, though this will give a - * visible hyphen at breaks. Other browsers just use . - * @type {string} - * @private - */ - WORD_BREAK: goog.userAgent.WEBKIT - ? '' : goog.userAgent.OPERA ? '­' : '' - }; -} - - -if (!goog.i18n) { - goog.i18n = { - bidi: { - /** - * Check the directionality of a piece of text, return true if the piece - * of text should be laid out in RTL direction. - * @param {string} text The piece of text that need to be detected. - * @param {boolean=} opt_isHtml Whether {@code text} is HTML/HTML-escaped. - * Default: false. - * @return {boolean} - * @private - */ - detectRtlDirectionality: function(text, opt_isHtml) { - text = soyshim.$$bidiStripHtmlIfNecessary_(text, opt_isHtml); - return soyshim.$$bidiRtlWordRatio_(text) - > soyshim.$$bidiRtlDetectionThreshold_; - } - } - }; -} - -/** - * Directionality enum. - * @enum {number} - */ -goog.i18n.bidi.Dir = { - RTL: -1, - UNKNOWN: 0, - LTR: 1 -}; - - -/** - * Convert a directionality given in various formats to a goog.i18n.bidi.Dir - * constant. Useful for interaction with different standards of directionality - * representation. - * - * @param {goog.i18n.bidi.Dir|number|boolean} givenDir Directionality given in - * one of the following formats: - * 1. A goog.i18n.bidi.Dir constant. - * 2. A number (positive = LRT, negative = RTL, 0 = unknown). - * 3. A boolean (true = RTL, false = LTR). - * @return {goog.i18n.bidi.Dir} A goog.i18n.bidi.Dir constant matching the given - * directionality. - */ -goog.i18n.bidi.toDir = function(givenDir) { - if (typeof givenDir == 'number') { - return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : - givenDir < 0 ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.UNKNOWN; - } else { - return givenDir ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR; - } -}; - - -/** - * Utility class for formatting text for display in a potentially - * opposite-directionality context without garbling. Provides the following - * functionality: - * - * @param {goog.i18n.bidi.Dir|number|boolean} dir The context - * directionality as a number - * (positive = LRT, negative = RTL, 0 = unknown). - * @constructor - */ -goog.i18n.BidiFormatter = function(dir) { - this.dir_ = goog.i18n.bidi.toDir(dir); -}; - - -/** - * Returns 'dir="ltr"' or 'dir="rtl"', depending on {@code text}'s estimated - * directionality, if it is not the same as the context directionality. - * Otherwise, returns the empty string. - * - * @param {string} text Text whose directionality is to be estimated. - * @param {boolean=} opt_isHtml Whether {@code text} is HTML / HTML-escaped. - * Default: false. - * @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for - * LTR text in non-LTR context; else, the empty string. - */ -goog.i18n.BidiFormatter.prototype.dirAttr = function (text, opt_isHtml) { - var dir = soy.$$bidiTextDir(text, opt_isHtml); - return dir && dir != this.dir_ ? dir < 0 ? 'dir="rtl"' : 'dir="ltr"' : ''; -}; - -/** - * Returns the trailing horizontal edge, i.e. "right" or "left", depending on - * the global bidi directionality. - * @return {string} "left" for RTL context and "right" otherwise. - */ -goog.i18n.BidiFormatter.prototype.endEdge = function () { - return this.dir_ < 0 ? 'left' : 'right'; -}; - -/** - * Returns the Unicode BiDi mark matching the context directionality (LRM for - * LTR context directionality, RLM for RTL context directionality), or the - * empty string for neutral / unknown context directionality. - * - * @return {string} LRM for LTR context directionality and RLM for RTL context - * directionality. - */ -goog.i18n.BidiFormatter.prototype.mark = function () { - return ( - (this.dir_ > 0) ? '\u200E' /*LRM*/ : - (this.dir_ < 0) ? '\u200F' /*RLM*/ : - ''); -}; - -/** - * Returns a Unicode BiDi mark matching the context directionality (LRM or RLM) - * if the directionality or the exit directionality of {@code text} are opposite - * to the context directionality. Otherwise returns the empty string. - * - * @param {string} text The input text. - * @param {boolean=} opt_isHtml Whether {@code text} is HTML / HTML-escaped. - * Default: false. - * @return {string} A Unicode bidi mark matching the global directionality or - * the empty string. - */ -goog.i18n.BidiFormatter.prototype.markAfter = function (text, opt_isHtml) { - var dir = soy.$$bidiTextDir(text, opt_isHtml); - return soyshim.$$bidiMarkAfterKnownDir_(this.dir_, dir, text, opt_isHtml); -}; - -/** - * Formats a string of unknown directionality for use in HTML output of the - * context directionality, so an opposite-directionality string is neither - * garbled nor garbles what follows it. - * - * @param {string} str The input text. - * @param {boolean=} placeholder This argument exists for consistency with the - * Closure Library. Specifying it has no effect. - * @return {string} Input text after applying the above processing. - */ -goog.i18n.BidiFormatter.prototype.spanWrap = function(str, placeholder) { - str = String(str); - var textDir = soy.$$bidiTextDir(str, true); - var reset = soyshim.$$bidiMarkAfterKnownDir_(this.dir_, textDir, str, true); - if (textDir > 0 && this.dir_ <= 0) { - str = '' + str + ''; - } else if (textDir < 0 && this.dir_ >= 0) { - str = '' + str + ''; - } - return str + reset; -}; - -/** - * Returns the leading horizontal edge, i.e. "left" or "right", depending on - * the global bidi directionality. - * @return {string} "right" for RTL context and "left" otherwise. - */ -goog.i18n.BidiFormatter.prototype.startEdge = function () { - return this.dir_ < 0 ? 'right' : 'left'; -}; - -/** - * Formats a string of unknown directionality for use in plain-text output of - * the context directionality, so an opposite-directionality string is neither - * garbled nor garbles what follows it. - * As opposed to {@link #spanWrap}, this makes use of unicode BiDi formatting - * characters. In HTML, its *only* valid use is inside of elements that do not - * allow mark-up, e.g. an 'option' tag. - * - * @param {string} str The input text. - * @param {boolean=} placeholder This argument exists for consistency with the - * Closure Library. Specifying it has no effect. - * @return {string} Input text after applying the above processing. - */ -goog.i18n.BidiFormatter.prototype.unicodeWrap = function(str, placeholder) { - str = String(str); - var textDir = soy.$$bidiTextDir(str, true); - var reset = soyshim.$$bidiMarkAfterKnownDir_(this.dir_, textDir, str, true); - if (textDir > 0 && this.dir_ <= 0) { - str = '\u202A' + str + '\u202C'; - } else if (textDir < 0 && this.dir_ >= 0) { - str = '\u202B' + str + '\u202C'; - } - return str + reset; -}; - - -if (!goog.string) { - goog.string = { - /** - * Converts \r\n, \r, and \n to
s - * @param {*} str The string in which to convert newlines. - * @param {boolean=} opt_xml Whether to use XML compatible tags. - * @return {string} A copy of {@code str} with converted newlines. - */ - newLineToBr: function(str, opt_xml) { - - str = String(str); - - // This quick test helps in the case when there are no chars to replace, - // in the worst case this makes barely a difference to the time taken. - if (!goog.string.NEWLINE_TO_BR_RE_.test(str)) { - return str; - } - - return str.replace(/(\r\n|\r|\n)/g, opt_xml ? '
' : '
'); - }, - urlEncode: encodeURIComponent, - /** - * Regular expression used within newlineToBr(). - * @type {RegExp} - * @private - */ - NEWLINE_TO_BR_RE_: /[\r\n]/ - }; -} - -/** - * Utility class to facilitate much faster string concatenation in IE, - * using Array.join() rather than the '+' operator. For other browsers - * we simply use the '+' operator. - * - * @param {Object|number|string|boolean=} opt_a1 Optional first initial item - * to append. - * @param {...Object|number|string|boolean} var_args Other initial items to - * append, e.g., new goog.string.StringBuffer('foo', 'bar'). - * @constructor - */ -goog.string.StringBuffer = function(opt_a1, var_args) { - /** - * Internal buffer for the string to be concatenated. - * @type {string|Array} - * @private - */ - this.buffer_ = goog.userAgent.jscript.HAS_JSCRIPT ? [] : ''; - - if (opt_a1 != null) { - this.append.apply(this, arguments); - } -}; - - -/** - * Length of internal buffer (faster than calling buffer_.length). - * Only used for IE. - * @type {number} - * @private - */ -goog.string.StringBuffer.prototype.bufferLength_ = 0; - -/** - * Appends one or more items to the string. - * - * Calling this with null, undefined, or empty arguments is an error. - * - * @param {Object|number|string|boolean} a1 Required first string. - * @param {Object|number|string|boolean=} opt_a2 Optional second string. - * @param {...Object|number|string|boolean} var_args Other items to append, - * e.g., sb.append('foo', 'bar', 'baz'). - * @return {goog.string.StringBuffer} This same StringBuilder object. - */ -goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) { - - if (goog.userAgent.jscript.HAS_JSCRIPT) { - if (opt_a2 == null) { // no second argument (note: undefined == null) - // Array assignment is 2x faster than Array push. Also, use a1 - // directly to avoid arguments instantiation, another 2x improvement. - this.buffer_[this.bufferLength_++] = a1; - } else { - var arr = /**@type {Array.}*/(this.buffer_); - arr.push.apply(arr, arguments); - this.bufferLength_ = this.buffer_.length; - } - - } else { - - // Use a1 directly to avoid arguments instantiation for single-arg case. - this.buffer_ += a1; - if (opt_a2 != null) { // no second argument (note: undefined == null) - for (var i = 1; i < arguments.length; i++) { - this.buffer_ += arguments[i]; - } - } - } - - return this; -}; - - -/** - * Clears the string. - */ -goog.string.StringBuffer.prototype.clear = function() { - - if (goog.userAgent.jscript.HAS_JSCRIPT) { - this.buffer_.length = 0; // reuse array to avoid creating new object - this.bufferLength_ = 0; - - } else { - this.buffer_ = ''; - } -}; - - -/** - * Returns the concatenated string. - * - * @return {string} The concatenated string. - */ -goog.string.StringBuffer.prototype.toString = function() { - - if (goog.userAgent.jscript.HAS_JSCRIPT) { - var str = this.buffer_.join(''); - // Given a string with the entire contents, simplify the StringBuilder by - // setting its contents to only be this string, rather than many fragments. - this.clear(); - if (str) { - this.append(str); - } - return str; - - } else { - return /** @type {string} */ (this.buffer_); - } -}; - - -if (!goog.soy) goog.soy = { - /** - * Helper function to render a Soy template and then set the - * output string as the innerHTML of an element. It is recommended - * to use this helper function instead of directly setting - * innerHTML in your hand-written code, so that it will be easier - * to audit the code for cross-site scripting vulnerabilities. - * - * @param {Function} template The Soy template defining element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Object=} opt_injectedData The injected data for the template. - * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM - * nodes will be created. - */ - renderAsElement: function( - template, opt_templateData, opt_injectedData, opt_dom) { - return /** @type {!Element} */ (soyshim.$$renderWithWrapper_( - template, opt_templateData, opt_dom, true /* asElement */, - opt_injectedData)); - }, - /** - * Helper function to render a Soy template into a single node or - * a document fragment. If the rendered HTML string represents a - * single node, then that node is returned (note that this is - * *not* a fragment, despite them name of the method). Otherwise a - * document fragment is returned containing the rendered nodes. - * - * @param {Function} template The Soy template defining element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Object=} opt_injectedData The injected data for the template. - * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM - * nodes will be created. - * @return {!Node} The resulting node or document fragment. - */ - renderAsFragment: function( - template, opt_templateData, opt_injectedData, opt_dom) { - return soyshim.$$renderWithWrapper_( - template, opt_templateData, opt_dom, false /* asElement */, - opt_injectedData); - }, - /** - * Helper function to render a Soy template and then set the output string as - * the innerHTML of an element. It is recommended to use this helper function - * instead of directly setting innerHTML in your hand-written code, so that it - * will be easier to audit the code for cross-site scripting vulnerabilities. - * - * NOTE: New code should consider using goog.soy.renderElement instead. - * - * @param {Element} element The element whose content we are rendering. - * @param {Function} template The Soy template defining the element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Object=} opt_injectedData The injected data for the template. - */ - renderElement: function( - element, template, opt_templateData, opt_injectedData) { - element.innerHTML = template(opt_templateData, null, opt_injectedData); - }, - data: {} -}; - - -/** - * A type of textual content. - * - * This is an enum of type Object so that these values are unforgeable. - * - * @enum {!Object} - */ -goog.soy.data.SanitizedContentKind = { - - /** - * A snippet of HTML that does not start or end inside a tag, comment, entity, - * or DOCTYPE; and that does not contain any executable code - * (JS, {@code }s, etc.) from a different trust domain. - */ - HTML: {}, - - /** - * Executable Javascript code or expression, safe for insertion in a - * script-tag or event handler context, known to be free of any - * attacker-controlled scripts. This can either be side-effect-free - * Javascript (such as JSON) or Javascript that entirely under Google's - * control. - */ - JS: goog.DEBUG ? {sanitizedContentJsStrChars: true} : {}, - - /** - * A sequence of code units that can appear between quotes (either kind) in a - * JS program without causing a parse error, and without causing any side - * effects. - *

- * The content should not contain unescaped quotes, newlines, or anything else - * that would cause parsing to fail or to cause a JS parser to finish the - * string its parsing inside the content. - *

- * The content must also not end inside an escape sequence ; no partial octal - * escape sequences or odd number of '{@code \}'s at the end. - */ - JS_STR_CHARS: {}, - - /** A properly encoded portion of a URI. */ - URI: {}, - - /** - * Repeated attribute names and values. For example, - * {@code dir="ltr" foo="bar" onclick="trustedFunction()" checked}. - */ - ATTRIBUTES: goog.DEBUG ? {sanitizedContentHtmlAttribute: true} : {}, - - // TODO: Consider separating rules, declarations, and values into - // separate types, but for simplicity, we'll treat explicitly blessed - // SanitizedContent as allowed in all of these contexts. - /** - * A CSS3 declaration, property, value or group of semicolon separated - * declarations. - */ - CSS: {}, - - /** - * Unsanitized plain-text content. - * - * This is effectively the "null" entry of this enum, and is sometimes used - * to explicitly mark content that should never be used unescaped. Since any - * string is safe to use as text, being of ContentKind.TEXT makes no - * guarantees about its safety in any other context such as HTML. - */ - TEXT: {} -}; - - - -/** - * A string-like object that carries a content-type. - * - * IMPORTANT! Do not create these directly, nor instantiate the subclasses. - * Instead, use a trusted, centrally reviewed library as endorsed by your team - * to generate these objects. Otherwise, you risk accidentally creating - * SanitizedContent that is attacker-controlled and gets evaluated unescaped in - * templates. - * - * @constructor - */ -goog.soy.data.SanitizedContent = function() { - throw Error('Do not instantiate directly'); -}; - - -/** - * The context in which this content is safe from XSS attacks. - * @type {goog.soy.data.SanitizedContentKind} - */ -goog.soy.data.SanitizedContent.prototype.contentKind; - - -/** - * The already-safe content. - * @type {string} - */ -goog.soy.data.SanitizedContent.prototype.content; - - -/** @override */ -goog.soy.data.SanitizedContent.prototype.toString = function() { - return this.content; -}; - - -var soy = { esc: {} }; -var soydata = {}; -soydata.VERY_UNSAFE = {}; -var soyshim = { $$DEFAULT_TEMPLATE_DATA_: {} }; -/** - * Helper function to render a Soy template into a single node or a document - * fragment. If the rendered HTML string represents a single node, then that - * node is returned. Otherwise a document fragment is created and returned - * (wrapped in a DIV element if #opt_singleNode is true). - * - * @param {Function} template The Soy template defining the element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM - * nodes will be created. - * @param {boolean=} opt_asElement Whether to wrap the fragment in an - * element if the template does not render a single element. If true, - * result is always an Element. - * @param {Object=} opt_injectedData The injected data for the template. - * @return {!Node} The resulting node or document fragment. - * @private - */ -soyshim.$$renderWithWrapper_ = function( - template, opt_templateData, opt_dom, opt_asElement, opt_injectedData) { - - var dom = opt_dom || document; - var wrapper = dom.createElement('div'); - wrapper.innerHTML = template( - opt_templateData || soyshim.$$DEFAULT_TEMPLATE_DATA_, undefined, - opt_injectedData); - - // If the template renders as a single element, return it. - if (wrapper.childNodes.length == 1) { - var firstChild = wrapper.firstChild; - if (!opt_asElement || firstChild.nodeType == 1 /* Element */) { - return /** @type {!Node} */ (firstChild); - } - } - - // If we're forcing it to be a single element, return the wrapper DIV. - if (opt_asElement) { - return wrapper; - } - - // Otherwise, create and return a fragment. - var fragment = dom.createDocumentFragment(); - while (wrapper.firstChild) { - fragment.appendChild(wrapper.firstChild); - } - return fragment; -}; - - -/** - * Returns a Unicode BiDi mark matching bidiGlobalDir (LRM or RLM) if the - * directionality or the exit directionality of text are opposite to - * bidiGlobalDir. Otherwise returns the empty string. - * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes - * in text, making the logic suitable for HTML and HTML-escaped text. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @param {number} dir text's directionality: 1 if ltr, -1 if rtl, 0 if unknown. - * @param {string} text The text whose directionality is to be estimated. - * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped. - * Default: false. - * @return {string} A Unicode bidi mark matching bidiGlobalDir, or - * the empty string when text's overall and exit directionalities both match - * bidiGlobalDir, or bidiGlobalDir is 0 (unknown). - * @private - */ -soyshim.$$bidiMarkAfterKnownDir_ = function( - bidiGlobalDir, dir, text, opt_isHtml) { - return ( - bidiGlobalDir > 0 && (dir < 0 || - soyshim.$$bidiIsRtlExitText_(text, opt_isHtml)) ? '\u200E' : // LRM - bidiGlobalDir < 0 && (dir > 0 || - soyshim.$$bidiIsLtrExitText_(text, opt_isHtml)) ? '\u200F' : // RLM - ''); -}; - - -/** - * Strips str of any HTML mark-up and escapes. Imprecise in several ways, but - * precision is not very important, since the result is only meant to be used - * for directionality detection. - * @param {string} str The string to be stripped. - * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped. - * Default: false. - * @return {string} The stripped string. - * @private - */ -soyshim.$$bidiStripHtmlIfNecessary_ = function(str, opt_isHtml) { - return opt_isHtml ? str.replace(soyshim.$$BIDI_HTML_SKIP_RE_, ' ') : str; -}; - - -/** - * Simplified regular expression for am HTML tag (opening or closing) or an HTML - * escape - the things we want to skip over in order to ignore their ltr - * characters. - * @type {RegExp} - * @private - */ -soyshim.$$BIDI_HTML_SKIP_RE_ = /<[^>]*>|&[^;]+;/g; - - -/** - * A practical pattern to identify strong LTR character. This pattern is not - * theoretically correct according to unicode standard. It is simplified for - * performance and small code size. - * @type {string} - * @private - */ -soyshim.$$bidiLtrChars_ = - 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' + - '\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF'; - - -/** - * A practical pattern to identify strong neutral and weak character. This - * pattern is not theoretically correct according to unicode standard. It is - * simplified for performance and small code size. - * @type {string} - * @private - */ -soyshim.$$bidiNeutralChars_ = - '\u0000-\u0020!-@[-`{-\u00BF\u00D7\u00F7\u02B9-\u02FF\u2000-\u2BFF'; - - -/** - * A practical pattern to identify strong RTL character. This pattern is not - * theoretically correct according to unicode standard. It is simplified for - * performance and small code size. - * @type {string} - * @private - */ -soyshim.$$bidiRtlChars_ = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC'; - - -/** - * Regular expressions to check if a piece of text is of RTL directionality - * on first character with strong directionality. - * @type {RegExp} - * @private - */ -soyshim.$$bidiRtlDirCheckRe_ = new RegExp( - '^[^' + soyshim.$$bidiLtrChars_ + ']*[' + soyshim.$$bidiRtlChars_ + ']'); - - -/** - * Regular expressions to check if a piece of text is of neutral directionality. - * Url are considered as neutral. - * @type {RegExp} - * @private - */ -soyshim.$$bidiNeutralDirCheckRe_ = new RegExp( - '^[' + soyshim.$$bidiNeutralChars_ + ']*$|^http://'); - - -/** - * Check the directionality of the a piece of text based on the first character - * with strong directionality. - * @param {string} str string being checked. - * @return {boolean} return true if rtl directionality is being detected. - * @private - */ -soyshim.$$bidiIsRtlText_ = function(str) { - return soyshim.$$bidiRtlDirCheckRe_.test(str); -}; - - -/** - * Check the directionality of the a piece of text based on the first character - * with strong directionality. - * @param {string} str string being checked. - * @return {boolean} true if all characters have neutral directionality. - * @private - */ -soyshim.$$bidiIsNeutralText_ = function(str) { - return soyshim.$$bidiNeutralDirCheckRe_.test(str); -}; - - -/** - * This constant controls threshold of rtl directionality. - * @type {number} - * @private - */ -soyshim.$$bidiRtlDetectionThreshold_ = 0.40; - - -/** - * Returns the RTL ratio based on word count. - * @param {string} str the string that need to be checked. - * @return {number} the ratio of RTL words among all words with directionality. - * @private - */ -soyshim.$$bidiRtlWordRatio_ = function(str) { - var rtlCount = 0; - var totalCount = 0; - var tokens = str.split(' '); - for (var i = 0; i < tokens.length; i++) { - if (soyshim.$$bidiIsRtlText_(tokens[i])) { - rtlCount++; - totalCount++; - } else if (!soyshim.$$bidiIsNeutralText_(tokens[i])) { - totalCount++; - } - } - - return totalCount == 0 ? 0 : rtlCount / totalCount; -}; - - -/** - * Regular expressions to check if the last strongly-directional character in a - * piece of text is LTR. - * @type {RegExp} - * @private - */ -soyshim.$$bidiLtrExitDirCheckRe_ = new RegExp( - '[' + soyshim.$$bidiLtrChars_ + '][^' + soyshim.$$bidiRtlChars_ + ']*$'); - - -/** - * Regular expressions to check if the last strongly-directional character in a - * piece of text is RTL. - * @type {RegExp} - * @private - */ -soyshim.$$bidiRtlExitDirCheckRe_ = new RegExp( - '[' + soyshim.$$bidiRtlChars_ + '][^' + soyshim.$$bidiLtrChars_ + ']*$'); - - -/** - * Check if the exit directionality a piece of text is LTR, i.e. if the last - * strongly-directional character in the string is LTR. - * @param {string} str string being checked. - * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped. - * Default: false. - * @return {boolean} Whether LTR exit directionality was detected. - * @private - */ -soyshim.$$bidiIsLtrExitText_ = function(str, opt_isHtml) { - str = soyshim.$$bidiStripHtmlIfNecessary_(str, opt_isHtml); - return soyshim.$$bidiLtrExitDirCheckRe_.test(str); -}; - - -/** - * Check if the exit directionality a piece of text is RTL, i.e. if the last - * strongly-directional character in the string is RTL. - * @param {string} str string being checked. - * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped. - * Default: false. - * @return {boolean} Whether RTL exit directionality was detected. - * @private - */ -soyshim.$$bidiIsRtlExitText_ = function(str, opt_isHtml) { - str = soyshim.$$bidiStripHtmlIfNecessary_(str, opt_isHtml); - return soyshim.$$bidiRtlExitDirCheckRe_.test(str); -}; - - -// ============================================================================= -// COPIED FROM soyutils_usegoog.js - - -// ----------------------------------------------------------------------------- -// StringBuilder (compatible with the 'stringbuilder' code style). - - -/** - * Utility class to facilitate much faster string concatenation in IE, - * using Array.join() rather than the '+' operator. For other browsers - * we simply use the '+' operator. - * - * @param {Object} var_args Initial items to append, - * e.g., new soy.StringBuilder('foo', 'bar'). - * @constructor - */ -soy.StringBuilder = goog.string.StringBuffer; - - -// ----------------------------------------------------------------------------- -// soydata: Defines typed strings, e.g. an HTML string {@code "ac"} is -// semantically distinct from the plain text string {@code "ac"} and smart -// templates can take that distinction into account. - -/** - * A type of textual content. - * - * This is an enum of type Object so that these values are unforgeable. - * - * @enum {!Object} - */ -soydata.SanitizedContentKind = goog.soy.data.SanitizedContentKind; - - -/** - * Content of type {@link soydata.SanitizedContentKind.HTML}. - * - * The content is a string of HTML that can safely be embedded in a PCDATA - * context in your app. If you would be surprised to find that an HTML - * sanitizer produced {@code s} (e.g. it runs code or fetches bad URLs) and - * you wouldn't write a template that produces {@code s} on security or privacy - * grounds, then don't pass {@code s} here. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedHtml = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedHtml, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedHtml.prototype.contentKind = soydata.SanitizedContentKind.HTML; - - -/** - * Content of type {@link soydata.SanitizedContentKind.JS}. - * - * The content is Javascript source that when evaluated does not execute any - * attacker-controlled scripts. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedJs = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedJs, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedJs.prototype.contentKind = - soydata.SanitizedContentKind.JS; - - -/** - * Content of type {@link soydata.SanitizedContentKind.JS_STR_CHARS}. - * - * The content can be safely inserted as part of a single- or double-quoted - * string without terminating the string. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedJsStrChars = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedJsStrChars, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedJsStrChars.prototype.contentKind = - soydata.SanitizedContentKind.JS_STR_CHARS; - - -/** - * Content of type {@link soydata.SanitizedContentKind.URI}. - * - * The content is a URI chunk that the caller knows is safe to emit in a - * template. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedUri = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedUri, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedUri.prototype.contentKind = soydata.SanitizedContentKind.URI; - - -/** - * Content of type {@link soydata.SanitizedContentKind.ATTRIBUTES}. - * - * The content should be safely embeddable within an open tag, such as a - * key="value" pair. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedHtmlAttribute = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedHtmlAttribute, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedHtmlAttribute.prototype.contentKind = - soydata.SanitizedContentKind.ATTRIBUTES; - - -/** - * Content of type {@link soydata.SanitizedContentKind.CSS}. - * - * The content is non-attacker-exploitable CSS, such as {@code color:#c3d9ff}. - * - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.SanitizedCss = function() { - goog.soy.data.SanitizedContent.call(this); // Throws an exception. -}; -goog.inherits(soydata.SanitizedCss, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.SanitizedCss.prototype.contentKind = - soydata.SanitizedContentKind.CSS; - - -/** - * Unsanitized plain text string. - * - * While all strings are effectively safe to use as a plain text, there are no - * guarantees about safety in any other context such as HTML. This is - * sometimes used to mark that should never be used unescaped. - * - * @param {*} content Plain text with no guarantees. - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ -soydata.UnsanitizedText = function(content) { - /** @override */ - this.content = String(content); -}; -goog.inherits(soydata.UnsanitizedText, goog.soy.data.SanitizedContent); - -/** @override */ -soydata.UnsanitizedText.prototype.contentKind = - soydata.SanitizedContentKind.TEXT; - - -/** - * Creates a factory for SanitizedContent types. - * - * This is a hack so that the soydata.VERY_UNSAFE.ordainSanitized* can - * instantiate Sanitized* classes, without making the Sanitized* constructors - * publicly usable. Requiring all construction to use the VERY_UNSAFE names - * helps callers and their reviewers easily tell that creating SanitizedContent - * is not always safe and calls for careful review. - * - * @param {function(new: T, string)} ctor A constructor. - * @return {!function(*): T} A factory that takes content and returns a - * new instance. - * @template T - * @private - */ -soydata.$$makeSanitizedContentFactory_ = function(ctor) { - /** @constructor */ - function InstantiableCtor() {} - InstantiableCtor.prototype = ctor.prototype; - return function(content) { - var result = new InstantiableCtor(); - result.content = String(content); - return result; - }; -}; - - -// ----------------------------------------------------------------------------- -// Sanitized content ordainers. Please use these with extreme caution (with the -// exception of markUnsanitizedText). A good recommendation is to limit usage -// of these to just a handful of files in your source tree where usages can be -// carefully audited. - - -/** - * Protects a string from being used in an noAutoescaped context. - * - * This is useful for content where there is significant risk of accidental - * unescaped usage in a Soy template. A great case is for user-controlled - * data that has historically been a source of vulernabilities. - * - * @param {*} content Text to protect. - * @return {!soydata.UnsanitizedText} A wrapper that is rejected by the - * Soy noAutoescape print directive. - */ -soydata.markUnsanitizedText = function(content) { - return new soydata.UnsanitizedText(content); -}; - - -/** - * Takes a leap of faith that the provided content is "safe" HTML. - * - * @param {*} content A string of HTML that can safely be embedded in - * a PCDATA context in your app. If you would be surprised to find that an - * HTML sanitizer produced {@code s} (e.g. it runs code or fetches bad URLs) - * and you wouldn't write a template that produces {@code s} on security or - * privacy grounds, then don't pass {@code s} here. - * @return {!soydata.SanitizedHtml} Sanitized content wrapper that - * indicates to Soy not to escape when printed as HTML. - */ -soydata.VERY_UNSAFE.ordainSanitizedHtml = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedHtml); - - -/** - * Takes a leap of faith that the provided content is "safe" (non-attacker- - * controlled, XSS-free) Javascript. - * - * @param {*} content Javascript source that when evaluated does not - * execute any attacker-controlled scripts. - * @return {!soydata.SanitizedJs} Sanitized content wrapper that indicates to - * Soy not to escape when printed as Javascript source. - */ -soydata.VERY_UNSAFE.ordainSanitizedJs = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedJs); - - -// TODO: This function is probably necessary, either externally or internally -// as an implementation detail. Generally, plain text will always work here, -// as there's no harm to unescaping the string and then re-escaping when -// finally printed. -/** - * Takes a leap of faith that the provided content can be safely embedded in - * a Javascript string without re-esacping. - * - * @param {*} content Content that can be safely inserted as part of a - * single- or double-quoted string without terminating the string. - * @return {!soydata.SanitizedJsStrChars} Sanitized content wrapper that - * indicates to Soy not to escape when printed in a JS string. - */ -soydata.VERY_UNSAFE.ordainSanitizedJsStrChars = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedJsStrChars); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as a URI - * in a Soy template. - * - * This creates a Soy SanitizedContent object which indicates to Soy there is - * no need to escape it when printed as a URI (e.g. in an href or src - * attribute), such as if it's already been encoded or if it's a Javascript: - * URI. - * - * @param {*} content A chunk of URI that the caller knows is safe to - * emit in a template. - * @return {!soydata.SanitizedUri} Sanitized content wrapper that indicates to - * Soy not to escape or filter when printed in URI context. - */ -soydata.VERY_UNSAFE.ordainSanitizedUri = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedUri); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as an - * HTML attribute. - * - * @param {*} content An attribute name and value, such as - * {@code dir="ltr"}. - * @return {!soydata.SanitizedHtmlAttribute} Sanitized content wrapper that - * indicates to Soy not to escape when printed as an HTML attribute. - */ -soydata.VERY_UNSAFE.ordainSanitizedHtmlAttribute = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedHtmlAttribute); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as CSS - * in a style attribute or block. - * - * @param {*} content CSS, such as {@code color:#c3d9ff}. - * @return {!soydata.SanitizedCss} Sanitized CSS wrapper that indicates to - * Soy there is no need to escape or filter when printed in CSS context. - */ -soydata.VERY_UNSAFE.ordainSanitizedCss = - soydata.$$makeSanitizedContentFactory_(soydata.SanitizedCss); - - -// ----------------------------------------------------------------------------- -// Public utilities. - - -/** - * Helper function to render a Soy template and then set the output string as - * the innerHTML of an element. It is recommended to use this helper function - * instead of directly setting innerHTML in your hand-written code, so that it - * will be easier to audit the code for cross-site scripting vulnerabilities. - * - * NOTE: New code should consider using goog.soy.renderElement instead. - * - * @param {Element} element The element whose content we are rendering. - * @param {Function} template The Soy template defining the element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Object=} opt_injectedData The injected data for the template. - */ -soy.renderElement = goog.soy.renderElement; - - -/** - * Helper function to render a Soy template into a single node or a document - * fragment. If the rendered HTML string represents a single node, then that - * node is returned (note that this is *not* a fragment, despite them name of - * the method). Otherwise a document fragment is returned containing the - * rendered nodes. - * - * NOTE: New code should consider using goog.soy.renderAsFragment - * instead (note that the arguments are different). - * - * @param {Function} template The Soy template defining the element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Document=} opt_document The document used to create DOM nodes. If not - * specified, global document object is used. - * @param {Object=} opt_injectedData The injected data for the template. - * @return {!Node} The resulting node or document fragment. - */ -soy.renderAsFragment = function( - template, opt_templateData, opt_document, opt_injectedData) { - return goog.soy.renderAsFragment( - template, opt_templateData, opt_injectedData, - new goog.dom.DomHelper(opt_document)); -}; - - -/** - * Helper function to render a Soy template into a single node. If the rendered - * HTML string represents a single node, then that node is returned. Otherwise, - * a DIV element is returned containing the rendered nodes. - * - * NOTE: New code should consider using goog.soy.renderAsElement - * instead (note that the arguments are different). - * - * @param {Function} template The Soy template defining the element's content. - * @param {Object=} opt_templateData The data for the template. - * @param {Document=} opt_document The document used to create DOM nodes. If not - * specified, global document object is used. - * @param {Object=} opt_injectedData The injected data for the template. - * @return {!Element} Rendered template contents, wrapped in a parent DIV - * element if necessary. - */ -soy.renderAsElement = function( - template, opt_templateData, opt_document, opt_injectedData) { - return goog.soy.renderAsElement( - template, opt_templateData, opt_injectedData, - new goog.dom.DomHelper(opt_document)); -}; - - -// ----------------------------------------------------------------------------- -// Below are private utilities to be used by Soy-generated code only. - - -/** - * Builds an augmented map. The returned map will contain mappings from both - * the base map and the additional map. If the same key appears in both, then - * the value from the additional map will be visible, while the value from the - * base map will be hidden. The base map will be used, but not modified. - * - * @param {!Object} baseMap The original map to augment. - * @param {!Object} additionalMap A map containing the additional mappings. - * @return {!Object} An augmented map containing both the original and - * additional mappings. - */ -soy.$$augmentMap = function(baseMap, additionalMap) { - - // Create a new map whose '__proto__' field is set to baseMap. - /** @constructor */ - function TempCtor() {} - TempCtor.prototype = baseMap; - var augmentedMap = new TempCtor(); - - // Add the additional mappings to the new map. - for (var key in additionalMap) { - augmentedMap[key] = additionalMap[key]; - } - - return augmentedMap; -}; - - -/** - * Checks that the given map key is a string. - * @param {*} key Key to check. - * @return {string} The given key. - */ -soy.$$checkMapKey = function(key) { - if ((typeof key) != 'string') { - throw Error( - 'Map literal\'s key expression must evaluate to string' + - ' (encountered type "' + (typeof key) + '").'); - } - return key; -}; - - -/** - * Gets the keys in a map as an array. There are no guarantees on the order. - * @param {Object} map The map to get the keys of. - * @return {Array.} The array of keys in the given map. - */ -soy.$$getMapKeys = function(map) { - var mapKeys = []; - for (var key in map) { - mapKeys.push(key); - } - return mapKeys; -}; - - -/** - * Gets a consistent unique id for the given delegate template name. Two calls - * to this function will return the same id if and only if the input names are - * the same. - * - *

Important: This function must always be called with a string constant. - * - *

If Closure Compiler is not being used, then this is just this identity - * function. If Closure Compiler is being used, then each call to this function - * will be replaced with a short string constant, which will be consistent per - * input name. - * - * @param {string} delTemplateName The delegate template name for which to get a - * consistent unique id. - * @return {string} A unique id that is consistent per input name. - * - * @consistentIdGenerator - */ -soy.$$getDelTemplateId = function(delTemplateName) { - return delTemplateName; -}; - - -/** - * Map from registered delegate template key to the priority of the - * implementation. - * @type {Object} - * @private - */ -soy.$$DELEGATE_REGISTRY_PRIORITIES_ = {}; - -/** - * Map from registered delegate template key to the implementation function. - * @type {Object} - * @private - */ -soy.$$DELEGATE_REGISTRY_FUNCTIONS_ = {}; - - -/** - * Registers a delegate implementation. If the same delegate template key (id - * and variant) has been registered previously, then priority values are - * compared and only the higher priority implementation is stored (if - * priorities are equal, an error is thrown). - * - * @param {string} delTemplateId The delegate template id. - * @param {string} delTemplateVariant The delegate template variant (can be - * empty string). - * @param {number} delPriority The implementation's priority value. - * @param {Function} delFn The implementation function. - */ -soy.$$registerDelegateFn = function( - delTemplateId, delTemplateVariant, delPriority, delFn) { - - var mapKey = 'key_' + delTemplateId + ':' + delTemplateVariant; - var currPriority = soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey]; - if (currPriority === undefined || delPriority > currPriority) { - // Registering new or higher-priority function: replace registry entry. - soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey] = delPriority; - soy.$$DELEGATE_REGISTRY_FUNCTIONS_[mapKey] = delFn; - } else if (delPriority == currPriority) { - // Registering same-priority function: error. - throw Error( - 'Encountered two active delegates with the same priority ("' + - delTemplateId + ':' + delTemplateVariant + '").'); - } else { - // Registering lower-priority function: do nothing. - } -}; - - -/** - * Retrieves the (highest-priority) implementation that has been registered for - * a given delegate template key (id and variant). If no implementation has - * been registered for the key, then the fallback is the same id with empty - * variant. If the fallback is also not registered, and allowsEmptyDefault is - * true, then returns an implementation that is equivalent to an empty template - * (i.e. rendered output would be empty string). - * - * @param {string} delTemplateId The delegate template id. - * @param {string} delTemplateVariant The delegate template variant (can be - * empty string). - * @param {boolean} allowsEmptyDefault Whether to default to the empty template - * function if there's no active implementation. - * @return {Function} The retrieved implementation function. - */ -soy.$$getDelegateFn = function( - delTemplateId, delTemplateVariant, allowsEmptyDefault) { - - var delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_[ - 'key_' + delTemplateId + ':' + delTemplateVariant]; - if (! delFn && delTemplateVariant != '') { - // Fallback to empty variant. - delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_['key_' + delTemplateId + ':']; - } - - if (delFn) { - return delFn; - } else if (allowsEmptyDefault) { - return soy.$$EMPTY_TEMPLATE_FN_; - } else { - throw Error( - 'Found no active impl for delegate call to "' + delTemplateId + ':' + - delTemplateVariant + '" (and not allowemptydefault="true").'); - } -}; - - -/** - * Private helper soy.$$getDelegateFn(). This is the empty template function - * that is returned whenever there's no delegate implementation found. - * - * @param {Object.=} opt_data - * @param {soy.StringBuilder=} opt_sb - * @param {Object.=} opt_ijData - * @return {string} - * @private - */ -soy.$$EMPTY_TEMPLATE_FN_ = function(opt_data, opt_sb, opt_ijData) { - return ''; -}; - - -// ----------------------------------------------------------------------------- -// Escape/filter/normalize. - - -/** - * Escapes HTML special characters in a string. Escapes double quote '"' in - * addition to '&', '<', and '>' so that a string can be included in an HTML - * tag attribute value within double quotes. - * Will emit known safe HTML as-is. - * - * @param {*} value The string-like value to be escaped. May not be a string, - * but the value will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeHtml = function(value) { - // TODO: Perhaps we should just ignore the contentKind property and instead - // look only at the constructor. - if (value && value.contentKind && - value.contentKind === goog.soy.data.SanitizedContentKind.HTML) { - goog.asserts.assert( - value.constructor === soydata.SanitizedHtml); - return value.content; - } - return soy.esc.$$escapeHtmlHelper(value); -}; - - -/** - * Strips unsafe tags to convert a string of untrusted HTML into HTML that - * is safe to embed. - * - * @param {*} value The string-like value to be escaped. May not be a string, - * but the value will be coerced to a string. - * @return {string} A sanitized and normalized version of value. - */ -soy.$$cleanHtml = function(value) { - if (value && value.contentKind && - value.contentKind === goog.soy.data.SanitizedContentKind.HTML) { - goog.asserts.assert( - value.constructor === soydata.SanitizedHtml); - return value.content; - } - return soy.$$stripHtmlTags(value, soy.esc.$$SAFE_TAG_WHITELIST_); -}; - - -/** - * Escapes HTML special characters in a string so that it can be embedded in - * RCDATA. - *

- * Escapes HTML special characters so that the value will not prematurely end - * the body of a tag like {@code }. - *

- * Will normalize known safe HTML to make sure that sanitized HTML (which could - * contain an innocuous {@code } don't prematurely end an RCDATA - * element. - * - * @param {*} value The string-like value to be escaped. May not be a string, - * but the value will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeHtmlRcdata = function(value) { - if (value && value.contentKind && - value.contentKind === goog.soy.data.SanitizedContentKind.HTML) { - goog.asserts.assert( - value.constructor === soydata.SanitizedHtml); - return soy.esc.$$normalizeHtmlHelper(value.content); - } - return soy.esc.$$escapeHtmlHelper(value); -}; - - -/** - * Matches any/only HTML5 void elements' start tags. - * See http://www.w3.org/TR/html-markup/syntax.html#syntax-elements - * @type {RegExp} - * @private - */ -soy.$$HTML5_VOID_ELEMENTS_ = new RegExp( - '^<(?:area|base|br|col|command|embed|hr|img|input' + - '|keygen|link|meta|param|source|track|wbr)\\b'); - - -/** - * Removes HTML tags from a string of known safe HTML. - * If opt_tagWhitelist is not specified or is empty, then - * the result can be used as an attribute value. - * - * @param {*} value The HTML to be escaped. May not be a string, but the - * value will be coerced to a string. - * @param {Object.=} opt_tagWhitelist Has an own property whose - * name is a lower-case tag name and whose value is {@code 1} for - * each element that is allowed in the output. - * @return {string} A representation of value without disallowed tags, - * HTML comments, or other non-text content. - */ -soy.$$stripHtmlTags = function(value, opt_tagWhitelist) { - if (!opt_tagWhitelist) { - // If we have no white-list, then use a fast track which elides all tags. - return String(value).replace(soy.esc.$$HTML_TAG_REGEX_, '') - // This is just paranoia since callers should normalize the result - // anyway, but if they didn't, it would be necessary to ensure that - // after the first replace non-tag uses of < do not recombine into - // tags as in "<script>alert(1337)script>". - .replace(soy.esc.$$LT_REGEX_, '<'); - } - - // Escapes '[' so that we can use [123] below to mark places where tags - // have been removed. - var html = String(value).replace(/\[/g, '['); - - // Consider all uses of '<' and replace whitelisted tags with markers like - // [1] which are indices into a list of approved tag names. - // Replace all other uses of < and > with entities. - var tags = []; - html = html.replace( - soy.esc.$$HTML_TAG_REGEX_, - function(tok, tagName) { - if (tagName) { - tagName = tagName.toLowerCase(); - if (opt_tagWhitelist.hasOwnProperty(tagName) && - opt_tagWhitelist[tagName]) { - var start = tok.charAt(1) === '/' ? ''; - return '[' + index + ']'; - } - } - return ''; - }); - - // Escape HTML special characters. Now there are no '<' in html that could - // start a tag. - html = soy.esc.$$normalizeHtmlHelper(html); - - var finalCloseTags = soy.$$balanceTags_(tags); - - // Now html contains no tags or less-than characters that could become - // part of a tag via a replacement operation and tags only contains - // approved tags. - // Reinsert the white-listed tags. - html = html.replace( - /\[(\d+)\]/g, function(_, index) { return tags[index]; }); - - // Close any still open tags. - // This prevents unclosed formatting elements like

    and from - // breaking the layout of containing HTML. - return html + finalCloseTags; -}; - - -/** - * Throw out any close tags that don't correspond to start tags. - * If {@code
    } is used for formatting, embedded HTML shouldn't be able - * to use a mismatched {@code
    } to break page layout. - * - * @param {Array.} tags an array of tags that will be modified in place - * include tags, the empty string, or concatenations of empty tags. - * @return {string} zero or more closed tags that close all elements that are - * opened in tags but not closed. - * @private - */ -soy.$$balanceTags_ = function(tags) { - var open = []; - for (var i = 0, n = tags.length; i < n; ++i) { - var tag = tags[i]; - if (tag.charAt(1) === '/') { - var openTagIndex = open.length - 1; - // NOTE: This is essentially lastIndexOf, but it's not supported in IE. - while (openTagIndex >= 0 && open[openTagIndex] != tag) { - openTagIndex--; - } - if (openTagIndex < 0) { - tags[i] = ''; // Drop close tag. - } else { - tags[i] = open.slice(openTagIndex).reverse().join(''); - open.length = openTagIndex; - } - } else if (!soy.$$HTML5_VOID_ELEMENTS_.test(tag)) { - open.push('Hello World - return soy.esc.$$filterHtmlElementNameHelper(value); -}; - - -/** - * Escapes characters in the value to make it valid content for a JS string - * literal. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - * @deprecated - */ -soy.$$escapeJs = function(value) { - return soy.$$escapeJsString(value); -}; - - -/** - * Escapes characters in the value to make it valid content for a JS string - * literal. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeJsString = function(value) { - if (value && - value.contentKind === goog.soy.data.SanitizedContentKind.JS_STR_CHARS) { - // TODO: It might still be worthwhile to normalize it to remove - // unescaped quotes, null, etc: replace(/(?:^|[^\])['"]/g, '\\$ - goog.asserts.assert(value.constructor === - soydata.SanitizedJsStrChars); - return value.content; - } - return soy.esc.$$escapeJsStringHelper(value); -}; - - -/** - * Encodes a value as a JavaScript literal. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} A JavaScript code representation of the input. - */ -soy.$$escapeJsValue = function(value) { - // We surround values with spaces so that they can't be interpolated into - // identifiers by accident. - // We could use parentheses but those might be interpreted as a function call. - if (value == null) { // Intentionally matches undefined. - // Java returns null from maps where there is no corresponding key while - // JS returns undefined. - // We always output null for compatibility with Java which does not have a - // distinct undefined value. - return ' null '; - } - if (value.contentKind == goog.soy.data.SanitizedContentKind.JS) { - goog.asserts.assert(value.constructor === - soydata.SanitizedJs); - return value.content; - } - switch (typeof value) { - case 'boolean': case 'number': - return ' ' + value + ' '; - default: - return "'" + soy.esc.$$escapeJsStringHelper(String(value)) + "'"; - } -}; - - -/** - * Escapes characters in the string to make it valid content for a JS regular - * expression literal. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeJsRegex = function(value) { - return soy.esc.$$escapeJsRegexHelper(value); -}; - - -/** - * Matches all URI mark characters that conflict with HTML attribute delimiters - * or that cannot appear in a CSS uri. - * From G.2: CSS grammar - *
    - *     url        ([!#$%&*-~]|{nonascii}|{escape})*
    - * 
    - * - * @type {RegExp} - * @private - */ -soy.$$problematicUriMarks_ = /['()]/g; - -/** - * @param {string} ch A single character in {@link soy.$$problematicUriMarks_}. - * @return {string} - * @private - */ -soy.$$pctEncode_ = function(ch) { - return '%' + ch.charCodeAt(0).toString(16); -}; - -/** - * Escapes a string so that it can be safely included in a URI. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeUri = function(value) { - if (value && value.contentKind === goog.soy.data.SanitizedContentKind.URI) { - goog.asserts.assert(value.constructor === - soydata.SanitizedUri); - return soy.$$normalizeUri(value); - } - // Apostophes and parentheses are not matched by encodeURIComponent. - // They are technically special in URIs, but only appear in the obsolete mark - // production in Appendix D.2 of RFC 3986, so can be encoded without changing - // semantics. - var encoded = soy.esc.$$escapeUriHelper(value); - soy.$$problematicUriMarks_.lastIndex = 0; - if (soy.$$problematicUriMarks_.test(encoded)) { - return encoded.replace(soy.$$problematicUriMarks_, soy.$$pctEncode_); - } - return encoded; -}; - - -/** - * Removes rough edges from a URI by escaping any raw HTML/JS string delimiters. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$normalizeUri = function(value) { - return soy.esc.$$normalizeUriHelper(value); -}; - - -/** - * Vets a URI's protocol and removes rough edges from a URI by escaping - * any raw HTML/JS string delimiters. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$filterNormalizeUri = function(value) { - if (value && value.contentKind == goog.soy.data.SanitizedContentKind.URI) { - goog.asserts.assert(value.constructor === - soydata.SanitizedUri); - return soy.$$normalizeUri(value); - } - return soy.esc.$$filterNormalizeUriHelper(value); -}; - - -/** - * Escapes a string so it can safely be included inside a quoted CSS string. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeCssString = function(value) { - return soy.esc.$$escapeCssStringHelper(value); -}; - - -/** - * Encodes a value as a CSS identifier part, keyword, or quantity. - * - * @param {*} value The value to escape. May not be a string, but the value - * will be coerced to a string. - * @return {string} A safe CSS identifier part, keyword, or quanitity. - */ -soy.$$filterCssValue = function(value) { - if (value && value.contentKind === goog.soy.data.SanitizedContentKind.CSS) { - goog.asserts.assert(value.constructor === - soydata.SanitizedCss); - return value.content; - } - // Uses == to intentionally match null and undefined for Java compatibility. - if (value == null) { - return ''; - } - return soy.esc.$$filterCssValueHelper(value); -}; - - -/** - * Sanity-checks noAutoescape input for explicitly tainted content. - * - * SanitizedContentKind.TEXT is used to explicitly mark input that was never - * meant to be used unescaped. - * - * @param {*} value The value to filter. - * @return {string} The value, that we dearly hope will not cause an attack. - */ -soy.$$filterNoAutoescape = function(value) { - if (value && value.contentKind === goog.soy.data.SanitizedContentKind.TEXT) { - // Fail in development mode. - goog.asserts.fail( - 'Tainted SanitizedContentKind.TEXT for |noAutoescape: `%s`', - [value.content]); - // Return innocuous data in production. - return 'zSoyz'; - } - return String(value); -}; - - -// ----------------------------------------------------------------------------- -// Basic directives/functions. - - -/** - * Converts \r\n, \r, and \n to
    s - * @param {*} str The string in which to convert newlines. - * @return {string} A copy of {@code str} with converted newlines. - */ -soy.$$changeNewlineToBr = function(str) { - return goog.string.newLineToBr(String(str), false); -}; - - -/** - * Inserts word breaks ('wbr' tags) into a HTML string at a given interval. The - * counter is reset if a space is encountered. Word breaks aren't inserted into - * HTML tags or entities. Entites count towards the character count; HTML tags - * do not. - * - * @param {*} str The HTML string to insert word breaks into. Can be other - * types, but the value will be coerced to a string. - * @param {number} maxCharsBetweenWordBreaks Maximum number of non-space - * characters to allow before adding a word break. - * @return {string} The string including word breaks. - */ -soy.$$insertWordBreaks = function(str, maxCharsBetweenWordBreaks) { - return goog.format.insertWordBreaks(String(str), maxCharsBetweenWordBreaks); -}; - - -/** - * Truncates a string to a given max length (if it's currently longer), - * optionally adding ellipsis at the end. - * - * @param {*} str The string to truncate. Can be other types, but the value will - * be coerced to a string. - * @param {number} maxLen The maximum length of the string after truncation - * (including ellipsis, if applicable). - * @param {boolean} doAddEllipsis Whether to add ellipsis if the string needs - * truncation. - * @return {string} The string after truncation. - */ -soy.$$truncate = function(str, maxLen, doAddEllipsis) { - - str = String(str); - if (str.length <= maxLen) { - return str; // no need to truncate - } - - // If doAddEllipsis, either reduce maxLen to compensate, or else if maxLen is - // too small, just turn off doAddEllipsis. - if (doAddEllipsis) { - if (maxLen > 3) { - maxLen -= 3; - } else { - doAddEllipsis = false; - } - } - - // Make sure truncating at maxLen doesn't cut up a unicode surrogate pair. - if (soy.$$isHighSurrogate_(str.charAt(maxLen - 1)) && - soy.$$isLowSurrogate_(str.charAt(maxLen))) { - maxLen -= 1; - } - - // Truncate. - str = str.substring(0, maxLen); - - // Add ellipsis. - if (doAddEllipsis) { - str += '...'; - } - - return str; -}; - -/** - * Private helper for $$truncate() to check whether a char is a high surrogate. - * @param {string} ch The char to check. - * @return {boolean} Whether the given char is a unicode high surrogate. - * @private - */ -soy.$$isHighSurrogate_ = function(ch) { - return 0xD800 <= ch && ch <= 0xDBFF; -}; - -/** - * Private helper for $$truncate() to check whether a char is a low surrogate. - * @param {string} ch The char to check. - * @return {boolean} Whether the given char is a unicode low surrogate. - * @private - */ -soy.$$isLowSurrogate_ = function(ch) { - return 0xDC00 <= ch && ch <= 0xDFFF; -}; - - -// ----------------------------------------------------------------------------- -// Bidi directives/functions. - - -/** - * Cache of bidi formatter by context directionality, so we don't keep on - * creating new objects. - * @type {!Object.} - * @private - */ -soy.$$bidiFormatterCache_ = {}; - - -/** - * Returns cached bidi formatter for bidiGlobalDir, or creates a new one. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @return {goog.i18n.BidiFormatter} A formatter for bidiGlobalDir. - * @private - */ -soy.$$getBidiFormatterInstance_ = function(bidiGlobalDir) { - return soy.$$bidiFormatterCache_[bidiGlobalDir] || - (soy.$$bidiFormatterCache_[bidiGlobalDir] = - new goog.i18n.BidiFormatter(bidiGlobalDir)); -}; - - -/** - * Estimate the overall directionality of text. If opt_isHtml, makes sure to - * ignore the LTR nature of the mark-up and escapes in text, making the logic - * suitable for HTML and HTML-escaped text. - * @param {string} text The text whose directionality is to be estimated. - * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped. - * Default: false. - * @return {number} 1 if text is LTR, -1 if it is RTL, and 0 if it is neutral. - */ -soy.$$bidiTextDir = function(text, opt_isHtml) { - if (!text) { - return 0; - } - return goog.i18n.bidi.detectRtlDirectionality(text, opt_isHtml) ? -1 : 1; -}; - - -/** - * Returns 'dir="ltr"' or 'dir="rtl"', depending on text's estimated - * directionality, if it is not the same as bidiGlobalDir. - * Otherwise, returns the empty string. - * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes - * in text, making the logic suitable for HTML and HTML-escaped text. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @param {string} text The text whose directionality is to be estimated. - * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped. - * Default: false. - * @return {soydata.SanitizedHtmlAttribute} 'dir="rtl"' for RTL text in non-RTL - * context; 'dir="ltr"' for LTR text in non-LTR context; - * else, the empty string. - */ -soy.$$bidiDirAttr = function(bidiGlobalDir, text, opt_isHtml) { - return soydata.VERY_UNSAFE.ordainSanitizedHtmlAttribute( - soy.$$getBidiFormatterInstance_(bidiGlobalDir).dirAttr(text, opt_isHtml)); -}; - - -/** - * Returns a Unicode BiDi mark matching bidiGlobalDir (LRM or RLM) if the - * directionality or the exit directionality of text are opposite to - * bidiGlobalDir. Otherwise returns the empty string. - * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes - * in text, making the logic suitable for HTML and HTML-escaped text. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @param {string} text The text whose directionality is to be estimated. - * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped. - * Default: false. - * @return {string} A Unicode bidi mark matching bidiGlobalDir, or the empty - * string when text's overall and exit directionalities both match - * bidiGlobalDir, or bidiGlobalDir is 0 (unknown). - */ -soy.$$bidiMarkAfter = function(bidiGlobalDir, text, opt_isHtml) { - var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir); - return formatter.markAfter(text, opt_isHtml); -}; - - -/** - * Returns str wrapped in a according to its directionality - * - but only if that is neither neutral nor the same as the global context. - * Otherwise, returns str unchanged. - * Always treats str as HTML/HTML-escaped, i.e. ignores mark-up and escapes when - * estimating str's directionality. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @param {*} str The string to be wrapped. Can be other types, but the value - * will be coerced to a string. - * @return {string} The wrapped string. - */ -soy.$$bidiSpanWrap = function(bidiGlobalDir, str) { - var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir); - return formatter.spanWrap(str + '', true); -}; - - -/** - * Returns str wrapped in Unicode BiDi formatting characters according to its - * directionality, i.e. either LRE or RLE at the beginning and PDF at the end - - * but only if str's directionality is neither neutral nor the same as the - * global context. Otherwise, returns str unchanged. - * Always treats str as HTML/HTML-escaped, i.e. ignores mark-up and escapes when - * estimating str's directionality. - * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1 - * if rtl, 0 if unknown. - * @param {*} str The string to be wrapped. Can be other types, but the value - * will be coerced to a string. - * @return {string} The wrapped string. - */ -soy.$$bidiUnicodeWrap = function(bidiGlobalDir, str) { - var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir); - return formatter.unicodeWrap(str + '', true); -}; - - -// ----------------------------------------------------------------------------- -// Generated code. - - - - -// START GENERATED CODE FOR ESCAPERS. - -/** - * @type {function (*) : string} - */ -soy.esc.$$escapeUriHelper = function(v) { - return encodeURIComponent(String(v)); -}; - -/** - * Maps charcters to the escaped versions for the named escape directives. - * @type {Object.} - * @private - */ -soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = { - '\x00': '\x26#0;', - '\x22': '\x26quot;', - '\x26': '\x26amp;', - '\x27': '\x26#39;', - '\x3c': '\x26lt;', - '\x3e': '\x26gt;', - '\x09': '\x26#9;', - '\x0a': '\x26#10;', - '\x0b': '\x26#11;', - '\x0c': '\x26#12;', - '\x0d': '\x26#13;', - ' ': '\x26#32;', - '-': '\x26#45;', - '\/': '\x26#47;', - '\x3d': '\x26#61;', - '`': '\x26#96;', - '\x85': '\x26#133;', - '\xa0': '\x26#160;', - '\u2028': '\x26#8232;', - '\u2029': '\x26#8233;' -}; - -/** - * A function that can be used with String.replace.. - * @param {string} ch A single character matched by a compatible matcher. - * @return {string} A token in the output language. - * @private - */ -soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = function(ch) { - return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_[ch]; -}; - -/** - * Maps charcters to the escaped versions for the named escape directives. - * @type {Object.} - * @private - */ -soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = { - '\x00': '\\x00', - '\x08': '\\x08', - '\x09': '\\t', - '\x0a': '\\n', - '\x0b': '\\x0b', - '\x0c': '\\f', - '\x0d': '\\r', - '\x22': '\\x22', - '\x26': '\\x26', - '\x27': '\\x27', - '\/': '\\\/', - '\x3c': '\\x3c', - '\x3d': '\\x3d', - '\x3e': '\\x3e', - '\\': '\\\\', - '\x85': '\\x85', - '\u2028': '\\u2028', - '\u2029': '\\u2029', - '$': '\\x24', - '(': '\\x28', - ')': '\\x29', - '*': '\\x2a', - '+': '\\x2b', - ',': '\\x2c', - '-': '\\x2d', - '.': '\\x2e', - ':': '\\x3a', - '?': '\\x3f', - '[': '\\x5b', - ']': '\\x5d', - '^': '\\x5e', - '{': '\\x7b', - '|': '\\x7c', - '}': '\\x7d' -}; - -/** - * A function that can be used with String.replace.. - * @param {string} ch A single character matched by a compatible matcher. - * @return {string} A token in the output language. - * @private - */ -soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = function(ch) { - return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_[ch]; -}; - -/** - * Maps charcters to the escaped versions for the named escape directives. - * @type {Object.} - * @private - */ -soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_ = { - '\x00': '\\0 ', - '\x08': '\\8 ', - '\x09': '\\9 ', - '\x0a': '\\a ', - '\x0b': '\\b ', - '\x0c': '\\c ', - '\x0d': '\\d ', - '\x22': '\\22 ', - '\x26': '\\26 ', - '\x27': '\\27 ', - '(': '\\28 ', - ')': '\\29 ', - '*': '\\2a ', - '\/': '\\2f ', - ':': '\\3a ', - ';': '\\3b ', - '\x3c': '\\3c ', - '\x3d': '\\3d ', - '\x3e': '\\3e ', - '@': '\\40 ', - '\\': '\\5c ', - '{': '\\7b ', - '}': '\\7d ', - '\x85': '\\85 ', - '\xa0': '\\a0 ', - '\u2028': '\\2028 ', - '\u2029': '\\2029 ' -}; - -/** - * A function that can be used with String.replace.. - * @param {string} ch A single character matched by a compatible matcher. - * @return {string} A token in the output language. - * @private - */ -soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_ = function(ch) { - return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_[ch]; -}; - -/** - * Maps charcters to the escaped versions for the named escape directives. - * @type {Object.} - * @private - */ -soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = { - '\x00': '%00', - '\x01': '%01', - '\x02': '%02', - '\x03': '%03', - '\x04': '%04', - '\x05': '%05', - '\x06': '%06', - '\x07': '%07', - '\x08': '%08', - '\x09': '%09', - '\x0a': '%0A', - '\x0b': '%0B', - '\x0c': '%0C', - '\x0d': '%0D', - '\x0e': '%0E', - '\x0f': '%0F', - '\x10': '%10', - '\x11': '%11', - '\x12': '%12', - '\x13': '%13', - '\x14': '%14', - '\x15': '%15', - '\x16': '%16', - '\x17': '%17', - '\x18': '%18', - '\x19': '%19', - '\x1a': '%1A', - '\x1b': '%1B', - '\x1c': '%1C', - '\x1d': '%1D', - '\x1e': '%1E', - '\x1f': '%1F', - ' ': '%20', - '\x22': '%22', - '\x27': '%27', - '(': '%28', - ')': '%29', - '\x3c': '%3C', - '\x3e': '%3E', - '\\': '%5C', - '{': '%7B', - '}': '%7D', - '\x7f': '%7F', - '\x85': '%C2%85', - '\xa0': '%C2%A0', - '\u2028': '%E2%80%A8', - '\u2029': '%E2%80%A9', - '\uff01': '%EF%BC%81', - '\uff03': '%EF%BC%83', - '\uff04': '%EF%BC%84', - '\uff06': '%EF%BC%86', - '\uff07': '%EF%BC%87', - '\uff08': '%EF%BC%88', - '\uff09': '%EF%BC%89', - '\uff0a': '%EF%BC%8A', - '\uff0b': '%EF%BC%8B', - '\uff0c': '%EF%BC%8C', - '\uff0f': '%EF%BC%8F', - '\uff1a': '%EF%BC%9A', - '\uff1b': '%EF%BC%9B', - '\uff1d': '%EF%BC%9D', - '\uff1f': '%EF%BC%9F', - '\uff20': '%EF%BC%A0', - '\uff3b': '%EF%BC%BB', - '\uff3d': '%EF%BC%BD' -}; - -/** - * A function that can be used with String.replace.. - * @param {string} ch A single character matched by a compatible matcher. - * @return {string} A token in the output language. - * @private - */ -soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = function(ch) { - return soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_[ch]; -}; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_ESCAPE_HTML_ = /[\x00\x22\x26\x27\x3c\x3e]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_ = /[\x00\x22\x27\x3c\x3e]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x26\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_ = /[\x00\x08-\x0d\x22\x26\x27\/\x3c-\x3e\\\x85\u2028\u2029]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_ = /[\x00\x08-\x0d\x22\x24\x26-\/\x3a\x3c-\x3f\x5b-\x5e\x7b-\x7d\x85\u2028\u2029]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_ = /[\x00\x08-\x0d\x22\x26-\x2a\/\x3a-\x3e@\\\x7b\x7d\x85\xa0\u2028\u2029]/g; - -/** - * Matches characters that need to be escaped for the named directives. - * @type RegExp - * @private - */ -soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = /[\x00- \x22\x27-\x29\x3c\x3e\\\x7b\x7d\x7f\x85\xa0\u2028\u2029\uff01\uff03\uff04\uff06-\uff0c\uff0f\uff1a\uff1b\uff1d\uff1f\uff20\uff3b\uff3d]/g; - -/** - * A pattern that vets values produced by the named directives. - * @type RegExp - * @private - */ -soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_ = /^(?!-*(?:expression|(?:moz-)?binding))(?:[.#]?-?(?:[_a-z0-9-]+)(?:-[_a-z0-9-]+)*-?|-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[a-z]{1,2}|%)?|!important|)$/i; - -/** - * A pattern that vets values produced by the named directives. - * @type RegExp - * @private - */ -soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_ = /^(?:(?:https?|mailto):|[^&:\/?#]*(?:[\/?#]|$))/i; - -/** - * A pattern that vets values produced by the named directives. - * @type RegExp - * @private - */ -soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTES_ = /^(?!style|on|action|archive|background|cite|classid|codebase|data|dsync|href|longdesc|src|usemap)(?:[a-z0-9_$:-]*)$/i; - -/** - * A pattern that vets values produced by the named directives. - * @type RegExp - * @private - */ -soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_ = /^(?!script|style|title|textarea|xmp|no)[a-z0-9_$:-]*$/i; - -/** - * A helper for the Soy directive |escapeHtml - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$escapeHtmlHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_ESCAPE_HTML_, - soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_); -}; - -/** - * A helper for the Soy directive |normalizeHtml - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$normalizeHtmlHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_, - soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_); -}; - -/** - * A helper for the Soy directive |escapeHtmlNospace - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$escapeHtmlNospaceHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_, - soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_); -}; - -/** - * A helper for the Soy directive |normalizeHtmlNospace - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$normalizeHtmlNospaceHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_, - soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_); -}; - -/** - * A helper for the Soy directive |escapeJsString - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$escapeJsStringHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_, - soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_); -}; - -/** - * A helper for the Soy directive |escapeJsRegex - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$escapeJsRegexHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_, - soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_); -}; - -/** - * A helper for the Soy directive |escapeCssString - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$escapeCssStringHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_, - soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_); -}; - -/** - * A helper for the Soy directive |filterCssValue - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$filterCssValueHelper = function(value) { - var str = String(value); - if (!soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_.test(str)) { - return 'zSoyz'; - } - return str; -}; - -/** - * A helper for the Soy directive |normalizeUri - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$normalizeUriHelper = function(value) { - var str = String(value); - return str.replace( - soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_, - soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_); -}; - -/** - * A helper for the Soy directive |filterNormalizeUri - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$filterNormalizeUriHelper = function(value) { - var str = String(value); - if (!soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_.test(str)) { - return '#zSoyz'; - } - return str.replace( - soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_, - soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_); -}; - -/** - * A helper for the Soy directive |filterHtmlAttributes - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$filterHtmlAttributesHelper = function(value) { - var str = String(value); - if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTES_.test(str)) { - return 'zSoyz'; - } - return str; -}; - -/** - * A helper for the Soy directive |filterHtmlElementName - * @param {*} value Can be of any type but will be coerced to a string. - * @return {string} The escaped text. - */ -soy.esc.$$filterHtmlElementNameHelper = function(value) { - var str = String(value); - if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_.test(str)) { - return 'zSoyz'; - } - return str; -}; - -/** - * Matches all tags, HTML comments, and DOCTYPEs in tag soup HTML. - * By removing these, and replacing any '<' or '>' characters with - * entities we guarantee that the result can be embedded into a - * an attribute without introducing a tag boundary. - * - * @type {RegExp} - * @private - */ -soy.esc.$$HTML_TAG_REGEX_ = /<(?:!|\/?([a-zA-Z][a-zA-Z0-9:\-]*))(?:[^>'"]|"[^"]*"|'[^']*')*>/g; - -/** - * Matches all occurrences of '<'. - * - * @type {RegExp} - * @private - */ -soy.esc.$$LT_REGEX_ = /} - * @private - */ -soy.esc.$$SAFE_TAG_WHITELIST_ = {'b': 1, 'br': 1, 'em': 1, 'i': 1, 's': 1, 'sub': 1, 'sup': 1, 'u': 1}; - -// END GENERATED CODE diff --git a/apps/code/code.js b/apps/code/code.js deleted file mode 100644 index 45cf73ebe..000000000 --- a/apps/code/code.js +++ /dev/null @@ -1,228 +0,0 @@ -/** - * Blockly Apps: Code - * - * Copyright 2012 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview JavaScript for Blockly's Code application. - * @author fraser@google.com (Neil Fraser) - */ - -// Supported languages. -BlocklyApps.LANGUAGES = - ['ace', 'ar', 'ca', 'cs', 'da', 'de', 'el', 'en', 'es', 'fa', 'fr', 'he', - 'hrx', 'hu', 'is', 'it', 'ko', 'mg', 'ms', 'nl', 'pl', 'pms', 'pt-br', - 'ro', 'ru', 'sco', 'sr', 'sv', 'th', 'tlh', 'tr', 'uk', 'vi', 'zh-hans', - 'zh-hant']; -BlocklyApps.LANG = BlocklyApps.getLang(); - -document.write('\n'); - -/** - * Create a namespace for the application. - */ -var Code = {}; - -/** - * List of tab names. - * @private - */ -Code.TABS_ = ['blocks', 'javascript', 'python', 'dart', 'xml']; - -Code.selected = 'blocks'; - -/** - * Switch the visible pane when a tab is clicked. - * @param {string} clickedName Name of tab clicked. - */ -Code.tabClick = function(clickedName) { - // If the XML tab was open, save and render the content. - if (document.getElementById('tab_xml').className == 'tabon') { - var xmlTextarea = document.getElementById('content_xml'); - var xmlText = xmlTextarea.value; - var xmlDom = null; - try { - xmlDom = Blockly.Xml.textToDom(xmlText); - } catch (e) { - var q = - window.confirm(BlocklyApps.getMsg('Code_badXml').replace('%1', e)); - if (!q) { - // Leave the user on the XML tab. - return; - } - } - if (xmlDom) { - Blockly.mainWorkspace.clear(); - Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xmlDom); - } - } - - // Deselect all tabs and hide all panes. - for (var i = 0; i < Code.TABS_.length; i++) { - var name = Code.TABS_[i]; - document.getElementById('tab_' + name).className = 'taboff'; - document.getElementById('content_' + name).style.visibility = 'hidden'; - } - - // Select the active tab. - Code.selected = clickedName; - document.getElementById('tab_' + clickedName).className = 'tabon'; - // Show the selected pane. - document.getElementById('content_' + clickedName).style.visibility = - 'visible'; - Code.renderContent(); - Blockly.fireUiEvent(window, 'resize'); -}; - -/** - * Populate the currently selected pane with content generated from the blocks. - */ -Code.renderContent = function() { - var content = document.getElementById('content_' + Code.selected); - // Initialize the pane. - if (content.id == 'content_xml') { - var xmlTextarea = document.getElementById('content_xml'); - var xmlDom = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace); - var xmlText = Blockly.Xml.domToPrettyText(xmlDom); - xmlTextarea.value = xmlText; - xmlTextarea.focus(); - } else if (content.id == 'content_javascript') { - var code = Blockly.JavaScript.workspaceToCode(); - content.textContent = code; - if (typeof prettyPrintOne == 'function') { - code = content.innerHTML; - code = prettyPrintOne(code, 'js'); - content.innerHTML = code; - } - } else if (content.id == 'content_python') { - code = Blockly.Python.workspaceToCode(); - content.textContent = code; - if (typeof prettyPrintOne == 'function') { - code = content.innerHTML; - code = prettyPrintOne(code, 'py'); - content.innerHTML = code; - } - } else if (content.id == 'content_dart') { - code = Blockly.Dart.workspaceToCode(); - content.textContent = code; - if (typeof prettyPrintOne == 'function') { - code = content.innerHTML; - code = prettyPrintOne(code, 'dart'); - content.innerHTML = code; - } - } -}; - -/** - * Initialize Blockly. Called on page load. - */ -Code.init = function() { - BlocklyApps.init(); - - var rtl = BlocklyApps.isRtl(); - var container = document.getElementById('content_area'); - var onresize = function(e) { - var bBox = BlocklyApps.getBBox_(container); - for (var i = 0; i < Code.TABS_.length; i++) { - var el = document.getElementById('content_' + Code.TABS_[i]); - el.style.top = bBox.y + 'px'; - el.style.left = bBox.x + 'px'; - // Height and width need to be set, read back, then set again to - // compensate for scrollbars. - el.style.height = bBox.height + 'px'; - el.style.height = (2 * bBox.height - el.offsetHeight) + 'px'; - el.style.width = bBox.width + 'px'; - el.style.width = (2 * bBox.width - el.offsetWidth) + 'px'; - } - // Make the 'Blocks' tab line up with the toolbox. - if (Blockly.Toolbox.width) { - document.getElementById('tab_blocks').style.minWidth = - (Blockly.Toolbox.width - 38) + 'px'; - // Account for the 19 pixel margin and on each side. - } - }; - window.addEventListener('resize', onresize, false); - - var toolbox = document.getElementById('toolbox'); - Blockly.inject(document.getElementById('content_blocks'), - {media: '../../media/', - rtl: rtl, - toolbox: toolbox}); - - // Add to reserved word list: Local variables in execution evironment (runJS) - // and the infinite loop detection function. - Blockly.JavaScript.addReservedWords('code,timeouts,checkTimeout'); - - BlocklyApps.loadBlocks(''); - - if ('BlocklyStorage' in window) { - // Hook a save function onto unload. - BlocklyStorage.backupOnUnload(); - } - - Code.tabClick(Code.selected); - Blockly.fireUiEvent(window, 'resize'); - - BlocklyApps.bindClick('trashButton', - function() {Code.discard(); Code.renderContent();}); - BlocklyApps.bindClick('runButton', Code.runJS); - - for (var i = 0; i < Code.TABS_.length; i++) { - var name = Code.TABS_[i]; - BlocklyApps.bindClick('tab_' + name, - function(name_) {return function() {Code.tabClick(name_);};}(name)); - } - - // Lazy-load the syntax-highlighting. - window.setTimeout(BlocklyApps.importPrettify, 1); -}; - -window.addEventListener('load', Code.init); - -/** - * Execute the user's code. - * Just a quick and dirty eval. Catch infinite loops. - */ -Code.runJS = function() { - Blockly.JavaScript.INFINITE_LOOP_TRAP = ' checkTimeout();\n'; - var timeouts = 0; - var checkTimeout = function() { - if (timeouts++ > 1000000) { - throw BlocklyApps.getMsg('Code_timeout'); - } - }; - var code = Blockly.JavaScript.workspaceToCode(); - Blockly.JavaScript.INFINITE_LOOP_TRAP = null; - try { - eval(code); - } catch (e) { - alert(BlocklyApps.getMsg('Code_badCode').replace('%1', e)); - } -}; - -/** - * Discard all blocks from the workspace. - */ -Code.discard = function() { - var count = Blockly.mainWorkspace.getAllBlocks().length; - if (count < 2 || - window.confirm(BlocklyApps.getMsg('Code_discard').replace('%1', count))) { - Blockly.mainWorkspace.clear(); - window.location.hash = ''; - } -}; diff --git a/apps/code/generated/ace.js b/apps/code/generated/ace.js deleted file mode 100644 index 8b45899d5..000000000 --- a/apps/code/generated/ace.js +++ /dev/null @@ -1,50 +0,0 @@ -// This file was automatically generated from common.soy. -// Please don't edit this file by hand. - -if (typeof apps == 'undefined') { var apps = {}; } - - -apps.messages = function(opt_data, opt_ignored, opt_ijData) { - return '
    Ruweuëng meuprogram ban leumahTeutheunEu kode JavaScript yang geupeuhaséKeubah ngon neupawôt keu theunNeupeujak program nyang geupeuteutap le seuneutheun lam ruweuëng keurijaPeujak programAtô keulayiKa gotPeubateuëLogisKuwienMatematikHaraihDapeutaWareunaMeumacamProsedurNa masalah lam neumeulakèeNeubagi seuneutheun droëneuh ngon peunawôt nyoë: %1Meu\'ah, \'%1\' hana saban sakri ngon peuë mantong program nyang meukeubahBeureukaih keuneubah droëneuh han jeuët geupasoë. Kadang na neupeugot ngon versi seuneutheun yang la\'éndapeutaharaih
    '; -}; - - -apps.dialog = function(opt_data, opt_ignored, opt_ijData) { - return '
    '; -}; - - -apps.codeDialog = function(opt_data, opt_ignored, opt_ijData) { - return '
    ' + apps.ok(null, null, opt_ijData) + '
    '; -}; - - -apps.storageDialog = function(opt_data, opt_ignored, opt_ijData) { - return '
    ' + apps.ok(null, null, opt_ijData) + '
    '; -}; - - -apps.ok = function(opt_data, opt_ignored, opt_ijData) { - return '
    '; -}; - -; -// This file was automatically generated from template.soy. -// Please don't edit this file by hand. - -if (typeof codepage == 'undefined') { var codepage = {}; } - - -codepage.messages = function(opt_data, opt_ignored, opt_ijData) { - return apps.messages(null, null, opt_ijData) + '
    Ralat \'oh geuploh XML\n%1\n\nNeupileh \'OK\' keu peulucôt meuandam droëneuh atawa \'Peubateuë\' keu neusambông meuandam XML-jihRalat program\n%1Eksekusi maksimum ka leupahSampôh mandum %1 seuneutheun
    '; -}; - - -codepage.start = function(opt_data, opt_ignored, opt_ijData) { - return codepage.messages(null, null, opt_ijData) + ' - - - - - - - - diff --git a/apps/common.css b/apps/common.css deleted file mode 100644 index ce57787a7..000000000 --- a/apps/common.css +++ /dev/null @@ -1,119 +0,0 @@ -body { - background-color: #fff; - font-family: sans-serif; - margin-top: 0; -} -h1 { - font-weight: normal; - font-size: 140%; -} -a:hover { - color: #f00; -} -.farSide { - text-align: right; -} -html[dir="RTL"] .farSide { - text-align: left; -} - -/* Buttons */ -button { - margin: 5px; - padding: 10px; - border-radius: 4px; - border: 1px solid #ddd; - font-size: large; - background-color: #eee; - color: #000; -} -button.primary { - border: 1px solid #dd4b39; - background-color: #dd4b39; - color: #fff; -} -button.secondary { - border: 1px solid #4d90fe; - background-color: #4d90fe; - color: #fff; -} -button.primary>img, -button.secondary>img { - opacity: 1; -} -button>img { - opacity: 0.6; - vertical-align: text-bottom; -} -button:hover>img { - opacity: 1; -} -button:active { - border: 1px solid #888 !important; -} -button:hover { - box-shadow: 2px 2px 5px #888; -} -button.disabled:hover>img { - opacity: 0.6; -} -button.disabled { - display: none; -} -button.notext { - font-size: 10%; -} - -/* Dialogs */ -#dialog { - visibility: hidden; - background-color: #fff; - color: #000; - border: 1px solid #ccc; - position: absolute; - border-radius: 8px; - box-shadow: 5px 5px 5px #888; - padding: 10px; -} -#dialogBorder { - visibility: hidden; - position: absolute; - background-color: #fff; - color: #000; - border: 1px solid #000; - border-radius: 6px; - box-shadow: 5px 5px 5px #888; -} -#dialogShadow { - visibility: hidden; - position: fixed; - top: 0; - left: 0; - height: 100%; - width: 100%; - background-color: #000; - opacity: 0.3 -} -.dialogAnimate { - transition-property: width height left top opacity; - transition-duration: 0.2s; - transition-timing-function: linear; -} -.dialogHiddenContent { - visibility: hidden; - position: absolute; - top: 0; - left: 0; - z-index: -1; -} -#dialogHeader { - height: 25px; - margin: -10px -10px 15px; - border-top-left-radius: 8px; - border-top-right-radius: 8px; - background-color: #ddd; - cursor: move; -} -#dialog button { - min-width: 4em; -} diff --git a/apps/common.js b/apps/common.js deleted file mode 100644 index 35f057059..000000000 --- a/apps/common.js +++ /dev/null @@ -1,873 +0,0 @@ -/** - * Blockly Apps: Common code - * - * Copyright 2013 Google Inc. - * https://developers.google.com/blockly/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @fileoverview Common support code for Blockly apps. - * @author fraser@google.com (Neil Fraser) - */ -'use strict'; - -var BlocklyApps = {}; - -/** - * Lookup for names of languages. Keys should be in ISO 639 format. - */ -BlocklyApps.LANGUAGE_NAME = { - 'ace': 'بهسا اچيه', - 'af': 'Afrikaans', - 'ar': 'العربية', - 'az': 'Azərbaycanca', - 'be-tarask': 'Taraškievica', - 'br': 'Brezhoneg', - 'ca': 'Català', - 'cdo': '閩東語', - 'cs': 'Česky', - 'da': 'Dansk', - 'de': 'Deutsch', - 'el': 'Ελληνικά', - 'en': 'English', - 'es': 'Español', - 'eu': 'Euskara', - 'fa': 'فارسی', - 'fi': 'Suomi', - 'fo': 'Føroyskt', - 'fr': 'Français', - 'frr': 'Frasch', - 'gl': 'Galego', - 'hak': '客家話', - 'he': 'עברית', - 'hi': 'हिन्दी', - 'hrx': 'Hunsrik', - 'hu': 'Magyar', - 'ia': 'Interlingua', - 'id': 'Bahasa Indonesia', - 'is': 'Íslenska', - 'it': 'Italiano', - 'ja': '日本語', - 'ka': 'ქართული', - 'km': 'ភាសាខ្មែរ', - 'ko': '한국어', - 'ksh': 'Ripoarėsch', - 'ky': 'Кыргызча', - 'la': 'Latine', - 'lb': 'Lëtzebuergesch', - 'lt': 'Lietuvių', - 'lv': 'Latviešu', - 'mg': 'Malagasy', - 'ml': 'മലയാളം', - 'mk': 'Македонски', - 'mr': 'मराठी', - 'ms': 'Bahasa Melayu', - 'mzn': 'مازِرونی', - 'nb': 'Norsk Bokmål', - 'nl': 'Nederlands, Vlaams', - 'oc': 'Lenga d\'òc', - 'pa': 'पंजाबी', - 'pl': 'Polski', - 'pms': 'Piemontèis', - 'ps': 'پښتو', - 'pt': 'Português', - 'ro': 'Română', - 'pt-br': 'Português Brasileiro', - 'ru': 'Русский', - 'sc': 'Sardu', - 'sco': 'Scots', - 'si': 'සිංහල', - 'sk': 'Slovenčina', - 'sr': 'Српски', - 'sv': 'Svenska', - 'sw': 'Kishwahili', - 'th': 'ภาษาไทย', - 'tl': 'Tagalog', - 'tlh': 'tlhIngan Hol', - 'tr': 'Türkçe', - 'uk': 'Українська', - 'vi': 'Tiếng Việt', - 'zh-hans': '簡體中文', - 'zh-hant': '正體中文' -}; - -/** - * List of RTL languages. - */ -BlocklyApps.LANGUAGE_RTL = ['ace', 'ar', 'fa', 'he', 'mzn', 'ps']; - -/** - * Lookup for Blockly core block language pack. - */ -BlocklyApps.LANGUAGE_PACK = { - 'ar': 'msg/js/ar.js', - 'az-latn': 'msg/js/az-latn.js', - 'az': 'msg/js/az.js', - 'ca': 'msg/js/ca.js', - 'cdo': 'msg/js/zh-hant.js', - 'cs': 'msg/js/cs.js', - 'da': 'msg/js/da.js', - 'de': 'msg/js/de.js', - 'el': 'msg/js/el.js', - 'en': 'msg/js/en.js', - 'en_us': 'msg/js/en_us.js', - 'es': 'msg/js/es.js', - 'fa': 'msg/js/fa.js', - 'fi': 'msg/js/fi.js', - 'fr': 'msg/js/fr.js', - 'frr': 'msg/js/de.js', - 'he': 'msg/js/he.js', - 'hrx': 'msg/js/hrx.js', - 'hu': 'msg/js/hu.js', - 'id': 'msg/js/id.js', - 'is': 'msg/js/is.js', - 'it': 'msg/js/it.js', - 'ja': 'msg/js/ja.js', - 'ko': 'msg/js/ko.js', - 'ksh': 'msg/js/de.js', - 'lb': 'msg/js/de.js', - 'ms': 'msg/js/ms.js', - 'nb': 'msg/js/nb.js', - 'nl': 'msg/js/nl.js', - 'no': 'msg/js/no.js', - 'pl': 'msg/js/pl.js', - 'pms': 'msg/js/pms.js', - 'pt': 'msg/js/pt.js', - 'pt-br': 'msg/js/pt-br.js', - // We used to use pt_br for pt-br (until November 2013). - // Users may still have URLs. - 'pt_br': 'msg/js/pt-br.js', - 'ro': 'msg/js/ro.js', - 'ru': 'msg/js/ru.js', - 'sq': 'msg/js/sq.js', - 'sr': 'msg/js/sr.js', - 'sv': 'msg/js/sv.js', - 'th': 'msg/js/th.js', - 'tl': 'msg/js/tl.js', - 'tlh': 'msg/js/tlh.js', - 'tr': 'msg/js/tr.js', - 'uk': 'msg/js/uk.js', - 'vi': 'msg/js/vi.js', - 'zh-hans': 'msg/js/zh-hans.js', - 'zh-hant': 'msg/js/zh-hant.js', - // We used to use zh-tw for zh-hant (until November 2013). - // Users may still have URLs. - 'zh-tw': 'msg/js/zh-hant.js', - 'default': 'msg/js/en.js' -}; - -/** - * User's language (e.g. "en"). - * @type string= - */ -BlocklyApps.LANG = undefined; - -/** - * List of languages supported by this app. Values should be in ISO 639 format. - * @type !Array.= - */ -BlocklyApps.LANGUAGES = undefined; - -/** - * Length of time to supress clicks to avoid a double-click. - * @type number - */ -BlocklyApps.DOUBLE_CLICK_TIME = 400; - -/** - * Extracts a parameter from the URL. - * If the parameter is absent default_value is returned. - * @param {string} name The name of the parameter. - * @param {string} defaultValue Value to return if paramater not found. - * @return {string} The parameter value or the default value if not found. - */ -BlocklyApps.getStringParamFromUrl = function(name, defaultValue) { - var val = - window.location.search.match(new RegExp('[?&]' + name + '=([^&]+)')); - return val ? decodeURIComponent(val[1].replace(/\+/g, '%20')) : defaultValue; -}; - -/** - * Extracts a numeric parameter from the URL. - * If the parameter is absent or less than min_value, min_value is - * returned. If it is greater than max_value, max_value is returned. - * @param {string} name The name of the parameter. - * @param {number} minValue The minimum legal value. - * @param {number} maxValue The maximum legal value. - * @return {number} A number in the range [min_value, max_value]. - */ -BlocklyApps.getNumberParamFromUrl = function(name, minValue, maxValue) { - var val = Number(BlocklyApps.getStringParamFromUrl(name, 'NaN')); - return isNaN(val) ? minValue : Math.min(Math.max(minValue, val), maxValue); -}; - -/** - * Use a series of heuristics that determine the likely language of this user. - * Use a session cookie to load/save the language preference. - * @return {string} User's language. - * @throws {string} If no languages exist in this app. - */ -BlocklyApps.getLang = function() { - // First choice: The URL specified language. - var lang = BlocklyApps.getStringParamFromUrl('lang', ''); - if (BlocklyApps.LANGUAGES.indexOf(lang) != -1) { - // Save this explicit choice as cookie. - // Use of a session cookie for saving language is explicitly permitted - // in the EU's Cookie Consent Exemption policy. Section 3.6: - // http://ec.europa.eu/justice/data-protection/article-29/documentation/ - // opinion-recommendation/files/2012/wp194_en.pdf - document.cookie = 'lang=' + escape(lang) + '; path=/'; - return lang; - } - // Second choice: Language cookie. - var cookie = document.cookie.match(/(^|;)\s*lang=(\w+)/); - if (cookie) { - lang = unescape(cookie[2]); - if (BlocklyApps.LANGUAGES.indexOf(lang) != -1) { - return lang; - } - } - // Third choice: The browser's language. - lang = navigator.language; - if (BlocklyApps.LANGUAGES.indexOf(lang) != -1) { - return lang; - } - // Fourth choice: English. - lang = 'en'; - if (BlocklyApps.LANGUAGES.indexOf(lang) != -1) { - return lang; - } - // Fifth choice: I'm feeling lucky. - if (BlocklyApps.LANGUAGES.length) { - return BlocklyApps.LANGUAGES[0]; - } - // Sixth choice: Die. - throw 'No languages available.'; -}; - -/** - * Is the current language (BlocklyApps.LANG) an RTL language? - * @return {boolean} True if RTL, false if LTR. - */ -BlocklyApps.isRtl = function() { - return BlocklyApps.LANGUAGE_RTL.indexOf(BlocklyApps.LANG) != -1; -}; - -/** - * Look up the Blockly language pack for current language (BlocklyApps.LANG). - * @return {string} URL to langugae pack (e.g. 'msg/js/en.js'). - */ -BlocklyApps.languagePack = function() { - return BlocklyApps.LANGUAGE_PACK[BlocklyApps.LANG] || - BlocklyApps.LANGUAGE_PACK['default']; -}; - -/** - * Common startup tasks for all apps. - */ -BlocklyApps.init = function() { - // Set the page title with the content of the H1 title. - document.title = document.getElementById('title').textContent; - - // Set the HTML's language and direction. - // document.dir fails in Mozilla, use document.body.parentNode.dir instead. - // https://bugzilla.mozilla.org/show_bug.cgi?id=151407 - var rtl = BlocklyApps.isRtl(); - document.head.parentElement.setAttribute('dir', rtl ? 'rtl' : 'ltr'); - document.head.parentElement.setAttribute('lang', BlocklyApps.LANG); - - // Sort languages alphabetically. - var languages = []; - for (var i = 0; i < BlocklyApps.LANGUAGES.length; i++) { - var lang = BlocklyApps.LANGUAGES[i]; - languages.push([BlocklyApps.LANGUAGE_NAME[lang], lang]); - } - var comp = function(a, b) { - // Sort based on first argument ('English', 'Русский', '简体字', etc). - if (a[0] > b[0]) return 1; - if (a[0] < b[0]) return -1; - return 0; - }; - languages.sort(comp); - // Populate the language selection menu. - var languageMenu = document.getElementById('languageMenu'); - languageMenu.options.length = 0; - for (var i = 0; i < languages.length; i++) { - var tuple = languages[i]; - var lang = tuple[tuple.length - 1]; - var option = new Option(tuple[0], lang); - if (lang == BlocklyApps.LANG) { - option.selected = true; - } - languageMenu.options.add(option); - } - languageMenu.addEventListener('change', BlocklyApps.changeLanguage, true); - - // Disable the link button if page isn't backed by App Engine storage. - var linkButton = document.getElementById('linkButton'); - if ('BlocklyStorage' in window) { - BlocklyStorage['HTTPREQUEST_ERROR'] = - BlocklyApps.getMsg('httpRequestError'); - BlocklyStorage['LINK_ALERT'] = BlocklyApps.getMsg('linkAlert'); - BlocklyStorage['HASH_ERROR'] = BlocklyApps.getMsg('hashError'); - BlocklyStorage['XML_ERROR'] = BlocklyApps.getMsg('xmlError'); - // Swap out the BlocklyStorage's alert() for a nicer dialog. - BlocklyStorage.alert = BlocklyApps.storageAlert; - BlocklyApps.bindClick(linkButton, BlocklyStorage.link); - } else if (linkButton) { - linkButton.className = 'disabled'; - } - - if (document.getElementById('codeButton')) { - BlocklyApps.bindClick('codeButton', BlocklyApps.showCode); - } - - // Fixes viewport for small screens. - var viewport = document.querySelector('meta[name="viewport"]'); - if (viewport && screen.availWidth < 725) { - viewport.setAttribute('content', - 'width=725, initial-scale=.35, user-scalable=no'); - } -}; - -/** - * Initialize Blockly for a readonly iframe. Called on page load. - * XML argument may be generated from the console with: - * encodeURIComponent(Blockly.Xml.domToText(Blockly.Xml.workspaceToDom(Blockly.mainWorkspace)).slice(5, -6)) - */ -BlocklyApps.initReadonly = function() { - Blockly.inject(document.getElementById('blockly'), - {media: '../../media/', - readOnly: true, - rtl: BlocklyApps.isRtl(), - scrollbars: false}); - - // Add the blocks. - var xml = BlocklyApps.getStringParamFromUrl('xml', ''); - xml = Blockly.Xml.textToDom('' + xml + ''); - Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); -}; - -/** - * Load blocks saved on App Engine Storage or in session/local storage. - * @param {string} defaultXml Text representation of default blocks. - */ -BlocklyApps.loadBlocks = function(defaultXml) { - try { - var loadOnce = window.sessionStorage.loadOnceBlocks; - } catch(e) { - // Firefox sometimes throws a SecurityError when accessing sessionStorage. - // Restarting Firefox fixes this, so it looks like a bug. - var loadOnce = null; - } - if ('BlocklyStorage' in window && window.location.hash.length > 1) { - // An href with #key trigers an AJAX call to retrieve saved blocks. - BlocklyStorage.retrieveXml(window.location.hash.substring(1)); - } else if (loadOnce) { - // Language switching stores the blocks during the reload. - delete window.sessionStorage.loadOnceBlocks; - var xml = Blockly.Xml.textToDom(loadOnce); - Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); - } else if (defaultXml) { - // Load the editor with default starting blocks. - var xml = Blockly.Xml.textToDom(defaultXml); - Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); - } else if ('BlocklyStorage' in window) { - // Restore saved blocks in a separate thread so that subsequent - // initialization is not affected from a failed load. - window.setTimeout(BlocklyStorage.restoreBlocks, 0); - } -}; - -/** - * Save the blocks and reload with a different language. - */ -BlocklyApps.changeLanguage = function() { - // Store the blocks for the duration of the reload. - // This should be skipped for the index page, which has no blocks and does - // not load Blockly. - // MSIE 11 does not support sessionStorage on file:// URLs. - if (typeof Blockly != 'undefined' && window.sessionStorage) { - var xml = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace); - var text = Blockly.Xml.domToText(xml); - window.sessionStorage.loadOnceBlocks = text; - } - - var languageMenu = document.getElementById('languageMenu'); - var newLang = encodeURIComponent( - languageMenu.options[languageMenu.selectedIndex].value); - var search = window.location.search; - if (search.length <= 1) { - search = '?lang=' + newLang; - } else if (search.match(/[?&]lang=[^&]*/)) { - search = search.replace(/([?&]lang=)[^&]*/, '$1' + newLang); - } else { - search = search.replace(/\?/, '?lang=' + newLang + '&'); - } - - window.location = window.location.protocol + '//' + - window.location.host + window.location.pathname + search; -}; - -/** - * Highlight the block (or clear highlighting). - * @param {?string} id ID of block that triggered this action. - */ -BlocklyApps.highlight = function(id) { - if (id) { - var m = id.match(/^block_id_(\d+)$/); - if (m) { - id = m[1]; - } - } - Blockly.mainWorkspace.highlightBlock(id); -}; - -/** - * If the user has executed too many actions, we're probably in an infinite - * loop. Sadly I wasn't able to solve the Halting Problem. - * @param {?string} opt_id ID of loop block to highlight. - * @throws {Infinity} Throws an error to terminate the user's program. - */ -BlocklyApps.checkTimeout = function(opt_id) { - if (opt_id) { - BlocklyApps.log.push([null, opt_id]); - } - if (BlocklyApps.ticks-- < 0) { - throw Infinity; - } -}; - -/** - * Is the dialog currently onscreen? - * @private - */ -BlocklyApps.isDialogVisible_ = false; - -/** - * A closing dialog should animate towards this element. - * @type Element - * @private - */ -BlocklyApps.dialogOrigin_ = null; - -/** - * A function to call when a dialog closes. - * @type Function - * @private - */ -BlocklyApps.dialogDispose_ = null; - -/** - * Show the dialog pop-up. - * @param {!Element} content DOM element to display in the dialog. - * @param {Element} origin Animate the dialog opening/closing from/to this - * DOM element. If null, don't show any animations for opening or closing. - * @param {boolean} animate Animate the dialog opening (if origin not null). - * @param {boolean} modal If true, grey out background and prevent interaction. - * @param {!Object} style A dictionary of style rules for the dialog. - * @param {Function} disposeFunc An optional function to call when the dialog - * closes. Normally used for unhooking events. - */ -BlocklyApps.showDialog = function(content, origin, animate, modal, style, - disposeFunc) { - if (BlocklyApps.isDialogVisible_) { - BlocklyApps.hideDialog(false); - } - BlocklyApps.isDialogVisible_ = true; - BlocklyApps.dialogOrigin_ = origin; - BlocklyApps.dialogDispose_ = disposeFunc; - var dialog = document.getElementById('dialog'); - var shadow = document.getElementById('dialogShadow'); - var border = document.getElementById('dialogBorder'); - - // Copy all the specified styles to the dialog. - for (var name in style) { - dialog.style[name] = style[name]; - } - if (modal) { - shadow.style.visibility = 'visible'; - shadow.style.opacity = 0.3; - var header = document.createElement('div'); - header.id = 'dialogHeader'; - dialog.appendChild(header); - BlocklyApps.dialogMouseDownWrapper_ = - Blockly.bindEvent_(header, 'mousedown', null, - BlocklyApps.dialogMouseDown_); - } - dialog.appendChild(content); - content.className = content.className.replace('dialogHiddenContent', ''); - - function endResult() { - // Check that the dialog wasn't closed during opening. - if (BlocklyApps.isDialogVisible_) { - dialog.style.visibility = 'visible'; - dialog.style.zIndex = 1; - border.style.visibility = 'hidden'; - } - } - if (animate && origin) { - BlocklyApps.matchBorder_(origin, false, 0.2); - BlocklyApps.matchBorder_(dialog, true, 0.8); - // In 175ms show the dialog and hide the animated border. - window.setTimeout(endResult, 175); - } else { - // No animation. Just set the final state. - endResult(); - } -}; - -/** - * Horizontal start coordinate of dialog drag. - */ -BlocklyApps.dialogStartX_ = 0; - -/** - * Vertical start coordinate of dialog drag. - */ -BlocklyApps.dialogStartY_ = 0; - -/** - * Handle start of drag of dialog. - * @param {!Event} e Mouse down event. - * @private - */ -BlocklyApps.dialogMouseDown_ = function(e) { - BlocklyApps.dialogUnbindDragEvents_(); - if (Blockly.isRightButton(e)) { - // Right-click. - return; - } - // Left click (or middle click). - // Record the starting offset between the current location and the mouse. - var dialog = document.getElementById('dialog'); - BlocklyApps.dialogStartX_ = dialog.offsetLeft - e.clientX; - BlocklyApps.dialogStartY_ = dialog.offsetTop - e.clientY; - - BlocklyApps.dialogMouseUpWrapper_ = Blockly.bindEvent_(document, - 'mouseup', null, BlocklyApps.dialogUnbindDragEvents_); - BlocklyApps.dialogMouseMoveWrapper_ = Blockly.bindEvent_(document, - 'mousemove', null, BlocklyApps.dialogMouseMove_); - // This event has been handled. No need to bubble up to the document. - e.stopPropagation(); -}; - -/** - * Drag the dialog to follow the mouse. - * @param {!Event} e Mouse move event. - * @private - */ -BlocklyApps.dialogMouseMove_ = function(e) { - var dialog = document.getElementById('dialog'); - var dialogLeft = BlocklyApps.dialogStartX_ + e.clientX; - var dialogTop = BlocklyApps.dialogStartY_ + e.clientY; - dialogTop = Math.max(dialogTop, 0); - dialogTop = Math.min(dialogTop, window.innerHeight - dialog.offsetHeight); - dialogLeft = Math.max(dialogLeft, 0); - dialogLeft = Math.min(dialogLeft, window.innerWidth - dialog.offsetWidth); - dialog.style.left = dialogLeft + 'px'; - dialog.style.top = dialogTop + 'px'; -}; - -/** - * Stop binding to the global mouseup and mousemove events. - * @private - */ -BlocklyApps.dialogUnbindDragEvents_ = function() { - if (BlocklyApps.dialogMouseUpWrapper_) { - Blockly.unbindEvent_(BlocklyApps.dialogMouseUpWrapper_); - BlocklyApps.dialogMouseUpWrapper_ = null; - } - if (BlocklyApps.dialogMouseMoveWrapper_) { - Blockly.unbindEvent_(BlocklyApps.dialogMouseMoveWrapper_); - BlocklyApps.dialogMouseMoveWrapper_ = null; - } -}; - -/** - * Hide the dialog pop-up. - * @param {boolean} opt_animate Animate the dialog closing. Defaults to true. - * Requires that origin was not null when dialog was opened. - */ -BlocklyApps.hideDialog = function(opt_animate) { - if (!BlocklyApps.isDialogVisible_) { - return; - } - BlocklyApps.dialogUnbindDragEvents_(); - if (BlocklyApps.dialogMouseDownWrapper_) { - Blockly.unbindEvent_(BlocklyApps.dialogMouseDownWrapper_); - BlocklyApps.dialogMouseDownWrapper_ = null; - } - - BlocklyApps.isDialogVisible_ = false; - BlocklyApps.dialogDispose_ && BlocklyApps.dialogDispose_(); - BlocklyApps.dialogDispose_ = null; - var origin = (opt_animate === false) ? null : BlocklyApps.dialogOrigin_; - var dialog = document.getElementById('dialog'); - var shadow = document.getElementById('dialogShadow'); - var border = document.getElementById('dialogBorder'); - - shadow.style.opacity = 0; - - function endResult() { - shadow.style.visibility = 'hidden'; - border.style.visibility = 'hidden'; - } - if (origin) { - BlocklyApps.matchBorder_(dialog, false, 0.8); - BlocklyApps.matchBorder_(origin, true, 0.2); - // In 175ms hide both the shadow and the animated border. - window.setTimeout(endResult, 175); - } else { - // No animation. Just set the final state. - endResult(); - } - dialog.style.visibility = 'hidden'; - dialog.style.zIndex = -1; - var header = document.getElementById('dialogHeader'); - if (header) { - header.parentNode.removeChild(header); - } - while (dialog.firstChild) { - var content = dialog.firstChild; - content.className += ' dialogHiddenContent'; - document.body.appendChild(content); - } -}; - -/** - * Match the animated border to the a element's size and location. - * @param {!Element} element Element to match. - * @param {boolean} animate Animate to the new location. - * @param {number} opacity Opacity of border. - * @private - */ -BlocklyApps.matchBorder_ = function(element, animate, opacity) { - if (!element) { - return; - } - var border = document.getElementById('dialogBorder'); - var bBox = BlocklyApps.getBBox_(element); - function change() { - border.style.width = bBox.width + 'px'; - border.style.height = bBox.height + 'px'; - border.style.left = bBox.x + 'px'; - border.style.top = bBox.y + 'px'; - border.style.opacity = opacity; - } - if (animate) { - border.className = 'dialogAnimate'; - window.setTimeout(change, 1); - } else { - border.className = ''; - change(); - } - border.style.visibility = 'visible'; -}; - -/** - * Compute the absolute coordinates and dimensions of an HTML or SVG element. - * @param {!Element} element Element to match. - * @return {!Object} Contains height, width, x, and y properties. - * @private - */ -BlocklyApps.getBBox_ = function(element) { - if (element.getBBox) { - // SVG element. - var bBox = element.getBBox(); - var height = bBox.height; - var width = bBox.width; - var xy = Blockly.getAbsoluteXY_(element); - var x = xy.x; - var y = xy.y; - } else { - // HTML element. - var height = element.offsetHeight; - var width = element.offsetWidth; - var x = 0; - var y = 0; - do { - x += element.offsetLeft; - y += element.offsetTop; - element = element.offsetParent; - } while (element); - } - return { - height: height, - width: width, - x: x, - y: y - }; -}; - -/** - * Display a storage-related modal dialog. - * @param {string} message Text to alert. - */ -BlocklyApps.storageAlert = function(message) { - var container = document.getElementById('containerStorage'); - container.textContent = ''; - var lines = message.split('\n'); - for (var i = 0; i < lines.length; i++) { - var p = document.createElement('p'); - p.appendChild(document.createTextNode(lines[i])); - container.appendChild(p); - } - - var content = document.getElementById('dialogStorage'); - var origin = document.getElementById('linkButton'); - var style = { - width: '50%', - left: '25%', - top: '5em' - }; - BlocklyApps.showDialog(content, origin, true, true, style, - BlocklyApps.stopDialogKeyDown()); - BlocklyApps.startDialogKeyDown(); -}; - -/** - * Convert the user's code to raw JavaScript. - * @param {string} code Generated code. - * @return {string} The code without serial numbers and timeout checks. - */ -BlocklyApps.stripCode = function(code) { - // Strip out serial numbers. - code = code.replace(/(,\s*)?'block_id_\d+'\)/g, ')'); - // Remove timeouts. - var regex = new RegExp(Blockly.JavaScript.INFINITE_LOOP_TRAP - .replace('(%1)', '\\((\'\\d+\')?\\)'), 'g'); - return code.replace(regex, ''); -}; - -/** - * Show the user's code in raw JavaScript. - * @param {!Event} e Mouse or touch event. - */ -BlocklyApps.showCode = function(e) { - var origin = e.target; - var code = Blockly.JavaScript.workspaceToCode(); - code = BlocklyApps.stripCode(code); - var pre = document.getElementById('containerCode'); - pre.textContent = code; - if (typeof prettyPrintOne == 'function') { - code = pre.innerHTML; - code = prettyPrintOne(code, 'js'); - pre.innerHTML = code; - } - - var content = document.getElementById('dialogCode'); - var style = { - width: '40%', - left: '30%', - top: '5em' - }; - BlocklyApps.showDialog(content, origin, true, true, style, - BlocklyApps.stopDialogKeyDown); - BlocklyApps.startDialogKeyDown(); -}; - -/** - * If the user preses enter, escape, or space, hide the dialog. - * @param {!Event} e Keyboard event. - * @private - */ -BlocklyApps.dialogKeyDown_ = function(e) { - if (BlocklyApps.isDialogVisible_) { - if (e.keyCode == 13 || - e.keyCode == 27 || - e.keyCode == 32) { - BlocklyApps.hideDialog(true); - e.stopPropagation(); - e.preventDefault(); - } - } -}; - -/** - * Start listening for BlocklyApps.dialogKeyDown_. - */ -BlocklyApps.startDialogKeyDown = function() { - document.body.addEventListener('keydown', - BlocklyApps.dialogKeyDown_, true); -}; - -/** - * Stop listening for BlocklyApps.dialogKeyDown_. - */ -BlocklyApps.stopDialogKeyDown = function() { - document.body.removeEventListener('keydown', - BlocklyApps.dialogKeyDown_, true); -}; - -/** - * Gets the message with the given key from the document. - * @param {string} key The key of the document element. - * @return {string} The textContent of the specified element, - * or an error message if the element was not found. - */ -BlocklyApps.getMsg = function(key) { - var msg = BlocklyApps.getMsgOrNull(key); - return msg === null ? '[Unknown message: ' + key + ']' : msg; -}; - -/** - * Gets the message with the given key from the document. - * @param {string} key The key of the document element. - * @return {string} The textContent of the specified element, - * or null if the element was not found. - */ -BlocklyApps.getMsgOrNull = function(key) { - var element = document.getElementById(key); - if (element) { - var text = element.textContent; - // Convert newline sequences. - text = text.replace(/\\n/g, '\n'); - return text; - } else { - return null; - } -}; - -/** - * Bind a function to a button's click event. - * On touch enabled browsers, ontouchend is treated as equivalent to onclick. - * @param {!Element|string} el Button element or ID thereof. - * @param {!Function} func Event handler to bind. - */ -BlocklyApps.bindClick = function(el, func) { - if (typeof el == 'string') { - el = document.getElementById(el); - } - el.addEventListener('click', func, true); - el.addEventListener('touchend', func, true); -}; - -/** - * Load the Prettify CSS and JavaScript. - */ -BlocklyApps.importPrettify = function() { - // - // - var link = document.createElement('link'); - link.setAttribute('rel', 'stylesheet'); - link.setAttribute('type', 'text/css'); - link.setAttribute('href', '../prettify.css'); - document.head.appendChild(link); - var script = document.createElement('script'); - script.setAttribute('type', 'text/javascript'); - script.setAttribute('src', '../prettify.js'); - document.head.appendChild(script); -}; diff --git a/apps/common.soy b/apps/common.soy deleted file mode 100644 index d688ab1af..000000000 --- a/apps/common.soy +++ /dev/null @@ -1,108 +0,0 @@ -{namespace apps} - -/** - * This is a Closure Template. - * - * Run the following command after changing the messages in any of the - * included apps subdirectories. If building on Windows, you may need to - * substitute '\' for '/'. - * - * java -jar _soy/SoyMsgExtractor.jar --outputFile extracted_msgs.xlf --srcs common.soy,code/template.soy - * - * Create en.json, keys.json, and qqq.json. - * ../i18n/xliff_to_json.py --xlf extracted_msgs.xlf --templates common.soy code/template.soy - * or in Windows: - * python ..\i18n\xliff_to_json.py --xlf extracted_msgs.xlf --templates common.soy code\template.soy - * - * Generate .js files for code app: - * ../i18n/json_to_js.py --output_dir=code/generated --template common.soy,code/template.soy json/*.json - * or in Windows: - * python ..\i18n\json_to_js.py --output_dir=code\generated --template common.soy,code\template.soy json\*.json - */ - -/** - * All messages to be translated. - */ -{template .messages} -
    - // Only used externally. - {msg meaning="Apps.subtitle" desc="A short description of Blockly."}a visual programming environment{/msg} - - // Common messages used in multiple applications are defined here. - // The applications' template.soy file may also contain msg statements - // with the same "meaning" value. The "desc" value must be set to "IBID" - // (case-insensitive) or identical to the one in this file (not - // recommended), or an error will be raised during generation of qqq.json. - // The source-language text in the applications' definitions is ignored. - {msg meaning="Blockly" desc="The project name. If readers of your language would know approximately how to pronounce 'Blockly', leave unchanged. Otherwise, include a transliteration in parentheses, such as the Russian: 'Blockly (Блoкли)'."}Blockly{/msg} - - // Buttons and tooltips. - {msg meaning="Apps.codeTooltip" desc="tooltip - Pressing the button causes a program in the JavaScript computer language to be displayed, based on the program created by the user."}See generated JavaScript code.{/msg} - {msg meaning="Apps.linkTooltip" desc="tooltip - Clicking on this button will cause the current program to be saved and for a URL to be shown to later retrieve it."}Save and link to blocks.{/msg} - {msg meaning="Apps.runTooltip" desc="tooltip - Pressing this button runs the computer program the user has written."}Run the program defined by the blocks in the workspace.{/msg} - {msg meaning="Apps.runProgram" desc="button label - Pressing the button runs the computer program the user has written."}Run Program{/msg} - {msg meaning="Apps.resetProgram" desc="button label - Pressing the button causes the output of the program to be erased but does not delete the user's program)."}Reset{/msg} - {{msg meaning="Apps.dialogOk" desc="Label on button for user to press when done reading help information.\n{lb}{lb}Identical|OK{rb}{rb}"}}OK{{/msg}} - {{msg meaning="Apps.dialogCancel" desc="Label on button for user to press when not wanting to proceed.\n{lb}{lb}Identical|Cancel{rb}{rb}"}}Cancel{{/msg}} - - // Categories. Apps can use these names or their own. - {msg meaning="Apps.catLogic" desc="category - Blocks related to [https://github.com/google/blockly/wiki/Logic logic]."}Logic{/msg} - {msg meaning="Apps.catLoops" desc="category - Blocks related to [https://en.wikipedia.org/wiki/Control_flow#Loops loops]."}Loops{/msg} - {msg meaning="Apps.catMath" desc="category - Blocks related to mathematics."}Math{/msg} - {{msg meaning="Apps.catText" desc="category - Blocks related to [https://github.com/google/blockly/wiki/Text text processing].\n{lb}{lb}Identical|Text{rb}{rb}"}}Text{{/msg}} - {{msg meaning="Apps.catLists" desc="category - Blocks related to [https://github.com/google/blockly/wiki/Lists lists].\n{lb}{lb}Identical|Lists{rb}{rb}"}}Lists{{/msg}} - {{msg meaning="Apps.catColour" desc="category - Blocks related to [https://github.com/google/blockly/wiki/Colour colour].\n{lb}{lb}Identical|Colour{rb}{rb}"}}Colour{{/msg}} - {msg meaning="Apps.catVariables" desc="category - Blocks related to [https://github.com/google/blockly/wiki/Variables variables]."}Variables{/msg} - {msg meaning="Apps.catProcedures" desc="category - Blocks related to [https://en.wikipedia.org/wiki/Subroutine defining or using procedures/functions]."}Functions{/msg} - - // Error messages related to loading/storing user programs. - {msg meaning="Apps.httpRequestError" desc="alert - The URL is invalid or a server error occurred. This message will be followed by technical information useful to engineers trying to understand the problem."}There was a problem with the request.{/msg} - {msg meaning="Apps.linkAlert" desc="alert - After the user has pressed a button to save his/her program, this provides the URL (%1) to retrieve the program. The characters '\n\n' indicate that a blank line will be displayed before the URL (in English). Leave those in unless you move %1 to the beginning or middle of the text, in which case you should use your judgment about where blank lines would be most useful.\n\nParameters:\n* %1 - URL of saved program."}Share your blocks with this link:\n\n%1{/msg} - {{msg meaning="Apps.hashError" desc="alert - A request to retrieve a stored program does not have a valid URL. %1 is the invalid portion of the URL."}}Sorry, '%1' doesn't correspond with any saved program.{{/msg}} - {msg meaning="Apps.xmlError" desc="alert - There was a problem loading a file previously saved by the user. The most likely reason for the problem is that it was created with an earlier, incompatible version of Blockly. This message will be followed by technical information useful to engineers trying to understand the problem."}Could not load your saved file. Perhaps it was created with a different version of Blockly?{/msg} - - // Default variable names. - {msg meaning="Apps.listVariable" desc="variable name - Default [https://github.com/google/blockly/wiki/Variables variable] representing a [https://github.com/google/blockly/wiki/Lists list]. This should be a single word, preferably short."}list{/msg} - {{msg meaning="Apps.textVariable" desc="variable name - Default [https://github.com/google/blockly/wiki/Variables variable] representing a [https://github.com/google/blockly/wiki/Text piece of text]. This should be a single word, preferably short.\n{lb}{lb}Identical|Text{rb}{rb}"}}text{{/msg}} -
    -{/template} - -/** - * Dialogs. - */ -{template .dialog private="true"} -
    -
    -
    -{/template} - -/** - * Code dialog. - */ -{template .codeDialog private="true"} -
    -
    
    -    {call apps.ok /}
    -  
    -{/template} - -/** - * Storage dialog. - */ -{template .storageDialog private="true"} -
    -
    - {call apps.ok /} -
    -{/template} - -/** - * OK button for dialogs. - */ -{template .ok private="true"} -
    - -
    -{/template} diff --git a/apps/index.html b/apps/index.html deleted file mode 100644 index 400f9c41e..000000000 --- a/apps/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - Blockly Apps - - - -

    Blockly Apps

    - -

    Blockly is a graphical programming environment. Below are some sample - applications that use Blockly.

    - - - - - - -
    - - - - - -
    Export a Blockly program into JavaScript, Python, Dart or XML.
    -
    - -

    Blockly is free and open source. To contribute code or translations to - Blockly, or to use Blockly in your own app, visit - developers.google.com/blockly.

    - - - diff --git a/apps/json/ace.json b/apps/json/ace.json deleted file mode 100644 index e9f9bbd2b..000000000 --- a/apps/json/ace.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Ayie7791" - ] - }, - "Apps.subtitle": "Ruweuëng meuprogram ban leumah", - "Blockly": "Teutheun", - "Apps.codeTooltip": "Eu kode JavaScript yang geupeuhasé", - "Apps.linkTooltip": "Keubah ngon neupawôt keu theun", - "Apps.runTooltip": "Neupeujak program nyang geupeuteutap le seuneutheun lam ruweuëng keurija", - "Apps.runProgram": "Peujak program", - "Apps.resetProgram": "Atô keulayi", - "Apps.dialogOk": "Ka got", - "Apps.dialogCancel": "Peubateuë", - "Apps.catLogic": "Logis", - "Apps.catLoops": "Kuwien", - "Apps.catMath": "Matematik", - "Apps.catText": "Haraih", - "Apps.catLists": "Dapeuta", - "Apps.catColour": "Wareuna", - "Apps.catVariables": "Meumacam", - "Apps.catProcedures": "Prosedur", - "Apps.httpRequestError": "Na masalah lam neumeulakèe", - "Apps.linkAlert": "Neubagi seuneutheun droëneuh ngon peunawôt nyoë: %1", - "Apps.hashError": "Meu'ah, '%1' hana saban sakri ngon peuë mantong program nyang meukeubah", - "Apps.xmlError": "Beureukaih keuneubah droëneuh han jeuët geupasoë. Kadang na neupeugot ngon versi seuneutheun yang la'én", - "Apps.listVariable": "dapeuta", - "Apps.textVariable": "haraih", - "Code.badXml": "Ralat 'oh geuploh XML\n%1\n\nNeupileh 'OK' keu peulucôt meuandam droëneuh atawa 'Peubateuë' keu neusambông meuandam XML-jih", - "Code.badCode": "Ralat program\n%1", - "Code.timeout": "Eksekusi maksimum ka leupah", - "Code.discard": "Sampôh mandum %1 seuneutheun", - "Code.title": "Kode", - "Code.blocks": "Seuneutheun", - "Code.trashTooltip": "Boh mandum seuneutheun" -} diff --git a/apps/json/ar.json b/apps/json/ar.json deleted file mode 100644 index 70319a061..000000000 --- a/apps/json/ar.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Espertus", - "Kuwaity26", - "Meno25", - "Mgi92" - ] - }, - "Apps.subtitle": "بيئة برمجة مرئية", - "Blockly": "بلوكلي", - "Apps.codeTooltip": "راجع إنشاء تعليمات برمجية JavaScript.", - "Apps.linkTooltip": "احفظ ووصلة إلى البلوكات.", - "Apps.runTooltip": "شغل البرنامج المعرف بواسطة البلوكات في مساحة العمل.", - "Apps.runProgram": "شغِّل البرنامج", - "Apps.resetProgram": "إعادة ضبط", - "Apps.dialogOk": "حسن", - "Apps.dialogCancel": "إلغاء الأمر", - "Apps.catLogic": "منطق", - "Apps.catLoops": "الحلقات", - "Apps.catMath": "رياضيات", - "Apps.catText": "نص", - "Apps.catLists": "قوائم", - "Apps.catColour": "لون", - "Apps.catVariables": "متغيرات", - "Apps.catProcedures": "إجراءات", - "Apps.httpRequestError": "كانت هناك مشكلة مع هذا الطلب.", - "Apps.linkAlert": "مشاركة كود بلوكلي الخاص بك مع هذا الرابط:\n %1", - "Apps.hashError": "عذراً،ال '%1' لا تتوافق مع أي برنامج تم حفظه.", - "Apps.xmlError": "تعذر تحميل الملف المحفوظة الخاصة بك. ربما تم إنشاؤه باستخدام إصدار مختلف من بلوكلي؟", - "Apps.listVariable": "قائمة", - "Apps.textVariable": "نص", - "Code.badXml": "خطأ في توزيع ال \"XML\":\n %1\n\nحدد 'موافق' للتخلي عن التغييرات أو 'إلغاء الأمر' لمواصلة تحرير ال\"XML\".", - "Code.badCode": "خطأ في البرنامج:\n %1", - "Code.timeout": "تم تجاوز الحد الأقصى لتكرارات التنفيذ .", - "Code.discard": "حذف كل بلوكات %1؟", - "Code.title": "كود", - "Code.blocks": "البلوكات", - "Code.trashTooltip": "تجاهل كل البلوكات." -} diff --git a/apps/json/az.json b/apps/json/az.json deleted file mode 100644 index 107ead308..000000000 --- a/apps/json/az.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Cekli829", - "Khan27", - "Mushviq Abdulla", - "Wertuose" - ] - }, - "Apps.dialogOk": "TAMAM", - "Apps.dialogCancel": "Ləğv et", - "Apps.catText": "Mətn", - "Apps.catLists": "Siyahılar", - "Apps.catColour": "Rəng", - "Apps.catVariables": "Dəyişənlər", - "Apps.catProcedures": "Funksiyalar", - "Apps.httpRequestError": "Sorğu ilə əlaqəli problem var.", - "Apps.listVariable": "siyahı", - "Apps.textVariable": "mətn", - "Code.badCode": "Proqram xətası:\n%1", - "Code.title": "Kod", - "Code.blocks": "Bloklar", - "Code.trashTooltip": "Bütün bloklardan imtina et." -} diff --git a/apps/json/be-tarask.json b/apps/json/be-tarask.json deleted file mode 100644 index 91a0e00cc..000000000 --- a/apps/json/be-tarask.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Wizardist", - "Jim-by", - "Renessaince" - ] - }, - "Apps.subtitle": "Асяродзьдзе віртуальнага праграмаваньня", - "Blockly": "Blockly (Блоклі)", - "Apps.codeTooltip": "Глядзі згенераваны код JavaScript.", - "Apps.linkTooltip": "Захаваць і зьвязаць з блёкамі.", - "Apps.runTooltip": "Запусьціце праграму, вызначаную блёкамі ў працоўнай вобласьці.", - "Apps.runProgram": "Запусьціць праграму", - "Apps.resetProgram": "Скасаваць", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Скасаваць", - "Apps.catLogic": "Лёгіка", - "Apps.catLoops": "Петлі", - "Apps.catMath": "Матэматычныя формулы", - "Apps.catText": "Тэкст", - "Apps.catLists": "Сьпісы", - "Apps.catColour": "Колер", - "Apps.catVariables": "Зьменныя", - "Apps.catProcedures": "Функцыі", - "Apps.httpRequestError": "Узьнікла праблема з запытам.", - "Apps.linkAlert": "Падзяліцца Вашым блёкам праз гэтую спасылку:\n\n%1", - "Apps.hashError": "Прабачце, '%1' не адпавядае ніводнай захаванай праграме.", - "Apps.xmlError": "Не атрымалася загрузіць захаваны файл. Магчыма, ён быў створаны з іншай вэрсіяй Блёклі?", - "Apps.listVariable": "сьпіс", - "Apps.textVariable": "тэкст", - "Code.badXml": "Памылка сынтаксічнага аналізу XML:\n%1\n\nАбярыце \"ОК\", каб адмовіцца ад зьменаў ці \"Скасаваць\" для далейшага рэдагаваньня XML.", - "Code.badCode": "Памылка праграмы:\n%1", - "Code.timeout": "Перавышана максымальная колькасьць ітэрацыяў.", - "Code.discard": "Выдаліць усе блёкі %1?", - "Code.title": "Код", - "Code.blocks": "Блёкі", - "Code.trashTooltip": "Выдаліць усе блёкі." -} diff --git a/apps/json/br.json b/apps/json/br.json deleted file mode 100644 index 3a67cb157..000000000 --- a/apps/json/br.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Fohanno", - "Fulup", - "Gwenn-Ael", - "Y-M D" - ] - }, - "Apps.subtitle": "un endro programmiñ da welet", - "Blockly": "Blockly", - "Apps.codeTooltip": "Gwelet ar c'hod JavaScript krouet.", - "Apps.linkTooltip": "Enrollañ ha liammañ d'ar bloc'hadoù.", - "Apps.runTooltip": "Lañsañ ar programm termenet gant ar bloc'hadoù en takad labour.", - "Apps.runProgram": "Lañsañ ar programm", - "Apps.resetProgram": "Adderaouekaat", - "Apps.dialogOk": "Mat eo", - "Apps.dialogCancel": "Nullañ", - "Apps.catLogic": "Poell", - "Apps.catLoops": "Boukloù", - "Apps.catMath": "Matematik", - "Apps.catText": "Testenn", - "Apps.catLists": "Rolloù", - "Apps.catColour": "Liv", - "Apps.catVariables": "Argemmennoù", - "Apps.catProcedures": "Arc'hwelioù", - "Apps.httpRequestError": "Ur gudenn zo gant ar reked.", - "Apps.linkAlert": "Rannañ ho ploc'hoù gant al liamm-mañ :\n\n%1", - "Apps.hashError": "Digarezit. \"%1\" ne glot gant programm enrollet ebet.", - "Apps.xmlError": "Ne c'haller ket kargañ ho restr enrollet. Marteze e oa bet krouet gant ur stumm disheñvel eus Blockly ?", - "Apps.listVariable": "roll", - "Apps.textVariable": "testenn", - "Code.badXml": "Fazi dielfennañ XML :\n%1\n\nDibabit \"Mat eo\" evit dilezel ar c'hemmoù-se pe \"Nullañ\" evit kemmañ an XML c'hoazh.", - "Code.badCode": "Fazi programm :\n%1", - "Code.timeout": "Tizhet eo bet an niver brasañ a iteradurioù seveniñ aotreet.", - "Code.discard": "Diverkañ an holl vloc'hoù %1 ?", - "Code.title": "Kod", - "Code.blocks": "Bloc'hoù", - "Code.trashTooltip": "Disteurel an holl vloc'hoù." -} diff --git a/apps/json/ca.json b/apps/json/ca.json deleted file mode 100644 index dd370240e..000000000 --- a/apps/json/ca.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Alvaro Vidal-Abarca", - "Fitoschido" - ] - }, - "Apps.subtitle": "un entorn visual de programació", - "Blockly": "Blockly", - "Apps.codeTooltip": "Vegeu el codi JavaScript generat.", - "Apps.linkTooltip": "Desa i enllaça als blocs.", - "Apps.runTooltip": "Executa el programa definit pels blocs de l'àrea de treball.", - "Apps.runProgram": "Executa el programa", - "Apps.resetProgram": "Reinicialitza", - "Apps.dialogOk": "D'acord", - "Apps.dialogCancel": "Cancel·la", - "Apps.catLogic": "Lògica", - "Apps.catLoops": "Bucles", - "Apps.catMath": "Matemàtiques", - "Apps.catText": "Text", - "Apps.catLists": "Llistes", - "Apps.catColour": "Color", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Procediments", - "Apps.httpRequestError": "Hi ha hagut un problema amb la sol·licitud.", - "Apps.linkAlert": "Comparteix els teus blocs amb aquest enllaç: %1", - "Apps.hashError": "Ho sentim, '%1' no es correspon amb cap fitxer desat de Blockly.", - "Apps.xmlError": "No s'ha pogut carregar el teu fitxer desat. Potser va ser creat amb una versió diferent de Blockly?", - "Apps.listVariable": "llista", - "Apps.textVariable": "text", - "Code.badXml": "Error d'anàlisi XML:\n%1\n\nSeleccioneu 'Acceptar' per abandonar els vostres canvis, o 'Cancel·lar' per continuar editant l'XML.", - "Code.badCode": "Error de programa:\n %1", - "Code.timeout": "S'ha superat el nombre màxim d'iteracions d'execució.", - "Code.discard": "Esborrar els %1 blocs?", - "Code.title": "Codi", - "Code.blocks": "Blocs", - "Code.trashTooltip": "Descarta tots els blocs." -} diff --git a/apps/json/cs.json b/apps/json/cs.json deleted file mode 100644 index a50036da0..000000000 --- a/apps/json/cs.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Chmee2", - "Michaelbrabec" - ] - }, - "Apps.subtitle": "grafické programovací prostředí", - "Blockly": "Blockly", - "Apps.codeTooltip": "Zobrazit generovaný JavaScriptový kód.", - "Apps.linkTooltip": "Ulož a spoj bloky..", - "Apps.runProgram": "Spusť program", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Zrušit", - "Apps.catLogic": "Logika", - "Apps.catLoops": "Smyčky", - "Apps.catMath": "Matematika", - "Apps.catText": "Text", - "Apps.catLists": "Seznamy", - "Apps.catColour": "Barva", - "Apps.catVariables": "Proměnné", - "Apps.catProcedures": "Procedury", - "Apps.httpRequestError": "Došlo k potížím s požadavkem.", - "Apps.linkAlert": "Sdílej bloky tímto odkazem: \n\n%1", - "Apps.hashError": "Omlouváme se, '%1' nesouhlasí s žádným z uložených souborů.", - "Apps.xmlError": "Nepodařilo se uložit vás soubor. Pravděpodobně byl vytvořen jinou verzí Blockly?", - "Apps.listVariable": "seznam", - "Apps.textVariable": "text", - "Code.badXml": "Chyba parsování XML:\n%1\n\nVybrat \"OK\" pro zahození vašich změn nebo 'Cancel' k dalšímu upravování XML.", - "Code.badCode": "Chyba programu:\n%1", - "Code.discard": "Odstranit všechny bloky %1?", - "Code.title": "Kód", - "Code.blocks": "Bloky", - "Code.trashTooltip": "Zahodit všechny bloky." -} diff --git a/apps/json/da.json b/apps/json/da.json deleted file mode 100644 index 33810a756..000000000 --- a/apps/json/da.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Christian List", - "Hein0170", - "Peter Alberti", - "Simeondahl" - ] - }, - "Apps.subtitle": "et visuelt programmeringsmiljø", - "Blockly": "Blockly", - "Apps.codeTooltip": "Se den genererede JavaScript kode.", - "Apps.linkTooltip": "Gem og link til blokke.", - "Apps.runTooltip": "Kør programmet, der er defineret af blokkene i arbejdsområdet.", - "Apps.runProgram": "Kør program", - "Apps.resetProgram": "Nulstil", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Afbryd", - "Apps.catLogic": "Logik", - "Apps.catLoops": "Løkker", - "Apps.catMath": "Matematik", - "Apps.catText": "Tekst", - "Apps.catLists": "Lister", - "Apps.catColour": "Farve", - "Apps.catVariables": "Variabler", - "Apps.catProcedures": "Funktioner", - "Apps.httpRequestError": "Der var et problem med forespørgslen.", - "Apps.linkAlert": "Del dine blokke med dette link:\n\n%1", - "Apps.hashError": "Beklager, '%1' passer ikke med nogen gemt Blockly fil.", - "Apps.xmlError": "Kunne ikke hente din gemte fil. Måske er den lavet med en anden udgave af Blockly?", - "Apps.listVariable": "liste", - "Apps.textVariable": "tekst", - "Code.badXml": "Fejl under fortolkningen af XML:\n%1\n\nVælg 'OK' for at opgive dine ændringer eller 'Afbryd' for at redigere XML-filen yderligere.", - "Code.badCode": "Programfejl:\n%1", - "Code.timeout": "Maksimale antal udførelsesgentagelser overskredet.", - "Code.discard": "Slet alle %1 blokke?", - "Code.title": "Kode", - "Code.blocks": "Blokke", - "Code.trashTooltip": "Kassér alle blokke." -} diff --git a/apps/json/de.json b/apps/json/de.json deleted file mode 100644 index dca3eb7ea..000000000 --- a/apps/json/de.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Flow", - "Metalhead64", - "Das Schäfchen" - ] - }, - "Apps.subtitle": "Visuelle Programmierumgebung", - "Blockly": "Blockly", - "Apps.codeTooltip": "Erzeugten JavaScript-Code ansehen.", - "Apps.linkTooltip": "Speichern und auf Bausteine verlinken.", - "Apps.runTooltip": "Das Programm ausführen, das von den Bausteinen im Arbeitsbereich definiert ist.", - "Apps.runProgram": "Programm ausführen", - "Apps.resetProgram": "Zurücksetzen", - "Apps.dialogOk": "Okay", - "Apps.dialogCancel": "Abbrechen", - "Apps.catLogic": "Logik", - "Apps.catLoops": "Schleifen", - "Apps.catMath": "Mathematik", - "Apps.catText": "Text", - "Apps.catLists": "Listen", - "Apps.catColour": "Farbe", - "Apps.catVariables": "Variablen", - "Apps.catProcedures": "Funktionen", - "Apps.httpRequestError": "Mit der Anfrage gab es ein Problem.", - "Apps.linkAlert": "Teile deine Bausteine mit diesem Link:\n\n%1", - "Apps.hashError": "„%1“ stimmt leider mit keinem gespeicherten Programm überein.", - "Apps.xmlError": "Deine gespeicherte Datei konnte nicht geladen werden. Vielleicht wurde sie mit einer anderen Version von Blockly erstellt.", - "Apps.listVariable": "Liste", - "Apps.textVariable": "Text", - "Code.badXml": "Fehler beim Parsen von XML:\n%1\n\nWähle 'OK' zum Verwerfen deiner Änderungen oder 'Abbrechen' zum weiteren Bearbeiten des XML.", - "Code.badCode": "Programmfehler:\n%1", - "Code.timeout": "Die maximalen Ausführungswiederholungen wurden überschritten.", - "Code.discard": "Alle %1 Bausteine löschen?", - "Code.title": "Code", - "Code.blocks": "Bausteine", - "Code.trashTooltip": "Alle Bausteine verwerfen." -} diff --git a/apps/json/diq.json b/apps/json/diq.json deleted file mode 100644 index 9d0945ef6..000000000 --- a/apps/json/diq.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Gorizon", - "Marmase", - "Mirzali" - ] - }, - "Apps.subtitle": "yew grafikê programkerdışê dormey", - "Blockly": "Blockly", - "Apps.codeTooltip": "Kodê JavaScriptê vıraştey bımocne.", - "Apps.linkTooltip": "Qeyd ke û be blokan ra gıre de.", - "Apps.runTooltip": "Cayê kari de programo ke terefê blokan ra name biyo, ey bıgurene.", - "Apps.runProgram": "Programi Akar fi", - "Apps.resetProgram": "Reset kerê", - "Apps.dialogOk": "TEMAM", - "Apps.dialogCancel": "Bıtexelne", - "Apps.catLogic": "Mantığ", - "Apps.catLoops": "Dingeki", - "Apps.catMath": "Matematik", - "Apps.catText": "Metin", - "Apps.catLists": "Listey", - "Apps.catColour": "Reng", - "Apps.catVariables": "Vırneyeni", - "Apps.catProcedures": "Fonksiyoni", - "Apps.httpRequestError": "waştışi deyne zew problem esto", - "Apps.linkAlert": "Blokan na linkera bıhesrne\n\n%1", - "Apps.hashError": "Melûlime, '%1' be qet yew programi ra yewbini nêgêno.", - "Apps.listVariable": "liste", - "Apps.textVariable": "nuşte", - "Code.badCode": "Xeta programi:%1", - "Code.title": "Kod", - "Code.blocks": "Bloki", - "Code.trashTooltip": "Blokan hemın çek" -} diff --git a/apps/json/el.json b/apps/json/el.json deleted file mode 100644 index 7ef27182c..000000000 --- a/apps/json/el.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Azountas", - "Evropi", - "Namatreasure", - "Sfyrakis", - "Tifa93", - "Indoril" - ] - }, - "Apps.subtitle": "γραφικό περιβάλλον προγραμματισμού", - "Blockly": "Blockly (Μπλόκλι)", - "Apps.codeTooltip": "Δες τον κώδικα JavaScript που δημιουργήθηκε.", - "Apps.linkTooltip": "Αποθηκεύει και συνδέει σε μπλοκ.", - "Apps.runTooltip": "Εκτελεί το πρόγραμμα που ορίζεται από τα μπλοκ στον χώρο εργασίας.", - "Apps.runProgram": "Εκτέλεση Προγράμματος", - "Apps.resetProgram": "Επανεκκίνηση", - "Apps.dialogOk": "Εντάξει", - "Apps.dialogCancel": "Ακύρωση", - "Apps.catLogic": "Λογική", - "Apps.catLoops": "Επαναλήψεις", - "Apps.catMath": "Μαθηματικά", - "Apps.catText": "Κείμενο", - "Apps.catLists": "Λίστες", - "Apps.catColour": "Χρώμα", - "Apps.catVariables": "Μεταβλητές", - "Apps.catProcedures": "Συναρτήσεις", - "Apps.httpRequestError": "Υπήρξε πρόβλημα με το αίτημα.", - "Apps.linkAlert": "Κοινοποίησε τα μπλοκ σου με αυτόν τον σύνδεσμο:\n\n%1", - "Apps.hashError": "Λυπάμαι, το «%1» δεν αντιστοιχεί σε κανένα αποθηκευμένο πρόγραμμα.", - "Apps.xmlError": "Δεν μπορώ να φορτώσω το αποθηκευμένο αρχείο σου. Μήπως δημιουργήθηκε από μία παλιότερη έκδοση του Blockly;", - "Apps.listVariable": "λίστα", - "Apps.textVariable": "κείμενο", - "Code.badXml": "Σφάλμα ανάλυσης XML:\n%1\n\nΕπίλεξε «Εντάξει» για να εγκαταλείψεις τις αλλαγές σου ή «Ακύρωση» για να επεξεργαστείς το XML κι άλλο.", - "Code.badCode": "Σφάλμα προγράμματος:\n%1", - "Code.timeout": "Υπέρβαση μέγιστου αριθμού επαναλήψεων.", - "Code.discard": "Να διαγραφούν και τα %1 μπλοκ?", - "Code.title": "Κώδικας", - "Code.blocks": "Μπλοκ", - "Code.trashTooltip": "Απόρριψη όλων των μπλοκ." -} diff --git a/apps/json/en.json b/apps/json/en.json deleted file mode 100644 index cf265c08b..000000000 --- a/apps/json/en.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "author": "Ellen Spertus ", - "lastupdated": "2014-11-14 14:57:01.750962", - "locale": "en", - "messagedocumentation" : "qqq" - }, - "Apps.subtitle": "a visual programming environment", - "Blockly": "Blockly", - "Apps.codeTooltip": "See generated JavaScript code.", - "Apps.linkTooltip": "Save and link to blocks.", - "Apps.runTooltip": "Run the program defined by the blocks in the workspace.", - "Apps.runProgram": "Run Program", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Cancel", - "Apps.catLogic": "Logic", - "Apps.catLoops": "Loops", - "Apps.catMath": "Math", - "Apps.catText": "Text", - "Apps.catLists": "Lists", - "Apps.catColour": "Colour", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Functions", - "Apps.httpRequestError": "There was a problem with the request.", - "Apps.linkAlert": "Share your blocks with this link:\n\n%1", - "Apps.hashError": "Sorry, '%1' doesn't correspond with any saved program.", - "Apps.xmlError": "Could not load your saved file. Perhaps it was created with a different version of Blockly?", - "Apps.listVariable": "list", - "Apps.textVariable": "text", - "Code.badXml": "Error parsing XML:\n%1\n\nSelect 'OK' to abandon your changes or 'Cancel' to further edit the XML.", - "Code.badCode": "Program error:\n%1", - "Code.timeout": "Maximum execution iterations exceeded.", - "Code.discard": "Delete all %1 blocks?", - "Code.title": "Code", - "Code.blocks": "Blocks", - "Code.trashTooltip": "Discard all blocks." -} diff --git a/apps/json/es.json b/apps/json/es.json deleted file mode 100644 index 1ce73e690..000000000 --- a/apps/json/es.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "@metadata": { - "authors": [ - "EDGI", - "Fitoschido", - "McDutchie", - "VegaDark", - "WeSiToS" - ] - }, - "Apps.subtitle": "un entorno de programación visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Mira el código JavaScript generado.", - "Apps.linkTooltip": "Guarda conexión a los bloques.", - "Apps.runTooltip": "Ejecute el programa definido por los bloques en el área de trabajo.", - "Apps.runProgram": "Ejecutar el programa", - "Apps.resetProgram": "Restablecer", - "Apps.dialogOk": "Aceptar", - "Apps.dialogCancel": "Cancelar", - "Apps.catLogic": "Lógica", - "Apps.catLoops": "Secuencias", - "Apps.catMath": "Matemáticas", - "Apps.catText": "Texto", - "Apps.catLists": "Listas", - "Apps.catColour": "Color", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Funciones", - "Apps.httpRequestError": "Hubo un problema con la petición.", - "Apps.linkAlert": "Comparte tus bloques con este enlace:\n\n%1", - "Apps.hashError": "«%1» no corresponde con ningún programa guardado.", - "Apps.xmlError": "No se pudo cargar el archivo guardado. ¿Quizá fue creado con otra versión de Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "texto", - "Code.badXml": "Error de análisis XML:\n%1\n\nSelecciona OK para abandonar tus cambios o Cancelar para seguir editando el XML.", - "Code.badCode": "Error del programa:\n%1", - "Code.timeout": "Se excedio el máximo de iteraciones ejecutadas permitidas.", - "Code.discard": "¿Eliminar todos los bloques %1?", - "Code.title": "Código", - "Code.blocks": "Bloques", - "Code.trashTooltip": "Descartar todos los bloques." -} diff --git a/apps/json/eu.json b/apps/json/eu.json deleted file mode 100644 index 46a4d6adf..000000000 --- a/apps/json/eu.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Xabier Armendaritz", - "Subi" - ] - }, - "Blockly": "Blockly", - "Apps.codeTooltip": "Ikusi sorturiko JavaScript kodea.", - "Apps.linkTooltip": "Gorde eta lotura sortu.", - "Apps.runProgram": "Programa exekutatu", - "Apps.resetProgram": "Berriz hasi", - "Apps.dialogOk": "Ados", - "Apps.dialogCancel": "Utzi", - "Apps.catLogic": "Logika", - "Apps.catLoops": "Begiztak", - "Apps.catMath": "Matematika", - "Apps.catText": "Testua", - "Apps.catLists": "Zerrendak", - "Apps.catColour": "Kolorea", - "Apps.catVariables": "Aldagaiak", - "Apps.catProcedures": "Prozedurak", - "Apps.httpRequestError": "Eskaerarekin arazo bat egon da.", - "Apps.linkAlert": "Elkarbanatu blokeak lotura honekin:\n\n%1", - "Apps.hashError": "Barkatu, «%1» ez dator bat gordetako ezein programarekin.", - "Apps.xmlError": "Ezin izan da zure fitxategia kargatu. Agian Blockly-ren beste bertsio batekin sortua izan zen?", - "Apps.listVariable": "zerrenda", - "Apps.textVariable": "testua", - "Code.title": "Kodea", - "Code.blocks": "Blokeak", - "Code.trashTooltip": "Bloke guztiak baztertu." -} diff --git a/apps/json/fa.json b/apps/json/fa.json deleted file mode 100644 index 05623a541..000000000 --- a/apps/json/fa.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Ebraminio", - "Reza1615" - ] - }, - "Apps.subtitle": "یک محیط برنامه‌نویسی بصری", - "Blockly": "بلوکی", - "Apps.codeTooltip": "دیدن کد جاوااسکریپت ایجادشده.", - "Apps.linkTooltip": "ذخیره و پیوند به بلوک‌ها.", - "Apps.runTooltip": "اجرای برنامهٔ تعریف‌شده توسط بلوک‌ها در فضای کار.", - "Apps.runProgram": "اجرای برنامه", - "Apps.resetProgram": "از نو", - "Apps.dialogOk": "تأیید", - "Apps.dialogCancel": "لغو", - "Apps.catLogic": "منطق", - "Apps.catLoops": "حلقه‌ها", - "Apps.catMath": "ریاضی", - "Apps.catText": "متن", - "Apps.catLists": "فهرست‌ها", - "Apps.catColour": "رنگ", - "Apps.catVariables": "متغییرها", - "Apps.catProcedures": "توابع", - "Apps.httpRequestError": "مشکلی با درخواست وجود داشت.", - "Apps.linkAlert": "اشتراک‌گذاری بلاک‌هایتان با این پیوند:\n\n%1", - "Apps.hashError": "شرمنده، «%1» با هیچ برنامهٔ ذخیره‌شده‌ای تطبیق پیدا نکرد.", - "Apps.xmlError": "نتوانست پروندهٔ ذخیرهٔ شما بارگیری شود. احتمالاً با نسخهٔ متفاوتی از بلوکی درست شده‌است؟", - "Apps.listVariable": "فهرست", - "Apps.textVariable": "متن", - "Code.badXml": "خطای تجزیهٔ اکس‌ام‌ال:\n%1\n\n«باشد» را برای ذخیره و «فسخ» را برای ویرایش بیشتر اکس‌ام‌ال انتخاب کنید.", - "Code.badCode": "خطای برنامه:\n%1", - "Code.timeout": "حداکثر تکرارهای اجرا رد شده‌است.", - "Code.discard": "حذف همهٔ بلاک‌های %1؟", - "Code.title": "کد", - "Code.blocks": "بلوک‌ها", - "Code.trashTooltip": "دورریختن همهٔ بلوک‌ها." -} diff --git a/apps/json/fi.json b/apps/json/fi.json deleted file mode 100644 index 230f412d7..000000000 --- a/apps/json/fi.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Samoasambia", - "Silvonen" - ] - }, - "Apps.subtitle": "visuaalinen ohjelmointiympäristö", - "Blockly": "Blockly", - "Apps.codeTooltip": "Katso luotua JavaScript-koodia.", - "Apps.runProgram": "Suorita ohjelma", - "Apps.resetProgram": "Nollaa", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Peruuta", - "Apps.catLogic": "Kirjaudu", - "Apps.catText": "Teksti", - "Apps.catColour": "Väri", - "Apps.catVariables": "Muuttujat", - "Apps.textVariable": "teksti", - "Code.title": "Koodi" -} diff --git a/apps/json/fr.json b/apps/json/fr.json deleted file mode 100644 index b865a670f..000000000 --- a/apps/json/fr.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Gomoko", - "Immortal", - "Mulcyber" - ] - }, - "Apps.subtitle": "un environnement de programmation visuel", - "Blockly": "Blockly", - "Apps.codeTooltip": "Voir le code JavaScript généré.", - "Apps.linkTooltip": "Sauvegarder et lier aux blocs.", - "Apps.runTooltip": "Lancer le programme défini par les blocs dans l’espace de travail.", - "Apps.runProgram": "Exécuter le programme", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Annuler", - "Apps.catLogic": "Logique", - "Apps.catLoops": "Boucles", - "Apps.catMath": "Math", - "Apps.catText": "Texte", - "Apps.catLists": "Listes", - "Apps.catColour": "Couleur", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Fonctions", - "Apps.httpRequestError": "Il y a eu un problème avec la demande.", - "Apps.linkAlert": "Partagez vos blocs grâce à ce lien:\n\n%1", - "Apps.hashError": "Désolé, '%1' ne correspond à aucun programme sauvegardé.", - "Apps.xmlError": "Impossible de charger le fichier de sauvegarde. Peut être a t-il été créé avec une autre version de Blockly?", - "Apps.listVariable": "liste", - "Apps.textVariable": "texte", - "Code.badXml": "Erreur d’analyse du XML :\n%1\n\nSélectionner 'OK' pour abandonner vos modifications ou 'Annuler' pour continuer à modifier le XML.", - "Code.badCode": "Erreur du programme :\n%1", - "Code.timeout": "Nombre maximum d’itérations d’exécution dépassé.", - "Code.discard": "Supprimer tous les %1 blocs ?", - "Code.title": "Code", - "Code.blocks": "Blocs", - "Code.trashTooltip": "Jeter tous les blocs." -} diff --git a/apps/json/gl.json b/apps/json/gl.json deleted file mode 100644 index 26940d7c7..000000000 --- a/apps/json/gl.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Toliño" - ] - }, - "Apps.subtitle": "un contorno de programación visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Ver o código JavaScript xerado.", - "Apps.linkTooltip": "Gardar e crear unha ligazón aos bloques.", - "Apps.runTooltip": "Executar o programa definido polos bloques no espazo de traballo.", - "Apps.runProgram": "Executar o programa", - "Apps.resetProgram": "Restablecer", - "Apps.dialogOk": "Aceptar", - "Apps.dialogCancel": "Cancelar", - "Apps.catLogic": "Lóxica", - "Apps.catLoops": "Bucles", - "Apps.catMath": "Matemáticas", - "Apps.catText": "Texto", - "Apps.catLists": "Listas", - "Apps.catColour": "Cor", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Funcións", - "Apps.httpRequestError": "Houbo un problema coa solicitude.", - "Apps.linkAlert": "Comparte os teus bloques con esta ligazón:\n\n%1", - "Apps.hashError": "Sentímolo, \"%1\" non se corresponde con ningún programa gardado.", - "Apps.xmlError": "Non se puido cargar o ficheiro gardado. Se cadra, foi creado cunha versión diferente de Blockly.", - "Apps.listVariable": "lista", - "Apps.textVariable": "texto", - "Code.badXml": "Erro de análise do XML:\n%1\n\nSelecciona \"Aceptar\" se queres anular os cambios ou \"Cancelar\" para seguir editando o XML.", - "Code.badCode": "Erro do programa:\n%1", - "Code.timeout": "Superouse o número máximo de iteracións durante a execución.", - "Code.discard": "Queres borrar os %1 bloques?", - "Code.title": "Código", - "Code.blocks": "Bloques", - "Code.trashTooltip": "Descartar todos os bloques." -} diff --git a/apps/json/gn.json b/apps/json/gn.json deleted file mode 100644 index 0ce0430d7..000000000 --- a/apps/json/gn.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "@metadata": { - "authors": [ - "P. S. F. Freitas" - ] - }, - "Apps.subtitle": "peteĩ techa myatyrõ hekoha", - "Blockly": "Blockly", - "Apps.codeTooltip": "Ehecha JavaScript mba'e apopyre.", - "Apps.linkTooltip": "Oñongatu ha ombojoaju vorekuéra.", - "Apps.runTooltip": "Pejapo pe jejaporã vorekuéra ohechauka akue tembiapo rendápe.", - "Apps.runProgram": "Pejapo pe Jejaporã", - "Apps.resetProgram": "Ñepyrũ jey", - "Apps.catLogic": "Kuaarape", - "Apps.catLoops": "Tapykuegua", - "Apps.catMath": "Papapykuaa", - "Apps.catText": "Jehaipy", - "Apps.catLists": "Tysýi", - "Apps.catColour": "Sa'y", - "Apps.catVariables": "Ñemoambuéva", - "Apps.catProcedures": "Aporeko", - "Apps.httpRequestError": "Peteĩ tekojepe'y ohechauka.", - "Apps.linkAlert": "Temboja'o nde vorekuéra ko joaju ndie:\n\n%1", - "Apps.listVariable": "tysýi", - "Apps.textVariable": "jehaipy" -} diff --git a/apps/json/hak.json b/apps/json/hak.json deleted file mode 100644 index 3ad5a38d3..000000000 --- a/apps/json/hak.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "@metadata": { - "authors": [ - "EagerLin", - "Jetlag" - ] - }, - "Apps.dialogOk": "確定", - "Apps.dialogCancel": "取消", - "Apps.catMath": "Sṳ-ho̍k kûng-sṳt", - "Apps.catText": "文字", - "Apps.catLists": "列表", - "Apps.catColour": "顏色", - "Apps.catVariables": "變量", - "Apps.catProcedures": "函數", - "Apps.httpRequestError": "命令出現錯誤。", - "Apps.xmlError": "沒存到你保存个檔案。可能它係從其他版本个Blockly創建麼?", - "Apps.listVariable": "列表", - "Apps.textVariable": "文字", - "Code.badCode": "程式毋錯:\n%1", - "Code.timeout": "超過最大執行數。", - "Code.title": "程式碼" -} diff --git a/apps/json/he.json b/apps/json/he.json deleted file mode 100644 index 5ee3253dd..000000000 --- a/apps/json/he.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Dorongol", - "Orsa", - "YaronSh", - "Inkbug", - "Amire80", - "Noamrotem" - ] - }, - "Apps.subtitle": "סביבת תיכנות חזותי", - "Blockly": "בלוקלי", - "Apps.codeTooltip": "הצגת קוד ה־Javascript שנוצר.", - "Apps.linkTooltip": "שמירה וקישור לקטעי קוד.", - "Apps.runTooltip": "הרצת התכנית שהוגדרה על ידי קטעי הקוד שבמרחב העבודה.", - "Apps.runProgram": "הרץ תכנית", - "Apps.resetProgram": "איפוס", - "Apps.dialogOk": "אישור", - "Apps.dialogCancel": "ביטול", - "Apps.catLogic": "לוגיקה", - "Apps.catLoops": "לולאות", - "Apps.catMath": "מתמטיקה", - "Apps.catText": "טקסט", - "Apps.catLists": "רשימות", - "Apps.catColour": "צבע", - "Apps.catVariables": "משתנים", - "Apps.catProcedures": "פונקציות", - "Apps.httpRequestError": "הבקשה נכשלה.", - "Apps.linkAlert": "ניתן לשתף את קטעי הקוד שלך באמצעות קישור זה:\n\n%1", - "Apps.hashError": "לצערנו, '%1' איננו מתאים לאף אחת מהתוכניות השמורות", - "Apps.xmlError": "נסיון הטעינה של הקובץ השמור שלך נכשל. האם ייתכן שהוא נוצר בגרסא שונה של בלוקלי?", - "Apps.listVariable": "רשימה", - "Apps.textVariable": "טקסט", - "Code.badXml": "תקלה בפענוח XML:\n\n%1\n\nנא לבחור 'אישור' כדי לנטוש את השינויים שלך או 'ביטול' כדי להמשיך ולערוך את ה־XML.", - "Code.badCode": "שגיאה בתכנית: %1", - "Code.timeout": "חריגה ממספר פעולות חוזרות אפשריות.", - "Code.discard": "האם למחוק את כל %1 קטעי הקוד?", - "Code.title": "קוד", - "Code.blocks": "קטעי קוד", - "Code.trashTooltip": "השלך את כל קטעי הקוד." -} diff --git a/apps/json/hi.json b/apps/json/hi.json deleted file mode 100644 index c16f4de70..000000000 --- a/apps/json/hi.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Bl707" - ] - }, - "Apps.subtitle": "एक विषुयल प्रोग्रामिंग वातावरण", - "Blockly": "Blockly (ब्लॉकली)", - "Apps.codeTooltip": "बना हुआ जावास्क्रिप्ट कोड देखें।", - "Apps.linkTooltip": "सेव करें और ब्लॉक से लिंक करें।", - "Apps.runTooltip": "कार्यस्थान में ब्लॉक द्वारा वर्णन किया गया प्रोग्राम चलाएँ।", - "Apps.runProgram": "प्रोग्राम चलाएँ", - "Apps.resetProgram": "रीसेट करें", - "Apps.dialogOk": "ओके", - "Apps.dialogCancel": "रद्द करें", - "Apps.catLogic": "तर्क", - "Apps.catLoops": "लूप", - "Apps.catMath": "गणित", - "Apps.catText": "टेक्स्ट", - "Apps.catLists": "सूचियाँ", - "Apps.catColour": "रंग", - "Apps.catVariables": "चर", - "Apps.catProcedures": "प्रोसीजर", - "Apps.httpRequestError": "अनुरोध के साथ समस्या हुई।", - "Apps.linkAlert": "इस लिंक के साथ का अपने ब्लॉक का साझा करें:\n\n %1", - "Apps.hashError": "खेद है, '%1' किसी सेव किए गए प्रोग्राम से संबंधित नहीं है।", - "Apps.xmlError": "आपकी सेव की गई फ़ाइल लोड नहीं हो सकी। शायद यह ब्लॉकली के किसी भिन्न संस्करण के साथ बनाई गयी थी?", - "Apps.listVariable": "सूची", - "Apps.textVariable": "टेक्स्ट", - "Code.badCode": "प्रोग्राम त्रुटि:\n %1", - "Code.timeout": "अधिकतम एक्सक्यूशन पुनरावृत्ति पार हो गई।", - "Code.discard": "सारे %1 ब्लॉक हटाएँ?", - "Code.title": "कोड", - "Code.blocks": "ब्लॉक", - "Code.trashTooltip": "सभी ब्लाकों को त्यागें।" -} diff --git a/apps/json/hrx.json b/apps/json/hrx.json deleted file mode 100644 index 4c0bdeff6..000000000 --- a/apps/json/hrx.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Paul Beppler" - ] - }, - "Apps.subtitle": "Visuelle Programmierumgebung", - "Blockly": "Blockly", - "Apps.codeTooltip": "Generierte Java-COde oonsiehn.", - "Apps.linkTooltip": "Speichre und auf Bausten verlinke.", - "Apps.runTooltip": "Das Programm ausfüahre, das von den Bausten im Oorweitsbereich definiert ist.", - "Apps.runProgram": "Programm ausführe", - "Apps.resetProgram": "Zurücksetze", - "Apps.dialogOk": "Okay", - "Apps.dialogCancel": "Abbreche", - "Apps.catLogic": "Logik", - "Apps.catLoops": "Schleife", - "Apps.catMath": "Mathematik", - "Apps.catText": "Text", - "Apps.catLists": "Liste", - "Apps.catColour": "Farreb", - "Apps.catVariables": "Variable", - "Apps.catProcedures": "Funktione", - "Apps.httpRequestError": "Mit der Oonfroch hots en Problem geb.", - "Apps.linkAlert": "Tel von dein Bausten mit dem Link:\n\n%1", - "Apps.hashError": "„%1“ stimmt leider mit kenem üweren gespeicherte Programm.", - "Apps.xmlError": "Dein gespeicherte Datei könnt net gelood sin. Vielleicht woard se mit ener annre Version von Blockly erstellt.", - "Apps.listVariable": "List", - "Apps.textVariable": "Text", - "Code.badXml": "Fehler beim Parse von XML:\n%1\n\nWähle 'OK' zum Verwerfe von deiner Ändrunge orrer 'Abbreche' zum XML weiter beoorbeite.", - "Code.badCode": "Programmfehler:\n%1", - "Code.timeout": "Die maximale Ausführungswiederholunge woore üwerschritt.", - "Code.discard": "All %1 Bausten lösche?", - "Code.title": "Code", - "Code.blocks": "Bausten", - "Code.trashTooltip": "All Bausten verwerfe." -} diff --git a/apps/json/hu.json b/apps/json/hu.json deleted file mode 100644 index 33c781faa..000000000 --- a/apps/json/hu.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Takács Viktor László", - "아라" - ] - }, - "Apps.subtitle": "egy vizuális programozási környezet", - "Blockly": "Blockly", - "Apps.codeTooltip": "A JavaScript forráskód megtekintése.", - "Apps.linkTooltip": "Hivatkozás létrehozása", - "Apps.runTooltip": "Program futtatása.", - "Apps.runProgram": "Program futtatása", - "Apps.resetProgram": "Alaphelyzet", - "Apps.dialogOk": "Elolvastam", - "Apps.dialogCancel": "Mégsem", - "Apps.catLogic": "Logikai műveletek", - "Apps.catLoops": "Ciklusok", - "Apps.catMath": "Matematikai műveletek", - "Apps.catText": "Sztring műveletek", - "Apps.catLists": "Listakezelés", - "Apps.catColour": "Színek", - "Apps.catVariables": "Változók", - "Apps.catProcedures": "Eljárások", - "Apps.httpRequestError": "A kéréssel kapcsolatban probléma merült fel.", - "Apps.linkAlert": "Ezzel a hivatkozással tudod megosztani a programodat:\n\n%1", - "Apps.hashError": "Sajnos a '%1' hivatkozás nem tartozik egyetlen programhoz sem.", - "Apps.xmlError": "A programodat nem lehet betölteni. Elképzelhető, hogy a Blockly egy másik verziójában készült?", - "Apps.listVariable": "lista", - "Apps.textVariable": "szöveg", - "Code.badXml": "Hiba az XML feldolgozásakor:\n%1\n\nVáltozások elvetése?", - "Code.badCode": "Program hiba:\n%1", - "Code.timeout": "A program elérte a maximális végrehajtási időt.", - "Code.discard": "Az összes %1 blokk törlése?", - "Code.title": "Kódszerkesztő", - "Code.blocks": "Blokkok", - "Code.trashTooltip": "Összes blokk törlése." -} diff --git a/apps/json/ia.json b/apps/json/ia.json deleted file mode 100644 index 750f67430..000000000 --- a/apps/json/ia.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "McDutchie" - ] - }, - "Apps.subtitle": "un ambiente de programmation visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Vider le codice JavaScript generate.", - "Apps.linkTooltip": "Salveguardar e ligar a blocos.", - "Apps.runTooltip": "Executar le programma definite per le blocos in le spatio de travalio.", - "Apps.runProgram": "Executar programma", - "Apps.resetProgram": "Reinitialisar", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Cancellar", - "Apps.catLogic": "Logica", - "Apps.catLoops": "Buclas", - "Apps.catMath": "Mathematica", - "Apps.catText": "Texto", - "Apps.catLists": "Listas", - "Apps.catColour": "Color", - "Apps.catVariables": "Variabiles", - "Apps.catProcedures": "Functiones", - "Apps.httpRequestError": "Il habeva un problema con le requesta.", - "Apps.linkAlert": "Divide tu blocos con iste ligamine:\n\n%1", - "Apps.hashError": "Infelicemente, '%1' non corresponde a alcun programma salveguardate.", - "Apps.xmlError": "Impossibile cargar le file salveguardate. Pote esser que illo ha essite create con un altere version de Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "texto", - "Code.badXml": "Error de analyse del XML:\n%1\n\nSelige 'OK' pro abandonar le modificationes o 'Cancellar' pro continuar a modificar le codice XML.", - "Code.badCode": "Error del programma:\n%1", - "Code.timeout": "Le numero de iterationes executate ha excedite le maximo.", - "Code.discard": "Deler tote le %1 blocos?", - "Code.title": "Codice", - "Code.blocks": "Blocos", - "Code.trashTooltip": "Abandonar tote le blocos." -} diff --git a/apps/json/is.json b/apps/json/is.json deleted file mode 100644 index 8e5bf875a..000000000 --- a/apps/json/is.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Jonbg" - ] - }, - "Apps.subtitle": "sjónrænt forritunarumhverfi", - "Blockly": "Blockly", - "Apps.codeTooltip": "Sjá forritið sem JavaScript kóða.", - "Apps.linkTooltip": "Vista og tengja við kubba.", - "Apps.runTooltip": "Keyra forritið sem kubbarnir á vinnusvæðinu mynda.", - "Apps.runProgram": "Keyra forritið", - "Apps.resetProgram": "Byrja aftur", - "Apps.dialogOk": "Í lagi", - "Apps.dialogCancel": "Hætta við", - "Apps.catLogic": "Rökvísi", - "Apps.catLoops": "Lykkjur", - "Apps.catMath": "Reikningur", - "Apps.catText": "Texti", - "Apps.catLists": "Listar", - "Apps.catColour": "Litir", - "Apps.catVariables": "Breytur", - "Apps.catProcedures": "Stefjur", - "Apps.httpRequestError": "Það kom upp vandamál með beiðnina.", - "Apps.linkAlert": "Deildu kubbunum þínum með þessari krækju:", - "Apps.hashError": "Því miður, '%1' passar ekki við neitt vistað forrit.", - "Apps.xmlError": "Gat ekki hlaðið vistuðu skrána þína. Var hún kannske búin til í annarri útgáfu af Blockly?", - "Apps.listVariable": "listi", - "Apps.textVariable": "texti", - "Code.badXml": "Villa við úrvinnslu XML:\n%1\n\nVeldu 'Í lagi' til að sleppa breytingum eða 'Hætta við' til að halda áfram með XML.", - "Code.badCode": "Villa í forriti:\n%1", - "Code.timeout": "Forritið hefur endurtekið sig of oft.", - "Code.discard": "Eyða öllum %1 kubbunum?", - "Code.title": "Kóði", - "Code.blocks": "Kubbar", - "Code.trashTooltip": "Fleygja öllum kubbum." -} diff --git a/apps/json/it.json b/apps/json/it.json deleted file mode 100644 index 66f94cfa1..000000000 --- a/apps/json/it.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Beta16", - "Isiond", - "Nerimic" - ] - }, - "Apps.subtitle": "un ambiente di programmazione grafico", - "Blockly": "Blockly", - "Apps.codeTooltip": "Vedi il codice JavaScript generato.", - "Apps.linkTooltip": "Salva e collega ai blocchi.", - "Apps.runTooltip": "Esegui il programma definito dai blocchi nell'area di lavoro.", - "Apps.runProgram": "Esegui programma", - "Apps.resetProgram": "Reimposta", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Annulla", - "Apps.catLogic": "Logica", - "Apps.catLoops": "Cicli", - "Apps.catMath": "Matematica", - "Apps.catText": "Testo", - "Apps.catLists": "Elenchi", - "Apps.catColour": "Colore", - "Apps.catVariables": "Variabili", - "Apps.catProcedures": "Funzioni", - "Apps.httpRequestError": "La richiesta non è stata soddisfatta.", - "Apps.linkAlert": "Condividi i tuoi blocchi con questo collegamento:\n\n%1", - "Apps.hashError": "Mi spiace, '%1' non corrisponde ad alcun programma salvato.", - "Apps.xmlError": "Non è stato possibile caricare il documento. Forse è stato creato con una versione diversa di Blockly?", - "Apps.listVariable": "elenco", - "Apps.textVariable": "testo", - "Code.badXml": "Errore durante l'analisi XML:\n%1\n\nSeleziona 'OK' per abbandonare le modifiche o 'Annulla' per continuare a modificare l'XML.", - "Code.badCode": "Errore programma:\n%1", - "Code.timeout": "È stato superato il numero massimo consentito di interazioni eseguite.", - "Code.discard": "Cancellare tutti i %1 blocchi?", - "Code.title": "Codice", - "Code.blocks": "Blocchi", - "Code.trashTooltip": "Elimina tutti i blocchi." -} diff --git a/apps/json/ja.json b/apps/json/ja.json deleted file mode 100644 index 708127394..000000000 --- a/apps/json/ja.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Shirayuki", - "Oda" - ] - }, - "Apps.subtitle": "視覚的なプログラミング環境", - "Blockly": "ブロックリー", - "Apps.codeTooltip": "生成された JavaScript コードを表示します。", - "Apps.linkTooltip": "ブロックの状態を保存してリンクを取得します。", - "Apps.runTooltip": "ブロックで作成したプログラムを実行します。", - "Apps.runProgram": "プログラムを実行", - "Apps.resetProgram": "リセット", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "キャンセル", - "Apps.catLogic": "論理", - "Apps.catLoops": "繰り返し", - "Apps.catMath": "数学", - "Apps.catText": "テキスト", - "Apps.catLists": "リスト", - "Apps.catColour": "色", - "Apps.catVariables": "変数", - "Apps.catProcedures": "関数", - "Apps.httpRequestError": "ネットワーク接続のエラーです。", - "Apps.linkAlert": "ブロックの状態をこのリンクで共有できます:\n\n%1", - "Apps.hashError": "すみません。「%1」という名前のプログラムは保存されていません。", - "Apps.xmlError": "保存されたファイルを読み込めませんでした。別のバージョンのブロックリーで作成された可能性があります。", - "Apps.listVariable": "リスト", - "Apps.textVariable": "テキスト", - "Code.badXml": "XML のエラーです:\n%1\n\nXML の変更をやめるには「OK」、編集を続けるには「キャンセル」を選んでください。", - "Code.badCode": "プログラムのエラー:\n%1", - "Code.timeout": "命令の実行回数が制限値を超えました。", - "Code.discard": "%1 個すべてのブロックを消しますか?", - "Code.title": "コード", - "Code.blocks": "ブロック", - "Code.trashTooltip": "すべてのブロックを消します。" -} diff --git a/apps/json/keys.json b/apps/json/keys.json deleted file mode 100644 index a5343742e..000000000 --- a/apps/json/keys.json +++ /dev/null @@ -1,32 +0,0 @@ -{ -"Apps.subtitle": "9151382257658567281", -"Blockly": "213423414108596757", -"Apps.codeTooltip": "5838195295317713027", -"Apps.linkTooltip": "5391382062551588177", -"Apps.runTooltip": "6316320629891574281", -"Apps.runProgram": "6189808175540281396", -"Apps.resetProgram": "6533409555866489852", -"Apps.dialogOk": "3964361619617826429", -"Apps.dialogCancel": "8605819299263106886", -"Apps.catLogic": "1686883036031489642", -"Apps.catLoops": "8514812131842527965", -"Apps.catMath": "8504064665960111059", -"Apps.catText": "2561306449483326985", -"Apps.catLists": "7880221162350996120", -"Apps.catColour": "5532942470899034153", -"Apps.catVariables": "3279501947911403228", -"Apps.catProcedures": "1274375705158281519", -"Apps.httpRequestError": "6491926390857975299", -"Apps.linkAlert": "6192625840582724866", -"Apps.hashError": "2570539532822249158", -"Apps.xmlError": "5758425077401246127", -"Apps.listVariable": "7314181232693154293", -"Apps.textVariable": "768570576516576913", -"Code.badXml": "148032336181194017", -"Code.badCode": "8943253138333696551", -"Code.timeout": "1350759209070481203", -"Code.discard": "1020451542663054555", -"Code.title": "339365101010834276", -"Code.blocks": "586801704101593425", -"Code.trashTooltip": "1406728939680691839" -} diff --git a/apps/json/ko.json b/apps/json/ko.json deleted file mode 100644 index c9cc1136c..000000000 --- a/apps/json/ko.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Hym411", - "아라", - "Priviet" - ] - }, - "Apps.subtitle": "시각 프로그래밍 환경", - "Blockly": "블록리", - "Apps.codeTooltip": "생성된 자바스크립트 코드를 봅니다.", - "Apps.linkTooltip": "블록을 저장하고 링크를 가져옵니다.", - "Apps.runTooltip": "작업 공간에서 블록으로 정의된 프로그램을 실행합니다.", - "Apps.runProgram": "프로그램 실행", - "Apps.resetProgram": "초기화", - "Apps.dialogOk": "확인", - "Apps.dialogCancel": "취소", - "Apps.catLogic": "논리", - "Apps.catLoops": "반복", - "Apps.catMath": "수학", - "Apps.catText": "텍스트", - "Apps.catLists": "목록", - "Apps.catColour": "색", - "Apps.catVariables": "변수", - "Apps.catProcedures": "기능", - "Apps.httpRequestError": "요청에 문제가 있습니다.", - "Apps.linkAlert": "다음 링크로 블록을 공유하세요:\n\n%1", - "Apps.hashError": "죄송하지만 '%1'은 어떤 저장된 프로그램으로 일치하지 않습니다.", - "Apps.xmlError": "저장된 파일을 불러올 수 없습니다. 혹시 블록리의 다른 버전으로 만들었습니까?", - "Apps.listVariable": "목록", - "Apps.textVariable": "텍스트", - "Code.badXml": "XML 구문 분석 오류:\n%1\n\n바뀜을 포기하려면 '확인'을 선택하고 XML을 더 편집하려면 '취소'를 선택하세요.", - "Code.badCode": "프로그램 오류:\n%1", - "Code.timeout": "최대 실행 반복을 초과했습니다.", - "Code.discard": "모든 블록 %1개를 삭제하겠습니까?", - "Code.title": "코드", - "Code.blocks": "블록", - "Code.trashTooltip": "모든 블록을 버립니다." -} diff --git a/apps/json/lb.json b/apps/json/lb.json deleted file mode 100644 index ba58d2058..000000000 --- a/apps/json/lb.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Robby" - ] - }, - "Blockly": "Blockly", - "Apps.codeTooltip": "Generéierte JavaScript Code kucken.", - "Apps.linkTooltip": "Späicheren a mat de Bléck verlinken", - "Apps.runProgram": "Programm ausféieren", - "Apps.resetProgram": "Zrécksetzen", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Ofbriechen", - "Apps.catLogic": "Logik", - "Apps.catText": "Text", - "Apps.catLists": "Lëschten", - "Apps.catColour": "Faarf", - "Apps.catVariables": "Variabelen", - "Apps.catProcedures": "Funktiounen", - "Apps.httpRequestError": "Et gouf e Problem mat der Ufro.", - "Apps.hashError": "Pardon, '%1' entsprécht kengem vun de gespäicherte Programmer.", - "Apps.xmlError": "Äre gespäicherte Fichier konnt net geluede ginn. Vläicht hutt Dir e mat enger anerer Versioun vu Blockly gemaach?", - "Apps.listVariable": "Lëscht", - "Apps.textVariable": "Text", - "Code.badXml": "Feeler beim Parse vum XML:\n%1\n\nKlickt 'OK' fir Är Ännerungen opzeginn oder 'Ofbriechen' fir den XML weider z'änneren.", - "Code.badCode": "Programmfeeler:\n%1", - "Code.discard": "All %1 Bléck läschen?", - "Code.title": "Code", - "Code.blocks": "Bléck" -} diff --git a/apps/json/lrc.json b/apps/json/lrc.json deleted file mode 100644 index 10662778d..000000000 --- a/apps/json/lrc.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Mogoeilor" - ] - }, - "Apps.subtitle": "یه راساگه برنامه نیسی قاول دیئن", - "Blockly": "قلف بیه", - "Apps.codeTooltip": "سیل کد جاوا اسکریپت راس بیه بکید", - "Apps.linkTooltip": "بخشیانه ذخیره و هوم پیوند بکید", - "Apps.runProgram": "برنامه نه اجرا بکیت", - "Apps.resetProgram": "د نو شرو كردن", - "Apps.dialogOk": "خوئه", - "Apps.dialogCancel": "رد كردن", - "Apps.catLogic": "علقمنی", - "Apps.catLoops": "حلقه یا", - "Apps.catMath": "حساو کتاو", - "Apps.catText": "متن", - "Apps.catLists": "نوم گه یا", - "Apps.catColour": "رن", - "Apps.catVariables": "آلشت ونا", - "Apps.catProcedures": "رویه یا", - "Apps.httpRequestError": "یه گل مشگل وا درحاست هئ", - "Apps.linkAlert": "بخشیاتونه وا ای هوم پیوند بهر بکید", - "Apps.listVariable": "نوم گه", - "Apps.textVariable": "متن", - "Code.badCode": "خطا برنامه:%1", - "Code.discard": " %1 د همه برشتیا نه پاکسا کو?", - "Code.title": "کد", - "Code.blocks": "بخشیا" -} diff --git a/apps/json/lt.json b/apps/json/lt.json deleted file mode 100644 index 7939efd98..000000000 --- a/apps/json/lt.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Eitvys200", - "Vilius2001", - "Garas", - "Jurgis" - ] - }, - "Apps.subtitle": "vizualus programavimas", - "Blockly": "Blockly", - "Apps.codeTooltip": "Peržiūrėti atitinkantį JavaScript kodą.", - "Apps.linkTooltip": "Išsaugoti (sugeneruoti URL nuorodą).", - "Apps.runTooltip": "Vykdyti programą.", - "Apps.runProgram": "Paleisti Programą", - "Apps.resetProgram": "Atnaujinti", - "Apps.dialogOk": "Gerai", - "Apps.dialogCancel": "Atšaukti", - "Apps.catLogic": "Logika", - "Apps.catLoops": "Kartojimas", - "Apps.catMath": "Matematika", - "Apps.catText": "Tekstas", - "Apps.catLists": "Sąrašai", - "Apps.catColour": "Spalva", - "Apps.catVariables": "Kintamieji", - "Apps.catProcedures": "Funkcijos", - "Apps.httpRequestError": "Iškilo problema su prašymu.", - "Apps.linkAlert": "%1", - "Apps.hashError": "Deja, '%1' neatitinka jokios išsaugotos programos.", - "Apps.xmlError": "Nesuprantu pateikto failo. Gal jis buvo sukurtas su kita Blocky versija?", - "Apps.listVariable": "sąrašas", - "Apps.textVariable": "tekstas", - "Code.badCode": "Programos klaida:\n%1", - "Code.timeout": "Per ilgai vykdoma programa.", - "Code.discard": "Ar ištrinti visus %1 blokus?", - "Code.title": "Kodas", - "Code.blocks": "Blokai", - "Code.trashTooltip": "Pašalinti visus blokus." -} diff --git a/apps/json/lv.json b/apps/json/lv.json deleted file mode 100644 index 041ba608f..000000000 --- a/apps/json/lv.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Elomage", - "Papuass" - ] - }, - "Apps.subtitle": "vizuāla programmēšanas vide", - "Blockly": "Blockly", - "Apps.codeTooltip": "Apskatīt ģenerēto JavaScript pirmkodu.", - "Apps.linkTooltip": "Saglabāt un piesaistīt blokiem.", - "Apps.runTooltip": "Palaidiet programmu, ko definē bloki darbvietā.", - "Apps.runProgram": "Izpildīt programmu", - "Apps.resetProgram": "Sākt no sākuma", - "Apps.dialogOk": "Labi", - "Apps.dialogCancel": "Atcelt", - "Apps.catLogic": "Loģika", - "Apps.catLoops": "Cikli", - "Apps.catMath": "Matemātika", - "Apps.catText": "Teksts", - "Apps.catLists": "Saraksti", - "Apps.catColour": "Krāsa", - "Apps.catVariables": "Mainīgie", - "Apps.catProcedures": "Procedūras", - "Apps.httpRequestError": "Pieprasījuma kļūda.", - "Apps.linkAlert": "Dalies ar saviem blokiem ar šo saiti:\n\n%1", - "Apps.hashError": "Atvainojiet, bet '%1' neatbilst nevienai no saglabātajām programmām.", - "Apps.xmlError": "Nevaru ielādēt tavu saglabāto failu. Iespējams, tas tika izveidots ar citu Blockly versiju?", - "Apps.listVariable": "saraksts", - "Apps.textVariable": "teksts", - "Code.badXml": "XML parsēšanas kļūda:\n %1\n\nIzvēlieties 'Labi', lai zaudētu savas izmaiņas vai 'Atcelt', lai rediģētu XML.", - "Code.badCode": "Programmas kļūda:\n %1", - "Code.timeout": "Pārsniegts maksimālais iterāciju skaits.", - "Code.discard": "Vai izdzēst visus %1 blokus?", - "Code.title": "Pirmkods", - "Code.blocks": "Bloki", - "Code.trashTooltip": "Izmest visus blokus." -} diff --git a/apps/json/mg.json b/apps/json/mg.json deleted file mode 100644 index b0c799895..000000000 --- a/apps/json/mg.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Jagwar" - ] - }, - "Apps.subtitle": "Tontolo fanoratam-pandaharana ara-pijery", - "Blockly": "Blockly", - "Apps.codeTooltip": "Hijery ny kaody JavaScript namboarina.", - "Apps.linkTooltip": "Hitahiry ary hampirohy amin'ny bolongana.", - "Apps.runTooltip": "Handefa ny fandaharana voafaritry ny bolongana ao amin'ny erana iasana.", - "Apps.runProgram": "Handefa ny fandaharana", - "Apps.resetProgram": "Averina", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Aoka ihany", - "Apps.catLogic": "Lôjika", - "Apps.catLoops": "Tondro mifolaka", - "Apps.catMath": "Matematika", - "Apps.catText": "Soratra", - "Apps.catLists": "Lisitra", - "Apps.catColour": "Loko", - "Apps.catVariables": "Ova", - "Apps.catProcedures": "Paika", - "Apps.httpRequestError": "Nisy olana tamin'ilay hataka.", - "Apps.linkAlert": "Zarao amin'ity rohy ity ny bolonganao: \n\n%1", - "Apps.hashError": "Miala tsiny, tsy miady amin'ny fandaharana notehirizina '%1'.", - "Apps.xmlError": "Tsy nahasokatra ny rakitra voatahirinao. Mety namboarina tamin'ny versionan'i Blockly hafa angamba ilay izy?", - "Apps.listVariable": "lisitra", - "Apps.textVariable": "soratra", - "Code.badXml": "Hadisoana tam-pamakiana ny XML:\n%1\n\nSafidio 'OK' raha hamoy ny fiovana, na 'Aoka ihany' raha mbola hitoy hanova ny XML.", - "Code.badCode": "Hadisoam-pandaharana:\n%1", - "Code.timeout": "Tafahoatra ny isa ambony indrindra ny isan'ny fiverimberenana.", - "Code.discard": "Hamafa ny bolongana %1?", - "Code.title": "Kaody", - "Code.blocks": "Bolongana", - "Code.trashTooltip": "Hanary ny bolongana rehetra." -} diff --git a/apps/json/mk.json b/apps/json/mk.json deleted file mode 100644 index a3c9b804d..000000000 --- a/apps/json/mk.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Bjankuloski06", - "M4r51n" - ] - }, - "Apps.subtitle": "визуелна околина за програмирање", - "Blockly": "Блокли", - "Apps.codeTooltip": "Погл. создадениот JavaScript-код.", - "Apps.linkTooltip": "Зачувај и стави врска до блокчињата.", - "Apps.runTooltip": "Пушти го програмот определен од блокчињата во работниот простор.", - "Apps.runProgram": "Пушти го програмот", - "Apps.resetProgram": "Одново", - "Apps.dialogOk": "ОК", - "Apps.dialogCancel": "Откажи", - "Apps.catLogic": "Логика", - "Apps.catLoops": "Јамки", - "Apps.catMath": "Математика", - "Apps.catText": "Текст", - "Apps.catLists": "Списоци", - "Apps.catColour": "Боја", - "Apps.catVariables": "Променливи", - "Apps.catProcedures": "Функции", - "Apps.httpRequestError": "Се појави проблем во барањето.", - "Apps.linkAlert": "Споделете ги вашите блокчиња со оваа врска:\n\n%1", - "Apps.hashError": "„%1“ не одговара на ниеден зачуван програм.", - "Apps.xmlError": "Не можев да ја вчитам зачуваната податотека. Да не сте ја создале со друга верзија на Blockly?", - "Apps.listVariable": "список", - "Apps.textVariable": "текст", - "Code.badXml": "Грешка при расчленувањето на XML:\n%1\n\nСтиснете на „ОК“ за да ги напуштите промените или на „Откажи“ ако сакате уште да ја уредувате XML-податотеката.", - "Code.badCode": "Грешка во програмот:\n%1", - "Code.timeout": "Го надминавте допуштениот број на повторувања во извршувањето.", - "Code.discard": "Да ги избришам сите %1 блокчиња?", - "Code.title": "Код", - "Code.blocks": "Блокчиња", - "Code.trashTooltip": "Отстрани ги сите блокчиња." -} diff --git a/apps/json/mr.json b/apps/json/mr.json deleted file mode 100644 index b1827cbd6..000000000 --- a/apps/json/mr.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@metadata": { - "authors": [ - "V.narsikar" - ] - }, - "Apps.runProgram": "प्रोग्राम चालवा(दौडवा)", - "Apps.resetProgram": "पुनर्स्थापित करा", - "Apps.catLoops": "वेटोळ्या(लूप्स)", - "Apps.catText": "मजकूर", - "Apps.catColour": "रंग", - "Apps.catVariables": "अस्थिरके", - "Apps.listVariable": "यादी", - "Apps.textVariable": "मजकूर", - "Code.title": "संकेत", - "Code.blocks": "ब्लॉक्स" -} diff --git a/apps/json/ms.json b/apps/json/ms.json deleted file mode 100644 index 7d6da19a8..000000000 --- a/apps/json/ms.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Anakmalaysia", - "Aurora", - "Kurniasan", - "Espertus" - ] - }, - "Apps.subtitle": "persekitaran pengaturcaraan visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Lihat kod JavaScript yang dihasilkan.", - "Apps.linkTooltip": "Simpan dan pautkan kepada blok.", - "Apps.runTooltip": "Jalankan aturcara yang ditetapkan oleh blok-blok di dalam ruang kerja.", - "Apps.runProgram": "Jalankan Program", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Batalkan", - "Apps.catLogic": "Logik", - "Apps.catLoops": "Gelung", - "Apps.catMath": "Matematik", - "Apps.catText": "Teks", - "Apps.catLists": "Senarai", - "Apps.catColour": "Warna", - "Apps.catVariables": "Pemboleh ubah", - "Apps.catProcedures": "Fungsi", - "Apps.httpRequestError": "Permintaan itu terdapat masalah.", - "Apps.linkAlert": "Kongsikan blok-blok anda dengan pautan ini:\n\n%1", - "Apps.hashError": "Maaf, '%1' tidak berpadanan dengan sebarang aturcara yang disimpan.", - "Apps.xmlError": "Fail simpanan anda tidak dapat dimuatkan. Jangan-jangan ia dicipta dengan versi Blockly yang berlainan?", - "Apps.listVariable": "senarai", - "Apps.textVariable": "teks", - "Code.badXml": "Ralat ketika menghuraian XML:\n%1\n\nPilih 'OK' untuk melucutkan suntingan anda atau 'Batal' untuk bersambung menyunting XML-nya.", - "Code.badCode": "Ralat atur cara:\n%1", - "Code.timeout": "Takat maksimum lelaran pelaksanaan dicecah.", - "Code.discard": "Hapuskan kesemua %1 blok?", - "Code.title": "Kod", - "Code.blocks": "Blok", - "Code.trashTooltip": "Buang semua blok." -} diff --git a/apps/json/nb.json b/apps/json/nb.json deleted file mode 100644 index f091dbbf8..000000000 --- a/apps/json/nb.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Osgraven", - "Cocu" - ] - }, - "Apps.subtitle": "Et visuelt programmeringsmiljø", - "Blockly": "Blockly", - "Apps.codeTooltip": "Se generert JavaScriptkode", - "Apps.linkTooltip": "Lagre og lenke til blokker.", - "Apps.runTooltip": "Kjør programmet definert av blokken i arbeidsområdet.", - "Apps.runProgram": "Kjør Programmet", - "Apps.resetProgram": "Nullstill", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Avbryt", - "Apps.catLogic": "Logikk", - "Apps.catLoops": "Looper", - "Apps.catMath": "Matte", - "Apps.catText": "Tekst", - "Apps.catLists": "Lister", - "Apps.catColour": "Farge", - "Apps.catVariables": "Variabler", - "Apps.catProcedures": "Funksjoner", - "Apps.httpRequestError": "Det oppsto et problem med forespørselen din", - "Apps.linkAlert": "Del dine blokker med denne lenken:\n\n%1", - "Apps.hashError": "Beklager, '%1' samsvarer ikke med noe lagret program.", - "Apps.xmlError": "Kunne ikke laste inn filen. Kanskje den ble laget med en annen versjon av Blockly?", - "Apps.listVariable": "Liste", - "Apps.textVariable": "Tekst", - "Code.badXml": "Feil ved parsering av XML:\n%1\n\nVelg 'OK' for å avbryte endringene eller 'Cancel' for å fortsette å redigere XML-koden.", - "Code.badCode": "Programfeil:\n%1", - "Code.timeout": "Det maksimale antallet utførte looper er oversteget.", - "Code.discard": "Slett alle %1 blokker?", - "Code.title": "Kode", - "Code.blocks": "Blokker", - "Code.trashTooltip": "Fjern alle blokker" -} diff --git a/apps/json/ne.json b/apps/json/ne.json deleted file mode 100644 index e053d900a..000000000 --- a/apps/json/ne.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "@metadata": { - "authors": [ - "सरोज कुमार ढकाल" - ] - }, - "Apps.subtitle": "एक भिज्युअल प्रोग्रामिङ्ग वातावरण", - "Blockly": "Blockly(ब्लकली)", - "Apps.runProgram": "अनुप्रयोग चलाउने", - "Apps.resetProgram": "रिसेट गर्नुहोस्", - "Apps.dialogOk": "हुन्छ", - "Apps.dialogCancel": "रद्द गर्ने", - "Apps.catLogic": "लजिक", - "Apps.catLoops": "लुपहरू", - "Apps.catMath": "गणित", - "Apps.catText": "पाठ", - "Apps.catLists": "सूची", - "Apps.catColour": "रंग", - "Apps.catVariables": "चल राशी(variables)", - "Apps.catProcedures": "अनुक्रियाहरु", - "Apps.listVariable": "सूची", - "Apps.textVariable": "पाठ", - "Code.title": "कोड", - "Code.blocks": "ब्लकहरू" -} diff --git a/apps/json/nl.json b/apps/json/nl.json deleted file mode 100644 index ce8ed1d64..000000000 --- a/apps/json/nl.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Moorooboorai", - "Siebrand" - ] - }, - "Apps.subtitle": "een visuele programmeeromgeving", - "Blockly": "Blockly", - "Apps.codeTooltip": "Bekijk de gemaakte JavaScriptcode.", - "Apps.linkTooltip": "Opslaan en koppelen naar blokken.", - "Apps.runTooltip": "Voer het programma uit dat met de blokken in de werkruimte is gemaakt.", - "Apps.runProgram": "Programma uitvoeren", - "Apps.resetProgram": "Opnieuw instellen", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Annuleren", - "Apps.catLogic": "Logica", - "Apps.catLoops": "Lussen", - "Apps.catMath": "Formules", - "Apps.catText": "Tekst", - "Apps.catLists": "Lijsten", - "Apps.catColour": "Kleur", - "Apps.catVariables": "Variabelen", - "Apps.catProcedures": "Functies", - "Apps.httpRequestError": "Er is een probleem opgetreden tijdens het verwerken van het verzoek.", - "Apps.linkAlert": "Deel uw blokken via deze koppeling:\n\n%1", - "Apps.hashError": "\"%1\" komt helaas niet overeen met een opgeslagen bestand.", - "Apps.xmlError": "Uw opgeslagen bestand kan niet geladen worden. Is het misschien gemaakt met een andere versie van Blockly?", - "Apps.listVariable": "lijst", - "Apps.textVariable": "tekst", - "Code.badXml": "Fout tijdens het verwerken van de XML:\n%1\n\nSelecteer \"OK\" om uw wijzigingen te negeren of \"Annuleren\" om de XML verder te bewerken.", - "Code.badCode": "Programmafout:\n%1", - "Code.timeout": "Het maximale aantal iteraties is overschreden.", - "Code.discard": "Alle %1 blokken verwijderen?", - "Code.title": "Code", - "Code.blocks": "Blokken", - "Code.trashTooltip": "Alle blokken verwijderen" -} diff --git a/apps/json/oc.json b/apps/json/oc.json deleted file mode 100644 index 07876f083..000000000 --- a/apps/json/oc.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Cedric31" - ] - }, - "Apps.subtitle": "un environament de programacion visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Veire lo còde JavaScript generat.", - "Apps.linkTooltip": "Salva e liga als blòts.", - "Apps.runTooltip": "Aviar lo programa definit pels blòts dins l’espaci de trabalh.", - "Apps.runProgram": "Executa lo programa", - "Apps.resetProgram": "Reïnicializar", - "Apps.dialogOk": "D'acòrdi", - "Apps.dialogCancel": "Anullar", - "Apps.catLogic": "Logic", - "Apps.catLoops": "Boclas", - "Apps.catMath": "Math", - "Apps.catText": "Tèxte", - "Apps.catLists": "Listas", - "Apps.catColour": "Color", - "Apps.catVariables": "Variablas", - "Apps.catProcedures": "Foncions", - "Apps.httpRequestError": "I a agut un problèma amb la demanda.", - "Apps.linkAlert": "Partejatz vòstres blòts gràcia a aqueste ligam :\n\n%1", - "Apps.hashError": "O planhèm, '%1' correspond pas a un fichièr Blockly salvament.", - "Apps.xmlError": "Impossible de cargar lo fichièr de salvament. Benlèu qu'es estat creat amb una autra version de Blockly ?", - "Apps.listVariable": "lista", - "Apps.textVariable": "tèxte", - "Code.badXml": "Error d’analisi del XML :\n%1\n\nSeleccionar 'D'acòrdi' per abandonar vòstras modificacions o 'Anullar' per modificar encara lo XML.", - "Code.badCode": "Error del programa :\n%1", - "Code.timeout": "Nombre maximum d’iteracions d’execucion depassat.", - "Code.discard": "Suprimir totes los %1 blòts ?", - "Code.title": "Còde", - "Code.blocks": "Blòts", - "Code.trashTooltip": "Getar totes los blòts." -} diff --git a/apps/json/pl.json b/apps/json/pl.json deleted file mode 100644 index 2287099b0..000000000 --- a/apps/json/pl.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Chrumps", - "Faren", - "Rezonansowy", - "Ty221", - "Jchwastowska", - "Stocki", - "Pio387" - ] - }, - "Apps.subtitle": "graficzne środowisko programistyczne", - "Blockly": "Blockly", - "Apps.codeTooltip": "Zobacz wygenerowany kod JavaScript.", - "Apps.linkTooltip": "Zapisz i podlinkuj do bloków", - "Apps.runTooltip": "Uruchom program zdefinowany przez bloki w obszarze roboczym", - "Apps.runProgram": "Uruchom Program", - "Apps.resetProgram": "Zresetuj", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Anuluj", - "Apps.catLogic": "Logika", - "Apps.catLoops": "Pętle", - "Apps.catMath": "Matematyka", - "Apps.catText": "Tekst", - "Apps.catLists": "Listy", - "Apps.catColour": "Kolor", - "Apps.catVariables": "Zmienne", - "Apps.catProcedures": "Funkcje", - "Apps.httpRequestError": "Wystąpił problem z żądaniem.", - "Apps.linkAlert": "Udpostępnij swoje bloki korzystając z poniższego linku : \n\n\n%1", - "Apps.hashError": "Przepraszamy, \"%1\" nie odpowiada żadnemu zapisanemu programowi.", - "Apps.xmlError": "Nie można załadować zapisanego pliku. Być może został utworzony za pomocą innej wersji Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "tekst", - "Code.badXml": "Błąd parsowania XML : \n%1\n\nZaznacz 'OK' aby odrzucić twoje zmiany lub 'Cancel', żeby w przyszłości edytować XML.", - "Code.badCode": "Błąd programu:\n%1", - "Code.timeout": "Maksymalna liczba iteracji wykonywań przekroczona", - "Code.discard": "Usunąć wszystkie %1 bloki?", - "Code.title": "Kod", - "Code.blocks": "Bloki", - "Code.trashTooltip": "Odrzuć wszystkie bloki." -} diff --git a/apps/json/pms.json b/apps/json/pms.json deleted file mode 100644 index ac5a347e2..000000000 --- a/apps/json/pms.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Borichèt" - ] - }, - "Apps.subtitle": "n'ambient ëd programassion visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Vëdde ël còdes JavaScript generà.", - "Apps.linkTooltip": "Argistré e lijé ai blòch.", - "Apps.runTooltip": "Fé andé ël programa definì dai blòch ant lë spassi ëd travaj.", - "Apps.runProgram": "Fé andé ël programa", - "Apps.resetProgram": "Buté torna coma al prinsipi", - "Apps.dialogOk": "Va bin", - "Apps.dialogCancel": "Anulé", - "Apps.catLogic": "Lògica", - "Apps.catLoops": "Liasse", - "Apps.catMath": "Matemàtica", - "Apps.catText": "Test", - "Apps.catLists": "Liste", - "Apps.catColour": "Color", - "Apps.catVariables": "Variàbij", - "Apps.catProcedures": "Fonsion", - "Apps.httpRequestError": "A-i é staje un problema con l'arcesta.", - "Apps.linkAlert": "Ch'a partagia ij sò blòch grassie a sta liura: %1", - "Apps.hashError": "An dëspias, '%1 a corëspond a gnun programa salvà.", - "Apps.xmlError": "A l'é nen podusse carié so archivi salvà. Miraco a l'é stàit creà con na version diferenta ëd Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "test", - "Code.badXml": "Eror d'anàlisi dl'XML:\n%1\n\nSelessioné 'Va bin' për lassé perde toe modìfiche o 'Anulé' për modifiché ancora l'XML.", - "Code.badCode": "Eror dël programa:\n%1", - "Code.timeout": "Nùmer màssim d'arpetission d'esecussion sorpassà.", - "Code.discard": "Scancelé tuti ij %1 blòch?", - "Code.title": "Còdes", - "Code.blocks": "Blòch", - "Code.trashTooltip": "Scarté tuti ij blòch." -} diff --git a/apps/json/ps.json b/apps/json/ps.json deleted file mode 100644 index fb53210bf..000000000 --- a/apps/json/ps.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Ahmed-Najib-Biabani-Ibrahimkhel" - ] - }, - "Apps.dialogOk": "ښه", - "Apps.dialogCancel": "ناگارل", - "Apps.catLogic": "منطق", - "Apps.catText": "متن", - "Apps.catLists": "لړليکونه", - "Apps.catColour": "رنگ", - "Apps.httpRequestError": "د دې غوښتنې سره يوه ستونزه رامېنځ ته شوه", - "Apps.listVariable": "لړليک", - "Apps.textVariable": "متن", - "Code.title": "کوډ" -} diff --git a/apps/json/pt-br.json b/apps/json/pt-br.json deleted file mode 100644 index e7bed3612..000000000 --- a/apps/json/pt-br.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Cainamarques", - "Espertus", - "Luckas", - "Prilopes", - "Slovato", - "Mordecaista", - "Elival", - "Amgauna", - "TheGabrielZaum" - ] - }, - "Apps.subtitle": "um ambiente de programação visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Veja o código JavaScript gerado.", - "Apps.linkTooltip": "Salvar e ligar aos blocos.", - "Apps.runTooltip": "Execute o programa definido pelos blocos na área de trabalho.", - "Apps.runProgram": "Executar o programa", - "Apps.resetProgram": "Reiniciar", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Cancelar", - "Apps.catLogic": "Lógica", - "Apps.catLoops": "Laços", - "Apps.catMath": "Matemática", - "Apps.catText": "Texto", - "Apps.catLists": "Listas", - "Apps.catColour": "Cor", - "Apps.catVariables": "Variáveis", - "Apps.catProcedures": "Funções", - "Apps.httpRequestError": "Houve um problema com a requisição.", - "Apps.linkAlert": "Compartilhe seus blocos com este link:\n\n%1", - "Apps.hashError": "Desculpe, '%1' não corresponde a um programa salvo.", - "Apps.xmlError": "Não foi possível carregar seu arquivo salvo. Talvez ele tenha sido criado com uma versão diferente do Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "texto", - "Code.badXml": "Erro de análise XML:\n%1\n\nSelecione 'OK' para abandonar suas mudanças ou 'Cancelar' para editar o XML.", - "Code.badCode": "Erro no programa:\n%1", - "Code.timeout": "Máximo de iterações de execução excedido.", - "Code.discard": "Apagar todos os %1 blocos?", - "Code.title": "Código", - "Code.blocks": "Blocos", - "Code.trashTooltip": "Descartar todos os blocos." -} diff --git a/apps/json/pt.json b/apps/json/pt.json deleted file mode 100644 index 18e41a246..000000000 --- a/apps/json/pt.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Luckas", - "Espertus", - "Imperadeiro98" - ] - }, - "Apps.subtitle": "um ambiente de programação visual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Veja o código JavaScript gerado.", - "Apps.linkTooltip": "Salva conexão com o blockly.", - "Apps.runProgram": "Executar programa", - "Apps.resetProgram": "Reiniciar", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Cancelar", - "Apps.catLogic": "Lógica", - "Apps.catMath": "Matemática", - "Apps.catText": "Texto", - "Apps.catLists": "Listas", - "Apps.catColour": "Cor", - "Apps.catVariables": "Variáveis", - "Apps.catProcedures": "Funções", - "Apps.httpRequestError": "Houve um problema com a solicitação.", - "Apps.linkAlert": "Compartilhe os seus blocos com este link:\n\n%1", - "Apps.hashError": "Desculpe, '%1' não corresponde a um blockly salvo.", - "Apps.xmlError": "Não foi possível ler o seu arquivo salvo. Talvez ele tenha sido gerado por uma versão antiga do Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "texto", - "Code.badXml": "Erro de análise do XML:\n%1\n\nSeleccionar 'OK' para abandonar as suas alterações ou 'Cancelar' para editar o XML.", - "Code.badCode": "Erro do programa:\n%1", - "Code.discard": "Eliminar todos os blocos (%1)?", - "Code.title": "Código", - "Code.blocks": "Bloqueios" -} diff --git a/apps/json/qqq.json b/apps/json/qqq.json deleted file mode 100644 index 7ffa9a8ec..000000000 --- a/apps/json/qqq.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "Apps.subtitle": "A short description of Blockly.", - "Blockly": "The project name. If readers of your language would know approximately how to pronounce 'Blockly', leave unchanged. Otherwise, include a transliteration in parentheses, such as the Russian: 'Blockly (Блoкли)'.", - "Apps.codeTooltip": "tooltip - Pressing the button causes a program in the JavaScript computer language to be displayed, based on the program created by the user.", - "Apps.linkTooltip": "tooltip - Clicking on this button will cause the current program to be saved and for a URL to be shown to later retrieve it.", - "Apps.runTooltip": "tooltip - Pressing this button runs the computer program the user has written.", - "Apps.runProgram": "button label - Pressing the button runs the computer program the user has written.", - "Apps.resetProgram": "button label - Pressing the button causes the output of the program to be erased but does not delete the user's program).", - "Apps.dialogOk": "Label on button for user to press when done reading help information.\n{{Identical|OK}}", - "Apps.dialogCancel": "Label on button for user to press when not wanting to proceed.\n{{Identical|Cancel}}", - "Apps.catLogic": "category - Blocks related to [https://github.com/google/blockly/wiki/Logic logic].", - "Apps.catLoops": "category - Blocks related to [https://en.wikipedia.org/wiki/Control_flow#Loops loops].", - "Apps.catMath": "category - Blocks related to mathematics.", - "Apps.catText": "category - Blocks related to [https://github.com/google/blockly/wiki/Text text processing].\n{{Identical|Text}}", - "Apps.catLists": "category - Blocks related to [https://github.com/google/blockly/wiki/Lists lists].\n{{Identical|Lists}}", - "Apps.catColour": "category - Blocks related to [https://github.com/google/blockly/wiki/Colour colour].\n{{Identical|Colour}}", - "Apps.catVariables": "category - Blocks related to [https://github.com/google/blockly/wiki/Variables variables].", - "Apps.catProcedures": "category - Blocks related to [https://en.wikipedia.org/wiki/Subroutine defining or using procedures/functions].", - "Apps.httpRequestError": "alert - The URL is invalid or a server error occurred. This message will be followed by technical information useful to engineers trying to understand the problem.", - "Apps.linkAlert": "alert - After the user has pressed a button to save his/her program, this provides the URL (%1) to retrieve the program. The characters '\n\n' indicate that a blank line will be displayed before the URL (in English). Leave those in unless you move %1 to the beginning or middle of the text, in which case you should use your judgment about where blank lines would be most useful.\n\nParameters:\n* %1 - URL of saved program.", - "Apps.hashError": "alert - A request to retrieve a stored program does not have a valid URL. %1 is the invalid portion of the URL.", - "Apps.xmlError": "alert - There was a problem loading a file previously saved by the user. The most likely reason for the problem is that it was created with an earlier, incompatible version of Blockly. This message will be followed by technical information useful to engineers trying to understand the problem.", - "Apps.listVariable": "variable name - Default [https://github.com/google/blockly/wiki/Variables variable] representing a [https://github.com/google/blockly/wiki/Lists list]. This should be a single word, preferably short.", - "Apps.textVariable": "variable name - Default [https://github.com/google/blockly/wiki/Variables variable] representing a [https://github.com/google/blockly/wiki/Text piece of text]. This should be a single word, preferably short.\n{{Identical|Text}}", - "Code.badXml": "alert - Message shown when the user tries switching from the XML tab after entering XML text that could not be parsed. This asks whether they wish to abandon the XML they added. If they select 'OK' (or the translated equivalent), the XML is cleared, and the other tab is shown. If they select 'Cancel', they remain on the XML tab with the bad XML.\n\nUsed in JavaScript window.confirm().", - "Code.badCode": "alert - Message shown if an error occurs while interpreting the user program. The error description follows.", - "Code.timeout": "alert - Message shown if the program has run for more than the permitted number of steps. This exists so that programs with infinite loops do not run forever.", - "Code.discard": "alert - Message shown after the user clicks on the 'discard all' icon. Selecting 'OK' (or the translated equivalent) causes all of the blocks to be discarded. Selecting 'Cancel' prevents blocks from being deleted.\n\nParameters:\n* %1 - number of blocks to be deleted. It is always an integer greater than or equal to 2.", - "Code.title": "title - Title of this application, indicating that it is for writing arbitrary programs.\n{{Identical|Code}}", - "Code.blocks": "tab text - Displays and allows editing of the user's program as blocks.\n{{Identical|Blocks}}", - "Code.trashTooltip": "tooltip - Clicking on this causes the user program to be discarded." -} diff --git a/apps/json/ro.json b/apps/json/ro.json deleted file mode 100644 index e6e62bdc7..000000000 --- a/apps/json/ro.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Costin PIETRARU", - "Espertus", - "Minisarm", - "Oana" - ] - }, - "Apps.subtitle": "un mediu de programare vizual", - "Blockly": "Blockly", - "Apps.codeTooltip": "Vizualizează codul JavaScript generat.", - "Apps.linkTooltip": "Salvează și adaugă la blocuri.", - "Apps.runTooltip": "Execută programul definit de către blocuri în spațiul de lucru.", - "Apps.runProgram": "Rulează programul", - "Apps.resetProgram": "Resetează", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Revocare", - "Apps.catLogic": "Logic", - "Apps.catLoops": "Bucle", - "Apps.catMath": "Matematică", - "Apps.catText": "Text", - "Apps.catLists": "Liste", - "Apps.catColour": "Culoare", - "Apps.catVariables": "Variabile", - "Apps.catProcedures": "Funcții", - "Apps.httpRequestError": "A apărut o problemă la solicitare.", - "Apps.linkAlert": "Distribuie-ți blocurile folosind această legătură:\n\n%1", - "Apps.hashError": "Scuze, „%1” nu corespunde nici unui program salvat.", - "Apps.xmlError": "Sistemul nu a putut încărca fișierul salvat. Poate că a fost creat cu o altă versiune de Blockly?", - "Apps.listVariable": "listă", - "Apps.textVariable": "text", - "Code.badXml": "Eroare de parsare XML:\n%1\n\nAlege „OK” pentru a renunța la modificările efectuate sau „Revocare” pentru a modifica în continuare fișierul XML.", - "Code.badCode": "Eroare de program:\n%1", - "Code.timeout": "Numărul maxim de iterații a fost depășit.", - "Code.discard": "Ștergi toate cele %1 (de) blocuri?", - "Code.title": "Cod", - "Code.blocks": "Blocuri", - "Code.trashTooltip": "Șterge toate blocurile." -} diff --git a/apps/json/ru.json b/apps/json/ru.json deleted file mode 100644 index 5c389246f..000000000 --- a/apps/json/ru.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Eleferen", - "Lockal", - "MS", - "Okras" - ] - }, - "Apps.subtitle": "среда визуального программирования", - "Blockly": "Blockly (Блoкли)", - "Apps.codeTooltip": "Просмотреть созданный код JavaScript.", - "Apps.linkTooltip": "Сохранить и показать ссылку на блоки.", - "Apps.runTooltip": "Запустить программу, заданную блоками в рабочей области.", - "Apps.runProgram": "Запустить Программу", - "Apps.resetProgram": "Сбросить", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Отмена", - "Apps.catLogic": "Логические", - "Apps.catLoops": "Циклы", - "Apps.catMath": "Математика", - "Apps.catText": "Текст", - "Apps.catLists": "Списки", - "Apps.catColour": "Цвет", - "Apps.catVariables": "Переменные", - "Apps.catProcedures": "Функции", - "Apps.httpRequestError": "Произошла проблема при запросе.", - "Apps.linkAlert": "Поделитесь своими блоками по этой ссылке:\n\n%1", - "Apps.hashError": "К сожалению, «%1» не соответствует ни одному сохраненному файлу Блокли.", - "Apps.xmlError": "Не удалось загрузить ваш сохраненный файл. Возможно, он был создан в другой версии Блокли?", - "Apps.listVariable": "список", - "Apps.textVariable": "текст", - "Code.badXml": "Ошибка синтаксического анализа XML:\n%1\n\nВыберите 'ОК', чтобы отказаться от изменений или 'Cancel' для дальнейшего редактирования XML.", - "Code.badCode": "Ошибка программы:\n%1", - "Code.timeout": "Превышено максимальное количество итераций.", - "Code.discard": "Удалить все блоки (%1)?", - "Code.title": "Код", - "Code.blocks": "Блоки", - "Code.trashTooltip": "Удалить все блоки." -} diff --git a/apps/json/sc.json b/apps/json/sc.json deleted file mode 100644 index af42a9365..000000000 --- a/apps/json/sc.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Via maxima" - ] - }, - "Apps.subtitle": "un'ambienti gràficu po programai", - "Blockly": "Blockly", - "Apps.codeTooltip": "Càstia su còdixi JavaScript ingenerau.", - "Apps.linkTooltip": "Sarva e alliòngia a is brocus.", - "Apps.runTooltip": "Arròllia su programa cumpostu de is brocus in s'àrea de traballu.", - "Apps.runProgram": "Arròllia su Programa", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Anudda", - "Apps.catLogic": "Lògica", - "Apps.catLoops": "Lòrigas", - "Apps.catMath": "Matemàtica", - "Apps.catText": "Testu", - "Apps.catLists": "Lista", - "Apps.catColour": "Colori", - "Apps.catVariables": "Variabilis", - "Apps.catProcedures": "Funtzionis", - "Apps.httpRequestError": "Ddui fut unu problema cun sa pregunta", - "Apps.linkAlert": "Poni is brocus tuus in custu acàpiu:\n\n%1", - "Apps.hashError": "Mi dispraxit, '%1' non torrat a pari cun nimancu unu de is programas sarvaus.", - "Apps.xmlError": "Non potzu carrigai su file sarvau. Fortzis est stètiu fatu cun d-una versioni diferenti de Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "testu", - "Code.badXml": "Errori in s'anàlisi XML:\n%1\n\nCraca 'OK' po perdi is mudàntzias 'Anudda' po sighì a scriri su XML.", - "Code.badCode": "Errori in su Programa:\n%1", - "Code.timeout": "Giai lòmpius a su màssimu numeru de repicus.", - "Code.discard": "Scancellu su %1 de is brocus?", - "Code.title": "Còdixi", - "Code.blocks": "Brocus", - "Code.trashTooltip": "Boganci totu is brocus." -} diff --git a/apps/json/sco.json b/apps/json/sco.json deleted file mode 100644 index 2f08e3475..000000000 --- a/apps/json/sco.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "John Reid" - ] - }, - "Apps.subtitle": "ae veesual programin environment", - "Blockly": "Blockly (Blocklie)", - "Apps.codeTooltip": "See generated JavaScript code.", - "Apps.linkTooltip": "Hain n airt til blocks.", - "Apps.runTooltip": "Rin the program defined bi the blocks in the wairkspace.", - "Apps.runProgram": "Rin Program", - "Apps.resetProgram": "Reset", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Cancel", - "Apps.catLogic": "Logeec", - "Apps.catLoops": "Luips", - "Apps.catMath": "Maths", - "Apps.catText": "Tex", - "Apps.catLists": "Leets", - "Apps.catColour": "Colour", - "Apps.catVariables": "Variables", - "Apps.catProcedures": "Functions", - "Apps.httpRequestError": "Thaur wis ae problem wi the request.", - "Apps.linkAlert": "Shair yer blocks wi this airtin:\n\n%1", - "Apps.hashError": "Sairrie, '%1' disna correspond wi onie hained program.", - "Apps.xmlError": "Coudnae laid yer hained file. Perhaps it wis makit wi ae deefferent version o Blockly?", - "Apps.listVariable": "leet", - "Apps.textVariable": "tex", - "Code.badXml": "Mistak parsin XML:\n%1\n\nSelect 'OK' tae hiff yer chynges or 'Cancel' tae further eedit the XML.", - "Code.badCode": "Program mistak:\n%1", - "Code.timeout": "Mucklest execution iterations exceedit.", - "Code.discard": "Delyte aw %1 blocks?", - "Code.title": "Code", - "Code.blocks": "Blocks", - "Code.trashTooltip": "Hiff aw blocks." -} diff --git a/apps/json/si.json b/apps/json/si.json deleted file mode 100644 index bc1241f9d..000000000 --- a/apps/json/si.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Sahan.ssw" - ] - }, - "Apps.runProgram": "මෘදුකාංගය ක්‍රියාත්මක කරන්න", - "Apps.resetProgram": "නැවත සකසන්න", - "Apps.dialogOk": "හරි", - "Apps.dialogCancel": "අවලංගු කරන්න", - "Apps.catLogic": "තර්කය", - "Apps.catMath": "ගණිත", - "Apps.catText": "පෙළ", - "Apps.catLists": "ලැයිස්තු", - "Apps.catColour": "වර්ණය", - "Apps.catVariables": "විචල්‍යයන්", - "Apps.catProcedures": "ශ්‍රිත", - "Apps.httpRequestError": "ඉල්ලීමෙහි දෝෂයක් තිබුනි.", - "Apps.listVariable": "ලැයිස්තුව", - "Apps.textVariable": "පෙළ" -} diff --git a/apps/json/sk.json b/apps/json/sk.json deleted file mode 100644 index 3424fb660..000000000 --- a/apps/json/sk.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Kusavica", - "Marian.stano", - "Rudko" - ] - }, - "Apps.subtitle": "vizuálne programovacie prostredie", - "Blockly": "Blockly", - "Apps.codeTooltip": "Prezrieť vygenerovaný javascriptový kód.", - "Apps.linkTooltip": "Uložiť a zdieľať odkaz na tento program.", - "Apps.runTooltip": "Spustiť program, zložený z dielcov na pracovnej ploche.", - "Apps.runProgram": "Spustiť program", - "Apps.resetProgram": "Odznova", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Zrušiť", - "Apps.catLogic": "Logika", - "Apps.catLoops": "Cykly", - "Apps.catMath": "Matematické", - "Apps.catText": "Text", - "Apps.catLists": "Zoznamy", - "Apps.catColour": "Farby", - "Apps.catVariables": "Premenné", - "Apps.catProcedures": "Funkcie", - "Apps.httpRequestError": "Problém so spracovaním požiadavky.", - "Apps.linkAlert": "Zdieľať tento program skopírovaním odkazu\n\n%1", - "Apps.hashError": "Prepáč, '%1' nie je meno žiadnemu uloženému programu.", - "Apps.xmlError": "Nebolo možné načítať uložený súbor. Možno bol vytvorený v inej verzii Blocky.", - "Apps.listVariable": "zoznam", - "Apps.textVariable": "text", - "Code.badXml": "Chyba pri parsovaní XML:\n%1\n\nStlačte 'OK' ak chcete zrušiť zmeny alebo 'Zrušiť' pre pokračovanie v úpravách XML.", - "Code.badCode": "Chyba v programe:\n%1", - "Code.timeout": "Bol prekročený maximálny počet opakovaní.", - "Code.discard": "Zmazať všetkých %1 dielcov?", - "Code.title": "Kód", - "Code.blocks": "Bloky", - "Code.trashTooltip": "Zahodiť všetky dielce." -} diff --git a/apps/json/sr.json b/apps/json/sr.json deleted file mode 100644 index 7306dd8e1..000000000 --- a/apps/json/sr.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Rancher" - ] - }, - "Apps.subtitle": "визуелно окружење за програмирање", - "Blockly": "Blockly", - "Apps.codeTooltip": "Погледајте генерисани JavaScript кôд.", - "Apps.linkTooltip": "Сачувајте и повежите са блоковима.", - "Apps.runTooltip": "Покрените програм заснован на блоковима у радном простору.", - "Apps.runProgram": "Покрени програм", - "Apps.resetProgram": "Поново постави", - "Apps.dialogOk": "У реду", - "Apps.dialogCancel": "Откажи", - "Apps.catLogic": "Логика", - "Apps.catLoops": "Петље", - "Apps.catMath": "Математика", - "Apps.catText": "Текст", - "Apps.catLists": "Спискови", - "Apps.catColour": "Боја", - "Apps.catVariables": "Променљиве", - "Apps.catProcedures": "Процедуре", - "Apps.httpRequestError": "Дошло је до проблема у захтеву.", - "Apps.linkAlert": "Делите своје блокове овом везом:\n\n%1", - "Apps.hashError": "„%1“ не одговара ниједном сачуваном програму.", - "Apps.xmlError": "Не могу да учитам сачувану датотеку. Можда је направљена другом верзијом Blockly-ја.", - "Apps.listVariable": "списак", - "Apps.textVariable": "текст", - "Code.badXml": "Грешка при рашчлањивању XML-а:\n%1\n\nПритисните „У реду“ да напустите измене или „Откажи“ да наставите са уређивањем XML датотеке.", - "Code.badCode": "Грешка у програму:\n%1", - "Code.timeout": "Достигнут је максималан број понављања у извршавању.", - "Code.discard": "Обрисати %1 блокова?", - "Code.title": "Кôд", - "Code.blocks": "Блокови", - "Code.trashTooltip": "Одбаците све блокове." -} diff --git a/apps/json/sv.json b/apps/json/sv.json deleted file mode 100644 index e24843fb9..000000000 --- a/apps/json/sv.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Jopparn", - "WikiPhoenix", - "Abbedabb" - ] - }, - "Apps.subtitle": "en visuell programmeringsmiljö", - "Blockly": "Blockly", - "Apps.codeTooltip": "Se genererad JavaScript-kod.", - "Apps.linkTooltip": "Spara och länka till block.", - "Apps.runTooltip": "Kör programmet som definierats av blocken i arbetsytan.", - "Apps.runProgram": "Kör program", - "Apps.resetProgram": "Återställ", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Avbryt", - "Apps.catLogic": "Logik", - "Apps.catLoops": "Loopar", - "Apps.catMath": "Matematik", - "Apps.catText": "Text", - "Apps.catLists": "Listor", - "Apps.catColour": "Färg", - "Apps.catVariables": "Variabler", - "Apps.catProcedures": "Funktioner", - "Apps.httpRequestError": "Det uppstod ett problem med begäran.", - "Apps.linkAlert": "Dela dina block med denna länk: \n\n%1", - "Apps.hashError": "Tyvärr, '%1' överensstämmer inte med något sparat program.", - "Apps.xmlError": "Kunde inte läsa din sparade fil. Den skapades kanske med en annan version av Blockly?", - "Apps.listVariable": "lista", - "Apps.textVariable": "text", - "Code.badXml": "Fel vid parsning av XML:\n%1\n\nKlicka på 'OK' för att strunta i dina ändringar eller 'Avbryt' för att fortsätta redigera XML-koden.", - "Code.badCode": "Programfel:\n%1", - "Code.timeout": "Det maximala antalet utförda loopar har överskridits.", - "Code.discard": "Radera alla %1 block?", - "Code.title": "Kod", - "Code.blocks": "Block", - "Code.trashTooltip": "Släng alla block." -} diff --git a/apps/json/sw.json b/apps/json/sw.json deleted file mode 100644 index 8e38c29ce..000000000 --- a/apps/json/sw.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "@metadata": [], - "Apps.subtitle": "mazingira ya programu ya kuona", - "Blockly": "Blockly", - "Apps.codeTooltip": "Tazama mwandiko wa JavaScript inayotokana.", - "Apps.linkTooltip": "Hifadhi na kiungo cha vishiku.", - "Apps.runProgram": "Endesha Programu", - "Apps.resetProgram": "Seti upya", - "Apps.dialogOk": "Sawa", - "Apps.httpRequestError": "Kuna shida na amri.", - "Apps.linkAlert": "Sambaza vishiku vyako na kiungo hiki: \n\n%1", - "Apps.hashError": "Samahani, '%1' haiendani na faili yoyote ya Blockly.", - "Apps.xmlError": "Upakiaji wa faili yako iliyohifadhiwa haiwezekani. Labda iliundwa na toleo tofauti ya Blockly?" -} diff --git a/apps/json/th.json b/apps/json/th.json deleted file mode 100644 index 99557cf6d..000000000 --- a/apps/json/th.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Azpirin", - "Taweetham" - ] - }, - "Apps.subtitle": "ระบบการเขียนโปรแกรมด้วยรูปภาพ", - "Blockly": "Blockly", - "Apps.codeTooltip": "ดูโค้ด JavaScript ที่ถูกสร้างขึ้น", - "Apps.linkTooltip": "บันทึกและสร้างลิงก์มายังบล็อกเหล่านี้", - "Apps.runTooltip": "เรียกใช้โปรแกรมตามที่กำหนดไว้ด้วยบล็อกที่อยู่ในพื้นที่ทำงาน", - "Apps.runProgram": "เรียกใช้โปรแกรม", - "Apps.resetProgram": "เริ่มใหม่", - "Apps.dialogOk": "ตกลง", - "Apps.dialogCancel": "ยกเลิก", - "Apps.catLogic": "ตรรกะ", - "Apps.catLoops": "การวนซ้ำ", - "Apps.catMath": "คณิตศาสตร์", - "Apps.catText": "ข้อความ", - "Apps.catLists": "รายการ", - "Apps.catColour": "สี", - "Apps.catVariables": "ตัวแปร", - "Apps.catProcedures": "ฟังก์ชัน", - "Apps.httpRequestError": "มีปัญหาเกี่ยวกับการร้องขอ", - "Apps.linkAlert": "แบ่งปันบล็อกของคุณด้วยลิงก์นี้:\n\n%1", - "Apps.hashError": "เสียใจด้วย '%1' ไม่ตรงกับโปรแกรมใดๆ ที่เคยบันทึกเอาไว้เลย", - "Apps.xmlError": "ไม่สามารถโหลดไฟล์ที่บันทึกไว้ของคุณได้ บางทีมันอาจจะถูกสร้างขึ้นด้วย Blockly รุ่นอื่นที่แตกต่างกัน?", - "Apps.listVariable": "รายการ", - "Apps.textVariable": "ข้อความ", - "Code.badXml": "เกิดข้อผิดพลาดในการแยกวิเคราะห์ XML:\n%1\n\nเลือก 'ตกลง' เพื่อละทิ้งการเปลี่ยนแปลงต่างๆ ที่ทำไว้ หรือเลือก 'ยกเลิก' เพื่อแก้ไข XML ต่อไป", - "Code.badCode": "โปรแกรมเกิดข้อผิดพลาด:\n%1", - "Code.timeout": "โปรแกรมทำงานซ้ำคำสั่งเดิมมากเกินไป", - "Code.discard": "ต้องการลบบล็อกทั้ง %1 บล็อกใช่หรือไม่?", - "Code.title": "เขียนโปรแกรม", - "Code.blocks": "บล็อก", - "Code.trashTooltip": "ยกเลิกบล็อกทั้งหมด" -} diff --git a/apps/json/tlh.json b/apps/json/tlh.json deleted file mode 100644 index 89ef0dc30..000000000 --- a/apps/json/tlh.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "@metadata": { - "author": "De'vID ", - "lastupdated": "2014-03-24 23:00:00.000000", - "locale": "tlh", - "messagedocumentation" : "qqq" - }, - "Apps.subtitle": "ngoq DaleghlaHbogh, ngogh DaghunlaHbogh", - "Blockly": "ghunmeH ngogh", - "Apps.dialogOk": "ruch", - "Apps.dialogCancel": "qIl", - "Apps.catLogic": "meq", - "Apps.catLoops": "vIHtaHbogh ghomey", - "Apps.catMath": "mI'QeD", - "Apps.catText": "ghItlhHommey", - "Apps.catLists": "tetlhmey", - "Apps.catColour": "rItlh", - "Apps.catVariables": "lIwmey", - "Apps.catProcedures": "mIwmey", - "Apps.httpRequestError": "Qapbe' tlhobmeH QIn.", - "Apps.linkAlert": "latlhvaD ngoghmeylIj DangeHmeH Quvvam yIlo':\n\n%1", - "Apps.hashError": "Do'Ha', ngogh nab pollu'pu'bogh 'oHbe'law' \"%1\"'e'.", - "Apps.xmlError": "ngogh nablIj pollu'pu'bogh chu'qa'laHbe' vay'. chaq pollu'pu'DI' ghunmeH ngogh pIm lo'lu'pu'.", - "Apps.listVariable": "tetlh", - "Apps.textVariable": "ghItlhHom", - "Code.badXml": "XML yajchu'laHbe' vay':\n%1\n\nchoHmeylIj DalonmeH \"ruch\" yIwIv pagh XML DachoHqa'meH \"qIl\" yIwIv.", - "Code.badCode": "Qagh:\n%1", - "Code.timeout": "tlhoy nI'qu' poH.", - "Code.discard": "Hoch %1 ngoghmey Qaw'?", - "Code.title": "ngoq", - "Code.blocks": "ngoghmey" -} diff --git a/apps/json/tr.json b/apps/json/tr.json deleted file mode 100644 index ee222fef9..000000000 --- a/apps/json/tr.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Bahadir", - "Espertus", - "Joseph", - "Kozlu", - "Trockya" - ] - }, - "Apps.subtitle": "görsel bir programlama ortamı", - "Blockly": "Blockly", - "Apps.codeTooltip": "Oluşturulan JavaScript kodunu görüntüle.", - "Apps.linkTooltip": "Blokları ve bağlantı adresini kaydet.", - "Apps.runTooltip": "Çalışma alanında bloklar tarafından tanımlanan programını çalıştırın.", - "Apps.runProgram": "Programı Çalıştır", - "Apps.resetProgram": "Tekrar", - "Apps.dialogOk": "TAMAM", - "Apps.dialogCancel": "İptal", - "Apps.catLogic": "Mantık", - "Apps.catLoops": "Döngüler", - "Apps.catMath": "Matematik", - "Apps.catText": "Metin", - "Apps.catLists": "Listeler", - "Apps.catColour": "Renk", - "Apps.catVariables": "Değişkenler", - "Apps.catProcedures": "İşlevler", - "Apps.httpRequestError": "İstek ile ilgili bir problem var.", - "Apps.linkAlert": "Bloklarını bu bağlantı ile paylaş:\n\n%1", - "Apps.hashError": "Üzgünüz, '%1' hiç bir kaydedilmiş program ile uyuşmuyor.", - "Apps.xmlError": "Kaydedilen dosyanız yüklenemiyor\nBlockly'nin önceki sürümü ile kaydedilmiş olabilir mi?", - "Apps.listVariable": "liste", - "Apps.textVariable": "metin", - "Code.badXml": "XML ayrıştırma hatası:\n%1\n\nDeğişikliklerden vazgeçmek için 'Tamam'ı, düzenlemeye devam etmek için 'İptal' seçeneğini seçiniz.", - "Code.badCode": "Program hatası:\n %1", - "Code.timeout": "Maksimum yürütme yinelemeleri aşıldı.", - "Code.discard": "Tüm %1 blok silinsin mi?", - "Code.title": "Kod", - "Code.blocks": "Bloklar", - "Code.trashTooltip": "Bütün blokları at." -} diff --git a/apps/json/uk.json b/apps/json/uk.json deleted file mode 100644 index cb3bec736..000000000 --- a/apps/json/uk.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Andriykopanytsia" - ] - }, - "Apps.subtitle": "візуальне середовище програмування", - "Blockly": "Blockly (Блоклі)", - "Apps.codeTooltip": "Див. згенерований код JavaScript.", - "Apps.linkTooltip": "Зберегти і пов'язати з блоками.", - "Apps.runTooltip": "Запустіть програму, визначену блоками у робочій області.", - "Apps.runProgram": "Запустити програму", - "Apps.resetProgram": "Очистити", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Скасувати", - "Apps.catLogic": "Логіка", - "Apps.catLoops": "Петлі", - "Apps.catMath": "Математика", - "Apps.catText": "Текст", - "Apps.catLists": "Списки", - "Apps.catColour": "Колір", - "Apps.catVariables": "Змінні", - "Apps.catProcedures": "Функції", - "Apps.httpRequestError": "Виникла проблема із запитом.", - "Apps.linkAlert": "Поділитися вашим блоками через посилання:\n\n%1", - "Apps.hashError": "На жаль, \"%1\" не відповідає жодній збереженій програмі.", - "Apps.xmlError": "Не вдалося завантажити ваш збережений файл. Можливо, він був створений з іншої версії Blockly?", - "Apps.listVariable": "список", - "Apps.textVariable": "текст", - "Code.badXml": "Помилка синтаксичного аналізу XML:\n%1\n\nВиберіть \"Гаразд\", щоб відмовитися від змін або 'Скасувати' для подальшого редагування XML.", - "Code.badCode": "Помилка програми:\n%1", - "Code.timeout": "Максимальне виконання ітерацій перевищено.", - "Code.discard": "Вилучити всі блоки %1?", - "Code.title": "Код", - "Code.blocks": "Блоки", - "Code.trashTooltip": "Відкинути всі блоки." -} diff --git a/apps/json/vi.json b/apps/json/vi.json deleted file mode 100644 index 3197571f1..000000000 --- a/apps/json/vi.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Baonguyen21022003", - "Qneutron", - "Withoutaname", - "Dstream" - ] - }, - "Apps.subtitle": "môi trường lập trình trực quan", - "Blockly": "Blockly", - "Apps.codeTooltip": "Xem code đã tạo bằng JavaScript.", - "Apps.linkTooltip": "Lưu và lấy địa chỉ liên kết.", - "Apps.runTooltip": "Chạy chương trình.", - "Apps.runProgram": "Chạy chương trình", - "Apps.resetProgram": "Làm lại", - "Apps.dialogOk": "OK", - "Apps.dialogCancel": "Hủy", - "Apps.catLogic": "Logic", - "Apps.catLoops": "Vòng lặp", - "Apps.catMath": "Công thức toán", - "Apps.catText": "Văn bản", - "Apps.catLists": "Danh sách", - "Apps.catColour": "Màu", - "Apps.catVariables": "Biến", - "Apps.catProcedures": "Hàm", - "Apps.httpRequestError": "Hoạt động bị trục trặc, không thực hiện được yêu cầu của bạn.", - "Apps.linkAlert": "Chia sẻ chương trình của bạn với liên kết sau:\n\n %1", - "Apps.hashError": "Không tìm thấy chương trình được lưu ở '%1'.", - "Apps.xmlError": "Không mở được chương trình của bạn. Có thể nó nằm trong một phiên bản khác của Blockly?", - "Apps.listVariable": "danh sách", - "Apps.textVariable": "văn bản", - "Code.badXml": "Lỗi sử lý XML:\n %1\n\nChọn 'OK' để từ bỏ các thay đổi hoặc 'Hủy' để tiếp tục chỉnh sửa các XML.", - "Code.badCode": "'Lỗi chương trình:\n%1", - "Code.timeout": "Đã vượt quá số lần lặp cho phép.", - "Code.discard": "Xóa hết %1 mảnh?", - "Code.title": "Chương trình", - "Code.blocks": "Các mảnh", - "Code.trashTooltip": "Xóa tất cả mọi mảnh." -} diff --git a/apps/json/zh-hans.json b/apps/json/zh-hans.json deleted file mode 100644 index 20258aba4..000000000 --- a/apps/json/zh-hans.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Hydra", - "Hzy980512", - "Liuxinyu970226", - "Luotiancheng", - "Qiyue2001", - "Yfdyh000" - ] - }, - "Apps.subtitle": "一个可视化编程环境", - "Blockly": "Blockly", - "Apps.codeTooltip": "查看生成的JavaScript代码。", - "Apps.linkTooltip": "保存模块并生成链接。", - "Apps.runTooltip": "于工作区中运行块所定义的程式。", - "Apps.runProgram": "运行程序", - "Apps.resetProgram": "重置", - "Apps.dialogOk": "确认", - "Apps.dialogCancel": "取消", - "Apps.catLogic": "逻辑", - "Apps.catLoops": "循环", - "Apps.catMath": "数学", - "Apps.catText": "文本", - "Apps.catLists": "列表", - "Apps.catColour": "颜色", - "Apps.catVariables": "变量", - "Apps.catProcedures": "函数", - "Apps.httpRequestError": "请求存在问题。", - "Apps.linkAlert": "通过这个链接分享您的模块:\n\n%1", - "Apps.hashError": "对不起,没有任何已保存的程序对应'%1' 。", - "Apps.xmlError": "无法载入您保存的文件。您是否使用其他版本的Blockly创建该文件的?", - "Apps.listVariable": "列表", - "Apps.textVariable": "文本", - "Code.badXml": "XML解析错误:\n%1\n\n选择“确定”以取消您对XML的修改,或选择“取消”以继续编辑XML。", - "Code.badCode": "程序错误:\n%1", - "Code.timeout": "超过最大执行行数。", - "Code.discard": "删除所有%1块吗?", - "Code.title": "代码", - "Code.blocks": "块", - "Code.trashTooltip": "放弃所有块。" -} diff --git a/apps/json/zh-hant.json b/apps/json/zh-hant.json deleted file mode 100644 index e7cb3cf12..000000000 --- a/apps/json/zh-hant.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Gasolin", - "Justincheng12345" - ] - }, - "Apps.subtitle": "視覺化程式設計環境", - "Blockly": "Blockly", - "Apps.codeTooltip": "查看產生的JavaScript程式碼。", - "Apps.linkTooltip": "儲存積木組並提供連結。", - "Apps.runTooltip": "於工作區中執行積木組所定義的程式。", - "Apps.runProgram": "執行程式", - "Apps.resetProgram": "重設", - "Apps.dialogOk": "確定", - "Apps.dialogCancel": "取消", - "Apps.catLogic": "邏輯", - "Apps.catLoops": "迴圈", - "Apps.catMath": "數學式", - "Apps.catText": "文字", - "Apps.catLists": "列表", - "Apps.catColour": "顏色", - "Apps.catVariables": "變量", - "Apps.catProcedures": "流程", - "Apps.httpRequestError": "命令出現錯誤。", - "Apps.linkAlert": "透過此連結分享您的積木組:\n\n%1", - "Apps.hashError": "對不起,「%1」並未對應任何已保存的程式。", - "Apps.xmlError": "未能載入您保存的檔案。或許它是由其他版本的Blockly創建?", - "Apps.listVariable": "列表", - "Apps.textVariable": "文字", - "Code.badXml": "解析 XML 時出現錯誤:\n%1\n\n選擇'確定'以放棄您的更改,或選擇'取消'以進一步編輯 XML。", - "Code.badCode": "程式錯誤:\n%1", - "Code.timeout": "超過最大執行數。", - "Code.discard": "刪除共%1個積木?", - "Code.title": "程式碼", - "Code.blocks": "積木", - "Code.trashTooltip": "捨棄所有積木。" -} diff --git a/apps/prettify.css b/apps/prettify.css deleted file mode 100644 index d44b3a228..000000000 --- a/apps/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} \ No newline at end of file diff --git a/apps/prettify.js b/apps/prettify.js deleted file mode 100644 index 7b990496d..000000000 --- a/apps/prettify.js +++ /dev/null @@ -1,30 +0,0 @@ -!function(){var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function S(a){function d(e){var b=e.charCodeAt(0);if(b!==92)return b;var a=e.charAt(1);return(b=r[a])?b:"0"<=a&&a<="7"?parseInt(e.substring(1),8):a==="u"||a==="x"?parseInt(e.substring(2),16):e.charCodeAt(1)}function g(e){if(e<32)return(e<16?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return e==="\\"||e==="-"||e==="]"||e==="^"?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),e=[],a= -b[0]==="^",c=["["];a&&c.push("^");for(var a=a?1:0,f=b.length;a122||(l<65||h>90||e.push([Math.max(65,h)|32,Math.min(l,90)|32]),l<97||h>122||e.push([Math.max(97,h)&-33,Math.min(l,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});b=[];f=[];for(a=0;ah[0]&&(h[1]+1>h[0]&&c.push("-"),c.push(g(h[1])));c.push("]");return c.join("")}function s(e){for(var a=e.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),c=a.length,d=[],f=0,h=0;f=2&&e==="["?a[f]=b(l):e!=="\\"&&(a[f]=l.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var x=0,m=!1,j=!1,k=0,c=a.length;k=5&&"lang-"===w.substring(0,5))&&!(t&&typeof t[1]==="string"))f=!1,w="src";f||(r[z]=w)}h=c;c+=z.length;if(f){f=t[1];var l=z.indexOf(f),B=l+f.length;t[2]&&(B=z.length-t[2].length,l=B-f.length);w=w.substring(5);H(j+h,z.substring(0,l),g,k);H(j+h+l,f,I(w,f),k);H(j+h+B,z.substring(B),g,k)}else k.push(j+h,w)}a.g=k}var b={},s;(function(){for(var g=a.concat(d),j=[],k={},c=0,i=g.length;c=0;)b[n.charAt(e)]=r;r=r[1];n=""+r;k.hasOwnProperty(n)||(j.push(r),k[n]=q)}j.push(/[\S\s]/);s=S(j)})();var x=d.length;return g}function v(a){var d=[],g=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?d.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):d.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&g.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var b=a.hashComments;b&&(a.cStyleComments?(b>1?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),g.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,q])):d.push(["com", -/^#[^\n\r]*/,q,"#"]));a.cStyleComments&&(g.push(["com",/^\/\/[^\n\r]*/,q]),g.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));if(b=a.regexLiterals){var s=(b=b>1?"":"\n\r")?".":"[\\S\\s]";g.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+s+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+ -s+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&g.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&g.push(["kwd",RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),q]);d.push(["pln",/^\s+/,q," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");g.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/, -q],["pun",RegExp(b),q]);return C(d,g)}function J(a,d,g){function b(a){var c=a.nodeType;if(c==1&&!x.test(a.className))if("br"===a.nodeName)s(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((c==3||c==4)&&g){var d=a.nodeValue,i=d.match(m);if(i)c=d.substring(0,i.index),a.nodeValue=c,(d=d.substring(i.index+i[0].length))&&a.parentNode.insertBefore(j.createTextNode(d),a.nextSibling),s(a),c||a.parentNode.removeChild(a)}}function s(a){function b(a,c){var d= -c?a.cloneNode(!1):a,e=a.parentNode;if(e){var e=b(e,1),g=a.nextSibling;e.appendChild(d);for(var i=g;i;i=g)g=i.nextSibling,e.appendChild(i)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),d;(d=a.parentNode)&&d.nodeType===1;)a=d;c.push(a)}for(var x=/(?:^|\s)nocode(?:\s|$)/,m=/\r\n?|\n/,j=a.ownerDocument,k=j.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var c=[k],i=0;i=0;){var b=d[g];F.hasOwnProperty(b)?D.console&&console.warn("cannot override language handler %s",b):F[b]=a}}function I(a,d){if(!a||!F.hasOwnProperty(a))a=/^\s*=l&&(b+=2);g>=B&&(r+=2)}}finally{if(f)f.style.display=h}}catch(u){D.console&&console.log(u&&u.stack||u)}}var D=window,y=["break,continue,do,else,for,if,return,while"],E=[[y,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],M=[E,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],N=[E,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"], -O=[N,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],E=[E,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],P=[y,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -Q=[y,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],W=[y,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],y=[y,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],R=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/, -V=/\S/,X=v({keywords:[M,O,E,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",P,Q,y],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),F={};p(X,["default-code"]);p(C([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-", -/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);p(C([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/], -["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);p(C([],[["atv",/^[\S\s]+/]]),["uq.val"]);p(v({keywords:M,hashComments:!0,cStyleComments:!0,types:R}),["c","cc","cpp","cxx","cyc","m"]);p(v({keywords:"null,true,false"}),["json"]);p(v({keywords:O,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:R}), -["cs"]);p(v({keywords:N,cStyleComments:!0}),["java"]);p(v({keywords:y,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);p(v({keywords:P,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);p(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);p(v({keywords:Q, -hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);p(v({keywords:E,cStyleComments:!0,regexLiterals:!0}),["javascript","js"]);p(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);p(v({keywords:W,cStyleComments:!0,multilineStrings:!0}),["rc","rs","rust"]); -p(C([],[["str",/^[\S\s]+/]]),["regex"]);var Y=D.PR={createSimpleLexer:C,registerLangHandler:p,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:D.prettyPrintOne=function(a,d,g){var b=document.createElement("div");b.innerHTML="
    "+a+"
    ";b=b.firstChild;g&&J(b,g,!0);K({h:d,j:g,c:b,i:1}); -return b.innerHTML},prettyPrint:D.prettyPrint=function(a,d){function g(){for(var b=D.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;i 1) { + // An href with #key trigers an AJAX call to retrieve saved blocks. + BlocklyStorage.retrieveXml(window.location.hash.substring(1)); + } else if (loadOnce) { + // Language switching stores the blocks during the reload. + delete window.sessionStorage.loadOnceBlocks; + var xml = Blockly.Xml.textToDom(loadOnce); + Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); + } else if (defaultXml) { + // Load the editor with default starting blocks. + var xml = Blockly.Xml.textToDom(defaultXml); + Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); + } else if ('BlocklyStorage' in window) { + // Restore saved blocks in a separate thread so that subsequent + // initialization is not affected from a failed load. + window.setTimeout(BlocklyStorage.restoreBlocks, 0); + } +}; + +/** + * Save the blocks and reload with a different language. + */ +Code.changeLanguage = function() { + // Store the blocks for the duration of the reload. + // This should be skipped for the index page, which has no blocks and does + // not load Blockly. + // MSIE 11 does not support sessionStorage on file:// URLs. + if (typeof Blockly != 'undefined' && window.sessionStorage) { + var xml = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace); + var text = Blockly.Xml.domToText(xml); + window.sessionStorage.loadOnceBlocks = text; + } + + var languageMenu = document.getElementById('languageMenu'); + var newLang = encodeURIComponent( + languageMenu.options[languageMenu.selectedIndex].value); + var search = window.location.search; + if (search.length <= 1) { + search = '?lang=' + newLang; + } else if (search.match(/[?&]lang=[^&]*/)) { + search = search.replace(/([?&]lang=)[^&]*/, '$1' + newLang); + } else { + search = search.replace(/\?/, '?lang=' + newLang + '&'); + } + + window.location = window.location.protocol + '//' + + window.location.host + window.location.pathname + search; +}; + +/** + * Bind a function to a button's click event. + * On touch enabled browsers, ontouchend is treated as equivalent to onclick. + * @param {!Element|string} el Button element or ID thereof. + * @param {!Function} func Event handler to bind. + */ +Code.bindClick = function(el, func) { + if (typeof el == 'string') { + el = document.getElementById(el); + } + el.addEventListener('click', func, true); + el.addEventListener('touchend', func, true); +}; + +/** + * Load the Prettify CSS and JavaScript. + */ +Code.importPrettify = function() { + // + // + var link = document.createElement('link'); + link.setAttribute('rel', 'stylesheet'); + link.setAttribute('type', 'text/css'); + link.setAttribute('href', '../prettify.css'); + document.head.appendChild(link); + var script = document.createElement('script'); + script.setAttribute('type', 'text/javascript'); + script.setAttribute('src', '../prettify.js'); + document.head.appendChild(script); +}; + +/** + * Compute the absolute coordinates and dimensions of an HTML element. + * @param {!Element} element Element to match. + * @return {!Object} Contains height, width, x, and y properties. + * @private + */ +Code.getBBox_ = function(element) { + var height = element.offsetHeight; + var width = element.offsetWidth; + var x = 0; + var y = 0; + do { + x += element.offsetLeft; + y += element.offsetTop; + element = element.offsetParent; + } while (element); + return { + height: height, + width: width, + x: x, + y: y + }; +}; + +/** + * User's language (e.g. "en"). + * @type string + */ +Code.LANG = Code.getLang(); + +/** + * List of tab names. + * @private + */ +Code.TABS_ = ['blocks', 'javascript', 'python', 'dart', 'xml']; + +Code.selected = 'blocks'; + +/** + * Switch the visible pane when a tab is clicked. + * @param {string} clickedName Name of tab clicked. + */ +Code.tabClick = function(clickedName) { + // If the XML tab was open, save and render the content. + if (document.getElementById('tab_xml').className == 'tabon') { + var xmlTextarea = document.getElementById('content_xml'); + var xmlText = xmlTextarea.value; + var xmlDom = null; + try { + xmlDom = Blockly.Xml.textToDom(xmlText); + } catch (e) { + var q = + window.confirm(MSG['badXml'].replace('%1', e)); + if (!q) { + // Leave the user on the XML tab. + return; + } + } + if (xmlDom) { + Blockly.mainWorkspace.clear(); + Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xmlDom); + } + } + + // Deselect all tabs and hide all panes. + for (var i = 0; i < Code.TABS_.length; i++) { + var name = Code.TABS_[i]; + document.getElementById('tab_' + name).className = 'taboff'; + document.getElementById('content_' + name).style.visibility = 'hidden'; + } + + // Select the active tab. + Code.selected = clickedName; + document.getElementById('tab_' + clickedName).className = 'tabon'; + // Show the selected pane. + document.getElementById('content_' + clickedName).style.visibility = + 'visible'; + Code.renderContent(); + Blockly.fireUiEvent(window, 'resize'); +}; + +/** + * Populate the currently selected pane with content generated from the blocks. + */ +Code.renderContent = function() { + var content = document.getElementById('content_' + Code.selected); + // Initialize the pane. + if (content.id == 'content_xml') { + var xmlTextarea = document.getElementById('content_xml'); + var xmlDom = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace); + var xmlText = Blockly.Xml.domToPrettyText(xmlDom); + xmlTextarea.value = xmlText; + xmlTextarea.focus(); + } else if (content.id == 'content_javascript') { + var code = Blockly.JavaScript.workspaceToCode(); + content.textContent = code; + if (typeof prettyPrintOne == 'function') { + code = content.innerHTML; + code = prettyPrintOne(code, 'js'); + content.innerHTML = code; + } + } else if (content.id == 'content_python') { + code = Blockly.Python.workspaceToCode(); + content.textContent = code; + if (typeof prettyPrintOne == 'function') { + code = content.innerHTML; + code = prettyPrintOne(code, 'py'); + content.innerHTML = code; + } + } else if (content.id == 'content_dart') { + code = Blockly.Dart.workspaceToCode(); + content.textContent = code; + if (typeof prettyPrintOne == 'function') { + code = content.innerHTML; + code = prettyPrintOne(code, 'dart'); + content.innerHTML = code; + } + } +}; + +/** + * Initialize Blockly. Called on page load. + */ +Code.init = function() { + Code.initLanguage(); + + // Disable the link button if page isn't backed by App Engine storage. + var linkButton = document.getElementById('linkButton'); + if ('BlocklyStorage' in window) { + BlocklyStorage['HTTPREQUEST_ERROR'] = MSG['httpRequestError']; + BlocklyStorage['LINK_ALERT'] = MSG['linkAlert']; + BlocklyStorage['HASH_ERROR'] = MSG['hashError']; + BlocklyStorage['XML_ERROR'] = MSG['xmlError']; + BlocklyApps.bindClick(linkButton, BlocklyStorage.link); + } else if (linkButton) { + linkButton.className = 'disabled'; + } + + var rtl = Code.isRtl(); + var container = document.getElementById('content_area'); + var onresize = function(e) { + var bBox = Code.getBBox_(container); + for (var i = 0; i < Code.TABS_.length; i++) { + var el = document.getElementById('content_' + Code.TABS_[i]); + el.style.top = bBox.y + 'px'; + el.style.left = bBox.x + 'px'; + // Height and width need to be set, read back, then set again to + // compensate for scrollbars. + el.style.height = bBox.height + 'px'; + el.style.height = (2 * bBox.height - el.offsetHeight) + 'px'; + el.style.width = bBox.width + 'px'; + el.style.width = (2 * bBox.width - el.offsetWidth) + 'px'; + } + // Make the 'Blocks' tab line up with the toolbox. + if (Blockly.Toolbox.width) { + document.getElementById('tab_blocks').style.minWidth = + (Blockly.Toolbox.width - 38) + 'px'; + // Account for the 19 pixel margin and on each side. + } + }; + window.addEventListener('resize', onresize, false); + + var toolbox = document.getElementById('toolbox'); + Blockly.inject(document.getElementById('content_blocks'), + {media: '../../media/', + rtl: rtl, + toolbox: toolbox}); + + // Add to reserved word list: Local variables in execution evironment (runJS) + // and the infinite loop detection function. + Blockly.JavaScript.addReservedWords('code,timeouts,checkTimeout'); + + Code.loadBlocks(''); + + if ('BlocklyStorage' in window) { + // Hook a save function onto unload. + BlocklyStorage.backupOnUnload(); + } + + Code.tabClick(Code.selected); + Blockly.fireUiEvent(window, 'resize'); + + Code.bindClick('trashButton', + function() {Code.discard(); Code.renderContent();}); + Code.bindClick('runButton', Code.runJS); + + for (var i = 0; i < Code.TABS_.length; i++) { + var name = Code.TABS_[i]; + Code.bindClick('tab_' + name, + function(name_) {return function() {Code.tabClick(name_);};}(name)); + } + + // Lazy-load the syntax-highlighting. + window.setTimeout(Code.importPrettify, 1); +}; + +/** + * Initialize the page language. + */ +Code.initLanguage = function() { + // Set the HTML's language and direction. + // document.dir fails in Mozilla, use document.body.parentNode.dir instead. + // https://bugzilla.mozilla.org/show_bug.cgi?id=151407 + var rtl = Code.isRtl(); + document.head.parentElement.setAttribute('dir', rtl ? 'rtl' : 'ltr'); + document.head.parentElement.setAttribute('lang', Code.LANG); + + // Sort languages alphabetically. + var languages = []; + for (var lang in Code.LANGUAGE_NAME) { + languages.push([Code.LANGUAGE_NAME[lang], lang]); + } + var comp = function(a, b) { + // Sort based on first argument ('English', 'Русский', '简体字', etc). + if (a[0] > b[0]) return 1; + if (a[0] < b[0]) return -1; + return 0; + }; + languages.sort(comp); + // Populate the language selection menu. + var languageMenu = document.getElementById('languageMenu'); + languageMenu.options.length = 0; + for (var i = 0; i < languages.length; i++) { + var tuple = languages[i]; + var lang = tuple[tuple.length - 1]; + var option = new Option(tuple[0], lang); + if (lang == Code.LANG) { + option.selected = true; + } + languageMenu.options.add(option); + } + languageMenu.addEventListener('change', Code.changeLanguage, true); + + // Inject language strings. + document.title += ' ' + MSG['title']; + document.getElementById('title').textContent = MSG['title']; + document.getElementById('tab_blocks').textContent = MSG['blocks']; + + document.getElementById('linkButton').title = MSG['linkTooltip']; + document.getElementById('runButton').title = MSG['runTooltip']; + document.getElementById('trashButton').title = MSG['trashTooltip']; + + var categories = ['catLogic', 'catLoops', 'catMath', 'catText', 'catLists', + 'catColour', 'catVariables', 'catFunctions']; + for (var i = 0, cat; cat = categories[i]; i++) { + document.getElementById(cat).setAttribute('name', MSG[cat]); + } + var textVars = document.getElementsByClassName('textVar'); + for (var i = 0, textVar; textVar = textVars[i]; i++) { + textVar.textContent = MSG['textVariable']; + } + var listVars = document.getElementsByClassName('listVar'); + for (var i = 0, listVar; listVar = listVars[i]; i++) { + listVar.textContent = MSG['listVariable']; + } +}; + +/** + * Execute the user's code. + * Just a quick and dirty eval. Catch infinite loops. + */ +Code.runJS = function() { + Blockly.JavaScript.INFINITE_LOOP_TRAP = ' checkTimeout();\n'; + var timeouts = 0; + var checkTimeout = function() { + if (timeouts++ > 1000000) { + throw MSG['timeout']; + } + }; + var code = Blockly.JavaScript.workspaceToCode(); + Blockly.JavaScript.INFINITE_LOOP_TRAP = null; + try { + eval(code); + } catch (e) { + alert(MSG['badCode'].replace('%1', e)); + } +}; + +/** + * Discard all blocks from the workspace. + */ +Code.discard = function() { + var count = Blockly.mainWorkspace.getAllBlocks().length; + if (count < 2 || + window.confirm(MSG['discard'].replace('%1', count))) { + Blockly.mainWorkspace.clear(); + window.location.hash = ''; + } +}; + +// Load the Code demo's language strings. +document.write('\n'); +// Load Blockly's language strings. +document.write('\n'); + +window.addEventListener('load', Code.init); diff --git a/apps/code/icon.png b/demos/code/icon.png similarity index 100% rename from apps/code/icon.png rename to demos/code/icon.png diff --git a/apps/code/icons.png b/demos/code/icons.png similarity index 100% rename from apps/code/icons.png rename to demos/code/icons.png diff --git a/apps/code/template.soy b/demos/code/index.html similarity index 61% rename from apps/code/template.soy rename to demos/code/index.html index 71a55df78..221c3e6ce 100644 --- a/apps/code/template.soy +++ b/demos/code/index.html @@ -1,49 +1,25 @@ -{namespace codepage} - -/** - * This is a Closure Template. - * - * To regenerate just en.js, run this command: - * java -jar ../_soy/SoyToJsSrcCompiler.jar --outputPathFormat generated/en.js --srcs ../common.soy,template.soy - * - * To regenerate all files, see: trunk/apps/common.soy - */ - -/** - * Translated messages for use in JavaScript. - */ -{template .messages} - {call apps.messages /} -
    - {msg meaning="Code.badXml" desc="alert - Message shown when the user tries switching from the XML tab after entering XML text that could not be parsed. This asks whether they wish to abandon the XML they added. If they select 'OK' (or the translated equivalent), the XML is cleared, and the other tab is shown. If they select 'Cancel', they remain on the XML tab with the bad XML.\n\nUsed in JavaScript window.confirm()."}Error parsing XML:\n%1\n\nSelect 'OK' to abandon your changes or 'Cancel' to further edit the XML.{/msg} - {msg meaning="Code.badCode" desc="alert - Message shown if an error occurs while interpreting the user program. The error description follows."}Program error:\n%1{/msg} - {msg meaning="Code.timeout" desc="alert - Message shown if the program has run for more than the permitted number of steps. This exists so that programs with infinite loops do not run forever."}Maximum execution iterations exceeded.{/msg} - {msg meaning="Code.discard" desc="alert - Message shown after the user clicks on the 'discard all' icon. Selecting 'OK' (or the translated equivalent) causes all of the blocks to be discarded. Selecting 'Cancel' prevents blocks from being deleted.\n\nParameters:\n* %1 - number of blocks to be deleted. It is always an integer greater than or equal to 2."}Delete all %1 blocks?{/msg} -
    -{/template} - -/** - * Web page structure. - */ -{template .start} - {call .messages /} + + + + + + Blockly Demo: + + - + + + @@ -148,6 +148,18 @@ + + + + +
    -

    - - {msg meaning="Blockly" desc="IBID"}Blockly{/msg} - {sp}:{sp} - {{msg meaning="Code.title" desc="title - Title of this application, indicating that it is for writing arbitrary programs.\n{lb}{lb}Identical|Code{rb}{rb}"}} - Code - {{/msg}} - +

    Blockly > + Demos > + ...

    @@ -54,7 +30,7 @@ - + @@ -64,13 +40,13 @@ @@ -80,7 +56,6 @@
    {{msg meaning="Code.blocks" desc="tab text - Displays and allows editing of the user's program as blocks.\n{lb}{lb}Identical|Blocks{rb}{rb}"}}Blocks{{/msg}}...   JavaScript    XML - {sp} - + {sp} - +
    - {call .toolbox /}
    @@ -89,16 +64,9 @@
    
       
    
       
    -  {call apps.dialog /}
    -  {call apps.storageDialog /}
    -{/template}
     
    -/**
    - * Toolbox.
    - */
    -{template .toolbox}
       
    -{/template}
    +
    +
    +
    diff --git a/demos/code/msg/ace.js b/demos/code/msg/ace.js
    new file mode 100644
    index 000000000..9a6f2e366
    --- /dev/null
    +++ b/demos/code/msg/ace.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kode",
    +  blocks: "Seuneutheun",
    +  linkTooltip: "Keubah ngon neupawôt keu theun",
    +  runTooltip: "Neupeujak program nyang geupeuteutap le seuneutheun lam ruweuëng keurija",
    +  badCode: "Ralat program\n%1",
    +  timeout: "Eksekusi maksimum ka leupah",
    +  discard: "Sampôh mandum %1 seuneutheun",
    +  trashTooltip: "Boh mandum seuneutheun",
    +  catLogic: "Logis",
    +  catLoops: "Kuwien",
    +  catMath: "Matematik",
    +  catText: "Haraih",
    +  catLists: "Dapeuta",
    +  catColour: "Wareuna",
    +  catVariables: "Meumacam",
    +  catFunctions: "Prosedur",
    +  listVariable: "dapeuta",
    +  textVariable: "haraih",
    +  httpRequestError: "Na masalah lam neumeulakèe",
    +  linkAlert: "Neubagi seuneutheun droëneuh ngon peunawôt nyoë: %1",
    +  hashError: "Meu'ah, '%1' hana saban sakri ngon peuë mantong program nyang meukeubah",
    +  xmlError: "Beureukaih keuneubah droëneuh han jeuët geupasoë. Kadang na neupeugot ngon versi seuneutheun yang la'én",
    +  badXml: "Ralat 'oh geuploh XML\n%1\n\nNeupileh 'OK' keu peulucôt meuandam droëneuh atawa 'Peubateuë' keu neusambông meuandam XML-jih"
    +};
    diff --git a/demos/code/msg/ar.js b/demos/code/msg/ar.js
    new file mode 100644
    index 000000000..bba0f5b60
    --- /dev/null
    +++ b/demos/code/msg/ar.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "كود",
    +  blocks: "البلوكات",
    +  linkTooltip: "احفظ ووصلة إلى البلوكات.",
    +  runTooltip: "شغل البرنامج المعرف بواسطة البلوكات في مساحة العمل.",
    +  badCode: "خطأ في البرنامج:\n %1",
    +  timeout: "تم تجاوز الحد الأقصى لتكرارات التنفيذ .",
    +  discard: "حذف كل بلوكات %1؟",
    +  trashTooltip: "تجاهل كل البلوكات.",
    +  catLogic: "منطق",
    +  catLoops: "الحلقات",
    +  catMath: "رياضيات",
    +  catText: "نص",
    +  catLists: "قوائم",
    +  catColour: "لون",
    +  catVariables: "متغيرات",
    +  catFunctions: "إجراءات",
    +  listVariable: "قائمة",
    +  textVariable: "نص",
    +  httpRequestError: "كانت هناك مشكلة مع هذا الطلب.",
    +  linkAlert: "مشاركة كود بلوكلي الخاص بك مع هذا الرابط:\n %1",
    +  hashError: "عذراً،ال '%1' لا تتوافق مع أي برنامج تم حفظه.",
    +  xmlError: "تعذر تحميل الملف المحفوظة الخاصة بك.  ربما تم إنشاؤه باستخدام إصدار مختلف من بلوكلي؟",
    +  badXml: "خطأ في توزيع ال \"XML\":\n %1\n\nحدد 'موافق' للتخلي عن التغييرات أو 'إلغاء الأمر' لمواصلة تحرير ال\"XML\"."
    +};
    diff --git a/demos/code/msg/be-tarask.js b/demos/code/msg/be-tarask.js
    new file mode 100644
    index 000000000..613ecb542
    --- /dev/null
    +++ b/demos/code/msg/be-tarask.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Код",
    +  blocks: "Блёкі",
    +  linkTooltip: "Захаваць і зьвязаць з блёкамі.",
    +  runTooltip: "Запусьціце праграму, вызначаную блёкамі ў працоўнай вобласьці.",
    +  badCode: "Памылка праграмы:\n%1",
    +  timeout: "Перавышана максымальная колькасьць ітэрацыяў.",
    +  discard: "Выдаліць усе блёкі %1?",
    +  trashTooltip: "Выдаліць усе блёкі.",
    +  catLogic: "Лёгіка",
    +  catLoops: "Петлі",
    +  catMath: "Матэматычныя формулы",
    +  catText: "Тэкст",
    +  catLists: "Сьпісы",
    +  catColour: "Колер",
    +  catVariables: "Зьменныя",
    +  catFunctions: "Функцыі",
    +  listVariable: "сьпіс",
    +  textVariable: "тэкст",
    +  httpRequestError: "Узьнікла праблема з запытам.",
    +  linkAlert: "Падзяліцца Вашым блёкам праз гэтую спасылку:\n\n%1",
    +  hashError: "Прабачце, '%1' не адпавядае ніводнай захаванай праграме.",
    +  xmlError: "Не атрымалася загрузіць захаваны файл. Магчыма, ён быў створаны з іншай вэрсіяй Блёклі?",
    +  badXml: "Памылка сынтаксічнага аналізу XML:\n%1\n\nАбярыце \"ОК\", каб адмовіцца ад зьменаў ці \"Скасаваць\" для далейшага рэдагаваньня XML."
    +};
    diff --git a/demos/code/msg/br.js b/demos/code/msg/br.js
    new file mode 100644
    index 000000000..8cbbeb4b5
    --- /dev/null
    +++ b/demos/code/msg/br.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kod",
    +  blocks: "Bloc'hoù",
    +  linkTooltip: "Enrollañ ha liammañ d'ar bloc'hadoù.",
    +  runTooltip: "Lañsañ ar programm termenet gant ar bloc'hadoù en takad labour.",
    +  badCode: "Fazi programm :\n%1",
    +  timeout: "Tizhet eo bet an niver brasañ a iteradurioù seveniñ aotreet.",
    +  discard: "Diverkañ an holl vloc'hoù %1 ?",
    +  trashTooltip: "Disteurel an holl vloc'hoù.",
    +  catLogic: "Poell",
    +  catLoops: "Boukloù",
    +  catMath: "Matematik",
    +  catText: "Testenn",
    +  catLists: "Rolloù",
    +  catColour: "Liv",
    +  catVariables: "Argemmennoù",
    +  catFunctions: "Arc'hwelioù",
    +  listVariable: "roll",
    +  textVariable: "testenn",
    +  httpRequestError: "Ur gudenn zo gant ar reked.",
    +  linkAlert: "Rannañ ho ploc'hoù gant al liamm-mañ :\n\n%1",
    +  hashError: "Digarezit. \"%1\" ne glot gant programm enrollet ebet.",
    +  xmlError: "Ne c'haller ket kargañ ho restr enrollet. Marteze e oa bet krouet gant ur stumm disheñvel eus Blockly ?",
    +  badXml: "Fazi dielfennañ XML :\n%1\n\nDibabit \"Mat eo\" evit dilezel ar c'hemmoù-se pe \"Nullañ\" evit kemmañ an XML c'hoazh."
    +};
    diff --git a/demos/code/msg/ca.js b/demos/code/msg/ca.js
    new file mode 100644
    index 000000000..33cf9c34d
    --- /dev/null
    +++ b/demos/code/msg/ca.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Codi",
    +  blocks: "Blocs",
    +  linkTooltip: "Desa i enllaça als blocs.",
    +  runTooltip: "Executa el programa definit pels blocs de l'àrea de treball.",
    +  badCode: "Error de programa:\n %1",
    +  timeout: "S'ha superat el nombre màxim d'iteracions d'execució.",
    +  discard: "Esborrar els %1 blocs?",
    +  trashTooltip: "Descarta tots els blocs.",
    +  catLogic: "Lògica",
    +  catLoops: "Bucles",
    +  catMath: "Matemàtiques",
    +  catText: "Text",
    +  catLists: "Llistes",
    +  catColour: "Color",
    +  catVariables: "Variables",
    +  catFunctions: "Procediments",
    +  listVariable: "llista",
    +  textVariable: "text",
    +  httpRequestError: "Hi ha hagut un problema amb la sol·licitud.",
    +  linkAlert: "Comparteix els teus blocs amb aquest enllaç: %1",
    +  hashError: "Ho sentim, '%1' no es correspon amb cap fitxer desat de Blockly.",
    +  xmlError: "No s'ha pogut carregar el teu fitxer desat.  Potser va ser creat amb una versió diferent de Blockly?",
    +  badXml: "Error d'anàlisi XML:\n%1\n\nSeleccioneu 'Acceptar' per abandonar els vostres canvis, o 'Cancel·lar' per continuar editant l'XML."
    +};
    diff --git a/demos/code/msg/cs.js b/demos/code/msg/cs.js
    new file mode 100644
    index 000000000..b1232a632
    --- /dev/null
    +++ b/demos/code/msg/cs.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kód",
    +  blocks: "Bloky",
    +  linkTooltip: "Ulož a spoj bloky..",
    +  runTooltip: "",
    +  badCode: "Chyba programu:\n%1",
    +  timeout: "Maximum execution iterations exceeded.",
    +  discard: "Odstranit všechny bloky %1?",
    +  trashTooltip: "Zahodit všechny bloky.",
    +  catLogic: "Logika",
    +  catLoops: "Smyčky",
    +  catMath: "Matematika",
    +  catText: "Text",
    +  catLists: "Seznamy",
    +  catColour: "Barva",
    +  catVariables: "Proměnné",
    +  catFunctions: "Procedury",
    +  listVariable: "seznam",
    +  textVariable: "text",
    +  httpRequestError: "Došlo k potížím s požadavkem.",
    +  linkAlert: "Sdílej bloky tímto odkazem: \n\n%1",
    +  hashError: "Omlouváme se, '%1' nesouhlasí s žádným z uložených souborů.",
    +  xmlError: "Nepodařilo se uložit vás soubor.  Pravděpodobně byl vytvořen jinou verzí Blockly?",
    +  badXml: "Chyba parsování XML:\n%1\n\nVybrat \"OK\" pro zahození vašich změn nebo 'Cancel' k dalšímu upravování XML."
    +};
    diff --git a/demos/code/msg/da.js b/demos/code/msg/da.js
    new file mode 100644
    index 000000000..7d5cbdf70
    --- /dev/null
    +++ b/demos/code/msg/da.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kode",
    +  blocks: "Blokke",
    +  linkTooltip: "Gem og link til blokke.",
    +  runTooltip: "Kør programmet, der er defineret af blokkene i arbejdsområdet.",
    +  badCode: "Programfejl:\n%1",
    +  timeout: "Maksimale antal udførelsesgentagelser overskredet.",
    +  discard: "Slet alle %1 blokke?",
    +  trashTooltip: "Kassér alle blokke.",
    +  catLogic: "Logik",
    +  catLoops: "Løkker",
    +  catMath: "Matematik",
    +  catText: "Tekst",
    +  catLists: "Lister",
    +  catColour: "Farve",
    +  catVariables: "Variabler",
    +  catFunctions: "Funktioner",
    +  listVariable: "liste",
    +  textVariable: "tekst",
    +  httpRequestError: "Der var et problem med forespørgslen.",
    +  linkAlert: "Del dine blokke med dette link:\n\n%1",
    +  hashError: "Beklager, '%1' passer ikke med nogen gemt Blockly fil.",
    +  xmlError: "Kunne ikke hente din gemte fil.  Måske er den lavet med en anden udgave af Blockly?",
    +  badXml: "Fejl under fortolkningen af XML:\n%1\n\nVælg 'OK' for at opgive dine ændringer eller 'Afbryd' for at redigere XML-filen yderligere."
    +};
    diff --git a/demos/code/msg/de.js b/demos/code/msg/de.js
    new file mode 100644
    index 000000000..2d6562062
    --- /dev/null
    +++ b/demos/code/msg/de.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Bausteine",
    +  linkTooltip: "Speichern und auf Bausteine verlinken.",
    +  runTooltip: "Das Programm ausführen, das von den Bausteinen im Arbeitsbereich definiert ist.",
    +  badCode: "Programmfehler:\n%1",
    +  timeout: "Die maximalen Ausführungswiederholungen wurden überschritten.",
    +  discard: "Alle %1 Bausteine löschen?",
    +  trashTooltip: "Alle Bausteine verwerfen.",
    +  catLogic: "Logik",
    +  catLoops: "Schleifen",
    +  catMath: "Mathematik",
    +  catText: "Text",
    +  catLists: "Listen",
    +  catColour: "Farbe",
    +  catVariables: "Variablen",
    +  catFunctions: "Funktionen",
    +  listVariable: "Liste",
    +  textVariable: "Text",
    +  httpRequestError: "Mit der Anfrage gab es ein Problem.",
    +  linkAlert: "Teile deine Bausteine mit diesem Link:\n\n%1",
    +  hashError: "„%1“ stimmt leider mit keinem gespeicherten Programm überein.",
    +  xmlError: "Deine gespeicherte Datei konnte nicht geladen werden. Vielleicht wurde sie mit einer anderen Version von Blockly erstellt.",
    +  badXml: "Fehler beim Parsen von XML:\n%1\n\nWähle 'OK' zum Verwerfen deiner Änderungen oder 'Abbrechen' zum weiteren Bearbeiten des XML."
    +};
    diff --git a/demos/code/msg/el.js b/demos/code/msg/el.js
    new file mode 100644
    index 000000000..3e128ad5b
    --- /dev/null
    +++ b/demos/code/msg/el.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Κώδικας",
    +  blocks: "Μπλοκ",
    +  linkTooltip: "Αποθηκεύει και συνδέει σε μπλοκ.",
    +  runTooltip: "Εκτελεί το πρόγραμμα που ορίζεται από τα μπλοκ στον χώρο εργασίας.",
    +  badCode: "Σφάλμα προγράμματος:\n%1",
    +  timeout: "Υπέρβαση μέγιστου αριθμού επαναλήψεων.",
    +  discard: "Να διαγραφούν και τα %1 μπλοκ?",
    +  trashTooltip: "Απόρριψη όλων των μπλοκ.",
    +  catLogic: "Λογική",
    +  catLoops: "Επαναλήψεις",
    +  catMath: "Μαθηματικά",
    +  catText: "Κείμενο",
    +  catLists: "Λίστες",
    +  catColour: "Χρώμα",
    +  catVariables: "Μεταβλητές",
    +  catFunctions: "Συναρτήσεις",
    +  listVariable: "λίστα",
    +  textVariable: "κείμενο",
    +  httpRequestError: "Υπήρξε πρόβλημα με το αίτημα.",
    +  linkAlert: "Κοινοποίησε τα μπλοκ σου με αυτόν τον σύνδεσμο:\n\n%1",
    +  hashError: "Λυπάμαι, το «%1» δεν αντιστοιχεί σε κανένα αποθηκευμένο πρόγραμμα.",
    +  xmlError: "Δεν μπορώ να φορτώσω το αποθηκευμένο αρχείο σου.  Μήπως δημιουργήθηκε από μία παλιότερη έκδοση του Blockly;",
    +  badXml: "Σφάλμα ανάλυσης XML:\n%1\n\nΕπίλεξε «Εντάξει» για να εγκαταλείψεις τις αλλαγές σου ή «Ακύρωση» για να επεξεργαστείς το XML κι άλλο."
    +};
    diff --git a/demos/code/msg/en.js b/demos/code/msg/en.js
    new file mode 100644
    index 000000000..8432b75ff
    --- /dev/null
    +++ b/demos/code/msg/en.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Blocks",
    +  linkTooltip: "Save and link to blocks.",
    +  runTooltip: "Run the program defined by the blocks in the workspace.",
    +  badCode: "Program error:\n%1",
    +  timeout: "Maximum execution iterations exceeded.",
    +  discard: "Delete all %1 blocks?",
    +  trashTooltip: "Discard all blocks.",
    +  catLogic: "Logic",
    +  catLoops: "Loops",
    +  catMath: "Math",
    +  catText: "Text",
    +  catLists: "Lists",
    +  catColour: "Colour",
    +  catVariables: "Variables",
    +  catFunctions: "Functions",
    +  listVariable: "list",
    +  textVariable: "text",
    +  httpRequestError: "There was a problem with the request.",
    +  linkAlert: "Share your blocks with this link:\n\n%1",
    +  hashError: "Sorry, '%1' doesn't correspond with any saved program.",
    +  xmlError: "Could not load your saved file. Perhaps it was created with a different version of Blockly?",
    +  badXml: "Error parsing XML:\n%1\n\nSelect 'OK' to abandon your changes or 'Cancel' to further edit the XML."
    +};
    diff --git a/demos/code/msg/es.js b/demos/code/msg/es.js
    new file mode 100644
    index 000000000..8d60c3157
    --- /dev/null
    +++ b/demos/code/msg/es.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Código",
    +  blocks: "Bloques",
    +  linkTooltip: "Guarda conexión a los bloques.",
    +  runTooltip: "Ejecute el programa definido por los bloques en el área de trabajo.",
    +  badCode: "Error del programa:\n%1",
    +  timeout: "Se excedio el máximo de iteraciones ejecutadas permitidas.",
    +  discard: "¿Eliminar todos los bloques %1?",
    +  trashTooltip: "Descartar todos los bloques.",
    +  catLogic: "Lógica",
    +  catLoops: "Secuencias",
    +  catMath: "Matemáticas",
    +  catText: "Texto",
    +  catLists: "Listas",
    +  catColour: "Color",
    +  catVariables: "Variables",
    +  catFunctions: "Funciones",
    +  listVariable: "lista",
    +  textVariable: "texto",
    +  httpRequestError: "Hubo un problema con la petición.",
    +  linkAlert: "Comparte tus bloques con este enlace:\n\n%1",
    +  hashError: "«%1» no corresponde con ningún programa guardado.",
    +  xmlError: "No se pudo cargar el archivo guardado.  ¿Quizá fue creado con otra versión de Blockly?",
    +  badXml: "Error de análisis XML:\n%1\n\nSelecciona OK para abandonar tus cambios o Cancelar para seguir editando el XML."
    +};
    diff --git a/demos/code/msg/fa.js b/demos/code/msg/fa.js
    new file mode 100644
    index 000000000..f604e9fea
    --- /dev/null
    +++ b/demos/code/msg/fa.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "کد",
    +  blocks: "بلوک‌ها",
    +  linkTooltip: "ذخیره و پیوند به بلوک‌ها.",
    +  runTooltip: "اجرای برنامهٔ تعریف‌شده توسط بلوک‌ها در فضای کار.",
    +  badCode: "خطای برنامه:\n%1",
    +  timeout: "حداکثر تکرارهای اجرا رد شده‌است.",
    +  discard: "حذف همهٔ بلاک‌های %1؟",
    +  trashTooltip: "دورریختن همهٔ بلوک‌ها.",
    +  catLogic: "منطق",
    +  catLoops: "حلقه‌ها",
    +  catMath: "ریاضی",
    +  catText: "متن",
    +  catLists: "فهرست‌ها",
    +  catColour: "رنگ",
    +  catVariables: "متغییرها",
    +  catFunctions: "توابع",
    +  listVariable: "فهرست",
    +  textVariable: "متن",
    +  httpRequestError: "مشکلی با درخواست وجود داشت.",
    +  linkAlert: "اشتراک‌گذاری بلاک‌هایتان با این پیوند:\n\n%1",
    +  hashError: "شرمنده، «%1» با هیچ برنامهٔ ذخیره‌شده‌ای تطبیق پیدا نکرد.",
    +  xmlError: "نتوانست پروندهٔ ذخیرهٔ شما بارگیری شود.  احتمالاً با نسخهٔ متفاوتی از بلوکی درست شده‌است؟",
    +  badXml: "خطای تجزیهٔ اکس‌ام‌ال:\n%1\n\n«باشد» را برای ذخیره و «فسخ» را برای ویرایش بیشتر اکس‌ام‌ال انتخاب کنید."
    +};
    diff --git a/demos/code/msg/fr.js b/demos/code/msg/fr.js
    new file mode 100644
    index 000000000..17e91474d
    --- /dev/null
    +++ b/demos/code/msg/fr.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Blocs",
    +  linkTooltip: "Sauvegarder et lier aux blocs.",
    +  runTooltip: "Lancer le programme défini par les blocs dans l’espace de travail.",
    +  badCode: "Erreur du programme :\n%1",
    +  timeout: "Nombre maximum d’itérations d’exécution dépassé.",
    +  discard: "Supprimer tous les %1 blocs ?",
    +  trashTooltip: "Jeter tous les blocs.",
    +  catLogic: "Logique",
    +  catLoops: "Boucles",
    +  catMath: "Math",
    +  catText: "Texte",
    +  catLists: "Listes",
    +  catColour: "Couleur",
    +  catVariables: "Variables",
    +  catFunctions: "Fonctions",
    +  listVariable: "liste",
    +  textVariable: "texte",
    +  httpRequestError: "Il y a eu un problème avec la demande.",
    +  linkAlert: "Partagez vos blocs grâce à ce lien:\n\n%1",
    +  hashError: "Désolé, '%1' ne correspond à aucun programme sauvegardé.",
    +  xmlError: "Impossible de charger le fichier de sauvegarde.  Peut être a t-il été créé avec une autre version de Blockly?",
    +  badXml: "Erreur d’analyse du XML :\n%1\n\nSélectionner 'OK' pour abandonner vos modifications ou 'Annuler' pour continuer à modifier le XML."
    +};
    diff --git a/demos/code/msg/gl.js b/demos/code/msg/gl.js
    new file mode 100644
    index 000000000..acfe428a4
    --- /dev/null
    +++ b/demos/code/msg/gl.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Código",
    +  blocks: "Bloques",
    +  linkTooltip: "Gardar e crear unha ligazón aos bloques.",
    +  runTooltip: "Executar o programa definido polos bloques no espazo de traballo.",
    +  badCode: "Erro do programa:\n%1",
    +  timeout: "Superouse o número máximo de iteracións durante a execución.",
    +  discard: "Queres borrar os %1 bloques?",
    +  trashTooltip: "Descartar todos os bloques.",
    +  catLogic: "Lóxica",
    +  catLoops: "Bucles",
    +  catMath: "Matemáticas",
    +  catText: "Texto",
    +  catLists: "Listas",
    +  catColour: "Cor",
    +  catVariables: "Variables",
    +  catFunctions: "Funcións",
    +  listVariable: "lista",
    +  textVariable: "texto",
    +  httpRequestError: "Houbo un problema coa solicitude.",
    +  linkAlert: "Comparte os teus bloques con esta ligazón:\n\n%1",
    +  hashError: "Sentímolo, \"%1\" non se corresponde con ningún programa gardado.",
    +  xmlError: "Non se puido cargar o ficheiro gardado. Se cadra, foi creado cunha versión diferente de Blockly.",
    +  badXml: "Erro de análise do XML:\n%1\n\nSelecciona \"Aceptar\" se queres anular os cambios ou \"Cancelar\" para seguir editando o XML."
    +};
    diff --git a/demos/code/msg/he.js b/demos/code/msg/he.js
    new file mode 100644
    index 000000000..d11982c41
    --- /dev/null
    +++ b/demos/code/msg/he.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "קוד",
    +  blocks: "קטעי קוד",
    +  linkTooltip: "שמירה וקישור לקטעי קוד.",
    +  runTooltip: "הרצת התכנית שהוגדרה על ידי קטעי הקוד שבמרחב העבודה.",
    +  badCode: "שגיאה בתכנית: %1",
    +  timeout: "חריגה ממספר פעולות חוזרות אפשריות.",
    +  discard: "האם למחוק את כל %1 קטעי הקוד?",
    +  trashTooltip: "השלך את כל קטעי הקוד.",
    +  catLogic: "לוגיקה",
    +  catLoops: "לולאות",
    +  catMath: "מתמטיקה",
    +  catText: "טקסט",
    +  catLists: "רשימות",
    +  catColour: "צבע",
    +  catVariables: "משתנים",
    +  catFunctions: "פונקציות",
    +  listVariable: "רשימה",
    +  textVariable: "טקסט",
    +  httpRequestError: "הבקשה נכשלה.",
    +  linkAlert: "ניתן לשתף את קטעי הקוד שלך באמצעות קישור זה:\n\n%1",
    +  hashError: "לצערנו, '%1' איננו מתאים לאף אחת מהתוכניות השמורות",
    +  xmlError: "נסיון הטעינה של הקובץ השמור שלך נכשל. האם ייתכן שהוא נוצר בגרסא שונה של בלוקלי?",
    +  badXml: "תקלה בפענוח XML:\n\n%1\n\nנא לבחור 'אישור' כדי לנטוש את השינויים שלך או 'ביטול' כדי להמשיך ולערוך את ה־XML."
    +};
    diff --git a/demos/code/msg/hrx.js b/demos/code/msg/hrx.js
    new file mode 100644
    index 000000000..11f790c27
    --- /dev/null
    +++ b/demos/code/msg/hrx.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Bausten",
    +  linkTooltip: "Speichre und auf Bausten verlinke.",
    +  runTooltip: "Das Programm ausfüahre, das von den Bausten im Oorweitsbereich definiert ist.",
    +  badCode: "Programmfehler:\n%1",
    +  timeout: "Die maximale Ausführungswiederholunge woore üwerschritt.",
    +  discard: "All %1 Bausten lösche?",
    +  trashTooltip: "All Bausten verwerfe.",
    +  catLogic: "Logik",
    +  catLoops: "Schleife",
    +  catMath: "Mathematik",
    +  catText: "Text",
    +  catLists: "Liste",
    +  catColour: "Farreb",
    +  catVariables: "Variable",
    +  catFunctions: "Funktione",
    +  listVariable: "List",
    +  textVariable: "Text",
    +  httpRequestError: "Mit der Oonfroch hots en Problem geb.",
    +  linkAlert: "Tel von dein Bausten mit dem Link:\n\n%1",
    +  hashError: "„%1“ stimmt leider mit kenem üweren gespeicherte Programm.",
    +  xmlError: "Dein gespeicherte Datei könnt net gelood sin. Vielleicht woard se mit ener annre Version von Blockly erstellt.",
    +  badXml: "Fehler beim Parse von XML:\n%1\n\nWähle 'OK' zum Verwerfe von deiner Ändrunge orrer 'Abbreche' zum XML weiter beoorbeite."
    +};
    diff --git a/demos/code/msg/hu.js b/demos/code/msg/hu.js
    new file mode 100644
    index 000000000..a2f2c5081
    --- /dev/null
    +++ b/demos/code/msg/hu.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kódszerkesztő",
    +  blocks: "Blokkok",
    +  linkTooltip: "Hivatkozás létrehozása",
    +  runTooltip: "Program futtatása.",
    +  badCode: "Program hiba:\n%1",
    +  timeout: "A program elérte a maximális végrehajtási időt.",
    +  discard: "Az összes %1 blokk törlése?",
    +  trashTooltip: "Összes blokk törlése.",
    +  catLogic: "Logikai műveletek",
    +  catLoops: "Ciklusok",
    +  catMath: "Matematikai műveletek",
    +  catText: "Sztring műveletek",
    +  catLists: "Listakezelés",
    +  catColour: "Színek",
    +  catVariables: "Változók",
    +  catFunctions: "Eljárások",
    +  listVariable: "lista",
    +  textVariable: "szöveg",
    +  httpRequestError: "A kéréssel kapcsolatban probléma merült fel.",
    +  linkAlert: "Ezzel a hivatkozással tudod megosztani a programodat:\n\n%1",
    +  hashError: "Sajnos a '%1' hivatkozás nem tartozik egyetlen programhoz sem.",
    +  xmlError: "A programodat nem lehet betölteni.  Elképzelhető, hogy a Blockly egy másik verziójában készült?",
    +  badXml: "Hiba az XML feldolgozásakor:\n%1\n\nVáltozások elvetése?"
    +};
    diff --git a/demos/code/msg/ia.js b/demos/code/msg/ia.js
    new file mode 100644
    index 000000000..a5557c221
    --- /dev/null
    +++ b/demos/code/msg/ia.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Codice",
    +  blocks: "Blocos",
    +  linkTooltip: "Salveguardar e ligar a blocos.",
    +  runTooltip: "Executar le programma definite per le blocos in le spatio de travalio.",
    +  badCode: "Error del programma:\n%1",
    +  timeout: "Le numero de iterationes executate ha excedite le maximo.",
    +  discard: "Deler tote le %1 blocos?",
    +  trashTooltip: "Abandonar tote le blocos.",
    +  catLogic: "Logica",
    +  catLoops: "Buclas",
    +  catMath: "Mathematica",
    +  catText: "Texto",
    +  catLists: "Listas",
    +  catColour: "Color",
    +  catVariables: "Variabiles",
    +  catFunctions: "Functiones",
    +  listVariable: "lista",
    +  textVariable: "texto",
    +  httpRequestError: "Il habeva un problema con le requesta.",
    +  linkAlert: "Divide tu blocos con iste ligamine:\n\n%1",
    +  hashError: "Infelicemente, '%1' non corresponde a alcun programma salveguardate.",
    +  xmlError: "Impossibile cargar le file salveguardate. Pote esser que illo ha essite create con un altere version de Blockly?",
    +  badXml: "Error de analyse del XML:\n%1\n\nSelige 'OK' pro abandonar le modificationes o 'Cancellar' pro continuar a modificar le codice XML."
    +};
    diff --git a/demos/code/msg/is.js b/demos/code/msg/is.js
    new file mode 100644
    index 000000000..b1035b159
    --- /dev/null
    +++ b/demos/code/msg/is.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kóði",
    +  blocks: "Kubbar",
    +  linkTooltip: "Vista og tengja við kubba.",
    +  runTooltip: "Keyra forritið sem kubbarnir á vinnusvæðinu mynda.",
    +  badCode: "Villa í forriti:\n%1",
    +  timeout: "Forritið hefur endurtekið sig of oft.",
    +  discard: "Eyða öllum %1 kubbunum?",
    +  trashTooltip: "Fleygja öllum kubbum.",
    +  catLogic: "Rökvísi",
    +  catLoops: "Lykkjur",
    +  catMath: "Reikningur",
    +  catText: "Texti",
    +  catLists: "Listar",
    +  catColour: "Litir",
    +  catVariables: "Breytur",
    +  catFunctions: "Stefjur",
    +  listVariable: "listi",
    +  textVariable: "texti",
    +  httpRequestError: "Það kom upp vandamál með beiðnina.",
    +  linkAlert: "Deildu kubbunum þínum með þessari krækju:",
    +  hashError: "Því miður, '%1' passar ekki við neitt vistað forrit.",
    +  xmlError: "Gat ekki hlaðið vistuðu skrána þína. Var hún kannske búin til í annarri útgáfu af Blockly?",
    +  badXml: "Villa við úrvinnslu XML:\n%1\n\nVeldu 'Í lagi' til að sleppa breytingum eða 'Hætta við' til að halda áfram með XML."
    +};
    diff --git a/demos/code/msg/it.js b/demos/code/msg/it.js
    new file mode 100644
    index 000000000..6fba6493e
    --- /dev/null
    +++ b/demos/code/msg/it.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Codice",
    +  blocks: "Blocchi",
    +  linkTooltip: "Salva e collega ai blocchi.",
    +  runTooltip: "Esegui il programma definito dai blocchi nell'area di lavoro.",
    +  badCode: "Errore programma:\n%1",
    +  timeout: "È stato superato il numero massimo consentito di interazioni eseguite.",
    +  discard: "Cancellare tutti i %1 blocchi?",
    +  trashTooltip: "Elimina tutti i blocchi.",
    +  catLogic: "Logica",
    +  catLoops: "Cicli",
    +  catMath: "Matematica",
    +  catText: "Testo",
    +  catLists: "Elenchi",
    +  catColour: "Colore",
    +  catVariables: "Variabili",
    +  catFunctions: "Funzioni",
    +  listVariable: "elenco",
    +  textVariable: "testo",
    +  httpRequestError: "La richiesta non è stata soddisfatta.",
    +  linkAlert: "Condividi i tuoi blocchi con questo collegamento:\n\n%1",
    +  hashError: "Mi spiace, '%1' non corrisponde ad alcun programma salvato.",
    +  xmlError: "Non è stato possibile caricare il documento.  Forse è stato creato con una versione diversa di Blockly?",
    +  badXml: "Errore durante l'analisi XML:\n%1\n\nSeleziona 'OK' per abbandonare le modifiche o 'Annulla' per continuare a modificare l'XML."
    +};
    diff --git a/demos/code/msg/ja.js b/demos/code/msg/ja.js
    new file mode 100644
    index 000000000..9ff356ccd
    --- /dev/null
    +++ b/demos/code/msg/ja.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "コード",
    +  blocks: "ブロック",
    +  linkTooltip: "ブロックの状態を保存してリンクを取得します。",
    +  runTooltip: "ブロックで作成したプログラムを実行します。",
    +  badCode: "プログラムのエラー:\n%1",
    +  timeout: "命令の実行回数が制限値を超えました。",
    +  discard: "%1 個すべてのブロックを消しますか?",
    +  trashTooltip: "すべてのブロックを消します。",
    +  catLogic: "論理",
    +  catLoops: "繰り返し",
    +  catMath: "数学",
    +  catText: "テキスト",
    +  catLists: "リスト",
    +  catColour: "色",
    +  catVariables: "変数",
    +  catFunctions: "関数",
    +  listVariable: "リスト",
    +  textVariable: "テキスト",
    +  httpRequestError: "ネットワーク接続のエラーです。",
    +  linkAlert: "ブロックの状態をこのリンクで共有できます:\n\n%1",
    +  hashError: "すみません。「%1」という名前のプログラムは保存されていません。",
    +  xmlError: "保存されたファイルを読み込めませんでした。別のバージョンのブロックリーで作成された可能性があります。",
    +  badXml: "XML のエラーです:\n%1\n\nXML の変更をやめるには「OK」、編集を続けるには「キャンセル」を選んでください。"
    +};
    diff --git a/demos/code/msg/ko.js b/demos/code/msg/ko.js
    new file mode 100644
    index 000000000..24edd7d69
    --- /dev/null
    +++ b/demos/code/msg/ko.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "코드",
    +  blocks: "블록",
    +  linkTooltip: "블록을 저장하고 링크를 가져옵니다.",
    +  runTooltip: "작업 공간에서 블록으로 정의된 프로그램을 실행합니다.",
    +  badCode: "프로그램 오류:\n%1",
    +  timeout: "최대 실행 반복을 초과했습니다.",
    +  discard: "모든 블록 %1개를 삭제하겠습니까?",
    +  trashTooltip: "모든 블록을 버립니다.",
    +  catLogic: "논리",
    +  catLoops: "반복",
    +  catMath: "수학",
    +  catText: "텍스트",
    +  catLists: "목록",
    +  catColour: "색",
    +  catVariables: "변수",
    +  catFunctions: "기능",
    +  listVariable: "목록",
    +  textVariable: "텍스트",
    +  httpRequestError: "요청에 문제가 있습니다.",
    +  linkAlert: "다음 링크로 블록을 공유하세요:\n\n%1",
    +  hashError: "죄송하지만 '%1'은 어떤 저장된 프로그램으로 일치하지 않습니다.",
    +  xmlError: "저장된 파일을 불러올 수 없습니다. 혹시 블록리의 다른 버전으로 만들었습니까?",
    +  badXml: "XML 구문 분석 오류:\n%1\n\n바뀜을 포기하려면 '확인'을 선택하고 XML을 더 편집하려면 '취소'를 선택하세요."
    +};
    diff --git a/demos/code/msg/lv.js b/demos/code/msg/lv.js
    new file mode 100644
    index 000000000..40143506d
    --- /dev/null
    +++ b/demos/code/msg/lv.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Pirmkods",
    +  blocks: "Bloki",
    +  linkTooltip: "Saglabāt un piesaistīt blokiem.",
    +  runTooltip: "Palaidiet programmu, ko definē bloki darbvietā.",
    +  badCode: "Programmas kļūda:\n %1",
    +  timeout: "Pārsniegts maksimālais iterāciju skaits.",
    +  discard: "Vai izdzēst visus %1 blokus?",
    +  trashTooltip: "Izmest visus blokus.",
    +  catLogic: "Loģika",
    +  catLoops: "Cikli",
    +  catMath: "Matemātika",
    +  catText: "Teksts",
    +  catLists: "Saraksti",
    +  catColour: "Krāsa",
    +  catVariables: "Mainīgie",
    +  catFunctions: "Procedūras",
    +  listVariable: "saraksts",
    +  textVariable: "teksts",
    +  httpRequestError: "Pieprasījuma kļūda.",
    +  linkAlert: "Dalies ar saviem blokiem ar šo saiti:\n\n%1",
    +  hashError: "Atvainojiet, bet '%1' neatbilst nevienai no saglabātajām programmām.",
    +  xmlError: "Nevaru ielādēt tavu saglabāto failu.  Iespējams, tas tika izveidots ar citu Blockly versiju?",
    +  badXml: "XML parsēšanas kļūda:\n %1\n\nIzvēlieties 'Labi', lai zaudētu savas izmaiņas vai 'Atcelt', lai rediģētu XML."
    +};
    diff --git a/demos/code/msg/mg.js b/demos/code/msg/mg.js
    new file mode 100644
    index 000000000..949793e59
    --- /dev/null
    +++ b/demos/code/msg/mg.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kaody",
    +  blocks: "Bolongana",
    +  linkTooltip: "Hitahiry ary hampirohy amin'ny bolongana.",
    +  runTooltip: "Handefa ny fandaharana voafaritry ny bolongana ao amin'ny erana iasana.",
    +  badCode: "Hadisoam-pandaharana:\n%1",
    +  timeout: "Tafahoatra ny isa ambony indrindra ny isan'ny fiverimberenana.",
    +  discard: "Hamafa ny bolongana %1?",
    +  trashTooltip: "Hanary ny bolongana rehetra.",
    +  catLogic: "Lôjika",
    +  catLoops: "Tondro mifolaka",
    +  catMath: "Matematika",
    +  catText: "Soratra",
    +  catLists: "Lisitra",
    +  catColour: "Loko",
    +  catVariables: "Ova",
    +  catFunctions: "Paika",
    +  listVariable: "lisitra",
    +  textVariable: "soratra",
    +  httpRequestError: "Nisy olana tamin'ilay hataka.",
    +  linkAlert: "Zarao amin'ity rohy ity ny bolonganao: \n\n%1",
    +  hashError: "Miala tsiny, tsy miady amin'ny fandaharana notehirizina '%1'.",
    +  xmlError: "Tsy nahasokatra ny rakitra voatahirinao. Mety namboarina tamin'ny versionan'i Blockly hafa angamba ilay izy?",
    +  badXml: "Hadisoana tam-pamakiana ny XML:\n%1\n\nSafidio 'OK' raha hamoy ny fiovana, na 'Aoka ihany' raha mbola hitoy hanova ny XML."
    +};
    diff --git a/demos/code/msg/mk.js b/demos/code/msg/mk.js
    new file mode 100644
    index 000000000..f1c58afb6
    --- /dev/null
    +++ b/demos/code/msg/mk.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Код",
    +  blocks: "Блокчиња",
    +  linkTooltip: "Зачувај и стави врска до блокчињата.",
    +  runTooltip: "Пушти го програмот определен од блокчињата во работниот простор.",
    +  badCode: "Грешка во програмот:\n%1",
    +  timeout: "Го надминавте допуштениот број на повторувања во извршувањето.",
    +  discard: "Да ги избришам сите %1 блокчиња?",
    +  trashTooltip: "Отстрани ги сите блокчиња.",
    +  catLogic: "Логика",
    +  catLoops: "Јамки",
    +  catMath: "Математика",
    +  catText: "Текст",
    +  catLists: "Списоци",
    +  catColour: "Боја",
    +  catVariables: "Променливи",
    +  catFunctions: "Функции",
    +  listVariable: "список",
    +  textVariable: "текст",
    +  httpRequestError: "Се појави проблем во барањето.",
    +  linkAlert: "Споделете ги вашите блокчиња со оваа врска:\n\n%1",
    +  hashError: "„%1“ не одговара на ниеден зачуван програм.",
    +  xmlError: "Не можев да ја вчитам зачуваната податотека. Да не сте ја создале со друга верзија на Blockly?",
    +  badXml: "Грешка при расчленувањето на XML:\n%1\n\nСтиснете на „ОК“ за да ги напуштите промените или на „Откажи“ ако сакате уште да ја уредувате XML-податотеката."
    +};
    diff --git a/demos/code/msg/ms.js b/demos/code/msg/ms.js
    new file mode 100644
    index 000000000..f08c1caf2
    --- /dev/null
    +++ b/demos/code/msg/ms.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kod",
    +  blocks: "Blok",
    +  linkTooltip: "Simpan dan pautkan kepada blok.",
    +  runTooltip: "Jalankan aturcara yang ditetapkan oleh blok-blok di dalam ruang kerja.",
    +  badCode: "Ralat atur cara:\n%1",
    +  timeout: "Takat maksimum lelaran pelaksanaan dicecah.",
    +  discard: "Hapuskan kesemua %1 blok?",
    +  trashTooltip: "Buang semua blok.",
    +  catLogic: "Logik",
    +  catLoops: "Gelung",
    +  catMath: "Matematik",
    +  catText: "Teks",
    +  catLists: "Senarai",
    +  catColour: "Warna",
    +  catVariables: "Pemboleh ubah",
    +  catFunctions: "Fungsi",
    +  listVariable: "senarai",
    +  textVariable: "teks",
    +  httpRequestError: "Permintaan itu terdapat masalah.",
    +  linkAlert: "Kongsikan blok-blok anda dengan pautan ini:\n\n%1",
    +  hashError: "Maaf, '%1' tidak berpadanan dengan sebarang aturcara yang disimpan.",
    +  xmlError: "Fail simpanan anda tidak dapat dimuatkan. Jangan-jangan ia dicipta dengan versi Blockly yang berlainan?",
    +  badXml: "Ralat ketika menghuraian XML:\n%1\n\nPilih 'OK' untuk melucutkan suntingan anda atau 'Batal' untuk bersambung menyunting XML-nya."
    +};
    diff --git a/demos/code/msg/nb.js b/demos/code/msg/nb.js
    new file mode 100644
    index 000000000..409fe08b8
    --- /dev/null
    +++ b/demos/code/msg/nb.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kode",
    +  blocks: "Blokker",
    +  linkTooltip: "Lagre og lenke til blokker.",
    +  runTooltip: "Kjør programmet definert av blokken i arbeidsområdet.",
    +  badCode: "Programfeil:\n%1",
    +  timeout: "Det maksimale antallet utførte looper er oversteget.",
    +  discard: "Slett alle %1 blokker?",
    +  trashTooltip: "Fjern alle blokker",
    +  catLogic: "Logikk",
    +  catLoops: "Looper",
    +  catMath: "Matte",
    +  catText: "Tekst",
    +  catLists: "Lister",
    +  catColour: "Farge",
    +  catVariables: "Variabler",
    +  catFunctions: "Funksjoner",
    +  listVariable: "Liste",
    +  textVariable: "Tekst",
    +  httpRequestError: "Det oppsto et problem med forespørselen din",
    +  linkAlert: "Del dine blokker med denne lenken:\n\n%1",
    +  hashError: "Beklager, '%1' samsvarer ikke med noe lagret program.",
    +  xmlError: "Kunne ikke laste inn filen. Kanskje den ble laget med en annen versjon av Blockly?",
    +  badXml: "Feil ved parsering av XML:\n%1\n\nVelg 'OK' for å avbryte endringene eller 'Cancel' for å fortsette å redigere XML-koden."
    +};
    diff --git a/demos/code/msg/nl.js b/demos/code/msg/nl.js
    new file mode 100644
    index 000000000..c9c394c9f
    --- /dev/null
    +++ b/demos/code/msg/nl.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Blokken",
    +  linkTooltip: "Opslaan en koppelen naar blokken.",
    +  runTooltip: "Voer het programma uit dat met de blokken in de werkruimte is gemaakt.",
    +  badCode: "Programmafout:\n%1",
    +  timeout: "Het maximale aantal iteraties is overschreden.",
    +  discard: "Alle %1 blokken verwijderen?",
    +  trashTooltip: "Alle blokken verwijderen",
    +  catLogic: "Logica",
    +  catLoops: "Lussen",
    +  catMath: "Formules",
    +  catText: "Tekst",
    +  catLists: "Lijsten",
    +  catColour: "Kleur",
    +  catVariables: "Variabelen",
    +  catFunctions: "Functies",
    +  listVariable: "lijst",
    +  textVariable: "tekst",
    +  httpRequestError: "Er is een probleem opgetreden tijdens het verwerken van het verzoek.",
    +  linkAlert: "Deel uw blokken via deze koppeling:\n\n%1",
    +  hashError: "\"%1\" komt helaas niet overeen met een opgeslagen bestand.",
    +  xmlError: "Uw opgeslagen bestand kan niet geladen worden. Is het misschien gemaakt met een andere versie van Blockly?",
    +  badXml: "Fout tijdens het verwerken van de XML:\n%1\n\nSelecteer \"OK\" om uw wijzigingen te negeren of \"Annuleren\" om de XML verder te bewerken."
    +};
    diff --git a/demos/code/msg/oc.js b/demos/code/msg/oc.js
    new file mode 100644
    index 000000000..29d29d9ad
    --- /dev/null
    +++ b/demos/code/msg/oc.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Còde",
    +  blocks: "Blòts",
    +  linkTooltip: "Salva e liga als blòts.",
    +  runTooltip: "Aviar lo programa definit pels blòts dins l’espaci de trabalh.",
    +  badCode: "Error del programa :\n%1",
    +  timeout: "Nombre maximum d’iteracions d’execucion depassat.",
    +  discard: "Suprimir totes los %1 blòts ?",
    +  trashTooltip: "Getar totes los blòts.",
    +  catLogic: "Logic",
    +  catLoops: "Boclas",
    +  catMath: "Math",
    +  catText: "Tèxte",
    +  catLists: "Listas",
    +  catColour: "Color",
    +  catVariables: "Variablas",
    +  catFunctions: "Foncions",
    +  listVariable: "lista",
    +  textVariable: "tèxte",
    +  httpRequestError: "I a agut un problèma amb la demanda.",
    +  linkAlert: "Partejatz vòstres blòts gràcia a aqueste ligam :\n\n%1",
    +  hashError: "O planhèm, '%1' correspond pas a un fichièr Blockly salvament.",
    +  xmlError: "Impossible de cargar lo fichièr de salvament.  Benlèu qu'es estat creat amb una autra version de Blockly ?",
    +  badXml: "Error d’analisi del XML :\n%1\n\nSeleccionar 'D'acòrdi' per abandonar vòstras modificacions o 'Anullar' per modificar encara lo XML."
    +};
    diff --git a/demos/code/msg/pl.js b/demos/code/msg/pl.js
    new file mode 100644
    index 000000000..c8ca562f3
    --- /dev/null
    +++ b/demos/code/msg/pl.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kod",
    +  blocks: "Bloki",
    +  linkTooltip: "Zapisz i podlinkuj do bloków",
    +  runTooltip: "Uruchom program zdefinowany przez bloki w obszarze roboczym",
    +  badCode: "Błąd programu:\n%1",
    +  timeout: "Maksymalna liczba iteracji wykonywań przekroczona",
    +  discard: "Usunąć wszystkie %1 bloki?",
    +  trashTooltip: "Odrzuć wszystkie bloki.",
    +  catLogic: "Logika",
    +  catLoops: "Pętle",
    +  catMath: "Matematyka",
    +  catText: "Tekst",
    +  catLists: "Listy",
    +  catColour: "Kolor",
    +  catVariables: "Zmienne",
    +  catFunctions: "Funkcje",
    +  listVariable: "lista",
    +  textVariable: "tekst",
    +  httpRequestError: "Wystąpił problem z żądaniem.",
    +  linkAlert: "Udpostępnij swoje bloki korzystając z poniższego linku : \n\n\n%1",
    +  hashError: "Przepraszamy, \"%1\" nie odpowiada żadnemu zapisanemu programowi.",
    +  xmlError: "Nie można załadować zapisanego pliku. Być może został utworzony za pomocą innej wersji Blockly?",
    +  badXml: "Błąd parsowania XML : \n%1\n\nZaznacz 'OK' aby odrzucić twoje zmiany lub 'Cancel', żeby w przyszłości edytować XML."
    +};
    diff --git a/demos/code/msg/pms.js b/demos/code/msg/pms.js
    new file mode 100644
    index 000000000..27edbc879
    --- /dev/null
    +++ b/demos/code/msg/pms.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Còdes",
    +  blocks: "Blòch",
    +  linkTooltip: "Argistré e lijé ai blòch.",
    +  runTooltip: "Fé andé ël programa definì dai blòch ant lë spassi ëd travaj.",
    +  badCode: "Eror dël programa:\n%1",
    +  timeout: "Nùmer màssim d'arpetission d'esecussion sorpassà.",
    +  discard: "Scancelé tuti ij %1 blòch?",
    +  trashTooltip: "Scarté tuti ij blòch.",
    +  catLogic: "Lògica",
    +  catLoops: "Liasse",
    +  catMath: "Matemàtica",
    +  catText: "Test",
    +  catLists: "Liste",
    +  catColour: "Color",
    +  catVariables: "Variàbij",
    +  catFunctions: "Fonsion",
    +  listVariable: "lista",
    +  textVariable: "test",
    +  httpRequestError: "A-i é staje un problema con l'arcesta.",
    +  linkAlert: "Ch'a partagia ij sò blòch grassie a sta liura: %1",
    +  hashError: "An dëspias, '%1 a corëspond a gnun programa salvà.",
    +  xmlError: "A l'é nen podusse carié so archivi salvà. Miraco a l'é stàit creà con na version diferenta ëd Blockly?",
    +  badXml: "Eror d'anàlisi dl'XML:\n%1\n\nSelessioné 'Va bin' për lassé perde toe modìfiche o 'Anulé' për modifiché ancora l'XML."
    +};
    diff --git a/demos/code/msg/pt-br.js b/demos/code/msg/pt-br.js
    new file mode 100644
    index 000000000..470761735
    --- /dev/null
    +++ b/demos/code/msg/pt-br.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Código",
    +  blocks: "Blocos",
    +  linkTooltip: "Salvar e ligar aos blocos.",
    +  runTooltip: "Execute o programa definido pelos blocos na área de trabalho.",
    +  badCode: "Erro no programa:\n%1",
    +  timeout: "Máximo de iterações de execução excedido.",
    +  discard: "Apagar todos os %1 blocos?",
    +  trashTooltip: "Descartar todos os blocos.",
    +  catLogic: "Lógica",
    +  catLoops: "Laços",
    +  catMath: "Matemática",
    +  catText: "Texto",
    +  catLists: "Listas",
    +  catColour: "Cor",
    +  catVariables: "Variáveis",
    +  catFunctions: "Funções",
    +  listVariable: "lista",
    +  textVariable: "texto",
    +  httpRequestError: "Houve um problema com a requisição.",
    +  linkAlert: "Compartilhe seus blocos com este link:\n\n%1",
    +  hashError: "Desculpe, '%1' não corresponde a um programa salvo.",
    +  xmlError: "Não foi possível carregar seu arquivo salvo. Talvez ele tenha sido criado com uma versão diferente do Blockly?",
    +  badXml: "Erro de análise XML:\n%1\n\nSelecione 'OK' para abandonar suas mudanças ou 'Cancelar' para editar o XML."
    +};
    diff --git a/demos/code/msg/ro.js b/demos/code/msg/ro.js
    new file mode 100644
    index 000000000..7ffe7b470
    --- /dev/null
    +++ b/demos/code/msg/ro.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Cod",
    +  blocks: "Blocuri",
    +  linkTooltip: "Salvează și adaugă la blocuri.",
    +  runTooltip: "Execută programul definit de către blocuri în spațiul de lucru.",
    +  badCode: "Eroare de program:\n%1",
    +  timeout: "Numărul maxim de iterații a fost depășit.",
    +  discard: "Ștergi toate cele %1 (de) blocuri?",
    +  trashTooltip: "Șterge toate blocurile.",
    +  catLogic: "Logic",
    +  catLoops: "Bucle",
    +  catMath: "Matematică",
    +  catText: "Text",
    +  catLists: "Liste",
    +  catColour: "Culoare",
    +  catVariables: "Variabile",
    +  catFunctions: "Funcții",
    +  listVariable: "listă",
    +  textVariable: "text",
    +  httpRequestError: "A apărut o problemă la solicitare.",
    +  linkAlert: "Distribuie-ți blocurile folosind această legătură:\n\n%1",
    +  hashError: "Scuze, „%1” nu corespunde nici unui program salvat.",
    +  xmlError: "Sistemul nu a putut încărca fișierul salvat. Poate că a fost creat cu o altă versiune de Blockly?",
    +  badXml: "Eroare de parsare XML:\n%1\n\nAlege „OK” pentru a renunța la modificările efectuate sau „Revocare” pentru a modifica în continuare fișierul XML."
    +};
    diff --git a/demos/code/msg/ru.js b/demos/code/msg/ru.js
    new file mode 100644
    index 000000000..0d972687f
    --- /dev/null
    +++ b/demos/code/msg/ru.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Код",
    +  blocks: "Блоки",
    +  linkTooltip: "Сохранить и показать ссылку на блоки.",
    +  runTooltip: "Запустить программу, заданную блоками в рабочей области.",
    +  badCode: "Ошибка программы:\n%1",
    +  timeout: "Превышено максимальное количество итераций.",
    +  discard: "Удалить все блоки (%1)?",
    +  trashTooltip: "Удалить все блоки.",
    +  catLogic: "Логические",
    +  catLoops: "Циклы",
    +  catMath: "Математика",
    +  catText: "Текст",
    +  catLists: "Списки",
    +  catColour: "Цвет",
    +  catVariables: "Переменные",
    +  catFunctions: "Функции",
    +  listVariable: "список",
    +  textVariable: "текст",
    +  httpRequestError: "Произошла проблема при запросе.",
    +  linkAlert: "Поделитесь своими блоками по этой ссылке:\n\n%1",
    +  hashError: "К сожалению, «%1» не соответствует ни одному сохраненному файлу Блокли.",
    +  xmlError: "Не удалось загрузить ваш сохраненный файл.  Возможно, он был создан в другой версии Блокли?",
    +  badXml: "Ошибка синтаксического анализа XML:\n%1\n\nВыберите 'ОК', чтобы отказаться от изменений или 'Cancel' для дальнейшего редактирования XML."
    +};
    diff --git a/demos/code/msg/sc.js b/demos/code/msg/sc.js
    new file mode 100644
    index 000000000..f0015a82a
    --- /dev/null
    +++ b/demos/code/msg/sc.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Còdixi",
    +  blocks: "Brocus",
    +  linkTooltip: "Sarva e alliòngia a is brocus.",
    +  runTooltip: "Arròllia su programa cumpostu de is brocus in s'àrea de traballu.",
    +  badCode: "Errori in su Programa:\n%1",
    +  timeout: "Giai lòmpius a su màssimu numeru de repicus.",
    +  discard: "Scancellu su %1 de is brocus?",
    +  trashTooltip: "Boganci totu is brocus.",
    +  catLogic: "Lògica",
    +  catLoops: "Lòrigas",
    +  catMath: "Matemàtica",
    +  catText: "Testu",
    +  catLists: "Lista",
    +  catColour: "Colori",
    +  catVariables: "Variabilis",
    +  catFunctions: "Funtzionis",
    +  listVariable: "lista",
    +  textVariable: "testu",
    +  httpRequestError: "Ddui fut unu problema cun sa pregunta",
    +  linkAlert: "Poni is brocus tuus in custu acàpiu:\n\n%1",
    +  hashError: "Mi dispraxit, '%1' non torrat a pari cun nimancu unu de is programas sarvaus.",
    +  xmlError: "Non potzu carrigai su file sarvau. Fortzis est stètiu fatu cun d-una versioni diferenti de Blockly?",
    +  badXml: "Errori in s'anàlisi XML:\n%1\n\nCraca 'OK' po perdi is mudàntzias 'Anudda' po sighì a scriri su XML."
    +};
    diff --git a/demos/code/msg/sco.js b/demos/code/msg/sco.js
    new file mode 100644
    index 000000000..161513937
    --- /dev/null
    +++ b/demos/code/msg/sco.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Code",
    +  blocks: "Blocks",
    +  linkTooltip: "Hain n airt til blocks.",
    +  runTooltip: "Rin the program defined bi the blocks in the wairkspace.",
    +  badCode: "Program mistak:\n%1",
    +  timeout: "Mucklest execution iterations exceedit.",
    +  discard: "Delyte aw %1 blocks?",
    +  trashTooltip: "Hiff aw blocks.",
    +  catLogic: "Logeec",
    +  catLoops: "Luips",
    +  catMath: "Maths",
    +  catText: "Tex",
    +  catLists: "Leets",
    +  catColour: "Colour",
    +  catVariables: "Variables",
    +  catFunctions: "Functions",
    +  listVariable: "leet",
    +  textVariable: "tex",
    +  httpRequestError: "Thaur wis ae problem wi the request.",
    +  linkAlert: "Shair yer blocks wi this airtin:\n\n%1",
    +  hashError: "Sairrie, '%1' disna correspond wi onie hained program.",
    +  xmlError: "Coudnae laid yer hained file.  Perhaps it wis makit wi ae deefferent version o Blockly?",
    +  badXml: "Mistak parsin XML:\n%1\n\nSelect 'OK' tae hiff yer chynges or 'Cancel' tae further eedit the XML."
    +};
    diff --git a/demos/code/msg/sk.js b/demos/code/msg/sk.js
    new file mode 100644
    index 000000000..08282ac28
    --- /dev/null
    +++ b/demos/code/msg/sk.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kód",
    +  blocks: "Bloky",
    +  linkTooltip: "Uložiť a zdieľať odkaz na tento program.",
    +  runTooltip: "Spustiť program, zložený z dielcov na pracovnej ploche.",
    +  badCode: "Chyba v programe:\n%1",
    +  timeout: "Bol prekročený maximálny počet opakovaní.",
    +  discard: "Zmazať všetkých %1 dielcov?",
    +  trashTooltip: "Zahodiť všetky dielce.",
    +  catLogic: "Logika",
    +  catLoops: "Cykly",
    +  catMath: "Matematické",
    +  catText: "Text",
    +  catLists: "Zoznamy",
    +  catColour: "Farby",
    +  catVariables: "Premenné",
    +  catFunctions: "Funkcie",
    +  listVariable: "zoznam",
    +  textVariable: "text",
    +  httpRequestError: "Problém so spracovaním požiadavky.",
    +  linkAlert: "Zdieľať tento program skopírovaním odkazu\n\n%1",
    +  hashError: "Prepáč, '%1' nie je meno žiadnemu uloženému programu.",
    +  xmlError: "Nebolo možné načítať uložený súbor. Možno bol vytvorený v inej verzii Blocky.",
    +  badXml: "Chyba pri parsovaní XML:\n%1\n\nStlačte 'OK' ak chcete zrušiť zmeny alebo 'Zrušiť' pre pokračovanie v úpravách XML."
    +};
    diff --git a/demos/code/msg/sr.js b/demos/code/msg/sr.js
    new file mode 100644
    index 000000000..cb29673ed
    --- /dev/null
    +++ b/demos/code/msg/sr.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Кôд",
    +  blocks: "Блокови",
    +  linkTooltip: "Сачувајте и повежите са блоковима.",
    +  runTooltip: "Покрените програм заснован на блоковима у радном простору.",
    +  badCode: "Грешка у програму:\n%1",
    +  timeout: "Достигнут је максималан број понављања у извршавању.",
    +  discard: "Обрисати %1 блокова?",
    +  trashTooltip: "Одбаците све блокове.",
    +  catLogic: "Логика",
    +  catLoops: "Петље",
    +  catMath: "Математика",
    +  catText: "Текст",
    +  catLists: "Спискови",
    +  catColour: "Боја",
    +  catVariables: "Променљиве",
    +  catFunctions: "Процедуре",
    +  listVariable: "списак",
    +  textVariable: "текст",
    +  httpRequestError: "Дошло је до проблема у захтеву.",
    +  linkAlert: "Делите своје блокове овом везом:\n\n%1",
    +  hashError: "„%1“ не одговара ниједном сачуваном програму.",
    +  xmlError: "Не могу да учитам сачувану датотеку. Можда је направљена другом верзијом Blockly-ја.",
    +  badXml: "Грешка при рашчлањивању XML-а:\n%1\n\nПритисните „У реду“ да напустите измене или „Откажи“ да наставите са уређивањем XML датотеке."
    +};
    diff --git a/demos/code/msg/sv.js b/demos/code/msg/sv.js
    new file mode 100644
    index 000000000..d92e9415e
    --- /dev/null
    +++ b/demos/code/msg/sv.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kod",
    +  blocks: "Block",
    +  linkTooltip: "Spara och länka till block.",
    +  runTooltip: "Kör programmet som definierats av blocken i arbetsytan.",
    +  badCode: "Programfel:\n%1",
    +  timeout: "Det maximala antalet utförda loopar har överskridits.",
    +  discard: "Radera alla %1 block?",
    +  trashTooltip: "Släng alla block.",
    +  catLogic: "Logik",
    +  catLoops: "Loopar",
    +  catMath: "Matematik",
    +  catText: "Text",
    +  catLists: "Listor",
    +  catColour: "Färg",
    +  catVariables: "Variabler",
    +  catFunctions: "Funktioner",
    +  listVariable: "lista",
    +  textVariable: "text",
    +  httpRequestError: "Det uppstod ett problem med begäran.",
    +  linkAlert: "Dela dina block med denna länk: \n\n%1",
    +  hashError: "Tyvärr, '%1' överensstämmer inte med något sparat program.",
    +  xmlError: "Kunde inte läsa din sparade fil. Den skapades kanske med en annan version av Blockly?",
    +  badXml: "Fel vid parsning av XML:\n%1\n\nKlicka på 'OK' för att strunta i dina ändringar eller 'Avbryt' för att fortsätta redigera XML-koden."
    +};
    diff --git a/demos/code/msg/th.js b/demos/code/msg/th.js
    new file mode 100644
    index 000000000..c6c3c2666
    --- /dev/null
    +++ b/demos/code/msg/th.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "เขียนโปรแกรม",
    +  blocks: "บล็อก",
    +  linkTooltip: "บันทึกและสร้างลิงก์มายังบล็อกเหล่านี้",
    +  runTooltip: "เรียกใช้โปรแกรมตามที่กำหนดไว้ด้วยบล็อกที่อยู่ในพื้นที่ทำงาน",
    +  badCode: "โปรแกรมเกิดข้อผิดพลาด:\n%1",
    +  timeout: "โปรแกรมทำงานซ้ำคำสั่งเดิมมากเกินไป",
    +  discard: "ต้องการลบบล็อกทั้ง %1 บล็อกใช่หรือไม่?",
    +  trashTooltip: "ยกเลิกบล็อกทั้งหมด",
    +  catLogic: "ตรรกะ",
    +  catLoops: "การวนซ้ำ",
    +  catMath: "คณิตศาสตร์",
    +  catText: "ข้อความ",
    +  catLists: "รายการ",
    +  catColour: "สี",
    +  catVariables: "ตัวแปร",
    +  catFunctions: "ฟังก์ชัน",
    +  listVariable: "รายการ",
    +  textVariable: "ข้อความ",
    +  httpRequestError: "มีปัญหาเกี่ยวกับการร้องขอ",
    +  linkAlert: "แบ่งปันบล็อกของคุณด้วยลิงก์นี้:\n\n%1",
    +  hashError: "เสียใจด้วย '%1' ไม่ตรงกับโปรแกรมใดๆ ที่เคยบันทึกเอาไว้เลย",
    +  xmlError: "ไม่สามารถโหลดไฟล์ที่บันทึกไว้ของคุณได้ บางทีมันอาจจะถูกสร้างขึ้นด้วย Blockly รุ่นอื่นที่แตกต่างกัน?",
    +  badXml: "เกิดข้อผิดพลาดในการแยกวิเคราะห์ XML:\n%1\n\nเลือก 'ตกลง' เพื่อละทิ้งการเปลี่ยนแปลงต่างๆ ที่ทำไว้ หรือเลือก 'ยกเลิก' เพื่อแก้ไข XML ต่อไป"
    +};
    diff --git a/demos/code/msg/tlh.js b/demos/code/msg/tlh.js
    new file mode 100644
    index 000000000..6347575bb
    --- /dev/null
    +++ b/demos/code/msg/tlh.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "ngoq",
    +  blocks: "ngoghmey",
    +  linkTooltip: "",
    +  runTooltip: "",
    +  badCode: "Qagh:\n%1",
    +  timeout: "tlhoy nI'qu' poH.",
    +  discard: "Hoch %1 ngoghmey Qaw'?",
    +  trashTooltip: "",
    +  catLogic: "meq",
    +  catLoops: "vIHtaHbogh ghomey",
    +  catMath: "mI'QeD",
    +  catText: "ghItlhHommey",
    +  catLists: "tetlhmey",
    +  catColour: "rItlh",
    +  catVariables: "lIwmey",
    +  catFunctions: "mIwmey",
    +  listVariable: "tetlh",
    +  textVariable: "ghItlhHom",
    +  httpRequestError: "Qapbe' tlhobmeH QIn.",
    +  linkAlert: "latlhvaD ngoghmeylIj DangeHmeH Quvvam yIlo':\n\n%1",
    +  hashError: "Do'Ha', ngogh nab pollu'pu'bogh 'oHbe'law' \"%1\"'e'.",
    +  xmlError: "ngogh nablIj pollu'pu'bogh chu'qa'laHbe' vay'.  chaq pollu'pu'DI' ghunmeH ngogh pIm lo'lu'pu'.",
    +  badXml: "XML yajchu'laHbe' vay':\n%1\n\nchoHmeylIj DalonmeH \"ruch\" yIwIv pagh XML DachoHqa'meH \"qIl\" yIwIv."
    +};
    diff --git a/demos/code/msg/tr.js b/demos/code/msg/tr.js
    new file mode 100644
    index 000000000..2cf29b0aa
    --- /dev/null
    +++ b/demos/code/msg/tr.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Kod",
    +  blocks: "Bloklar",
    +  linkTooltip: "Blokları ve bağlantı adresini kaydet.",
    +  runTooltip: "Çalışma alanında bloklar tarafından tanımlanan programını çalıştırın.",
    +  badCode: "Program hatası:\n %1",
    +  timeout: "Maksimum yürütme yinelemeleri aşıldı.",
    +  discard: "Tüm %1 blok silinsin mi?",
    +  trashTooltip: "Bütün blokları at.",
    +  catLogic: "Mantık",
    +  catLoops: "Döngüler",
    +  catMath: "Matematik",
    +  catText: "Metin",
    +  catLists: "Listeler",
    +  catColour: "Renk",
    +  catVariables: "Değişkenler",
    +  catFunctions: "İşlevler",
    +  listVariable: "liste",
    +  textVariable: "metin",
    +  httpRequestError: "İstek ile ilgili bir problem var.",
    +  linkAlert: "Bloklarını bu bağlantı ile paylaş:\n\n%1",
    +  hashError: "Üzgünüz, '%1' hiç bir kaydedilmiş program ile uyuşmuyor.",
    +  xmlError: "Kaydedilen dosyanız yüklenemiyor\nBlockly'nin önceki sürümü ile kaydedilmiş olabilir mi?",
    +  badXml: "XML ayrıştırma hatası:\n%1\n\nDeğişikliklerden vazgeçmek için 'Tamam'ı, düzenlemeye devam etmek için 'İptal' seçeneğini seçiniz."
    +};
    diff --git a/demos/code/msg/uk.js b/demos/code/msg/uk.js
    new file mode 100644
    index 000000000..8e7d6434a
    --- /dev/null
    +++ b/demos/code/msg/uk.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Код",
    +  blocks: "Блоки",
    +  linkTooltip: "Зберегти і пов'язати з блоками.",
    +  runTooltip: "Запустіть програму, визначену блоками у робочій області.",
    +  badCode: "Помилка програми:\n%1",
    +  timeout: "Максимальне виконання ітерацій перевищено.",
    +  discard: "Вилучити всі блоки %1?",
    +  trashTooltip: "Відкинути всі блоки.",
    +  catLogic: "Логіка",
    +  catLoops: "Петлі",
    +  catMath: "Математика",
    +  catText: "Текст",
    +  catLists: "Списки",
    +  catColour: "Колір",
    +  catVariables: "Змінні",
    +  catFunctions: "Функції",
    +  listVariable: "список",
    +  textVariable: "текст",
    +  httpRequestError: "Виникла проблема із запитом.",
    +  linkAlert: "Поділитися вашим блоками через посилання:\n\n%1",
    +  hashError: "На жаль, \"%1\" не відповідає жодній збереженій програмі.",
    +  xmlError: "Не вдалося завантажити ваш збережений файл.  Можливо, він був створений з іншої версії Blockly?",
    +  badXml: "Помилка синтаксичного аналізу XML:\n%1\n\nВиберіть \"Гаразд\", щоб відмовитися від змін або 'Скасувати' для подальшого редагування XML."
    +};
    diff --git a/demos/code/msg/vi.js b/demos/code/msg/vi.js
    new file mode 100644
    index 000000000..38be4e562
    --- /dev/null
    +++ b/demos/code/msg/vi.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "Chương trình",
    +  blocks: "Các mảnh",
    +  linkTooltip: "Lưu và lấy địa chỉ liên kết.",
    +  runTooltip: "Chạy chương trình.",
    +  badCode: "'Lỗi chương trình:\n%1",
    +  timeout: "Đã vượt quá số lần lặp cho phép.",
    +  discard: "Xóa hết %1 mảnh?",
    +  trashTooltip: "Xóa tất cả mọi mảnh.",
    +  catLogic: "Logic",
    +  catLoops: "Vòng lặp",
    +  catMath: "Công thức toán",
    +  catText: "Văn bản",
    +  catLists: "Danh sách",
    +  catColour: "Màu",
    +  catVariables: "Biến",
    +  catFunctions: "Hàm",
    +  listVariable: "danh sách",
    +  textVariable: "văn bản",
    +  httpRequestError: "Hoạt động bị trục trặc, không thực hiện được yêu cầu của bạn.",
    +  linkAlert: "Chia sẻ chương trình của bạn với liên kết sau:\n\n %1",
    +  hashError: "Không tìm thấy chương trình được lưu ở '%1'.",
    +  xmlError: "Không mở được chương trình của bạn.  Có thể nó nằm trong một phiên bản khác của Blockly?",
    +  badXml: "Lỗi sử lý XML:\n %1\n\nChọn 'OK' để từ bỏ các thay đổi hoặc 'Hủy' để tiếp tục chỉnh sửa các XML."
    +};
    diff --git a/demos/code/msg/zh-hans.js b/demos/code/msg/zh-hans.js
    new file mode 100644
    index 000000000..37aec45d4
    --- /dev/null
    +++ b/demos/code/msg/zh-hans.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "代码",
    +  blocks: "块",
    +  linkTooltip: "保存模块并生成链接。",
    +  runTooltip: "于工作区中运行块所定义的程式。",
    +  badCode: "程序错误:\n%1",
    +  timeout: "超过最大执行行数。",
    +  discard: "删除所有%1块吗?",
    +  trashTooltip: "放弃所有块。",
    +  catLogic: "逻辑",
    +  catLoops: "循环",
    +  catMath: "数学",
    +  catText: "文本",
    +  catLists: "列表",
    +  catColour: "颜色",
    +  catVariables: "变量",
    +  catFunctions: "函数",
    +  listVariable: "列表",
    +  textVariable: "文本",
    +  httpRequestError: "请求存在问题。",
    +  linkAlert: "通过这个链接分享您的模块:\n\n%1",
    +  hashError: "对不起,没有任何已保存的程序对应'%1' 。",
    +  xmlError: "无法载入您保存的文件。您是否使用其他版本的Blockly创建该文件的?",
    +  badXml: "XML解析错误:\n%1\n\n选择“确定”以取消您对XML的修改,或选择“取消”以继续编辑XML。"
    +};
    diff --git a/demos/code/msg/zh-hant.js b/demos/code/msg/zh-hant.js
    new file mode 100644
    index 000000000..1f7211834
    --- /dev/null
    +++ b/demos/code/msg/zh-hant.js
    @@ -0,0 +1,25 @@
    +var MSG = {
    +  title: "程式碼",
    +  blocks: "積木",
    +  linkTooltip: "儲存積木組並提供連結。",
    +  runTooltip: "於工作區中執行積木組所定義的程式。",
    +  badCode: "程式錯誤:\n%1",
    +  timeout: "超過最大執行數。",
    +  discard: "刪除共%1個積木?",
    +  trashTooltip: "捨棄所有積木。",
    +  catLogic: "邏輯",
    +  catLoops: "迴圈",
    +  catMath: "數學式",
    +  catText: "文字",
    +  catLists: "列表",
    +  catColour: "顏色",
    +  catVariables: "變量",
    +  catFunctions: "流程",
    +  listVariable: "列表",
    +  textVariable: "文字",
    +  httpRequestError: "命令出現錯誤。",
    +  linkAlert: "透過此連結分享您的積木組:\n\n%1",
    +  hashError: "對不起,「%1」並未對應任何已保存的程式。",
    +  xmlError: "未能載入您保存的檔案。或許它是由其他版本的Blockly創建?",
    +  badXml: "解析 XML 時出現錯誤:\n%1\n\n選擇'確定'以放棄您的更改,或選擇'取消'以進一步編輯 XML。"
    +};
    diff --git a/apps/code/style.css b/demos/code/style.css
    similarity index 66%
    rename from apps/code/style.css
    rename to demos/code/style.css
    index 3fa7f5a7f..6194b12a1 100644
    --- a/apps/code/style.css
    +++ b/demos/code/style.css
    @@ -1,11 +1,66 @@
     html, body {
       height: 100%;
     }
    +
     body {
    +  background-color: #fff;
    +  font-family: sans-serif;
       margin: 0;
       overflow: hidden;
     }
    +
    +.farSide {
    +  text-align: right;
    +}
    +
    +html[dir="RTL"] .farSide {
    +  text-align: left;
    +}
    +
    +/* Buttons */
    +button {
    +  margin: 5px;
    +  padding: 10px;
    +  border-radius: 4px;
    +  border: 1px solid #ddd;
    +  font-size: large;
    +  background-color: #eee;
    +  color: #000;
    +}
    +button.primary {
    +  border: 1px solid #dd4b39;
    +  background-color: #dd4b39;
    +  color: #fff;
    +}
    +button.primary>img {
    +  opacity: 1;
    +}
    +button>img {
    +  opacity: 0.6;
    +  vertical-align: text-bottom;
    +}
    +button:hover>img {
    +  opacity: 1;
    +}
    +button:active {
    +  border: 1px solid #888 !important;
    +}
    +button:hover {
    +  box-shadow: 2px 2px 5px #888;
    +}
    +button.disabled:hover>img {
    +  opacity: 0.6;
    +}
    +button.disabled {
    +  display: none;
    +}
    +button.notext {
    +  font-size: 10%;
    +}
    +
     h1 {
    +  font-weight: normal;
    +  font-size: 140%;
       margin-left: 5px;
       margin-right: 5px;
     }
    diff --git a/demos/index.html b/demos/index.html
    index 9bcde075f..688ffbb6b 100644
    --- a/demos/index.html
    +++ b/demos/index.html
    @@ -132,7 +132,7 @@
           
    -
    Closure Templates to support 35 languages.
    +
    Using Closure Templates to support 35 languages.
    + + + + + +
    Export a Blockly program into JavaScript, Python, Dart or XML.
    +
    diff --git a/demos/plane/plane.js b/demos/plane/plane.js index 8beda12c1..89581dc02 100644 --- a/demos/plane/plane.js +++ b/demos/plane/plane.js @@ -18,7 +18,7 @@ */ /** - * @fileoverview JavaScript for Blockly's Plane Seat Calculator application. + * @fileoverview JavaScript for Blockly's Plane Seat Calculator demo. * @author fraser@google.com (Neil Fraser) */ 'use strict'; diff --git a/generators/javascript/loops.js b/generators/javascript/loops.js index a5b108631..117cf1ea0 100644 --- a/generators/javascript/loops.js +++ b/generators/javascript/loops.js @@ -156,7 +156,7 @@ Blockly.JavaScript['controls_forEach'] = function(block) { variable0 + '_index', Blockly.Variables.NAME_TYPE); branch = Blockly.JavaScript.INDENT + variable0 + ' = ' + argument0 + '[' + indexVar + '];\n' + branch; - var code = 'for (var ' + indexVar + ' in ' + argument0 + ') {\n' + + var code = 'for (var ' + indexVar + ' in ' + argument0 + ') {\n' + branch + '}\n'; return code; };