diff options
| author | Gubolin <gubolin@fantasymail.de> | 2015-01-02 10:30:00 +0100 |
|---|---|---|
| committer | Gubolin <gubolin@fantasymail.de> | 2015-01-02 10:30:00 +0100 |
| commit | aba651ba26bc9e79016b34070da5eacd407dac99 (patch) | |
| tree | 8c92107550bbce2c715e32e90f4cd9a14fde7015 | |
| parent | 98755a4467991b6fb31563b17f8c15b1c5266294 (diff) | |
| parent | b31df39d7f126eaa303c8dae1cf6a14c739a2cc5 (diff) | |
| download | snap-anykey_issue387.tar.gz snap-anykey_issue387.zip | |
resolve merge conflictanykey_issue387
| -rw-r--r-- | blocks.js | 43 | ||||
| -rw-r--r-- | byob.js | 5 | ||||
| -rw-r--r-- | favicon.ico | bin | 0 -> 8062 bytes | |||
| -rw-r--r-- | gui.js | 18 | ||||
| -rwxr-xr-x | history.txt | 95 | ||||
| -rw-r--r-- | lang-kn.js | 1273 | ||||
| -rwxr-xr-x | lang-pt.js | 23 | ||||
| -rw-r--r-- | lang-sv.js | 1359 | ||||
| -rw-r--r-- | lists.js | 5 | ||||
| -rw-r--r-- | locale.js | 26 | ||||
| -rw-r--r-- | morphic.js | 58 | ||||
| -rw-r--r-- | objects.js | 101 | ||||
| -rwxr-xr-x | snap.html | 4 | ||||
| -rw-r--r-- | store.js | 14 | ||||
| -rw-r--r-- | threads.js | 430 | ||||
| -rw-r--r-- | tools.xml | 2 |
16 files changed, 3200 insertions, 256 deletions
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-October-01'; +modules.blocks = '2014-November-21'; var SyntaxElementMorph; @@ -394,10 +394,10 @@ SyntaxElementMorph.prototype.allInputs = function () { }; SyntaxElementMorph.prototype.allEmptySlots = function () { -/* - answer empty input slots of all children excluding myself, - but omit those in nested rings (lambdas) and JS-Function primitives -*/ + // answer empty input slots of all children excluding myself, + // but omit those in nested rings (lambdas) and JS-Function primitives. + // Used by the evaluator when binding implicit formal parameters + // to empty input slots var empty = []; if (!(this instanceof RingMorph) && (this.selector !== 'reportJSFunction')) { @@ -412,6 +412,26 @@ SyntaxElementMorph.prototype.allEmptySlots = function () { return empty; }; +SyntaxElementMorph.prototype.tagExitBlocks = function (stopTag, isCommand) { + // tag 'report' and 'stop this block' blocks of all children including + // myself, with either a stopTag (for "stop" blocks) or an indicator of + // being inside a command block definition, but omit those in nested + // rings (lambdas. Used by the evaluator when entering a procedure + if (this.selector === 'doReport') { + this.partOfCustomCommand = isCommand; + } else if (this.selector === 'doStopThis') { + this.exitTag = stopTag; + } else { + if (!(this instanceof RingMorph)) { + this.children.forEach(function (morph) { + if (morph.tagExitBlocks) { + morph.tagExitBlocks(stopTag, isCommand); + } + }); + } + } +}; + SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) { var scripts = this.parentThatIsA(ScriptsMorph), replacement = newArg, @@ -3171,9 +3191,14 @@ BlockMorph.prototype.snap = function () { I inherit from BlockMorph adding the following most important public accessors: - nextBlock() - set / get the block attached to my bottom - bottomBlock() - answer the bottom block of my stack - blockSequence() - answer an array of blocks starting with myself + nextBlock() - set / get the block attached to my bottom + bottomBlock() - answer the bottom block of my stack + blockSequence() - answer an array of blocks starting with myself + + and the following "lexical awareness" indicators: + + partOfCustomCommand - temporary bool set by the evaluator + exitTag - temporary string or number set by the evaluator */ // CommandBlockMorph inherits from BlockMorph: @@ -3191,6 +3216,8 @@ function CommandBlockMorph() { CommandBlockMorph.prototype.init = function () { CommandBlockMorph.uber.init.call(this); this.setExtent(new Point(200, 100)); + this.partOfCustomCommand = false; + this.exitTag = null; }; // CommandBlockMorph enumerating: @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-September-30'; +modules.byob = '2014-November-20'; // Declarations @@ -688,7 +688,8 @@ CustomCommandBlockMorph.prototype.labelPart = function (spec) { return CustomCommandBlockMorph.uber.labelPart.call(this, spec); } if ((spec[0] === '%') && (spec.length > 1)) { - part = new BlockInputFragmentMorph(spec.slice(1)); + // part = new BlockInputFragmentMorph(spec.slice(1)); + part = new BlockInputFragmentMorph(spec.replace(/%/g, '')); } else { part = new BlockLabelFragmentMorph(spec); part.fontSize = this.fontSize; diff --git a/favicon.ico b/favicon.ico Binary files differnew file mode 100644 index 0000000..b2b1e60 --- /dev/null +++ b/favicon.ico @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-October-06'; +modules.gui = '2014-December-04'; // Declarations @@ -233,10 +233,6 @@ IDE_Morph.prototype.init = function (isAutoFill) { IDE_Morph.prototype.openIn = function (world) { var hash, usr, myself = this, urlLanguage = null; - this.buildPanes(); - world.add(this); - world.userMenu = this.userMenu; - // get persistent user data, if any if (localStorage) { usr = localStorage['-snap-user']; @@ -245,10 +241,17 @@ IDE_Morph.prototype.openIn = function (world) { if (usr) { SnapCloud.username = usr.username || null; SnapCloud.password = usr.password || null; + if (SnapCloud.username) { + this.source = 'cloud'; + } } } } + this.buildPanes(); + world.add(this); + world.userMenu = this.userMenu; + // override SnapCloud's user message with Morphic SnapCloud.message = function (string) { var m = new MenuMorph(null, string), @@ -2511,8 +2514,9 @@ IDE_Morph.prototype.aboutSnap = function () { + 'jens@moenig.org, bh@cs.berkeley.edu\n\n' + 'Snap! is developed by the University of California, Berkeley\n' - + ' with support from the National Science Foundation ' - + 'and MioSoft. \n' + + ' with support from the National Science Foundation, ' + + 'MioSoft, \n' + + 'and the Communications Design Group at SAP Labs. \n' + 'The design of Snap! is influenced and inspired by Scratch,\n' + 'from the Lifelong Kindergarten group at the MIT Media Lab\n\n' diff --git a/history.txt b/history.txt index 28116b9..6d6f0ff 100755 --- a/history.txt +++ b/history.txt @@ -2309,3 +2309,98 @@ ______ 141008 ------ * Objects: fixed #608, #610 + +141106 +------ +* Morphic: Enable mouseMove events with right button pressed + +141114 +------ +* Threads, Store: Fix reporting out of nested custom C-shaped blocks + +141117 +------ +* Threads, Blocks: Treat REPORT blocks inside custom command definitions as STOP THIS BLOCK / IGNORE INPUTS + +141120 +------ +* Lists: Fixed #642 avoid “freezing” when calling CONS on non-list/null +* Threads: Fixed #364 avoid “freezing” when calling LAUNCH on empty ring +* Threads: Added optional “onComplete” callback to Process, thanks, @bromagosa! +* GUI: Set Default Save location to Cloud on load, thanks, @cycomachead! +* GUI: Updated the “About” Dialog with a mention of support from CDG (SAP Labs) +* BYOB: Percent sign fix for block labels, thanks, @natashasandy! +* Threads: fix ‘line’ option in ‘split’ block for Windows files, thanks, @brianharvey! +* Morphic: fix slider range 1, thanks, @tonychenr ! +* translation update, thanks, Manuel! + +141121 +------ +* Threads, Blocks: Fix STOP THIS BLOCK’s lexical awareness + +1411213 +------- +* Threads: Fix “stop this block” primitive for tail-call-elimination + +1411224 +------- +* Threads: Fixed #318 +* Objects: Fixed #416 +* Objects: Fixed #372 +* Threads: Fixed #644 +* Store: Fixed #34 +* Threads: Fixed #131 +* snap.html, favicon.ico: new Favicon, thanks, Michael! +* Threads: improved whitespace detection for “split” primitive, thanks, Michael! +* Threads: tail-call-elimination for reporters experiment (commented out, under construction) + +1411225 +------- +* Threads: Evaluator optimizations (reducing the stack size for reporters) +* Threads: Full TCO (tail-call-elimination), now Snap! *is* Scheme :-) + +1411225 +------- +* Threads: Fixed #656 + +141201 +------ +* Objects: Hide hidden elements in the project thumbnail +* GUI: Point project dialog to cloud if already signed in, thanks, Michael! +* favicon: Transparent background, thanks, Michael! + +141202 +------ +* New Kannada translation. Yay!! Thanks, Vinayakumar R!! + +141203 +------ +* Morphic: Cache actual bounding box of the Pen arrow shape +* Threads, Objects: Improve edge-collision detection of default sprite “arrow” shape + +141204 +------ +* Threads, Objects: Experimental “ForEach” primitive (hidden in dev mode) +* GUI: Another attempt at pointing the project dialog to the cloud if signed in + +141205 +------ +* Morphic: Avoid auto-scaling artefacts in Safari on retina displays (resulting in “traces” when dragging items) + +141206 +------ +* Store: Fixed #668 + +141211 +------ +* Threads: yield after each cycle in the experimental “forEach” primitive + +141215 +------ +* New Swedish translation! Yay!! Thanks, Erik A Olsson! + +141217 +------ +* Objects, Store: Experimental “processes” count watcher (hidden in dev mode) +* Threads: Remove terminated processes from expired clones +* Threads: Let “zombifying” scripts access receivers’ local vars diff --git a/lang-kn.js b/lang-kn.js new file mode 100644 index 0000000..24da267 --- /dev/null +++ b/lang-kn.js @@ -0,0 +1,1273 @@ +/*
+
+ lang-kn.js
+
+ Kannada translation for SNAP!
+
+ written by Vinayakumar R
+
+ Copyright (C) 2014 by Vinayakumar R
+
+ This file is part of Snap!.
+
+ Snap! is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+ Note to Translators:
+ --------------------
+ At this stage of development, Snap! can be translated to any LTR language
+ maintaining the current order of inputs (formal parameters in blocks).
+
+ Translating Snap! is easy:
+
+
+ 1. Download
+
+ Download the sources and extract them into a local folder on your
+ computer:
+
+ <http://snap.berkeley.edu/snapsource/snap.zip>
+
+ Use the German translation file (named 'lang-de.js') as template for your
+ own translations. Start with editing the original file, because that way
+ you will be able to immediately check the results in your browsers while
+ you're working on your translation (keep the local copy of snap.html open
+ in your web browser, and refresh it as you progress with your
+ translation).
+
+
+ 2. Edit
+
+ Edit the translation file with a regular text editor, or with your
+ favorite JavaScript editor.
+
+ In the first non-commented line (the one right below this
+ note) replace "de" with the two-letter ISO 639-1 code for your language,
+ e.g.
+
+ fr - French => SnapTranslator.dict.fr = {
+ it - Italian => SnapTranslator.dict.it = {
+ pl - Polish => SnapTranslator.dict.pl = {
+ pt - Portuguese => SnapTranslator.dict.pt = {
+ es - Spanish => SnapTranslator.dict.es = {
+ el - Greek => => SnapTranslator.dict.el = {
+
+ etc. (see <http://en.wikipedia.org/wiki/ISO_639-1>)
+
+
+ 3. Translate
+
+ Then work through the dictionary, replacing the German strings against
+ your translations. The dictionary is a straight-forward JavaScript ad-hoc
+ object, for review purposes it should be formatted as follows:
+
+ {
+ 'English string':
+ 'Translation string',
+ 'last key':
+ } 'last value'
+
+ and you only edit the indented value strings. Note that each key-value
+ pair needs to be delimited by a comma, but that there shouldn't be a comma
+ after the last pair (again, just overwrite the template file and you'll be
+ fine).
+
+ If something doesn't work, or if you're unsure about the formalities you
+ should check your file with
+
+ <http://JSLint.com>
+
+ This will inform you about any missed commas etc.
+
+
+ 4. Accented characters
+
+ Depending on which text editor and which file encoding you use you can
+ directly enter special characters (e.g. Umlaut, accented characters) on
+ your keyboard. However, I've noticed that some browsers may not display
+ special characters correctly, even if other browsers do. So it's best to
+ check your results in several browsers. If you want to be on the safe
+ side, it's even better to escape these characters using Unicode.
+
+ see: <http://0xcc.net/jsescape/>
+
+
+ 5. Block specs:
+
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+
+
+ 6. Submit
+
+ When you're done, rename the edited file by replacing the "de" part of the
+ filename with the two-letter ISO 639-1 code for your language, e.g.
+
+ fr - French => lang-fr.js
+ it - Italian => lang-it.js
+ pl - Polish => lang-pl.js
+ pt - Portuguese => lang-pt.js
+ es - Spanish => lang-es.js
+ el - Greek => => lang-el.js
+
+ and send it to me for inclusion in the official Snap! distribution.
+ Once your translation has been included, Your name will the shown in the
+ "Translators" tab in the "About Snap!" dialog box, and you will be able to
+ directly launch a translated version of Snap! in your browser by appending
+
+ lang:xx
+
+ to the URL, xx representing your translations two-letter code.
+
+
+ 7. Known issues
+
+ In some browsers accents or ornaments located in typographic ascenders
+ above the cap height are currently (partially) cut-off.
+
+ Enjoy!
+ -Jens
+*/
+
+/*global SnapTranslator*/
+
+SnapTranslator.dict.kn = {
+
+
+ // translations meta information
+ 'language_name':
+ '\u0C95\u0CA8\u0CCD\u0CA8\u0CA1', // the name as it should appear in the language menu
+ 'language_translator':
+ 'Vinayakumar R', // your name for the Translators tab
+ 'translator_e-mail':
+ 'vnkmr7620@gmail.com', // optional
+ 'last_changed':
+ '2014-25-11', // this, too, will appear in the Translators tab
+
+ // GUI
+ // control bar:
+ 'untitled':
+ 'Unbenannt',
+ 'development mode':
+ 'Hackermodus',
+
+ // categories:
+ 'Motion':
+ '\u0C9A\u0CB2\u0CA8\u0CC6',
+ 'Looks':
+ '\u0C95\u0CBE\u0CA3\u0CC1\u0CB5\u0CC1\u0CA6\u0CC1',
+ 'Sound':
+ '\u0CB6\u0CAC\u0CCD\u0CA6',
+ 'Pen':
+ '\u0CB2\u0CC7\u0C96\u0CA8\u0CBF',
+ 'Control':
+ '\u0CB9\u0CBF\u0CA1\u0CBF\u0CA4',
+ 'Sensing':
+ '\u0C97\u0CCD\u0CB0\u0CB9\u0CBF\u0CB8\u0CC1\u0CB5\u0CC1\u0CA6\u0CC1',
+ 'Operators':
+ '\u0C9A\u0CBF\u0CB9\u0CCD\u0CA8\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0CC1',
+ 'Variables':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0C97\u0CB3\u0CC1',
+ 'Lists':
+ '\u0CAA\u0C9F\u0CCD\u0C9F\u0CBF\u0C97\u0CB3\u0CC1',
+ 'Other':
+ '\u0C87\u0CA4\u0CB0\u0CC6',
+
+ // editor:
+ 'draggable':
+ '\u0C8E\u0CB3\u0CC6\u0CAF\u0CAC\u0CB9\u0CC1\u0CA6\u0CBE\u0CA6',
+
+ // tabs:
+ 'Scripts':
+ '\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0CC1',
+ 'Costumes':
+ '\u0C89\u0CA1\u0CC1\u0CAA\u0CC1\u0C97\u0CB3\u0CC1',
+ 'Sounds':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0C97\u0CB3\u0CC1',
+
+ // names:
+ 'Sprite':
+ '\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0CA3\u0CBF',
+ 'Stage':
+ '\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6',
+
+ // rotation styles:
+ 'don\'t rotate':
+ '\u0CA4\u0CBF\u0CB0\u0CC1\u0C97\u0CAC\u0CC7\u0CA1',
+ 'can rotate':
+ '\u0CA4\u0CBF\u0CB0\u0CC1\u0C97\u0CBF\u0CB8\u0CAC\u0CB9\u0CC1\u0CA6\u0CC1',
+ 'only face left/right':
+ '\u0CAE\u0CC1\u0C96\u0020\u0CAC\u0CB2\u0C97\u0CA1\u0CC6\u002F\u0C8E\u0CA1\u0C97\u0CA1\u0CC6',
+
+ // new sprite button:
+ 'add a new sprite':
+ '\u0CB9\u0CCA\u0CB8\u0020\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0CA3\u0CBF\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CC1',
+
+ // tab help
+ 'costumes tab help':
+ '\u0C87\u0CA8\u0CCD\u0CA8\u0CBF\u0CA4\u0CB0\u0020\u0C9C\u0CBE\u0CB2\u0CA4\u0CBE\u0CA3\u0020\u0C85\u0CA5\u0CB5\u0CBE\u0020\u0CA8\u0CBF\u0CAE\u0CCD\u0CAE\u0020\u0C97\u0CA3\u0C95\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0CA6\u0CBF\u0C82\u0CA6\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C87\u0CB2\u0CCD\u0CB2\u0CBF\u0C97\u0CC6\u0020\u0C8E\u0CB3\u0CC6\u0CAF\u0CC1\u0CB5\u0CC1\u0CA6\u0CB0\u0CBF\u0C82\u0CA6\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CAC\u0CB9\u0CC1\u0CA6\u0CC1\u0020'
+ ,
+ 'import a sound from your computer\nby dragging it into here':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA8\u0CBF\u0CAE\u0CCD\u0CAE\u0020\u0C97\u0CA3\u0C95\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0CA6\u0CBF\u0C82\u0CA6\u0020\u0C87\u0CB2\u0CCD\u0CB2\u0CBF\u0C97\u0CC6\u0020\u0C8E\u0CB3\u0CC6\u0CAF\u0CC1\u0CB5\u0CC1\u0CA6\u0CB0\u0CBF\u0C82\u0CA6\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CAC\u0CB9\u0CC1\u0CA6\u0CC1',
+
+ // primitive blocks:
+
+ /*
+ Attention Translators:
+ ----------------------
+ At this time your translation of block specs will only work
+ correctly, if the order of formal parameters and their types
+ are unchanged. Placeholders for inputs (formal parameters) are
+ indicated by a preceding % prefix and followed by a type
+ abbreviation.
+
+ For example:
+
+ 'say %s for %n secs'
+
+ can currently not be changed into
+
+ 'say %n secs long %s'
+
+ and still work as intended.
+
+ Similarly
+
+ 'point towards %dst'
+
+ cannot be changed into
+
+ 'point towards %cst'
+
+ without breaking its functionality.
+ */
+
+ // motion:
+ 'Stage selected:\nno motion primitives':
+ 'B\u00fchne ausgew\u00e4hlt:\nkeine Standardbewegungsbl\u00f6cke\n'
+ + 'vorhanden',
+
+ 'move %n steps':
+ '\u0C9A\u0CB2\u0CBF\u0CB8\u0CC1 %n \u0CB9\u0CC6\u0C9C\u0CCD\u0C9C\u0CC6\u0C97\u0CB3\u0CC1',
+ 'turn %clockwise %n degrees':
+ '\u0CA4\u0CBF\u0CB0\u0CC1\u0C97\u0CC1 %clockwise %n \u0C95\u0CCB\u0CA8\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF',
+ 'turn %counterclockwise %n degrees':
+ '\u0CA4\u0CBF\u0CB0\u0CC1\u0C97\u0CC1 %counterclockwise %n \u0C95\u0CCB\u0CA8\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF',
+ 'point in direction %dir':
+ '\u0CAC\u0CBF\u0C82\u0CA6\u0CC1\u0CB5\u0CBF\u0CA8\u0020\u0CA6\u0CBF\u0C95\u0CCD\u0C95\u0CBF\u0CA8\u0020\u0C95\u0CA1\u0CC7 %dir',
+ 'point towards %dst':
+ '\u0CA6\u0CBF\u0C95\u0CCD\u0C95\u0CBF\u0CA8\u0020\u0C95\u0CA1\u0CC7\u0C97\u0CC6 %dst',
+ 'go to x: %n y: %n':
+ '\u0CB9\u0CCB\u0C97\u0CC1 x: %n y: %n',
+ 'go to %dst':
+ '\u0CB9\u0CCB\u0C97\u0CC1 %dst',
+ 'glide %n secs to x: %n y: %n':
+ '\u0CB8\u0CB0\u0CBF %n \u0CB8\u0CC6\u0C95\u0CC6\u0C82\u0CA1\u0CBF\u0CA8\u0CB2\u0CCD\u0CB2\u0CBF,\u0CAC\u0CBF\u0C82\u0CA6\u0CC1\u0CB5\u0CBF\u0C97\u0CC6 x: %n y: %n',
+ 'change x by %n':
+ '\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 x \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %n',
+ 'set x to %n':
+ '\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 x \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %n',
+ 'change y by %n':
+ '\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 y \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %n',
+ 'set y to %n':
+ '\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 y \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %n',
+ 'if on edge, bounce':
+ '\u0C92\u0C82\u0CA6\u0CC1\u0020\u0CB5\u0CC7\u0CB3\u0CC6\u0020\u0C95\u0CCA\u0CA8\u0CC6\u0C97\u0CC6\u0020\u0CB9\u0CCB\u0CA6\u0CBE\u0C97\u0020\u0C9C\u0CBF\u0C97\u0CBF',
+ 'x position':
+ 'x-\u0CB8\u0CCD\u0CA5\u0CBE\u0CA8',
+ 'y position':
+ 'y-\u0CB8\u0CCD\u0CA5\u0CBE\u0CA8',
+ 'direction':
+ '\u0CA6\u0CBF\u0C95\u0CCD\u0C95\u0CC1',
+
+ // looks:
+ 'switch to costume %cst':
+ '\u0C89\u0CA1\u0CC1\u0CAA\u0CA8\u0CCD\u0CA8\u0CC1 %cst \u0C97\u0CC6\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1',
+ 'next costume':
+ '\u0CAE\u0CC1\u0C82\u0CA6\u0CBF\u0CA8\u0020\u0C89\u0CA1\u0CC1\u0CAA\u0CC1',
+ 'costume #':
+ '\u0C89\u0CA1\u0CC1\u0CAA\u0CC1',
+ 'say %s for %n secs':
+ '\u0CB9\u0CC7\u0CB3\u0CC1 %s \u0C85\u0C82\u0CA4 %n \u0CB8\u0CC6\u0C95\u0CC6\u0C82\u0CA1\u0CBF\u0CA8\u0CB2\u0CCD\u0CB2\u0CBF',
+ 'say %s':
+ '\u0CB9\u0CC7\u0CB3\u0CC1 %s',
+ 'think %s for %n secs':
+ '\u0CAF\u0CCB\u0C9A\u0CBF\u0CB8\u0CC1 %s \u0C85\u0C82\u0CA4 %n \u0CB8\u0CC6\u0C95\u0CC6\u0C82\u0CA1\u0CC1\u0C97\u0CB3\u0CB5\u0CB0\u0C97\u0CC6',
+ 'think %s':
+ '\u0CAF\u0CCB\u0C9A\u0CBF\u0CB8\u0CC1 %s',
+ 'Hello!':
+ '\u0CA8\u0CAE\u0CB8\u0CCD\u0C95\u0CBE\u0CB0!',
+ 'Hmm...':
+ '\u0C85\u0CB9\u0C83...',
+ 'change %eff effect by %n':
+ '\u0CAA\u0CB0\u0CBF\u0CA3\u0CBE\u0CAE\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1 %eff \u0C97\u0CC6\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set %eff effect to %n':
+ '\u0CAA\u0CB0\u0CBF\u0CA3\u0CBE\u0CAE\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1 %eff \u0C97\u0CC6\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %n',
+ 'clear graphic effects':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0CAA\u0CB0\u0CBF\u0CA3\u0CBE\u0CAE\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'change size by %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set size to %n %':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %n %',
+ 'size':
+ '\u0C97\u0CBE\u0CA4\u0CCD\u0CB0',
+ 'show':
+ '\u0CA4\u0CCB\u0CB0\u0CBF\u0CB8\u0CC1',
+ 'hide':
+ '\u0CAC\u0C9A\u0CCD\u0C9A\u0CBF\u0CA1\u0CC1',
+ 'go to front':
+ '\u0CAE\u0CC1\u0C82\u0CA6\u0C95\u0CCD\u0C95\u0CC6\u0020\u0CB9\u0CCB\u0C97\u0CC1',
+ 'go back %n layers':
+ '\u0CAA\u0CA6\u0CB0\u0C97\u0CB3\u0CC1 %n \u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CB9\u0CBF\u0C82\u0CA6\u0C95\u0CCD\u0C95\u0CC6\u0020\u0CB9\u0CCB\u0C97\u0CC1',
+
+ 'development mode \ndebugging primitives:':
+ '\u0CAC\u0CC6\u0CB3\u0CB5\u0CA3\u0CBF\u0C97\u0CC6\u0CAF\u0020\u0C95\u0CCD\u0CB0\u0CAE \n\u0CA6\u0CCB\u0CB7\u0020\u0CA8\u0CBF\u0CA6\u0CBE\u0CA8\u0020\u0CAE\u0CC1\u0CB2\u0CBE\u0C97\u0CB3\u0CC1',
+ 'console log %mult%s':
+ '\u0CAE\u0CC1\u0C96\u0CCD\u0CAF\u0020\u0C9F\u0CB0\u0CCD\u0CAE\u0CBF\u0CA8\u0CB2\u0CCD\u0020\u0C95\u0CA1\u0CA4: %mult%s',
+ 'alert %mult%s':
+ '\u0C8E\u0C9A\u0CCD\u0C9A\u0CB0\u0CBF\u0C95\u0CC6 %mult%s',
+
+ // sound:
+ 'play sound %snd':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0020\u0C95\u0CC7\u0CB3\u0CBF\u0CB8\u0CC1 %snd',
+ 'play sound %snd until done':
+ '\u0C86\u0C97\u0CC1\u0CB5\u0CB5\u0CB0\u0C97\u0CC6\u0020 %snd \u0CB6\u0CAC\u0CCD\u0CA6\u0020\u0C95\u0CC7\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'stop all sounds':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0CB6\u0CAC\u0CCD\u0CA6\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1',
+ 'rest for %n beats':
+ '\u0CB2\u0CAF\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1 %n \u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CBF',
+ 'play note %n for %n beats':
+ '\u0CB8\u0C82\u0C97\u0CC0\u0CA4\u0CB8\u0CCD\u0CB5\u0CB0 %n \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %n \u0CB2\u0CAF\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF\u0020\u0C95\u0CC7\u0CB3\u0CBF\u0CB8\u0CBF',
+ 'change tempo by %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CA4\u0CBE\u0CB3\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set tempo to %n bpm':
+ '\u0CA4\u0CBE\u0CB3\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1 %n \u0C97\u0CC6\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1',
+ 'tempo':
+ '\u0CA4\u0CBE\u0CB3',
+
+ // pen:
+ 'clear':
+ '\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'pen down':
+ '\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0CAF\u0CC1\u0C95\u0CCD\u0CA4',
+ 'pen up':
+ '\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0CAE\u0CC1\u0C95\u0CCD\u0CA4',
+ 'set pen color to %clr':
+ '\u0C97\u0CC6\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0CAC\u0CA3\u0CCD\u0CA3\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %clr',
+ 'change pen color by %n':
+ '\u0C97\u0CC6\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0CAC\u0CA3\u0CCD\u0CA3\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set pen color to %n':
+ '\u0C97\u0CC6\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0CAC\u0CA3\u0CCD\u0CA3\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %n',
+ 'change pen shade by %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0CA8\u0CC6\u0CB0\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set pen shade to %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0CA8\u0CC6\u0CB0\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %n',
+ 'change pen size by %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %n',
+ 'set pen size to %n':
+ '\u0CB0\u0CB7\u0CCD\u0C9F\u0CC1\u0020\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %n',
+ 'stamp':
+ '\u0CAE\u0CC1\u0CA6\u0CCD\u0CB0\u0CBF\u0CB8\u0CC1',
+
+ // control:
+ 'when %greenflag clicked':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CBE\u0CA6\u0CB0\u0CC2 %greenflag \u0C92\u0CA4\u0CCD\u0CA4\u0CBF\u0CA6\u0CBE\u0C97',
+ 'when %keyHat key pressed':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CBE\u0CA6\u0CB0\u0CC2 %keyHat \u0C95\u0CC0\u0020\u0C92\u0CA4\u0CCD\u0CA4\u0CBF\u0CA6\u0CBE\u0C97',
+ 'when I am clicked':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CBE\u0CA6\u0CB0\u0CC2\u0020\u0CA8\u0CBE\u0CA8\u0CC1\u0020\u0C92\u0CA4\u0CCD\u0CA4\u0CBF\u0CA6\u0CBE\u0C97',
+ 'when I receive %msgHat':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CBE\u0CA6\u0CB0\u0CC1 %msgHat \u0CB8\u0CCD\u0CB5\u0CC0\u0C95\u0CB0\u0CBF\u0CB8\u0CBF\u0CA6\u0CBE\u0C97',
+ 'broadcast %msg':
+ '\u0CAA\u0CCD\u0CB0\u0CB8\u0CB0\u0CBF\u0CB8\u0CC1 %msg',
+ 'broadcast %msg and wait':
+ '\u0CAA\u0CCD\u0CB0\u0CB8\u0CB0\u0CBF\u0CB8\u0CC1 %msg \u0CAE\u0CA4\u0CCD\u0CA4\u0CC1\u0020\u0C95\u0CBE\u0CAF\u0CAC\u0CC7\u0C95\u0CC1',
+ 'Message name':
+ '\u0CAE\u0CBE\u0CB9\u0CBF\u0CA4\u0CBF\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1',
+ 'message':
+ '\u0CAE\u0CBE\u0CB9\u0CBF\u0CA4\u0CBF',
+ 'any message':
+ '\u0CAF\u0CBE\u0CB5\u0CC1\u0CA6\u0CBE\u0CA6\u0CB0\u0CC1\u0020\u0CAE\u0CBE\u0CB9\u0CBF\u0CA4\u0CBF',
+ 'wait %n secs':
+ '\u0CA8\u0CBF\u0CA7\u0CBE\u0CA8\u0CBF\u0CB8\u0CC1 %n \u0CB8\u0CC6\u0C95\u0CC6\u0C82\u0CA1\u0CBF\u0CA8\u0CB7\u0CCD\u0C9F\u0CC1',
+ 'wait until %b':
+ '\u0CB5\u0CB0\u0C97\u0CC2\u0020\u0C95\u0CBE\u0CAF\u0CAC\u0CC7\u0C95\u0CC1 %b',
+ 'forever %c':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CC1 %c',
+ 'repeat %n %c':
+ '\u0CAE\u0CB0\u0CC1\u0C95\u0CB3\u0CBF\u0CB8\u0CC1 %n mal %c',
+ 'repeat until %b %c':
+ '\u0CB5\u0CB0\u0CC6\u0C97\u0CC2\u0020\u0CAE\u0CB0\u0CC1\u0C95\u0CB3\u0CBF\u0CB8\u0CC1 %b %c',
+ 'if %b %c':
+ '\u0C92\u0C82\u0CA6\u0CC1\u0CB5\u0CC7\u0CB3\u0CC6 %b %c',
+ 'if %b %c else %c':
+ '\u0C92\u0C82\u0CA6\u0CC1\u0CB5\u0CC7\u0CB3\u0CC6 %b %c \u0C87\u0CB2\u0CCD\u0CB2\u0CA6\u0CBF\u0CA6\u0CCD\u0CA6\u0CB0\u0CC6 %c',
+ 'report %s':
+ '\u0CA8\u0CBF\u0CB0\u0CC2\u0CAA\u0CBF\u0CB8\u0CC1 %s',
+ 'stop %stopChoices':
+ '\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1 %stopChoices',
+ 'all':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE',
+ 'this script':
+ '\u0C87\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6',
+ 'this block':
+ '\u0C87\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97',
+ 'stop %stopOthersChoices':
+ '\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1 %stopOthersChoices',
+ 'all but this script':
+ '\u0C87\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CBF\u0C9F\u0CCD\u0C9F\u0CC1\u0020\u0CAE\u0CA4\u0CCD\u0CA4\u0CA6\u0CCD\u0CA6\u0CC6\u0CB2\u0CCD\u0CB2',
+ 'other scripts in sprite':
+ '\u0C87\u0020\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0CA3\u0CBF\u0CAF\u0CB2\u0CCD\u0CB2\u0CBF\u0020\u0C87\u0CA8\u0CCD\u0CA8\u0CBF\u0CA4\u0CB0\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0CC1',
+ 'pause all %pause':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1 %pause',
+ 'run %cmdRing %inputs':
+ '\u0C93\u0CA1\u0CBF\u0CB8\u0CC1 %cmdRing %inputs',
+ 'launch %cmdRing %inputs':
+ '\u0C89\u0CA1\u0CBE\u0CAF\u0CBF\u0CB8\u0CC1 %cmdRing %inputs',
+ 'call %repRing %inputs':
+ '\u0C95\u0CB0\u0CC6 %repRing %inputs',
+ 'run %cmdRing w/continuation':
+ '\u0C93\u0CA1\u0CBF\u0CB8\u0CC1 %cmdRing \u0C85\u0CA5\u0CB5\u0CBE\u0020\u0CAE\u0CC1\u0C82\u0CA6\u0CC1\u0CB5\u0CB0\u0CBF\u0C95\u0CC6',
+ 'call %cmdRing w/continuation':
+ '\u0C95\u0CB0\u0CC6 %cmdRing \u0C85\u0CA5\u0CB5\u0CBE\u0020\u0CAE\u0CC1\u0C82\u0CA6\u0CC1\u0CB5\u0CB0\u0CBF\u0C95\u0CC6',
+ 'warp %c':
+ '\u0CB8\u0CC1\u0CA4\u0CCD\u0CA4\u0CBF\u0CB9\u0CBE\u0C95\u0CC1 %c',
+ 'when I start as a clone':
+ '\u0CAF\u0CBE\u0CB5\u0CBE\u0C97\u0CB2\u0CBE\u0CA6\u0CB0\u0CC1\u0020\u0CA4\u0CA6\u0CCD\u0CB0\u0CC2\u0CAA\u0CC1\u0020\u0CA4\u0CB0\u0CB9\u0020\u0CAA\u0CCD\u0CB0\u0CBE\u0CB0\u0C82\u0CAD\u0CBF\u0CB8\u0CBF\u0CA6\u0CBE\u0C97',
+ 'create a clone of %cln':
+ '\u0CA8\u0C82\u0CA4\u0CC6\u0020\u0CA4\u0CA6\u0CCD\u0CB0\u0CC2\u0CAA\u0CC1\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0C9A\u0CBF\u0CB8\u0CBF\u000A %cln',
+ 'myself':
+ '\u0CB8\u0CCD\u0CB5\u0CA4\u0C83\u0020\u0CA8\u0CBE\u0CA8\u0CC1',
+ 'delete this clone':
+ '\u0CA4\u0CA6\u0CCD\u0CB0\u0CC2\u0CAA\u0CC1\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+
+ // sensing:
+ 'touching %col ?':
+ '\u0CAE\u0CC1\u0C9F\u0CCD\u0C9F\u0CBF\u0CA6\u0CB0\u0CC6 %col ?',
+ 'touching %clr ?':
+ '\u0CAE\u0CC1\u0C9F\u0CCD\u0C9F\u0CBF\u0CA6\u0CBE\u0C97 %clr ?',
+ 'color %clr is touching %clr ?':
+ '\u0CAC\u0CA3\u0CCD\u0CA3 %clr \u0C85\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAE\u0CC1\u0C9F\u0CCD\u0C9F\u0CBF\u0CA6\u0CBE\u0C97\u0020 %clr ?',
+ 'ask %s and wait':
+ '\u0C95\u0CC7\u0CB3\u0CC1 %s \u0CAE\u0CA4\u0CCD\u0CA4\u0CC1\u0020\u0CA8\u0CBF\u0CA7\u0CBE\u0CA8\u0CBF\u0CB8\u0CC1',
+ 'what\'s your name?':
+ '\u0CA8\u0CBF\u0CAE\u0CCD\u0CAE\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC7\u0CA8\u0CC1\u003F',
+ 'answer':
+ '\u0C89\u0CA4\u0CCD\u0CA4\u0CB0',
+ 'mouse x':
+ '\u0CAE\u0CCC\u0CB8\u0CCD\u0020\u0078',
+ 'mouse y':
+ '\u0CAE\u0CCC\u0CB8\u0CCD\u0020\u0079',
+ 'mouse down?':
+ '\u0CAE\u0CCC\u0CB8\u0CCD\u0020\u0CAE\u0CC1\u0C95\u0CCD\u0CA4?',
+ 'key %key pressed?':
+ '\u0C95\u0CC0 %key \u0C92\u0CA4\u0CCD\u0CA4\u0CBF\u0CA6\u0CBE\u0C97?',
+ 'distance to %dst':
+ '\u0C95\u0CCD\u0C95\u0CC6\u0020\u0CA6\u0CC2\u0CB0 %dst',
+ 'reset timer':
+ '\u0CB8\u0CAE\u0CAF\u0CB8\u0CC2\u0C9A\u0C95\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAE\u0CB0\u0CC1\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1',
+ 'timer':
+ '\u0CB8\u0CAE\u0CAF\u0CB8\u0CC2\u0C9A\u0C95',
+ '%att of %spr':
+ '%att \u0C87\u0CA6\u0CB0\u0CA6\u0CCD\u0CA6\u0CC1 %spr',
+ 'http:// %s':
+ 'http:// %s',
+ 'turbo mode?':
+ '\u0C97\u0CBE\u0CB3\u0CBF\u0020\u0CB5\u0CBF\u0CA7\u0CBE\u0CA8?',
+ 'set turbo mode to %b':
+ '\u0C97\u0CC6\u0020\u0C97\u0CBE\u0CB3\u0CBF\u0020\u0CB5\u0CBF\u0CA7\u0CBE\u0CA8\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CC1 %b',
+
+ 'filtered for %clr':
+ '\u0C87\u0CA6\u0C95\u0CCD\u0C95\u0CC6\u0020\u0CB6\u0CCB\u0CA7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 %clr',
+ 'stack size':
+ '\u0CAE\u0CC6\u0CA6\u0CC6\u0CAF\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0',
+ 'frames':
+ '\u0C9A\u0CCC\u0C95\u0C9F\u0CCD\u0C9F\u0CC1\u0C97\u0CB3\u0CC1',
+
+ // operators:
+ '%n mod %n':
+ '%n \u0CB6\u0CC7\u0CB7 %n',
+ 'round %n':
+ '\u0CB8\u0CB0\u0CBF\u0CAE\u0CBE\u0CA1\u0CC1 %n',
+ '%fun of %n':
+ '%fun \u0CB0\u0CA6\u0CCD\u0CA6\u0CC1 %n',
+ 'pick random %n to %n':
+ '\u0C8E\u0CB7\u0CCD\u0C9F\u0CA8\u0CBE\u0CA6\u0CB0\u0CC1\u0020\u0CAF\u0CBE\u0CA6\u0CC3\u0C9A\u0CBF\u0C95\u0CB5\u0CBE\u0C97\u0CBF\u0020\u0C86\u0CAF\u0CCD\u0CA6\u0CC1\u0C95\u0CCB %n \u0CB0\u0CBF\u0C82\u0CA6 %n',
+ '%b and %b':
+ '%b \u0CAE\u0CA4\u0CCD\u0CA4\u0CC1 %b',
+ '%b or %b':
+ '%b \u0C85\u0CA5\u0CB5\u0CBE %b',
+ 'not %b':
+ '\u0C87\u0CB2\u0CCD\u0CB2 %b',
+ '\u0CB8\u0CB0\u0CBF':
+ 'wahr',
+ 'false':
+ '\u0CA4\u0CAA\u0CCD\u0CAA\u0CC1',
+ 'join %words':
+ '\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CC1 %words',
+ 'split %s by %delim':
+ '\u0CAC\u0CC7\u0CB0\u0CC6\u0CAE\u0CBE\u0CA1\u0CC1 %s \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %delim',
+ 'hello':
+ '\u0CA8\u0CAE\u0CB8\u0CCD\u0C95\u0CBE\u0CB0',
+ 'world':
+ '\u0CAA\u0CCD\u0CB0\u0CAA\u0C82\u0C9A',
+ 'letter %n of %s':
+ '\u0C85\u0C95\u0CCD\u0CB7\u0CB0 %n \u0CB0\u0CB2\u0CCD\u0CB2\u0CBF %s',
+ 'length of %s':
+ '\u0CA8\u0020\u0C89\u0CA6\u0CCD\u0CA6 %s',
+ 'unicode of %s':
+ '\u0CB0\u0020\u0CAF\u0CC2\u0CA8\u0CBF\u0C95\u0CCB\u0CA1\u0CCD %s',
+ 'unicode %n as letter':
+ '\u0CAF\u0CC2\u0CA8\u0CBF\u0C95\u0CCB\u0CA1\u0CCD %n \u0CA8\u0020\u0C85\u0C95\u0CCD\u0CB7\u0CB0\u0020',
+ 'is %s a %typ ?':
+ '\u0C87\u0CA6\u0CC1 %s \u0C87\u0CA6\u0CB0\u0CA6\u0CC7 %typ ?',
+ 'is %s identical to %s ?':
+ '\u0C87\u0CA6\u0CC1 %s \u0C92\u0C82\u0CA6\u0CC7\u0020\u0CB0\u0CC0\u0CA4\u0CBF\u0CAF\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 %s ?',
+
+ 'type of %s':
+ '\u0CAC\u0C97\u0CC6\u0020 %s',
+
+ // variables:
+ 'Make a variable':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0020\u0CAE\u0CBE\u0CA1\u0CC1',
+ 'Variable name':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1',
+ 'Script variable name':
+ '\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0020\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1',
+ 'Delete a variable':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+
+ 'set %var to %s':
+ '\u0C97\u0CC6\u0020\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CC1 %var \u0C85\u0CA8\u0CCD\u0CA8\u0CC1 %s',
+ 'change %var by %n':
+ '\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %var \u0CB0\u0CB7\u0CCD\u0C9F\u0CC1 %n',
+ 'show variable %var':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CCB\u0CB0\u0CBF\u0CB8\u0CC1 %var',
+ 'hide variable %var':
+ '\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0C9A\u0CCD\u0C9A\u0CBF\u0CA1\u0CC1 %var',
+ 'script variables %scriptVars':
+ '\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0020\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0C95\u0C97\u0CB3\u0CC1 %scriptVars',
+
+ // lists:
+ 'list %exp':
+ '\u0CAA\u0C9F\u0CCD\u0C9F\u0CBF %exp',
+ '%s in front of %l':
+ '%s \u0CAE\u0CC1\u0C82\u0CA6\u0CC6 %l',
+ 'item %idx of %l':
+ '\u0C85\u0C82\u0CB6 %idx \u0CB0 %l',
+ 'all but first of %l':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0C86\u0CA6\u0CB0\u0CC6\u0020\u0CAE\u0CCA\u0CA6\u0CB2\u0CA8\u0CC6\u0CAF\u0CA6\u0CC1 %l',
+ 'length of %l':
+ '\u0CA8\u0020\u0C89\u0CA6\u0CCD\u0CA6 %l',
+ '%l contains %s':
+ '%l \u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CA6\u0CC6 %s',
+ 'thing':
+ '\u0C85\u0C82\u0CB6',
+ 'add %s to %l':
+ '\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CC1 %s \u0C97\u0CC6 %l',
+ 'delete %ida of %l':
+ '\u0C85\u0CB3\u0CBF\u0CB8\u0CC1 %ida \u0CA8 %l',
+ 'insert %s at %idx of %l':
+ '\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CC1 %s \u0CB0\u0CB2\u0CCD\u0CB2\u0CBF %idx \u0CA8 %l',
+ 'replace item %idx of %l with %s':
+ '\u0C85\u0C82\u0CB6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CB9\u0CBF\u0CB8\u0CC1 %idx \u0CB0 %l \u0C9C\u0CCA\u0CA4\u0CC6 %s',
+
+ // other
+ 'Make a block':
+ '\u0CB9\u0CCA\u0CB8\u0CA6\u0CBE\u0CA6\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97',
+
+ // menus
+ // snap menu
+ 'About...':
+ '\u0CB8\u0CC1\u0CA4\u0CCD\u0CA4\u0CAE\u0CC1\u0CA4\u0CCD\u0CA4\u0020!...',
+ 'Reference manual':
+ '\u0C89\u0CB2\u0CCD\u0CB2\u0CC7\u0C96\u0020\u0C95\u0CC8\u0CAA\u0CBF\u0CA1\u0CBF',
+ 'Snap! website':
+ 'Snap! \u0C9C\u0CBE\u0CB2\u0CA4\u0CBE\u0CA3',
+ 'Download source':
+ '\u0C86\u0CA7\u0CBE\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C87\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'Switch back to user mode':
+ '\u0CAC\u0CB3\u0C95\u0CC6\u0CA6\u0CBE\u0CB0\u0CB0\u0020\u0CA6\u0CBF\u0CB6\u0CC6\u0C97\u0CC6\u0020\u0CAE\u0CB0\u0CC1\u0C95\u0CB0\u0CB3\u0CBF\u0CB8\u0CBF',
+ 'disable deep-Morphic\ncontext menus\nand show user-friendly ones':
+ 'verl\u00e4sst Morphic',
+ 'Switch to dev mode':
+ '\u0CAC\u0CC6\u0CB3\u0CB5\u0CA3\u0CBF\u0C97\u0CC6\u0CAF\u0020\u0CA6\u0CBF\u0CB6\u0CC6\u0C97\u0CC6\u0020\u0CAE\u0CB0\u0CC1\u0C95\u0CB0\u0CB3\u0CBF\u0CB8\u0CBF',
+ 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!':
+ 'erm\u00f6glicht Morphic Funktionen',
+
+ // project menu
+ 'Project notes...':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0020\u0C9F\u0CBF\u0CAA\u0CCD\u0CAA\u0CA3\u0CBF\u0C97\u0CB3\u0CC1...',
+ 'New':
+ '\u0CB9\u0CCA\u0CB8',
+ 'Open...':
+ '\u0CA4\u0CC6\u0CB0\u0CC6...',
+ 'Save':
+ '\u0C89\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'Save As...':
+ '\u0C8E\u0C82\u0CA6\u0CC1\u0020\u0C89\u0CB3\u0CBF\u0CB8\u0CC1...',
+ 'Import...':
+ '\u0C86\u0CAE\u0CA6\u0CC1...',
+ 'file menu import hint':
+ '\u0C95\u0CA1\u0CA4\u0CA6\u0020\u0CAA\u0CB0\u0CBF\u0CB5\u0CBF\u0CA1\u0CBF\u0020\u0CB8\u0CC2\u0C9A\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CBF'
+ ,
+ 'Export project as plain text...':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB8\u0CCD\u0CAA\u0CB7\u0CCD\u0C9F\u0020\u0C85\u0C95\u0CCD\u0CB7\u0CB0\u0CA6\u0C82\u0CA4\u0CC6\u0020\u0CB0\u0CAA\u0CCD\u0CA4\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0CB0\u0CBF...',
+ 'Export project...':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0CAA\u0CCD\u0CA4\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0CB0\u0CBF...',
+ 'show project data as XML\nin a new browser window':
+ '\u0CB9\u0CCA\u0CB8\u0020\u0CB5\u0CC0\u0C95\u0CCD\u0CB7\u0C95\u0020\u0CA4\u0C82\u0CA4\u0CCD\u0CB0\u0CBE\u0C82\u0CB6\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF\u005C\u006E\u0020\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0020\u0CA6\u0CA4\u0CCD\u0CA4\u0CBE\u0C82\u0CB6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0058\u004D\u004C\u0020\u0CA8\u0C82\u0CA4\u0CC6\u0020\u0CA4\u0CCB\u0CB0\u0CBF\u0CB8\u0CBF\u0CB0\u0CBF\u0020',
+ 'Export blocks...':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0CAA\u0CCD\u0CA4\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0CB0\u0CBF...',
+ 'show global custom block definitions as XML\nin a new browser window':
+ '\u0CB9\u0CCA\u0CB8\u0020\u0CB5\u0CC0\u0C95\u0CCD\u0CB7\u0C95\u0020\u0CA4\u0C82\u0CA4\u0CCD\u0CB0\u0CBE\u0C82\u0CB6\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF\u005C\u006E\u0020\u0C9C\u0CBE\u0C97\u0CA4\u0CBF\u0C95\u0CB5\u0CBE\u0CA6\u0020\u0C97\u0CCD\u0CB0\u0CBE\u0CB9\u0C95\u0CC0\u0C95\u0CC3\u0CA4\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0020\u0CB5\u0CCD\u0CAF\u0CBE\u0C96\u0CCD\u0CAF\u0CC6\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC2\u0020\u0CA4\u0CCB\u0CB0\u0CBF\u0CB8\u0CBF\u0CB0\u0CBF\u0020',
+ 'Import tools':
+ '\u0C89\u0CAA\u0C95\u0CB0\u0CA3\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC2\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CBF\u0CB0\u0CBF',
+ 'load the official library of\npowerful blocks':
+ '\u0CB6\u0C95\u0CCD\u0CA4\u0CBF\u0CAF\u0CC1\u0CA4\u0CB5\u0CBE\u0CA6\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u005C\u006E\u0020\u0C85\u0CA7\u0CBF\u0C95\u0CC3\u0CA4\u0020\u0CAD\u0C82\u0CA1\u0CBE\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CC1\u0C82\u0CAC\u0CBF\u0CB8\u0CBF\u0CB0\u0CBF',
+ 'Libraries...':
+ '\u0CAD\u0C82\u0CA1\u0CBE\u0CB0...',
+ 'Import library':
+ '\u0CAD\u0C82\u0CA1\u0CBE\u0CB0\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CBF',
+
+ // cloud menu
+ 'Login...':
+ '\u0CAA\u0CCD\u0CB0\u0CB5\u0CC7\u0CB6\u0CBF\u0CB8\u0CC1...',
+ 'Signup...':
+ '\u0CB0\u0CC1\u0C9C\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CC1...',
+
+ // settings menu
+ 'Language...':
+ '\u0CAD\u0CBE\u0CB7\u0CC6...',
+ 'Zoom blocks...':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CBF\u0C97\u0CCD\u0C97\u0CBF\u0CB8\u0CC1...',
+ 'Stage size...':
+ '\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0...',
+ 'Stage size':
+ '\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C97\u0CBE\u0CA4\u0CCD\u0CB0',
+ 'Stage width':
+ '\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C85\u0C97\u0CB2\u0020',
+ 'Stage height':
+ '\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C89\u0CA6\u0CCD\u0CA6',
+ 'Default':
+ '\u0C97\u0CC8\u0CB0\u0CC1\u0CB9\u0CBE\u0C9C\u0CB0\u0CBF',
+ 'Blurred shadows':
+ '\u0C85\u0CB8\u0CCD\u0CAA\u0CB7\u0CCD\u0C9F\u0020\u0CA8\u0CC6\u0CB0\u0CB3\u0CC1',
+ 'uncheck to use solid drop\nshadows and highlights':
+ '\u0CA6\u0CC3\u0CA2\u0020\u0C87\u0CB3\u0CBF\u0CA4\u0020\u0C89\u0CAA\u0CAF\u0CCB\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA8\u0CBF\u0CB7\u0CCD\u0C95\u0CCD\u0CB0\u0CBF\u0CAF\u0CC6\u0C97\u0CCA\u0CB3\u0CBF\u0CB8\u0CBF\n\u0CA8\u0CC6\u0CB0\u0CB3\u0CC1\u0020\u0CAE\u0CA4\u0CCD\u0CA4\u0CC1\u0020\u0CB8\u0CC1\u0CAA\u0CCD\u0CB0\u0C95\u0CBE\u0CB6\u0C95',
+ 'check to use blurred drop\nshadows and highlights':
+ 'einschalten f\u00fcr harte Schatten\nund Beleuchtung',
+ 'Zebra coloring':
+ '\u0CAA\u0C9F\u0CCD\u0C9F\u0CC6\u0C95\u0CC1\u0CA6\u0CC1\u0CB0\u0CC6\u0020\u0CAC\u0CA3\u0CCD\u0CA3\u0020\u0CB9\u0C9A\u0CCD\u0C9A\u0CC1\u0CB5\u0CBF\u0C95\u0CC6',
+ 'check to enable alternating\ncolors for nested blocks':
+ 'einschalten \u00fcr abwechselnde Farbnuancen\nin Bl\u00f6cken',
+ 'uncheck to disable alternating\ncolors for nested block':
+ 'ausschalten verhindert abwechselnde\nFarbnuancen in Bl\u00f6cken',
+ 'Dynamic input labels':
+ 'Eingabenbeschriftung',
+ 'uncheck to disable dynamic\nlabels for variadic inputs':
+ 'ausschalten verhindert Beschriftung\nvon Mehrfacheingaben',
+ 'check to enable dynamic\nlabels for variadic inputs':
+ 'einschalten um Mehrfacheingabefelder\nautomatisch zu beschriften',
+ 'Prefer empty slot drops':
+ 'Leere Platzhalter bevorzugen',
+ 'settings menu prefer empty slots hint':
+ 'einschalten um leere Platzhalter\nbeim Platzieren von Bl\u00f6cken'
+ + 'zu bevorzugen',
+ 'uncheck to allow dropped\nreporters to kick out others':
+ 'ausschalten um das "Rauskicken"\nvon platzierten Bl\u00f6cken\n'
+ + 'zu erm\u00f6glichen',
+ 'Long form input dialog':
+ 'Ausf\u00fchrlicher Input-Dialog',
+ 'Plain prototype labels':
+ 'Einfache Prototyp-Beschriftung',
+ 'uncheck to always show (+) symbols\nin block prototype labels':
+ 'ausschalten, um (+) Zeichen\nim Blockeditor zu verbergen',
+ 'check to hide (+) symbols\nin block prototype labels':
+ 'einschalten, um (+) Zeichen\nim Blockeditor immer anzuzeigen',
+ 'check to always show slot\ntypes in the input dialog':
+ 'einschalten, um immer die Datentypen\nim Input-Dialog zu sehen',
+ 'uncheck to use the input\ndialog in short form':
+ 'ausschalten f\u00fcr kurzen\nInput-Dialog',
+ 'Virtual keyboard':
+ 'Virtuelle Tastatur',
+ 'uncheck to disable\nvirtual keyboard support\nfor mobile devices':
+ 'ausschalten um die virtuelle\nTastatur auf mobilen Ger\u00e4ten\n'
+ + 'zu sperren',
+ 'check to enable\nvirtual keyboard support\nfor mobile devices':
+ 'einschalten um die virtuelle\nTastatur auf mobilen Ger\u00e4ten\n'
+ + 'zu erm\u00f6glichen',
+ 'Input sliders':
+ 'Eingabeschieber',
+ 'uncheck to disable\ninput sliders for\nentry fields':
+ 'ausschalten um Schieber\nin Eingabefeldern zu verhindern',
+ 'check to enable\ninput sliders for\nentry fields':
+ 'einschalten um Schieber\nin Eingabefeldern zu aktivieren',
+ 'Clicking sound':
+ 'Akustisches Klicken',
+ 'uncheck to turn\nblock clicking\nsound off':
+ 'ausschalten um akustisches\nKlicken zu deaktivieren',
+ 'check to turn\nblock clicking\nsound on':
+ 'einschalten um akustisches\nKlicken zu aktivieren',
+ 'Animations':
+ 'Animationen',
+ 'uncheck to disable\nIDE animations':
+ 'ausschalten um IDE-\nAnimationen zu verhindern',
+ 'Turbo mode':
+ 'Turbomodus',
+ 'check to prioritize\nscript execution':
+ 'einschalten, um Skripte\nzu priorisieren',
+ 'uncheck to run scripts\nat normal speed':
+ 'ausschalten, um Skripte\nnormal auszuf\u00fchren',
+ 'check to enable\nIDE animations':
+ 'einschalten um IDE-\nAnimationen zu erlauben',
+ 'Thread safe scripts':
+ 'Threadsicherheit',
+ 'uncheck to allow\nscript reentrance':
+ 'verhindert, dass unvollendete\nSkripte erneut gestartet werden',
+ 'check to disallow\nscript reentrance':
+ 'verhindert, dass unvollendete\nSkripte erneut gestartet werden',
+ 'Prefer smooth animations':
+ 'Fixe Framerate',
+ 'uncheck for greater speed\nat variable frame rates':
+ 'ausschalten, um Animationen \ndynamischer auszuf\u00fchren',
+ 'check for smooth, predictable\nanimations across computers':
+ 'einschalten, damit Animationen\n\u00fcberall gleich laufen',
+ 'Flat line ends':
+ 'Flache Pinselstriche',
+ 'check for flat ends of lines':
+ 'einschalten f\u00fcr flache\nPinselstrichenden',
+ 'uncheck for round ends of lines':
+ 'auschalten f\u00fcr runde\nPinselstrichenden',
+
+ // inputs
+ 'with inputs':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C9C\u0CCA\u0CA4\u0CC6',
+ 'input names:':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1\u0C97\u0CB3\u0CC1:',
+ 'Input Names:':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1\u0C97\u0CB3\u0CC1:',
+ 'input list:':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CAA\u0C9F\u0CCD\u0C9F\u0CBF:',
+
+ // context menus:
+ 'help':
+ '\u0CB8\u0CB9\u0CBE\u0CAF',
+
+ // palette:
+ 'hide primitives':
+ 'Basisbl\u00f6cke ausblenden',
+ 'show primitives':
+ '\u0CAE\u0CC2\u0CB2\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC2\u0020\u0CAC\u0C9A\u0CCD\u0C9A\u0CBF\u0CA1\u0CBF',
+
+ // blocks:
+ 'help...':
+ '\u0CB8\u0CB9\u0CBE\u0CAF...',
+ 'relabel...':
+ '\u0CAE\u0CA4\u0CCD\u0CA4\u0CC6\u0020\u0CAC\u0CB0\u0CC6...',
+ 'duplicate':
+ '\u0CA8\u0C95\u0CB2\u0CC1',
+ 'make a copy\nand pick it up':
+ '\u0CA8\u0C95\u0CB2\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0020\u005C\u006E\u0CAE\u0CA4\u0CCD\u0CA4\u0CC1\u0020\u0CA4\u0CC6\u0C97\u0CC6\u0CA6\u0CC1\u0C95\u0CCA\u0CB3\u0CCD\u0CB3\u0CBF',
+ 'only duplicate this block':
+ '\u0C88\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAE\u0CBE\u0CA4\u0CCD\u0CB0\u0020\u0CA8\u0C95\u0CB2\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF',
+ 'delete':
+ '\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'script pic...':
+ '\u0C86\u0C97\u0CCD\u0CA8\u0CCD\u0CB9\u0CC6\u0CAF\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0...',
+ 'open a new window\nwith a picture of this script':
+ '\u0C88\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0CAF\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0CA6\u0020\u0C9C\u0CCA\u0CA4\u0CC6\u0020\u005C\u006E\u0CB9\u0CCA\u0CB8\u0020\u0C95\u0CBF\u0C9F\u0C95\u0CBF\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CC6\u0CB0\u0CC6',
+ 'ringify':
+ 'Umringen',
+ 'unringify':
+ 'Entringen',
+
+ // custom blocks:
+ 'delete block definition...':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CA6\u0020\u0CB5\u0CCD\u0CAF\u0CBE\u0C96\u0CCD\u0CAF\u0CC6\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC2\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CBF',
+ 'edit...':
+ '\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0020\u0CB8\u0C82\u0C95\u0CB2\u0CA8...',
+
+ // sprites:
+ 'edit':
+ '\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0020\u0CB8\u0C82\u0C95\u0CB2\u0CA8',
+ 'move':
+ '\u0C9A\u0CB2\u0CBF\u0CB8\u0CC1',
+ 'detach from':
+ '\u0C87\u0CA6\u0CB0\u0CBF\u0C82\u0CA6\u0020\u0C85\u0C97\u0CC1\u0CB2\u0CBF\u0CB8\u0CC1',
+ 'detach all parts':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0C97\u0CC1\u0CB2\u0CBF\u0CB8\u0CC1\u0020',
+ 'export...':
+ '\u0CB0\u0CAB\u0CCD\u0CA4\u0CC1\u0CAE\u0CBE\u0CA1\u0CC1...',
+
+ // stage:
+ 'show all':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CCB\u0CB0\u0CBF\u0CB8\u0CC1',
+ 'pic...':
+ '\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0...',
+ 'open a new window\nwith a picture of the stage':
+ '\u0C88\u0020\u0CB5\u0CC7\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0CA6\u0020\u0C9C\u0CCA\u0CA4\u0CC6\u005C\u006E\u0020\u0CB9\u0CCA\u0CB8\u0020\u0C95\u0CBF\u0C9F\u0C95\u0CBF\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CC6\u0CB0\u0CC6',
+
+ // scripting area
+ 'clean up':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CC1\u0020',
+ 'arrange scripts\nvertically':
+ '\u0CB2\u0C82\u0CAC\u0CB5\u0CBE\u0C97\u0CBF\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC2\u005C\u006E\u0020\u0020\u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0CB8\u0CBF\u0CB0\u0CBF\u0020',
+ 'add comment':
+ '\u0C9F\u0CC0\u0C95\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CBF\u0020',
+ 'undrop':
+ '\u0C85\u0CB5\u0CA8\u0CA4\u0CBF\u0020\u0CAE\u0CBE\u0CA1\u0CA6\u0020',
+ 'undo the last\nblock drop\nin this pane':
+ '\u0C88\u0020\u0CAB\u0CB2\u0C95\u0CA6\u0CB2\u0CCD\u0CB2\u0CBF\u005C\u006E\u0020\u0C95\u0CCA\u0CA8\u0CC6\u0CAF\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CA6\u005C\u006E\u0020\u0C85\u0CB5\u0CA8\u0CA4\u0CBF\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0CA6\u0CCD\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CC1',
+ 'scripts pic...':
+ '\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0CAF\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0020...',
+ 'open a new window\nwith a picture of all scripts':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0C86\u0C9C\u0CCD\u0C9E\u0CCD\u0CB9\u0CC6\u0C97\u0CB3\u0020\u0C9A\u0CBF\u0CA4\u0CCD\u0CB0\u0CA6\u0020\u0C9C\u0CCA\u0CA4\u0CC6\u005C\u006E\u0020\u0CB9\u0CCA\u0CB8\u0020\u0C95\u0CBF\u0C9F\u0C95\u0CBF\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CC6\u0CB0\u0CC6\u0020',
+ 'make a block...':
+ '\u0CB9\u0CCA\u0CB8\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0020...',
+
+ // costumes
+ 'rename':
+ '\u0CAA\u0CC1\u0CA8\u0CB0\u0CCD\u0CA8\u0CBE\u0CAE\u0C95\u0CB0\u0CA3',
+ 'export':
+ '\u0CB0\u0CAA\u0CCD\u0CA4\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CC1\u0020',
+ 'rename costume':
+ '\u0C89\u0CA1\u0CC1\u0CAA\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAA\u0CC1\u0CA8\u0CB0\u0CCD\u0CA8\u0CBE\u0CAE\u0C95\u0CB0\u0CA3\u0020\u0CAE\u0CBE\u0CA1\u0CC1\u0020',
+
+ // sounds
+ 'Play sound':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C95\u0CC7\u0CB3\u0CBF\u0CB8\u0CC1\u0020',
+ 'Stop sound':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1\u0020',
+ 'Stop':
+ '\u0CA8\u0CBF\u0CB2\u0CCD\u0CB2\u0CBF\u0CB8\u0CC1\u0020',
+ 'Play':
+ '\u0C95\u0CC7\u0CB3\u0CBF\u0CB8\u0CC1\u0020',
+ 'rename sound':
+ '\u0CB6\u0CAC\u0CCD\u0CA6\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAA\u0CC1\u0CA8\u0CB0\u0CCD\u0CA8\u0CBE\u0CAE\u0C95\u0CB0\u0CA3\u0020\u0CAE\u0CBE\u0CA1\u0CC1\u0020',
+
+ // dialogs
+ // buttons
+ 'OK':
+ '\u0CB8\u0CB0\u0CBF',
+ 'Ok':
+ '\u0CB8\u0CB0\u0CBF',
+ 'Cancel':
+ '\u0CB0\u0CA6\u0CCD\u0CA6\u0CC1\u0CAE\u0CBE\u0CA1\u0CC1',
+ 'Yes':
+ '\u0CB9\u0CCC\u0CA6\u0CC1',
+ 'No':
+ '\u0C87\u0CB2\u0CCD\u0CB2',
+
+ // help
+ 'Help':
+ '\u0CB8\u0CB9\u0CBE\u0CAF',
+
+ // zoom blocks
+ 'Zoom blocks':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CBF\u0C97\u0CCD\u0C97\u0CBF\u0CB8\u0CC1',
+ 'build':
+ '\u0CA8\u0CBF\u0CB0\u0CCD\u0CAE\u0CBF\u0CB8\u0CC1',
+ 'your own':
+ '\u0CA8\u0CBF\u0CAE\u0CCD\u0CAE\u0020\u0CB8\u0CCD\u0CB5\u0C82\u0CA4\u0CBF\u0C95\u0CC6',
+ 'blocks':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CC1',
+ 'normal (1x)':
+ '\u0CB8\u0CBE\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF (1x)',
+ 'demo (1.2x)':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CA4\u0CCD\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0C95\u0CC6 (1.2x)',
+ 'presentation (1.4x)':
+ '\u0CAA\u0CCD\u0CB0\u0CA6\u0CB0\u0CCD\u0CB6\u0CA8 (1.4x)',
+ 'big (2x)':
+ '\u0CA6\u0CCA\u0CA1\u0CCD\u0CA1\u0CA6\u0CC1 (2x)',
+ 'huge (4x)':
+ '\u0C85\u0CA7\u0CBF\u0C95 (4x)',
+ 'giant (8x)':
+ '\u0020\u0CA6\u0CC8\u0CA4\u0CCD\u0CAF (8x)',
+ 'monstrous (10x)':
+ '\u0C98\u0CCB\u0CB0\u0CBE\u0C95\u0CBE\u0CB0\u0CA6 (10x)',
+
+ // Project Manager
+ 'Untitled':
+ '\u0CB9\u0CC6\u0CB8\u0CB0\u0CBF\u0CA1\u0CA6\u0020',
+ 'Open Project':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CA4\u0CC6\u0CB0\u0CC6\u0020',
+ '(empty)':
+ '(\u0C96\u0CBE\u0CB2\u0CBF)',
+ 'Saved!':
+ '\u0C89\u0CB3\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6!',
+ 'Delete Project':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'Are you sure you want to delete':
+ '\u0CA8\u0CC0\u0CB5\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CB2\u0CC1\u0020\u0CB8\u0CBF\u0CA6\u0CCD\u0CA7\u0CB5\u0CBE\u0C97\u0CBF\u0CA6\u0CCD\u0CA6\u0CBF\u0CB0\u0CBE?',
+ 'rename...':
+ '\u0CAA\u0CC1\u0CA8\u0CB0\u0CCD\u0CA8\u0CBE\u0CAE\u0C95\u0CB0\u0CA3...',
+
+ // costume editor
+ 'Costume Editor':
+ '\u0C89\u0CA1\u0CC1\u0CAA\u0CBF\u0CA8\u0020\u0CB8\u0C82\u0CAA\u0CBE\u0CA6\u0C95',
+ 'click or drag crosshairs to move the rotation center':
+ 'Fadenkreuz anklicken oder bewegen um den Drehpunkt zu setzen',
+
+ // project notes
+ 'Project Notes':
+ '\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0020\u0C9F\u0CBF\u0CAA\u0CCD\u0CAA\u0CA3\u0CBF\u0C97\u0CB3\u0CC1',
+
+ // new project
+ 'New Project':
+ '\u0CB9\u0CCA\u0CB8\u0020\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6',
+ 'Replace the current project with a new one?':
+ '\u0CB9\u0CC0\u0C97\u0CBF\u0CA8\u0020\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB9\u0CCA\u0CB8\u0CA6\u0CB0\u0020\u0C9C\u0CCA\u0CA4\u0CC6\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CAF\u0CBF\u0CB8\u0CBF\u0020?',
+
+ // save project
+ 'Save Project As...':
+ '\u0020\u0CAA\u0CCD\u0CB0\u0CBE\u0CAF\u0CCB\u0C9C\u0CA8\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C8E\u0C82\u0CA6\u0CC1\u0020\u0C89\u0CB3\u0CBF\u0CB8\u0CBF\u0020...',
+
+ // export blocks
+ 'Export blocks':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0CAA\u0CCD\u0CA4\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0CB0\u0CBF\u0020',
+ 'Import blocks':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C86\u0CAE\u0CA6\u0CC1\u0020\u0CAE\u0CBE\u0CA1\u0CBF\u0CB0\u0CBF\u0020',
+ 'this project doesn\'t have any\ncustom global blocks yet':
+ 'in diesem Projekt gibt es noch keine\nglobalen Bl\u00f6cke',
+ 'select':
+ '\u0C86\u0CAF\u0CCD\u0C95\u0CC6\u0020',
+ 'none':
+ '\u0CAF\u0CBE\u0CB5\u0CC1\u0CA6\u0CC2\u0020\u0C87\u0CB2\u0CCD\u0CB2',
+
+ // variable dialog
+ 'for all sprites':
+ '\u0C8E\u0CB2\u0CCD\u0CB2\u0CBE\u0020\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0CA3\u0CBF\u0C97\u0CB3\u0CBF\u0C97\u0CC6',
+ 'for this sprite only':
+ '\u0C88\u0020\u0CAF\u0C95\u0CCD\u0CB7\u0CBF\u0CA3\u0CBF\u0C97\u0CC6\u0020\u0CAE\u0CBE\u0CA4\u0CCD\u0CB0\u0020',
+
+ // block dialog
+ 'Change block':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CAC\u0CA6\u0CB2\u0CBE\u0CAF\u0CBF\u0CB8\u0CBF\u0020',
+ 'Command':
+ '\u0C86\u0CA6\u0CC7\u0CB6',
+ 'Reporter':
+ '\u0CB5\u0CB0\u0CA6\u0CBF\u0C97\u0CBE\u0CB0',
+ 'Predicate':
+ '\u0CB5\u0CBF\u0C9C\u0CCD\u0C9D\u0CCD\u0CA8\u0CCD\u0CAF\u0CBE\u0CAA\u0CBF\u0CB8\u0CC1',
+
+ // block editor
+ 'Block Editor':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0C97\u0CB3\u0020\u0CB8\u0C82\u0CAA\u0CBE\u0CA6\u0C95',
+ 'Apply':
+ '\u0C85\u0CA8\u0CCD\u0CB5\u0CAF\u0CBF\u0CB8\u0CC1',
+
+ // block deletion dialog
+ 'Delete Custom Block':
+ '\u0CB8\u0CCD\u0CB5\u0CAF\u0C82\u0020\u0CA8\u0CBF\u0CB0\u0CCD\u0CAE\u0CBF\u0CA4\u0020\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CBF',
+ 'block deletion dialog text':
+ '\u0CB5\u0CBF\u0CAD\u0CBE\u0C97\u0020\u0C85\u0CB3\u0CBF\u0CB8\u0CAC\u0CC7\u0C95\u0CBE\u0CA6\u0020\u0CB8\u0C82\u0CAD\u0CBE\u0CB7\u0CA3\u0CBE\u0020\u0CAA\u0CA0\u0CCD\u0CAF',
+
+ // input dialog
+ 'Create input name':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0C9A\u0CBF\u0CB8\u0CBF',
+ 'Edit input name':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB8\u0C82\u0CAA\u0CBE\u0CA6\u0CBF\u0CB8\u0CC1',
+ 'Edit label fragment':
+ '\u0CA4\u0CB2\u0CC6\u0C9A\u0CC0\u0C9F\u0CBF\u0CAF\u0020\u0C9A\u0CC2\u0CB0\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB8\u0C82\u0CAA\u0CBE\u0CA6\u0CBF\u0CB8\u0CC1',
+ 'Title text':
+ '\u0CB6\u0CC0\u0CB0\u0CCD\u0CB7\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0C85\u0C95\u0CCD\u0CB7\u0CB0\u0020',
+ 'Input name':
+ '\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0CAF\u0020\u0CB9\u0CC6\u0CB8\u0CB0\u0CC1',
+ 'Delete':
+ '\u0C85\u0CB3\u0CBF\u0CB8\u0CC1',
+ 'Object':
+ '\u0CB5\u0CB8\u0CCD\u0CA4\u0CC1',
+ 'Number':
+ '\u0C85\u0C82\u0C95\u0CBF',
+ 'Text':
+ '\u0CAA\u0CA0\u0CCD\u0CAF',
+ 'List':
+ '\u0CAA\u0C9F\u0CCD\u0C9F\u0CBF',
+ 'Any type':
+ '\u0CAF\u0CBE\u0CB5\u0CC1\u0CA6\u0CBE\u0CA6\u0CB0\u0CC1\u0020\u0CAE\u0CBE\u0CA6\u0CB0\u0CBF',
+ 'Boolean (T/F)':
+ '\u0CAC\u0CC2\u0CB2\u0CBF\u0CAF\u0CA8\u0CCD (\u0CB8\u0CB0\u0CBF\u002F\u0CA4\u0CAA\u0CCD\u0CAA\u0CC1)',
+ 'Command\n(inline)':
+ '\u0C86\u0CA6\u0CC7\u0CB6\n(\u0CAE\u0CA7\u0CCD\u0CAF\u0CB8\u0CCD\u0CA5\u0020)',
+ 'Command\n(C-shape)':
+ '\u0C86\u0CA6\u0CC7\u0CB6\n(\u0CB8\u0CBF-\u0C86\u0C95\u0CC3\u0CA4\u0CBF)',
+ 'Any\n(unevaluated)':
+ '\u0CAF\u0CBE\u0CB5\u0CC1\u0CA6\u0CBE\u0CA6\u0CB0\u0CC1\u0020\n(\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF\u0CC0\u0C95\u0CB0\u0CBF\u0CB8\u0CA6)',
+ 'Boolean\n(unevaluated)':
+ '\u0CAC\u0CC2\u0CB2\u0CBF\u0CAF\u0CA8\u0CCD\n(\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF\u0CC0\u0C95\u0CB0\u0CBF\u0CB8\u0CA6)',
+ 'Single input.':
+ '\u0C92\u0C82\u0CA6\u0CC7\u0020\u0C92\u0C82\u0CA6\u0CC1\u0020\u0C8A\u0CA1\u0CBF\u0C95\u0CC6\u0020.',
+ 'Default Value:':
+ '\u0C97\u0CC8\u0CB0\u0CC1\u0CB9\u0CBE\u0C9C\u0CB0\u0CBF\u0020\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF:',
+ 'Multiple inputs (value is list of inputs)':
+ '\u0CAC\u0CB9\u0CC1\u0CB0\u0CC0\u0CA4\u0CBF\u0CAF\u0020\u0C8A\u0CA1\u0CBF\u0C95\u0CC6 (\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF\u0CB5\u0CC1\u0020\u0C92\u0C82\u0CA6\u0C95\u0CBF\u0C82\u0CA4\u0020\u0CB9\u0CC6\u0C9A\u0CCD\u0C9A\u0CBE\u0C97\u0CBF\u0CA6\u0CC6)',
+ 'Upvar - make internal variable visible to caller':
+ '\u0CB9\u0CCA\u0CB0\u0C97\u0CA1\u0CC6\u0020\u0CAA\u0CB0\u0CBF\u0CB5\u0CB0\u0CCD\u0CA4\u0C95\u0CB5\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0CB0\u0C9A\u0CBF\u0CB8\u0CC1\u0CB5\u0CC1\u0CA6\u0CB0\u0CBF\u0C82\u0CA6\u0020\u0CAC\u0CC7\u0C9F\u0CBF\u0C97\u0CBE\u0CB0\u0CB0\u0CBF\u0C97\u0CC6\u0020\u0C95\u0CBE\u0CA3\u0CAC\u0CB9\u0CC1\u0CA6\u0CC1\u0020',
+
+ // About Snap
+ 'About Snap':
+ '\u0CB8\u0CCD\u0CA8\u0CCD\u0CAF\u0CBE\u0CAA\u0CCD\u0020\u0020\u0CA8\u0020\u0CAC\u0C97\u0CCD\u0C97\u0CC6\u0020',
+ 'Back...':
+ '\u0CB9\u0CBF\u0C82\u0CA6\u0CC6...',
+ 'License...':
+ '\u0C85\u0CA8\u0CC1\u0CAE\u0CA4\u0CBF...',
+ 'Modules...':
+ '\u0C85\u0CA7\u0CCD\u0CAF\u0CBE\u0CAF\u0C97\u0CB3\u0CC1...',
+ 'Credits...':
+ '\u0CAA\u0CCD\u0CB0\u0CA4\u0CCD\u0CAF\u0CAF\u0C97\u0CB3\u0CC1...',
+ 'Translators...':
+ '\u0CAD\u0CBE\u0CB7\u0CBE\u0C82\u0CA4\u0CB0\u0C95\u0CBE\u0CB0...',
+ 'License':
+ '\u0C85\u0CA8\u0CC1\u0CAE\u0CA4\u0CBF',
+ 'current module versions:':
+ '\u0CB9\u0CC0\u0C97\u0CBF\u0CA8\u0020\u0C85\u0CA7\u0CCD\u0CAF\u0CBE\u0CAF\u0CA6\u0020\u0C86\u0CB5\u0CC3\u0CA4\u0CCD\u0CA4\u0CBF',
+ 'Contributors':
+ '\u0CB8\u0CB9\u0CBE\u0CAF\u0C95',
+ 'Translations':
+ '\u0CAD\u0CBE\u0CB7\u0CBE\u0C82\u0CA4\u0CB0\u0C95\u0CBE\u0CB0',
+
+ // variable watchers
+ 'normal':
+ '\u0CB8\u0CBE\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF',
+ 'large':
+ '\u0CA6\u0CCA\u0CA1\u0CCD\u0CA1\u0CA6\u0CC1',
+ 'slider':
+ '\u0C9C\u0CBE\u0CB0\u0CC1\u0020\u0CA8\u0CBF\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0C95',
+ 'slider min...':
+ '\u0C95\u0CA1\u0CBF\u0CAE\u0CC6\u0020\u0C9C\u0CBE\u0CB0\u0CC1\u0020\u0CA8\u0CBF\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0C95...',
+ 'slider max...':
+ '\u0C85\u0CA7\u0CBF\u0C95\u0020\u0C9C\u0CBE\u0CB0\u0CC1\u0020\u0CA8\u0CBF\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0C95...',
+ 'import...':
+ '\u0C86\u0CAE\u0CA6\u0CC1...',
+ 'Slider minimum value':
+ '\u0C9C\u0CBE\u0CB0\u0CC1\u0020\u0CA8\u0CBF\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0C95\u0CA6\u0020\u0C95\u0CA1\u0CBF\u0CAE\u0CC6\u0020\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF',
+ 'Slider maximum value':
+ '\u0C9C\u0CBE\u0CB0\u0CC1\u0020\u0CA8\u0CBF\u0CAF\u0C82\u0CA4\u0CCD\u0CB0\u0C95\u0CA6\u0020\u0C85\u0CA7\u0CBF\u0C95\u0020\u0CAE\u0CCC\u0CB2\u0CCD\u0CAF',
+
+ // list watchers
+ 'length: ':
+ '\u0C89\u0CA6\u0CCD\u0CA6: ',
+
+ // coments
+ 'add comment here...':
+ '\u0C9F\u0CC0\u0C95\u0CC6\u0CAF\u0CA8\u0CCD\u0CA8\u0CC1\u0020\u0C87\u0CB2\u0CCD\u0CB2\u0CBF\u0020\u0C95\u0CC2\u0CA1\u0CBF\u0CB8\u0CBF\u0020',
+
+ // drow downs
+ // directions
+ '(90) right':
+ '(90) \u0CAC\u0CB2\u0020\u0CAD\u0CBE\u0C97\u0020',
+ '(-90) left':
+ '(-90) \u0C8E\u0CA1\u0020\u0CAD\u0CBE\u0C97',
+ '(0) up':
+ '(0) \u0CAE\u0CC7\u0CB2\u0CC6',
+ '(180) down':
+ '(180) \u0C95\u0CC6\u0CB3\u0C97\u0CA1\u0CC6',
+
+ // collision detection
+ 'mouse-pointer':
+ '\u0CB8\u0CC2\u0C9A\u0C95\u0CB8\u0CBE\u0CA7\u0CA8\u0020\u0CAE\u0CCC\u0CB8\u0CCD',
+ 'edge':
+ '\u0C85\u0C82\u0C9A\u0CC1',
+ 'pen trails':
+ '\u0CB2\u0CC7\u0C96\u0CA8\u0CBF\u0CAF\u0020\u0CAA\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CA3\u0CC6',
+
+ // costumes
+ 'Turtle':
+ '\u0C86\u0CAE\u0CC6',
+ 'Empty':
+ '\u0C96\u0CBE\u0CB2\u0CBF',
+
+ // graphical effects
+ 'brightness':
+ '\u0CAA\u0CCD\u0CB0\u0C95\u0CBE\u0CB6\u0CAE\u0CBE\u0CA8',
+ 'ghost':
+ '\u0CA6\u0CC6\u0CB5\u0CCD\u0CB5',
+ 'negative':
+ '\u0CA8\u0C95\u0CBE\u0CB0\u0CBE\u0CA4\u0CCD\u0CAE\u0C95',
+ 'comic':
+ '\u0CB9\u0CBE\u0CB8\u0CCD\u0CAF',
+ 'confetti':
+ 'Farbverschiebung',
+
+ // keys
+ 'space':
+ '\u0C9C\u0CBE\u0C97\u0020',
+ 'up arrow':
+ '\u0CAE\u0CC7\u0CB2\u0CBF\u0CA8\u0CAC\u0CBE\u0CA3',
+ 'down arrow':
+ '\u0C95\u0CC6\u0CB3\u0CAE\u0CC1\u0C96\u0020\u0CAC\u0CBE\u0CA3',
+ 'right arrow':
+ '\u0CAC\u0CB2\u0020\u0CAC\u0CBE\u0CA3',
+ 'left arrow':
+ '\u0C8E\u0CA1\u0020\u0CAC\u0CBE\u0CA3',
+ 'a':
+ 'a',
+ 'b':
+ 'b',
+ 'c':
+ 'c',
+ 'd':
+ 'd',
+ 'e':
+ 'e',
+ 'f':
+ 'f',
+ 'g':
+ 'g',
+ 'h':
+ 'h',
+ 'i':
+ 'i',
+ 'j':
+ 'j',
+ 'k':
+ 'k',
+ 'l':
+ 'l',
+ 'm':
+ 'm',
+ 'n':
+ 'n',
+ 'o':
+ 'o',
+ 'p':
+ 'p',
+ 'q':
+ 'q',
+ 'r':
+ 'r',
+ 's':
+ 's',
+ 't':
+ 't',
+ 'u':
+ 'u',
+ 'v':
+ 'v',
+ 'w':
+ 'w',
+ 'x':
+ 'x',
+ 'y':
+ 'y',
+ 'z':
+ 'z',
+ '0':
+ '0',
+ '1':
+ '1',
+ '2':
+ '2',
+ '3':
+ '3',
+ '4':
+ '4',
+ '5':
+ '5',
+ '6':
+ '6',
+ '7':
+ '7',
+ '8':
+ '8',
+ '9':
+ '9',
+
+ // messages
+ 'new...':
+ '\u0CB9\u0CCA\u0CB8...',
+
+ // math functions
+ 'abs':
+ 'Betrag',
+ 'floor':
+ 'Abgerundet',
+ 'sqrt':
+ 'Wurzel',
+ 'sin':
+ 'sin',
+ 'cos':
+ 'cos',
+ 'tan':
+ 'tan',
+ 'asin':
+ 'asin',
+ 'acos':
+ 'acos',
+ 'atan':
+ 'atan',
+ 'ln':
+ 'ln',
+ 'e^':
+ 'e^',
+
+ // delimiters
+ 'letter':
+ '\u0C85\u0C95\u0CCD\u0CB7\u0CB0',
+ 'whitespace':
+ '\u0C96\u0CBE\u0CB2\u0CBF\u0C9C\u0CBE\u0C97',
+ 'line':
+ '\u0CB8\u0CBE\u0CB2\u0CC1',
+ 'tab':
+ '\u0020\u0C95\u0CC0\u0CB2\u0CBF',
+ 'cr':
+ '\u0CB8\u0CBF\u0C85\u0CB0\u0CCD',
+
+ // data types
+ 'number':
+ '\u0C85\u0C82\u0C95\u0CBF:',
+ 'text':
+ '\u0CAA\u0CA0\u0CCD\u0CAF',
+ 'Boolean':
+ '\u0CAC\u0CC2\u0CB2\u0CBF\u0CAF\u0CA8\u0CCD',
+ 'list':
+ '\u0CAA\u0C9F\u0CCD\u0C9F\u0CBF',
+ 'command':
+ '\u0C86\u0CA6\u0CC7\u0CB6\u0020',
+ 'reporter':
+ '\u0CB5\u0CB0\u0CA6\u0CBF\u0C97\u0CBE\u0CB0',
+ 'predicate':
+ '\u0CB5\u0CBF\u0C9C\u0CCD\u0C9D\u0CCD\u0CA8\u0CCD\u0CAF\u0CBE\u0CAA\u0CBF\u0CB8\u0CC1',
+
+ // list indices
+ 'last':
+ '\u0C95\u0CCA\u0CA8\u0CC6',
+ 'any':
+ '\u0CAF\u0CBE\u0CB5\u0CC1\u0CA6\u0CBE\u0CA6\u0CB0\u0CC1\u0020'
+};
@@ -650,11 +650,12 @@ SnapTranslator.dict.pt = { 'Save As...': 'Guardar este projecto como…', 'Import...': - 'Importar para este projecto…', + 'Importar…', 'file menu import hint': - 'Importar para este projecto\num projecto exportado,\n' - + 'uma biblioteca de blocos,\n' - + 'um traje ou um som.', + 'Abrir um projecto exportado,\n' + + 'substitundo o projecto corrente, ou\n' + + 'importar uma biblioteca de blocos, um\n' + + 'traje ou um som para o projecto corrente.', 'Export project as plain text...': 'Exportar este projecto como texto simples…', 'Export project...': @@ -1616,7 +1617,7 @@ SnapTranslator.dict.pt = { 'unshared.': 'deixado de partilhar.', 'Unshare': - 'Deixar de Partilhar', + 'Não Partilhar', 'password has been changed.': 'a sua palavra-passe foi alterada.', 'SVG costumes are\nnot yet fully supported\nin every browser': @@ -1641,6 +1642,18 @@ SnapTranslator.dict.pt = { 'Seleccionar um traje da biblioteca de média.', 'edit rotation point only...': 'editar apenas ponto de rotação…', + 'Export Project As...': + 'Exportar Projecto Como…', + 'a variable of name \'': + 'não existe uma variável «', + '\'\ndoes not exist in this context': + '»\nneste contexto', + '(temporary)': + '(temporária)', + 'expecting': + 'esperavam-se', + 'input(s), but getting': + 'argumento(s), mas foram passados', // produção de código 'map %cmdRing to %codeKind %code': diff --git a/lang-sv.js b/lang-sv.js new file mode 100644 index 0000000..382f2bd --- /dev/null +++ b/lang-sv.js @@ -0,0 +1,1359 @@ +/* + + lang-sv.js + + Swedish translation for SNAP! + + written by Erik A Olsson + + Copyright (C) 2014 by Jens Mönig + + This file is part of Snap!. + + Snap! is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + + + Note to Translators: + -------------------- + At this stage of development, Snap! can be translated to any LTR language + maintaining the current order of inputs (formal parameters in blocks). + + Translating Snap! is easy: + + + 1. Download + + Download the sources and extract them into a local folder on your + computer: + + <http://snap.berkeley.edu/snapsource/snap.zip> + + Use the German translation file (named 'lang-de.js') as template for your + own translations. Start with editing the original file, because that way + you will be able to immediately check the results in your browsers while + you're working on your translation (keep the local copy of snap.html open + in your web browser, and refresh it as you progress with your + translation). + + + 2. Edit + + Edit the translation file with a regular text editor, or with your + favorite JavaScript editor. + + In the first non-commented line (the one right below this + note) replace "de" with the two-letter ISO 639-1 code for your language, + e.g. + + fr - French => SnapTranslator.dict.fr = { + it - Italian => SnapTranslator.dict.it = { + pl - Polish => SnapTranslator.dict.pl = { + pt - Portuguese => SnapTranslator.dict.pt = { + es - Spanish => SnapTranslator.dict.es = { + el - Greek => => SnapTranslator.dict.el = { + + etc. (see <http://en.wikipedia.org/wiki/ISO_639-1>) + + + 3. Translate + + Then work through the dictionary, replacing the German strings against + your translations. The dictionary is a straight-forward JavaScript ad-hoc + object, for review purposes it should be formatted as follows: + + { + 'English string': + 'Translation string', + 'last key': + } 'last value' + + and you only edit the indented value strings. Note that each key-value + pair needs to be delimited by a comma, but that there shouldn't be a comma + after the last pair (again, just overwrite the template file and you'll be + fine). + + If something doesn't work, or if you're unsure about the formalities you + should check your file with + <http://JSLint.com> + + + This will inform you about any missed commas etc. + + + 4. Accented characters + + Depending on which text editor and which file encoding you use you can + directly enter special characters (e.g. Umlaut, accented characters) on + your keyboard. However, I've noticed that some browsers may not display + special characters correctly, even if other browsers do. So it's best to + check your results in several browsers. If you want to be on the safe + side, it's even better to escape these characters using Unicode. + + see: <http://0xcc.net/jsescape/> + + + 5. Block specs: + + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + + + 6. Submit + + When you're done, rename the edited file by replacing the "de" part of the + filename with the two-letter ISO 639-1 code for your language, e.g. + + fr - French => lang-fr.js + it - Italian => lang-it.js + pl - Polish => lang-pl.js + pt - Portuguese => lang-pt.js + es - Spanish => lang-es.js + el - Greek => => lang-el.js + + and send it to me for inclusion in the official Snap! distribution. + Once your translation has been included, Your name will the shown in the + "Translators" tab in the "About Snap!" dialog box, and you will be able to + directly launch a translated version of Snap! in your browser by appending + + lang:xx + + to the URL, xx representing your translations two-letter code. + + + 7. Known issues + + In some browsers accents or ornaments located in typographic ascenders + above the cap height are currently (partially) cut-off. + + Enjoy! + -Jens +*/ + +/*global SnapTranslator*/ + +SnapTranslator.dict.sv = { + +/* + Special characters: (see <http://0xcc.net/jsescape/>) + + å , \u00E5 + ä , \u00E4 + ö , \u00F6 + Å , \u00C5 + Ä ; \u00C4 + Ö , \u00D6 +*/ + + // translations meta information + 'language_name': + 'svenska', // the name as it should appear in the language menu + 'language_translator': + 'Erik A Olsson', // your name for the Translators tab + 'translator_e-mail': + 'eolsson@gmail.com', // optional + 'last_changed': + '2014-11-01', // this, too, will appear in the Translators tab + + // GUI + // control bar: + 'untitled': + 'namnl\u00F6s', + 'development mode': + 'utvecklarel\u00E4ge', + + // categories: + 'Motion': + 'R\u00F6relse', + 'Looks': + 'Utseende', + 'Sound': + 'Ljud', + 'Pen': + 'Penna', + 'Control': + 'Kontroll', + 'Sensing': + 'K\u00E4nna av', + 'Operators': + 'Operatorer', + 'Variables': + 'Variabler', + 'Lists': + 'Listor', + 'Other': + 'Annat', + + // editor: + 'draggable': + 'flyttbar', + + // tabs: + 'Scripts': + 'Skript', + 'Costumes': + 'Kostymer', + 'Sounds': + 'Ljud', + + // names: + 'Sprite': + 'Sprite', + 'Stage': + 'Scen', + + // rotation styles: + 'don\'t rotate': + 'rotera inte', + 'can rotate': + 'rotera', + 'only face left/right': + 'peka bara h\u00F6ger/v\u00E4nster', + + // new sprite button: + 'add a new Sprite': + 'l\u00E4gg till ny Sprite', + + // tab help + 'costumes tab help': + 'importera en bild fr\u00E5n en annan webbsida eller fr\u00E5n\nen fil på din dator genom att dra den hit', + + 'import a sound from your computer\nby dragging it into here': + 'importera en ljudfil fr\u00E5n din dator\ngenom att dra den hit', + +// primitive blocks: + + /* + Attention Translators: + ---------------------- + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + */ + + // motion: + 'Stage selected:\nno motion primitives': + 'Scen vald:\ninga standard r\u00F6relser' + + 'finns', + 'move %n steps': + 'g\u00E5 %n steg', + 'turn %clockwise %n degrees': + 'v\u00E4nd %clockwise %n grader', + 'turn %counterclockwise %n degrees': + 'v\u00E4nd %counterclockwise %n grader', + 'point in direction %dir': + 'peka mot riktning %dir', + 'point towards %dst': + 'peka mot %dst', + 'go to x: %n y: %n': + 'g\u00E5 till x: %n y: %n', + 'go to %dst': + 'g\u00E5 till %dst', + 'glide %n secs to x: %n y: %n': + 'glid %n sek till x: %n y: %n', + 'change x by %n': + '\u00E4ndra x med %n', + 'set x to %n': + 's\u00E4tt x till %n', + 'change y by %n': + '\u00E4ndra y med %n', + 'set y to %n': + 's\u00E4tt y till %n', + 'if on edge, bounce': + 'studsa om vid kanten', + 'x position': + 'x-position', + 'y position': + 'y-position', + 'direction': + 'riktning', + + // looks: + 'switch to costume %cst': + 'byt till kostym %cst', + 'next costume': + 'n\u00E4sta kostym', + 'costume #': + 'kostym nr.', + 'say %s for %n secs': + 's\u00E4g %s i %n sek', + 'say %s': + 's\u00E4g %s', + 'think %s for %n secs': + 't\u00E4nk %s i %n sek', + 'think %s': + 't\u00E4nk %s', + 'Hello!': + 'Hej!', + 'Hmm...': + 'Hmm...', + 'change %eff effect by %n': + '\u00E4ndra %eff -effekt med %n', + 'set %eff effect to %n': + 's\u00E4tt %eff -effekt til %n', + 'clear graphic effects': + 'nollst\u00E4ll grafiska effekter', + 'change size by %n': + '\u00E4ndra storlek med %n', + 'set size to %n %': + 's\u00E4tt storlek till %n %', + 'size': + 'storlek', + 'show': + 'visa', + 'hide': + 'g\u00F6m', + 'go to front': + 'l\u00E4gg \u00F6verst', + 'go back %n layers': + 'flytta %n lager bak\u00E5t', + + 'development mode \ndebugging primitives:': + 'utvecklarl\u00E4ge \nDebugging av block', + 'console log %mult%s': + 'skriv till konsoll: %mult%s', + 'alert %mult%s': + 'Pop-up: %mult%s', + + // sound: + 'play sound %snd': + 'spela ljud %snd', + 'play sound %snd until done': + 'spela ljud %snd tills f\u00E4rdig', + 'stop all sounds': + 'stoppa alla ljud', + 'rest for %n beats': + 'pausa %n slag', + 'play note %n for %n beats': + 'spela ton %n i %n slag', + 'change tempo by %n': + '\u00E4ndra tempo med %n', + 'set tempo to %n bpm': + 's\u00E4tt tempo till %n bpm', + 'tempo': + 'tempo', + + // pen: + 'clear': + 'rensa', + 'pen down': + 'penna ned', + 'pen up': + 'penna upp', + 'set pen color to %clr': + 's\u00E4tt pennf\u00E4rg till %clr', + 'change pen color by %n': + '\u00E4ndra pennf\u00E4rg till %n', + 'set pen color to %n': + 's\u00E4tt penf\u00E4rg till %n', + 'change pen shade by %n': + '\u00E4ndra pennstyrka med %n', + 'set pen shade to %n': + 's\u00E4tt pennstyrka till %n', + 'change pen size by %n': + '\u00E4ndra penntjocklek med %n', + 'set pen size to %n': + 's\u00E4tt penntjocklek til %n', + 'stamp': + 'st\u00E4mpla', + + // control: + 'when %greenflag clicked': + 'n\u00E4r %greenflag klickas p\u00E5', + 'when %key key pressed': + 'n\u00E4r tangent %key trycks ned', + 'when I am clicked': + 'n\u00E4r jag klickas p\u00E5', + 'when I receive %msg': + 'n\u00E4r jag tar emot meddelande %msg', + 'broadcast %msg': + 'skicka meddelande %msg', + 'broadcast %msg and wait': + 'skicka meddelande %msg och v\u00E4nta', + 'Message name': + 'Meddelandets namn', + 'wait %n secs': + 'v\u00E4nta %n sek', + 'wait until %b': + 'v\u00E4nta tills %b', + 'forever %c': + 'f\u00F6r alltid %c', + 'repeat %n %c': + 'upprepa %n g\u00E5nger %c', + 'repeat until %b %c': + 'upprepa tills %b %c', + 'if %b %c': + 'om %b %c', + 'if %b %c else %c': + 'om %b %c d\u00E5 %c', + 'report %s': + 'returnera %s', + 'stop block': + 'stoppa block', + 'stop script': + 'stoppa skript', + 'stop all %stop': + 'stoppa alla %stop', + 'pause all %pause': + 'pausa alla %pause', + + 'run %cmdRing %inputs': + 'k\u00F6r %cmdRing med %inputs', + 'launch %cmdRing %inputs': + 'starta %cmdRing med %inputs', + 'call %repRing %inputs': + 'anropa %repRing med %inputs', + 'run %cmdRing w/continuation': + 'k\u00F6r %cmdRing och forts\u00E4tt', + 'call %cmdRing w/continuation': + 'anropa %cmdRing och forts\u00E4tt', + 'when I start as a clone': + 'n\u00E4r jag startar som klon', + 'create a clone of %cln': + 'skapa klon av %cln', + 'myself': + 'mig sj\u00E4lv', + 'delete this clone': + 'radera klon', + + + 'warp %c': + 'warp %c', + + // sensing: + 'touching %col ?': + 'r\u00F6r %col ?', + 'touching %clr ?': + 'r\u00F6r %clr ?', + 'color %clr is touching %clr ?': + 'f\u00E4rgen %clr r\u00F6r %clr ?', + 'ask %s and wait': + 'fr\u00E5ga %s och v\u00E4nta', + 'what\'s your name?': + 'vad heter du?', + 'answer': + 'svar', + 'mouse x': + 'mus x-pos', + 'mouse y': + 'mus y-pos', + 'mouse down?': + 'musknapp nedtryckt?', + 'key %key pressed?': + 'tangent %key nedtryckt?', + 'distance to %dst': + 'avst\u00E5nd till %dst', + 'reset timer': + 'nollst\u00E4ll stoppur', + 'timer': + 'stoppur', + 'http:// %s': + 'http:// %s', + + 'turbo mode?': + 'turbol\u00E4ge?', + 'set turbo mode to %b': + 's\u00E4tt turbol\u00E4ge till %b', + + + 'filtered for %clr': + 'filtrera p\u00E5 %clr', + 'stack size': + 'stack-storlek', + 'frames': + 'ramar', + + // operators: + '%n mod %n': + '%n mod %n', + 'round %n': + 'avrunda %n', + '%fun av %n': + '%fun von %n', + 'pick random %n to %n': + 'slumptal fr\u00E5n %n till %n', + '%b and %b': + '%b och %b', + '%b or %b': + '%b eller %b', + 'not %b': + 'inte %b', + 'true': + 'sant', + 'false': + 'falskt', + 'join %words': + 'sl\u00E5 ihop %words', + 'hello': + 'hej', + 'world': + 'v\u00E4rlden', + 'letter %n of %s': + 'bokstav %n av %s', + 'length of %s': + 'l\u00E4ngden av %s', + 'unicode of %s': + 'unicode av %s', + 'unicode %n as letter': + 'unicode %n som bokstav', + 'is %s a %typ ?': + '%s \u00E4r %typ ?', + 'is %s identical to %s ?': + '%s identisk med %s ?', + + 'type of %s': + 'type %s', + + // variables: + 'Make a variable': + 'Ny variabel', + 'Variable name': + 'Variabelnamn', + 'Delete a variable': + 'Radera variabel', + + 'set %var to %s': + 's\u00E4tt %var till %s', + 'change %var by %n': + '\u00E4ndra %var med %n', + 'show variable %var': + 'visa variabel %var', + 'hide variable %var': + 'g\u00F6m variabel %var', + 'script variables %scriptVars': + 'skriptvariabel %scriptVars', + + // lists: + 'list %exp': + 'lista %exp', + '%s in front of %l': + '%s fr\u00E4mst i %l', + 'item %idx of %l': + 'element %idx i %l', + 'all but first of %l': + 'allt utom f\u00F6rsta i %l', + 'length of %l': + 'l\u00E4ngd av %l', + '%l contains %s': + '%l inneh\u00E5ller %s', + 'thing': + 'sak', + 'add %s to %l': + 'l\u00E4gg %s till %l', + 'delete %ida of %l': + 'radera %ida fr\u00E5n %l', + 'insert %s at %idx of %l': + 'l\u00E4gg in %s p\u00E5 plats %idx i lista %l', + 'replace item %idx of %l with %s': + 'ers\u00E4tt element %idx i %l med %s', + + // other + 'Make a block': + 'Skapa nytt block', + + // menus + // snap menu + 'About...': + 'Om Snap!...', + 'Snap! website': + 'Snap! webbsida', + 'Download source': + 'Ladda ner k\u00E4llkoden', + 'Switch back to user mode': + 'Tillbaka till anv\u00E4ndarl\u00E4ge', + 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': + 'st\u00E4ng av Morphic\nmenyeroch visa \nanv\u00E4ndarv\u00E4nliga ist\u00E4llet', + 'Switch to dev mode': + 'Byt till utvecklarl\u00E4ge', + 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': + 'aktivera Morphic menyer\noch inspektorer,\ninte anv\u00E4ndarv\u00E4nligt!', + + // project menu + 'Project notes...': + 'Annoteringar...', + 'New': + 'Ny', + 'Open...': + '\u00D6ppna...', + 'Save': + 'Spara', + 'Save As...': + 'Spara som...', + 'Import...': + 'Importera...', + 'file menu import hint': + 'l\u00E4ser in ett exporterat projekt,\nett bibliotek med block,\nen kostym, eller ett ljud', + 'Export project as plain text ...': + 'Exportera projektet som vanlig text...', + 'Export project...': + 'Exportera projekt...', + 'show project data as XML\nin a new browser window': + 'visa projektdata som XML\ni ett ny f\u00F6nster', + 'Export blocks...': + 'Exportera block...', + 'show global custom block definitions as XML\nin a new browser window': + 'visa globala anpassade blockdefinitioner som XML\ni ett nytt f\u00F6nster', + 'Import tools...': + 'Importverktyg...', + 'load the official library of\npowerful blocks': + 'ladda ner det officiella\nsuperblock biblioteket ', + 'Libraries...': + 'Bibliotek...', + 'Import library': + 'Importera bibliotek', + + // cloud menu + 'Login...': + 'Logga in...', + 'Registrer deg...': + 'Registrera dig...', + + // settings menu + 'Language...': + 'Spr\u00E5k...', + 'Zoom blocks...': + 'F\u00F6rstora blocken...', + 'Blurred shadows': + 'Suddade skuggor', + 'uncheck to use solid drop\nshadows and highlights': + 'avmarkera f\u00F6r att anv\u00E4nda\nifyllda skuggor och belysningar', + 'check to use blurred drop\nshadows and highlights': + 'kryssa f\u00F6r att anv\u00E4nda\nsuddiga skuggor och belysningar', + 'Zebra coloring': + 'Zebraf\u00E4rg', + 'check to enable alternating\ncolors for nested blocks': + 'kryssa f\u00F6r att v\u00E4xla blockf\u00E4rger\ni nestlade block', + 'uncheck to disable alternating\ncolors for nested block': + 'avmarkera f\u00F6r att inaktivera v\u00E4xlade\nf\u00E4rger i nestlade block', + 'Dynamic input labels': + 'Dynamiska namn f\u00F6r indata', + 'uncheck to disable dynamic\nlabels for variadic inputs': + 'avmarkera f\u00F6r att inaktivera \ndynamiska namn f\u00F6r indata \nmed flera variabelf\u00E4lt', + 'check to enable dynamic\nlabels for variadic inputs': + 'kryssa f\u00F6r att aktivera \ndynamiska namn f\u00F6r indata \nmed flera variabelf\u00E4lt', + 'Prefer empty slot drops': + 'F\u00F6redra sl\u00E4pp p\u00E5 tomma utrymmen', + 'settings menu prefer empty slots hint': + 'Inst\u00E4llningar\nf\u00F6redra sl\u00E4pp p\u00E5 tomma utrymmen', + 'uncheck to allow dropped\nreporters to kick out others': + 'avmarkera f\u00F6r att till\u00E5ta placerade\n rappporterare att flytta ut andra', + 'Long form input dialog': + 'Komplett inmatningsf\u00F6nster', + 'check to always show slot\ntypes in the input dialog': + 'kryssa f\u00F6r att alltid visa\n alla typer i inmatningsf\u00F6nstret', + 'uncheck to use the input\ndialog in short form': + 'avmarkera f\u00F6r att visa lilla inmatningsf\u00F6nstret', + 'Virtual keyboard': + 'Virtuellt tangentbord', + 'uncheck to disable\nvirtual keyboard support\nfor mobile devices': + 'avmarkera f\u00F6r att inaktivera\nst\u00F6d f\u00F6r virtuellt \ntangentbord p\u00E5 mobila enheter', + 'check to enable\nvirtual keyboard support\nfor mobile devices': + 'kryssa f\u00F6r att aktivera\nst\u00F6d f\u00F6r virtuellt \ntangentbord p\u00E5 mobila enheter', + 'Input sliders': + 'Volymkontroller', + 'uncheck to disable\ninput sliders for\nentry fields': + 'avmarkera f\u00F6r att inaktivera \nvolymkontroller f\u00F6r inmatningsf\u00E4lt', + 'check to enable\ninput sliders for\nentry fields': + 'kryssa f\u00F6r att aktivera \nvolymkontroller f\u00F6r inmatningsf\u00E4lt', + 'Clicking sound': + 'Klickljud', + 'uncheck to turn\nblock clicking\nsound off': + 'avmarkera f\u00F6r att\n inaktivera klickljud', + 'check to turn\nblock clicking\nsound on': + 'kryssa f\u00F6r att aktivera klickljud', + 'Animations': + 'Animationer', + 'uncheck to disable\nIDE animations': + 'avmarkera f\u00F6r att st\u00E4nga\n av IDE-animationer', + 'Turbo mode': + 'Turbol\u00E4ge', + 'check to enable\nIDE animations': + 'kryssa f\u00F6r att aktivera\n IDE-animationer', + 'Thread safe scripts': + 'Tr\u00E5ds\u00E4kra skript', + 'uncheck to allow\nscript reentrancy': + 'avmarkera f\u00F6r att till\u00E5ta \nskript att \u00E5terintr\u00E4da', + 'check to disallow\nscript reentrancy': + 'kryssa f\u00F6r att f\u00F6rbjuda \nskript att \u00E5terintr\u00E4da', + 'Prefer smooth animations': + 'J\u00E4mna animeringar', + 'uncheck for greater speed\nat variable frame rates': + 'avmarkera f\u00F6r h\u00F6gre fart \nvid variabel frame rate', + 'check for smooth, predictable\nanimations across computers': + 'kryssa f\u00F6r j\u00E4mna animeringar\n p\u00E5 alla plattformar', +// inputs + 'with inputs': + 'med indata', + 'input names:': + 'indatanamn:', + 'Input Names:': + 'Indatanamn:', + 'input list:': + 'indata lista:', + + // context menus: + 'help': + 'hj\u00E4lp', + + // blocks: + 'hjelp...': + 'hj\u00E4lp...', + 'relabel...': + 'd\u00F6p om...', + 'duplicate': + 'duplicera', + 'make a copy\nand pick it up': + 'g\u00F6r en kopia\noch plocka upp den', + 'only duplicate this block': + 'duplicera endast detta block', + 'delete': + 'radera', + 'script pic...': + 'skript bild...', + 'open a new window\nwith a picture of this script': + '\u00F6ppna ett nytt f\u00F6nster\nmed en bild av detta skript', + 'ringify': + 'ring runt', + 'unringify': + 'radera ringen runt', + + // custom blocks: + 'delete block definition...': + 'radera blockdefinition...', + 'edit...': + 'redigera...', + + // sprites: + 'edit': + 'redigera', + 'export...': + 'exportera...', + + // stage: + 'show all': + 'visa allt', + + // scripting area + 'clean up': + 'st\u00E4da', + 'arrange scripts\nvertically': + 'organisera skript\nvertikalt', + 'add comment': + 'l\u00E4gg till kommentar', + 'make a block...': + 'skapa nytt block...', + + // costumes + 'rename': + 'd\u00F6p om', + 'export': + 'exportera', + 'rename costume': + 'd\u00F6p om kostymen', + + // sounds + 'Play sound': + 'Spela ljud', + 'Stop sound': + 'Stoppa ljud', + 'Stop': + 'Stoppa', + 'Play': + 'Starta', + 'rename sound': + 'd\u00F6p om ljud', + + // dialogs + // buttons + 'OK': + 'OK', + 'Ok': + 'OK', + 'Cancel': + 'Avbryt', + 'Yes': + 'Ja', + 'No': + 'Nej', + + // help + 'Help': + 'Hj\u00E4lp', + + // Project Manager + 'Untitled': + 'Namnl\u00F6s', + 'Open Project': + '\u00D6ppna projekt', + '(empty)': + '(tomt)', + 'Saved!': + 'Sparat!', + 'Delete Project': + 'Radera projekt', + 'Are you sure you want to delete': + '\u00C4r du s\u00E4ker p\u00E5 att du vill radera', + 'rename...': + 'd\u00F6p om...', + + // costume editor + 'Costume Editor': + 'Kostymredigerare', + 'click or drag crosshairs to move the rotation center': + 'Klicka eller dra krysset f\u00F6r att markera mitten', + + // project notes + 'Project Notes': + 'Annoteringar', + + // new project + 'New Project': + 'Nytt projekt', + 'Replace the current project with a new one?': + 'Ers\u00E4tt aktuella projektet med ett nytt?', + + // save project + 'Save Project As...': + 'Spara projekt som...', + + // export blocks + 'Export blocks': + 'Exportera block', + 'Import blocks': + 'Importera block', + 'this project doesn\'t have any\ncustom global blocks yet': + 'Detta projekt saknar\negna globala block', + 'select': + 'v\u00E4lj', + 'all': + 'allt', + 'none': + 'ingenting', + + // variable dialog + 'for all sprites': + 'f\u00F6r alla sprites', + 'for this sprite only': + 'bara f\u00F6r denna sprite', + + // block dialog + 'Change block': + '\u00C4ndra block', + 'Command': + 'Kommando', + 'Reporter': + 'Funktion', + 'Predicate': + 'Predikat', + + // block editor + 'Block Editor': + 'Blockredigerare', + 'Apply': + 'Verkst\u00E4ll', + + // block deletion dialog + 'Delete Custom Block': + 'Radera custom blokk', + 'block deletion dialog text': + 'Skal denne blokken med alle dens instanser\n' + + 'bli slettet?', + + // input dialog + 'Create input name': + 'Skapa indata-namn', + 'Edit input name': + 'Redigera indata-namn', + 'Edit label fragment': + 'Redigera etikettdel', + 'Title text': + 'Titel', + 'Input name': + 'Indata-namn', + 'Delete': + 'Radera', + 'Object': + 'Objekt', + 'Number': + 'Nummer', + 'Text': + 'Text', + 'List': + 'Lista', + 'Any type': + 'Valfri typ', + 'Boolean (T/F)': + 'Boolean (S/F)', + 'Command\n(inline)': + 'Kommando\n(inline)', + 'Command\n(C-shape)': + 'Kommando\n(C-Form)', + 'Any\n(unevaluated)': + 'Vilken som helst\n(oevaluerad)', + 'Boolean\n(unevaluated)': + 'Boolean\n(oevaluerad)', + 'Single input.': + 'Enkel indata.', + 'Default Value:': + 'Standardv\u00E4rde:', + 'Multiple inputs (value is list of inputs)': + 'Flera indata (v\u00E4rdet \u00E4r en lista av indata)', + 'Upvar - make internal variable visible to caller': + 'Upvar - g\u00F6r internal variabel synlig f\u00F6r anroparen', + + // About Snap + 'About Snap': + 'Om Snap', + 'Back...': + 'Tillbaka...', + 'License...': + 'Licens...', + 'Modules...': + 'Moduler...', + 'Credits...': + 'Tack till...', + 'Translators...': + '\u00D6vers\u00E4ttare', + 'License': + 'Licens', + 'current module versions:': + 'Modulversioner', + 'Contributors': + 'Bidragsgivare', + 'Translations': + '\u00D6vers\u00E4ttningar', + + // variable watchers + 'normal': + 'normal', + 'large': + 'stor', + 'slider': + 'volymkontroll', + 'slider min...': + 'volymkontroll min...', + 'slider max...': + 'volymkontroll max...', + 'import...': + 'importera...', + 'Slider minimum value': + 'Volymkontroll - minsta v\u00E4rde', + 'Slider maximum value': + 'volymkontroll - h\u00F6gsta v\u00E4rde', + + // list watchers + 'length: ': + 'l\u00E4ngd: ', + + // coments + 'add comment here...': + 'l\u00E4gg till kommentar h\u00E4r...', + + // drow downs + // directions + '(90) right': + '(90) h\u00F6ger', + '(-90) left': + '(-90) v\u00E4nster', + '(0) up': + '(0) upp', + '(180) down': + '(180) ned', + + // collision detection + 'mouse-pointer': + 'muspekare', + 'edge': + 'kant', + 'pen trails': + 'pennsp\u00E5r', + + // costumes + 'Turtle': + 'Sk\u00F6ldpadda', + + // graphical effects + 'ghost': + 'sp\u00F6k', + + // keys + 'space': + 'mellanslag', + 'up arrow': + 'pil upp', + 'down arrow': + 'pil ned', + 'right arrow': + 'pil h\u00F6ger', + 'left arrow': + 'pil v\u00E4nster', + 'a': + 'a', + 'b': + 'b', + 'c': + 'c', + 'd': + 'd', + 'e': + 'e', + 'f': + 'f', + 'g': + 'g', + 'h': + 'h', + 'i': + 'i', + 'j': + 'j', + 'k': + 'k', + 'l': + 'l', + 'm': + 'm', + 'n': + 'n', + 'o': + 'o', + 'p': + 'p', + 'q': + 'q', + 'r': + 'r', + 's': + 's', + 't': + 't', + 'u': + 'u', + 'v': + 'v', + 'w': + 'w', + 'x': + 'x', + 'y': + 'y', + 'z': + 'z', + '0': + '0', + '1': + '1', + '2': + '2', + '3': + '3', + '4': + '4', + '5': + '5', + '6': + '6', + '7': + '7', + '8': + '8', + '9': + '9', + + // messages + 'new...': + 'ny...', + + // math functions + 'abs': + 'abs', + 'sqrt': + 'kvadratrot', + 'sin': + 'sin', + 'cos': + 'cos', + 'tan': + 'tan', + 'asin': + 'arc-1', + 'acos': + 'cos-1', + 'atan': + 'tan-1', + 'ln': + 'ln', + 'e^': + 'e^', + + // data types + 'number': + 'nummer', + 'text': + 'text', + 'Boolean': + 'boolean', + 'list': + 'lista', + 'command': + 'kommando', + 'reporter': + 'funktionsblock', + 'predicate': + 'predikat', + + // list indices + 'last': + 'sista', + 'any': + 'vilken som helst', + + // missing labels from initial translation added below + 'add a new sprite': + 'ny sprite', + 'when %keyHat key pressed': + 'n\u00E4r tangent %keyHat trycks ned', + 'when I receive %msgHat': + 'n\u00E4r jag tar emot %msgHat', + 'message': + 'meddelande', + 'any message': + 'n\u00E5got meddelande', + 'stop %stopChoices': + 'stoppa %stopChoices', + 'this script': + 'detta skript', + 'this block': + 'detta block', + 'stop %stopOthersChoices': + 'stoppa %stopOthersChoices', + 'all but this script': + 'alla f\u00F6rutom detta skript', + 'other scripts in sprite': + 'andra skript i denna sprite', + '%att of %spr': + '%att av %spr', + '%fun of %n': + '%fun av %n', + 'split %s by %delim': + 'dela %s med tecken %delim', + 'Script variable name': + 'Skriptvariabelnamn', + 'Reference manual': + 'Referensbok', + 'Export project as plain text...': + 'Exportera projektet som vanlig text...', + 'Import tools': + 'Importverktyg', + 'Signup...': + 'Registrera...', + 'Stage size...': + 'Scenstorlek...', + 'Stage size': + 'Scenstorlek', + 'Stage width': + 'Scenbredd', + 'Stage height': + 'Scenh\u00F6jd', + 'Default': + 'Standard', + 'Plain prototype labels': + 'Vanliga prototypetiketter', + 'uncheck to always show (+) symbols\nin block prototype labels': + 'avmarkera f\u00F6r att visa (+) symboler \n i blockprototypetiketter', + 'check to hide (+) symbols\nin block prototype labels': + 'kryssa f\u00F6r att visa (+) symboler \n i blockprototypetiketter', + 'check to prioritize\nscript execution': + 'kryssa f\u00F6r att prioritera \nskriptexekvering', + 'uncheck to run scripts\nat normal speed': + 'avmarkera f\u00F6r att k\u00F6ra \nskript vid normal hastighet', + 'uncheck to allow\nscript reentrance': + 'avmarkera f\u00F6r att till\u00E5ta \nskript att \u00E5tertilltr\u00E4da', + 'check to disallow\nscript reentrance': + 'kryssa f\u00F6r att f\u00F6rbjuda \nskript att \u00E5tertilltr\u00E4da', + 'Flat line ends': + 'Platta streckslut', + 'check for flat ends of lines': + 'kryssa f\u00F6r platta streckslut', + 'uncheck for round ends of lines': + 'avmarkera f\u00F6r avrundade streckslut', + 'hide primitives': + 'g\u00F6m primitiva', + 'show primitives': + 'visa primitiva', + 'help...': + 'hj\u00E4lp...', + 'move': + 'flytta', + 'detach from': + 'koppla bort', + 'detach all parts': + 'koppla bort alla delar', + 'pic...': + 'bild...', + 'open a new window\nwith a picture of the stage': + '\u00F6ppna ett nytt f\u00F6nster\nmed en bild av scenen', + 'undrop': + '\u00E5ngra sl\u00E4pp', + 'undo the last\nblock drop\nin this pane': + '\u00E5ngra sista \nblocksl\u00E4ppet i\ndetta omr\u00E5de', + 'scripts pic...': + 'skriptbild...', + 'open a new window\nwith a picture of all scripts': + '\u00F6ppna ett nytt f\u00F6nster\nmed en bild p\u00E5 alla skript', + 'Zoom blocks': + 'F\u00F6rstora blocken', + 'build': + 'bygg', + 'your own': + 'dina egna', + 'blocks': + 'block', + 'normal (1x)': + 'normal (1x)', + 'demo (1.2x)': + 'demo (1.2x)', + 'presentation (1.4x)': + 'presentation (1.4x)', + 'big (2x)': + 'stor (2x)', + 'huge (4x)': + 'j\u00E4ttestor (4x)', + 'giant (8x)': + 'enorm (8x)', + 'monstrous (10x)': + 'gigantisk (10x)', + 'Empty': + 'Tom', + 'brightness': + 'ljusstyrke', + 'negative': + 'negativ', + 'comic': + 'komisk', + 'confetti': + 'konfetti', + 'floor': + 'golv', + 'letter': + 'bokstav', + 'whitespace': + 'mellanslag', + 'line': + 'rad', + 'tab': + 'tab', + 'cr': + 'retur', + 'warp %c': + 'snabbspola %c', + 'Reset Password...': + 'Nollst\u00E4ll l\u00F6senord...', + 'Codification support': + 'St\u00F6d f\u00F6r textprogrammering', + 'Flat design': + 'Platt utseende', + 'check for block\nto text mapping features': + 'kryssa f\u00F6r att aktivera\nblock-till-text funktioner', + 'uncheck to disable\nblock to text mapping features': + 'avmarkera f\u00F6r att inaktivera\nblock-till-text funktioner', + 'check for alternative\nGUI design': + 'kryssa f\u00F6r att aktivera ett\nalternativt utseende', + 'uncheck for default\nGUI design': + 'avmarkera f\u00F6r att byta\ntill standardutseendet', + 'Select categories of additional blocks to add to this project.': + 'v\u00E4lj grupper av extrablock att l\u00E4gga till i projektet', + 'Select a costume from the media library': + 'v\u00E4lj en kostym fr\u00E5n mediabiblioteket', + 'Select a sound from the media library': + 'v\u00E4lj ett ljud fr\u00E5n mediabiblioteket', + 'Iteration, composition': + 'Upprepning, komposition', + 'List utilities': + 'Listverktyg', + 'Streams (lazy lists)': + 'Str\u00F6mmar (lata listor)', + 'Variadic reporters': + 'Variabla rapporterare', + 'Words, sentences': + 'Ord, meningar', + 'Paint a new costume': + 'Rita en ny kostym', + 'add a new Turtle sprite': + 'l\u00E4gg till en ny Sk\u00F6ldpadda-sprite', + 'paint a new sprite': + 'rita en ny sprite', + 'Paint Editor': + 'Rita', + 'undo': + '\u00E5ngra', + 'grow': + 'st\u00F6rre', + 'shrink': + 'mindre', + 'flip ↔': + 'v\u00E4nd ↔', + 'flip ↕': + 'v\u00E4nd ↕', + 'Brush size': + 'Pennstorlek', + 'Constrain proportions of shapes?\n(you can also hold shift)': + 'Beh\u00E5ll figurernas proportioner?\n(du kan ocks\u00E5 h\u00E5lla skift nedtryckt)' + +}; @@ -61,7 +61,7 @@ PushButtonMorph, SyntaxElementMorph, Color, Point, WatcherMorph, StringMorph, SpriteMorph, ScrollFrameMorph, CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences*/ -modules.lists = '2014-July-28'; +modules.lists = '2014-November-20'; var List; var ListWatcherMorph; @@ -125,6 +125,9 @@ List.prototype.changed = function () { List.prototype.cons = function (car, cdr) { var answer = new List(); + if (!(cdr instanceof List || isNil(cdr))) { + throw new Error("cdr isn't a list: " + cdr); + } answer.first = isNil(car) ? null : car; answer.rest = cdr || null; answer.isLinked = true; @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-October-01'; +modules.locale = '2014-December-15'; // Global stuff @@ -392,6 +392,18 @@ SnapTranslator.dict.fi = { '2014-04-18' }; +SnapTranslator.dict.sv = { + // meta information + 'language_name': + 'svenska', + 'language_translator': + 'Erik A. Olsson', + 'translator_e-mail': + 'eolsson@gmail.com', + 'last_changed': + '2014-12-14' +}; + SnapTranslator.dict.pt_BR = { // meta information 'language_name': @@ -415,3 +427,15 @@ SnapTranslator.dict.bn = { 'last_changed': '2014-07-02' }; + +SnapTranslator.dict.kn = { + // translations meta information + 'language_name': + '\u0C95\u0CA8\u0CCD\u0CA8\u0CA1', + 'language_translator': + 'Vinayakumar R', + 'translator_e-mail': + 'vnkmr7620@gmail.com', + 'last_changed': + '2014-12-02' +}; @@ -464,9 +464,15 @@ MyMorph.prototype.mouseMove = function(pos) {}; - The only optional parameter of such a method is a Point object + All of these methods have as optional parameter a Point object indicating the current position of the Hand inside the World's - coordinate system. + coordinate system. The + + mouseMove(pos, button) + + event method has an additional optional parameter indicating the + currently pressed mouse button, which is either 'left' or 'right'. + You can use this to let users interact with 3D environments. Events may be "bubbled" up a morph's owner chain by calling @@ -1035,7 +1041,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-September-30'; +var morphicVersion = '2014-December-05'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -1925,7 +1931,9 @@ Rectangle.prototype.round = function () { Rectangle.prototype.spread = function () { // round me by applying floor() to my origin and ceil() to my corner - return this.origin.floor().corner(this.corner.ceil()); + // expand by 1 to be on the safe side, this eliminates rounding + // artefacts caused by Safari's auto-scaling on retina displays + return this.origin.floor().corner(this.corner.ceil()).expandBy(1); }; Rectangle.prototype.amountToTranslateWithin = function (aRect) { @@ -3972,6 +3980,7 @@ PenMorph.prototype.init = function () { this.size = 1; this.wantsRedraw = false; this.penPoint = 'tip'; // or 'center" + this.penBounds = null; // rect around the visible arrow shape HandleMorph.uber.init.call(this); this.setExtent(new Point(size, size)); @@ -3994,11 +4003,9 @@ PenMorph.prototype.changed = function () { // PenMorph display: PenMorph.prototype.drawNew = function (facing) { -/* - my orientation can be overridden with the "facing" parameter to - implement Scratch-style rotation styles + // my orientation can be overridden with the "facing" parameter to + // implement Scratch-style rotation styles -*/ var context, start, dest, left, right, len, direction = facing || this.heading; @@ -4021,6 +4028,15 @@ PenMorph.prototype.drawNew = function (facing) { right = start.distanceAngle(len * 0.33, direction - 230); } + // cache penBounds + this.penBounds = new Rectangle( + Math.min(start.x, dest.x, left.x, right.x), + Math.min(start.y, dest.y, left.y, right.y), + Math.max(start.x, dest.x, left.x, right.x), + Math.max(start.y, dest.y, left.y, right.y) + ); + + // draw arrow shape context.fillStyle = this.color.toString(); context.beginPath(); @@ -4037,7 +4053,6 @@ PenMorph.prototype.drawNew = function (facing) { context.lineWidth = 1; context.stroke(); context.fill(); - }; // PenMorph access: @@ -5754,7 +5769,7 @@ SliderMorph.prototype.rangeSize = function () { }; SliderMorph.prototype.ratio = function () { - return this.size / this.rangeSize(); + return this.size / (this.rangeSize() + 1); }; SliderMorph.prototype.unitSize = function () { @@ -9346,11 +9361,11 @@ HandMorph.prototype.init = function (aWorld) { this.world = aWorld; this.mouseButton = null; this.mouseOverList = []; - this.mouseDownMorph = null; this.morphToGrab = null; this.grabOrigin = null; this.temporaries = []; this.touchHoldTimeout = null; + this.contextMenuEnabled = false; }; HandMorph.prototype.changed = function () { @@ -9494,9 +9509,10 @@ HandMorph.prototype.drop = function () { */ HandMorph.prototype.processMouseDown = function (event) { - var morph, expectedClick, actualClick; + var morph, actualClick; this.destroyTemporaries(); + this.contextMenuEnabled = true; this.morphToGrab = null; if (this.children.length !== 0) { this.drop(); @@ -9529,15 +9545,9 @@ HandMorph.prototype.processMouseDown = function (event) { if (event.button === 2 || event.ctrlKey) { this.mouseButton = 'right'; actualClick = 'mouseDownRight'; - expectedClick = 'mouseClickRight'; } else { this.mouseButton = 'left'; actualClick = 'mouseDownLeft'; - expectedClick = 'mouseClickLeft'; - } - this.mouseDownMorph = morph; - while (!this.mouseDownMorph[expectedClick]) { - this.mouseDownMorph = this.mouseDownMorph.parent; } while (!morph[actualClick]) { morph = morph.parent; @@ -9596,7 +9606,7 @@ HandMorph.prototype.processMouseUp = function () { expectedClick = 'mouseClickLeft'; } else { expectedClick = 'mouseClickRight'; - if (this.mouseButton) { + if (this.mouseButton && this.contextMenuEnabled) { context = morph; contextMenu = context.contextMenu(); while ((!contextMenu) && @@ -9654,16 +9664,18 @@ HandMorph.prototype.processMouseMove = function (event) { // mouseOverNew = this.allMorphsAtPointer(); mouseOverNew = this.morphAtPointer().allParents(); - if ((this.children.length === 0) && - (this.mouseButton === 'left')) { + if (!this.children.length && this.mouseButton) { topMorph = this.morphAtPointer(); morph = topMorph.rootForGrab(); if (topMorph.mouseMove) { - topMorph.mouseMove(pos); + topMorph.mouseMove(pos, this.mouseButton); + if (this.mouseButton === 'right') { + this.contextMenuEnabled = false; + } } // if a morph is marked for grabbing, just grab it - if (this.morphToGrab) { + if (this.mouseButton === 'left' && this.morphToGrab) { if (this.morphToGrab.isDraggable) { morph = this.morphToGrab; this.grab(morph); @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-October-08'; +modules.objects = '2014-December-17'; var SpriteMorph; var StageMorph; @@ -793,6 +793,12 @@ SpriteMorph.prototype.initBlocks = function () { category: 'sensing', spec: 'frames' }, + reportThreadCount: { + dev: true, + type: 'reporter', + category: 'sensing', + spec: 'processes' + }, doAsk: { type: 'command', category: 'sensing', @@ -1156,6 +1162,13 @@ SpriteMorph.prototype.initBlocks = function () { category: 'lists', spec: 'map %repRing over %l' }, + doForEach: { + dev: true, + type: 'command', + category: 'lists', + spec: 'for %upvar in %l %cs', + defaults: [localize('each item')] + }, // Code mapping - experimental doMapCodeOrHeader: { // experimental @@ -1679,6 +1692,20 @@ SpriteMorph.prototype.blockTemplates = function (category) { return menu; } + function addVar(pair) { + if (pair) { + if (myself.variables.silentFind(pair[0])) { + myself.inform('that name is already in use'); + } else { + myself.addVariable(pair[0], pair[1]); + myself.toggleVariableWatcher(pair[0], pair[1]); + myself.blocksCache[cat] = null; + myself.paletteCache[cat] = null; + myself.parentThatIsA(IDE_Morph).refreshPalette(); + } + } + } + if (cat === 'motion') { blocks.push(block('forward')); @@ -1903,6 +1930,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { txt.setColor(this.paletteTextColor); blocks.push(txt); blocks.push('-'); + blocks.push(watcherToggle('reportThreadCount')); + blocks.push(block('reportThreadCount')); blocks.push(block('colorFiltered')); blocks.push(block('reportStackSize')); blocks.push(block('reportFrameCount')); @@ -1973,15 +2002,7 @@ SpriteMorph.prototype.blockTemplates = function (category) { function () { new VariableDialogMorph( null, - function (pair) { - if (pair && !myself.variables.silentFind(pair[0])) { - myself.addVariable(pair[0], pair[1]); - myself.toggleVariableWatcher(pair[0], pair[1]); - myself.blocksCache[cat] = null; - myself.paletteCache[cat] = null; - myself.parentThatIsA(IDE_Morph).refreshPalette(); - } - }, + addVar, myself ).prompt( 'Variable name', @@ -2063,6 +2084,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(txt); blocks.push('-'); blocks.push(block('reportMap')); + blocks.push('-'); + blocks.push(block('doForEach')); } ///////////////////////////////// @@ -2170,8 +2193,8 @@ SpriteMorph.prototype.freshPalette = function (category) { var defs = SpriteMorph.prototype.blocks, hiddens = StageMorph.prototype.hiddenPrimitives; return Object.keys(hiddens).some(function (any) { - return defs[any].category === category || - contains((more[category] || []), any); + return !isNil(defs[any]) && (defs[any].category === category + || contains((more[category] || []), any)); }); } @@ -2210,7 +2233,7 @@ SpriteMorph.prototype.freshPalette = function (category) { var hiddens = StageMorph.prototype.hiddenPrimitives, defs = SpriteMorph.prototype.blocks; Object.keys(hiddens).forEach(function (sel) { - if (defs[sel].category === category) { + if (defs[sel] && (defs[sel].category === category)) { delete StageMorph.prototype.hiddenPrimitives[sel]; } }); @@ -3238,8 +3261,11 @@ SpriteMorph.prototype.setCenter = function (aPoint, justMe) { SpriteMorph.prototype.nestingBounds = function () { // same as fullBounds(), except that it uses "parts" instead of children - var result; - result = this.bounds; + // and special cases the costume-less "arrow" shape's bounding box + var result = this.bounds; + if (!this.costume && this.penBounds) { + result = this.penBounds.translateBy(this.position()); + } this.parts.forEach(function (part) { if (part.isVisible) { result = result.merge(part.nestingBounds()); @@ -3589,6 +3615,16 @@ SpriteMorph.prototype.reportMouseY = function () { return 0; }; +// SpriteMorph thread count (for debugging) + +SpriteMorph.prototype.reportThreadCount = function () { + var stage = this.parentThatIsA(StageMorph); + if (stage) { + return stage.threads.processes.length; + } + return 0; +}; + // SpriteMorph variable watchers (for palette checkbox toggling) SpriteMorph.prototype.findVariableWatcher = function (varName) { @@ -4896,6 +4932,20 @@ StageMorph.prototype.blockTemplates = function (category) { ); } + function addVar(pair) { + if (pair) { + if (myself.variables.silentFind(pair[0])) { + myself.inform('that name is already in use'); + } else { + myself.addVariable(pair[0], pair[1]); + myself.toggleVariableWatcher(pair[0], pair[1]); + myself.blocksCache[cat] = null; + myself.paletteCache[cat] = null; + myself.parentThatIsA(IDE_Morph).refreshPalette(); + } + } + } + if (cat === 'motion') { txt = new TextMorph(localize( @@ -5066,6 +5116,8 @@ StageMorph.prototype.blockTemplates = function (category) { txt.setColor(this.paletteTextColor); blocks.push(txt); blocks.push('-'); + blocks.push(watcherToggle('reportThreadCount')); + blocks.push(block('reportThreadCount')); blocks.push(block('colorFiltered')); blocks.push(block('reportStackSize')); blocks.push(block('reportFrameCount')); @@ -5138,15 +5190,7 @@ StageMorph.prototype.blockTemplates = function (category) { function () { new VariableDialogMorph( null, - function (pair) { - if (pair && !myself.variables.silentFind(pair[0])) { - myself.addVariable(pair[0], pair[1]); - myself.toggleVariableWatcher(pair[0], pair[1]); - myself.blocksCache[cat] = null; - myself.paletteCache[cat] = null; - myself.parentThatIsA(IDE_Morph).refreshPalette(); - } - }, + addVar, myself ).prompt( 'Variable name', @@ -5222,6 +5266,8 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(txt); blocks.push('-'); blocks.push(block('reportMap')); + blocks.push('-'); + blocks.push(block('doForEach')); } ///////////////////////////////// @@ -5360,7 +5406,7 @@ StageMorph.prototype.thumbnail = function (extentPoint, excludedSprite) { this.dimensions.y * this.scale ); this.children.forEach(function (morph) { - if (morph !== excludedSprite) { + if (morph.isVisible && (morph !== excludedSprite)) { fb = morph.fullBounds(); fimg = morph.fullImage(); if (fimg.width && fimg.height) { @@ -5522,6 +5568,9 @@ StageMorph.prototype.watcherFor = StageMorph.prototype.getLastAnswer = SpriteMorph.prototype.getLastAnswer; +StageMorph.prototype.reportThreadCount + = SpriteMorph.prototype.reportThreadCount; + // StageMorph message broadcasting StageMorph.prototype.allMessageNames @@ -6770,7 +6819,7 @@ WatcherMorph.prototype.object = function () { WatcherMorph.prototype.isGlobal = function (selector) { return contains( ['getLastAnswer', 'getKeysPressed', 'getLastMessage', 'getTempo', 'getTimer', - 'reportMouseX', 'reportMouseY'], + 'reportMouseX', 'reportMouseY', 'reportThreadCount'], selector ); }; @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Snap! Build Your Own Blocks. Beta</title> - <link rel="shortcut icon" href="http://snap.berkeley.edu/fav3.gif" type="image/gif"> + <link rel="shortcut icon" href="favicon.ico"> <script type="text/javascript" src="morphic.js"></script> <script type="text/javascript" src="widgets.js"></script> <script type="text/javascript" src="blocks.js"></script> @@ -33,5 +33,5 @@ </head> <body style="margin: 0;"> <canvas id="world" tabindex="1" style="position: absolute;" /> - </body> + </body> </html> @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-October-01'; +modules.store = '2014-December-17'; // XML_Serializer /////////////////////////////////////////////////////// @@ -261,11 +261,14 @@ SnapSerializer.prototype.watcherLabels = { yPosition: 'y position', direction: 'direction', getScale: 'size', + getTempo: 'tempo', getLastAnswer: 'answer', + getLastMessage: 'message', getTimer: 'timer', getCostumeIdx: 'costume #', reportMouseX: 'mouse x', - reportMouseY: 'mouse y' + reportMouseY: 'mouse y', + reportThreadCount: 'processes' }; // SnapSerializer instance creation: @@ -1199,6 +1202,10 @@ SnapSerializer.prototype.loadValue = function (model) { if (el) { v.outerContext = this.loadValue(el); } + if (v.outerContext && v.receiver && + !v.outerContext.variables.parentFrame) { + v.outerContext.variables.parentFrame = v.receiver.variables; + } return v; case 'costume': center = new Point(); @@ -1824,9 +1831,8 @@ Context.prototype.toXML = function (serializer) { return ''; } return serializer.format( - '<context% ~><inputs>%</inputs><variables>%</variables>' + + '<context ~><inputs>%</inputs><variables>%</variables>' + '%<receiver>%</receiver>%</context>', - this.isLambda ? ' lambda="lambda"' : '', this.inputs.reduce( function (xml, input) { return xml + serializer.format('<input>$</input>', input); @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-October-01'; +modules.threads = '2014-December-17'; var ThreadManager; var Process; @@ -100,8 +100,18 @@ function snapEquals(a, b) { var x = +a, y = +b, + i, specials = [true, false, '']; + // "zum Schneckengang verdorben, was Adlerflug geworden wäre" + // collecting edge-cases that somebody complained about + // on Github. Folks, take it easy and keep it fun, okay? + // Shit like this is patently ugly and slows Snap down. Tnx! + for (i = 9; i <= 13; i += 1) { + specials.push(String.fromCharCode(i)); + } + specials.push(String.fromCharCode(160)); + // check for special values before coercing to numbers if (isNaN(x) || isNaN(y) || [a, b].some(function (any) {return contains(specials, any) || @@ -110,7 +120,7 @@ function snapEquals(a, b) { y = b; } - // handle text comparision case-insensitive. + // handle text comparison case-insensitive. if (isString(x) && isString(y)) { return x.toLowerCase() === y.toLowerCase(); } @@ -136,7 +146,8 @@ ThreadManager.prototype.toggleProcess = function (block) { ThreadManager.prototype.startProcess = function ( block, isThreadSafe, - exportResult + exportResult, + callback ) { var active = this.findProcess(block), top = block.topBlock(), @@ -149,7 +160,7 @@ ThreadManager.prototype.startProcess = function ( this.removeTerminatedProcesses(); } top.addHighlight(); - newProc = new Process(block.topBlock()); + newProc = new Process(block.topBlock(), callback); newProc.exportResult = exportResult; this.processes.push(newProc); return newProc; @@ -207,11 +218,10 @@ ThreadManager.prototype.resumeAll = function (stage) { }; ThreadManager.prototype.step = function () { -/* - run each process until it gives up control, skipping processes - for sprites that are currently picked up, then filter out any - processes that have been terminated -*/ + // run each process until it gives up control, skipping processes + // for sprites that are currently picked up, then filter out any + // processes that have been terminated + this.processes.forEach(function (proc) { if (!proc.homeContext.receiver.isPickedUp() && !proc.isDead) { proc.runStep(); @@ -224,9 +234,10 @@ ThreadManager.prototype.removeTerminatedProcesses = function () { // and un-highlight their scripts var remaining = []; this.processes.forEach(function (proc) { - if (!proc.isRunning() && !proc.errorFlag && !proc.isDead) { - proc.topBlock.removeHighlight(); - + if ((!proc.isRunning() && !proc.errorFlag) || proc.isDead) { + if (proc.topBlock instanceof BlockMorph) { + proc.topBlock.removeHighlight(); + } if (proc.prompter) { proc.prompter.destroy(); if (proc.homeContext.receiver.stopTalking) { @@ -235,18 +246,22 @@ ThreadManager.prototype.removeTerminatedProcesses = function () { } if (proc.topBlock instanceof ReporterBlockMorph) { - if (proc.homeContext.inputs[0] instanceof List) { - proc.topBlock.showBubble( - new ListWatcherMorph( - proc.homeContext.inputs[0] - ), - proc.exportResult - ); + if (proc.onComplete instanceof Function) { + proc.onComplete(proc.homeContext.inputs[0]); } else { - proc.topBlock.showBubble( - proc.homeContext.inputs[0], - proc.exportResult - ); + if (proc.homeContext.inputs[0] instanceof List) { + proc.topBlock.showBubble( + new ListWatcherMorph( + proc.homeContext.inputs[0] + ), + proc.exportResult + ); + } else { + proc.topBlock.showBubble( + proc.homeContext.inputs[0], + proc.exportResult + ); + } } } } else { @@ -295,9 +310,9 @@ ThreadManager.prototype.findProcess = function (block) { are children receiver object (sprite) to which the process applies, cached from the top block - context the Context describing the current state + context the Context describing the current state of this process - homeContext stores information relevant to the whole process, + homeContext stores information relevant to the whole process, i.e. its receiver, result etc. isPaused boolean indicating whether to pause readyToYield boolean indicating whether to yield control to @@ -305,15 +320,20 @@ ThreadManager.prototype.findProcess = function (block) { readyToTerminate boolean indicating whether the stop method has been called isDead boolean indicating a terminated clone process - timeout msecs after which to force yield - lastYield msecs when the process last yielded - errorFlag boolean indicating whether an error was encountered + timeout msecs after which to force yield + lastYield msecs when the process last yielded + errorFlag boolean indicating whether an error was encountered prompter active instance of StagePrompterMorph httpRequest active instance of an HttpRequest or null pauseOffset msecs between the start of an interpolated operation and when the process was paused exportResult boolean flag indicating whether a picture of the top block along with the result bubble shoud be exported + onComplete an optional callback function to be executed when + the process is done + procedureCount number counting procedure call entries, + used to tag custom block calls, so "stop block" + invocations can catch them */ Process.prototype = {}; @@ -321,7 +341,7 @@ Process.prototype.contructor = Process; Process.prototype.timeout = 500; // msecs after which to force yield Process.prototype.isCatchingErrors = true; -function Process(topBlock) { +function Process(topBlock, onComplete) { this.topBlock = topBlock || null; this.readyToYield = false; @@ -338,6 +358,8 @@ function Process(topBlock) { this.pauseOffset = null; this.frameCount = 0; this.exportResult = false; + this.onComplete = onComplete || null; + this.procedureCount = 0; if (topBlock) { this.homeContext.receiver = topBlock.receiver(); @@ -361,13 +383,13 @@ Process.prototype.isRunning = function () { // Process entry points Process.prototype.runStep = function () { -/* - a step is an an uninterruptable 'atom', it can consist - of several contexts, even of several blocks -*/ + // a step is an an uninterruptable 'atom', it can consist + // of several contexts, even of several blocks + if (this.isPaused) { // allow pausing in between atomic steps: return this.pauseStep(); } + this.readyToYield = false; while (!this.readyToYield && this.context @@ -435,8 +457,10 @@ Process.prototype.pauseStep = function () { Process.prototype.evaluateContext = function () { var exp = this.context.expression; - this.frameCount += 1; + if (this.context.tag === 'exit') { + this.expectReport(); + } if (exp instanceof Array) { return this.evaluateSequence(exp); } @@ -460,7 +484,7 @@ Process.prototype.evaluateContext = function () { Process.prototype.evaluateBlock = function (block, argCount) { // check for special forms - if (contains(['reportOr', 'reportAnd'], block.selector)) { + if (contains(['reportOr', 'reportAnd', 'doReport'], block.selector)) { return this[block.selector](block); } @@ -526,6 +550,35 @@ Process.prototype.reportAnd = function (block) { } }; +Process.prototype.doReport = function (block) { + var outer = this.context.outerContext; + if (this.context.expression.partOfCustomCommand) { + this.doStopCustomBlock(); + this.popContext(); + } else { + while (this.context && this.context.tag !== 'exit') { + if (this.context.expression === 'doStopWarping') { + this.doStopWarping(); + } else { + this.popContext(); + } + } + if (this.context) { + if (this.context.expression === 'expectReport') { + // pop off inserted top-level exit context + this.popContext(); + } else { + // un-tag and preserve original caller + this.context.tag = null; + } + } + } + // in any case evaluate (and ignore) + // the input, because it could be + // and HTTP Request for a hardware extension + this.pushContext(block.inputs()[0], outer); +}; + // Process: Non-Block evaluation Process.prototype.evaluateMultiSlot = function (multiSlot, argCount) { @@ -586,7 +639,6 @@ Process.prototype.evaluateInput = function (input) { ) || (input instanceof CSlotMorph && !input.isStatic)) { // I know, this still needs yet to be done right.... ans = this.reify(ans, new List()); - ans.isImplicitLambda = true; } } } @@ -597,8 +649,6 @@ Process.prototype.evaluateInput = function (input) { Process.prototype.evaluateSequence = function (arr) { var pc = this.context.pc, outer = this.context.outerContext, - isLambda = this.context.isLambda, - isImplicitLambda = this.context.isImplicitLambda, isCustomBlock = this.context.isCustomBlock; if (pc === (arr.length - 1)) { // tail call elimination this.context = new Context( @@ -607,8 +657,6 @@ Process.prototype.evaluateSequence = function (arr) { this.context.outerContext, this.context.receiver ); - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; } else { if (pc >= arr.length) { @@ -626,8 +674,8 @@ Process.prototype.evaluateSequence = function (arr) { Caution: we cannot just revert to this version of the method, because to make tail call elimination work many tweaks had to be done to various primitives. For the most part these tweaks are about schlepping the outer context (for -the variable bindings) and the isLambda flag along, and are indicated by a -short comment in the code. But to really revert would take a good measure +the variable bindings) and the isCustomBlock flag along, and are indicated +by a short comment in the code. But to really revert would take a good measure of trial and error as well as debugging. In the developers file archive there is a version of threads.js dated 120119(2) which basically resembles the last version before introducing tail call optimization on 120123. @@ -679,6 +727,10 @@ Process.prototype.doYield = function () { } }; +Process.prototype.expectReport = function () { + this.handleError(new Error("reporter didn't report")); +}; + // Process Exception Handling Process.prototype.handleError = function (error, element) { @@ -757,8 +809,8 @@ Process.prototype.reportJSFunction = function (parmNames, body) { ); }; -Process.prototype.doRun = function (context, args, isCustomBlock) { - return this.evaluate(context, args, true, isCustomBlock); +Process.prototype.doRun = function (context, args) { + return this.evaluate(context, args, true); }; Process.prototype.evaluate = function ( @@ -781,8 +833,9 @@ Process.prototype.evaluate = function ( } var outer = new Context(null, null, context.outerContext), + caller = this.context.parentContext, + exit, runnable, - extra, parms = args.asArray(), i, value; @@ -796,25 +849,13 @@ Process.prototype.evaluate = function ( outer, context.receiver ); - extra = new Context(runnable, 'doYield'); + this.context.parentContext = runnable; - /* - Note: if the context's expression is a ReporterBlockMorph, - the extra context gets popped off immediately without taking - effect (i.e. it doesn't yield within evaluating a stack of - nested reporters) - */ - - if (isCommand || (context.expression instanceof ReporterBlockMorph)) { - this.context.parentContext = extra; - } else { - this.context.parentContext = runnable; + if (context.expression instanceof ReporterBlockMorph) { + // auto-"warp" nested reporters + this.readyToYield = (Date.now() - this.lastYield > this.timeout); } - runnable.isLambda = true; - runnable.isImplicitLambda = context.isImplicitLambda; - runnable.isCustomBlock = false; - // assign parameters if any were passed if (parms.length > 0) { @@ -849,8 +890,9 @@ Process.prototype.evaluate = function ( } else if (context.emptySlots !== 1) { throw new Error( - 'expecting ' + context.emptySlots + ' input(s), ' - + 'but getting ' + parms.length + localize('expecting') + ' ' + context.emptySlots + ' ' + + localize('input(s), but getting') + ' ' + + parms.length ); } } @@ -858,6 +900,23 @@ Process.prototype.evaluate = function ( if (runnable.expression instanceof CommandBlockMorph) { runnable.expression = runnable.expression.blockSequence(); + if (!isCommand) { + if (caller) { + // tag caller, so "report" can catch it later + caller.tag = 'exit'; + } else { + // top-level context, insert a tagged exit context + // which "report" can catch later + exit = new Context( + runnable.parentContext, + 'expectReport', + outer, + outer.receiver + ); + exit.tag = 'exit'; + runnable.parentContext = exit; + } + } } }; @@ -867,6 +926,9 @@ Process.prototype.fork = function (context, args) { 'continuations cannot be forked' ); } + if (!(context instanceof Context)) { + throw new Error('expecting a ring but getting ' + context); + } var outer = new Context(null, null, context.outerContext), runnable = new Context(null, @@ -879,8 +941,6 @@ Process.prototype.fork = function (context, args) { stage = this.homeContext.receiver.parentThatIsA(StageMorph), proc = new Process(); - runnable.isLambda = true; - // assign parameters if any were passed if (parms.length > 0) { @@ -915,8 +975,9 @@ Process.prototype.fork = function (context, args) { } else if (context.emptySlots !== 1) { throw new Error( - 'expecting ' + context.emptySlots + ' input(s), ' - + 'but getting ' + parms.length + localize('expecting') + ' ' + context.emptySlots + ' ' + + localize('input(s), but getting') + ' ' + + parms.length ); } } @@ -933,68 +994,48 @@ Process.prototype.fork = function (context, args) { stage.threads.processes.push(proc); }; -Process.prototype.doReport = function (value, isCSlot) { - while (this.context && !this.context.isLambda) { +// Process stopping blocks primitives + +Process.prototype.doStopBlock = function () { + var target = this.context.expression.exitTag; + if (isNil(target)) { + return this.doStopCustomBlock(); + } + while (this.context && + (isNil(this.context.tag) || (this.context.tag > target))) { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); } else { this.popContext(); } } - if (this.context && this.context.isImplicitLambda) { + this.pushContext(); +}; + +Process.prototype.doStopCustomBlock = function () { + // fallback solution for "report" blocks inside + // custom command definitions and untagged "stop" blocks + while (this.context && !this.context.isCustomBlock) { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); } else { this.popContext(); } - return this.doReport(value, true); - } - if (this.context && this.context.isCustomBlock) { - // now I'm back at the custom block sequence. - // advance my pc to my expression's length - this.context.pc = this.context.expression.length - 1; } - if (isCSlot) { - if (this.context && - this.context.parentContext && - this.context.parentContext.expression instanceof Array) { - this.popContext(); - } - } - return value; -}; - -Process.prototype.doStopBlock = function () { - this.doReport(); -}; - -// Process evaluation variants, commented out for now (redundant) - -/* -Process.prototype.doRunWithInputList = function (context, args) { - // provide an extra selector for the palette - return this.doRun(context, args); -}; - -Process.prototype.evaluateWithInputList = function (context, args) { - // provide an extra selector for the palette - return this.evaluate(context, args); }; -Process.prototype.forkWithInputList = function (context, args) { - // provide an extra selector for the palette - return this.fork(context, args); -}; -*/ - // Process continuations primitives -Process.prototype.doCallCC = function (aContext) { - this.evaluate(aContext, new List([this.context.continuation()])); +Process.prototype.doCallCC = function (aContext, isReporter) { + this.evaluate( + aContext, + new List([this.context.continuation()]), + !isReporter + ); }; Process.prototype.reportCallCC = function (aContext) { - this.doCallCC(aContext); + this.doCallCC(aContext, true); }; Process.prototype.runContinuation = function (aContext, args) { @@ -1012,19 +1053,21 @@ Process.prototype.runContinuation = function (aContext, args) { // Process custom block primitives Process.prototype.evaluateCustomBlock = function () { - var context = this.context.expression.definition.body, + var caller = this.context.parentContext, + context = this.context.expression.definition.body, declarations = this.context.expression.definition.declarations, args = new List(this.context.inputs), parms = args.asArray(), runnable, - extra, + exit, i, value, outer; if (!context) {return null; } + this.procedureCount += 1; outer = new Context(); - outer.receiver = this.context.receiver; // || this.homeContext.receiver; + outer.receiver = this.context.receiver; outer.variables.parentFrame = outer.receiver ? outer.receiver.variables : null; @@ -1032,15 +1075,10 @@ Process.prototype.evaluateCustomBlock = function () { this.context.parentContext, context.expression, outer, - outer.receiver, - true // is custom block + outer.receiver ); - extra = new Context(runnable, 'doYield'); - - this.context.parentContext = extra; - - runnable.isLambda = true; runnable.isCustomBlock = true; + this.context.parentContext = runnable; // passing parameters if any were passed if (parms.length > 0) { @@ -1062,9 +1100,43 @@ Process.prototype.evaluateCustomBlock = function () { } } - if (runnable.expression instanceof CommandBlockMorph) { - runnable.expression = runnable.expression.blockSequence(); + // tag return target + if (this.context.expression.definition.type !== 'command') { + if (caller) { + // tag caller, so "report" can catch it later + caller.tag = 'exit'; + } else { + // top-level context, insert a tagged exit context + // which "report" can catch later + exit = new Context( + runnable.parentContext, + 'expectReport', + outer, + outer.receiver + ); + exit.tag = 'exit'; + runnable.parentContext = exit; + } + // auto-"warp" nested reporters + this.readyToYield = (Date.now() - this.lastYield > this.timeout); + } else { + // tag all "stop this block" blocks with the current + // procedureCount as exitTag, and mark all "report" blocks + // as being inside a custom command definition + runnable.expression.tagExitBlocks(this.procedureCount, true); + + // tag the caller with the current procedure count, so + // "stop this block" blocks can catch it, but only + // if the caller hasn't been tagged already + if (caller && !caller.tag) { + caller.tag = this.procedureCount; + } + // yield commands unless explicitly "warped" + if (!this.isAtomic) { + this.readyToYield = true; + } } + runnable.expression = runnable.expression.blockSequence(); }; // Process variables primitives @@ -1148,7 +1220,7 @@ Process.prototype.doShowVar = function (varName) { if (isGlobal || target.owner) { label = name; } else { - label = name + ' (temporary)'; + label = name + ' ' + localize('(temporary)'); } watcher = new WatcherMorph( label, @@ -1259,7 +1331,7 @@ Process.prototype.doInsertInList = function (element, index, list) { return null; } if (this.inputOption(index) === 'any') { - idx = this.reportRandom(1, list.length()); + idx = this.reportRandom(1, list.length() + 1); } if (this.inputOption(index) === 'last') { idx = list.length() + 1; @@ -1308,16 +1380,12 @@ Process.prototype.reportListContainsItem = function (list, element) { Process.prototype.doIf = function () { var args = this.context.inputs, outer = this.context.outerContext, // for tail call elimination - isLambda = this.context.isLambda, - isImplicitLambda = this.context.isImplicitLambda, isCustomBlock = this.context.isCustomBlock; this.popContext(); if (args[0]) { if (args[1]) { this.pushContext(args[1].blockSequence(), outer); - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; } } @@ -1327,8 +1395,6 @@ Process.prototype.doIf = function () { Process.prototype.doIfElse = function () { var args = this.context.inputs, outer = this.context.outerContext, // for tail call elimination - isLambda = this.context.isLambda, - isImplicitLambda = this.context.isImplicitLambda, isCustomBlock = this.context.isCustomBlock; this.popContext(); @@ -1344,8 +1410,6 @@ Process.prototype.doIfElse = function () { } } if (this.context) { - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; } @@ -1420,8 +1484,6 @@ Process.prototype.doStopOthers = function (choice) { Process.prototype.doWarp = function (body) { // execute my contents block atomically (more or less) var outer = this.context.outerContext, // for tail call elimination - isLambda = this.context.isLambda, - isImplicitLambda = this.context.isImplicitLambda, isCustomBlock = this.context.isCustomBlock, stage; @@ -1438,13 +1500,8 @@ Process.prototype.doWarp = function (body) { stage.fps = 0; // variable frame rate } } - this.pushContext('doYield'); - - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; - if (!this.isAtomic) { this.pushContext('doStopWarping'); } @@ -1523,28 +1580,19 @@ Process.prototype.doForever = function (body) { Process.prototype.doRepeat = function (counter, body) { var block = this.context.expression, outer = this.context.outerContext, // for tail call elimination - isLambda = this.context.isLambda, - isImplicitLambda = this.context.isImplicitLambda, isCustomBlock = this.context.isCustomBlock; if (counter < 1) { // was '=== 0', which caused infinite loops on non-ints return null; } this.popContext(); - this.pushContext(block, outer); - - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; - this.context.addInput(counter - 1); - this.pushContext('doYield'); if (body) { this.pushContext(body.blockSequence()); } - this.pushContext(); }; @@ -1631,6 +1679,27 @@ Process.prototype.reportMap = function (reporter, list) { } }; +Process.prototype.doForEach = function (upvar, list, script) { + // perform a script for each element of a list, assigning the + // current iteration's element to a variable with the name + // specified in the "upvar" parameter, so it can be referenced + // within the script. Uses the context's - unused - fourth + // element as temporary storage for the current list index + + if (isNil(this.context.inputs[3])) {this.context.inputs[3] = 1; } + var index = this.context.inputs[3]; + this.context.outerContext.variables.addVar(upvar); + this.context.outerContext.variables.setVar( + upvar, + list.at(index) + ); + if (index > list.length()) {return; } + this.context.inputs[3] += 1; + this.pushContext('doYield'); + this.pushContext(); + this.evaluate(script, new List(), true); +}; + // Process interpolated primitives Process.prototype.doWait = function (secs) { @@ -2134,15 +2203,17 @@ Process.prototype.reportTextSplit = function (string, delimiter) { str, del; if (!contains(types, strType)) { - throw new Error('expecting a text instad of a ' + strType); + throw new Error('expecting text instead of a ' + strType); } if (!contains(types, delType)) { - throw new Error('expecting a text delimiter instad of a ' + delType); + throw new Error('expecting a text delimiter instead of a ' + delType); } str = (string || '').toString(); switch (this.inputOption(delimiter)) { case 'line': - del = '\n'; + // Unicode Compliant Line Splitting (Platform independent) + // http://www.unicode.org/reports/tr18/#Line_Boundaries + del = /\r\n|[\n\v\f\r\x85\u2028\u2029]/; break; case 'tab': del = '\t'; @@ -2151,7 +2222,9 @@ Process.prototype.reportTextSplit = function (string, delimiter) { del = '\r'; break; case 'whitespace': - return new List(str.trim().split(/[\t\r\n ]+/)); + str = str.trim(); + del = /\s+/; + break; case 'letter': del = ''; break; @@ -2316,6 +2389,7 @@ Process.prototype.objectTouchingObject = function (thisObj, name) { var myself = this, those, stage, + box, mouse; if (this.inputOption(name) === 'mouse-pointer') { @@ -2327,9 +2401,14 @@ Process.prototype.objectTouchingObject = function (thisObj, name) { } else { stage = thisObj.parentThatIsA(StageMorph); if (stage) { - if (this.inputOption(name) === 'edge' && - !stage.bounds.containsRectangle(thisObj.bounds)) { - return true; + if (this.inputOption(name) === 'edge') { + box = thisObj.bounds; + if (!thisObj.costume && thisObj.penBounds) { + box = thisObj.penBounds.translateBy(thisObj.position()); + } + if (!stage.bounds.containsRectangle(box)) { + return true; + } } if (this.inputOption(name) === 'pen trails' && thisObj.isTouching(stage.penTrailsMorph())) { @@ -2467,6 +2546,7 @@ Process.prototype.reportContextFor = function (context, otherObj) { if (result.outerContext) { result.outerContext = copy(result.outerContext); result.outerContext.receiver = otherObj; + result.outerContext.variables.parentFrame = otherObj.variables; } return result; }; @@ -2760,25 +2840,25 @@ Process.prototype.reportFrameCount = function () { structure: - parentContext the Context to return to when this one has + parentContext the Context to return to when this one has been evaluated. outerContext the Context holding my lexical scope - expression SyntaxElementMorph, an array of blocks to evaluate, + expression SyntaxElementMorph, an array of blocks to evaluate, null or a String denoting a selector, e.g. 'doYield' receiver the object to which the expression applies, if any - variables the current VariableFrame, if any - inputs an array of input values computed so far + variables the current VariableFrame, if any + inputs an array of input values computed so far (if expression is a BlockMorph) - pc the index of the next block to evaluate + pc the index of the next block to evaluate (if expression is an array) - startTime time when the context was first evaluated - startValue initial value for interpolated operations + startTime time when the context was first evaluated + startValue initial value for interpolated operations activeAudio audio buffer for interpolated operations, don't persist activeNote audio oscillator for interpolated ops, don't persist - isLambda marker for return ops - isImplicitLambda marker for return ops isCustomBlock marker for return ops - emptySlots caches the number of empty slots for reification + emptySlots caches the number of empty slots for reification + tag string or number to optionally identify the Context, + as a "return" target (for the "stop block" primitive) */ function Context( @@ -2801,22 +2881,19 @@ function Context( this.startTime = null; this.activeAudio = null; this.activeNote = null; - this.isLambda = false; // marks the end of a lambda - this.isImplicitLambda = false; // marks the end of a C-shaped slot this.isCustomBlock = false; // marks the end of a custom block's stack this.emptySlots = 0; // used for block reification + this.tag = null; // lexical catch-tag for custom blocks } Context.prototype.toString = function () { - var pref = this.isLambda ? '\u03BB-' : '', - expr = this.expression; - + var expr = this.expression; if (expr instanceof Array) { if (expr.length > 0) { expr = '[' + expr[0] + ']'; } } - return pref + 'Context >> ' + expr + ' ' + this.variables; + return 'Context >> ' + expr + ' ' + this.variables; }; Context.prototype.image = function () { @@ -2870,9 +2947,10 @@ Context.prototype.continuation = function () { } else if (this.parentContext) { cont = this.parentContext; } else { - return new Context(null, 'doStop'); + return new Context(null, 'doYield'); } cont = cont.copyForContinuation(); + cont.tag = null; cont.isContinuation = true; return cont; }; @@ -3003,9 +3081,9 @@ VariableFrame.prototype.find = function (name) { var frame = this.silentFind(name); if (frame) {return frame; } throw new Error( - 'a variable of name \'' + localize('a variable of name \'') + name - + '\'\ndoes not exist in this context' + + localize('\'\ndoes not exist in this context') ); }; @@ -3070,9 +3148,9 @@ VariableFrame.prototype.getVar = function (name) { return ''; } throw new Error( - 'a variable of name \'' + localize('a variable of name \'') + name - + '\'\ndoes not exist in this context' + + localize('\'\ndoes not exist in this context') ); }; @@ -1 +1 @@ -<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="map %'function' over %'lists'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%repRing"></input><input type="%mult%l"></input></inputs><script><block s="doWarp"><script><block s="doDeclareVariables"><list><l>mapone</l><l>mapmany</l></list></block><block s="doSetVar"><l>mapone</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="evaluate"><block var="mapone"/><list><block s="reportCDR"><block var="data"/></block></list></block></block></block></script><list><l>data</l></list></block></block><block s="doSetVar"><l>mapmany</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportListItem"><l>1</l><block var="data lists"/></block></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><custom-block s="map %repRing over %mult%l"><block s="reifyReporter"><autolambda><block s="reportListItem"><l>1</l><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block></block><block s="evaluate"><block var="mapmany"/><list><custom-block s="map %repRing over %mult%l"><block s="reifyReporter"><autolambda><block s="reportCDR"><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block></list></block></block></block></script><list><l>data lists</l></list></block></block><block s="doIfElse"><custom-block s="empty? %l"><block s="reportCDR"><block var="lists"/></block></custom-block><script><block s="doReport"><block s="evaluate"><block var="mapone"/><list><block s="reportListItem"><l>1</l><block var="lists"/></block></list></block></block></script><script><block s="doReport"><block s="evaluate"><block var="mapmany"/><list><block var="lists"/></list></block></block></script></block></script></block></script></block-definition><block-definition s="empty? %'data'" type="predicate" category="lists"><header></header><code></code><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="reportEquals"><block var="data"/><block s="reportNewList"><list></list></block></block></block></script></block-definition><block-definition s="keep items such that %'pred' from %'data'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%predRing"></input><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIfElse"><block s="evaluate"><block var="pred"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="data"/></block><custom-block s="keep items such that %predRing from %l"><block var="pred"/><block s="reportCDR"><block var="data"/></block></custom-block></block></block></script><script><block s="doReport"><custom-block s="keep items such that %predRing from %l"><block var="pred"/><block s="reportCDR"><block var="data"/></block></custom-block></block></script></block></script></block></script></block-definition><block-definition s="combine with %'function' items of %'data'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%repRing"></input><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportCDR"><block var="data"/></block></custom-block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="data"/></block></block></script></block><block s="doReport"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="data"/></block><custom-block s="combine with %repRing items of %l"><block var="function"/><block s="reportCDR"><block var="data"/></block></custom-block></list></block></block></script></block></script></block-definition><block-definition s="if %'test' then %'true' else %'false'" type="reporter" category="control"><header></header><code></code><inputs><input type="%b"></input><input type="%anyUE"></input><input type="%anyUE"></input></inputs><script><block s="doIfElse"><block var="test"/><script><block s="doReport"><block s="evaluate"><block var="true"/><list></list></block></block></script><script><block s="doReport"><block s="evaluate"><block var="false"/><list></list></block></block></script></block></script></block-definition><block-definition s="for %'i' = %'start' to %'end' %'action'" type="command" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%n">1</input><input type="%n">10</input><input type="%cs"></input></inputs><script><block s="doDeclareVariables"><list><l>step</l><l>tester</l></list></block><block s="doIfElse"><block s="reportGreaterThan"><block var="start"/><block var="end"/></block><script><block s="doSetVar"><l>step</l><l>-1</l></block><block s="doSetVar"><l>tester</l><block s="reifyReporter"><autolambda><block s="reportLessThan"><block var="i"/><block var="end"/></block></autolambda><list></list></block></block></script><script><block s="doSetVar"><l>step</l><l>1</l></block><block s="doSetVar"><l>tester</l><block s="reifyReporter"><autolambda><block s="reportGreaterThan"><block var="i"/><block var="end"/></block></autolambda><list></list></block></block></script></block><block s="doSetVar"><l>i</l><block var="start"/></block><block s="doUntil"><block s="evaluate"><block var="tester"/><list></list></block><script><block s="doRun"><block var="action"/><list></list></block><block s="doChangeVar"><l>i</l><block var="step"/></block></script></block></script></block-definition><block-definition s="join words %'words'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%mult%txt"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportCDR"><block var="words"/></block></custom-block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="words"/></block></block></script></block><block s="doReport"><block s="reportJoinWords"><list><block s="reportListItem"><l>1</l><block var="words"/></block><block s="reportJoinWords"><list><l> </l><block s="evaluate"><block s="reifyReporter"><autolambda><custom-block s="join words %mult%txt"><block s="reportCDR"><block var="words"/></block></custom-block></autolambda><list></list></block><list></list></block></list></block></list></block></block></script></block></script></block-definition><block-definition s="list $arrowRight sentence %'data'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doReport"><custom-block s="combine with %repRing items of %l"><block s="reifyReporter"><autolambda><custom-block s="join words %mult%txt"><list><l></l><l></l></list></custom-block></autolambda><list></list></block><block var="data"/></custom-block></block></script></block></script></block-definition><block-definition s="sentence $arrowRight list %'text'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%txt"></input></inputs><script><block s="doWarp"><script><block s="doReport"><block s="reportTextSplit"><block var="text"/><l><option>whitespace</option></l></block></block></script></block></script></block-definition><block-definition s="catch %'tag' %'action'" type="command" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%cs"></input></inputs><script><block s="doCallCC"><block s="reifyScript"><script><block s="doSetVar"><l>tag</l><block var="cont"/></block><block s="doRun"><block var="action"/><list></list></block></script><list><l>cont</l></list></block></block></script></block-definition><block-definition s="throw %'cont'" type="command" category="control"><header></header><code></code><inputs><input type="%s">catchtag</input></inputs><script><block s="doRun"><block var="cont"/><list></list></block></script></block-definition><block-definition s="catch %'tag' %'value'" type="reporter" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%anyUE"></input></inputs><script><block s="doCallCC"><block s="reifyScript"><script><block s="doSetVar"><l>tag</l><block var="cont"/></block><block s="doReport"><block s="evaluate"><block var="value"/><list></list></block></block></script><list><l>cont</l></list></block></block></script></block-definition><block-definition s="throw %'tag' %'value'" type="command" category="control"><header></header><code></code><inputs><input type="%s">catchtag</input><input type="%s"></input></inputs><script><block s="doRun"><block var="tag"/><list><block var="value"/></list></block></script></block-definition><block-definition s="for each %'item' of %'data' %'action'" type="command" category="lists"><header></header><code></code><inputs><input type="%upvar"></input><input type="%l"></input><input type="%cs"></input></inputs><script><block s="doUntil"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doSetVar"><l>item</l><block s="reportListItem"><l>1</l><block var="data"/></block></block><block s="doRun"><block var="action"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="doSetVar"><l>data</l><block s="reportCDR"><block var="data"/></block></block></script></block></script></block-definition><block-definition s="if %'test' do %'action' and pause all $pause-1-255-220-0" type="command" category="control"><header></header><code></code><inputs><input type="%boolUE"></input><input type="%cs"></input></inputs><script><block s="doDeclareVariables"><list><l>breakpoint</l></list></block><block s="doIf"><block s="evaluate"><block var="test"/><list></list></block><script><block s="doSetVar"><l>breakpoint</l><block var="test"/></block><block s="doShowVar"><l>breakpoint</l></block><block s="doRun"><block var="action"/><list></list></block><block s="doPauseAll"></block><block s="doHideVar"><l></l></block></script></block></script></block-definition><block-definition s="word $arrowRight list %'word'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%txt"></input></inputs><script><block s="doWarp"><script><block s="doReport"><block s="reportTextSplit"><block var="word"/><l><option>letter</option></l></block></block></script></block></script></block-definition></blocks>
\ No newline at end of file +<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="map %'function' over %'lists'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%repRing"></input><input type="%mult%l"></input></inputs><script><block s="doWarp"><script><block s="doDeclareVariables"><list><l>mapone</l><l>mapmany</l></list></block><block s="doSetVar"><l>mapone</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="evaluate"><block var="mapone"/><list><block s="reportCDR"><block var="data"/></block></list></block></block></block></script><list><l>data</l></list></block></block><block s="doSetVar"><l>mapmany</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportListItem"><l>1</l><block var="data lists"/></block></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><custom-block s="map %repRing over %mult%l"><block s="reifyReporter"><autolambda><block s="reportListItem"><l>1</l><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block></block><block s="evaluate"><block var="mapmany"/><list><custom-block s="map %repRing over %mult%l"><block s="reifyReporter"><autolambda><block s="reportCDR"><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block></list></block></block></block></script><list><l>data lists</l></list></block></block><block s="doIfElse"><custom-block s="empty? %l"><block s="reportCDR"><block var="lists"/></block></custom-block><script><block s="doReport"><block s="evaluate"><block var="mapone"/><list><block s="reportListItem"><l>1</l><block var="lists"/></block></list></block></block></script><script><block s="doReport"><block s="evaluate"><block var="mapmany"/><list><block var="lists"/></list></block></block></script></block></script></block></script></block-definition><block-definition s="empty? %'data'" type="predicate" category="lists"><header></header><code></code><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="reportEquals"><block var="data"/><block s="reportNewList"><list></list></block></block></block></script></block-definition><block-definition s="keep items such that %'pred' from %'data'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%predRing"></input><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIfElse"><block s="evaluate"><block var="pred"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="data"/></block><custom-block s="keep items such that %predRing from %l"><block var="pred"/><block s="reportCDR"><block var="data"/></block></custom-block></block></block></script><script><block s="doReport"><custom-block s="keep items such that %predRing from %l"><block var="pred"/><block s="reportCDR"><block var="data"/></block></custom-block></block></script></block></script></block></script></block-definition><block-definition s="combine with %'function' items of %'data'" type="reporter" category="lists"><header></header><code></code><inputs><input type="%repRing"></input><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportCDR"><block var="data"/></block></custom-block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="data"/></block></block></script></block><block s="doReport"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="data"/></block><custom-block s="combine with %repRing items of %l"><block var="function"/><block s="reportCDR"><block var="data"/></block></custom-block></list></block></block></script></block></script></block-definition><block-definition s="if %'test' then %'true' else %'false'" type="reporter" category="control"><header></header><code></code><inputs><input type="%b"></input><input type="%anyUE"></input><input type="%anyUE"></input></inputs><script><block s="doIfElse"><block var="test"/><script><block s="doReport"><block s="evaluate"><block var="true"/><list></list></block></block></script><script><block s="doReport"><block s="evaluate"><block var="false"/><list></list></block></block></script></block></script></block-definition><block-definition s="for %'i' = %'start' to %'end' %'action'" type="command" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%n">1</input><input type="%n">10</input><input type="%cs"></input></inputs><script><block s="doDeclareVariables"><list><l>step</l><l>tester</l></list></block><block s="doIfElse"><block s="reportGreaterThan"><block var="start"/><block var="end"/></block><script><block s="doSetVar"><l>step</l><l>-1</l></block><block s="doSetVar"><l>tester</l><block s="reifyReporter"><autolambda><block s="reportLessThan"><block var="i"/><block var="end"/></block></autolambda><list></list></block></block></script><script><block s="doSetVar"><l>step</l><l>1</l></block><block s="doSetVar"><l>tester</l><block s="reifyReporter"><autolambda><block s="reportGreaterThan"><block var="i"/><block var="end"/></block></autolambda><list></list></block></block></script></block><block s="doSetVar"><l>i</l><block var="start"/></block><block s="doUntil"><block s="evaluate"><block var="tester"/><list></list></block><script><block s="doRun"><block var="action"/><list></list></block><block s="doChangeVar"><l>i</l><block var="step"/></block></script></block></script></block-definition><block-definition s="join words %'words'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%mult%txt"></input></inputs><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportCDR"><block var="words"/></block></custom-block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="words"/></block></block></script></block><block s="doReport"><block s="reportJoinWords"><list><block s="reportListItem"><l>1</l><block var="words"/></block><block s="reportJoinWords"><list><l> </l><block s="evaluate"><block s="reifyReporter"><autolambda><custom-block s="join words %mult%txt"><block s="reportCDR"><block var="words"/></block></custom-block></autolambda><list></list></block><list></list></block></list></block></list></block></block></script></block></script></block-definition><block-definition s="list $arrowRight sentence %'data'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doReport"><custom-block s="combine with %repRing items of %l"><block s="reifyReporter"><autolambda><custom-block s="join words %mult%txt"><list><l></l><l></l></list></custom-block></autolambda><list></list></block><block var="data"/></custom-block></block></script></block></script></block-definition><block-definition s="sentence $arrowRight list %'text'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%txt"></input></inputs><script><block s="doWarp"><script><block s="doReport"><block s="reportTextSplit"><block var="text"/><l><option>whitespace</option></l></block></block></script></block></script></block-definition><block-definition s="catch %'tag' %'action'" type="command" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%cs"></input></inputs><script><block s="doCallCC"><block s="reifyScript"><script><block s="doSetVar"><l>tag</l><block var="cont"/></block><block s="doRun"><block var="action"/><list></list></block></script><list><l>cont</l></list></block></block></script></block-definition><block-definition s="throw %'cont'" type="command" category="control"><header></header><code></code><inputs><input type="%s">catchtag</input></inputs><script><block s="doRun"><block var="cont"/><list></list></block></script></block-definition><block-definition s="catch %'tag' %'value'" type="reporter" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%anyUE"></input></inputs><script><block s="doCallCC"><block s="reifyScript"><script><block s="doSetVar"><l>tag</l><block var="cont"/></block><block s="doReport"><block s="evaluate"><block var="value"/><list></list></block></block></script><list><l>cont</l></list></block></block></script></block-definition><block-definition s="throw %'tag' %'value'" type="command" category="control"><header></header><code></code><inputs><input type="%s">catchtag</input><input type="%s"></input></inputs><script><block s="doRun"><block var="tag"/><list><block var="value"/></list></block></script></block-definition><block-definition s="for each %'item' of %'data' %'action'" type="command" category="lists"><header></header><code></code><inputs><input type="%upvar"></input><input type="%l"></input><input type="%cs"></input></inputs><script><block s="doUntil"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doSetVar"><l>item</l><block s="reportListItem"><l>1</l><block var="data"/></block></block><block s="doRun"><block var="action"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="doSetVar"><l>data</l><block s="reportCDR"><block var="data"/></block></block></script></block></script></block-definition><block-definition s="if %'test' do %'action' and pause all $pause-1-255-220-0" type="command" category="control"><header></header><code></code><inputs><input type="%boolUE"></input><input type="%cs"></input></inputs><script><block s="doDeclareVariables"><list><l>breakpoint</l></list></block><block s="doIf"><block s="evaluate"><block var="test"/><list></list></block><script><block s="doSetVar"><l>breakpoint</l><block var="test"/></block><block s="doShowVar"><l>breakpoint</l></block><block s="doRun"><block var="action"/><list></list></block><block s="doPauseAll"></block><block s="doHideVar"><l></l></block></script></block></script></block-definition><block-definition s="word $arrowRight list %'word'" type="reporter" category="operators"><header></header><code></code><inputs><input type="%txt"></input></inputs><script><block s="doWarp"><script><block s="doReport"><block s="reportTextSplit"><block var="word"/><l><option>letter</option></l></block></block></script></block></script></block-definition><block-definition s="ignore %'x'" type="command" category="control"><header></header><code></code><inputs><input type="%s"></input></inputs></block-definition></blocks>
\ No newline at end of file |
