├── README.md
├── blockly.html
├── blockly
├── blockly.html
├── blockly_compressed.js
├── blockly_espruino.js
├── blocks_compressed.js
├── changes.diff
├── en.js
├── field_textarea.js
├── javascript_compressed.js
└── media
│ ├── 1x1.gif
│ ├── anon.jpeg
│ ├── click.mp3
│ ├── click.ogg
│ ├── click.wav
│ ├── delete.mp3
│ ├── delete.ogg
│ ├── delete.wav
│ ├── handclosed.cur
│ ├── handopen.cur
│ ├── progress.gif
│ ├── quote0.png
│ ├── quote1.png
│ ├── sprites.png
│ ├── trashbody.png
│ ├── trashlid.png
│ └── tree.png
├── blockly_simple.html
├── circuit.fzz
├── circuit.png
├── circuit_single.fzz
├── circuit_single.png
├── colour_chooser.html
├── data
└── terminal_initial.html
├── ide.html
├── index.html
├── plugin.html
├── plugin.js
├── serial_to_audio.js
├── terminal.css
└── test.html
/README.md:
--------------------------------------------------------------------------------
1 | EspruinoOrion - Eclipse Orion plugin
2 | ====================================
3 |
4 |
5 | Espruino plugin for Eclipse Orion.
6 |
7 | [There's a forum post about it here](http://forum.espruino.com/conversations/257732/)
8 |
9 | Simply:
10 |
11 | * Host this on an HTTPS capable webserver (or use [GitHub](https://espruino.github.io/EspruinoOrion/))
12 | * Add [plugin.html](https://espruino.github.io/EspruinoOrion/plugin.html) to Eclipse Orion
13 | * Open [index.html](https://espruino.github.io/EspruinoOrion/index.html) in a new window
14 | * Connect Espruino to your AUDIO JACKS (wiring below)
15 | * In Orion, open a file, go to 'Tools', and click 'Send to Espruino'
16 |
17 | If you'd rather just use USB and the Web IDE...
18 |
19 | * Use Chrome and install the [Web IDE](http://github.com/espruino/EspruinoWebIDE)
20 | * Add [plugin.html](https://espruino.github.io/EspruinoOrion/plugin.html) to Eclipse Orion
21 | * Open [ide.html](https://espruino.github.io/EspruinoOrion/ide.html) in a new window
22 |
23 | Or if you want to use Blockly instead:
24 |
25 | * Open [index.html](https://espruino.github.io/EspruinoOrion/index.html) in a new window
26 | * Open [blockly.html](https://espruino.github.io/EspruinoOrion/blockly.html)
27 |
28 | **Note:** If this doesn't work, your device may have RX and/or TX polarity mixed up. Try clicking the checkboxes and trying again.
29 |
30 | One-way communication
31 | ------------------
32 |
33 | You can also do one-directional communication (from the PC to an Espruino board). There's a simple library for this called [serial_to_audio.js](serial_to_audio.js).
34 |
35 | Examples of this are:
36 |
37 | * [blockly_simple.html](https://espruino.github.io/EspruinoOrion/blockly_simple.html) - the previous Blockly Example, but with no need for a separate window. Works perfectly on tablets!
38 | * [colour_chooser.html](https://espruino.github.io/EspruinoOrion/colour_chooser.html) - a simple colour chooser that will change the colour of connected WS2811 lights (on B15) when you click a coloured square.
39 |
40 | How it works
41 | ----------
42 |
43 | Data is sent and received at 9600 baud using your headphone and microphone jacks - no local software needed!
44 |
45 | When you click 'Send to Espruino' in Orion, a cookie is set with the code in.
46 |
47 | The Terminal (index.html) reads this code and converts it to sound waves which it sends to Espruino.
48 |
49 |
50 | Connections
51 | ----------
52 |
53 | 
54 |
55 | * Connect Espruino GND to the sheath on both headphone and microphone jacks
56 | * Connect Espruino A9 (TX) to a 10k resistor, and connect that to the microphone Left+Right
57 | * Connect a 10k resistor to the microphone sheath and connect that to microphone Left+Right too
58 | * Connect Espruino A10 (RX) to the Left channel of the headphone jack
59 | * Connect a 40k resistor between the headphone jack left channel and the headphone jack sheath
60 |
61 | This creates:
62 | * A potential divider to convert the 3.3v Espruino TX signal to a 1.6v signal for the microphone
63 | * A bias to 1.6v for Espruino's RX (by default Espruino turns on an internal 40k pullup resistor on the Usart to stop noise getting in)
64 |
65 | **Note:** Most computers have a ~10uF capacitor in their headphone output - this allows the DC bias to work. However some computers may not have it, in which case the resting voltage for A10 will be 0v insread of 1.6v. In that case, you'll need to add a 10uF capacitor between Espruino + the resistor and the actual headphone output.
66 |
67 | Connections for One-way communication
68 | ----------------------------------------
69 |
70 | 
71 |
72 | This is just as before, but with the microphone part removed - so you only have two parts to solder!
73 |
--------------------------------------------------------------------------------
/blockly.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
39 |
40 |
63 |
64 |
65 |
66 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/blockly/blockly.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 10
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | 1
48 |
49 |
50 |
51 |
52 | 10
53 |
54 |
55 |
56 |
57 | 1
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 0
67 |
68 |
69 | ADD
70 |
71 |
72 | ROOT
73 |
74 |
75 | SIN
76 |
77 |
78 | PI
79 |
80 |
81 |
82 | EVEN
83 |
84 |
85 | item
86 |
87 |
88 | 1
89 |
90 |
91 |
92 |
93 | ROUND
94 |
95 |
96 | SUM
97 |
98 |
99 |
100 |
101 |
102 | 1
103 |
104 |
105 |
106 |
107 | 100
108 |
109 |
110 |
111 |
112 |
113 |
114 | 1
115 |
116 |
117 |
118 |
119 | 100
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | item
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | FIRST
144 |
145 |
146 | text
147 |
148 |
149 |
150 |
151 |
152 | FROM_START
153 |
154 |
155 | text
156 |
157 |
158 |
159 |
160 |
161 | FROM_START
162 | FROM_START
163 |
164 |
165 | text
166 |
167 |
168 |
169 |
170 | UPPERCASE
171 |
172 |
173 | BOTH
174 |
175 |
176 |
177 |
178 | list
179 |
180 |
181 | list
182 |
183 |
184 |
185 |
186 | list
187 |
188 |
189 |
190 | 5
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | FIRST
199 |
200 |
201 | list
202 |
203 |
204 |
205 |
206 |
207 | GET
208 | FROM_START
209 |
210 |
211 | list
212 |
213 |
214 |
215 |
216 |
217 | SET
218 | FROM_START
219 |
220 |
221 | list
222 |
223 |
224 |
225 |
226 |
227 | FROM_START
228 | FROM_START
229 |
230 |
231 | list
232 |
233 |
234 |
235 |
236 |
237 |
238 | item
239 |
240 |
241 | item
242 |
243 |
244 |
258 |
259 |
260 | 1
261 |
262 |
263 | 1
264 |
265 |
266 |
267 |
268 | BTN1
269 |
270 |
271 | LED1
272 |
273 |
274 | LED1
275 | TRUE
276 | 100
277 |
278 |
279 | BTN1
280 |
281 |
282 | A1
283 |
284 |
285 | A0
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 | LED2TRUE1LED1TRUE0.5LED1FALSE
296 |
297 |
298 |
299 |
300 |
--------------------------------------------------------------------------------
/blockly/blockly_espruino.js:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2014 Gordon Williams (gw@pur3.co.uk)
3 |
4 | This Source Code is subject to the terms of the Mozilla Public
5 | License, v2.0. If a copy of the MPL was not distributed with this
6 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 |
8 | ------------------------------------------------------------------
9 | Blockly blocks for Espruino
10 | ------------------------------------------------------------------
11 | **/
12 |
13 | // --------------------------------- Blockly init code - see /js/core/editorBlockly.js
14 | window.onload = function() {
15 | Blockly.inject(document.body,{path: '', toolbox: document.getElementById('toolbox')});
16 | Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, document.getElementById('blocklyInitial'));
17 | window.parent.window.blocklyLoaded(Blockly, window); // see core/editorBlockly.js
18 | };
19 | // When we have JSON from the board, use it to
20 | // update our list of available pins
21 | Blockly.setBoardJSON = function(info) {
22 | console.log("Blockly.setBoardJSON ", info);
23 | if (!("pins" in info)) return;
24 | if (!("devices" in info)) return;
25 | PINS = [];
26 | var i,s;
27 | for (i=1;i<8;i++) {
28 | s = "LED"+i;
29 | if (s in info.devices) PINS.push([s,s]);
30 | }
31 | for (i=1;i<8;i++) {
32 | s = "BTN"+i;
33 | if (s in info.devices) PINS.push([s,s]);
34 | }
35 | for (i in info.pins)
36 | PINS.push([info.pins[i].name, info.pins[i].name]);
37 |
38 |
39 | };
40 | // ---------------------------------
41 |
42 | var ESPRUINO_COL = 190;
43 |
44 | var PORTS = ["A","B","C"];
45 | var PINS = [
46 | ["LED1", 'LED1'],
47 | ["LED2", 'LED2'],
48 | ["LED3", 'LED3'],
49 | ["BTN1", 'BTN1']];
50 | for (var p in PORTS)
51 | for (var i=0;i<16;i++) {
52 | var pinname = PORTS[p]+i;
53 | PINS.push([pinname,pinname]);
54 | }
55 |
56 | Blockly.Blocks.espruino_timeout = {
57 | category: 'Espruino',
58 | init: function() {
59 | this.appendValueInput('SECONDS')
60 | .setCheck('Number')
61 | .appendField('wait');
62 | this.appendDummyInput()
63 | .appendField("seconds");
64 | this.appendStatementInput('DO')
65 | .appendField('do');
66 |
67 | this.setPreviousStatement(true);
68 | this.setNextStatement(true);
69 | this.setColour(ESPRUINO_COL);
70 | this.setInputsInline(true);
71 | this.setTooltip('Waits for a certain period before running code');
72 | }
73 | };
74 | Blockly.Blocks.espruino_interval = {
75 | category: 'Espruino',
76 | init: function() {
77 | this.appendValueInput('SECONDS')
78 | .setCheck('Number')
79 | .appendField('every');
80 | this.appendDummyInput()
81 | .appendField("seconds");
82 | this.appendStatementInput('DO')
83 | .appendField('do');
84 |
85 | this.setPreviousStatement(true);
86 | this.setNextStatement(true);
87 | this.setColour(ESPRUINO_COL);
88 | this.setInputsInline(true);
89 | this.setTooltip('Runs code repeatedly, every so many seconds');
90 | }
91 | };
92 |
93 | Blockly.Blocks.espruino_pin = {
94 | // category: 'Espruino',
95 | init: function() {
96 |
97 | var start = 0;
98 | var incrementStep = 10;
99 | var originalPin = undefined;
100 | var listGen = function() {
101 | originalPin = this.value_;
102 | var list = PINS.slice(start, start+incrementStep);
103 | if (start>0) list.unshift(['Back...', 'Back']);
104 | if (start+incrementStep","LT"],["\u2265","LTE"],["<","GT"],["\u2264","GTE"]]:[["=","EQ"],["\u2260","NEQ"],["<","LT"],["\u2264","LTE"],[">","GT"],["\u2265","GTE"]];this.setHelpUrl(Blockly.Msg.LOGIC_COMPARE_HELPURL);this.setColour(210);this.setOutput(!0,"Boolean");this.appendValueInput("A");this.appendValueInput("B").appendField(new Blockly.FieldDropdown(a),"OP");this.setInputsInline(!0);var b=this;this.setTooltip(function(){var a=
116 | b.getFieldValue("OP");return{EQ:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ,NEQ:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ,LT:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT,LTE:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE,GT:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT,GTE:Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE}[a]})}};
117 | Blockly.Blocks.logic_operation={init:function(){var a=[[Blockly.Msg.LOGIC_OPERATION_AND,"AND"],[Blockly.Msg.LOGIC_OPERATION_OR,"OR"]];this.setHelpUrl(Blockly.Msg.LOGIC_OPERATION_HELPURL);this.setColour(210);this.setOutput(!0,"Boolean");this.appendValueInput("A").setCheck("Boolean");this.appendValueInput("B").setCheck("Boolean").appendField(new Blockly.FieldDropdown(a),"OP");this.setInputsInline(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("OP");return{AND:Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND,
118 | OR:Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR}[a]})}};Blockly.Blocks.logic_negate={init:function(){this.setHelpUrl(Blockly.Msg.LOGIC_NEGATE_HELPURL);this.setColour(210);this.setOutput(!0,"Boolean");this.interpolateMsg(Blockly.Msg.LOGIC_NEGATE_TITLE,["BOOL","Boolean",Blockly.ALIGN_RIGHT],Blockly.ALIGN_RIGHT);this.setTooltip(Blockly.Msg.LOGIC_NEGATE_TOOLTIP)}};
119 | Blockly.Blocks.logic_boolean={init:function(){var a=[[Blockly.Msg.LOGIC_BOOLEAN_TRUE,"TRUE"],[Blockly.Msg.LOGIC_BOOLEAN_FALSE,"FALSE"]];this.setHelpUrl(Blockly.Msg.LOGIC_BOOLEAN_HELPURL);this.setColour(210);this.setOutput(!0,"Boolean");this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"BOOL");this.setTooltip(Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP)}};
120 | Blockly.Blocks.logic_null={init:function(){this.setHelpUrl(Blockly.Msg.LOGIC_NULL_HELPURL);this.setColour(210);this.setOutput(!0);this.appendDummyInput().appendField(Blockly.Msg.LOGIC_NULL);this.setTooltip(Blockly.Msg.LOGIC_NULL_TOOLTIP)}};
121 | Blockly.Blocks.logic_ternary={init:function(){this.setHelpUrl(Blockly.Msg.LOGIC_TERNARY_HELPURL);this.setColour(210);this.appendValueInput("IF").setCheck("Boolean").appendField(Blockly.Msg.LOGIC_TERNARY_CONDITION);this.appendValueInput("THEN").appendField(Blockly.Msg.LOGIC_TERNARY_IF_TRUE);this.appendValueInput("ELSE").appendField(Blockly.Msg.LOGIC_TERNARY_IF_FALSE);this.setOutput(!0);this.setTooltip(Blockly.Msg.LOGIC_TERNARY_TOOLTIP)}};
122 | // Copyright 2012 Google Inc. Apache License 2.0
123 | Blockly.Blocks.procedures={};
124 | Blockly.Blocks.procedures_defnoreturn={init:function(){this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.setColour(290);var a=Blockly.Procedures.findLegalName(Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE,this);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(new Blockly.FieldTextInput(a,Blockly.Procedures.rename),"NAME").appendField("","PARAMS");this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));
125 | this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.arguments_=[];this.statementConnection_=null},updateParams_:function(){for(var a=!1,b={},c=0;cSeveral lines:
114 | First line.
115 | Second line.
116 | */
117 | var y=2;
118 | var that=this;
119 | //var textNode = document.createTextNode(text);
120 | text.split(/\n/).map(function(textline){
121 | textline = textline.replace(/\s/g, Blockly.Field.NBSP);
122 | var tspan = Blockly.createSvgElement('tspan', {x:0,y:y}, that.textElement_)
123 | .appendChild(document.createTextNode(textline));
124 | y+=20;
125 | });
126 |
127 | //this.textElement_.appendChild(textNode);
128 |
129 | // Cached width is obsolete. Clear it.
130 | this.size_.width = 0;
131 |
132 | if (this.sourceBlock_ && this.sourceBlock_.rendered) {
133 | this.sourceBlock_.render();
134 | this.sourceBlock_.bumpNeighbours_();
135 | this.sourceBlock_.workspace.fireChangeEvent();
136 | }
137 | };
138 |
139 | /**
140 | * Draws the border with the correct width.
141 | * Saves the computed width in a property.
142 | * @private
143 | */
144 | Blockly.FieldTextArea.prototype.render_ = function() {
145 |
146 | this.size_.width = this.textElement_.getBBox().width + 5;
147 |
148 | this.size_.height= (this.text_.split(/\n/).length ||1)*20 + (Blockly.BlockSvg.SEP_SPACE_Y+5) ;
149 |
150 | if (this.borderRect_) {
151 | this.borderRect_.setAttribute('width',
152 | this.size_.width + Blockly.BlockSvg.SEP_SPACE_X);
153 | this.borderRect_.setAttribute('height',
154 | this.size_.height - (Blockly.BlockSvg.SEP_SPACE_Y+5));
155 | }
156 |
157 | };
158 |
159 |
160 |
161 | /**
162 | * Show the inline free-text editor on top of the text.
163 | * @param {boolean=} opt_quietInput True if editor should be created without
164 | * focus. Defaults to false.
165 | * @private
166 | */
167 | Blockly.FieldTextArea.prototype.showEditor_ = function(opt_quietInput) {
168 | var quietInput = opt_quietInput || false;
169 | if (!quietInput && (goog.userAgent.MOBILE || goog.userAgent.ANDROID ||
170 | goog.userAgent.IPAD)) {
171 | // Mobile browsers have issues with in-line textareas (focus & keyboards).
172 | var newValue = window.prompt(Blockly.Msg.CHANGE_VALUE_TITLE, this.text_);
173 | if (this.changeHandler_) {
174 | var override = this.changeHandler_(newValue);
175 | if (override !== undefined) {
176 | newValue = override;
177 | }
178 | }
179 | if (newValue !== null) {
180 | this.setText(newValue);
181 | }
182 | return;
183 | }
184 |
185 | Blockly.WidgetDiv.show(this, this.widgetDispose_());
186 | var div = Blockly.WidgetDiv.DIV;
187 | // Create the input.
188 | var htmlInput = goog.dom.createDom('textarea', 'blocklyHtmlInput');
189 | Blockly.FieldTextArea.htmlInput_ = htmlInput;
190 | htmlInput.style.resize = 'none';
191 | htmlInput.style['line-height'] = '20px';
192 | htmlInput.style.height = '100%';//this.size_.height - Blockly.BlockSvg.SEP_SPACE_Y + 'px';
193 | div.appendChild(htmlInput);
194 |
195 | htmlInput.value = htmlInput.defaultValue = this.text_;
196 | htmlInput.oldValue_ = null;
197 | this.validate_();
198 | this.resizeEditor_();
199 | if (!quietInput) {
200 | htmlInput.focus();
201 | htmlInput.select();
202 | }
203 |
204 | // Bind to keyup -- trap Enter and Esc; resize after every keystroke.
205 | htmlInput.onKeyUpWrapper_ =
206 | Blockly.bindEvent_(htmlInput, 'keyup', this, this.onHtmlInputChange_);
207 | // Bind to keyPress -- repeatedly resize when holding down a key.
208 | htmlInput.onKeyPressWrapper_ =
209 | Blockly.bindEvent_(htmlInput, 'keypress', this, this.onHtmlInputChange_);
210 | var workspaceSvg = this.sourceBlock_.workspace.getCanvas();
211 | htmlInput.onWorkspaceChangeWrapper_ =
212 | Blockly.bindEvent_(workspaceSvg, 'blocklyWorkspaceChange', this,
213 | this.resizeEditor_);
214 | };
215 |
216 | /**
217 | * Handle a change to the editor.
218 | * @param {!Event} e Keyboard event.
219 | * @private
220 | */
221 | Blockly.FieldTextArea.prototype.onHtmlInputChange_ = function(e) {
222 | var htmlInput = Blockly.FieldTextArea.htmlInput_;
223 | if (e.keyCode == 27) {
224 | // Esc
225 | this.setText(htmlInput.defaultValue);
226 | Blockly.WidgetDiv.hide();
227 | } else {
228 | // Update source block.
229 | var text = htmlInput.value;
230 | if (text !== htmlInput.oldValue_) {
231 | htmlInput.oldValue_ = text;
232 | this.setText(text);
233 | this.validate_();
234 | } else if (goog.userAgent.WEBKIT) {
235 | // Cursor key. Render the source block to show the caret moving.
236 | // Chrome only (version 26, OS X).
237 | this.sourceBlock_.render();
238 | }
239 | this.resizeEditor_();
240 | }
241 | };
242 |
243 | /**
244 | * Check to see if the contents of the editor validates.
245 | * Style the editor accordingly.
246 | * @private
247 | */
248 | Blockly.FieldTextArea.prototype.validate_ = function() {
249 | var valid = true;
250 | goog.asserts.assertObject(Blockly.FieldTextArea.htmlInput_);
251 | var htmlInput = /** @type {!Element} */ (Blockly.FieldTextArea.htmlInput_);
252 | if (this.changeHandler_) {
253 | valid = this.changeHandler_(htmlInput.value);
254 | }
255 | if (valid === null) {
256 | Blockly.addClass_(htmlInput, 'blocklyInvalidInput');
257 | } else {
258 | Blockly.removeClass_(htmlInput, 'blocklyInvalidInput');
259 | }
260 | };
261 |
262 | /**
263 | * Resize the editor and the underlying block to fit the text.
264 | * @private
265 | */
266 | Blockly.FieldTextArea.prototype.resizeEditor_ = function() {
267 | var div = Blockly.WidgetDiv.DIV;
268 | var bBox = this.fieldGroup_.getBBox();
269 | div.style.width = bBox.width + 'px';
270 | div.style.height = bBox.height + 'px';
271 | var xy = Blockly.getAbsoluteXY_(/** @type {!Element} */ (this.borderRect_));
272 | // In RTL mode block fields and LTR input fields the left edge moves,
273 | // whereas the right edge is fixed. Reposition the editor.
274 | if (Blockly.RTL) {
275 | var borderBBox = this.borderRect_.getBBox();
276 | xy.x += borderBBox.width;
277 | xy.x -= div.offsetWidth;
278 | }
279 | // Shift by a few pixels to line up exactly.
280 | xy.y += 1;
281 | if (goog.userAgent.WEBKIT) {
282 | xy.y -= 3;
283 | }
284 | div.style.left = xy.x + 'px';
285 | div.style.top = xy.y + 'px';
286 | };
287 |
288 | /**
289 | * Close the editor, save the results, and dispose of the editable
290 | * text field's elements.
291 | * @return {!Function} Closure to call on destruction of the WidgetDiv.
292 | * @private
293 | */
294 | Blockly.FieldTextArea.prototype.widgetDispose_ = function() {
295 | var thisField = this;
296 | return function() {
297 | var htmlInput = Blockly.FieldTextArea.htmlInput_;
298 | // Save the edit (if it validates).
299 | var text = htmlInput.value;
300 | if (thisField.changeHandler_) {
301 | text = thisField.changeHandler_(text);
302 | if (text === null) {
303 | // Invalid edit.
304 | text = htmlInput.defaultValue;
305 | }
306 | }
307 | thisField.setText(text);
308 | thisField.sourceBlock_.rendered && thisField.sourceBlock_.render();
309 | Blockly.unbindEvent_(htmlInput.onKeyUpWrapper_);
310 | Blockly.unbindEvent_(htmlInput.onKeyPressWrapper_);
311 | Blockly.unbindEvent_(htmlInput.onWorkspaceChangeWrapper_);
312 | Blockly.FieldTextArea.htmlInput_ = null;
313 | // Delete the width property.
314 | Blockly.WidgetDiv.DIV.style.width = 'auto';
315 | };
316 | };
317 |
318 |
319 |
--------------------------------------------------------------------------------
/blockly/javascript_compressed.js:
--------------------------------------------------------------------------------
1 | // Do not edit this file; automatically generated by build.py.
2 | "use strict";
3 |
4 |
5 | // Copyright 2012 Google Inc. Apache License 2.0
6 | Blockly.JavaScript=new Blockly.Generator("JavaScript");Blockly.JavaScript.addReservedWords("Blockly,break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with,class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield,const,null,true,false,Array,ArrayBuffer,Boolean,Date,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Error,eval,EvalError,Float32Array,Float64Array,Function,Infinity,Int16Array,Int32Array,Int8Array,isFinite,isNaN,Iterator,JSON,Math,NaN,Number,Object,parseFloat,parseInt,RangeError,ReferenceError,RegExp,StopIteration,String,SyntaxError,TypeError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,undefined,uneval,URIError,applicationCache,closed,Components,content,_content,controllers,crypto,defaultStatus,dialogArguments,directories,document,frameElement,frames,fullScreen,globalStorage,history,innerHeight,innerWidth,length,location,locationbar,localStorage,menubar,messageManager,mozAnimationStartTime,mozInnerScreenX,mozInnerScreenY,mozPaintCount,name,navigator,opener,outerHeight,outerWidth,pageXOffset,pageYOffset,parent,performance,personalbar,pkcs11,returnValue,screen,screenX,screenY,scrollbars,scrollMaxX,scrollMaxY,scrollX,scrollY,self,sessionStorage,sidebar,status,statusbar,toolbar,top,URL,window,addEventListener,alert,atob,back,blur,btoa,captureEvents,clearImmediate,clearInterval,clearTimeout,close,confirm,disableExternalCapture,dispatchEvent,dump,enableExternalCapture,escape,find,focus,forward,GeckoActiveXObject,getAttention,getAttentionWithCycleCount,getComputedStyle,getSelection,home,matchMedia,maximize,minimize,moveBy,moveTo,mozRequestAnimationFrame,open,openDialog,postMessage,print,prompt,QueryInterface,releaseEvents,removeEventListener,resizeBy,resizeTo,restore,routeEvent,scroll,scrollBy,scrollByLines,scrollByPages,scrollTo,setCursor,setImmediate,setInterval,setResizable,setTimeout,showModalDialog,sizeToContent,stop,unescape,updateCommands,XPCNativeWrapper,XPCSafeJSObjectWrapper,onabort,onbeforeunload,onblur,onchange,onclick,onclose,oncontextmenu,ondevicemotion,ondeviceorientation,ondragdrop,onerror,onfocus,onhashchange,onkeydown,onkeypress,onkeyup,onload,onmousedown,onmousemove,onmouseout,onmouseover,onmouseup,onmozbeforepaint,onpaint,onpopstate,onreset,onresize,onscroll,onselect,onsubmit,onunload,onpageshow,onpagehide,Image,Option,Worker,Event,Range,File,FileReader,Blob,BlobBuilder,Attr,CDATASection,CharacterData,Comment,console,DocumentFragment,DocumentType,DomConfiguration,DOMError,DOMErrorHandler,DOMException,DOMImplementation,DOMImplementationList,DOMImplementationRegistry,DOMImplementationSource,DOMLocator,DOMObject,DOMString,DOMStringList,DOMTimeStamp,DOMUserData,Entity,EntityReference,MediaQueryList,MediaQueryListListener,NameList,NamedNodeMap,Node,NodeFilter,NodeIterator,NodeList,Notation,Plugin,PluginArray,ProcessingInstruction,SharedWorker,Text,TimeRanges,Treewalker,TypeInfo,UserDataHandler,Worker,WorkerGlobalScope,HTMLDocument,HTMLElement,HTMLAnchorElement,HTMLAppletElement,HTMLAudioElement,HTMLAreaElement,HTMLBaseElement,HTMLBaseFontElement,HTMLBodyElement,HTMLBRElement,HTMLButtonElement,HTMLCanvasElement,HTMLDirectoryElement,HTMLDivElement,HTMLDListElement,HTMLEmbedElement,HTMLFieldSetElement,HTMLFontElement,HTMLFormElement,HTMLFrameElement,HTMLFrameSetElement,HTMLHeadElement,HTMLHeadingElement,HTMLHtmlElement,HTMLHRElement,HTMLIFrameElement,HTMLImageElement,HTMLInputElement,HTMLKeygenElement,HTMLLabelElement,HTMLLIElement,HTMLLinkElement,HTMLMapElement,HTMLMenuElement,HTMLMetaElement,HTMLModElement,HTMLObjectElement,HTMLOListElement,HTMLOptGroupElement,HTMLOptionElement,HTMLOutputElement,HTMLParagraphElement,HTMLParamElement,HTMLPreElement,HTMLQuoteElement,HTMLScriptElement,HTMLSelectElement,HTMLSourceElement,HTMLSpanElement,HTMLStyleElement,HTMLTableElement,HTMLTableCaptionElement,HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement,HTMLTableColElement,HTMLTableRowElement,HTMLTableSectionElement,HTMLTextAreaElement,HTMLTimeElement,HTMLTitleElement,HTMLTrackElement,HTMLUListElement,HTMLUnknownElement,HTMLVideoElement,HTMLCanvasElement,CanvasRenderingContext2D,CanvasGradient,CanvasPattern,TextMetrics,ImageData,CanvasPixelArray,HTMLAudioElement,HTMLVideoElement,NotifyAudioAvailableEvent,HTMLCollection,HTMLAllCollection,HTMLFormControlsCollection,HTMLOptionsCollection,HTMLPropertiesCollection,DOMTokenList,DOMSettableTokenList,DOMStringMap,RadioNodeList,SVGDocument,SVGElement,SVGAElement,SVGAltGlyphElement,SVGAltGlyphDefElement,SVGAltGlyphItemElement,SVGAnimationElement,SVGAnimateElement,SVGAnimateColorElement,SVGAnimateMotionElement,SVGAnimateTransformElement,SVGSetElement,SVGCircleElement,SVGClipPathElement,SVGColorProfileElement,SVGCursorElement,SVGDefsElement,SVGDescElement,SVGEllipseElement,SVGFilterElement,SVGFilterPrimitiveStandardAttributes,SVGFEBlendElement,SVGFEColorMatrixElement,SVGFEComponentTransferElement,SVGFECompositeElement,SVGFEConvolveMatrixElement,SVGFEDiffuseLightingElement,SVGFEDisplacementMapElement,SVGFEDistantLightElement,SVGFEFloodElement,SVGFEGaussianBlurElement,SVGFEImageElement,SVGFEMergeElement,SVGFEMergeNodeElement,SVGFEMorphologyElement,SVGFEOffsetElement,SVGFEPointLightElement,SVGFESpecularLightingElement,SVGFESpotLightElement,SVGFETileElement,SVGFETurbulenceElement,SVGComponentTransferFunctionElement,SVGFEFuncRElement,SVGFEFuncGElement,SVGFEFuncBElement,SVGFEFuncAElement,SVGFontElement,SVGFontFaceElement,SVGFontFaceFormatElement,SVGFontFaceNameElement,SVGFontFaceSrcElement,SVGFontFaceUriElement,SVGForeignObjectElement,SVGGElement,SVGGlyphElement,SVGGlyphRefElement,SVGGradientElement,SVGLinearGradientElement,SVGRadialGradientElement,SVGHKernElement,SVGImageElement,SVGLineElement,SVGMarkerElement,SVGMaskElement,SVGMetadataElement,SVGMissingGlyphElement,SVGMPathElement,SVGPathElement,SVGPatternElement,SVGPolylineElement,SVGPolygonElement,SVGRectElement,SVGScriptElement,SVGStopElement,SVGStyleElement,SVGSVGElement,SVGSwitchElement,SVGSymbolElement,SVGTextElement,SVGTextPathElement,SVGTitleElement,SVGTRefElement,SVGTSpanElement,SVGUseElement,SVGViewElement,SVGVKernElement,SVGAngle,SVGColor,SVGICCColor,SVGElementInstance,SVGElementInstanceList,SVGLength,SVGLengthList,SVGMatrix,SVGNumber,SVGNumberList,SVGPaint,SVGPoint,SVGPointList,SVGPreserveAspectRatio,SVGRect,SVGStringList,SVGTransform,SVGTransformList,SVGAnimatedAngle,SVGAnimatedBoolean,SVGAnimatedEnumeration,SVGAnimatedInteger,SVGAnimatedLength,SVGAnimatedLengthList,SVGAnimatedNumber,SVGAnimatedNumberList,SVGAnimatedPreserveAspectRatio,SVGAnimatedRect,SVGAnimatedString,SVGAnimatedTransformList,SVGPathSegList,SVGPathSeg,SVGPathSegArcAbs,SVGPathSegArcRel,SVGPathSegClosePath,SVGPathSegCurvetoCubicAbs,SVGPathSegCurvetoCubicRel,SVGPathSegCurvetoCubicSmoothAbs,SVGPathSegCurvetoCubicSmoothRel,SVGPathSegCurvetoQuadraticAbs,SVGPathSegCurvetoQuadraticRel,SVGPathSegCurvetoQuadraticSmoothAbs,SVGPathSegCurvetoQuadraticSmoothRel,SVGPathSegLinetoAbs,SVGPathSegLinetoHorizontalAbs,SVGPathSegLinetoHorizontalRel,SVGPathSegLinetoRel,SVGPathSegLinetoVerticalAbs,SVGPathSegLinetoVerticalRel,SVGPathSegMovetoAbs,SVGPathSegMovetoRel,ElementTimeControl,TimeEvent,SVGAnimatedPathData,SVGAnimatedPoints,SVGColorProfileRule,SVGCSSRule,SVGExternalResourcesRequired,SVGFitToViewBox,SVGLangSpace,SVGLocatable,SVGRenderingIntent,SVGStylable,SVGTests,SVGTextContentElement,SVGTextPositioningElement,SVGTransformable,SVGUnitTypes,SVGURIReference,SVGViewSpec,SVGZoomAndPan");
7 | Blockly.JavaScript.ORDER_ATOMIC=0;Blockly.JavaScript.ORDER_MEMBER=1;Blockly.JavaScript.ORDER_NEW=1;Blockly.JavaScript.ORDER_FUNCTION_CALL=2;Blockly.JavaScript.ORDER_INCREMENT=3;Blockly.JavaScript.ORDER_DECREMENT=3;Blockly.JavaScript.ORDER_LOGICAL_NOT=4;Blockly.JavaScript.ORDER_BITWISE_NOT=4;Blockly.JavaScript.ORDER_UNARY_PLUS=4;Blockly.JavaScript.ORDER_UNARY_NEGATION=4;Blockly.JavaScript.ORDER_TYPEOF=4;Blockly.JavaScript.ORDER_VOID=4;Blockly.JavaScript.ORDER_DELETE=4;
8 | Blockly.JavaScript.ORDER_MULTIPLICATION=5;Blockly.JavaScript.ORDER_DIVISION=5;Blockly.JavaScript.ORDER_MODULUS=5;Blockly.JavaScript.ORDER_ADDITION=6;Blockly.JavaScript.ORDER_SUBTRACTION=6;Blockly.JavaScript.ORDER_BITWISE_SHIFT=7;Blockly.JavaScript.ORDER_RELATIONAL=8;Blockly.JavaScript.ORDER_IN=8;Blockly.JavaScript.ORDER_INSTANCEOF=8;Blockly.JavaScript.ORDER_EQUALITY=9;Blockly.JavaScript.ORDER_BITWISE_AND=10;Blockly.JavaScript.ORDER_BITWISE_XOR=11;Blockly.JavaScript.ORDER_BITWISE_OR=12;
9 | Blockly.JavaScript.ORDER_LOGICAL_AND=13;Blockly.JavaScript.ORDER_LOGICAL_OR=14;Blockly.JavaScript.ORDER_CONDITIONAL=15;Blockly.JavaScript.ORDER_ASSIGNMENT=16;Blockly.JavaScript.ORDER_COMMA=17;Blockly.JavaScript.ORDER_NONE=99;
10 | Blockly.JavaScript.init=function(){Blockly.JavaScript.definitions_=Object.create(null);Blockly.JavaScript.functionNames_=Object.create(null);if(Blockly.Variables){Blockly.JavaScript.variableDB_?Blockly.JavaScript.variableDB_.reset():Blockly.JavaScript.variableDB_=new Blockly.Names(Blockly.JavaScript.RESERVED_WORDS_);for(var a=[],b=Blockly.Variables.allVariables(),c=0;c",GTE:">="}[a.getFieldValue("OP")],c="=="==b||"!="==b?Blockly.JavaScript.ORDER_EQUALITY:Blockly.JavaScript.ORDER_RELATIONAL,d=Blockly.JavaScript.valueToCode(a,"A",c)||"0";a=Blockly.JavaScript.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
39 | Blockly.JavaScript.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"&&":"||",c="&&"==b?Blockly.JavaScript.ORDER_LOGICAL_AND:Blockly.JavaScript.ORDER_LOGICAL_OR,d=Blockly.JavaScript.valueToCode(a,"A",c);a=Blockly.JavaScript.valueToCode(a,"B",c);if(d||a){var e="&&"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]};
40 | Blockly.JavaScript.logic_negate=function(a){var b=Blockly.JavaScript.ORDER_LOGICAL_NOT;return["!"+(Blockly.JavaScript.valueToCode(a,"BOOL",b)||"true"),b]};Blockly.JavaScript.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.logic_null=function(a){return["null",Blockly.JavaScript.ORDER_ATOMIC]};
41 | Blockly.JavaScript.logic_ternary=function(a){var b=Blockly.JavaScript.valueToCode(a,"IF",Blockly.JavaScript.ORDER_CONDITIONAL)||"false",c=Blockly.JavaScript.valueToCode(a,"THEN",Blockly.JavaScript.ORDER_CONDITIONAL)||"null";a=Blockly.JavaScript.valueToCode(a,"ELSE",Blockly.JavaScript.ORDER_CONDITIONAL)||"null";return[b+" ? "+c+" : "+a,Blockly.JavaScript.ORDER_CONDITIONAL]};
42 | // Copyright 2012 Google Inc. Apache License 2.0
43 | Blockly.JavaScript.loops={};Blockly.JavaScript.controls_repeat=function(a){var b=Number(a.getFieldValue("TIMES")),c=Blockly.JavaScript.statementToCode(a,"DO"),c=Blockly.JavaScript.addLoopTrap(c,a.id);a=Blockly.JavaScript.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE);return"for (var "+a+" = 0; "+a+" < "+b+"; "+a+"++) {\n"+c+"}\n"};
44 | Blockly.JavaScript.controls_repeat_ext=function(a){var b=Blockly.JavaScript.valueToCode(a,"TIMES",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0",c=Blockly.JavaScript.statementToCode(a,"DO"),c=Blockly.JavaScript.addLoopTrap(c,a.id);a="";var d=Blockly.JavaScript.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE),e=b;b.match(/^\w+$/)||Blockly.isNumber(b)||(e=Blockly.JavaScript.variableDB_.getDistinctName("repeat_end",Blockly.Variables.NAME_TYPE),a+="var "+e+" = "+b+";\n");return a+("for (var "+
45 | d+" = 0; "+d+" < "+e+"; "+d+"++) {\n"+c+"}\n")};Blockly.JavaScript.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.JavaScript.valueToCode(a,"BOOL",b?Blockly.JavaScript.ORDER_LOGICAL_NOT:Blockly.JavaScript.ORDER_NONE)||"false",d=Blockly.JavaScript.statementToCode(a,"DO"),d=Blockly.JavaScript.addLoopTrap(d,a.id);b&&(c="!"+c);return"while ("+c+") {\n"+d+"}\n"};
46 | Blockly.JavaScript.controls_for=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0",d=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0",e=Blockly.JavaScript.valueToCode(a,"BY",Blockly.JavaScript.ORDER_ASSIGNMENT)||"1",f=Blockly.JavaScript.statementToCode(a,"DO"),f=Blockly.JavaScript.addLoopTrap(f,a.id);if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&
47 | Blockly.isNumber(e)){var g=parseFloat(c)<=parseFloat(d);a="for ("+b+" = "+c+"; "+b+(g?" <= ":" >= ")+d+"; "+b;b=Math.abs(parseFloat(e));a=(1==b?a+(g?"++":"--"):a+((g?" += ":" -= ")+b))+(") {\n"+f+"}\n")}else a="",g=c,c.match(/^\w+$/)||Blockly.isNumber(c)||(g=Blockly.JavaScript.variableDB_.getDistinctName(b+"_start",Blockly.Variables.NAME_TYPE),a+="var "+g+" = "+c+";\n"),c=d,d.match(/^\w+$/)||Blockly.isNumber(d)||(c=Blockly.JavaScript.variableDB_.getDistinctName(b+"_end",Blockly.Variables.NAME_TYPE),
48 | a+="var "+c+" = "+d+";\n"),d=Blockly.JavaScript.variableDB_.getDistinctName(b+"_inc",Blockly.Variables.NAME_TYPE),a+="var "+d+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+";\n"):a+("Math.abs("+e+");\n"),a+="if ("+g+" > "+c+") {\n",a+=Blockly.JavaScript.INDENT+d+" = -"+d+";\n",a+="}\n",a+="for ("+b+" = "+g+";\n "+d+" >= 0 ? "+b+" <= "+c+" : "+b+" >= "+c+";\n "+b+" += "+d+") {\n"+f+"}\n";return a};
49 | Blockly.JavaScript.controls_forEach=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_ASSIGNMENT)||"[]",d=Blockly.JavaScript.statementToCode(a,"DO"),d=Blockly.JavaScript.addLoopTrap(d,a.id);a=Blockly.JavaScript.variableDB_.getDistinctName(b+"_index",Blockly.Variables.NAME_TYPE);d=Blockly.JavaScript.INDENT+b+" = "+c+"["+a+"];\n"+d;return"for (var "+a+" in "+c+") {\n"+d+"}\n"};
50 | Blockly.JavaScript.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break;\n";case "CONTINUE":return"continue;\n"}throw"Unknown flow statement.";};
51 | // Copyright 2012 Google Inc. Apache License 2.0
52 | Blockly.JavaScript.math={};Blockly.JavaScript.math_number=function(a){return[parseFloat(a.getFieldValue("NUM")),Blockly.JavaScript.ORDER_ATOMIC]};
53 | Blockly.JavaScript.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.JavaScript.ORDER_ADDITION],MINUS:[" - ",Blockly.JavaScript.ORDER_SUBTRACTION],MULTIPLY:[" * ",Blockly.JavaScript.ORDER_MULTIPLICATION],DIVIDE:[" / ",Blockly.JavaScript.ORDER_DIVISION],POWER:[null,Blockly.JavaScript.ORDER_COMMA]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.JavaScript.valueToCode(a,"A",b)||"0";a=Blockly.JavaScript.valueToCode(a,"B",b)||"0";return c?[d+c+a,b]:["Math.pow("+d+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
54 | Blockly.JavaScript.math_single=function(a){var b=a.getFieldValue("OP"),c;if("NEG"==b)return a=Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_UNARY_NEGATION)||"0","-"==a[0]&&(a=" "+a),["-"+a,Blockly.JavaScript.ORDER_UNARY_NEGATION];a="SIN"==b||"COS"==b||"TAN"==b?Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_DIVISION)||"0":Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_NONE)||"0";switch(b){case "ABS":c="Math.abs("+a+")";break;case "ROOT":c="Math.sqrt("+
55 | a+")";break;case "LN":c="Math.log("+a+")";break;case "EXP":c="Math.exp("+a+")";break;case "POW10":c="Math.pow(10,"+a+")";break;case "ROUND":c="Math.round("+a+")";break;case "ROUNDUP":c="Math.ceil("+a+")";break;case "ROUNDDOWN":c="Math.floor("+a+")";break;case "SIN":c="Math.sin("+a+" / 180 * Math.PI)";break;case "COS":c="Math.cos("+a+" / 180 * Math.PI)";break;case "TAN":c="Math.tan("+a+" / 180 * Math.PI)"}if(c)return[c,Blockly.JavaScript.ORDER_FUNCTION_CALL];switch(b){case "LOG10":c="Math.log("+a+
56 | ") / Math.log(10)";break;case "ASIN":c="Math.asin("+a+") / Math.PI * 180";break;case "ACOS":c="Math.acos("+a+") / Math.PI * 180";break;case "ATAN":c="Math.atan("+a+") / Math.PI * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.JavaScript.ORDER_DIVISION]};
57 | Blockly.JavaScript.math_constant=function(a){return{PI:["Math.PI",Blockly.JavaScript.ORDER_MEMBER],E:["Math.E",Blockly.JavaScript.ORDER_MEMBER],GOLDEN_RATIO:["(1 + Math.sqrt(5)) / 2",Blockly.JavaScript.ORDER_DIVISION],SQRT2:["Math.SQRT2",Blockly.JavaScript.ORDER_MEMBER],SQRT1_2:["Math.SQRT1_2",Blockly.JavaScript.ORDER_MEMBER],INFINITY:["Infinity",Blockly.JavaScript.ORDER_ATOMIC]}[a.getFieldValue("CONSTANT")]};
58 | Blockly.JavaScript.math_number_property=function(a){var b=Blockly.JavaScript.valueToCode(a,"NUMBER_TO_CHECK",Blockly.JavaScript.ORDER_MODULUS)||"0",c=a.getFieldValue("PROPERTY"),d;if("PRIME"==c)return d=Blockly.JavaScript.provideFunction_("math_isPrime",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(n) {"," // https://en.wikipedia.org/wiki/Primality_test#Naive_methods"," if (n == 2 || n == 3) {"," return true;"," }"," // False if n is NaN, negative, is 1, or not whole."," // And false if n is divisible by 2 or 3.",
59 | " if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) {"," return false;"," }"," // Check all the numbers of form 6k +/- 1, up to sqrt(n)."," for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {"," if (n % (x - 1) == 0 || n % (x + 1) == 0) {"," return false;"," }"," }"," return true;","}"])+"("+b+")",[d,Blockly.JavaScript.ORDER_FUNCTION_CALL];switch(c){case "EVEN":d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=
60 | b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.JavaScript.valueToCode(a,"DIVISOR",Blockly.JavaScript.ORDER_MODULUS)||"0",d=b+" % "+a+" == 0"}return[d,Blockly.JavaScript.ORDER_EQUALITY]};Blockly.JavaScript.math_change=function(a){var b=Blockly.JavaScript.valueToCode(a,"DELTA",Blockly.JavaScript.ORDER_ADDITION)||"0";a=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);return a+" = (typeof "+a+" == 'number' ? "+a+" : 0) + "+b+";\n"};
61 | Blockly.JavaScript.math_round=Blockly.JavaScript.math_single;Blockly.JavaScript.math_trig=Blockly.JavaScript.math_single;
62 | Blockly.JavaScript.math_on_list=function(a){var b=a.getFieldValue("OP");switch(b){case "SUM":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_MEMBER)||"[]";a+=".reduce(function(x, y) {return x + y;})";break;case "MIN":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_COMMA)||"[]";a="Math.min.apply(null, "+a+")";break;case "MAX":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_COMMA)||"[]";a="Math.max.apply(null, "+a+")";break;case "AVERAGE":b=Blockly.JavaScript.provideFunction_("math_mean",
63 | ["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(myList) {"," return myList.reduce(function(x, y) {return x + y;}) / myList.length;","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "MEDIAN":b=Blockly.JavaScript.provideFunction_("math_median",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(myList) {"," var localList = myList.filter(function (x) {return typeof x == 'number';});"," if (!localList.length) return null;",
64 | " localList.sort(function(a, b) {return b - a;});"," if (localList.length % 2 == 0) {"," return (localList[localList.length / 2 - 1] + localList[localList.length / 2]) / 2;"," } else {"," return localList[(localList.length - 1) / 2];"," }","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "MODE":b=Blockly.JavaScript.provideFunction_("math_modes",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(values) {"," var modes = [];",
65 | " var counts = [];"," var maxCount = 0;"," for (var i = 0; i < values.length; i++) {"," var value = values[i];"," var found = false;"," var thisCount;"," for (var j = 0; j < counts.length; j++) {"," if (counts[j][0] === value) {"," thisCount = ++counts[j][1];"," found = true;"," break;"," }"," }"," if (!found) {"," counts.push([value, 1]);"," thisCount = 1;"," }"," maxCount = Math.max(thisCount, maxCount);"," }"," for (var j = 0; j < counts.length; j++) {",
66 | " if (counts[j][1] == maxCount) {"," modes.push(counts[j][0]);"," }"," }"," return modes;","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "STD_DEV":b=Blockly.JavaScript.provideFunction_("math_standard_deviation",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(numbers) {"," var n = numbers.length;"," if (!n) return null;"," var mean = numbers.reduce(function(x, y) {return x + y;}) / n;"," var variance = 0;",
67 | " for (var j = 0; j < n; j++) {"," variance += Math.pow(numbers[j] - mean, 2);"," }"," variance = variance / n;"," return Math.sqrt(variance);","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "RANDOM":b=Blockly.JavaScript.provideFunction_("math_random_list",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(list) {"," var x = Math.floor(Math.random() * list.length);"," return list[x];","}"]);a=Blockly.JavaScript.valueToCode(a,
68 | "LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;default:throw"Unknown operator: "+b;}return[a,Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_modulo=function(a){var b=Blockly.JavaScript.valueToCode(a,"DIVIDEND",Blockly.JavaScript.ORDER_MODULUS)||"0";a=Blockly.JavaScript.valueToCode(a,"DIVISOR",Blockly.JavaScript.ORDER_MODULUS)||"0";return[b+" % "+a,Blockly.JavaScript.ORDER_MODULUS]};
69 | Blockly.JavaScript.math_constrain=function(a){var b=Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_COMMA)||"0",c=Blockly.JavaScript.valueToCode(a,"LOW",Blockly.JavaScript.ORDER_COMMA)||"0";a=Blockly.JavaScript.valueToCode(a,"HIGH",Blockly.JavaScript.ORDER_COMMA)||"Infinity";return["Math.min(Math.max("+b+", "+c+"), "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
70 | Blockly.JavaScript.math_random_int=function(a){var b=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_COMMA)||"0";a=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_COMMA)||"0";return[Blockly.JavaScript.provideFunction_("math_random_int",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(a, b) {"," if (a > b) {"," // Swap a and b to ensure a is smaller."," var c = a;"," a = b;"," b = c;"," }"," return Math.floor(Math.random() * (b - a + 1) + a);",
71 | "}"])+"("+b+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_random_float=function(a){return["Math.random()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
72 | // Copyright 2012 Google Inc. Apache License 2.0
73 | Blockly.JavaScript.procedures={};
74 | Blockly.JavaScript.procedures_defreturn=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=Blockly.JavaScript.statementToCode(a,"STACK");Blockly.JavaScript.STATEMENT_PREFIX&&(c=Blockly.JavaScript.prefixLines(Blockly.JavaScript.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+"'"),Blockly.JavaScript.INDENT)+c);Blockly.JavaScript.INFINITE_LOOP_TRAP&&(c=Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var d=Blockly.JavaScript.valueToCode(a,
75 | "RETURN",Blockly.JavaScript.ORDER_NONE)||"";d&&(d=" return "+d+";\n");for(var e=[],f=0;f
2 |
3 |
4 |
40 |
41 |
42 |
76 |
77 |
78 |
79 |
83 |
84 |
85 |
86 |
87 |