diff --git a/.eslintignore b/.eslintignore
index c884c6b9e..792c074e6 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,6 +4,7 @@ gulpfile.js
/msg/*
/core/utils/global.js
/tests/blocks/*
+/tests/themes/*
/tests/compile/*
/tests/jsunit/*
/tests/generators/*
@@ -16,3 +17,4 @@ gulpfile.js
/appengine/*
/externs/*
/closure/*
+/scripts/gulpfiles/*
diff --git a/.travis.yml b/.travis.yml
index 643c96a63..287cf1f5a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,7 @@ node_js:
addons:
chrome: stable
firefox: latest
- # TODO (#2114): reenable osx build.
+ # TODO (#2114): re-enable osx build.
# - os: osx
# node_js: stable
# osx_image: xcode8.3
diff --git a/appengine/.gcloudignore b/appengine/.gcloudignore
index 83d812a47..8a3772bae 100644
--- a/appengine/.gcloudignore
+++ b/appengine/.gcloudignore
@@ -1,23 +1,24 @@
# Do not upload these files.
.*
-deploy
*.soy
-static/appengine/
-static/closure/
-static/demos/plane/soy/*.jar
-static/demos/plane/xlf/
-static/externs/
-static/i18n/
-static/msg/json/
-static/node_modules/
-static/package/
-static/theme_scripts/
-static/typings/
+*.komodoproject
+/deploy
+/static/appengine/
+/static/closure/
+/static/demos/plane/soy/*.jar
+/static/demos/plane/xlf/
+/static/externs/
+/static/i18n/
+/static/msg/json/
+/static/node_modules/
+/static/package/
+/static/theme_scripts/
+/static/typings/
-static/build.py
-static/gulpfile.js
-static/jsconfig.json
-static/LICENSE
-static/package-lock.json
-static/package.json
-static/README.md
+/static/build.py
+/static/gulpfile.js
+/static/jsconfig.json
+/static/LICENSE
+/static/package-lock.json
+/static/package.json
+/static/README.md
diff --git a/appengine/README.txt b/appengine/README.txt
index 6ba262bba..caaa8e7b7 100644
--- a/appengine/README.txt
+++ b/appengine/README.txt
@@ -11,12 +11,13 @@ structure:
blockly/
|- app.yaml
+ |- deploy
|- index.yaml
- |- index_redirect.py
+ |- main.py
|- README.txt
+ |- requirements.txt
|- storage.js
|- storage.py
- |- closure-library/ (Optional)
`- static/
|- blocks/
|- core/
@@ -26,7 +27,7 @@ blockly/
|- msg/
|- tests/
|- blockly_compressed.js
- |- blockly_uncompressed.js (Optional)
+ |- blockly_uncompressed.js
|- blocks_compressed.js
|- dart_compressed.js
|- javascript_compressed.js
@@ -34,11 +35,8 @@ blockly/
|- php_compressed.js
`- python_compressed.js
-Instructions for fetching the optional Closure library may be found here:
- https://developers.google.com/blockly/guides/modify/web/closure
-
Go to https://appengine.google.com/ and create your App Engine application.
-Modify the 'application' name of app.yaml to your App Engine application name.
+Modify the 'PROJECT' name in the 'deploy' file to your App Engine application name.
Finally, upload this directory structure to your App Engine account,
-wait a minute, then go to http://YOURAPPNAME.appspot.com/
+then go to http://YOURAPPNAME.appspot.com/
diff --git a/appengine/storage.js b/appengine/storage.js
index dc62a0035..82a74052a 100644
--- a/appengine/storage.js
+++ b/appengine/storage.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/blockly_compressed.js b/blockly_compressed.js
index c21c79d82..08b305a36 100644
--- a/blockly_compressed.js
+++ b/blockly_compressed.js
@@ -1,8 +1,7 @@
// Do not edit this file; automatically generated by gulp.
-'use strict';var Blockly={constants:{},LINE_MODE_MULTIPLIER:40,PAGE_MODE_MULTIPLIER:125,DRAG_RADIUS:5,FLYOUT_DRAG_RADIUS:10,SNAP_RADIUS:28};Blockly.CONNECTING_SNAP_RADIUS=Blockly.SNAP_RADIUS;Blockly.CURRENT_CONNECTION_PREFERENCE=8;Blockly.INSERTION_MARKER_COLOUR="#000000";Blockly.BUMP_DELAY=250;Blockly.BUMP_RANDOMNESS=10;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.DRAG_STACK=!0;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;
-Blockly.SPRITE={width:96,height:124,url:"sprites.png"};Blockly.INPUT_VALUE=1;Blockly.OUTPUT_VALUE=2;Blockly.NEXT_STATEMENT=3;Blockly.PREVIOUS_STATEMENT=4;Blockly.DUMMY_INPUT=5;Blockly.ALIGN_LEFT=-1;Blockly.ALIGN_CENTRE=0;Blockly.ALIGN_RIGHT=1;Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE]=Blockly.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE]=Blockly.INPUT_VALUE;
-Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT]=Blockly.PREVIOUS_STATEMENT;Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT]=Blockly.NEXT_STATEMENT;Blockly.TOOLBOX_AT_TOP=0;Blockly.TOOLBOX_AT_BOTTOM=1;Blockly.TOOLBOX_AT_LEFT=2;Blockly.TOOLBOX_AT_RIGHT=3;Blockly.DELETE_AREA_NONE=null;Blockly.DELETE_AREA_TRASH=1;Blockly.DELETE_AREA_TOOLBOX=2;Blockly.VARIABLE_CATEGORY_NAME="VARIABLE";Blockly.VARIABLE_DYNAMIC_CATEGORY_NAME="VARIABLE_DYNAMIC";Blockly.PROCEDURE_CATEGORY_NAME="PROCEDURE";
-Blockly.RENAME_VARIABLE_ID="RENAME_VARIABLE_ID";Blockly.DELETE_VARIABLE_ID="DELETE_VARIABLE_ID";Blockly.utils={};Blockly.utils.global=function(){return"object"===typeof self?self:"object"===typeof window?window:"object"===typeof global?global:this}();Blockly.Msg={};Blockly.utils.global.Blockly||(Blockly.utils.global.Blockly={});Blockly.utils.global.Blockly.Msg||(Blockly.utils.global.Blockly.Msg=Blockly.Msg);Blockly.utils.colour={};
+'use strict';var Blockly={constants:{},LINE_MODE_MULTIPLIER:40,PAGE_MODE_MULTIPLIER:125,DRAG_RADIUS:5,FLYOUT_DRAG_RADIUS:10,SNAP_RADIUS:28};Blockly.CONNECTING_SNAP_RADIUS=Blockly.SNAP_RADIUS;Blockly.CURRENT_CONNECTION_PREFERENCE=8;Blockly.BUMP_DELAY=250;Blockly.BUMP_RANDOMNESS=10;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.DRAG_STACK=!0;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;Blockly.SPRITE={width:96,height:124,url:"sprites.png"};Blockly.INPUT_VALUE=1;
+Blockly.OUTPUT_VALUE=2;Blockly.NEXT_STATEMENT=3;Blockly.PREVIOUS_STATEMENT=4;Blockly.DUMMY_INPUT=5;Blockly.ALIGN_LEFT=-1;Blockly.ALIGN_CENTRE=0;Blockly.ALIGN_RIGHT=1;Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE]=Blockly.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE]=Blockly.INPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT]=Blockly.PREVIOUS_STATEMENT;
+Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT]=Blockly.NEXT_STATEMENT;Blockly.TOOLBOX_AT_TOP=0;Blockly.TOOLBOX_AT_BOTTOM=1;Blockly.TOOLBOX_AT_LEFT=2;Blockly.TOOLBOX_AT_RIGHT=3;Blockly.DELETE_AREA_NONE=null;Blockly.DELETE_AREA_TRASH=1;Blockly.DELETE_AREA_TOOLBOX=2;Blockly.VARIABLE_CATEGORY_NAME="VARIABLE";Blockly.VARIABLE_DYNAMIC_CATEGORY_NAME="VARIABLE_DYNAMIC";Blockly.PROCEDURE_CATEGORY_NAME="PROCEDURE";Blockly.RENAME_VARIABLE_ID="RENAME_VARIABLE_ID";Blockly.DELETE_VARIABLE_ID="DELETE_VARIABLE_ID";Blockly.utils={};Blockly.utils.global=function(){return"object"===typeof self?self:"object"===typeof window?window:"object"===typeof global?global:this}();Blockly.Msg={};Blockly.utils.global.Blockly||(Blockly.utils.global.Blockly={});Blockly.utils.global.Blockly.Msg||(Blockly.utils.global.Blockly.Msg=Blockly.Msg);Blockly.utils.colour={};
Blockly.utils.colour.parse=function(a){a=String(a).toLowerCase().trim();var b=Blockly.utils.colour.names[a];if(b)return b;b="0x"==a.substring(0,2)?"#"+a.substring(2):a;b="#"==b[0]?b:"#"+b;if(/^#[0-9a-f]{6}$/.test(b))return b;if(/^#[0-9a-f]{3}$/.test(b))return["#",b[1],b[1],b[2],b[2],b[3],b[3]].join("");var c=a.match(/^(?:rgb)?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);return c&&(a=Number(c[1]),b=Number(c[2]),c=Number(c[3]),0<=a&&256>a&&0<=b&&256>b&&0<=c&&256>c)?Blockly.utils.colour.rgbToHex(a,b,
c):null};Blockly.utils.colour.rgbToHex=function(a,b,c){b=a<<16|b<<8|c;return 16>a?"#"+(16777216|b).toString(16).substr(1):"#"+b.toString(16)};Blockly.utils.colour.hexToRgb=function(a){a=Blockly.utils.colour.parse(a);if(!a)return[0,0,0];a=parseInt(a.substr(1),16);return[a>>16,a>>8&255,a&255]};
Blockly.utils.colour.hsvToHex=function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=c;else{var g=Math.floor(a/60),h=a/60-g;a=c*(1-b);var k=c*(1-b*h);b=c*(1-b*(1-h));switch(g){case 1:d=k;e=c;f=a;break;case 2:d=a;e=c;f=b;break;case 3:d=a;e=k;f=c;break;case 4:d=b;e=a;f=c;break;case 5:d=c;e=a;f=k;break;case 6:case 0:d=c,e=b,f=a}}return Blockly.utils.colour.rgbToHex(Math.floor(d),Math.floor(e),Math.floor(f))};
@@ -46,15 +45,18 @@ Blockly.Events.fromJson=function(a,b){switch(a.type){case Blockly.Events.CREATE:
new Blockly.Events.VarRename(null,"");break;case Blockly.Events.UI:c=new Blockly.Events.Ui(null,"","","");break;case Blockly.Events.COMMENT_CREATE:c=new Blockly.Events.CommentCreate(null);break;case Blockly.Events.COMMENT_CHANGE:c=new Blockly.Events.CommentChange(null,"","");break;case Blockly.Events.COMMENT_MOVE:c=new Blockly.Events.CommentMove(null);break;case Blockly.Events.COMMENT_DELETE:c=new Blockly.Events.CommentDelete(null);break;case Blockly.Events.FINISHED_LOADING:c=new Blockly.Events.FinishedLoading(b);
break;default:throw Error("Unknown event type.");}c.fromJson(a);c.workspaceId=b.id;return c};
Blockly.Events.disableOrphans=function(a){if((a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE)&&a.workspaceId){var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId)){var c=a.getParent();if(c&&c.isEnabled())for(b=a.getDescendants(!1),a=0;c=b[a];a++)c.setEnabled(!0);else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setEnabled(!1),a=a.getNextBlock();while(a)}}}};Blockly.Events.Abstract=function(){this.workspaceId=void 0;this.group=Blockly.Events.getGroup();this.recordUndo=Blockly.Events.recordUndo};Blockly.Events.Abstract.prototype.toJson=function(){var a={type:this.type};this.group&&(a.group=this.group);return a};Blockly.Events.Abstract.prototype.fromJson=function(a){this.group=a.group};Blockly.Events.Abstract.prototype.isNull=function(){return!1};Blockly.Events.Abstract.prototype.run=function(a){};
-Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){if(this.workspaceId)var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.utils.object={};Blockly.utils.object.inherits=function(a,b){a.superClass_=b.prototype;a.prototype=Object.create(b.prototype);a.prototype.constructor=a};Blockly.utils.object.mixin=function(a,b){for(var c in b)a[c]=b[c]};Blockly.utils.object.values=function(a){return Object.values?Object.values(a):Object.keys(a).map(function(b){return a[b]})};Blockly.Events.Ui=function(a,b,c,d){Blockly.Events.Ui.superClass_.constructor.call(this);this.blockId=a?a.id:null;this.workspaceId=a?a.workspace.id:void 0;this.element=b;this.oldValue=c;this.newValue=d;this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.Ui,Blockly.Events.Abstract);Blockly.Events.Ui.prototype.type=Blockly.Events.UI;
+Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){if(this.workspaceId)var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.utils.object={};Blockly.utils.object.inherits=function(a,b){a.superClass_=b.prototype;a.prototype=Object.create(b.prototype);a.prototype.constructor=a};Blockly.utils.object.mixin=function(a,b){for(var c in b)a[c]=b[c]};Blockly.utils.object.deepMerge=function(a,b){for(var c in b)a[c]="object"===typeof b[c]?Blockly.utils.object.deepMerge(a[c]||Object.create(null),b[c]):b[c];return a};Blockly.utils.object.values=function(a){return Object.values?Object.values(a):Object.keys(a).map(function(b){return a[b]})};Blockly.Events.Ui=function(a,b,c,d){Blockly.Events.Ui.superClass_.constructor.call(this);this.blockId=a?a.id:null;this.workspaceId=a?a.workspace.id:void 0;this.element=b;this.oldValue=c;this.newValue=d;this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.Ui,Blockly.Events.Abstract);Blockly.Events.Ui.prototype.type=Blockly.Events.UI;
Blockly.Events.Ui.prototype.toJson=function(){var a=Blockly.Events.Ui.superClass_.toJson.call(this);a.element=this.element;void 0!==this.newValue&&(a.newValue=this.newValue);this.blockId&&(a.blockId=this.blockId);return a};Blockly.Events.Ui.prototype.fromJson=function(a){Blockly.Events.Ui.superClass_.fromJson.call(this,a);this.element=a.element;this.newValue=a.newValue;this.blockId=a.blockId};Blockly.utils.dom={};Blockly.utils.dom.SVG_NS="http://www.w3.org/2000/svg";Blockly.utils.dom.HTML_NS="http://www.w3.org/1999/xhtml";Blockly.utils.dom.XLINK_NS="http://www.w3.org/1999/xlink";Blockly.utils.dom.Node={ELEMENT_NODE:1,TEXT_NODE:3,COMMENT_NODE:8,DOCUMENT_POSITION_CONTAINED_BY:16};Blockly.utils.dom.cacheWidths_=null;Blockly.utils.dom.cacheReference_=0;Blockly.utils.dom.canvasContext_=null;
Blockly.utils.dom.createSvgElement=function(a,b,c){a=document.createElementNS(Blockly.utils.dom.SVG_NS,a);for(var d in b)a.setAttribute(d,b[d]);document.body.runtimeStyle&&(a.runtimeStyle=a.currentStyle=a.style);c&&c.appendChild(a);return a};Blockly.utils.dom.addClass=function(a,b){var c=a.getAttribute("class")||"";if(-1!=(" "+c+" ").indexOf(" "+b+" "))return!1;c&&(c+=" ");a.setAttribute("class",c+b);return!0};
Blockly.utils.dom.removeClass=function(a,b){var c=a.getAttribute("class");if(-1==(" "+c+" ").indexOf(" "+b+" "))return!1;c=c.split(/\s+/);for(var d=0;db||b>this.getChildCount())throw Error(Blockly.Component.Error.CHILD_INDEX_OUT_OF_BOUNDS);this.childIndex_[a.getId()]=a;if(a.getParent()==this){var d=this.children_.indexOf(a);-1>>/g,a),a=document.createElement("style"),a.id="blockly-common-style",c=document.createTextNode(c),a.appendChild(c),document.head.insertBefore(a,document.head.firstChild))}};Blockly.Css.setCursor=function(a){console.warn("Deprecated call to Blockly.Css.setCursor. See https://github.com/google/blockly/issues/981 for context")};
@@ -77,25 +79,25 @@ Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;",
"border-top-left-radius: 4px;","border-color: inherit;","}",".blocklyArrowBottom {","border-bottom: 1px solid;","border-right: 1px solid;","border-bottom-right-radius: 4px;","border-color: inherit;","}",".blocklyResizeSE {","cursor: se-resize;","fill: #aaa;","}",".blocklyResizeSW {","cursor: sw-resize;","fill: #aaa;","}",".blocklyResizeLine {","stroke: #515A5A;","stroke-width: 1;","}",".blocklyHighlightedConnectionPath {","fill: none;","stroke: #fc3;","stroke-width: 4px;","}",".blocklyPathLight {",
"fill: none;","stroke-linecap: round;","stroke-width: 1;","}",".blocklySelected>.blocklyPathLight {","display: none;","}",".blocklyDraggable {",'cursor: url("<<>>/handopen.cur"), auto;',"cursor: grab;","cursor: -webkit-grab;","}",".blocklyDragging {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyDraggable:active {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyBlockDragSurface .blocklyDraggable {",
'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyDragging.blocklyDraggingDelete {",'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {","fill-opacity: .8;","stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {","display: none;","}",".blocklyDisabled>.blocklyPath {","fill-opacity: .5;","stroke-opacity: .5;","}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {",
-"display: none;","}",".blocklyInsertionMarker>.blocklyPath,",".blocklyInsertionMarker>.blocklyPathLight,",".blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: .2;","stroke: none","}",".blocklyMultilineText {","font-family: monospace;","}",".blocklyNonEditableText>text {","pointer-events: none;","}",".blocklyBubbleText {","fill: #000;","}",".blocklyFlyout {","position: absolute;","z-index: 20;","}",".blocklyText text {","cursor: default;","}",".blocklySvg text, .blocklyBlockDragSurface text {",
-"user-select: none;","-ms-user-select: none;","-webkit-user-select: none;","cursor: inherit;","}",".blocklyHidden {","display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {","display: block;","}",".blocklyIconGroup {","cursor: default;","}",".blocklyIconGroup:not(:hover),",".blocklyIconGroupReadonly {","opacity: .6;","}",".blocklyIconShape {","fill: #00f;","stroke: #fff;","stroke-width: 1px;","}",".blocklyIconSymbol {","fill: #fff;","}",".blocklyMinimalBody {","margin: 0;","padding: 0;",
-"}",".blocklyHtmlInput {","border: none;","border-radius: 4px;","height: 100%;","margin: 0;","outline: none;","padding: 0;","width: 100%;","text-align: center;","display: block;","box-sizing: border-box;","}",".blocklyHtmlInput::-ms-clear {","display: none;","}",".blocklyMainBackground {","stroke-width: 1;","stroke: #c6c6c6;","}",".blocklyMutatorBackground {","fill: #fff;","stroke: #ddd;","stroke-width: 1;","}",".blocklyFlyoutBackground {","fill: #ddd;","fill-opacity: .8;","}",".blocklyMainWorkspaceScrollbar {",
-"z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",
-".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyContextMenu {","border-radius: 4px;","max-height: 100%;","}",".blocklyDropdownMenu {","border-radius: 2px;","padding: 0 !important;","}",".blocklyWidgetDiv .blocklyDropdownMenu .goog-menuitem,",".blocklyDropDownDiv .blocklyDropdownMenu .goog-menuitem {","padding-left: 28px;","}",".blocklyWidgetDiv .blocklyDropdownMenu .goog-menuitem.goog-menuitem-rtl,",".blocklyDropDownDiv .blocklyDropdownMenu .goog-menuitem.goog-menuitem-rtl {",
-"padding-left: 5px;","padding-right: 28px;","}",".blocklyVerticalMarker {","stroke-width: 3px;","fill: rgba(255,255,255,.5);","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon,",".blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<>>/sprites.png) no-repeat -48px -16px;","}",".blocklyWidgetDiv .goog-menu {","background: #fff;",
-"border-color: transparent;","border-style: solid;","border-width: 1px;","cursor: default;","font: normal 13px Arial, sans-serif;","margin: 0;","outline: none;","padding: 4px 0;","position: absolute;","overflow-y: auto;","overflow-x: hidden;","max-height: 100%;","z-index: 20000;","box-shadow: 0px 0px 3px 1px rgba(0,0,0,.3);","}",".blocklyWidgetDiv .goog-menu.focused {","box-shadow: 0px 0px 6px 1px rgba(0,0,0,.3);","}",".blocklyDropDownDiv .goog-menu {","cursor: default;",'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;',
+"display: none;","}",".blocklyInsertionMarker>.blocklyPath,",".blocklyInsertionMarker>.blocklyPathLight,",".blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: .2;","stroke: none","}",".blocklyMultilineText {","font-family: monospace;","}",".blocklyNonEditableText>text {","pointer-events: none;","}",".blocklyFlyout {","position: absolute;","z-index: 20;","}",".blocklyText text {","cursor: default;","}",".blocklySvg text, .blocklyBlockDragSurface text {","user-select: none;","-ms-user-select: none;",
+"-webkit-user-select: none;","cursor: inherit;","}",".blocklyHidden {","display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {","display: block;","}",".blocklyIconGroup {","cursor: default;","}",".blocklyIconGroup:not(:hover),",".blocklyIconGroupReadonly {","opacity: .6;","}",".blocklyIconShape {","fill: #00f;","stroke: #fff;","stroke-width: 1px;","}",".blocklyIconSymbol {","fill: #fff;","}",".blocklyMinimalBody {","margin: 0;","padding: 0;","}",".blocklyHtmlInput {","border: none;","border-radius: 4px;",
+"height: 100%;","margin: 0;","outline: none;","padding: 0;","width: 100%;","text-align: center;","display: block;","box-sizing: border-box;","}",".blocklyHtmlInput::-ms-clear {","display: none;","}",".blocklyMainBackground {","stroke-width: 1;","stroke: #c6c6c6;","}",".blocklyMutatorBackground {","fill: #fff;","stroke: #ddd;","stroke-width: 1;","}",".blocklyFlyoutBackground {","fill: #ddd;","fill-opacity: .8;","}",".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;",
+"}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyFlyout .blocklyScrollbarHandle:hover {",
+"fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyContextMenu {","border-radius: 4px;","max-height: 100%;","}",".blocklyDropdownMenu {","border-radius: 2px;","padding: 0 !important;","}",".blocklyWidgetDiv .blocklyDropdownMenu .goog-menuitem,",".blocklyDropDownDiv .blocklyDropdownMenu .goog-menuitem {","padding-left: 28px;","}",".blocklyWidgetDiv .blocklyDropdownMenu .goog-menuitem.goog-menuitem-rtl,",".blocklyDropDownDiv .blocklyDropdownMenu .goog-menuitem.goog-menuitem-rtl {",
+"padding-left: 5px;","padding-right: 28px;","}",".blocklyVerticalMarker {","stroke-width: 3px;","fill: rgba(255,255,255,.5);","pointer-events: none","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon,",".blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<>>/sprites.png) no-repeat -48px -16px;","}",".blocklyWidgetDiv .goog-menu {",
+"background: #fff;","border-color: transparent;","border-style: solid;","border-width: 1px;","cursor: default;","font: normal 13px Arial, sans-serif;","margin: 0;","outline: none;","padding: 4px 0;","position: absolute;","overflow-y: auto;","overflow-x: hidden;","max-height: 100%;","z-index: 20000;","box-shadow: 0px 0px 3px 1px rgba(0,0,0,.3);","}",".blocklyWidgetDiv .goog-menu.focused {","box-shadow: 0px 0px 6px 1px rgba(0,0,0,.3);","}",".blocklyDropDownDiv .goog-menu {","cursor: default;",'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;',
"outline: none;","z-index: 20000;","}",".blocklyWidgetDiv .goog-menuitem,",".blocklyDropDownDiv .goog-menuitem {","color: #000;","font: normal 13px Arial, sans-serif;","list-style: none;","margin: 0;","min-width: 7em;","border: none;","padding: 6px 15px;","white-space: nowrap;","cursor: pointer;","}",".blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem,",".blocklyWidgetDiv .goog-menu-noicon .goog-menuitem,",".blocklyDropDownDiv .goog-menu-nocheckbox .goog-menuitem,",".blocklyDropDownDiv .goog-menu-noicon .goog-menuitem {",
"padding-left: 12px;","}",".blocklyWidgetDiv .goog-menuitem-content,",".blocklyDropDownDiv .goog-menuitem-content {","font-family: Arial, sans-serif;","font-size: 13px;","}",".blocklyWidgetDiv .goog-menuitem-content {","color: #000;","}",".blocklyDropDownDiv .goog-menuitem-content {","color: #000;","}",".blocklyWidgetDiv .goog-menuitem-disabled,",".blocklyDropDownDiv .goog-menuitem-disabled {","cursor: inherit;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content,",".blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-content {",
"color: #ccc !important;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon,",".blocklyDropDownDiv .goog-menuitem-disabled .goog-menuitem-icon {","opacity: .3;","filter: alpha(opacity=30);","}",".blocklyWidgetDiv .goog-menuitem-highlight ,",".blocklyDropDownDiv .goog-menuitem-highlight {","background-color: rgba(0,0,0,.1);","}",".blocklyWidgetDiv .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-icon,",".blocklyDropDownDiv .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-menuitem-icon {",
"background-repeat: no-repeat;","height: 16px;","left: 6px;","position: absolute;","right: auto;","vertical-align: middle;","width: 16px;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon,",".blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-icon {","left: auto;","right: 6px;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon,",
".blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon {","position: static;","float: left;","margin-left: -24px;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon,",".blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyDropDownDiv .goog-menuitem-rtl .goog-menuitem-icon {","float: right;","margin-right: -24px;","}",".blocklyComputeCanvas {",
-"position: absolute;","width: 0;","height: 0;","}",".blocklyNoPointerEvents {","pointer-events: none;","}"];Blockly.utils.math={};Blockly.utils.math.toRadians=function(a){return a*Math.PI/180};Blockly.utils.math.toDegrees=function(a){return 180*a/Math.PI};Blockly.utils.math.clamp=function(a,b,c){if(ce.top?Blockly.DropDownDiv.getPositionAboveMetrics_(c,d,e,f):b+f.heightdocument.documentElement.clientTop?Blockly.DropDownDiv.getPositionAboveMetrics_(c,
d,e,f):Blockly.DropDownDiv.getPositionTopOfPageMetrics_(a,e,f)};Blockly.DropDownDiv.getPositionBelowMetrics_=function(a,b,c,d){a=Blockly.DropDownDiv.getPositionX(a,c.left,c.right,d.width);return{initialX:a.divX,initialY:b,finalX:a.divX,finalY:b+Blockly.DropDownDiv.PADDING_Y,arrowX:a.arrowX,arrowY:-(Blockly.DropDownDiv.ARROW_SIZE/2+Blockly.DropDownDiv.BORDER_SIZE),arrowAtTop:!0,arrowVisible:!0}};
@@ -104,13 +106,15 @@ Blockly.DropDownDiv.getPositionTopOfPageMetrics_=function(a,b,c){a=Blockly.DropD
Blockly.DropDownDiv.isVisible=function(){return!!Blockly.DropDownDiv.owner_};Blockly.DropDownDiv.hideIfOwner=function(a,b){return Blockly.DropDownDiv.owner_===a?(b?Blockly.DropDownDiv.hideWithoutAnimation():Blockly.DropDownDiv.hide(),!0):!1};
Blockly.DropDownDiv.hide=function(){var a=Blockly.DropDownDiv.DIV_;a.style.transform="translate(0, 0)";a.style.opacity=0;Blockly.DropDownDiv.animateOutTimer_=setTimeout(function(){Blockly.DropDownDiv.hideWithoutAnimation()},1E3*Blockly.DropDownDiv.ANIMATION_TIME);Blockly.DropDownDiv.onHide_&&(Blockly.DropDownDiv.onHide_(),Blockly.DropDownDiv.onHide_=null)};
Blockly.DropDownDiv.hideWithoutAnimation=function(){if(Blockly.DropDownDiv.isVisible()){Blockly.DropDownDiv.animateOutTimer_&&clearTimeout(Blockly.DropDownDiv.animateOutTimer_);var a=Blockly.DropDownDiv.DIV_;a.style.transform="";a.style.left="";a.style.top="";a.style.opacity=0;a.style.display="none";a.style.backgroundColor="";a.style.borderColor="";Blockly.DropDownDiv.onHide_&&(Blockly.DropDownDiv.onHide_(),Blockly.DropDownDiv.onHide_=null);Blockly.DropDownDiv.clearContent();Blockly.DropDownDiv.owner_=
-null;Blockly.DropDownDiv.rendererClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.rendererClassName_),Blockly.DropDownDiv.rendererClassName_=null);Blockly.DropDownDiv.themeClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.themeClassName_),Blockly.DropDownDiv.themeClassName_=null);Blockly.getMainWorkspace().markFocused()}};
+null;Blockly.DropDownDiv.rendererClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.rendererClassName_),Blockly.DropDownDiv.rendererClassName_="");Blockly.DropDownDiv.themeClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.themeClassName_),Blockly.DropDownDiv.themeClassName_="");Blockly.getMainWorkspace().markFocused()}};
Blockly.DropDownDiv.positionInternal_=function(a,b,c,d){a=Blockly.DropDownDiv.getPositionMetrics_(a,b,c,d);a.arrowVisible?(Blockly.DropDownDiv.arrow_.style.display="",Blockly.DropDownDiv.arrow_.style.transform="translate("+a.arrowX+"px,"+a.arrowY+"px) rotate(45deg)",Blockly.DropDownDiv.arrow_.setAttribute("class",a.arrowAtTop?"blocklyDropDownArrow blocklyArrowTop":"blocklyDropDownArrow blocklyArrowBottom")):Blockly.DropDownDiv.arrow_.style.display="none";b=Math.floor(a.initialX);c=Math.floor(a.initialY);
d=Math.floor(a.finalX);var e=Math.floor(a.finalY),f=Blockly.DropDownDiv.DIV_;f.style.left=b+"px";f.style.top=c+"px";f.style.display="block";f.style.opacity=1;f.style.transform="translate("+(d-b)+"px,"+(e-c)+"px)";return a.arrowAtTop};
Blockly.DropDownDiv.repositionForWindowResize=function(){if(Blockly.DropDownDiv.owner_){var a=Blockly.DropDownDiv.owner_,b=Blockly.DropDownDiv.owner_.getSourceBlock();a=Blockly.DropDownDiv.positionToField_?Blockly.DropDownDiv.getScaledBboxOfField_(a):Blockly.DropDownDiv.getScaledBboxOfBlock_(b);b=a.left+(a.right-a.left)/2;Blockly.DropDownDiv.positionInternal_(b,a.bottom,b,a.top)}else Blockly.DropDownDiv.hide()};Blockly.Grid=function(a,b){this.gridPattern_=a;this.spacing_=b.spacing;this.length_=b.length;this.line2_=(this.line1_=a.firstChild)&&this.line1_.nextSibling;this.snapToGrid_=b.snap};Blockly.Grid.prototype.scale_=1;Blockly.Grid.prototype.dispose=function(){this.gridPattern_=null};Blockly.Grid.prototype.shouldSnap=function(){return this.snapToGrid_};Blockly.Grid.prototype.getSpacing=function(){return this.spacing_};Blockly.Grid.prototype.getPatternId=function(){return this.gridPattern_.id};
Blockly.Grid.prototype.update=function(a){this.scale_=a;var b=this.spacing_*a||100;this.gridPattern_.setAttribute("width",b);this.gridPattern_.setAttribute("height",b);b=Math.floor(this.spacing_/2)+.5;var c=b-this.length_/2,d=b+this.length_/2;b*=a;c*=a;d*=a;this.setLineAttributes_(this.line1_,a,c,d,b,b);this.setLineAttributes_(this.line2_,a,b,b,c,d)};
Blockly.Grid.prototype.setLineAttributes_=function(a,b,c,d,e,f){a&&(a.setAttribute("stroke-width",b),a.setAttribute("x1",c),a.setAttribute("y1",e),a.setAttribute("x2",d),a.setAttribute("y2",f))};Blockly.Grid.prototype.moveTo=function(a,b){this.gridPattern_.setAttribute("x",a);this.gridPattern_.setAttribute("y",b);(Blockly.utils.userAgent.IE||Blockly.utils.userAgent.EDGE)&&this.update(this.scale_)};
-Blockly.Grid.createDom=function(a,b,c){a=Blockly.utils.dom.createSvgElement("pattern",{id:"blocklyGridPattern"+a,patternUnits:"userSpaceOnUse"},c);0]*[^/])?>[^<]*)\n([^<]*<\/)/;do{var c=a;a=a.replace(b,"$1
$2")}while(a!=c);return a};Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1$2>");return a.replace(/^\n/,"")};
+Blockly.Xml.domToText=function(a){a=Blockly.utils.xml.domToText(a);var b=/(<[^/](?:[^>]*[^/])?>[^<]*)\n([^<]*<\/)/;do{var c=a;a=a.replace(b,"$1
$2")}while(a!=c);return a.replace(/<(\w+)([^<]*)\/>/g,"<$1$2>$1>")};
+Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1$2>");return a.replace(/^\n/,"")};
Blockly.Xml.textToDom=function(a){var b=Blockly.utils.xml.textToDomDocument(a);if(!b||!b.documentElement||b.getElementsByTagName("parsererror").length)throw Error("textToDom was unable to parse: "+a);return b.documentElement};Blockly.Xml.clearWorkspaceAndLoadFromXml=function(a,b){b.setResizesEnabled(!1);b.clear();a=Blockly.Xml.domToWorkspace(a,b);b.setResizesEnabled(!0);return a};
Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];Blockly.utils.dom.startTextWidthCache();var e=Blockly.Events.getGroup();e||Blockly.Events.setGroup(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var f=!0;try{for(var g=0,h;h=a.childNodes[g];g++){var k=h.nodeName.toLowerCase(),l=h;if("block"==k||"shadow"==k&&!Blockly.Events.recordUndo){var m=
Blockly.Xml.domToBlock(l,b);c.push(m.id);var n=l.hasAttribute("x")?parseInt(l.getAttribute("x"),10):10,p=l.hasAttribute("y")?parseInt(l.getAttribute("y"),10):10;isNaN(n)||isNaN(p)||m.moveBy(b.RTL?d-n:n,p);f=!1}else{if("shadow"==k)throw TypeError("Shadow block cannot be a top-level block.");if("comment"==k)b.rendered?Blockly.WorkspaceCommentSvg?Blockly.WorkspaceCommentSvg.fromXml(l,b,d):console.warn("Missing require for Blockly.WorkspaceCommentSvg, ignoring workspace comment."):Blockly.WorkspaceComment?
@@ -166,10 +171,10 @@ break;case "next":h&&c.nextConnection&&c.nextConnection.setShadowDom(h);if(f){if
c.setInputsInline("true"==e);(e=a.getAttribute("disabled"))&&c.setEnabled("true"!=e&&"disabled"!=e);(e=a.getAttribute("deletable"))&&c.setDeletable("true"==e);(e=a.getAttribute("movable"))&&c.setMovable("true"==e);(e=a.getAttribute("editable"))&&c.setEditable("true"==e);(e=a.getAttribute("collapsed"))&&c.setCollapsed("true"==e);if("shadow"==a.nodeName.toLowerCase()){a=c.getChildren(!1);for(e=0;b=a[e];e++)if(!b.isShadow())throw TypeError("Shadow block not allowed non-shadow child.");if(c.getVarModels().length)throw TypeError("Shadow blocks cannot have variable references.");
c.setShadow(!0)}return c};Blockly.Xml.domToField_=function(a,b,c){var d=a.getField(b);d?d.fromXml(c):console.warn("Ignoring non-existent field "+b+" in block "+a.type)};Blockly.Xml.deleteNext=function(a){for(var b=0,c;c=a.childNodes[b];b++)if("next"==c.nodeName.toLowerCase()){a.removeChild(c);break}};Blockly.Options=function(a){var b=!!a.readOnly;if(b)var c=null,d=!1,e=!1,f=!1,g=!1,h=!1,k=!1;else{c=Blockly.Options.parseToolboxTree(a.toolbox||null);d=!(!c||!c.getElementsByTagName("category").length);e=a.trashcan;void 0===e&&(e=d);var l=a.maxTrashcanContents;e?void 0===l&&(l=32):l=0;f=a.collapse;void 0===f&&(f=d);g=a.comments;void 0===g&&(g=d);h=a.disable;void 0===h&&(h=d);k=a.sounds;void 0===k&&(k=!0)}var m=!!a.rtl,n=a.horizontalLayout;void 0===n&&(n=!1);var p=a.toolboxPosition;p="end"!==p;p=n?
p?Blockly.TOOLBOX_AT_TOP:Blockly.TOOLBOX_AT_BOTTOM:p==m?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT;var q=a.css;void 0===q&&(q=!0);var r="https://blockly-demo.appspot.com/static/media/";a.media?r=a.media:a.path&&(r=a.path+"media/");var t=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex,u=a.keyMap||Blockly.user.keyMap.createDefaultKeyMap(),v=a.renderer||"geras";this.RTL=m;this.oneBasedIndex=t;this.collapse=f;this.comments=g;this.disable=h;this.readOnly=b;this.maxBlocks=a.maxBlocks||Infinity;this.maxInstances=
-a.maxInstances;this.pathToMedia=r;this.hasCategories=d;this.moveOptions=Blockly.Options.parseMoveOptions(a,d);this.hasScrollbars=this.moveOptions.scrollbars;this.hasTrashcan=e;this.maxTrashcanContents=l;this.hasSounds=k;this.hasCss=q;this.horizontalLayout=n;this.languageTree=c;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=p;this.theme=Blockly.Options.parseThemeOptions_(a);this.keyMap=u;this.renderer=v;this.gridPattern=
-void 0;this.parentWorkspace=a.parentWorkspace};Blockly.BlocklyOptions=function(){};Blockly.Options.parseMoveOptions=function(a,b){var c=a.move||{},d={};d.scrollbars=void 0===c.scrollbars&&void 0===a.scrollbars?b:!!c.scrollbars||!!a.scrollbars;d.wheel=d.scrollbars&&void 0!==c.wheel?!!c.wheel:!1;d.drag=d.scrollbars?void 0===c.drag?!0:!!c.drag:!1;return d};
+a.maxInstances;this.pathToMedia=r;this.hasCategories=d;this.moveOptions=Blockly.Options.parseMoveOptions(a,d);this.hasScrollbars=this.moveOptions.scrollbars;this.hasTrashcan=e;this.maxTrashcanContents=l;this.hasSounds=k;this.hasCss=q;this.horizontalLayout=n;this.languageTree=c;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=p;this.theme=Blockly.Options.parseThemeOptions_(a);this.keyMap=u;this.renderer=v;this.rendererOverrides=
+a.rendererOverrides;this.gridPattern=void 0;this.parentWorkspace=a.parentWorkspace};Blockly.BlocklyOptions=function(){};Blockly.Options.parseMoveOptions=function(a,b){var c=a.move||{},d={};d.scrollbars=void 0===c.scrollbars&&void 0===a.scrollbars?b:!!c.scrollbars||!!a.scrollbars;d.wheel=d.scrollbars&&void 0!==c.wheel?!!c.wheel:!1;d.drag=d.scrollbars?void 0===c.drag?!0:!!c.drag:!1;return d};
Blockly.Options.parseZoomOptions_=function(a){a=a.zoom||{};var b={};b.controls=void 0===a.controls?!1:!!a.controls;b.wheel=void 0===a.wheel?!1:!!a.wheel;b.startScale=void 0===a.startScale?1:Number(a.startScale);b.maxScale=void 0===a.maxScale?3:Number(a.maxScale);b.minScale=void 0===a.minScale?.3:Number(a.minScale);b.scaleSpeed=void 0===a.scaleSpeed?1.2:Number(a.scaleSpeed);b.pinch=void 0===a.pinch?b.wheel||b.controls:!!a.pinch;return b};
-Blockly.Options.parseGridOptions_=function(a){a=a.grid||{};var b={};b.spacing=Number(a.spacing)||0;b.colour=a.colour||"#888";b.length=void 0===a.length?1:Number(a.length);b.snap=0 document.");}else a=null;return a};Blockly.Touch={};Blockly.Touch.TOUCH_ENABLED="ontouchstart"in Blockly.utils.global||!!(Blockly.utils.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!Blockly.utils.global.navigator||!Blockly.utils.global.navigator.maxTouchPoints&&!Blockly.utils.global.navigator.msMaxTouchPoints);Blockly.Touch.touchIdentifier_=null;Blockly.Touch.TOUCH_MAP={};
Blockly.utils.global.PointerEvent?Blockly.Touch.TOUCH_MAP={mousedown:["pointerdown"],mouseenter:["pointerenter"],mouseleave:["pointerleave"],mousemove:["pointermove"],mouseout:["pointerout"],mouseover:["pointerover"],mouseup:["pointerup","pointercancel"],touchend:["pointerup"],touchcancel:["pointercancel"]}:Blockly.Touch.TOUCH_ENABLED&&(Blockly.Touch.TOUCH_MAP={mousedown:["touchstart"],mousemove:["touchmove"],mouseup:["touchend","touchcancel"]});Blockly.longPid_=0;
Blockly.longStart=function(a,b){Blockly.longStop_();a.changedTouches&&1!=a.changedTouches.length||(Blockly.longPid_=setTimeout(function(){a.changedTouches&&(a.button=2,a.clientX=a.changedTouches[0].clientX,a.clientY=a.changedTouches[0].clientY);b&&b.handleRightClick(a)},Blockly.LONGPRESS))};Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)};Blockly.Touch.clearTouchIdentifier=function(){Blockly.Touch.touchIdentifier_=null};
@@ -204,12 +209,14 @@ a.stopPropagation(),a.preventDefault())};Blockly.Scrollbar.prototype.onMouseMove
Blockly.Scrollbar.prototype.cleanUp_=function(){Blockly.hideChaff(!0);Blockly.Scrollbar.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_),Blockly.Scrollbar.onMouseUpWrapper_=null);Blockly.Scrollbar.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseMoveWrapper_),Blockly.Scrollbar.onMouseMoveWrapper_=null)};
Blockly.Scrollbar.prototype.constrainHandle_=function(a){return a=0>=a||isNaN(a)||this.scrollViewSize_Blockly.Tooltip.RADIUS_OK&&Blockly.Tooltip.hide()}else Blockly.Tooltip.poisonedElement_!=Blockly.Tooltip.element_&&(clearTimeout(Blockly.Tooltip.showPid_),Blockly.Tooltip.lastX_=a.pageX,Blockly.Tooltip.lastY_=a.pageY,Blockly.Tooltip.showPid_=setTimeout(Blockly.Tooltip.show_,
-Blockly.Tooltip.HOVER_MS))};Blockly.Tooltip.hide=function(){Blockly.Tooltip.visible&&(Blockly.Tooltip.visible=!1,Blockly.Tooltip.DIV&&(Blockly.Tooltip.DIV.style.display="none"));Blockly.Tooltip.showPid_&&clearTimeout(Blockly.Tooltip.showPid_)};Blockly.Tooltip.block=function(){Blockly.Tooltip.hide();Blockly.Tooltip.blocked_=!0};Blockly.Tooltip.unblock=function(){Blockly.Tooltip.blocked_=!1};
-Blockly.Tooltip.show_=function(){if(!Blockly.Tooltip.blocked_&&(Blockly.Tooltip.poisonedElement_=Blockly.Tooltip.element_,Blockly.Tooltip.DIV)){Blockly.Tooltip.DIV.innerHTML="";for(var a=Blockly.Tooltip.element_.tooltip;"function"==typeof a;)a=a();a=Blockly.utils.string.wrap(a,Blockly.Tooltip.LIMIT);a=a.split("\n");for(var b=0;bc+window.scrollY&&(e-=Blockly.Tooltip.DIV.offsetHeight+2*Blockly.Tooltip.OFFSET_Y);a?d=Math.max(Blockly.Tooltip.MARGINS-window.scrollX,
d):d+Blockly.Tooltip.DIV.offsetWidth>b+window.scrollX-2*Blockly.Tooltip.MARGINS&&(d=b-Blockly.Tooltip.DIV.offsetWidth-2*Blockly.Tooltip.MARGINS);Blockly.Tooltip.DIV.style.top=e+"px";Blockly.Tooltip.DIV.style.left=d+"px"}};Blockly.WorkspaceDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.dragGroup_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.container_=null;
Blockly.WorkspaceDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=Blockly.utils.dom.createSvgElement("svg",{xmlns:Blockly.utils.dom.SVG_NS,"xmlns:html":Blockly.utils.dom.HTML_NS,"xmlns:xlink":Blockly.utils.dom.XLINK_NS,version:"1.1","class":"blocklyWsDragSurface blocklyOverflowVisible"},null),this.container_.appendChild(this.SVG_))};
@@ -276,33 +283,32 @@ Blockly.blockAnimations.connectionUiEffect=function(a){var b=a.workspace,c=b.sca
Blockly.blockAnimations.connectionUiStep_=function(a,b,c){var d=(new Date-b)/150;1a.workspace.scale)){var b=a.getHeightWidth().height;b=Math.atan(10/b)/Math.PI*180;a.RTL||(b*=-1);Blockly.blockAnimations.disconnectUiStep_(a.getSvgRoot(),b,new Date)}};
Blockly.blockAnimations.disconnectUiStep_=function(a,b,c){var d=(new Date-c)/200;1b-Blockly.CURRENT_CONNECTION_PREFERENCE)}if(this.localConnection_||this.closestConnection_)console.error("Only one of localConnection_ and closestConnection_ was set.");
else return!0}else return!(!this.localConnection_||!this.closestConnection_);console.error("Returning true from shouldUpdatePreviews, but it's not clear why.");return!0};Blockly.InsertionMarkerManager.prototype.getCandidate_=function(a){for(var b=this.getStartRadius_(),c=null,d=null,e=0;ethis.constants_.FIELD_TEXT_HEIGHT&&(c+=(this.size_.height-c)/2);this.textElement_=Blockly.utils.dom.createSvgElement("text",{"class":"blocklyText",y:b?this.size_.height/2:c,dy:this.constants_.FIELD_TEXT_Y_OFFSET,
-x:a},this.fieldGroup_);b&&this.textElement_.setAttribute("dominant-baseline","central");this.textContent_=document.createTextNode("");this.textElement_.appendChild(this.textContent_)};Blockly.Field.prototype.bindEvents_=function(){Blockly.Tooltip.bindMouseEvents(this.getClickTarget_());this.mouseDownWrapper_=Blockly.bindEventWithChecks_(this.getClickTarget_(),"mousedown",this,this.onMouseDown_)};Blockly.Field.prototype.fromXml=function(a){this.setValue(a.textContent)};
-Blockly.Field.prototype.toXml=function(a){a.textContent=this.getValue();return a};Blockly.Field.prototype.dispose=function(){Blockly.DropDownDiv.hideIfOwner(this);Blockly.WidgetDiv.hideIfOwner(this);this.mouseDownWrapper_&&Blockly.unbindEvent_(this.mouseDownWrapper_);Blockly.utils.dom.removeNode(this.fieldGroup_);this.disposed=!0};
+Blockly.Field.prototype.createBorderRect_=function(){this.borderRect_=Blockly.utils.dom.createSvgElement("rect",{rx:this.getConstants().FIELD_BORDER_RECT_RADIUS,ry:this.getConstants().FIELD_BORDER_RECT_RADIUS,x:0,y:0,height:this.size_.height,width:this.size_.width,"class":"blocklyFieldRect"},this.fieldGroup_)};
+Blockly.Field.prototype.createTextElement_=function(){this.textElement_=Blockly.utils.dom.createSvgElement("text",{"class":"blocklyText"},this.fieldGroup_);this.getConstants().FIELD_TEXT_BASELINE_CENTER&&this.textElement_.setAttribute("dominant-baseline","central");this.textContent_=document.createTextNode("");this.textElement_.appendChild(this.textContent_)};
+Blockly.Field.prototype.bindEvents_=function(){Blockly.Tooltip.bindMouseEvents(this.getClickTarget_());this.mouseDownWrapper_=Blockly.bindEventWithChecks_(this.getClickTarget_(),"mousedown",this,this.onMouseDown_)};Blockly.Field.prototype.fromXml=function(a){this.setValue(a.textContent)};Blockly.Field.prototype.toXml=function(a){a.textContent=this.getValue();return a};
+Blockly.Field.prototype.dispose=function(){Blockly.DropDownDiv.hideIfOwner(this);Blockly.WidgetDiv.hideIfOwner(this);Blockly.Tooltip.unbindMouseEvents(this.getClickTarget_());this.mouseDownWrapper_&&Blockly.unbindEvent_(this.mouseDownWrapper_);Blockly.utils.dom.removeNode(this.fieldGroup_);this.disposed=!0};
Blockly.Field.prototype.updateEditable=function(){var a=this.fieldGroup_;this.EDITABLE&&a&&(this.sourceBlock_.isEditable()?(Blockly.utils.dom.addClass(a,"blocklyEditableText"),Blockly.utils.dom.removeClass(a,"blocklyNonEditableText"),a.style.cursor=this.CURSOR):(Blockly.utils.dom.addClass(a,"blocklyNonEditableText"),Blockly.utils.dom.removeClass(a,"blocklyEditableText"),a.style.cursor=""))};
Blockly.Field.prototype.isClickable=function(){return!!this.sourceBlock_&&this.sourceBlock_.isEditable()&&!!this.showEditor_&&"function"===typeof this.showEditor_};Blockly.Field.prototype.isCurrentlyEditable=function(){return this.EDITABLE&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()};
Blockly.Field.prototype.isSerializable=function(){var a=!1;this.name&&(this.SERIALIZABLE?a=!0:this.EDITABLE&&(console.warn("Detected an editable field that was not serializable. Please define SERIALIZABLE property as true on all editable custom fields. Proceeding with serialization."),a=!0));return a};Blockly.Field.prototype.isVisible=function(){return this.visible_};
Blockly.Field.prototype.setVisible=function(a){if(this.visible_!=a){this.visible_=a;var b=this.getSvgRoot();b&&(b.style.display=a?"block":"none")}};Blockly.Field.prototype.setValidator=function(a){this.validator_=a};Blockly.Field.prototype.getValidator=function(){return this.validator_};Blockly.Field.prototype.classValidator=function(a){return a};
-Blockly.Field.prototype.callValidator=function(a){var b=this.classValidator(a);if(null===b)return null;void 0!==b&&(a=b);if(b=this.getValidator()){b=b.call(this,a);if(null===b)return null;void 0!==b&&(a=b)}return a};Blockly.Field.prototype.getSvgRoot=function(){return this.fieldGroup_};Blockly.Field.prototype.applyColour=function(){};Blockly.Field.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_(),this.updateSize_())};
+Blockly.Field.prototype.callValidator=function(a){var b=this.classValidator(a);if(null===b)return null;void 0!==b&&(a=b);if(b=this.getValidator()){b=b.call(this,a);if(null===b)return null;void 0!==b&&(a=b)}return a};Blockly.Field.prototype.getSvgRoot=function(){return this.fieldGroup_};Blockly.Field.prototype.applyColour=function(){};Blockly.Field.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_());this.updateSize_()};
Blockly.Field.prototype.showEditor=function(a){this.isClickable()&&this.showEditor_(a)};Blockly.Field.prototype.updateWidth=function(){console.warn("Deprecated call to updateWidth, call Blockly.Field.updateSize_ to force an update to the size of the field, or Blockly.utils.dom.getTextWidth() to check the size of the field.");this.updateSize_()};
-Blockly.Field.prototype.updateSize_=function(){var a=Blockly.utils.dom.getFastTextWidth(this.textElement_,this.constants_.FIELD_TEXT_FONTSIZE,this.constants_.FIELD_TEXT_FONTWEIGHT,this.constants_.FIELD_TEXT_FONTFAMILY);this.borderRect_&&(a+=2*this.constants_.FIELD_BORDER_RECT_X_PADDING,this.borderRect_.setAttribute("width",a));this.size_.width=a};
+Blockly.Field.prototype.updateSize_=function(a){var b=this.getConstants();a=void 0!=a?a:this.borderRect_?this.getConstants().FIELD_BORDER_RECT_X_PADDING:0;var c=2*a,d=b.FIELD_TEXT_HEIGHT,e=0;this.textElement_&&(e=Blockly.utils.dom.getFastTextWidth(this.textElement_,b.FIELD_TEXT_FONTSIZE,b.FIELD_TEXT_FONTWEIGHT,b.FIELD_TEXT_FONTFAMILY),c+=e);this.borderRect_&&(d=Math.max(d,b.FIELD_BORDER_RECT_HEIGHT));this.size_.height=d;this.size_.width=c;this.positionTextElement_(a,e);this.positionBorderRect_()};
+Blockly.Field.prototype.positionTextElement_=function(a,b){if(this.textElement_){var c=this.getConstants(),d=this.size_.height/2;this.textElement_.setAttribute("x",this.sourceBlock_.RTL?this.size_.width-b-a:a);this.textElement_.setAttribute("y",c.FIELD_TEXT_BASELINE_CENTER?d:d-c.FIELD_TEXT_HEIGHT/2+c.FIELD_TEXT_BASELINE)}};
+Blockly.Field.prototype.positionBorderRect_=function(){this.borderRect_&&(this.borderRect_.setAttribute("width",this.size_.width),this.borderRect_.setAttribute("height",this.size_.height),this.borderRect_.setAttribute("rx",this.getConstants().FIELD_BORDER_RECT_RADIUS),this.borderRect_.setAttribute("ry",this.getConstants().FIELD_BORDER_RECT_RADIUS))};
Blockly.Field.prototype.getSize=function(){if(!this.isVisible())return new Blockly.utils.Size(0,0);this.isDirty_?(this.render_(),this.isDirty_=!1):this.visible_&&0==this.size_.width&&(console.warn("Deprecated use of setting size_.width to 0 to rerender a field. Set field.isDirty_ to true instead."),this.render_());return this.size_};
Blockly.Field.prototype.getScaledBBox=function(){if(this.borderRect_)a=this.borderRect_.getBoundingClientRect(),c=Blockly.utils.style.getPageOffset(this.borderRect_),d=a.width,a=a.height;else{var a=this.sourceBlock_.getHeightWidth(),b=this.sourceBlock_.workspace.scale,c=this.getAbsoluteXY_(),d=a.width*b;a=a.height*b;Blockly.utils.userAgent.GECKO?(c.x+=1.5*b,c.y+=1.5*b):Blockly.utils.userAgent.EDGE||Blockly.utils.userAgent.IE||(c.x-=.5*b,c.y-=.5*b);d+=1*b;a+=1*b}return{top:c.y,bottom:c.y+a,left:c.x,
right:c.x+d}};Blockly.Field.prototype.getDisplayText_=function(){var a=this.getText();if(!a)return Blockly.Field.NBSP;a.length>this.maxDisplayLength&&(a=a.substring(0,this.maxDisplayLength-2)+"\u2026");a=a.replace(/\s/g,Blockly.Field.NBSP);this.sourceBlock_&&this.sourceBlock_.RTL&&(a+="\u200f");return a};Blockly.Field.prototype.getText=function(){if(this.getText_){var a=this.getText_.call(this);if(null!==a)return String(a)}return String(this.getValue())};
-Blockly.Field.prototype.setText=function(a){throw Error("setText method is deprecated");};Blockly.Field.prototype.markDirty=function(){this.isDirty_=!0};Blockly.Field.prototype.forceRerender=function(){this.isDirty_=!0;this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours())};
+Blockly.Field.prototype.setText=function(a){throw Error("setText method is deprecated");};Blockly.Field.prototype.markDirty=function(){this.isDirty_=!0;this.constants_=null};Blockly.Field.prototype.forceRerender=function(){this.isDirty_=!0;this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours(),this.updateMarkers_())};
Blockly.Field.prototype.setValue=function(a){if(null!==a){var b=this.doClassValidation_(a);a=this.processValidation_(a,b);if(!(a instanceof Error)){if(b=this.getValidator())if(b=b.call(this,a),a=this.processValidation_(a,b),a instanceof Error)return;b=this.getValue();b!==a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name||null,b,a)),this.doValueUpdate_(a),this.isDirty_&&this.forceRerender())}}};
Blockly.Field.prototype.processValidation_=function(a,b){if(null===b)return this.doValueInvalid_(a),this.isDirty_&&this.forceRerender(),Error();void 0!==b&&(a=b);return a};Blockly.Field.prototype.getValue=function(){return this.value_};Blockly.Field.prototype.doClassValidation_=function(a){return null===a||void 0===a?null:a=this.classValidator(a)};Blockly.Field.prototype.doValueUpdate_=function(a){this.value_=a;this.isDirty_=!0};Blockly.Field.prototype.doValueInvalid_=function(a){};
Blockly.Field.prototype.onMouseDown_=function(a){this.sourceBlock_&&this.sourceBlock_.workspace&&(a=this.sourceBlock_.workspace.getGesture(a))&&a.setStartField(this)};Blockly.Field.prototype.setTooltip=function(a){var b=this.getClickTarget_();b?b.tooltip=a||""===a?a:this.sourceBlock_:this.tooltip_=a};Blockly.Field.prototype.getClickTarget_=function(){return this.clickTarget_||this.getSvgRoot()};Blockly.Field.prototype.getAbsoluteXY_=function(){return Blockly.utils.style.getPageOffset(this.getClickTarget_())};
Blockly.Field.prototype.referencesVariables=function(){return!1};Blockly.Field.prototype.getParentInput=function(){for(var a=null,b=this.sourceBlock_,c=b.inputList,d=0;da||a>this.fieldRow.length)throw Error("index "+a+" out of bounds.");if(!(b||""==b&&c))return a;"string"==typeof b&&(b=new Blockly.FieldLabel(b));b.setSourceBlock(this.sourceBlock_);this.sourceBlock_.rendered&&b.init();b.name=c;b.prefixField&&(a=this.insertFieldAt(a,b.prefixField));this.fieldRow.splice(a,0,b);++a;b.suffixField&&(a=this.insertFieldAt(a,b.suffixField));this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours());
@@ -468,9 +476,9 @@ return a};Blockly.Input.prototype.removeField=function(a){for(var b=0,c;c=this.f
Blockly.Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;for(var c=(this.visible_=a)?"block":"none",d=0,e;e=this.fieldRow[d];d++)e.setVisible(a);this.connection&&(a?b=this.connection.startTrackingAll():this.connection.stopTrackingAll(),d=this.connection.targetBlock())&&(d.getSvgRoot().style.display=c,a||(d.rendered=!1));return b};Blockly.Input.prototype.markDirty=function(){for(var a=0,b;b=this.fieldRow[a];a++)b.markDirty()};
Blockly.Input.prototype.setCheck=function(a){if(!this.connection)throw Error("This input does not have a connection.");this.connection.setCheck(a);return this};Blockly.Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&this.sourceBlock_.render();return this};Blockly.Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;a=k||k>b.length)throw Error('Block "'+this.type+'": Message index %'+k+" out of range.");if(f[k])throw Error('Block "'+this.type+'": Message index %'+k+" duplicated.");f[k]=!0;g++;a.push(b[k-1])}else(k=k.trim())&&a.push(k)}if(g!=b.length)throw Error('Block "'+this.type+'": Message does not reference all '+b.length+" arg(s).");
a.length&&("string"==typeof a[a.length-1]||Blockly.utils.string.startsWith(a[a.length-1].type,"field_"))&&(h={type:"input_dummy"},c&&(h.align=c),a.push(h));c={LEFT:Blockly.ALIGN_LEFT,RIGHT:Blockly.ALIGN_RIGHT,CENTRE:Blockly.ALIGN_CENTRE,CENTER:Blockly.ALIGN_CENTRE};b=[];for(h=0;h=this.inputList.length)throw RangeError("Input index "+a+" out of bounds.");if(b>this.inputList.length)throw RangeError("Reference input "+b+" out of bounds.");var c=this.inputList[a];this.inputList.splice(a,1);aa?b-1:a},this.highlightedIndex_)};
-Blockly.Menu.prototype.highlightHelper=function(a,b){b=0>b?-1:b;var c=this.getChildCount();b=a.call(this,b,c);for(var d=0;d<=c;){var e=this.getChildAt(b);if(e&&this.canHighlightItem(e))return this.setHighlightedIndex(b),!0;d++;b=a.call(this,b,c)}return!1};Blockly.Menu.prototype.canHighlightItem=function(a){return a.isEnabled()};Blockly.Menu.prototype.handleMouseOver_=function(a){(a=this.getMenuItem(a.target))&&a.isEnabled()&&this.getHighlighted()!==a&&(this.unhighlightCurrent(),this.setHighlighted(a))};
-Blockly.Menu.prototype.handleClick_=function(a){var b=this.openingCoords;this.openingCoords=null;if(b&&"number"===typeof a.clientX){var c=new Blockly.utils.Coordinate(a.clientX,a.clientY);if(1>Blockly.utils.Coordinate.distance(b,c))return}(b=this.getMenuItem(a.target))&&b.handleClick(a)&&a.preventDefault()};Blockly.Menu.prototype.handleMouseEnter_=function(a){this.focus()};Blockly.Menu.prototype.handleMouseLeave_=function(a){this.getElement()&&(this.blur(),this.clearHighlighted())};
-Blockly.Menu.prototype.handleKeyEvent=function(a){return 0!=this.getChildCount()&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
+Blockly.Menu.prototype.highlightHelper=function(a,b){b=0>b?-1:b;var c=this.getChildCount();b=a.call(this,b,c);for(var d=0;d<=c;){var e=this.getChildAt(b);if(e&&this.canHighlightItem(e))return this.setHighlightedIndex(b),!0;d++;b=a.call(this,b,c)}return!1};Blockly.Menu.prototype.canHighlightItem=function(a){return a.isEnabled()};
+Blockly.Menu.prototype.handleMouseOver_=function(a){if(a=this.getMenuItem(a.target))a.isEnabled()?this.getHighlighted()!==a&&(this.unhighlightCurrent(),this.setHighlighted(a)):this.unhighlightCurrent()};Blockly.Menu.prototype.handleClick_=function(a){var b=this.openingCoords;this.openingCoords=null;if(b&&"number"===typeof a.clientX){var c=new Blockly.utils.Coordinate(a.clientX,a.clientY);if(1>Blockly.utils.Coordinate.distance(b,c))return}(b=this.getMenuItem(a.target))&&b.handleClick(a)&&a.preventDefault()};
+Blockly.Menu.prototype.handleMouseEnter_=function(a){this.focus()};Blockly.Menu.prototype.handleMouseLeave_=function(a){this.getElement()&&(this.blur(),this.clearHighlighted())};Blockly.Menu.prototype.handleKeyEvent=function(a){return 0!=this.getChildCount()&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
Blockly.Menu.prototype.handleKeyEventInternal=function(a){var b=this.getHighlighted();if(b&&"function"==typeof b.handleKeyEvent&&b.handleKeyEvent(a))return!0;if(a.shiftKey||a.ctrlKey||a.metaKey||a.altKey)return!1;switch(a.keyCode){case Blockly.utils.KeyCodes.ENTER:b&&b.performActionInternal(a);break;case Blockly.utils.KeyCodes.UP:this.highlightPrevious();break;case Blockly.utils.KeyCodes.DOWN:this.highlightNext();break;default:return!1}return!0};Blockly.MenuItem=function(a,b){Blockly.Component.call(this);this.setContentInternal(a);this.setValue(b);this.enabled_=!0};Blockly.utils.object.inherits(Blockly.MenuItem,Blockly.Component);
-Blockly.MenuItem.prototype.createDom=function(){var a=document.createElement("div");a.id=this.getId();this.setElementInternal(a);a.className="goog-menuitem goog-option "+(this.enabled_?"":"goog-menuitem-disabled ")+(this.checked_?"goog-option-selected ":"")+(this.isRightToLeft()?"goog-menuitem-rtl ":"");var b=this.getContentWrapperDom();a.appendChild(b);var c=this.getCheckboxDom();c&&b.appendChild(c);b.appendChild(this.getContentDom());Blockly.utils.aria.setRole(a,this.roleName_||(this.checkable_?
-Blockly.utils.aria.Role.MENUITEMCHECKBOX:Blockly.utils.aria.Role.MENUITEM));Blockly.utils.aria.setState(a,Blockly.utils.aria.State.SELECTED,this.checkable_&&this.checked_||!1)};Blockly.MenuItem.prototype.getCheckboxDom=function(){if(!this.checkable_)return null;var a=document.createElement("div");a.className="goog-menuitem-checkbox";return a};Blockly.MenuItem.prototype.getContentDom=function(){var a=this.content_;"string"===typeof a&&(a=document.createTextNode(a));return a};
+Blockly.MenuItem.prototype.createDom=function(){var a=document.createElement("div");a.id=this.getId();this.setElementInternal(a);a.className="goog-menuitem goog-option "+(this.enabled_?"":"goog-menuitem-disabled ")+(this.checked_?"goog-option-selected ":"")+(this.rightToLeft_?"goog-menuitem-rtl ":"");var b=this.getContentWrapperDom();a.appendChild(b);var c=this.getCheckboxDom();c&&b.appendChild(c);b.appendChild(this.getContentDom());Blockly.utils.aria.setRole(a,this.roleName_||(this.checkable_?Blockly.utils.aria.Role.MENUITEMCHECKBOX:
+Blockly.utils.aria.Role.MENUITEM));Blockly.utils.aria.setState(a,Blockly.utils.aria.State.SELECTED,this.checkable_&&this.checked_||!1)};Blockly.MenuItem.prototype.getCheckboxDom=function(){if(!this.checkable_)return null;var a=document.createElement("div");a.className="goog-menuitem-checkbox";return a};Blockly.MenuItem.prototype.getContentDom=function(){var a=this.content_;"string"===typeof a&&(a=document.createTextNode(a));return a};
Blockly.MenuItem.prototype.getContentWrapperDom=function(){var a=document.createElement("div");a.className="goog-menuitem-content";return a};Blockly.MenuItem.prototype.setContentInternal=function(a){this.content_=a};Blockly.MenuItem.prototype.setValue=function(a){this.value_=a};Blockly.MenuItem.prototype.getValue=function(){return this.value_};Blockly.MenuItem.prototype.setRole=function(a){this.roleName_=a};Blockly.MenuItem.prototype.setCheckable=function(a){this.checkable_=a};
Blockly.MenuItem.prototype.setChecked=function(a){if(this.checkable_){this.checked_=a;var b=this.getElement();b&&this.isEnabled()&&(a?(Blockly.utils.dom.addClass(b,"goog-option-selected"),Blockly.utils.aria.setState(b,Blockly.utils.aria.State.SELECTED,!0)):(Blockly.utils.dom.removeClass(b,"goog-option-selected"),Blockly.utils.aria.setState(b,Blockly.utils.aria.State.SELECTED,!1)))}};
Blockly.MenuItem.prototype.setHighlighted=function(a){this.highlight_=a;var b=this.getElement();b&&this.isEnabled()&&(a?Blockly.utils.dom.addClass(b,"goog-menuitem-highlight"):Blockly.utils.dom.removeClass(b,"goog-menuitem-highlight"))};Blockly.MenuItem.prototype.isEnabled=function(){return this.enabled_};Blockly.MenuItem.prototype.setEnabled=function(a){this.enabled_=a;(a=this.getElement())&&(this.enabled_?Blockly.utils.dom.removeClass(a,"goog-menuitem-disabled"):Blockly.utils.dom.addClass(a,"goog-menuitem-disabled"))};
@@ -580,26 +588,26 @@ Blockly.BlockSvg.prototype.moveBy=function(a,b){if(this.parentBlock_)throw Error
Blockly.BlockSvg.prototype.moveToDragSurface=function(){if(this.useDragSurface_){var a=this.getRelativeToSurfaceXY();this.clearTransformAttributes_();this.workspace.getBlockDragSurface().translateSurface(a.x,a.y);(a=this.getSvgRoot())&&this.workspace.getBlockDragSurface().setBlocksAndShow(a)}};Blockly.BlockSvg.prototype.moveTo=function(a){var b=this.getRelativeToSurfaceXY();this.moveBy(a.x-b.x,a.y-b.y)};
Blockly.BlockSvg.prototype.moveOffDragSurface=function(a){this.useDragSurface_&&(this.translate(a.x,a.y),this.workspace.getBlockDragSurface().clearAndHide(this.workspace.getCanvas()))};Blockly.BlockSvg.prototype.moveDuringDrag=function(a){this.useDragSurface_?this.workspace.getBlockDragSurface().translateSurface(a.x,a.y):(this.svgGroup_.translate_="translate("+a.x+","+a.y+")",this.svgGroup_.setAttribute("transform",this.svgGroup_.translate_+this.svgGroup_.skew_))};
Blockly.BlockSvg.prototype.clearTransformAttributes_=function(){this.getSvgRoot().removeAttribute("transform")};Blockly.BlockSvg.prototype.snapToGrid=function(){if(this.workspace&&!this.workspace.isDragging()&&!this.getParent()&&!this.isInFlyout){var a=this.workspace.getGrid();if(a&&a.shouldSnap()){var b=a.getSpacing(),c=b/2,d=this.getRelativeToSurfaceXY();a=Math.round((d.x-c)/b)*b+c-d.x;b=Math.round((d.y-c)/b)*b+c-d.y;a=Math.round(a);b=Math.round(b);0==a&&0==b||this.moveBy(a,b)}}};
-Blockly.BlockSvg.prototype.getBoundingRectangle=function(){var a=this.getRelativeToSurfaceXY(),b=this.getHeightWidth();if(this.RTL){var c=a.x-b.width;var d=a.x}else c=a.x,d=a.x+b.width;return new Blockly.utils.Rect(a.y,a.y+b.height,c,d)};Blockly.BlockSvg.prototype.markDirty=function(){for(var a=0,b;b=this.inputList[a];a++)b.markDirty()};
+Blockly.BlockSvg.prototype.getBoundingRectangle=function(){var a=this.getRelativeToSurfaceXY(),b=this.getHeightWidth();if(this.RTL){var c=a.x-b.width;var d=a.x}else c=a.x,d=a.x+b.width;return new Blockly.utils.Rect(a.y,a.y+b.height,c,d)};Blockly.BlockSvg.prototype.markDirty=function(){this.pathObject.constants=this.workspace.getRenderer().getConstants();for(var a=0,b;b=this.inputList[a];a++)b.markDirty()};
Blockly.BlockSvg.prototype.setCollapsed=function(a){if(this.collapsed_!=a){for(var b=[],c=0,d;d=this.inputList[c];c++)b.push.apply(b,d.setVisible(!a));if(a){d=this.getIcons();for(c=0;c=this.connections_.length)return-1;b=a.y;for(var d=c;0<=d&&this.connections_[d].y==b;){if(this.connections_[d]==a)return d;d--}for(;ca)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection=function(a,b){a=this.findIndexOfConnection_(a,b);if(-1==a)throw Error("Unable to find connection in connectionDB.");this.connections_.splice(a,1)};
Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x,g=f-d[a].y;Math.sqrt(c*c+g*g)<=b&&k.push(d[a]);return ga)throw Error("Cannot unsubscribe a workspace that hasn't been subscribed.");this.subscribedWorkspaces_.splice(a,1)};
+Blockly.MarkerManager.prototype.setMarkerSvg=function(a){a?this.workspace_.getBlockCanvas()&&(this.cursorSvg_?this.workspace_.getBlockCanvas().insertBefore(a,this.cursorSvg_):this.workspace_.getBlockCanvas().appendChild(a)):this.markerSvg_=null};Blockly.MarkerManager.prototype.updateMarkers=function(){this.workspace_.keyboardAccessibilityMode&&this.cursorSvg_&&this.workspace_.getCursor().draw()};
+Blockly.MarkerManager.prototype.dispose=function(){for(var a=Object.keys(this.markers_),b=0,c;c=a[b];b++)this.unregisterMarker(c);this.markers_=null;this.cursor_.dispose();this.cursor_=null};Blockly.ThemeManager=function(a,b){this.workspace_=a;this.theme_=b;this.subscribedWorkspaces_=[];this.componentDB_=Object.create(null)};Blockly.ThemeManager.prototype.getTheme=function(){return this.theme_};
+Blockly.ThemeManager.prototype.setTheme=function(a){var b=this.theme_;this.theme_=a;if(a=this.workspace_.getInjectionDiv())b&&Blockly.utils.dom.removeClass(a,b.getClassName()),Blockly.utils.dom.addClass(a,this.theme_.getClassName());for(b=0;a=this.subscribedWorkspaces_[b];b++)a.refreshTheme();b=0;a=Object.keys(this.componentDB_);for(var c;c=a[b];b++)for(var d=0,e;e=this.componentDB_[c][d];d++){var f=e.element;e=e.propertyName;var g=this.theme_&&this.theme_.getComponentStyle(c);f.style[e]=g||""}Blockly.hideChaff()};
+Blockly.ThemeManager.prototype.subscribeWorkspace=function(a){this.subscribedWorkspaces_.push(a)};Blockly.ThemeManager.prototype.unsubscribeWorkspace=function(a){a=this.subscribedWorkspaces_.indexOf(a);if(0>a)throw Error("Cannot unsubscribe a workspace that hasn't been subscribed.");this.subscribedWorkspaces_.splice(a,1)};
Blockly.ThemeManager.prototype.subscribe=function(a,b,c){this.componentDB_[b]||(this.componentDB_[b]=[]);this.componentDB_[b].push({element:a,propertyName:c});b=this.theme_&&this.theme_.getComponentStyle(b);a.style[c]=b||""};Blockly.ThemeManager.prototype.unsubscribe=function(a){if(a)for(var b=Object.keys(this.componentDB_),c=0,d;d=b[c];c++){for(var e=this.componentDB_[d],f=e.length-1;0<=f;f--)e[f].element===a&&e.splice(f,1);this.componentDB_[d].length||delete this.componentDB_[d]}};
Blockly.ThemeManager.prototype.dispose=function(){this.componentDB_=this.subscribedWorkspaces_=this.theme_=this.owner_=null};Blockly.TouchGesture=function(a,b){Blockly.TouchGesture.superClass_.constructor.call(this,a,b);this.isMultiTouch_=!1;this.cachedPoints_=Object.create(null);this.startDistance_=this.previousScale_=0;this.isPinchZoomEnabled_=this.onStartWrapper_=null};Blockly.utils.object.inherits(Blockly.TouchGesture,Blockly.Gesture);Blockly.TouchGesture.ZOOM_IN_MULTIPLIER=5;Blockly.TouchGesture.ZOOM_OUT_MULTIPLIER=6;
Blockly.TouchGesture.prototype.doStart=function(a){this.isPinchZoomEnabled_=this.startWorkspace_.options.zoomOptions&&this.startWorkspace_.options.zoomOptions.pinch;Blockly.TouchGesture.superClass_.doStart.call(this,a);!this.isEnding_&&Blockly.Touch.isTouchEvent(a)&&this.handleTouchStart(a)};
@@ -640,27 +650,27 @@ b;a.preventDefault()};Blockly.TouchGesture.prototype.handleTouchEnd=function(a){
Blockly.WorkspaceAudio.prototype.load=function(a,b){if(a.length){try{var c=new Blockly.utils.global.Audio}catch(h){return}for(var d,e=0;e=this.remainingCapacity()||(this.currentGesture_&&this.currentGesture_.cancel(),"comment"==a.tagName.toLowerCase()?this.pasteWorkspaceComment_(a):this.pasteBlock_(a))};
Blockly.WorkspaceSvg.prototype.pasteBlock_=function(a){Blockly.Events.disable();try{var b=Blockly.Xml.domToBlock(a,this),c=this.getMarker(Blockly.navigation.MARKER_NAME).getCurNode();if(this.keyboardAccessibilityMode&&c&&c.isConnection()){var d=c.getLocation();Blockly.navigation.insertBlock(b,d);return}var e=parseInt(a.getAttribute("x"),10),f=parseInt(a.getAttribute("y"),10);if(!isNaN(e)&&!isNaN(f)){this.RTL&&(e=-e);do{a=!1;var g=this.getAllBlocks(!1);c=0;for(var h;h=g[c];c++){var k=h.getRelativeToSurfaceXY();
@@ -688,7 +698,7 @@ Blockly.WorkspaceSvg.prototype.cleanUp=function(){this.setResizesEnabled(!1);Blo
Blockly.WorkspaceSvg.prototype.showContextMenu=function(a){function b(a){if(a.isDeletable())p=p.concat(a.getDescendants(!1));else{a=a.getChildren(!1);for(var c=0;cp.length?c():Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",p.length),function(a){a&&
-c()})}};d.push(h);this.configureContextMenu&&this.configureContextMenu(d);Blockly.ContextMenu.show(a,d,this.RTL)}};
+c()})}};d.push(h);this.configureContextMenu&&this.configureContextMenu(d,a);Blockly.ContextMenu.show(a,d,this.RTL)}};
Blockly.WorkspaceSvg.prototype.updateToolbox=function(a){if(a=Blockly.Options.parseToolboxTree(a)){if(!this.options.languageTree)throw Error("Existing toolbox is null. Can't create new toolbox.");if(a.getElementsByTagName("category").length){if(!this.toolbox_)throw Error("Existing toolbox has no categories. Can't change mode.");this.options.languageTree=a;this.toolbox_.renderTree(a)}else{if(!this.flyout_)throw Error("Existing toolbox has categories. Can't change mode.");this.options.languageTree=
a;this.flyout_.show(a.childNodes)}}else if(this.options.languageTree)throw Error("Can't nullify an existing toolbox.");};Blockly.WorkspaceSvg.prototype.markFocused=function(){this.options.parentWorkspace?this.options.parentWorkspace.markFocused():(Blockly.mainWorkspace=this,this.setBrowserFocus())};Blockly.WorkspaceSvg.prototype.setBrowserFocus=function(){document.activeElement&&document.activeElement.blur();try{this.getParentSvg().focus({preventScroll:!0})}catch(a){try{this.getParentSvg().parentNode.setActive()}catch(b){this.getParentSvg().parentNode.focus({preventScroll:!0})}}};
Blockly.WorkspaceSvg.prototype.zoom=function(a,b,c){c=Math.pow(this.options.zoomOptions.scaleSpeed,c);var d=this.scale*c;if(this.scale!=d){d>this.options.zoomOptions.maxScale?c=this.options.zoomOptions.maxScale/this.scale:dthis.options.zoomOptions.maxScale?a=this.options.zoomOptions.maxScale:this.options.zoomOptions.minScale&&ab.viewBottom||b.contentLeftb.viewRight){c=null;a&&(c=Blockly.Events.getGroup(),Blockly.Events.setGroup(a.group));switch(a.type){case Blockly.Events.BLOCK_CREATE:case Blockly.Events.BLOCK_MOVE:var f=
e.getBlockById(a.blockId);f&&(f=f.getRootBlock());break;case Blockly.Events.COMMENT_CREATE:case Blockly.Events.COMMENT_MOVE:f=e.getCommentById(a.commentId)}if(f){d=f.getBoundingRectangle();d.height=d.bottom-d.top;d.width=d.right-d.left;var m=b.viewTop,n=b.viewBottom-d.height;n=Math.max(m,n);m=Blockly.utils.math.clamp(m,d.top,n)-d.top;n=b.viewLeft;var p=b.viewRight-d.width;b.RTL?n=Math.min(p,n):p=Math.max(n,p);b=Blockly.utils.math.clamp(n,d.left,p)-d.left;f.moveBy(b,m)}a&&(!a.group&&f&&console.log("WARNING: Moved object in bounds but there was no event group. This may break undo."),
@@ -725,7 +735,7 @@ b.hasTrashcan&&(c=a.trashcan.init(c));b.zoomOptions&&b.zoomOptions.controls&&a.z
Blockly.inject.bindDocumentEvents_=function(){Blockly.documentEventsBound_||(Blockly.bindEventWithChecks_(document,"scroll",null,function(){for(var a=Blockly.Workspace.getAll(),b=0,c;c=a[b];b++)c.updateInverseScreenCTM&&c.updateInverseScreenCTM()}),Blockly.bindEventWithChecks_(document,"keydown",null,Blockly.onKeyDown),Blockly.bindEvent_(document,"touchend",null,Blockly.longStop_),Blockly.bindEvent_(document,"touchcancel",null,Blockly.longStop_),Blockly.utils.userAgent.IPAD&&Blockly.bindEventWithChecks_(window,
"orientationchange",document,function(){Blockly.svgResize(Blockly.getMainWorkspace())}));Blockly.documentEventsBound_=!0};
Blockly.inject.loadSounds_=function(a,b){var c=b.getAudioManager();c.load([a+"click.mp3",a+"click.wav",a+"click.ogg"],"click");c.load([a+"disconnect.wav",a+"disconnect.mp3",a+"disconnect.ogg"],"disconnect");c.load([a+"delete.mp3",a+"delete.ogg",a+"delete.wav"],"delete");var d=[];a=function(){for(;d.length;)Blockly.unbindEvent_(d.pop());c.preload()};d.push(Blockly.bindEventWithChecks_(document,"mousemove",null,a,!0));d.push(Blockly.bindEventWithChecks_(document,"touchstart",null,a,!0))};Blockly.Names=function(a,b){this.variablePrefix_=b||"";this.reservedDict_=Object.create(null);if(a)for(a=a.split(","),b=0;be?Blockly.WidgetDiv.positionInternal_(a,0,c.height+e):Blockly.WidgetDiv.positionInternal_(a,e,c.height)};Blockly.WidgetDiv.calculateX_=function(a,b,c,d){if(d)return b=Math.max(b.right-c.width,a.left),Math.min(b,a.right-c.width);b=Math.min(b.left,a.right-c.width);return Math.max(b,a.left)};
-Blockly.WidgetDiv.calculateY_=function(a,b,c){return b.bottom+c.height>=a.bottom?b.top-c.height:b.bottom};Blockly.VERSION="3.20200123.1";Blockly.mainWorkspace=null;Blockly.selected=null;Blockly.draggingConnections=[];Blockly.clipboardXml_=null;Blockly.clipboardSource_=null;Blockly.clipboardTypeCounts_=null;Blockly.cache3dSupported_=null;Blockly.svgSize=function(a){return{width:a.cachedWidth_,height:a.cachedHeight_}};Blockly.resizeSvgContents=function(a){a.resizeContents()};
+Blockly.WidgetDiv.calculateY_=function(a,b,c){return b.bottom+c.height>=a.bottom?b.top-c.height:b.bottom};Blockly.VERSION="3.20200402.0";Blockly.mainWorkspace=null;Blockly.selected=null;Blockly.draggingConnections=[];Blockly.clipboardXml_=null;Blockly.clipboardSource_=null;Blockly.clipboardTypeCounts_=null;Blockly.cache3dSupported_=null;Blockly.parentContainer=null;Blockly.svgSize=function(a){return{width:a.cachedWidth_,height:a.cachedHeight_}};Blockly.resizeSvgContents=function(a){a.resizeContents()};
Blockly.svgResize=function(a){for(;a.options.parentWorkspace;)a=a.options.parentWorkspace;var b=a.getParentSvg(),c=b.parentNode;if(c){var d=c.offsetWidth;c=c.offsetHeight;b.cachedWidth_!=d&&(b.setAttribute("width",d+"px"),b.cachedWidth_=d);b.cachedHeight_!=c&&(b.setAttribute("height",c+"px"),b.cachedHeight_=c);a.resize()}};
Blockly.onKeyDown=function(a){var b=Blockly.mainWorkspace;if(b&&!(Blockly.utils.isTargetInput(a)||b.rendered&&!b.isVisible()))if(b.options.readOnly)Blockly.navigation.onKeyPress(a);else{var c=!1;if(a.keyCode==Blockly.utils.KeyCodes.ESC)Blockly.hideChaff(),Blockly.navigation.onBlocklyAction(Blockly.navigation.ACTION_EXIT);else{if(Blockly.navigation.onKeyPress(a))return;if(a.keyCode==Blockly.utils.KeyCodes.BACKSPACE||a.keyCode==Blockly.utils.KeyCodes.DELETE){a.preventDefault();if(Blockly.Gesture.inProgress())return;
Blockly.selected&&Blockly.selected.isDeletable()&&(c=!0)}else if(a.altKey||a.ctrlKey||a.metaKey){if(Blockly.Gesture.inProgress())return;Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()&&(a.keyCode==Blockly.utils.KeyCodes.C?(Blockly.hideChaff(),Blockly.copy_(Blockly.selected)):a.keyCode!=Blockly.utils.KeyCodes.X||Blockly.selected.workspace.isFlyout||(Blockly.copy_(Blockly.selected),c=!0));a.keyCode==Blockly.utils.KeyCodes.V?Blockly.clipboardXml_&&(a=Blockly.clipboardSource_,
@@ -774,7 +784,7 @@ k,!1),f.push([a,h,k])}return f};Blockly.unbindEvent_=function(a){for(;a.length;)
Blockly.checkBlockColourConstants=function(){Blockly.checkBlockColourConstant_("LOGIC_HUE",["Blocks","logic","HUE"],void 0);Blockly.checkBlockColourConstant_("LOGIC_HUE",["Constants","Logic","HUE"],210);Blockly.checkBlockColourConstant_("LOOPS_HUE",["Blocks","loops","HUE"],void 0);Blockly.checkBlockColourConstant_("LOOPS_HUE",["Constants","Loops","HUE"],120);Blockly.checkBlockColourConstant_("MATH_HUE",["Blocks","math","HUE"],void 0);Blockly.checkBlockColourConstant_("MATH_HUE",["Constants","Math",
"HUE"],230);Blockly.checkBlockColourConstant_("TEXTS_HUE",["Blocks","texts","HUE"],void 0);Blockly.checkBlockColourConstant_("TEXTS_HUE",["Constants","Text","HUE"],160);Blockly.checkBlockColourConstant_("LISTS_HUE",["Blocks","lists","HUE"],void 0);Blockly.checkBlockColourConstant_("LISTS_HUE",["Constants","Lists","HUE"],260);Blockly.checkBlockColourConstant_("COLOUR_HUE",["Blocks","colour","HUE"],void 0);Blockly.checkBlockColourConstant_("COLOUR_HUE",["Constants","Colour","HUE"],20);Blockly.checkBlockColourConstant_("VARIABLES_HUE",
["Blocks","variables","HUE"],void 0);Blockly.checkBlockColourConstant_("VARIABLES_HUE",["Constants","Variables","HUE"],330);Blockly.checkBlockColourConstant_("VARIABLES_DYNAMIC_HUE",["Constants","VariablesDynamic","HUE"],310);Blockly.checkBlockColourConstant_("PROCEDURES_HUE",["Blocks","procedures","HUE"],void 0)};
-Blockly.checkBlockColourConstant_=function(a,b,c){for(var d="Blockly",e=Blockly,f=0;f-b||a<-180+b||a>180-b?!0:!1};Blockly.VerticalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.left;return this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?new Blockly.utils.Rect(-1E9,1E9,-1E9,b+a.width):new Blockly.utils.Rect(-1E9,1E9,b,1E9)};
Blockly.VerticalFlyout.prototype.reflowInternal_=function(){this.workspace_.scale=this.targetWorkspace_.scale;for(var a=0,b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getHeightWidth().width;d.outputConnection&&(e-=this.tabWidth_);a=Math.max(a,e)}for(c=0;d=this.buttons_[c];c++)a=Math.max(a,d.width);a+=1.5*this.MARGIN+this.tabWidth_;a*=this.workspace_.scale;a+=Blockly.Scrollbar.scrollbarThickness;if(this.width_!=a){for(c=0;d=b[c];c++){if(this.RTL){e=d.getRelativeToSurfaceXY().x;var f=
-a/this.workspace_.scale-this.MARGIN;d.outputConnection||(f-=this.tabWidth_);d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}if(this.RTL)for(c=0;d=this.buttons_[c];c++)b=d.getPosition().y,d.moveTo(a/this.workspace_.scale-d.width-this.MARGIN-this.tabWidth_,b);this.width_=a;this.position()}};Blockly.FlyoutButton=function(a,b,c,d){this.workspace_=a;this.targetWorkspace_=b;this.text_=c.getAttribute("text");this.position_=new Blockly.utils.Coordinate(0,0);this.isLabel_=d;this.callbackKey_=c.getAttribute("callbackKey")||c.getAttribute("callbackkey");this.cssClass_=c.getAttribute("web-class")||null;this.onMouseUpWrapper_=null};Blockly.FlyoutButton.MARGIN=5;Blockly.FlyoutButton.prototype.width=0;Blockly.FlyoutButton.prototype.height=0;
+a/this.workspace_.scale-this.MARGIN;d.outputConnection||(f-=this.tabWidth_);d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}if(this.RTL)for(c=0;d=this.buttons_[c];c++)b=d.getPosition().y,d.moveTo(a/this.workspace_.scale-d.width-this.MARGIN-this.tabWidth_,b);this.width_=a;this.position()}};Blockly.FlyoutButton=function(a,b,c,d){this.workspace_=a;this.targetWorkspace_=b;this.text_=c.getAttribute("text");this.position_=new Blockly.utils.Coordinate(0,0);this.isLabel_=d;this.callbackKey_=c.getAttribute("callbackKey")||c.getAttribute("callbackkey");this.cssClass_=c.getAttribute("web-class")||null;this.onMouseUpWrapper_=null};Blockly.FlyoutButton.MARGIN_X=5;Blockly.FlyoutButton.MARGIN_Y=2;Blockly.FlyoutButton.prototype.width=0;Blockly.FlyoutButton.prototype.height=0;
Blockly.FlyoutButton.prototype.createDom=function(){var a=this.isLabel_?"blocklyFlyoutLabel":"blocklyFlyoutButton";this.cssClass_&&(a+=" "+this.cssClass_);this.svgGroup_=Blockly.utils.dom.createSvgElement("g",{"class":a},this.workspace_.getCanvas());if(!this.isLabel_)var b=Blockly.utils.dom.createSvgElement("rect",{"class":"blocklyFlyoutButtonShadow",rx:4,ry:4,x:1,y:1},this.svgGroup_);a=Blockly.utils.dom.createSvgElement("rect",{"class":this.isLabel_?"blocklyFlyoutLabelBackground":"blocklyFlyoutButtonBackground",
-rx:4,ry:4},this.svgGroup_);var c=Blockly.utils.dom.createSvgElement("text",{"class":this.isLabel_?"blocklyFlyoutLabelText":"blocklyText",x:0,y:0,"text-anchor":"middle"},this.svgGroup_),d=Blockly.utils.replaceMessageReferences(this.text_);this.workspace_.RTL&&(d+="\u200f");c.textContent=d;this.isLabel_&&(this.svgText_=c,this.workspace_.getThemeManager().subscribe(this.svgText_,"flyoutForegroundColour","fill"));this.width=Blockly.utils.dom.getTextWidth(c);this.height=20;this.isLabel_||(this.width+=
-2*Blockly.FlyoutButton.MARGIN,b.setAttribute("width",this.width),b.setAttribute("height",this.height));a.setAttribute("width",this.width);a.setAttribute("height",this.height);c.setAttribute("x",this.width/2);c.setAttribute("y",this.height-Blockly.FlyoutButton.MARGIN);this.updateTransform_();this.onMouseUpWrapper_=Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.onMouseUp_);return this.svgGroup_};
-Blockly.FlyoutButton.prototype.show=function(){this.updateTransform_();this.svgGroup_.setAttribute("display","block")};Blockly.FlyoutButton.prototype.updateTransform_=function(){this.svgGroup_.setAttribute("transform","translate("+this.position_.x+","+this.position_.y+")")};Blockly.FlyoutButton.prototype.moveTo=function(a,b){this.position_.x=a;this.position_.y=b;this.updateTransform_()};Blockly.FlyoutButton.prototype.getPosition=function(){return this.position_};
-Blockly.FlyoutButton.prototype.getTargetWorkspace=function(){return this.targetWorkspace_};Blockly.FlyoutButton.prototype.dispose=function(){this.onMouseUpWrapper_&&Blockly.unbindEvent_(this.onMouseUpWrapper_);this.svgGroup_&&Blockly.utils.dom.removeNode(this.svgGroup_);this.svgText_&&this.workspace_.getThemeManager().unsubscribe(this.svgText_)};
-Blockly.FlyoutButton.prototype.onMouseUp_=function(a){(a=this.targetWorkspace_.getGesture(a))&&a.cancel();this.isLabel_&&this.callbackKey_?console.warn("Labels should not have callbacks. Label text: "+this.text_):this.isLabel_||this.callbackKey_&&this.targetWorkspace_.getButtonCallback(this.callbackKey_)?this.isLabel_||this.targetWorkspace_.getButtonCallback(this.callbackKey_)(this):console.warn("Buttons should have callbacks. Button text: "+this.text_)};Blockly.Css.register(".blocklyFlyoutButton {,fill: #888;,cursor: default;,},.blocklyFlyoutButtonShadow {,fill: #666;,},.blocklyFlyoutButton:hover {,fill: #aaa;,},.blocklyFlyoutLabel {,cursor: default;,},.blocklyFlyoutLabelBackground {,opacity: 0;,},.blocklyFlyoutLabelText {,fill: #000;,}".split(","));Blockly.Generator=function(a){this.name_=a;this.FUNCTION_NAME_PLACEHOLDER_REGEXP_=new RegExp(this.FUNCTION_NAME_PLACEHOLDER_,"g")};Blockly.Generator.NAME_TYPE="generated_function";Blockly.Generator.prototype.INFINITE_LOOP_TRAP=null;Blockly.Generator.prototype.STATEMENT_PREFIX=null;Blockly.Generator.prototype.STATEMENT_SUFFIX=null;Blockly.Generator.prototype.INDENT=" ";Blockly.Generator.prototype.COMMENT_WRAP=60;Blockly.Generator.prototype.ORDER_OVERRIDES=[];
+rx:4,ry:4},this.svgGroup_);var c=Blockly.utils.dom.createSvgElement("text",{"class":this.isLabel_?"blocklyFlyoutLabelText":"blocklyText",x:0,y:0,"text-anchor":"middle"},this.svgGroup_),d=Blockly.utils.replaceMessageReferences(this.text_);this.workspace_.RTL&&(d+="\u200f");c.textContent=d;this.isLabel_&&(this.svgText_=c,this.workspace_.getThemeManager().subscribe(this.svgText_,"flyoutForegroundColour","fill"));var e=Blockly.utils.style.getComputedStyle(c,"fontSize"),f=Blockly.utils.style.getComputedStyle(c,
+"fontWeight"),g=Blockly.utils.style.getComputedStyle(c,"fontFamily");this.width=Blockly.utils.dom.getFastTextWidthWithSizeString(c,e,f,g);d=Blockly.utils.dom.measureFontMetrics(d,e,f,g);this.height=d.height;this.isLabel_||(this.width+=2*Blockly.FlyoutButton.MARGIN_X,this.height+=2*Blockly.FlyoutButton.MARGIN_Y,b.setAttribute("width",this.width),b.setAttribute("height",this.height));a.setAttribute("width",this.width);a.setAttribute("height",this.height);c.setAttribute("x",this.width/2);c.setAttribute("y",
+this.height/2-d.height/2+d.baseline);this.updateTransform_();this.onMouseUpWrapper_=Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.onMouseUp_);return this.svgGroup_};Blockly.FlyoutButton.prototype.show=function(){this.updateTransform_();this.svgGroup_.setAttribute("display","block")};Blockly.FlyoutButton.prototype.updateTransform_=function(){this.svgGroup_.setAttribute("transform","translate("+this.position_.x+","+this.position_.y+")")};
+Blockly.FlyoutButton.prototype.moveTo=function(a,b){this.position_.x=a;this.position_.y=b;this.updateTransform_()};Blockly.FlyoutButton.prototype.getPosition=function(){return this.position_};Blockly.FlyoutButton.prototype.getTargetWorkspace=function(){return this.targetWorkspace_};Blockly.FlyoutButton.prototype.dispose=function(){this.onMouseUpWrapper_&&Blockly.unbindEvent_(this.onMouseUpWrapper_);this.svgGroup_&&Blockly.utils.dom.removeNode(this.svgGroup_);this.svgText_&&this.workspace_.getThemeManager().unsubscribe(this.svgText_)};
+Blockly.FlyoutButton.prototype.onMouseUp_=function(a){(a=this.targetWorkspace_.getGesture(a))&&a.cancel();this.isLabel_&&this.callbackKey_?console.warn("Labels should not have callbacks. Label text: "+this.text_):this.isLabel_||this.callbackKey_&&this.targetWorkspace_.getButtonCallback(this.callbackKey_)?this.isLabel_||this.targetWorkspace_.getButtonCallback(this.callbackKey_)(this):console.warn("Buttons should have callbacks. Button text: "+this.text_)};Blockly.Css.register(".blocklyFlyoutButton {,fill: #888;,cursor: default;,},.blocklyFlyoutButtonShadow {,fill: #666;,},.blocklyFlyoutButton:hover {,fill: #aaa;,},.blocklyFlyoutLabel {,cursor: default;,},.blocklyFlyoutLabelBackground {,opacity: 0;,}".split(","));Blockly.Generator=function(a){this.name_=a;this.FUNCTION_NAME_PLACEHOLDER_REGEXP_=new RegExp(this.FUNCTION_NAME_PLACEHOLDER_,"g")};Blockly.Generator.NAME_TYPE="generated_function";Blockly.Generator.prototype.INFINITE_LOOP_TRAP=null;Blockly.Generator.prototype.STATEMENT_PREFIX=null;Blockly.Generator.prototype.STATEMENT_SUFFIX=null;Blockly.Generator.prototype.INDENT=" ";Blockly.Generator.prototype.COMMENT_WRAP=60;Blockly.Generator.prototype.ORDER_OVERRIDES=[];
Blockly.Generator.prototype.workspaceToCode=function(a){a||(console.warn("No workspace specified in workspaceToCode call. Guessing."),a=Blockly.getMainWorkspace());var b=[];this.init(a);a=a.getTopBlocks(!0);for(var c=0,d;d=a[c];c++){var e=this.blockToCode(d);Array.isArray(e)&&(e=e[0]);e&&(d.outputConnection&&(e=this.scrubNakedValue(e),this.STATEMENT_PREFIX&&!d.suppressPrefixSuffix&&(e=this.injectId(this.STATEMENT_PREFIX,d)+e),this.STATEMENT_SUFFIX&&!d.suppressPrefixSuffix&&(e+=this.injectId(this.STATEMENT_SUFFIX,
d))),b.push(e))}b=b.join("\n");b=this.finish(b);b=b.replace(/^\s+\n/,"");b=b.replace(/\n\s+$/,"\n");return b=b.replace(/[ \t]+\n/g,"\n")};Blockly.Generator.prototype.prefixLines=function(a,b){return b+a.replace(/(?!\n$)\n/g,"\n"+b)};Blockly.Generator.prototype.allNestedComments=function(a){var b=[];a=a.getDescendants(!0);for(var c=0;ca&&(a=this.computeDepth_(),this.setDepth_(a));return a};Blockly.tree.BaseNode.prototype.computeDepth_=function(){var a=this.getParent();return a?a.getDepth()+1:0};Blockly.tree.BaseNode.prototype.setDepth_=function(a){if(a!=this.depth_){this.depth_=a;var b=this.getRowElement();if(b){var c=this.getPixelIndent_()+"px";this.isRightToLeft()?b.style.paddingRight=c:b.style.paddingLeft=c}this.forEachChild(function(b){b.setDepth_(a+1)})}};
-Blockly.tree.BaseNode.prototype.contains=function(a){for(;a;){if(a==this)return!0;a=a.getParent()}return!1};Blockly.tree.BaseNode.prototype.getChildren=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};Blockly.tree.BaseNode.prototype.getFirstChild=function(){return this.getChildAt(0)};Blockly.tree.BaseNode.prototype.getLastChild=function(){return this.getChildAt(this.getChildCount()-1)};Blockly.tree.BaseNode.prototype.getPreviousSibling=function(){return this.previousSibling_};
-Blockly.tree.BaseNode.prototype.getNextSibling=function(){return this.nextSibling_};Blockly.tree.BaseNode.prototype.isLastSibling=function(){return!this.nextSibling_};Blockly.tree.BaseNode.prototype.isSelected=function(){return this.selected_};Blockly.tree.BaseNode.prototype.select=function(){var a=this.getTree();a&&a.setSelectedItem(this)};Blockly.tree.BaseNode.prototype.selectFirst=function(){var a=this.getTree();a&&this.firstChild_&&a.setSelectedItem(this.firstChild_)};
-Blockly.tree.BaseNode.prototype.setSelectedInternal=function(a){if(this.selected_!=a){this.selected_=a;this.updateRow();var b=this.getElement();b&&(Blockly.utils.aria.setState(b,Blockly.utils.aria.State.SELECTED,a),a&&(a=this.getTree().getElement(),Blockly.utils.aria.setState(a,Blockly.utils.aria.State.ACTIVEDESCENDANT,this.getId())))}};Blockly.tree.BaseNode.prototype.getExpanded=function(){return this.expanded_};Blockly.tree.BaseNode.prototype.setExpandedInternal=function(a){this.expanded_=a};
+Blockly.tree.BaseNode.prototype.addChildAt=function(a,b){var c=this.getChildAt(b-1),d=this.getChildAt(b);Blockly.tree.BaseNode.superClass_.addChildAt.call(this,a,b);a.previousSibling_=c;a.nextSibling_=d;c&&(c.nextSibling_=a);d&&(d.previousSibling_=a);(b=this.getTree())&&a.setTreeInternal(b);a.setDepth_(this.getDepth()+1);if(b=this.getElement())if(this.updateExpandIcon(),Blockly.utils.aria.setState(b,Blockly.utils.aria.State.EXPANDED,this.expanded_),this.expanded_){b=this.getChildrenElement();a.getElement()||
+a.createDom();var e=a.getElement(),f=d&&d.getElement();b.insertBefore(e,f);this.isInDocument()&&a.enterDocument();d||(c?c.updateExpandIcon():(Blockly.utils.style.setElementShown(b,!0),this.setExpanded(this.expanded_)))}};Blockly.tree.BaseNode.prototype.add=function(a){if(a.getParent())throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);this.addChildAt(a,this.getChildCount())};Blockly.tree.BaseNode.prototype.getTree=function(){return null};
+Blockly.tree.BaseNode.prototype.getDepth=function(){var a=this.depth_;0>a&&(a=(a=this.getParent())?a.getDepth()+1:0,this.setDepth_(a));return a};Blockly.tree.BaseNode.prototype.setDepth_=function(a){if(a!=this.depth_){this.depth_=a;var b=this.getRowElement();if(b){var c=this.getPixelIndent_()+"px";this.rightToLeft_?b.style.paddingRight=c:b.style.paddingLeft=c}this.forEachChild(function(b){b.setDepth_(a+1)})}};Blockly.tree.BaseNode.prototype.contains=function(a){for(;a;){if(a==this)return!0;a=a.getParent()}return!1};
+Blockly.tree.BaseNode.prototype.getChildren=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};Blockly.tree.BaseNode.prototype.getPreviousSibling=function(){return this.previousSibling_};Blockly.tree.BaseNode.prototype.getNextSibling=function(){return this.nextSibling_};Blockly.tree.BaseNode.prototype.isLastSibling=function(){return!this.nextSibling_};Blockly.tree.BaseNode.prototype.isSelected=function(){return this.selected_};
+Blockly.tree.BaseNode.prototype.select=function(){var a=this.getTree();a&&a.setSelectedItem(this)};Blockly.tree.BaseNode.prototype.setSelected=function(a){if(this.selected_!=a){this.selected_=a;this.updateRow();var b=this.getElement();b&&(Blockly.utils.aria.setState(b,Blockly.utils.aria.State.SELECTED,a),a&&(a=this.getTree().getElement(),Blockly.utils.aria.setState(a,Blockly.utils.aria.State.ACTIVEDESCENDANT,this.getId())))}};
Blockly.tree.BaseNode.prototype.setExpanded=function(a){var b=a!=this.expanded_,c;this.expanded_=a;var d=this.getTree(),e=this.getElement();if(this.hasChildren()){if(!a&&d&&this.contains(d.getSelectedItem())&&this.select(),e){if(c=this.getChildrenElement())Blockly.utils.style.setElementShown(c,a),Blockly.utils.aria.setState(e,Blockly.utils.aria.State.EXPANDED,a),a&&this.isInDocument()&&!c.hasChildNodes()&&(this.forEachChild(function(a){c.appendChild(a.toDom())}),this.forEachChild(function(a){a.enterDocument()}));
-this.updateExpandIcon()}}else(c=this.getChildrenElement())&&Blockly.utils.style.setElementShown(c,!1);e&&this.updateIcon_();b&&(a?this.doNodeExpanded():this.doNodeCollapsed())};Blockly.tree.BaseNode.prototype.doNodeExpanded=function(){};Blockly.tree.BaseNode.prototype.doNodeCollapsed=function(){};Blockly.tree.BaseNode.prototype.toggle=function(){this.setExpanded(!this.getExpanded())};Blockly.tree.BaseNode.prototype.isUserCollapsible=function(){return this.isUserCollapsible_};
-Blockly.tree.BaseNode.prototype.toDom=function(){var a=this.getExpanded()&&this.hasChildren(),b=document.createElement("div");b.style.backgroundPosition=this.getBackgroundPosition();a||(b.style.display="none");a&&this.forEachChild(function(a){b.appendChild(a.toDom())});a=document.createElement("div");a.id=this.getId();a.appendChild(this.getRowDom());a.appendChild(b);return a};Blockly.tree.BaseNode.prototype.getPixelIndent_=function(){return Math.max(0,(this.getDepth()-1)*this.config_.indentWidth)};
-Blockly.tree.BaseNode.prototype.getRowDom=function(){var a=document.createElement("div");a.className=this.getRowClassName();a.style["padding-"+(this.isRightToLeft()?"right":"left")]=this.getPixelIndent_()+"px";a.appendChild(this.getIconDom());a.appendChild(this.getLabelDom());return a};Blockly.tree.BaseNode.prototype.getRowClassName=function(){var a="";this.isSelected()&&(a=" "+(this.config_.cssSelectedRow||""));return this.config_.cssTreeRow+a};
-Blockly.tree.BaseNode.prototype.getLabelDom=function(){var a=document.createElement("span");a.className=this.config_.cssItemLabel||"";a.textContent=this.getText();return a};Blockly.tree.BaseNode.prototype.getIconDom=function(){var a=document.createElement("span");a.style.display="inline-block";a.className=this.getCalculatedIconClass();return a};Blockly.tree.BaseNode.prototype.getCalculatedIconClass=function(){throw Error("unimplemented abstract method");};
+this.updateExpandIcon()}}else(c=this.getChildrenElement())&&Blockly.utils.style.setElementShown(c,!1);e&&this.updateIcon_();b&&(a?this.doNodeExpanded():this.doNodeCollapsed())};Blockly.tree.BaseNode.prototype.doNodeExpanded=function(){};Blockly.tree.BaseNode.prototype.doNodeCollapsed=function(){};Blockly.tree.BaseNode.prototype.toggle=function(){this.setExpanded(!this.expanded_)};
+Blockly.tree.BaseNode.prototype.toDom=function(){var a=this.expanded_&&this.hasChildren(),b=document.createElement("div");b.style.backgroundPosition=this.getBackgroundPosition();a||(b.style.display="none");a&&this.forEachChild(function(a){b.appendChild(a.toDom())});a=document.createElement("div");a.id=this.getId();a.appendChild(this.getRowDom());a.appendChild(b);return a};Blockly.tree.BaseNode.prototype.getPixelIndent_=function(){return Math.max(0,(this.getDepth()-1)*this.config_.indentWidth)};
+Blockly.tree.BaseNode.prototype.getRowDom=function(){var a=document.createElement("div");a.className=this.getRowClassName();a.style["padding-"+(this.rightToLeft_?"right":"left")]=this.getPixelIndent_()+"px";a.appendChild(this.getIconDom());a.appendChild(this.getLabelDom());return a};Blockly.tree.BaseNode.prototype.getRowClassName=function(){var a="";this.isSelected()&&(a=" "+(this.config_.cssSelectedRow||""));return this.config_.cssTreeRow+a};
+Blockly.tree.BaseNode.prototype.getLabelDom=function(){var a=document.createElement("span");a.className=this.config_.cssItemLabel||"";a.textContent=this.content;return a};Blockly.tree.BaseNode.prototype.getIconDom=function(){var a=document.createElement("span");a.style.display="inline-block";a.className=this.getCalculatedIconClass();return a};Blockly.tree.BaseNode.prototype.getCalculatedIconClass=function(){throw Error("unimplemented abstract method");};
Blockly.tree.BaseNode.prototype.getBackgroundPosition=function(){return(this.isLastSibling()?"-100":(this.getDepth()-1)*this.config_.indentWidth)+"px 0"};Blockly.tree.BaseNode.prototype.getElement=function(){var a=Blockly.tree.BaseNode.superClass_.getElement.call(this);a||(a=document.getElementById(this.getId()),this.setElementInternal(a));return a};Blockly.tree.BaseNode.prototype.getRowElement=function(){var a=this.getElement();return a?a.firstChild:null};
-Blockly.tree.BaseNode.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};Blockly.tree.BaseNode.prototype.getLabelElement=function(){var a=this.getRowElement();return a&&a.lastChild?a.lastChild.previousSibling:null};Blockly.tree.BaseNode.prototype.getChildrenElement=function(){var a=this.getElement();return a?a.lastChild:null};Blockly.tree.BaseNode.prototype.getIconClass=function(){return this.iconClass_};
-Blockly.tree.BaseNode.prototype.getExpandedIconClass=function(){return this.expandedIconClass_};Blockly.tree.BaseNode.prototype.setText=function(a){this.content_=a};Blockly.tree.BaseNode.prototype.getText=function(){return this.content_};Blockly.tree.BaseNode.prototype.updateRow=function(){var a=this.getRowElement();a&&(a.className=this.getRowClassName())};Blockly.tree.BaseNode.prototype.updateExpandIcon=function(){var a=this.getChildrenElement();a&&(a.style.backgroundPosition=this.getBackgroundPosition())};
-Blockly.tree.BaseNode.prototype.updateIcon_=function(){this.getIconElement().className=this.getCalculatedIconClass()};Blockly.tree.BaseNode.prototype.onMouseDown=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()?this.isUserCollapsible_&&this.toggle():(this.select(),this.updateRow())};Blockly.tree.BaseNode.prototype.onClick_=function(a){a.preventDefault()};
-Blockly.tree.BaseNode.prototype.onKeyDown=function(a){var b=!0;switch(a.keyCode){case Blockly.utils.KeyCodes.RIGHT:if(a.altKey)break;b=this.selectChild();break;case Blockly.utils.KeyCodes.LEFT:if(a.altKey)break;b=this.selectParent();break;case Blockly.utils.KeyCodes.DOWN:b=this.selectNext();break;case Blockly.utils.KeyCodes.UP:b=this.selectPrevious();break;default:b=!1}b&&a.preventDefault();return b};
-Blockly.tree.BaseNode.prototype.selectNext=function(){var a=this.getNextShownNode();a&&a.select();return!0};Blockly.tree.BaseNode.prototype.selectPrevious=function(){var a=this.getPreviousShownNode();a&&a.select();return!0};Blockly.tree.BaseNode.prototype.selectParent=function(){if(this.hasChildren()&&this.getExpanded()&&this.isUserCollapsible_)this.setExpanded(!1);else{var a=this.getParent(),b=this.getTree();a&&a!=b&&a.select()}return!0};
-Blockly.tree.BaseNode.prototype.selectChild=function(){return this.hasChildren()?(this.getExpanded()?this.getFirstChild().select():this.setExpanded(!0),!0):!1};Blockly.tree.BaseNode.prototype.getLastShownDescendant=function(){return this.getExpanded()&&this.hasChildren()?this.getLastChild().getLastShownDescendant():this};
-Blockly.tree.BaseNode.prototype.getNextShownNode=function(){if(this.hasChildren()&&this.getExpanded())return this.getFirstChild();for(var a=this,b;a!=this.getTree();){b=a.getNextSibling();if(null!=b)return b;a=a.getParent()}return null};Blockly.tree.BaseNode.prototype.getPreviousShownNode=function(){var a=this.getPreviousSibling();if(null!=a)return a.getLastShownDescendant();a=this.getParent();var b=this.getTree();return a==b||this==b?null:a};Blockly.tree.BaseNode.prototype.getConfig=function(){return this.config_};
+Blockly.tree.BaseNode.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};Blockly.tree.BaseNode.prototype.getLabelElement=function(){var a=this.getRowElement();return a&&a.lastChild?a.lastChild.previousSibling:null};Blockly.tree.BaseNode.prototype.getChildrenElement=function(){var a=this.getElement();return a?a.lastChild:null};Blockly.tree.BaseNode.prototype.updateRow=function(){var a=this.getRowElement();a&&(a.className=this.getRowClassName())};
+Blockly.tree.BaseNode.prototype.updateExpandIcon=function(){var a=this.getChildrenElement();a&&(a.style.backgroundPosition=this.getBackgroundPosition())};Blockly.tree.BaseNode.prototype.updateIcon_=function(){this.getIconElement().className=this.getCalculatedIconClass()};Blockly.tree.BaseNode.prototype.onMouseDown=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()?this.isUserCollapsible_&&this.toggle():(this.select(),this.updateRow())};
+Blockly.tree.BaseNode.prototype.onClick_=function(a){a.preventDefault()};Blockly.tree.BaseNode.prototype.onKeyDown=function(a){var b=!0;switch(a.keyCode){case Blockly.utils.KeyCodes.RIGHT:if(a.altKey)break;b=this.selectChild();break;case Blockly.utils.KeyCodes.LEFT:if(a.altKey)break;b=this.selectParent();break;case Blockly.utils.KeyCodes.DOWN:b=this.selectNext();break;case Blockly.utils.KeyCodes.UP:b=this.selectPrevious();break;default:b=!1}b&&a.preventDefault();return b};
+Blockly.tree.BaseNode.prototype.selectNext=function(){var a=this.getNextShownNode();a&&a.select();return!0};Blockly.tree.BaseNode.prototype.selectPrevious=function(){var a=this.getPreviousShownNode();a&&a.select();return!0};Blockly.tree.BaseNode.prototype.selectParent=function(){if(this.hasChildren()&&this.expanded_&&this.isUserCollapsible_)this.setExpanded(!1);else{var a=this.getParent(),b=this.getTree();a&&a!=b&&a.select()}return!0};
+Blockly.tree.BaseNode.prototype.selectChild=function(){return this.hasChildren()?(this.expanded_?this.getChildAt(0).select():this.setExpanded(!0),!0):!1};Blockly.tree.BaseNode.prototype.getLastShownDescendant=function(){return this.expanded_&&this.hasChildren()?this.getChildAt(this.getChildCount()-1).getLastShownDescendant():this};
+Blockly.tree.BaseNode.prototype.getNextShownNode=function(){if(this.hasChildren()&&this.expanded_)return this.getChildAt(0);for(var a=this,b;a!=this.getTree();){b=a.getNextSibling();if(null!=b)return b;a=a.getParent()}return null};Blockly.tree.BaseNode.prototype.getPreviousShownNode=function(){var a=this.getPreviousSibling();if(null!=a)return a.getLastShownDescendant();a=this.getParent();var b=this.getTree();return a==b||this==b?null:a};
Blockly.tree.BaseNode.prototype.setTreeInternal=function(a){this.tree!=a&&(this.tree=a,this.forEachChild(function(b){b.setTreeInternal(a)}))};Blockly.tree.TreeNode=function(a,b,c){this.toolbox_=a;Blockly.tree.BaseNode.call(this,b,c)};Blockly.utils.object.inherits(Blockly.tree.TreeNode,Blockly.tree.BaseNode);Blockly.tree.TreeNode.prototype.getTree=function(){if(this.tree)return this.tree;var a=this.getParent();return a&&(a=a.getTree())?(this.setTreeInternal(a),a):null};
-Blockly.tree.TreeNode.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();if(this.hasChildren()){if(a&&b.cssExpandedFolderIcon)return b.cssTreeIcon+" "+b.cssExpandedFolderIcon;if(!a&&b.cssCollapsedFolderIcon)return b.cssTreeIcon+" "+b.cssCollapsedFolderIcon}else if(b.cssFileIcon)return b.cssTreeIcon+" "+b.cssFileIcon;return""};
-Blockly.tree.TreeNode.prototype.onClick_=function(a){this.hasChildren()&&this.isUserCollapsible()?(this.toggle(),this.select()):this.isSelected()?this.getTree().setSelectedItem(null):this.select();this.updateRow()};Blockly.tree.TreeNode.prototype.onMouseDown=function(a){};
-Blockly.tree.TreeNode.prototype.onKeyDown=function(a){if(this.tree.toolbox_.horizontalLayout_){var b={},c=Blockly.utils.KeyCodes.DOWN,d=Blockly.utils.KeyCodes.UP;b[Blockly.utils.KeyCodes.RIGHT]=this.isRightToLeft()?d:c;b[Blockly.utils.KeyCodes.LEFT]=this.isRightToLeft()?c:d;b[Blockly.utils.KeyCodes.UP]=Blockly.utils.KeyCodes.LEFT;b[Blockly.utils.KeyCodes.DOWN]=Blockly.utils.KeyCodes.RIGHT;Object.defineProperties(a,{keyCode:{value:b[a.keyCode]||a.keyCode}})}return Blockly.tree.TreeNode.superClass_.onKeyDown.call(this,
-a)};Blockly.tree.TreeNode.prototype.onSizeChanged=function(a){this.onSizeChanged_=a};Blockly.tree.TreeNode.prototype.resizeToolbox_=function(){this.onSizeChanged_&&this.onSizeChanged_.call(this.toolbox_)};Blockly.tree.TreeNode.prototype.doNodeExpanded=Blockly.tree.TreeNode.prototype.resizeToolbox_;Blockly.tree.TreeNode.prototype.doNodeCollapsed=Blockly.tree.TreeNode.prototype.resizeToolbox_;Blockly.tree.TreeControl=function(a,b){this.toolbox_=a;this.onKeydownWrapper_=this.onClickWrapper_=this.onBlurWrapper_=this.onFocusWrapper_=null;Blockly.tree.BaseNode.call(this,"",b);this.setExpandedInternal(!0);this.setSelectedInternal(!0);this.selectedItem_=this};Blockly.utils.object.inherits(Blockly.tree.TreeControl,Blockly.tree.BaseNode);Blockly.tree.TreeControl.prototype.getTree=function(){return this};Blockly.tree.TreeControl.prototype.getToolbox=function(){return this.toolbox_};
+Blockly.tree.TreeNode.prototype.getCalculatedIconClass=function(){var a=this.expanded_;if(a&&this.expandedIconClass)return this.expandedIconClass;var b=this.iconClass;if(!a&&b)return b;b=this.config_;if(this.hasChildren()){if(a&&b.cssExpandedFolderIcon)return b.cssTreeIcon+" "+b.cssExpandedFolderIcon;if(!a&&b.cssCollapsedFolderIcon)return b.cssTreeIcon+" "+b.cssCollapsedFolderIcon}else if(b.cssFileIcon)return b.cssTreeIcon+" "+b.cssFileIcon;return""};
+Blockly.tree.TreeNode.prototype.onClick_=function(a){this.hasChildren()&&this.isUserCollapsible_?(this.toggle(),this.select()):this.isSelected()?this.getTree().setSelectedItem(null):this.select();this.updateRow()};Blockly.tree.TreeNode.prototype.onMouseDown=function(a){};
+Blockly.tree.TreeNode.prototype.onKeyDown=function(a){if(this.tree.toolbox_.horizontalLayout_){var b={},c=Blockly.utils.KeyCodes.DOWN,d=Blockly.utils.KeyCodes.UP;b[Blockly.utils.KeyCodes.RIGHT]=this.rightToLeft_?d:c;b[Blockly.utils.KeyCodes.LEFT]=this.rightToLeft_?c:d;b[Blockly.utils.KeyCodes.UP]=Blockly.utils.KeyCodes.LEFT;b[Blockly.utils.KeyCodes.DOWN]=Blockly.utils.KeyCodes.RIGHT;Object.defineProperties(a,{keyCode:{value:b[a.keyCode]||a.keyCode}})}return Blockly.tree.TreeNode.superClass_.onKeyDown.call(this,
+a)};Blockly.tree.TreeNode.prototype.onSizeChanged=function(a){this.onSizeChanged_=a};Blockly.tree.TreeNode.prototype.resizeToolbox_=function(){this.onSizeChanged_&&this.onSizeChanged_.call(this.toolbox_)};Blockly.tree.TreeNode.prototype.doNodeExpanded=Blockly.tree.TreeNode.prototype.resizeToolbox_;Blockly.tree.TreeNode.prototype.doNodeCollapsed=Blockly.tree.TreeNode.prototype.resizeToolbox_;Blockly.tree.TreeControl=function(a,b){this.toolbox_=a;this.onKeydownWrapper_=this.onClickWrapper_=this.onBlurWrapper_=this.onFocusWrapper_=null;Blockly.tree.BaseNode.call(this,"",b);this.selected_=this.expanded_=!0;this.selectedItem_=this};Blockly.utils.object.inherits(Blockly.tree.TreeControl,Blockly.tree.BaseNode);Blockly.tree.TreeControl.prototype.getTree=function(){return this};Blockly.tree.TreeControl.prototype.getToolbox=function(){return this.toolbox_};
Blockly.tree.TreeControl.prototype.getDepth=function(){return 0};Blockly.tree.TreeControl.prototype.handleFocus_=function(a){this.focused_=!0;a=this.getElement();Blockly.utils.dom.addClass(a,"focused");this.selectedItem_&&this.selectedItem_.select()};Blockly.tree.TreeControl.prototype.handleBlur_=function(a){this.focused_=!1;a=this.getElement();Blockly.utils.dom.removeClass(a,"focused")};Blockly.tree.TreeControl.prototype.hasFocus=function(){return this.focused_};
-Blockly.tree.TreeControl.prototype.getExpanded=function(){return!0};Blockly.tree.TreeControl.prototype.setExpanded=function(a){this.setExpandedInternal(a)};Blockly.tree.TreeControl.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};Blockly.tree.TreeControl.prototype.updateExpandIcon=function(){};Blockly.tree.TreeControl.prototype.getRowClassName=function(){return Blockly.tree.TreeControl.superClass_.getRowClassName.call(this)+" "+this.getConfig().cssHideRoot};
-Blockly.tree.TreeControl.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();return a&&b.cssExpandedRootIcon?b.cssTreeIcon+" "+b.cssExpandedRootIcon:""};
-Blockly.tree.TreeControl.prototype.setSelectedItem=function(a){if(a!=this.selectedItem_&&(!this.onBeforeSelected_||this.onBeforeSelected_.call(this.toolbox_,a))){var b=this.getSelectedItem();this.selectedItem_&&this.selectedItem_.setSelectedInternal(!1);(this.selectedItem_=a)&&a.setSelectedInternal(!0);this.onAfterSelected_&&this.onAfterSelected_.call(this.toolbox_,b,a)}};Blockly.tree.TreeControl.prototype.onBeforeSelected=function(a){this.onBeforeSelected_=a};
+Blockly.tree.TreeControl.prototype.setExpanded=function(a){this.expanded_=a};Blockly.tree.TreeControl.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};Blockly.tree.TreeControl.prototype.updateExpandIcon=function(){};Blockly.tree.TreeControl.prototype.getRowClassName=function(){return Blockly.tree.TreeControl.superClass_.getRowClassName.call(this)+" "+this.config_.cssHideRoot};
+Blockly.tree.TreeControl.prototype.getCalculatedIconClass=function(){var a=this.expanded_;if(a&&this.expandedIconClass)return this.expandedIconClass;var b=this.iconClass;return!a&&b?b:a&&this.config_.cssExpandedRootIcon?this.config_.cssTreeIcon+" "+this.config_.cssExpandedRootIcon:""};
+Blockly.tree.TreeControl.prototype.setSelectedItem=function(a){if(a!=this.selectedItem_&&(!this.onBeforeSelected_||this.onBeforeSelected_.call(this.toolbox_,a))){var b=this.getSelectedItem();this.selectedItem_&&this.selectedItem_.setSelected(!1);(this.selectedItem_=a)&&a.setSelected(!0);this.onAfterSelected_&&this.onAfterSelected_.call(this.toolbox_,b,a)}};Blockly.tree.TreeControl.prototype.onBeforeSelected=function(a){this.onBeforeSelected_=a};
Blockly.tree.TreeControl.prototype.onAfterSelected=function(a){this.onAfterSelected_=a};Blockly.tree.TreeControl.prototype.getSelectedItem=function(){return this.selectedItem_};Blockly.tree.TreeControl.prototype.initAccessibility=function(){Blockly.tree.TreeControl.superClass_.initAccessibility.call(this);var a=this.getElement();Blockly.utils.aria.setRole(a,Blockly.utils.aria.Role.TREE);Blockly.utils.aria.setState(a,Blockly.utils.aria.State.LABELLEDBY,this.getLabelElement().id)};
-Blockly.tree.TreeControl.prototype.enterDocument=function(){Blockly.tree.TreeControl.superClass_.enterDocument.call(this);var a=this.getElement();a.className=this.getConfig().cssRoot;a.setAttribute("hideFocus","true");this.attachEvents_();this.initAccessibility()};Blockly.tree.TreeControl.prototype.exitDocument=function(){Blockly.tree.TreeControl.superClass_.exitDocument.call(this);this.detachEvents_()};
+Blockly.tree.TreeControl.prototype.enterDocument=function(){Blockly.tree.TreeControl.superClass_.enterDocument.call(this);var a=this.getElement();a.className=this.config_.cssRoot;a.setAttribute("hideFocus","true");this.attachEvents_();this.initAccessibility()};Blockly.tree.TreeControl.prototype.exitDocument=function(){Blockly.tree.TreeControl.superClass_.exitDocument.call(this);this.detachEvents_()};
Blockly.tree.TreeControl.prototype.attachEvents_=function(){var a=this.getElement();a.tabIndex=0;this.onFocusWrapper_=Blockly.bindEvent_(a,"focus",this,this.handleFocus_);this.onBlurWrapper_=Blockly.bindEvent_(a,"blur",this,this.handleBlur_);this.onClickWrapper_=Blockly.bindEventWithChecks_(a,"click",this,this.handleMouseEvent_);this.onKeydownWrapper_=Blockly.bindEvent_(a,"keydown",this,this.handleKeyEvent_)};
Blockly.tree.TreeControl.prototype.detachEvents_=function(){this.onFocusWrapper_&&(Blockly.unbindEvent_(this.onFocusWrapper_),this.onFocusWrapper_=null);this.onBlurWrapper_&&(Blockly.unbindEvent_(this.onBlurWrapper_),this.onBlurWrapper_=null);this.onClickWrapper_&&(Blockly.unbindEvent_(this.onClickWrapper_),this.onClickWrapper_=null);this.onKeydownWrapper_&&(Blockly.unbindEvent_(this.onKeydownWrapper_),this.onKeydownWrapper_=null)};
Blockly.tree.TreeControl.prototype.handleMouseEvent_=function(a){var b=this.getNodeFromEvent_(a);if(b)switch(a.type){case "mousedown":b.onMouseDown(a);break;case "click":b.onClick_(a)}};Blockly.tree.TreeControl.prototype.handleKeyEvent_=function(a){var b=!1;if(b=this.selectedItem_&&this.selectedItem_.onKeyDown(a)||b)Blockly.utils.style.scrollIntoContainerView(this.selectedItem_.getElement(),this.getElement().parentNode),a.preventDefault();return b};
-Blockly.tree.TreeControl.prototype.getNodeFromEvent_=function(a){for(var b=a.target;null!=b;){if(a=Blockly.tree.BaseNode.allNodes[b.id])return a;if(b==this.getElement())break;b=b.parentNode}return null};Blockly.tree.TreeControl.prototype.createNode=function(a){return new Blockly.tree.TreeNode(this.toolbox_,a||"",this.getConfig())};Blockly.Toolbox=function(a){this.workspace_=a;this.RTL=a.options.RTL;this.horizontalLayout_=a.options.horizontalLayout;this.toolboxPosition=a.options.toolboxPosition;this.config_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"};this.treeSeparatorConfig_={cssTreeRow:"blocklyTreeSeparator"};
+Blockly.tree.TreeControl.prototype.getNodeFromEvent_=function(a){for(var b=a.target;null!=b;){if(a=Blockly.tree.BaseNode.allNodes[b.id])return a;if(b==this.getElement())break;if(b.getAttribute("role")==Blockly.utils.aria.Role.GROUP)break;b=b.parentNode}return null};Blockly.tree.TreeControl.prototype.createNode=function(a){return new Blockly.tree.TreeNode(this.toolbox_,a||"",this.config_)};Blockly.Toolbox=function(a){this.workspace_=a;this.RTL=a.options.RTL;this.horizontalLayout_=a.options.horizontalLayout;this.toolboxPosition=a.options.toolboxPosition;this.config_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"};this.treeSeparatorConfig_={cssTreeRow:"blocklyTreeSeparator"};
this.horizontalLayout_&&(this.config_.cssTreeRow+=a.RTL?" blocklyHorizontalTreeRtl":" blocklyHorizontalTree",this.treeSeparatorConfig_.cssTreeRow="blocklyTreeSeparatorHorizontal "+(a.RTL?"blocklyHorizontalTreeRtl":"blocklyHorizontalTree"),this.config_.cssTreeIcon="");this.flyout_=null};Blockly.Toolbox.prototype.width=0;Blockly.Toolbox.prototype.height=0;Blockly.Toolbox.prototype.selectedOption_=null;Blockly.Toolbox.prototype.lastCategory_=null;
Blockly.Toolbox.prototype.init=function(){var a=this.workspace_,b=this.workspace_.getParentSvg();this.HtmlDiv=document.createElement("div");this.HtmlDiv.className="blocklyToolboxDiv blocklyNonSelectable";this.HtmlDiv.setAttribute("dir",a.RTL?"RTL":"LTR");b.parentNode.insertBefore(this.HtmlDiv,b);var c=a.getThemeManager();c.subscribe(this.HtmlDiv,"toolboxBackgroundColour","background-color");c.subscribe(this.HtmlDiv,"toolboxForegroundColour","color");Blockly.bindEventWithChecks_(this.HtmlDiv,"mousedown",
-this,function(a){Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0);Blockly.Touch.clearTouchIdentifier()},!1,!0);c=new Blockly.Options({parentWorkspace:a,rtl:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,renderer:a.options.renderer});c.toolboxPosition=a.options.toolboxPosition;if(a.horizontalLayout){if(!Blockly.HorizontalFlyout)throw Error("Missing require for Blockly.HorizontalFlyout");this.flyout_=new Blockly.HorizontalFlyout(c)}else{if(!Blockly.VerticalFlyout)throw Error("Missing require for Blockly.VerticalFlyout");
-this.flyout_=new Blockly.VerticalFlyout(c)}if(!this.flyout_)throw Error("One of Blockly.VerticalFlyout or Blockly.Horizontal must berequired.");Blockly.utils.dom.insertAfter(this.flyout_.createDom("svg"),b);this.flyout_.init(a);this.config_.cleardotPath=a.options.pathToMedia+"1x1.gif";this.config_.cssCollapsedFolderIcon="blocklyTreeIconClosed"+(a.RTL?"Rtl":"Ltr");this.renderTree(a.options.languageTree)};
-Blockly.Toolbox.prototype.renderTree=function(a){this.tree_&&(this.tree_.dispose(),this.lastCategory_=null);var b=new Blockly.tree.TreeControl(this,this.config_);this.tree_=b;b.setSelectedItem(null);b.onBeforeSelected(this.handleBeforeTreeSelected_);b.onAfterSelected(this.handleAfterTreeSelected_);var c=null;if(a){this.tree_.blocks=[];this.hasColours_=!1;c=this.syncTrees_(a,this.tree_,this.workspace_.options.pathToMedia);if(this.tree_.blocks.length)throw Error("Toolbox cannot have both blocks and categories in the root level.");
-this.workspace_.resizeContents()}b.render(this.HtmlDiv);c&&b.setSelectedItem(c);this.addColour_();this.position();this.horizontalLayout_&&Blockly.utils.aria.setState(this.tree_.getElement(),Blockly.utils.aria.State.ORIENTATION,"horizontal")};Blockly.Toolbox.prototype.handleBeforeTreeSelected_=function(a){if(a==this.tree_)return!1;this.lastCategory_&&(this.lastCategory_.getRowElement().style.backgroundColor="");if(a){var b=a.hexColour||"#57e";a.getRowElement().style.backgroundColor=b;this.addColour_(a)}return!0};
+this,function(a){Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0);Blockly.Touch.clearTouchIdentifier()},!1,!0);c=new Blockly.Options({parentWorkspace:a,rtl:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,renderer:a.options.renderer,rendererOverrides:a.options.rendererOverrides});c.toolboxPosition=a.options.toolboxPosition;if(a.horizontalLayout){if(!Blockly.HorizontalFlyout)throw Error("Missing require for Blockly.HorizontalFlyout");
+this.flyout_=new Blockly.HorizontalFlyout(c)}else{if(!Blockly.VerticalFlyout)throw Error("Missing require for Blockly.VerticalFlyout");this.flyout_=new Blockly.VerticalFlyout(c)}if(!this.flyout_)throw Error("One of Blockly.VerticalFlyout or Blockly.Horizontal must berequired.");Blockly.utils.dom.insertAfter(this.flyout_.createDom("svg"),b);this.flyout_.init(a);this.config_.cleardotPath=a.options.pathToMedia+"1x1.gif";this.config_.cssCollapsedFolderIcon="blocklyTreeIconClosed"+(a.RTL?"Rtl":"Ltr");
+this.renderTree(a.options.languageTree)};
+Blockly.Toolbox.prototype.renderTree=function(a){this.tree_&&(this.tree_.dispose(),this.lastCategory_=null);var b=new Blockly.tree.TreeControl(this,this.config_);this.tree_=b;b.setSelectedItem(null);b.onBeforeSelected(this.handleBeforeTreeSelected_);b.onAfterSelected(this.handleAfterTreeSelected_);var c=null;if(a){this.tree_.blocks=[];this.hasColours_=!1;c=this.syncTrees_(a,this.tree_,this.workspace_.options.pathToMedia);if(this.tree_.blocks.length)throw Error("Toolbox cannot have both blocks and categories in the root level.");this.workspace_.resizeContents()}b.render(this.HtmlDiv);
+c&&b.setSelectedItem(c);this.addColour_();this.position();this.horizontalLayout_&&Blockly.utils.aria.setState(this.tree_.getElement(),Blockly.utils.aria.State.ORIENTATION,"horizontal")};Blockly.Toolbox.prototype.handleBeforeTreeSelected_=function(a){if(a==this.tree_)return!1;this.lastCategory_&&(this.lastCategory_.getRowElement().style.backgroundColor="");if(a){var b=a.hexColour||"#57e";a.getRowElement().style.backgroundColor=b;this.addColour_(a)}return!0};
Blockly.Toolbox.prototype.handleAfterTreeSelected_=function(a,b){b&&b.blocks&&b.blocks.length?(this.flyout_.show(b.blocks),this.lastCategory_!=b&&this.flyout_.scrollToStart(),this.workspace_.keyboardAccessibilityMode&&Blockly.navigation.setState(Blockly.navigation.STATE_TOOLBOX)):(this.flyout_.hide(),!this.workspace_.keyboardAccessibilityMode||b instanceof Blockly.Toolbox.TreeSeparator||Blockly.navigation.setState(Blockly.navigation.STATE_WS));a!=b&&a!=this&&(a=new Blockly.Events.Ui(null,"category",
-a&&a.getText(),b&&b.getText()),a.workspaceId=this.workspace_.id,Blockly.Events.fire(a));b&&(this.lastCategory_=b)};Blockly.Toolbox.prototype.handleNodeSizeChanged_=function(){Blockly.svgResize(this.workspace_)};
+a&&a.content,b&&b.content),a.workspaceId=this.workspace_.id,Blockly.Events.fire(a));b&&(this.lastCategory_=b)};Blockly.Toolbox.prototype.handleNodeSizeChanged_=function(){Blockly.svgResize(this.workspace_)};
Blockly.Toolbox.prototype.onBlocklyAction=function(a){var b=this.tree_.getSelectedItem();if(!b)return!1;switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return b.selectPrevious();case Blockly.navigation.actionNames.OUT:return b.selectParent();case Blockly.navigation.actionNames.NEXT:return b.selectNext();case Blockly.navigation.actionNames.IN:return b.selectChild();default:return!1}};
Blockly.Toolbox.prototype.dispose=function(){this.flyout_.dispose();this.tree_.dispose();this.workspace_.getThemeManager().unsubscribe(this.HtmlDiv);Blockly.utils.dom.removeNode(this.HtmlDiv);this.lastCategory_=null};Blockly.Toolbox.prototype.getWidth=function(){return this.width};Blockly.Toolbox.prototype.getHeight=function(){return this.height};Blockly.Toolbox.prototype.getFlyout=function(){return this.flyout_};
Blockly.Toolbox.prototype.position=function(){var a=this.HtmlDiv;if(a){var b=Blockly.svgSize(this.workspace_.getParentSvg());this.horizontalLayout_?(a.style.left="0",a.style.height="auto",a.style.width=b.width+"px",this.height=a.offsetHeight,this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?a.style.top="0":a.style.bottom="0"):(this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?a.style.right="0":a.style.left="0",a.style.height=b.height+"px",this.width=a.offsetWidth);this.flyout_.position()}};
@@ -914,26 +923,27 @@ Blockly.Toolbox.prototype.updateColourFromTheme=function(){var a=this.tree_;a&&(
Blockly.Toolbox.prototype.addColour_=function(a){a=(a||this.tree_).getChildren(!1);for(var b=0,c;c=a[b];b++){var d=c.getRowElement();if(d){var e=this.hasColours_?"8px solid "+(c.hexColour||"#ddd"):"none";this.workspace_.RTL?d.style.borderRight=e:d.style.borderLeft=e}this.addColour_(c)}};Blockly.Toolbox.prototype.clearSelection=function(){this.tree_.setSelectedItem(null)};Blockly.Toolbox.prototype.addStyle=function(a){Blockly.utils.dom.addClass(this.HtmlDiv,a)};
Blockly.Toolbox.prototype.removeStyle=function(a){Blockly.utils.dom.removeClass(this.HtmlDiv,a)};
Blockly.Toolbox.prototype.getClientRect=function(){if(!this.HtmlDiv)return null;var a=this.HtmlDiv.getBoundingClientRect(),b=a.top,c=b+a.height,d=a.left;a=d+a.width;return this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?new Blockly.utils.Rect(-1E7,c,-1E7,1E7):this.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM?new Blockly.utils.Rect(b,1E7,-1E7,1E7):this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT?new Blockly.utils.Rect(-1E7,1E7,-1E7,a):new Blockly.utils.Rect(-1E7,1E7,d,1E7)};
-Blockly.Toolbox.prototype.refreshSelection=function(){var a=this.tree_.getSelectedItem();a&&a.blocks&&this.flyout_.show(a.blocks)};Blockly.Toolbox.prototype.selectFirstCategory=function(){this.tree_.getSelectedItem()||this.tree_.selectFirst()};Blockly.Toolbox.TreeSeparator=function(a){Blockly.tree.TreeNode.call(this,null,"",a)};Blockly.utils.object.inherits(Blockly.Toolbox.TreeSeparator,Blockly.tree.TreeNode);
+Blockly.Toolbox.prototype.refreshSelection=function(){var a=this.tree_.getSelectedItem();a&&a.blocks&&this.flyout_.show(a.blocks)};Blockly.Toolbox.prototype.selectFirstCategory=function(){this.tree_.getSelectedItem()||this.tree_.selectChild()};Blockly.Toolbox.TreeSeparator=function(a){Blockly.tree.TreeNode.call(this,null,"",a)};Blockly.utils.object.inherits(Blockly.Toolbox.TreeSeparator,Blockly.tree.TreeNode);
Blockly.Css.register([".blocklyToolboxDelete {",'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyToolboxGrab {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyToolboxDiv {","background-color: #ddd;","overflow-x: visible;","overflow-y: auto;","position: absolute;","z-index: 70;","-webkit-tap-highlight-color: transparent;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {",
-"height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;",
-"}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;","}",".blocklyTreeIconClosedRtl {","background-position: 0 -1px;","}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {",
+"height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: rgba(255, 255, 255, 0.2);","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;",
+"margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;","}",".blocklyTreeIconClosedRtl {","background-position: 0 -1px;","}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {",
"background-position: -32px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedRtl {","background-position: 0 -17px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeIconNone,",".blocklyTreeSelected>.blocklyTreeIconNone {","background-position: -48px -1px;","}",".blocklyTreeLabel {","cursor: default;","font-family: sans-serif;","font-size: 16px;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",
-'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}"]);Blockly.Trashcan=function(a){this.workspace_=a;this.contents_=[];this.flyout=null;if(!(0>=this.workspace_.options.maxTrashcanContents)){a=new Blockly.Options({scrollbars:!0,parentWorkspace:this.workspace_,rtl:this.workspace_.RTL,oneBasedIndex:this.workspace_.options.oneBasedIndex,renderer:this.workspace_.options.renderer});if(this.workspace_.horizontalLayout){a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_TOP?Blockly.TOOLBOX_AT_BOTTOM:Blockly.TOOLBOX_AT_TOP;if(!Blockly.HorizontalFlyout)throw Error("Missing require for Blockly.HorizontalFlyout");
-this.flyout=new Blockly.HorizontalFlyout(a)}else{a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?Blockly.TOOLBOX_AT_LEFT:Blockly.TOOLBOX_AT_RIGHT;if(!Blockly.VerticalFlyout)throw Error("Missing require for Blockly.VerticalFlyout");this.flyout=new Blockly.VerticalFlyout(a)}this.workspace_.addChangeListener(this.onDelete_.bind(this))}};Blockly.Trashcan.prototype.WIDTH_=47;Blockly.Trashcan.prototype.BODY_HEIGHT_=44;Blockly.Trashcan.prototype.LID_HEIGHT_=16;
-Blockly.Trashcan.prototype.MARGIN_BOTTOM_=20;Blockly.Trashcan.prototype.MARGIN_SIDE_=20;Blockly.Trashcan.prototype.MARGIN_HOTSPOT_=10;Blockly.Trashcan.prototype.SPRITE_LEFT_=0;Blockly.Trashcan.prototype.SPRITE_TOP_=32;Blockly.Trashcan.prototype.HAS_BLOCKS_LID_ANGLE=.1;Blockly.Trashcan.prototype.isOpen=!1;Blockly.Trashcan.prototype.minOpenness_=0;Blockly.Trashcan.prototype.svgGroup_=null;Blockly.Trashcan.prototype.svgLid_=null;Blockly.Trashcan.prototype.lidTask_=0;
-Blockly.Trashcan.prototype.lidOpen_=0;Blockly.Trashcan.prototype.left_=0;Blockly.Trashcan.prototype.top_=0;
+'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}"]);Blockly.Trashcan=function(a){this.workspace_=a;this.contents_=[];this.flyout=null;if(!(0>=this.workspace_.options.maxTrashcanContents)){a=new Blockly.Options({scrollbars:!0,parentWorkspace:this.workspace_,rtl:this.workspace_.RTL,oneBasedIndex:this.workspace_.options.oneBasedIndex,renderer:this.workspace_.options.renderer,rendererOverrides:this.workspace_.options.rendererOverrides});if(this.workspace_.horizontalLayout){a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_TOP?Blockly.TOOLBOX_AT_BOTTOM:
+Blockly.TOOLBOX_AT_TOP;if(!Blockly.HorizontalFlyout)throw Error("Missing require for Blockly.HorizontalFlyout");this.flyout=new Blockly.HorizontalFlyout(a)}else{a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?Blockly.TOOLBOX_AT_LEFT:Blockly.TOOLBOX_AT_RIGHT;if(!Blockly.VerticalFlyout)throw Error("Missing require for Blockly.VerticalFlyout");this.flyout=new Blockly.VerticalFlyout(a)}this.workspace_.addChangeListener(this.onDelete_.bind(this))}};
+Blockly.Trashcan.prototype.WIDTH_=47;Blockly.Trashcan.prototype.BODY_HEIGHT_=44;Blockly.Trashcan.prototype.LID_HEIGHT_=16;Blockly.Trashcan.prototype.MARGIN_BOTTOM_=20;Blockly.Trashcan.prototype.MARGIN_SIDE_=20;Blockly.Trashcan.prototype.MARGIN_HOTSPOT_=10;Blockly.Trashcan.prototype.SPRITE_LEFT_=0;Blockly.Trashcan.prototype.SPRITE_TOP_=32;Blockly.Trashcan.prototype.HAS_BLOCKS_LID_ANGLE_=.1;Blockly.Trashcan.ANIMATION_LENGTH_=80;Blockly.Trashcan.ANIMATION_FRAMES_=4;Blockly.Trashcan.OPACITY_MIN_=.4;
+Blockly.Trashcan.OPACITY_MAX_=.8;Blockly.Trashcan.MAX_LID_ANGLE_=45;Blockly.Trashcan.prototype.isOpen=!1;Blockly.Trashcan.prototype.minOpenness_=0;Blockly.Trashcan.prototype.svgGroup_=null;Blockly.Trashcan.prototype.svgLid_=null;Blockly.Trashcan.prototype.lidTask_=0;Blockly.Trashcan.prototype.lidOpen_=0;Blockly.Trashcan.prototype.left_=0;Blockly.Trashcan.prototype.top_=0;
Blockly.Trashcan.prototype.createDom=function(){this.svgGroup_=Blockly.utils.dom.createSvgElement("g",{"class":"blocklyTrash"},null);var a=String(Math.random()).substring(2);var b=Blockly.utils.dom.createSvgElement("clipPath",{id:"blocklyTrashBodyClipPath"+a},this.svgGroup_);Blockly.utils.dom.createSvgElement("rect",{width:this.WIDTH_,height:this.BODY_HEIGHT_,y:this.LID_HEIGHT_},b);var c=Blockly.utils.dom.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,
y:-this.SPRITE_TOP_,"clip-path":"url(#blocklyTrashBodyClipPath"+a+")"},this.svgGroup_);c.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);b=Blockly.utils.dom.createSvgElement("clipPath",{id:"blocklyTrashLidClipPath"+a},this.svgGroup_);Blockly.utils.dom.createSvgElement("rect",{width:this.WIDTH_,height:this.LID_HEIGHT_},b);this.svgLid_=Blockly.utils.dom.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,
y:-this.SPRITE_TOP_,"clip-path":"url(#blocklyTrashLidClipPath"+a+")"},this.svgGroup_);this.svgLid_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.click);Blockly.bindEvent_(c,"mouseover",this,this.mouseOver_);Blockly.bindEvent_(c,"mouseout",this,this.mouseOut_);this.animateLid_();return this.svgGroup_};
Blockly.Trashcan.prototype.init=function(a){0this.minOpenness_&&1>this.lidOpen_&&(this.lidTask_=setTimeout(this.animateLid_.bind(this),20))};
-Blockly.Trashcan.prototype.setLidAngle_=function(a){var b=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT||this.workspace_.horizontalLayout&&this.workspace_.RTL;this.svgLid_.setAttribute("transform","rotate("+(b?-a:a)+","+(b?4:this.WIDTH_-4)+","+(this.LID_HEIGHT_-2)+")")};Blockly.Trashcan.prototype.close=function(){this.setOpen(!1)};Blockly.Trashcan.prototype.click=function(){if(this.contents_.length){for(var a=[],b=0,c;c=this.contents_[b];b++)a[b]=Blockly.Xml.textToDom(c);this.flyout.show(a)}};
-Blockly.Trashcan.prototype.mouseOver_=function(){this.contents_.length&&this.setOpen(!0)};Blockly.Trashcan.prototype.mouseOut_=function(){this.setOpen(!1)};
-Blockly.Trashcan.prototype.onDelete_=function(a){if(!(0>=this.workspace_.options.maxTrashcanContents)&&a.type==Blockly.Events.BLOCK_DELETE&&"shadow"!=a.oldXml.tagName.toLowerCase()&&(a=this.cleanBlockXML_(a.oldXml),-1==this.contents_.indexOf(a))){for(this.contents_.unshift(a);this.contents_.length>this.workspace_.options.maxTrashcanContents;)this.contents_.pop();this.minOpenness_=this.HAS_BLOCKS_LID_ANGLE;this.setLidAngle_(45*this.minOpenness_)}};
+Blockly.Trashcan.prototype.setOpen=function(a){this.isOpen!=a&&(clearTimeout(this.lidTask_),this.isOpen=a,this.animateLid_())};
+Blockly.Trashcan.prototype.animateLid_=function(){var a=Blockly.Trashcan.ANIMATION_FRAMES_,b=1/(a+1);this.lidOpen_+=this.isOpen?b:-b;this.lidOpen_=Math.min(Math.max(this.lidOpen_,this.minOpenness_),1);this.setLidAngle_(this.lidOpen_*Blockly.Trashcan.MAX_LID_ANGLE_);b=Blockly.Trashcan.OPACITY_MIN_;this.svgGroup_.style.opacity=b+this.lidOpen_*(Blockly.Trashcan.OPACITY_MAX_-b);this.lidOpen_>this.minOpenness_&&1>this.lidOpen_&&(this.lidTask_=setTimeout(this.animateLid_.bind(this),Blockly.Trashcan.ANIMATION_LENGTH_/
+a))};Blockly.Trashcan.prototype.setLidAngle_=function(a){var b=this.workspace_.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT||this.workspace_.horizontalLayout&&this.workspace_.RTL;this.svgLid_.setAttribute("transform","rotate("+(b?-a:a)+","+(b?4:this.WIDTH_-4)+","+(this.LID_HEIGHT_-2)+")")};Blockly.Trashcan.prototype.setMinOpenness_=function(a){this.minOpenness_=a;this.isOpen||this.setLidAngle_(a*Blockly.Trashcan.MAX_LID_ANGLE_)};Blockly.Trashcan.prototype.close=function(){this.setOpen(!1)};
+Blockly.Trashcan.prototype.click=function(){if(this.contents_.length){for(var a=[],b=0,c;c=this.contents_[b];b++)a[b]=Blockly.Xml.textToDom(c);this.flyout.show(a)}};Blockly.Trashcan.prototype.mouseOver_=function(){this.contents_.length&&this.setOpen(!0)};Blockly.Trashcan.prototype.mouseOut_=function(){this.setOpen(!1)};
+Blockly.Trashcan.prototype.onDelete_=function(a){if(!(0>=this.workspace_.options.maxTrashcanContents)&&a.type==Blockly.Events.BLOCK_DELETE&&"shadow"!=a.oldXml.tagName.toLowerCase()&&(a=this.cleanBlockXML_(a.oldXml),-1==this.contents_.indexOf(a))){for(this.contents_.unshift(a);this.contents_.length>this.workspace_.options.maxTrashcanContents;)this.contents_.pop();this.setMinOpenness_(this.HAS_BLOCKS_LID_ANGLE_)}};
Blockly.Trashcan.prototype.cleanBlockXML_=function(a){for(var b=a=a.cloneNode(!0);b;){b.removeAttribute&&(b.removeAttribute("x"),b.removeAttribute("y"),b.removeAttribute("id"),b.removeAttribute("disabled"),"comment"==b.nodeName&&(b.removeAttribute("h"),b.removeAttribute("w"),b.removeAttribute("pinned")));var c=b.firstChild||b.nextSibling;if(!c)for(c=b.parentNode;c;){if(c.nextSibling){c=c.nextSibling;break}c=c.parentNode}b=c}return Blockly.Xml.domToText(a)};Blockly.VariablesDynamic={};Blockly.VariablesDynamic.onCreateVariableButtonClick_String=function(a){Blockly.Variables.createVariableButtonHandler(a.getTargetWorkspace(),void 0,"String")};Blockly.VariablesDynamic.onCreateVariableButtonClick_Number=function(a){Blockly.Variables.createVariableButtonHandler(a.getTargetWorkspace(),void 0,"Number")};Blockly.VariablesDynamic.onCreateVariableButtonClick_Colour=function(a){Blockly.Variables.createVariableButtonHandler(a.getTargetWorkspace(),void 0,"Colour")};
Blockly.VariablesDynamic.flyoutCategory=function(a){var b=[],c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_STRING_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_STRING");b.push(c);c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_NUMBER_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_NUMBER");b.push(c);c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_COLOUR_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_COLOUR");
b.push(c);a.registerButtonCallback("CREATE_VARIABLE_STRING",Blockly.VariablesDynamic.onCreateVariableButtonClick_String);a.registerButtonCallback("CREATE_VARIABLE_NUMBER",Blockly.VariablesDynamic.onCreateVariableButtonClick_Number);a.registerButtonCallback("CREATE_VARIABLE_COLOUR",Blockly.VariablesDynamic.onCreateVariableButtonClick_Colour);a=Blockly.VariablesDynamic.flyoutCategoryBlocks(a);return b=b.concat(a)};
@@ -952,8 +962,8 @@ Blockly.Css.register([".blocklyZoom>image, .blocklyZoom>svg>image {","opacity: .
Blockly.Mutator.prototype.drawIcon_=function(a){Blockly.utils.dom.createSvgElement("rect",{"class":"blocklyIconShape",rx:"4",ry:"4",height:"16",width:"16"},a);Blockly.utils.dom.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 -0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z"},
a);Blockly.utils.dom.createSvgElement("circle",{"class":"blocklyIconShape",r:"2.7",cx:"8",cy:"8"},a)};Blockly.Mutator.prototype.iconClick_=function(a){this.block_.isEditable()&&Blockly.Icon.prototype.iconClick_.call(this,a)};
Blockly.Mutator.prototype.createEditor_=function(){this.svgDialog_=Blockly.utils.dom.createSvgElement("svg",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);if(this.quarkNames_.length)for(var a=Blockly.utils.xml.createElement("xml"),b=0,c;c=this.quarkNames_[b];b++){var d=Blockly.utils.xml.createElement("block");d.setAttribute("type",c);a.appendChild(d)}else a=null;b=new Blockly.Options({disable:!1,parentWorkspace:this.block_.workspace,media:this.block_.workspace.options.pathToMedia,
-rtl:this.block_.RTL,horizontalLayout:!1,renderer:this.block_.workspace.options.renderer});b.toolboxPosition=this.block_.RTL?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT;b.languageTree=a;b.getMetrics=this.getFlyoutMetrics_.bind(this);this.workspace_=new Blockly.WorkspaceSvg(b);this.workspace_.isMutator=!0;this.workspace_.addChangeListener(Blockly.Events.disableOrphans);a=this.workspace_.addFlyout("g");b=this.workspace_.createDom("blocklyMutatorBackground");b.insertBefore(a,this.workspace_.svgBlockCanvas_);
-this.svgDialog_.appendChild(b);return this.svgDialog_};Blockly.Mutator.prototype.updateEditable=function(){Blockly.Mutator.superClass_.updateEditable.call(this);this.block_.isInFlyout||(this.block_.isEditable()?this.iconGroup_&&Blockly.utils.dom.removeClass(this.iconGroup_,"blocklyIconGroupReadonly"):(this.setVisible(!1),this.iconGroup_&&Blockly.utils.dom.addClass(this.iconGroup_,"blocklyIconGroupReadonly")))};
+rtl:this.block_.RTL,horizontalLayout:!1,renderer:this.block_.workspace.options.renderer,rendererOverrides:this.block_.workspace.options.rendererOverrides});b.toolboxPosition=this.block_.RTL?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT;b.languageTree=a;b.getMetrics=this.getFlyoutMetrics_.bind(this);this.workspace_=new Blockly.WorkspaceSvg(b);this.workspace_.isMutator=!0;this.workspace_.addChangeListener(Blockly.Events.disableOrphans);a=this.workspace_.addFlyout("g");b=this.workspace_.createDom("blocklyMutatorBackground");
+b.insertBefore(a,this.workspace_.svgBlockCanvas_);this.svgDialog_.appendChild(b);return this.svgDialog_};Blockly.Mutator.prototype.updateEditable=function(){Blockly.Mutator.superClass_.updateEditable.call(this);this.block_.isInFlyout||(this.block_.isEditable()?this.iconGroup_&&Blockly.utils.dom.removeClass(this.iconGroup_,"blocklyIconGroupReadonly"):(this.setVisible(!1),this.iconGroup_&&Blockly.utils.dom.addClass(this.iconGroup_,"blocklyIconGroupReadonly")))};
Blockly.Mutator.prototype.resizeBubble_=function(){var a=2*Blockly.Bubble.BORDER_WIDTH,b=this.workspace_.getCanvas().getBBox();var c=this.block_.RTL?-b.x:b.width+b.x;b=b.height+3*a;var d=this.workspace_.getFlyout();d&&(d=d.getMetrics_(),b=Math.max(b,d.contentHeight+20));c+=3*a;if(Math.abs(this.workspaceWidth_-c)>a||Math.abs(this.workspaceHeight_-b)>a)this.workspaceWidth_=c,this.workspaceHeight_=b,this.bubble_.setBubbleSize(c+a,b+a),this.svgDialog_.setAttribute("width",this.workspaceWidth_),this.svgDialog_.setAttribute("height",
this.workspaceHeight_);this.block_.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a));this.workspace_.resize()};Blockly.Mutator.prototype.onBubbleMove_=function(){this.workspace_&&this.workspace_.recordDeleteAreas()};
Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"mutatorOpen",!a,a)),a){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.pathObject.svgPath,this.iconXY_,null,null);this.bubble_.setSvgId(this.block_.id);this.bubble_.registerMoveEvent(this.onBubbleMove_.bind(this));var b=this.workspace_.options.languageTree;a=this.workspace_.getFlyout();b&&(a.init(this.workspace_),a.show(b.childNodes));
@@ -965,14 +975,14 @@ Blockly.Mutator.prototype.getFlyoutMetrics_=function(){return{viewHeight:this.wo
Blockly.Mutator.prototype.updateBlockStyle=function(){var a=this.workspace_;if(a&&a.getAllBlocks(!1)){for(var b=a.getAllBlocks(!1),c=0;c=a&&this.sourceBlock_.outputConnection&&!b}else this.fullBlockClickTarget_=!1;this.fullBlockClickTarget_?this.clickTarget_=this.sourceBlock_.getSvgRoot():this.createBorderRect_();this.createTextElement_()};
+Blockly.FieldTextInput.prototype.initView=function(){if(this.getConstants().FULL_BLOCK_FIELDS){for(var a=0,b=0,c=0,d;d=this.sourceBlock_.inputList[c];c++){for(var e=0;d.fieldRow[e];e++)a++;d.connection&&b++}this.fullBlockClickTarget_=1>=a&&this.sourceBlock_.outputConnection&&!b}else this.fullBlockClickTarget_=!1;this.fullBlockClickTarget_?this.clickTarget_=this.sourceBlock_.getSvgRoot():this.createBorderRect_();this.createTextElement_()};
Blockly.FieldTextInput.prototype.doClassValidation_=function(a){return null===a||void 0===a?null:String(a)};Blockly.FieldTextInput.prototype.doValueInvalid_=function(a){this.isBeingEdited_&&(this.isTextValid_=!1,a=this.value_,this.value_=this.htmlInput_.untypedDefaultValue_,this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name||null,a,this.value_)))};
-Blockly.FieldTextInput.prototype.doValueUpdate_=function(a){this.isTextValid_=!0;this.value_=a;this.isBeingEdited_||(this.isDirty_=!0)};Blockly.FieldTextInput.prototype.applyColour=function(){this.sourceBlock_&&this.constants_.FULL_BLOCK_FIELDS&&(this.borderRect_?this.borderRect_.setAttribute("stroke",this.sourceBlock_.style.colourTertiary):this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.constants_.FIELD_BORDER_RECT_COLOUR))};
+Blockly.FieldTextInput.prototype.doValueUpdate_=function(a){this.isTextValid_=!0;this.value_=a;this.isBeingEdited_||(this.isDirty_=!0)};Blockly.FieldTextInput.prototype.applyColour=function(){this.sourceBlock_&&this.getConstants().FULL_BLOCK_FIELDS&&(this.borderRect_?this.borderRect_.setAttribute("stroke",this.sourceBlock_.style.colourTertiary):this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.getConstants().FIELD_BORDER_RECT_COLOUR))};
Blockly.FieldTextInput.prototype.render_=function(){Blockly.FieldTextInput.superClass_.render_.call(this);if(this.isBeingEdited_){this.resizeEditor_();var a=this.htmlInput_;this.isTextValid_?(Blockly.utils.dom.removeClass(a,"blocklyInvalidInput"),Blockly.utils.aria.setState(a,Blockly.utils.aria.State.INVALID,!1)):(Blockly.utils.dom.addClass(a,"blocklyInvalidInput"),Blockly.utils.aria.setState(a,Blockly.utils.aria.State.INVALID,!0))}};
Blockly.FieldTextInput.prototype.setSpellcheck=function(a){a!=this.spellcheck_&&(this.spellcheck_=a,this.htmlInput_&&this.htmlInput_.setAttribute("spellcheck",this.spellcheck_))};Blockly.FieldTextInput.prototype.showEditor_=function(a,b){this.workspace_=this.sourceBlock_.workspace;a=b||!1;!a&&(Blockly.utils.userAgent.MOBILE||Blockly.utils.userAgent.ANDROID||Blockly.utils.userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};
Blockly.FieldTextInput.prototype.showPromptEditor_=function(){var a=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.getText(),function(b){a.setValue(b)})};Blockly.FieldTextInput.prototype.showInlineEditor_=function(a){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_.bind(this));this.htmlInput_=this.widgetCreate_();this.isBeingEdited_=!0;a||(this.htmlInput_.focus({preventScroll:!0}),this.htmlInput_.select())};
-Blockly.FieldTextInput.prototype.widgetCreate_=function(){var a=Blockly.WidgetDiv.DIV;Blockly.utils.dom.addClass(this.getClickTarget_(),"editing");var b=document.createElement("input");b.className="blocklyHtmlInput";b.setAttribute("spellcheck",this.spellcheck_);var c=this.workspace_.scale,d=this.constants_.FIELD_TEXT_FONTSIZE*c+"pt";a.style.fontSize=d;b.style.fontSize=d;d=Blockly.FieldTextInput.BORDERRADIUS*c+"px";if(this.fullBlockClickTarget_){d=this.getScaledBBox();d=(d.bottom-d.top)/2+"px";var e=
-this.sourceBlock_.getParent()?this.sourceBlock_.getParent().style.colourTertiary:this.sourceBlock_.style.colourTertiary;b.style.border=1*c+"px solid "+e;a.style.borderRadius=d;a.style.transition="box-shadow 0.25s ease 0s";this.constants_.FIELD_TEXTINPUT_BOX_SHADOW&&(a.style.boxShadow="rgba(255, 255, 255, 0.3) 0px 0px 0px "+4*c+"px")}b.style.borderRadius=d;a.appendChild(b);b.value=b.defaultValue=this.getEditorText_(this.value_);b.untypedDefaultValue_=this.value_;b.oldValue_=null;this.resizeEditor_();
+Blockly.FieldTextInput.prototype.widgetCreate_=function(){var a=Blockly.WidgetDiv.DIV;Blockly.utils.dom.addClass(this.getClickTarget_(),"editing");var b=document.createElement("input");b.className="blocklyHtmlInput";b.setAttribute("spellcheck",this.spellcheck_);var c=this.workspace_.getScale(),d=this.getConstants().FIELD_TEXT_FONTSIZE*c+"pt";a.style.fontSize=d;b.style.fontSize=d;d=Blockly.FieldTextInput.BORDERRADIUS*c+"px";if(this.fullBlockClickTarget_){d=this.getScaledBBox();d=(d.bottom-d.top)/2+
+"px";var e=this.sourceBlock_.getParent()?this.sourceBlock_.getParent().style.colourTertiary:this.sourceBlock_.style.colourTertiary;b.style.border=1*c+"px solid "+e;a.style.borderRadius=d;a.style.transition="box-shadow 0.25s ease 0s";this.getConstants().FIELD_TEXTINPUT_BOX_SHADOW&&(a.style.boxShadow="rgba(255, 255, 255, 0.3) 0px 0px 0px "+4*c+"px")}b.style.borderRadius=d;a.appendChild(b);b.value=b.defaultValue=this.getEditorText_(this.value_);b.untypedDefaultValue_=this.value_;b.oldValue_=null;this.resizeEditor_();
this.bindInputEvents_(b);return b};Blockly.FieldTextInput.prototype.widgetDispose_=function(){this.isBeingEdited_=!1;this.isTextValid_=!0;this.forceRerender();if(this.onFinishEditing_)this.onFinishEditing_(this.value_);this.unbindInputEvents_();var a=Blockly.WidgetDiv.DIV.style;a.width="auto";a.height="auto";a.fontSize="";a.transition="";a.boxShadow="";this.htmlInput_=null;Blockly.utils.dom.removeClass(this.getClickTarget_(),"editing")};
Blockly.FieldTextInput.prototype.bindInputEvents_=function(a){this.onKeyDownWrapper_=Blockly.bindEventWithChecks_(a,"keydown",this,this.onHtmlInputKeyDown_);this.onKeyInputWrapper_=Blockly.bindEventWithChecks_(a,"input",this,this.onHtmlInputChange_)};
Blockly.FieldTextInput.prototype.unbindInputEvents_=function(){this.onKeyDownWrapper_&&(Blockly.unbindEvent_(this.onKeyDownWrapper_),this.onKeyDownWrapper_=null);this.onKeyInputWrapper_&&(Blockly.unbindEvent_(this.onKeyInputWrapper_),this.onKeyInputWrapper_=null)};
@@ -995,15 +1005,14 @@ Blockly.FieldAngle.prototype.updateGraph_=function(){if(this.gauge_){var a=Numbe
Blockly.FieldAngle.RADIUS;b=Math.abs(Math.floor((b-f)/Math.PI)%2);e&&(b=1-b);a.push(" l ",g,",",h," A ",Blockly.FieldAngle.RADIUS,",",Blockly.FieldAngle.RADIUS," 0 ",b," ",e," ",c,",",d," z")}this.gauge_.setAttribute("d",a.join(""));this.line_.setAttribute("x2",c);this.line_.setAttribute("y2",d)}};
Blockly.FieldAngle.prototype.onHtmlInputKeyDown_=function(a){Blockly.FieldAngle.superClass_.onHtmlInputKeyDown_.call(this,a);var b;a.keyCode===Blockly.utils.KeyCodes.LEFT?b=this.sourceBlock_.RTL?1:-1:a.keyCode===Blockly.utils.KeyCodes.RIGHT?b=this.sourceBlock_.RTL?-1:1:a.keyCode===Blockly.utils.KeyCodes.DOWN?b=-1:a.keyCode===Blockly.utils.KeyCodes.UP&&(b=1);if(b){var c=this.getValue();this.displayMouseOrKeyboardValue_(c+b*this.round_);a.preventDefault();a.stopPropagation()}};
Blockly.FieldAngle.prototype.doClassValidation_=function(a){a=Number(a);return isNaN(a)||!isFinite(a)?null:this.wrapValue_(a)};Blockly.FieldAngle.prototype.wrapValue_=function(a){a%=360;0>a&&(a+=360);a>this.wrap_&&(a-=360);return a};Blockly.Css.register(".blocklyAngleCircle {,stroke: #444;,stroke-width: 1;,fill: #ddd;,fill-opacity: .8;,},.blocklyAngleMarks {,stroke: #444;,stroke-width: 1;,},.blocklyAngleGauge {,fill: #f88;,fill-opacity: .8;,pointer-events: none;,},.blocklyAngleLine {,stroke: #f00;,stroke-width: 2;,stroke-linecap: round;,pointer-events: none;,}".split(","));
-Blockly.fieldRegistry.register("field_angle",Blockly.FieldAngle);Blockly.FieldCheckbox=function(a,b,c){this.checkChar_=null;null==a&&(a="FALSE");Blockly.FieldCheckbox.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.fromJson=function(a){return new Blockly.FieldCheckbox(a.checked,void 0,a)};Blockly.FieldCheckbox.CHECK_CHAR="\u2713";Blockly.FieldCheckbox.prototype.SERIALIZABLE=!0;Blockly.FieldCheckbox.prototype.CURSOR="default";Blockly.FieldCheckbox.prototype.isDirty_=!1;
-Blockly.FieldCheckbox.prototype.configure_=function(a){Blockly.FieldCheckbox.superClass_.configure_.call(this,a);a.checkCharacter&&(this.checkChar_=a.checkCharacter)};
-Blockly.FieldCheckbox.prototype.initView=function(){this.size_.width=this.constants_.FIELD_CHECKBOX_DEFAULT_WIDTH;Blockly.FieldCheckbox.superClass_.initView.call(this);this.textElement_.setAttribute("x",this.constants_.FIELD_CHECKBOX_X_OFFSET);this.textElement_.setAttribute("y",this.constants_.FIELD_CHECKBOX_Y_OFFSET);this.textElement_.removeAttribute("dominant-baseline");Blockly.utils.dom.addClass(this.textElement_,"blocklyCheckbox");this.textContent_.nodeValue=this.checkChar_||Blockly.FieldCheckbox.CHECK_CHAR;
-this.textElement_.style.display=this.value_?"block":"none"};Blockly.FieldCheckbox.prototype.setCheckCharacter=function(a){this.checkChar_=a;this.textContent_&&(this.textContent_.nodeValue=a||Blockly.FieldCheckbox.CHECK_CHAR)};Blockly.FieldCheckbox.prototype.showEditor_=function(){this.setValue(!this.value_)};Blockly.FieldCheckbox.prototype.doClassValidation_=function(a){return!0===a||"TRUE"===a?"TRUE":!1===a||"FALSE"===a?"FALSE":null};
-Blockly.FieldCheckbox.prototype.doValueUpdate_=function(a){this.value_=this.convertValueToBool_(a);this.textElement_&&(this.textElement_.style.display=this.value_?"block":"none")};Blockly.FieldCheckbox.prototype.getValue=function(){return this.value_?"TRUE":"FALSE"};Blockly.FieldCheckbox.prototype.getValueBoolean=function(){return this.value_};Blockly.FieldCheckbox.prototype.getText=function(){return String(this.convertValueToBool_(this.value_))};
-Blockly.FieldCheckbox.prototype.convertValueToBool_=function(a){return"string"==typeof a?"TRUE"==a:!!a};Blockly.fieldRegistry.register("field_checkbox",Blockly.FieldCheckbox);Blockly.FieldColour=function(a,b,c){Blockly.FieldColour.superClass_.constructor.call(this,a||Blockly.FieldColour.COLOURS[0],b,c);this.onKeyDownWrapper_=this.onMouseLeaveWrapper_=this.onMouseEnterWrapper_=this.onMouseMoveWrapper_=this.onClickWrapper_=this.highlightedIndex_=this.picker_=null};Blockly.utils.object.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.fromJson=function(a){return new Blockly.FieldColour(a.colour,void 0,a)};Blockly.FieldColour.prototype.SERIALIZABLE=!0;
+Blockly.fieldRegistry.register("field_angle",Blockly.FieldAngle);Blockly.FieldCheckbox=function(a,b,c){this.checkChar_=null;null==a&&(a="FALSE");Blockly.FieldCheckbox.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.fromJson=function(a){return new Blockly.FieldCheckbox(a.checked,void 0,a)};Blockly.FieldCheckbox.CHECK_CHAR="\u2713";Blockly.FieldCheckbox.prototype.SERIALIZABLE=!0;Blockly.FieldCheckbox.prototype.CURSOR="default";
+Blockly.FieldCheckbox.prototype.configure_=function(a){Blockly.FieldCheckbox.superClass_.configure_.call(this,a);a.checkCharacter&&(this.checkChar_=a.checkCharacter)};Blockly.FieldCheckbox.prototype.initView=function(){Blockly.FieldCheckbox.superClass_.initView.call(this);Blockly.utils.dom.addClass(this.textElement_,"blocklyCheckbox");this.textElement_.style.display=this.value_?"block":"none"};
+Blockly.FieldCheckbox.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_());this.updateSize_(this.getConstants().FIELD_CHECKBOX_X_OFFSET)};Blockly.FieldCheckbox.prototype.getDisplayText_=function(){return this.checkChar_||Blockly.FieldCheckbox.CHECK_CHAR};Blockly.FieldCheckbox.prototype.setCheckCharacter=function(a){this.checkChar_=a;this.forceRerender()};Blockly.FieldCheckbox.prototype.showEditor_=function(){this.setValue(!this.value_)};
+Blockly.FieldCheckbox.prototype.doClassValidation_=function(a){return!0===a||"TRUE"===a?"TRUE":!1===a||"FALSE"===a?"FALSE":null};Blockly.FieldCheckbox.prototype.doValueUpdate_=function(a){this.value_=this.convertValueToBool_(a);this.textElement_&&(this.textElement_.style.display=this.value_?"block":"none")};Blockly.FieldCheckbox.prototype.getValue=function(){return this.value_?"TRUE":"FALSE"};Blockly.FieldCheckbox.prototype.getValueBoolean=function(){return this.value_};
+Blockly.FieldCheckbox.prototype.getText=function(){return String(this.convertValueToBool_(this.value_))};Blockly.FieldCheckbox.prototype.convertValueToBool_=function(a){return"string"==typeof a?"TRUE"==a:!!a};Blockly.fieldRegistry.register("field_checkbox",Blockly.FieldCheckbox);Blockly.FieldColour=function(a,b,c){Blockly.FieldColour.superClass_.constructor.call(this,a||Blockly.FieldColour.COLOURS[0],b,c);this.onKeyDownWrapper_=this.onMouseLeaveWrapper_=this.onMouseEnterWrapper_=this.onMouseMoveWrapper_=this.onClickWrapper_=this.highlightedIndex_=this.picker_=null};Blockly.utils.object.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.fromJson=function(a){return new Blockly.FieldColour(a.colour,void 0,a)};Blockly.FieldColour.prototype.SERIALIZABLE=!0;
Blockly.FieldColour.prototype.CURSOR="default";Blockly.FieldColour.prototype.isDirty_=!1;Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.titles_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.configure_=function(a){Blockly.FieldColour.superClass_.configure_.call(this,a);a.colourOptions&&(this.colours_=a.colourOptions,this.titles_=a.colourTitles);a.columns&&(this.columns_=a.columns)};
-Blockly.FieldColour.prototype.initView=function(){this.size_=new Blockly.utils.Size(this.constants_.FIELD_COLOUR_DEFAULT_WIDTH,this.constants_.FIELD_COLOUR_DEFAULT_HEIGHT);this.constants_.FIELD_COLOUR_FULL_BLOCK?this.clickTarget_=this.sourceBlock_.getSvgRoot():(this.createBorderRect_(),this.borderRect_.style.fillOpacity="1")};
-Blockly.FieldColour.prototype.applyColour=function(){this.constants_.FIELD_COLOUR_FULL_BLOCK?(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.getValue()),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff")):this.borderRect_&&(this.borderRect_.style.fill=this.getValue())};Blockly.FieldColour.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:Blockly.utils.colour.parse(a)};
+Blockly.FieldColour.prototype.initView=function(){this.size_=new Blockly.utils.Size(this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);this.getConstants().FIELD_COLOUR_FULL_BLOCK?this.clickTarget_=this.sourceBlock_.getSvgRoot():(this.createBorderRect_(),this.borderRect_.style.fillOpacity="1")};
+Blockly.FieldColour.prototype.applyColour=function(){this.getConstants().FIELD_COLOUR_FULL_BLOCK?(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.getValue()),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff")):this.borderRect_&&(this.borderRect_.style.fill=this.getValue())};Blockly.FieldColour.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:Blockly.utils.colour.parse(a)};
Blockly.FieldColour.prototype.doValueUpdate_=function(a){this.value_=a;this.borderRect_?this.borderRect_.style.fill=a:this.sourceBlock_&&(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",a),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff"))};Blockly.FieldColour.prototype.getText=function(){var a=this.value_;/^#(.)\1(.)\2(.)\3$/.test(a)&&(a="#"+a[1]+a[3]+a[5]);return a};Blockly.FieldColour.COLOURS="#ffffff #cccccc #c0c0c0 #999999 #666666 #333333 #000000 #ffcccc #ff6666 #ff0000 #cc0000 #990000 #660000 #330000 #ffcc99 #ff9966 #ff9900 #ff6600 #cc6600 #993300 #663300 #ffff99 #ffff66 #ffcc66 #ffcc33 #cc9933 #996633 #663333 #ffffcc #ffff33 #ffff00 #ffcc00 #999900 #666600 #333300 #99ff99 #66ff99 #33ff33 #33cc00 #009900 #006600 #003300 #99ffff #33ffff #66cccc #00cccc #339999 #336666 #003333 #ccffff #66ffff #33ccff #3366ff #3333ff #000099 #000066 #ccccff #9999ff #6666cc #6633ff #6600cc #333399 #330099 #ffccff #ff99ff #cc66cc #cc33cc #993399 #663366 #330033".split(" ");
Blockly.FieldColour.TITLES=[];Blockly.FieldColour.COLUMNS=7;Blockly.FieldColour.prototype.setColours=function(a,b){this.colours_=a;b&&(this.titles_=b);return this};Blockly.FieldColour.prototype.setColumns=function(a){this.columns_=a;return this};Blockly.FieldColour.prototype.showEditor_=function(){this.picker_=this.dropdownCreate_();Blockly.DropDownDiv.getContentDiv().appendChild(this.picker_);Blockly.DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.picker_.focus({preventScroll:!0})};
Blockly.FieldColour.prototype.onClick_=function(a){a=(a=a.target)&&a.label;null!==a&&(this.setValue(a),Blockly.DropDownDiv.hideIfOwner(this))};
@@ -1022,11 +1031,11 @@ this.onKeyDownWrapper_=null);this.highlightedIndex_=this.picker_=null};
Blockly.Css.register([".blocklyColourTable {","border-collapse: collapse;","display: block;","outline: none;","padding: 1px;","}",".blocklyColourTable>tr>td {","border: .5px solid #888;","box-sizing: border-box;","cursor: pointer;","display: inline-block;","height: 20px;","padding: 0;","width: 20px;","}",".blocklyColourTable>tr>td.blocklyColourHighlighted {","border-color: #eee;","box-shadow: 2px 2px 7px 2px rgba(0,0,0,.3);","position: relative;","}",".blocklyColourSelected, .blocklyColourSelected:hover {",
"border-color: #eee !important;","outline: 1px solid #333;","position: relative;","}"]);Blockly.fieldRegistry.register("field_colour",Blockly.FieldColour);Blockly.FieldDropdown=function(a,b,c){"function"!=typeof a&&Blockly.FieldDropdown.validateOptions_(a);this.menuGenerator_=a;this.generatedOptions_=null;this.trimOptions_();this.selectedOption_=this.getOptions(!1)[0];Blockly.FieldDropdown.superClass_.constructor.call(this,this.selectedOption_[1],b,c);this.svgArrow_=this.arrow_=this.imageElement_=this.menu_=this.selectedMenuItem_=null};Blockly.utils.object.inherits(Blockly.FieldDropdown,Blockly.Field);
Blockly.FieldDropdown.fromJson=function(a){return new Blockly.FieldDropdown(a.options,void 0,a)};Blockly.FieldDropdown.prototype.SERIALIZABLE=!0;Blockly.FieldDropdown.CHECKMARK_OVERHANG=25;Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH=.45;Blockly.FieldDropdown.IMAGE_Y_OFFSET=5;Blockly.FieldDropdown.IMAGE_Y_PADDING=2*Blockly.FieldDropdown.IMAGE_Y_OFFSET;Blockly.FieldDropdown.ARROW_CHAR=Blockly.utils.userAgent.ANDROID?"\u25bc":"\u25be";Blockly.FieldDropdown.prototype.CURSOR="default";
-Blockly.FieldDropdown.prototype.initView=function(){this.shouldAddBorderRect_()?this.createBorderRect_():this.clickTarget_=this.sourceBlock_.getSvgRoot();this.createTextElement_();this.imageElement_=Blockly.utils.dom.createSvgElement("image",{},this.fieldGroup_);this.constants_.FIELD_DROPDOWN_SVG_ARROW?this.createSVGArrow_():this.createTextArrow_();this.borderRect_&&Blockly.utils.dom.addClass(this.borderRect_,"blocklyDropdownRect")};
-Blockly.FieldDropdown.prototype.shouldAddBorderRect_=function(){return!this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW&&!this.sourceBlock_.isShadow()};
+Blockly.FieldDropdown.prototype.initView=function(){this.shouldAddBorderRect_()?this.createBorderRect_():this.clickTarget_=this.sourceBlock_.getSvgRoot();this.createTextElement_();this.imageElement_=Blockly.utils.dom.createSvgElement("image",{},this.fieldGroup_);this.getConstants().FIELD_DROPDOWN_SVG_ARROW?this.createSVGArrow_():this.createTextArrow_();this.borderRect_&&Blockly.utils.dom.addClass(this.borderRect_,"blocklyDropdownRect")};
+Blockly.FieldDropdown.prototype.shouldAddBorderRect_=function(){return!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW&&!this.sourceBlock_.isShadow()};
Blockly.FieldDropdown.prototype.createTextArrow_=function(){this.arrow_=Blockly.utils.dom.createSvgElement("tspan",{},this.textElement_);this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL?Blockly.FieldDropdown.ARROW_CHAR+" ":" "+Blockly.FieldDropdown.ARROW_CHAR));this.sourceBlock_.RTL?this.textElement_.insertBefore(this.arrow_,this.textContent_):this.textElement_.appendChild(this.arrow_)};
-Blockly.FieldDropdown.prototype.createSVGArrow_=function(){this.svgArrow_=Blockly.utils.dom.createSvgElement("image",{height:this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE+"px",width:this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE+"px"},this.fieldGroup_);this.svgArrow_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.constants_.FIELD_DROPDOWN_SVG_ARROW_DATAURI)};
-Blockly.FieldDropdown.prototype.showEditor_=function(a){this.menu_=this.dropdownCreate_();this.menu_.openingCoords=a&&"number"===typeof a.clientX?new Blockly.utils.Coordinate(a.clientX,a.clientY):null;this.menu_.render(Blockly.DropDownDiv.getContentDiv());Blockly.utils.dom.addClass(this.menu_.getElement(),"blocklyDropdownMenu");if(this.constants_.FIELD_DROPDOWN_COLOURED_DIV){a=this.sourceBlock_.isShadow()?this.sourceBlock_.getParent().getColour():this.sourceBlock_.getColour();var b=this.sourceBlock_.isShadow()?
+Blockly.FieldDropdown.prototype.createSVGArrow_=function(){this.svgArrow_=Blockly.utils.dom.createSvgElement("image",{height:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px",width:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px"},this.fieldGroup_);this.svgArrow_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.getConstants().FIELD_DROPDOWN_SVG_ARROW_DATAURI)};
+Blockly.FieldDropdown.prototype.showEditor_=function(a){this.menu_=this.dropdownCreate_();this.menu_.openingCoords=a&&"number"===typeof a.clientX?new Blockly.utils.Coordinate(a.clientX,a.clientY):null;this.menu_.render(Blockly.DropDownDiv.getContentDiv());Blockly.utils.dom.addClass(this.menu_.getElement(),"blocklyDropdownMenu");if(this.getConstants().FIELD_DROPDOWN_COLOURED_DIV){a=this.sourceBlock_.isShadow()?this.sourceBlock_.getParent().getColour():this.sourceBlock_.getColour();var b=this.sourceBlock_.isShadow()?
this.sourceBlock_.getParent().style.colourTertiary:this.sourceBlock_.style.colourTertiary;Blockly.DropDownDiv.setColour(a,b)}Blockly.DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.menu_.focus();this.selectedMenuItem_&&Blockly.utils.style.scrollIntoContainerView(this.selectedMenuItem_.getElement(),this.menu_.getElement());this.applyColour()};
Blockly.FieldDropdown.prototype.dropdownCreate_=function(){var a=new Blockly.Menu;a.setRightToLeft(this.sourceBlock_.RTL);a.setRole(Blockly.utils.aria.Role.LISTBOX);var b=this.getOptions(!1);this.selectedMenuItem_=null;for(var c=0;c=c||0>=b)throw Error("Height and width values of an image field must be greater than 0.");this.flipRtl_=!1;this.altText_="";Blockly.FieldImage.superClass_.constructor.call(this,
a||"",null,g);g||(this.flipRtl_=!!f,this.altText_=Blockly.utils.replaceMessageReferences(d)||"");this.size_=new Blockly.utils.Size(b,c+Blockly.FieldImage.Y_PADDING);this.imageHeight_=c;this.clickHandler_=null;"function"==typeof e&&(this.clickHandler_=e);this.imageElement_=null};Blockly.utils.object.inherits(Blockly.FieldImage,Blockly.Field);Blockly.FieldImage.fromJson=function(a){return new Blockly.FieldImage(a.src,a.width,a.height,void 0,void 0,void 0,a)};Blockly.FieldImage.Y_PADDING=1;
Blockly.FieldImage.prototype.EDITABLE=!1;Blockly.FieldImage.prototype.isDirty_=!1;Blockly.FieldImage.prototype.configure_=function(a){Blockly.FieldImage.superClass_.configure_.call(this,a);this.flipRtl_=!!a.flipRtl;this.altText_=Blockly.utils.replaceMessageReferences(a.alt)||""};
-Blockly.FieldImage.prototype.initView=function(){this.imageElement_=Blockly.utils.dom.createSvgElement("image",{height:this.imageHeight_+"px",width:this.size_.width+"px",alt:this.altText_},this.fieldGroup_);this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_)};Blockly.FieldImage.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:a};
-Blockly.FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",String(this.value_))};Blockly.FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_};Blockly.FieldImage.prototype.setAlt=function(a){a!=this.altText_&&(this.altText_=a||"",this.imageElement_&&this.imageElement_.setAttribute("alt",this.altText_))};Blockly.FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)};
-Blockly.FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};Blockly.FieldImage.prototype.getText_=function(){return this.altText_};Blockly.fieldRegistry.register("field_image",Blockly.FieldImage);Blockly.FieldMultilineInput=function(a,b,c){null==a&&(a="");Blockly.FieldMultilineInput.superClass_.constructor.call(this,a,b,c);this.textGroup_=null};Blockly.utils.object.inherits(Blockly.FieldMultilineInput,Blockly.FieldTextInput);Blockly.FieldMultilineInput.LINE_HEIGHT=20;Blockly.FieldMultilineInput.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldMultilineInput(b,void 0,a)};
+Blockly.FieldImage.prototype.initView=function(){this.imageElement_=Blockly.utils.dom.createSvgElement("image",{height:this.imageHeight_+"px",width:this.size_.width+"px",alt:this.altText_},this.fieldGroup_);this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_);this.clickHandler_&&(this.imageElement_.style.cursor="pointer")};Blockly.FieldImage.prototype.updateSize_=function(){};
+Blockly.FieldImage.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:a};Blockly.FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",String(this.value_))};Blockly.FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_};Blockly.FieldImage.prototype.setAlt=function(a){a!=this.altText_&&(this.altText_=a||"",this.imageElement_&&this.imageElement_.setAttribute("alt",this.altText_))};
+Blockly.FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)};Blockly.FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};Blockly.FieldImage.prototype.getText_=function(){return this.altText_};Blockly.fieldRegistry.register("field_image",Blockly.FieldImage);Blockly.FieldMultilineInput=function(a,b,c){null==a&&(a="");Blockly.FieldMultilineInput.superClass_.constructor.call(this,a,b,c);this.textGroup_=null};Blockly.utils.object.inherits(Blockly.FieldMultilineInput,Blockly.FieldTextInput);Blockly.FieldMultilineInput.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldMultilineInput(b,void 0,a)};
Blockly.FieldMultilineInput.prototype.initView=function(){this.createBorderRect_();this.textGroup_=Blockly.utils.dom.createSvgElement("g",{"class":"blocklyEditableText"},this.fieldGroup_)};
Blockly.FieldMultilineInput.prototype.getDisplayText_=function(){var a=this.value_;if(!a)return Blockly.Field.NBSP;var b=a.split("\n");a="";for(var c=0;cthis.maxDisplayLength&&(d=d.substring(0,this.maxDisplayLength-4)+"...");d=d.replace(/\s/g,Blockly.Field.NBSP);a+=d;c!==b.length-1&&(a+="\n")}this.sourceBlock_.RTL&&(a+="\u200f");return a};
-Blockly.FieldMultilineInput.prototype.render_=function(){for(var a;a=this.textGroup_.firstChild;)this.textGroup_.removeChild(a);a=this.getDisplayText_().split("\n");for(var b=0,c=0;cb&&(b=e);c+=Blockly.FieldMultilineInput.LINE_HEIGHT}this.borderRect_&&(b+=2*this.constants_.FIELD_BORDER_RECT_X_PADDING,this.borderRect_.setAttribute("width",b),this.borderRect_.setAttribute("height",c));this.size_.width=b;this.size_.height=c};
-Blockly.FieldMultilineInput.prototype.resizeEditor_=function(){var a=Blockly.WidgetDiv.DIV,b=this.getScaledBBox();a.style.width=b.right-b.left+"px";a.style.height=b.bottom-b.top+"px";b=new Blockly.utils.Coordinate(this.sourceBlock_.RTL?b.right-a.offsetWidth:b.left,b.top);a.style.left=b.x+"px";a.style.top=b.y+"px"};
-Blockly.FieldMultilineInput.prototype.widgetCreate_=function(){var a=Blockly.WidgetDiv.DIV,b=this.workspace_.scale,c=document.createElement("textarea");c.className="blocklyHtmlInput blocklyHtmlTextAreaInput";c.setAttribute("spellcheck",this.spellcheck_);var d=this.constants_.FIELD_TEXT_FONTSIZE*b+"pt";a.style.fontSize=d;c.style.fontSize=d;c.style.borderRadius=Blockly.FieldTextInput.BORDERRADIUS*b+"px";d=this.constants_.FIELD_BORDER_RECT_X_PADDING*b;c.style.paddingLeft=d+"px";c.style.width="calc(100% - "+
-d+"px)";c.style.lineHeight=Blockly.FieldMultilineInput.LINE_HEIGHT*b+"px";a.appendChild(c);c.value=c.defaultValue=this.getEditorText_(this.value_);c.untypedDefaultValue_=this.value_;c.oldValue_=null;Blockly.utils.userAgent.GECKO?setTimeout(this.resizeEditor_.bind(this),0):this.resizeEditor_();this.bindInputEvents_(c);return c};
+Blockly.FieldMultilineInput.prototype.render_=function(){for(var a;a=this.textGroup_.firstChild;)this.textGroup_.removeChild(a);a=this.getDisplayText_().split("\n");for(var b=0,c=0;cb&&(b=e);c+=this.getConstants().FIELD_TEXT_HEIGHT+(0this.max_&&Blockly.utils.aria.setState(a,Blockly.utils.aria.State.VALUEMAX,this.max_);return a};Blockly.fieldRegistry.register("field_number",Blockly.FieldNumber);Blockly.FieldVariable=function(a,b,c,d,e){this.menuGenerator_=Blockly.FieldVariable.dropdownCreate;this.defaultVariableName=a||"";this.size_=new Blockly.utils.Size(0,0);e&&this.configure_(e);b&&this.setValidator(b);e||this.setTypes_(c,d)};Blockly.utils.object.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);Blockly.FieldVariable.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.variable);return new Blockly.FieldVariable(b,void 0,void 0,void 0,a)};
Blockly.FieldVariable.prototype.workspace_=null;Blockly.FieldVariable.prototype.SERIALIZABLE=!0;Blockly.FieldVariable.prototype.configure_=function(a){Blockly.FieldVariable.superClass_.configure_.call(this,a);this.setTypes_(a.variableTypes,a.defaultType)};Blockly.FieldVariable.prototype.initModel=function(){if(!this.variable_){var a=Blockly.Variables.getOrCreateVariablePackage(this.sourceBlock_.workspace,null,this.defaultVariableName,this.defaultType_);this.doValueUpdate_(a.getId())}};
-Blockly.FieldVariable.prototype.shouldAddBorderRect_=function(){return Blockly.FieldVariable.superClass_.shouldAddBorderRect_.call(this)&&(!this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||"variables_get"!=this.sourceBlock_.type)};
+Blockly.FieldVariable.prototype.shouldAddBorderRect_=function(){return Blockly.FieldVariable.superClass_.shouldAddBorderRect_.call(this)&&(!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||"variables_get"!=this.sourceBlock_.type)};
Blockly.FieldVariable.prototype.fromXml=function(a){var b=a.getAttribute("id"),c=a.textContent,d=a.getAttribute("variabletype")||a.getAttribute("variableType")||"";b=Blockly.Variables.getOrCreateVariablePackage(this.sourceBlock_.workspace,b,c,d);if(null!=d&&d!==b.type)throw Error("Serialized variable type with id '"+b.getId()+"' had type "+b.type+", and does not match variable field that references it: "+Blockly.Xml.domToText(a)+".");this.setValue(b.getId())};
Blockly.FieldVariable.prototype.toXml=function(a){this.initModel();a.id=this.variable_.getId();a.textContent=this.variable_.name;this.variable_.type&&a.setAttribute("variabletype",this.variable_.type);return a};Blockly.FieldVariable.prototype.setSourceBlock=function(a){if(a.isShadow())throw Error("Variable fields are not allowed to exist on shadow blocks.");Blockly.FieldVariable.superClass_.setSourceBlock.call(this,a)};
Blockly.FieldVariable.prototype.getValue=function(){return this.variable_?this.variable_.getId():null};Blockly.FieldVariable.prototype.getText=function(){return this.variable_?this.variable_.name:""};Blockly.FieldVariable.prototype.getVariable=function(){return this.variable_};Blockly.FieldVariable.prototype.getValidator=function(){return this.variable_?this.validator_:null};
@@ -1082,15 +1091,20 @@ Blockly.Msg.DELETE_VARIABLE&&c.push([Blockly.Msg.DELETE_VARIABLE.replace("%1",a)
Blockly.FieldVariable.prototype.referencesVariables=function(){return!0};Blockly.fieldRegistry.register("field_variable",Blockly.FieldVariable);Blockly.utils.svgPaths={};Blockly.utils.svgPaths.point=function(a,b){return" "+a+","+b+" "};Blockly.utils.svgPaths.curve=function(a,b){return" "+a+b.join("")};Blockly.utils.svgPaths.moveTo=function(a,b){return" M "+a+","+b+" "};Blockly.utils.svgPaths.moveBy=function(a,b){return" m "+a+","+b+" "};Blockly.utils.svgPaths.lineTo=function(a,b){return" l "+a+","+b+" "};Blockly.utils.svgPaths.line=function(a){return" l"+a.join("")};Blockly.utils.svgPaths.lineOnAxis=function(a,b){return" "+a+" "+b+" "};
Blockly.utils.svgPaths.arc=function(a,b,c,d){return a+" "+c+" "+c+" "+b+d};Blockly.blockRendering.ConstantProvider=function(){this.NO_PADDING=0;this.SMALL_PADDING=3;this.MEDIUM_PADDING=5;this.MEDIUM_LARGE_PADDING=8;this.LARGE_PADDING=10;this.TALL_INPUT_FIELD_OFFSET_Y=this.MEDIUM_PADDING;this.TAB_HEIGHT=15;this.TAB_OFFSET_FROM_TOP=5;this.TAB_VERTICAL_OVERLAP=2.5;this.TAB_WIDTH=8;this.NOTCH_WIDTH=15;this.NOTCH_HEIGHT=4;this.MIN_BLOCK_WIDTH=12;this.EMPTY_BLOCK_SPACER_HEIGHT=16;this.DUMMY_INPUT_SHADOW_MIN_HEIGHT=this.DUMMY_INPUT_MIN_HEIGHT=this.TAB_HEIGHT;this.CORNER_RADIUS=
8;this.STATEMENT_INPUT_NOTCH_OFFSET=this.NOTCH_OFFSET_LEFT=15;this.STATEMENT_BOTTOM_SPACER=0;this.STATEMENT_INPUT_PADDING_LEFT=20;this.BETWEEN_STATEMENT_PADDING_Y=4;this.TOP_ROW_MIN_HEIGHT=this.MEDIUM_PADDING;this.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT=this.LARGE_PADDING;this.BOTTOM_ROW_MIN_HEIGHT=this.MEDIUM_PADDING;this.BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT=this.LARGE_PADDING;this.ADD_START_HATS=!1;this.START_HAT_HEIGHT=15;this.START_HAT_WIDTH=100;this.SPACER_DEFAULT_HEIGHT=15;this.MIN_BLOCK_HEIGHT=
-24;this.EMPTY_INLINE_INPUT_PADDING=14.5;this.EMPTY_INLINE_INPUT_HEIGHT=this.TAB_HEIGHT+11;this.EXTERNAL_VALUE_INPUT_PADDING=2;this.EMPTY_STATEMENT_INPUT_HEIGHT=this.MIN_BLOCK_HEIGHT;this.START_POINT=Blockly.utils.svgPaths.moveBy(0,0);this.JAGGED_TEETH_HEIGHT=12;this.JAGGED_TEETH_WIDTH=6;this.FIELD_TEXT_FONTSIZE=11;this.FIELD_TEXT_HEIGHT=16;this.FIELD_TEXT_FONTWEIGHT="normal";this.FIELD_TEXT_FONTFAMILY="sans-serif";this.FIELD_BORDER_RECT_RADIUS=4;this.FIELD_BORDER_RECT_HEIGHT=16;this.FIELD_BORDER_RECT_X_PADDING=
-5;this.FIELD_BORDER_RECT_Y_PADDING=3;this.FIELD_BORDER_RECT_COLOUR="#fff";this.FIELD_TEXT_BASELINE_Y=Blockly.utils.userAgent.GECKO?12:13.09;this.FIELD_TEXT_Y_OFFSET=0;this.FIELD_TEXT_BASELINE_CENTER=!Blockly.utils.userAgent.IE&&!Blockly.utils.userAgent.EDGE;this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT=this.FIELD_BORDER_RECT_HEIGHT;this.FIELD_DROPDOWN_SVG_ARROW=this.FIELD_DROPDOWN_COLOURED_DIV=this.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW=!1;this.FIELD_DROPDOWN_SVG_ARROW_PADDING=this.FIELD_BORDER_RECT_X_PADDING;
-this.FIELD_DROPDOWN_SVG_ARROW_SIZE=12;this.FIELD_DROPDOWN_SVG_ARROW_DATAURI="data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMi43MSIgaGVpZ2h0PSI4Ljc5IiB2aWV3Qm94PSIwIDAgMTIuNzEgOC43OSI+PHRpdGxlPmRyb3Bkb3duLWFycm93PC90aXRsZT48ZyBvcGFjaXR5PSIwLjEiPjxwYXRoIGQ9Ik0xMi43MSwyLjQ0QTIuNDEsMi40MSwwLDAsMSwxMiw0LjE2TDguMDgsOC4wOGEyLjQ1LDIuNDUsMCwwLDEtMy40NSwwTDAuNzIsNC4xNkEyLjQyLDIuNDIsMCwwLDEsMCwyLjQ0LDIuNDgsMi40OCwwLDAsMSwuNzEuNzFDMSwwLjQ3LDEuNDMsMCw2LjM2LDBTMTEuNzUsMC40NiwxMiwuNzFBMi40NCwyLjQ0LDAsMCwxLDEyLjcxLDIuNDRaIiBmaWxsPSIjMjMxZjIwIi8+PC9nPjxwYXRoIGQ9Ik02LjM2LDcuNzlhMS40MywxLjQzLDAsMCwxLTEtLjQyTDEuNDIsMy40NWExLjQ0LDEuNDQsMCwwLDEsMC0yYzAuNTYtLjU2LDkuMzEtMC41Niw5Ljg3LDBhMS40NCwxLjQ0LDAsMCwxLDAsMkw3LjM3LDcuMzdBMS40MywxLjQzLDAsMCwxLDYuMzYsNy43OVoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=";
-this.FIELD_COLOUR_FULL_BLOCK=this.FIELD_TEXTINPUT_BOX_SHADOW=!1;this.FIELD_COLOUR_DEFAULT_WIDTH=26;this.FIELD_COLOUR_DEFAULT_HEIGHT=this.FIELD_BORDER_RECT_HEIGHT;this.FIELD_CHECKBOX_X_OFFSET=this.FIELD_BORDER_RECT_X_PADDING-3;this.FIELD_CHECKBOX_Y_OFFSET=14;this.FIELD_CHECKBOX_DEFAULT_WIDTH=15;this.randomIdentifier_=String(Math.random()).substring(2);this.embossFilterId="";this.embossFilter_=null;this.disabledPatternId="";this.disabledPattern_=null;this.CURSOR_COLOUR="#cc0a0a";this.MARKER_COLOUR=
-"#4286f4";this.CURSOR_WS_WIDTH=100;this.WS_CURSOR_HEIGHT=5;this.CURSOR_STACK_PADDING=10;this.CURSOR_BLOCK_PADDING=2;this.CURSOR_STROKE_WIDTH=4;this.FULL_BLOCK_FIELDS=!1;this.SHAPES={PUZZLE:1,NOTCH:2}};Blockly.blockRendering.ConstantProvider.prototype.init=function(){this.JAGGED_TEETH=this.makeJaggedTeeth();this.NOTCH=this.makeNotch();this.START_HAT=this.makeStartHat();this.PUZZLE_TAB=this.makePuzzleTab();this.INSIDE_CORNERS=this.makeInsideCorners();this.OUTSIDE_CORNERS=this.makeOutsideCorners()};
-Blockly.blockRendering.ConstantProvider.prototype.refreshTheme=function(a){this.blockStyles={};a=a.blockStyles;for(var b in a)this.blockStyles[b]=this.validatedBlockStyle_(a[b])};Blockly.blockRendering.ConstantProvider.prototype.getBlockStyleForColour=function(a){var b="auto_"+a;this.blockStyles[b]||(this.blockStyles[b]=this.createBlockStyle_(a));return{style:this.blockStyles[b],name:b}};Blockly.blockRendering.ConstantProvider.prototype.getBlockStyle=function(a){return this.blockStyles[a||""]||this.createBlockStyle_("#000000")};
-Blockly.blockRendering.ConstantProvider.prototype.createBlockStyle_=function(a){return this.validatedBlockStyle_({colourPrimary:a})};
+24;this.EMPTY_INLINE_INPUT_PADDING=14.5;this.EMPTY_INLINE_INPUT_HEIGHT=this.TAB_HEIGHT+11;this.EXTERNAL_VALUE_INPUT_PADDING=2;this.EMPTY_STATEMENT_INPUT_HEIGHT=this.MIN_BLOCK_HEIGHT;this.START_POINT=Blockly.utils.svgPaths.moveBy(0,0);this.JAGGED_TEETH_HEIGHT=12;this.JAGGED_TEETH_WIDTH=6;this.FIELD_TEXT_FONTSIZE=11;this.FIELD_TEXT_FONTWEIGHT="normal";this.FIELD_TEXT_FONTFAMILY="sans-serif";this.FIELD_TEXT_BASELINE=this.FIELD_TEXT_HEIGHT=-1;this.FIELD_BORDER_RECT_RADIUS=4;this.FIELD_BORDER_RECT_HEIGHT=
+16;this.FIELD_BORDER_RECT_X_PADDING=5;this.FIELD_BORDER_RECT_Y_PADDING=3;this.FIELD_BORDER_RECT_COLOUR="#fff";this.FIELD_TEXT_BASELINE_CENTER=!Blockly.utils.userAgent.IE&&!Blockly.utils.userAgent.EDGE;this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT=this.FIELD_BORDER_RECT_HEIGHT;this.FIELD_DROPDOWN_SVG_ARROW=this.FIELD_DROPDOWN_COLOURED_DIV=this.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW=!1;this.FIELD_DROPDOWN_SVG_ARROW_PADDING=this.FIELD_BORDER_RECT_X_PADDING;this.FIELD_DROPDOWN_SVG_ARROW_SIZE=12;this.FIELD_DROPDOWN_SVG_ARROW_DATAURI=
+"data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMi43MSIgaGVpZ2h0PSI4Ljc5IiB2aWV3Qm94PSIwIDAgMTIuNzEgOC43OSI+PHRpdGxlPmRyb3Bkb3duLWFycm93PC90aXRsZT48ZyBvcGFjaXR5PSIwLjEiPjxwYXRoIGQ9Ik0xMi43MSwyLjQ0QTIuNDEsMi40MSwwLDAsMSwxMiw0LjE2TDguMDgsOC4wOGEyLjQ1LDIuNDUsMCwwLDEtMy40NSwwTDAuNzIsNC4xNkEyLjQyLDIuNDIsMCwwLDEsMCwyLjQ0LDIuNDgsMi40OCwwLDAsMSwuNzEuNzFDMSwwLjQ3LDEuNDMsMCw2LjM2LDBTMTEuNzUsMC40NiwxMiwuNzFBMi40NCwyLjQ0LDAsMCwxLDEyLjcxLDIuNDRaIiBmaWxsPSIjMjMxZjIwIi8+PC9nPjxwYXRoIGQ9Ik02LjM2LDcuNzlhMS40MywxLjQzLDAsMCwxLTEtLjQyTDEuNDIsMy40NWExLjQ0LDEuNDQsMCwwLDEsMC0yYzAuNTYtLjU2LDkuMzEtMC41Niw5Ljg3LDBhMS40NCwxLjQ0LDAsMCwxLDAsMkw3LjM3LDcuMzdBMS40MywxLjQzLDAsMCwxLDYuMzYsNy43OVoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=";
+this.FIELD_COLOUR_FULL_BLOCK=this.FIELD_TEXTINPUT_BOX_SHADOW=!1;this.FIELD_COLOUR_DEFAULT_WIDTH=26;this.FIELD_COLOUR_DEFAULT_HEIGHT=this.FIELD_BORDER_RECT_HEIGHT;this.FIELD_CHECKBOX_X_OFFSET=this.FIELD_BORDER_RECT_X_PADDING-3;this.randomIdentifier=String(Math.random()).substring(2);this.embossFilterId="";this.embossFilter_=null;this.disabledPatternId="";this.disabledPattern_=null;this.debugFilterId="";this.cssNode_=this.debugFilter_=null;this.CURSOR_COLOUR="#cc0a0a";this.MARKER_COLOUR="#4286f4";this.CURSOR_WS_WIDTH=
+100;this.WS_CURSOR_HEIGHT=5;this.CURSOR_STACK_PADDING=10;this.CURSOR_BLOCK_PADDING=2;this.CURSOR_STROKE_WIDTH=4;this.FULL_BLOCK_FIELDS=!1;this.INSERTION_MARKER_COLOUR="#000000";this.INSERTION_MARKER_OPACITY=.2;this.SHAPES={PUZZLE:1,NOTCH:2}};
+Blockly.blockRendering.ConstantProvider.prototype.init=function(){this.JAGGED_TEETH=this.makeJaggedTeeth();this.NOTCH=this.makeNotch();this.START_HAT=this.makeStartHat();this.PUZZLE_TAB=this.makePuzzleTab();this.INSIDE_CORNERS=this.makeInsideCorners();this.OUTSIDE_CORNERS=this.makeOutsideCorners()};Blockly.blockRendering.ConstantProvider.prototype.setTheme=function(a){this.blockStyles={};var b=a.blockStyles,c;for(c in b)this.blockStyles[c]=this.validatedBlockStyle_(b[c]);this.setDynamicProperties_(a)};
+Blockly.blockRendering.ConstantProvider.prototype.setDynamicProperties_=function(a){this.setFontConstants_(a);this.setComponentConstants_(a);this.ADD_START_HATS=null!=a.startHats?a.startHats:this.ADD_START_HATS};
+Blockly.blockRendering.ConstantProvider.prototype.setFontConstants_=function(a){this.FIELD_TEXT_FONTFAMILY=a.fontStyle&&void 0!=a.fontStyle.family?a.fontStyle.family:this.FIELD_TEXT_FONTFAMILY;this.FIELD_TEXT_FONTWEIGHT=a.fontStyle&&void 0!=a.fontStyle.weight?a.fontStyle.weight:this.FIELD_TEXT_FONTWEIGHT;this.FIELD_TEXT_FONTSIZE=a.fontStyle&&void 0!=a.fontStyle.size?a.fontStyle.size:this.FIELD_TEXT_FONTSIZE;a=Blockly.utils.dom.measureFontMetrics("Hg",this.FIELD_TEXT_FONTSIZE+"pt",this.FIELD_TEXT_FONTWEIGHT,
+this.FIELD_TEXT_FONTFAMILY);this.FIELD_TEXT_HEIGHT=a.height;this.FIELD_TEXT_BASELINE=a.baseline};
+Blockly.blockRendering.ConstantProvider.prototype.setComponentConstants_=function(a){this.CURSOR_COLOUR=a.getComponentStyle("cursorColour")||this.CURSOR_COLOUR;this.MARKER_COLOUR=a.getComponentStyle("markerColour")||this.MARKER_COLOUR;this.INSERTION_MARKER_COLOUR=a.getComponentStyle("insertionMarkerColour")||this.INSERTION_MARKER_COLOUR;this.INSERTION_MARKER_OPACITY=Number(a.getComponentStyle("insertionMarkerOpacity"))||this.INSERTION_MARKER_OPACITY};
+Blockly.blockRendering.ConstantProvider.prototype.getBlockStyleForColour=function(a){var b="auto_"+a;this.blockStyles[b]||(this.blockStyles[b]=this.createBlockStyle_(a));return{style:this.blockStyles[b],name:b}};Blockly.blockRendering.ConstantProvider.prototype.getBlockStyle=function(a){return this.blockStyles[a||""]||(a&&0==a.indexOf("auto_")?this.getBlockStyleForColour(a.substring(5)).style:this.createBlockStyle_("#000000"))};Blockly.blockRendering.ConstantProvider.prototype.createBlockStyle_=function(a){return this.validatedBlockStyle_({colourPrimary:a})};
Blockly.blockRendering.ConstantProvider.prototype.validatedBlockStyle_=function(a){var b={};a&&Blockly.utils.object.mixin(b,a);a=Blockly.utils.parseBlockColour(b.colourPrimary||"#000");b.colourPrimary=a.hex;b.colourSecondary=b.colourSecondary?Blockly.utils.parseBlockColour(b.colourSecondary).hex:this.generateSecondaryColour_(b.colourPrimary);b.colourTertiary=b.colourTertiary?Blockly.utils.parseBlockColour(b.colourTertiary).hex:this.generateTertiaryColour_(b.colourPrimary);b.hat=b.hat||"";return b};
-Blockly.blockRendering.ConstantProvider.prototype.generateSecondaryColour_=function(a){return Blockly.utils.colour.blend("#fff",a,.6)||a};Blockly.blockRendering.ConstantProvider.prototype.generateTertiaryColour_=function(a){return Blockly.utils.colour.blend("#fff",a,.3)||a};Blockly.blockRendering.ConstantProvider.prototype.dispose=function(){this.embossFilter_&&Blockly.utils.dom.removeNode(this.embossFilter_);this.disabledPattern_&&Blockly.utils.dom.removeNode(this.disabledPattern_)};
+Blockly.blockRendering.ConstantProvider.prototype.generateSecondaryColour_=function(a){return Blockly.utils.colour.blend("#fff",a,.6)||a};Blockly.blockRendering.ConstantProvider.prototype.generateTertiaryColour_=function(a){return Blockly.utils.colour.blend("#fff",a,.3)||a};
+Blockly.blockRendering.ConstantProvider.prototype.dispose=function(){this.embossFilter_&&Blockly.utils.dom.removeNode(this.embossFilter_);this.disabledPattern_&&Blockly.utils.dom.removeNode(this.disabledPattern_);this.debugFilter_&&Blockly.utils.dom.removeNode(this.debugFilter_);this.cssNode_=null};
Blockly.blockRendering.ConstantProvider.prototype.makeJaggedTeeth=function(){var a=this.JAGGED_TEETH_HEIGHT,b=this.JAGGED_TEETH_WIDTH,c=Blockly.utils.svgPaths.line([Blockly.utils.svgPaths.point(b,a/4),Blockly.utils.svgPaths.point(2*-b,a/2),Blockly.utils.svgPaths.point(b,a/4)]);return{height:a,width:b,path:c}};
Blockly.blockRendering.ConstantProvider.prototype.makeStartHat=function(){var a=this.START_HAT_HEIGHT,b=this.START_HAT_WIDTH,c=Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(30,-a),Blockly.utils.svgPaths.point(70,-a),Blockly.utils.svgPaths.point(b,0)]);return{height:a,width:b,path:c}};
Blockly.blockRendering.ConstantProvider.prototype.makePuzzleTab=function(){function a(a){a=a?-1:1;var d=-a,e=c/2,f=e+2.5,l=e+.5,m=Blockly.utils.svgPaths.point(-b,a*e);e=Blockly.utils.svgPaths.point(b,a*e);return Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(0,a*f),Blockly.utils.svgPaths.point(-b,d*l),m])+Blockly.utils.svgPaths.curve("s",[Blockly.utils.svgPaths.point(b,2.5*d),e])}var b=this.TAB_WIDTH,c=this.TAB_HEIGHT,d=a(!0),e=a(!1);return{type:this.SHAPES.PUZZLE,width:b,height:c,
@@ -1098,14 +1112,15 @@ pathDown:e,pathUp:d}};Blockly.blockRendering.ConstantProvider.prototype.makeNotc
Blockly.blockRendering.ConstantProvider.prototype.makeInsideCorners=function(){var a=this.CORNER_RADIUS,b=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(-a,a)),c=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(a,a));return{width:a,height:a,pathTop:b,pathBottom:c}};
Blockly.blockRendering.ConstantProvider.prototype.makeOutsideCorners=function(){var a=this.CORNER_RADIUS,b=Blockly.utils.svgPaths.moveBy(0,a)+Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(a,-a)),c=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(a,a)),d=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(-a,-a)),e=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(-a,a));return{topLeft:b,topRight:c,bottomRight:e,bottomLeft:d,
rightHeight:a}};Blockly.blockRendering.ConstantProvider.prototype.shapeFor=function(a){switch(a.type){case Blockly.INPUT_VALUE:case Blockly.OUTPUT_VALUE:return this.PUZZLE_TAB;case Blockly.PREVIOUS_STATEMENT:case Blockly.NEXT_STATEMENT:return this.NOTCH;default:throw Error("Unknown connection type");}};
-Blockly.blockRendering.ConstantProvider.prototype.createDom=function(a){a=Blockly.utils.dom.createSvgElement("defs",{},a);var b=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyEmbossFilter"+this.randomIdentifier_},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceAlpha",stdDeviation:1,result:"blur"},b);var c=Blockly.utils.dom.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",result:"specOut"},
-b);Blockly.utils.dom.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},c);Blockly.utils.dom.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},b);Blockly.utils.dom.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1,k4:0},b);this.embossFilterId=b.id;this.embossFilter_=b;a=Blockly.utils.dom.createSvgElement("pattern",{id:"blocklyDisabledPattern"+this.randomIdentifier_,patternUnits:"userSpaceOnUse",
-width:10,height:10},a);Blockly.utils.dom.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},a);Blockly.utils.dom.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},a);this.disabledPatternId=a.id;this.disabledPattern_=a};
-Blockly.blockRendering.ConstantProvider.prototype.injectCSS=function(a){var b=this.getCSS_(a);a="blockly-renderer-style-"+a;if(!document.getElementById(a)){var c=b.join("\n");b=document.createElement("style");b.id=a;a=document.createTextNode(c);b.appendChild(a);document.head.insertBefore(b,document.head.firstChild)}};
-Blockly.blockRendering.ConstantProvider.prototype.getCSS_=function(a){a="."+a+"-renderer";return[a+" .blocklyText {","fill: #fff;","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-size: "+this.FIELD_TEXT_FONTSIZE+"pt;","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklyNonEditableText>rect,",a+" .blocklyEditableText>rect {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","fill-opacity: .6;","stroke: none;","}",a+" .blocklyNonEditableText>text,",a+" .blocklyEditableText>text {","fill: #000;",
-"}",a+" .blocklyEditableText:not(.editing):hover>rect {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklySelected>.blocklyPath {","stroke: #fc3;","stroke-width: 3px;","}",a+" .blocklyHighlightedConnectionPath {","stroke: #fc3;","}",a+" .blocklyReplaceable .blocklyPath {","fill-opacity: .5;","}",a+" .blocklyReplaceable .blocklyPathLight,",a+" .blocklyReplaceable .blocklyPathDark {",
-"display: none;","}"]};Blockly.blockRendering.MarkerSvg=function(a,b,c){this.workspace_=a;this.marker_=c;this.parent_=null;this.constants_=b;this.currentMarkerSvg=null;a=this.isCursor()?this.constants_.CURSOR_COLOUR:this.constants_.MARKER_COLOUR;this.colour_=c.colour||a};Blockly.blockRendering.MarkerSvg.CURSOR_CLASS="blocklyCursor";Blockly.blockRendering.MarkerSvg.MARKER_CLASS="blocklyMarker";Blockly.blockRendering.MarkerSvg.HEIGHT_MULTIPLIER=.75;Blockly.blockRendering.MarkerSvg.prototype.getSvgRoot=function(){return this.svgGroup_};
-Blockly.blockRendering.MarkerSvg.prototype.isCursor=function(){return"cursor"==this.marker_.type};Blockly.blockRendering.MarkerSvg.prototype.createDom=function(){var a=this.isCursor()?Blockly.blockRendering.MarkerSvg.CURSOR_CLASS:Blockly.blockRendering.MarkerSvg.MARKER_CLASS;this.svgGroup_=Blockly.utils.dom.createSvgElement("g",{"class":a},null);this.createDomInternal_();return this.svgGroup_};
+Blockly.blockRendering.ConstantProvider.prototype.createDom=function(a,b,c){this.injectCSS_(b,c);a=Blockly.utils.dom.createSvgElement("defs",{},a);b=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyEmbossFilter"+this.randomIdentifier},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceAlpha",stdDeviation:1,result:"blur"},b);c=Blockly.utils.dom.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",
+result:"specOut"},b);Blockly.utils.dom.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},c);Blockly.utils.dom.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},b);Blockly.utils.dom.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1,k4:0},b);this.embossFilterId=b.id;this.embossFilter_=b;b=Blockly.utils.dom.createSvgElement("pattern",{id:"blocklyDisabledPattern"+this.randomIdentifier,patternUnits:"userSpaceOnUse",
+width:10,height:10},a);Blockly.utils.dom.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},b);Blockly.utils.dom.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},b);this.disabledPatternId=b.id;this.disabledPattern_=b;Blockly.blockRendering.Debug&&(a=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyDebugFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a),b=Blockly.utils.dom.createSvgElement("feComponentTransfer",{result:"outBlur"},a),Blockly.utils.dom.createSvgElement("feFuncA",
+{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},b),Blockly.utils.dom.createSvgElement("feFlood",{"flood-color":"#ff0000","flood-opacity":.5,result:"outColor"},a),Blockly.utils.dom.createSvgElement("feComposite",{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},a),this.debugFilterId=a.id,this.debugFilter_=a)};
+Blockly.blockRendering.ConstantProvider.prototype.injectCSS_=function(a,b){b=this.getCSS_(b);a="blockly-renderer-style-"+a;this.cssNode_=document.getElementById(a);var c=b.join("\n");this.cssNode_?this.cssNode_.firstChild.textContent=c:(b=document.createElement("style"),b.id=a,a=document.createTextNode(c),b.appendChild(a),document.head.insertBefore(b,document.head.firstChild),this.cssNode_=b)};
+Blockly.blockRendering.ConstantProvider.prototype.getCSS_=function(a){return[a+" .blocklyText, ",a+" .blocklyFlyoutLabelText {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-size: "+this.FIELD_TEXT_FONTSIZE+"pt;","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklyText {","fill: #fff;","}",a+" .blocklyNonEditableText>rect,",a+" .blocklyEditableText>rect {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","fill-opacity: .6;","stroke: none;","}",a+" .blocklyNonEditableText>text,",a+" .blocklyEditableText>text {",
+"fill: #000;","}",a+" .blocklyFlyoutLabelText {","fill: #000;","}",a+" .blocklyText.blocklyBubbleText {","fill: #000;","}",a+" .blocklyEditableText:not(.editing):hover>rect {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklySelected>.blocklyPath {","stroke: #fc3;","stroke-width: 3px;","}",a+" .blocklyHighlightedConnectionPath {","stroke: #fc3;","}",a+" .blocklyReplaceable .blocklyPath {",
+"fill-opacity: .5;","}",a+" .blocklyReplaceable .blocklyPathLight,",a+" .blocklyReplaceable .blocklyPathDark {","display: none;","}",a+" .blocklyInsertionMarker>.blocklyPath {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none","}"]};Blockly.blockRendering.MarkerSvg=function(a,b,c){this.workspace_=a;this.marker_=c;this.parent_=null;this.constants_=b;this.currentMarkerSvg=null;a=this.isCursor()?this.constants_.CURSOR_COLOUR:this.constants_.MARKER_COLOUR;this.colour_=c.colour||a};Blockly.blockRendering.MarkerSvg.CURSOR_CLASS="blocklyCursor";Blockly.blockRendering.MarkerSvg.MARKER_CLASS="blocklyMarker";Blockly.blockRendering.MarkerSvg.HEIGHT_MULTIPLIER=.75;Blockly.blockRendering.MarkerSvg.prototype.getSvgRoot=function(){return this.svgGroup_};
+Blockly.blockRendering.MarkerSvg.prototype.isCursor=function(){return"cursor"==this.marker_.type};Blockly.blockRendering.MarkerSvg.prototype.createDom=function(){var a=this.isCursor()?Blockly.blockRendering.MarkerSvg.CURSOR_CLASS:Blockly.blockRendering.MarkerSvg.MARKER_CLASS;this.svgGroup_=Blockly.utils.dom.createSvgElement("g",{"class":a},null);this.createDomInternal_();this.applyColour_();return this.svgGroup_};
Blockly.blockRendering.MarkerSvg.prototype.setParent_=function(a){this.isCursor()?(this.parent_&&this.parent_.setCursorSvg(null),a.setCursorSvg(this.getSvgRoot())):(this.parent_&&this.parent_.setMarkerSvg(null),a.setMarkerSvg(this.getSvgRoot()));this.parent_=a};
Blockly.blockRendering.MarkerSvg.prototype.showWithBlockPrevOutput_=function(a){if(a){var b=a.width,c=a.height,d=c*Blockly.blockRendering.MarkerSvg.HEIGHT_MULTIPLIER,e=this.constants_.CURSOR_BLOCK_PADDING;if(a.previousConnection){var f=this.constants_.shapeFor(a.previousConnection);this.positionPrevious_(b,e,d,f)}else a.outputConnection?(f=this.constants_.shapeFor(a.outputConnection),this.positionOutput_(b,c,f)):this.positionBlock_(b,e,d);this.setParent_(a);this.showCurrent_()}};
Blockly.blockRendering.MarkerSvg.prototype.showWithCoordinates_=function(a){var b=a.getWsCoordinate();a=b.x;b=b.y;this.workspace_.RTL&&(a-=this.constants_.CURSOR_WS_WIDTH);this.positionLine_(a,b,this.constants_.CURSOR_WS_WIDTH);this.setParent_(this.workspace_);this.showCurrent_()};Blockly.blockRendering.MarkerSvg.prototype.showWithField_=function(a){a=a.getLocation();var b=a.getSize().width,c=a.getSize().height;this.positionRect_(0,0,b,c);this.setParent_(a);this.showCurrent_()};
@@ -1117,13 +1132,16 @@ Blockly.blockRendering.MarkerSvg.prototype.positionLine_=function(a,b,c){this.ma
Blockly.blockRendering.MarkerSvg.prototype.positionOutput_=function(a,b,c){a=Blockly.utils.svgPaths.moveBy(a,0)+Blockly.utils.svgPaths.lineOnAxis("h",-(a-c.width))+Blockly.utils.svgPaths.lineOnAxis("v",this.constants_.TAB_OFFSET_FROM_TOP)+c.pathDown+Blockly.utils.svgPaths.lineOnAxis("V",b)+Blockly.utils.svgPaths.lineOnAxis("H",a);this.markerBlock_.setAttribute("d",a);this.workspace_.RTL&&this.flipRtl_(this.markerBlock_);this.currentMarkerSvg=this.markerBlock_};
Blockly.blockRendering.MarkerSvg.prototype.positionPrevious_=function(a,b,c,d){a=Blockly.utils.svgPaths.moveBy(-b,c)+Blockly.utils.svgPaths.lineOnAxis("V",-b)+Blockly.utils.svgPaths.lineOnAxis("H",this.constants_.NOTCH_OFFSET_LEFT)+d.pathLeft+Blockly.utils.svgPaths.lineOnAxis("H",a+2*b)+Blockly.utils.svgPaths.lineOnAxis("V",c);this.markerBlock_.setAttribute("d",a);this.workspace_.RTL&&this.flipRtl_(this.markerBlock_);this.currentMarkerSvg=this.markerBlock_};
Blockly.blockRendering.MarkerSvg.prototype.positionRect_=function(a,b,c,d){this.markerSvgRect_.setAttribute("x",a);this.markerSvgRect_.setAttribute("y",b);this.markerSvgRect_.setAttribute("width",c);this.markerSvgRect_.setAttribute("height",d);this.currentMarkerSvg=this.markerSvgRect_};Blockly.blockRendering.MarkerSvg.prototype.flipRtl_=function(a){a.setAttribute("transform","scale(-1 1)")};
-Blockly.blockRendering.MarkerSvg.prototype.hide=function(){this.markerSvgLine_.style.display="none";this.markerSvgRect_.style.display="none";this.markerInput_.style.display="none";this.markerBlock_.style.display="none"};Blockly.blockRendering.MarkerSvg.prototype.draw=function(a,b){b?(this.showAtLocation_(b),this.firemarkerEvent_(a,b),a=this.currentMarkerSvg.childNodes[0],void 0!==a&&a.beginElement&&a.beginElement()):this.hide()};
+Blockly.blockRendering.MarkerSvg.prototype.hide=function(){this.markerSvgLine_.style.display="none";this.markerSvgRect_.style.display="none";this.markerInput_.style.display="none";this.markerBlock_.style.display="none"};
+Blockly.blockRendering.MarkerSvg.prototype.draw=function(a,b){if(b){this.constants_=this.workspace_.getRenderer().getConstants();var c=this.isCursor()?this.constants_.CURSOR_COLOUR:this.constants_.MARKER_COLOUR;this.colour_=this.marker_.colour||c;this.applyColour_();this.showAtLocation_(b);this.firemarkerEvent_(a,b);a=this.currentMarkerSvg.childNodes[0];void 0!==a&&a.beginElement&&a.beginElement()}else this.hide()};
Blockly.blockRendering.MarkerSvg.prototype.showAtLocation_=function(a){a.getType()==Blockly.ASTNode.types.BLOCK?(a=a.getLocation(),this.showWithBlockPrevOutput_(a)):a.getType()==Blockly.ASTNode.types.OUTPUT?(a=a.getLocation().getSourceBlock(),this.showWithBlockPrevOutput_(a)):a.getLocation().type==Blockly.INPUT_VALUE?this.showWithInput_(a):a.getLocation().type==Blockly.NEXT_STATEMENT?this.showWithNext_(a):a.getType()==Blockly.ASTNode.types.PREVIOUS?(a=a.getLocation().getSourceBlock(),this.showWithBlockPrevOutput_(a)):
a.getType()==Blockly.ASTNode.types.FIELD?this.showWithField_(a):a.getType()==Blockly.ASTNode.types.WORKSPACE?this.showWithCoordinates_(a):a.getType()==Blockly.ASTNode.types.STACK&&this.showWithStack_(a)};Blockly.blockRendering.MarkerSvg.prototype.firemarkerEvent_=function(a,b){var c=b.getSourceBlock(),d=this.isCursor()?"cursorMove":"markerMove";a=new Blockly.Events.Ui(c,d,a,b);b.getType()==Blockly.ASTNode.types.WORKSPACE&&(a.workspaceId=b.getLocation().id);Blockly.Events.fire(a)};
Blockly.blockRendering.MarkerSvg.prototype.getBlinkProperties_=function(){return{attributeType:"XML",attributeName:"fill",dur:"1s",values:this.colour_+";transparent;transparent;",repeatCount:"indefinite"}};
-Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_=function(){this.markerSvg_=Blockly.utils.dom.createSvgElement("g",{width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT},this.svgGroup_);this.markerSvgLine_=Blockly.utils.dom.createSvgElement("rect",{fill:this.colour_,width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT,style:"display: none"},this.markerSvg_);this.markerSvgRect_=Blockly.utils.dom.createSvgElement("rect",{"class":"blocklyVerticalMarker",
-rx:10,ry:10,style:"display: none",stroke:this.colour_},this.markerSvg_);this.markerInput_=Blockly.utils.dom.createSvgElement("path",{transform:"",style:"display: none",fill:this.colour_},this.markerSvg_);this.markerBlock_=Blockly.utils.dom.createSvgElement("path",{transform:"",style:"display: none",fill:"none",stroke:this.colour_,"stroke-width":this.constants_.CURSOR_STROKE_WIDTH},this.markerSvg_);if(this.isCursor()){var a=this.getBlinkProperties_();Blockly.utils.dom.createSvgElement("animate",this.getBlinkProperties_(),
-this.markerSvgLine_);Blockly.utils.dom.createSvgElement("animate",a,this.markerInput_);a.attributeName="stroke";Blockly.utils.dom.createSvgElement("animate",a,this.markerBlock_)}return this.markerSvg_};Blockly.blockRendering.MarkerSvg.prototype.dispose=function(){this.svgGroup_&&Blockly.utils.dom.removeNode(this.svgGroup_)};Blockly.blockRendering.Types={NONE:0,FIELD:1,HAT:2,ICON:4,SPACER:8,BETWEEN_ROW_SPACER:16,IN_ROW_SPACER:32,EXTERNAL_VALUE_INPUT:64,INPUT:128,INLINE_INPUT:256,STATEMENT_INPUT:512,CONNECTION:1024,PREVIOUS_CONNECTION:2048,NEXT_CONNECTION:4096,OUTPUT_CONNECTION:8192,CORNER:16384,LEFT_SQUARE_CORNER:32768,LEFT_ROUND_CORNER:65536,RIGHT_SQUARE_CORNER:131072,RIGHT_ROUND_CORNER:262144,JAGGED_EDGE:524288,ROW:1048576,TOP_ROW:2097152,BOTTOM_ROW:4194304,INPUT_ROW:8388608};
+Blockly.blockRendering.MarkerSvg.prototype.createDomInternal_=function(){this.markerSvg_=Blockly.utils.dom.createSvgElement("g",{width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT},this.svgGroup_);this.markerSvgLine_=Blockly.utils.dom.createSvgElement("rect",{width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT,style:"display: none"},this.markerSvg_);this.markerSvgRect_=Blockly.utils.dom.createSvgElement("rect",{"class":"blocklyVerticalMarker",rx:10,
+ry:10,style:"display: none"},this.markerSvg_);this.markerInput_=Blockly.utils.dom.createSvgElement("path",{transform:"",style:"display: none"},this.markerSvg_);this.markerBlock_=Blockly.utils.dom.createSvgElement("path",{transform:"",style:"display: none",fill:"none","stroke-width":this.constants_.CURSOR_STROKE_WIDTH},this.markerSvg_);if(this.isCursor()){var a=this.getBlinkProperties_();Blockly.utils.dom.createSvgElement("animate",a,this.markerSvgLine_);Blockly.utils.dom.createSvgElement("animate",
+a,this.markerInput_);a.attributeName="stroke";Blockly.utils.dom.createSvgElement("animate",a,this.markerBlock_)}return this.markerSvg_};
+Blockly.blockRendering.MarkerSvg.prototype.applyColour_=function(){this.markerSvgLine_.setAttribute("fill",this.colour_);this.markerSvgRect_.setAttribute("stroke",this.colour_);this.markerInput_.setAttribute("fill",this.colour_);this.markerBlock_.setAttribute("stroke",this.colour_);if(this.isCursor()){var a=this.colour_+";transparent;transparent;";this.markerSvgLine_.firstChild.setAttribute("values",a);this.markerInput_.firstChild.setAttribute("values",a);this.markerBlock_.firstChild.setAttribute("values",
+a)}};Blockly.blockRendering.MarkerSvg.prototype.dispose=function(){this.svgGroup_&&Blockly.utils.dom.removeNode(this.svgGroup_)};Blockly.blockRendering.Types={NONE:0,FIELD:1,HAT:2,ICON:4,SPACER:8,BETWEEN_ROW_SPACER:16,IN_ROW_SPACER:32,EXTERNAL_VALUE_INPUT:64,INPUT:128,INLINE_INPUT:256,STATEMENT_INPUT:512,CONNECTION:1024,PREVIOUS_CONNECTION:2048,NEXT_CONNECTION:4096,OUTPUT_CONNECTION:8192,CORNER:16384,LEFT_SQUARE_CORNER:32768,LEFT_ROUND_CORNER:65536,RIGHT_SQUARE_CORNER:131072,RIGHT_ROUND_CORNER:262144,JAGGED_EDGE:524288,ROW:1048576,TOP_ROW:2097152,BOTTOM_ROW:4194304,INPUT_ROW:8388608};
Blockly.blockRendering.Types.LEFT_CORNER=Blockly.blockRendering.Types.LEFT_SQUARE_CORNER|Blockly.blockRendering.Types.LEFT_ROUND_CORNER;Blockly.blockRendering.Types.RIGHT_CORNER=Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER|Blockly.blockRendering.Types.RIGHT_ROUND_CORNER;Blockly.blockRendering.Types.nextTypeValue_=16777216;
Blockly.blockRendering.Types.getType=function(a){Blockly.blockRendering.Types.hasOwnProperty(a)||(Blockly.blockRendering.Types[a]=Blockly.blockRendering.Types.nextTypeValue_,Blockly.blockRendering.Types.nextTypeValue_<<=1);return Blockly.blockRendering.Types[a]};Blockly.blockRendering.Types.isField=function(a){return a.type&Blockly.blockRendering.Types.FIELD};Blockly.blockRendering.Types.isHat=function(a){return a.type&Blockly.blockRendering.Types.HAT};
Blockly.blockRendering.Types.isIcon=function(a){return a.type&Blockly.blockRendering.Types.ICON};Blockly.blockRendering.Types.isSpacer=function(a){return a.type&Blockly.blockRendering.Types.SPACER};Blockly.blockRendering.Types.isInRowSpacer=function(a){return a.type&Blockly.blockRendering.Types.IN_ROW_SPACER};Blockly.blockRendering.Types.isInput=function(a){return a.type&Blockly.blockRendering.Types.INPUT};Blockly.blockRendering.Types.isExternalInput=function(a){return a.type&Blockly.blockRendering.Types.EXTERNAL_VALUE_INPUT};
@@ -1158,10 +1176,10 @@ Blockly.blockRendering.BottomRow.prototype.measure=function(){for(var a=0,b=0,c=
Blockly.blockRendering.BottomRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.blockRendering.SpacerRow=function(a,b,c){Blockly.blockRendering.SpacerRow.superClass_.constructor.call(this,a);this.type=this.type|Blockly.blockRendering.Types.SPACER|Blockly.blockRendering.Types.BETWEEN_ROW_SPACER;this.width=c;this.height=b;this.followsStatement=!1;this.widthWithConnectedBlocks=0;this.elements=[new Blockly.blockRendering.InRowSpacer(this.constants_,c)]};
Blockly.utils.object.inherits(Blockly.blockRendering.SpacerRow,Blockly.blockRendering.Row);Blockly.blockRendering.SpacerRow.prototype.measure=function(){};Blockly.blockRendering.InputRow=function(a){Blockly.blockRendering.InputRow.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.INPUT_ROW;this.connectedBlockWidths=0};Blockly.utils.object.inherits(Blockly.blockRendering.InputRow,Blockly.blockRendering.Row);
Blockly.blockRendering.InputRow.prototype.measure=function(){this.width=this.minWidth;this.height=this.minHeight;for(var a=0,b=0,c;c=this.elements[b];b++)this.width+=c.width,Blockly.blockRendering.Types.isInput(c)&&(Blockly.blockRendering.Types.isStatementInput(c)?a+=c.connectedBlockWidth:Blockly.blockRendering.Types.isExternalInput(c)&&0!=c.connectedBlockWidth&&(a+=c.connectedBlockWidth-c.connectionWidth)),Blockly.blockRendering.Types.isSpacer(c)||(this.height=Math.max(this.height,c.height));this.connectedBlockWidths=
-a;this.widthWithConnectedBlocks=this.width+a};Blockly.blockRendering.InputRow.prototype.endsWithElemSpacer=function(){return!this.hasExternalInput&&!this.hasStatement};Blockly.blockRendering.RenderInfo=function(a,b){this.block_=b;this.renderer_=a;this.constants_=this.renderer_.getConstants();this.outputConnection=b.outputConnection?new Blockly.blockRendering.OutputConnection(this.constants_,b.outputConnection):null;this.isInline=b.getInputsInline()&&!b.isCollapsed();this.isCollapsed=b.isCollapsed();this.isInsertionMarker=b.isInsertionMarker();this.RTL=b.RTL;this.statementEdge=this.width=this.widthWithChildren=this.height=0;this.rows=[];this.inputRowNum_=1;this.hiddenIcons=
+a;this.widthWithConnectedBlocks=this.width+a};Blockly.blockRendering.InputRow.prototype.endsWithElemSpacer=function(){return!this.hasExternalInput&&!this.hasStatement};Blockly.blockRendering.RenderInfo=function(a,b){this.block_=b;this.renderer_=a;this.constants_=this.renderer_.getConstants();this.outputConnection=b.outputConnection?new Blockly.blockRendering.OutputConnection(this.constants_,b.outputConnection):null;this.isInline=b.getInputsInline()&&!b.isCollapsed();this.isCollapsed=b.isCollapsed();this.isInsertionMarker=b.isInsertionMarker();this.RTL=b.RTL;this.statementEdge=this.width=this.widthWithChildren=this.height=0;this.rows=[];this.inputRows=[];this.hiddenIcons=
[];this.topRow=new Blockly.blockRendering.TopRow(this.constants_);this.bottomRow=new Blockly.blockRendering.BottomRow(this.constants_);this.startY=this.startX=0};Blockly.blockRendering.RenderInfo.prototype.getRenderer=function(){return this.renderer_};Blockly.blockRendering.RenderInfo.prototype.measure=function(){this.createRows_();this.addElemSpacing_();this.addRowSpacing_();this.computeBounds_();this.alignRowElements_();this.finalize_()};
-Blockly.blockRendering.RenderInfo.prototype.createRows_=function(){this.populateTopRow_();this.rows.push(this.topRow);var a=new Blockly.blockRendering.InputRow(this.constants_),b=this.block_.getIcons();if(b.length)for(var c=0,d;d=b[c];c++){var e=new Blockly.blockRendering.Icon(this.constants_,d);this.isCollapsed&&d.collapseHidden?this.hiddenIcons.push(e):a.elements.push(e)}d=null;for(c=0;b=this.block_.inputList[c];c++)if(b.isVisible()){this.shouldStartNewRow_(b,d)&&(this.rows.push(a),a=new Blockly.blockRendering.InputRow(this.constants_),
-this.inputRowNum_++);for(d=0;e=b.fieldRow[d];d++)a.elements.push(new Blockly.blockRendering.Field(this.constants_,e,b));this.addInput_(b,a);d=b}this.isCollapsed&&(a.hasJaggedEdge=!0,a.elements.push(new Blockly.blockRendering.JaggedEdge(this.constants_)));(a.elements.length||a.hasDummyInput)&&this.rows.push(a);this.populateBottomRow_();this.rows.push(this.bottomRow)};
+Blockly.blockRendering.RenderInfo.prototype.createRows_=function(){this.populateTopRow_();this.rows.push(this.topRow);var a=new Blockly.blockRendering.InputRow(this.constants_);this.inputRows.push(a);var b=this.block_.getIcons();if(b.length)for(var c=0,d;d=b[c];c++){var e=new Blockly.blockRendering.Icon(this.constants_,d);this.isCollapsed&&d.collapseHidden?this.hiddenIcons.push(e):a.elements.push(e)}d=null;for(c=0;b=this.block_.inputList[c];c++)if(b.isVisible()){this.shouldStartNewRow_(b,d)&&(this.rows.push(a),
+a=new Blockly.blockRendering.InputRow(this.constants_),this.inputRows.push(a));for(d=0;e=b.fieldRow[d];d++)a.elements.push(new Blockly.blockRendering.Field(this.constants_,e,b));this.addInput_(b,a);d=b}this.isCollapsed&&(a.hasJaggedEdge=!0,a.elements.push(new Blockly.blockRendering.JaggedEdge(this.constants_)));(a.elements.length||a.hasDummyInput)&&this.rows.push(a);this.populateBottomRow_();this.rows.push(this.bottomRow)};
Blockly.blockRendering.RenderInfo.prototype.populateTopRow_=function(){var a=!!this.block_.previousConnection,b=(this.block_.hat?"cap"===this.block_.hat:this.constants_.ADD_START_HATS)&&!this.outputConnection&&!a;this.topRow.hasLeftSquareCorner(this.block_)?this.topRow.elements.push(new Blockly.blockRendering.SquareCorner(this.constants_)):this.topRow.elements.push(new Blockly.blockRendering.RoundCorner(this.constants_));b?(a=new Blockly.blockRendering.Hat(this.constants_),this.topRow.elements.push(a),
this.topRow.capline=a.ascenderHeight):a&&(this.topRow.hasPreviousConnection=!0,this.topRow.connection=new Blockly.blockRendering.PreviousConnection(this.constants_,this.block_.previousConnection),this.topRow.elements.push(this.topRow.connection));this.block_.inputList.length&&this.block_.inputList[0].type==Blockly.NEXT_STATEMENT&&!this.block_.isCollapsed()?this.topRow.minHeight=this.constants_.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT:this.topRow.minHeight=this.constants_.TOP_ROW_MIN_HEIGHT;this.topRow.hasRightSquareCorner(this.block_)?
this.topRow.elements.push(new Blockly.blockRendering.SquareCorner(this.constants_,"right")):this.topRow.elements.push(new Blockly.blockRendering.RoundCorner(this.constants_,"right"))};
@@ -1175,15 +1193,14 @@ b.elements.push(new Blockly.blockRendering.InRowSpacer(this.constants_,this.getI
Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_=function(a,b){if(!a&&b&&Blockly.blockRendering.Types.isStatementInput(b))return this.constants_.STATEMENT_INPUT_PADDING_LEFT;if(a&&Blockly.blockRendering.Types.isInput(a)&&!b){if(Blockly.blockRendering.Types.isExternalInput(a))return this.constants_.NO_PADDING;if(Blockly.blockRendering.Types.isInlineInput(a))return this.constants_.LARGE_PADDING;if(Blockly.blockRendering.Types.isStatementInput(a))return this.constants_.NO_PADDING}return a&&
Blockly.blockRendering.Types.isLeftSquareCorner(a)&&b&&(Blockly.blockRendering.Types.isPreviousConnection(b)||Blockly.blockRendering.Types.isNextConnection(b))?b.notchOffset:a&&Blockly.blockRendering.Types.isLeftRoundedCorner(a)&&b&&(Blockly.blockRendering.Types.isPreviousConnection(b)||Blockly.blockRendering.Types.isNextConnection(b))?b.notchOffset-this.constants_.CORNER_RADIUS:this.constants_.MEDIUM_PADDING};
Blockly.blockRendering.RenderInfo.prototype.computeBounds_=function(){for(var a=0,b=0,c=0,d=0,e;e=this.rows[d];d++){e.measure();b=Math.max(b,e.width);if(e.hasStatement){var f=e.getLastInput();a=Math.max(a,e.width-f.width)}c=Math.max(c,e.widthWithConnectedBlocks)}this.statementEdge=a;this.width=b;for(d=0;e=this.rows[d];d++)e.hasStatement&&(e.statementEdge=this.statementEdge);this.widthWithChildren=Math.max(b,c);this.outputConnection&&(this.startX=this.outputConnection.width,this.width+=this.outputConnection.width,
-this.widthWithChildren+=this.outputConnection.width)};Blockly.blockRendering.RenderInfo.prototype.alignRowElements_=function(){for(var a=0,b;b=this.rows[a];a++)if(b.hasStatement)this.alignStatementRow_(b);else{var c=b.width;c=this.getDesiredRowWidth_(b)-c;0.blocklyPathLight,",a+" .blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none","}"])};Blockly.geras.Highlighter=function(a){this.info_=a;this.inlineSteps_=this.steps_="";this.RTL_=this.info_.RTL;a=a.getRenderer();this.constants_=a.getConstants();this.highlightConstants_=a.getHighlightConstants();this.highlightOffset_=this.highlightConstants_.OFFSET;this.outsideCornerPaths_=this.highlightConstants_.OUTSIDE_CORNER;this.insideCornerPaths_=this.highlightConstants_.INSIDE_CORNER;this.puzzleTabPaths_=this.highlightConstants_.PUZZLE_TAB;this.notchPaths_=this.highlightConstants_.NOTCH;this.startPaths_=
this.highlightConstants_.START_HAT;this.jaggedTeethPaths_=this.highlightConstants_.JAGGED_TEETH};Blockly.geras.Highlighter.prototype.getPath=function(){return this.steps_+"\n"+this.inlineSteps_};
Blockly.geras.Highlighter.prototype.drawTopCorner=function(a){this.steps_+=Blockly.utils.svgPaths.moveBy(a.xPos,this.info_.startY);for(var b=0,c;c=a.elements[b];b++)Blockly.blockRendering.Types.isLeftSquareCorner(c)?this.steps_+=this.highlightConstants_.START_POINT:Blockly.blockRendering.Types.isLeftRoundedCorner(c)?this.steps_+=this.outsideCornerPaths_.topLeft(this.RTL_):Blockly.blockRendering.Types.isPreviousConnection(c)?this.steps_+=this.notchPaths_.pathLeft:Blockly.blockRendering.Types.isHat(c)?
-this.steps_+=this.startPaths_.path(this.RTL_):Blockly.blockRendering.Types.isSpacer(c)&&0!=c.width&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",c.xPos+c.width-this.highlightOffset_));this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",a.xPos+a.width-this.highlightOffset_)};
-Blockly.geras.Highlighter.prototype.drawJaggedEdge_=function(a){this.info_.RTL&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",a.width-this.highlightOffset_),this.steps_+=this.jaggedTeethPaths_.pathLeft,this.steps_+=Blockly.utils.svgPaths.lineOnAxis("v",a.height-this.jaggedTeethPaths_.height-this.highlightOffset_))};
+this.steps_+=this.startPaths_.path(this.RTL_):Blockly.blockRendering.Types.isSpacer(c)&&0!=c.width&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",c.xPos+c.width-this.highlightOffset_));this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",a.xPos+a.width-this.highlightOffset_)};Blockly.geras.Highlighter.prototype.drawJaggedEdge_=function(a){this.info_.RTL&&(this.steps_+=this.jaggedTeethPaths_.pathLeft+Blockly.utils.svgPaths.lineOnAxis("v",a.height-this.jaggedTeethPaths_.height-this.highlightOffset_))};
Blockly.geras.Highlighter.prototype.drawValueInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-b.connectionHeight;this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos+b.width-this.highlightOffset_,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)+Blockly.utils.svgPaths.lineOnAxis("v",c)}else this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos+b.width,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)};
Blockly.geras.Highlighter.prototype.drawStatementInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-2*this.insideCornerPaths_.height;this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos,a.yPos)+this.insideCornerPaths_.pathTop(this.RTL_)+Blockly.utils.svgPaths.lineOnAxis("v",c)+this.insideCornerPaths_.pathBottom(this.RTL_)+Blockly.utils.svgPaths.lineTo(a.width-b.xPos-this.insideCornerPaths_.width,0)}else this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos,a.yPos+a.height)+this.insideCornerPaths_.pathBottom(this.RTL_)+
Blockly.utils.svgPaths.lineTo(a.width-b.xPos-this.insideCornerPaths_.width,0)};Blockly.geras.Highlighter.prototype.drawRightSideRow=function(a){var b=a.xPos+a.width-this.highlightOffset_;a.followsStatement&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",b));this.RTL_&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",b),a.height>this.highlightOffset_&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",a.yPos+a.height-this.highlightOffset_)))};
@@ -1249,22 +1269,22 @@ Blockly.geras.Drawer.prototype.drawValueInput_=function(a){this.highlighter_.dra
Blockly.geras.Drawer.prototype.drawRightSideRow_=function(a){this.highlighter_.drawRightSideRow(a);this.outlinePath_+=Blockly.utils.svgPaths.lineOnAxis("H",a.xPos+a.width)+Blockly.utils.svgPaths.lineOnAxis("V",a.yPos+a.height)};Blockly.geras.Drawer.prototype.drawBottom_=function(){this.highlighter_.drawBottomRow(this.info_.bottomRow);Blockly.geras.Drawer.superClass_.drawBottom_.call(this)};Blockly.geras.Drawer.prototype.drawLeft_=function(){this.highlighter_.drawLeft();Blockly.geras.Drawer.superClass_.drawLeft_.call(this)};
Blockly.geras.Drawer.prototype.drawInlineInput_=function(a){this.highlighter_.drawInlineInput(a);Blockly.geras.Drawer.superClass_.drawInlineInput_.call(this,a)};Blockly.geras.Drawer.prototype.positionInlineInputConnection_=function(a){var b=a.centerline-a.height/2;if(a.connectionModel){var c=a.xPos+a.connectionWidth+this.constants_.DARK_PATH_OFFSET;this.info_.RTL&&(c*=-1);a.connectionModel.setOffsetInBlock(c,b+a.connectionOffsetY+this.constants_.DARK_PATH_OFFSET)}};
Blockly.geras.Drawer.prototype.positionStatementInputConnection_=function(a){var b=a.getLastInput();if(b.connectionModel){var c=a.xPos+a.statementEdge+b.notchOffset;c=this.info_.RTL?-1*c:c+this.constants_.DARK_PATH_OFFSET;b.connectionModel.setOffsetInBlock(c,a.yPos+this.constants_.DARK_PATH_OFFSET)}};
-Blockly.geras.Drawer.prototype.positionExternalValueConnection_=function(a){var b=a.getLastInput();if(b.connectionModel){var c=a.xPos+a.width+this.constants_.DARK_PATH_OFFSET;this.info_.RTL&&(c*=-1);b.connectionModel.setOffsetInBlock(c,a.yPos)}};Blockly.geras.Drawer.prototype.positionNextConnection_=function(){var a=this.info_.bottomRow;if(a.connection){var b=a.connection,c=b.xPos;b.connectionModel.setOffsetInBlock((this.info_.RTL?-c:c)+this.constants_.DARK_PATH_OFFSET/2,a.baseline+this.constants_.DARK_PATH_OFFSET)}};Blockly.geras.HighlightConstantProvider=function(a){this.constantProvider=a;this.OFFSET=.5;this.START_POINT=Blockly.utils.svgPaths.moveBy(this.OFFSET,this.OFFSET);this.INSIDE_CORNER=this.makeInsideCorner();this.OUTSIDE_CORNER=this.makeOutsideCorner();this.PUZZLE_TAB=this.makePuzzleTab();this.NOTCH=this.makeNotch();this.JAGGED_TEETH=this.makeJaggedTeeth();this.START_HAT=this.makeStartHat()};
+Blockly.geras.Drawer.prototype.positionExternalValueConnection_=function(a){var b=a.getLastInput();if(b.connectionModel){var c=a.xPos+a.width+this.constants_.DARK_PATH_OFFSET;this.info_.RTL&&(c*=-1);b.connectionModel.setOffsetInBlock(c,a.yPos)}};Blockly.geras.Drawer.prototype.positionNextConnection_=function(){var a=this.info_.bottomRow;if(a.connection){var b=a.connection,c=b.xPos;b.connectionModel.setOffsetInBlock((this.info_.RTL?-c:c)+this.constants_.DARK_PATH_OFFSET/2,a.baseline+this.constants_.DARK_PATH_OFFSET)}};Blockly.geras.HighlightConstantProvider=function(a){this.constantProvider=a;this.OFFSET=.5;this.START_POINT=Blockly.utils.svgPaths.moveBy(this.OFFSET,this.OFFSET)};Blockly.geras.HighlightConstantProvider.prototype.init=function(){this.INSIDE_CORNER=this.makeInsideCorner();this.OUTSIDE_CORNER=this.makeOutsideCorner();this.PUZZLE_TAB=this.makePuzzleTab();this.NOTCH=this.makeNotch();this.JAGGED_TEETH=this.makeJaggedTeeth();this.START_HAT=this.makeStartHat()};
Blockly.geras.HighlightConstantProvider.prototype.makeInsideCorner=function(){var a=this.constantProvider.CORNER_RADIUS,b=this.OFFSET,c=(1-Math.SQRT1_2)*(a+b)-b,d=Blockly.utils.svgPaths.moveBy(c,c)+Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(-c-b,a-c)),e=Blockly.utils.svgPaths.arc("a","0 0,0",a+b,Blockly.utils.svgPaths.point(a+b,a+b)),f=Blockly.utils.svgPaths.moveBy(c,-c)+Blockly.utils.svgPaths.arc("a","0 0,0",a+b,Blockly.utils.svgPaths.point(a-c,c+b));return{width:a+b,height:a,
pathTop:function(a){return a?d:""},pathBottom:function(a){return a?e:f}}};
Blockly.geras.HighlightConstantProvider.prototype.makeOutsideCorner=function(){var a=this.constantProvider.CORNER_RADIUS,b=this.OFFSET,c=(1-Math.SQRT1_2)*(a-b)+b,d=Blockly.utils.svgPaths.moveBy(c,c)+Blockly.utils.svgPaths.arc("a","0 0,1",a-b,Blockly.utils.svgPaths.point(a-c,-c+b)),e=Blockly.utils.svgPaths.moveBy(b,a)+Blockly.utils.svgPaths.arc("a","0 0,1",a-b,Blockly.utils.svgPaths.point(a,-a+b)),f=-c,g=Blockly.utils.svgPaths.moveBy(c,f)+Blockly.utils.svgPaths.arc("a","0 0,1",a-b,Blockly.utils.svgPaths.point(-c+
b,-f-a));return{height:a,topLeft:function(a){return a?d:e},bottomLeft:function(){return g}}};
Blockly.geras.HighlightConstantProvider.prototype.makePuzzleTab=function(){var a=this.constantProvider.TAB_WIDTH,b=this.constantProvider.TAB_HEIGHT,c=Blockly.utils.svgPaths.moveBy(-2,-b+3.4)+Blockly.utils.svgPaths.lineTo(-.45*a,-2.1),d=Blockly.utils.svgPaths.lineOnAxis("v",2.5)+Blockly.utils.svgPaths.moveBy(.97*-a,2.5)+Blockly.utils.svgPaths.curve("q",[Blockly.utils.svgPaths.point(.05*-a,10),Blockly.utils.svgPaths.point(.3*a,9.5)])+Blockly.utils.svgPaths.moveBy(.67*a,-1.9)+Blockly.utils.svgPaths.lineOnAxis("v",
2.5),e=Blockly.utils.svgPaths.lineOnAxis("v",-1.5)+Blockly.utils.svgPaths.moveBy(-.92*a,-.5)+Blockly.utils.svgPaths.curve("q",[Blockly.utils.svgPaths.point(-.19*a,-5.5),Blockly.utils.svgPaths.point(0,-11)])+Blockly.utils.svgPaths.moveBy(.92*a,1),f=Blockly.utils.svgPaths.moveBy(-5,b-.7)+Blockly.utils.svgPaths.lineTo(.46*a,-2.1);return{width:a,height:b,pathUp:function(a){return a?c:e},pathDown:function(a){return a?d:f}}};
-Blockly.geras.HighlightConstantProvider.prototype.makeNotch=function(){return{pathLeft:Blockly.utils.svgPaths.lineOnAxis("h",this.OFFSET)+this.constantProvider.NOTCH.pathLeft}};Blockly.geras.HighlightConstantProvider.prototype.makeJaggedTeeth=function(){return{pathLeft:Blockly.utils.svgPaths.lineTo(5.1,2.6)+Blockly.utils.svgPaths.moveBy(-10.2,6.8)+Blockly.utils.svgPaths.lineTo(5.1,2.6)}};
+Blockly.geras.HighlightConstantProvider.prototype.makeNotch=function(){return{pathLeft:Blockly.utils.svgPaths.lineOnAxis("h",this.OFFSET)+this.constantProvider.NOTCH.pathLeft}};Blockly.geras.HighlightConstantProvider.prototype.makeJaggedTeeth=function(){return{pathLeft:Blockly.utils.svgPaths.lineTo(5.1,2.6)+Blockly.utils.svgPaths.moveBy(-10.2,6.8)+Blockly.utils.svgPaths.lineTo(5.1,2.6),height:12,width:10.2}};
Blockly.geras.HighlightConstantProvider.prototype.makeStartHat=function(){var a=this.constantProvider.START_HAT.height,b=Blockly.utils.svgPaths.moveBy(25,-8.7)+Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(29.7,-6.2),Blockly.utils.svgPaths.point(57.2,-.5),Blockly.utils.svgPaths.point(75,8.7)]),c=Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(17.8,-9.2),Blockly.utils.svgPaths.point(45.3,-14.9),Blockly.utils.svgPaths.point(75,-8.7)])+Blockly.utils.svgPaths.moveTo(100.5,
-a+.5);return{path:function(a){return a?b:c}}};Blockly.geras.PathObject=function(a,b,c){this.constants_=c;this.svgRoot=a;this.svgPathDark=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgRoot);this.svgPath=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPath"},this.svgRoot);this.svgPathLight=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPathLight"},this.svgRoot);this.colourDark="#000000";this.style=b};Blockly.utils.object.inherits(Blockly.geras.PathObject,Blockly.blockRendering.PathObject);
+a+.5);return{path:function(a){return a?b:c}}};Blockly.geras.PathObject=function(a,b,c){this.constants=c;this.svgRoot=a;this.svgPathDark=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgRoot);this.svgPath=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPath"},this.svgRoot);this.svgPathLight=Blockly.utils.dom.createSvgElement("path",{"class":"blocklyPathLight"},this.svgRoot);this.colourDark="#000000";this.style=b};Blockly.utils.object.inherits(Blockly.geras.PathObject,Blockly.blockRendering.PathObject);
Blockly.geras.PathObject.prototype.setPath=function(a){this.svgPath.setAttribute("d",a);this.svgPathDark.setAttribute("d",a)};Blockly.geras.PathObject.prototype.setHighlightPath=function(a){this.svgPathLight.setAttribute("d",a)};Blockly.geras.PathObject.prototype.flipRTL=function(){this.svgPath.setAttribute("transform","scale(-1 1)");this.svgPathLight.setAttribute("transform","scale(-1 1)");this.svgPathDark.setAttribute("transform","translate(1,1) scale(-1 1)")};
Blockly.geras.PathObject.prototype.applyColour=function(a){this.svgPathLight.style.display="";this.svgPathDark.style.display="";this.svgPathLight.setAttribute("stroke",this.style.colourTertiary);this.svgPathDark.setAttribute("fill",this.colourDark);Blockly.geras.PathObject.superClass_.applyColour.call(this,a);this.svgPath.setAttribute("stroke","none")};
-Blockly.geras.PathObject.prototype.setStyle=function(a){this.style=a;this.colourDark=Blockly.utils.colour.blend("#000",this.style.colourPrimary,.2)||this.colourDark};Blockly.geras.PathObject.prototype.updateHighlighted=function(a){a?(this.svgPath.setAttribute("filter","url(#"+this.constants_.embossFilterId+")"),this.svgPathLight.style.display="none"):(this.svgPath.setAttribute("filter","none"),this.svgPathLight.style.display="inline")};
-Blockly.geras.PathObject.prototype.updateShadow_=function(a){a&&(this.svgPathLight.style.display="none",this.svgPathDark.setAttribute("fill",this.style.colourSecondary),this.svgPath.setAttribute("stroke","none"),this.svgPath.setAttribute("fill",this.style.colourSecondary))};Blockly.geras.PathObject.prototype.updateDisabled_=function(a){Blockly.geras.PathObject.superClass_.updateDisabled_.call(this,a);a&&this.svgPath.setAttribute("stroke","none")};Blockly.geras.Renderer=function(a){Blockly.geras.Renderer.superClass_.constructor.call(this,a);this.highlightConstants_=null};Blockly.utils.object.inherits(Blockly.geras.Renderer,Blockly.blockRendering.Renderer);Blockly.geras.Renderer.prototype.init=function(){Blockly.geras.Renderer.superClass_.init.call(this);this.highlightConstants_=this.makeHighlightConstants_()};Blockly.geras.Renderer.prototype.makeConstants_=function(){return new Blockly.geras.ConstantProvider};
-Blockly.geras.Renderer.prototype.makeRenderInfo_=function(a){return new Blockly.geras.RenderInfo(this,a)};Blockly.geras.Renderer.prototype.makeDrawer_=function(a,b){return new Blockly.geras.Drawer(a,b)};Blockly.geras.Renderer.prototype.makePathObject=function(a,b){return new Blockly.geras.PathObject(a,b,this.getConstants())};Blockly.geras.Renderer.prototype.makeHighlightConstants_=function(){return new Blockly.geras.HighlightConstantProvider(this.getConstants())};
-Blockly.geras.Renderer.prototype.getHighlightConstants=function(){return this.highlightConstants_};Blockly.blockRendering.register("geras",Blockly.geras.Renderer);Blockly.thrasos={};Blockly.thrasos.RenderInfo=function(a,b){Blockly.thrasos.RenderInfo.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.thrasos.RenderInfo,Blockly.blockRendering.RenderInfo);Blockly.thrasos.RenderInfo.prototype.getRenderer=function(){return this.renderer_};
+Blockly.geras.PathObject.prototype.setStyle=function(a){this.style=a;this.colourDark=Blockly.utils.colour.blend("#000",this.style.colourPrimary,.2)||this.colourDark};Blockly.geras.PathObject.prototype.updateHighlighted=function(a){a?(this.svgPath.setAttribute("filter","url(#"+this.constants.embossFilterId+")"),this.svgPathLight.style.display="none"):(this.svgPath.setAttribute("filter","none"),this.svgPathLight.style.display="inline")};
+Blockly.geras.PathObject.prototype.updateShadow_=function(a){a&&(this.svgPathLight.style.display="none",this.svgPathDark.setAttribute("fill",this.style.colourSecondary),this.svgPath.setAttribute("stroke","none"),this.svgPath.setAttribute("fill",this.style.colourSecondary))};Blockly.geras.PathObject.prototype.updateDisabled_=function(a){Blockly.geras.PathObject.superClass_.updateDisabled_.call(this,a);a&&this.svgPath.setAttribute("stroke","none")};Blockly.geras.Renderer=function(a){Blockly.geras.Renderer.superClass_.constructor.call(this,a);this.highlightConstants_=null};Blockly.utils.object.inherits(Blockly.geras.Renderer,Blockly.blockRendering.Renderer);Blockly.geras.Renderer.prototype.init=function(a,b){Blockly.geras.Renderer.superClass_.init.call(this,a,b);this.highlightConstants_=this.makeHighlightConstants_();this.highlightConstants_.init()};
+Blockly.geras.Renderer.prototype.refreshDom=function(a,b){Blockly.geras.Renderer.superClass_.refreshDom.call(this,a,b);this.getHighlightConstants().init()};Blockly.geras.Renderer.prototype.makeConstants_=function(){return new Blockly.geras.ConstantProvider};Blockly.geras.Renderer.prototype.makeRenderInfo_=function(a){return new Blockly.geras.RenderInfo(this,a)};Blockly.geras.Renderer.prototype.makeDrawer_=function(a,b){return new Blockly.geras.Drawer(a,b)};
+Blockly.geras.Renderer.prototype.makePathObject=function(a,b){return new Blockly.geras.PathObject(a,b,this.getConstants())};Blockly.geras.Renderer.prototype.makeHighlightConstants_=function(){return new Blockly.geras.HighlightConstantProvider(this.getConstants())};Blockly.geras.Renderer.prototype.getHighlightConstants=function(){return this.highlightConstants_};Blockly.blockRendering.register("geras",Blockly.geras.Renderer);Blockly.thrasos={};Blockly.thrasos.RenderInfo=function(a,b){Blockly.thrasos.RenderInfo.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.thrasos.RenderInfo,Blockly.blockRendering.RenderInfo);Blockly.thrasos.RenderInfo.prototype.getRenderer=function(){return this.renderer_};
Blockly.thrasos.RenderInfo.prototype.addElemSpacing_=function(){for(var a=!1,b=0,c;c=this.rows[b];b++)c.hasExternalInput&&(a=!0);for(b=0;c=this.rows[b];b++){var d=c.elements;c.elements=[];c.startsWithElemSpacer()&&c.elements.push(new Blockly.blockRendering.InRowSpacer(this.constants_,this.getInRowSpacing_(null,d[0])));for(var e=0;eb?b:c;e=e?-1:1;a=(d?-1:1)*a/2;return Blockly.utils.svgPaths.lineTo(-e*c,a)+Blockly.utils.svgPaths.lineTo(e*c,a)}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;return{type:this.SHAPES.HEXAGONAL,isDynamic:!0,width:function(a){a/=2;return a>b?b:a},height:function(a){return a},connectionOffsetY:function(a){return a/2},connectionOffsetX:function(a){return-a},pathDown:function(b){return a(b,!1,!1)},pathUp:function(b){return a(b,
+!0,!1)},pathRightDown:function(b){return a(b,!1,!0)},pathRightUp:function(b){return a(b,!1,!0)}}};
+Blockly.zelos.ConstantProvider.prototype.makeRounded=function(){function a(a,b,f){var d=a>c?a-c:0;a=(a>c?c:a)/2;return Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point((b?-1:1)*a,(b?-1:1)*a))+Blockly.utils.svgPaths.lineOnAxis("v",(f?1:-1)*d)+Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point((b?1:-1)*a,(b?-1:1)*a))}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH,c=2*b;return{type:this.SHAPES.ROUND,isDynamic:!0,width:function(a){a/=2;return a>b?b:a},height:function(a){return a},
+connectionOffsetY:function(a){return a/2},connectionOffsetX:function(a){return-a},pathDown:function(b){return a(b,!1,!1)},pathUp:function(b){return a(b,!0,!1)},pathRightDown:function(b){return a(b,!1,!0)},pathRightUp:function(b){return a(b,!1,!0)}}};
Blockly.zelos.ConstantProvider.prototype.makeSquared=function(){function a(a,d,e){a-=2*b;return Blockly.utils.svgPaths.arc("a","0 0,1",b,Blockly.utils.svgPaths.point((d?-1:1)*b,(d?-1:1)*b))+Blockly.utils.svgPaths.lineOnAxis("v",(e?1:-1)*a)+Blockly.utils.svgPaths.arc("a","0 0,1",b,Blockly.utils.svgPaths.point((d?1:-1)*b,(d?-1:1)*b))}var b=this.CORNER_RADIUS;return{type:this.SHAPES.SQUARE,isDynamic:!0,width:function(a){return b},height:function(a){return a},connectionOffsetY:function(a){return a/2},
connectionOffsetX:function(a){return-a},pathDown:function(b){return a(b,!1,!1)},pathUp:function(b){return a(b,!0,!1)},pathRightDown:function(b){return a(b,!1,!0)},pathRightUp:function(b){return a(b,!1,!0)}}};
Blockly.zelos.ConstantProvider.prototype.shapeFor=function(a){var b=a.getCheck();!b&&a.targetConnection&&(b=a.targetConnection.getCheck());switch(a.type){case Blockly.INPUT_VALUE:case Blockly.OUTPUT_VALUE:a=a.getSourceBlock().getOutputShape();if(null!=a)switch(a){case this.SHAPES.HEXAGONAL:return this.HEXAGONAL;case this.SHAPES.ROUND:return this.ROUNDED;case this.SHAPES.SQUARE:return this.SQUARED}if(b&&-1!=b.indexOf("Boolean"))return this.HEXAGONAL;if(b&&-1!=b.indexOf("Number"))return this.ROUNDED;
@@ -1299,69 +1322,66 @@ Blockly.zelos.ConstantProvider.prototype.makeNotch=function(){function a(a){retu
[Blockly.utils.svgPaths.point(a*e/2,0),Blockly.utils.svgPaths.point(a*e*3/4,-(g/2)),Blockly.utils.svgPaths.point(a*e,-g)])+Blockly.utils.svgPaths.line([Blockly.utils.svgPaths.point(a*e,-f)])+Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(a*e/4,-(g/2)),Blockly.utils.svgPaths.point(a*e/2,-g),Blockly.utils.svgPaths.point(a*e,-g)])}var b=this.NOTCH_WIDTH,c=this.NOTCH_HEIGHT,d=b/3,e=d/3,f=c/2,g=f/2,h=a(1),k=a(-1);return{type:this.SHAPES.NOTCH,width:b,height:c,pathLeft:h,pathRight:k}};
Blockly.zelos.ConstantProvider.prototype.makeInsideCorners=function(){var a=this.CORNER_RADIUS,b=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(-a,a)),c=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(-a,a)),d=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(a,a)),e=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(a,a));return{width:a,height:a,pathTop:b,pathBottom:d,rightWidth:a,rightHeight:a,pathTopRight:c,pathBottomRight:e}};
Blockly.zelos.ConstantProvider.prototype.generateSecondaryColour_=function(a){return Blockly.utils.colour.blend("#000",a,.15)||a};Blockly.zelos.ConstantProvider.prototype.generateTertiaryColour_=function(a){return Blockly.utils.colour.blend("#000",a,.25)||a};
-Blockly.zelos.ConstantProvider.prototype.createDom=function(a){Blockly.zelos.ConstantProvider.superClass_.createDom.call(this,a);a=Blockly.utils.dom.createSvgElement("defs",{},a);var b=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyHighlightGlowFilter"+this.randomIdentifier_,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceGraphic",stdDeviation:.5},b);var c=Blockly.utils.dom.createSvgElement("feComponentTransfer",{result:"outBlur"},
-b);Blockly.utils.dom.createSvgElement("feFuncA",{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},c);Blockly.utils.dom.createSvgElement("feFlood",{"flood-color":"#fff200","flood-opacity":1,result:"outColor"},b);Blockly.utils.dom.createSvgElement("feComposite",{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},b);this.highlightGlowFilterId=b.id;this.highlightGlowFilter_=b;a=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyReplacementGlowFilter"+this.randomIdentifier_,
-height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceGraphic",stdDeviation:2},a);b=Blockly.utils.dom.createSvgElement("feComponentTransfer",{result:"outBlur"},a);Blockly.utils.dom.createSvgElement("feFuncA",{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},b);Blockly.utils.dom.createSvgElement("feFlood",{"flood-color":"#fff200","flood-opacity":1,result:"outColor"},a);Blockly.utils.dom.createSvgElement("feComposite",{"in":"outColor",
-in2:"outBlur",operator:"in",result:"outGlow"},a);Blockly.utils.dom.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"outGlow",operator:"over"},a);this.replacementGlowFilterId=a.id;this.replacementGlowFilter_=a};
-Blockly.zelos.ConstantProvider.prototype.getCSS_=function(a){a="."+a+"-renderer";return[a+" .blocklyText {","fill: #fff;","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-size: "+this.FIELD_TEXT_FONTSIZE+"pt;","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklyNonEditableText>rect:not(.blocklyDropdownRect),",a+" .blocklyEditableText>rect:not(.blocklyDropdownRect) {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","}",a+" .blocklyNonEditableText>text,",a+" .blocklyEditableText>text,",a+
-" .blocklyNonEditableText>g>text,",a+" .blocklyEditableText>g>text {","fill: #575E75;","}",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>rect ,",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>.blocklyPath {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","color: #575E75;","}",a+" .blocklyDropdownText {","fill: #fff !important;",
-"}",a+".blocklyWidgetDiv .goog-menuitem,",a+".blocklyDropDownDiv .goog-menuitem {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","}",a+".blocklyDropDownDiv .goog-menuitem-content {","color: #fff;","}",a+" .blocklyHighlightedConnectionPath {","stroke: #fff200;","}",a+" .blocklyDisabled > .blocklyOutlinePath {","fill: url(#blocklyDisabledPattern"+this.randomIdentifier_+")","}"]};Blockly.zelos.TopRow=function(a){Blockly.zelos.TopRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.TopRow,Blockly.blockRendering.TopRow);Blockly.zelos.TopRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.TopRow.prototype.hasLeftSquareCorner=function(a){var b=(a.hat?"cap"===a.hat:this.constants_.ADD_START_HATS)&&!a.outputConnection&&!a.previousConnection;return!!a.outputConnection||b};Blockly.zelos.TopRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection};
-Blockly.zelos.BottomRow=function(a){Blockly.zelos.BottomRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.BottomRow,Blockly.blockRendering.BottomRow);Blockly.zelos.BottomRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner=function(a){return!!a.outputConnection};Blockly.zelos.BottomRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection};Blockly.zelos.RightConnectionShape=function(a){Blockly.zelos.RightConnectionShape.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.getType("RIGHT_CONNECTION");this.width=this.height=0};Blockly.utils.object.inherits(Blockly.zelos.RightConnectionShape,Blockly.blockRendering.Measurable);Blockly.zelos.StatementInput=function(a,b){Blockly.zelos.StatementInput.superClass_.constructor.call(this,a,b);if(this.connectedBlock){for(a=this.connectedBlock;a.getNextBlock();)a=a.getNextBlock();a.nextConnection||(this.height=this.connectedBlockHeight,this.connectedBottomNextConnection=!0)}};Blockly.utils.object.inherits(Blockly.zelos.StatementInput,Blockly.blockRendering.StatementInput);Blockly.zelos.RenderInfo=function(a,b){Blockly.zelos.RenderInfo.superClass_.constructor.call(this,a,b);this.topRow=new Blockly.zelos.TopRow(this.constants_);this.bottomRow=new Blockly.zelos.BottomRow(this.constants_);this.isInline=!0;this.isMultiRow=!b.getInputsInline()||b.isCollapsed();this.rightSide=this.outputConnection?new Blockly.zelos.RightConnectionShape(this.constants_):null};Blockly.utils.object.inherits(Blockly.zelos.RenderInfo,Blockly.blockRendering.RenderInfo);
+Blockly.zelos.ConstantProvider.prototype.createDom=function(a,b,c){Blockly.zelos.ConstantProvider.superClass_.createDom.call(this,a,b,c);a=Blockly.utils.dom.createSvgElement("defs",{},a);b=Blockly.utils.dom.createSvgElement("filter",{id:"blocklySelectedGlowFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceGraphic",stdDeviation:this.SELECTED_GLOW_SIZE},b);c=Blockly.utils.dom.createSvgElement("feComponentTransfer",
+{result:"outBlur"},b);Blockly.utils.dom.createSvgElement("feFuncA",{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},c);Blockly.utils.dom.createSvgElement("feFlood",{"flood-color":this.SELECTED_GLOW_COLOUR,"flood-opacity":1,result:"outColor"},b);Blockly.utils.dom.createSvgElement("feComposite",{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},b);this.selectedGlowFilterId=b.id;this.selectedGlowFilter_=b;a=Blockly.utils.dom.createSvgElement("filter",{id:"blocklyReplacementGlowFilter"+
+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement("feGaussianBlur",{"in":"SourceGraphic",stdDeviation:this.REPLACEMENT_GLOW_SIZE},a);b=Blockly.utils.dom.createSvgElement("feComponentTransfer",{result:"outBlur"},a);Blockly.utils.dom.createSvgElement("feFuncA",{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},b);Blockly.utils.dom.createSvgElement("feFlood",{"flood-color":this.REPLACEMENT_GLOW_COLOUR,"flood-opacity":1,result:"outColor"},
+a);Blockly.utils.dom.createSvgElement("feComposite",{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},a);Blockly.utils.dom.createSvgElement("feComposite",{"in":"SourceGraphic",in2:"outGlow",operator:"over"},a);this.replacementGlowFilterId=a.id;this.replacementGlowFilter_=a};
+Blockly.zelos.ConstantProvider.prototype.getCSS_=function(a){return[a+" .blocklyText, ",a+" .blocklyFlyoutLabelText {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-size: "+this.FIELD_TEXT_FONTSIZE+"pt;","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","}",a+" .blocklyText {","fill: #fff;","}",a+" .blocklyNonEditableText>rect:not(.blocklyDropdownRect),",a+" .blocklyEditableText>rect:not(.blocklyDropdownRect) {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","}",a+" .blocklyNonEditableText>text,",
+a+" .blocklyEditableText>text,",a+" .blocklyNonEditableText>g>text,",a+" .blocklyEditableText>g>text {","fill: #575E75;","}",a+" .blocklyFlyoutLabelText {","fill: #575E75;","}",a+" .blocklyText.blocklyBubbleText {","fill: #575E75;","}",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>rect ,",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>.blocklyPath {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+
+this.FIELD_TEXT_FONTFAMILY+";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","color: #575E75;","}",a+" .blocklyDropdownText {","fill: #fff !important;","}",a+".blocklyWidgetDiv .goog-menuitem,",a+".blocklyDropDownDiv .goog-menuitem {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","}",a+".blocklyDropDownDiv .goog-menuitem-content {","color: #fff;","}",a+" .blocklyHighlightedConnectionPath {","stroke: "+this.SELECTED_GLOW_COLOUR+";","}",a+" .blocklyDisabled > .blocklyOutlinePath {","fill: url(#blocklyDisabledPattern"+
+this.randomIdentifier+")","}",a+" .blocklyInsertionMarker>.blocklyPath {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none","}"]};Blockly.zelos.TopRow=function(a){Blockly.zelos.TopRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.TopRow,Blockly.blockRendering.TopRow);Blockly.zelos.TopRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.TopRow.prototype.hasLeftSquareCorner=function(a){var b=(a.hat?"cap"===a.hat:this.constants_.ADD_START_HATS)&&!a.outputConnection&&!a.previousConnection;return!!a.outputConnection||b};
+Blockly.zelos.TopRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection&&!a.statementInputCount&&!a.nextConnection};Blockly.zelos.BottomRow=function(a){Blockly.zelos.BottomRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.BottomRow,Blockly.blockRendering.BottomRow);Blockly.zelos.BottomRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner=function(a){return!!a.outputConnection};
+Blockly.zelos.BottomRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection&&!a.statementInputCount&&!a.nextConnection};Blockly.zelos.RightConnectionShape=function(a){Blockly.zelos.RightConnectionShape.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.getType("RIGHT_CONNECTION");this.width=this.height=0};Blockly.utils.object.inherits(Blockly.zelos.RightConnectionShape,Blockly.blockRendering.Measurable);Blockly.zelos.StatementInput=function(a,b){Blockly.zelos.StatementInput.superClass_.constructor.call(this,a,b);if(this.connectedBlock){for(a=this.connectedBlock;a.getNextBlock();)a=a.getNextBlock();a.nextConnection||(this.height=this.connectedBlockHeight,this.connectedBottomNextConnection=!0)}};Blockly.utils.object.inherits(Blockly.zelos.StatementInput,Blockly.blockRendering.StatementInput);Blockly.zelos.RenderInfo=function(a,b){Blockly.zelos.RenderInfo.superClass_.constructor.call(this,a,b);this.topRow=new Blockly.zelos.TopRow(this.constants_);this.bottomRow=new Blockly.zelos.BottomRow(this.constants_);this.isInline=!0;this.isMultiRow=!b.getInputsInline()||b.isCollapsed();this.hasStatementInput=0=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!f.precedesStatement;if(Blockly.blockRendering.Types.isInputRow(e)&&e.hasStatement)e.measure(),b=e.width-e.getLastInput().width+a;else if(d&&(2==c||f)&&
Blockly.blockRendering.Types.isInputRow(e)&&!e.hasStatement){f=e.xPos;d=null;for(var g=0,h;h=e.elements[g];g++)Blockly.blockRendering.Types.isSpacer(h)&&(d=h),!(d&&(Blockly.blockRendering.Types.isField(h)||Blockly.blockRendering.Types.isInput(h))&&fc?c:this.height/2,b-c*(1-Math.sin(Math.acos((c-this.constants_.SMALL_PADDING)/c)));default:return 0}if(Blockly.blockRendering.Types.isInlineInput(a)){var e=a.connectedBlock;a=e?e.pathObject.outputShapeType:
+a.shape.type;return e&&e.outputConnection&&(e.statementInputCount||e.nextConnection)||c==d.SHAPES.HEXAGONAL&&c!=a?0:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][a]}return Blockly.blockRendering.Types.isField(a)?c==d.SHAPES.ROUND&&a.field instanceof Blockly.FieldTextInput?b-2.75*d.GRID_UNIT:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][0]:Blockly.blockRendering.Types.isIcon(a)?this.constants_.SMALL_PADDING:0};
Blockly.zelos.RenderInfo.prototype.finalizeVerticalAlignment_=function(){if(!this.outputConnection)for(var a=2;a=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!d.precedesStatement;if(e?this.topRow.hasPreviousConnection:b.followsStatement){var g=3==c.elements.length&&(c.elements[1].field instanceof Blockly.FieldLabel||c.elements[1].field instanceof Blockly.FieldImage);if(!e&&g)b.height-=this.constants_.SMALL_PADDING,
d.height-=this.constants_.SMALL_PADDING,c.height-=this.constants_.MEDIUM_PADDING;else if(!e&&!f)b.height+=this.constants_.SMALL_PADDING;else if(f){e=!1;for(f=0;g=c.elements[f];f++)if(Blockly.blockRendering.Types.isInlineInput(g)&&g.connectedBlock&&!g.connectedBlock.isShadow()&&40<=g.connectedBlock.getHeightWidth().height){e=!0;break}e&&(b.height-=this.constants_.SMALL_PADDING,d.height-=this.constants_.SMALL_PADDING)}}}};
-Blockly.zelos.RenderInfo.prototype.finalize_=function(){this.finalizeOutputConnection_();this.finalizeHorizontalAlignment_();this.finalizeVerticalAlignment_();Blockly.zelos.RenderInfo.superClass_.finalize_.call(this)};Blockly.zelos.Drawer=function(a,b){Blockly.zelos.Drawer.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.zelos.Drawer,Blockly.blockRendering.Drawer);
+Blockly.zelos.RenderInfo.prototype.finalize_=function(){this.finalizeOutputConnection_();this.finalizeHorizontalAlignment_();this.finalizeVerticalAlignment_();Blockly.zelos.RenderInfo.superClass_.finalize_.call(this);this.rightSide&&(this.widthWithChildren+=this.rightSide.width)};Blockly.zelos.Drawer=function(a,b){Blockly.zelos.Drawer.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.zelos.Drawer,Blockly.blockRendering.Drawer);
Blockly.zelos.Drawer.prototype.draw=function(){var a=this.block_.pathObject;a.beginDrawing();this.hideHiddenIcons_();this.drawOutline_();this.drawInternals_();a.setPath(this.outlinePath_+"\n"+this.inlinePath_);this.info_.RTL&&a.flipRTL();Blockly.blockRendering.useDebugger&&this.block_.renderingDebugger.drawDebug(this.block_,this.info_);this.recordSizeOnBlock_();this.info_.outputConnection&&(a.outputShapeType=this.info_.outputConnection.shape.type);a.endDrawing()};
-Blockly.zelos.Drawer.prototype.drawOutline_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape?(this.drawFlatTop_(),this.drawRightDynamicConnection_(),this.drawFlatBottom_(),this.drawLeftDynamicConnection_()):Blockly.zelos.Drawer.superClass_.drawOutline_.call(this)};
+Blockly.zelos.Drawer.prototype.drawOutline_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape&&!this.info_.hasStatementInput&&!this.info_.bottomRow.hasNextConnection?(this.drawFlatTop_(),this.drawRightDynamicConnection_(),this.drawFlatBottom_(),this.drawLeftDynamicConnection_()):Blockly.zelos.Drawer.superClass_.drawOutline_.call(this)};
+Blockly.zelos.Drawer.prototype.drawLeft_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape?this.drawLeftDynamicConnection_():Blockly.zelos.Drawer.superClass_.drawLeft_.call(this)};
Blockly.zelos.Drawer.prototype.drawRightSideRow_=function(a){if(!(0>=a.height))if(a.precedesStatement||a.followsStatement){var b=this.constants_.INSIDE_CORNERS.rightHeight;b=a.height-(a.precedesStatement?b:0);this.outlinePath_+=(a.followsStatement?this.constants_.INSIDE_CORNERS.pathBottomRight:"")+(0d;d++){var f=1==d?b:c;f&&!f.outputConnection.checkType(e)&&(Blockly.Events.setGroup(a.group),e===this.prevParentConnection_?(this.unplug(),e.getSourceBlock().bumpNeighbours()):(f.unplug(),f.bumpNeighbours()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
-e}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;
+Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN={prevParentConnection_:null,onchange:function(a){var b=this.getInputTargetBlock("THEN"),c=this.getInputTargetBlock("ELSE"),d=this.outputConnection.targetConnection;if((b||c)&&d)for(var e=0;2>e;e++){var f=1==e?b:c;f&&!f.outputConnection.checkType(d)&&(Blockly.Events.setGroup(a.group),d===this.prevParentConnection_?(this.unplug(),d.getSourceBlock().bumpNeighbours()):(f.unplug(),f.bumpNeighbours()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
+d}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;
Blockly.defineBlocksWithJsonArray([{type:"controls_repeat_ext",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"input_value",name:"TIMES",check:"Number"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_repeat",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"field_number",name:"TIMES",value:10,
min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_whileUntil",message0:"%1 %2",args0:[{type:"field_dropdown",name:"MODE",options:[["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}","WHILE"],["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}","UNTIL"]]},{type:"input_value",name:"BOOL",check:"Boolean"}],
message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",name:"BY",
@@ -66,10 +66,10 @@ check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",arg
args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",
extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};
Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
-Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var e={enabled:!0};e.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c);b=Blockly.Variables.generateVariableFieldDom(b);c=Blockly.utils.xml.createElement("block");c.setAttribute("type","variables_get");c.appendChild(b);e.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(e)}}}};
+Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var d={enabled:!0};d.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c);b=Blockly.Variables.generateVariableFieldDom(b);c=Blockly.utils.xml.createElement("block");c.setAttribute("type","variables_get");c.appendChild(b);d.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}}}};
Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOR_TOOLTIP}","VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOREACH_TOOLTIP}","VAR"));
-Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],suppressPrefixSuffix:!0,getSurroundLoop:function(a){do{if(-1!=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type))return a;a=a.getSurroundParent()}while(a);return null},onchange:function(a){this.workspace.isDragging&&!this.workspace.isDragging()&&(Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this)?
-(this.setWarningText(null),this.isInFlyout||this.setEnabled(!0)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||this.getInheritedDisabled()||this.setEnabled(!1)))}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;
+Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],suppressPrefixSuffix:!0,getSurroundLoop:function(a){do{if(-1!=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type))return a;a=a.getSurroundParent()}while(a);return null},onchange:function(a){if(this.workspace.isDragging&&!this.workspace.isDragging()&&a.type==Blockly.Events.BLOCK_MOVE&&a.blockId==this.id){var b=
+Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this);this.setWarningText(b?null:Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);if(!this.isInFlyout){var c=Blockly.Events.getGroup();Blockly.Events.setGroup(a.group);this.setEnabled(b);Blockly.Events.setGroup(c)}}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;
Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",style:"math_blocks",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",
@@ -90,34 +90,34 @@ Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"=
Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK","RETURN")):this.removeInput("STACK",!0),this.hasStatements_=
-a)},updateParams_:function(){var a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},mutationToDom:function(a){var b=Blockly.utils.xml.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c} lookupTable The table of field values to
* tooltip text.
- * @return {Function} The extension function.
+ * @return {!Function} The extension function.
*/
Blockly.Extensions.buildTooltipForDropdown = function(dropdownName,
lookupTable) {
@@ -412,7 +401,7 @@ Blockly.Extensions.checkDropdownOptionsInTable_ = function(block, dropdownName,
* @param {string} msgTemplate The template form to of the message text, with
* %1 placeholder.
* @param {string} fieldName The field with the replacement text.
- * @return {Function} The extension function.
+ * @return {!Function} The extension function.
*/
Blockly.Extensions.buildTooltipWithFieldText = function(msgTemplate,
fieldName) {
diff --git a/core/field.js b/core/field.js
index 09507898d..2c6328fc8 100644
--- a/core/field.js
+++ b/core/field.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -205,7 +194,7 @@ Blockly.Field.prototype.getText_;
* clicked. Blockly will automatically set the field as clickable if this
* method is defined.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @return {void}
* @protected
*/
@@ -260,9 +249,19 @@ Blockly.Field.prototype.setSourceBlock = function(block) {
throw Error('Field already bound to a block.');
}
this.sourceBlock_ = block;
- if (block.workspace.rendered) {
- this.constants_ = block.workspace.getRenderer().getConstants();
+};
+
+/**
+ * Get the renderer constant provider.
+ * @return {?Blockly.blockRendering.ConstantProvider} The renderer constant
+ * provider.
+ */
+Blockly.Field.prototype.getConstants = function() {
+ if (!this.constants_ && this.sourceBlock_ && this.sourceBlock_.workspace &&
+ this.sourceBlock_.workspace.rendered) {
+ this.constants_ = this.sourceBlock_.workspace.getRenderer().getConstants();
}
+ return this.constants_;
};
/**
@@ -321,15 +320,11 @@ Blockly.Field.prototype.initModel = function() {
* @protected
*/
Blockly.Field.prototype.createBorderRect_ = function() {
- this.size_.height =
- Math.max(this.size_.height, this.constants_.FIELD_BORDER_RECT_HEIGHT);
- this.size_.width =
- Math.max(this.size_.width, this.constants_.FIELD_BORDER_RECT_X_PADDING * 2);
this.borderRect_ = /** @type {!SVGRectElement} **/
(Blockly.utils.dom.createSvgElement('rect',
{
- 'rx': this.constants_.FIELD_BORDER_RECT_RADIUS,
- 'ry': this.constants_.FIELD_BORDER_RECT_RADIUS,
+ 'rx': this.getConstants().FIELD_BORDER_RECT_RADIUS,
+ 'ry': this.getConstants().FIELD_BORDER_RECT_RADIUS,
'x': 0,
'y': 0,
'height': this.size_.height,
@@ -345,24 +340,12 @@ Blockly.Field.prototype.createBorderRect_ = function() {
* @protected
*/
Blockly.Field.prototype.createTextElement_ = function() {
- var xOffset = this.borderRect_ ?
- this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
- var baselineCenter = this.constants_.FIELD_TEXT_BASELINE_CENTER;
- var baselineY = this.constants_.FIELD_TEXT_BASELINE_Y;
- this.size_.height = Math.max(this.size_.height, baselineCenter ?
- this.constants_.FIELD_TEXT_HEIGHT : baselineY);
- if (this.size_.height > this.constants_.FIELD_TEXT_HEIGHT) {
- baselineY += (this.size_.height - baselineY) / 2;
- }
this.textElement_ = /** @type {!SVGTextElement} **/
(Blockly.utils.dom.createSvgElement('text',
{
'class': 'blocklyText',
- 'y': baselineCenter ? this.size_.height / 2 : baselineY,
- 'dy': this.constants_.FIELD_TEXT_Y_OFFSET,
- 'x': xOffset
}, this.fieldGroup_));
- if (baselineCenter) {
+ if (this.getConstants().FIELD_TEXT_BASELINE_CENTER) {
this.textElement_.setAttribute('dominant-baseline', 'central');
}
this.textContent_ = document.createTextNode('');
@@ -411,6 +394,7 @@ Blockly.Field.prototype.toXml = function(fieldElement) {
Blockly.Field.prototype.dispose = function() {
Blockly.DropDownDiv.hideIfOwner(this);
Blockly.WidgetDiv.hideIfOwner(this);
+ Blockly.Tooltip.unbindMouseEvents(this.getClickTarget_());
if (this.mouseDownWrapper_) {
Blockly.unbindEvent_(this.mouseDownWrapper_);
@@ -598,14 +582,14 @@ Blockly.Field.prototype.applyColour = function() {
Blockly.Field.prototype.render_ = function() {
if (this.textContent_) {
this.textContent_.nodeValue = this.getDisplayText_();
- this.updateSize_();
}
+ this.updateSize_();
};
/**
* Show an editor when the field is clicked only if the field is clickable.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @package
*/
Blockly.Field.prototype.showEditor = function(opt_e) {
@@ -630,22 +614,73 @@ Blockly.Field.prototype.updateWidth = function() {
/**
* Updates the size of the field based on the text.
+ * @param {number=} opt_margin margin to use when positioning the text element.
* @protected
*/
-Blockly.Field.prototype.updateSize_ = function() {
- var textWidth = Blockly.utils.dom.getFastTextWidth(
- /** @type {!SVGTextElement} */ (this.textElement_),
- this.constants_.FIELD_TEXT_FONTSIZE,
- this.constants_.FIELD_TEXT_FONTWEIGHT,
- this.constants_.FIELD_TEXT_FONTFAMILY);
- var totalWidth = textWidth;
- if (this.borderRect_) {
- totalWidth += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
- this.borderRect_.setAttribute('width', totalWidth);
+Blockly.Field.prototype.updateSize_ = function(opt_margin) {
+ var constants = this.getConstants();
+ var xOffset = opt_margin != undefined ? opt_margin :
+ (this.borderRect_ ? this.getConstants().FIELD_BORDER_RECT_X_PADDING : 0);
+ var totalWidth = xOffset * 2;
+ var totalHeight = constants.FIELD_TEXT_HEIGHT;
+
+ var contentWidth = 0;
+ if (this.textElement_) {
+ contentWidth = Blockly.utils.dom.getFastTextWidth(this.textElement_,
+ constants.FIELD_TEXT_FONTSIZE,
+ constants.FIELD_TEXT_FONTWEIGHT,
+ constants.FIELD_TEXT_FONTFAMILY);
+ totalWidth += contentWidth;
}
+ if (this.borderRect_) {
+ totalHeight = Math.max(totalHeight, constants.FIELD_BORDER_RECT_HEIGHT);
+ }
+
+ this.size_.height = totalHeight;
this.size_.width = totalWidth;
+
+ this.positionTextElement_(xOffset, contentWidth);
+ this.positionBorderRect_();
};
+/**
+ * Position a field's text element after a size change. This handles both LTR
+ * and RTL positioning.
+ * @param {number} xOffset x offset to use when positioning the text element.
+ * @param {number} contentWidth The content width.
+ * @protected
+ */
+Blockly.Field.prototype.positionTextElement_ = function(xOffset, contentWidth) {
+ if (!this.textElement_) {
+ return;
+ }
+ var constants = this.getConstants();
+ var halfHeight = this.size_.height / 2;
+
+ this.textElement_.setAttribute('x', this.sourceBlock_.RTL ?
+ this.size_.width - contentWidth - xOffset : xOffset);
+ this.textElement_.setAttribute('y', constants.FIELD_TEXT_BASELINE_CENTER ?
+ halfHeight : halfHeight - constants.FIELD_TEXT_HEIGHT / 2 +
+ constants.FIELD_TEXT_BASELINE);
+};
+
+/**
+ * Position a field's border rect after a size change.
+ * @protected
+ */
+Blockly.Field.prototype.positionBorderRect_ = function() {
+ if (!this.borderRect_) {
+ return;
+ }
+ this.borderRect_.setAttribute('width', this.size_.width);
+ this.borderRect_.setAttribute('height', this.size_.height);
+ this.borderRect_.setAttribute('rx',
+ this.getConstants().FIELD_BORDER_RECT_RADIUS);
+ this.borderRect_.setAttribute('ry',
+ this.getConstants().FIELD_BORDER_RECT_RADIUS);
+};
+
+
/**
* Returns the height and width of the field.
*
@@ -772,6 +807,7 @@ Blockly.Field.prototype.setText = function(_newText) {
*/
Blockly.Field.prototype.markDirty = function() {
this.isDirty_ = true;
+ this.constants_ = null;
};
/**
@@ -786,6 +822,7 @@ Blockly.Field.prototype.forceRerender = function() {
if (this.sourceBlock_ && this.sourceBlock_.rendered) {
this.sourceBlock_.render();
this.sourceBlock_.bumpNeighbours();
+ this.updateMarkers_();
}
};
@@ -898,7 +935,7 @@ Blockly.Field.prototype.doValueUpdate_ = function(newValue) {
};
/**
- * Used to notify the field an invalid value was input. Can be overidden by
+ * Used to notify the field an invalid value was input. Can be overridden by
* subclasses, see FieldTextInput.
* No-op by default.
* @param {*} _invalidValue The input value that was determined to be invalid.
@@ -1058,3 +1095,17 @@ Blockly.Field.prototype.setMarkerSvg = function(markerSvg) {
this.fieldGroup_.appendChild(markerSvg);
this.markerSvg_ = markerSvg;
};
+
+/**
+ * Redraw any attached marker or cursor svgs if needed.
+ * @protected
+ */
+Blockly.Field.prototype.updateMarkers_ = function() {
+ var workspace = this.sourceBlock_.workspace;
+ if (workspace.keyboardAccessibilityMode && this.cursorSvg_) {
+ workspace.getCursor().draw();
+ }
+ if (workspace.keyboardAccessibilityMode && this.markerSvg_) {
+ workspace.getMarker(Blockly.navigation.MARKER_NAME).draw();
+ }
+};
diff --git a/core/field_angle.js b/core/field_angle.js
index 131adce28..4dbe1b19c 100644
--- a/core/field_angle.js
+++ b/core/field_angle.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2013 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -257,7 +246,7 @@ Blockly.FieldAngle.prototype.render_ = function() {
/**
* Create and show the angle field's editor.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @private
*/
Blockly.FieldAngle.prototype.showEditor_ = function(opt_e) {
diff --git a/core/field_checkbox.js b/core/field_checkbox.js
index ea417927f..e4818ebe8 100644
--- a/core/field_checkbox.js
+++ b/core/field_checkbox.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -93,15 +82,6 @@ Blockly.FieldCheckbox.prototype.SERIALIZABLE = true;
*/
Blockly.FieldCheckbox.prototype.CURSOR = 'default';
-/**
- * Used to tell if the field needs to be rendered the next time the block is
- * rendered. Checkbox fields are statically sized, and only need to be
- * rendered at initialization.
- * @type {boolean}
- * @protected
- */
-Blockly.FieldCheckbox.prototype.isDirty_ = false;
-
/**
* Configure the field based on the given map of options.
* @param {!Object} config A map of options to configure the field based on.
@@ -119,19 +99,30 @@ Blockly.FieldCheckbox.prototype.configure_ = function(config) {
* @package
*/
Blockly.FieldCheckbox.prototype.initView = function() {
- this.size_.width = this.constants_.FIELD_CHECKBOX_DEFAULT_WIDTH;
Blockly.FieldCheckbox.superClass_.initView.call(this);
- this.textElement_.setAttribute('x', this.constants_.FIELD_CHECKBOX_X_OFFSET);
- this.textElement_.setAttribute('y', this.constants_.FIELD_CHECKBOX_Y_OFFSET);
- this.textElement_.removeAttribute('dominant-baseline');
- Blockly.utils.dom.addClass(this.textElement_, 'blocklyCheckbox');
-
- this.textContent_.nodeValue =
- this.checkChar_ || Blockly.FieldCheckbox.CHECK_CHAR;
+ Blockly.utils.dom.addClass(
+ /** @type {!SVGTextElement} **/ (this.textElement_), 'blocklyCheckbox');
this.textElement_.style.display = this.value_ ? 'block' : 'none';
};
+/**
+ * @override
+ */
+Blockly.FieldCheckbox.prototype.render_ = function() {
+ if (this.textContent_) {
+ this.textContent_.nodeValue = this.getDisplayText_();
+ }
+ this.updateSize_(this.getConstants().FIELD_CHECKBOX_X_OFFSET);
+};
+
+/**
+ * @override
+ */
+Blockly.FieldCheckbox.prototype.getDisplayText_ = function() {
+ return this.checkChar_ || Blockly.FieldCheckbox.CHECK_CHAR;
+};
+
/**
* Set the character used for the check mark.
* @param {?string} character The character to use for the check mark, or
@@ -139,9 +130,7 @@ Blockly.FieldCheckbox.prototype.initView = function() {
*/
Blockly.FieldCheckbox.prototype.setCheckCharacter = function(character) {
this.checkChar_ = character;
- if (this.textContent_) {
- this.textContent_.nodeValue = character || Blockly.FieldCheckbox.CHECK_CHAR;
- }
+ this.forceRerender();
};
/**
diff --git a/core/field_colour.js b/core/field_colour.js
index 1909f874c..6cf82d089 100644
--- a/core/field_colour.js
+++ b/core/field_colour.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -184,9 +173,9 @@ Blockly.FieldColour.prototype.configure_ = function(config) {
*/
Blockly.FieldColour.prototype.initView = function() {
this.size_ = new Blockly.utils.Size(
- this.constants_.FIELD_COLOUR_DEFAULT_WIDTH,
- this.constants_.FIELD_COLOUR_DEFAULT_HEIGHT);
- if (!this.constants_.FIELD_COLOUR_FULL_BLOCK) {
+ this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,
+ this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);
+ if (!this.getConstants().FIELD_COLOUR_FULL_BLOCK) {
this.createBorderRect_();
this.borderRect_.style['fillOpacity'] = '1';
} else {
@@ -198,7 +187,7 @@ Blockly.FieldColour.prototype.initView = function() {
* @override
*/
Blockly.FieldColour.prototype.applyColour = function() {
- if (!this.constants_.FIELD_COLOUR_FULL_BLOCK) {
+ if (!this.getConstants().FIELD_COLOUR_FULL_BLOCK) {
if (this.borderRect_) {
this.borderRect_.style.fill = this.getValue();
}
diff --git a/core/field_date.js b/core/field_date.js
index a39ca849e..aaed6bfa4 100644
--- a/core/field_date.js
+++ b/core/field_date.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2015 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/field_dropdown.js b/core/field_dropdown.js
index 4a42c3429..87062c5a4 100644
--- a/core/field_dropdown.js
+++ b/core/field_dropdown.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -212,7 +201,7 @@ Blockly.FieldDropdown.prototype.initView = function() {
this.imageElement_ = /** @type {!SVGImageElement} */
(Blockly.utils.dom.createSvgElement('image', {}, this.fieldGroup_));
- if (this.constants_.FIELD_DROPDOWN_SVG_ARROW) {
+ if (this.getConstants().FIELD_DROPDOWN_SVG_ARROW) {
this.createSVGArrow_();
} else {
this.createTextArrow_();
@@ -229,8 +218,8 @@ Blockly.FieldDropdown.prototype.initView = function() {
* @protected
*/
Blockly.FieldDropdown.prototype.shouldAddBorderRect_ = function() {
- return !this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
- (this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW &&
+ return !this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
+ (this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW &&
!this.sourceBlock_.isShadow());
};
@@ -258,17 +247,17 @@ Blockly.FieldDropdown.prototype.createTextArrow_ = function() {
*/
Blockly.FieldDropdown.prototype.createSVGArrow_ = function() {
this.svgArrow_ = Blockly.utils.dom.createSvgElement('image', {
- 'height': this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px',
- 'width': this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px'
+ 'height': this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px',
+ 'width': this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE + 'px'
}, this.fieldGroup_);
this.svgArrow_.setAttributeNS(Blockly.utils.dom.XLINK_NS, 'xlink:href',
- this.constants_.FIELD_DROPDOWN_SVG_ARROW_DATAURI);
+ this.getConstants().FIELD_DROPDOWN_SVG_ARROW_DATAURI);
};
/**
* Create a dropdown menu under the text.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @private
*/
Blockly.FieldDropdown.prototype.showEditor_ = function(opt_e) {
@@ -284,7 +273,7 @@ Blockly.FieldDropdown.prototype.showEditor_ = function(opt_e) {
Blockly.utils.dom.addClass(
/** @type {!Element} */ (this.menu_.getElement()), 'blocklyDropdownMenu');
- if (this.constants_.FIELD_DROPDOWN_COLOURED_DIV) {
+ if (this.getConstants().FIELD_DROPDOWN_COLOURED_DIV) {
var primaryColour = (this.sourceBlock_.isShadow()) ?
this.sourceBlock_.getParent().getColour() :
this.sourceBlock_.getColour();
@@ -575,10 +564,8 @@ Blockly.FieldDropdown.prototype.render_ = function() {
} else {
this.renderSelectedText_();
}
- if (this.borderRect_) {
- this.borderRect_.setAttribute('height', this.size_.height);
- this.borderRect_.setAttribute('width', this.size_.width);
- }
+
+ this.positionBorderRect_();
};
/**
@@ -599,36 +586,36 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function(imageJson) {
// Height and width include the border rect.
var hasBorder = !!this.borderRect_;
- this.size_.height = Math.max(
- hasBorder ? this.constants_.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
+ var height = Math.max(
+ hasBorder ? this.getConstants().FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
imageHeight + Blockly.FieldDropdown.IMAGE_Y_PADDING);
- var halfHeight = this.size_.height / 2;
- var xPadding = hasBorder ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
+ var xPadding = hasBorder ? this.getConstants().FIELD_BORDER_RECT_X_PADDING : 0;
var arrowWidth = 0;
if (this.svgArrow_) {
- arrowWidth = this.positionSVGArrow_(imageWidth + xPadding, halfHeight -
- this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
+ arrowWidth = this.positionSVGArrow_(imageWidth + xPadding, height / 2 -
+ this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
} else {
arrowWidth = Blockly.utils.dom.getFastTextWidth(
/** @type {!SVGTSpanElement} */ (this.arrow_),
- this.constants_.FIELD_TEXT_FONTSIZE,
- this.constants_.FIELD_TEXT_FONTWEIGHT,
- this.constants_.FIELD_TEXT_FONTFAMILY);
+ this.getConstants().FIELD_TEXT_FONTSIZE,
+ this.getConstants().FIELD_TEXT_FONTWEIGHT,
+ this.getConstants().FIELD_TEXT_FONTFAMILY);
}
this.size_.width = imageWidth + arrowWidth + xPadding * 2;
+ this.size_.height = height;
+ var arrowX = 0;
if (this.sourceBlock_.RTL) {
var imageX = xPadding + arrowWidth;
- var arrowX = xPadding - 1;
this.imageElement_.setAttribute('x', imageX);
- this.textElement_.setAttribute('x', arrowX);
} else {
- var arrowX = imageWidth + arrowWidth + xPadding + 1;
+ arrowX = imageWidth + arrowWidth;
this.textElement_.setAttribute('text-anchor', 'end');
- this.textElement_.setAttribute('x', arrowX);
this.imageElement_.setAttribute('x', xPadding);
}
- this.imageElement_.setAttribute('y', halfHeight - imageHeight / 2);
+ this.imageElement_.setAttribute('y', height / 2 - imageHeight / 2);
+
+ this.positionTextElement_(arrowX + xPadding, imageWidth + arrowWidth);
};
/**
@@ -644,31 +631,23 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
// Height and width include the border rect.
var hasBorder = !!this.borderRect_;
- this.size_.height = Math.max(
- hasBorder ? this.constants_.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
- this.constants_.FIELD_TEXT_HEIGHT);
- var halfHeight = this.size_.height / 2;
+ var height = Math.max(
+ hasBorder ? this.getConstants().FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
+ this.getConstants().FIELD_TEXT_HEIGHT);
var textWidth = Blockly.utils.dom.getFastTextWidth(this.textElement_,
- this.constants_.FIELD_TEXT_FONTSIZE,
- this.constants_.FIELD_TEXT_FONTWEIGHT,
- this.constants_.FIELD_TEXT_FONTFAMILY);
- var xPadding = hasBorder ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
+ this.getConstants().FIELD_TEXT_FONTSIZE,
+ this.getConstants().FIELD_TEXT_FONTWEIGHT,
+ this.getConstants().FIELD_TEXT_FONTFAMILY);
+ var xPadding = hasBorder ? this.getConstants().FIELD_BORDER_RECT_X_PADDING : 0;
var arrowWidth = 0;
if (this.svgArrow_) {
- arrowWidth = this.positionSVGArrow_(textWidth + xPadding, halfHeight -
- this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
+ arrowWidth = this.positionSVGArrow_(textWidth + xPadding, height / 2 -
+ this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE / 2);
}
this.size_.width = textWidth + arrowWidth + xPadding * 2;
+ this.size_.height = height;
- this.textElement_.setAttribute('x', this.sourceBlock_.RTL ?
- this.size_.width - textWidth - xPadding : xPadding);
- this.textElement_.setAttribute('y', halfHeight);
- if (!this.constants_.FIELD_TEXT_BASELINE_CENTER) {
- this.textElement_.setAttribute('dy',
- this.constants_.FIELD_TEXT_BASELINE_Y -
- this.constants_.FIELD_TEXT_HEIGHT / 2 +
- this.constants_.FIELD_TEXT_Y_OFFSET);
- }
+ this.positionTextElement_(xPadding, textWidth);
};
/**
@@ -683,9 +662,9 @@ Blockly.FieldDropdown.prototype.positionSVGArrow_ = function(x, y) {
return 0;
}
var hasBorder = !!this.borderRect_;
- var xPadding = hasBorder ? this.constants_.FIELD_BORDER_RECT_X_PADDING : 0;
- var textPadding = this.constants_.FIELD_DROPDOWN_SVG_ARROW_PADDING;
- var svgArrowSize = this.constants_.FIELD_DROPDOWN_SVG_ARROW_SIZE;
+ var xPadding = hasBorder ? this.getConstants().FIELD_BORDER_RECT_X_PADDING : 0;
+ var textPadding = this.getConstants().FIELD_DROPDOWN_SVG_ARROW_PADDING;
+ var svgArrowSize = this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE;
var arrowX = this.sourceBlock_.RTL ? xPadding : x + textPadding;
this.svgArrow_.setAttribute('transform',
'translate(' + arrowX + ',' + y + ')');
diff --git a/core/field_image.js b/core/field_image.js
index f60c40a92..32af8adca 100644
--- a/core/field_image.js
+++ b/core/field_image.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -191,6 +180,17 @@ Blockly.FieldImage.prototype.initView = function() {
this.fieldGroup_));
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
'xlink:href', /** @type {string} */ (this.value_));
+
+ if (this.clickHandler_) {
+ this.imageElement_.style.cursor = 'pointer';
+ }
+};
+
+/**
+ * @override
+ */
+Blockly.FieldImage.prototype.updateSize_ = function() {
+ // NOP
};
/**
diff --git a/core/field_label.js b/core/field_label.js
index 510a457d7..666e2ec78 100644
--- a/core/field_label.js
+++ b/core/field_label.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/field_label_serializable.js b/core/field_label_serializable.js
index 38eff9179..eeaac9ffa 100644
--- a/core/field_label_serializable.js
+++ b/core/field_label_serializable.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/field_multilineinput.js b/core/field_multilineinput.js
index df4293e5b..734f4135a 100644
--- a/core/field_multilineinput.js
+++ b/core/field_multilineinput.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -71,13 +60,6 @@ Blockly.utils.object.inherits(Blockly.FieldMultilineInput,
Blockly.FieldTextInput);
-/**
- * The default height of a single line of text.
- * @type {number}
- * @const
- */
-Blockly.FieldMultilineInput.LINE_HEIGHT = 20;
-
/**
* Construct a FieldMultilineInput from a JSON arg object,
* dereferencing any string table references.
@@ -154,14 +136,16 @@ Blockly.FieldMultilineInput.prototype.render_ = function() {
var lines = this.getDisplayText_().split('\n');
var y = 0;
for (var i = 0; i < lines.length; i++) {
+ var lineHeight = this.getConstants().FIELD_TEXT_HEIGHT +
+ this.getConstants().FIELD_BORDER_RECT_Y_PADDING;
var span = Blockly.utils.dom.createSvgElement('text', {
'class': 'blocklyText blocklyMultilineText',
- x: this.constants_.FIELD_BORDER_RECT_X_PADDING,
- y: y + this.constants_.FIELD_BORDER_RECT_Y_PADDING,
- dy: Blockly.FieldMultilineInput.LINE_HEIGHT / 2
+ x: this.getConstants().FIELD_BORDER_RECT_X_PADDING,
+ y: y + this.getConstants().FIELD_BORDER_RECT_Y_PADDING,
+ dy: this.getConstants().FIELD_TEXT_BASELINE
}, this.textGroup_);
span.appendChild(document.createTextNode(lines[i]));
- y += Blockly.FieldMultilineInput.LINE_HEIGHT;
+ y += lineHeight;
}
this.updateSize_();
@@ -202,34 +186,19 @@ Blockly.FieldMultilineInput.prototype.updateSize_ = function() {
if (textWidth > totalWidth) {
totalWidth = textWidth;
}
- totalHeight += Blockly.FieldMultilineInput.LINE_HEIGHT;
+ totalHeight += this.getConstants().FIELD_TEXT_HEIGHT +
+ (i > 0 ? this.getConstants().FIELD_BORDER_RECT_Y_PADDING : 0);
}
if (this.borderRect_) {
- totalWidth += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
+ totalHeight += this.getConstants().FIELD_BORDER_RECT_Y_PADDING * 2;
+ totalWidth += this.getConstants().FIELD_BORDER_RECT_X_PADDING * 2;
this.borderRect_.setAttribute('width', totalWidth);
this.borderRect_.setAttribute('height', totalHeight);
}
this.size_.width = totalWidth;
this.size_.height = totalHeight;
-};
-/**
- * Resize the editor to fit the text.
- * @protected
- */
-Blockly.FieldMultilineInput.prototype.resizeEditor_ = function() {
- var div = Blockly.WidgetDiv.DIV;
- var bBox = this.getScaledBBox();
- div.style.width = bBox.right - bBox.left + 'px';
- div.style.height = bBox.bottom - bBox.top + 'px';
-
- // In RTL mode block fields and LTR input fields the left edge moves,
- // whereas the right edge is fixed. Reposition the editor.
- var x = this.sourceBlock_.RTL ? bBox.right - div.offsetWidth : bBox.left;
- var xy = new Blockly.utils.Coordinate(x, bBox.top);
-
- div.style.left = xy.x + 'px';
- div.style.top = xy.y + 'px';
+ this.positionBorderRect_();
};
/**
@@ -239,21 +208,24 @@ Blockly.FieldMultilineInput.prototype.resizeEditor_ = function() {
*/
Blockly.FieldMultilineInput.prototype.widgetCreate_ = function() {
var div = Blockly.WidgetDiv.DIV;
- var scale = this.workspace_.scale;
+ var scale = this.workspace_.getScale();
- var htmlInput = /** @type {HTMLTextAreaElement} */ (document.createElement('textarea'));
+ var htmlInput =
+ /** @type {HTMLTextAreaElement} */ (document.createElement('textarea'));
htmlInput.className = 'blocklyHtmlInput blocklyHtmlTextAreaInput';
htmlInput.setAttribute('spellcheck', this.spellcheck_);
- var fontSize = (this.constants_.FIELD_TEXT_FONTSIZE * scale) + 'pt';
+ var fontSize = (this.getConstants().FIELD_TEXT_FONTSIZE * scale) + 'pt';
div.style.fontSize = fontSize;
htmlInput.style.fontSize = fontSize;
var borderRadius = (Blockly.FieldTextInput.BORDERRADIUS * scale) + 'px';
htmlInput.style.borderRadius = borderRadius;
- var padding = this.constants_.FIELD_BORDER_RECT_X_PADDING * scale;
- htmlInput.style.paddingLeft = padding + 'px';
- htmlInput.style.width = 'calc(100% - ' + padding + 'px)';
- htmlInput.style.lineHeight =
- (Blockly.FieldMultilineInput.LINE_HEIGHT * scale) + 'px';
+ var paddingX = this.getConstants().FIELD_BORDER_RECT_X_PADDING * scale;
+ var paddingY = this.getConstants().FIELD_BORDER_RECT_Y_PADDING * scale / 2;
+ htmlInput.style.padding = paddingY + 'px ' + paddingX + 'px ' + paddingY +
+ 'px ' + paddingX + 'px';
+ var lineHeight = this.getConstants().FIELD_TEXT_HEIGHT +
+ this.getConstants().FIELD_BORDER_RECT_Y_PADDING;
+ htmlInput.style.lineHeight = (lineHeight * scale) + 'px';
div.appendChild(htmlInput);
diff --git a/core/field_number.js b/core/field_number.js
index 9cdd99439..8e49a2abe 100644
--- a/core/field_number.js
+++ b/core/field_number.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2016 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/field_registry.js b/core/field_registry.js
index 4f0814fcd..5e6b7bde0 100644
--- a/core/field_registry.js
+++ b/core/field_registry.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/field_textinput.js b/core/field_textinput.js
index 69b20bc54..2343a2232 100644
--- a/core/field_textinput.js
+++ b/core/field_textinput.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -139,7 +128,7 @@ Blockly.FieldTextInput.prototype.configure_ = function(config) {
* @override
*/
Blockly.FieldTextInput.prototype.initView = function() {
- if (this.constants_.FULL_BLOCK_FIELDS) {
+ if (this.getConstants().FULL_BLOCK_FIELDS) {
// Step one: figure out if this is the only field on this block.
// Rendering is quite different in that case.
var nFields = 0;
@@ -227,13 +216,13 @@ Blockly.FieldTextInput.prototype.doValueUpdate_ = function(newValue) {
* @package
*/
Blockly.FieldTextInput.prototype.applyColour = function() {
- if (this.sourceBlock_ && this.constants_.FULL_BLOCK_FIELDS) {
+ if (this.sourceBlock_ && this.getConstants().FULL_BLOCK_FIELDS) {
if (this.borderRect_) {
this.borderRect_.setAttribute('stroke',
this.sourceBlock_.style.colourTertiary);
} else {
this.sourceBlock_.pathObject.svgPath.setAttribute('fill',
- this.constants_.FIELD_BORDER_RECT_COLOUR);
+ this.getConstants().FIELD_BORDER_RECT_COLOUR);
}
}
};
@@ -279,7 +268,7 @@ Blockly.FieldTextInput.prototype.setSpellcheck = function(check) {
/**
* Show the inline free-text editor on top of the text.
* @param {Event=} _opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @param {boolean=} opt_quietInput True if editor should be created without
* focus. Defaults to false.
* @protected
@@ -341,9 +330,9 @@ Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
var htmlInput = /** @type {HTMLInputElement} */ (document.createElement('input'));
htmlInput.className = 'blocklyHtmlInput';
htmlInput.setAttribute('spellcheck', this.spellcheck_);
- var scale = this.workspace_.scale;
+ var scale = this.workspace_.getScale();
var fontSize =
- (this.constants_.FIELD_TEXT_FONTSIZE * scale) + 'pt';
+ (this.getConstants().FIELD_TEXT_FONTSIZE * scale) + 'pt';
div.style.fontSize = fontSize;
htmlInput.style.fontSize = fontSize;
var borderRadius =
@@ -361,7 +350,7 @@ Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
htmlInput.style.border = (1 * scale) + 'px solid ' + strokeColour;
div.style.borderRadius = borderRadius;
div.style.transition = 'box-shadow 0.25s ease 0s';
- if (this.constants_.FIELD_TEXTINPUT_BOX_SHADOW) {
+ if (this.getConstants().FIELD_TEXTINPUT_BOX_SHADOW) {
div.style.boxShadow = 'rgba(255, 255, 255, 0.3) 0px 0px 0px ' +
4 * scale + 'px';
}
diff --git a/core/field_variable.js b/core/field_variable.js
index 8d486d197..7d7801384 100644
--- a/core/field_variable.js
+++ b/core/field_variable.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -156,7 +145,7 @@ Blockly.FieldVariable.prototype.initModel = function() {
*/
Blockly.FieldVariable.prototype.shouldAddBorderRect_ = function() {
return Blockly.FieldVariable.superClass_.shouldAddBorderRect_.call(this) &&
- (!this.constants_.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
+ (!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
this.sourceBlock_.type != 'variables_get');
};
diff --git a/core/flyout_base.js b/core/flyout_base.js
index 471c4d558..5d0628700 100644
--- a/core/flyout_base.js
+++ b/core/flyout_base.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2011 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -57,6 +46,8 @@ Blockly.Flyout = function(workspaceOptions) {
*/
this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
this.workspace_.isFlyout = true;
+ // Keep the workspace visibility consistent with the flyout's visibility.
+ this.workspace_.setVisible(this.isVisible_);
/**
* Is RTL vs LTR.
@@ -557,6 +548,7 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
for (var j = 0; j < this.mats_.length; j++) {
var rect = this.mats_[j];
if (rect) {
+ Blockly.Tooltip.unbindMouseEvents(rect);
Blockly.utils.dom.removeNode(rect);
}
}
@@ -638,8 +630,8 @@ Blockly.Flyout.prototype.isBlockCreatable_ = function(block) {
/**
* Create a copy of this block on the workspace.
* @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout.
- * @return {Blockly.BlockSvg} The newly created block, or null if something
- * went wrong with deserialization.
+ * @return {!Blockly.BlockSvg} The newly created block.
+ * @throws {Error} if something went wrong with deserialization.
* @package
*/
Blockly.Flyout.prototype.createBlock = function(originalBlock) {
diff --git a/core/flyout_button.js b/core/flyout_button.js
index f400f0fb6..f4cead8af 100644
--- a/core/flyout_button.js
+++ b/core/flyout_button.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2016 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -97,9 +86,14 @@ Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) {
};
/**
- * The margin around the text in the button.
+ * The horizontal margin around the text in the button.
*/
-Blockly.FlyoutButton.MARGIN = 5;
+Blockly.FlyoutButton.MARGIN_X = 5;
+
+/**
+ * The vertical margin around the text in the button.
+ */
+Blockly.FlyoutButton.MARGIN_Y = 2;
/**
* The width of the button's rect.
@@ -164,11 +158,18 @@ Blockly.FlyoutButton.prototype.createDom = function() {
'flyoutForegroundColour', 'fill');
}
- this.width = Blockly.utils.dom.getTextWidth(svgText);
- this.height = 20; // Can't compute it :(
-
+ var fontSize = Blockly.utils.style.getComputedStyle(svgText, 'fontSize');
+ var fontWeight = Blockly.utils.style.getComputedStyle(svgText, 'fontWeight');
+ var fontFamily = Blockly.utils.style.getComputedStyle(svgText, 'fontFamily');
+ this.width = Blockly.utils.dom.getFastTextWidthWithSizeString(svgText,
+ fontSize, fontWeight, fontFamily);
+ var fontMetrics = Blockly.utils.dom.measureFontMetrics(text, fontSize,
+ fontWeight, fontFamily);
+ this.height = fontMetrics.height;
+
if (!this.isLabel_) {
- this.width += 2 * Blockly.FlyoutButton.MARGIN;
+ this.width += 2 * Blockly.FlyoutButton.MARGIN_X;
+ this.height += 2 * Blockly.FlyoutButton.MARGIN_Y;
shadow.setAttribute('width', this.width);
shadow.setAttribute('height', this.height);
}
@@ -176,7 +177,8 @@ Blockly.FlyoutButton.prototype.createDom = function() {
rect.setAttribute('height', this.height);
svgText.setAttribute('x', this.width / 2);
- svgText.setAttribute('y', this.height - Blockly.FlyoutButton.MARGIN);
+ svgText.setAttribute('y', this.height / 2 - fontMetrics.height / 2 +
+ fontMetrics.baseline);
this.updateTransform_();
@@ -292,9 +294,5 @@ Blockly.Css.register([
'.blocklyFlyoutLabelBackground {',
'opacity: 0;',
'}',
-
- '.blocklyFlyoutLabelText {',
- 'fill: #000;',
- '}'
/* eslint-enable indent */
]);
diff --git a/core/flyout_dragger.js b/core/flyout_dragger.js
index 545c2fb1e..3b0828e8c 100644
--- a/core/flyout_dragger.js
+++ b/core/flyout_dragger.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/flyout_horizontal.js b/core/flyout_horizontal.js
index 1bb701790..7efea87f5 100644
--- a/core/flyout_horizontal.js
+++ b/core/flyout_horizontal.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js
index 0404ff205..ae27031ee 100644
--- a/core/flyout_vertical.js
+++ b/core/flyout_vertical.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/generator.js b/core/generator.js
index 8a73d5f8c..6937042d5 100644
--- a/core/generator.js
+++ b/core/generator.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/gesture.js b/core/gesture.js
index 1e069ec4e..3de14fc38 100644
--- a/core/gesture.js
+++ b/core/gesture.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/grid.js b/core/grid.js
index 72367c10b..89b1a4ca8 100644
--- a/core/grid.js
+++ b/core/grid.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -178,7 +167,7 @@ Blockly.Grid.prototype.setLineAttributes_ = function(line, width,
* Move the grid to a new x and y position, and make sure that change is
* visible.
* @param {number} x The new x position of the grid (in px).
- * @param {number} y The new y position ofthe grid (in px).
+ * @param {number} y The new y position of the grid (in px).
* @package
*/
Blockly.Grid.prototype.moveTo = function(x, y) {
diff --git a/core/icon.js b/core/icon.js
index 5fb7cf9c7..7123dbc6a 100644
--- a/core/icon.js
+++ b/core/icon.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2013 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/inject.js b/core/inject.js
index cade0f695..cc599ab9f 100644
--- a/core/inject.js
+++ b/core/inject.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2011 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -167,9 +156,9 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
// Set the theme name and renderer name onto the injection div.
Blockly.utils.dom.addClass(mainWorkspace.getInjectionDiv(),
- (wsOptions.renderer || 'geras') + '-renderer');
+ mainWorkspace.getRenderer().getClassName());
Blockly.utils.dom.addClass(mainWorkspace.getInjectionDiv(),
- mainWorkspace.getTheme().name + '-theme');
+ mainWorkspace.getTheme().getClassName());
if (!wsOptions.hasCategories && wsOptions.languageTree) {
// Add flyout as an that is a sibling of the workspace svg.
diff --git a/core/input.js b/core/input.js
index b8fd2e944..8e6bfb7b4 100644
--- a/core/input.js
+++ b/core/input.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/insertion_marker_manager.js b/core/insertion_marker_manager.js
index 92860e643..49f264e72 100644
--- a/core/insertion_marker_manager.js
+++ b/core/insertion_marker_manager.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -116,20 +105,19 @@ Blockly.InsertionMarkerManager = function(block) {
this.markerConnection_ = null;
/**
- * Whether we are currently highlighting the block (shadow or real) that would
- * be replaced if the drag were released immediately.
- * @type {boolean}
- * @private
- */
- this.highlightingBlock_ = false;
-
- /**
- * The block that is being highlighted for replacement, or null.
+ * The block that currently has an input being highlighted, or null.
* @type {Blockly.BlockSvg}
* @private
*/
this.highlightedBlock_ = null;
+ /**
+ * The block being faded to indicate replacement, or null.
+ * @type {Blockly.BlockSvg}
+ * @private
+ */
+ this.fadedBlock_ = null;
+
/**
* The connections on the dragging blocks that are available to connect to
* other blocks. This includes all open connections on the top block, as well
@@ -141,6 +129,17 @@ Blockly.InsertionMarkerManager = function(block) {
this.availableConnections_ = this.initAvailableConnections_();
};
+/**
+ * An enum describing different kinds of previews the InsertionMarkerManager
+ * could display.
+ * @enum {number}
+ */
+Blockly.InsertionMarkerManager.PREVIEW_TYPE = {
+ INSERTION_MARKER: 0,
+ INPUT_OUTLINE: 1,
+ REPLACEMENT_FADE: 2,
+};
+
/**
* Sever all links from this object.
* @package
@@ -210,7 +209,7 @@ Blockly.InsertionMarkerManager.prototype.applyConnections = function() {
};
/**
- * Update highlighted connections based on the most recent move location.
+ * Update connections based on the most recent move location.
* @param {!Blockly.utils.Coordinate} dxy Position relative to drag start,
* in workspace units.
* @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH},
@@ -255,16 +254,19 @@ Blockly.InsertionMarkerManager.prototype.createMarkerBlock_ = function(sourceBlo
}
}
result.setCollapsed(sourceBlock.isCollapsed());
- // Copy field values from the other block. These values may impact the
- // rendered size of the insertion marker. Note that we do not care about
- // child blocks here.
+ result.setInputsInline(sourceBlock.getInputsInline());
+ // Copy visible field values from the other block. These values may impact
+ // the rendered size of the insertion marker. Note that we do not care
+ // about child blocks here.
for (var i = 0; i < sourceBlock.inputList.length; i++) {
var sourceInput = sourceBlock.inputList[i];
- var resultInput = result.inputList[i];
- for (var j = 0; j < sourceInput.fieldRow.length; j++) {
- var sourceField = sourceInput.fieldRow[j];
- var resultField = resultInput.fieldRow[j];
- resultField.setValue(sourceField.getValue());
+ if (sourceInput.isVisible()) {
+ var resultInput = result.inputList[i];
+ for (var j = 0; j < sourceInput.fieldRow.length; j++) {
+ var sourceField = sourceInput.fieldRow[j];
+ var resultField = resultInput.fieldRow[j];
+ resultField.setValue(sourceField.getValue());
+ }
}
}
@@ -394,48 +396,6 @@ Blockly.InsertionMarkerManager.prototype.getStartRadius_ = function() {
return Blockly.SNAP_RADIUS;
};
-/**
- * Whether ending the drag would replace a block or insert a block.
- * @return {boolean} True if dropping the block immediately would replace
- * another block. False if dropping the block immediately would result in
- * the block being inserted in a block stack.
- * @private
- */
-Blockly.InsertionMarkerManager.prototype.shouldReplace_ = function() {
- var closest = this.closestConnection_;
- var local = this.localConnection_;
-
- // Dragging a block over an existing block in an input.
- if (local.type == Blockly.OUTPUT_VALUE) {
- // Insert the dragged block into the stack if possible.
- if (closest &&
- this.workspace_.getRenderer()
- .shouldInsertDraggedBlock(this.topBlock_, closest)) {
- return false; // Insert.
- }
- // Otherwise replace the existing block and bump it out.
- return true; // Replace.
- }
-
- // Connecting to a statement input of c-block is an insertion, even if that
- // c-block is terminal (e.g. forever).
- if (local == local.getSourceBlock().getFirstStatementConnection()) {
- return false; // Insert.
- }
-
- // Dragging a terminal block over another (connected) terminal block will
- // replace, not insert.
- var isTerminalBlock = !this.topBlock_.nextConnection;
- var isConnectedTerminal = isTerminalBlock &&
- local.type == Blockly.PREVIOUS_STATEMENT && closest.isConnected();
- if (isConnectedTerminal) {
- return true; // Replace.
- }
-
- // Otherwise it's an insertion.
- return false;
-};
-
/**
* Whether ending the drag would delete the block.
* @param {!Object} candidate An object containing a local connection, a closest
@@ -498,16 +458,28 @@ Blockly.InsertionMarkerManager.prototype.maybeShowPreview_ = function(candidate)
* @private
*/
Blockly.InsertionMarkerManager.prototype.showPreview_ = function() {
- if (this.shouldReplace_()) {
- this.highlightBlock_();
- } else { // Should insert
- this.connectMarker_();
+ var closest = this.closestConnection_;
+ var renderer = this.workspace_.getRenderer();
+ var method = renderer.getConnectionPreviewMethod(
+ /** @type {!Blockly.RenderedConnection} */ (closest),
+ /** @type {!Blockly.RenderedConnection} */ (this.localConnection_),
+ this.topBlock_);
+
+ switch (method) {
+ case Blockly.InsertionMarkerManager.PREVIEW_TYPE.INPUT_OUTLINE:
+ this.showInsertionInputOutline_();
+ break;
+ case Blockly.InsertionMarkerManager.PREVIEW_TYPE.INSERTION_MARKER:
+ this.showInsertionMarker_();
+ break;
+ case Blockly.InsertionMarkerManager.PREVIEW_TYPE.REPLACEMENT_FADE:
+ this.showReplacementFade_();
+ break;
}
- // Also highlight the actual connection, as a nod to previous behaviour.
- if (this.closestConnection_ && this.closestConnection_.targetBlock() &&
- this.workspace_.getRenderer()
- .shouldHighlightConnection(this.closestConnection_)) {
- this.closestConnection_.highlight();
+
+ // Optionally highlight the actual connection, as a nod to previous behaviour.
+ if (closest && renderer.shouldHighlightConnection(closest)) {
+ closest.highlight();
}
};
@@ -555,53 +527,57 @@ Blockly.InsertionMarkerManager.prototype.hidePreview_ = function() {
.shouldHighlightConnection(this.closestConnection_)) {
this.closestConnection_.unhighlight();
}
- if (this.highlightingBlock_) {
- this.unhighlightBlock_();
+ if (this.fadedBlock_) {
+ this.hideReplacementFade_();
+ } else if (this.highlightedBlock_) {
+ this.hideInsertionInputOutline_();
} else if (this.markerConnection_) {
- this.disconnectMarker_();
+ this.hideInsertionMarker_();
}
};
/**
- * Add highlighting showing which block will be replaced.
+ * Shows an insertion marker connected to the appropriate blocks (based on
+ * manager state).
* @private
*/
-Blockly.InsertionMarkerManager.prototype.highlightBlock_ = function() {
- var closest = this.closestConnection_;
+Blockly.InsertionMarkerManager.prototype.showInsertionMarker_ = function() {
var local = this.localConnection_;
- if (closest.targetBlock()) {
- this.highlightedBlock_ = closest.targetBlock();
- closest.targetBlock().highlightForReplacement(true);
- } else if (local.type == Blockly.OUTPUT_VALUE) {
- this.highlightedBlock_ = closest.getSourceBlock();
- closest.getSourceBlock().highlightShapeForInput(closest, true);
- }
- this.highlightingBlock_ = true;
-};
-
-/**
- * Get rid of the highlighting marking the block that will be replaced.
- * @private
- */
-Blockly.InsertionMarkerManager.prototype.unhighlightBlock_ = function() {
var closest = this.closestConnection_;
- // If there's no block in place, but we're still connecting to a value input,
- // then we must have been highlighting an input shape.
- if (closest.type == Blockly.INPUT_VALUE && !closest.isConnected()) {
- this.highlightedBlock_.highlightShapeForInput(closest, false);
- } else {
- this.highlightedBlock_.highlightForReplacement(false);
+
+ var isLastInStack = this.lastOnStack_ && local == this.lastOnStack_;
+ var imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_;
+ var imConn = imBlock.getMatchingConnection(local.getSourceBlock(), local);
+
+ if (imConn == this.markerConnection_) {
+ throw Error('Made it to showInsertionMarker_ even though the marker isn\'t ' +
+ 'changing');
}
- this.highlightedBlock_ = null;
- this.highlightingBlock_ = false;
+
+ // Render disconnected from everything else so that we have a valid
+ // connection location.
+ imBlock.render();
+ imBlock.rendered = true;
+ imBlock.getSvgRoot().setAttribute('visibility', 'visible');
+
+ if (imConn && closest) {
+ // Position so that the existing block doesn't move.
+ imBlock.positionNearConnection(imConn, closest);
+ }
+ if (closest) {
+ // Connect() also renders the insertion marker.
+ imConn.connect(closest);
+ }
+
+ this.markerConnection_ = imConn;
};
/**
- * Disconnect the insertion marker block in a manner that returns the stack to
- * original state.
+ * Disconnects and hides the current insertion marker. Should return the blocks
+ * to their original state.
* @private
*/
-Blockly.InsertionMarkerManager.prototype.disconnectMarker_ = function() {
+Blockly.InsertionMarkerManager.prototype.hideInsertionMarker_ = function() {
if (!this.markerConnection_) {
console.log('No insertion marker connection to disconnect');
return;
@@ -649,38 +625,41 @@ Blockly.InsertionMarkerManager.prototype.disconnectMarker_ = function() {
};
/**
- * Add an insertion marker connected to the appropriate blocks.
+ * Shows an outline around the input the closest connection belongs to.
* @private
*/
-Blockly.InsertionMarkerManager.prototype.connectMarker_ = function() {
- var local = this.localConnection_;
+Blockly.InsertionMarkerManager.prototype.showInsertionInputOutline_ = function() {
var closest = this.closestConnection_;
+ this.highlightedBlock_ = closest.getSourceBlock();
+ this.highlightedBlock_.highlightShapeForInput(closest, true);
+};
- var isLastInStack = this.lastOnStack_ && local == this.lastOnStack_;
- var imBlock = isLastInStack ? this.lastMarker_ : this.firstMarker_;
- var imConn = imBlock.getMatchingConnection(local.getSourceBlock(), local);
+/**
+ * Hides any visible input outlines.
+ * @private
+ */
+Blockly.InsertionMarkerManager.prototype.hideInsertionInputOutline_ = function() {
+ this.highlightedBlock_.highlightShapeForInput(this.closestConnection_, false);
+ this.highlightedBlock_ = null;
+};
- if (imConn == this.markerConnection_) {
- throw Error('Made it to connectMarker_ even though the marker isn\'t ' +
- 'changing');
- }
+/**
+ * Shows a replacement fade affect on the closest connection's target block
+ * (the block that is currently connected to it).
+ * @private
+ */
+Blockly.InsertionMarkerManager.prototype.showReplacementFade_ = function() {
+ this.fadedBlock_ = this.closestConnection_.targetBlock();
+ this.fadedBlock_.fadeForReplacement(true);
+};
- // Render disconnected from everything else so that we have a valid
- // connection location.
- imBlock.render();
- imBlock.rendered = true;
- imBlock.getSvgRoot().setAttribute('visibility', 'visible');
-
- if (imConn && closest) {
- // Position so that the existing block doesn't move.
- imBlock.positionNearConnection(imConn, closest);
- }
- if (closest) {
- // Connect() also renders the insertion marker.
- imConn.connect(closest);
- }
-
- this.markerConnection_ = imConn;
+/**
+ * Hides/Removes any visible fade affects.
+ * @private
+ */
+Blockly.InsertionMarkerManager.prototype.hideReplacementFade_ = function() {
+ this.fadedBlock_.fadeForReplacement(false);
+ this.fadedBlock_ = null;
};
/**
diff --git a/core/keyboard_nav/action.js b/core/keyboard_nav/action.js
index d4a3dbbe8..348049bf0 100644
--- a/core/keyboard_nav/action.js
+++ b/core/keyboard_nav/action.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/keyboard_nav/ast_node.js b/core/keyboard_nav/ast_node.js
index 509759aaf..4f111b84c 100644
--- a/core/keyboard_nav/ast_node.js
+++ b/core/keyboard_nav/ast_node.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -31,7 +20,7 @@ goog.require('Blockly.utils.Coordinate');
* It is recommended that you use one of the createNode methods instead of
* creating a node directly.
* @param {string} type The type of the location.
- * Must be in Bockly.ASTNode.types.
+ * Must be in Blockly.ASTNode.types.
* @param {!(Blockly.Block|Blockly.Connection|Blockly.Field|Blockly.Workspace)}
* location The position in the AST.
* @param {!Object=} opt_params Optional dictionary of options.
diff --git a/core/keyboard_nav/basic_cursor.js b/core/keyboard_nav/basic_cursor.js
index d301a2fb1..981c8cc89 100644
--- a/core/keyboard_nav/basic_cursor.js
+++ b/core/keyboard_nav/basic_cursor.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -90,7 +79,7 @@ Blockly.BasicCursor.prototype.prev = function() {
};
/**
- * For a basic cursor we only have the ability to go next and previou, so
+ * For a basic cursor we only have the ability to go next and previous, so
* out will allow the user to get to the previous node in the pre order traversal.
* @return {Blockly.ASTNode} The previous node, or null if the current node is
* not set or there is no previous value.
diff --git a/core/keyboard_nav/cursor.js b/core/keyboard_nav/cursor.js
index 7342e2491..1d8b4ae78 100644
--- a/core/keyboard_nav/cursor.js
+++ b/core/keyboard_nav/cursor.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/keyboard_nav/flyout_cursor.js b/core/keyboard_nav/flyout_cursor.js
index 9208a24fe..abe7a80a3 100644
--- a/core/keyboard_nav/flyout_cursor.js
+++ b/core/keyboard_nav/flyout_cursor.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/keyboard_nav/key_map.js b/core/keyboard_nav/key_map.js
index 01e5cea49..e0c4b7957 100644
--- a/core/keyboard_nav/key_map.js
+++ b/core/keyboard_nav/key_map.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/keyboard_nav/marker.js b/core/keyboard_nav/marker.js
index f70fa0eea..069475985 100644
--- a/core/keyboard_nav/marker.js
+++ b/core/keyboard_nav/marker.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/keyboard_nav/navigation.js b/core/keyboard_nav/navigation.js
index a2b861b5a..385ef676a 100644
--- a/core/keyboard_nav/navigation.js
+++ b/core/keyboard_nav/navigation.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -793,7 +782,7 @@ Blockly.navigation.onBlocklyAction = function(action) {
} else if (Blockly.navigation.READONLY_ACTION_LIST.indexOf(action) > -1) {
actionHandled = Blockly.navigation.handleActions_(action);
}
- // If not in accessibility mode only hanlde turning on keyboard navigation.
+ // If not in accessibility mode only handle turning on keyboard navigation.
} else if (action.name === Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV) {
Blockly.navigation.enableKeyboardAccessibility();
actionHandled = true;
@@ -1042,7 +1031,7 @@ Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV = new Blockly.Action(
'Turns on and off keyboard navigation.');
/**
- * The action to move the cursor to the keft on a worksapce.
+ * The action to move the cursor to the left on a workspace.
* @type {!Blockly.Action}
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT = new Blockly.Action(
@@ -1050,7 +1039,7 @@ Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT = new Blockly.Action(
'Move the workspace cursor to the lefts.');
/**
- * The action to move the cursor to the right on a worksapce.
+ * The action to move the cursor to the right on a workspace.
* @type {!Blockly.Action}
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT = new Blockly.Action(
@@ -1058,7 +1047,7 @@ Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT = new Blockly.Action(
'Move the workspace cursor to the right.');
/**
- * The action to move the cursor up on a worksapce.
+ * The action to move the cursor up on a workspace.
* @type {!Blockly.Action}
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP = new Blockly.Action(
@@ -1066,7 +1055,7 @@ Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP = new Blockly.Action(
'Move the workspace cursor up.');
/**
- * The action to move the cursor down on a worksapce.
+ * The action to move the cursor down on a workspace.
* @type {!Blockly.Action}
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN = new Blockly.Action(
diff --git a/core/keyboard_nav/tab_navigate_cursor.js b/core/keyboard_nav/tab_navigate_cursor.js
index 4074f3588..5e85136a9 100644
--- a/core/keyboard_nav/tab_navigate_cursor.js
+++ b/core/keyboard_nav/tab_navigate_cursor.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/marker_manager.js b/core/marker_manager.js
index e64ff2d74..22090e81e 100644
--- a/core/marker_manager.js
+++ b/core/marker_manager.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -165,6 +154,16 @@ Blockly.MarkerManager.prototype.setMarkerSvg = function(markerSvg) {
}
};
+/**
+ * Redraw the attached cursor svg if needed.
+ * @package
+ */
+Blockly.MarkerManager.prototype.updateMarkers = function() {
+ if (this.workspace_.keyboardAccessibilityMode && this.cursorSvg_) {
+ this.workspace_.getCursor().draw();
+ }
+};
+
/**
* Dispose of the marker manager.
* Go through and delete all markers associated with this marker manager.
diff --git a/core/msg.js b/core/msg.js
index 905ea8ec3..8cf7a2c5b 100644
--- a/core/msg.js
+++ b/core/msg.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2013 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/mutator.js b/core/mutator.js
index 9971f26be..313e3f101 100644
--- a/core/mutator.js
+++ b/core/mutator.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -171,7 +160,8 @@ Blockly.Mutator.prototype.createEditor_ = function() {
'media': this.block_.workspace.options.pathToMedia,
'rtl': this.block_.RTL,
'horizontalLayout': false,
- 'renderer': this.block_.workspace.options.renderer
+ 'renderer': this.block_.workspace.options.renderer,
+ 'rendererOverrides': this.block_.workspace.options.rendererOverrides
}));
workspaceOptions.toolboxPosition = this.block_.RTL ? Blockly.TOOLBOX_AT_RIGHT :
Blockly.TOOLBOX_AT_LEFT;
@@ -304,7 +294,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
for (var i = 0, child; (child = blocks[i]); i++) {
child.render();
}
- // The root block should not be dragable or deletable.
+ // The root block should not be draggable or deletable.
this.rootBlock_.setMovable(false);
this.rootBlock_.setDeletable(false);
if (flyout) {
diff --git a/core/names.js b/core/names.js
index daa7edb73..8772f1e41 100644
--- a/core/names.js
+++ b/core/names.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -93,7 +82,7 @@ Blockly.Names.prototype.setVariableMap = function(map) {
Blockly.Names.prototype.getNameForUserVariable_ = function(id) {
if (!this.variableMap_) {
console.log('Deprecated call to Blockly.Names.prototype.getName without ' +
- 'defining a variable map. To fix, add the folowing code in your ' +
+ 'defining a variable map. To fix, add the following code in your ' +
'generator\'s init() function:\n' +
'Blockly.YourGeneratorName.variableDB_.setVariableMap(' +
'workspace.getVariableMap());');
diff --git a/core/options.js b/core/options.js
index cf0d8dba2..fd97f8d94 100644
--- a/core/options.js
+++ b/core/options.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2016 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -142,6 +131,7 @@ Blockly.Options = function(options) {
this.theme = Blockly.Options.parseThemeOptions_(options);
this.keyMap = keyMap;
this.renderer = renderer;
+ this.rendererOverrides = options['rendererOverrides'];
/**
* The SVG element for the grid pattern.
@@ -160,7 +150,8 @@ Blockly.Options = function(options) {
/**
* Blockly options.
- * This interface is further described in `typings/blockly-interfaces.d.ts`.
+ * This interface is further described in
+ * `typings/parts/blockly-interfaces.d.ts`.
* @interface
*/
Blockly.BlocklyOptions = function() {};
@@ -292,8 +283,7 @@ Blockly.Options.parseThemeOptions_ = function(options) {
if (theme instanceof Blockly.Theme) {
return /** @type {!Blockly.Theme} */ (theme);
}
- return new Blockly.Theme('builtin',
- theme['blockStyles'], theme['categoryStyles'], theme['componentStyles']);
+ return Blockly.Theme.defineTheme('builtin', theme);
};
/**
diff --git a/core/procedures.js b/core/procedures.js
index b0bb55651..79fa4e630 100644
--- a/core/procedures.js
+++ b/core/procedures.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2012 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/rendered_connection.js b/core/rendered_connection.js
index 5ede9de0e..d6eab4827 100644
--- a/core/rendered_connection.js
+++ b/core/rendered_connection.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2016 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/core/renderers/common/block_rendering.js b/core/renderers/common/block_rendering.js
index da3a71f6a..8a7757cd1 100644
--- a/core/renderers/common/block_rendering.js
+++ b/core/renderers/common/block_rendering.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -90,27 +79,18 @@ Blockly.blockRendering.stopDebugger = function() {
/**
* Initialize anything needed for rendering (constants, etc).
* @param {!string} name Name of the renderer to initialize.
+ * @param {!Blockly.Theme} theme The workspace theme object.
+ * @param {Object=} opt_rendererOverrides Rendering constant overrides.
* @return {!Blockly.blockRendering.Renderer} The new instance of a renderer.
* Already initialized.
* @package
*/
-Blockly.blockRendering.init = function(name) {
+Blockly.blockRendering.init = function(name, theme, opt_rendererOverrides) {
if (!Blockly.blockRendering.rendererMap_[name]) {
throw Error('Renderer not registered: ', name);
}
- /**
- * Wrap the renderer constructor into a temporary constructor
- * function so the closure compiler treats it as a constructor.
- * @param {string} name The renderer name.
- * @constructor
- * @extends {Blockly.blockRendering.Renderer}
- */
- var rendererCtor = function(name) {
- rendererCtor.superClass_.constructor.call(this, name);
- };
- Blockly.utils.object.inherits(rendererCtor,
- Blockly.blockRendering.rendererMap_[name]);
- var renderer = new rendererCtor(name);
- renderer.init();
+ var renderer = (/** @type {!Blockly.blockRendering.Renderer} */ (
+ new Blockly.blockRendering.rendererMap_[name](name)));
+ renderer.init(theme, opt_rendererOverrides);
return renderer;
};
diff --git a/core/renderers/common/constants.js b/core/renderers/common/constants.js
index 654208612..8a5b19cff 100644
--- a/core/renderers/common/constants.js
+++ b/core/renderers/common/constants.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -29,6 +18,8 @@ goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.svgPaths');
goog.require('Blockly.utils.userAgent');
+goog.requireType('Blockly.blockRendering.Debug');
+
/**
* An object that provides constants for rendering blocks.
@@ -247,12 +238,6 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_TEXT_FONTSIZE = 11;
- /**
- * Height of text.
- * @type {number}
- */
- this.FIELD_TEXT_HEIGHT = 16;
-
/**
* Text font weight.
* @type {string}
@@ -265,6 +250,20 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_TEXT_FONTFAMILY = 'sans-serif';
+ /**
+ * Height of text. This constant is dynamically set in ``setFontConstants_``
+ * to be the height of the text based on the font used.
+ * @type {number}
+ */
+ this.FIELD_TEXT_HEIGHT = -1; // Dynamically set
+
+ /**
+ * Text baseline. This constant is dynamically set in ``setFontConstants_``
+ * to be the baseline of the text based on the font used.
+ * @type {number}
+ */
+ this.FIELD_TEXT_BASELINE = -1; // Dynamically set
+
/**
* A field's border rect corner radius.
* @type {number}
@@ -296,19 +295,6 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_BORDER_RECT_COLOUR = '#fff';
- /**
- * Field text baseline.
- * This is only used if `FIELD_TEXT_BASELINE_CENTER` is false.
- * @type {number}
- */
- this.FIELD_TEXT_BASELINE_Y = Blockly.utils.userAgent.GECKO ? 12 : 13.09;
-
- /**
- * An text offset adjusting the Y position of text after positioning.
- * @type {number}
- */
- this.FIELD_TEXT_Y_OFFSET = 0;
-
/**
* A field's text element's dominant baseline.
* @type {boolean}
@@ -403,25 +389,13 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.FIELD_CHECKBOX_X_OFFSET = this.FIELD_BORDER_RECT_X_PADDING - 3;
- /**
- * A checkbox field's Y offset.
- * @type {number}
- */
- this.FIELD_CHECKBOX_Y_OFFSET = 14;
-
- /**
- * A checkbox field's default width.
- * @type {number}
- */
- this.FIELD_CHECKBOX_DEFAULT_WIDTH = 15;
-
/**
* A random identifier used to ensure a unique ID is used for each
* filter/pattern for the case of multiple Blockly instances on a page.
* @type {string}
- * @protected
+ * @package
*/
- this.randomIdentifier_ = String(Math.random()).substring(2);
+ this.randomIdentifier = String(Math.random()).substring(2);
/**
* The ID of the emboss filter, or the empty string if no filter is set.
@@ -451,6 +425,27 @@ Blockly.blockRendering.ConstantProvider = function() {
*/
this.disabledPattern_ = null;
+ /**
+ * The ID of the debug filter, or the empty string if no pattern is set.
+ * @type {string}
+ * @package
+ */
+ this.debugFilterId = '';
+
+ /**
+ * The element to use for a debug highlight, or null if not set.
+ * @type {SVGElement}
+ * @private
+ */
+ this.debugFilter_ = null;
+
+ /**
+ * The
@@ -631,6 +675,15 @@ var spaghettiXml = [
+
+ Rendering:
+
+ Font Size
+
+
+
Log events:
@@ -1608,6 +1661,7 @@ var spaghettiXml = [
+
diff --git a/tests/playgrounds/screenshot.js b/tests/playgrounds/screenshot.js
index 4282cdec2..07521b310 100644
--- a/tests/playgrounds/screenshot.js
+++ b/tests/playgrounds/screenshot.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/tests/rendering/zelos/pxtblockly/zelos.html b/tests/rendering/zelos/pxtblockly/zelos.html
index 6d00f750e..4568ba25e 100644
--- a/tests/rendering/zelos/pxtblockly/zelos.html
+++ b/tests/rendering/zelos/pxtblockly/zelos.html
@@ -5,26 +5,6 @@
-
-
@@ -34,10 +14,6 @@
goog.require('Blockly.zelos.Renderer');
// Blockly.blockRendering.startDebugger();
- // This stub is a workaround in order to load pxt-blockly blocks, as they
- // rely on a setOutputShape method on the block.
- Blockly.BlockSvg.prototype.setOutputShape = function() { };
-
var blocklyDiv = document.getElementById('blocklyDiv');
var workspace;
window.addEventListener('message', function (msg) {
@@ -56,6 +32,11 @@
workspace = Blockly.inject(blocklyDiv, {
renderer: 'zelos',
+ rendererOverrides: {
+ 'FIELD_TEXT_FONTFAMILY': '"Helvetica Neue", "Segoe UI", Helvetica, sans-serif',
+ 'FIELD_TEXT_FONTWEIGHT': 'bold',
+ 'FIELD_TEXT_FONTSIZE': 12
+ },
move: {
scrollbars: true,
drag: true,
@@ -66,10 +47,6 @@
startScale: 2,
}
});
- var constants = workspace.getRenderer().getConstants();
- constants.FIELD_TEXT_FONTSIZE = 12;
- constants.FIELD_TEXT_FONTWEIGHT = 'bold';
- constants.FIELD_TEXT_FONTFAMILY = 'Helvetica Neue';
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
@@ -82,7 +59,7 @@
from: 'zelos',
text: datauri
}, '*');
- }, document.getElementById('blocklycss').innerText);
+ });
} catch (err) {
console.error(err);
}
diff --git a/tests/rendering/zelos/scratchblocks/zelos.html b/tests/rendering/zelos/scratchblocks/zelos.html
index 3cc6810a9..877c4f4cb 100644
--- a/tests/rendering/zelos/scratchblocks/zelos.html
+++ b/tests/rendering/zelos/scratchblocks/zelos.html
@@ -7,31 +7,6 @@
-
-
-
-
-
-
@@ -34,10 +14,6 @@
goog.require('Blockly.zelos.Renderer');
// Blockly.blockRendering.startDebugger();
- // This stub is a workaround in order to load pxt-blockly blocks, as they
- // rely on a setOutputShape method on the block.
- Blockly.BlockSvg.prototype.setOutputShape = function() { };
-
var blocklyDiv = document.getElementById('blocklyDiv');
var workspace;
window.addEventListener('message', function (msg) {
@@ -56,6 +32,11 @@
workspace = Blockly.inject(blocklyDiv, {
renderer: 'zelos',
+ rendererOverrides: {
+ 'FIELD_TEXT_FONTFAMILY': '"Helvetica Neue", "Segoe UI", Helvetica, sans-serif',
+ 'FIELD_TEXT_FONTWEIGHT': 'bold',
+ 'FIELD_TEXT_FONTSIZE': 12
+ },
move: {
scrollbars: true,
drag: true,
@@ -66,10 +47,6 @@
startScale: 2,
}
});
- var constants = workspace.getRenderer().getConstants();
- constants.FIELD_TEXT_FONTSIZE = 12;
- constants.FIELD_TEXT_FONTWEIGHT = 'bold';
- constants.FIELD_TEXT_FONTFAMILY = 'Helvetica Neue';
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
@@ -82,7 +59,7 @@
from: 'zelos',
text: datauri
}, '*');
- }, document.getElementById('blocklycss').innerText);
+ });
} catch (err) {
console.error(err);
}
diff --git a/tests/screenshot/diff-reporter.js b/tests/screenshot/diff-reporter.js
index b8abced17..25a4b6929 100644
--- a/tests/screenshot/diff-reporter.js
+++ b/tests/screenshot/diff-reporter.js
@@ -3,18 +3,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/tests/screenshot/diff_screenshots.js b/tests/screenshot/diff_screenshots.js
index 512f34a4a..d4df57ad2 100644
--- a/tests/screenshot/diff_screenshots.js
+++ b/tests/screenshot/diff_screenshots.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/tests/screenshot/gen_screenshots.js b/tests/screenshot/gen_screenshots.js
index fc938ea60..48af66d12 100644
--- a/tests/screenshot/gen_screenshots.js
+++ b/tests/screenshot/gen_screenshots.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
diff --git a/tests/scripts/check_metadata.sh b/tests/scripts/check_metadata.sh
index 9b36c4447..243b1f17d 100755
--- a/tests/scripts/check_metadata.sh
+++ b/tests/scripts/check_metadata.sh
@@ -21,8 +21,8 @@ ANSI_RESET='\033[0m'
# Build the compressed files for core and blocks
echo "Building files"
npm install
-gulp build-compressed
-gulp build-blocks
+gulp buildCompressed
+gulp buildBlocks
# GZip them for additional size comparisons
echo "Zipping the compressed files"
diff --git a/tests/themes/test_themes.js b/tests/themes/test_themes.js
new file mode 100644
index 000000000..30792ae9e
--- /dev/null
+++ b/tests/themes/test_themes.js
@@ -0,0 +1,64 @@
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+'use strict';
+
+goog.provide('Blockly.TestThemes');
+
+
+/**
+ * A theme with classic colours but enables start hats.
+ */
+Blockly.Themes.TestHats = Blockly.Theme.defineTheme('testhats', {
+ 'base': Blockly.Themes.Classic
+});
+Blockly.Themes.TestHats.setStartHats(true);
+
+/**
+ * A theme with classic colours but a different font.
+ */
+Blockly.Themes.TestFont = Blockly.Theme.defineTheme('testfont', {
+ 'base': Blockly.Themes.Classic
+});
+Blockly.Themes.TestFont.setFontStyle({
+ 'family': '"Times New Roman", Times, serif',
+ 'weight': null, // Use default font-weight
+ 'size': 16
+});
+
+/**
+ * Holds the test theme name to Theme instance mapping.
+ * @type {!Object}
+ * @private
+ */
+Blockly.Themes.testThemes_ = {
+ 'Test Hats': Blockly.Themes.TestHats,
+ 'Test Font': Blockly.Themes.TestFont
+};
+
+/**
+ * Get a test theme by name.
+ * @param {string} value The theme name.
+ * @return {Blockly.Theme} A theme object or undefined if one doesn't exist.
+ * @package
+ */
+function getTestTheme(value) {
+ return Blockly.Themes.testThemes_[value];
+}
+
+/**
+ * Populate the theme changer dropdown to list the set of test themes.
+ * @package
+ */
+function populateTestThemes() {
+ var themeChanger = document.getElementById('themeChanger');
+ var keys = Object.keys(Blockly.Themes.testThemes_);
+ for (var i = 0, key; (key = keys[i]); i++) {
+ var option = document.createElement('option');
+ option.setAttribute('value', key);
+ option.textContent = key;
+ themeChanger.appendChild(option);
+ }
+}
diff --git a/tests/workspace_svg/event_svg_test.js b/tests/workspace_svg/event_svg_test.js
index 46d48f98e..698a6fffe 100644
--- a/tests/workspace_svg/event_svg_test.js
+++ b/tests/workspace_svg/event_svg_test.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
'use strict';
diff --git a/tests/workspace_svg/procedure_svg_test.js b/tests/workspace_svg/procedure_svg_test.js
index 1c27245d4..c3775dbb1 100644
--- a/tests/workspace_svg/procedure_svg_test.js
+++ b/tests/workspace_svg/procedure_svg_test.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
'use strict';
diff --git a/tests/workspace_svg/workspace_svg_test.js b/tests/workspace_svg/workspace_svg_test.js
index 56eccb64a..1a5e9fa4b 100644
--- a/tests/workspace_svg/workspace_svg_test.js
+++ b/tests/workspace_svg/workspace_svg_test.js
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2017 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
'use strict';
diff --git a/typings/blockly.d.ts b/typings/blockly.d.ts
index da6ebfd59..425ab3ff4 100644
--- a/typings/blockly.d.ts
+++ b/typings/blockly.d.ts
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
@@ -59,6 +48,7 @@ declare module Blockly {
minScale?: number;
scaleSpeed?: number;
};
+ renderer?: string;
}
interface BlocklyThemeOptions {
@@ -196,6 +186,13 @@ declare module Blockly {
*/
hat: string|any /*undefined*/;
+ /**
+ * A count of statement inputs on the block.
+ * @type {number}
+ * @package
+ */
+ statementInputCount: number;
+
/** @type {string} */
type: string;
@@ -547,7 +544,7 @@ declare module Blockly {
* initializer function.
* @param {function(Blockly.Events.Abstract)} onchangeFn The callback to call
* when the block's workspace changes.
- * @throws {Error} if onchangeFn is not falsey or a function.
+ * @throws {Error} if onchangeFn is not falsey and not a function.
*/
setOnChange(onchangeFn: { (_0: Blockly.Events.Abstract): any /*missing*/ }): void;
@@ -1423,6 +1420,36 @@ declare module Blockly {
*/
initSvg(): void;
+ /**
+ * Get the secondary colour of a block.
+ * @return {?string} #RRGGBB string.
+ */
+ getColourSecondary(): string;
+
+ /**
+ * Get the tertiary colour of a block.
+ * @return {?string} #RRGGBB string.
+ */
+ getColourTertiary(): string;
+
+ /**
+ * Get the shadow colour of a block.
+ * @return {?string} #RRGGBB string.
+ * @deprecated Use style.colourSecondary. (2020 January 21)
+ */
+ getColourShadow(): string;
+
+ /**
+ * Get the border colour(s) of a block.
+ * @return {{colourDark, colourLight, colourBorder}} An object containing
+ * colour values for the border(s) of the block. If the block is using a
+ * style the colourBorder will be defined and equal to the tertiary colour
+ * of the style (#RRGGBB string). Otherwise the colourDark and colourLight
+ * attributes will be defined (#RRGGBB strings).
+ * @deprecated Use style.colourTertiary. (2020 January 21)
+ */
+ getColourBorder(): { colourDark: any /*missing*/; colourLight: any /*missing*/; colourBorder: any /*missing*/ };
+
/**
* Select this block. Highlight it visually.
*/
@@ -1533,7 +1560,7 @@ declare module Blockly {
/**
* Notify every input on this block to mark its fields as dirty.
- * A dirty field is a field that needs to be re-rendererd.
+ * A dirty field is a field that needs to be re-rendered.
*/
markDirty(): void;
@@ -1843,6 +1870,12 @@ declare module Blockly {
*/
render(opt_bubble?: boolean): void;
+ /**
+ * Redraw any attached marker or cursor svgs if needed.
+ * @protected
+ */
+ updateMarkers_(): void;
+
/**
* Add the cursor svg to this block's svg group.
* @param {SVGElement} cursorSvg The svg root of the cursor to be added to the
@@ -1874,7 +1907,7 @@ declare module Blockly {
* @param {boolean} add True if highlighting should be added.
* @package
*/
- highlightForReplacement(add: boolean): void;
+ fadeForReplacement(add: boolean): void;
/**
* Visual effect to show that if the dragging block is dropped it will connect
@@ -1940,6 +1973,13 @@ declare module Blockly {
*/
var draggingConnections: Blockly.Connection[];
+ /**
+ * Container element to render the WidgetDiv, DropDownDiv and Tooltip.
+ * @type {?Element}
+ * @package
+ */
+ var parentContainer: Element;
+
/**
* Blockly opaque event data used to unbind events when using
* `Blockly.bindEvent_` and `Blockly.bindEventWithChecks_`.
@@ -2096,6 +2136,15 @@ declare module Blockly {
* @package
*/
function checkBlockColourConstants(): void;
+
+ /**
+ * Set the parent container. This is the container element that the WidgetDiv,
+ * DropDownDiv, and Tooltip are rendered into the first time `Blockly.inject`
+ * is called.
+ * This method is a NOP if called after the first ``Blockly.inject``.
+ * @param {!Element} container The container element.
+ */
+ function setParentContainer(container: Element): void;
}
@@ -2767,12 +2816,6 @@ declare module Blockly {
*/
var CURRENT_CONNECTION_PREFERENCE: any /*missing*/;
- /**
- * The main colour of insertion markers, in hex. The block is rendered a
- * transparent grey by changing the fill opacity in CSS.
- */
- var INSERTION_MARKER_COLOUR: any /*missing*/;
-
/**
* Delay in ms between trigger and bumping unconnected block out of alignment.
*/
@@ -3642,7 +3685,7 @@ declare module Blockly.Extensions {
* to the lookup table.
* @param {!Object.} lookupTable The table of field values to
* tooltip text.
- * @return {Function} The extension function.
+ * @return {!Function} The extension function.
*/
function buildTooltipForDropdown(dropdownName: string, lookupTable: { [key: string]: string }): Function;
@@ -3653,7 +3696,7 @@ declare module Blockly.Extensions {
* @param {string} msgTemplate The template form to of the message text, with
* %1 placeholder.
* @param {string} fieldName The field with the replacement text.
- * @return {Function} The extension function.
+ * @return {!Function} The extension function.
*/
function buildTooltipWithFieldText(msgTemplate: string, fieldName: string): Function;
}
@@ -3798,7 +3841,7 @@ declare module Blockly {
* clicked. Blockly will automatically set the field as clickable if this
* method is defined.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @return {void}
* @protected
*/
@@ -3834,6 +3877,13 @@ declare module Blockly {
*/
setSourceBlock(block: Blockly.Block): void;
+ /**
+ * Get the renderer constant provider.
+ * @return {?Blockly.blockRendering.ConstantProvider} The renderer constant
+ * provider.
+ */
+ getConstants(): Blockly.blockRendering.ConstantProvider;
+
/**
* Get the block this field is attached to.
* @return {Blockly.Block} The block containing this field.
@@ -4014,7 +4064,7 @@ declare module Blockly {
/**
* Show an editor when the field is clicked only if the field is clickable.
* @param {Event=} opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @package
*/
showEditor(opt_e?: Event): void;
@@ -4029,9 +4079,25 @@ declare module Blockly {
/**
* Updates the size of the field based on the text.
+ * @param {number=} opt_margin margin to use when positioning the text element.
* @protected
*/
- updateSize_(): void;
+ updateSize_(opt_margin?: number): void;
+
+ /**
+ * Position a field's text element after a size change. This handles both LTR
+ * and RTL positioning.
+ * @param {number} xOffset x offset to use when positioning the text element.
+ * @param {number} contentWidth The content width.
+ * @protected
+ */
+ positionTextElement_(xOffset: number, contentWidth: number): void;
+
+ /**
+ * Position a field's border rect after a size change.
+ * @protected
+ */
+ positionBorderRect_(): void;
/**
* Returns the height and width of the field.
@@ -4122,7 +4188,7 @@ declare module Blockly {
doValueUpdate_(newValue: any): void;
/**
- * Used to notify the field an invalid value was input. Can be overidden by
+ * Used to notify the field an invalid value was input. Can be overridden by
* subclasses, see FieldTextInput.
* No-op by default.
* @param {*} _invalidValue The input value that was determined to be invalid.
@@ -4214,6 +4280,12 @@ declare module Blockly {
* @package
*/
setMarkerSvg(markerSvg: SVGElement): void;
+
+ /**
+ * Redraw any attached marker or cursor svgs if needed.
+ * @protected
+ */
+ updateMarkers_(): void;
}
}
@@ -4373,15 +4445,6 @@ declare module Blockly {
*/
CURSOR: any /*missing*/;
- /**
- * Used to tell if the field needs to be rendered the next time the block is
- * rendered. Checkbox fields are statically sized, and only need to be
- * rendered at initialization.
- * @type {boolean}
- * @protected
- */
- isDirty_: boolean;
-
/**
* Create the block UI for this checkbox.
* @package
@@ -5133,12 +5196,6 @@ declare module Blockly {
*/
updateSize_(): void;
- /**
- * Resize the editor to fit the text.
- * @protected
- */
- resizeEditor_(): void;
-
/**
* Create the text input editor widget.
* @return {!HTMLTextAreaElement} The newly created text input editor.
@@ -5159,13 +5216,6 @@ declare module Blockly {
declare module Blockly.FieldMultilineInput {
- /**
- * The default height of a single line of text.
- * @type {number}
- * @const
- */
- var LINE_HEIGHT: number;
-
/**
* Construct a FieldMultilineInput from a JSON arg object,
* dereferencing any string table references.
@@ -5441,7 +5491,7 @@ declare module Blockly {
/**
* Show the inline free-text editor on top of the text.
* @param {Event=} _opt_e Optional mouse event that triggered the field to open,
- * or undefined if triggered programatically.
+ * or undefined if triggered programmatically.
* @param {boolean=} opt_quietInput True if editor should be created without
* focus. Defaults to false.
* @protected
@@ -5470,13 +5520,6 @@ declare module Blockly {
*/
onHtmlInputKeyDown_(e: Event): void;
- /**
- * Handle blur for the editor.
- * @param {!Event} _e Focus event.
- * @protected
- */
- onHtmlInputBlur_(_e: Event): void;
-
/**
* Set the html input value and the field's internal value. The difference
* between this and ``setValue`` is that this also updates the html input
@@ -5961,8 +6004,8 @@ declare module Blockly {
/**
* Create a copy of this block on the workspace.
* @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout.
- * @return {Blockly.BlockSvg} The newly created block, or null if something
- * went wrong with deserialization.
+ * @return {!Blockly.BlockSvg} The newly created block.
+ * @throws {Error} if something went wrong with deserialization.
* @package
*/
createBlock(originalBlock: Blockly.BlockSvg): Blockly.BlockSvg;
@@ -6098,9 +6141,14 @@ declare module Blockly {
declare module Blockly.FlyoutButton {
/**
- * The margin around the text in the button.
+ * The horizontal margin around the text in the button.
*/
- var MARGIN: any /*missing*/;
+ var MARGIN_X: any /*missing*/;
+
+ /**
+ * The vertical margin around the text in the button.
+ */
+ var MARGIN_Y: any /*missing*/;
}
@@ -6724,7 +6772,7 @@ declare module Blockly {
* Move the grid to a new x and y position, and make sure that change is
* visible.
* @param {number} x The new x position of the grid (in px).
- * @param {number} y The new y position ofthe grid (in px).
+ * @param {number} y The new y position of the grid (in px).
* @package
*/
moveTo(x: number, y: number): void;
@@ -7034,7 +7082,7 @@ declare module Blockly {
applyConnections(): void;
/**
- * Update highlighted connections based on the most recent move location.
+ * Update connections based on the most recent move location.
* @param {!Blockly.utils.Coordinate} dxy Position relative to drag start,
* in workspace units.
* @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH},
@@ -7055,6 +7103,16 @@ declare module Blockly {
}
+declare module Blockly.InsertionMarkerManager {
+
+ /**
+ * An enum describing different kinds of previews the InsertionMarkerManager
+ * could display.
+ * @enum {number}
+ */
+ enum PREVIEW_TYPE { INSERTION_MARKER, INPUT_OUTLINE, REPLACEMENT_FADE }
+}
+
declare module Blockly {
@@ -7119,6 +7177,12 @@ declare module Blockly {
*/
setMarkerSvg(markerSvg: SVGElement): void;
+ /**
+ * Redraw the attached cursor svg if needed.
+ * @package
+ */
+ updateMarkers(): void;
+
/**
* Dispose of the marker manager.
* Go through and delete all markers associated with this marker manager.
@@ -7813,21 +7877,20 @@ declare module Blockly {
/**
* Class for a theme.
* @param {string} name Theme name.
- * @param {!Object.} blockStyles A map from
- * style names (strings) to objects with style attributes for blocks.
- * @param {!Object.} categoryStyles A map
- * from style names (strings) to objects with style attributes for
+ * @param {!Object.=} opt_blockStyles A map
+ * from style names (strings) to objects with style attributes for blocks.
+ * @param {!Object.=} opt_categoryStyles A
+ * map from style names (strings) to objects with style attributes for
* categories.
- * @param {!Object.=} opt_componentStyles A map of Blockly component
- * names to style value.
+ * @param {!Blockly.Theme.ComponentStyle=} opt_componentStyles A map of Blockly
+ * component names to style value.
* @constructor
*/
- constructor(name: string, blockStyles: { [key: string]: Blockly.Theme.BlockStyle }, categoryStyles: { [key: string]: Blockly.Theme.CategoryStyle }, opt_componentStyles?: { [key: string]: any });
+ constructor(name: string, opt_blockStyles?: { [key: string]: Blockly.Theme.BlockStyle }, opt_categoryStyles?: { [key: string]: Blockly.Theme.CategoryStyle }, opt_componentStyles?: Blockly.Theme.ComponentStyle);
/**
* The theme name. This can be used to reference a specific theme in CSS.
* @type {string}
- * @package
*/
name: string;
@@ -7845,6 +7908,49 @@ declare module Blockly {
*/
categoryStyles: { [key: string]: Blockly.Theme.CategoryStyle };
+ /**
+ * The UI components styles map.
+ * @type {!Blockly.Theme.ComponentStyle}
+ * @package
+ */
+ componentStyles: Blockly.Theme.ComponentStyle;
+
+ /**
+ * The font style.
+ * @type {!Blockly.Theme.FontStyle}
+ * @package
+ */
+ fontStyle: Blockly.Theme.FontStyle;
+
+ /**
+ * Whether or not to add a 'hat' on top of all blocks with no previous or
+ * output connections.
+ * @type {?boolean}
+ * @package
+ */
+ startHats: boolean;
+
+ /**
+ * Gets the class name that identifies this theme.
+ * @return {string} The CSS class name.
+ * @package
+ */
+ getClassName(): string;
+
+ /**
+ * Overrides or adds a style to the blockStyles map.
+ * @param {string} blockStyleName The name of the block style.
+ * @param {Blockly.Theme.BlockStyle} blockStyle The block style.
+ */
+ setBlockStyle(blockStyleName: string, blockStyle: Blockly.Theme.BlockStyle): void;
+
+ /**
+ * Overrides or adds a style to the categoryStyles map.
+ * @param {string} categoryStyleName The name of the category style.
+ * @param {Blockly.Theme.CategoryStyle} categoryStyle The category style.
+ */
+ setCategoryStyle(categoryStyleName: string, categoryStyle: Blockly.Theme.CategoryStyle): void;
+
/**
* Gets the style for a given Blockly UI component. If the style value is a
* string, we attempt to find the value of any named references.
@@ -7859,6 +7965,19 @@ declare module Blockly {
* @param {*} styleValue The style value.
*/
setComponentStyle(componentName: string, styleValue: any): void;
+
+ /**
+ * Configure a theme's font style.
+ * @param {Blockly.Theme.FontStyle} fontStyle The font style.
+ */
+ setFontStyle(fontStyle: Blockly.Theme.FontStyle): void;
+
+ /**
+ * Configure a theme's start hats.
+ * @param {boolean} startHats True if the theme enables start hats, false
+ * otherwise.
+ */
+ setStartHats(startHats: boolean): void;
}
}
@@ -7868,12 +7987,12 @@ declare module Blockly.Theme {
/**
* A block style.
* @typedef {{
- * colourPrimary:string,
- * colourSecondary:string,
- * colourTertiary:string,
- * hat:string
- * }}
- */
+ * colourPrimary:string,
+ * colourSecondary:string,
+ * colourTertiary:string,
+ * hat:string
+ * }}
+ */
interface BlockStyle {
colourPrimary: string;
colourSecondary: string;
@@ -7884,12 +8003,74 @@ declare module Blockly.Theme {
/**
* A category style.
* @typedef {{
- * colour:string
- * }}
- */
+ * colour:string
+ * }}
+ */
interface CategoryStyle {
colour: string
}
+
+ /**
+ * A component style.
+ * @typedef {{
+ * workspaceBackgroundColour:string?,
+ * toolboxBackgroundColour:string?,
+ * toolboxForegroundColour:string?,
+ * flyoutBackgroundColour:string?,
+ * flyoutForegroundColour:string?,
+ * flyoutOpacity:number?,
+ * scrollbarColour:string?,
+ * scrollbarOpacity:number?,
+ * insertionMarkerColour:string?,
+ * insertionMarkerOpacity:number?,
+ * markerColour:string?,
+ * cursorColour:string?,
+ * selectedGlowColour:string?,
+ * selectedGlowOpacity:number?,
+ * replacementGlowColour:string?,
+ * replacementGlowOpacity:number?
+ * }}
+ */
+ interface ComponentStyle {
+ workspaceBackgroundColour: string;
+ toolboxBackgroundColour: string;
+ toolboxForegroundColour: string;
+ flyoutBackgroundColour: string;
+ flyoutForegroundColour: string;
+ flyoutOpacity: number;
+ scrollbarColour: string;
+ scrollbarOpacity: number;
+ insertionMarkerColour: string;
+ insertionMarkerOpacity: number;
+ markerColour: string;
+ cursorColour: string;
+ selectedGlowColour: string;
+ selectedGlowOpacity: number;
+ replacementGlowColour: string;
+ replacementGlowOpacity: number
+ }
+
+ /**
+ * A font style.
+ * @typedef {{
+ * family:string?,
+ * weight:string?,
+ * size:number?
+ * }}
+ */
+ interface FontStyle {
+ family: string;
+ weight: string;
+ size: number
+ }
+
+ /**
+ * Define a new Blockly theme.
+ * @param {string} name The name of the theme.
+ * @param {!Object} themeObj An object containing theme properties.
+ * @return {!Blockly.Theme} A new Blockly theme.
+ */
+ function defineTheme(name: string, themeObj: Object): Blockly.Theme;
}
@@ -8196,6 +8377,18 @@ declare module Blockly.Tooltip {
*/
function bindMouseEvents(element: Element): void;
+ /**
+ * Unbinds tooltip mouse events from the SVG element.
+ * @param {!Element} element SVG element onto which tooltip is bound.
+ */
+ function unbindMouseEvents(element: Element): void;
+
+ /**
+ * Dispose of the tooltip.
+ * @package
+ */
+ function dispose(): void;
+
/**
* Hide the tooltip.
*/
@@ -8494,6 +8687,18 @@ declare module Blockly {
*/
dispose(): void;
+ /**
+ * Returns true if the trashcan contents-flyout is currently open.
+ * @return {boolean} True if the trashcan contents-flyout is currently open.
+ */
+ contentsIsOpen(): boolean;
+
+ /**
+ * Empties the trashcan's contents. If the contents-flyout is currently open
+ * it will be closed.
+ */
+ emptyContents(): void;
+
/**
* Position the trashcan.
* It is positioned in the opposite corner to the corner the
@@ -8529,6 +8734,24 @@ declare module Blockly {
}
+declare module CustomDialog {
+
+ /** Hides any currently visible dialog. */
+ function hide(): void;
+
+ /**
+ * Shows the dialog.
+ * Allowed options:
+ * - showOkay: Whether to show the OK button.
+ * - showCancel: Whether to show the Cancel button.
+ * - showInput: Whether to show the text input field.
+ * - onOkay: Callback to handle the okay button.
+ * - onCancel: Callback to handle the cancel button and backdrop clicks.
+ */
+ function show(title: any /* jsdoc error */, message: any /* jsdoc error */, options: any /* jsdoc error */): void;
+}
+
+
declare module Blockly.Events {
class Ui extends Ui__Class { }
@@ -8751,7 +8974,7 @@ declare module Blockly.utils {
* Converts screen coordinates to workspace coordinates.
* @param {Blockly.WorkspaceSvg} ws The workspace to find the coordinates on.
* @param {Blockly.utils.Coordinate} screenCoordinates The screen coordinates to
- * be converted to workspace coordintaes
+ * be converted to workspace coordinates
* @return {Blockly.utils.Coordinate} The workspace coordinates.
* @package
*/
@@ -10584,7 +10807,6 @@ declare module Blockly {
/**
* True if keyboard accessibility mode is on, false otherwise.
* @type {boolean}
- * @package
*/
keyboardAccessibilityMode: boolean;
@@ -10708,8 +10930,9 @@ declare module Blockly {
* Developers may define this function to add custom menu options to the
* workspace's context menu or edit the workspace-created set of menu options.
* @param {!Array.} options List of menu options to add to.
+ * @param {!Event} e The right-click event that triggered the context menu.
*/
- configureContextMenu(options: Object[]): void;
+ configureContextMenu(options: Object[], e: Event): void;
/**
* In a flyout, the target workspace where blocks should be placed after a drag.
@@ -11226,6 +11449,13 @@ declare module Blockly {
*/
setScale(newScale: number): void;
+ /**
+ * Get the workspace's zoom factor. If the workspace has a parent, we call into
+ * the parent to get the workspace scale.
+ * @return {number} The workspace zoom factor. Units: (pixels / workspaceUnit).
+ */
+ getScale(): number;
+
/**
* Scroll the workspace to a specified offset (in pixels), keeping in the
* workspace bounds. See comment on workspaceSvg.scrollX for more detail on
@@ -11782,6 +12012,13 @@ declare module Blockly {
*/
constructor();
+ /**
+ * Whether the component is rendered right-to-left.
+ * @type {boolean}
+ * @protected
+ */
+ rightToLeft_: boolean;
+
/**
* Gets the unique ID for the instance of this component. If the instance
* doesn't already have an ID, generates one on the fly.
@@ -11979,15 +12216,6 @@ declare module Blockly {
*/
getContentElement(): Element;
- /**
- * Returns true if the component is rendered right-to-left, false otherwise.
- * The first time this function is invoked, the right-to-left rendering property
- * is set if it has not been already.
- * @return {boolean} Whether the control is rendered right-to-left.
- * @protected
- */
- isRightToLeft(): boolean;
-
/**
* Set is right-to-left. This function should be used if the component needs
* to know the rendering direction during DOM creation (i.e. before
@@ -12100,7 +12328,7 @@ declare module Blockly {
* It is recommended that you use one of the createNode methods instead of
* creating a node directly.
* @param {string} type The type of the location.
- * Must be in Bockly.ASTNode.types.
+ * Must be in Blockly.ASTNode.types.
* @param {!(Blockly.Block|Blockly.Connection|Blockly.Field|Blockly.Workspace)}
* location The position in the AST.
* @param {!Object=} opt_params Optional dictionary of options.
@@ -12716,25 +12944,25 @@ declare module Blockly.navigation {
var ACTION_TOGGLE_KEYBOARD_NAV: Blockly.Action;
/**
- * The action to move the cursor to the keft on a worksapce.
+ * The action to move the cursor to the left on a workspace.
* @type {!Blockly.Action}
*/
var ACTION_MOVE_WS_CURSOR_LEFT: Blockly.Action;
/**
- * The action to move the cursor to the right on a worksapce.
+ * The action to move the cursor to the right on a workspace.
* @type {!Blockly.Action}
*/
var ACTION_MOVE_WS_CURSOR_RIGHT: Blockly.Action;
/**
- * The action to move the cursor up on a worksapce.
+ * The action to move the cursor up on a workspace.
* @type {!Blockly.Action}
*/
var ACTION_MOVE_WS_CURSOR_UP: Blockly.Action;
/**
- * The action to move the cursor down on a worksapce.
+ * The action to move the cursor down on a workspace.
* @type {!Blockly.Action}
*/
var ACTION_MOVE_WS_CURSOR_DOWN: Blockly.Action;
@@ -13092,6 +13320,30 @@ declare module Blockly.utils.dom {
* @return {number} Width of element.
*/
function getFastTextWidth(textElement: Element, fontSize: number, fontWeight: string, fontFamily: string): number;
+
+ /**
+ * Gets the width of a text element using a faster method than `getTextWidth`.
+ * This method requires that we know the text element's font family and size in
+ * advance. Similar to `getTextWidth`, we cache the width we compute.
+ * This method is similar to ``getFastTextWidth`` but expects the font size
+ * parameter to be a string.
+ * @param {!Element} textElement An SVG 'text' element.
+ * @param {string} fontSize The font size to use.
+ * @param {string} fontWeight The font weight to use.
+ * @param {string} fontFamily The font family to use.
+ * @return {number} Width of element.
+ */
+ function getFastTextWidthWithSizeString(textElement: Element, fontSize: string, fontWeight: string, fontFamily: string): number;
+
+ /**
+ * Measure a font's metrics. The height and baseline values.
+ * @param {string} text Text to measure the font dimensions of.
+ * @param {string} fontSize The font size to use.
+ * @param {string} fontWeight The font weight to use.
+ * @param {string} fontFamily The font family to use.
+ * @return {{height: number, baseline: number}} Font measurements.
+ */
+ function measureFontMetrics(text: string, fontSize: string, fontWeight: string, fontFamily: string): { height: number; baseline: number };
}
@@ -13182,6 +13434,14 @@ declare module Blockly.utils.object {
*/
function mixin(target: Object, source: Object): void;
+ /**
+ * Complete a deep merge of all members of a source object with a target object.
+ * @param {!Object} target Target.
+ * @param {!Object} source Source.
+ * @return {!Object} The resulting object.
+ */
+ function deepMerge(target: Object, source: Object): Object;
+
/**
* Returns an array of a given object's own enumerable property values.
* @param {!Object} obj Object containing values.
@@ -13453,7 +13713,7 @@ declare module Blockly.utils.svgPaths {
function point(x: number, y: number): string;
/**
- * Draw a curbic or quadratic curve. See
+ * Draw a cubic or quadratic curve. See
* developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve
* These coordinates are unitless and hence in the user coordinate system.
* @param {string} command The command to use.
@@ -13619,12 +13879,59 @@ declare module Blockly.tree {
*/
constructor(content: string, config: Blockly.tree.BaseNode.Config);
+ /**
+ * Text content of the node label.
+ * @type {string}
+ * @package
+ */
+ content: string;
+
+ /**
+ * @type {string}
+ * @package
+ */
+ iconClass: string;
+
+ /**
+ * @type {string}
+ * @package
+ */
+ expandedIconClass: string;
+
+ /**
+ * The configuration for the tree.
+ * @type {!Blockly.tree.BaseNode.Config}
+ * @protected
+ */
+ config_: Blockly.tree.BaseNode.Config;
+
/**
* @type {Blockly.tree.TreeControl}
* @protected
*/
tree: Blockly.tree.TreeControl;
+ /**
+ * Whether the tree item is selected.
+ * @type {boolean}
+ * @protected
+ */
+ selected_: boolean;
+
+ /**
+ * Whether the tree node is expanded.
+ * @type {boolean}
+ * @protected
+ */
+ expanded_: boolean;
+
+ /**
+ * Whether to allow user to collapse this node.
+ * @type {boolean}
+ * @protected
+ */
+ isUserCollapsible_: boolean;
+
/**
* Adds roles and states.
* @protected
@@ -13677,18 +13984,6 @@ declare module Blockly.tree {
*/
getChildren(): Blockly.tree.BaseNode[];
- /**
- * @return {Blockly.tree.BaseNode} The first child of this node.
- * @protected
- */
- getFirstChild(): Blockly.tree.BaseNode;
-
- /**
- * @return {Blockly.tree.BaseNode} The last child of this node.
- * @protected
- */
- getLastChild(): Blockly.tree.BaseNode;
-
/**
* @return {Blockly.tree.BaseNode} The previous sibling of this node.
* @protected
@@ -13719,31 +14014,12 @@ declare module Blockly.tree {
*/
select(): void;
- /**
- * Selects the first node.
- * @protected
- */
- selectFirst(): void;
-
/**
* Called from the tree to instruct the node change its selection state.
* @param {boolean} selected The new selection state.
* @protected
*/
- setSelectedInternal(selected: boolean): void;
-
- /**
- * @return {boolean} Whether the node is expanded.
- * @protected
- */
- getExpanded(): boolean;
-
- /**
- * Sets the node to be expanded internally, without state change events.
- * @param {boolean} expanded Whether to expand or close the node.
- * @protected
- */
- setExpandedInternal(expanded: boolean): void;
+ setSelected(selected: boolean): void;
/**
* Sets the node to be expanded.
@@ -13754,14 +14030,14 @@ declare module Blockly.tree {
/**
* Used to notify a node of that we have expanded it.
- * Can be overidden by subclasses, see Blockly.tree.TreeNode.
+ * Can be overridden by subclasses, see Blockly.tree.TreeNode.
* @protected
*/
doNodeExpanded(): void;
/**
* Used to notify a node that we have collapsed it.
- * Can be overidden by subclasses, see Blockly.tree.TreeNode.
+ * Can be overridden by subclasses, see Blockly.tree.TreeNode.
* @protected
*/
doNodeCollapsed(): void;
@@ -13772,12 +14048,6 @@ declare module Blockly.tree {
*/
toggle(): void;
- /**
- * @return {boolean} Whether the node is collapsible by user actions.
- * @protected
- */
- isUserCollapsible(): boolean;
-
/**
* Creates HTML Element for the node.
* @return {!Element} HTML element
@@ -13846,35 +14116,6 @@ declare module Blockly.tree {
*/
getChildrenElement(): Element;
- /**
- * Gets the icon class for the node.
- * @return {string} s The icon source.
- * @protected
- */
- getIconClass(): string;
-
- /**
- * Gets the icon class for when the node is expanded.
- * @return {string} The class.
- * @protected
- */
- getExpandedIconClass(): string;
-
- /**
- * Sets the text of the label.
- * @param {string} s The plain text of the label.
- * @protected
- */
- setText(s: string): void;
-
- /**
- * Returns the text of the label. If the text was originally set as HTML, the
- * return value is unspecified.
- * @return {string} The plain text of the label.
- * @package
- */
- getText(): string;
-
/**
* Updates the row styles.
* @protected
@@ -13957,12 +14198,6 @@ declare module Blockly.tree {
*/
getPreviousShownNode(): Blockly.tree.BaseNode;
- /**
- * @return {!Blockly.tree.BaseNode.Config} The configuration for the tree.
- * @protected
- */
- getConfig(): Blockly.tree.BaseNode.Config;
-
/**
* Internal method that is used to set the tree control on the node.
* @param {Blockly.tree.TreeControl} tree The tree control.
@@ -14432,11 +14667,13 @@ declare module Blockly.blockRendering {
/**
* Initialize anything needed for rendering (constants, etc).
* @param {!string} name Name of the renderer to initialize.
+ * @param {!Blockly.Theme} theme The workspace theme object.
+ * @param {Object=} opt_rendererOverrides Rendering constant overrides.
* @return {!Blockly.blockRendering.Renderer} The new instance of a renderer.
* Already initialized.
* @package
*/
- function init(name: string): Blockly.blockRendering.Renderer;
+ function init(name: string, theme: Blockly.Theme, opt_rendererOverrides?: Object): Blockly.blockRendering.Renderer;
}
@@ -14648,12 +14885,6 @@ declare module Blockly.blockRendering {
*/
FIELD_TEXT_FONTSIZE: number;
- /**
- * Height of text.
- * @type {number}
- */
- FIELD_TEXT_HEIGHT: number;
-
/**
* Text font weight.
* @type {string}
@@ -14666,6 +14897,20 @@ declare module Blockly.blockRendering {
*/
FIELD_TEXT_FONTFAMILY: string;
+ /**
+ * Height of text. This constant is dynamically set in ``setFontConstants_``
+ * to be the height of the text based on the font used.
+ * @type {number}
+ */
+ FIELD_TEXT_HEIGHT: number;
+
+ /**
+ * Text baseline. This constant is dynamically set in ``setFontConstants_``
+ * to be the baseline of the text based on the font used.
+ * @type {number}
+ */
+ FIELD_TEXT_BASELINE: number;
+
/**
* A field's border rect corner radius.
* @type {number}
@@ -14697,19 +14942,6 @@ declare module Blockly.blockRendering {
*/
FIELD_BORDER_RECT_COLOUR: string;
- /**
- * Field text baseline.
- * This is only used if `FIELD_TEXT_BASELINE_CENTER` is false.
- * @type {number}
- */
- FIELD_TEXT_BASELINE_Y: number;
-
- /**
- * An text offset adjusting the Y position of text after positioning.
- * @type {number}
- */
- FIELD_TEXT_Y_OFFSET: number;
-
/**
* A field's text element's dominant baseline.
* @type {boolean}
@@ -14792,25 +15024,13 @@ declare module Blockly.blockRendering {
*/
FIELD_CHECKBOX_X_OFFSET: number;
- /**
- * A checkbox field's Y offset.
- * @type {number}
- */
- FIELD_CHECKBOX_Y_OFFSET: number;
-
- /**
- * A checkbox field's default width.
- * @type {number}
- */
- FIELD_CHECKBOX_DEFAULT_WIDTH: number;
-
/**
* A random identifier used to ensure a unique ID is used for each
* filter/pattern for the case of multiple Blockly instances on a page.
* @type {string}
- * @protected
+ * @package
*/
- randomIdentifier_: string;
+ randomIdentifier: string;
/**
* The ID of the emboss filter, or the empty string if no filter is set.
@@ -14826,6 +15046,13 @@ declare module Blockly.blockRendering {
*/
disabledPatternId: string;
+ /**
+ * The ID of the debug filter, or the empty string if no pattern is set.
+ * @type {string}
+ * @package
+ */
+ debugFilterId: string;
+
/**
* Cursor colour.
* @type {string}
@@ -14882,6 +15109,21 @@ declare module Blockly.blockRendering {
*/
FULL_BLOCK_FIELDS: boolean;
+ /**
+ * The main colour of insertion markers, in hex. The block is rendered a
+ * transparent grey by changing the fill opacity in CSS.
+ * @type {string}
+ * @package
+ */
+ INSERTION_MARKER_COLOUR: string;
+
+ /**
+ * The insertion marker opacity.
+ * @type {number}
+ * @package
+ */
+ INSERTION_MARKER_OPACITY: number;
+
/**
* Enum for connection shapes.
* @enum {number}
@@ -14936,7 +15178,7 @@ declare module Blockly.blockRendering {
* @param {!Blockly.Theme} theme The current workspace theme.
* @package
*/
- refreshTheme(theme: Blockly.Theme): void;
+ setTheme(theme: Blockly.Theme): void;
/**
* The block styles map.
@@ -14945,6 +15187,27 @@ declare module Blockly.blockRendering {
*/
blockStyles: { [key: string]: Blockly.Theme.BlockStyle };
+ /**
+ * Sets dynamic properties that depend on other values or theme properties.
+ * @param {!Blockly.Theme} theme The current workspace theme.
+ * @protected
+ */
+ setDynamicProperties_(theme: Blockly.Theme): void;
+
+ /**
+ * Set constants related to fonts.
+ * @param {!Blockly.Theme} theme The current workspace theme.
+ * @protected
+ */
+ setFontConstants_(theme: Blockly.Theme): void;
+
+ /**
+ * Set constants from a theme's component styles.
+ * @param {!Blockly.Theme} theme The current workspace theme.
+ * @protected
+ */
+ setComponentConstants_(theme: Blockly.Theme): void;
+
/**
* Get or create a block style based on a single colour value. Generate a name
* for the style based on the colour.
@@ -15066,24 +15329,28 @@ declare module Blockly.blockRendering {
/**
* Create any DOM elements that this renderer needs (filters, patterns, etc).
* @param {!SVGElement} svg The root of the workspace's SVG.
+ * @param {string} tagName The name to use for the CSS style tag.
+ * @param {string} selector The CSS selector to use.
+ * @suppress {strictModuleDepCheck} Debug renderer only included in playground.
* @package
*/
- createDom(svg: SVGElement): void;
+ createDom(svg: SVGElement, tagName: string, selector: string): void;
/**
* Inject renderer specific CSS into the page.
- * @param {string} name Name of the renderer.
- * @package
+ * @param {string} tagName The name of the style tag to use.
+ * @param {string} selector The CSS selector to use.
+ * @protected
*/
- injectCSS(name: string): void;
+ injectCSS_(tagName: string, selector: string): void;
/**
* Get any renderer specific CSS to inject when the renderer is initialized.
- * @param {string} name Name of the renderer.
+ * @param {string} selector CSS selector to use.
* @return {!Array.} Array of CSS strings.
* @protected
*/
- getCSS_(name: string): string[];
+ getCSS_(selector: string): string[];
}
}
@@ -15097,10 +15364,12 @@ declare module Blockly.blockRendering {
/**
* An object that renders rectangles and dots for debugging rendering code.
+ * @param {!Blockly.blockRendering.ConstantProvider} constants The renderer's
+ * constants.
* @package
* @constructor
*/
- constructor();
+ constructor(constants: Blockly.blockRendering.ConstantProvider);
/**
* Remove all elements the this object created on the last pass.
@@ -15179,6 +15448,13 @@ declare module Blockly.blockRendering {
* @package
*/
drawDebug(block: Blockly.BlockSvg, info: Blockly.blockRendering.RenderInfo): void;
+
+ /**
+ * Show a debug filter to highlight that a block has been rendered.
+ * @param {!SVGElement} svgPath The block's svg path.
+ * @package
+ */
+ drawRender(svgPath: SVGElement): void;
}
}
@@ -15469,7 +15745,7 @@ declare module Blockly.blockRendering {
* @param {boolean} enable True if styling should be added.
* @package
*/
- updateReplacementHighlight(enable: boolean): void;
+ updateReplacementFade(enable: boolean): void;
}
}
@@ -15573,11 +15849,10 @@ declare module Blockly.blockRendering {
rows: Blockly.blockRendering.Row[];
/**
- * The total number of input rows added onto the block.
- * @type {number}
- * @protected
+ * An array of input rows on the block.
+ * @type {!Array.}
*/
- inputRowNum_: number;
+ inputRows: Blockly.blockRendering.InputRow[];
/**
* An array of measurable objects containing hidden icons.
@@ -15952,6 +16227,12 @@ declare module Blockly.blockRendering {
*/
createDomInternal_(): Element;
+ /**
+ * Apply the marker's colour.
+ * @protected
+ */
+ applyColour_(): void;
+
/**
* Dispose of this marker.
* @package
@@ -16008,9 +16289,9 @@ declare module Blockly.blockRendering {
/**
* The renderer's constant provider.
* @type {!Blockly.blockRendering.ConstantProvider}
- * @protected
+ * @package
*/
- constants_: Blockly.blockRendering.ConstantProvider;
+ constants: Blockly.blockRendering.ConstantProvider;
/**
* The primary path of the block.
@@ -16026,6 +16307,22 @@ declare module Blockly.blockRendering {
*/
style: Blockly.Theme.BlockStyle;
+ /**
+ * Holds the cursors svg element when the cursor is attached to the block.
+ * This is null if there is no cursor on the block.
+ * @type {SVGElement}
+ * @package
+ */
+ cursorSvg: SVGElement;
+
+ /**
+ * Holds the markers svg element when the marker is attached to the block.
+ * This is null if there is no marker on the block.
+ * @type {SVGElement}
+ * @package
+ */
+ markerSvg: SVGElement;
+
/**
* Set the path generated by the renderer onto the respective SVG element.
* @param {string} pathString The path.
@@ -16138,7 +16435,7 @@ declare module Blockly.blockRendering {
* @param {boolean} enable True if styling should be added.
* @package
*/
- updateReplacementHighlight(enable: boolean): void;
+ updateReplacementFade(enable: boolean): void;
/**
* Add or remove styling that shows that if the dragging block is dropped, this
@@ -16175,10 +16472,49 @@ declare module Blockly.blockRendering {
name: string;
/**
- * Initialize the renderer.
+ * Rendering constant overrides, passed in through options.
+ * @type {?Object}
* @package
*/
- init(): void;
+ overrides: Object;
+
+ /**
+ * Gets the class name that identifies this renderer.
+ * @return {string} The CSS class name.
+ * @package
+ */
+ getClassName(): string;
+
+ /**
+ * Initialize the renderer.
+ * @param {!Blockly.Theme} theme The workspace theme object.
+ * @param {Object=} opt_rendererOverrides Rendering constant overrides.
+ * @package
+ */
+ init(theme: Blockly.Theme, opt_rendererOverrides?: Object): void;
+
+ /**
+ * Create any DOM elements that this renderer needs.
+ * @param {!SVGElement} svg The root of the workspace's SVG.
+ * @param {!Blockly.Theme} theme The workspace theme object.
+ * @package
+ */
+ createDom(svg: SVGElement, theme: Blockly.Theme): void;
+
+ /**
+ * Refresh the renderer after a theme change.
+ * @param {!SVGElement} svg The root of the workspace's SVG.
+ * @param {!Blockly.Theme} theme The workspace theme object.
+ * @package
+ */
+ refreshDom(svg: SVGElement, theme: Blockly.Theme): void;
+
+ /**
+ * Dispose of this renderer.
+ * Delete all DOM elements that this renderer and its constants created.
+ * @package
+ */
+ dispose(): void;
/**
* Create a new instance of the renderer's constant provider.
@@ -16251,13 +16587,32 @@ declare module Blockly.blockRendering {
shouldHighlightConnection(_conn: Blockly.Connection): boolean;
/**
- * Determine whether or not to insert a dragged block into a stack.
- * @param {!Blockly.Block} block The target block.
- * @param {!Blockly.Connection} conn The closest connection.
- * @return {boolean} True if we should insert the dragged block into the stack.
+ * Checks if an orphaned block can connect to the "end" of the topBlock's
+ * block-clump. If the clump is a row the end is the last input. If the clump
+ * is a stack, the end is the last next connection. If the clump is neither,
+ * then this returns false.
+ * @param {!Blockly.BlockSvg} topBlock The top block of the block clump we want to try and
+ * connect to.
+ * @param {!Blockly.BlockSvg} orphanBlock The orphan block that wants to find
+ * a home.
+ * @param {number} localType The type of the connection being dragged.
+ * @return {boolean} Whether there is a home for the orphan or not.
* @package
*/
- shouldInsertDraggedBlock(block: Blockly.Block, conn: Blockly.Connection): boolean;
+ orphanCanConnectAtEnd(topBlock: Blockly.BlockSvg, orphanBlock: Blockly.BlockSvg, localType: number): boolean;
+
+ /**
+ * Chooses a connection preview method based on the available connection, the
+ * current dragged connection, and the block being dragged.
+ * @param {!Blockly.RenderedConnection} closest The available connection.
+ * @param {!Blockly.RenderedConnection} local The connection currently being
+ * dragged.
+ * @param {!Blockly.BlockSvg} topBlock The block currently being dragged.
+ * @return {!Blockly.InsertionMarkerManager.PREVIEW_TYPE} The preview type
+ * to display.
+ * @package
+ */
+ getConnectionPreviewMethod(closest: Blockly.RenderedConnection, local: Blockly.RenderedConnection, topBlock: Blockly.BlockSvg): Blockly.InsertionMarkerManager.PREVIEW_TYPE;
/**
* Render the block.
@@ -16967,7 +17322,7 @@ declare module Blockly.blockRendering.Types {
/**
* Get the enum flag value of an existing type or register a new type.
* @param {!string} type The name of the type.
- * @return {!number} The enum flag value assosiated with that type.
+ * @return {!number} The enum flag value associated with that type.
* @package
*/
function getType(type: string): number;
diff --git a/typings/parts/blockly-header.d.ts b/typings/parts/blockly-header.d.ts
index df410339e..15bcf14dd 100644
--- a/typings/parts/blockly-header.d.ts
+++ b/typings/parts/blockly-header.d.ts
@@ -1,18 +1,7 @@
/**
* @license
* Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**