From f308c23824fcb48e25d2296ddc44a3ab4bcbef64 Mon Sep 17 00:00:00 2001 From: tonychenr Date: Tue, 7 Oct 2014 19:15:08 -0700 Subject: Fixed range 1 slider bug issue # 301 --- morphic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morphic.js b/morphic.js index 4e18482..b19d390 100644 --- a/morphic.js +++ b/morphic.js @@ -5754,7 +5754,7 @@ SliderMorph.prototype.rangeSize = function () { }; SliderMorph.prototype.ratio = function () { - return this.size / this.rangeSize(); + return this.size / (this.rangeSize() + 1); }; SliderMorph.prototype.unitSize = function () { -- cgit v1.3.1 From dda2d48f16ae56a139cad8feeb8172c3a54b182f Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 14 Oct 2014 17:58:57 +0100 Subject: add localization to unknown variable error --- threads.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/threads.js b/threads.js index 6a59f3c..086ffcb 100644 --- a/threads.js +++ b/threads.js @@ -3003,9 +3003,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 +3070,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') ); }; -- cgit v1.3.1 From dc805a9012d66cc906301ae5c63fc96b15e6dd12 Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 14 Oct 2014 18:00:35 +0100 Subject: correct translation of 'unshare'; add new translations --- lang-pt.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lang-pt.js b/lang-pt.js index cd3b5fe..79303a7 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -1616,7 +1616,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 +1641,12 @@ 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', // produção de código 'map %cmdRing to %codeKind %code': -- cgit v1.3.1 From dbf2e6665b4ff7ef8cb863bcfef5939117a2f795 Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Sat, 18 Oct 2014 23:00:11 -0700 Subject: Improvements to Split block for whitespace and lines: * Split by whitespace now uses the built-in definition of whitespace \s This catches all characters definted as whitespace, see below: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp * Split a line by all unicode compliant line breaks. The biggest impact here is that OSX and Windows files will now split the same way. The cr option is still around, but ther's no longer a need for it, IMO. --- threads.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/threads.js b/threads.js index 6a59f3c..2359166 100644 --- a/threads.js +++ b/threads.js @@ -2134,15 +2134,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'; + // Entirely 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 +2153,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; -- cgit v1.3.1 From 413e6a0e6a884ef9811221a3f92353f1d3fa6544 Mon Sep 17 00:00:00 2001 From: natashasandy Date: Tue, 21 Oct 2014 18:03:15 -0700 Subject: Fixed percent symbols in custom blocks This fixes issue #476 --- byob.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/byob.js b/byob.js index 1277bb6..71b3298 100644 --- a/byob.js +++ b/byob.js @@ -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)); + var label = spec.replace(/%/g, ''); + part = new BlockInputFragmentMorph(label); } else { part = new BlockLabelFragmentMorph(spec); part.fontSize = this.fontSize; -- cgit v1.3.1 From 0dcca0606c3ae570110614d0dd94d6a38255100f Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Mon, 27 Oct 2014 18:19:29 -0700 Subject: Set Default Save location to Cloud on Snap! load When Snap! is loaded, Snap! will now check whether a user is logged in (via the presence of `SnapCloud.username`) and if so, the default save location will be the cloud. --- gui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui.js b/gui.js index 04481cc..bb440b1 100644 --- a/gui.js +++ b/gui.js @@ -190,7 +190,7 @@ IDE_Morph.prototype.init = function (isAutoFill) { // additional properties: this.cloudMsg = null; - this.source = 'local'; + this.source = SnapCloud.username ? 'cloud' : 'local'; this.serializer = new SnapSerializer(); this.globalVariables = new VariableFrame(); -- cgit v1.3.1 From 33229b34b834c61509c4a17f6404efcbdae93f0a Mon Sep 17 00:00:00 2001 From: Erik Olsson Date: Thu, 30 Oct 2014 13:00:02 +0100 Subject: Added Swedish --- lang-sv.js | 1169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ locale.js | 12 + 2 files changed, 1181 insertions(+) create mode 100644 lang-sv.js diff --git a/lang-sv.js b/lang-sv.js new file mode 100644 index 0000000..b4599c9 --- /dev/null +++ b/lang-sv.js @@ -0,0 +1,1169 @@ +/* + + 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 . + + + + 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: + + + + 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 ) + + + 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 + + + + 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: + + + 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 ) + + ¯ , \u00F8 + Ê , \u00E6 +  , \u00E5 + ÿ , \u00D8 + ∆ ; \u00C6 + ≈ , \u00C5 +*/ + + // 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': + '2013-09-16', // this, too, will appear in the Translators tab + + // GUI + // control bar: + 'untitled': + 'inget namn', + 'development mode': + 'utvecklareläge', + + // categories: + 'Motion': + 'Rörelse', + 'Looks': + 'Utseende', + 'Sound': + 'Ljud', + 'Pen': + 'Penna', + 'Control': + 'Kontroll', + 'Sensing': + 'Känna 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öger/vänster', + + // new sprite button: + 'add a new Sprite': + 'lägg till ny Sprite', + + // tab help + 'costumes tab help': + 'kostymflikshjälp', + + 'import a sound from your computer\nby dragging it into here': + 'importera en ljudfil från 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örelser' + + 'finns', + 'move %n steps': + 'gå %n steg', + 'turn %clockwise %n degrees': + 'vänd %clockwise %n grader', + 'turn %counterclockwise %n degrees': + 'vänd %counterclockwise %n grader', + 'point in direction %dir': + 'peka mot riktning %dir', + 'point towards %dst': + 'peka mot %dst', + 'go to x: %n y: %n': + 'gå till x: %n y: %n', + 'go to %dst': + 'gå till %dst', + 'glide %n secs to x: %n y: %n': + 'glid %n sek till x: %n y: %n', + 'change x by %n': + 'ändra x med %n', + 'set x to %n': + 'sätt x till %n', + 'change y by %n': + 'ändra y med %n', + 'set y to %n': + 'sätt 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ästa kostym', + 'costume #': + 'kostym nr.', + 'say %s for %n secs': + 'säg %s i %n sek', + 'say %s': + 'säg %s', + 'think %s for %n secs': + 'tänk %s i %n sek', + 'think %s': + 'tänk %s', + 'Hello!': + 'Hej!', + 'Hmm...': + 'Oj...', + 'change %eff effect by %n': + 'ändra %eff -effekt med %n', + 'set %eff effect to %n': + 'sätt %eff -effekt til %n', + 'clear graphic effects': + 'nollställ grafiska effekter', + 'change size by %n': + 'ändra storlek med %n', + 'set size to %n %': + 'sätt storlek till %n %', + 'size': + 'storlek', + 'show': + 'visa', + 'hide': + 'göm', + 'go to front': + 'lägg överst', + 'go back %n layers': + 'flytta %n lager bakåt', + + 'development mode \ndebugging primitives:': + 'utvecklarläge \nDebugging av block', + 'console log %mult%s': + 'skriv till konsoll: %mult%s', + 'alert %mult%s': + 'Pop-up: %mult%s', + + // sound: + 'play sound %snd': + 'spill lyd %snd', + 'play sound %snd until done': + 'spill lyd %snd ferdig', + 'stop all sounds': + 'stopp all lyd', + 'rest for %n beats': + 'pause i %n slag', + 'play note %n for %n beats': + 'spill note %n i %n slag', + 'change tempo by %n': + 'endre tempo med %n', + 'set tempo to %n bpm': + 'sett tempo til %n bpm', + 'tempo': + 'tempo', + + // pen: + 'clear': + 'slett', + 'pen down': + 'penn ned', + 'pen up': + 'penn opp', + 'set pen color to %clr': + 'sett pennfargen til %clr', + 'change pen color by %n': + 'endre pennfargen med %n', + 'set pen color to %n': + 'sett penfargen til %n', + 'change pen shade by %n': + 'endre pennintensitet med %n', + 'set pen shade to %n': + 'sett pennintensitet til %n', + 'change pen size by %n': + 'endre pennbredde med %n', + 'set pen size to %n': + 'sett pennbredde til %n', + 'stamp': + 'stemple', + + // control: + 'when %greenflag clicked': + 'N\u00E5r %greenflag klikkes', + 'when %key key pressed': + 'N\u00E5r tast %key trykkes', + 'when I am clicked': + 'N\u00E5r jeg klikkes', + 'when I receive %msg': + 'N\u00E5r jeg %msg mottar', + 'broadcast %msg': + 'send melding %msg', + 'broadcast %msg and wait': + 'send melding %msg og vent', + 'Message name': + 'Meldingens navn', + 'wait %n secs': + 'vent i %n sek', + 'wait until %b': + 'vent til %b', + 'forever %c': + 'for alltid %c', + 'repeat %n %c': + 'gjenta %n ganger %c', + 'repeat until %b %c': + 'gjenta til %b %c', + 'if %b %c': + 'hvis %b %c', + 'if %b %c else %c': + 'hvis %b %c ellers %c', + 'report %s': + 'returner %s', + 'stop block': + 'stopp denne blokk', + 'stop script': + 'stopp dette skript', + 'stop all %stop': + 'stopp alt %stop', + 'pause all %pause': + 'pause (alle) %pause', + + 'run %cmdRing %inputs': + 'kj\u00F8r %cmdRing fra %inputs', + 'launch %cmdRing %inputs': + 'start %cmdRing %inputs', + 'call %repRing %inputs': + 'kall %repRing fra %inputs', + 'run %cmdRing w/continuation': + 'kj\u00F8r %cmdRing med kontinuering', + 'call %cmdRing w/continuation': + 'kall %cmdRing med kontinuering', + 'when I start as a clone': + 'n\u00E5r klon startes', + 'create a clone of %cln': + 'opprett %cln', + 'myself': + 'meg', + 'delete this clone': + 'slett klon', + + + 'warp %c': + 'warp %c', + + // sensing: + 'touching %col ?': + 'ber\u00F8rer %col ?', + 'touching %clr ?': + 'ber\u00F8rer %clr ?', + 'color %clr is touching %clr ?': + 'farge %clr ber\u00F8rer %clr ?', + 'ask %s and wait': + 'sp\u00F8r %s og vent', + 'what\'s your name?': + 'hva heter du?', + 'answer': + 'svar', + 'mouse x': + 'mus x-posisjon', + 'mouse y': + 'mus y-posisjon', + 'mouse down?': + 'mustast trykket?', + 'key %key pressed?': + 'tast %key trykket?', + 'distance to %dst': + 'avstand til %dst', + 'reset timer': + 'start stoppeklokke', + 'timer': + 'stoppeklokke', + 'http:// %s': + 'http:// %s', + + 'turbo mode?': + 'turbo modus?', + 'set turbo mode to %b': + 'sett turbo modus til %b', + + + 'filtered for %clr': + 'filter %clr', + 'stack size': + 'stack-st\u00F8rrelse', + 'frames': + 'rammer', + + // operators: + '%n mod %n': + '%n mod %n', + 'round %n': + 'rund av %n', + '%fun av %n': + '%fun von %n', + 'pick random %n to %n': + 'tilfeldig fra %n til %n', + '%b and %b': + '%b OG %b', + '%b or %b': + '%b ELLER %b', + 'not %b': + 'IKKE %b', + 'true': + 'SANN', + 'false': + 'USANN', + 'join %words': + 'skj\u00F8t %words', + 'hello': + 'hei', + 'world': + 'verden', + 'letter %n of %s': + 'bokstav %n av %s', + 'length of %s': + 'lengde av %s', + 'unicode of %s': + 'unicode av %s', + 'unicode %n as letter': + 'unicode %n som bokstav', + 'is %s a %typ ?': + '%s er %typ ?', + 'is %s identical to %s ?': + '%s identisk med %s ?', + + 'type of %s': + 'type %s', + + // variables: + 'Make a variable': + 'Ny variabel', + 'Variable name': + 'Variabelnavn', + 'Delete a variable': + 'Slett variabel', + + 'set %var to %s': + 'sett %var til %s', + 'change %var by %n': + 'endre %var med %n', + 'show variable %var': + 'vis variabel %var', + 'hide variable %var': + 'skjul variabel %var', + 'script variables %scriptVars': + 'skriptvariable %scriptVars', + + // lists: + 'list %exp': + 'liste %exp', + '%s in front of %l': + '%s framfor %l', + 'item %idx of %l': + 'element %idx av %l', + 'all but first of %l': + 'alt utenom f\u00F8rste av %l', + 'length of %l': + 'lengde av %l', + '%l contains %s': + '%l inneholder %s', + 'thing': + 'noe', + 'add %s to %l': + 'legg %s til %l', + 'delete %ida of %l': + 'fjern %ida fra %l', + 'insert %s at %idx of %l': + 'sett inn %s ved %idx i %l ein', + 'replace item %idx of %l with %s': + 'erstatt element %idx i %l med %s', + + // other + 'Make a block': + 'Ny blokk', + + // menus + // snap menu + 'About...': + 'Om Snap!...', + 'Snap! website': + 'Snap! websiden', + 'Download source': + 'Last ned kildekoden', + 'Switch back to user mode': + 'Tilbake til brukermodus', + 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': + 'ut av Morphic\nkontekst menyer\nog vis kun brukervennlige', + 'Switch to dev mode': + 'inn i utviklermodus', + 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': + 'inn i Morphic funksjoner\nog inspektorer,\nikke brukervennlig', + + // project menu + 'Project notes...': + 'Prosjektnotater...', + 'New': + 'Nytt', + 'Open...': + '\u00C5pne...', + 'Save': + 'Lagre', + 'Save As...': + 'Lagre som...', + 'Import...': + 'Importer...', + 'file menu import hint': + 'laster inn eksportertes prosjekt,\net bibliotek med ' + + 'blokker\n' + + 'et kostym eller en lyd', + 'Export project as plain text ...': + 'Eksporter prosjekt som ren tekst...', + 'Export project...': + 'Eksporter prosjekt...', + 'show project data as XML\nin a new browser window': + 'vis prosjektdata som XML\ni et nytt nettleser vindu', + 'Export blocks...': + 'Eksporter blokker...', + 'show global custom block definitions as XML\nin a new browser window': + 'viser globale blokkdefinisjoner fra bruker\nsom XML i et nytt nettleser vindu', + 'Import tools...': + 'Importer verkt\u00F8y...', + 'load the official library of\npowerful blocks': + 'last ned snap-bibliotek med ekstra blokker', + 'Libraries...': + 'Biblioteker...', + 'Import library': + 'Importer biblioteker', + + // cloud menu + 'Login...': + 'Logg inn...', + 'Registrer deg...': + 'Registrering...', + + // settings menu + 'Language...': + 'Spr\u00E5k...', + 'Zoom blocks...': + 'Zoom blokkene...', + 'Blurred shadows': + 'Mjuke skygger (blurred)', + 'uncheck to use solid drop\nshadows and highlights': + 'fjern kryss for hard skygge\nog lyssetting', + 'check to use blurred drop\nshadows and highlights': + 'kryss av for hard skygge\nog lyssetting', + 'Zebra coloring': + 'Zebra farget', + 'check to enable alternating\ncolors for nested blocks': + 'kryss av for vekslende fargenyanser\ni nestede blokker', + 'uncheck to disable alternating\ncolors for nested block': + 'fjern kryss for \u00E5 hindre vekslende\nfargenyanser i nestede blokker', + 'Dynamic input labels': + 'Dynamisk inndata navn', + 'uncheck to disable dynamic\nlabels for variadic inputs': + 'fjern kryss for \u00E5 hindre dynamisk benevning\nav inndata med flere variabelfelt', + 'check to enable dynamic\nlabels for variadic inputs': + 'kryss av for\ndynamisk benevning av inndata med flere variabelfelt', + 'Prefer empty slot drops': + 'Preferanse for tomme variabelfelt', + 'settings menu prefer empty slots hint': + 'Valg meny\ntomme variabelfelt' + + 'preferanse', + 'uncheck to allow dropped\nreporters to kick out others': + 'kryss vekk for at flyttede reportere vil ta plassen til andre\n', + 'Long form input dialog': + 'Lange dialoger for inndata', + 'check to always show slot\ntypes in the input dialog': + 'kryss av for \u00E5 vise variabelfelttype\ni inndata dialoger', + 'uncheck to use the input\ndialog in short form': + 'kryss vekk for \u00E5 bruke korte inndata\ndialoger', + 'Virtual keyboard': + 'Virtuelt tastatur', + 'uncheck to disable\nvirtual keyboard support\nfor mobile devices': + 'kryss vekk for \u00E5 sl\u00E5 av virtuelt\ntastatur p\u00E5 mobile enheter', + 'check to enable\nvirtual keyboard support\nfor mobile devices': + 'kryss av for \u00E5 sl\u00E5 p\u00E5 virtuelt\ntastatur p\u00E5 mobile enheter', + 'Input sliders': + 'Skyveknapp inndata ', + 'uncheck to disable\ninput sliders for\nentry fields': + 'kryss vekk for \u00E5 sl\u00E5 av\nskyveknapper i inndatafelt', + 'check to enable\ninput sliders for\nentry fields': + 'kryss av for \u00E5 sl\u00E5 p\u00E5 skyveknapper\ni inndatafelt', + 'Clicking sound': + 'Klikkelyd', + 'uncheck to turn\nblock clicking\nsound off': + 'kryss vekk for sl\u00E5 av klikkelyd', + 'check to turn\nblock clicking\nsound on': + 'kryss av for \u00E5 sl\u00E5 p\u00E5 klikkelyd', + 'Animations': + 'Animasjoner', + 'uncheck to disable\nIDE animations': + 'kryss vekk for \u00E5 sl\u00E5 av IDE-animasjoner', + 'Turbo mode': + 'Turbo modus', + 'check to enable\nIDE animations': + 'kryss av for \u00E5 sl\u00E5 p\u00E5 IDE-animasjoner', + 'Thread safe scripts': + 'Tr\u00E5dsikker skripting', + 'uncheck to allow\nscript reentrancy': + 'kryss vekk for \u00E5 sl\u00E5 p\u00E5 gjenbruk av p\u00E5begynte skripter', + 'check to disallow\nscript reentrancy': + 'kryss av for \u00E5 sl\u00E5 av gjenbruk av p\u00E5begynte skripter', + 'Prefer smooth animations': + 'Jevnere animasjoner', + 'uncheck for greater speed\nat variable frame rates': + 'kryss bort for st¯rre fart ved variabel frame rate', + 'check for smooth, predictable\nanimations across computers': + 'kryss av for jevne animasjoner p alle maskinplattformer', +// inputs + 'with inputs': + 'med inndata', + 'input names:': + 'inndata navn:', + 'Input Names:': + 'Inndata navn:', + 'input list:': + 'inndata liste:', + + // context menus: + 'help': + 'hjelp', + + // blocks: + 'hjelp...': + 'hjelp...', + 'relabel...': + 'gi nytt navn...', + 'duplicate': + 'dupliser', + 'make a copy\nand pick it up': + 'lag kopi\n og plukk opp', + 'only duplicate this block': + 'dupliser kun denne blokk', + 'delete': + 'slette', + 'script pic...': + 'skript bilde...', + 'open a new window\nwith a picture of this script': + '\u00E5pne nytt vindu med bildet av dette skriptet', + 'ringify': + 'ring rundt', + 'unringify': + 'fjerne ringen rundt', + + // custom blocks: + 'delete block definition...': + 'slett blokk definisjoner', + 'edit...': + 'rediger...', + + // sprites: + 'edit': + 'redigere', + 'export...': + 'eksporter...', + + // stage: + 'show all': + 'vis alt', + + // scripting area + 'clean up': + 'rydd', + 'arrange scripts\nvertically': + 'sett opp skriptene\nvertikalt', + 'add comment': + 'legg til kommentar', + 'make a block...': + 'lag ny blokk...', + + // costumes + 'rename': + 'nytt navn', + 'export': + 'eksportere', + 'rename costume': + 'nytt navn for drakt', + + // sounds + 'Play sound': + 'Spill lyd', + 'Stop sound': + 'Stop lyd', + 'Stop': + 'Stop', + 'Play': + 'Start', + 'rename sound': + 'nytt navn lyd', + + // dialogs + // buttons + 'OK': + 'OK', + 'Ok': + 'OK', + 'Cancel': + 'Avbryt', + 'Yes': + 'Ja', + 'No': + 'Nei', + + // help + 'Help': + 'Hjelp', + + // Project Manager + 'Untitled': + 'Uten navn', + 'Open Project': + '≈pne prosjekt', + '(empty)': + '(tomt)', + 'Saved!': + 'Lagret!', + 'Delete Project': + 'Slett prosjekt', + 'Are you sure you want to delete': + 'Vil du virkelig slette?', + 'rename...': + 'nytt navn...', + + // costume editor + 'Costume Editor': + 'Drakt editor', + 'click or drag crosshairs to move the rotation center': + 'Klikk p\u00E5 kors for \u00E5 flytte rotasjonssenteret', + + // project notes + 'Project Notes': + 'Prosjekt notater', + + // new project + 'New Project': + 'Nytt prosjekt', + 'Replace the current project with a new one?': + 'Erstatt n\u00E5v\u00E6rende prosjekt med nytt prosjekt?', + + // save project + 'Save Project As...': + 'Lagre prosjekt som...', + + // export blocks + 'Export blocks': + 'Eksporter blokker', + 'Import blocks': + 'Importer blokker', + 'this project doesn\'t have any\ncustom global blocks yet': + 'dette prosjektet har s\u00E5langt ingen\nglobale blokker fra bruker', + 'select': + 'velg', + 'all': + 'alt', + 'none': + 'ingenting', + + // variable dialog + 'for all sprites': + 'for alle objekter', + 'for this sprite only': + 'kun for dette objektet', + + // block dialog + 'Change block': + 'Endre blokker', + 'Command': + 'Styring', + 'Reporter': + 'Funksjon', + 'Predicate': + 'Predikat', + + // block editor + 'Block Editor': + 'Blokk editor', + 'Apply': + 'Gj\u00F8r gjeldende', + + // block deletion dialog + 'Delete Custom Block': + 'Slett custom blokk', + 'block deletion dialog text': + 'Skal denne blokken med alle dens instanser\n' + + 'bli slettet?', + + // input dialog + 'Create input name': + 'Lag inndata navn', + 'Edit input name': + 'Rediger inndata navn', + 'Edit label fragment': + 'Rediger label fragment', + 'Title text': + 'Tittel', + 'Input name': + 'Inndata navn', + 'Delete': + 'Slett', + 'Object': + 'Objekt', + 'Number': + 'Tall', + 'Text': + 'Tekst', + 'List': + 'Liste', + 'Any type': + 'Type valgfritt', + 'Boolean (T/F)': + 'Boolsk (S/U)', + 'Command\n(inline)': + 'Kommando\n(inline)', + 'Command\n(C-shape)': + 'Kommando\n(C-Form)', + 'Any\n(unevaluated)': + 'Hvilken som helst\n(uevaluert)', + 'Boolean\n(unevaluated)': + 'Boolsk\n(uevaluert)', + 'Single input.': + 'Singel inndata.', + 'Default Value:': + 'Standardverdi:', + 'Multiple inputs (value is list of inputs)': + 'Fler-inndata (verdi er liste over inndata)', + 'Upvar - make internal variable visible to caller': + 'Upvar - gj\u00F8r interne variable synlig for den som kaller', + + // About Snap + 'About Snap': + 'Om Snap', + 'Back...': + 'Tilbake...', + 'License...': + 'Lisens...', + 'Modules...': + 'Moduler...', + 'Credits...': + 'Takk til...', + 'Translators...': + 'Oversettere', + 'License': + 'Lisens', + 'current module versions:': + 'Komponent-versjoner', + 'Contributors': + 'Bidragsytere', + 'Translations': + 'Oversettelser', + + // variable watchers + 'normal': + 'normal', + 'large': + 'stor', + 'slider': + 'skyveknapp', + 'slider min...': + 'skyveknapp min...', + 'slider max...': + 'skyveknapp max...', + 'import...': + 'importer...', + 'Slider minimum value': + 'Skyveknapp - minimumsverdi', + 'Slider maximum value': + 'Skyveknapp - maksimumsverdi', + + // list watchers + 'length: ': + 'lengde: ', + + // coments + 'add comment here...': + 'legg til kommentar her...', + + // drow downs + // directions + '(90) h\u00F8yre': + '(90) h\u00F8yre', + '(-90) venstre': + '(-90) venstre', + '(0) opp': + '(0) oppe', + '(180) ned': + '(180) nede', + + // collision detection + 'mouse-pointer': + 'musepeker', + 'edge': + 'kant', + 'pen trails': + 'pennspor', + + // costumes + 'Turtle': + 'Objekt', + + // graphical effects + 'ghost': + 'gjennomsiktig', + + // keys + 'space': + 'mellomrom', + 'up arrow': + 'pil opp', + 'down arrow': + 'pil ned', + 'right arrow': + 'pil h\u00F8yre', + 'left arrow': + 'pil', + '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': + 'kvardrat', + 'sin': + 'sin', + 'cos': + 'cos', + 'tan': + 'tan', + 'asin': + 'arc-1', + 'acos': + 'cos-1', + 'atan': + 'tan-1', + 'ln': + 'ln', + 'e^': + 'e^', + + // data types + 'number': + 'tall', + 'text': + 'tekst', + 'Boolean': + 'boolsk', + 'list': + 'liste', + 'command': + 'kommando', + 'reporter': + 'funksjonsblokk', + 'predicate': + 'predikat', + + // list indices + 'last': + 'siste', + 'any': + 'hvilken som helst' +}; diff --git a/locale.js b/locale.js index 2db2e1f..48d3656 100644 --- a/locale.js +++ b/locale.js @@ -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-11-01' +}; + SnapTranslator.dict.pt_BR = { // meta information 'language_name': -- cgit v1.3.1 From 4ce74cc186a0f5983aaed7298d483cafde2bc076 Mon Sep 17 00:00:00 2001 From: Erik Olsson Date: Thu, 30 Oct 2014 15:09:39 +0100 Subject: Added Swedish translations --- lang-sv.js | 220 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/lang-sv.js b/lang-sv.js index b4599c9..a0a9387 100644 --- a/lang-sv.js +++ b/lang-sv.js @@ -342,7 +342,7 @@ SnapTranslator.dict.sv = { 'Hello!': 'Hej!', 'Hmm...': - 'Oj...', + 'Hmm...', 'change %eff effect by %n': 'ändra %eff -effekt med %n', 'set %eff effect to %n': @@ -373,104 +373,104 @@ SnapTranslator.dict.sv = { // sound: 'play sound %snd': - 'spill lyd %snd', + 'spela ljud %snd', 'play sound %snd until done': - 'spill lyd %snd ferdig', + 'spela ljud %snd tills färdig', 'stop all sounds': - 'stopp all lyd', + 'stoppa alla ljud', 'rest for %n beats': - 'pause i %n slag', + 'pausa %n slag', 'play note %n for %n beats': - 'spill note %n i %n slag', + 'spela ton %n i %n slag', 'change tempo by %n': - 'endre tempo med %n', + 'ändra tempo med %n', 'set tempo to %n bpm': - 'sett tempo til %n bpm', + 'sätt tempo till %n bpm', 'tempo': 'tempo', // pen: 'clear': - 'slett', + 'rensa', 'pen down': - 'penn ned', + 'penna ned', 'pen up': - 'penn opp', + 'penna upp', 'set pen color to %clr': - 'sett pennfargen til %clr', + 'sätt pennfärg till %clr', 'change pen color by %n': - 'endre pennfargen med %n', + 'ändra pennfärg till %n', 'set pen color to %n': - 'sett penfargen til %n', + 'sätt penfärg till %n', 'change pen shade by %n': - 'endre pennintensitet med %n', + 'ändra pennstyrka med %n', 'set pen shade to %n': - 'sett pennintensitet til %n', + 'sätt pennstyrka till %n', 'change pen size by %n': - 'endre pennbredde med %n', + 'ändra penntjocklek med %n', 'set pen size to %n': - 'sett pennbredde til %n', + 'sätt penntjocklek til %n', 'stamp': - 'stemple', + 'stämpla', // control: 'when %greenflag clicked': - 'N\u00E5r %greenflag klikkes', + 'när %greenflag klickas på', 'when %key key pressed': - 'N\u00E5r tast %key trykkes', + 'när tangent %key trycks ned', 'when I am clicked': - 'N\u00E5r jeg klikkes', + 'när jag klickas', 'when I receive %msg': - 'N\u00E5r jeg %msg mottar', + 'när jag tar emot meddelande %msg', 'broadcast %msg': - 'send melding %msg', + 'skicka meddelande %msg', 'broadcast %msg and wait': - 'send melding %msg og vent', + 'skicka meddelande %msg och vänta', 'Message name': - 'Meldingens navn', + 'Meddelandets namn', 'wait %n secs': - 'vent i %n sek', + 'vänta %n sek', 'wait until %b': - 'vent til %b', + 'vänta tills %b', 'forever %c': - 'for alltid %c', + 'för alltid %c', 'repeat %n %c': - 'gjenta %n ganger %c', + 'upprepa %n gånger %c', 'repeat until %b %c': - 'gjenta til %b %c', + 'upprepa tills %b %c', 'if %b %c': - 'hvis %b %c', + 'om %b %c', 'if %b %c else %c': - 'hvis %b %c ellers %c', + 'om %b %c då %c', 'report %s': - 'returner %s', + 'returnera %s', 'stop block': - 'stopp denne blokk', + 'stoppa block', 'stop script': - 'stopp dette skript', + 'stoppa skript', 'stop all %stop': - 'stopp alt %stop', + 'stoppa alla %stop', 'pause all %pause': - 'pause (alle) %pause', + 'pausa alla %pause', 'run %cmdRing %inputs': - 'kj\u00F8r %cmdRing fra %inputs', + 'kör %cmdRing med %inputs', 'launch %cmdRing %inputs': - 'start %cmdRing %inputs', + 'starta %cmdRing med %inputs', 'call %repRing %inputs': - 'kall %repRing fra %inputs', + 'anropa %repRing med %inputs', 'run %cmdRing w/continuation': - 'kj\u00F8r %cmdRing med kontinuering', + 'kör %cmdRing och fortsätt', 'call %cmdRing w/continuation': - 'kall %cmdRing med kontinuering', + 'anropa %cmdRing och fortsätt', 'when I start as a clone': - 'n\u00E5r klon startes', + 'när jag startar som klon', 'create a clone of %cln': - 'opprett %cln', + 'skapa klon av %cln', 'myself': - 'meg', + 'mig själv', 'delete this clone': - 'slett klon', + 'radera klon', 'warp %c': @@ -478,72 +478,72 @@ SnapTranslator.dict.sv = { // sensing: 'touching %col ?': - 'ber\u00F8rer %col ?', + 'rör %col ?', 'touching %clr ?': - 'ber\u00F8rer %clr ?', + 'rör %clr ?', 'color %clr is touching %clr ?': - 'farge %clr ber\u00F8rer %clr ?', + 'färgen %clr rör %clr ?', 'ask %s and wait': - 'sp\u00F8r %s og vent', + 'fråga %s och vänta', 'what\'s your name?': - 'hva heter du?', + 'vad heter du?', 'answer': 'svar', 'mouse x': - 'mus x-posisjon', + 'mus x-pos', 'mouse y': - 'mus y-posisjon', + 'mus y-pos', 'mouse down?': - 'mustast trykket?', + 'musknapp nedtryckt?', 'key %key pressed?': - 'tast %key trykket?', + 'tangent %key nedtryckt?', 'distance to %dst': - 'avstand til %dst', + 'avstånd till %dst', 'reset timer': - 'start stoppeklokke', + 'nollställ stoppur', 'timer': - 'stoppeklokke', + 'stoppur', 'http:// %s': 'http:// %s', 'turbo mode?': - 'turbo modus?', + 'turboläge?', 'set turbo mode to %b': - 'sett turbo modus til %b', + 'sätt turboläge till %b', 'filtered for %clr': - 'filter %clr', + 'filtrera på %clr', 'stack size': - 'stack-st\u00F8rrelse', + 'stack-storlek', 'frames': - 'rammer', + 'ramar', // operators: '%n mod %n': '%n mod %n', 'round %n': - 'rund av %n', + 'avrunda %n', '%fun av %n': '%fun von %n', 'pick random %n to %n': - 'tilfeldig fra %n til %n', + 'slumptal från %n till %n', '%b and %b': - '%b OG %b', + '%b och %b', '%b or %b': - '%b ELLER %b', + '%b eller %b', 'not %b': - 'IKKE %b', + 'inte %b', 'true': - 'SANN', + 'sant', 'false': - 'USANN', + 'falskt', 'join %words': - 'skj\u00F8t %words', + 'slå ihop %words', 'hello': - 'hei', + 'hej', 'world': - 'verden', + 'världen', 'letter %n of %s': 'bokstav %n av %s', 'length of %s': @@ -553,7 +553,7 @@ SnapTranslator.dict.sv = { 'unicode %n as letter': 'unicode %n som bokstav', 'is %s a %typ ?': - '%s er %typ ?', + '%s är %typ ?', 'is %s identical to %s ?': '%s identisk med %s ?', @@ -564,79 +564,79 @@ SnapTranslator.dict.sv = { 'Make a variable': 'Ny variabel', 'Variable name': - 'Variabelnavn', + 'Variabelnamn', 'Delete a variable': - 'Slett variabel', + 'Radera variabel', 'set %var to %s': - 'sett %var til %s', + 'sätt %var till %s', 'change %var by %n': - 'endre %var med %n', + 'ändra %var med %n', 'show variable %var': - 'vis variabel %var', + 'visa variabel %var', 'hide variable %var': - 'skjul variabel %var', + 'göm variabel %var', 'script variables %scriptVars': - 'skriptvariable %scriptVars', + 'skriptvariabel %scriptVars', // lists: 'list %exp': - 'liste %exp', + 'lista %exp', '%s in front of %l': - '%s framfor %l', + '%s främst i %l', 'item %idx of %l': - 'element %idx av %l', + 'element %idx i %l', 'all but first of %l': - 'alt utenom f\u00F8rste av %l', + 'allt utom första i %l', 'length of %l': - 'lengde av %l', + 'längd av %l', '%l contains %s': - '%l inneholder %s', + '%l innehåller %s', 'thing': - 'noe', + 'sak', 'add %s to %l': - 'legg %s til %l', + 'lägg %s till %l', 'delete %ida of %l': - 'fjern %ida fra %l', + 'radera %ida från %l', 'insert %s at %idx of %l': - 'sett inn %s ved %idx i %l ein', + 'lägg in %s på plats %idx i lista %l', 'replace item %idx of %l with %s': - 'erstatt element %idx i %l med %s', + 'ersätt element %idx i %l med %s', // other 'Make a block': - 'Ny blokk', + 'Ny block', // menus // snap menu 'About...': 'Om Snap!...', 'Snap! website': - 'Snap! websiden', + 'Snap! webbsida', 'Download source': - 'Last ned kildekoden', + 'Ladda ner källkoden', 'Switch back to user mode': - 'Tilbake til brukermodus', + 'Byt tillbaka till användarläge', 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': 'ut av Morphic\nkontekst menyer\nog vis kun brukervennlige', 'Switch to dev mode': - 'inn i utviklermodus', + 'Byt till utvecklarläge', 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': 'inn i Morphic funksjoner\nog inspektorer,\nikke brukervennlig', // project menu 'Project notes...': - 'Prosjektnotater...', + 'Projektannoteringar...', 'New': - 'Nytt', + 'Ny', 'Open...': - '\u00C5pne...', + 'Öppna...', 'Save': - 'Lagre', + 'Spara', 'Save As...': - 'Lagre som...', + 'Spara som...', 'Import...': - 'Importer...', + 'Importera...', 'file menu import hint': 'laster inn eksportertes prosjekt,\net bibliotek med ' + 'blokker\n' @@ -841,19 +841,19 @@ SnapTranslator.dict.sv = { // Project Manager 'Untitled': - 'Uten navn', + 'Namnlös', 'Open Project': - '≈pne prosjekt', + 'Öppna projekt', '(empty)': '(tomt)', 'Saved!': - 'Lagret!', + 'Sparat!', 'Delete Project': - 'Slett prosjekt', + 'Radera projekt', 'Are you sure you want to delete': - 'Vil du virkelig slette?', + 'Är du säker på att du vill radera', 'rename...': - 'nytt navn...', + 'nytt namn...', // costume editor 'Costume Editor': -- cgit v1.3.1 From 98f56a3e9e29ca928ace455d2ffba47b6cec571a Mon Sep 17 00:00:00 2001 From: Erik Olsson Date: Thu, 30 Oct 2014 23:11:58 +0100 Subject: Completed first pass Swedish --- lang-sv.js | 255 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 127 insertions(+), 128 deletions(-) diff --git a/lang-sv.js b/lang-sv.js index a0a9387..240fb08 100644 --- a/lang-sv.js +++ b/lang-sv.js @@ -187,12 +187,12 @@ SnapTranslator.dict.sv = { 'translator_e-mail': 'eolsson@gmail.com', // optional 'last_changed': - '2013-09-16', // this, too, will appear in the Translators tab + '2014-11-01', // this, too, will appear in the Translators tab // GUI // control bar: 'untitled': - 'inget namn', + 'namnlös', 'development mode': 'utvecklareläge', @@ -605,7 +605,7 @@ SnapTranslator.dict.sv = { // other 'Make a block': - 'Ny block', + 'Skapa nytt block', // menus // snap menu @@ -616,17 +616,17 @@ SnapTranslator.dict.sv = { 'Download source': 'Ladda ner källkoden', 'Switch back to user mode': - 'Byt tillbaka till användarläge', + 'Tillbaka till användarläge', 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': - 'ut av Morphic\nkontekst menyer\nog vis kun brukervennlige', + 'stäng av Morphic\nmenyeroch visa \nanvändarvänliga istället', 'Switch to dev mode': 'Byt till utvecklarläge', 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': - 'inn i Morphic funksjoner\nog inspektorer,\nikke brukervennlig', + 'aktivera Morphic menyer\noch inspektorer,\ninte användarvänligt!', // project menu 'Project notes...': - 'Projektannoteringar...', + 'Annoteringar...', 'New': 'Ny', 'Open...': @@ -642,58 +642,57 @@ SnapTranslator.dict.sv = { + 'blokker\n' + 'et kostym eller en lyd', 'Export project as plain text ...': - 'Eksporter prosjekt som ren tekst...', + 'Exportera projektet som vanlig text...', 'Export project...': - 'Eksporter prosjekt...', + 'Exportera projekt...', 'show project data as XML\nin a new browser window': - 'vis prosjektdata som XML\ni et nytt nettleser vindu', + 'visa projektdata som XML\ni ett ny fönster', 'Export blocks...': - 'Eksporter blokker...', + 'Exportera block...', 'show global custom block definitions as XML\nin a new browser window': - 'viser globale blokkdefinisjoner fra bruker\nsom XML i et nytt nettleser vindu', + 'visa globala anpassade blockdefinitioner som XML\ni ett nytt fönster', 'Import tools...': - 'Importer verkt\u00F8y...', + 'Importverktyg...', 'load the official library of\npowerful blocks': - 'last ned snap-bibliotek med ekstra blokker', + 'ladda ner det officiella\nsuperblock biblioteket ', 'Libraries...': 'Biblioteker...', 'Import library': - 'Importer biblioteker', + 'Importera bibliotek', // cloud menu 'Login...': - 'Logg inn...', + 'Logga in...', 'Registrer deg...': - 'Registrering...', + 'Registrera dig...', // settings menu 'Language...': - 'Spr\u00E5k...', + 'Språk...', 'Zoom blocks...': - 'Zoom blokkene...', + 'Förstora blocken...', 'Blurred shadows': - 'Mjuke skygger (blurred)', + 'Suddade skuggor', 'uncheck to use solid drop\nshadows and highlights': - 'fjern kryss for hard skygge\nog lyssetting', + 'bocka av för att använda\nfasta skuggor och belysningar', 'check to use blurred drop\nshadows and highlights': - 'kryss av for hard skygge\nog lyssetting', + 'bocka i för att använda\nsuddiga skuggor och belysningar', 'Zebra coloring': - 'Zebra farget', + 'Zebrafärgning', 'check to enable alternating\ncolors for nested blocks': - 'kryss av for vekslende fargenyanser\ni nestede blokker', + 'bocka i för att växla blockfärger\nför nestlade block', 'uncheck to disable alternating\ncolors for nested block': - 'fjern kryss for \u00E5 hindre vekslende\nfargenyanser i nestede blokker', + 'bocka av för inaktivera växlade\nfärger för nestlade block', 'Dynamic input labels': - 'Dynamisk inndata navn', + 'Dynamisk namn för indata', 'uncheck to disable dynamic\nlabels for variadic inputs': - 'fjern kryss for \u00E5 hindre dynamisk benevning\nav inndata med flere variabelfelt', + 'bocka av för att inaktivera \ndynamiska namn för indata \nmed flera variabelfält', 'check to enable dynamic\nlabels for variadic inputs': - 'kryss av for\ndynamisk benevning av inndata med flere variabelfelt', + 'bocka i för att aktivera \ndynamiska namn för indata \nmed flera variabelfält', 'Prefer empty slot drops': - 'Preferanse for tomme variabelfelt', + 'Föredra släpp på tomma utrymmen', 'settings menu prefer empty slots hint': - 'Valg meny\ntomme variabelfelt' - + 'preferanse', + 'Inställningar\nföredra tomma utrymmen', 'uncheck to allow dropped\nreporters to kick out others': 'kryss vekk for at flyttede reportere vil ta plassen til andre\n', 'Long form input dialog': @@ -709,118 +708,118 @@ SnapTranslator.dict.sv = { 'check to enable\nvirtual keyboard support\nfor mobile devices': 'kryss av for \u00E5 sl\u00E5 p\u00E5 virtuelt\ntastatur p\u00E5 mobile enheter', 'Input sliders': - 'Skyveknapp inndata ', + 'Volymkontroll för indata', 'uncheck to disable\ninput sliders for\nentry fields': 'kryss vekk for \u00E5 sl\u00E5 av\nskyveknapper i inndatafelt', 'check to enable\ninput sliders for\nentry fields': 'kryss av for \u00E5 sl\u00E5 p\u00E5 skyveknapper\ni inndatafelt', 'Clicking sound': - 'Klikkelyd', + 'Klickljud', 'uncheck to turn\nblock clicking\nsound off': 'kryss vekk for sl\u00E5 av klikkelyd', 'check to turn\nblock clicking\nsound on': 'kryss av for \u00E5 sl\u00E5 p\u00E5 klikkelyd', 'Animations': - 'Animasjoner', + 'Animationer', 'uncheck to disable\nIDE animations': 'kryss vekk for \u00E5 sl\u00E5 av IDE-animasjoner', 'Turbo mode': - 'Turbo modus', + 'Turboläge', 'check to enable\nIDE animations': 'kryss av for \u00E5 sl\u00E5 p\u00E5 IDE-animasjoner', 'Thread safe scripts': - 'Tr\u00E5dsikker skripting', + 'Trådsäker skripting', 'uncheck to allow\nscript reentrancy': 'kryss vekk for \u00E5 sl\u00E5 p\u00E5 gjenbruk av p\u00E5begynte skripter', 'check to disallow\nscript reentrancy': 'kryss av for \u00E5 sl\u00E5 av gjenbruk av p\u00E5begynte skripter', 'Prefer smooth animations': - 'Jevnere animasjoner', + 'Föredra jämna animeringar', 'uncheck for greater speed\nat variable frame rates': 'kryss bort for st¯rre fart ved variabel frame rate', 'check for smooth, predictable\nanimations across computers': 'kryss av for jevne animasjoner p alle maskinplattformer', // inputs 'with inputs': - 'med inndata', + 'med indata', 'input names:': - 'inndata navn:', + 'indatanamn:', 'Input Names:': - 'Inndata navn:', + 'Indatanamn:', 'input list:': - 'inndata liste:', + 'indata lista:', // context menus: 'help': - 'hjelp', + 'hjälp', // blocks: 'hjelp...': - 'hjelp...', + 'hjälp...', 'relabel...': - 'gi nytt navn...', + 'döp om...', 'duplicate': - 'dupliser', + 'duplicera', 'make a copy\nand pick it up': - 'lag kopi\n og plukk opp', + 'gör en kopia\noch plocka upp den', 'only duplicate this block': - 'dupliser kun denne blokk', + 'duplicera endast detta block', 'delete': - 'slette', + 'radera', 'script pic...': - 'skript bilde...', + 'skript bild...', 'open a new window\nwith a picture of this script': - '\u00E5pne nytt vindu med bildet av dette skriptet', + 'öppna ett nytt fönster\nmed en bild av detta skript', 'ringify': - 'ring rundt', + 'ring runt', 'unringify': - 'fjerne ringen rundt', + 'radera ringen runt', // custom blocks: 'delete block definition...': - 'slett blokk definisjoner', + 'radera blockdefinition...', 'edit...': - 'rediger...', + 'redigera...', // sprites: 'edit': - 'redigere', + 'redigera', 'export...': - 'eksporter...', + 'exportera...', // stage: 'show all': - 'vis alt', + 'visa allt', // scripting area 'clean up': - 'rydd', + 'städa', 'arrange scripts\nvertically': - 'sett opp skriptene\nvertikalt', + 'organisera skript\nvertikalt', 'add comment': - 'legg til kommentar', + 'lägg till kommentar', 'make a block...': - 'lag ny blokk...', + 'skapa nytt block...', // costumes 'rename': - 'nytt navn', + 'döp om', 'export': - 'eksportere', + 'exportera', 'rename costume': - 'nytt navn for drakt', + 'döp om kostymen', // sounds 'Play sound': - 'Spill lyd', + 'Spela ljud', 'Stop sound': - 'Stop lyd', + 'Stoppa ljud', 'Stop': - 'Stop', + 'Stoppa', 'Play': - 'Start', + 'Starta', 'rename sound': - 'nytt navn lyd', + 'döp om ljud', // dialogs // buttons @@ -833,11 +832,11 @@ SnapTranslator.dict.sv = { 'Yes': 'Ja', 'No': - 'Nei', + 'Nej', // help 'Help': - 'Hjelp', + 'Hjälp', // Project Manager 'Untitled': @@ -853,51 +852,51 @@ SnapTranslator.dict.sv = { 'Are you sure you want to delete': 'Är du säker på att du vill radera', 'rename...': - 'nytt namn...', + 'döp om...', // costume editor 'Costume Editor': - 'Drakt editor', + 'Kostym redigerare', 'click or drag crosshairs to move the rotation center': - 'Klikk p\u00E5 kors for \u00E5 flytte rotasjonssenteret', + 'Klicka eller dra krysset för att marker mitten', // project notes 'Project Notes': - 'Prosjekt notater', + 'Annoteringar', // new project 'New Project': - 'Nytt prosjekt', + 'Nytt projekt', 'Replace the current project with a new one?': - 'Erstatt n\u00E5v\u00E6rende prosjekt med nytt prosjekt?', + 'Ersätt aktuella projektet med ett nytt?', // save project 'Save Project As...': - 'Lagre prosjekt som...', + 'Spara projekt som...', // export blocks 'Export blocks': - 'Eksporter blokker', + 'Exportera block', 'Import blocks': - 'Importer blokker', + 'Importera block', 'this project doesn\'t have any\ncustom global blocks yet': - 'dette prosjektet har s\u00E5langt ingen\nglobale blokker fra bruker', + 'detta projekt har inte ännu\nnågra egna globala block', 'select': - 'velg', + 'välj', 'all': - 'alt', + 'allt', 'none': 'ingenting', // variable dialog 'for all sprites': - 'for alle objekter', + 'för alla sprites', 'for this sprite only': - 'kun for dette objektet', + 'bara för denna sprite', // block dialog 'Change block': - 'Endre blokker', + 'Ändra block', 'Command': 'Styring', 'Reporter': @@ -907,9 +906,9 @@ SnapTranslator.dict.sv = { // block editor 'Block Editor': - 'Blokk editor', + 'Blockredigerare', 'Apply': - 'Gj\u00F8r gjeldende', + 'Verkställ', // block deletion dialog 'Delete Custom Block': @@ -964,23 +963,23 @@ SnapTranslator.dict.sv = { 'About Snap': 'Om Snap', 'Back...': - 'Tilbake...', + 'Tillbaka...', 'License...': - 'Lisens...', + 'Licens...', 'Modules...': 'Moduler...', 'Credits...': - 'Takk til...', + 'Tack till...', 'Translators...': - 'Oversettere', + 'Översättare', 'License': - 'Lisens', + 'Licens', 'current module versions:': - 'Komponent-versjoner', + 'Modulversioner', 'Contributors': - 'Bidragsytere', + 'Bidragsgivare', 'Translations': - 'Oversettelser', + 'Översättningar', // variable watchers 'normal': @@ -988,64 +987,64 @@ SnapTranslator.dict.sv = { 'large': 'stor', 'slider': - 'skyveknapp', + 'volymkontroll', 'slider min...': - 'skyveknapp min...', + 'volymkontroll min...', 'slider max...': - 'skyveknapp max...', + 'volymkontroll max...', 'import...': - 'importer...', + 'importera...', 'Slider minimum value': - 'Skyveknapp - minimumsverdi', + 'Volymkontroll - minsta värde', 'Slider maximum value': - 'Skyveknapp - maksimumsverdi', + 'volymkontroll - högsta värde', // list watchers 'length: ': - 'lengde: ', + 'längd: ', // coments 'add comment here...': - 'legg til kommentar her...', + 'lägg till kommentar här...', // drow downs // directions - '(90) h\u00F8yre': - '(90) h\u00F8yre', - '(-90) venstre': - '(-90) venstre', - '(0) opp': - '(0) oppe', - '(180) ned': - '(180) nede', + '(90) right': + '(90) höger', + '(-90) left': + '(-90) vänster', + '(0) up': + '(0) upp', + '(180) down': + '(180) ned', // collision detection 'mouse-pointer': - 'musepeker', + 'muspekare', 'edge': 'kant', 'pen trails': - 'pennspor', + 'pennspår', // costumes 'Turtle': - 'Objekt', + 'Sköldpadda', // graphical effects 'ghost': - 'gjennomsiktig', + 'genomskinligt', // keys 'space': - 'mellomrom', + 'mellanslag', 'up arrow': - 'pil opp', + 'pil upp', 'down arrow': 'pil ned', 'right arrow': - 'pil h\u00F8yre', + 'pil höger', 'left arrow': - 'pil', + 'pil vänster', 'a': 'a', 'b': @@ -1127,7 +1126,7 @@ SnapTranslator.dict.sv = { 'abs': 'abs', 'sqrt': - 'kvardrat', + 'kvadrat', 'sin': 'sin', 'cos': @@ -1147,23 +1146,23 @@ SnapTranslator.dict.sv = { // data types 'number': - 'tall', + 'tal', 'text': - 'tekst', + 'text', 'Boolean': - 'boolsk', + 'boolean', 'list': - 'liste', + 'lista', 'command': 'kommando', 'reporter': - 'funksjonsblokk', + 'funktionsblock', 'predicate': 'predikat', // list indices 'last': - 'siste', + 'sista', 'any': - 'hvilken som helst' + 'vilken som helst' }; -- cgit v1.3.1 From 43626c46519d88acb415e76c49b4983907de9dcd Mon Sep 17 00:00:00 2001 From: Erik Olsson Date: Thu, 30 Oct 2014 23:21:45 +0100 Subject: Completed first pass Swedish --- lang-sv.js | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lang-sv.js b/lang-sv.js index 240fb08..5606999 100644 --- a/lang-sv.js +++ b/lang-sv.js @@ -734,7 +734,7 @@ SnapTranslator.dict.sv = { 'check to disallow\nscript reentrancy': 'kryss av for \u00E5 sl\u00E5 av gjenbruk av p\u00E5begynte skripter', 'Prefer smooth animations': - 'Föredra jämna animeringar', + 'Jämna animeringar', 'uncheck for greater speed\nat variable frame rates': 'kryss bort for st¯rre fart ved variabel frame rate', 'check for smooth, predictable\nanimations across computers': @@ -898,9 +898,9 @@ SnapTranslator.dict.sv = { 'Change block': 'Ändra block', 'Command': - 'Styring', + 'Kommando', 'Reporter': - 'Funksjon', + 'Funktion', 'Predicate': 'Predikat', @@ -912,52 +912,52 @@ SnapTranslator.dict.sv = { // block deletion dialog 'Delete Custom Block': - 'Slett custom blokk', + 'Radera custom blokk', 'block deletion dialog text': 'Skal denne blokken med alle dens instanser\n' + 'bli slettet?', // input dialog 'Create input name': - 'Lag inndata navn', + 'Skapa indata-namn', 'Edit input name': - 'Rediger inndata navn', + 'Redigera indata-namn', 'Edit label fragment': - 'Rediger label fragment', + 'Redigera etikettdel', 'Title text': - 'Tittel', + 'Titel', 'Input name': - 'Inndata navn', + 'Indata-namn', 'Delete': - 'Slett', + 'Radera', 'Object': 'Objekt', 'Number': - 'Tall', + 'Nummer', 'Text': - 'Tekst', + 'Text', 'List': - 'Liste', + 'Lista', 'Any type': - 'Type valgfritt', + 'Valfri typ', 'Boolean (T/F)': - 'Boolsk (S/U)', + 'Boolean (S/F)', 'Command\n(inline)': 'Kommando\n(inline)', 'Command\n(C-shape)': 'Kommando\n(C-Form)', 'Any\n(unevaluated)': - 'Hvilken som helst\n(uevaluert)', + 'Vilken som helst\n(oevaluerad)', 'Boolean\n(unevaluated)': - 'Boolsk\n(uevaluert)', + 'Boolean\n(oevaluerad)', 'Single input.': - 'Singel inndata.', + 'Enkel indata.', 'Default Value:': - 'Standardverdi:', + 'Standardvärde:', 'Multiple inputs (value is list of inputs)': - 'Fler-inndata (verdi er liste over inndata)', + 'Flera indata (värdet är en lista av indata)', 'Upvar - make internal variable visible to caller': - 'Upvar - gj\u00F8r interne variable synlig for den som kaller', + 'Upvar - gör internal variabel synlig för anroparen', // About Snap 'About Snap': @@ -1146,7 +1146,7 @@ SnapTranslator.dict.sv = { // data types 'number': - 'tal', + 'nummer', 'text': 'text', 'Boolean': -- cgit v1.3.1 From 7b96be6c40fac46bb53752531f24878425eb9330 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 6 Nov 2014 17:03:51 +0100 Subject: enable mouseMove events with right button pressed to support user interactions in 3D environments, such as CAD systems or Beetleblocks --- morphic.js | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/morphic.js b/morphic.js index 4e18482..0115c82 100644 --- a/morphic.js +++ b/morphic.js @@ -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-November-06'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -9346,11 +9352,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 +9500,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 +9536,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 +9597,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 +9655,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); -- cgit v1.3.1 From b36a358173fcf4f2a4a77a9c202d6dc0d6c1a7b8 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 14 Nov 2014 12:49:01 +0100 Subject: Fix reporting out of nested custom C-shaped blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit REPORT now reports to the nearest lexical element expecting an input (which may not be the block holding the REPORT statement, this lets you REPORT out of nested FOR loops). STOP THIS BLOCK behaves as it used to. If you’ve been using REPORT instead of STOP THIS BLOCK, you should migrate. --- history.txt | 8 +++ store.js | 5 +- threads.js | 170 ++++++++++++++++++++++++------------------------------------ 3 files changed, 77 insertions(+), 106 deletions(-) diff --git a/history.txt b/history.txt index 28116b9..b3bc7da 100755 --- a/history.txt +++ b/history.txt @@ -2309,3 +2309,11 @@ ______ 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 diff --git a/store.js b/store.js index cb91139..bc24849 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-October-01'; +modules.store = '2014-November-14'; // XML_Serializer /////////////////////////////////////////////////////// @@ -1824,9 +1824,8 @@ Context.prototype.toXML = function (serializer) { return ''; } return serializer.format( - '%%' + + '%%' + '%%%', - this.isLambda ? ' lambda="lambda"' : '', this.inputs.reduce( function (xml, input) { return xml + serializer.format('$', input); diff --git a/threads.js b/threads.js index 6a59f3c..dfa335e 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-October-01'; +modules.threads = '2014-November-15'; var ThreadManager; var Process; @@ -586,7 +586,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 +596,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 +604,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 +621,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 +674,11 @@ Process.prototype.doYield = function () { } }; +Process.prototype.exitReporter = function () { + // catch-tag for REPORT and STOP BLOCK primitives + this.popContext(); +}; + // Process Exception Handling Process.prototype.handleError = function (error, element) { @@ -757,9 +757,15 @@ 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 ( context, @@ -783,6 +789,7 @@ Process.prototype.evaluate = function ( var outer = new Context(null, null, context.outerContext), runnable, extra, + exit, parms = args.asArray(), i, value; @@ -798,23 +805,17 @@ Process.prototype.evaluate = function ( ); extra = new Context(runnable, 'doYield'); - /* - 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) - */ + // 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)) { + if (context.expression instanceof ReporterBlockMorph) { this.context.parentContext = extra; } else { this.context.parentContext = runnable; } - runnable.isLambda = true; - runnable.isImplicitLambda = context.isImplicitLambda; - runnable.isCustomBlock = false; - // assign parameters if any were passed if (parms.length > 0) { @@ -858,6 +859,18 @@ Process.prototype.evaluate = function ( if (runnable.expression instanceof CommandBlockMorph) { runnable.expression = runnable.expression.blockSequence(); + + // insert a reporter exit tag for the + // CALL SCRIPT primitive variant + if (!isCommand) { + exit = new Context( + runnable.parentContext, + 'exitReporter', + outer, + outer.receiver + ); + runnable.parentContext = exit; + } } }; @@ -879,8 +892,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) { @@ -933,68 +944,39 @@ Process.prototype.fork = function (context, args) { stage.threads.processes.push(proc); }; -Process.prototype.doReport = function (value, isCSlot) { - while (this.context && !this.context.isLambda) { +Process.prototype.doReport = function (value) { + while (this.context && this.context.expression !== 'exitReporter') { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); } else { this.popContext(); } } - if (this.context && this.context.isImplicitLambda) { + return value; +}; + +Process.prototype.doStopBlock = function () { + 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) { @@ -1017,6 +999,7 @@ Process.prototype.evaluateCustomBlock = function () { args = new List(this.context.inputs), parms = args.asArray(), runnable, + exit, extra, i, value, @@ -1024,7 +1007,7 @@ Process.prototype.evaluateCustomBlock = function () { if (!context) {return null; } 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,16 +1015,12 @@ Process.prototype.evaluateCustomBlock = function () { this.context.parentContext, context.expression, outer, - outer.receiver, - true // is custom block + outer.receiver ); + runnable.isCustomBlock = true; extra = new Context(runnable, 'doYield'); - this.context.parentContext = extra; - runnable.isLambda = true; - runnable.isCustomBlock = true; - // passing parameters if any were passed if (parms.length > 0) { @@ -1064,6 +1043,18 @@ Process.prototype.evaluateCustomBlock = function () { if (runnable.expression instanceof CommandBlockMorph) { runnable.expression = runnable.expression.blockSequence(); + + // insert a reporter exit tag for the + // CALL SCRIPT primitive variant + if (this.context.expression.definition.type !== 'command') { + exit = new Context( + runnable.parentContext, + 'exitReporter', + outer, + outer.receiver + ); + runnable.parentContext = exit; + } } }; @@ -1308,16 +1299,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 +1314,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 +1329,6 @@ Process.prototype.doIfElse = function () { } } if (this.context) { - this.context.isLambda = isLambda; - this.context.isImplicitLambda = isImplicitLambda; this.context.isCustomBlock = isCustomBlock; } @@ -1420,8 +1403,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 +1419,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 +1499,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(); }; @@ -2775,8 +2742,6 @@ Process.prototype.reportFrameCount = function () { 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 */ @@ -2801,22 +2766,18 @@ 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 } 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 () { @@ -2872,6 +2833,9 @@ Context.prototype.continuation = function () { } else { return new Context(null, 'doStop'); } + if (cont.expression === 'exitReporter') { + return cont.continuation(); + } cont = cont.copyForContinuation(); cont.isContinuation = true; return cont; -- cgit v1.3.1 From ea05f7859fe5a042f0c0dd49b189c594b9a798d3 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 17 Nov 2014 10:22:39 +0100 Subject: Treat REPORT blocks inside custom command definitions as STOP THIS BLOCK / IGNORE INPUTS this also enables all existing FINCH blocks and other hardware extensions again, which used the REPORT (HTTP://) pattern --- blocks.js | 33 +++++++++++++++++++++++++-------- history.txt | 4 ++++ threads.js | 12 +++++++++--- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/blocks.js b/blocks.js index 73ef884..82ef601 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-October-01'; +modules.blocks = '2014-November-17'; var SyntaxElementMorph; @@ -394,10 +394,8 @@ 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 var empty = []; if (!(this instanceof RingMorph) && (this.selector !== 'reportJSFunction')) { @@ -412,6 +410,21 @@ SyntaxElementMorph.prototype.allEmptySlots = function () { return empty; }; +SyntaxElementMorph.prototype.allReportBlocks = function () { + // answer report blocks of all children including myself, + // but omit those in nested rings (lambdas) + if (this.selector === 'doReport') {return [this]; } + var reports = []; + if (!(this instanceof RingMorph)) { + this.children.forEach(function (morph) { + if (morph.allReportBlocks) { + reports = reports.concat(morph.allReportBlocks()); + } + }); + } + return reports; +}; + SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) { var scripts = this.parentThatIsA(ScriptsMorph), replacement = newArg, @@ -3169,9 +3182,13 @@ 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" indicator: + + partOfCustomCommand - temporary bool set by the evaluator */ // CommandBlockMorph inherits from BlockMorph: diff --git a/history.txt b/history.txt index b3bc7da..88d7ca4 100755 --- a/history.txt +++ b/history.txt @@ -2317,3 +2317,7 @@ ______ 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 diff --git a/threads.js b/threads.js index dfa335e..cf97362 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-15'; +modules.threads = '2014-November-17'; var ThreadManager; var Process; @@ -945,6 +945,9 @@ Process.prototype.fork = function (context, args) { }; Process.prototype.doReport = function (value) { + if (this.context.expression.partOfCustomCommand) { + return this.doStopBlock(); + } while (this.context && this.context.expression !== 'exitReporter') { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); @@ -1042,8 +1045,6 @@ Process.prototype.evaluateCustomBlock = function () { } if (runnable.expression instanceof CommandBlockMorph) { - runnable.expression = runnable.expression.blockSequence(); - // insert a reporter exit tag for the // CALL SCRIPT primitive variant if (this.context.expression.definition.type !== 'command') { @@ -1054,7 +1055,12 @@ Process.prototype.evaluateCustomBlock = function () { outer.receiver ); runnable.parentContext = exit; + } else { // mark all REPORT blocks as being part of a custom command + runnable.expression.allReportBlocks().forEach(function (rb) { + rb.partOfCustomCommand = true; + }); } + runnable.expression = runnable.expression.blockSequence(); } }; -- cgit v1.3.1 From f537f62ace4092e1f46d0ca54577ea8810e7510a Mon Sep 17 00:00:00 2001 From: Bernat Romagosa Date: Mon, 17 Nov 2014 14:05:13 +0100 Subject: Added callback to Process --- threads.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/threads.js b/threads.js index cf97362..4592e92 100644 --- a/threads.js +++ b/threads.js @@ -136,7 +136,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 +150,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; @@ -314,6 +315,7 @@ ThreadManager.prototype.findProcess = function (block) { 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 + callback a function to be executed when the process is done */ Process.prototype = {}; @@ -321,7 +323,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, callback) { this.topBlock = topBlock || null; this.readyToYield = false; @@ -338,6 +340,7 @@ function Process(topBlock) { this.pauseOffset = null; this.frameCount = 0; this.exportResult = false; + this.callback = callback; if (topBlock) { this.homeContext.receiver = topBlock.receiver(); @@ -435,8 +438,8 @@ Process.prototype.pauseStep = function () { Process.prototype.evaluateContext = function () { var exp = this.context.expression; - this.frameCount += 1; + if (exp instanceof Array) { return this.evaluateSequence(exp); } @@ -476,9 +479,9 @@ Process.prototype.evaluateBlock = function (block, argCount) { } if (this.isCatchingErrors) { try { - this.returnValueToParentContext( - rcvr[block.selector].apply(rcvr, inputs) - ); + var result = rcvr[block.selector].apply(rcvr, inputs); + if (this.callback) { this.callback(result) }; + this.returnValueToParentContext(result); this.popContext(); } catch (error) { this.handleError(error, block); -- cgit v1.3.1 From 8e992dcaa877044a2b2f15edf86c003f4df7253c Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 18 Nov 2014 18:11:14 +0000 Subject: Add localization to number of arguments error and temporary watchers --- threads.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/threads.js b/threads.js index 086ffcb..d194220 100644 --- a/threads.js +++ b/threads.js @@ -849,8 +849,8 @@ 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 ); } } @@ -915,8 +915,8 @@ 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 ); } } @@ -1148,7 +1148,7 @@ Process.prototype.doShowVar = function (varName) { if (isGlobal || target.owner) { label = name; } else { - label = name + ' (temporary)'; + label = name + ' ' + localize('(temporary)'); } watcher = new WatcherMorph( label, -- cgit v1.3.1 From 522dfba12fd609e708cb568c6d0cc918169affb1 Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 18 Nov 2014 18:12:43 +0000 Subject: Correct import translation and add a few missing translations. --- lang-pt.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lang-pt.js b/lang-pt.js index 79303a7..2d3804a 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -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...': @@ -1647,6 +1648,12 @@ SnapTranslator.dict.pt = { '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': -- cgit v1.3.1 From 51ee69b7df3f27e69fdf98545d57a5fa67c1ec27 Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Tue, 18 Nov 2014 17:30:41 -0800 Subject: update tools with Brain's ignore block --- tools.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools.xml b/tools.xml index 25336c9..e05d7bb 100644 --- a/tools.xml +++ b/tools.xml @@ -1 +1 @@ -
1datamapmany1data lists
1
1
110i
1
cont
catchtag
cont
catchtag
\ No newline at end of file +
1datamapmany1data lists
1
1
110i
1
cont
catchtag
cont
catchtag
\ No newline at end of file -- cgit v1.3.1 From 91690adb29633368ec458ca510086c3b17e0490f Mon Sep 17 00:00:00 2001 From: Bernat Romagosa Date: Wed, 19 Nov 2014 09:34:59 +0100 Subject: callback is only executed when the outmost block returns a value --- threads.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/threads.js b/threads.js index 4592e92..4522d35 100644 --- a/threads.js +++ b/threads.js @@ -137,7 +137,7 @@ ThreadManager.prototype.startProcess = function ( block, isThreadSafe, exportResult, - callback + callback ) { var active = this.findProcess(block), top = block.topBlock(), @@ -236,18 +236,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.callback) { + proc.callback(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 { @@ -315,7 +319,7 @@ ThreadManager.prototype.findProcess = function (block) { 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 - callback a function to be executed when the process is done + callback a function to be executed when the process is done */ Process.prototype = {}; @@ -340,7 +344,7 @@ function Process(topBlock, callback) { this.pauseOffset = null; this.frameCount = 0; this.exportResult = false; - this.callback = callback; + this.callback = callback; if (topBlock) { this.homeContext.receiver = topBlock.receiver(); @@ -439,7 +443,7 @@ Process.prototype.pauseStep = function () { Process.prototype.evaluateContext = function () { var exp = this.context.expression; this.frameCount += 1; - + if (exp instanceof Array) { return this.evaluateSequence(exp); } @@ -479,9 +483,7 @@ Process.prototype.evaluateBlock = function (block, argCount) { } if (this.isCatchingErrors) { try { - var result = rcvr[block.selector].apply(rcvr, inputs); - if (this.callback) { this.callback(result) }; - this.returnValueToParentContext(result); + this.returnValueToParentContext(rcvr[block.selector].apply(rcvr, inputs)); this.popContext(); } catch (error) { this.handleError(error, block); -- cgit v1.3.1 From 89c2835130e5f77e92c35c52b26d58370be07a7c Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 14:17:06 +0100 Subject: Fixed #642, avoid “freezing” when calling CONS on non-list/null MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit thanks, @brianharvey ! --- history.txt | 4 ++++ lists.js | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 88d7ca4..53bd4a6 100755 --- a/history.txt +++ b/history.txt @@ -2321,3 +2321,7 @@ ______ 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 diff --git a/lists.js b/lists.js index a4aff6c..bd856fe 100644 --- a/lists.js +++ b/lists.js @@ -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; -- cgit v1.3.1 From 5771e93fa150c9a39e84bd9fad0e8a0bd2d61085 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 14:21:56 +0100 Subject: Fixed #364 avoid “freezing” when calling LAUNCH on empty ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- history.txt | 3 ++- threads.js | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index 53bd4a6..c26599c 100755 --- a/history.txt +++ b/history.txt @@ -2324,4 +2324,5 @@ ______ 141120 ------ -* Lists: Fixed #642, avoid “freezing” when calling CONS on non-list/null +* Lists: Fixed #642 avoid “freezing” when calling CONS on non-list/null +* Threads: Fixed #364 avoid “freezing” when calling LAUNCH on empty ring diff --git a/threads.js b/threads.js index cf97362..c6b0fde 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-17'; +modules.threads = '2014-November-20'; var ThreadManager; var Process; @@ -225,8 +225,9 @@ ThreadManager.prototype.removeTerminatedProcesses = function () { var remaining = []; this.processes.forEach(function (proc) { if (!proc.isRunning() && !proc.errorFlag && !proc.isDead) { - proc.topBlock.removeHighlight(); - + if (proc.topBlock instanceof BlockMorph) { + proc.topBlock.removeHighlight(); + } if (proc.prompter) { proc.prompter.destroy(); if (proc.homeContext.receiver.stopTalking) { @@ -880,6 +881,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, -- cgit v1.3.1 From f37e90436a21a906d3cef536871c3e1913a4a2b7 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 14:40:13 +0100 Subject: renamed Process::callback to "onComplete" --- history.txt | 1 + threads.js | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/history.txt b/history.txt index c26599c..bb6eac8 100755 --- a/history.txt +++ b/history.txt @@ -2326,3 +2326,4 @@ ______ ------ * 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! diff --git a/threads.js b/threads.js index d1209bf..f210380 100644 --- a/threads.js +++ b/threads.js @@ -237,8 +237,8 @@ ThreadManager.prototype.removeTerminatedProcesses = function () { } if (proc.topBlock instanceof ReporterBlockMorph) { - if (proc.callback) { - proc.callback(proc.homeContext.inputs[0]) + if (proc.onComplete instanceof Function) { + proc.onComplete(proc.homeContext.inputs[0]); } else { if (proc.homeContext.inputs[0] instanceof List) { proc.topBlock.showBubble( @@ -301,9 +301,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 @@ -311,16 +311,17 @@ 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 - callback a function to be executed when the process is done + onComplete an optional callback function to be executed when + the process is done */ Process.prototype = {}; @@ -328,7 +329,7 @@ Process.prototype.contructor = Process; Process.prototype.timeout = 500; // msecs after which to force yield Process.prototype.isCatchingErrors = true; -function Process(topBlock, callback) { +function Process(topBlock, onComplete) { this.topBlock = topBlock || null; this.readyToYield = false; @@ -345,7 +346,7 @@ function Process(topBlock, callback) { this.pauseOffset = null; this.frameCount = 0; this.exportResult = false; - this.callback = callback; + this.onComplete = onComplete || null; if (topBlock) { this.homeContext.receiver = topBlock.receiver(); @@ -444,7 +445,6 @@ Process.prototype.pauseStep = function () { Process.prototype.evaluateContext = function () { var exp = this.context.expression; this.frameCount += 1; - if (exp instanceof Array) { return this.evaluateSequence(exp); } @@ -484,7 +484,9 @@ Process.prototype.evaluateBlock = function (block, argCount) { } if (this.isCatchingErrors) { try { - this.returnValueToParentContext(rcvr[block.selector].apply(rcvr, inputs)); + this.returnValueToParentContext( + rcvr[block.selector].apply(rcvr, inputs) + ); this.popContext(); } catch (error) { this.handleError(error, block); -- cgit v1.3.1 From cbe3d6fe185531758397bc44a38a2817aed885e6 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 14:55:31 +0100 Subject: Updated the “About” Dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit with a mention of support from CDG (SAP Labs) --- gui.js | 7 ++++--- history.txt | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gui.js b/gui.js index bb440b1..f01f19d 100644 --- a/gui.js +++ b/gui.js @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-October-06'; +modules.gui = '2014-November-20'; // Declarations @@ -2511,8 +2511,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 bb6eac8..8cf87e7 100755 --- a/history.txt +++ b/history.txt @@ -2327,3 +2327,5 @@ ______ * 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) -- cgit v1.3.1 From 4768102b098281d4f2462d4c4b0fe8b5cf228ef6 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 15:13:21 +0100 Subject: integrate percent sign fix for JSLint --- byob.js | 6 +++--- history.txt | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/byob.js b/byob.js index 71b3298..b5905ce 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-September-30'; +modules.byob = '2014-November-20'; // Declarations @@ -688,8 +688,8 @@ CustomCommandBlockMorph.prototype.labelPart = function (spec) { return CustomCommandBlockMorph.uber.labelPart.call(this, spec); } if ((spec[0] === '%') && (spec.length > 1)) { - var label = spec.replace(/%/g, ''); - part = new BlockInputFragmentMorph(label); + // part = new BlockInputFragmentMorph(spec.slice(1)); + part = new BlockInputFragmentMorph(spec.replace(/%/g, '')); } else { part = new BlockLabelFragmentMorph(spec); part.fontSize = this.fontSize; diff --git a/history.txt b/history.txt index 8cf87e7..b022790 100755 --- a/history.txt +++ b/history.txt @@ -2328,4 +2328,5 @@ ______ * 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) +* GUI: Updated the “About” Dialog with a mention of support from CDG (SAP Labs) +* BYOB: Percent sign fix for block labels, thanks, @natashasandy! -- cgit v1.3.1 From ce93fe8da73738e67683fa9cbfe7741de62f5336 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 15:16:12 +0100 Subject: fix ‘line’ option in ‘split’ block for Windows files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit thanks, @brianharvey! --- history.txt | 1 + threads.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index b022790..c44a57b 100755 --- a/history.txt +++ b/history.txt @@ -2330,3 +2330,4 @@ ______ * 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! diff --git a/threads.js b/threads.js index f210380..11b72dc 100644 --- a/threads.js +++ b/threads.js @@ -2126,7 +2126,7 @@ Process.prototype.reportTextSplit = function (string, delimiter) { str = (string || '').toString(); switch (this.inputOption(delimiter)) { case 'line': - del = '\n'; + del = '\r?\n'; break; case 'tab': del = '\t'; -- cgit v1.3.1 From 3cc28b1f1ce44f053399686e58be860f9c4a7018 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 15:40:20 +0100 Subject: push morphic.js version date --- history.txt | 1 + morphic.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index c44a57b..110ea89 100755 --- a/history.txt +++ b/history.txt @@ -2331,3 +2331,4 @@ ______ * 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 ! diff --git a/morphic.js b/morphic.js index b9d834f..763a196 100644 --- a/morphic.js +++ b/morphic.js @@ -1041,7 +1041,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-November-06'; +var morphicVersion = '2014-November-20'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug -- cgit v1.3.1 From f2d0c2eba5d6b012fc3fb1167c82b64b2f8ed447 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 20 Nov 2014 15:53:14 +0100 Subject: integrate translation update --- history.txt | 1 + threads.js | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/history.txt b/history.txt index 110ea89..0faac6b 100755 --- a/history.txt +++ b/history.txt @@ -2332,3 +2332,4 @@ ______ * 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! diff --git a/threads.js b/threads.js index ea563f1..7d656c4 100644 --- a/threads.js +++ b/threads.js @@ -858,8 +858,9 @@ Process.prototype.evaluate = function ( } else if (context.emptySlots !== 1) { throw new Error( - localize('expecting') + ' ' + context.emptySlots + ' ' - + localize('input(s), but getting') + ' ' + parms.length + localize('expecting') + ' ' + context.emptySlots + ' ' + + localize('input(s), but getting') + ' ' + + parms.length ); } } @@ -937,8 +938,9 @@ Process.prototype.fork = function (context, args) { } else if (context.emptySlots !== 1) { throw new Error( - localize('expecting') + ' ' + context.emptySlots + ' ' - + localize('input(s), but getting') + ' ' + parms.length + localize('expecting') + ' ' + context.emptySlots + ' ' + + localize('input(s), but getting') + ' ' + + parms.length ); } } @@ -2986,7 +2988,7 @@ VariableFrame.prototype.find = function (name) { throw new Error( localize('a variable of name \'') + name - + localize('\'\ndoes not exist in this context') + + localize('\'\ndoes not exist in this context') ); }; -- cgit v1.3.1 From d63d78208cc823d801071c1984223380701f9f9b Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Fri, 21 Nov 2014 05:04:11 -0800 Subject: Add a new Favicon to Snap! (Clearer Lambda) This is essentially the same icon (lambda, yellow w/ brown border) but newly rendered at 64, 32, 24 and 16px for the best resolution on all platforms. --- favicon.ico | Bin 0 -> 32988 bytes snap.html | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 favicon.ico diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..46a1369 Binary files /dev/null and b/favicon.ico differ diff --git a/snap.html b/snap.html index 904aba8..93b4c73 100755 --- a/snap.html +++ b/snap.html @@ -3,7 +3,7 @@ Snap! Build Your Own Blocks. Beta - + @@ -33,5 +33,5 @@ - + -- cgit v1.3.1 From 9e91a93ac029056adae89e7b8e07558b47f9634f Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 21 Nov 2014 16:55:25 +0100 Subject: Fix "stop this block"’s lexical awareness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit “stop this block” when used inside a custom block definition now always returns out of the lexically enclosing script (the definition), even if it is used inside other nested, C-shaped custom blocks in the definition code. Previously it only stopped the nearest encompassing “for” block, now it always stops the block whose definition it is in. I don’t expect this fix to break any existing projects. --- blocks.js | 40 +++++++++++++++++++++++-------------- history.txt | 4 ++++ threads.js | 65 ++++++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 74 insertions(+), 35 deletions(-) diff --git a/blocks.js b/blocks.js index 82ef601..e56d0ed 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-November-17'; +modules.blocks = '2014-November-21'; var SyntaxElementMorph; @@ -395,7 +395,9 @@ 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 + // 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')) { @@ -410,19 +412,24 @@ SyntaxElementMorph.prototype.allEmptySlots = function () { return empty; }; -SyntaxElementMorph.prototype.allReportBlocks = function () { - // answer report blocks of all children including myself, - // but omit those in nested rings (lambdas) - if (this.selector === 'doReport') {return [this]; } - var reports = []; - if (!(this instanceof RingMorph)) { - this.children.forEach(function (morph) { - if (morph.allReportBlocks) { - reports = reports.concat(morph.allReportBlocks()); - } - }); +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); + } + }); + } } - return reports; }; SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) { @@ -3186,9 +3193,10 @@ BlockMorph.prototype.snap = function () { bottomBlock() - answer the bottom block of my stack blockSequence() - answer an array of blocks starting with myself - and the following "lexical awareness" indicator: + 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: @@ -3206,6 +3214,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: diff --git a/history.txt b/history.txt index 0faac6b..c468c99 100755 --- a/history.txt +++ b/history.txt @@ -2333,3 +2333,7 @@ ______ * 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 diff --git a/threads.js b/threads.js index 7d656c4..ab40460 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-20'; +modules.threads = '2014-November-21'; var ThreadManager; var Process; @@ -322,6 +322,9 @@ ThreadManager.prototype.findProcess = function (block) { 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 = {}; @@ -347,6 +350,7 @@ function Process(topBlock, onComplete) { this.frameCount = 0; this.exportResult = false; this.onComplete = onComplete || null; + this.procedureCount = 0; if (topBlock) { this.homeContext.receiver = topBlock.receiver(); @@ -765,12 +769,6 @@ 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); }; @@ -957,9 +955,11 @@ Process.prototype.fork = function (context, args) { stage.threads.processes.push(proc); }; +// Process "return" primitives + Process.prototype.doReport = function (value) { if (this.context.expression.partOfCustomCommand) { - return this.doStopBlock(); + return this.doStopCustomBlock(); } while (this.context && this.context.expression !== 'exitReporter') { if (this.context.expression === 'doStopWarping') { @@ -972,6 +972,22 @@ Process.prototype.doReport = function (value) { }; Process.prototype.doStopBlock = function () { + var target = this.context.expression.exitTag; + if (isNil(target)) { + return this.doStopCustomBlock(); + } + while (this.context && this.context.tag !== target) { + if (this.context.expression === 'doStopWarping') { + this.doStopWarping(); + } else { + this.popContext(); + } + } +}; + +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(); @@ -1022,6 +1038,7 @@ Process.prototype.evaluateCustomBlock = function () { outer; if (!context) {return null; } + this.procedureCount += 1; outer = new Context(); outer.receiver = this.context.receiver; outer.variables.parentFrame = outer.receiver ? @@ -1068,10 +1085,15 @@ Process.prototype.evaluateCustomBlock = function () { outer.receiver ); runnable.parentContext = exit; - } else { // mark all REPORT blocks as being part of a custom command - runnable.expression.allReportBlocks().forEach(function (rb) { - rb.partOfCustomCommand = true; - }); + } 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 runnable with the current procedure count, so + // "stop this block" blocks can catch it + runnable.tag = this.procedureCount; } runnable.expression = runnable.expression.blockSequence(); } @@ -2746,23 +2768,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 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( @@ -2787,6 +2811,7 @@ function Context( this.activeNote = null; 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 () { -- cgit v1.3.1 From 781144aa3cf05ea00652d224baef03eb157dce52 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Sun, 23 Nov 2014 13:53:34 +0100 Subject: Fix “stop this block” primitive for tail-call-elimination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- history.txt | 4 ++++ threads.js | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/history.txt b/history.txt index c468c99..5a41f5a 100755 --- a/history.txt +++ b/history.txt @@ -2337,3 +2337,7 @@ ______ 141121 ------ * Threads, Blocks: Fix STOP THIS BLOCK’s lexical awareness + +1411213 +------- +* Threads: Fix “stop this block” primitive for tail-call-elimination diff --git a/threads.js b/threads.js index ab40460..68387dc 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-21'; +modules.threads = '2014-November-23'; var ThreadManager; var Process; @@ -976,13 +976,15 @@ Process.prototype.doStopBlock = function () { if (isNil(target)) { return this.doStopCustomBlock(); } - while (this.context && this.context.tag !== target) { + while (this.context && + (isNil(this.context.tag) || (this.context.tag > target))) { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); } else { this.popContext(); } } + this.pushContext(); }; Process.prototype.doStopCustomBlock = function () { @@ -1026,7 +1028,8 @@ 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(), @@ -1091,9 +1094,12 @@ Process.prototype.evaluateCustomBlock = function () { // as being inside a custom command definition runnable.expression.tagExitBlocks(this.procedureCount, true); - // tag runnable with the current procedure count, so - // "stop this block" blocks can catch it - runnable.tag = this.procedureCount; + // 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; + } } runnable.expression = runnable.expression.blockSequence(); } -- cgit v1.3.1 From 8814b61a323a2fb554cf1869f6a7b8ab06009764 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 09:28:45 +0100 Subject: Fixed #318 --- history.txt | 5 +++++ threads.js | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 5a41f5a..4d17e3e 100755 --- a/history.txt +++ b/history.txt @@ -2341,3 +2341,8 @@ ______ 1411213 ------- * Threads: Fix “stop this block” primitive for tail-call-elimination + +1411214 +------- +* Threads: Fixed #318 + diff --git a/threads.js b/threads.js index 68387dc..d5040c5 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-23'; +modules.threads = '2014-November-24'; 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(); } -- cgit v1.3.1 From 927448d7ab4f7069661eb73018463fbf0e40651a Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 10:05:19 +0100 Subject: Fixed #416 --- history.txt | 1 + objects.js | 50 +++++++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/history.txt b/history.txt index 4d17e3e..9d977ad 100755 --- a/history.txt +++ b/history.txt @@ -2345,4 +2345,5 @@ ______ 1411214 ------- * Threads: Fixed #318 +* Objects: Fixed #416 diff --git a/objects.js b/objects.js index 4be213a..3b2c07b 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-October-08'; +modules.objects = '2014-November-24'; var SpriteMorph; var StageMorph; @@ -1674,6 +1674,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')); @@ -1967,15 +1981,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', @@ -4858,6 +4864,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( @@ -5099,15 +5119,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', -- cgit v1.3.1 From 0d8cc567e7f04a9416fc2518646f2d9187840d70 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 10:43:53 +0100 Subject: Fixed #372 --- history.txt | 2 +- objects.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index 9d977ad..2d7e53e 100755 --- a/history.txt +++ b/history.txt @@ -2346,4 +2346,4 @@ ______ ------- * Threads: Fixed #318 * Objects: Fixed #416 - +* Objects: Fixed #372 diff --git a/objects.js b/objects.js index 3b2c07b..69376c8 100644 --- a/objects.js +++ b/objects.js @@ -2170,8 +2170,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 +2210,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]; } }); -- cgit v1.3.1 From e48eda6cc0bdd234f2b385974d1cee66656e070a Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 10:48:49 +0100 Subject: Fixed #644 --- history.txt | 1 + threads.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 2d7e53e..819dcf0 100755 --- a/history.txt +++ b/history.txt @@ -2347,3 +2347,4 @@ ______ * Threads: Fixed #318 * Objects: Fixed #416 * Objects: Fixed #372 +* Threads: Fixed #644 diff --git a/threads.js b/threads.js index d5040c5..574fd35 100644 --- a/threads.js +++ b/threads.js @@ -1307,7 +1307,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; -- cgit v1.3.1 From 2cee474cb676f9ad04d55cc25f8d3fc42c002cce Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 11:08:12 +0100 Subject: Fixed #34 --- history.txt | 1 + store.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 819dcf0..2efc442 100755 --- a/history.txt +++ b/history.txt @@ -2348,3 +2348,4 @@ ______ * Objects: Fixed #416 * Objects: Fixed #372 * Threads: Fixed #644 +* Store: Fixed #34 diff --git a/store.js b/store.js index bc24849..3568809 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-November-14'; +modules.store = '2014-November-24'; // XML_Serializer /////////////////////////////////////////////////////// @@ -261,7 +261,9 @@ SnapSerializer.prototype.watcherLabels = { yPosition: 'y position', direction: 'direction', getScale: 'size', + getTempo: 'tempo', getLastAnswer: 'answer', + getLastMessage: 'message', getTimer: 'timer', getCostumeIdx: 'costume #', reportMouseX: 'mouse x', -- cgit v1.3.1 From 68c4d2d291c8da03798164f0740ed18889f09db3 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 12:59:02 +0100 Subject: fixed #131 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and display an error if a reporter or a “called” ring is missing a “report” statement --- history.txt | 1 + threads.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 2efc442..30de1ab 100755 --- a/history.txt +++ b/history.txt @@ -2349,3 +2349,4 @@ ______ * Objects: Fixed #372 * Threads: Fixed #644 * Store: Fixed #34 +* Threads: Fixed #131 diff --git a/threads.js b/threads.js index 574fd35..9161417 100644 --- a/threads.js +++ b/threads.js @@ -698,7 +698,7 @@ Process.prototype.doYield = function () { Process.prototype.exitReporter = function () { // catch-tag for REPORT and STOP BLOCK primitives - this.popContext(); + this.handleError(new Error("missing 'report' statement in reporter")); }; // Process Exception Handling @@ -1098,6 +1098,7 @@ Process.prototype.evaluateCustomBlock = function () { outer.receiver ); runnable.parentContext = exit; + this.popContext(); // don't yield when done } else { // tag all "stop this block" blocks with the current // procedureCount as exitTag, and mark all "report" blocks -- cgit v1.3.1 From 66eae625fb6251738bca6ad649e7dee3a4b3bf15 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 13:52:25 +0100 Subject: updated history --- history.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/history.txt b/history.txt index 30de1ab..f710d77 100755 --- a/history.txt +++ b/history.txt @@ -2350,3 +2350,5 @@ ______ * 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! -- cgit v1.3.1 From bd37771334e7c82f86aa99f7509f88dc6950b8c5 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 14:38:27 +0100 Subject: allow recursive reporters to be stopped by user --- threads.js | 1 - 1 file changed, 1 deletion(-) diff --git a/threads.js b/threads.js index 1782984..1f1915b 100644 --- a/threads.js +++ b/threads.js @@ -1098,7 +1098,6 @@ Process.prototype.evaluateCustomBlock = function () { outer.receiver ); runnable.parentContext = exit; - this.popContext(); // don't yield when done } else { // tag all "stop this block" blocks with the current // procedureCount as exitTag, and mark all "report" blocks -- cgit v1.3.1 From 4be96bb240ea8518fa95218cba7111846af93baa Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 24 Nov 2014 16:02:21 +0100 Subject: tail-call-elimination for reporters - experiment (commented out, under construction) --- history.txt | 1 + threads.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/history.txt b/history.txt index f710d77..964686e 100755 --- a/history.txt +++ b/history.txt @@ -2352,3 +2352,4 @@ ______ * 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) diff --git a/threads.js b/threads.js index 1f1915b..a6b824b 100644 --- a/threads.js +++ b/threads.js @@ -548,6 +548,34 @@ Process.prototype.reportAnd = function (block) { } }; +/* + tail-call-elimination for reporters + ----------------------------------- + currently under construction, commented out for now + to activate add 'doReport' to the list of special forms + selectors in evaluateBlock() and comment out / remove + the current 'doReport' primitive in the "return" + section of the code + +Process.prototype.doReport = function (block) { + +// if (this.context.expression.partOfCustomCommand) { +// return this.doStopCustomBlock(); +// } + + var outer = this.context.outerContext; + while (this.context && this.context.expression !== 'exitReporter') { + if (this.context.expression === 'doStopWarping') { + this.doStopWarping(); + } else { + this.popContext(); + } + } + this.popContext(); + this.pushContext(block.inputs()[0], outer); +}; +*/ + // Process: Non-Block evaluation Process.prototype.evaluateMultiSlot = function (multiSlot, argCount) { -- cgit v1.3.1 From 75849a59a2ac594c2c78a7cf6ef1e8be6c1eec57 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 25 Nov 2014 12:24:20 +0100 Subject: Evaluator optimizations reducing the stack size for reporters --- history.txt | 6 ++- threads.js | 127 +++++++++++++++++++++++++++++------------------------------- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/history.txt b/history.txt index 964686e..22215e9 100755 --- a/history.txt +++ b/history.txt @@ -2342,7 +2342,7 @@ ______ ------- * Threads: Fix “stop this block” primitive for tail-call-elimination -1411214 +1411224 ------- * Threads: Fixed #318 * Objects: Fixed #416 @@ -2353,3 +2353,7 @@ ______ * 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) diff --git a/threads.js b/threads.js index a6b824b..aef13a1 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-24'; +modules.threads = '2014-November-25'; var ThreadManager; var Process; @@ -218,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(); @@ -384,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 @@ -459,6 +458,9 @@ 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); } @@ -482,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); } @@ -548,33 +550,29 @@ Process.prototype.reportAnd = function (block) { } }; -/* - tail-call-elimination for reporters - ----------------------------------- - currently under construction, commented out for now - to activate add 'doReport' to the list of special forms - selectors in evaluateBlock() and comment out / remove - the current 'doReport' primitive in the "return" - section of the code - Process.prototype.doReport = function (block) { - -// if (this.context.expression.partOfCustomCommand) { -// return this.doStopCustomBlock(); -// } - + if (this.context.expression.partOfCustomCommand) { + this.doStopCustomBlock(); + this.popContext(); + return; + } var outer = this.context.outerContext; - while (this.context && this.context.expression !== 'exitReporter') { + while (this.context && this.context.tag !== 'exit') { if (this.context.expression === 'doStopWarping') { this.doStopWarping(); } else { this.popContext(); } } - this.popContext(); + 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; + } this.pushContext(block.inputs()[0], outer); }; -*/ // Process: Non-Block evaluation @@ -724,9 +722,8 @@ Process.prototype.doYield = function () { } }; -Process.prototype.exitReporter = function () { - // catch-tag for REPORT and STOP BLOCK primitives - this.handleError(new Error("missing 'report' statement in reporter")); +Process.prototype.expectReport = function () { + this.handleError(new Error("reporter didn't report")); }; // Process Exception Handling @@ -831,9 +828,10 @@ Process.prototype.evaluate = function ( } var outer = new Context(null, null, context.outerContext), + caller = this.context.parentContext, + exit, runnable, extra, - exit, parms = args.asArray(), i, value; @@ -904,17 +902,22 @@ Process.prototype.evaluate = function ( if (runnable.expression instanceof CommandBlockMorph) { runnable.expression = runnable.expression.blockSequence(); - - // insert a reporter exit tag for the - // CALL SCRIPT primitive variant if (!isCommand) { - exit = new Context( - runnable.parentContext, - 'exitReporter', - outer, - outer.receiver - ); - runnable.parentContext = exit; + 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; + } } } }; @@ -993,21 +996,7 @@ Process.prototype.fork = function (context, args) { stage.threads.processes.push(proc); }; -// Process "return" primitives - -Process.prototype.doReport = function (value) { - if (this.context.expression.partOfCustomCommand) { - return this.doStopCustomBlock(); - } - while (this.context && this.context.expression !== 'exitReporter') { - if (this.context.expression === 'doStopWarping') { - this.doStopWarping(); - } else { - this.popContext(); - } - } - return value; -}; +// Process stopping blocks primitives Process.prototype.doStopBlock = function () { var target = this.context.expression.exitTag; @@ -1119,13 +1108,21 @@ Process.prototype.evaluateCustomBlock = function () { // insert a reporter exit tag for the // CALL SCRIPT primitive variant if (this.context.expression.definition.type !== 'command') { - exit = new Context( - runnable.parentContext, - 'exitReporter', - outer, - outer.receiver - ); - runnable.parentContext = exit; + 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; + } } else { // tag all "stop this block" blocks with the current // procedureCount as exitTag, and mark all "report" blocks @@ -2925,7 +2922,7 @@ Context.prototype.continuation = function () { } else { return new Context(null, 'doStop'); } - if (cont.expression === 'exitReporter') { + if (cont.expression === 'expectReport') { return cont.continuation(); } cont = cont.copyForContinuation(); -- cgit v1.3.1 From 723c232f3d6655bb592b98333a2397d3cc2689c1 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 25 Nov 2014 17:51:04 +0100 Subject: Full TCO (tail-call-elimination) now Snap! really *is* Scheme :-) --- history.txt | 1 + threads.js | 102 ++++++++++++++++++++++++++++-------------------------------- 2 files changed, 49 insertions(+), 54 deletions(-) diff --git a/history.txt b/history.txt index 22215e9..7d876c8 100755 --- a/history.txt +++ b/history.txt @@ -2357,3 +2357,4 @@ ______ 1411225 ------- * Threads: Evaluator optimizations (reducing the stack size for reporters) +* Threads: Full TCO (tail-call-elimination), now Snap! *is* Scheme :-) diff --git a/threads.js b/threads.js index aef13a1..bdb780a 100644 --- a/threads.js +++ b/threads.js @@ -564,12 +564,14 @@ Process.prototype.doReport = function (block) { this.popContext(); } } - 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; + 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; + } } this.pushContext(block.inputs()[0], outer); }; @@ -831,7 +833,6 @@ Process.prototype.evaluate = function ( caller = this.context.parentContext, exit, runnable, - extra, parms = args.asArray(), i, value; @@ -845,17 +846,11 @@ Process.prototype.evaluate = function ( outer, context.receiver ); - extra = new Context(runnable, 'doYield'); - - // 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) + this.context.parentContext = runnable; if (context.expression instanceof ReporterBlockMorph) { - this.context.parentContext = extra; - } else { - this.context.parentContext = runnable; + // auto-"warp" nested reporters + this.readyToYield = (Date.now() - this.lastYield > this.timeout); } // assign parameters if any were passed @@ -1062,7 +1057,6 @@ Process.prototype.evaluateCustomBlock = function () { parms = args.asArray(), runnable, exit, - extra, i, value, outer; @@ -1081,8 +1075,7 @@ Process.prototype.evaluateCustomBlock = function () { outer.receiver ); runnable.isCustomBlock = true; - extra = new Context(runnable, 'doYield'); - this.context.parentContext = extra; + this.context.parentContext = runnable; // passing parameters if any were passed if (parms.length > 0) { @@ -1104,40 +1097,43 @@ Process.prototype.evaluateCustomBlock = function () { } } - if (runnable.expression instanceof CommandBlockMorph) { - // insert a reporter exit tag for the - // CALL SCRIPT primitive variant - 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; - } + // tag return target + if (this.context.expression.definition.type !== 'command') { + if (caller) { + // tag caller, so "report" can catch it later + caller.tag = 'exit'; } 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; - } + // 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(); } + runnable.expression = runnable.expression.blockSequence(); }; // Process variables primitives @@ -2920,12 +2916,10 @@ Context.prototype.continuation = function () { } else if (this.parentContext) { cont = this.parentContext; } else { - return new Context(null, 'doStop'); - } - if (cont.expression === 'expectReport') { - return cont.continuation(); + return new Context(null, 'doYield'); } cont = cont.copyForContinuation(); + cont.tag = null; cont.isContinuation = true; return cont; }; -- cgit v1.3.1 From 320bfd0c990ea60e1dcf6bfdbe7538b203283709 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 26 Nov 2014 16:26:53 +0100 Subject: Fixed #656 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make sure to always evaluate the “report” block’s input, even if used inside a custom command definition, because hardware extensions (and other reporters with side-effects) rely on it. --- history.txt | 4 ++++ threads.js | 37 ++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/history.txt b/history.txt index 7d876c8..39a801d 100755 --- a/history.txt +++ b/history.txt @@ -2358,3 +2358,7 @@ ______ ------- * Threads: Evaluator optimizations (reducing the stack size for reporters) * Threads: Full TCO (tail-call-elimination), now Snap! *is* Scheme :-) + +1411225 +------- +* Threads: Fixed #656 diff --git a/threads.js b/threads.js index bdb780a..59dd23a 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-25'; +modules.threads = '2014-November-26'; var ThreadManager; var Process; @@ -551,28 +551,31 @@ Process.prototype.reportAnd = function (block) { }; Process.prototype.doReport = function (block) { + var outer = this.context.outerContext; if (this.context.expression.partOfCustomCommand) { this.doStopCustomBlock(); this.popContext(); - return; - } - var outer = this.context.outerContext; - while (this.context && this.context.tag !== 'exit') { - if (this.context.expression === 'doStopWarping') { - this.doStopWarping(); - } else { - 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; + 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); }; -- cgit v1.3.1 From 26c74d9d7104fc0a56ca9e0b68018e13b8d423e3 Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Thu, 27 Nov 2014 00:42:20 -0800 Subject: make the new favicon transparent --- favicon.ico | Bin 32988 -> 8062 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/favicon.ico b/favicon.ico index 46a1369..b2b1e60 100644 Binary files a/favicon.ico and b/favicon.ico differ -- cgit v1.3.1 From 919b72e3d48a08f061e9334076b068779395199c Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Sun, 30 Nov 2014 21:56:33 -0800 Subject: Fix to set SnapCloud variable before the IDE morph is built. This makes it so that #627 works as intended, correctly fixing #502 --- gui.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gui.js b/gui.js index f01f19d..76048c2 100644 --- a/gui.js +++ b/gui.js @@ -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']; @@ -249,6 +245,10 @@ IDE_Morph.prototype.openIn = function (world) { } } + 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), -- cgit v1.3.1 From 1f5934c81f494e897c78f5dde0885e16af913e4d Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 1 Dec 2014 11:25:28 +0100 Subject: Don't show hidden elements in the project thumbnail --- history.txt | 4 ++++ objects.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 39a801d..34f967c 100755 --- a/history.txt +++ b/history.txt @@ -2362,3 +2362,7 @@ ______ 1411225 ------- * Threads: Fixed #656 + +141201 +------ +* Objects: Hide hidden elements in the project thumbnail diff --git a/objects.js b/objects.js index 69376c8..f0fe942 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-November-24'; +modules.objects = '2014-December-01'; var SpriteMorph; var StageMorph; @@ -5333,7 +5333,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) { -- cgit v1.3.1 From d393d13b3746ecc9f84c5e2b7f386e1bdee740ae Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 1 Dec 2014 11:55:02 +0100 Subject: updated history --- gui.js | 2 +- history.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gui.js b/gui.js index 76048c2..b3bb460 100644 --- a/gui.js +++ b/gui.js @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-November-20'; +modules.gui = '2014-December-01'; // Declarations diff --git a/history.txt b/history.txt index 34f967c..b8f1300 100755 --- a/history.txt +++ b/history.txt @@ -2366,3 +2366,5 @@ ______ 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! -- cgit v1.3.1 From 19736839b7c73af5ae3b40d826bc161a78dd0114 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 2 Dec 2014 10:53:07 +0100 Subject: New Kannada Translation, by Vinayakumar R Yay! Thanks for this important contribution, Vinayakumar R. Snap is now available in 25 languages! --- history.txt | 4 + lang-kn.js | 1273 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ locale.js | 14 +- 3 files changed, 1290 insertions(+), 1 deletion(-) create mode 100644 lang-kn.js diff --git a/history.txt b/history.txt index b8f1300..986bcc4 100755 --- a/history.txt +++ b/history.txt @@ -2368,3 +2368,7 @@ ______ * 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!! 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 . + + + + 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: + + + + 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 ) + + + 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 + + + + 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: + + + 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' +}; diff --git a/locale.js b/locale.js index 2db2e1f..ecb77fd 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-October-01'; +modules.locale = '2014-December-02'; // Global stuff @@ -415,3 +415,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' +}; -- cgit v1.3.1 From d94d9ff4e85b50ce57e4c62d63250994c4b9b4c7 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 3 Dec 2014 12:42:46 +0100 Subject: Cache actual bounding box of the Pen arrow shape for improved collision detection --- morphic.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/morphic.js b/morphic.js index 763a196..a001c6f 100644 --- a/morphic.js +++ b/morphic.js @@ -1041,7 +1041,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-November-20'; +var morphicVersion = '2014-December-03'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -3978,6 +3978,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)); @@ -4000,11 +4001,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; @@ -4027,6 +4026,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(); @@ -4043,7 +4051,6 @@ PenMorph.prototype.drawNew = function (facing) { context.lineWidth = 1; context.stroke(); context.fill(); - }; // PenMorph access: -- cgit v1.3.1 From 17b6ae839b5c15c942440f38fc07bfcc45bc0811 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 3 Dec 2014 12:48:31 +0100 Subject: Improve edge-collision detection of default sprite “arrow” shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- history.txt | 5 +++++ objects.js | 9 ++++++--- threads.js | 14 ++++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/history.txt b/history.txt index 986bcc4..b8af0f0 100755 --- a/history.txt +++ b/history.txt @@ -2372,3 +2372,8 @@ ______ 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 diff --git a/objects.js b/objects.js index f0fe942..4ad376c 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-December-01'; +modules.objects = '2014-December-03'; var SpriteMorph; var StageMorph; @@ -3238,8 +3238,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()); diff --git a/threads.js b/threads.js index 59dd23a..9f9a221 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-November-26'; +modules.threads = '2014-December-03'; var ThreadManager; var Process; @@ -2368,6 +2368,7 @@ Process.prototype.objectTouchingObject = function (thisObj, name) { var myself = this, those, stage, + box, mouse; if (this.inputOption(name) === 'mouse-pointer') { @@ -2379,9 +2380,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())) { -- cgit v1.3.1 From 2b2ff77823d085a9bd6e4a8bca8553ba72922e06 Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Thu, 4 Dec 2014 03:01:40 -0800 Subject: Really fix setting the cloud as default save location when logged in --- gui.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gui.js b/gui.js index b3bb460..8c56e1e 100644 --- a/gui.js +++ b/gui.js @@ -190,7 +190,7 @@ IDE_Morph.prototype.init = function (isAutoFill) { // additional properties: this.cloudMsg = null; - this.source = SnapCloud.username ? 'cloud' : 'local'; + this.source = 'local'; this.serializer = new SnapSerializer(); this.globalVariables = new VariableFrame(); @@ -241,6 +241,9 @@ IDE_Morph.prototype.openIn = function (world) { if (usr) { SnapCloud.username = usr.username || null; SnapCloud.password = usr.password || null; + if (SnapCould.username) { + this.source = 'cloud'; + } } } } -- cgit v1.3.1 From ad1fe34d1ed900e1e4fd75e5c5666f6ab28b9c80 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 4 Dec 2014 15:45:18 +0100 Subject: Experimental “ForEach” primitive (hidden in dev mode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- objects.js | 13 ++++++++++++- threads.js | 22 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/objects.js b/objects.js index 4ad376c..7277719 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-December-03'; +modules.objects = '2014-December-04'; var SpriteMorph; var StageMorph; @@ -1151,6 +1151,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 @@ -2063,6 +2070,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(txt); blocks.push('-'); blocks.push(block('reportMap')); + blocks.push('-'); + blocks.push(block('doForEach')); } ///////////////////////////////// @@ -5198,6 +5207,8 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(txt); blocks.push('-'); blocks.push(block('reportMap')); + blocks.push('-'); + blocks.push(block('doForEach')); } ///////////////////////////////// diff --git a/threads.js b/threads.js index 9f9a221..c21375e 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-December-03'; +modules.threads = '2014-December-04'; var ThreadManager; var Process; @@ -1679,6 +1679,26 @@ 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(); + this.evaluate(script, new List(), true); +}; + // Process interpolated primitives Process.prototype.doWait = function (secs) { -- cgit v1.3.1 From 060643c1617766a0de0b7f0fc5592f118fadd89a Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 4 Dec 2014 15:54:52 +0100 Subject: fix typo & update history --- gui.js | 4 ++-- history.txt | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gui.js b/gui.js index 8c56e1e..8cd9403 100644 --- a/gui.js +++ b/gui.js @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-December-01'; +modules.gui = '2014-December-04'; // Declarations @@ -241,7 +241,7 @@ IDE_Morph.prototype.openIn = function (world) { if (usr) { SnapCloud.username = usr.username || null; SnapCloud.password = usr.password || null; - if (SnapCould.username) { + if (SnapCloud.username) { this.source = 'cloud'; } } diff --git a/history.txt b/history.txt index b8af0f0..5be35f0 100755 --- a/history.txt +++ b/history.txt @@ -2377,3 +2377,8 @@ ______ ------ * 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 -- cgit v1.3.1 From 6608d1098ffe6d6b5f23ba85ea842754724ec277 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 5 Dec 2014 12:53:02 +0100 Subject: Avoid auto-scaling artefacts in Safari on retina displays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (resulting in “traces” when dragging items) --- history.txt | 4 ++++ morphic.js | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 5be35f0..f1baa92 100755 --- a/history.txt +++ b/history.txt @@ -2382,3 +2382,7 @@ ______ ------ * 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) diff --git a/morphic.js b/morphic.js index a001c6f..9616897 100644 --- a/morphic.js +++ b/morphic.js @@ -1041,7 +1041,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-December-03'; +var morphicVersion = '2014-December-05'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -1931,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) { -- cgit v1.3.1 From 8338384bf572beb06ebd12a0c9af18029e99262a Mon Sep 17 00:00:00 2001 From: jmoenig Date: Sat, 6 Dec 2014 11:36:35 +0100 Subject: Fixed #668 --- history.txt | 4 ++++ store.js | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index f1baa92..ff38bfb 100755 --- a/history.txt +++ b/history.txt @@ -2386,3 +2386,7 @@ ______ 141205 ------ * Morphic: Avoid auto-scaling artefacts in Safari on retina displays (resulting in “traces” when dragging items) + +141206 +------ +* Store: Fixed #668 diff --git a/store.js b/store.js index 3568809..7b2b7e1 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-November-24'; +modules.store = '2014-December-06'; // XML_Serializer /////////////////////////////////////////////////////// @@ -1201,6 +1201,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(); -- cgit v1.3.1 From 0a239b703c8c7fde5540ce63c4236522a22ee049 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 11 Dec 2014 14:17:29 +0100 Subject: yield after each cycle in the experimental “forEach” primitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit thanks, Bernat, for reporting this bug! --- history.txt | 4 ++++ threads.js | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index ff38bfb..edbf4d0 100755 --- a/history.txt +++ b/history.txt @@ -2390,3 +2390,7 @@ ______ 141206 ------ * Store: Fixed #668 + +141211 +------ +* Threads: yield after each cycle in the experimental “forEach” primitive diff --git a/threads.js b/threads.js index c21375e..b80ee9e 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-December-04'; +modules.threads = '2014-December-11'; var ThreadManager; var Process; @@ -1695,6 +1695,7 @@ Process.prototype.doForEach = function (upvar, list, script) { ); if (index > list.length()) {return; } this.context.inputs[3] += 1; + this.pushContext('doYield'); this.pushContext(); this.evaluate(script, new List(), true); }; -- cgit v1.3.1 From d8026a43247c9d414aa94c689a7abc39dbc42127 Mon Sep 17 00:00:00 2001 From: Erik Olsson Date: Sun, 14 Dec 2014 21:45:45 +0100 Subject: Completed Swedish translation --- lang-sv.js | 543 +++++++++++++++++++++++++++++++++++++++++-------------------- locale.js | 2 +- 2 files changed, 368 insertions(+), 177 deletions(-) diff --git a/lang-sv.js b/lang-sv.js index 5606999..382f2bd 100644 --- a/lang-sv.js +++ b/lang-sv.js @@ -171,12 +171,12 @@ SnapTranslator.dict.sv = { /* Special characters: (see ) - ¯ , \u00F8 - Ê , \u00E6 -  , \u00E5 - ÿ , \u00D8 - ∆ ; \u00C6 - ≈ , \u00C5 + å , \u00E5 + ä , \u00E4 + ö , \u00F6 + Å , \u00C5 + Ä ; \u00C4 + Ö , \u00D6 */ // translations meta information @@ -192,13 +192,13 @@ SnapTranslator.dict.sv = { // GUI // control bar: 'untitled': - 'namnlös', + 'namnl\u00F6s', 'development mode': - 'utvecklareläge', + 'utvecklarel\u00E4ge', // categories: 'Motion': - 'Rörelse', + 'R\u00F6relse', 'Looks': 'Utseende', 'Sound': @@ -208,7 +208,7 @@ SnapTranslator.dict.sv = { 'Control': 'Kontroll', 'Sensing': - 'Känna av', + 'K\u00E4nna av', 'Operators': 'Operatorer', 'Variables': @@ -242,18 +242,18 @@ SnapTranslator.dict.sv = { 'can rotate': 'rotera', 'only face left/right': - 'peka bara höger/vänster', + 'peka bara h\u00F6ger/v\u00E4nster', // new sprite button: 'add a new Sprite': - 'lägg till ny Sprite', + 'l\u00E4gg till ny Sprite', // tab help 'costumes tab help': - 'kostymflikshjälp', + '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ån din dator\ngenom att dra den hit', + 'importera en ljudfil fr\u00E5n din dator\ngenom att dra den hit', // primitive blocks: @@ -289,32 +289,32 @@ SnapTranslator.dict.sv = { // motion: 'Stage selected:\nno motion primitives': - 'Scen vald:\ninga standard rörelser' + 'Scen vald:\ninga standard r\u00F6relser' + 'finns', 'move %n steps': - 'gå %n steg', + 'g\u00E5 %n steg', 'turn %clockwise %n degrees': - 'vänd %clockwise %n grader', + 'v\u00E4nd %clockwise %n grader', 'turn %counterclockwise %n degrees': - 'vänd %counterclockwise %n grader', + '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å till x: %n y: %n', + 'g\u00E5 till x: %n y: %n', 'go to %dst': - 'gå till %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': - 'ändra x med %n', + '\u00E4ndra x med %n', 'set x to %n': - 'sätt x till %n', + 's\u00E4tt x till %n', 'change y by %n': - 'ändra y med %n', + '\u00E4ndra y med %n', 'set y to %n': - 'sätt y till %n', + 's\u00E4tt y till %n', 'if on edge, bounce': 'studsa om vid kanten', 'x position': @@ -328,44 +328,44 @@ SnapTranslator.dict.sv = { 'switch to costume %cst': 'byt till kostym %cst', 'next costume': - 'nästa kostym', + 'n\u00E4sta kostym', 'costume #': 'kostym nr.', 'say %s for %n secs': - 'säg %s i %n sek', + 's\u00E4g %s i %n sek', 'say %s': - 'säg %s', + 's\u00E4g %s', 'think %s for %n secs': - 'tänk %s i %n sek', + 't\u00E4nk %s i %n sek', 'think %s': - 'tänk %s', + 't\u00E4nk %s', 'Hello!': 'Hej!', 'Hmm...': 'Hmm...', 'change %eff effect by %n': - 'ändra %eff -effekt med %n', + '\u00E4ndra %eff -effekt med %n', 'set %eff effect to %n': - 'sätt %eff -effekt til %n', + 's\u00E4tt %eff -effekt til %n', 'clear graphic effects': - 'nollställ grafiska effekter', + 'nollst\u00E4ll grafiska effekter', 'change size by %n': - 'ändra storlek med %n', + '\u00E4ndra storlek med %n', 'set size to %n %': - 'sätt storlek till %n %', + 's\u00E4tt storlek till %n %', 'size': 'storlek', 'show': 'visa', 'hide': - 'göm', + 'g\u00F6m', 'go to front': - 'lägg överst', + 'l\u00E4gg \u00F6verst', 'go back %n layers': - 'flytta %n lager bakåt', + 'flytta %n lager bak\u00E5t', 'development mode \ndebugging primitives:': - 'utvecklarläge \nDebugging av block', + 'utvecklarl\u00E4ge \nDebugging av block', 'console log %mult%s': 'skriv till konsoll: %mult%s', 'alert %mult%s': @@ -375,7 +375,7 @@ SnapTranslator.dict.sv = { 'play sound %snd': 'spela ljud %snd', 'play sound %snd until done': - 'spela ljud %snd tills färdig', + 'spela ljud %snd tills f\u00E4rdig', 'stop all sounds': 'stoppa alla ljud', 'rest for %n beats': @@ -383,9 +383,9 @@ SnapTranslator.dict.sv = { 'play note %n for %n beats': 'spela ton %n i %n slag', 'change tempo by %n': - 'ändra tempo med %n', + '\u00E4ndra tempo med %n', 'set tempo to %n bpm': - 'sätt tempo till %n bpm', + 's\u00E4tt tempo till %n bpm', 'tempo': 'tempo', @@ -397,51 +397,51 @@ SnapTranslator.dict.sv = { 'pen up': 'penna upp', 'set pen color to %clr': - 'sätt pennfärg till %clr', + 's\u00E4tt pennf\u00E4rg till %clr', 'change pen color by %n': - 'ändra pennfärg till %n', + '\u00E4ndra pennf\u00E4rg till %n', 'set pen color to %n': - 'sätt penfärg till %n', + 's\u00E4tt penf\u00E4rg till %n', 'change pen shade by %n': - 'ändra pennstyrka med %n', + '\u00E4ndra pennstyrka med %n', 'set pen shade to %n': - 'sätt pennstyrka till %n', + 's\u00E4tt pennstyrka till %n', 'change pen size by %n': - 'ändra penntjocklek med %n', + '\u00E4ndra penntjocklek med %n', 'set pen size to %n': - 'sätt penntjocklek til %n', + 's\u00E4tt penntjocklek til %n', 'stamp': - 'stämpla', + 'st\u00E4mpla', // control: 'when %greenflag clicked': - 'när %greenflag klickas på', + 'n\u00E4r %greenflag klickas p\u00E5', 'when %key key pressed': - 'när tangent %key trycks ned', + 'n\u00E4r tangent %key trycks ned', 'when I am clicked': - 'när jag klickas', + 'n\u00E4r jag klickas p\u00E5', 'when I receive %msg': - 'när jag tar emot meddelande %msg', + 'n\u00E4r jag tar emot meddelande %msg', 'broadcast %msg': 'skicka meddelande %msg', 'broadcast %msg and wait': - 'skicka meddelande %msg och vänta', + 'skicka meddelande %msg och v\u00E4nta', 'Message name': 'Meddelandets namn', 'wait %n secs': - 'vänta %n sek', + 'v\u00E4nta %n sek', 'wait until %b': - 'vänta tills %b', + 'v\u00E4nta tills %b', 'forever %c': - 'för alltid %c', + 'f\u00F6r alltid %c', 'repeat %n %c': - 'upprepa %n gånger %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å %c', + 'om %b %c d\u00E5 %c', 'report %s': 'returnera %s', 'stop block': @@ -454,21 +454,21 @@ SnapTranslator.dict.sv = { 'pausa alla %pause', 'run %cmdRing %inputs': - 'kör %cmdRing med %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ör %cmdRing och fortsätt', + 'k\u00F6r %cmdRing och forts\u00E4tt', 'call %cmdRing w/continuation': - 'anropa %cmdRing och fortsätt', + 'anropa %cmdRing och forts\u00E4tt', 'when I start as a clone': - 'när jag startar som klon', + 'n\u00E4r jag startar som klon', 'create a clone of %cln': 'skapa klon av %cln', 'myself': - 'mig själv', + 'mig sj\u00E4lv', 'delete this clone': 'radera klon', @@ -478,13 +478,13 @@ SnapTranslator.dict.sv = { // sensing: 'touching %col ?': - 'rör %col ?', + 'r\u00F6r %col ?', 'touching %clr ?': - 'rör %clr ?', + 'r\u00F6r %clr ?', 'color %clr is touching %clr ?': - 'färgen %clr rör %clr ?', + 'f\u00E4rgen %clr r\u00F6r %clr ?', 'ask %s and wait': - 'fråga %s och vänta', + 'fr\u00E5ga %s och v\u00E4nta', 'what\'s your name?': 'vad heter du?', 'answer': @@ -498,22 +498,22 @@ SnapTranslator.dict.sv = { 'key %key pressed?': 'tangent %key nedtryckt?', 'distance to %dst': - 'avstånd till %dst', + 'avst\u00E5nd till %dst', 'reset timer': - 'nollställ stoppur', + 'nollst\u00E4ll stoppur', 'timer': 'stoppur', 'http:// %s': 'http:// %s', 'turbo mode?': - 'turboläge?', + 'turbol\u00E4ge?', 'set turbo mode to %b': - 'sätt turboläge till %b', + 's\u00E4tt turbol\u00E4ge till %b', 'filtered for %clr': - 'filtrera på %clr', + 'filtrera p\u00E5 %clr', 'stack size': 'stack-storlek', 'frames': @@ -527,7 +527,7 @@ SnapTranslator.dict.sv = { '%fun av %n': '%fun von %n', 'pick random %n to %n': - 'slumptal från %n till %n', + 'slumptal fr\u00E5n %n till %n', '%b and %b': '%b och %b', '%b or %b': @@ -539,21 +539,21 @@ SnapTranslator.dict.sv = { 'false': 'falskt', 'join %words': - 'slå ihop %words', + 'sl\u00E5 ihop %words', 'hello': 'hej', 'world': - 'världen', + 'v\u00E4rlden', 'letter %n of %s': 'bokstav %n av %s', 'length of %s': - 'lengde av %s', + 'l\u00E4ngden av %s', 'unicode of %s': 'unicode av %s', 'unicode %n as letter': 'unicode %n som bokstav', 'is %s a %typ ?': - '%s är %typ ?', + '%s \u00E4r %typ ?', 'is %s identical to %s ?': '%s identisk med %s ?', @@ -569,13 +569,13 @@ SnapTranslator.dict.sv = { 'Radera variabel', 'set %var to %s': - 'sätt %var till %s', + 's\u00E4tt %var till %s', 'change %var by %n': - 'ändra %var med %n', + '\u00E4ndra %var med %n', 'show variable %var': 'visa variabel %var', 'hide variable %var': - 'göm variabel %var', + 'g\u00F6m variabel %var', 'script variables %scriptVars': 'skriptvariabel %scriptVars', @@ -583,25 +583,25 @@ SnapTranslator.dict.sv = { 'list %exp': 'lista %exp', '%s in front of %l': - '%s främst i %l', + '%s fr\u00E4mst i %l', 'item %idx of %l': 'element %idx i %l', 'all but first of %l': - 'allt utom första i %l', + 'allt utom f\u00F6rsta i %l', 'length of %l': - 'längd av %l', + 'l\u00E4ngd av %l', '%l contains %s': - '%l innehåller %s', + '%l inneh\u00E5ller %s', 'thing': 'sak', 'add %s to %l': - 'lägg %s till %l', + 'l\u00E4gg %s till %l', 'delete %ida of %l': - 'radera %ida från %l', + 'radera %ida fr\u00E5n %l', 'insert %s at %idx of %l': - 'lägg in %s på plats %idx i lista %l', + 'l\u00E4gg in %s p\u00E5 plats %idx i lista %l', 'replace item %idx of %l with %s': - 'ersätt element %idx i %l med %s', + 'ers\u00E4tt element %idx i %l med %s', // other 'Make a block': @@ -614,15 +614,15 @@ SnapTranslator.dict.sv = { 'Snap! website': 'Snap! webbsida', 'Download source': - 'Ladda ner källkoden', + 'Ladda ner k\u00E4llkoden', 'Switch back to user mode': - 'Tillbaka till användarläge', + 'Tillbaka till anv\u00E4ndarl\u00E4ge', 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': - 'stäng av Morphic\nmenyeroch visa \nanvändarvänliga istället', + 'st\u00E4ng av Morphic\nmenyeroch visa \nanv\u00E4ndarv\u00E4nliga ist\u00E4llet', 'Switch to dev mode': - 'Byt till utvecklarläge', + 'Byt till utvecklarl\u00E4ge', 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': - 'aktivera Morphic menyer\noch inspektorer,\ninte användarvänligt!', + 'aktivera Morphic menyer\noch inspektorer,\ninte anv\u00E4ndarv\u00E4nligt!', // project menu 'Project notes...': @@ -630,7 +630,7 @@ SnapTranslator.dict.sv = { 'New': 'Ny', 'Open...': - 'Öppna...', + '\u00D6ppna...', 'Save': 'Spara', 'Save As...': @@ -638,25 +638,23 @@ SnapTranslator.dict.sv = { 'Import...': 'Importera...', 'file menu import hint': - 'laster inn eksportertes prosjekt,\net bibliotek med ' - + 'blokker\n' - + 'et kostym eller en lyd', + '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önster', + '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önster', + '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...': - 'Biblioteker...', + 'Bibliotek...', 'Import library': 'Importera bibliotek', @@ -668,77 +666,77 @@ SnapTranslator.dict.sv = { // settings menu 'Language...': - 'Språk...', + 'Spr\u00E5k...', 'Zoom blocks...': - 'Förstora blocken...', + 'F\u00F6rstora blocken...', 'Blurred shadows': 'Suddade skuggor', 'uncheck to use solid drop\nshadows and highlights': - 'bocka av för att använda\nfasta skuggor och belysningar', + 'avmarkera f\u00F6r att anv\u00E4nda\nifyllda skuggor och belysningar', 'check to use blurred drop\nshadows and highlights': - 'bocka i för att använda\nsuddiga skuggor och belysningar', + 'kryssa f\u00F6r att anv\u00E4nda\nsuddiga skuggor och belysningar', 'Zebra coloring': - 'Zebrafärgning', + 'Zebraf\u00E4rg', 'check to enable alternating\ncolors for nested blocks': - 'bocka i för att växla blockfärger\nför nestlade block', + 'kryssa f\u00F6r att v\u00E4xla blockf\u00E4rger\ni nestlade block', 'uncheck to disable alternating\ncolors for nested block': - 'bocka av för inaktivera växlade\nfärger för nestlade block', + 'avmarkera f\u00F6r att inaktivera v\u00E4xlade\nf\u00E4rger i nestlade block', 'Dynamic input labels': - 'Dynamisk namn för indata', + 'Dynamiska namn f\u00F6r indata', 'uncheck to disable dynamic\nlabels for variadic inputs': - 'bocka av för att inaktivera \ndynamiska namn för indata \nmed flera variabelfält', + 'avmarkera f\u00F6r att inaktivera \ndynamiska namn f\u00F6r indata \nmed flera variabelf\u00E4lt', 'check to enable dynamic\nlabels for variadic inputs': - 'bocka i för att aktivera \ndynamiska namn för indata \nmed flera variabelfält', + 'kryssa f\u00F6r att aktivera \ndynamiska namn f\u00F6r indata \nmed flera variabelf\u00E4lt', 'Prefer empty slot drops': - 'Föredra släpp på tomma utrymmen', + 'F\u00F6redra sl\u00E4pp p\u00E5 tomma utrymmen', 'settings menu prefer empty slots hint': - 'Inställningar\nföredra tomma utrymmen', + 'Inst\u00E4llningar\nf\u00F6redra sl\u00E4pp p\u00E5 tomma utrymmen', 'uncheck to allow dropped\nreporters to kick out others': - 'kryss vekk for at flyttede reportere vil ta plassen til andre\n', + 'avmarkera f\u00F6r att till\u00E5ta placerade\n rappporterare att flytta ut andra', 'Long form input dialog': - 'Lange dialoger for inndata', + 'Komplett inmatningsf\u00F6nster', 'check to always show slot\ntypes in the input dialog': - 'kryss av for \u00E5 vise variabelfelttype\ni inndata dialoger', + 'kryssa f\u00F6r att alltid visa\n alla typer i inmatningsf\u00F6nstret', 'uncheck to use the input\ndialog in short form': - 'kryss vekk for \u00E5 bruke korte inndata\ndialoger', + 'avmarkera f\u00F6r att visa lilla inmatningsf\u00F6nstret', 'Virtual keyboard': - 'Virtuelt tastatur', + 'Virtuellt tangentbord', 'uncheck to disable\nvirtual keyboard support\nfor mobile devices': - 'kryss vekk for \u00E5 sl\u00E5 av virtuelt\ntastatur p\u00E5 mobile enheter', + 'avmarkera f\u00F6r att inaktivera\nst\u00F6d f\u00F6r virtuellt \ntangentbord p\u00E5 mobila enheter', 'check to enable\nvirtual keyboard support\nfor mobile devices': - 'kryss av for \u00E5 sl\u00E5 p\u00E5 virtuelt\ntastatur p\u00E5 mobile enheter', + 'kryssa f\u00F6r att aktivera\nst\u00F6d f\u00F6r virtuellt \ntangentbord p\u00E5 mobila enheter', 'Input sliders': - 'Volymkontroll för indata', + 'Volymkontroller', 'uncheck to disable\ninput sliders for\nentry fields': - 'kryss vekk for \u00E5 sl\u00E5 av\nskyveknapper i inndatafelt', + 'avmarkera f\u00F6r att inaktivera \nvolymkontroller f\u00F6r inmatningsf\u00E4lt', 'check to enable\ninput sliders for\nentry fields': - 'kryss av for \u00E5 sl\u00E5 p\u00E5 skyveknapper\ni inndatafelt', + 'kryssa f\u00F6r att aktivera \nvolymkontroller f\u00F6r inmatningsf\u00E4lt', 'Clicking sound': 'Klickljud', 'uncheck to turn\nblock clicking\nsound off': - 'kryss vekk for sl\u00E5 av klikkelyd', + 'avmarkera f\u00F6r att\n inaktivera klickljud', 'check to turn\nblock clicking\nsound on': - 'kryss av for \u00E5 sl\u00E5 p\u00E5 klikkelyd', + 'kryssa f\u00F6r att aktivera klickljud', 'Animations': 'Animationer', 'uncheck to disable\nIDE animations': - 'kryss vekk for \u00E5 sl\u00E5 av IDE-animasjoner', + 'avmarkera f\u00F6r att st\u00E4nga\n av IDE-animationer', 'Turbo mode': - 'Turboläge', + 'Turbol\u00E4ge', 'check to enable\nIDE animations': - 'kryss av for \u00E5 sl\u00E5 p\u00E5 IDE-animasjoner', + 'kryssa f\u00F6r att aktivera\n IDE-animationer', 'Thread safe scripts': - 'Trådsäker skripting', + 'Tr\u00E5ds\u00E4kra skript', 'uncheck to allow\nscript reentrancy': - 'kryss vekk for \u00E5 sl\u00E5 p\u00E5 gjenbruk av p\u00E5begynte skripter', + 'avmarkera f\u00F6r att till\u00E5ta \nskript att \u00E5terintr\u00E4da', 'check to disallow\nscript reentrancy': - 'kryss av for \u00E5 sl\u00E5 av gjenbruk av p\u00E5begynte skripter', + 'kryssa f\u00F6r att f\u00F6rbjuda \nskript att \u00E5terintr\u00E4da', 'Prefer smooth animations': - 'Jämna animeringar', + 'J\u00E4mna animeringar', 'uncheck for greater speed\nat variable frame rates': - 'kryss bort for st¯rre fart ved variabel frame rate', + 'avmarkera f\u00F6r h\u00F6gre fart \nvid variabel frame rate', 'check for smooth, predictable\nanimations across computers': - 'kryss av for jevne animasjoner p alle maskinplattformer', + 'kryssa f\u00F6r j\u00E4mna animeringar\n p\u00E5 alla plattformar', // inputs 'with inputs': 'med indata', @@ -751,17 +749,17 @@ SnapTranslator.dict.sv = { // context menus: 'help': - 'hjälp', + 'hj\u00E4lp', // blocks: 'hjelp...': - 'hjälp...', + 'hj\u00E4lp...', 'relabel...': - 'döp om...', + 'd\u00F6p om...', 'duplicate': 'duplicera', 'make a copy\nand pick it up': - 'gör en kopia\noch plocka upp den', + 'g\u00F6r en kopia\noch plocka upp den', 'only duplicate this block': 'duplicera endast detta block', 'delete': @@ -769,7 +767,7 @@ SnapTranslator.dict.sv = { 'script pic...': 'skript bild...', 'open a new window\nwith a picture of this script': - 'öppna ett nytt fönster\nmed en bild av detta skript', + '\u00F6ppna ett nytt f\u00F6nster\nmed en bild av detta skript', 'ringify': 'ring runt', 'unringify': @@ -793,21 +791,21 @@ SnapTranslator.dict.sv = { // scripting area 'clean up': - 'städa', + 'st\u00E4da', 'arrange scripts\nvertically': 'organisera skript\nvertikalt', 'add comment': - 'lägg till kommentar', + 'l\u00E4gg till kommentar', 'make a block...': 'skapa nytt block...', // costumes 'rename': - 'döp om', + 'd\u00F6p om', 'export': 'exportera', 'rename costume': - 'döp om kostymen', + 'd\u00F6p om kostymen', // sounds 'Play sound': @@ -819,7 +817,7 @@ SnapTranslator.dict.sv = { 'Play': 'Starta', 'rename sound': - 'döp om ljud', + 'd\u00F6p om ljud', // dialogs // buttons @@ -836,13 +834,13 @@ SnapTranslator.dict.sv = { // help 'Help': - 'Hjälp', + 'Hj\u00E4lp', // Project Manager 'Untitled': - 'Namnlös', + 'Namnl\u00F6s', 'Open Project': - 'Öppna projekt', + '\u00D6ppna projekt', '(empty)': '(tomt)', 'Saved!': @@ -850,15 +848,15 @@ SnapTranslator.dict.sv = { 'Delete Project': 'Radera projekt', 'Are you sure you want to delete': - 'Är du säker på att du vill radera', + '\u00C4r du s\u00E4ker p\u00E5 att du vill radera', 'rename...': - 'döp om...', + 'd\u00F6p om...', // costume editor 'Costume Editor': - 'Kostym redigerare', + 'Kostymredigerare', 'click or drag crosshairs to move the rotation center': - 'Klicka eller dra krysset för att marker mitten', + 'Klicka eller dra krysset f\u00F6r att markera mitten', // project notes 'Project Notes': @@ -868,7 +866,7 @@ SnapTranslator.dict.sv = { 'New Project': 'Nytt projekt', 'Replace the current project with a new one?': - 'Ersätt aktuella projektet med ett nytt?', + 'Ers\u00E4tt aktuella projektet med ett nytt?', // save project 'Save Project As...': @@ -880,9 +878,9 @@ SnapTranslator.dict.sv = { 'Import blocks': 'Importera block', 'this project doesn\'t have any\ncustom global blocks yet': - 'detta projekt har inte ännu\nnågra egna globala block', + 'Detta projekt saknar\negna globala block', 'select': - 'välj', + 'v\u00E4lj', 'all': 'allt', 'none': @@ -890,13 +888,13 @@ SnapTranslator.dict.sv = { // variable dialog 'for all sprites': - 'för alla sprites', + 'f\u00F6r alla sprites', 'for this sprite only': - 'bara för denna sprite', + 'bara f\u00F6r denna sprite', // block dialog 'Change block': - 'Ändra block', + '\u00C4ndra block', 'Command': 'Kommando', 'Reporter': @@ -908,7 +906,7 @@ SnapTranslator.dict.sv = { 'Block Editor': 'Blockredigerare', 'Apply': - 'Verkställ', + 'Verkst\u00E4ll', // block deletion dialog 'Delete Custom Block': @@ -953,11 +951,11 @@ SnapTranslator.dict.sv = { 'Single input.': 'Enkel indata.', 'Default Value:': - 'Standardvärde:', + 'Standardv\u00E4rde:', 'Multiple inputs (value is list of inputs)': - 'Flera indata (värdet är en lista av indata)', + 'Flera indata (v\u00E4rdet \u00E4r en lista av indata)', 'Upvar - make internal variable visible to caller': - 'Upvar - gör internal variabel synlig för anroparen', + 'Upvar - g\u00F6r internal variabel synlig f\u00F6r anroparen', // About Snap 'About Snap': @@ -971,7 +969,7 @@ SnapTranslator.dict.sv = { 'Credits...': 'Tack till...', 'Translators...': - 'Översättare', + '\u00D6vers\u00E4ttare', 'License': 'Licens', 'current module versions:': @@ -979,7 +977,7 @@ SnapTranslator.dict.sv = { 'Contributors': 'Bidragsgivare', 'Translations': - 'Översättningar', + '\u00D6vers\u00E4ttningar', // variable watchers 'normal': @@ -995,24 +993,24 @@ SnapTranslator.dict.sv = { 'import...': 'importera...', 'Slider minimum value': - 'Volymkontroll - minsta värde', + 'Volymkontroll - minsta v\u00E4rde', 'Slider maximum value': - 'volymkontroll - högsta värde', + 'volymkontroll - h\u00F6gsta v\u00E4rde', // list watchers 'length: ': - 'längd: ', + 'l\u00E4ngd: ', // coments 'add comment here...': - 'lägg till kommentar här...', + 'l\u00E4gg till kommentar h\u00E4r...', // drow downs // directions '(90) right': - '(90) höger', + '(90) h\u00F6ger', '(-90) left': - '(-90) vänster', + '(-90) v\u00E4nster', '(0) up': '(0) upp', '(180) down': @@ -1024,15 +1022,15 @@ SnapTranslator.dict.sv = { 'edge': 'kant', 'pen trails': - 'pennspår', + 'pennsp\u00E5r', // costumes 'Turtle': - 'Sköldpadda', + 'Sk\u00F6ldpadda', // graphical effects 'ghost': - 'genomskinligt', + 'sp\u00F6k', // keys 'space': @@ -1042,9 +1040,9 @@ SnapTranslator.dict.sv = { 'down arrow': 'pil ned', 'right arrow': - 'pil höger', + 'pil h\u00F6ger', 'left arrow': - 'pil vänster', + 'pil v\u00E4nster', 'a': 'a', 'b': @@ -1126,7 +1124,7 @@ SnapTranslator.dict.sv = { 'abs': 'abs', 'sqrt': - 'kvadrat', + 'kvadratrot', 'sin': 'sin', 'cos': @@ -1164,5 +1162,198 @@ SnapTranslator.dict.sv = { 'last': 'sista', 'any': - 'vilken som helst' + '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)' + }; diff --git a/locale.js b/locale.js index 508d116..915b017 100644 --- a/locale.js +++ b/locale.js @@ -401,7 +401,7 @@ SnapTranslator.dict.sv = { 'translator_e-mail': 'eolsson@gmail.com', 'last_changed': - '2014-11-01' + '2014-12-14' }; SnapTranslator.dict.pt_BR = { -- cgit v1.3.1 From 33b859739c6fe64da5703fe2e3e12bc5907cba32 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 15 Dec 2014 09:54:20 +0100 Subject: updated history --- history.txt | 4 ++++ locale.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index edbf4d0..a7b88af 100755 --- a/history.txt +++ b/history.txt @@ -2394,3 +2394,7 @@ ______ 141211 ------ * Threads: yield after each cycle in the experimental “forEach” primitive + +141215 +------ +* New Swedish translation! Yay!! Thanks, Erik A Olsson! diff --git a/locale.js b/locale.js index 915b017..b3c2ce5 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-December-02'; +modules.locale = '2014-December-15'; // Global stuff -- cgit v1.3.1 From 777498a9f416a8a383e435d19a41f7bdae8ad048 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 17 Dec 2014 08:12:35 +0100 Subject: Experimental “processes” count watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (hidden in dev mode) --- history.txt | 4 ++++ objects.js | 27 +++++++++++++++++++++++++-- store.js | 5 +++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index a7b88af..2f82c32 100755 --- a/history.txt +++ b/history.txt @@ -2398,3 +2398,7 @@ ______ 141215 ------ * New Swedish translation! Yay!! Thanks, Erik A Olsson! + +141217 +------ +* Objects, Store: Experimental “processes” count watcher (hidden in dev mode) diff --git a/objects.js b/objects.js index 7277719..b155b05 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-December-04'; +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', @@ -1918,6 +1924,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')); @@ -3579,6 +3587,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) { @@ -5059,6 +5077,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')); @@ -5509,6 +5529,9 @@ StageMorph.prototype.watcherFor = StageMorph.prototype.getLastAnswer = SpriteMorph.prototype.getLastAnswer; +StageMorph.prototype.reportThreadCount + = SpriteMorph.prototype.reportThreadCount; + // StageMorph message broadcasting StageMorph.prototype.allMessageNames @@ -6757,7 +6780,7 @@ WatcherMorph.prototype.object = function () { WatcherMorph.prototype.isGlobal = function (selector) { return contains( ['getLastAnswer', 'getLastMessage', 'getTempo', 'getTimer', - 'reportMouseX', 'reportMouseY'], + 'reportMouseX', 'reportMouseY', 'reportThreadCount'], selector ); }; diff --git a/store.js b/store.js index 7b2b7e1..8cbc10f 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-December-06'; +modules.store = '2014-December-17'; // XML_Serializer /////////////////////////////////////////////////////// @@ -267,7 +267,8 @@ SnapSerializer.prototype.watcherLabels = { getTimer: 'timer', getCostumeIdx: 'costume #', reportMouseX: 'mouse x', - reportMouseY: 'mouse y' + reportMouseY: 'mouse y', + reportThreadCount: 'processes' }; // SnapSerializer instance creation: -- cgit v1.3.1 From fc256e9e727bfe85fbf885cc65afa3b152430c71 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 17 Dec 2014 09:41:21 +0100 Subject: Remove terminated processes from expired clones --- history.txt | 1 + threads.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 2f82c32..1ec5c83 100755 --- a/history.txt +++ b/history.txt @@ -2402,3 +2402,4 @@ ______ 141217 ------ * Objects, Store: Experimental “processes” count watcher (hidden in dev mode) +* Threads: Remove terminated processes from expired clones diff --git a/threads.js b/threads.js index b80ee9e..6078f5b 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-December-11'; +modules.threads = '2014-December-17'; var ThreadManager; var Process; @@ -234,7 +234,7 @@ ThreadManager.prototype.removeTerminatedProcesses = function () { // and un-highlight their scripts var remaining = []; this.processes.forEach(function (proc) { - if (!proc.isRunning() && !proc.errorFlag && !proc.isDead) { + if ((!proc.isRunning() && !proc.errorFlag) || proc.isDead) { if (proc.topBlock instanceof BlockMorph) { proc.topBlock.removeHighlight(); } -- cgit v1.3.1 From b31df39d7f126eaa303c8dae1cf6a14c739a2cc5 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 17 Dec 2014 12:35:13 +0100 Subject: Let “zombifying” scripts access receivers’ local vars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- history.txt | 1 + threads.js | 1 + 2 files changed, 2 insertions(+) diff --git a/history.txt b/history.txt index 1ec5c83..6d6f0ff 100755 --- a/history.txt +++ b/history.txt @@ -2403,3 +2403,4 @@ ______ ------ * 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/threads.js b/threads.js index 6078f5b..791d81c 100644 --- a/threads.js +++ b/threads.js @@ -2546,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; }; -- cgit v1.3.1