Merge pull request #4548 from google/rc_2020_12

Rc 2020 12
This commit is contained in:
alschmiedt
2020-12-17 13:20:22 -08:00
committed by GitHub
193 changed files with 11542 additions and 8820 deletions
+198 -170
View File
@@ -53,14 +53,17 @@ Blockly.utils.getViewportBBox=function(){var a=Blockly.utils.style.getViewportPa
Blockly.utils.getDocumentScroll=function(){var a=document.documentElement,b=window;return Blockly.utils.userAgent.IE&&b.pageYOffset!=a.scrollTop?new Blockly.utils.Coordinate(a.scrollLeft,a.scrollTop):new Blockly.utils.Coordinate(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)};Blockly.utils.getBlockTypeCounts=function(a,b){var c=Object.create(null),d=a.getDescendants(!0);b&&(a=a.getNextBlock())&&(a=d.indexOf(a),d.splice(a,d.length-a));for(a=0;b=d[a];a++)c[b.type]?c[b.type]++:c[b.type]=1;return c};
Blockly.utils.screenToWsCoordinates=function(a,b){var c=b.x;b=b.y;var d=a.getInjectionDiv().getBoundingClientRect();c=new Blockly.utils.Coordinate(c-d.left,b-d.top);b=a.getOriginOffsetInPixels();return Blockly.utils.Coordinate.difference(c,b).scale(1/a.scale)};
Blockly.utils.parseBlockColour=function(a){var b="string"==typeof a?Blockly.utils.replaceMessageReferences(a):a,c=Number(b);if(!isNaN(c)&&0<=c&&360>=c)return{hue:c,hex:Blockly.utils.colour.hsvToHex(c,Blockly.HSV_SATURATION,255*Blockly.HSV_VALUE)};if(c=Blockly.utils.colour.parse(b))return{hue:null,hex:c};c='Invalid colour: "'+b+'"';a!=b&&(c+=' (from "'+a+'")');throw Error(c);};Blockly.Events={};Blockly.Events.group_="";Blockly.Events.recordUndo=!0;Blockly.Events.disabled_=0;Blockly.Events.CREATE="create";Blockly.Events.BLOCK_CREATE=Blockly.Events.CREATE;Blockly.Events.DELETE="delete";Blockly.Events.BLOCK_DELETE=Blockly.Events.DELETE;Blockly.Events.CHANGE="change";Blockly.Events.BLOCK_CHANGE=Blockly.Events.CHANGE;Blockly.Events.MOVE="move";Blockly.Events.BLOCK_MOVE=Blockly.Events.MOVE;Blockly.Events.VAR_CREATE="var_create";Blockly.Events.VAR_DELETE="var_delete";
Blockly.Events.VAR_RENAME="var_rename";Blockly.Events.UI="ui";Blockly.Events.COMMENT_CREATE="comment_create";Blockly.Events.COMMENT_DELETE="comment_delete";Blockly.Events.COMMENT_CHANGE="comment_change";Blockly.Events.COMMENT_MOVE="comment_move";Blockly.Events.FINISHED_LOADING="finished_loading";Blockly.Events.BUMP_EVENTS=[Blockly.Events.BLOCK_CREATE,Blockly.Events.BLOCK_MOVE,Blockly.Events.COMMENT_CREATE,Blockly.Events.COMMENT_MOVE];Blockly.Events.FIRE_QUEUE_=[];
Blockly.Events.fire=function(a){Blockly.Events.isEnabled()&&(Blockly.Events.FIRE_QUEUE_.length||setTimeout(Blockly.Events.fireNow_,0),Blockly.Events.FIRE_QUEUE_.push(a))};Blockly.Events.fireNow_=function(){for(var a=Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_,!0),b=Blockly.Events.FIRE_QUEUE_.length=0,c;c=a[b];b++)if(c.workspaceId){var d=Blockly.Workspace.getById(c.workspaceId);d&&d.fireChangeListener(c)}};
Blockly.Events.filter=function(a,b){a=a.slice();b||a.reverse();for(var c=[],d=Object.create(null),e=0,f;f=a[e];e++)if(!f.isNull()){var g=[f.type,f.blockId,f.workspaceId].join(" "),h=d[g],k=h?h.event:null;if(!h)d[g]={event:f,index:e},c.push(f);else if(f.type==Blockly.Events.MOVE&&h.index==e-1)k.newParentId=f.newParentId,k.newInputName=f.newInputName,k.newCoordinate=f.newCoordinate,h.index=e;else if(f.type==Blockly.Events.CHANGE&&f.element==k.element&&f.name==k.name)k.newValue=f.newValue;else if(f.type!=
Blockly.Events.UI||"click"!=f.element||"commentOpen"!=k.element&&"mutatorOpen"!=k.element&&"warningOpen"!=k.element)d[g]={event:f,index:1},c.push(f)}a=c.filter(function(l){return!l.isNull()});b||a.reverse();for(e=1;f=a[e];e++)f.type==Blockly.Events.CHANGE&&"mutation"==f.element&&a.unshift(a.splice(e,1)[0]);return a};Blockly.Events.clearPendingUndo=function(){for(var a=0,b;b=Blockly.Events.FIRE_QUEUE_[a];a++)b.recordUndo=!1};Blockly.Events.disable=function(){Blockly.Events.disabled_++};
Blockly.Events.enable=function(){Blockly.Events.disabled_--};Blockly.Events.isEnabled=function(){return 0==Blockly.Events.disabled_};Blockly.Events.getGroup=function(){return Blockly.Events.group_};Blockly.Events.setGroup=function(a){Blockly.Events.group_="boolean"==typeof a?a?Blockly.utils.genUid():"":a};Blockly.Events.getDescendantIds=function(a){var b=[];a=a.getDescendants(!1);for(var c=0,d;d=a[c];c++)b[c]=d.id;return b};
Blockly.Events.VAR_RENAME="var_rename";Blockly.Events.UI="ui";Blockly.Events.BLOCK_DRAG="drag";Blockly.Events.SELECTED="selected";Blockly.Events.CLICK="click";Blockly.Events.MARKER_MOVE="marker_move";Blockly.Events.BUBBLE_OPEN="bubble_open";Blockly.Events.TRASHCAN_OPEN="trashcan_open";Blockly.Events.TOOLBOX_ITEM_SELECT="toolbox_item_select";Blockly.Events.THEME_CHANGE="theme_change";Blockly.Events.VIEWPORT_CHANGE="viewport_change";Blockly.Events.COMMENT_CREATE="comment_create";
Blockly.Events.COMMENT_DELETE="comment_delete";Blockly.Events.COMMENT_CHANGE="comment_change";Blockly.Events.COMMENT_MOVE="comment_move";Blockly.Events.FINISHED_LOADING="finished_loading";Blockly.Events.BUMP_EVENTS=[Blockly.Events.BLOCK_CREATE,Blockly.Events.BLOCK_MOVE,Blockly.Events.COMMENT_CREATE,Blockly.Events.COMMENT_MOVE];Blockly.Events.FIRE_QUEUE_=[];Blockly.Events.fire=function(a){Blockly.Events.isEnabled()&&(Blockly.Events.FIRE_QUEUE_.length||setTimeout(Blockly.Events.fireNow_,0),Blockly.Events.FIRE_QUEUE_.push(a))};
Blockly.Events.fireNow_=function(){for(var a=Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_,!0),b=Blockly.Events.FIRE_QUEUE_.length=0,c;c=a[b];b++)if(c.workspaceId){var d=Blockly.Workspace.getById(c.workspaceId);d&&d.fireChangeListener(c)}};
Blockly.Events.filter=function(a,b){a=a.slice();b||a.reverse();for(var c=[],d=Object.create(null),e=0,f;f=a[e];e++)if(!f.isNull()){var g=[f.isUiEvent?Blockly.Events.UI:f.type,f.blockId,f.workspaceId].join(" "),h=d[g],k=h?h.event:null;if(!h)d[g]={event:f,index:e},c.push(f);else if(f.type==Blockly.Events.MOVE&&h.index==e-1)k.newParentId=f.newParentId,k.newInputName=f.newInputName,k.newCoordinate=f.newCoordinate,h.index=e;else if(f.type==Blockly.Events.CHANGE&&f.element==k.element&&f.name==k.name)k.newValue=
f.newValue;else if(f.type!=Blockly.Events.CLICK||k.type!=Blockly.Events.BUBBLE_OPEN)d[g]={event:f,index:e},c.push(f)}a=c.filter(function(l){return!l.isNull()});b||a.reverse();for(e=1;f=a[e];e++)f.type==Blockly.Events.CHANGE&&"mutation"==f.element&&a.unshift(a.splice(e,1)[0]);return a};Blockly.Events.clearPendingUndo=function(){for(var a=0,b;b=Blockly.Events.FIRE_QUEUE_[a];a++)b.recordUndo=!1};Blockly.Events.disable=function(){Blockly.Events.disabled_++};Blockly.Events.enable=function(){Blockly.Events.disabled_--};
Blockly.Events.isEnabled=function(){return 0==Blockly.Events.disabled_};Blockly.Events.getGroup=function(){return Blockly.Events.group_};Blockly.Events.setGroup=function(a){Blockly.Events.group_="boolean"==typeof a?a?Blockly.utils.genUid():"":a};Blockly.Events.getDescendantIds=function(a){var b=[];a=a.getDescendants(!1);for(var c=0,d;d=a[c];c++)b[c]=d.id;return b};
Blockly.Events.fromJson=function(a,b){var c=Blockly.registry.getClass(Blockly.registry.Type.EVENT,a.type);if(!c)throw Error("Unknown event type.");c=new c;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.isBlank=null;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.isBlank=!1;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.deepMerge=function(a,b){for(var c in b)a[c]=null!=b[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.isBlank="undefined"==typeof a;this.blockId=a?a.id:null;this.workspaceId=a?a.workspace.id:void 0;this.element="undefined"==typeof b?"":b;this.oldValue="undefined"==typeof c?"":c;this.newValue="undefined"==typeof d?"":d;this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.Ui,Blockly.Events.Abstract);Blockly.Events.Ui.prototype.type=Blockly.Events.UI;
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),c=b.getBlockById(a.blockId);if(c){a=Blockly.Events.recordUndo;try{Blockly.Events.recordUndo=!1;var d=c.getParent();if(d&&d.isEnabled()){var e=c.getDescendants(!1);b=0;for(var f;f=e[b];b++)f.setEnabled(!0)}else if((c.outputConnection||c.previousConnection)&&!b.isDragging()){do c.setEnabled(!1),c=c.getNextBlock();while(c)}}finally{Blockly.Events.recordUndo=
a}}}};Blockly.Events.Abstract=function(){this.isBlank=null;this.workspaceId=void 0;this.group=Blockly.Events.getGroup();this.recordUndo=Blockly.Events.recordUndo};Blockly.Events.Abstract.prototype.isUiEvent=!1;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.isBlank=!1;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.deepMerge=function(a,b){for(var c in b)a[c]=null!=b[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.UiBase=function(a){Blockly.Events.UiBase.superClass_.constructor.call(this);this.isBlank="undefined"==typeof a;this.workspaceId=a?a:"";this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.UiBase,Blockly.Events.Abstract);Blockly.Events.UiBase.prototype.isUiEvent=!0;
Blockly.Events.Ui=function(a,b,c,d){Blockly.Events.Ui.superClass_.constructor.call(this,a?a.workspace.id:void 0);this.blockId=a?a.id:null;this.element="undefined"==typeof b?"":b;this.oldValue="undefined"==typeof c?"":c;this.newValue="undefined"==typeof d?"":d};Blockly.utils.object.inherits(Blockly.Events.Ui,Blockly.Events.UiBase);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.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.UI,Blockly.Events.Ui);Blockly.utils.Svg=function(a){this.tagName_=a};Blockly.utils.Svg.prototype.toString=function(){return this.tagName_};Blockly.utils.Svg.ANIMATE=new Blockly.utils.Svg("animate");Blockly.utils.Svg.CIRCLE=new Blockly.utils.Svg("circle");Blockly.utils.Svg.CLIPPATH=new Blockly.utils.Svg("clipPath");Blockly.utils.Svg.DEFS=new Blockly.utils.Svg("defs");Blockly.utils.Svg.FECOMPOSITE=new Blockly.utils.Svg("feComposite");Blockly.utils.Svg.FECOMPONENTTRANSFER=new Blockly.utils.Svg("feComponentTransfer");
Blockly.utils.Svg.FEFLOOD=new Blockly.utils.Svg("feFlood");Blockly.utils.Svg.FEFUNCA=new Blockly.utils.Svg("feFuncA");Blockly.utils.Svg.FEGAUSSIANBLUR=new Blockly.utils.Svg("feGaussianBlur");Blockly.utils.Svg.FEPOINTLIGHT=new Blockly.utils.Svg("fePointLight");Blockly.utils.Svg.FESPECULARLIGHTING=new Blockly.utils.Svg("feSpecularLighting");Blockly.utils.Svg.FILTER=new Blockly.utils.Svg("filter");Blockly.utils.Svg.FOREIGNOBJECT=new Blockly.utils.Svg("foreignObject");Blockly.utils.Svg.G=new Blockly.utils.Svg("g");
Blockly.utils.Svg.IMAGE=new Blockly.utils.Svg("image");Blockly.utils.Svg.LINE=new Blockly.utils.Svg("line");Blockly.utils.Svg.PATH=new Blockly.utils.Svg("path");Blockly.utils.Svg.PATTERN=new Blockly.utils.Svg("pattern");Blockly.utils.Svg.POLYGON=new Blockly.utils.Svg("polygon");Blockly.utils.Svg.RECT=new Blockly.utils.Svg("rect");Blockly.utils.Svg.SVG=new Blockly.utils.Svg("svg");Blockly.utils.Svg.TEXT=new Blockly.utils.Svg("text");Blockly.utils.Svg.TSPAN=new Blockly.utils.Svg("tspan");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.NodeType={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;
@@ -78,15 +81,7 @@ Blockly.BlockDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_
Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow=function(a){if(this.dragGroup_.childNodes.length)throw Error("Already dragging a block.");this.dragGroup_.appendChild(a);this.SVG_.style.display="block";this.surfaceXY_=new Blockly.utils.Coordinate(0,0)};Blockly.BlockDragSurfaceSvg.prototype.translateAndScaleGroup=function(a,b,c){this.scale_=c;a=a.toFixed(0);b=b.toFixed(0);this.dragGroup_.setAttribute("transform","translate("+a+","+b+") scale("+c+")")};
Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_=function(){var a=this.surfaceXY_.x,b=this.surfaceXY_.y;a=a.toFixed(0);b=b.toFixed(0);this.SVG_.style.display="block";Blockly.utils.dom.setCssTransform(this.SVG_,"translate3d("+a+"px, "+b+"px, 0px)")};Blockly.BlockDragSurfaceSvg.prototype.translateSurface=function(a,b){this.surfaceXY_=new Blockly.utils.Coordinate(a*this.scale_,b*this.scale_);this.translateSurfaceInternal_()};
Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation=function(){var a=Blockly.utils.getRelativeXY(this.SVG_);return new Blockly.utils.Coordinate(a.x/this.scale_,a.y/this.scale_)};Blockly.BlockDragSurfaceSvg.prototype.getGroup=function(){return this.dragGroup_};Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock=function(){return this.dragGroup_.firstChild};
Blockly.BlockDragSurfaceSvg.prototype.clearAndHide=function(a){a?a.appendChild(this.getCurrentBlock()):this.dragGroup_.removeChild(this.getCurrentBlock());this.SVG_.style.display="none";if(this.dragGroup_.childNodes.length)throw Error("Drag group was not cleared.");this.surfaceXY_=null};Blockly.utils.IdGenerator={};Blockly.utils.IdGenerator.nextId_=0;Blockly.utils.IdGenerator.getNextUniqueId=function(){return"blockly-"+(Blockly.utils.IdGenerator.nextId_++).toString(36)};Blockly.Component=function(){this.rightToLeft_=Blockly.Component.defaultRightToLeft;this.id_=null;this.inDocument_=!1;this.parent_=this.element_=null;this.children_=[];this.childIndex_={};this.disposed_=!1};Blockly.Component.defaultRightToLeft=!1;Blockly.Component.Error={ALREADY_RENDERED:"Component already rendered",PARENT_UNABLE_TO_BE_SET:"Unable to set parent component",CHILD_INDEX_OUT_OF_BOUNDS:"Child component index out of bounds",ABSTRACT_METHOD:"Unimplemented abstract method"};
Blockly.Component.prototype.getId=function(){return this.id_||(this.id_=Blockly.utils.IdGenerator.getNextUniqueId())};Blockly.Component.prototype.getElement=function(){return this.element_};Blockly.Component.prototype.setElementInternal=function(a){this.element_=a};
Blockly.Component.prototype.setParent=function(a){if(this==a)throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);if(a&&this.parent_&&this.id_&&this.parent_.getChild(this.id_)&&this.parent_!=a)throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);this.parent_=a};Blockly.Component.prototype.getParent=function(){return this.parent_};Blockly.Component.prototype.isInDocument=function(){return this.inDocument_};
Blockly.Component.prototype.createDom=function(){throw Error(Blockly.Component.Error.ABSTRACT_METHOD);};Blockly.Component.prototype.render=function(a){this.render_(a)};Blockly.Component.prototype.render_=function(a,b){if(this.inDocument_)throw Error(Blockly.Component.Error.ALREADY_RENDERED);this.element_||this.createDom();a?a.insertBefore(this.element_,b||null):document.body.appendChild(this.element_);this.parent_&&!this.parent_.isInDocument()||this.enterDocument()};
Blockly.Component.prototype.enterDocument=function(){this.inDocument_=!0;this.forEachChild(function(a){!a.isInDocument()&&a.getElement()&&a.enterDocument()})};Blockly.Component.prototype.exitDocument=function(){this.forEachChild(function(a){a.isInDocument()&&a.exitDocument()});this.inDocument_=!1};Blockly.Component.prototype.dispose=function(){this.disposed_||(this.disposed_=!0,this.disposeInternal())};
Blockly.Component.prototype.disposeInternal=function(){this.inDocument_&&this.exitDocument();this.forEachChild(function(a){a.dispose()});this.element_&&Blockly.utils.dom.removeNode(this.element_);this.parent_=this.element_=this.childIndex_=this.children_=null};Blockly.Component.prototype.addChild=function(a,b){this.addChildAt(a,this.getChildCount(),b)};
Blockly.Component.prototype.addChildAt=function(a,b,c){if(a.inDocument_&&(c||!this.inDocument_))throw Error(Blockly.Component.Error.ALREADY_RENDERED);if(0>b||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<d&&this.children_.splice(d,1)}a.setParent(this);this.children_.splice(b,0,a);a.inDocument_&&this.inDocument_&&a.getParent()==this?(c=this.getContentElement(),b=c.childNodes[b]||
null,b!=a.getElement()&&c.insertBefore(a.getElement(),b)):c?(this.element_||this.createDom(),b=this.getChildAt(b+1),a.render_(this.getContentElement(),b?b.element_:null)):this.inDocument_&&!a.inDocument_&&a.element_&&a.element_.parentNode&&a.element_.parentNode.nodeType==Blockly.utils.dom.NodeType.ELEMENT_NODE&&a.enterDocument()};Blockly.Component.prototype.getContentElement=function(){return this.element_};Blockly.Component.prototype.hasChildren=function(){return 0!=this.children_.length};
Blockly.Component.prototype.getChildCount=function(){return this.children_.length};Blockly.Component.prototype.getChild=function(a){return a?this.childIndex_[a]||null:null};Blockly.Component.prototype.getChildAt=function(a){return this.children_[a]||null};Blockly.Component.prototype.forEachChild=function(a,b){for(var c=0;c<this.children_.length;c++)a.call(b,this.children_[c],c)};Blockly.Css={};Blockly.Css.injected_=!1;Blockly.Css.register=function(a){if(Blockly.Css.injected_)throw Error("CSS already injected");Array.prototype.push.apply(Blockly.Css.CONTENT,a);a.length=0};
Blockly.BlockDragSurfaceSvg.prototype.clearAndHide=function(a){a?a.appendChild(this.getCurrentBlock()):this.dragGroup_.removeChild(this.getCurrentBlock());this.SVG_.style.display="none";if(this.dragGroup_.childNodes.length)throw Error("Drag group was not cleared.");this.surfaceXY_=null};Blockly.Css={};Blockly.Css.injected_=!1;Blockly.Css.register=function(a){if(Blockly.Css.injected_)throw Error("CSS already injected");Array.prototype.push.apply(Blockly.Css.CONTENT,a);a.length=0};
Blockly.Css.inject=function(a,b){if(!Blockly.Css.injected_){Blockly.Css.injected_=!0;var c=Blockly.Css.CONTENT.join("\n");Blockly.Css.CONTENT.length=0;a&&(a=b.replace(/[\\/]$/,""),c=c.replace(/<<<PATH>>>/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.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;","overflow: hidden;","position: absolute;","display: block;","}",".blocklyWidgetDiv {","display: none;","position: absolute;","z-index: 99999;","}",".injectionDiv {","height: 100%;","position: relative;","overflow: hidden;","touch-action: none;","}",".blocklyNonSelectable {","user-select: none;","-ms-user-select: none;","-webkit-user-select: none;","}",".blocklyWsDragSurface {","display: none;","position: absolute;","top: 0;",
"left: 0;","}",".blocklyWsDragSurface.blocklyOverflowVisible {","overflow: visible;","}",".blocklyBlockDragSurface {","display: none;","position: absolute;","top: 0;","left: 0;","right: 0;","bottom: 0;","overflow: visible !important;","z-index: 50;","}",".blocklyBlockCanvas.blocklyCanvasTransitioning,",".blocklyBubbleCanvas.blocklyCanvasTransitioning {","transition: transform .5s;","}",".blocklyTooltipDiv {","background-color: #ffffc7;","border: 1px solid #ddc;","box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);",
@@ -101,8 +96,8 @@ Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;",
"}",".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;","}",".blocklyVerticalMarker {","stroke-width: 3px;","fill: rgba(255,255,255,.5);","pointer-events: none;","}",".blocklyComputeCanvas {","position: absolute;","width: 0;","height: 0;","}",".blocklyNoPointerEvents {","pointer-events: none;","}",".blocklyContextMenu {","border-radius: 4px;","max-height: 100%;","}",".blocklyDropdownMenu {","border-radius: 2px;","padding: 0 !important;","}",
".blocklyDropdownMenu .blocklyMenuItem {","padding-left: 28px;","}",".blocklyDropdownMenu .blocklyMenuItemRtl {","padding-left: 5px;","padding-right: 28px;","}",".blocklyWidgetDiv .blocklyMenu {","background: #fff;","border: 1px solid transparent;","box-shadow: 0 0 3px 1px rgba(0,0,0,.3);","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;","}",".blocklyWidgetDiv .blocklyMenu.blocklyFocused {",
"box-shadow: 0 0 6px 1px rgba(0,0,0,.3);","}",".blocklyDropDownDiv .blocklyMenu {",'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;',"outline: none;","z-index: 20000;","}",".blocklyMenuItem {","border: none;","color: #000;","cursor: pointer;","list-style: none;","margin: 0;","min-width: 7em;","padding: 6px 15px;","white-space: nowrap;","}",".blocklyMenuItemDisabled {","color: #ccc;","cursor: inherit;","}",".blocklyMenuItemHighlight {","background-color: rgba(0,0,0,.1);","}",".blocklyMenuItemCheckbox {",
"height: 16px;","position: absolute;","width: 16px;","}",".blocklyMenuItemSelected .blocklyMenuItemCheckbox {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px;","float: left;","margin-left: -24px;","position: static;","}",".blocklyMenuItemRtl .blocklyMenuItemCheckbox {","float: right;","margin-right: -24px;","}"];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(c<a){var d=c;c=a;a=d}return Math.max(a,Math.min(b,c))};Blockly.DropDownDiv=function(){};Blockly.DropDownDiv.boundsElement_=null;Blockly.DropDownDiv.owner_=null;Blockly.DropDownDiv.positionToField_=null;Blockly.DropDownDiv.ARROW_SIZE=16;Blockly.DropDownDiv.BORDER_SIZE=1;Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING=12;Blockly.DropDownDiv.PADDING_Y=16;Blockly.DropDownDiv.ANIMATION_TIME=.25;Blockly.DropDownDiv.animateOutTimer_=null;Blockly.DropDownDiv.onHide_=null;Blockly.DropDownDiv.rendererClassName_="";Blockly.DropDownDiv.themeClassName_="";
"box-shadow: 0 0 6px 1px rgba(0,0,0,.3);","}",".blocklyDropDownDiv .blocklyMenu {","background: inherit;","border: inherit;",'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;',"outline: none;","position: relative;","z-index: 20000;","}",".blocklyMenuItem {","border: none;","color: #000;","cursor: pointer;","list-style: none;","margin: 0;","min-width: 7em;","padding: 6px 15px;","white-space: nowrap;","}",".blocklyMenuItemDisabled {","color: #ccc;","cursor: inherit;","}",".blocklyMenuItemHighlight {",
"background-color: rgba(0,0,0,.1);","}",".blocklyMenuItemCheckbox {","height: 16px;","position: absolute;","width: 16px;","}",".blocklyMenuItemSelected .blocklyMenuItemCheckbox {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px;","float: left;","margin-left: -24px;","position: static;","}",".blocklyMenuItemRtl .blocklyMenuItemCheckbox {","float: right;","margin-right: -24px;","}"];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(c<a){var d=c;c=a;a=d}return Math.max(a,Math.min(b,c))};Blockly.DropDownDiv=function(){};Blockly.DropDownDiv.boundsElement_=null;Blockly.DropDownDiv.owner_=null;Blockly.DropDownDiv.positionToField_=null;Blockly.DropDownDiv.ARROW_SIZE=16;Blockly.DropDownDiv.BORDER_SIZE=1;Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING=12;Blockly.DropDownDiv.PADDING_Y=16;Blockly.DropDownDiv.ANIMATION_TIME=.25;Blockly.DropDownDiv.animateOutTimer_=null;Blockly.DropDownDiv.onHide_=null;Blockly.DropDownDiv.rendererClassName_="";Blockly.DropDownDiv.themeClassName_="";
Blockly.DropDownDiv.createDom=function(){if(!Blockly.DropDownDiv.DIV_){var a=document.createElement("div");a.className="blocklyDropDownDiv";(Blockly.parentContainer||document.body).appendChild(a);Blockly.DropDownDiv.DIV_=a;var b=document.createElement("div");b.className="blocklyDropDownContent";a.appendChild(b);Blockly.DropDownDiv.content_=b;b=document.createElement("div");b.className="blocklyDropDownArrow";a.appendChild(b);Blockly.DropDownDiv.arrow_=b;Blockly.DropDownDiv.DIV_.style.opacity=0;Blockly.DropDownDiv.DIV_.style.transition=
"transform "+Blockly.DropDownDiv.ANIMATION_TIME+"s, opacity "+Blockly.DropDownDiv.ANIMATION_TIME+"s";a.addEventListener("focusin",function(){Blockly.utils.dom.addClass(a,"blocklyFocused")});a.addEventListener("focusout",function(){Blockly.utils.dom.removeClass(a,"blocklyFocused")})}};Blockly.DropDownDiv.setBoundsElement=function(a){Blockly.DropDownDiv.boundsElement_=a};Blockly.DropDownDiv.getContentDiv=function(){return Blockly.DropDownDiv.content_};
Blockly.DropDownDiv.clearContent=function(){Blockly.DropDownDiv.content_.textContent="";Blockly.DropDownDiv.content_.style.width=""};Blockly.DropDownDiv.setColour=function(a,b){Blockly.DropDownDiv.DIV_.style.backgroundColor=a;Blockly.DropDownDiv.DIV_.style.borderColor=b};Blockly.DropDownDiv.showPositionedByBlock=function(a,b,c,d){return Blockly.DropDownDiv.showPositionedByRect_(Blockly.DropDownDiv.getScaledBboxOfBlock_(b),a,c,d)};
@@ -128,40 +123,34 @@ Blockly.Grid.createDom=function(a,b,c){a=Blockly.utils.dom.createSvgElement(Bloc
Blockly.Theme.prototype.setCategoryStyle=function(a,b){this.categoryStyles[a]=b};Blockly.Theme.prototype.getComponentStyle=function(a){return(a=this.componentStyles[a])&&"string"==typeof a&&this.getComponentStyle(a)?this.getComponentStyle(a):a?String(a):null};Blockly.Theme.prototype.setComponentStyle=function(a,b){this.componentStyles[a]=b};Blockly.Theme.prototype.setFontStyle=function(a){this.fontStyle=a};Blockly.Theme.prototype.setStartHats=function(a){this.startHats=a};
Blockly.Theme.defineTheme=function(a,b){var c=new Blockly.Theme(a),d=b.base;d&&("string"==typeof d&&(d=Blockly.registry.getObject(Blockly.registry.Type.THEME,d)),d instanceof Blockly.Theme&&(Blockly.utils.object.deepMerge(c,d),c.name=a));Blockly.utils.object.deepMerge(c.blockStyles,b.blockStyles);Blockly.utils.object.deepMerge(c.categoryStyles,b.categoryStyles);Blockly.utils.object.deepMerge(c.componentStyles,b.componentStyles);Blockly.utils.object.deepMerge(c.fontStyle,b.fontStyle);null!=b.startHats&&
(c.startHats=b.startHats);return c};Blockly.Themes={};Blockly.Themes.Classic={};Blockly.Themes.Classic.defaultBlockStyles={colour_blocks:{colourPrimary:"20"},list_blocks:{colourPrimary:"260"},logic_blocks:{colourPrimary:"210"},loop_blocks:{colourPrimary:"120"},math_blocks:{colourPrimary:"230"},procedure_blocks:{colourPrimary:"290"},text_blocks:{colourPrimary:"160"},variable_blocks:{colourPrimary:"330"},variable_dynamic_blocks:{colourPrimary:"310"},hat_blocks:{colourPrimary:"330",hat:"cap"}};
Blockly.Themes.Classic.categoryStyles={colour_category:{colour:"20"},list_category:{colour:"260"},logic_category:{colour:"210"},loop_category:{colour:"120"},math_category:{colour:"230"},procedure_category:{colour:"290"},text_category:{colour:"160"},variable_category:{colour:"330"},variable_dynamic_category:{colour:"310"}};Blockly.Themes.Classic=new Blockly.Theme("classic",Blockly.Themes.Classic.defaultBlockStyles,Blockly.Themes.Classic.categoryStyles);Blockly.utils.KeyCodes={WIN_KEY_FF_LINUX:0,MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PLUS_SIGN:43,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,FF_SEMICOLON:59,FF_EQUALS:61,FF_DASH:173,FF_HASH:163,QUESTION_MARK:63,AT_SIGN:64,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,
N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SCROLL_LOCK:145,FIRST_MEDIA_KEY:166,LAST_MEDIA_KEY:183,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,
PERIOD:190,SLASH:191,APOSTROPHE:192,TILDE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,MAC_WK_CMD_LEFT:91,MAC_WK_CMD_RIGHT:93,WIN_IME:229,VK_NONAME:252,PHANTOM:255};Blockly.user={};Blockly.user.keyMap={};Blockly.user.keyMap.map_={};Blockly.user.keyMap.modifierKeys={SHIFT:"Shift",CONTROL:"Control",ALT:"Alt",META:"Meta"};Blockly.user.keyMap.setActionForKey=function(a,b){var c=Blockly.user.keyMap.getKeyByAction(b);c&&delete Blockly.user.keyMap.map_[c];Blockly.user.keyMap.map_[a]=b};Blockly.user.keyMap.setKeyMap=function(a){Blockly.user.keyMap.map_=a};Blockly.user.keyMap.getKeyMap=function(){var a={};Blockly.utils.object.mixin(a,Blockly.user.keyMap.map_);return a};
Blockly.user.keyMap.getActionByKeyCode=function(a){return Blockly.user.keyMap.map_[a]};Blockly.user.keyMap.getKeyByAction=function(a){for(var b=Object.keys(Blockly.user.keyMap.map_),c=0,d;d=b[c];c++)if(Blockly.user.keyMap.map_[d].name===a.name)return d;return null};Blockly.user.keyMap.serializeKeyEvent=function(a){for(var b=Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys),c="",d=0,e;e=b[d];d++)a.getModifierState(e)&&(c+=e);return c+=a.keyCode};
Blockly.user.keyMap.checkModifiers_=function(a,b){for(var c=0,d;d=a[c];c++)if(0>b.indexOf(d))throw Error(d+" is not a valid modifier key.");};Blockly.user.keyMap.createSerializedKey=function(a,b){var c="",d=Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys);Blockly.user.keyMap.checkModifiers_(b,d);for(var e=0,f;f=d[e];e++)-1<b.indexOf(f)&&(c+=f);return c+a};
Blockly.user.keyMap.createDefaultKeyMap=function(){var a={},b=Blockly.user.keyMap.createSerializedKey(Blockly.utils.KeyCodes.K,[Blockly.user.keyMap.modifierKeys.CONTROL,Blockly.user.keyMap.modifierKeys.SHIFT]),c=Blockly.user.keyMap.createSerializedKey(Blockly.utils.KeyCodes.W,[Blockly.user.keyMap.modifierKeys.SHIFT]),d=Blockly.user.keyMap.createSerializedKey(Blockly.utils.KeyCodes.A,[Blockly.user.keyMap.modifierKeys.SHIFT]),e=Blockly.user.keyMap.createSerializedKey(Blockly.utils.KeyCodes.S,[Blockly.user.keyMap.modifierKeys.SHIFT]),
f=Blockly.user.keyMap.createSerializedKey(Blockly.utils.KeyCodes.D,[Blockly.user.keyMap.modifierKeys.SHIFT]);a[Blockly.utils.KeyCodes.W]=Blockly.navigation.ACTION_PREVIOUS;a[Blockly.utils.KeyCodes.A]=Blockly.navigation.ACTION_OUT;a[Blockly.utils.KeyCodes.S]=Blockly.navigation.ACTION_NEXT;a[Blockly.utils.KeyCodes.D]=Blockly.navigation.ACTION_IN;a[Blockly.utils.KeyCodes.I]=Blockly.navigation.ACTION_INSERT;a[Blockly.utils.KeyCodes.ENTER]=Blockly.navigation.ACTION_MARK;a[Blockly.utils.KeyCodes.X]=Blockly.navigation.ACTION_DISCONNECT;
a[Blockly.utils.KeyCodes.T]=Blockly.navigation.ACTION_TOOLBOX;a[Blockly.utils.KeyCodes.E]=Blockly.navigation.ACTION_EXIT;a[Blockly.utils.KeyCodes.ESC]=Blockly.navigation.ACTION_EXIT;a[b]=Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV;a[c]=Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP;a[d]=Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT;a[e]=Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN;a[f]=Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT;return a};Blockly.utils.Metrics=function(){};Blockly.utils.toolbox={};Blockly.utils.toolbox.CATEGORY_TOOLBOX_KIND="categoryToolbox";Blockly.utils.toolbox.FLYOUT_TOOLBOX_KIND="flyoutToolbox";Blockly.utils.toolbox.Position={TOP:Blockly.TOOLBOX_AT_TOP,BOTTOM:Blockly.TOOLBOX_AT_BOTTOM,LEFT:Blockly.TOOLBOX_AT_LEFT,RIGHT:Blockly.TOOLBOX_AT_RIGHT};
Blockly.Themes.Classic.categoryStyles={colour_category:{colour:"20"},list_category:{colour:"260"},logic_category:{colour:"210"},loop_category:{colour:"120"},math_category:{colour:"230"},procedure_category:{colour:"290"},text_category:{colour:"160"},variable_category:{colour:"330"},variable_dynamic_category:{colour:"310"}};Blockly.Themes.Classic=new Blockly.Theme("classic",Blockly.Themes.Classic.defaultBlockStyles,Blockly.Themes.Classic.categoryStyles);Blockly.utils.IdGenerator={};Blockly.utils.IdGenerator.nextId_=0;Blockly.utils.IdGenerator.getNextUniqueId=function(){return"blockly-"+(Blockly.utils.IdGenerator.nextId_++).toString(36)};Blockly.utils.Metrics=function(){};Blockly.utils.toolbox={};Blockly.utils.toolbox.CATEGORY_TOOLBOX_KIND="categoryToolbox";Blockly.utils.toolbox.FLYOUT_TOOLBOX_KIND="flyoutToolbox";Blockly.utils.toolbox.Position={TOP:Blockly.TOOLBOX_AT_TOP,BOTTOM:Blockly.TOOLBOX_AT_BOTTOM,LEFT:Blockly.TOOLBOX_AT_LEFT,RIGHT:Blockly.TOOLBOX_AT_RIGHT};
Blockly.utils.toolbox.convertToolboxDefToJson=function(a){if(!a)return null;if(a instanceof Element||"string"==typeof a)a=Blockly.utils.toolbox.parseToolboxTree(a),a=Blockly.utils.toolbox.convertToToolboxJson_(a);Blockly.utils.toolbox.validateToolbox_(a);return a};
Blockly.utils.toolbox.validateToolbox_=function(a){var b=a.kind;a=a.contents;if(b&&b!=Blockly.utils.toolbox.FLYOUT_TOOLBOX_KIND&&b!=Blockly.utils.toolbox.CATEGORY_TOOLBOX_KIND)throw Error("Invalid toolbox kind "+b+". Please supply either "+Blockly.utils.toolbox.FLYOUT_TOOLBOX_KIND+" or "+Blockly.utils.toolbox.CATEGORY_TOOLBOX_KIND);if(!a)throw Error("Toolbox must have a contents attribute.");};
Blockly.utils.toolbox.convertFlyoutDefToJsonArray=function(a){return a?a.contents?a.contents:Array.isArray(a)&&0<a.length&&!a[0].nodeType?a:Blockly.utils.toolbox.xmlToJsonArray_(a):[]};Blockly.utils.toolbox.hasCategories=function(a){if(!a)return!1;var b=a.kind;return b?b==Blockly.utils.toolbox.CATEGORY_TOOLBOX_KIND:!!a.contents.filter(function(c){return"CATEGORY"==c.kind.toUpperCase()}).length};
Blockly.utils.toolbox.isCategoryCollapsible=function(a){return a&&a.contents?!!a.contents.filter(function(b){return"CATEGORY"==b.kind.toUpperCase()}).length:!1};Blockly.utils.toolbox.convertToToolboxJson_=function(a){var b={contents:Blockly.utils.toolbox.xmlToJsonArray_(a)};a instanceof Node&&Blockly.utils.toolbox.addAttributes_(a,b);return b};
Blockly.utils.toolbox.xmlToJsonArray_=function(a){var b=[],c=a.childNodes;c||(c=a);a=0;for(var d;d=c[a];a++)if(d.tagName){var e={},f=d.tagName.toUpperCase();e.kind=f;"BLOCK"==f?e.blockxml=d:"CATEGORY"==f&&(e.contents=Blockly.utils.toolbox.xmlToJsonArray_(d));Blockly.utils.toolbox.addAttributes_(d,e);b.push(e)}return b};
Blockly.utils.toolbox.xmlToJsonArray_=function(a){var b=[],c=a.childNodes;c||(c=a);a=0;for(var d;d=c[a];a++)if(d.tagName){var e={},f=d.tagName.toUpperCase();e.kind=f;"BLOCK"==f?e.blockxml=d:d.childNodes&&0<d.childNodes.length&&(e.contents=Blockly.utils.toolbox.xmlToJsonArray_(d));Blockly.utils.toolbox.addAttributes_(d,e);b.push(e)}return b};
Blockly.utils.toolbox.addAttributes_=function(a,b){for(var c=0;c<a.attributes.length;c++){var d=a.attributes[c];-1<d.nodeName.indexOf("css-")?(b.cssconfig=b.cssconfig||{},b.cssconfig[d.nodeName.replace("css-","")]=d.value):b[d.nodeName]=d.value}};
Blockly.utils.toolbox.parseToolboxTree=function(a){if(a){if("string"!=typeof a&&(Blockly.utils.userAgent.IE&&a.outerHTML?a=a.outerHTML:a instanceof Element||(a=null)),"string"==typeof a&&(a=Blockly.Xml.textToDom(a),"xml"!=a.nodeName.toLowerCase()))throw TypeError("Toolbox should be an <xml> document.");}else a=null;return a};Blockly.utils.xml={};Blockly.utils.xml.NAME_SPACE="https://developers.google.com/blockly/xml";Blockly.utils.xml.document=function(){return document};Blockly.utils.xml.createElement=function(a){return Blockly.utils.xml.document().createElementNS(Blockly.utils.xml.NAME_SPACE,a)};Blockly.utils.xml.createTextNode=function(a){return Blockly.utils.xml.document().createTextNode(a)};Blockly.utils.xml.textToDomDocument=function(a){return(new DOMParser).parseFromString(a,"text/xml")};
Blockly.utils.xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};Blockly.Events.BlockBase=function(a){Blockly.Events.BlockBase.superClass_.constructor.call(this);this.blockId=(this.isBlank="undefined"==typeof a)?"":a.id;this.workspaceId=this.isBlank?"":a.workspace.id};Blockly.utils.object.inherits(Blockly.Events.BlockBase,Blockly.Events.Abstract);Blockly.Events.BlockBase.prototype.toJson=function(){var a=Blockly.Events.BlockBase.superClass_.toJson.call(this);a.blockId=this.blockId;return a};
Blockly.Events.BlockBase.prototype.fromJson=function(a){Blockly.Events.BlockBase.superClass_.fromJson.call(this,a);this.blockId=a.blockId};Blockly.Events.Change=function(a,b,c,d,e){Blockly.Events.Change.superClass_.constructor.call(this,a);a&&(this.element="undefined"==typeof b?"":b,this.name="undefined"==typeof c?"":c,this.oldValue="undefined"==typeof d?"":d,this.newValue="undefined"==typeof e?"":e)};Blockly.utils.object.inherits(Blockly.Events.Change,Blockly.Events.BlockBase);
Blockly.Events.BlockChange=Blockly.Events.Change;Blockly.Events.Change.prototype.type=Blockly.Events.CHANGE;Blockly.Events.Change.prototype.toJson=function(){var a=Blockly.Events.Change.superClass_.toJson.call(this);a.element=this.element;this.name&&(a.name=this.name);a.newValue=this.newValue;return a};Blockly.Events.Change.prototype.fromJson=function(a){Blockly.Events.Change.superClass_.fromJson.call(this,a);this.element=a.element;this.name=a.name;this.newValue=a.newValue};
Blockly.Events.Change.prototype.isNull=function(){return this.oldValue==this.newValue};
Blockly.Events.BlockChange=Blockly.Events.Change;Blockly.Events.Change.prototype.type=Blockly.Events.CHANGE;Blockly.Events.Change.prototype.toJson=function(){var a=Blockly.Events.Change.superClass_.toJson.call(this);a.element=this.element;this.name&&(a.name=this.name);a.oldValue=this.oldValue;a.newValue=this.newValue;return a};
Blockly.Events.Change.prototype.fromJson=function(a){Blockly.Events.Change.superClass_.fromJson.call(this,a);this.element=a.element;this.name=a.name;this.oldValue=a.oldValue;this.newValue=a.newValue};Blockly.Events.Change.prototype.isNull=function(){return this.oldValue==this.newValue};
Blockly.Events.Change.prototype.run=function(a){var b=this.getEventWorkspace_().getBlockById(this.blockId);if(b)switch(b.mutator&&b.mutator.setVisible(!1),a=a?this.newValue:this.oldValue,this.element){case "field":(b=b.getField(this.name))?b.setValue(a):console.warn("Can't set non-existent field: "+this.name);break;case "comment":b.setCommentText(a||null);break;case "collapsed":b.setCollapsed(!!a);break;case "disabled":b.setEnabled(!a);break;case "inline":b.setInputsInline(!!a);break;case "mutation":var c=
"";b.mutationToDom&&(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){var d=Blockly.Xml.textToDom(a||"<mutation/>");b.domToMutation(d)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a));break;default:console.warn("Unknown change type: "+this.element)}else console.warn("Can't change non-existent block: "+this.blockId)};
Blockly.Events.Create=function(a){Blockly.Events.Create.superClass_.constructor.call(this,a);a&&(a.isShadow()&&(this.recordUndo=!1),this.xml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a),this.ids=Blockly.Events.getDescendantIds(a))};Blockly.utils.object.inherits(Blockly.Events.Create,Blockly.Events.BlockBase);Blockly.Events.BlockCreate=Blockly.Events.Create;Blockly.Events.Create.prototype.type=Blockly.Events.CREATE;
Blockly.Events.Create.prototype.toJson=function(){var a=Blockly.Events.Create.superClass_.toJson.call(this);a.xml=Blockly.Xml.domToText(this.xml);a.ids=this.ids;return a};Blockly.Events.Create.prototype.fromJson=function(a){Blockly.Events.Create.superClass_.fromJson.call(this,a);this.xml=Blockly.Xml.textToDom(a.xml);this.ids=a.ids};
Blockly.Events.Create.prototype.toJson=function(){var a=Blockly.Events.Create.superClass_.toJson.call(this);a.xml=Blockly.Xml.domToText(this.xml);a.ids=this.ids;this.recordUndo||(a.recordUndo=this.recordUndo);return a};Blockly.Events.Create.prototype.fromJson=function(a){Blockly.Events.Create.superClass_.fromJson.call(this,a);this.xml=Blockly.Xml.textToDom(a.xml);this.ids=a.ids;void 0!==a.recordUndo&&(this.recordUndo=a.recordUndo)};
Blockly.Events.Create.prototype.run=function(a){var b=this.getEventWorkspace_();if(a)a=Blockly.utils.xml.createElement("xml"),a.appendChild(this.xml),Blockly.Xml.domToWorkspace(a,b);else{a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1):c==this.blockId&&console.warn("Can't uncreate non-existent block: "+c)}}};
Blockly.Events.Delete=function(a){Blockly.Events.Delete.superClass_.constructor.call(this,a);if(a){if(a.getParent())throw Error("Connected blocks cannot be deleted.");a.isShadow()&&(this.recordUndo=!1);this.oldXml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a);this.ids=Blockly.Events.getDescendantIds(a)}};Blockly.utils.object.inherits(Blockly.Events.Delete,Blockly.Events.BlockBase);Blockly.Events.BlockDelete=Blockly.Events.Delete;
Blockly.Events.Delete.prototype.type=Blockly.Events.DELETE;Blockly.Events.Delete.prototype.toJson=function(){var a=Blockly.Events.Delete.superClass_.toJson.call(this);a.ids=this.ids;return a};Blockly.Events.Delete.prototype.fromJson=function(a){Blockly.Events.Delete.superClass_.fromJson.call(this,a);this.ids=a.ids};
Blockly.Events.Delete.prototype.type=Blockly.Events.DELETE;Blockly.Events.Delete.prototype.toJson=function(){var a=Blockly.Events.Delete.superClass_.toJson.call(this);a.oldXml=Blockly.Xml.domToText(this.oldXml);a.ids=this.ids;this.recordUndo||(a.recordUndo=this.recordUndo);return a};Blockly.Events.Delete.prototype.fromJson=function(a){Blockly.Events.Delete.superClass_.fromJson.call(this,a);this.oldXml=Blockly.Xml.textToDom(a.oldXml);this.ids=a.ids;void 0!==a.recordUndo&&(this.recordUndo=a.recordUndo)};
Blockly.Events.Delete.prototype.run=function(a){var b=this.getEventWorkspace_();if(a){a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1):c==this.blockId&&console.warn("Can't delete non-existent block: "+c)}}else a=Blockly.utils.xml.createElement("xml"),a.appendChild(this.oldXml),Blockly.Xml.domToWorkspace(a,b)};
Blockly.Events.Move=function(a){Blockly.Events.Move.superClass_.constructor.call(this,a);a&&(a.isShadow()&&(this.recordUndo=!1),a=this.currentLocation_(),this.oldParentId=a.parentId,this.oldInputName=a.inputName,this.oldCoordinate=a.coordinate)};Blockly.utils.object.inherits(Blockly.Events.Move,Blockly.Events.BlockBase);Blockly.Events.BlockMove=Blockly.Events.Move;Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;
Blockly.Events.Move.prototype.toJson=function(){var a=Blockly.Events.Move.superClass_.toJson.call(this);this.newParentId&&(a.newParentId=this.newParentId);this.newInputName&&(a.newInputName=this.newInputName);this.newCoordinate&&(a.newCoordinate=Math.round(this.newCoordinate.x)+","+Math.round(this.newCoordinate.y));return a};
Blockly.Events.Move.prototype.fromJson=function(a){Blockly.Events.Move.superClass_.fromJson.call(this,a);this.newParentId=a.newParentId;this.newInputName=a.newInputName;a.newCoordinate&&(a=a.newCoordinate.split(","),this.newCoordinate=new Blockly.utils.Coordinate(Number(a[0]),Number(a[1])))};Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};
Blockly.Events.Move.prototype.currentLocation_=function(){var a=this.getEventWorkspace_().getBlockById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&Blockly.utils.Coordinate.equals(this.oldCoordinate,this.newCoordinate)};
Blockly.Events.Move.prototype.toJson=function(){var a=Blockly.Events.Move.superClass_.toJson.call(this);this.newParentId&&(a.newParentId=this.newParentId);this.newInputName&&(a.newInputName=this.newInputName);this.newCoordinate&&(a.newCoordinate=Math.round(this.newCoordinate.x)+","+Math.round(this.newCoordinate.y));this.recordUndo||(a.recordUndo=this.recordUndo);return a};
Blockly.Events.Move.prototype.fromJson=function(a){Blockly.Events.Move.superClass_.fromJson.call(this,a);this.newParentId=a.newParentId;this.newInputName=a.newInputName;if(a.newCoordinate){var b=a.newCoordinate.split(",");this.newCoordinate=new Blockly.utils.Coordinate(Number(b[0]),Number(b[1]))}void 0!==a.recordUndo&&(this.recordUndo=a.recordUndo)};
Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};Blockly.Events.Move.prototype.currentLocation_=function(){var a=this.getEventWorkspace_().getBlockById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};
Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&Blockly.utils.Coordinate.equals(this.oldCoordinate,this.newCoordinate)};
Blockly.Events.Move.prototype.run=function(a){var b=this.getEventWorkspace_(),c=b.getBlockById(this.blockId);if(c){var d=a?this.newParentId:this.oldParentId,e=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var f=null;if(d&&(f=b.getBlockById(d),!f)){console.warn("Can't connect to non-existent block: "+d);return}c.getParent()&&c.unplug();if(a)e=c.getRelativeToSurfaceXY(),c.moveBy(a.x-e.x,a.y-e.y);else{c=c.outputConnection||c.previousConnection;if(e){if(b=f.getInput(e))var g=
b.connection}else c.type==Blockly.PREVIOUS_STATEMENT&&(g=f.nextConnection);g?c.connect(g):console.warn("Can't connect to non-existent input: "+e)}}else console.warn("Can't move non-existent block: "+this.blockId)};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.CREATE,Blockly.Events.Create);Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.DELETE,Blockly.Events.Delete);Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.CHANGE,Blockly.Events.Change);
Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.MOVE,Blockly.Events.Move);Blockly.Events.FinishedLoading=function(a){this.isBlank="undefined"==typeof a;this.workspaceId=a?a.id:"";this.group=Blockly.Events.getGroup();this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.FinishedLoading,Blockly.Events.Ui);Blockly.Events.FinishedLoading.prototype.type=Blockly.Events.FINISHED_LOADING;Blockly.Events.FinishedLoading.prototype.toJson=function(){var a={type:this.type};this.group&&(a.group=this.group);this.workspaceId&&(a.workspaceId=this.workspaceId);return a};
Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.MOVE,Blockly.Events.Move);Blockly.Events.FinishedLoading=function(a){this.isBlank="undefined"==typeof a;this.workspaceId=a?a.id:"";this.group=Blockly.Events.getGroup();this.recordUndo=!1};Blockly.utils.object.inherits(Blockly.Events.FinishedLoading,Blockly.Events.Abstract);Blockly.Events.FinishedLoading.prototype.type=Blockly.Events.FINISHED_LOADING;Blockly.Events.FinishedLoading.prototype.toJson=function(){var a={type:this.type};this.group&&(a.group=this.group);this.workspaceId&&(a.workspaceId=this.workspaceId);return a};
Blockly.Events.FinishedLoading.prototype.fromJson=function(a){this.isBlank=!1;this.workspaceId=a.workspaceId;this.group=a.group};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.FINISHED_LOADING,Blockly.Events.FinishedLoading);Blockly.Events.VarBase=function(a){Blockly.Events.VarBase.superClass_.constructor.call(this);this.varId=(this.isBlank="undefined"==typeof a)?"":a.getId();this.workspaceId=this.isBlank?"":a.workspace.id};Blockly.utils.object.inherits(Blockly.Events.VarBase,Blockly.Events.Abstract);Blockly.Events.VarBase.prototype.toJson=function(){var a=Blockly.Events.VarBase.superClass_.toJson.call(this);a.varId=this.varId;return a};
Blockly.Events.VarBase.prototype.fromJson=function(a){Blockly.Events.VarBase.superClass_.toJson.call(this);this.varId=a.varId};Blockly.Events.VarCreate=function(a){Blockly.Events.VarCreate.superClass_.constructor.call(this,a);a&&(this.varType=a.type,this.varName=a.name)};Blockly.utils.object.inherits(Blockly.Events.VarCreate,Blockly.Events.VarBase);Blockly.Events.VarCreate.prototype.type=Blockly.Events.VAR_CREATE;
Blockly.Events.VarCreate.prototype.toJson=function(){var a=Blockly.Events.VarCreate.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a};Blockly.Events.VarCreate.prototype.fromJson=function(a){Blockly.Events.VarCreate.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};Blockly.Events.VarCreate.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.createVariable(this.varName,this.varType,this.varId):b.deleteVariableById(this.varId)};
@@ -192,9 +181,9 @@ setTimeout(function(){c.getCommentIcon().setVisible(!0)},1);break;case "data":c.
k&&h.connection.setShadowDom(k);break;case "next":if(f){if(!c.nextConnection)throw TypeError("Next statement does not exist.");if(c.nextConnection.isConnected())throw TypeError("Next statement is already connected.");f=Blockly.Xml.domToBlockHeadless_(f,b);if(!f.previousConnection)throw TypeError("Next block does not have previous statement.");c.nextConnection.connect(f.previousConnection)}k&&c.nextConnection&&c.nextConnection.setShadowDom(k);break;default:console.warn("Ignoring unknown tag: "+g.nodeName)}}l&&
c.initSvg();(e=a.getAttribute("inline"))&&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.utils.toolbox.convertToolboxDefToJson(a.toolbox);d=Blockly.utils.toolbox.hasCategories(c);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.utils.toolbox.Position.TOP:
Blockly.utils.toolbox.Position.BOTTOM:p==m?Blockly.utils.toolbox.Position.RIGHT:Blockly.utils.toolbox.Position.LEFT;var q=a.css;void 0===q&&(q=!0);var t="https://blockly-demo.appspot.com/static/media/";a.media?t=a.media:a.path&&(t=a.path+"media/");var r=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex,u=a.keyMap||Blockly.user.keyMap.createDefaultKeyMap(),v=a.renderer||"geras",w=a.plugins||{};this.RTL=m;this.oneBasedIndex=r;this.collapse=f;this.comments=g;this.disable=h;this.readOnly=b;this.maxBlocks=
a.maxBlocks||Infinity;this.maxInstances=a.maxInstances;this.pathToMedia=t;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=null;this.parentWorkspace=a.parentWorkspace;this.plugins=w};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.utils.toolbox.Position.BOTTOM:p==m?Blockly.utils.toolbox.Position.RIGHT:Blockly.utils.toolbox.Position.LEFT;var q=a.css;void 0===q&&(q=!0);var t="https://blockly-demo.appspot.com/static/media/";a.media?t=a.media:a.path&&(t=a.path+"media/");var r=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex,u=a.renderer||"geras",v=a.plugins||{};this.RTL=m;this.oneBasedIndex=r;this.collapse=f;this.comments=g;this.disable=h;this.readOnly=b;this.maxBlocks=a.maxBlocks||Infinity;this.maxInstances=a.maxInstances;
this.pathToMedia=t;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.renderer=u;this.rendererOverrides=a.rendererOverrides;
this.gridPattern=null;this.parentWorkspace=a.parentWorkspace;this.plugins=v};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<b.spacing&&!!a.snap;return b};Blockly.Options.parseThemeOptions_=function(a){a=a.theme||Blockly.Themes.Classic;return"string"==typeof a?Blockly.registry.getObject(Blockly.registry.Type.THEME,a):a instanceof Blockly.Theme?a:Blockly.Theme.defineTheme(a.name||"builtin"+Blockly.utils.IdGenerator.getNextUniqueId(),a)};
Blockly.Options.parseToolboxTree=function(a){Blockly.utils.deprecation.warn("Blockly.Options.parseToolboxTree","September 2020","September 2021","Blockly.utils.toolbox.parseToolboxTree");return Blockly.utils.toolbox.parseToolboxTree(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={};
@@ -302,7 +291,8 @@ 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;1<d?Blockly.utils.dom.removeNode(a):(a.setAttribute("r",25*d*c),a.style.opacity=1-d,Blockly.blockAnimations.disconnectPid_=setTimeout(Blockly.blockAnimations.connectionUiStep_,10,a,b,c))};
Blockly.blockAnimations.disconnectUiEffect=function(a){a.workspace.getAudioManager().play("disconnect");if(!(1>a.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;1<d?a.skew_="":(a.skew_="skewX("+Math.round(Math.sin(d*Math.PI*3)*(1-d)*b)+")",Blockly.blockAnimations.disconnectGroup_=a,Blockly.blockAnimations.disconnectPid_=setTimeout(Blockly.blockAnimations.disconnectUiStep_,10,a,b,c));a.setAttribute("transform",a.translate_+a.skew_)};
Blockly.blockAnimations.disconnectUiStop=function(){if(Blockly.blockAnimations.disconnectGroup_){clearTimeout(Blockly.blockAnimations.disconnectPid_);var a=Blockly.blockAnimations.disconnectGroup_;a.skew_="";a.setAttribute("transform",a.translate_);Blockly.blockAnimations.disconnectGroup_=null}};Blockly.InsertionMarkerManager=function(a){this.topBlock_=Blockly.selected=a;this.workspace_=a.workspace;this.lastMarker_=this.lastOnStack_=null;this.firstMarker_=this.createMarkerBlock_(this.topBlock_);this.localConnection_=this.closestConnection_=null;this.wouldDeleteBlock_=!1;this.fadedBlock_=this.highlightedBlock_=this.markerConnection_=null;this.availableConnections_=this.initAvailableConnections_()};Blockly.InsertionMarkerManager.PREVIEW_TYPE={INSERTION_MARKER:0,INPUT_OUTLINE:1,REPLACEMENT_FADE:2};
Blockly.blockAnimations.disconnectUiStop=function(){if(Blockly.blockAnimations.disconnectGroup_){clearTimeout(Blockly.blockAnimations.disconnectPid_);var a=Blockly.blockAnimations.disconnectGroup_;a.skew_="";a.setAttribute("transform",a.translate_);Blockly.blockAnimations.disconnectGroup_=null}};Blockly.Events.BlockDrag=function(a,b,c){Blockly.Events.BlockDrag.superClass_.constructor.call(this,a?a.workspace.id:void 0);this.blockId=a?a.id:null;this.isStart=b;this.blocks=c};Blockly.utils.object.inherits(Blockly.Events.BlockDrag,Blockly.Events.UiBase);Blockly.Events.BlockDrag.prototype.type=Blockly.Events.BLOCK_DRAG;
Blockly.Events.BlockDrag.prototype.toJson=function(){var a=Blockly.Events.BlockDrag.superClass_.toJson.call(this);a.isStart=this.isStart;a.blockId=this.blockId;a.blocks=this.blocks;return a};Blockly.Events.BlockDrag.prototype.fromJson=function(a){Blockly.Events.BlockDrag.superClass_.fromJson.call(this,a);this.isStart=a.isStart;this.blockId=a.blockId;this.blocks=a.blocks};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.BLOCK_DRAG,Blockly.Events.BlockDrag);Blockly.InsertionMarkerManager=function(a){this.topBlock_=Blockly.selected=a;this.workspace_=a.workspace;this.lastMarker_=this.lastOnStack_=null;this.firstMarker_=this.createMarkerBlock_(this.topBlock_);this.localConnection_=this.closestConnection_=null;this.wouldDeleteBlock_=!1;this.fadedBlock_=this.highlightedBlock_=this.markerConnection_=null;this.availableConnections_=this.initAvailableConnections_()};Blockly.InsertionMarkerManager.PREVIEW_TYPE={INSERTION_MARKER:0,INPUT_OUTLINE:1,REPLACEMENT_FADE:2};
Blockly.InsertionMarkerManager.prototype.dispose=function(){this.availableConnections_.length=0;Blockly.Events.disable();try{this.firstMarker_&&this.firstMarker_.dispose(),this.lastMarker_&&this.lastMarker_.dispose()}finally{Blockly.Events.enable()}};Blockly.InsertionMarkerManager.prototype.updateAvailableConnections=function(){this.availableConnections_=this.initAvailableConnections_()};Blockly.InsertionMarkerManager.prototype.wouldDeleteBlock=function(){return this.wouldDeleteBlock_};
Blockly.InsertionMarkerManager.prototype.wouldConnectBlock=function(){return!!this.closestConnection_};
Blockly.InsertionMarkerManager.prototype.applyConnections=function(){if(this.closestConnection_&&(Blockly.Events.disable(),this.hidePreview_(),Blockly.Events.enable(),this.localConnection_.connect(this.closestConnection_),this.topBlock_.rendered)){var a=this.localConnection_.isSuperior()?this.closestConnection_:this.localConnection_;Blockly.blockAnimations.connectionUiEffect(a.getSourceBlock());this.topBlock_.getRootBlock().bringToFront()}};
@@ -325,10 +315,10 @@ Blockly.InsertionMarkerManager.prototype.getInsertionMarkers=function(){var a=[]
Blockly.BlockDragger.initIconData_=function(a){var b=[];a=a.getDescendants(!1);for(var c=0,d;d=a[c];c++){d=d.getIcons();for(var e=0;e<d.length;e++){var f={location:d[e].getIconLocation(),icon:d[e]};b.push(f)}}return b};
Blockly.BlockDragger.prototype.startBlockDrag=function(a,b){Blockly.Events.getGroup()||Blockly.Events.setGroup(!0);this.fireDragStartEvent_();this.workspace_.isMutator&&this.draggingBlock_.bringToFront();Blockly.utils.dom.startTextWidthCache();this.workspace_.setResizesEnabled(!1);Blockly.blockAnimations.disconnectUiStop();if(this.draggingBlock_.getParent()||b&&this.draggingBlock_.nextConnection&&this.draggingBlock_.nextConnection.targetBlock())this.draggingBlock_.unplug(b),a=this.pixelsToWorkspaceUnits_(a),
a=Blockly.utils.Coordinate.sum(this.startXY_,a),this.draggingBlock_.translate(a.x,a.y),Blockly.blockAnimations.disconnectUiEffect(this.draggingBlock_),this.draggedConnectionManager_.updateAvailableConnections();this.draggingBlock_.setDragging(!0);this.draggingBlock_.moveToDragSurface();(a=this.workspace_.getToolbox())&&"function"==typeof a.addStyle&&(b=this.draggingBlock_.isDeletable()?"blocklyToolboxDelete":"blocklyToolboxGrab",a.addStyle(b))};
Blockly.BlockDragger.prototype.fireDragStartEvent_=function(){var a=new Blockly.Events.Ui(this.draggingBlock_,"dragStart",null,this.draggingBlock_.getDescendants(!1));Blockly.Events.fire(a)};Blockly.BlockDragger.prototype.dragBlock=function(a,b){b=this.pixelsToWorkspaceUnits_(b);var c=Blockly.utils.Coordinate.sum(this.startXY_,b);this.draggingBlock_.moveDuringDrag(c);this.dragIcons_(b);this.deleteArea_=this.workspace_.isDeleteArea(a);this.draggedConnectionManager_.update(b,this.deleteArea_);this.updateCursorDuringBlockDrag_()};
Blockly.BlockDragger.prototype.fireDragStartEvent_=function(){var a=new Blockly.Events.BlockDrag(this.draggingBlock_,!0,this.draggingBlock_.getDescendants(!1));Blockly.Events.fire(a)};Blockly.BlockDragger.prototype.dragBlock=function(a,b){b=this.pixelsToWorkspaceUnits_(b);var c=Blockly.utils.Coordinate.sum(this.startXY_,b);this.draggingBlock_.moveDuringDrag(c);this.dragIcons_(b);this.deleteArea_=this.workspace_.isDeleteArea(a);this.draggedConnectionManager_.update(b,this.deleteArea_);this.updateCursorDuringBlockDrag_()};
Blockly.BlockDragger.prototype.endBlockDrag=function(a,b){this.dragBlock(a,b);this.dragIconData_=[];this.fireDragEndEvent_();Blockly.utils.dom.stopTextWidthCache();Blockly.blockAnimations.disconnectUiStop();a=this.pixelsToWorkspaceUnits_(b);b=Blockly.utils.Coordinate.sum(this.startXY_,a);this.draggingBlock_.moveOffDragSurface(b);this.maybeDeleteBlock_()||(this.draggingBlock_.moveConnections(a.x,a.y),this.draggingBlock_.setDragging(!1),this.fireMoveEvent_(),this.draggedConnectionManager_.wouldConnectBlock()?
this.draggedConnectionManager_.applyConnections():this.draggingBlock_.render(),this.draggingBlock_.scheduleSnapAndBump());this.workspace_.setResizesEnabled(!0);(a=this.workspace_.getToolbox())&&"function"==typeof a.removeStyle&&(b=this.draggingBlock_.isDeletable()?"blocklyToolboxDelete":"blocklyToolboxGrab",a.removeStyle(b));Blockly.Events.setGroup(!1)};
Blockly.BlockDragger.prototype.fireDragEndEvent_=function(){var a=new Blockly.Events.Ui(this.draggingBlock_,"dragStop",this.draggingBlock_.getDescendants(!1),null);Blockly.Events.fire(a)};Blockly.BlockDragger.prototype.fireMoveEvent_=function(){var a=new Blockly.Events.BlockMove(this.draggingBlock_);a.oldCoordinate=this.startXY_;a.recordNew();Blockly.Events.fire(a)};
Blockly.BlockDragger.prototype.fireDragEndEvent_=function(){var a=new Blockly.Events.BlockDrag(this.draggingBlock_,!1,this.draggingBlock_.getDescendants(!1));Blockly.Events.fire(a)};Blockly.BlockDragger.prototype.fireMoveEvent_=function(){var a=new Blockly.Events.BlockMove(this.draggingBlock_);a.oldCoordinate=this.startXY_;a.recordNew();Blockly.Events.fire(a)};
Blockly.BlockDragger.prototype.maybeDeleteBlock_=function(){var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(a&&setTimeout(a.closeLid.bind(a),100),this.fireMoveEvent_(),this.draggingBlock_.dispose(!1,!0),Blockly.draggingConnections=[]):a&&a.closeLid();return this.wouldDeleteBlock_};
Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_=function(){this.wouldDeleteBlock_=this.draggedConnectionManager_.wouldDeleteBlock();var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(this.draggingBlock_.setDeleteStyle(!0),this.deleteArea_==Blockly.DELETE_AREA_TRASH&&a&&a.setLidOpen(!0)):(this.draggingBlock_.setDeleteStyle(!1),a&&a.setLidOpen(!1))};
Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_=function(a){a=new Blockly.utils.Coordinate(a.x/this.workspace_.scale,a.y/this.workspace_.scale);this.workspace_.isMutator&&a.scale(1/this.workspace_.options.parentWorkspace.scale);return a};Blockly.BlockDragger.prototype.dragIcons_=function(a){for(var b=0;b<this.dragIconData_.length;b++){var c=this.dragIconData_[b];c.icon.setIconLocation(Blockly.utils.Coordinate.sum(c.location,a))}};
@@ -391,7 +381,8 @@ Blockly.Bubble.prototype.renderArrow_=function(){var a=[],b=this.width_/2,c=this
m*d;e=c+m*e;m=b+h*l;var n=c+h*k;b-=h*l;c-=h*k;k=g+this.arrow_radians_;k>2*Math.PI&&(k-=2*Math.PI);g=Math.sin(k)*f/Blockly.Bubble.ARROW_BEND;f=Math.cos(k)*f/Blockly.Bubble.ARROW_BEND;a.push("M"+m+","+n);a.push("C"+(m+f)+","+(n+g)+" "+d+","+e+" "+d+","+e);a.push("C"+d+","+e+" "+(b+f)+","+(c+g)+" "+b+","+c)}a.push("z");this.bubbleArrow_.setAttribute("d",a.join(" "))};Blockly.Bubble.prototype.setColour=function(a){this.bubbleBack_.setAttribute("fill",a);this.bubbleArrow_.setAttribute("fill",a)};
Blockly.Bubble.prototype.dispose=function(){this.onMouseDownBubbleWrapper_&&Blockly.unbindEvent_(this.onMouseDownBubbleWrapper_);this.onMouseDownResizeWrapper_&&Blockly.unbindEvent_(this.onMouseDownResizeWrapper_);Blockly.Bubble.unbindDragEvents_();Blockly.utils.dom.removeNode(this.bubbleGroup_);this.disposed=!0};
Blockly.Bubble.prototype.moveDuringDrag=function(a,b){a?a.translateSurface(b.x,b.y):this.moveTo(b.x,b.y);this.relativeLeft_=this.workspace_.RTL?this.anchorXY_.x-b.x-this.width_:b.x-this.anchorXY_.x;this.relativeTop_=b.y-this.anchorXY_.y;this.renderArrow_()};Blockly.Bubble.prototype.getRelativeToSurfaceXY=function(){return new Blockly.utils.Coordinate(this.workspace_.RTL?-this.relativeLeft_+this.anchorXY_.x-this.width_:this.anchorXY_.x+this.relativeLeft_,this.anchorXY_.y+this.relativeTop_)};
Blockly.Bubble.prototype.setAutoLayout=function(a){this.autoLayout_=a};Blockly.Events.CommentBase=function(a){this.commentId=(this.isBlank="undefined"==typeof a)?"":a.id;this.workspaceId=this.isBlank?"":a.workspace.id;this.group=Blockly.Events.getGroup();this.recordUndo=Blockly.Events.recordUndo};Blockly.utils.object.inherits(Blockly.Events.CommentBase,Blockly.Events.Abstract);Blockly.Events.CommentBase.prototype.toJson=function(){var a=Blockly.Events.CommentBase.superClass_.toJson.call(this);this.commentId&&(a.commentId=this.commentId);return a};
Blockly.Bubble.prototype.setAutoLayout=function(a){this.autoLayout_=a};Blockly.Bubble.textToDom=function(a){var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TEXT,{"class":"blocklyText blocklyBubbleText blocklyNoPointerEvents",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c<a.length;c++){var d=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TSPAN,{dy:"1em",x:Blockly.Bubble.BORDER_WIDTH},b),e=document.createTextNode(a[c]);d.appendChild(e)}return b};
Blockly.Bubble.createNonEditableBubble=function(a,b,c){c=new Blockly.Bubble(b.workspace,a,b.pathObject.svgPath,c,null,null);c.setSvgId(b.id);if(b.RTL){b=a.getBBox().width;for(var d=0,e;e=a.childNodes[d];d++)e.setAttribute("text-anchor","end"),e.setAttribute("x",b+Blockly.Bubble.BORDER_WIDTH)}return c};Blockly.Events.CommentBase=function(a){this.commentId=(this.isBlank="undefined"==typeof a)?"":a.id;this.workspaceId=this.isBlank?"":a.workspace.id;this.group=Blockly.Events.getGroup();this.recordUndo=Blockly.Events.recordUndo};Blockly.utils.object.inherits(Blockly.Events.CommentBase,Blockly.Events.Abstract);Blockly.Events.CommentBase.prototype.toJson=function(){var a=Blockly.Events.CommentBase.superClass_.toJson.call(this);this.commentId&&(a.commentId=this.commentId);return a};
Blockly.Events.CommentBase.prototype.fromJson=function(a){Blockly.Events.CommentBase.superClass_.fromJson.call(this,a);this.commentId=a.commentId};Blockly.Events.CommentChange=function(a,b,c){Blockly.Events.CommentChange.superClass_.constructor.call(this,a);a&&(this.oldContents_="undefined"==typeof b?"":b,this.newContents_="undefined"==typeof c?"":c)};Blockly.utils.object.inherits(Blockly.Events.CommentChange,Blockly.Events.CommentBase);Blockly.Events.CommentChange.prototype.type=Blockly.Events.COMMENT_CHANGE;
Blockly.Events.CommentChange.prototype.toJson=function(){var a=Blockly.Events.CommentChange.superClass_.toJson.call(this);a.newContents=this.newContents_;return a};Blockly.Events.CommentChange.prototype.fromJson=function(a){Blockly.Events.CommentChange.superClass_.fromJson.call(this,a);this.newContents_=a.newValue};Blockly.Events.CommentChange.prototype.isNull=function(){return this.oldContents_==this.newContents_};
Blockly.Events.CommentChange.prototype.run=function(a){var b=this.getEventWorkspace_().getCommentById(this.commentId);b?b.setContent(a?this.newContents_:this.oldContents_):console.warn("Can't change non-existent comment: "+this.commentId)};Blockly.Events.CommentCreate=function(a){Blockly.Events.CommentCreate.superClass_.constructor.call(this,a);a&&(this.xml=a.toXmlWithXY())};Blockly.utils.object.inherits(Blockly.Events.CommentCreate,Blockly.Events.CommentBase);
@@ -409,14 +400,15 @@ Blockly.BubbleDragger.prototype.maybeDeleteBubble_=function(){var a=this.workspa
Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_=function(){this.wouldDeleteBubble_=this.deleteArea_!=Blockly.DELETE_AREA_NONE;var a=this.workspace_.trashcan;this.wouldDeleteBubble_?(this.draggingBubble_.setDeleteStyle(!0),this.deleteArea_==Blockly.DELETE_AREA_TRASH&&a&&a.setLidOpen(!0)):(this.draggingBubble_.setDeleteStyle(!1),a&&a.setLidOpen(!1))};
Blockly.BubbleDragger.prototype.endBubbleDrag=function(a,b){this.dragBubble(a,b);a=this.pixelsToWorkspaceUnits_(b);a=Blockly.utils.Coordinate.sum(this.startXY_,a);this.draggingBubble_.moveTo(a.x,a.y);this.maybeDeleteBubble_()||(this.dragSurface_&&this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas()),this.draggingBubble_.setDragging&&this.draggingBubble_.setDragging(!1),this.fireMoveEvent_());this.workspace_.setResizesEnabled(!0);(a=this.workspace_.getToolbox())&&"function"==typeof a.removeStyle&&
(b=this.draggingBubble_.isDeletable()?"blocklyToolboxDelete":"blocklyToolboxGrab",a.removeStyle(b));Blockly.Events.setGroup(!1)};Blockly.BubbleDragger.prototype.fireMoveEvent_=function(){if(this.draggingBubble_.isComment){var a=new Blockly.Events.CommentMove(this.draggingBubble_);a.setOldCoordinate(this.startXY_);a.recordNew();Blockly.Events.fire(a)}};
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_=function(a){a=new Blockly.utils.Coordinate(a.x/this.workspace_.scale,a.y/this.workspace_.scale);this.workspace_.isMutator&&a.scale(1/this.workspace_.options.parentWorkspace.scale);return a};Blockly.BubbleDragger.prototype.moveToDragSurface_=function(){this.draggingBubble_.moveTo(0,0);this.dragSurface_.translateSurface(this.startXY_.x,this.startXY_.y);this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot())};Blockly.WorkspaceDragger=function(a){this.workspace_=a;this.startScrollXY_=new Blockly.utils.Coordinate(a.scrollX,a.scrollY)};Blockly.WorkspaceDragger.prototype.dispose=function(){this.workspace_=null};Blockly.WorkspaceDragger.prototype.startDrag=function(){Blockly.selected&&Blockly.selected.unselect();this.workspace_.setupDragSurface()};Blockly.WorkspaceDragger.prototype.endDrag=function(a){this.drag(a);this.workspace_.resetDragSurface()};
Blockly.WorkspaceDragger.prototype.drag=function(a){a=Blockly.utils.Coordinate.sum(this.startScrollXY_,a);this.workspace_.scroll(a.x,a.y)};Blockly.FlyoutDragger=function(a){Blockly.FlyoutDragger.superClass_.constructor.call(this,a.getWorkspace());this.scrollbar_=a.scrollbar;this.horizontalLayout_=a.horizontalLayout};Blockly.utils.object.inherits(Blockly.FlyoutDragger,Blockly.WorkspaceDragger);Blockly.FlyoutDragger.prototype.drag=function(a){a=Blockly.utils.Coordinate.sum(this.startScrollXY_,a);this.horizontalLayout_?this.scrollbar_.set(-a.x):this.scrollbar_.set(-a.y)};Blockly.Action=function(a,b){this.name=a;this.desc=b};Blockly.navigation={};Blockly.navigation.loggingCallback=null;Blockly.navigation.STATE_FLYOUT=1;Blockly.navigation.STATE_WS=2;Blockly.navigation.STATE_TOOLBOX=3;Blockly.navigation.WS_MOVE_DISTANCE=40;Blockly.navigation.currentState_=Blockly.navigation.STATE_WS;
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_=function(a){a=new Blockly.utils.Coordinate(a.x/this.workspace_.scale,a.y/this.workspace_.scale);this.workspace_.isMutator&&a.scale(1/this.workspace_.options.parentWorkspace.scale);return a};Blockly.BubbleDragger.prototype.moveToDragSurface_=function(){this.draggingBubble_.moveTo(0,0);this.dragSurface_.translateSurface(this.startXY_.x,this.startXY_.y);this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot())};Blockly.Events.Click=function(a,b,c){Blockly.Events.Click.superClass_.constructor.call(this,a?a.workspace.id:b);this.blockId=a?a.id:null;this.targetType=c};Blockly.utils.object.inherits(Blockly.Events.Click,Blockly.Events.UiBase);Blockly.Events.Click.prototype.type=Blockly.Events.CLICK;Blockly.Events.Click.prototype.toJson=function(){var a=Blockly.Events.Click.superClass_.toJson.call(this);a.targetType=this.targetType;this.blockId&&(a.blockId=this.blockId);return a};
Blockly.Events.Click.prototype.fromJson=function(a){Blockly.Events.Click.superClass_.fromJson.call(this,a);this.targetType=a.targetType;this.blockId=a.blockId};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.CLICK,Blockly.Events.Click);Blockly.WorkspaceDragger=function(a){this.workspace_=a;this.startScrollXY_=new Blockly.utils.Coordinate(a.scrollX,a.scrollY)};Blockly.WorkspaceDragger.prototype.dispose=function(){this.workspace_=null};Blockly.WorkspaceDragger.prototype.startDrag=function(){Blockly.selected&&Blockly.selected.unselect();this.workspace_.setupDragSurface()};Blockly.WorkspaceDragger.prototype.endDrag=function(a){this.drag(a);this.workspace_.resetDragSurface()};
Blockly.WorkspaceDragger.prototype.drag=function(a){a=Blockly.utils.Coordinate.sum(this.startScrollXY_,a);this.workspace_.scroll(a.x,a.y)};Blockly.FlyoutDragger=function(a){Blockly.FlyoutDragger.superClass_.constructor.call(this,a.getWorkspace());this.scrollbar_=a.scrollbar;this.horizontalLayout_=a.horizontalLayout};Blockly.utils.object.inherits(Blockly.FlyoutDragger,Blockly.WorkspaceDragger);Blockly.FlyoutDragger.prototype.drag=function(a){a=Blockly.utils.Coordinate.sum(this.startScrollXY_,a);this.horizontalLayout_?this.scrollbar_.set(-a.x):this.scrollbar_.set(-a.y)};Blockly.navigation={};Blockly.navigation.loggingCallback=null;Blockly.navigation.STATE_FLYOUT=1;Blockly.navigation.STATE_WS=2;Blockly.navigation.STATE_TOOLBOX=3;Blockly.navigation.WS_MOVE_DISTANCE=40;Blockly.navigation.currentState_=Blockly.navigation.STATE_WS;
Blockly.navigation.actionNames={PREVIOUS:"previous",NEXT:"next",IN:"in",OUT:"out",INSERT:"insert",MARK:"mark",DISCONNECT:"disconnect",TOOLBOX:"toolbox",EXIT:"exit",TOGGLE_KEYBOARD_NAV:"toggle_keyboard_nav",MOVE_WS_CURSOR_UP:"move workspace cursor up",MOVE_WS_CURSOR_DOWN:"move workspace cursor down",MOVE_WS_CURSOR_LEFT:"move workspace cursor left",MOVE_WS_CURSOR_RIGHT:"move workspace cursor right"};Blockly.navigation.MARKER_NAME="local_marker_1";Blockly.navigation.getMarker=function(){return Blockly.navigation.getNavigationWorkspace().getMarker(Blockly.navigation.MARKER_NAME)};
Blockly.navigation.getNavigationWorkspace=function(){return Blockly.getMainWorkspace()};Blockly.navigation.focusToolbox_=function(){var a=Blockly.navigation.getNavigationWorkspace().getToolbox();a&&(Blockly.navigation.currentState_=Blockly.navigation.STATE_TOOLBOX,Blockly.navigation.resetFlyout_(!1),Blockly.navigation.getMarker().getCurNode()||Blockly.navigation.markAtCursor_(),a.getSelectedItem()||a.selectItemByPosition(0))};
Blockly.navigation.focusFlyout_=function(){Blockly.navigation.currentState_=Blockly.navigation.STATE_FLYOUT;var a=Blockly.navigation.getNavigationWorkspace();var b=a.getToolbox();a=b?b.getFlyout():a.getFlyout();Blockly.navigation.getMarker().getCurNode()||Blockly.navigation.markAtCursor_();a&&a.getWorkspace()&&(a=a.getWorkspace().getTopBlocks(!0),0<a.length&&(a=a[0],a=Blockly.ASTNode.createStackNode(a),Blockly.navigation.getFlyoutCursor_().setCurNode(a)))};
Blockly.navigation.focusWorkspace_=function(){Blockly.hideChaff();var a=Blockly.navigation.getNavigationWorkspace(),b=a.getCursor(),c=!!a.getToolbox(),d=a.getTopBlocks(!0);Blockly.navigation.resetFlyout_(c);Blockly.navigation.currentState_=Blockly.navigation.STATE_WS;0<d.length?b.setCurNode(Blockly.ASTNode.createTopNode(d[0])):(c=new Blockly.utils.Coordinate(100,100),a=Blockly.ASTNode.createWorkspaceNode(a,c),b.setCurNode(a))};
Blockly.navigation.getNavigationWorkspace=function(){return Blockly.getMainWorkspace()};Blockly.navigation.focusToolbox_=function(a){if(a=a.getToolbox())Blockly.navigation.currentState_=Blockly.navigation.STATE_TOOLBOX,Blockly.navigation.resetFlyout_(!1),Blockly.navigation.getMarker().getCurNode()||Blockly.navigation.markAtCursor_(),a.getSelectedItem()||a.selectItemByPosition(0)};
Blockly.navigation.focusFlyout_=function(a){Blockly.navigation.currentState_=Blockly.navigation.STATE_FLYOUT;var b=a.getToolbox();a=b?b.getFlyout():a.getFlyout();Blockly.navigation.getMarker().getCurNode()||Blockly.navigation.markAtCursor_();a&&a.getWorkspace()&&(a=a.getWorkspace().getTopBlocks(!0),0<a.length&&(a=a[0],a=Blockly.ASTNode.createStackNode(a),Blockly.navigation.getFlyoutCursor_().setCurNode(a)))};
Blockly.navigation.focusWorkspace_=function(a){Blockly.hideChaff();var b=a.getCursor(),c=!!a.getToolbox(),d=a.getTopBlocks(!0);Blockly.navigation.resetFlyout_(c);Blockly.navigation.currentState_=Blockly.navigation.STATE_WS;0<d.length?b.setCurNode(Blockly.ASTNode.createTopNode(d[0])):(c=new Blockly.utils.Coordinate(100,100),a=Blockly.ASTNode.createWorkspaceNode(a,c),b.setCurNode(a))};
Blockly.navigation.getFlyoutCursor_=function(){var a=Blockly.navigation.getNavigationWorkspace(),b=null;a.rendered&&(b=(a=(b=a.getToolbox())?b.getFlyout():a.getFlyout())?a.getWorkspace().getCursor():null);return b};
Blockly.navigation.insertFromFlyout=function(){var a=Blockly.navigation.getNavigationWorkspace(),b=a.getFlyout();if(b&&b.isVisible()){var c=Blockly.navigation.getFlyoutCursor_().getCurNode().getLocation();c.isEnabled()?(b=b.createBlock(c),b.render(),b.setConnectionTracking(!0),a.getCursor().setCurNode(Blockly.ASTNode.createBlockNode(b)),Blockly.navigation.modify_()||Blockly.navigation.warn_("Something went wrong while inserting a block from the flyout."),Blockly.navigation.focusWorkspace_(),a.getCursor().setCurNode(Blockly.ASTNode.createTopNode(b)),
Blockly.navigation.insertFromFlyout=function(a){var b=a.getFlyout();if(b&&b.isVisible()){var c=Blockly.navigation.getFlyoutCursor_().getCurNode().getLocation();c.isEnabled()?(b=b.createBlock(c),b.render(),b.setConnectionTracking(!0),a.getCursor().setCurNode(Blockly.ASTNode.createBlockNode(b)),Blockly.navigation.modify_()||Blockly.navigation.warn_("Something went wrong while inserting a block from the flyout."),Blockly.navigation.focusWorkspace_(a),a.getCursor().setCurNode(Blockly.ASTNode.createTopNode(b)),
Blockly.navigation.removeMark_()):Blockly.navigation.warn_("Can't insert a disabled block.")}else Blockly.navigation.warn_("Trying to insert from the flyout when the flyout does not exist or is not visible")};Blockly.navigation.resetFlyout_=function(a){Blockly.navigation.getFlyoutCursor_()&&(Blockly.navigation.getFlyoutCursor_().hide(),a&&Blockly.navigation.getNavigationWorkspace().getFlyout().hide())};
Blockly.navigation.modifyWarn_=function(){var a=Blockly.navigation.getMarker().getCurNode(),b=Blockly.navigation.getNavigationWorkspace().getCursor().getCurNode();if(!a)return Blockly.navigation.warn_("Cannot insert with no marked node."),!1;if(!b)return Blockly.navigation.warn_("Cannot insert with no cursor node."),!1;a=a.getType();b=b.getType();return a==Blockly.ASTNode.types.FIELD?(Blockly.navigation.warn_("Should not have been able to mark a field."),!1):a==Blockly.ASTNode.types.BLOCK?(Blockly.navigation.warn_("Should not have been able to mark a block."),
!1):a==Blockly.ASTNode.types.STACK?(Blockly.navigation.warn_("Should not have been able to mark a stack."),!1):b==Blockly.ASTNode.types.FIELD?(Blockly.navigation.warn_("Cannot attach a field to anything else."),!1):b==Blockly.ASTNode.types.WORKSPACE?(Blockly.navigation.warn_("Cannot attach a workspace to anything else."),!1):!0};
@@ -429,26 +421,36 @@ Blockly.navigation.connect_=function(a,b){if(!a||!b)return!1;var c=Blockly.navig
c.getErrorMessage(d,a,b));return!1};
Blockly.navigation.insertBlock=function(a,b){switch(b.type){case Blockly.PREVIOUS_STATEMENT:if(Blockly.navigation.connect_(a.nextConnection,b))return!0;break;case Blockly.NEXT_STATEMENT:if(Blockly.navigation.connect_(a.previousConnection,b))return!0;break;case Blockly.INPUT_VALUE:if(Blockly.navigation.connect_(a.outputConnection,b))return!0;break;case Blockly.OUTPUT_VALUE:for(var c=0;c<a.inputList.length;c++){var d=a.inputList[c].connection;if(d&&d.type===Blockly.INPUT_VALUE&&Blockly.navigation.connect_(d,
b))return!0}if(a.outputConnection&&Blockly.navigation.connect_(a.outputConnection,b))return!0}Blockly.navigation.warn_("This block can not be inserted at the marked location.");return!1};
Blockly.navigation.disconnectBlocks_=function(){var a=Blockly.navigation.getNavigationWorkspace(),b=a.getCursor().getCurNode();if(b.isConnection()){var c=b.getLocation();c.isConnected()?(b=c.isSuperior()?c:c.targetConnection,c=c.isSuperior()?c.targetConnection:c,c.getSourceBlock().isShadow()?Blockly.navigation.log_("Cannot disconnect a shadow block"):(b.disconnect(),c.bumpAwayFrom(b),b.getSourceBlock().getRootBlock().bringToFront(),b=Blockly.ASTNode.createConnectionNode(b),a.getCursor().setCurNode(b))):
Blockly.navigation.log_("Cannot disconnect unconnected connection")}else Blockly.navigation.log_("Cannot disconnect blocks when the cursor is not on a connection")};Blockly.navigation.markAtCursor_=function(){Blockly.navigation.getMarker().setCurNode(Blockly.navigation.getNavigationWorkspace().getCursor().getCurNode())};Blockly.navigation.removeMark_=function(){var a=Blockly.navigation.getMarker();a.setCurNode(null);a.hide()};
Blockly.navigation.setState=function(a){Blockly.navigation.currentState_=a};
Blockly.navigation.disconnectBlocks_=function(a){var b=a.getCursor().getCurNode();if(b.isConnection()){var c=b.getLocation();c.isConnected()?(b=c.isSuperior()?c:c.targetConnection,c=c.isSuperior()?c.targetConnection:c,c.getSourceBlock().isShadow()?Blockly.navigation.log_("Cannot disconnect a shadow block"):(b.disconnect(),c.bumpAwayFrom(b),b.getSourceBlock().getRootBlock().bringToFront(),b=Blockly.ASTNode.createConnectionNode(b),a.getCursor().setCurNode(b))):Blockly.navigation.log_("Cannot disconnect unconnected connection")}else Blockly.navigation.log_("Cannot disconnect blocks when the cursor is not on a connection")};
Blockly.navigation.markAtCursor_=function(){Blockly.navigation.getMarker().setCurNode(Blockly.navigation.getNavigationWorkspace().getCursor().getCurNode())};Blockly.navigation.removeMark_=function(){var a=Blockly.navigation.getMarker();a.setCurNode(null);a.hide()};Blockly.navigation.setState=function(a){Blockly.navigation.currentState_=a};
Blockly.navigation.moveCursorOnBlockDelete=function(a){var b=Blockly.navigation.getNavigationWorkspace();if(b&&(b=b.getCursor())){var c=b.getCurNode();c=c?c.getSourceBlock():null;c===a?c.getParent()?(a=c.previousConnection||c.outputConnection)&&b.setCurNode(Blockly.ASTNode.createConnectionNode(a.targetConnection)):b.setCurNode(Blockly.ASTNode.createWorkspaceNode(c.workspace,c.getRelativeToSurfaceXY())):c&&-1<a.getChildren(!1).indexOf(c)&&b.setCurNode(Blockly.ASTNode.createWorkspaceNode(c.workspace,
c.getRelativeToSurfaceXY()))}};Blockly.navigation.moveCursorOnBlockMutation=function(a){var b=Blockly.navigation.getNavigationWorkspace().getCursor();if(b){var c=b.getCurNode();c=c?c.getSourceBlock():null;c===a&&b.setCurNode(Blockly.ASTNode.createBlockNode(c))}};Blockly.navigation.enableKeyboardAccessibility=function(){var a=Blockly.navigation.getNavigationWorkspace();a.keyboardAccessibilityMode||(a.keyboardAccessibilityMode=!0,Blockly.navigation.focusWorkspace_())};
c.getRelativeToSurfaceXY()))}};Blockly.navigation.moveCursorOnBlockMutation=function(a){var b=Blockly.navigation.getNavigationWorkspace().getCursor();if(b){var c=b.getCurNode();c=c?c.getSourceBlock():null;c===a&&b.setCurNode(Blockly.ASTNode.createBlockNode(c))}};Blockly.navigation.enableKeyboardAccessibility=function(){var a=Blockly.navigation.getNavigationWorkspace();a.keyboardAccessibilityMode||(a.keyboardAccessibilityMode=!0,Blockly.navigation.focusWorkspace_(a))};
Blockly.navigation.disableKeyboardAccessibility=function(){var a=Blockly.navigation.getNavigationWorkspace();a.keyboardAccessibilityMode&&(a.keyboardAccessibilityMode=!1,a.getCursor().hide(),Blockly.navigation.getMarker().hide(),Blockly.navigation.getFlyoutCursor_()&&Blockly.navigation.getFlyoutCursor_().hide())};Blockly.navigation.log_=function(a){Blockly.navigation.loggingCallback?Blockly.navigation.loggingCallback("log",a):console.log(a)};
Blockly.navigation.warn_=function(a){Blockly.navigation.loggingCallback?Blockly.navigation.loggingCallback("warn",a):console.warn(a)};Blockly.navigation.error_=function(a){Blockly.navigation.loggingCallback?Blockly.navigation.loggingCallback("error",a):console.error(a)};Blockly.navigation.onKeyPress=function(a){a=Blockly.user.keyMap.serializeKeyEvent(a);return(a=Blockly.user.keyMap.getActionByKeyCode(a))?Blockly.navigation.onBlocklyAction(a):!1};
Blockly.navigation.onBlocklyAction=function(a){var b=Blockly.navigation.getNavigationWorkspace(),c=b.options.readOnly,d=!1;b.keyboardAccessibilityMode?c?-1<Blockly.navigation.READONLY_ACTION_LIST.indexOf(a)&&(d=Blockly.navigation.handleActions_(a)):d=Blockly.navigation.handleActions_(a):a.name===Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV&&(Blockly.navigation.enableKeyboardAccessibility(),d=!0);return d};
Blockly.navigation.handleActions_=function(a){return a.name==Blockly.navigation.actionNames.TOOLBOX||Blockly.navigation.currentState_==Blockly.navigation.STATE_TOOLBOX?Blockly.navigation.toolboxOnAction_(a):a.name==Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV?(Blockly.navigation.disableKeyboardAccessibility(),!0):Blockly.navigation.currentState_==Blockly.navigation.STATE_WS?Blockly.navigation.workspaceOnAction_(a):Blockly.navigation.currentState_==Blockly.navigation.STATE_FLYOUT?Blockly.navigation.flyoutOnAction_(a):
!1};Blockly.navigation.flyoutOnAction_=function(a){var b=Blockly.navigation.getNavigationWorkspace(),c=b.getToolbox();if((b=c?c.getFlyout():b.getFlyout())&&b.onBlocklyAction(a))return!0;switch(a.name){case Blockly.navigation.actionNames.OUT:return Blockly.navigation.focusToolbox_(),!0;case Blockly.navigation.actionNames.MARK:return Blockly.navigation.insertFromFlyout(),!0;case Blockly.navigation.actionNames.EXIT:return Blockly.navigation.focusWorkspace_(),!0;default:return!1}};
Blockly.navigation.toolboxOnAction_=function(a){var b=Blockly.navigation.getNavigationWorkspace(),c=b.getToolbox();return c&&"function"==typeof c.onBlocklyAction&&c.onBlocklyAction(a)?!0:a.name===Blockly.navigation.actionNames.TOOLBOX?(b.getToolbox()?Blockly.navigation.focusToolbox_():Blockly.navigation.focusFlyout_(),!0):a.name===Blockly.navigation.actionNames.IN?(Blockly.navigation.focusFlyout_(),!0):a.name===Blockly.navigation.actionNames.EXIT?(Blockly.navigation.focusWorkspace_(),!0):!1};
Blockly.navigation.moveWSCursor_=function(a,b){var c=Blockly.navigation.getNavigationWorkspace(),d=c.getCursor(),e=c.getCursor().getCurNode();if(e.getType()!==Blockly.ASTNode.types.WORKSPACE)return!1;e=e.getWsCoordinate();d.setCurNode(Blockly.ASTNode.createWorkspaceNode(c,new Blockly.utils.Coordinate(a*Blockly.navigation.WS_MOVE_DISTANCE+e.x,b*Blockly.navigation.WS_MOVE_DISTANCE+e.y)));return!0};
Blockly.navigation.workspaceOnAction_=function(a){if(Blockly.navigation.getNavigationWorkspace().getCursor().onBlocklyAction(a))return!0;switch(a.name){case Blockly.navigation.actionNames.INSERT:return Blockly.navigation.modify_(),!0;case Blockly.navigation.actionNames.MARK:return Blockly.navigation.handleEnterForWS_(),!0;case Blockly.navigation.actionNames.DISCONNECT:return Blockly.navigation.disconnectBlocks_(),!0;case Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP:return Blockly.navigation.moveWSCursor_(0,
-1);case Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN:return Blockly.navigation.moveWSCursor_(0,1);case Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT:return Blockly.navigation.moveWSCursor_(-1,0);case Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT:return Blockly.navigation.moveWSCursor_(1,0);default:return!1}};
Blockly.navigation.handleEnterForWS_=function(){var a=Blockly.navigation.getNavigationWorkspace().getCursor().getCurNode(),b=a.getType();b==Blockly.ASTNode.types.FIELD?a.getLocation().showEditor():a.isConnection()||b==Blockly.ASTNode.types.WORKSPACE?Blockly.navigation.markAtCursor_():b==Blockly.ASTNode.types.BLOCK?Blockly.navigation.warn_("Cannot mark a block."):b==Blockly.ASTNode.types.STACK&&Blockly.navigation.warn_("Cannot mark a stack.")};
Blockly.navigation.ACTION_PREVIOUS=new Blockly.Action(Blockly.navigation.actionNames.PREVIOUS,"Go to the previous location.");Blockly.navigation.ACTION_OUT=new Blockly.Action(Blockly.navigation.actionNames.OUT,"Go to the parent of the current location.");Blockly.navigation.ACTION_NEXT=new Blockly.Action(Blockly.navigation.actionNames.NEXT,"Go to the next location.");Blockly.navigation.ACTION_IN=new Blockly.Action(Blockly.navigation.actionNames.IN,"Go to the first child of the current location.");
Blockly.navigation.ACTION_INSERT=new Blockly.Action(Blockly.navigation.actionNames.INSERT,"Connect the current location to the marked location.");Blockly.navigation.ACTION_MARK=new Blockly.Action(Blockly.navigation.actionNames.MARK,"Mark the current location.");Blockly.navigation.ACTION_DISCONNECT=new Blockly.Action(Blockly.navigation.actionNames.DISCONNECT,"Disconnect the block at the current location from its parent.");
Blockly.navigation.ACTION_TOOLBOX=new Blockly.Action(Blockly.navigation.actionNames.TOOLBOX,"Open the toolbox.");Blockly.navigation.ACTION_EXIT=new Blockly.Action(Blockly.navigation.actionNames.EXIT,"Close the current modal, such as a toolbox or field editor.");Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV=new Blockly.Action(Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV,"Turns on and off keyboard navigation.");
Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT=new Blockly.Action(Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT,"Move the workspace cursor to the lefts.");Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT=new Blockly.Action(Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT,"Move the workspace cursor to the right.");Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP=new Blockly.Action(Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP,"Move the workspace cursor up.");
Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN=new Blockly.Action(Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN,"Move the workspace cursor down.");Blockly.navigation.READONLY_ACTION_LIST=[Blockly.navigation.ACTION_PREVIOUS,Blockly.navigation.ACTION_OUT,Blockly.navigation.ACTION_IN,Blockly.navigation.ACTION_NEXT,Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV];Blockly.Gesture=function(a,b){this.mouseDownXY_=null;this.currentDragDeltaXY_=new Blockly.utils.Coordinate(0,0);this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=this.startBubble_=null;this.creatorWorkspace_=b;this.isDraggingBubble_=this.isDraggingBlock_=this.isDraggingWorkspace_=this.hasExceededDragRadius_=!1;this.mostRecentEvent_=a;this.flyout_=this.workspaceDragger_=this.blockDragger_=this.bubbleDragger_=this.onUpWrapper_=this.onMoveWrapper_=null;this.isEnding_=this.hasStarted_=
Blockly.navigation.warn_=function(a){Blockly.navigation.loggingCallback?Blockly.navigation.loggingCallback("warn",a):console.warn(a)};Blockly.navigation.error_=function(a){Blockly.navigation.loggingCallback?Blockly.navigation.loggingCallback("error",a):console.error(a)};
Blockly.navigation.moveWSCursor_=function(a,b,c){var d=a.getCursor(),e=a.getCursor().getCurNode();if(e.getType()!==Blockly.ASTNode.types.WORKSPACE)return!1;e=e.getWsCoordinate();d.setCurNode(Blockly.ASTNode.createWorkspaceNode(a,new Blockly.utils.Coordinate(b*Blockly.navigation.WS_MOVE_DISTANCE+e.x,c*Blockly.navigation.WS_MOVE_DISTANCE+e.y)));return!0};
Blockly.navigation.handleEnterForWS_=function(a){a=a.getCursor().getCurNode();var b=a.getType();b==Blockly.ASTNode.types.FIELD?a.getLocation().showEditor():a.isConnection()||b==Blockly.ASTNode.types.WORKSPACE?Blockly.navigation.markAtCursor_():b==Blockly.ASTNode.types.BLOCK?Blockly.navigation.warn_("Cannot mark a block."):b==Blockly.ASTNode.types.STACK&&Blockly.navigation.warn_("Cannot mark a stack.")};
Blockly.navigation.registerPrevious=function(){var a={name:Blockly.navigation.actionNames.PREVIOUS,preconditionFn:function(b){return b.keyboardAccessibilityMode},callback:function(b,c,d){c=b.getToolbox();switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return b.getCursor().onBlocklyAction(d);case Blockly.navigation.STATE_FLYOUT:return b=c?c.getFlyout():b.getFlyout(),!(!b||!b.onBlocklyAction(d));case Blockly.navigation.STATE_TOOLBOX:return c&&"function"==typeof c.onBlocklyAction?
c.onBlocklyAction(d):!1;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.W,a.name)};
Blockly.navigation.registerOut=function(){var a={name:Blockly.navigation.actionNames.OUT,preconditionFn:function(b){return b.keyboardAccessibilityMode},callback:function(b,c,d){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return b.getCursor().onBlocklyAction(d);case Blockly.navigation.STATE_FLYOUT:return Blockly.navigation.focusToolbox_(b),!0;case Blockly.navigation.STATE_TOOLBOX:return(b=b.getToolbox())&&"function"==typeof b.onBlocklyAction?b.onBlocklyAction(d):!1;default:return!1}}};
Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.A,a.name)};
Blockly.navigation.registerNext=function(){var a={name:Blockly.navigation.actionNames.NEXT,preconditionFn:function(b){return b.keyboardAccessibilityMode},callback:function(b,c,d){c=b.getToolbox();switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return b.getCursor().onBlocklyAction(d);case Blockly.navigation.STATE_FLYOUT:return b=c?c.getFlyout():b.getFlyout(),!(!b||!b.onBlocklyAction(d));case Blockly.navigation.STATE_TOOLBOX:return c&&"function"==typeof c.onBlocklyAction?c.onBlocklyAction(d):
!1;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.S,a.name)};
Blockly.navigation.registerIn=function(){var a={name:Blockly.navigation.actionNames.IN,preconditionFn:function(b){return b.keyboardAccessibilityMode},callback:function(b,c,d){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return b.getCursor().onBlocklyAction(d);case Blockly.navigation.STATE_TOOLBOX:return(c=b.getToolbox())&&"function"==typeof c.onBlocklyAction&&c.onBlocklyAction(d)||Blockly.navigation.focusFlyout_(b),!0;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);
Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.D,a.name)};
Blockly.navigation.registerInsert=function(){var a={name:Blockly.navigation.actionNames.INSERT,preconditionFn:function(b){return b.keyboardAccessibilityMode&&!b.options.readOnly},callback:function(){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return Blockly.navigation.modify_();default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.I,a.name)};
Blockly.navigation.registerMark=function(){var a={name:Blockly.navigation.actionNames.MARK,preconditionFn:function(b){return b.keyboardAccessibilityMode&&!b.options.readOnly},callback:function(b){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return Blockly.navigation.handleEnterForWS_(b),!0;case Blockly.navigation.STATE_FLYOUT:return Blockly.navigation.insertFromFlyout(b),!0;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.ENTER,
a.name)};Blockly.navigation.registerDisconnect=function(){var a={name:Blockly.navigation.actionNames.DISCONNECT,preconditionFn:function(b){return b.keyboardAccessibilityMode&&!b.options.readOnly},callback:function(b){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return Blockly.navigation.disconnectBlocks_(b),!0;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.X,a.name)};
Blockly.navigation.registerToolboxFocus=function(){var a={name:Blockly.navigation.actionNames.TOOLBOX,preconditionFn:function(b){return b.keyboardAccessibilityMode&&!b.options.readOnly},callback:function(b){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_WS:return b.getToolbox()?Blockly.navigation.focusToolbox_(b):Blockly.navigation.focusFlyout_(b),!0;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.T,
a.name)};
Blockly.navigation.registerExit=function(){var a={name:Blockly.navigation.actionNames.EXIT,preconditionFn:function(b){return b.keyboardAccessibilityMode},callback:function(b){switch(Blockly.navigation.currentState_){case Blockly.navigation.STATE_FLYOUT:return Blockly.navigation.focusWorkspace_(b),!0;case Blockly.navigation.STATE_TOOLBOX:return Blockly.navigation.focusWorkspace_(b),!0;default:return!1}}};Blockly.ShortcutRegistry.registry.register(a,!0);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.ESC,a.name,
!0);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.E,a.name,!0)};
Blockly.navigation.registerToggleKeyboardNav=function(){var a={name:Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV,callback:function(c){c.keyboardAccessibilityMode?Blockly.navigation.disableKeyboardAccessibility():Blockly.navigation.enableKeyboardAccessibility();return!0}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.K,[Blockly.utils.KeyCodes.CTRL,Blockly.utils.KeyCodes.SHIFT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,
a.name)};Blockly.navigation.registerWorkspaceMoveLeft=function(){var a={name:Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT,preconditionFn:function(c){return c.keyboardAccessibilityMode&&!c.options.readOnly},callback:function(c){return Blockly.navigation.moveWSCursor_(c,-1,0)}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.A,[Blockly.utils.KeyCodes.SHIFT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.navigation.registerWorkspaceMoveRight=function(){var a={name:Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT,preconditionFn:function(c){return c.keyboardAccessibilityMode&&!c.options.readOnly},callback:function(c){return Blockly.navigation.moveWSCursor_(c,1,0)}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.D,[Blockly.utils.KeyCodes.SHIFT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.navigation.registerWorkspaceMoveUp=function(){var a={name:Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP,preconditionFn:function(c){return c.keyboardAccessibilityMode&&!c.options.readOnly},callback:function(c){return Blockly.navigation.moveWSCursor_(c,0,-1)}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.W,[Blockly.utils.KeyCodes.SHIFT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.navigation.registerWorkspaceMoveDown=function(){var a={name:Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN,preconditionFn:function(c){return c.keyboardAccessibilityMode&&!c.options.readOnly},callback:function(c){return Blockly.navigation.moveWSCursor_(c,0,1)}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.S,[Blockly.utils.KeyCodes.SHIFT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.navigation.registerNavigationShortcuts=function(){Blockly.navigation.registerIn();Blockly.navigation.registerNext();Blockly.navigation.registerOut();Blockly.navigation.registerPrevious();Blockly.navigation.registerWorkspaceMoveDown();Blockly.navigation.registerWorkspaceMoveLeft();Blockly.navigation.registerWorkspaceMoveRight();Blockly.navigation.registerWorkspaceMoveUp();Blockly.navigation.registerDisconnect();Blockly.navigation.registerExit();Blockly.navigation.registerInsert();Blockly.navigation.registerMark();
Blockly.navigation.registerToggleKeyboardNav();Blockly.navigation.registerToolboxFocus()};Blockly.Gesture=function(a,b){this.mouseDownXY_=null;this.currentDragDeltaXY_=new Blockly.utils.Coordinate(0,0);this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=this.startBubble_=null;this.creatorWorkspace_=b;this.isDraggingBubble_=this.isDraggingBlock_=this.isDraggingWorkspace_=this.hasExceededDragRadius_=!1;this.mostRecentEvent_=a;this.flyout_=this.workspaceDragger_=this.blockDragger_=this.bubbleDragger_=this.onUpWrapper_=this.onMoveWrapper_=null;this.isEnding_=this.hasStarted_=
this.calledUpdateIsDragging_=!1;this.healStack_=!Blockly.DRAG_STACK};Blockly.Gesture.prototype.dispose=function(){Blockly.Touch.clearTouchIdentifier();Blockly.Tooltip.unblock();this.creatorWorkspace_.clearGesture();this.onMoveWrapper_&&Blockly.unbindEvent_(this.onMoveWrapper_);this.onUpWrapper_&&Blockly.unbindEvent_(this.onUpWrapper_);this.blockDragger_&&this.blockDragger_.dispose();this.workspaceDragger_&&this.workspaceDragger_.dispose();this.bubbleDragger_&&this.bubbleDragger_.dispose()};
Blockly.Gesture.prototype.updateFromEvent_=function(a){var b=new Blockly.utils.Coordinate(a.clientX,a.clientY);this.updateDragDelta_(b)&&(this.updateIsDragging_(),Blockly.longStop_());this.mostRecentEvent_=a};
Blockly.Gesture.prototype.updateDragDelta_=function(a){this.currentDragDeltaXY_=Blockly.utils.Coordinate.difference(a,this.mouseDownXY_);return this.hasExceededDragRadius_?!1:this.hasExceededDragRadius_=Blockly.utils.Coordinate.magnitude(this.currentDragDeltaXY_)>(this.flyout_?Blockly.FLYOUT_DRAG_RADIUS:Blockly.DRAG_RADIUS)};
@@ -466,10 +468,10 @@ Blockly.Gesture.prototype.handleUp=function(a){this.updateFromEvent_(a);Blockly.
this.isBlockClick_()?this.doBlockClick_():this.isWorkspaceClick_()&&this.doWorkspaceClick_(a),a.preventDefault(),a.stopPropagation(),this.dispose())};
Blockly.Gesture.prototype.cancel=function(){this.isEnding_||(Blockly.longStop_(),this.isDraggingBubble_?this.bubbleDragger_.endBubbleDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.endBlockDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingWorkspace_&&this.workspaceDragger_.endDrag(this.currentDragDeltaXY_),this.dispose())};
Blockly.Gesture.prototype.handleRightClick=function(a){this.targetBlock_?(this.bringBlockToFront_(),Blockly.hideChaff(!!this.flyout_),this.targetBlock_.showContextMenu(a)):this.startBubble_?this.startBubble_.showContextMenu(a):this.startWorkspace_&&!this.flyout_&&(Blockly.hideChaff(),this.startWorkspace_.showContextMenu(a));a.preventDefault();a.stopPropagation();this.dispose()};
Blockly.Gesture.prototype.handleWsStart=function(a,b){if(this.hasStarted_)throw Error("Tried to call gesture.handleWsStart, but the gesture had already been started.");this.setStartWorkspace_(b);this.mostRecentEvent_=a;this.doStart(a);this.startWorkspace_.keyboardAccessibilityMode&&Blockly.navigation.setState(Blockly.navigation.STATE_WS)};Blockly.Gesture.prototype.fireWorkspaceClick_=function(a){var b=new Blockly.Events.Ui(null,"click",null,"workspace");b.workspaceId=a.id;Blockly.Events.fire(b)};
Blockly.Gesture.prototype.handleWsStart=function(a,b){if(this.hasStarted_)throw Error("Tried to call gesture.handleWsStart, but the gesture had already been started.");this.setStartWorkspace_(b);this.mostRecentEvent_=a;this.doStart(a);this.startWorkspace_.keyboardAccessibilityMode&&Blockly.navigation.setState(Blockly.navigation.STATE_WS)};Blockly.Gesture.prototype.fireWorkspaceClick_=function(a){a=new Blockly.Events.Click(null,a.id,"workspace");Blockly.Events.fire(a)};
Blockly.Gesture.prototype.handleFlyoutStart=function(a,b){if(this.hasStarted_)throw Error("Tried to call gesture.handleFlyoutStart, but the gesture had already been started.");this.setStartFlyout_(b);this.handleWsStart(a,b.getWorkspace())};Blockly.Gesture.prototype.handleBlockStart=function(a,b){if(this.hasStarted_)throw Error("Tried to call gesture.handleBlockStart, but the gesture had already been started.");this.setStartBlock(b);this.mostRecentEvent_=a};
Blockly.Gesture.prototype.handleBubbleStart=function(a,b){if(this.hasStarted_)throw Error("Tried to call gesture.handleBubbleStart, but the gesture had already been started.");this.setStartBubble(b);this.mostRecentEvent_=a};Blockly.Gesture.prototype.doBubbleClick_=function(){this.startBubble_.setFocus&&this.startBubble_.setFocus();this.startBubble_.select&&this.startBubble_.select()};Blockly.Gesture.prototype.doFieldClick_=function(){this.startField_.showEditor(this.mostRecentEvent_);this.bringBlockToFront_()};
Blockly.Gesture.prototype.doBlockClick_=function(){this.flyout_&&this.flyout_.autoClose?this.targetBlock_.isEnabled()&&(Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.flyout_.createBlock(this.targetBlock_).scheduleSnapAndBump()):Blockly.Events.fire(new Blockly.Events.Ui(this.startBlock_,"click",void 0,"block"));this.bringBlockToFront_();Blockly.Events.setGroup(!1)};
Blockly.Gesture.prototype.doBlockClick_=function(){if(this.flyout_&&this.flyout_.autoClose)this.targetBlock_.isEnabled()&&(Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.flyout_.createBlock(this.targetBlock_).scheduleSnapAndBump());else{var a=new Blockly.Events.Click(this.startBlock_,this.startWorkspace_.id,"block");Blockly.Events.fire(a)}this.bringBlockToFront_();Blockly.Events.setGroup(!1)};
Blockly.Gesture.prototype.doWorkspaceClick_=function(a){var b=this.creatorWorkspace_;a.shiftKey&&b.keyboardAccessibilityMode?(a=new Blockly.utils.Coordinate(a.clientX,a.clientY),a=Blockly.utils.screenToWsCoordinates(b,a),a=Blockly.ASTNode.createWorkspaceNode(b,a),b.getCursor().setCurNode(a)):Blockly.selected&&Blockly.selected.unselect();this.fireWorkspaceClick_(this.startWorkspace_||b)};Blockly.Gesture.prototype.bringBlockToFront_=function(){this.targetBlock_&&!this.flyout_&&this.targetBlock_.bringToFront()};
Blockly.Gesture.prototype.setStartField=function(a){if(this.hasStarted_)throw Error("Tried to call gesture.setStartField, but the gesture had already been started.");this.startField_||(this.startField_=a)};Blockly.Gesture.prototype.setStartBubble=function(a){this.startBubble_||(this.startBubble_=a)};Blockly.Gesture.prototype.setStartBlock=function(a){this.startBlock_||this.startBubble_||(this.startBlock_=a,a.isInFlyout&&a!=a.getRootBlock()?this.setTargetBlock_(a.getRootBlock()):this.setTargetBlock_(a))};
Blockly.Gesture.prototype.setTargetBlock_=function(a){a.isShadow()?this.setTargetBlock_(a.getParent()):this.targetBlock_=a};Blockly.Gesture.prototype.setStartWorkspace_=function(a){this.startWorkspace_||(this.startWorkspace_=a)};Blockly.Gesture.prototype.setStartFlyout_=function(a){this.flyout_||(this.flyout_=a)};Blockly.Gesture.prototype.isBubbleClick_=function(){return!!this.startBubble_&&!this.hasExceededDragRadius_};
@@ -485,18 +487,17 @@ Blockly.Field.prototype.dispose=function(){Blockly.DropDownDiv.hideIfOwner(this)
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){Blockly.utils.deprecation.warn("Field.prototype.classValidator","May 2019","December 2020","Blockly.Field.prototype.doClassValidation_");return a};
Blockly.Field.prototype.callValidator=function(a){Blockly.utils.deprecation.warn("Field.prototype.callValidator","May 2019","December 2020");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(){Blockly.utils.deprecation.warn("Field.prototype.updateWidth","May 2019","December 2020","Blockly.Field.prototype.updateSize_ or Blockly.utils.dom.getTextWidth");this.updateSize_()};
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.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.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 new Blockly.utils.Rect(c.y,c.y+
a,c.x,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){Blockly.utils.deprecation.warn("Field.prototype.setText","May 2019","December 2020","Blockly.Field.prototype.setValue");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.sourceBlock_;if(!b||!b.disposed){var c=this.getValue();c!==a&&(b&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(b,"field",this.name||null,c,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.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.sourceBlock_;if(!b||!b.disposed){var c=this.getValue();c===a?this.doValueUpdate_(a):(b&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(b,"field",this.name||null,c,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};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){a||""===a||(a=this.sourceBlock_);var b=this.getClickTarget_();b?b.tooltip=a:this.tooltip_=a};Blockly.Field.prototype.getTooltip=function(){var a=this.getClickTarget_();return a?Blockly.Tooltip.getTooltipOfObject(a):Blockly.Tooltip.getTooltipOfObject({tooltip:this.tooltip_})};
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;d<b.inputList.length;d++)for(var e=c[d],f=e.fieldRow,g=0;g<f.length;g++)if(f[g]===this){a=e;break}return a};
Blockly.Field.prototype.getFlipRtl=function(){return!1};Blockly.Field.prototype.isTabNavigable=function(){return!1};Blockly.Field.prototype.onBlocklyAction=function(a){return!1};Blockly.Field.prototype.setCursorSvg=function(a){a?(this.fieldGroup_.appendChild(a),this.cursorSvg_=a):this.cursorSvg_=null};Blockly.Field.prototype.setMarkerSvg=function(a){a?(this.fieldGroup_.appendChild(a),this.markerSvg_=a):this.markerSvg_=null};
@@ -516,7 +517,7 @@ Blockly.Block.prototype.dispose=function(a){if(this.workspace){this.onchangeWrap
Blockly.Block.prototype.unplugFromRow_=function(a){var b=null;this.outputConnection.isConnected()&&(b=this.outputConnection.targetConnection,this.outputConnection.disconnect());if(b&&a&&(a=this.getOnlyValueConnection_())&&a.isConnected()&&!a.targetBlock().isShadow())if(a=a.targetConnection,a.disconnect(),this.workspace.connectionChecker.canConnect(a,b,!1))b.connect(a);else a.onFailedConnect(b)};
Blockly.Block.prototype.getOnlyValueConnection_=function(){for(var a=null,b=0;b<this.inputList.length;b++){var c=this.inputList[b].connection;if(c&&c.type==Blockly.INPUT_VALUE&&c.targetConnection){if(a)return null;a=c}}return a};
Blockly.Block.prototype.unplugFromStack_=function(a){var b=null;this.previousConnection.isConnected()&&(b=this.previousConnection.targetConnection,this.previousConnection.disconnect());var c=this.getNextBlock();a&&c&&!c.isShadow()&&(a=this.nextConnection.targetConnection,a.disconnect(),b&&this.workspace.connectionChecker.canConnect(b,a,!1)&&b.connect(a))};
Blockly.Block.prototype.getConnections_=function(a){a=[];this.outputConnection&&a.push(this.outputConnection);this.previousConnection&&a.push(this.previousConnection);this.nextConnection&&a.push(this.nextConnection);for(var b=0,c;c=this.inputList[b];b++)c.connection&&a.push(c.connection);return a};Blockly.Block.prototype.lastConnectionInStack=function(){for(var a=this.nextConnection;a;){var b=a.targetBlock();if(!b)return a;a=b.nextConnection}return null};Blockly.Block.prototype.bumpNeighbours=function(){console.warn("Not expected to reach Block.bumpNeighbours function. BlockSvg.bumpNeighbours was expected to be called instead.")};
Blockly.Block.prototype.getConnections_=function(a){a=[];this.outputConnection&&a.push(this.outputConnection);this.previousConnection&&a.push(this.previousConnection);this.nextConnection&&a.push(this.nextConnection);for(var b=0,c;c=this.inputList[b];b++)c.connection&&a.push(c.connection);return a};Blockly.Block.prototype.lastConnectionInStack=function(){for(var a=this.nextConnection;a;){var b=a.targetBlock();if(!b)return a;a=b.nextConnection}return null};Blockly.Block.prototype.bumpNeighbours=function(){};
Blockly.Block.prototype.getParent=function(){return this.parentBlock_};Blockly.Block.prototype.getInputWithBlock=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&c.connection.targetBlock()==a)return c;return null};Blockly.Block.prototype.getSurroundParent=function(){var a=this;do{var b=a;a=a.getParent();if(!a)return null}while(a.getNextBlock()==b);return a};Blockly.Block.prototype.getNextBlock=function(){return this.nextConnection&&this.nextConnection.targetBlock()};
Blockly.Block.prototype.getPreviousBlock=function(){return this.previousConnection&&this.previousConnection.targetBlock()};Blockly.Block.prototype.getFirstStatementConnection=function(){for(var a=0,b;b=this.inputList[a];a++)if(b.connection&&b.connection.type==Blockly.NEXT_STATEMENT)return b.connection;return null};Blockly.Block.prototype.getRootBlock=function(){var a=this;do{var b=a;a=b.parentBlock_}while(a);return b};
Blockly.Block.prototype.getTopStackBlock=function(){var a=this;do var b=a.getPreviousBlock();while(b&&b.getNextBlock()==a&&(a=b));return a};Blockly.Block.prototype.getChildren=function(a){if(!a)return this.childBlocks_;a=[];for(var b=0,c;c=this.inputList[b];b++)c.connection&&(c=c.connection.targetBlock())&&a.push(c);(b=this.getNextBlock())&&a.push(b);return a};
@@ -535,8 +536,8 @@ this.previousConnection=null}};Blockly.Block.prototype.setNextStatement=function
Blockly.Block.prototype.setOutput=function(a,b){if(a){void 0===b&&(b=null);if(!this.outputConnection){if(this.previousConnection)throw Error("Remove previous connection prior to adding output connection.");this.outputConnection=this.makeConnection_(Blockly.OUTPUT_VALUE)}this.outputConnection.setCheck(b)}else if(this.outputConnection){if(this.outputConnection.isConnected())throw Error("Must disconnect output value before removing connection.");this.outputConnection.dispose();this.outputConnection=
null}};Blockly.Block.prototype.setInputsInline=function(a){this.inputsInline!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"inline",null,this.inputsInline,a)),this.inputsInline=a)};
Blockly.Block.prototype.getInputsInline=function(){if(void 0!=this.inputsInline)return this.inputsInline;for(var a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.DUMMY_INPUT&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!1;for(a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.INPUT_VALUE&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!0;return!1};Blockly.Block.prototype.setOutputShape=function(a){this.outputShape_=a};
Blockly.Block.prototype.getOutputShape=function(){return this.outputShape_};Blockly.Block.prototype.setDisabled=function(a){Blockly.utils.deprecation.warn("Block.prototype.setDisabled","May 2019","May 2020","Block.prototype.setEnabled");this.setEnabled(!a)};Blockly.Block.prototype.isEnabled=function(){return!this.disabled};Blockly.Block.prototype.setEnabled=function(a){this.isEnabled()!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"disabled",null,this.disabled,!a)),this.disabled=!a)};
Blockly.Block.prototype.getInheritedDisabled=function(){for(var a=this.getSurroundParent();a;){if(a.disabled)return!0;a=a.getSurroundParent()}return!1};Blockly.Block.prototype.isCollapsed=function(){return this.collapsed_};Blockly.Block.prototype.setCollapsed=function(a){this.collapsed_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"collapsed",null,this.collapsed_,a)),this.collapsed_=a)};
Blockly.Block.prototype.getOutputShape=function(){return this.outputShape_};Blockly.Block.prototype.isEnabled=function(){return!this.disabled};Blockly.Block.prototype.setEnabled=function(a){this.isEnabled()!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"disabled",null,this.disabled,!a)),this.disabled=!a)};Blockly.Block.prototype.getInheritedDisabled=function(){for(var a=this.getSurroundParent();a;){if(a.disabled)return!0;a=a.getSurroundParent()}return!1};
Blockly.Block.prototype.isCollapsed=function(){return this.collapsed_};Blockly.Block.prototype.setCollapsed=function(a){this.collapsed_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"collapsed",null,this.collapsed_,a)),this.collapsed_=a)};
Blockly.Block.prototype.toString=function(a,b){function c(l){var m=l.getCheck();!m&&l.targetConnection&&(m=l.targetConnection.getCheck());return!!m&&(-1!=m.indexOf("Boolean")||-1!=m.indexOf("Number"))}function d(){g&&g.getType()==h.getType()&&g.getLocation()==h.getLocation()&&(g=null)}var e=[];b=b||"?";var f=Blockly.ASTNode.NAVIGATE_ALL_FIELDS;Blockly.ASTNode.NAVIGATE_ALL_FIELDS=!0;for(var g=Blockly.ASTNode.createBlockNode(this),h=g;g;){switch(g.getType()){case Blockly.ASTNode.types.INPUT:var k=g.getLocation();
g.in()?c(k)&&e.push("("):e.push(b);break;case Blockly.ASTNode.types.FIELD:k=g.getLocation(),k.name!=Blockly.Block.COLLAPSED_FIELD_NAME&&e.push(k.getText())}k=g;g=k.in()||k.next();if(!g){g=k.out();for(d();g&&!g.next();)g=g.out(),d(),g&&g.getType()==Blockly.ASTNode.types.INPUT&&c(g.getLocation())&&e.push(")");g&&(g=g.next())}}Blockly.ASTNode.NAVIGATE_ALL_FIELDS=f;b=2;for(f=e.length;b<f;b++)"("==e[b-2]&&")"==e[b]&&(e[b-2]=e[b-1],e.splice(b-1,2),f-=2);e=e.join(" ").replace(/(\() | (\))/gmi,"$1$2").trim()||
"???";a&&e.length>a&&(e=e.substring(0,a-3)+"...");return e};Blockly.Block.prototype.appendValueInput=function(a){return this.appendInput_(Blockly.INPUT_VALUE,a)};Blockly.Block.prototype.appendStatementInput=function(a){return this.appendInput_(Blockly.NEXT_STATEMENT,a)};Blockly.Block.prototype.appendDummyInput=function(a){return this.appendInput_(Blockly.DUMMY_INPUT,a||"")};
@@ -556,7 +557,9 @@ Blockly.Block.prototype.getCommentText=function(){return this.commentModel.text}
Blockly.Block.prototype.moveBy=function(a,b){if(this.parentBlock_)throw Error("Block has parent.");var c=new Blockly.Events.BlockMove(this);this.xy_.translate(a,b);c.recordNew();Blockly.Events.fire(c)};Blockly.Block.prototype.makeConnection_=function(a){return new Blockly.Connection(this,a)};
Blockly.Block.prototype.allInputsFilled=function(a){void 0===a&&(a=!0);if(!a&&this.isShadow())return!1;for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&(c=c.connection.targetBlock(),!c||!c.allInputsFilled(a)))return!1;return(b=this.getNextBlock())?b.allInputsFilled(a):!0};Blockly.Block.prototype.toDevString=function(){var a=this.type?'"'+this.type+'" block':"Block";this.id&&(a+=' (id="'+this.id+'")');return a};Blockly.blockRendering={};Blockly.blockRendering.IPathObject=function(a,b){};Blockly.utils.aria={};Blockly.utils.aria.ARIA_PREFIX_="aria-";Blockly.utils.aria.ROLE_ATTRIBUTE_="role";Blockly.utils.aria.Role={GRID:"grid",GRIDCELL:"gridcell",GROUP:"group",LISTBOX:"listbox",MENU:"menu",MENUITEM:"menuitem",MENUITEMCHECKBOX:"menuitemcheckbox",OPTION:"option",PRESENTATION:"presentation",ROW:"row",TREE:"tree",TREEITEM:"treeitem"};
Blockly.utils.aria.State={ACTIVEDESCENDANT:"activedescendant",COLCOUNT:"colcount",DISABLED:"disabled",EXPANDED:"expanded",INVALID:"invalid",LABEL:"label",LABELLEDBY:"labelledby",LEVEL:"level",ORIENTATION:"orientation",POSINSET:"posinset",ROWCOUNT:"rowcount",SELECTED:"selected",SETSIZE:"setsize",VALUEMAX:"valuemax",VALUEMIN:"valuemin"};Blockly.utils.aria.setRole=function(a,b){a.setAttribute(Blockly.utils.aria.ROLE_ATTRIBUTE_,b)};
Blockly.utils.aria.setState=function(a,b,c){Array.isArray(c)&&(c=c.join(" "));a.setAttribute(Blockly.utils.aria.ARIA_PREFIX_+b,c)};Blockly.Menu=function(){this.menuItems_=[];this.roleName_=this.element_=this.onKeyDownHandler_=this.mouseLeaveHandler_=this.mouseEnterHandler_=this.clickHandler_=this.mouseOverHandler_=this.highlightedItem_=this.openingCoords=null};Blockly.Menu.prototype.addChild=function(a){this.menuItems_.push(a)};
Blockly.utils.aria.setState=function(a,b,c){Array.isArray(c)&&(c=c.join(" "));a.setAttribute(Blockly.utils.aria.ARIA_PREFIX_+b,c)};Blockly.utils.KeyCodes={WIN_KEY_FF_LINUX:0,MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PLUS_SIGN:43,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,FF_SEMICOLON:59,FF_EQUALS:61,FF_DASH:173,FF_HASH:163,QUESTION_MARK:63,AT_SIGN:64,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,
N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SCROLL_LOCK:145,FIRST_MEDIA_KEY:166,LAST_MEDIA_KEY:183,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,
PERIOD:190,SLASH:191,APOSTROPHE:192,TILDE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,MAC_WK_CMD_LEFT:91,MAC_WK_CMD_RIGHT:93,WIN_IME:229,VK_NONAME:252,PHANTOM:255};Blockly.Menu=function(){this.menuItems_=[];this.roleName_=this.element_=this.onKeyDownHandler_=this.mouseLeaveHandler_=this.mouseEnterHandler_=this.clickHandler_=this.mouseOverHandler_=this.highlightedItem_=this.openingCoords=null};Blockly.Menu.prototype.addChild=function(a){this.menuItems_.push(a)};
Blockly.Menu.prototype.render=function(a){var b=document.createElement("div");b.className="blocklyMenu goog-menu blocklyNonSelectable";b.tabIndex=0;this.roleName_&&Blockly.utils.aria.setRole(b,this.roleName_);this.element_=b;for(var c=0,d;d=this.menuItems_[c];c++)b.appendChild(d.createDom());this.mouseOverHandler_=Blockly.bindEventWithChecks_(b,"mouseover",this,this.handleMouseOver_,!0);this.clickHandler_=Blockly.bindEventWithChecks_(b,"click",this,this.handleClick_,!0);this.mouseEnterHandler_=Blockly.bindEventWithChecks_(b,
"mouseenter",this,this.handleMouseEnter_,!0);this.mouseLeaveHandler_=Blockly.bindEventWithChecks_(b,"mouseleave",this,this.handleMouseLeave_,!0);this.onKeyDownHandler_=Blockly.bindEventWithChecks_(b,"keydown",this,this.handleKeyEvent_);a.appendChild(b)};Blockly.Menu.prototype.getElement=function(){return this.element_};Blockly.Menu.prototype.focus=function(){var a=this.getElement();a&&(a.focus({preventScroll:!0}),Blockly.utils.dom.addClass(a,"blocklyFocused"))};
Blockly.Menu.prototype.blur_=function(){var a=this.getElement();a&&(a.blur(),Blockly.utils.dom.removeClass(a,"blocklyFocused"))};Blockly.Menu.prototype.setRole=function(a){this.roleName_=a};
@@ -579,30 +582,31 @@ Blockly.ContextMenu.createWidget_=function(a){a.render(Blockly.WidgetDiv.DIV);va
Blockly.ContextMenu.callbackFactory=function(a,b){return function(){Blockly.Events.disable();try{var c=Blockly.Xml.domToBlock(b,a.workspace),d=a.getRelativeToSurfaceXY();d.x=a.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y)}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!c.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(c));c.select()}};
Blockly.ContextMenu.commentDeleteOption=function(a){return{text:Blockly.Msg.REMOVE_COMMENT,enabled:!0,callback:function(){Blockly.Events.setGroup(!0);a.dispose(!0,!0);Blockly.Events.setGroup(!1)}}};Blockly.ContextMenu.commentDuplicateOption=function(a){return{text:Blockly.Msg.DUPLICATE_COMMENT,enabled:!0,callback:function(){Blockly.duplicate(a)}}};
Blockly.ContextMenu.workspaceCommentOption=function(a,b){if(!Blockly.WorkspaceCommentSvg)throw Error("Missing require for Blockly.WorkspaceCommentSvg");var c={enabled:!Blockly.utils.userAgent.IE};c.text=Blockly.Msg.ADD_COMMENT;c.callback=function(){var d=new Blockly.WorkspaceCommentSvg(a,Blockly.Msg.WORKSPACE_COMMENT_DEFAULT_TEXT,Blockly.WorkspaceCommentSvg.DEFAULT_SIZE,Blockly.WorkspaceCommentSvg.DEFAULT_SIZE),e=a.getInjectionDiv().getBoundingClientRect();e=new Blockly.utils.Coordinate(b.clientX-
e.left,b.clientY-e.top);var f=a.getOriginOffsetInPixels();e=Blockly.utils.Coordinate.difference(e,f);e.scale(1/a.scale);d.moveBy(e.x,e.y);a.rendered&&(d.initSvg(),d.render(),d.select())};return c};Blockly.ContextMenuItems={};Blockly.ContextMenuItems.registerUndo=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.UNDO},preconditionFn:function(a){return 0<a.workspace.getUndoStack().length?"enabled":"disabled"},callback:function(a){a.workspace.undo(!1)},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"undoWorkspace",weight:0})};
Blockly.ContextMenuItems.registerRedo=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.REDO},preconditionFn:function(a){return 0<a.workspace.getRedoStack().length?"enabled":"disabled"},callback:function(a){a.workspace.undo(!0)},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"redoWorkspace",weight:0})};
Blockly.ContextMenuItems.registerCleanup=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.CLEAN_UP},preconditionFn:function(a){return a.workspace.isMovable()?1<a.workspace.getTopBlocks(!1).length?"enabled":"disabled":"hidden"},callback:function(a){a.workspace.cleanUp()},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"cleanWorkspace",weight:0})};
e.left,b.clientY-e.top);var f=a.getOriginOffsetInPixels();e=Blockly.utils.Coordinate.difference(e,f);e.scale(1/a.scale);d.moveBy(e.x,e.y);a.rendered&&(d.initSvg(),d.render(),d.select())};return c};Blockly.ContextMenuItems={};Blockly.ContextMenuItems.registerUndo=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.UNDO},preconditionFn:function(a){return 0<a.workspace.getUndoStack().length?"enabled":"disabled"},callback:function(a){a.workspace.undo(!1)},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"undoWorkspace",weight:1})};
Blockly.ContextMenuItems.registerRedo=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.REDO},preconditionFn:function(a){return 0<a.workspace.getRedoStack().length?"enabled":"disabled"},callback:function(a){a.workspace.undo(!0)},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"redoWorkspace",weight:2})};
Blockly.ContextMenuItems.registerCleanup=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.CLEAN_UP},preconditionFn:function(a){return a.workspace.isMovable()?1<a.workspace.getTopBlocks(!1).length?"enabled":"disabled":"hidden"},callback:function(a){a.workspace.cleanUp()},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"cleanWorkspace",weight:3})};
Blockly.ContextMenuItems.toggleOption_=function(a,b){for(var c=0,d=0;d<b.length;d++)for(var e=b[d];e;)setTimeout(e.setCollapsed.bind(e,a),c),e=e.getNextBlock(),c+=10};
Blockly.ContextMenuItems.registerCollapse=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.COLLAPSE_ALL},preconditionFn:function(a){if(a.workspace.options.collapse){a=a.workspace.getTopBlocks(!1);for(var b=0;b<a.length;b++)for(var c=a[b];c;){if(!c.isCollapsed())return"enabled";c=c.getNextBlock()}return"disabled"}return"hidden"},callback:function(a){Blockly.ContextMenuItems.toggleOption_(!0,a.workspace.getTopBlocks(!0))},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id:"collapseWorkspace",weight:0})};
id:"collapseWorkspace",weight:4})};
Blockly.ContextMenuItems.registerExpand=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.EXPAND_ALL},preconditionFn:function(a){if(a.workspace.options.collapse){a=a.workspace.getTopBlocks(!1);for(var b=0;b<a.length;b++)for(var c=a[b];c;){if(c.isCollapsed())return"enabled";c=c.getNextBlock()}return"disabled"}return"hidden"},callback:function(a){Blockly.ContextMenuItems.toggleOption_(!1,a.workspace.getTopBlocks(!0))},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id:"expandWorkspace",weight:0})};Blockly.ContextMenuItems.addDeletableBlocks_=function(a,b){if(a.isDeletable())Array.prototype.push.apply(b,a.getDescendants(!1));else{a=a.getChildren(!1);for(var c=0;c<a.length;c++)Blockly.ContextMenuItems.addDeletableBlocks_(a[c],b)}};Blockly.ContextMenuItems.getDeletableBlocks_=function(a){var b=[];a=a.getTopBlocks(!0);for(var c=0;c<a.length;c++)Blockly.ContextMenuItems.addDeletableBlocks_(a[c],b);return b};
id:"expandWorkspace",weight:5})};Blockly.ContextMenuItems.addDeletableBlocks_=function(a,b){if(a.isDeletable())Array.prototype.push.apply(b,a.getDescendants(!1));else{a=a.getChildren(!1);for(var c=0;c<a.length;c++)Blockly.ContextMenuItems.addDeletableBlocks_(a[c],b)}};Blockly.ContextMenuItems.getDeletableBlocks_=function(a){var b=[];a=a.getTopBlocks(!0);for(var c=0;c<a.length;c++)Blockly.ContextMenuItems.addDeletableBlocks_(a[c],b);return b};
Blockly.ContextMenuItems.deleteNext_=function(a,b){Blockly.Events.setGroup(b);var c=a.shift();c&&(c.workspace?(c.dispose(!1,!0),setTimeout(Blockly.ContextMenuItems.deleteNext_,10,a,b)):Blockly.ContextMenuItems.deleteNext_(a,b));Blockly.Events.setGroup(!1)};
Blockly.ContextMenuItems.registerDeleteAll=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){if(a.workspace)return a=Blockly.ContextMenuItems.getDeletableBlocks_(a.workspace).length,1==a?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(a))},preconditionFn:function(a){if(a.workspace)return 0<Blockly.ContextMenuItems.getDeletableBlocks_(a.workspace).length?"enabled":"disabled"},callback:function(a){if(a.workspace){a.workspace.cancelCurrentGesture();
var b=Blockly.ContextMenuItems.getDeletableBlocks_(a.workspace),c=Blockly.utils.genUid();2>b.length?Blockly.ContextMenuItems.deleteNext_(b,c):Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",b.length),function(d){d&&Blockly.ContextMenuItems.deleteNext_(b,c)})}},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"workspaceDelete",weight:0})};
var b=Blockly.ContextMenuItems.getDeletableBlocks_(a.workspace),c=Blockly.utils.genUid();2>b.length?Blockly.ContextMenuItems.deleteNext_(b,c):Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",b.length),function(d){d&&Blockly.ContextMenuItems.deleteNext_(b,c)})}},scopeType:Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,id:"workspaceDelete",weight:6})};
Blockly.ContextMenuItems.registerWorkspaceOptions_=function(){Blockly.ContextMenuItems.registerUndo();Blockly.ContextMenuItems.registerRedo();Blockly.ContextMenuItems.registerCleanup();Blockly.ContextMenuItems.registerCollapse();Blockly.ContextMenuItems.registerExpand();Blockly.ContextMenuItems.registerDeleteAll()};
Blockly.ContextMenuItems.registerDuplicate=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.DUPLICATE_BLOCK},preconditionFn:function(a){a=a.block;return!a.isInFlyout&&a.isDeletable()&&a.isMovable()?a.isDuplicatable()?"enabled":"disabled":"hidden"},callback:function(a){a.block&&Blockly.duplicate(a.block)},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDuplicate",weight:0})};
Blockly.ContextMenuItems.registerDuplicate=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.DUPLICATE_BLOCK},preconditionFn:function(a){a=a.block;return!a.isInFlyout&&a.isDeletable()&&a.isMovable()?a.isDuplicatable()?"enabled":"disabled":"hidden"},callback:function(a){a.block&&Blockly.duplicate(a.block)},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDuplicate",weight:1})};
Blockly.ContextMenuItems.registerComment=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){return a.block.getCommentIcon()?Blockly.Msg.REMOVE_COMMENT:Blockly.Msg.ADD_COMMENT},preconditionFn:function(a){a=a.block;return Blockly.utils.userAgent.IE||a.isInFlyout||!a.workspace.options.comments||a.isCollapsed()||!a.isEditable()?"hidden":"enabled"},callback:function(a){a=a.block;a.getCommentIcon()?a.setCommentText(null):a.setCommentText("")},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id:"blockComment",weight:0})};
id:"blockComment",weight:2})};
Blockly.ContextMenuItems.registerInline=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){return a.block.getInputsInline()?Blockly.Msg.EXTERNAL_INPUTS:Blockly.Msg.INLINE_INPUTS},preconditionFn:function(a){a=a.block;if(!a.isInFlyout&&a.isMovable()&&!a.isCollapsed())for(var b=1;b<a.inputList.length;b++)if(a.inputList[b-1].type!=Blockly.NEXT_STATEMENT&&a.inputList[b].type!=Blockly.NEXT_STATEMENT)return"enabled";return"hidden"},callback:function(a){a.block.setInputsInline(!a.block.getInputsInline())},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id:"blockInline",weight:0})};Blockly.ContextMenuItems.registerCollapseExpandBlock=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){return a.block.isCollapsed()?Blockly.Msg.EXPAND_BLOCK:Blockly.Msg.COLLAPSE_BLOCK},preconditionFn:function(a){a=a.block;return!a.isInFlyout&&a.isMovable()?"enabled":"hidden"},callback:function(a){a.block.setCollapsed(!a.block.isCollapsed())},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockCollapseExpand",weight:0})};
id:"blockInline",weight:3})};Blockly.ContextMenuItems.registerCollapseExpandBlock=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){return a.block.isCollapsed()?Blockly.Msg.EXPAND_BLOCK:Blockly.Msg.COLLAPSE_BLOCK},preconditionFn:function(a){a=a.block;return!a.isInFlyout&&a.isMovable()?"enabled":"hidden"},callback:function(a){a.block.setCollapsed(!a.block.isCollapsed())},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockCollapseExpand",weight:4})};
Blockly.ContextMenuItems.registerDisable=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){return a.block.isEnabled()?Blockly.Msg.DISABLE_BLOCK:Blockly.Msg.ENABLE_BLOCK},preconditionFn:function(a){a=a.block;return!a.isInFlyout&&a.workspace.options.disable&&a.isEditable()?a.getInheritedDisabled()?"disabled":"enabled":"hidden"},callback:function(a){a=a.block;var b=Blockly.Events.getGroup();b||Blockly.Events.setGroup(!0);a.setEnabled(!a.isEnabled());b||Blockly.Events.setGroup(!1)},
scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDisable",weight:0})};
scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDisable",weight:5})};
Blockly.ContextMenuItems.registerDelete=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(a){var b=a.block;a=b.getDescendants(!1).length;(b=b.getNextBlock())&&(a-=b.getDescendants(!1).length);return 1==a?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(a))},preconditionFn:function(a){return!a.block.isInFlyout&&a.block.isDeletable()?"enabled":"hidden"},callback:function(a){Blockly.Events.setGroup(!0);a.block.dispose(!0,!0);Blockly.Events.setGroup(!1)},
scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDelete",weight:0})};Blockly.ContextMenuItems.registerHelp=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.HELP},preconditionFn:function(a){a=a.block;return("function"==typeof a.helpUrl?a.helpUrl():a.helpUrl)?"enabled":"hidden"},callback:function(a){a.block.showHelp()},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockHelp",weight:0})};
scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockDelete",weight:6})};Blockly.ContextMenuItems.registerHelp=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.HELP},preconditionFn:function(a){a=a.block;return("function"==typeof a.helpUrl?a.helpUrl():a.helpUrl)?"enabled":"hidden"},callback:function(a){a.block.showHelp()},scopeType:Blockly.ContextMenuRegistry.ScopeType.BLOCK,id:"blockHelp",weight:7})};
Blockly.ContextMenuItems.registerBlockOptions_=function(){Blockly.ContextMenuItems.registerDuplicate();Blockly.ContextMenuItems.registerComment();Blockly.ContextMenuItems.registerInline();Blockly.ContextMenuItems.registerCollapseExpandBlock();Blockly.ContextMenuItems.registerDisable();Blockly.ContextMenuItems.registerDelete();Blockly.ContextMenuItems.registerHelp()};Blockly.ContextMenuItems.registerDefaultOptions=function(){Blockly.ContextMenuItems.registerWorkspaceOptions_();Blockly.ContextMenuItems.registerBlockOptions_()};Blockly.ContextMenuRegistry=function(){Blockly.ContextMenuRegistry.registry=this;this.registry_={};Blockly.ContextMenuItems.registerDefaultOptions()};Blockly.ContextMenuRegistry.ScopeType={BLOCK:"block",WORKSPACE:"workspace"};Blockly.ContextMenuRegistry.registry=null;Blockly.ContextMenuRegistry.prototype.register=function(a){if(this.registry_[a.id])throw Error('Menu item with id "'+a.id+'" is already registered.');this.registry_[a.id]=a};
Blockly.ContextMenuRegistry.prototype.unregister=function(a){if(this.registry_[a])delete this.registry_[a];else throw Error('Menu item with id "'+a+'" not found.');};Blockly.ContextMenuRegistry.prototype.getItem=function(a){return this.registry_[a]?this.registry_[a]:null};
Blockly.ContextMenuRegistry.prototype.getContextMenuOptions=function(a,b){var c=[],d=this.registry_;Object.keys(d).forEach(function(e){e=d[e];if(a==e.scopeType){var f=e.preconditionFn(b);"hidden"!=f&&(e={text:"function"==typeof e.displayText?e.displayText(b):e.displayText,enabled:"enabled"==f,callback:e.callback,scope:b,weight:e.weight},c.push(e))}});c.sort(function(e,f){return e.weight-f.weight});return c};new Blockly.ContextMenuRegistry;Blockly.RenderedConnection=function(a,b){Blockly.RenderedConnection.superClass_.constructor.call(this,a,b);this.db_=a.workspace.connectionDBList[b];this.dbOpposite_=a.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[b]];this.offsetInBlock_=new Blockly.utils.Coordinate(0,0);this.trackedState_=Blockly.RenderedConnection.TrackedState.WILL_TRACK;this.targetConnection=null};Blockly.utils.object.inherits(Blockly.RenderedConnection,Blockly.Connection);
Blockly.ContextMenuRegistry.prototype.getContextMenuOptions=function(a,b){var c=[],d=this.registry_;Object.keys(d).forEach(function(e){e=d[e];if(a==e.scopeType){var f=e.preconditionFn(b);"hidden"!=f&&(e={text:"function"==typeof e.displayText?e.displayText(b):e.displayText,enabled:"enabled"==f,callback:e.callback,scope:b,weight:e.weight},c.push(e))}});c.sort(function(e,f){return e.weight-f.weight});return c};new Blockly.ContextMenuRegistry;Blockly.Events.Selected=function(a,b,c){Blockly.Events.Selected.superClass_.constructor.call(this,c);this.oldElementId=a;this.newElementId=b};Blockly.utils.object.inherits(Blockly.Events.Selected,Blockly.Events.UiBase);Blockly.Events.Selected.prototype.type=Blockly.Events.SELECTED;Blockly.Events.Selected.prototype.toJson=function(){var a=Blockly.Events.Selected.superClass_.toJson.call(this);a.oldElementId=this.oldElementId;a.newElementId=this.newElementId;return a};
Blockly.Events.Selected.prototype.fromJson=function(a){Blockly.Events.Selected.superClass_.fromJson.call(this,a);this.oldElementId=a.oldElementId;this.newElementId=a.newElementId};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.SELECTED,Blockly.Events.Selected);Blockly.RenderedConnection=function(a,b){Blockly.RenderedConnection.superClass_.constructor.call(this,a,b);this.db_=a.workspace.connectionDBList[b];this.dbOpposite_=a.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[b]];this.offsetInBlock_=new Blockly.utils.Coordinate(0,0);this.trackedState_=Blockly.RenderedConnection.TrackedState.WILL_TRACK;this.targetConnection=null};Blockly.utils.object.inherits(Blockly.RenderedConnection,Blockly.Connection);
Blockly.RenderedConnection.TrackedState={WILL_TRACK:-1,UNTRACKED:0,TRACKED:1};Blockly.RenderedConnection.prototype.dispose=function(){Blockly.RenderedConnection.superClass_.dispose.call(this);this.trackedState_==Blockly.RenderedConnection.TrackedState.TRACKED&&this.db_.removeConnection(this,this.y)};Blockly.RenderedConnection.prototype.getSourceBlock=function(){return Blockly.RenderedConnection.superClass_.getSourceBlock.call(this)};Blockly.RenderedConnection.prototype.targetBlock=function(){return Blockly.RenderedConnection.superClass_.targetBlock.call(this)};
Blockly.RenderedConnection.prototype.distanceFrom=function(a){var b=this.x-a.x;a=this.y-a.y;return Math.sqrt(b*b+a*a)};
Blockly.RenderedConnection.prototype.bumpAwayFrom=function(a){if(!this.sourceBlock_.workspace.isDragging()){var b=this.sourceBlock_.getRootBlock();if(!b.isInFlyout){var c=!1;if(!b.isMovable()){b=a.getSourceBlock().getRootBlock();if(!b.isMovable())return;a=this;c=!0}var d=Blockly.selected==b;d||b.addSelect();var e=a.x+Blockly.SNAP_RADIUS+Math.floor(Math.random()*Blockly.BUMP_RANDOMNESS)-this.x,f=a.y+Blockly.SNAP_RADIUS+Math.floor(Math.random()*Blockly.BUMP_RANDOMNESS)-this.y;c&&(f=-f);b.RTL&&(e=a.x-
@@ -627,12 +631,12 @@ Blockly.Cursor.prototype.onBlocklyAction=function(a){if(this.getCurNode()&&this.
Blockly.BasicCursor.prototype.prev=function(){var a=this.getCurNode();if(!a)return null;(a=this.getPreviousNode_(a,this.validNode_))&&this.setCurNode(a);return a};Blockly.BasicCursor.prototype.out=function(){return this.prev()};Blockly.BasicCursor.prototype.getNextNode_=function(a,b){if(!a)return null;var c=a.in()||a.next();if(b(c))return c;if(c)return this.getNextNode_(c,b);a=this.findSiblingOrParent_(a.out());return b(a)?a:a?this.getNextNode_(a,b):null};
Blockly.BasicCursor.prototype.getPreviousNode_=function(a,b){if(!a)return null;var c=a.prev();c=c?this.getRightMostChild_(c):a.out();return b(c)?c:c?this.getPreviousNode_(c,b):null};Blockly.BasicCursor.prototype.validNode_=function(a){var b=!1;a=a&&a.getType();if(a==Blockly.ASTNode.types.OUTPUT||a==Blockly.ASTNode.types.INPUT||a==Blockly.ASTNode.types.FIELD||a==Blockly.ASTNode.types.NEXT||a==Blockly.ASTNode.types.PREVIOUS||a==Blockly.ASTNode.types.WORKSPACE)b=!0;return b};
Blockly.BasicCursor.prototype.findSiblingOrParent_=function(a){if(!a)return null;var b=a.next();return b?b:this.findSiblingOrParent_(a.out())};Blockly.BasicCursor.prototype.getRightMostChild_=function(a){if(!a.in())return a;for(a=a.in();a.next();)a=a.next();return this.getRightMostChild_(a)};Blockly.TabNavigateCursor=function(){Blockly.TabNavigateCursor.superClass_.constructor.call(this)};Blockly.utils.object.inherits(Blockly.TabNavigateCursor,Blockly.BasicCursor);Blockly.TabNavigateCursor.prototype.validNode_=function(a){var b=!1,c=a&&a.getType();a&&(a=a.getLocation(),c==Blockly.ASTNode.types.FIELD&&a&&a.isTabNavigable()&&a.isClickable()&&(b=!0));return b};Blockly.BlockSvg=function(a,b,c){this.svgGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{},null);this.svgGroup_.translate_="";this.style=a.getRenderer().getConstants().getBlockStyle(null);this.pathObject=a.getRenderer().makePathObject(this.svgGroup_,this.style);this.renderIsInProgress_=this.rendered=!1;this.workspace=a;this.previousConnection=this.nextConnection=this.outputConnection=null;this.useDragSurface_=Blockly.utils.is3dSupported()&&!!a.getBlockDragSurface();var d=this.pathObject.svgPath;
d.tooltip=this;Blockly.Tooltip.bindMouseEvents(d);Blockly.BlockSvg.superClass_.constructor.call(this,a,b,c);this.svgGroup_.dataset&&(this.svgGroup_.dataset.id=this.id)};Blockly.utils.object.inherits(Blockly.BlockSvg,Blockly.Block);Blockly.BlockSvg.prototype.height=0;Blockly.BlockSvg.prototype.width=0;Blockly.BlockSvg.prototype.warningTextDb_=null;Blockly.BlockSvg.INLINE=-1;Blockly.BlockSvg.COLLAPSED_WARNING_ID="TEMP_COLLAPSED_WARNING_";
d.tooltip=this;Blockly.Tooltip.bindMouseEvents(d);Blockly.BlockSvg.superClass_.constructor.call(this,a,b,c);this.svgGroup_.dataset?this.svgGroup_.dataset.id=this.id:Blockly.utils.userAgent.IE&&this.svgGroup_.setAttribute("data-id",this.id)};Blockly.utils.object.inherits(Blockly.BlockSvg,Blockly.Block);Blockly.BlockSvg.prototype.height=0;Blockly.BlockSvg.prototype.width=0;Blockly.BlockSvg.prototype.warningTextDb_=null;Blockly.BlockSvg.INLINE=-1;Blockly.BlockSvg.COLLAPSED_WARNING_ID="TEMP_COLLAPSED_WARNING_";
Blockly.BlockSvg.prototype.initSvg=function(){if(!this.workspace.rendered)throw TypeError("Workspace is headless.");for(var a=0,b;b=this.inputList[a];a++)b.init();b=this.getIcons();for(a=0;a<b.length;a++)b[a].createIcon();this.applyColour();this.pathObject.updateMovable(this.isMovable());a=this.getSvgRoot();this.workspace.options.readOnly||this.eventsInit_||!a||Blockly.bindEventWithChecks_(a,"mousedown",this,this.onMouseDown_);this.eventsInit_=!0;a.parentNode||this.workspace.getCanvas().appendChild(a)};
Blockly.BlockSvg.prototype.getColourSecondary=function(){return this.style.colourSecondary};Blockly.BlockSvg.prototype.getColourTertiary=function(){return this.style.colourTertiary};Blockly.BlockSvg.prototype.getColourShadow=function(){Blockly.utils.deprecation.warn("BlockSvg.prototype.getColourShadow","January 2020","January 2021","style.colourSecondary");return this.getColourSecondary()};
Blockly.BlockSvg.prototype.getColourBorder=function(){Blockly.utils.deprecation.warn("BlockSvg.prototype.getColourBorder","January 2020","January 2021","style.colourTertiary");return{colourBorder:this.getColourTertiary(),colourLight:null,colourDark:null}};
Blockly.BlockSvg.prototype.select=function(){if(this.isShadow()&&this.getParent())this.getParent().select();else if(Blockly.selected!=this){var a=null;if(Blockly.selected){a=Blockly.selected.id;Blockly.Events.disable();try{Blockly.selected.unselect()}finally{Blockly.Events.enable()}}a=new Blockly.Events.Ui(null,"selected",a,this.id);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=this;this.addSelect()}};
Blockly.BlockSvg.prototype.unselect=function(){if(Blockly.selected==this){var a=new Blockly.Events.Ui(null,"selected",this.id,null);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=null;this.removeSelect()}};Blockly.BlockSvg.prototype.mutator=null;Blockly.BlockSvg.prototype.comment=null;Blockly.BlockSvg.prototype.commentIcon_=null;Blockly.BlockSvg.prototype.warning=null;
Blockly.BlockSvg.prototype.select=function(){if(this.isShadow()&&this.getParent())this.getParent().select();else if(Blockly.selected!=this){var a=null;if(Blockly.selected){a=Blockly.selected.id;Blockly.Events.disable();try{Blockly.selected.unselect()}finally{Blockly.Events.enable()}}a=new Blockly.Events.Selected(a,this.id,this.workspace.id);Blockly.Events.fire(a);Blockly.selected=this;this.addSelect()}};
Blockly.BlockSvg.prototype.unselect=function(){if(Blockly.selected==this){var a=new Blockly.Events.Selected(this.id,null,this.workspace.id);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=null;this.removeSelect()}};Blockly.BlockSvg.prototype.mutator=null;Blockly.BlockSvg.prototype.comment=null;Blockly.BlockSvg.prototype.commentIcon_=null;Blockly.BlockSvg.prototype.warning=null;
Blockly.BlockSvg.prototype.getIcons=function(){var a=[];this.mutator&&a.push(this.mutator);this.commentIcon_&&a.push(this.commentIcon_);this.warning&&a.push(this.warning);return a};
Blockly.BlockSvg.prototype.setParent=function(a){var b=this.parentBlock_;if(a!=b){Blockly.utils.dom.startTextWidthCache();Blockly.BlockSvg.superClass_.setParent.call(this,a);Blockly.utils.dom.stopTextWidthCache();var c=this.getSvgRoot();if(!this.workspace.isClearing&&c){var d=this.getRelativeToSurfaceXY();a?(a.getSvgRoot().appendChild(c),a=this.getRelativeToSurfaceXY(),this.moveConnections(a.x-d.x,a.y-d.y)):b&&(this.workspace.getCanvas().appendChild(c),this.translate(d.x,d.y));this.applyColour()}}};
Blockly.BlockSvg.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0,c=this.useDragSurface_?this.workspace.getBlockDragSurface().getGroup():null,d=this.getSvgRoot();if(d){do{var e=Blockly.utils.getRelativeXY(d);a+=e.x;b+=e.y;this.useDragSurface_&&this.workspace.getBlockDragSurface().getCurrentBlock()==d&&(e=this.workspace.getBlockDragSurface().getSurfaceTranslation(),a+=e.x,b+=e.y);d=d.parentNode}while(d&&d!=this.workspace.getCanvas()&&d!=c)}return new Blockly.utils.Coordinate(a,b)};
@@ -643,7 +647,7 @@ Blockly.BlockSvg.prototype.clearTransformAttributes_=function(){this.getSvgRoot(
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){this.collapsed_!=a&&(Blockly.BlockSvg.superClass_.setCollapsed.call(this,a),a?this.rendered&&this.render():this.updateCollapsed_())};
Blockly.BlockSvg.prototype.updateCollapsed_=function(){for(var a=this.isCollapsed(),b=Blockly.Block.COLLAPSED_INPUT_NAME,c=Blockly.Block.COLLAPSED_FIELD_NAME,d=0,e;e=this.inputList[d];d++)e.name!=b&&e.setVisible(!a);if(a){e=this.getIcons();for(d=0;a=e[d];d++)a.setVisible(!1);d=this.toString(Blockly.COLLAPSE_CHARS);(e=this.getField(c))?e.setValue(d):(e=this.getInput(b)||this.appendDummyInput(b),e.appendField(new Blockly.FieldLabel(d),c))}else this.removeInput(b)};
Blockly.BlockSvg.prototype.tab=function(a,b){var c=new Blockly.TabNavigateCursor;c.setCurNode(Blockly.ASTNode.createFieldNode(a));a=c.getCurNode();c.onBlocklyAction(b?Blockly.navigation.ACTION_NEXT:Blockly.navigation.ACTION_PREVIOUS);(b=c.getCurNode())&&b!==a&&(b.getLocation().showEditor(),this.workspace.keyboardAccessibilityMode&&this.workspace.getCursor().setCurNode(b))};
Blockly.BlockSvg.prototype.tab=function(a,b){var c=new Blockly.TabNavigateCursor;c.setCurNode(Blockly.ASTNode.createFieldNode(a));a=c.getCurNode();c.onBlocklyAction({name:b?Blockly.navigation.actionNames.NEXT:Blockly.navigation.actionNames.PREVIOUS});(b=c.getCurNode())&&b!==a&&(b.getLocation().showEditor(),this.workspace.keyboardAccessibilityMode&&this.workspace.getCursor().setCurNode(b))};
Blockly.BlockSvg.prototype.onMouseDown_=function(a){var b=this.workspace&&this.workspace.getGesture(a);b&&b.handleBlockStart(a,this)};Blockly.BlockSvg.prototype.showHelp=function(){var a="function"==typeof this.helpUrl?this.helpUrl():this.helpUrl;a&&window.open(a)};
Blockly.BlockSvg.prototype.generateContextMenu=function(){if(this.workspace.options.readOnly||!this.contextMenu)return null;var a=Blockly.ContextMenuRegistry.registry.getContextMenuOptions(Blockly.ContextMenuRegistry.ScopeType.BLOCK,{block:this});this.customContextMenu&&this.customContextMenu(a);return a};Blockly.BlockSvg.prototype.showContextMenu=function(a){var b=this.generateContextMenu();b&&b.length&&(Blockly.ContextMenu.show(a,b,this.RTL),Blockly.ContextMenu.currentBlock=this)};
Blockly.BlockSvg.prototype.moveConnections=function(a,b){if(this.rendered){for(var c=this.getConnections_(!1),d=0;d<c.length;d++)c[d].moveBy(a,b);c=this.getIcons();for(d=0;d<c.length;d++)c[d].computeIconLocation();for(d=0;d<this.childBlocks_.length;d++)this.childBlocks_[d].moveConnections(a,b)}};
@@ -658,9 +662,8 @@ Blockly.BlockSvg.prototype.setCommentText=function(a){if(!Blockly.Comment)throw
Blockly.BlockSvg.prototype.setWarningText=function(a,b){if(!Blockly.Warning)throw Error("Missing require for Blockly.Warning");this.warningTextDb_||(this.warningTextDb_=Object.create(null));var c=b||"";if(c)this.warningTextDb_[c]&&(clearTimeout(this.warningTextDb_[c]),delete this.warningTextDb_[c]);else for(var d in this.warningTextDb_)clearTimeout(this.warningTextDb_[d]),delete this.warningTextDb_[d];if(this.workspace.isDragging()){var e=this;this.warningTextDb_[c]=setTimeout(function(){e.workspace&&
(delete e.warningTextDb_[c],e.setWarningText(a,c))},100)}else{this.isInFlyout&&(a=null);b=!1;if("string"==typeof a){d=this.getSurroundParent();for(var f=null;d;)d.isCollapsed()&&(f=d),d=d.getSurroundParent();f&&f.setWarningText(Blockly.Msg.COLLAPSED_WARNINGS_WARNING,Blockly.BlockSvg.COLLAPSED_WARNING_ID);this.warning||(this.warning=new Blockly.Warning(this),b=!0);this.warning.setText(a,c)}else this.warning&&!c?(this.warning.dispose(),b=!0):this.warning&&(b=this.warning.getText(),this.warning.setText("",
c),(d=this.warning.getText())||this.warning.dispose(),b=b!=d);b&&this.rendered&&(this.render(),this.bumpNeighbours())}};Blockly.BlockSvg.prototype.setMutator=function(a){this.mutator&&this.mutator!==a&&this.mutator.dispose();a&&(a.setBlock(this),this.mutator=a,a.createIcon());this.rendered&&(this.render(),this.bumpNeighbours())};
Blockly.BlockSvg.prototype.setDisabled=function(a){Blockly.utils.deprecation.warn("BlockSvg.prototype.setDisabled","May 2019","May 2020","BlockSvg.prototype.setEnabled");this.setEnabled(!a)};Blockly.BlockSvg.prototype.setEnabled=function(a){this.isEnabled()!=a&&(Blockly.BlockSvg.superClass_.setEnabled.call(this,a),this.rendered&&!this.getInheritedDisabled()&&this.updateDisabled())};Blockly.BlockSvg.prototype.setHighlighted=function(a){this.rendered&&this.pathObject.updateHighlighted(a)};
Blockly.BlockSvg.prototype.addSelect=function(){this.pathObject.updateSelected(!0)};Blockly.BlockSvg.prototype.removeSelect=function(){this.pathObject.updateSelected(!1)};Blockly.BlockSvg.prototype.setDeleteStyle=function(a){this.pathObject.updateDraggingDelete(a)};Blockly.BlockSvg.prototype.getColour=function(){return this.style.colourPrimary};
Blockly.BlockSvg.prototype.setColour=function(a){Blockly.BlockSvg.superClass_.setColour.call(this,a);a=this.workspace.getRenderer().getConstants().getBlockStyleForColour(this.colour_);this.pathObject.setStyle(a.style);this.style=a.style;this.styleName_=a.name;this.applyColour()};
Blockly.BlockSvg.prototype.setEnabled=function(a){this.isEnabled()!=a&&(Blockly.BlockSvg.superClass_.setEnabled.call(this,a),this.rendered&&!this.getInheritedDisabled()&&this.updateDisabled())};Blockly.BlockSvg.prototype.setHighlighted=function(a){this.rendered&&this.pathObject.updateHighlighted(a)};Blockly.BlockSvg.prototype.addSelect=function(){this.pathObject.updateSelected(!0)};Blockly.BlockSvg.prototype.removeSelect=function(){this.pathObject.updateSelected(!1)};
Blockly.BlockSvg.prototype.setDeleteStyle=function(a){this.pathObject.updateDraggingDelete(a)};Blockly.BlockSvg.prototype.getColour=function(){return this.style.colourPrimary};Blockly.BlockSvg.prototype.setColour=function(a){Blockly.BlockSvg.superClass_.setColour.call(this,a);a=this.workspace.getRenderer().getConstants().getBlockStyleForColour(this.colour_);this.pathObject.setStyle(a.style);this.style=a.style;this.styleName_=a.name;this.applyColour()};
Blockly.BlockSvg.prototype.setStyle=function(a){var b=this.workspace.getRenderer().getConstants().getBlockStyle(a);this.styleName_=a;if(b)this.hat=b.hat,this.pathObject.setStyle(b),this.colour_=b.colourPrimary,this.style=b,this.applyColour();else throw Error("Invalid style name: "+a);};Blockly.BlockSvg.prototype.bringToFront=function(){var a=this;do{var b=a.getSvgRoot(),c=b.parentNode,d=c.childNodes;d[d.length-1]!==b&&c.appendChild(b);a=a.getParent()}while(a)};
Blockly.BlockSvg.prototype.setPreviousStatement=function(a,b){Blockly.BlockSvg.superClass_.setPreviousStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours())};Blockly.BlockSvg.prototype.setNextStatement=function(a,b){Blockly.BlockSvg.superClass_.setNextStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours())};Blockly.BlockSvg.prototype.setOutput=function(a,b){Blockly.BlockSvg.superClass_.setOutput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours())};
Blockly.BlockSvg.prototype.setInputsInline=function(a){Blockly.BlockSvg.superClass_.setInputsInline.call(this,a);this.rendered&&(this.render(),this.bumpNeighbours())};Blockly.BlockSvg.prototype.removeInput=function(a,b){a=Blockly.BlockSvg.superClass_.removeInput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours());return a};
@@ -681,7 +684,9 @@ Blockly.ConnectionDB.prototype.findIndexOfConnection_=function(a,b){if(!this.con
Blockly.ConnectionDB.prototype.calculateIndexForYPos_=function(a){if(!this.connections_.length)return 0;for(var b=0,c=this.connections_.length;b<c;){var d=Math.floor((b+c)/2);if(this.connections_[d].y<a)b=d+1;else if(this.connections_[d].y>a)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(l){var m=e-d[l].x,n=f-d[l].y;Math.sqrt(m*m+n*n)<=b&&k.push(d[l]);return n<b}var d=this.connections_,e=a.x,f=a.y;a=0;for(var g=d.length-2,h=g;a<h;)d[h].y<f?a=h:g=h,h=Math.floor((a+g)/2);var k=[];g=a=h;if(d.length){for(;0<=a&&c(a);)a--;do g++;while(g<d.length&&c(g))}return k};Blockly.ConnectionDB.prototype.isInYRange_=function(a,b,c){return Math.abs(this.connections_[a].y-b)<=c};
Blockly.ConnectionDB.prototype.searchForClosest=function(a,b,c){if(!this.connections_.length)return{connection:null,radius:b};var d=a.y,e=a.x;a.x=e+c.x;a.y=d+c.y;var f=this.calculateIndexForYPos_(a.y);c=null;for(var g=b,h,k=f-1;0<=k&&this.isInYRange_(k,a.y,b);)h=this.connections_[k],this.connectionChecker_.canConnect(a,h,!0,g)&&(c=h,g=h.distanceFrom(a)),k--;for(;f<this.connections_.length&&this.isInYRange_(f,a.y,b);)h=this.connections_[f],this.connectionChecker_.canConnect(a,h,!0,g)&&(c=h,g=h.distanceFrom(a)),
f++;a.x=e;a.y=d;return{connection:c,radius:g}};Blockly.ConnectionDB.init=function(a){var b=[];b[Blockly.INPUT_VALUE]=new Blockly.ConnectionDB(a);b[Blockly.OUTPUT_VALUE]=new Blockly.ConnectionDB(a);b[Blockly.NEXT_STATEMENT]=new Blockly.ConnectionDB(a);b[Blockly.PREVIOUS_STATEMENT]=new Blockly.ConnectionDB(a);return b};Blockly.MarkerManager=function(a){this.cursorSvg_=this.cursor_=null;this.markers_={};this.workspace_=a};Blockly.MarkerManager.prototype.registerMarker=function(a,b){this.markers_[a]&&this.unregisterMarker(a);b.setDrawer(this.workspace_.getRenderer().makeMarkerDrawer(this.workspace_,b));this.setMarkerSvg(b.getDrawer().createDom());this.markers_[a]=b};
f++;a.x=e;a.y=d;return{connection:c,radius:g}};Blockly.ConnectionDB.init=function(a){var b=[];b[Blockly.INPUT_VALUE]=new Blockly.ConnectionDB(a);b[Blockly.OUTPUT_VALUE]=new Blockly.ConnectionDB(a);b[Blockly.NEXT_STATEMENT]=new Blockly.ConnectionDB(a);b[Blockly.PREVIOUS_STATEMENT]=new Blockly.ConnectionDB(a);return b};Blockly.Events.ThemeChange=function(a,b){Blockly.Events.ThemeChange.superClass_.constructor.call(this,b);this.themeName=a};Blockly.utils.object.inherits(Blockly.Events.ThemeChange,Blockly.Events.UiBase);Blockly.Events.ThemeChange.prototype.type=Blockly.Events.THEME_CHANGE;Blockly.Events.ThemeChange.prototype.toJson=function(){var a=Blockly.Events.ThemeChange.superClass_.toJson.call(this);a.themeName=this.themeName;return a};
Blockly.Events.ThemeChange.prototype.fromJson=function(a){Blockly.Events.ThemeChange.superClass_.fromJson.call(this,a);this.themeName=a.themeName};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.THEME_CHANGE,Blockly.Events.ThemeChange);Blockly.Events.ViewportChange=function(a,b,c,d){Blockly.Events.ViewportChange.superClass_.constructor.call(this,d);this.viewTop=a;this.viewLeft=b;this.scale=c};Blockly.utils.object.inherits(Blockly.Events.ViewportChange,Blockly.Events.UiBase);Blockly.Events.ViewportChange.prototype.type=Blockly.Events.VIEWPORT_CHANGE;
Blockly.Events.ViewportChange.prototype.toJson=function(){var a=Blockly.Events.ViewportChange.superClass_.toJson.call(this);a.viewTop=this.viewTop;a.viewLeft=this.viewLeft;a.scale=this.scale;return a};Blockly.Events.ViewportChange.prototype.fromJson=function(a){Blockly.Events.ViewportChange.superClass_.fromJson.call(this,a);this.viewTop=a.viewTop;this.viewLeft=a.viewLeft;this.scale=a.scale};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.VIEWPORT_CHANGE,Blockly.Events.ViewportChange);Blockly.MarkerManager=function(a){this.cursorSvg_=this.cursor_=null;this.markers_={};this.workspace_=a};Blockly.MarkerManager.prototype.registerMarker=function(a,b){this.markers_[a]&&this.unregisterMarker(a);b.setDrawer(this.workspace_.getRenderer().makeMarkerDrawer(this.workspace_,b));this.setMarkerSvg(b.getDrawer().createDom());this.markers_[a]=b};
Blockly.MarkerManager.prototype.unregisterMarker=function(a){var b=this.markers_[a];if(b)b.dispose(),delete this.markers_[a];else throw Error("Marker with id "+a+" does not exist. Can only unregistermarkers that exist.");};Blockly.MarkerManager.prototype.getCursor=function(){return this.cursor_};Blockly.MarkerManager.prototype.getMarker=function(a){return this.markers_[a]};
Blockly.MarkerManager.prototype.setCursor=function(a){this.cursor_&&this.cursor_.getDrawer()&&this.cursor_.getDrawer().dispose();if(this.cursor_=a)a=this.workspace_.getRenderer().makeMarkerDrawer(this.workspace_,this.cursor_),this.cursor_.setDrawer(a),this.setCursorSvg(this.cursor_.getDrawer().createDom())};Blockly.MarkerManager.prototype.setCursorSvg=function(a){a?(this.workspace_.getBlockCanvas().appendChild(a),this.cursorSvg_=a):this.cursorSvg_=null};
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()};
@@ -704,12 +709,12 @@ Blockly.WorkspaceAudio.prototype.play=function(a,b){var c=this.SOUNDS_[a];c?(a=n
[];this.audioManager_=new Blockly.WorkspaceAudio(a.parentWorkspace);this.grid_=this.options.gridPattern?new Blockly.Grid(this.options.gridPattern,a.gridOptions):null;this.markerManager_=new Blockly.MarkerManager(this);this.toolboxCategoryCallbacks_={};this.flyoutButtonCallbacks_={};Blockly.Variables&&Blockly.Variables.flyoutCategory&&this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,Blockly.Variables.flyoutCategory);Blockly.VariablesDynamic&&Blockly.VariablesDynamic.flyoutCategory&&
this.registerToolboxCategoryCallback(Blockly.VARIABLE_DYNAMIC_CATEGORY_NAME,Blockly.VariablesDynamic.flyoutCategory);Blockly.Procedures&&Blockly.Procedures.flyoutCategory&&(this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME,Blockly.Procedures.flyoutCategory),this.addChangeListener(Blockly.Procedures.mutatorOpenListener));this.themeManager_=this.options.parentWorkspace?this.options.parentWorkspace.getThemeManager():new Blockly.ThemeManager(this,this.options.theme||Blockly.Themes.Classic);
this.themeManager_.subscribeWorkspace(this);this.renderer_=Blockly.blockRendering.init(this.options.renderer||"geras",this.getTheme(),this.options.rendererOverrides);this.cachedParentSvg_=null;this.keyboardAccessibilityMode=!1;this.topBoundedElements_=[]};Blockly.utils.object.inherits(Blockly.WorkspaceSvg,Blockly.Workspace);Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_=null;Blockly.WorkspaceSvg.prototype.rendered=!0;Blockly.WorkspaceSvg.prototype.isVisible_=!0;
Blockly.WorkspaceSvg.prototype.isFlyout=!1;Blockly.WorkspaceSvg.prototype.isMutator=!1;Blockly.WorkspaceSvg.prototype.resizesEnabled_=!0;Blockly.WorkspaceSvg.prototype.scrollX=0;Blockly.WorkspaceSvg.prototype.scrollY=0;Blockly.WorkspaceSvg.prototype.startScrollX=0;Blockly.WorkspaceSvg.prototype.startScrollY=0;Blockly.WorkspaceSvg.prototype.dragDeltaXY_=null;Blockly.WorkspaceSvg.prototype.scale=1;Blockly.WorkspaceSvg.prototype.trashcan=null;Blockly.WorkspaceSvg.prototype.scrollbar=null;
Blockly.WorkspaceSvg.prototype.flyout_=null;Blockly.WorkspaceSvg.prototype.toolbox_=null;Blockly.WorkspaceSvg.prototype.currentGesture_=null;Blockly.WorkspaceSvg.prototype.blockDragSurface_=null;Blockly.WorkspaceSvg.prototype.workspaceDragSurface_=null;Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_=!1;Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_=!1;Blockly.WorkspaceSvg.prototype.injectionDiv_=null;Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_=null;
Blockly.WorkspaceSvg.prototype.targetWorkspace=null;Blockly.WorkspaceSvg.prototype.inverseScreenCTM_=null;Blockly.WorkspaceSvg.prototype.inverseScreenCTMDirty_=!0;Blockly.WorkspaceSvg.prototype.getMarkerManager=function(){return this.markerManager_};Blockly.WorkspaceSvg.prototype.setCursorSvg=function(a){this.markerManager_.setCursorSvg(a)};Blockly.WorkspaceSvg.prototype.setMarkerSvg=function(a){this.markerManager_.setMarkerSvg(a)};
Blockly.WorkspaceSvg.prototype.isFlyout=!1;Blockly.WorkspaceSvg.prototype.isMutator=!1;Blockly.WorkspaceSvg.prototype.resizesEnabled_=!0;Blockly.WorkspaceSvg.prototype.scrollX=0;Blockly.WorkspaceSvg.prototype.scrollY=0;Blockly.WorkspaceSvg.prototype.startScrollX=0;Blockly.WorkspaceSvg.prototype.startScrollY=0;Blockly.WorkspaceSvg.prototype.dragDeltaXY_=null;Blockly.WorkspaceSvg.prototype.scale=1;Blockly.WorkspaceSvg.prototype.oldScale_=1;Blockly.WorkspaceSvg.prototype.oldTop_=0;
Blockly.WorkspaceSvg.prototype.oldLeft_=0;Blockly.WorkspaceSvg.prototype.trashcan=null;Blockly.WorkspaceSvg.prototype.scrollbar=null;Blockly.WorkspaceSvg.prototype.flyout_=null;Blockly.WorkspaceSvg.prototype.toolbox_=null;Blockly.WorkspaceSvg.prototype.currentGesture_=null;Blockly.WorkspaceSvg.prototype.blockDragSurface_=null;Blockly.WorkspaceSvg.prototype.workspaceDragSurface_=null;Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_=!1;Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_=!1;
Blockly.WorkspaceSvg.prototype.injectionDiv_=null;Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_=null;Blockly.WorkspaceSvg.prototype.targetWorkspace=null;Blockly.WorkspaceSvg.prototype.inverseScreenCTM_=null;Blockly.WorkspaceSvg.prototype.inverseScreenCTMDirty_=!0;Blockly.WorkspaceSvg.prototype.getMarkerManager=function(){return this.markerManager_};Blockly.WorkspaceSvg.prototype.setCursorSvg=function(a){this.markerManager_.setCursorSvg(a)};Blockly.WorkspaceSvg.prototype.setMarkerSvg=function(a){this.markerManager_.setMarkerSvg(a)};
Blockly.WorkspaceSvg.prototype.getMarker=function(a){return this.markerManager_?this.markerManager_.getMarker(a):null};Blockly.WorkspaceSvg.prototype.getCursor=function(){return this.markerManager_?this.markerManager_.getCursor():null};Blockly.WorkspaceSvg.prototype.getRenderer=function(){return this.renderer_};Blockly.WorkspaceSvg.prototype.getThemeManager=function(){return this.themeManager_};Blockly.WorkspaceSvg.prototype.getTheme=function(){return this.themeManager_.getTheme()};
Blockly.WorkspaceSvg.prototype.setTheme=function(a){a||(a=Blockly.Themes.Classic);this.themeManager_.setTheme(a)};
Blockly.WorkspaceSvg.prototype.refreshTheme=function(){this.svgGroup_&&this.renderer_.refreshDom(this.svgGroup_,this.getTheme());this.updateBlockStyles_(this.getAllBlocks(!1).filter(function(b){return void 0!==b.getStyleName()}));this.refreshToolboxSelection();this.toolbox_&&this.toolbox_.refreshTheme();this.isVisible()&&this.setVisible(!0);var a=new Blockly.Events.Ui(null,"theme",null,null);a.workspaceId=this.id;Blockly.Events.fire(a)};
Blockly.WorkspaceSvg.prototype.refreshTheme=function(){this.svgGroup_&&this.renderer_.refreshDom(this.svgGroup_,this.getTheme());this.updateBlockStyles_(this.getAllBlocks(!1).filter(function(b){return void 0!==b.getStyleName()}));this.refreshToolboxSelection();this.toolbox_&&this.toolbox_.refreshTheme();this.isVisible()&&this.setVisible(!0);var a=new Blockly.Events.ThemeChange(this.getTheme().name,this.id);Blockly.Events.fire(a)};
Blockly.WorkspaceSvg.prototype.updateBlockStyles_=function(a){for(var b=0,c;c=a[b];b++){var d=c.getStyleName();d&&(c.setStyle(d),c.mutator&&c.mutator.updateBlockStyle())}};Blockly.WorkspaceSvg.prototype.getInverseScreenCTM=function(){if(this.inverseScreenCTMDirty_){var a=this.getParentSvg().getScreenCTM();a&&(this.inverseScreenCTM_=a.inverse(),this.inverseScreenCTMDirty_=!1)}return this.inverseScreenCTM_};
Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM=function(){this.inverseScreenCTMDirty_=!0};Blockly.WorkspaceSvg.prototype.isVisible=function(){return this.isVisible_};
Blockly.WorkspaceSvg.prototype.getSvgXY=function(a){var b=0,c=0,d=1;if(Blockly.utils.dom.containsNode(this.getCanvas(),a)||Blockly.utils.dom.containsNode(this.getBubbleCanvas(),a))d=this.scale;do{var e=Blockly.utils.getRelativeXY(a);if(a==this.getCanvas()||a==this.getBubbleCanvas())d=1;b+=e.x*d;c+=e.y*d;a=a.parentNode}while(a&&a!=this.getParentSvg());return new Blockly.utils.Coordinate(b,c)};Blockly.WorkspaceSvg.prototype.getOriginOffsetInPixels=function(){return Blockly.utils.getInjectionDivXY_(this.getCanvas())};
@@ -725,7 +730,8 @@ Blockly.WorkspaceSvg.prototype.addFlyout=function(a){var b=new Blockly.Options({
this.flyout_=new Blockly.VerticalFlyout(b)}this.flyout_.autoClose=!1;this.flyout_.getWorkspace().setVisible(!0);return this.flyout_.createDom(a)};Blockly.WorkspaceSvg.prototype.getFlyout=function(a){return this.flyout_||a?this.flyout_:this.toolbox_?this.toolbox_.getFlyout():null};Blockly.WorkspaceSvg.prototype.getToolbox=function(){return this.toolbox_};Blockly.WorkspaceSvg.prototype.updateScreenCalculations_=function(){this.updateInverseScreenCTM();this.recordDeleteAreas()};
Blockly.WorkspaceSvg.prototype.resizeContents=function(){this.resizesEnabled_&&this.rendered&&(this.scrollbar&&this.scrollbar.resize(),this.updateInverseScreenCTM())};Blockly.WorkspaceSvg.prototype.resize=function(){this.toolbox_&&this.toolbox_.position();this.flyout_&&this.flyout_.position();this.trashcan&&this.trashcan.position();this.zoomControls_&&this.zoomControls_.position();this.scrollbar&&this.scrollbar.resize();this.updateScreenCalculations_()};
Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled=function(){var a=Blockly.utils.getDocumentScroll();Blockly.utils.Coordinate.equals(this.lastRecordedPageScroll_,a)||(this.lastRecordedPageScroll_=a,this.updateScreenCalculations_())};Blockly.WorkspaceSvg.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.WorkspaceSvg.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};
Blockly.WorkspaceSvg.prototype.getParentSvg=function(){if(!this.cachedParentSvg_)for(var a=this.svgGroup_;a;){if("svg"==a.tagName){this.cachedParentSvg_=a;break}a=a.parentNode}return this.cachedParentSvg_};Blockly.WorkspaceSvg.prototype.maybeFireViewportChangeEvent=function(){};
Blockly.WorkspaceSvg.prototype.getParentSvg=function(){if(!this.cachedParentSvg_)for(var a=this.svgGroup_;a;){if("svg"==a.tagName){this.cachedParentSvg_=a;break}a=a.parentNode}return this.cachedParentSvg_};
Blockly.WorkspaceSvg.prototype.maybeFireViewportChangeEvent=function(){if(Blockly.Events.isEnabled()){var a=this.scale,b=-this.scrollY,c=-this.scrollX;a==this.oldScale_&&1>Math.abs(b-this.oldTop_)&&1>Math.abs(c-this.oldLeft_)||(this.oldScale_=a,this.oldTop_=b,this.oldLeft_=c,a=new Blockly.Events.ViewportChange(b,c,a,this.id),Blockly.Events.fire(a))}};
Blockly.WorkspaceSvg.prototype.translate=function(a,b){if(this.useWorkspaceDragSurface_&&this.isDragSurfaceActive_)this.workspaceDragSurface_.translateSurface(a,b);else{var c="translate("+a+","+b+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",c);this.svgBubbleCanvas_.setAttribute("transform",c)}this.blockDragSurface_&&this.blockDragSurface_.translateAndScaleGroup(a,b,this.scale);this.grid_&&this.grid_.moveTo(a,b);this.maybeFireViewportChangeEvent()};
Blockly.WorkspaceSvg.prototype.resetDragSurface=function(){if(this.useWorkspaceDragSurface_){this.isDragSurfaceActive_=!1;var a=this.workspaceDragSurface_.getSurfaceTranslation();this.workspaceDragSurface_.clearAndHide(this.svgGroup_);a="translate("+a.x+","+a.y+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",a);this.svgBubbleCanvas_.setAttribute("transform",a)}};
Blockly.WorkspaceSvg.prototype.setupDragSurface=function(){if(this.useWorkspaceDragSurface_&&!this.isDragSurfaceActive_){this.isDragSurfaceActive_=!0;var a=this.svgBlockCanvas_.previousSibling,b=parseInt(this.getParentSvg().getAttribute("width"),10),c=parseInt(this.getParentSvg().getAttribute("height"),10),d=Blockly.utils.getRelativeXY(this.getCanvas());this.workspaceDragSurface_.setContentsAndShow(this.getCanvas(),this.getBubbleCanvas(),a,b,c,this.scale);this.workspaceDragSurface_.translateSurface(d.x,
@@ -736,7 +742,7 @@ Blockly.WorkspaceSvg.prototype.highlightBlock=function(a,b){if(void 0===b){for(v
Blockly.WorkspaceSvg.prototype.paste=function(a){!this.rendered||!a.tagName||a.getElementsByTagName("block").length>=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();
if(1>=Math.abs(e-k.x)&&1>=Math.abs(f-k.y)){a=!0;break}}if(!a){var l=b.getConnections_(!1);c=0;for(var m;m=l[c];c++)if(m.closest(Blockly.SNAP_RADIUS,new Blockly.utils.Coordinate(e,f)).connection){a=!0;break}}a&&(e=this.RTL?e-Blockly.SNAP_RADIUS:e+Blockly.SNAP_RADIUS,f+=2*Blockly.SNAP_RADIUS)}while(a);b.moveBy(e,f)}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(b));b.select()};
Blockly.WorkspaceSvg.prototype.pasteWorkspaceComment_=function(a){Blockly.Events.disable();try{var b=Blockly.WorkspaceCommentSvg.fromXml(a,this),c=parseInt(a.getAttribute("x"),10),d=parseInt(a.getAttribute("y"),10);isNaN(c)||isNaN(d)||(this.RTL&&(c=-c),b.moveBy(c+50,d+50))}finally{Blockly.Events.enable()}Blockly.Events.isEnabled();b.select()};
Blockly.WorkspaceSvg.prototype.pasteWorkspaceComment_=function(a){Blockly.Events.disable();try{var b=Blockly.WorkspaceCommentSvg.fromXml(a,this),c=parseInt(a.getAttribute("x"),10),d=parseInt(a.getAttribute("y"),10);isNaN(c)||isNaN(d)||(this.RTL&&(c=-c),b.moveBy(c+50,d+50))}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&Blockly.WorkspaceComment.fireCreateEvent(b);b.select()};
Blockly.WorkspaceSvg.prototype.refreshToolboxSelection=function(){var a=this.isFlyout?this.targetWorkspace:this;a&&!a.currentGesture_&&a.toolbox_&&a.toolbox_.getFlyout()&&a.toolbox_.refreshSelection()};Blockly.WorkspaceSvg.prototype.renameVariableById=function(a,b){Blockly.WorkspaceSvg.superClass_.renameVariableById.call(this,a,b);this.refreshToolboxSelection()};Blockly.WorkspaceSvg.prototype.deleteVariableById=function(a){Blockly.WorkspaceSvg.superClass_.deleteVariableById.call(this,a);this.refreshToolboxSelection()};
Blockly.WorkspaceSvg.prototype.createVariable=function(a,b,c){a=Blockly.WorkspaceSvg.superClass_.createVariable.call(this,a,b,c);this.refreshToolboxSelection();return a};Blockly.WorkspaceSvg.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan&&this.svgGroup_.parentNode?this.trashcan.getClientRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getClientRect():this.toolbox_&&"function"==typeof this.toolbox_.getClientRect?this.toolbox_.getClientRect():null};
Blockly.WorkspaceSvg.prototype.isDeleteArea=function(a){return this.deleteAreaTrash_&&this.deleteAreaTrash_.contains(a.clientX,a.clientY)?Blockly.DELETE_AREA_TRASH:this.deleteAreaToolbox_&&this.deleteAreaToolbox_.contains(a.clientX,a.clientY)?Blockly.DELETE_AREA_TOOLBOX:Blockly.DELETE_AREA_NONE};Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){var b=this.getGesture(a);b&&b.handleWsStart(a,this)};
@@ -749,7 +755,7 @@ this.zoom(b.x,b.y,d));a.preventDefault()}}};Blockly.WorkspaceSvg.prototype.getBl
Blockly.WorkspaceSvg.prototype.cleanUp=function(){this.setResizesEnabled(!1);Blockly.Events.setGroup(!0);for(var a=this.getTopBlocks(!0),b=0,c=0,d;d=a[c];c++)if(d.isMovable()){var e=d.getRelativeToSurfaceXY();d.moveBy(-e.x,b-e.y);d.snapToGrid();b=d.getRelativeToSurfaceXY().y+d.getHeightWidth().height+this.renderer_.getConstants().MIN_BLOCK_HEIGHT}Blockly.Events.setGroup(!1);this.setResizesEnabled(!0)};
Blockly.WorkspaceSvg.prototype.showContextMenu=function(a){if(!this.options.readOnly&&!this.isFlyout){var b=Blockly.ContextMenuRegistry.registry.getContextMenuOptions(Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,{workspace:this});this.configureContextMenu&&this.configureContextMenu(b,a);Blockly.ContextMenu.show(a,b,this.RTL)}};
Blockly.WorkspaceSvg.prototype.updateToolbox=function(a){if(a=Blockly.utils.toolbox.convertToolboxDefToJson(a)){if(!this.options.languageTree)throw Error("Existing toolbox is null. Can't create new toolbox.");if(Blockly.utils.toolbox.hasCategories(a)){if(!this.toolbox_)throw Error("Existing toolbox has no categories. Can't change mode.");this.options.languageTree=a;this.toolbox_.render(a)}else{if(!this.flyout_)throw Error("Existing toolbox has categories. Can't change mode.");this.options.languageTree=
a;this.flyout_.show(a)}}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})}}};
a;this.flyout_.show(a)}}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&&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:d<this.options.zoomOptions.minScale&&(c=this.options.zoomOptions.minScale/this.scale);var e=this.getCanvas().getCTM(),f=this.getParentSvg().createSVGPoint();f.x=a;f.y=b;f=f.matrixTransform(e.inverse());a=f.x;b=f.y;e=e.translate(a*(1-c),b*(1-c)).scale(c);this.scrollX=e.e;this.scrollY=
e.f;this.setScale(d)}};Blockly.WorkspaceSvg.prototype.zoomCenter=function(a){var b=this.getMetrics();if(this.flyout_){var c=b.svgWidth?b.svgWidth/2:0;b=b.svgHeight?b.svgHeight/2:0}else c=b.viewWidth/2+b.absoluteLeft,b=b.viewHeight/2+b.absoluteTop;this.zoom(c,b,a)};
Blockly.WorkspaceSvg.prototype.zoomToFit=function(){if(this.isMovable()){var a=this.getMetrics(),b=a.viewWidth;a=a.viewHeight;var c=this.getBlocksBoundingBox(),d=c.right-c.left;c=c.bottom-c.top;if(d){this.flyout_&&(this.horizontalLayout?(a+=this.flyout_.getHeight(),c+=this.flyout_.getHeight()/this.scale):(b+=this.flyout_.getWidth(),d+=this.flyout_.getWidth()/this.scale));b/=d;a/=c;Blockly.Events.disable();try{this.setScale(Math.min(b,a)),this.scrollCenter()}finally{Blockly.Events.enable()}this.maybeFireViewportChangeEvent()}}else console.warn("Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.")};
@@ -773,9 +779,8 @@ Blockly.WorkspaceSvg.prototype.clear=function(){this.setResizesEnabled(!1);Block
Blockly.WorkspaceSvg.prototype.removeButtonCallback=function(a){this.flyoutButtonCallbacks_[a]=null};Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback=function(a,b){if("function"!=typeof b)throw TypeError("Toolbox category callbacks must be functions.");this.toolboxCategoryCallbacks_[a]=b};Blockly.WorkspaceSvg.prototype.getToolboxCategoryCallback=function(a){return this.toolboxCategoryCallbacks_[a]||null};
Blockly.WorkspaceSvg.prototype.removeToolboxCategoryCallback=function(a){this.toolboxCategoryCallbacks_[a]=null};Blockly.WorkspaceSvg.prototype.getGesture=function(a){var b="mousedown"==a.type||"touchstart"==a.type||"pointerdown"==a.type,c=this.currentGesture_;return c?b&&c.hasStarted()?(console.warn("Tried to start the same gesture twice."),c.cancel(),null):c:b?this.currentGesture_=new Blockly.TouchGesture(a,this):null};
Blockly.WorkspaceSvg.prototype.clearGesture=function(){this.currentGesture_=null};Blockly.WorkspaceSvg.prototype.cancelCurrentGesture=function(){this.currentGesture_&&this.currentGesture_.cancel()};Blockly.WorkspaceSvg.prototype.getAudioManager=function(){return this.audioManager_};Blockly.WorkspaceSvg.prototype.getGrid=function(){return this.grid_};Blockly.inject=function(a,b){Blockly.checkBlockColourConstants();"string"==typeof a&&(a=document.getElementById(a)||document.querySelector(a));if(!a||!Blockly.utils.dom.containsNode(document,a))throw Error("Error: container is not in current document.");b=new Blockly.Options(b||{});var c=document.createElement("div");c.className="injectionDiv";c.tabIndex=0;Blockly.utils.aria.setState(c,Blockly.utils.aria.State.LABEL,Blockly.Msg.WORKSPACE_ARIA_LABEL);a.appendChild(c);a=Blockly.createDom_(c,b);var d=
new Blockly.BlockDragSurfaceSvg(c),e=new Blockly.WorkspaceDragSurfaceSvg(c),f=Blockly.createMainWorkspace_(a,b,d,e);Blockly.user.keyMap.setKeyMap(b.keyMap);Blockly.init_(f);Blockly.mainWorkspace=f;Blockly.svgResize(f);c.addEventListener("focusin",function(){Blockly.mainWorkspace=f});return f};
Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");Blockly.Component.defaultRightToLeft=b.RTL;Blockly.Css.inject(b.hasCss,b.pathToMedia);a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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":"blocklySvg",tabindex:"0"},a);var c=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS,{},a),d=String(Math.random()).substring(2);b.gridPattern=Blockly.Grid.createDom(d,
b.gridOptions,c);return a};
new Blockly.BlockDragSurfaceSvg(c),e=new Blockly.WorkspaceDragSurfaceSvg(c),f=Blockly.createMainWorkspace_(a,b,d,e);Blockly.init_(f);Blockly.mainWorkspace=f;Blockly.svgResize(f);c.addEventListener("focusin",function(){Blockly.mainWorkspace=f});return f};
Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");Blockly.Css.inject(b.hasCss,b.pathToMedia);a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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":"blocklySvg",tabindex:"0"},a);var c=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS,{},a),d=String(Math.random()).substring(2);b.gridPattern=Blockly.Grid.createDom(d,b.gridOptions,c);return a};
Blockly.createMainWorkspace_=function(a,b,c,d){b.parentWorkspace=null;var e=new Blockly.WorkspaceSvg(b,c,d);b=e.options;e.scale=b.zoomOptions.startScale;a.appendChild(e.createDom("blocklyMainBackground"));Blockly.utils.dom.addClass(e.getInjectionDiv(),e.getRenderer().getClassName());Blockly.utils.dom.addClass(e.getInjectionDiv(),e.getTheme().getClassName());!b.hasCategories&&b.languageTree&&(c=e.addFlyout(Blockly.utils.Svg.SVG),Blockly.utils.dom.insertAfter(c,a));b.hasTrashcan&&e.addTrashcan();b.zoomOptions&&
b.zoomOptions.controls&&e.addZoomControls();e.getThemeManager().subscribe(a,"workspaceBackgroundColour","background-color");e.translate(0,0);b.readOnly||e.isMovable()||e.addChangeListener(function(f){if(!e.isDragging()&&!e.isMovable()&&-1!=Blockly.Events.BUMP_EVENTS.indexOf(f.type)){var g=Object.create(null),h=e.getMetrics(),k=e.scale;g.RTL=e.RTL;g.viewLeft=h.viewLeft/k;g.viewTop=h.viewTop/k;g.viewRight=(h.viewLeft+h.viewWidth)/k;g.viewBottom=(h.viewTop+h.viewHeight)/k;e.isContentBounded()?(h=e.getBlocksBoundingBox(),
g.contentLeft=h.left,g.contentTop=h.top,g.contentRight=h.right,g.contentBottom=h.bottom):(g.contentLeft=h.contentLeft/k,g.contentTop=h.contentTop/k,g.contentRight=(h.contentLeft+h.contentWidth)/k,g.contentBottom=(h.contentTop+h.contentHeight)/k);if(g.contentTop<g.viewTop||g.contentBottom>g.viewBottom||g.contentLeft<g.viewLeft||g.contentRight>g.viewRight){h=null;f&&(h=Blockly.Events.getGroup(),Blockly.Events.setGroup(f.group));switch(f.type){case Blockly.Events.BLOCK_CREATE:case Blockly.Events.BLOCK_MOVE:var l=
@@ -796,10 +801,31 @@ Blockly.Procedures.flyoutCategory=function(a){function b(f,g){for(var h=0;h<f.le
d.setAttribute("type","procedures_defnoreturn");d.setAttribute("gap",16);var e=Blockly.utils.xml.createElement("field");e.setAttribute("name","NAME");e.appendChild(Blockly.utils.xml.createTextNode(Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE));d.appendChild(e);c.push(d)}Blockly.Blocks.procedures_defreturn&&(d=Blockly.utils.xml.createElement("block"),d.setAttribute("type","procedures_defreturn"),d.setAttribute("gap",16),e=Blockly.utils.xml.createElement("field"),e.setAttribute("name","NAME"),e.appendChild(Blockly.utils.xml.createTextNode(Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE)),
d.appendChild(e),c.push(d));Blockly.Blocks.procedures_ifreturn&&(d=Blockly.utils.xml.createElement("block"),d.setAttribute("type","procedures_ifreturn"),d.setAttribute("gap",16),c.push(d));c.length&&c[c.length-1].setAttribute("gap",24);a=Blockly.Procedures.allProcedures(a);b(a[0],"procedures_callnoreturn");b(a[1],"procedures_callreturn");return c};
Blockly.Procedures.updateMutatorFlyout_=function(a){for(var b=[],c=a.getBlocksByType("procedures_mutatorarg",!1),d=0,e;e=c[d];d++)b.push(e.getFieldValue("NAME"));c=Blockly.utils.xml.createElement("xml");d=Blockly.utils.xml.createElement("block");d.setAttribute("type","procedures_mutatorarg");e=Blockly.utils.xml.createElement("field");e.setAttribute("name","NAME");b=Blockly.Variables.generateUniqueNameFromOptions(Blockly.Procedures.DEFAULT_ARG,b);b=Blockly.utils.xml.createTextNode(b);e.appendChild(b);
d.appendChild(e);c.appendChild(d);a.updateToolbox(c)};Blockly.Procedures.mutatorOpenListener=function(a){if(a.type==Blockly.Events.UI&&"mutatorOpen"==a.element&&a.newValue){a=Blockly.Workspace.getById(a.workspaceId).getBlockById(a.blockId);var b=a.type;if("procedures_defnoreturn"==b||"procedures_defreturn"==b)a=a.mutator.getWorkspace(),Blockly.Procedures.updateMutatorFlyout_(a),a.addChangeListener(Blockly.Procedures.mutatorChangeListener_)}};
d.appendChild(e);c.appendChild(d);a.updateToolbox(c)};Blockly.Procedures.mutatorOpenListener=function(a){if(a.type==Blockly.Events.BUBBLE_OPEN&&"mutator"===a.bubbleType&&a.isOpen){a=Blockly.Workspace.getById(a.workspaceId).getBlockById(a.blockId);var b=a.type;if("procedures_defnoreturn"==b||"procedures_defreturn"==b)a=a.mutator.getWorkspace(),Blockly.Procedures.updateMutatorFlyout_(a),a.addChangeListener(Blockly.Procedures.mutatorChangeListener_)}};
Blockly.Procedures.mutatorChangeListener_=function(a){if(a.type==Blockly.Events.BLOCK_CREATE||a.type==Blockly.Events.BLOCK_DELETE||a.type==Blockly.Events.BLOCK_CHANGE)a=Blockly.Workspace.getById(a.workspaceId),Blockly.Procedures.updateMutatorFlyout_(a)};Blockly.Procedures.getCallers=function(a,b){var c=[];b=b.getAllBlocks(!1);for(var d=0;d<b.length;d++)if(b[d].getProcedureCall){var e=b[d].getProcedureCall();e&&Blockly.Names.equals(e,a)&&c.push(b[d])}return c};
Blockly.Procedures.mutateCallers=function(a){var b=Blockly.Events.recordUndo,c=a.getProcedureDef()[0],d=a.mutationToDom(!0);a=Blockly.Procedures.getCallers(c,a.workspace);c=0;for(var e;e=a[c];c++){var f=e.mutationToDom();f=f&&Blockly.Xml.domToText(f);e.domToMutation(d);var g=e.mutationToDom();g=g&&Blockly.Xml.domToText(g);f!=g&&(Blockly.Events.recordUndo=!1,Blockly.Events.fire(new Blockly.Events.BlockChange(e,"mutation",null,f,g)),Blockly.Events.recordUndo=b)}};
Blockly.Procedures.getDefinition=function(a,b){b=b.getTopBlocks(!1);for(var c=0;c<b.length;c++)if(b[c].getProcedureDef){var d=b[c].getProcedureDef();if(d&&Blockly.Names.equals(d[0],a))return b[c]}return null};Blockly.VariableModel=function(a,b,c,d){this.workspace=a;this.name=b;this.type=c||"";this.id_=d||Blockly.utils.genUid();Blockly.Events.fire(new Blockly.Events.VarCreate(this))};Blockly.VariableModel.prototype.getId=function(){return this.id_};Blockly.VariableModel.compareByName=function(a,b){a=a.name.toLowerCase();b=b.name.toLowerCase();return a<b?-1:a==b?0:1};Blockly.Variables={};Blockly.Variables.NAME_TYPE=Blockly.VARIABLE_CATEGORY_NAME;Blockly.Variables.allUsedVarModels=function(a){var b=a.getAllBlocks(!1);a=Object.create(null);for(var c=0;c<b.length;c++){var d=b[c].getVarModels();if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.getId();g&&(a[g]=f)}}b=[];for(g in a)b.push(a[g]);return b};Blockly.Variables.ALL_DEVELOPER_VARS_WARNINGS_BY_BLOCK_TYPE_={};
Blockly.Procedures.getDefinition=function(a,b){b=b.getTopBlocks(!1);for(var c=0;c<b.length;c++)if(b[c].getProcedureDef){var d=b[c].getProcedureDef();if(d&&Blockly.Names.equals(d[0],a))return b[c]}return null};Blockly.ShortcutItems={};Blockly.ShortcutItems.names={ESCAPE:"escape",DELETE:"delete",COPY:"copy",CUT:"cut",PASTE:"paste",UNDO:"undo",REDO:"redo"};Blockly.ShortcutItems.registerEscape=function(){var a={name:Blockly.ShortcutItems.names.ESCAPE,preconditionFn:function(b){return!b.options.readOnly},callback:function(){Blockly.hideChaff();return!0}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.ESC,a.name)};
Blockly.ShortcutItems.registerDelete=function(){var a={name:Blockly.ShortcutItems.names.DELETE,preconditionFn:function(b){return!b.options.readOnly&&Blockly.selected&&Blockly.selected.isDeletable()},callback:function(b,c){c.preventDefault();if(Blockly.Gesture.inProgress())return!1;Blockly.deleteBlock(Blockly.selected);return!0}};Blockly.ShortcutRegistry.registry.register(a);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.DELETE,a.name);Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.BACKSPACE,
a.name)};
Blockly.ShortcutItems.registerCopy=function(){var a={name:Blockly.ShortcutItems.names.COPY,preconditionFn:function(c){return!c.options.readOnly&&!Blockly.Gesture.inProgress()&&Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()},callback:function(){Blockly.hideChaff();Blockly.copy(Blockly.selected);return!0}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.C,[Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,
a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.C,[Blockly.utils.KeyCodes.ALT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.C,[Blockly.utils.KeyCodes.META]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.ShortcutItems.registerCut=function(){var a={name:Blockly.ShortcutItems.names.CUT,preconditionFn:function(c){return!c.options.readOnly&&!Blockly.Gesture.inProgress()&&Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()&&!Blockly.selected.workspace.isFlyout},callback:function(){Blockly.copy(Blockly.selected);Blockly.deleteBlock(Blockly.selected);return!0}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.X,
[Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.X,[Blockly.utils.KeyCodes.ALT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.X,[Blockly.utils.KeyCodes.META]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.ShortcutItems.registerPaste=function(){var a={name:Blockly.ShortcutItems.names.PASTE,preconditionFn:function(c){return!c.options.readOnly&&!Blockly.Gesture.inProgress()},callback:function(){return Blockly.paste()}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.V,[Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.V,
[Blockly.utils.KeyCodes.ALT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.V,[Blockly.utils.KeyCodes.META]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.ShortcutItems.registerUndo=function(){var a={name:Blockly.ShortcutItems.names.UNDO,preconditionFn:function(c){return!c.options.readOnly&&!Blockly.Gesture.inProgress()},callback:function(c){Blockly.hideChaff();c.undo(!1);return!0}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,[Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,
[Blockly.utils.KeyCodes.ALT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,[Blockly.utils.KeyCodes.META]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.ShortcutItems.registerRedo=function(){var a={name:Blockly.ShortcutItems.names.REDO,preconditionFn:function(c){return!Blockly.Gesture.inProgress()&&!c.options.readOnly},callback:function(c){Blockly.hideChaff();c.undo(!0);return!0}};Blockly.ShortcutRegistry.registry.register(a);var b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,[Blockly.utils.KeyCodes.SHIFT,Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,
[Blockly.utils.KeyCodes.SHIFT,Blockly.utils.KeyCodes.ALT]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Z,[Blockly.utils.KeyCodes.SHIFT,Blockly.utils.KeyCodes.META]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name);b=Blockly.ShortcutRegistry.registry.createSerializedKey(Blockly.utils.KeyCodes.Y,[Blockly.utils.KeyCodes.CTRL]);Blockly.ShortcutRegistry.registry.addKeyMapping(b,a.name)};
Blockly.ShortcutItems.registerDefaultShortcuts=function(){Blockly.ShortcutItems.registerEscape();Blockly.ShortcutItems.registerDelete();Blockly.ShortcutItems.registerCopy();Blockly.ShortcutItems.registerCut();Blockly.ShortcutItems.registerPaste();Blockly.ShortcutItems.registerUndo();Blockly.ShortcutItems.registerRedo()};Blockly.ShortcutRegistry=function(){Blockly.ShortcutRegistry.registry=this;this.registry_=Object.create(null);this.keyMap_=Object.create(null);Blockly.ShortcutItems.registerDefaultShortcuts();Blockly.navigation.registerNavigationShortcuts()};Blockly.ShortcutRegistry.modifierKeys={Shift:Blockly.utils.KeyCodes.SHIFT,Control:Blockly.utils.KeyCodes.CTRL,Alt:Blockly.utils.KeyCodes.ALT,Meta:Blockly.utils.KeyCodes.META};
Blockly.ShortcutRegistry.prototype.register=function(a,b){if(this.registry_[a.name]&&!b)throw Error('Shortcut with name "'+a.name+'" already exists.');this.registry_[a.name]=a};Blockly.ShortcutRegistry.prototype.unregister=function(a){if(!this.registry_[a])return console.warn('Keyboard shortcut with name "'+a+'" not found.'),!1;this.removeAllKeyMappings(a);delete this.registry_[a];return!0};
Blockly.ShortcutRegistry.prototype.addKeyMapping=function(a,b,c){var d=this.keyMap_[a];if(d&&!c)throw Error('Shortcut with name "'+b+'" collides with shortcuts '+d.toString());d&&c?d.unshift(b):this.keyMap_[a]=[b]};
Blockly.ShortcutRegistry.prototype.removeKeyMapping=function(a,b,c){var d=this.keyMap_[a];if(!d&&!c)return console.warn('No keyboard shortcut with name "'+b+'" registered with key code "'+a+'"'),!1;var e=d.indexOf(b);if(-1<e)return d.splice(e,1),0==d.length&&delete this.keyMap_[a],!0;c||console.warn('No keyboard shortcut with name "'+b+'" registered with key code "'+a+'"');return!1};
Blockly.ShortcutRegistry.prototype.removeAllKeyMappings=function(a){for(var b in this.keyMap_)this.removeKeyMapping(b,a,!0)};Blockly.ShortcutRegistry.prototype.setKeyMap=function(a){this.keyMap_=a};Blockly.ShortcutRegistry.prototype.getKeyMap=function(){return Blockly.utils.object.deepMerge(Object.create(null),this.keyMap_)};Blockly.ShortcutRegistry.prototype.getRegistry=function(){return Blockly.utils.object.deepMerge(Object.create(null),this.registry_)};
Blockly.ShortcutRegistry.prototype.onKeyDown=function(a,b){var c=this.serializeKeyEvent_(b);c=this.getShortcutNamesByKeyCode(c);if(!c)return!1;for(var d=0,e;e=c[d];d++)if(e=this.registry_[e],(!e.preconditionFn||e.preconditionFn(a))&&e.callback&&e.callback(a,b,e))return!0;return!1};Blockly.ShortcutRegistry.prototype.getShortcutNamesByKeyCode=function(a){return this.keyMap_[a]||[]};
Blockly.ShortcutRegistry.prototype.getKeyCodesByShortcutName=function(a){var b=[],c;for(c in this.keyMap_)-1<this.keyMap_[c].indexOf(a)&&b.push(c);return b};Blockly.ShortcutRegistry.prototype.serializeKeyEvent_=function(a){var b="",c;for(c in Blockly.ShortcutRegistry.modifierKeys)a.getModifierState(c)&&(""!=b&&(b+="+"),b+=c);""!=b&&a.keyCode?b=b+"+"+a.keyCode:a.keyCode&&(b=a.keyCode.toString());return b};
Blockly.ShortcutRegistry.prototype.checkModifiers_=function(a){for(var b=Blockly.utils.object.values(Blockly.ShortcutRegistry.modifierKeys),c=0,d;d=a[c];c++)if(0>b.indexOf(d))throw Error(d+" is not a valid modifier key.");};
Blockly.ShortcutRegistry.prototype.createSerializedKey=function(a,b){var c="";if(b){this.checkModifiers_(b);for(var d in Blockly.ShortcutRegistry.modifierKeys)-1<b.indexOf(Blockly.ShortcutRegistry.modifierKeys[d])&&(""!=c&&(c+="+"),c+=d)}""!=c&&a?c=c+"+"+a:a&&(c=a.toString());return c};new Blockly.ShortcutRegistry;Blockly.VariableModel=function(a,b,c,d){this.workspace=a;this.name=b;this.type=c||"";this.id_=d||Blockly.utils.genUid();Blockly.Events.fire(new Blockly.Events.VarCreate(this))};Blockly.VariableModel.prototype.getId=function(){return this.id_};Blockly.VariableModel.compareByName=function(a,b){a=a.name.toLowerCase();b=b.name.toLowerCase();return a<b?-1:a==b?0:1};Blockly.Variables={};Blockly.Variables.NAME_TYPE=Blockly.VARIABLE_CATEGORY_NAME;Blockly.Variables.allUsedVarModels=function(a){var b=a.getAllBlocks(!1);a=Object.create(null);for(var c=0;c<b.length;c++){var d=b[c].getVarModels();if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.getId();g&&(a[g]=f)}}b=[];for(g in a)b.push(a[g]);return b};Blockly.Variables.ALL_DEVELOPER_VARS_WARNINGS_BY_BLOCK_TYPE_={};
Blockly.Variables.allDeveloperVariables=function(a){a=a.getAllBlocks(!1);for(var b=Object.create(null),c=0,d;d=a[c];c++){var e=d.getDeveloperVariables;!e&&d.getDeveloperVars&&(e=d.getDeveloperVars,Blockly.Variables.ALL_DEVELOPER_VARS_WARNINGS_BY_BLOCK_TYPE_[d.type]||(console.warn("Function getDeveloperVars() deprecated. Use getDeveloperVariables() (block type '"+d.type+"')"),Blockly.Variables.ALL_DEVELOPER_VARS_WARNINGS_BY_BLOCK_TYPE_[d.type]=!0));if(e)for(d=e(),e=0;e<d.length;e++)b[d[e]]=!0}return Object.keys(b)};
Blockly.Variables.flyoutCategory=function(a){var b=[],c=document.createElement("button");c.setAttribute("text","%{BKY_NEW_VARIABLE}");c.setAttribute("callbackKey","CREATE_VARIABLE");a.registerButtonCallback("CREATE_VARIABLE",function(d){Blockly.Variables.createVariableButtonHandler(d.getTargetWorkspace())});b.push(c);a=Blockly.Variables.flyoutCategoryBlocks(a);return b=b.concat(a)};
Blockly.Variables.flyoutCategoryBlocks=function(a){a=a.getVariablesOfType("");var b=[];if(0<a.length){var c=a[a.length-1];if(Blockly.Blocks.variables_set){var d=Blockly.utils.xml.createElement("block");d.setAttribute("type","variables_set");d.setAttribute("gap",Blockly.Blocks.math_change?8:24);d.appendChild(Blockly.Variables.generateVariableFieldDom(c));b.push(d)}Blockly.Blocks.math_change&&(d=Blockly.utils.xml.createElement("block"),d.setAttribute("type","math_change"),d.setAttribute("gap",Blockly.Blocks.variables_get?
@@ -817,12 +843,11 @@ Blockly.WidgetDiv.show=function(a,b,c){Blockly.WidgetDiv.hide();Blockly.WidgetDi
Blockly.WidgetDiv.hide=function(){if(Blockly.WidgetDiv.isVisible()){Blockly.WidgetDiv.owner_=null;var a=Blockly.WidgetDiv.DIV;a.style.display="none";a.style.left="";a.style.top="";Blockly.WidgetDiv.dispose_&&Blockly.WidgetDiv.dispose_();Blockly.WidgetDiv.dispose_=null;a.textContent="";Blockly.WidgetDiv.rendererClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.WidgetDiv.rendererClassName_),Blockly.WidgetDiv.rendererClassName_="");Blockly.WidgetDiv.themeClassName_&&(Blockly.utils.dom.removeClass(a,
Blockly.WidgetDiv.themeClassName_),Blockly.WidgetDiv.themeClassName_="");Blockly.getMainWorkspace().markFocused()}};Blockly.WidgetDiv.isVisible=function(){return!!Blockly.WidgetDiv.owner_};Blockly.WidgetDiv.hideIfOwner=function(a){Blockly.WidgetDiv.owner_==a&&Blockly.WidgetDiv.hide()};Blockly.WidgetDiv.positionInternal_=function(a,b,c){Blockly.WidgetDiv.DIV.style.left=a+"px";Blockly.WidgetDiv.DIV.style.top=b+"px";Blockly.WidgetDiv.DIV.style.height=c+"px"};
Blockly.WidgetDiv.positionWithAnchor=function(a,b,c,d){var e=Blockly.WidgetDiv.calculateY_(a,b,c);a=Blockly.WidgetDiv.calculateX_(a,b,c,d);0>e?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.20200924.4";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 new Blockly.utils.Size(a.cachedWidth_,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.Gesture.inProgress()&&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_,a.isFlyout&&(a=a.targetWorkspace),Blockly.clipboardTypeCounts_&&a.isCapacityAvailable(Blockly.clipboardTypeCounts_)&&(Blockly.Events.setGroup(!0),a.paste(Blockly.clipboardXml_),Blockly.Events.setGroup(!1))):a.keyCode==Blockly.utils.KeyCodes.Z?(Blockly.hideChaff(),b.undo(a.shiftKey)):a.ctrlKey&&a.keyCode==Blockly.utils.KeyCodes.Y&&(Blockly.hideChaff(),b.undo(!0))}}c&&!Blockly.selected.workspace.isFlyout&&(Blockly.Events.setGroup(!0),Blockly.hideChaff(),Blockly.selected.dispose(!0,
!0),Blockly.Events.setGroup(!1))}};Blockly.copy_=function(a){if(a=a.toCopyData())Blockly.clipboardXml_=a.xml,Blockly.clipboardSource_=a.source,Blockly.clipboardTypeCounts_=a.typeCounts};Blockly.duplicate=function(a){var b=Blockly.clipboardXml_,c=Blockly.clipboardSource_;Blockly.copy_(a);a.workspace.paste(Blockly.clipboardXml_);Blockly.clipboardXml_=b;Blockly.clipboardSource_=c};Blockly.onContextMenu_=function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()};
Blockly.WidgetDiv.calculateY_=function(a,b,c){return b.bottom+c.height>=a.bottom?b.top-c.height:b.bottom};Blockly.VERSION="4.20201217.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 new Blockly.utils.Size(a.cachedWidth_,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()))Blockly.ShortcutRegistry.registry.onKeyDown(b,a)};
Blockly.deleteBlock=function(a){a.workspace.isFlyout||(Blockly.Events.setGroup(!0),Blockly.hideChaff(),a.dispose(!0,!0),Blockly.Events.setGroup(!1))};Blockly.copy=function(a){if(a=a.toCopyData())Blockly.clipboardXml_=a.xml,Blockly.clipboardSource_=a.source,Blockly.clipboardTypeCounts_=a.typeCounts};
Blockly.paste=function(){if(!Blockly.clipboardXml_)return!1;var a=Blockly.clipboardSource_;a.isFlyout&&(a=a.targetWorkspace);return Blockly.clipboardTypeCounts_&&a.isCapacityAvailable(Blockly.clipboardTypeCounts_)?(Blockly.Events.setGroup(!0),a.paste(Blockly.clipboardXml_),Blockly.Events.setGroup(!1),!0):!1};
Blockly.duplicate=function(a){var b=Blockly.clipboardXml_,c=Blockly.clipboardSource_;Blockly.copy(a);a.workspace.paste(Blockly.clipboardXml_);Blockly.clipboardXml_=b;Blockly.clipboardSource_=c};Blockly.onContextMenu_=function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()};
Blockly.hideChaff=function(a){Blockly.Tooltip.hide();Blockly.WidgetDiv.hide();Blockly.DropDownDiv.hideWithoutAnimation();a||(a=Blockly.getMainWorkspace(),a.trashcan&&a.trashcan.flyout&&a.trashcan.closeFlyout(),(a=a.getToolbox())&&a.getFlyout()&&a.getFlyout().autoClose&&a.clearSelection())};Blockly.getMainWorkspace=function(){return Blockly.mainWorkspace};Blockly.alert=function(a,b){alert(a);b&&b()};Blockly.confirm=function(a,b){b(confirm(a))};Blockly.prompt=function(a,b,c){c(prompt(a,b))};
Blockly.jsonInitFactory_=function(a){return function(){this.jsonInit(a)}};
Blockly.defineBlocksWithJsonArray=function(a){for(var b=0;b<a.length;b++){var c=a[b];if(c){var d=c.type;null==d||""===d?console.warn("Block definition #"+b+" in JSON array is missing a type attribute. Skipping."):(Blockly.Blocks[d]&&console.warn("Block definition #"+b+' in JSON array overwrites prior definition of "'+d+'".'),Blockly.Blocks[d]={init:Blockly.jsonInitFactory_(c)})}else console.warn("Block definition #"+b+" in JSON array is "+c+". Skipping.")}};
@@ -833,29 +858,27 @@ 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.length;++f)d+="."+b[f],e&&(e=e[b[f]]);e&&e!==c&&(a=(void 0===c?'%1 has been removed. Use Blockly.Msg["%2"].':'%1 is deprecated and unused. Override Blockly.Msg["%2"].').replace("%1",d).replace("%2",a),console.warn(a))};Blockly.setParentContainer=function(a){Blockly.parentContainer=a};Blockly.Icon=function(a){this.block_=a;this.iconGroup_=null};Blockly.Icon.prototype.collapseHidden=!0;Blockly.Icon.prototype.SIZE=17;Blockly.Icon.prototype.bubble_=null;Blockly.Icon.prototype.iconXY_=null;
Blockly.checkBlockColourConstant_=function(a,b,c){for(var d="Blockly",e=Blockly,f=0;f<b.length;++f)d+="."+b[f],e&&(e=e[b[f]]);e&&e!==c&&(a=(void 0===c?'%1 has been removed. Use Blockly.Msg["%2"].':'%1 is deprecated and unused. Override Blockly.Msg["%2"].').replace("%1",d).replace("%2",a),console.warn(a))};Blockly.setParentContainer=function(a){Blockly.parentContainer=a};Blockly.Events.BubbleOpen=function(a,b,c){Blockly.Events.BubbleOpen.superClass_.constructor.call(this,a?a.workspace.id:void 0);this.blockId=a?a.id:null;this.isOpen=b;this.bubbleType=c};Blockly.utils.object.inherits(Blockly.Events.BubbleOpen,Blockly.Events.UiBase);Blockly.Events.BubbleOpen.prototype.type=Blockly.Events.BUBBLE_OPEN;
Blockly.Events.BubbleOpen.prototype.toJson=function(){var a=Blockly.Events.BubbleOpen.superClass_.toJson.call(this);a.isOpen=this.isOpen;a.bubbleType=this.bubbleType;a.blockId=this.blockId;return a};Blockly.Events.BubbleOpen.prototype.fromJson=function(a){Blockly.Events.BubbleOpen.superClass_.fromJson.call(this,a);this.isOpen=a.isOpen;this.bubbleType=a.bubbleType;this.blockId=a.blockId};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.BUBBLE_OPEN,Blockly.Events.BubbleOpen);Blockly.Icon=function(a){this.block_=a;this.iconGroup_=null};Blockly.Icon.prototype.collapseHidden=!0;Blockly.Icon.prototype.SIZE=17;Blockly.Icon.prototype.bubble_=null;Blockly.Icon.prototype.iconXY_=null;
Blockly.Icon.prototype.createIcon=function(){this.iconGroup_||(this.iconGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{"class":"blocklyIconGroup"},null),this.block_.isInFlyout&&Blockly.utils.dom.addClass(this.iconGroup_,"blocklyIconGroupReadonly"),this.drawIcon_(this.iconGroup_),this.block_.getSvgRoot().appendChild(this.iconGroup_),Blockly.bindEventWithChecks_(this.iconGroup_,"mouseup",this,this.iconClick_),this.updateEditable())};
Blockly.Icon.prototype.dispose=function(){Blockly.utils.dom.removeNode(this.iconGroup_);this.iconGroup_=null;this.setVisible(!1);this.block_=null};Blockly.Icon.prototype.updateEditable=function(){};Blockly.Icon.prototype.isVisible=function(){return!!this.bubble_};Blockly.Icon.prototype.iconClick_=function(a){this.block_.workspace.isDragging()||this.block_.isInFlyout||Blockly.utils.isRightButton(a)||this.setVisible(!this.isVisible())};
Blockly.Icon.prototype.applyColour=function(){this.isVisible()&&this.bubble_.setColour(this.block_.style.colourPrimary)};Blockly.Icon.prototype.setIconLocation=function(a){this.iconXY_=a;this.isVisible()&&this.bubble_.setAnchorLocation(a)};
Blockly.Icon.prototype.computeIconLocation=function(){var a=this.block_.getRelativeToSurfaceXY(),b=Blockly.utils.getRelativeXY(this.iconGroup_);a=new Blockly.utils.Coordinate(a.x+b.x+this.SIZE/2,a.y+b.y+this.SIZE/2);Blockly.utils.Coordinate.equals(this.getIconLocation(),a)||this.setIconLocation(a)};Blockly.Icon.prototype.getIconLocation=function(){return this.iconXY_};
Blockly.Icon.prototype.getCorrectedSize=function(){return new Blockly.utils.Size(Blockly.Icon.prototype.SIZE,Blockly.Icon.prototype.SIZE-2)};Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_={}};Blockly.utils.object.inherits(Blockly.Warning,Blockly.Icon);Blockly.Warning.prototype.collapseHidden=!1;
Blockly.Warning.prototype.drawIcon_=function(a){Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{"class":"blocklyIconShape",d:"M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{"class":"blocklyIconSymbol",d:"m7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyIconSymbol",x:"7",y:"11",height:"2",width:"2"},a)};
Blockly.Warning.textToDom_=function(a){var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TEXT,{"class":"blocklyText blocklyBubbleText blocklyNoPointerEvents",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c<a.length;c++){var d=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TSPAN,{dy:"1em",x:Blockly.Bubble.BORDER_WIDTH},b),e=document.createTextNode(a[c]);d.appendChild(e)}return b};
Blockly.Warning.prototype.setVisible=function(a){a!=this.isVisible()&&(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"warningOpen",!a,a)),a?this.createBubble():this.disposeBubble())};
Blockly.Warning.prototype.createBubble=function(){this.paragraphElement_=Blockly.Warning.textToDom_(this.getText());this.bubble_=new Blockly.Bubble(this.block_.workspace,this.paragraphElement_,this.block_.pathObject.svgPath,this.iconXY_,null,null);this.bubble_.setSvgId(this.block_.id);if(this.block_.RTL)for(var a=this.paragraphElement_.getBBox().width,b=0,c;c=this.paragraphElement_.childNodes[b];b++)c.setAttribute("text-anchor","end"),c.setAttribute("x",a+Blockly.Bubble.BORDER_WIDTH);this.applyColour()};
Blockly.Warning.prototype.disposeBubble=function(){this.bubble_.dispose();this.paragraphElement_=this.body_=this.bubble_=null};Blockly.Warning.prototype.setText=function(a,b){this.text_[b]!=a&&(a?this.text_[b]=a:delete this.text_[b],this.isVisible()&&(this.setVisible(!1),this.setVisible(!0)))};Blockly.Warning.prototype.getText=function(){var a=[],b;for(b in this.text_)a.push(this.text_[b]);return a.join("\n")};Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Comment=function(a){Blockly.Comment.superClass_.constructor.call(this,a);this.model_=a.commentModel;this.model_.text=this.model_.text||"";this.cachedText_="";this.onInputWrapper_=this.onChangeWrapper_=this.onWheelWrapper_=this.onMouseUpWrapper_=null;this.createIcon()};Blockly.utils.object.inherits(Blockly.Comment,Blockly.Icon);
Blockly.Warning.prototype.setVisible=function(a){a!=this.isVisible()&&(Blockly.Events.fire(new Blockly.Events.BubbleOpen(this.block_,a,"warning")),a?this.createBubble_():this.disposeBubble_())};Blockly.Warning.prototype.createBubble_=function(){this.paragraphElement_=Blockly.Bubble.textToDom(this.getText());this.bubble_=Blockly.Bubble.createNonEditableBubble(this.paragraphElement_,this.block_,this.iconXY_);this.applyColour()};
Blockly.Warning.prototype.disposeBubble_=function(){this.bubble_.dispose();this.paragraphElement_=this.bubble_=null};Blockly.Warning.prototype.setText=function(a,b){this.text_[b]!=a&&(a?this.text_[b]=a:delete this.text_[b],this.isVisible()&&(this.setVisible(!1),this.setVisible(!0)))};Blockly.Warning.prototype.getText=function(){var a=[],b;for(b in this.text_)a.push(this.text_[b]);return a.join("\n")};Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Comment=function(a){Blockly.Comment.superClass_.constructor.call(this,a);this.model_=a.commentModel;this.model_.text=this.model_.text||"";this.cachedText_="";this.onInputWrapper_=this.onChangeWrapper_=this.onWheelWrapper_=this.onMouseUpWrapper_=null;this.createIcon()};Blockly.utils.object.inherits(Blockly.Comment,Blockly.Icon);
Blockly.Comment.prototype.drawIcon_=function(a){Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CIRCLE,{"class":"blocklyIconShape",r:"8",cx:"8",cy:"8"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{"class":"blocklyIconSymbol",d:"m6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.4050.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25-1.201,0.998 -1.201,1.528 -1.204,2.19z"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyIconSymbol",
x:"6.8",y:"10.78",height:"2",width:"2"},a)};
Blockly.Comment.prototype.createEditor_=function(){this.foreignObject_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FOREIGNOBJECT,{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);var a=document.createElementNS(Blockly.utils.dom.HTML_NS,"body");a.setAttribute("xmlns",Blockly.utils.dom.HTML_NS);a.className="blocklyMinimalBody";var b=this.textarea_=document.createElementNS(Blockly.utils.dom.HTML_NS,"textarea");b.className="blocklyCommentTextarea";b.setAttribute("dir",this.block_.RTL?
"RTL":"LTR");b.value=this.model_.text;this.resizeTextarea_();a.appendChild(b);this.foreignObject_.appendChild(a);this.onMouseUpWrapper_=Blockly.bindEventWithChecks_(b,"mouseup",this,this.startEdit_,!0,!0);this.onWheelWrapper_=Blockly.bindEventWithChecks_(b,"wheel",this,function(c){c.stopPropagation()});this.onChangeWrapper_=Blockly.bindEventWithChecks_(b,"change",this,function(c){this.cachedText_!=this.model_.text&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.block_,"comment",null,this.cachedText_,
this.model_.text))});this.onInputWrapper_=Blockly.bindEventWithChecks_(b,"input",this,function(c){this.model_.text=b.value});setTimeout(b.focus.bind(b),0);return this.foreignObject_};Blockly.Comment.prototype.updateEditable=function(){Blockly.Comment.superClass_.updateEditable.call(this);this.isVisible()&&(this.disposeBubble_(),this.createBubble_())};Blockly.Comment.prototype.onBubbleResize_=function(){this.isVisible()&&(this.model_.size=this.bubble_.getBubbleSize(),this.resizeTextarea_())};
Blockly.Comment.prototype.resizeTextarea_=function(){var a=this.model_.size,b=2*Blockly.Bubble.BORDER_WIDTH,c=a.width-b;a=a.height-b;this.foreignObject_.setAttribute("width",c);this.foreignObject_.setAttribute("height",a);this.textarea_.style.width=c-4+"px";this.textarea_.style.height=a-4+"px"};Blockly.Comment.prototype.setVisible=function(a){a!=this.isVisible()&&(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"commentOpen",!a,a)),(this.model_.pinned=a)?this.createBubble_():this.disposeBubble_())};
Blockly.Comment.prototype.resizeTextarea_=function(){var a=this.model_.size,b=2*Blockly.Bubble.BORDER_WIDTH,c=a.width-b;a=a.height-b;this.foreignObject_.setAttribute("width",c);this.foreignObject_.setAttribute("height",a);this.textarea_.style.width=c-4+"px";this.textarea_.style.height=a-4+"px"};Blockly.Comment.prototype.setVisible=function(a){a!=this.isVisible()&&(Blockly.Events.fire(new Blockly.Events.BubbleOpen(this.block_,a,"comment")),(this.model_.pinned=a)?this.createBubble_():this.disposeBubble_())};
Blockly.Comment.prototype.createBubble_=function(){!this.block_.isEditable()||Blockly.utils.userAgent.IE?this.createNonEditableBubble_():this.createEditableBubble_()};Blockly.Comment.prototype.createEditableBubble_=function(){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.pathObject.svgPath,this.iconXY_,this.model_.size.width,this.model_.size.height);this.bubble_.setSvgId(this.block_.id);this.bubble_.registerResizeEvent(this.onBubbleResize_.bind(this));this.applyColour()};
Blockly.Comment.prototype.createNonEditableBubble_=function(){Blockly.Warning.prototype.createBubble.call(this)};
Blockly.Comment.prototype.disposeBubble_=function(){this.paragraphElement_?Blockly.Warning.prototype.disposeBubble.call(this):(this.onMouseUpWrapper_&&(Blockly.unbindEvent_(this.onMouseUpWrapper_),this.onMouseUpWrapper_=null),this.onWheelWrapper_&&(Blockly.unbindEvent_(this.onWheelWrapper_),this.onWheelWrapper_=null),this.onChangeWrapper_&&(Blockly.unbindEvent_(this.onChangeWrapper_),this.onChangeWrapper_=null),this.onInputWrapper_&&(Blockly.unbindEvent_(this.onInputWrapper_),this.onInputWrapper_=
null),this.bubble_.dispose(),this.foreignObject_=this.textarea_=this.bubble_=null)};Blockly.Comment.prototype.startEdit_=function(a){this.bubble_.promote()&&this.textarea_.focus();this.cachedText_=this.model_.text};Blockly.Comment.prototype.getBubbleSize=function(){return this.model_.size};Blockly.Comment.prototype.setBubbleSize=function(a,b){this.bubble_?this.bubble_.setBubbleSize(a,b):(this.model_.size.width=a,this.model_.size.height=b)};
Blockly.Comment.prototype.getText=function(){Blockly.utils.deprecation.warn("Comment.prototype.getText","August 2019","December 2020","block.getCommentText");return this.model_.text||""};Blockly.Comment.prototype.setText=function(a){Blockly.utils.deprecation.warn("Comment.prototype.setText","August 2019","December 2020","block.setCommentText");this.model_.text!=a&&(this.model_.text=a,this.updateText())};
Blockly.Comment.prototype.updateText=function(){this.textarea_?this.textarea_.value=this.model_.text:this.paragraphElement_&&(this.paragraphElement_.firstChild.textContent=this.model_.text)};Blockly.Comment.prototype.dispose=function(){this.block_.comment=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Css.register(".blocklyCommentTextarea {,background-color: #fef49c;,border: 0;,outline: 0;,margin: 0;,padding: 3px;,resize: none;,display: block;,overflow: hidden;,}".split(","));Blockly.FlyoutCursor=function(){Blockly.FlyoutCursor.superClass_.constructor.call(this)};Blockly.utils.object.inherits(Blockly.FlyoutCursor,Blockly.Cursor);Blockly.FlyoutCursor.prototype.onBlocklyAction=function(a){switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return this.prev(),!0;case Blockly.navigation.actionNames.NEXT:return this.next(),!0;default:return!1}};
Blockly.Comment.prototype.createNonEditableBubble_=function(){this.paragraphElement_=Blockly.Bubble.textToDom(this.block_.getCommentText());this.bubble_=Blockly.Bubble.createNonEditableBubble(this.paragraphElement_,this.block_,this.iconXY_);this.applyColour()};
Blockly.Comment.prototype.disposeBubble_=function(){this.onMouseUpWrapper_&&(Blockly.unbindEvent_(this.onMouseUpWrapper_),this.onMouseUpWrapper_=null);this.onWheelWrapper_&&(Blockly.unbindEvent_(this.onWheelWrapper_),this.onWheelWrapper_=null);this.onChangeWrapper_&&(Blockly.unbindEvent_(this.onChangeWrapper_),this.onChangeWrapper_=null);this.onInputWrapper_&&(Blockly.unbindEvent_(this.onInputWrapper_),this.onInputWrapper_=null);this.bubble_.dispose();this.paragraphElement_=this.foreignObject_=this.textarea_=
this.bubble_=null};Blockly.Comment.prototype.startEdit_=function(a){this.bubble_.promote()&&this.textarea_.focus();this.cachedText_=this.model_.text};Blockly.Comment.prototype.getBubbleSize=function(){return this.model_.size};Blockly.Comment.prototype.setBubbleSize=function(a,b){this.bubble_?this.bubble_.setBubbleSize(a,b):(this.model_.size.width=a,this.model_.size.height=b)};
Blockly.Comment.prototype.updateText=function(){this.textarea_?this.textarea_.value=this.model_.text:this.paragraphElement_&&(this.paragraphElement_.firstChild.textContent=this.model_.text)};Blockly.Comment.prototype.dispose=function(){this.block_.comment=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Css.register(".blocklyCommentTextarea {,background-color: #fef49c;,border: 0;,outline: 0;,margin: 0;,padding: 3px;,resize: none;,display: block;,text-overflow: hidden;,}".split(","));Blockly.FlyoutCursor=function(){Blockly.FlyoutCursor.superClass_.constructor.call(this)};Blockly.utils.object.inherits(Blockly.FlyoutCursor,Blockly.Cursor);Blockly.FlyoutCursor.prototype.onBlocklyAction=function(a){switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return this.prev(),!0;case Blockly.navigation.actionNames.NEXT:return this.next(),!0;default:return!1}};
Blockly.FlyoutCursor.prototype.next=function(){var a=this.getCurNode();if(!a)return null;(a=a.next())&&this.setCurNode(a);return a};Blockly.FlyoutCursor.prototype.in=function(){return null};Blockly.FlyoutCursor.prototype.prev=function(){var a=this.getCurNode();if(!a)return null;(a=a.prev())&&this.setCurNode(a);return a};Blockly.FlyoutCursor.prototype.out=function(){return null};Blockly.Flyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);this.workspace_=new Blockly.WorkspaceSvg(a);this.workspace_.isFlyout=!0;this.workspace_.setVisible(this.isVisible_);this.RTL=!!a.RTL;this.horizontalLayout=!1;this.toolboxPosition_=a.toolboxPosition;this.eventWrappers_=[];this.mats_=[];this.buttons_=[];this.listeners_=[];this.permanentlyDisabled_=[];this.tabWidth_=this.workspace_.getRenderer().getConstants().TAB_WIDTH;this.targetWorkspace=null};
Blockly.Flyout.prototype.autoClose=!0;Blockly.Flyout.prototype.isVisible_=!1;Blockly.Flyout.prototype.containerVisible_=!0;Blockly.Flyout.prototype.CORNER_RADIUS=8;Blockly.Flyout.prototype.MARGIN=Blockly.Flyout.prototype.CORNER_RADIUS;Blockly.Flyout.prototype.GAP_X=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.GAP_Y=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.SCROLLBAR_PADDING=2;Blockly.Flyout.prototype.width_=0;Blockly.Flyout.prototype.height_=0;
Blockly.Flyout.prototype.dragAngleRange_=70;
@@ -887,9 +910,9 @@ Blockly.Flyout.prototype.isScrollable=function(){return this.scrollbar?this.scro
Blockly.Flyout.prototype.placeNewBlock_=function(a){var b=this.targetWorkspace;if(!a.getSvgRoot())throw Error("oldBlock is not rendered.");var c=Blockly.Xml.blockToDom(a,!0);b.setResizesEnabled(!1);c=Blockly.Xml.domToBlock(c,b);if(!c.getSvgRoot())throw Error("block is not rendered.");var d=b.getOriginOffsetInPixels(),e=this.workspace_.getOriginOffsetInPixels();a=a.getRelativeToSurfaceXY();a.scale(this.workspace_.scale);a=Blockly.utils.Coordinate.sum(e,a);d=Blockly.utils.Coordinate.difference(a,d);
d.scale(1/b.scale);c.moveBy(d.x,d.y);return c};Blockly.Flyout.prototype.onBlocklyAction=function(a){return this.workspace_.getCursor().onBlocklyAction(a)};Blockly.HorizontalFlyout=function(a){Blockly.HorizontalFlyout.superClass_.constructor.call(this,a);this.horizontalLayout=!0};Blockly.utils.object.inherits(Blockly.HorizontalFlyout,Blockly.Flyout);
Blockly.HorizontalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.SCROLLBAR_PADDING;this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM&&(b=0);var d=this.height_;this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP&&(d-=this.SCROLLBAR_PADDING);return{contentHeight:(a.height+2*this.MARGIN)*this.workspace_.scale,contentWidth:(a.width+2*this.MARGIN)*this.workspace_.scale,
contentTop:0,contentLeft:0,viewHeight:d,viewWidth:this.width_-2*this.SCROLLBAR_PADDING,viewTop:-this.workspace_.scrollY,viewLeft:-this.workspace_.scrollX,absoluteTop:b,absoluteLeft:c}};Blockly.HorizontalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&("number"==typeof a.x&&(this.workspace_.scrollX=-b.contentWidth*a.x),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
Blockly.HorizontalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace.getMetrics();a&&(this.width_=a.viewWidth,this.setBackgroundPath_(a.viewWidth-2*this.CORNER_RADIUS,this.height_-this.CORNER_RADIUS),this.positionAt_(this.width_,this.height_,0,this.targetWorkspace.toolboxPosition==this.toolboxPosition_?a.toolboxHeight?this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?a.toolboxHeight:a.viewHeight-this.height_:this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?0:a.viewHeight:
this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?0:a.viewHeight+a.absoluteTop-this.height_))}};
contentTop:0,contentLeft:0,viewHeight:d,viewWidth:this.width_-2*this.SCROLLBAR_PADDING,viewTop:-this.workspace_.scrollY,viewLeft:-this.workspace_.scrollX,absoluteTop:b,absoluteLeft:c}};Blockly.HorizontalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&("number"==typeof a.x&&(this.workspace_.scrollX=-b.contentWidth*a.x),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};Blockly.HorizontalFlyout.prototype.getX=function(){return 0};
Blockly.HorizontalFlyout.prototype.getY=function(){var a=this.targetWorkspace.getMetrics();return a?this.targetWorkspace.toolboxPosition==this.toolboxPosition_?a.toolboxHeight?this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?a.toolboxHeight:a.viewHeight-this.height_:this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?0:a.viewHeight:this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP?0:a.viewHeight+a.absoluteTop-this.height_:0};
Blockly.HorizontalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace.getMetrics();if(a){this.width_=a.viewWidth;this.setBackgroundPath_(a.viewWidth-2*this.CORNER_RADIUS,this.height_-this.CORNER_RADIUS);a=this.getX();var b=this.getY();this.positionAt_(this.width_,this.height_,a,b)}}};
Blockly.HorizontalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP,d=["M 0,"+(c?0:this.CORNER_RADIUS)];c?(d.push("h",a+2*this.CORNER_RADIUS),d.push("v",b),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("h",-a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,-this.CORNER_RADIUS)):(d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,-this.CORNER_RADIUS),
d.push("h",a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("v",b),d.push("h",-a-2*this.CORNER_RADIUS));d.push("z");this.svgBackground_.setAttribute("d",d.join(" "))};Blockly.HorizontalFlyout.prototype.scrollToStart=function(){this.scrollbar.set(this.RTL?Infinity:0)};
Blockly.HorizontalFlyout.prototype.wheel_=function(a){var b=Blockly.utils.getScrollDeltaPixels(a),c=b.x||b.y;c&&(b=this.getMetrics_(),c=b.viewLeft+c,c=Math.min(c,b.contentWidth-b.viewWidth),c=Math.max(c,0),this.scrollbar.set(c),Blockly.WidgetDiv.hide(),Blockly.DropDownDiv.hideWithoutAnimation());a.preventDefault();a.stopPropagation()};
@@ -900,8 +923,8 @@ Blockly.HorizontalFlyout.prototype.reflowInternal_=function(){this.workspace_.sc
this.targetWorkspace.translate(this.targetWorkspace.scrollX,this.targetWorkspace.scrollY+a);this.height_=a;this.position()}};Blockly.registry.register(Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,Blockly.registry.DEFAULT,Blockly.HorizontalFlyout);Blockly.VerticalFlyout=function(a){Blockly.VerticalFlyout.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.VerticalFlyout,Blockly.Flyout);Blockly.VerticalFlyout.registryName="verticalFlyout";
Blockly.VerticalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.height_-2*this.SCROLLBAR_PADDING,d=this.width_;this.RTL||(d-=this.SCROLLBAR_PADDING);return{contentHeight:a.height*this.workspace_.scale+2*this.MARGIN,contentWidth:a.width*this.workspace_.scale+2*this.MARGIN,contentTop:a.y,contentLeft:a.x,viewHeight:c,viewWidth:d,viewTop:-this.workspace_.scrollY+
a.y,viewLeft:-this.workspace_.scrollX,absoluteTop:b,absoluteLeft:0}};Blockly.VerticalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&("number"==typeof a.y&&(this.workspace_.scrollY=-b.contentHeight*a.y),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
Blockly.VerticalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace.getMetrics();a&&(this.height_=a.viewHeight,this.setBackgroundPath_(this.width_-this.CORNER_RADIUS,a.viewHeight-2*this.CORNER_RADIUS),this.positionAt_(this.width_,this.height_,this.targetWorkspace.toolboxPosition==this.toolboxPosition_?a.toolboxWidth?this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?a.toolboxWidth:a.viewWidth-this.width_:this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?0:a.viewWidth:this.toolboxPosition_==
Blockly.TOOLBOX_AT_LEFT?0:a.viewWidth+a.absoluteLeft-this.width_,0))}};
Blockly.VerticalFlyout.prototype.getX=function(){var a=this.targetWorkspace.getMetrics();return a?this.targetWorkspace.toolboxPosition==this.toolboxPosition_?a.toolboxWidth?this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?a.toolboxWidth:a.viewWidth-this.width_:this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?0:a.viewWidth:this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?0:a.viewWidth+a.absoluteLeft-this.width_:0};Blockly.VerticalFlyout.prototype.getY=function(){return 0};
Blockly.VerticalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace.getMetrics();if(a){this.height_=a.viewHeight;this.setBackgroundPath_(this.width_-this.CORNER_RADIUS,a.viewHeight-2*this.CORNER_RADIUS);a=this.getX();var b=this.getY();this.positionAt_(this.width_,this.height_,a,b)}}};
Blockly.VerticalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_RIGHT,d=a+this.CORNER_RADIUS;d=["M "+(c?d:0)+",0"];d.push("h",c?-a:a);d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?-this.CORNER_RADIUS:this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("v",Math.max(0,b));d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?this.CORNER_RADIUS:-this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("h",c?a:-a);d.push("z");this.svgBackground_.setAttribute("d",
d.join(" "))};Blockly.VerticalFlyout.prototype.scrollToStart=function(){this.scrollbar.set(0)};Blockly.VerticalFlyout.prototype.wheel_=function(a){var b=Blockly.utils.getScrollDeltaPixels(a);if(b.y){var c=this.getMetrics_();b=c.viewTop-c.contentTop+b.y;b=Math.min(b,c.contentHeight-c.viewHeight);b=Math.max(b,0);this.scrollbar.set(b);Blockly.WidgetDiv.hide();Blockly.DropDownDiv.hideWithoutAnimation()}a.preventDefault();a.stopPropagation()};
Blockly.VerticalFlyout.prototype.layout_=function(a,b){this.workspace_.scale=this.targetWorkspace.scale;for(var c=this.MARGIN,d=this.RTL?c:c+this.tabWidth_,e=0,f;f=a[e];e++)if("block"==f.type){f=f.block;for(var g=f.getDescendants(!1),h=0,k;k=g[h];h++)k.isInFlyout=!0;f.render();g=f.getSvgRoot();h=f.getHeightWidth();k=f.outputConnection?d-this.tabWidth_:d;f.moveBy(k,c);k=this.createRect_(f,this.RTL?k-h.width:k,c,h,e);this.addBlockListeners_(g,f,k);c+=h.height+b[e]}else"button"==f.type&&(this.initFlyoutButton_(f.button,
@@ -916,27 +939,28 @@ c.setAttribute("x",this.width/2);c.setAttribute("y",this.height/2-d.height/2+d.b
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.isLabel=function(){return this.isLabel_};Blockly.FlyoutButton.prototype.getPosition=function(){return this.position_};Blockly.FlyoutButton.prototype.getButtonText=function(){return this.text_};
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.isInitialized=null;
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;c<a.length;c++){var d=a[c].getCommentText();d&&b.push(d)}b.length&&b.push("");return b.join("\n")};
Blockly.Generator.prototype.blockToCode=function(a,b){if(!a)return"";if(!a.isEnabled())return b?"":this.blockToCode(a.getNextBlock());if(a.isInsertionMarker())return b?"":this.blockToCode(a.getChildren(!1)[0]);var c=this[a.type];if("function"!=typeof c)throw Error('Language "'+this.name_+'" does not know how to generate code for block type "'+a.type+'".');c=c.call(a,a);if(Array.isArray(c)){if(!a.outputConnection)throw TypeError("Expecting string from statement block: "+a.type);return[this.scrub_(a,
c[0],b),c[1]]}if("string"==typeof c)return this.STATEMENT_PREFIX&&!a.suppressPrefixSuffix&&(c=this.injectId(this.STATEMENT_PREFIX,a)+c),this.STATEMENT_SUFFIX&&!a.suppressPrefixSuffix&&(c+=this.injectId(this.STATEMENT_SUFFIX,a)),this.scrub_(a,c,b);if(null===c)return"";throw SyntaxError("Invalid code generated: "+c);};
Blockly.Generator.prototype.blockToCode=function(a,b){!1===this.isInitialized&&console.warn("Generator init was not called before blockToCode was called.");if(!a)return"";if(!a.isEnabled())return b?"":this.blockToCode(a.getNextBlock());if(a.isInsertionMarker())return b?"":this.blockToCode(a.getChildren(!1)[0]);var c=this[a.type];if("function"!=typeof c)throw Error('Language "'+this.name_+'" does not know how to generate code for block type "'+a.type+'".');c=c.call(a,a);if(Array.isArray(c)){if(!a.outputConnection)throw TypeError("Expecting string from statement block: "+
a.type);return[this.scrub_(a,c[0],b),c[1]]}if("string"==typeof c)return this.STATEMENT_PREFIX&&!a.suppressPrefixSuffix&&(c=this.injectId(this.STATEMENT_PREFIX,a)+c),this.STATEMENT_SUFFIX&&!a.suppressPrefixSuffix&&(c+=this.injectId(this.STATEMENT_SUFFIX,a)),this.scrub_(a,c,b);if(null===c)return"";throw SyntaxError("Invalid code generated: "+c);};
Blockly.Generator.prototype.valueToCode=function(a,b,c){if(isNaN(c))throw TypeError("Expecting valid order from block: "+a.type);var d=a.getInputTargetBlock(b);if(!d)return"";b=this.blockToCode(d);if(""===b)return"";if(!Array.isArray(b))throw TypeError("Expecting tuple from value block: "+d.type);a=b[0];b=b[1];if(isNaN(b))throw TypeError("Expecting valid order from value block: "+d.type);if(!a)return"";d=!1;var e=Math.floor(c),f=Math.floor(b);if(e<=f&&(e!=f||0!=e&&99!=e))for(d=!0,e=0;e<this.ORDER_OVERRIDES.length;e++)if(this.ORDER_OVERRIDES[e][0]==
c&&this.ORDER_OVERRIDES[e][1]==b){d=!1;break}d&&(a="("+a+")");return a};Blockly.Generator.prototype.statementToCode=function(a,b){a=a.getInputTargetBlock(b);b=this.blockToCode(a);if("string"!=typeof b)throw TypeError("Expecting code from statement block: "+(a&&a.type));b&&(b=this.prefixLines(b,this.INDENT));return b};
Blockly.Generator.prototype.addLoopTrap=function(a,b){this.INFINITE_LOOP_TRAP&&(a=this.prefixLines(this.injectId(this.INFINITE_LOOP_TRAP,b),this.INDENT)+a);this.STATEMENT_SUFFIX&&!b.suppressPrefixSuffix&&(a=this.prefixLines(this.injectId(this.STATEMENT_SUFFIX,b),this.INDENT)+a);this.STATEMENT_PREFIX&&!b.suppressPrefixSuffix&&(a+=this.prefixLines(this.injectId(this.STATEMENT_PREFIX,b),this.INDENT));return a};
Blockly.Generator.prototype.injectId=function(a,b){b=b.id.replace(/\$/g,"$$$$");return a.replace(/%1/g,"'"+b+"'")};Blockly.Generator.prototype.RESERVED_WORDS_="";Blockly.Generator.prototype.addReservedWords=function(a){this.RESERVED_WORDS_+=a+","};Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_="{leCUI8hutHZI4480Dc}";
Blockly.Generator.prototype.provideFunction_=function(a,b){if(!this.definitions_[a]){var c=this.variableDB_.getDistinctName(a,Blockly.PROCEDURE_CATEGORY_NAME);this.functionNames_[a]=c;b=b.join("\n").replace(this.FUNCTION_NAME_PLACEHOLDER_REGEXP_,c);for(var d;d!=b;)d=b,b=b.replace(/^(( {2})*) {2}/gm,"$1\x00");b=b.replace(/\0/g,this.INDENT);this.definitions_[a]=b}return this.functionNames_[a]};Blockly.Generator.prototype.init=function(a){};Blockly.Generator.prototype.scrub_=function(a,b,c){return b};
Blockly.Generator.prototype.finish=function(a){return a};Blockly.Generator.prototype.scrubNakedValue=function(a){return a};Blockly.ToolboxItem=function(a,b,c){this.id_=a.toolboxitemid||Blockly.utils.IdGenerator.getNextUniqueId();this.level_=(this.parent_=c||null)?this.parent_.getLevel()+1:0;this.toolboxItemDef_=a;this.parentToolbox_=b;this.workspace_=this.parentToolbox_.getWorkspace()};Blockly.ToolboxItem.prototype.init=function(){};Blockly.ToolboxItem.prototype.getDiv=function(){return null};Blockly.ToolboxItem.prototype.getId=function(){return this.id_};Blockly.ToolboxItem.prototype.getParent=function(){return null};
Blockly.ToolboxItem.prototype.getLevel=function(){return this.level_};Blockly.ToolboxItem.prototype.isSelectable=function(){return!1};Blockly.ToolboxItem.prototype.isCollapsible=function(){return!1};Blockly.ToolboxItem.prototype.dispose=function(){};Blockly.ToolboxCategory=function(a,b,c){Blockly.ToolboxCategory.superClass_.constructor.call(this,a,b,c);this.name_=Blockly.utils.replaceMessageReferences(a.name);this.colour_=this.getColour_(a);this.iconDom_=this.rowContents_=this.rowDiv_=this.htmlDiv_=null;this.cssConfig_=this.makeDefaultCssConfig_();Blockly.utils.object.mixin(this.cssConfig_,a.cssconfig||a.cssConfig);this.isDisabled_=this.isHidden_=!1;this.flyoutItems_=[];this.parseContents_(a)};
Blockly.ToolboxItem.prototype.getLevel=function(){return this.level_};Blockly.ToolboxItem.prototype.isSelectable=function(){return!1};Blockly.ToolboxItem.prototype.isCollapsible=function(){return!1};Blockly.ToolboxItem.prototype.dispose=function(){};Blockly.ToolboxCategory=function(a,b,c){Blockly.ToolboxCategory.superClass_.constructor.call(this,a,b,c);this.name_=Blockly.utils.replaceMessageReferences(a.name);this.colour_=this.getColour_(a);this.labelDom_=this.iconDom_=this.rowContents_=this.rowDiv_=this.htmlDiv_=null;this.cssConfig_=this.makeDefaultCssConfig_();Blockly.utils.object.mixin(this.cssConfig_,a.cssconfig||a.cssConfig);this.isDisabled_=this.isHidden_=!1;this.flyoutItems_=[];this.parseContents_(a)};
Blockly.utils.object.inherits(Blockly.ToolboxCategory,Blockly.ToolboxItem);Blockly.ToolboxCategory.registrationName="category";Blockly.ToolboxCategory.nestedPadding=19;Blockly.ToolboxCategory.borderWidth=8;Blockly.ToolboxCategory.defaultBackgroundColour="#57e";
Blockly.ToolboxCategory.prototype.makeDefaultCssConfig_=function(){return{container:"blocklyToolboxCategory",row:"blocklyTreeRow",rowcontentcontainer:"blocklyTreeRowContentContainer",icon:"blocklyTreeIcon",label:"blocklyTreeLabel",contents:"blocklyToolboxContents",selected:"blocklyTreeSelected",openicon:"blocklyTreeIconOpen",closedicon:"blocklyTreeIconClosed"}};
Blockly.ToolboxCategory.prototype.parseContents_=function(a){var b=a.contents;if(a.custom)this.flyoutItems_=a.custom;else if(b){a=0;for(var c;c=b[a];a++)this.flyoutItems_.push(c)}};Blockly.ToolboxCategory.prototype.init=function(){this.createDom_();"true"==this.toolboxItemDef_.hidden&&this.hide()};
Blockly.ToolboxCategory.prototype.createDom_=function(){this.htmlDiv_=this.createContainer_();Blockly.utils.aria.setRole(this.htmlDiv_,Blockly.utils.aria.Role.TREEITEM);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.SELECTED,!1);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.LEVEL,this.level_);this.rowDiv_=this.createRowContainer_();this.rowDiv_.setAttribute("id",this.id_);this.rowDiv_.style.pointerEvents="auto";this.htmlDiv_.appendChild(this.rowDiv_);this.rowContents_=
this.createRowContentsContainer_();this.rowContents_.style.pointerEvents="none";this.rowDiv_.appendChild(this.rowContents_);this.iconDom_=this.createIconDom_();Blockly.utils.aria.setRole(this.iconDom_,Blockly.utils.aria.Role.PRESENTATION);this.rowContents_.appendChild(this.iconDom_);var a=this.createLabelDom_(this.name_);this.rowContents_.appendChild(a);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.LABELLEDBY,a.getAttribute("id"));this.addColourBorder_(this.colour_);return this.htmlDiv_};
Blockly.ToolboxCategory.prototype.createDom_=function(){this.htmlDiv_=this.createContainer_();Blockly.utils.aria.setRole(this.htmlDiv_,Blockly.utils.aria.Role.TREEITEM);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.SELECTED,!1);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.LEVEL,this.level_);this.rowDiv_=this.createRowContainer_();this.rowDiv_.style.pointerEvents="auto";this.htmlDiv_.appendChild(this.rowDiv_);this.rowContents_=this.createRowContentsContainer_();
this.rowContents_.style.pointerEvents="none";this.rowDiv_.appendChild(this.rowContents_);this.iconDom_=this.createIconDom_();Blockly.utils.aria.setRole(this.iconDom_,Blockly.utils.aria.Role.PRESENTATION);this.rowContents_.appendChild(this.iconDom_);this.labelDom_=this.createLabelDom_(this.name_);this.rowContents_.appendChild(this.labelDom_);Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.LABELLEDBY,this.labelDom_.getAttribute("id"));this.addColourBorder_(this.colour_);return this.htmlDiv_};
Blockly.ToolboxCategory.prototype.createContainer_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,this.cssConfig_.container);return a};Blockly.ToolboxCategory.prototype.createRowContainer_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,this.cssConfig_.row);var b=Blockly.ToolboxCategory.nestedPadding*this.getLevel();b=b.toString()+"px";this.workspace_.RTL?a.style.paddingRight=b:a.style.paddingLeft=b;return a};
Blockly.ToolboxCategory.prototype.createRowContentsContainer_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,this.cssConfig_.rowcontentcontainer);return a};Blockly.ToolboxCategory.prototype.createIconDom_=function(){var a=document.createElement("span");this.parentToolbox_.isHorizontal()||Blockly.utils.dom.addClass(a,this.cssConfig_.icon);a.style.display="inline-block";return a};
Blockly.ToolboxCategory.prototype.createLabelDom_=function(a){var b=document.createElement("span");b.setAttribute("id",this.getId()+".label");b.textContent=a;Blockly.utils.dom.addClass(b,this.cssConfig_.label);return b};Blockly.ToolboxCategory.prototype.refreshTheme=function(){this.colour_=this.getColour_(this.toolboxItemDef_);this.addColourBorder_(this.colour_)};
Blockly.ToolboxCategory.prototype.addColourBorder_=function(a){a&&(a=Blockly.ToolboxCategory.borderWidth+"px solid "+(a||"#ddd"),this.workspace_.RTL?this.rowDiv_.style.borderRight=a:this.rowDiv_.style.borderLeft=a)};Blockly.ToolboxCategory.prototype.getColour_=function(a){var b=a.categorystyle||a.categoryStyle;if((a=a.colour)&&b)console.warn('Toolbox category "'+this.name_+'" must not have both a style and a colour');else return b?this.getColourfromStyle_(b):this.parseColour_(a);return""};
Blockly.ToolboxCategory.prototype.getColourfromStyle_=function(a){var b=this.workspace_.getTheme();if(a&&b){if((b=b.categoryStyles[a])&&b.colour)return this.parseColour_(b.colour);console.warn('Style "'+a+'" must exist and contain a colour value')}return""};
Blockly.ToolboxCategory.prototype.getColourfromStyle_=function(a){var b=this.workspace_.getTheme();if(a&&b){if((b=b.categoryStyles[a])&&b.colour)return this.parseColour_(b.colour);console.warn('Style "'+a+'" must exist and contain a colour value')}return""};Blockly.ToolboxCategory.prototype.getClickTarget=function(){return this.rowDiv_};
Blockly.ToolboxCategory.prototype.parseColour_=function(a){a=Blockly.utils.replaceMessageReferences(a);if(null==a||""===a)return"";var b=Number(a);if(isNaN(b)){if(b=Blockly.utils.colour.parse(a))return b;console.warn('Toolbox category "'+this.name_+'" has unrecognized colour attribute: '+a);return""}return Blockly.hueToHex(b)};Blockly.ToolboxCategory.prototype.openIcon_=function(a){a&&(Blockly.utils.dom.removeClasses(a,this.cssConfig_.closedicon),Blockly.utils.dom.addClass(a,this.cssConfig_.openicon))};
Blockly.ToolboxCategory.prototype.closeIcon_=function(a){a&&(Blockly.utils.dom.removeClasses(a,this.cssConfig_.openicon),Blockly.utils.dom.addClass(a,this.cssConfig_.closedicon))};Blockly.ToolboxCategory.prototype.setVisible_=function(a){this.htmlDiv_.style.display=a?"block":"none";this.isHidden_=!a;this.parentToolbox_.getSelectedItem()==this&&this.parentToolbox_.clearSelection()};Blockly.ToolboxCategory.prototype.hide=function(){this.setVisible_(!1)};Blockly.ToolboxCategory.prototype.show=function(){this.setVisible_(!0)};
Blockly.ToolboxCategory.prototype.isVisible=function(){return!this.isHidden_&&this.allAncestorsExpanded_()};Blockly.ToolboxCategory.prototype.allAncestorsExpanded_=function(){for(var a=this;a.getParent();)if(a=a.getParent(),!a.isExpanded())return!1;return!0};Blockly.ToolboxCategory.prototype.isSelectable=function(){return this.isVisible()&&!this.isDisabled_};Blockly.ToolboxCategory.prototype.onClick=function(a){};
@@ -954,21 +978,23 @@ Blockly.CollapsibleToolboxCategory.prototype.parseContents_=function(a){var b=a.
Blockly.CollapsibleToolboxCategory.prototype.createToolboxItem_=function(a){var b=a.kind;"CATEGORY"==b.toUpperCase()&&Blockly.utils.toolbox.isCategoryCollapsible(a)&&(b=Blockly.CollapsibleToolboxCategory.registrationName);a=new (Blockly.registry.getClass(Blockly.registry.Type.TOOLBOX_ITEM,b))(a,this.parentToolbox_,this);this.toolboxItems_.push(a)};
Blockly.CollapsibleToolboxCategory.prototype.init=function(){Blockly.CollapsibleToolboxCategory.superClass_.init.call(this);this.setExpanded("true"==this.toolboxItemDef_.expanded||this.toolboxItemDef_.expanded)};
Blockly.CollapsibleToolboxCategory.prototype.createDom_=function(){Blockly.CollapsibleToolboxCategory.superClass_.createDom_.call(this);var a=this.getChildToolboxItems();this.subcategoriesDiv_=this.createSubCategoriesDom_(a);Blockly.utils.aria.setRole(this.subcategoriesDiv_,Blockly.utils.aria.Role.GROUP);this.htmlDiv_.appendChild(this.subcategoriesDiv_);return this.htmlDiv_};
Blockly.CollapsibleToolboxCategory.prototype.createIconDom_=function(){var a=document.createElement("span");this.parentToolbox_.isHorizontal()||(Blockly.utils.dom.addClass(a,this.cssConfig_.icon),a.style.visibility="visible");a.style.display="inline-block";return a};Blockly.CollapsibleToolboxCategory.prototype.createSubCategoriesDom_=function(a){var b=document.createElement("div");Blockly.utils.dom.addClass(b,this.cssConfig_.contents);for(var c=0;c<a.length;c++){var d=a[c];d.init();d=d.getDiv();b.appendChild(d)}return b};
Blockly.CollapsibleToolboxCategory.prototype.createIconDom_=function(){var a=document.createElement("span");this.parentToolbox_.isHorizontal()||(Blockly.utils.dom.addClass(a,this.cssConfig_.icon),a.style.visibility="visible");a.style.display="inline-block";return a};
Blockly.CollapsibleToolboxCategory.prototype.createSubCategoriesDom_=function(a){var b=document.createElement("div");Blockly.utils.dom.addClass(b,this.cssConfig_.contents);for(var c=0;c<a.length;c++){var d=a[c];d.init();var e=d.getDiv();b.appendChild(e);d.getClickTarget&&d.getClickTarget().setAttribute("id",d.getId())}return b};
Blockly.CollapsibleToolboxCategory.prototype.setExpanded=function(a){this.expanded_!=a&&((this.expanded_=a)?(this.subcategoriesDiv_.style.display="block",this.openIcon_(this.iconDom_)):(this.subcategoriesDiv_.style.display="none",this.closeIcon_(this.iconDom_)),Blockly.utils.aria.setState(this.htmlDiv_,Blockly.utils.aria.State.EXPANDED,a),this.parentToolbox_.handleToolboxItemResize())};
Blockly.CollapsibleToolboxCategory.prototype.setVisible_=function(a){this.htmlDiv_.style.display=a?"block":"none";for(var b=0,c;c=this.getChildToolboxItems()[b];b++)c.setVisible_(a);this.isHidden_=!a;this.parentToolbox_.getSelectedItem()==this&&this.parentToolbox_.clearSelection()};Blockly.CollapsibleToolboxCategory.prototype.isExpanded=function(){return this.expanded_};Blockly.CollapsibleToolboxCategory.prototype.isCollapsible=function(){return!0};
Blockly.CollapsibleToolboxCategory.prototype.onClick=function(a){this.toggleExpanded()};Blockly.CollapsibleToolboxCategory.prototype.toggleExpanded=function(){this.setExpanded(!this.expanded_)};Blockly.CollapsibleToolboxCategory.prototype.getDiv=function(){return this.htmlDiv_};Blockly.CollapsibleToolboxCategory.prototype.getChildToolboxItems=function(){return this.toolboxItems_};Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,Blockly.CollapsibleToolboxCategory.registrationName,Blockly.CollapsibleToolboxCategory);Blockly.Toolbox=function(a){this.workspace_=a;this.toolboxDef_=a.options.languageTree||{contents:[]};this.horizontalLayout_=a.options.horizontalLayout;this.contentsDiv_=this.HtmlDiv=null;this.contents_=[];this.height_=this.width_=0;this.RTL=a.options.RTL;this.flyout_=null;this.contentMap_={};this.toolboxPosition=a.options.toolboxPosition;this.previouslySelectedItem_=this.selectedItem_=null;this.boundEvents_=[]};
Blockly.CollapsibleToolboxCategory.prototype.onClick=function(a){this.toggleExpanded()};Blockly.CollapsibleToolboxCategory.prototype.toggleExpanded=function(){this.setExpanded(!this.expanded_)};Blockly.CollapsibleToolboxCategory.prototype.getDiv=function(){return this.htmlDiv_};Blockly.CollapsibleToolboxCategory.prototype.getChildToolboxItems=function(){return this.toolboxItems_};Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,Blockly.CollapsibleToolboxCategory.registrationName,Blockly.CollapsibleToolboxCategory);Blockly.Events.ToolboxItemSelect=function(a,b,c){Blockly.Events.ToolboxItemSelect.superClass_.constructor.call(this,c);this.oldItem=a;this.newItem=b};Blockly.utils.object.inherits(Blockly.Events.ToolboxItemSelect,Blockly.Events.UiBase);Blockly.Events.ToolboxItemSelect.prototype.type=Blockly.Events.TOOLBOX_ITEM_SELECT;Blockly.Events.ToolboxItemSelect.prototype.toJson=function(){var a=Blockly.Events.ToolboxItemSelect.superClass_.toJson.call(this);a.oldItem=this.oldItem;a.newItem=this.newItem;return a};
Blockly.Events.ToolboxItemSelect.prototype.fromJson=function(a){Blockly.Events.ToolboxItemSelect.superClass_.fromJson.call(this,a);this.oldItem=a.oldItem;this.newItem=a.newItem};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.TOOLBOX_ITEM_SELECT,Blockly.Events.ToolboxItemSelect);Blockly.Toolbox=function(a){this.workspace_=a;this.toolboxDef_=a.options.languageTree||{contents:[]};this.horizontalLayout_=a.options.horizontalLayout;this.contentsDiv_=this.HtmlDiv=null;this.contents_=[];this.height_=this.width_=0;this.RTL=a.options.RTL;this.flyout_=null;this.contentMap_={};this.toolboxPosition=a.options.toolboxPosition;this.previouslySelectedItem_=this.selectedItem_=null;this.boundEvents_=[]};
Blockly.Toolbox.prototype.init=function(){var a=this.workspace_,b=a.getParentSvg();this.flyout_=this.createFlyout_();this.HtmlDiv=this.createDom_(this.workspace_);Blockly.utils.dom.insertAfter(this.flyout_.createDom("svg"),b);this.flyout_.init(a);this.render(this.toolboxDef_);a=a.getThemeManager();a.subscribe(this.HtmlDiv,"toolboxBackgroundColour","background-color");a.subscribe(this.HtmlDiv,"toolboxForegroundColour","color")};
Blockly.Toolbox.prototype.createDom_=function(a){a=a.getParentSvg();var b=this.createContainer_();this.contentsDiv_=this.createContentsContainer_();this.contentsDiv_.tabIndex=0;Blockly.utils.aria.setRole(this.contentsDiv_,Blockly.utils.aria.Role.TREE);b.appendChild(this.contentsDiv_);a.parentNode.insertBefore(b,a);this.attachEvents_(b,this.contentsDiv_);return b};
Blockly.Toolbox.prototype.createContainer_=function(){var a=document.createElement("div");a.setAttribute("layout",this.isHorizontal()?"h":"v");Blockly.utils.dom.addClass(a,"blocklyToolboxDiv");Blockly.utils.dom.addClass(a,"blocklyNonSelectable");a.setAttribute("dir",this.RTL?"RTL":"LTR");return a};
Blockly.Toolbox.prototype.createContentsContainer_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,"blocklyToolboxContents");this.isHorizontal()&&(a.style.flexDirection="row");return a};Blockly.Toolbox.prototype.attachEvents_=function(a,b){a=Blockly.bindEventWithChecks_(a,"mousedown",this,this.onClick_,!1,!0);this.boundEvents_.push(a);b=Blockly.bindEventWithChecks_(b,"keydown",this,this.onKeyDown_,!1,!0);this.boundEvents_.push(b)};
Blockly.Toolbox.prototype.onClick_=function(a){if(Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv)Blockly.hideChaff(!1);else{var b=a.srcElement.getAttribute("id");b&&(b=this.getToolboxItemById(b),b.isSelectable()&&(this.setSelectedItem(b),b.onClick(a)));Blockly.hideChaff(!0)}Blockly.Touch.clearTouchIdentifier()};
Blockly.Toolbox.prototype.createContentsContainer_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,"blocklyToolboxContents");this.isHorizontal()&&(a.style.flexDirection="row");return a};Blockly.Toolbox.prototype.attachEvents_=function(a,b){a=Blockly.bindEventWithChecks_(a,"click",this,this.onClick_,!1,!0);this.boundEvents_.push(a);b=Blockly.bindEventWithChecks_(b,"keydown",this,this.onKeyDown_,!1,!0);this.boundEvents_.push(b)};
Blockly.Toolbox.prototype.onClick_=function(a){if(Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv)Blockly.hideChaff(!1);else{var b=a.target.getAttribute("id");b&&(b=this.getToolboxItemById(b),b.isSelectable()&&(this.setSelectedItem(b),b.onClick(a)));Blockly.hideChaff(!0)}Blockly.Touch.clearTouchIdentifier()};
Blockly.Toolbox.prototype.onKeyDown_=function(a){var b=!1;switch(a.keyCode){case Blockly.utils.KeyCodes.DOWN:b=this.selectNext_();break;case Blockly.utils.KeyCodes.UP:b=this.selectPrevious_();break;case Blockly.utils.KeyCodes.LEFT:b=this.selectParent_();break;case Blockly.utils.KeyCodes.RIGHT:b=this.selectChild_();break;case Blockly.utils.KeyCodes.ENTER:case Blockly.utils.KeyCodes.SPACE:this.selectedItem_&&this.selectedItem_.isCollapsible()&&(this.selectedItem_.toggleExpanded(),b=!0);break;default:b=
!1}b&&a.preventDefault()};
Blockly.Toolbox.prototype.createFlyout_=function(){var a=this.workspace_,b=new Blockly.Options({parentWorkspace:a,rtl:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,renderer:a.options.renderer,rendererOverrides:a.options.rendererOverrides});b.toolboxPosition=a.options.toolboxPosition;a=a.horizontalLayout?Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,a.options):Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX,a.options);
if(!a)throw Error("Blockly.VerticalFlyout, Blockly.HorizontalFlyout or your own custom flyout must be required.");return new a(b)};Blockly.Toolbox.prototype.render=function(a){this.toolboxDef_=a;for(var b=0;b<this.contents_.length;b++){var c=this.contents_[b];c&&c.dispose()}this.contents_=[];this.contentMap_={};this.renderContents_(a.contents);this.position()};
!1}!b&&this.selectedItem_&&this.selectedItem_.onKeyDown&&(b=this.selectedItem_.onKeyDown(a));b&&a.preventDefault()};
Blockly.Toolbox.prototype.createFlyout_=function(){var a=this.workspace_,b=new Blockly.Options({parentWorkspace:a,rtl:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,renderer:a.options.renderer,rendererOverrides:a.options.rendererOverrides});b.toolboxPosition=a.options.toolboxPosition;a=a.horizontalLayout?Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,a.options):Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX,
a.options);if(!a)throw Error("Blockly.VerticalFlyout, Blockly.HorizontalFlyout or your own custom flyout must be required.");return new a(b)};Blockly.Toolbox.prototype.render=function(a){this.toolboxDef_=a;for(var b=0;b<this.contents_.length;b++){var c=this.contents_[b];c&&c.dispose()}this.contents_=[];this.contentMap_={};this.renderContents_(a.contents);this.position()};
Blockly.Toolbox.prototype.renderContents_=function(a){for(var b=document.createDocumentFragment(),c=0,d;d=a[c];c++)this.createToolboxItem_(d,b);this.contentsDiv_.appendChild(b)};
Blockly.Toolbox.prototype.createToolboxItem_=function(a,b){var c=a.kind;"CATEGORY"==c.toUpperCase()&&Blockly.utils.toolbox.isCategoryCollapsible(a)&&(c=Blockly.CollapsibleToolboxCategory.registrationName);if(c=Blockly.registry.getClass(Blockly.registry.Type.TOOLBOX_ITEM,c.toLowerCase()))a=new c(a,this),this.addToolboxItem_(a),a.init(),(a=a.getDiv())&&b.appendChild(a)};
Blockly.Toolbox.prototype.createToolboxItem_=function(a,b){var c=a.kind;"CATEGORY"==c.toUpperCase()&&Blockly.utils.toolbox.isCategoryCollapsible(a)&&(c=Blockly.CollapsibleToolboxCategory.registrationName);if(c=Blockly.registry.getClass(Blockly.registry.Type.TOOLBOX_ITEM,c.toLowerCase()))a=new c(a,this),this.addToolboxItem_(a),a.init(),(c=a.getDiv())&&b.appendChild(c),a.getClickTarget&&a.getClickTarget().setAttribute("id",a.getId())};
Blockly.Toolbox.prototype.addToolboxItem_=function(a){this.contents_.push(a);this.contentMap_[a.getId()]=a;if(a.isCollapsible())for(var b=0,c;c=a.getChildToolboxItems()[b];b++)this.addToolboxItem_(c)};Blockly.Toolbox.prototype.getToolboxItems=function(){return this.contents_};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.utils.toolbox.Position.TOP?new Blockly.utils.Rect(-1E7,c,-1E7,1E7):this.toolboxPosition==Blockly.utils.toolbox.Position.BOTTOM?new Blockly.utils.Rect(b,1E7,-1E7,1E7):this.toolboxPosition==Blockly.utils.toolbox.Position.LEFT?new Blockly.utils.Rect(-1E7,1E7,-1E7,a):new Blockly.utils.Rect(-1E7,1E7,d,1E7)};
Blockly.Toolbox.prototype.getToolboxItemById=function(a){return this.contentMap_[a]};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.getWorkspace=function(){return this.workspace_};Blockly.Toolbox.prototype.getSelectedItem=function(){return this.selectedItem_};Blockly.Toolbox.prototype.getPreviouslySelectedItem=function(){return this.previouslySelectedItem_};
@@ -978,21 +1004,22 @@ Blockly.Toolbox.prototype.refreshTheme=function(){for(var a=0;a<this.contents_.l
Blockly.Toolbox.prototype.setSelectedItem=function(a){var b=this.selectedItem_;!a&&!b||a&&!a.isSelectable()||(this.shouldDeselectItem_(b,a)&&null!=b&&this.deselectItem_(b),this.shouldSelectItem_(b,a)&&null!=a&&this.selectItem_(b,a),this.updateFlyout_(b,a),this.fireSelectEvent_(b,a))};Blockly.Toolbox.prototype.shouldDeselectItem_=function(a,b){return null!=a&&(!a.isCollapsible()||a!=b)};Blockly.Toolbox.prototype.shouldSelectItem_=function(a,b){return null!=b&&b!=a};
Blockly.Toolbox.prototype.deselectItem_=function(a){this.selectedItem_=null;this.previouslySelectedItem_=a;a.setSelected(!1);Blockly.utils.aria.setState(this.contentsDiv_,Blockly.utils.aria.State.ACTIVEDESCENDANT,"")};Blockly.Toolbox.prototype.selectItem_=function(a,b){this.selectedItem_=b;this.previouslySelectedItem_=a;b.setSelected(!0);Blockly.utils.aria.setState(this.contentsDiv_,Blockly.utils.aria.State.ACTIVEDESCENDANT,b.getId())};
Blockly.Toolbox.prototype.selectItemByPosition=function(a){-1<a&&a<this.contents_.length&&(a=this.contents_[a],a.isSelectable()&&this.setSelectedItem(a))};Blockly.Toolbox.prototype.updateFlyout_=function(a,b){(a!=b||b.isCollapsible())&&b&&b.getContents().length?(this.flyout_.show(b.getContents()),this.flyout_.scrollToStart()):this.flyout_.hide()};
Blockly.Toolbox.prototype.fireSelectEvent_=function(a,b){var c=a&&a.getName(),d=b&&b.getName();a==b&&(d=null);a=new Blockly.Events.Ui(null,"category",c,d);a.workspaceId=this.workspace_.id;Blockly.Events.fire(a)};
Blockly.Toolbox.prototype.fireSelectEvent_=function(a,b){var c=a&&a.getName(),d=b&&b.getName();a==b&&(d=null);a=new Blockly.Events.ToolboxItemSelect(c,d,this.workspace_.id);Blockly.Events.fire(a)};
Blockly.Toolbox.prototype.onBlocklyAction=function(a){if(!this.selectedItem_)return!1;switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return this.selectPrevious_();case Blockly.navigation.actionNames.OUT:return this.selectParent_();case Blockly.navigation.actionNames.NEXT:return this.selectNext_();case Blockly.navigation.actionNames.IN:return this.selectChild_();default:return!1}};
Blockly.Toolbox.prototype.selectParent_=function(){return this.selectedItem_?this.selectedItem_.isCollapsible()&&this.selectedItem_.isExpanded()?(this.selectedItem_.setExpanded(!1),!0):this.selectedItem_.getParent()&&this.selectedItem_.getParent().isSelectable()?(this.setSelectedItem(this.selectedItem_.getParent()),!0):!1:!1};
Blockly.Toolbox.prototype.selectChild_=function(){if(!this.selectedItem_||!this.selectedItem_.isCollapsible())return!1;var a=this.selectedItem_;a.isExpanded()?this.selectNext_():a.setExpanded(!0);return!0};Blockly.Toolbox.prototype.selectNext_=function(){if(!this.selectedItem_)return!1;var a=this.contents_.indexOf(this.selectedItem_)+1;if(-1<a&&a<this.contents_.length){for(var b=this.contents_[a];b&&!b.isSelectable();)b=this.contents_[++a];if(b&&b.isSelectable())return this.setSelectedItem(b),!0}return!1};
Blockly.Toolbox.prototype.selectPrevious_=function(){if(!this.selectedItem_)return!1;var a=this.contents_.indexOf(this.selectedItem_)-1;if(-1<a&&a<this.contents_.length){for(var b=this.contents_[a];b&&!b.isSelectable();)b=this.contents_[--a];if(b&&b.isSelectable())return this.setSelectedItem(b),!0}return!1};
Blockly.Toolbox.prototype.dispose=function(){this.flyout_.dispose();for(var a=0;a<this.contents_.length;a++)this.contents_[a].dispose();for(a=0;a<this.boundEvents_.length;a++)Blockly.unbindEvent_(this.boundEvents_[a]);this.boundEvents_=[];this.contents_=[];this.workspace_.getThemeManager().unsubscribe(this.HtmlDiv);Blockly.utils.dom.removeNode(this.HtmlDiv)};
Blockly.Css.register([".blocklyToolboxDelete {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyToolboxGrab {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyToolboxDiv {","background-color: #ddd;","overflow-x: visible;","overflow-y: auto;","padding: 4px 0 4px 0;","position: absolute;","z-index: 70;","-webkit-tap-highlight-color: transparent;","}",".blocklyToolboxContents {","display: flex;","flex-wrap: wrap;","flex-direction: column;",
"}",".blocklyToolboxContents:focus {","outline: none;","}"]);Blockly.registry.register(Blockly.registry.Type.TOOLBOX,Blockly.registry.DEFAULT,Blockly.Toolbox);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.utils.toolbox.Position.TOP?
"}",".blocklyToolboxContents:focus {","outline: none;","}"]);Blockly.registry.register(Blockly.registry.Type.TOOLBOX,Blockly.registry.DEFAULT,Blockly.Toolbox);Blockly.Events.TrashcanOpen=function(a,b){Blockly.Events.TrashcanOpen.superClass_.constructor.call(this,b);this.isOpen=a};Blockly.utils.object.inherits(Blockly.Events.TrashcanOpen,Blockly.Events.UiBase);Blockly.Events.TrashcanOpen.prototype.type=Blockly.Events.TRASHCAN_OPEN;Blockly.Events.TrashcanOpen.prototype.toJson=function(){var a=Blockly.Events.TrashcanOpen.superClass_.toJson.call(this);a.isOpen=this.isOpen;return a};
Blockly.Events.TrashcanOpen.prototype.fromJson=function(a){Blockly.Events.TrashcanOpen.superClass_.fromJson.call(this,a);this.isOpen=a.isOpen};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.TRASHCAN_OPEN,Blockly.Events.TrashcanOpen);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.utils.toolbox.Position.TOP?
Blockly.utils.toolbox.Position.BOTTOM:Blockly.utils.toolbox.Position.TOP;if(!Blockly.HorizontalFlyout)throw Error("Missing require for Blockly.HorizontalFlyout");this.flyout=new Blockly.HorizontalFlyout(a)}else{a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.utils.toolbox.Position.RIGHT?Blockly.utils.toolbox.Position.LEFT:Blockly.utils.toolbox.Position.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.isLidOpen=!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(Blockly.utils.Svg.G,{"class":"blocklyTrash"},null);var a=String(Math.random()).substring(2);var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CLIPPATH,{id:"blocklyTrashBodyClipPath"+a},this.svgGroup_);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:this.WIDTH_,height:this.BODY_HEIGHT_,y:this.LID_HEIGHT_},b);var c=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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(Blockly.utils.Svg.CLIPPATH,{id:"blocklyTrashLidClipPath"+a},this.svgGroup_);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:this.WIDTH_,height:this.LID_HEIGHT_},b);this.svgLid_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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){0<this.workspace_.options.maxTrashcanContents&&(Blockly.utils.dom.insertAfter(this.flyout.createDom(Blockly.utils.Svg.SVG),this.workspace_.getParentSvg()),this.flyout.init(this.workspace_));this.verticalSpacing_=this.MARGIN_BOTTOM_+a;this.setLidOpen(!1);return this.verticalSpacing_+this.BODY_HEIGHT_+this.LID_HEIGHT_};
{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.bindEvent_(this.svgGroup_,"mousedown",this,this.blockMouseDownWhenOpenable_);Blockly.bindEvent_(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){0<this.workspace_.options.maxTrashcanContents&&(Blockly.utils.dom.insertAfter(this.flyout.createDom(Blockly.utils.Svg.SVG),this.workspace_.getParentSvg()),this.flyout.init(this.workspace_));this.verticalSpacing_=this.MARGIN_BOTTOM_+a;this.setLidOpen(!1);return this.verticalSpacing_+this.BODY_HEIGHT_+this.LID_HEIGHT_};
Blockly.Trashcan.prototype.dispose=function(){this.svgGroup_&&(Blockly.utils.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.workspace_=this.svgLid_=null;clearTimeout(this.lidTask_)};Blockly.Trashcan.prototype.hasContents_=function(){return!!this.contents_.length};Blockly.Trashcan.prototype.contentsIsOpen=function(){return this.flyout.isVisible()};
Blockly.Trashcan.prototype.openFlyout=function(){if(!this.contentsIsOpen()){for(var a=[],b=0,c;c=this.contents_[b];b++)a[b]=Blockly.Xml.textToDom(c);this.flyout.show(a);this.fireUiEvent_(!0)}};Blockly.Trashcan.prototype.closeFlyout=function(){this.contentsIsOpen()&&(this.flyout.hide(),this.fireUiEvent_(!1))};Blockly.Trashcan.prototype.emptyContents=function(){this.hasContents_()&&(this.contents_.length=0,this.setMinOpenness_(0),this.closeFlyout())};
Blockly.Trashcan.prototype.position=function(){if(this.verticalSpacing_){var a=this.workspace_.getMetrics();a&&(this.left_=a.toolboxPosition==Blockly.TOOLBOX_AT_LEFT||this.workspace_.horizontalLayout&&!this.workspace_.RTL?a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_-Blockly.Scrollbar.scrollbarThickness:this.MARGIN_SIDE_+Blockly.Scrollbar.scrollbarThickness,this.top_=a.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM?this.verticalSpacing_:a.viewHeight+a.absoluteTop-(this.BODY_HEIGHT_+this.LID_HEIGHT_)-
@@ -1000,7 +1027,7 @@ this.verticalSpacing_,this.svgGroup_.setAttribute("transform","translate("+this.
Blockly.Trashcan.prototype.setLidOpen=function(a){this.isLidOpen!=a&&(clearTimeout(this.lidTask_),this.isLidOpen=a,this.animateLid_())};
Blockly.Trashcan.prototype.animateLid_=function(){var a=Blockly.Trashcan.ANIMATION_FRAMES_,b=1/(a+1);this.lidOpen_+=this.isLidOpen?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.isLidOpen||this.setLidAngle_(a*Blockly.Trashcan.MAX_LID_ANGLE_)};Blockly.Trashcan.prototype.closeLid=function(){this.setLidOpen(!1)};
Blockly.Trashcan.prototype.click=function(){this.hasContents_()&&this.openFlyout()};Blockly.Trashcan.prototype.fireUiEvent_=function(a){a=new Blockly.Events.Ui(null,"trashcanOpen",null,a);a.workspaceId=this.workspace_.id;Blockly.Events.fire(a)};Blockly.Trashcan.prototype.mouseOver_=function(){this.hasContents_()&&this.setLidOpen(!0)};Blockly.Trashcan.prototype.mouseOut_=function(){this.setLidOpen(!1)};
Blockly.Trashcan.prototype.click=function(){this.hasContents_()&&this.openFlyout()};Blockly.Trashcan.prototype.fireUiEvent_=function(a){a=new Blockly.Events.TrashcanOpen(a,this.workspace_.id);Blockly.Events.fire(a)};Blockly.Trashcan.prototype.blockMouseDownWhenOpenable_=function(a){!this.contentsIsOpen()&&this.hasContents_()&&a.stopPropagation()};Blockly.Trashcan.prototype.mouseOver_=function(){this.hasContents_()&&this.setLidOpen(!0)};Blockly.Trashcan.prototype.mouseOut_=function(){this.setLidOpen(!1)};
Blockly.Trashcan.prototype.onDelete_=function(a){if(!(0>=this.workspace_.options.maxTrashcanContents)&&a.type==Blockly.Events.BLOCK_DELETE&&a.oldXml.tagName&&"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");
@@ -1014,12 +1041,11 @@ this.zoomResetGroup_&&this.zoomResetGroup_.setAttribute("transform","translate(0
Blockly.ZoomControls.prototype.createZoomOutSvg_=function(a){this.zoomOutGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CLIPPATH,{id:"blocklyZoomoutClipPath"+a},this.zoomOutGroup_);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:32,height:32},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-64,y:-92,
"clip-path":"url(#blocklyZoomoutClipPath"+a+")"},this.zoomOutGroup_).setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);this.onZoomOutWrapper_=Blockly.bindEventWithChecks_(this.zoomOutGroup_,"mousedown",null,this.zoom_.bind(this,-1))};
Blockly.ZoomControls.prototype.createZoomInSvg_=function(a){this.zoomInGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CLIPPATH,{id:"blocklyZoominClipPath"+a},this.zoomInGroup_);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:32,height:32},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-32,y:-92,
"clip-path":"url(#blocklyZoominClipPath"+a+")"},this.zoomInGroup_).setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);this.onZoomInWrapper_=Blockly.bindEventWithChecks_(this.zoomInGroup_,"mousedown",null,this.zoom_.bind(this,1))};
Blockly.ZoomControls.prototype.zoom_=function(a,b){this.workspace_.markFocused();var c=this.workspace_.scale;this.workspace_.zoomCenter(a);this.fireZoomEvent_(c);Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()};
"clip-path":"url(#blocklyZoominClipPath"+a+")"},this.zoomInGroup_).setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);this.onZoomInWrapper_=Blockly.bindEventWithChecks_(this.zoomInGroup_,"mousedown",null,this.zoom_.bind(this,1))};Blockly.ZoomControls.prototype.zoom_=function(a,b){this.workspace_.markFocused();this.workspace_.zoomCenter(a);this.fireZoomEvent_();Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()};
Blockly.ZoomControls.prototype.createZoomResetSvg_=function(a){this.zoomResetGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CLIPPATH,{id:"blocklyZoomresetClipPath"+a},this.zoomResetGroup_);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:32,height:32},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,
y:-92,"clip-path":"url(#blocklyZoomresetClipPath"+a+")"},this.zoomResetGroup_).setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);this.onZoomResetWrapper_=Blockly.bindEventWithChecks_(this.zoomResetGroup_,"mousedown",null,this.resetZoom_.bind(this))};
Blockly.ZoomControls.prototype.resetZoom_=function(a){this.workspace_.markFocused();var b=this.workspace_.scale;this.workspace_.setScale(this.workspace_.options.zoomOptions.startScale);this.workspace_.beginCanvasTransition();this.workspace_.scrollCenter();setTimeout(this.workspace_.endCanvasTransition.bind(this.workspace_),500);this.fireZoomEvent_(b);Blockly.Touch.clearTouchIdentifier();a.stopPropagation();a.preventDefault()};
Blockly.ZoomControls.prototype.fireZoomEvent_=function(a){a=new Blockly.Events.Ui(null,"zoom",a,this.workspace_.scale);a.workspaceId=this.workspace_.id;Blockly.Events.fire(a)};Blockly.Css.register([".blocklyZoom>image, .blocklyZoom>svg>image {","opacity: .4;","}",".blocklyZoom>image:hover, .blocklyZoom>svg>image:hover {","opacity: .6;","}",".blocklyZoom>image:active, .blocklyZoom>svg>image:active {","opacity: .8;","}"]);Blockly.Mutator=function(a){Blockly.Mutator.superClass_.constructor.call(this,null);this.quarkNames_=a};Blockly.utils.object.inherits(Blockly.Mutator,Blockly.Icon);Blockly.Mutator.prototype.workspaceWidth_=0;Blockly.Mutator.prototype.workspaceHeight_=0;Blockly.Mutator.prototype.setBlock=function(a){this.block_=a};Blockly.Mutator.prototype.getWorkspace=function(){return this.workspace_};
Blockly.ZoomControls.prototype.resetZoom_=function(a){this.workspace_.markFocused();this.workspace_.setScale(this.workspace_.options.zoomOptions.startScale);this.workspace_.beginCanvasTransition();this.workspace_.scrollCenter();setTimeout(this.workspace_.endCanvasTransition.bind(this.workspace_),500);this.fireZoomEvent_();Blockly.Touch.clearTouchIdentifier();a.stopPropagation();a.preventDefault()};
Blockly.ZoomControls.prototype.fireZoomEvent_=function(){var a=new Blockly.Events.Click(null,this.workspace_.id,"zoom_controls");Blockly.Events.fire(a)};Blockly.Css.register([".blocklyZoom>image, .blocklyZoom>svg>image {","opacity: .4;","}",".blocklyZoom>image:hover, .blocklyZoom>svg>image:hover {","opacity: .6;","}",".blocklyZoom>image:active, .blocklyZoom>svg>image:active {","opacity: .8;","}"]);Blockly.Mutator=function(a){Blockly.Mutator.superClass_.constructor.call(this,null);this.quarkNames_=a};Blockly.utils.object.inherits(Blockly.Mutator,Blockly.Icon);Blockly.Mutator.prototype.workspaceWidth_=0;Blockly.Mutator.prototype.workspaceHeight_=0;Blockly.Mutator.prototype.setBlock=function(a){this.block_=a};Blockly.Mutator.prototype.getWorkspace=function(){return this.workspace_};
Blockly.Mutator.prototype.drawIcon_=function(a){Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyIconShape",rx:"4",ry:"4",height:"16",width:"16"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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(Blockly.utils.Svg.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(Blockly.utils.Svg.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,
@@ -1028,12 +1054,12 @@ a=c?this.workspace_.addFlyout(Blockly.utils.Svg.G):null;b=this.workspace_.create
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(),c=b.width+b.x,d=b.height+3*a,e=this.workspace_.getFlyout();if(e){var f=e.getMetrics_();d=Math.max(d,f.contentHeight+20);c+=e.getWidth()}this.block_.RTL&&(c=-b.x);c+=3*a;if(Math.abs(this.workspaceWidth_-c)>a||Math.abs(this.workspaceHeight_-d)>a)this.workspaceWidth_=c,this.workspaceHeight_=d,this.bubble_.setBubbleSize(c+a,d+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));this.rootBlock_=
Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.BubbleOpen(this.block_,a,"mutator")),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));this.rootBlock_=
this.block_.decompose(this.workspace_);b=this.rootBlock_.getDescendants(!1);for(var c=0,d;d=b[c];c++)d.render();this.rootBlock_.setMovable(!1);this.rootBlock_.setDeletable(!1);a?(b=2*a.CORNER_RADIUS,a=this.rootBlock_.RTL?a.getWidth()+b:b):a=b=16;this.block_.RTL&&(a=-a);this.rootBlock_.moveBy(a,b);if(this.block_.saveConnections){var e=this,f=this.block_;f.saveConnections(this.rootBlock_);this.sourceListener_=function(){f.saveConnections(e.rootBlock_)};this.block_.workspace.addChangeListener(this.sourceListener_)}this.resizeBubble_();
this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));this.applyColour()}else this.svgDialog_=null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(this.block_.workspace.removeChangeListener(this.sourceListener_),this.sourceListener_=null)};
Blockly.Mutator.prototype.workspaceChanged_=function(a){if(a.type!=Blockly.Events.UI&&(a.type!=Blockly.Events.CHANGE||"disabled"!=a.element)){if(!this.workspace_.isDragging())for(var b=this.workspace_.getTopBlocks(!1),c=0;a=b[c];c++){var d=a.getRelativeToSurfaceXY();20>d.y&&a.moveBy(0,20-d.y);if(a.RTL){var e=-20,f=this.workspace_.getFlyout();f&&(e-=f.getWidth());d.x>e&&a.moveBy(e-d.x,0)}else 20>d.x&&a.moveBy(20-d.x,0)}this.rootBlock_.workspace==this.workspace_&&(Blockly.Events.setGroup(!0),a=this.block_,
b=(b=a.mutationToDom())&&Blockly.Xml.domToText(b),c=a.rendered,a.rendered=!1,a.compose(this.rootBlock_),a.rendered=c,a.initSvg(),Blockly.getMainWorkspace().keyboardAccessibilityMode&&Blockly.navigation.moveCursorOnBlockMutation(a),a.rendered&&a.render(),c=(c=a.mutationToDom())&&Blockly.Xml.domToText(c),b!=c&&Blockly.Events.fire(new Blockly.Events.BlockChange(a,"mutation",null,b,c)),this.workspace_.isDragging()||this.resizeBubble_(),Blockly.Events.setGroup(!1))}};
Blockly.Mutator.prototype.getFlyoutMetrics_=function(){var a=this.workspace_.getFlyout();a=a?a.getWidth():0;return{contentHeight:0,contentWidth:0,contentTop:0,contentLeft:0,viewHeight:this.workspaceHeight_,viewWidth:this.workspaceWidth_-a,viewTop:0,viewLeft:0,absoluteTop:0,absoluteLeft:this.workspace_.RTL?0:a}};Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};
Blockly.Mutator.prototype.workspaceChanged_=function(a){if(!(a.isUiEvent||a.type==Blockly.Events.CHANGE&&"disabled"==a.element)){if(!this.workspace_.isDragging()){a=this.workspace_.getTopBlocks(!1);for(var b=0,c;c=a[b];b++){var d=c.getRelativeToSurfaceXY();20>d.y&&c.moveBy(0,20-d.y);if(c.RTL){var e=-20,f=this.workspace_.getFlyout();f&&(e-=f.getWidth());d.x>e&&c.moveBy(e-d.x,0)}else 20>d.x&&c.moveBy(20-d.x,0)}}if(this.rootBlock_.workspace==this.workspace_){Blockly.Events.setGroup(!0);c=this.block_;
a=(a=c.mutationToDom())&&Blockly.Xml.domToText(a);b=c.rendered;c.rendered=!1;c.compose(this.rootBlock_);c.rendered=b;c.initSvg();Blockly.getMainWorkspace().keyboardAccessibilityMode&&Blockly.navigation.moveCursorOnBlockMutation(c);c.rendered&&c.render();b=(b=c.mutationToDom())&&Blockly.Xml.domToText(b);if(a!=b){Blockly.Events.fire(new Blockly.Events.BlockChange(c,"mutation",null,a,b));var g=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(g);c.bumpNeighbours();Blockly.Events.setGroup(!1)},
Blockly.BUMP_DELAY)}this.workspace_.isDragging()||this.resizeBubble_();Blockly.Events.setGroup(!1)}}};Blockly.Mutator.prototype.getFlyoutMetrics_=function(){var a=this.workspace_.getFlyout();a=a?a.getWidth():0;return{contentHeight:0,contentWidth:0,contentTop:0,contentLeft:0,viewHeight:this.workspaceHeight_,viewWidth:this.workspaceWidth_-a,viewTop:0,viewLeft:0,absoluteTop:0,absoluteLeft:this.workspace_.RTL?0:a}};Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};
Blockly.Mutator.prototype.updateBlockStyle=function(){var a=this.workspace_;if(a&&a.getAllBlocks(!1)){for(var b=a.getAllBlocks(!1),c=0;c<b.length;c++){var d=b[c];d.setStyle(d.getStyleName())}if(c=a.getFlyout())for(a=c.workspace_.getAllBlocks(!1),c=0;c<a.length;c++)d=a[c],d.setStyle(d.getStyleName())}};
Blockly.Mutator.reconnect=function(a,b,c){if(!a||!a.getSourceBlock().workspace)return!1;c=b.getInput(c).connection;var d=a.targetBlock();return d&&d!=b||c.targetConnection==a?!1:(c.isConnected()&&c.disconnect(),c.connect(a),!0)};Blockly.Mutator.findParentWs=function(a){var b=null;if(a&&a.options){var c=a.options.parentWorkspace;a.isFlyout?c&&c.options&&(b=c.options.parentWorkspace):c&&(b=c)}return b};Blockly.FieldTextInput=function(a,b,c){this.spellcheck_=!0;Blockly.FieldTextInput.superClass_.constructor.call(this,a,b,c);this.onKeyInputWrapper_=this.onKeyDownWrapper_=this.htmlInput_=null;this.fullBlockClickTarget_=!1;this.workspace_=null};Blockly.utils.object.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.prototype.DEFAULT_VALUE="";
Blockly.FieldTextInput.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldTextInput(b,void 0,a)};Blockly.FieldTextInput.prototype.SERIALIZABLE=!0;Blockly.FieldTextInput.BORDERRADIUS=4;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.configure_=function(a){Blockly.FieldTextInput.superClass_.configure_.call(this,a);"boolean"==typeof a.spellcheck&&(this.spellcheck_=a.spellcheck)};
@@ -1042,7 +1068,7 @@ Blockly.FieldTextInput.prototype.doClassValidation_=function(a){return null===a|
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.showPromptEditor_=function(){Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.getText(),function(a){this.setValue(this.getValueFromEditorText_(a))}.bind(this))};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_.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")};
@@ -1050,9 +1076,8 @@ Blockly.FieldTextInput.prototype.bindInputEvents_=function(a){this.onKeyDownWrap
Blockly.FieldTextInput.prototype.unbindInputEvents_=function(){this.onKeyDownWrapper_&&(Blockly.unbindEvent_(this.onKeyDownWrapper_),this.onKeyDownWrapper_=null);this.onKeyInputWrapper_&&(Blockly.unbindEvent_(this.onKeyInputWrapper_),this.onKeyInputWrapper_=null)};
Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_=function(a){a.keyCode==Blockly.utils.KeyCodes.ENTER?(Blockly.WidgetDiv.hide(),Blockly.DropDownDiv.hideWithoutAnimation()):a.keyCode==Blockly.utils.KeyCodes.ESC?(this.htmlInput_.value=this.htmlInput_.defaultValue,Blockly.WidgetDiv.hide(),Blockly.DropDownDiv.hideWithoutAnimation()):a.keyCode==Blockly.utils.KeyCodes.TAB&&(Blockly.WidgetDiv.hide(),Blockly.DropDownDiv.hideWithoutAnimation(),this.sourceBlock_.tab(this,!a.shiftKey),a.preventDefault())};
Blockly.FieldTextInput.prototype.onHtmlInputChange_=function(a){a=this.htmlInput_.value;a!==this.htmlInput_.oldValue_&&(this.htmlInput_.oldValue_=a,Blockly.Events.setGroup(!0),a=this.getValueFromEditorText_(a),this.setValue(a),this.forceRerender(),this.resizeEditor_(),Blockly.Events.setGroup(!1))};Blockly.FieldTextInput.prototype.setEditorValue_=function(a){this.isDirty_=!0;this.isBeingEdited_&&(this.htmlInput_.value=this.getEditorText_(a));this.setValue(a)};
Blockly.FieldTextInput.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.FieldTextInput.numberValidator=function(a){console.warn("Blockly.FieldTextInput.numberValidator is deprecated. Use Blockly.FieldNumber instead.");if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=Number(a||0);return isNaN(a)?null:String(a)};Blockly.FieldTextInput.nonnegativeIntegerValidator=function(a){(a=Blockly.FieldTextInput.numberValidator(a))&&(a=String(Math.max(0,Math.floor(a))));return a};Blockly.FieldTextInput.prototype.isTabNavigable=function(){return!0};
Blockly.FieldTextInput.prototype.getText_=function(){return this.isBeingEdited_&&this.htmlInput_?this.htmlInput_.value:null};Blockly.FieldTextInput.prototype.getEditorText_=function(a){return String(a)};Blockly.FieldTextInput.prototype.getValueFromEditorText_=function(a){return a};Blockly.fieldRegistry.register("field_input",Blockly.FieldTextInput);Blockly.FieldAngle=function(a,b,c){this.clockwise_=Blockly.FieldAngle.CLOCKWISE;this.offset_=Blockly.FieldAngle.OFFSET;this.wrap_=Blockly.FieldAngle.WRAP;this.round_=Blockly.FieldAngle.ROUND;Blockly.FieldAngle.superClass_.constructor.call(this,a,b,c);this.moveSurfaceWrapper_=this.clickSurfaceWrapper_=this.clickWrapper_=this.line_=this.gauge_=null};Blockly.utils.object.inherits(Blockly.FieldAngle,Blockly.FieldTextInput);Blockly.FieldAngle.prototype.DEFAULT_VALUE=0;
Blockly.FieldTextInput.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.FieldTextInput.prototype.isTabNavigable=function(){return!0};Blockly.FieldTextInput.prototype.getText_=function(){return this.isBeingEdited_&&this.htmlInput_?this.htmlInput_.value:null};
Blockly.FieldTextInput.prototype.getEditorText_=function(a){return String(a)};Blockly.FieldTextInput.prototype.getValueFromEditorText_=function(a){return a};Blockly.fieldRegistry.register("field_input",Blockly.FieldTextInput);Blockly.FieldAngle=function(a,b,c){this.clockwise_=Blockly.FieldAngle.CLOCKWISE;this.offset_=Blockly.FieldAngle.OFFSET;this.wrap_=Blockly.FieldAngle.WRAP;this.round_=Blockly.FieldAngle.ROUND;Blockly.FieldAngle.superClass_.constructor.call(this,a,b,c);this.moveSurfaceWrapper_=this.clickSurfaceWrapper_=this.clickWrapper_=this.line_=this.gauge_=null};Blockly.utils.object.inherits(Blockly.FieldAngle,Blockly.FieldTextInput);Blockly.FieldAngle.prototype.DEFAULT_VALUE=0;
Blockly.FieldAngle.fromJson=function(a){return new Blockly.FieldAngle(a.angle,void 0,a)};Blockly.FieldAngle.prototype.SERIALIZABLE=!0;Blockly.FieldAngle.ROUND=15;Blockly.FieldAngle.HALF=50;Blockly.FieldAngle.CLOCKWISE=!1;Blockly.FieldAngle.OFFSET=0;Blockly.FieldAngle.WRAP=360;Blockly.FieldAngle.RADIUS=Blockly.FieldAngle.HALF-1;
Blockly.FieldAngle.prototype.configure_=function(a){Blockly.FieldAngle.superClass_.configure_.call(this,a);switch(a.mode){case "compass":this.clockwise_=!0;this.offset_=90;break;case "protractor":this.clockwise_=!1,this.offset_=0}var b=a.clockwise;"boolean"==typeof b&&(this.clockwise_=b);b=a.offset;null!=b&&(b=Number(b),isNaN(b)||(this.offset_=b));b=a.wrap;null!=b&&(b=Number(b),isNaN(b)||(this.wrap_=b));a=a.round;null!=a&&(a=Number(a),isNaN(a)||(this.round_=a))};
Blockly.FieldAngle.prototype.initView=function(){Blockly.FieldAngle.superClass_.initView.call(this);this.symbol_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TSPAN,{},null);this.symbol_.appendChild(document.createTextNode("\u00b0"));this.textElement_.appendChild(this.symbol_)};Blockly.FieldAngle.prototype.render_=function(){Blockly.FieldAngle.superClass_.render_.call(this);this.updateGraph_()};
@@ -1079,7 +1104,8 @@ Blockly.FieldColour.prototype.doValueUpdate_=function(a){this.value_=a;this.bord
Blockly.FieldColour.prototype.DEFAULT_VALUE=Blockly.FieldColour.COLOURS[0];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))};
Blockly.FieldColour.prototype.onKeyDown_=function(a){var b=!1;if(a.keyCode===Blockly.utils.KeyCodes.UP)this.moveHighlightBy_(0,-1),b=!0;else if(a.keyCode===Blockly.utils.KeyCodes.DOWN)this.moveHighlightBy_(0,1),b=!0;else if(a.keyCode===Blockly.utils.KeyCodes.LEFT)this.moveHighlightBy_(-1,0),b=!0;else if(a.keyCode===Blockly.utils.KeyCodes.RIGHT)this.moveHighlightBy_(1,0),b=!0;else if(a.keyCode===Blockly.utils.KeyCodes.ENTER){if(b=this.getHighlighted_())b=b&&b.label,null!==b&&this.setValue(b);Blockly.DropDownDiv.hideWithoutAnimation();
b=!0}b&&a.stopPropagation()};Blockly.FieldColour.prototype.onBlocklyAction=function(a){if(this.picker_){if(a===Blockly.navigation.ACTION_PREVIOUS)return this.moveHighlightBy_(0,-1),!0;if(a===Blockly.navigation.ACTION_NEXT)return this.moveHighlightBy_(0,1),!0;if(a===Blockly.navigation.ACTION_OUT)return this.moveHighlightBy_(-1,0),!0;if(a===Blockly.navigation.ACTION_IN)return this.moveHighlightBy_(1,0),!0}return Blockly.FieldColour.superClass_.onBlocklyAction.call(this,a)};
b=!0}b&&a.stopPropagation()};
Blockly.FieldColour.prototype.onBlocklyAction=function(a){if(this.picker_)switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return this.moveHighlightBy_(0,-1),!0;case Blockly.navigation.actionNames.NEXT:return this.moveHighlightBy_(0,1),!0;case Blockly.navigation.actionNames.OUT:return this.moveHighlightBy_(-1,0),!0;case Blockly.navigation.actionNames.IN:return this.moveHighlightBy_(1,0),!0;default:return!1}return Blockly.FieldColour.superClass_.onBlocklyAction.call(this,a)};
Blockly.FieldColour.prototype.moveHighlightBy_=function(a,b){var c=this.colours_||Blockly.FieldColour.COLOURS,d=this.columns_||Blockly.FieldColour.COLUMNS,e=this.highlightedIndex_%d,f=Math.floor(this.highlightedIndex_/d);e+=a;f+=b;0>a?0>e&&0<f?(e=d-1,f--):0>e&&(e=0):0<a?e>d-1&&f<Math.floor(c.length/d)-1?(e=0,f++):e>d-1&&e--:0>b?0>f&&(f=0):0<b&&f>Math.floor(c.length/d)-1&&(f=Math.floor(c.length/d)-1);this.setHighlightedCell_(this.picker_.childNodes[f].childNodes[e],f*d+e)};
Blockly.FieldColour.prototype.onMouseMove_=function(a){var b=(a=a.target)&&Number(a.getAttribute("data-index"));null!==b&&b!==this.highlightedIndex_&&this.setHighlightedCell_(a,b)};Blockly.FieldColour.prototype.onMouseEnter_=function(){this.picker_.focus({preventScroll:!0})};Blockly.FieldColour.prototype.onMouseLeave_=function(){this.picker_.blur();var a=this.getHighlighted_();a&&Blockly.utils.dom.removeClass(a,"blocklyColourHighlighted")};
Blockly.FieldColour.prototype.getHighlighted_=function(){var a=this.columns_||Blockly.FieldColour.COLUMNS,b=this.picker_.childNodes[Math.floor(this.highlightedIndex_/a)];return b?b.childNodes[this.highlightedIndex_%a]:null};
@@ -1117,7 +1143,7 @@ Blockly.FieldDropdown.prototype.positionSVGArrow_=function(a,b){if(!this.svgArro
Blockly.FieldDropdown.prototype.getText_=function(){if(!this.selectedOption_)return null;var a=this.selectedOption_[0];return"object"==typeof a?a.alt:a};
Blockly.FieldDropdown.validateOptions_=function(a){if(!Array.isArray(a))throw TypeError("FieldDropdown options must be an array.");if(!a.length)throw TypeError("FieldDropdown options must not be an empty array.");for(var b=!1,c=0;c<a.length;++c){var d=a[c];Array.isArray(d)?"string"!=typeof d[1]?(b=!0,console.error("Invalid option["+c+"]: Each FieldDropdown option id must be a string. Found "+d[1]+" in: ",d)):d[0]&&"string"!=typeof d[0]&&"string"!=typeof d[0].src&&(b=!0,console.error("Invalid option["+
c+"]: Each FieldDropdown option must have a string label or image description. Found"+d[0]+" in: ",d)):(b=!0,console.error("Invalid option["+c+"]: Each FieldDropdown option must be an array. Found: ",d))}if(b)throw TypeError("Found invalid FieldDropdown options.");};
Blockly.FieldDropdown.prototype.onBlocklyAction=function(a){if(this.menu_){if(a===Blockly.navigation.ACTION_PREVIOUS)return this.menu_.highlightPrevious(),!0;if(a===Blockly.navigation.ACTION_NEXT)return this.menu_.highlightNext(),!0}return Blockly.FieldDropdown.superClass_.onBlocklyAction.call(this,a)};Blockly.fieldRegistry.register("field_dropdown",Blockly.FieldDropdown);Blockly.FieldLabelSerializable=function(a,b,c){Blockly.FieldLabelSerializable.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.FieldLabelSerializable,Blockly.FieldLabel);Blockly.FieldLabelSerializable.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldLabelSerializable(b,void 0,a)};Blockly.FieldLabelSerializable.prototype.EDITABLE=!1;Blockly.FieldLabelSerializable.prototype.SERIALIZABLE=!0;
Blockly.FieldDropdown.prototype.onBlocklyAction=function(a){if(this.menu_)switch(a.name){case Blockly.navigation.actionNames.PREVIOUS:return this.menu_.highlightPrevious(),!0;case Blockly.navigation.actionNames.NEXT:return this.menu_.highlightNext(),!0;default:return!1}return Blockly.FieldDropdown.superClass_.onBlocklyAction.call(this,a)};Blockly.fieldRegistry.register("field_dropdown",Blockly.FieldDropdown);Blockly.FieldLabelSerializable=function(a,b,c){Blockly.FieldLabelSerializable.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.FieldLabelSerializable,Blockly.FieldLabel);Blockly.FieldLabelSerializable.fromJson=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldLabelSerializable(b,void 0,a)};Blockly.FieldLabelSerializable.prototype.EDITABLE=!1;Blockly.FieldLabelSerializable.prototype.SERIALIZABLE=!0;
Blockly.fieldRegistry.register("field_label_serializable",Blockly.FieldLabelSerializable);Blockly.FieldImage=function(a,b,c,d,e,f,g){if(!a)throw Error("Src value of an image field is required");a=Blockly.utils.replaceMessageReferences(a);c=Number(Blockly.utils.replaceMessageReferences(c));b=Number(Blockly.utils.replaceMessageReferences(b));if(isNaN(c)||isNaN(b))throw Error("Height and width values of an image field must cast to numbers.");if(0>=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.prototype.DEFAULT_VALUE="";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)||""};
@@ -1125,7 +1151,7 @@ Blockly.FieldImage.prototype.initView=function(){this.imageElement_=Blockly.util
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){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.toXml=function(a){a.textContent=this.getValue().replace(/\n/g,"&#10;");return a};
Blockly.FieldMultilineInput.prototype.fromXml=function(a){this.setValue(a.textContent.replace(/&#10;/g,"\n"))};Blockly.FieldMultilineInput.prototype.initView=function(){this.createBorderRect_();this.textGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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;c<b.length;c++){var d=b[c];d.length>this.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.getDisplayText_=function(){var a=this.getText();if(!a)return Blockly.Field.NBSP;var b=a.split("\n");a="";for(var c=0;c<b.length;c++){var d=b[c];d.length>this.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;c<a.length;c++){var d=this.getConstants().FIELD_TEXT_HEIGHT+this.getConstants().FIELD_BORDER_RECT_Y_PADDING;Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TEXT,{"class":"blocklyText blocklyMultilineText",x:this.getConstants().FIELD_BORDER_RECT_X_PADDING,y:b+this.getConstants().FIELD_BORDER_RECT_Y_PADDING,dy:this.getConstants().FIELD_TEXT_BASELINE},
this.textGroup_).appendChild(document.createTextNode(a[c]));b+=d}this.updateSize_();this.isBeingEdited_&&(this.sourceBlock_.RTL?setTimeout(this.resizeEditor_.bind(this),0):this.resizeEditor_(),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.FieldMultilineInput.prototype.updateSize_=function(){for(var a=this.textGroup_.childNodes,b=0,c=0,d=0;d<a.length;d++){var e=Blockly.utils.dom.getTextWidth(a[d]);e>b&&(b=e);c+=this.getConstants().FIELD_TEXT_HEIGHT+(0<d?this.getConstants().FIELD_BORDER_RECT_Y_PADDING:0)}this.borderRect_&&(c+=2*this.getConstants().FIELD_BORDER_RECT_Y_PADDING,b+=2*this.getConstants().FIELD_BORDER_RECT_X_PADDING,this.borderRect_.setAttribute("width",b),this.borderRect_.setAttribute("height",c));this.size_.width=
@@ -1137,7 +1163,7 @@ Blockly.FieldNumber.prototype.configure_=function(a){Blockly.FieldNumber.superCl
Blockly.FieldNumber.prototype.setMinInternal_=function(a){null==a?this.min_=-Infinity:(a=Number(a),isNaN(a)||(this.min_=a))};Blockly.FieldNumber.prototype.getMin=function(){return this.min_};Blockly.FieldNumber.prototype.setMax=function(a){this.setMaxInternal_(a);this.setValue(this.getValue())};Blockly.FieldNumber.prototype.setMaxInternal_=function(a){null==a?this.max_=Infinity:(a=Number(a),isNaN(a)||(this.max_=a))};Blockly.FieldNumber.prototype.getMax=function(){return this.max_};
Blockly.FieldNumber.prototype.setPrecision=function(a){this.setPrecisionInternal_(a);this.setValue(this.getValue())};Blockly.FieldNumber.prototype.setPrecisionInternal_=function(a){null==a?this.precision_=0:(a=Number(a),isNaN(a)||(this.precision_=a));var b=this.precision_.toLocaleString("en-US",{maximumFractionDigits:20}),c=b.indexOf(".");this.decimalPlaces_=-1==c?a?0:null:b.length-c-1};Blockly.FieldNumber.prototype.getPrecision=function(){return this.precision_};
Blockly.FieldNumber.prototype.doClassValidation_=function(a){if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=a.replace(/infinity/i,"Infinity");a=Number(a||0);if(isNaN(a))return null;a=Math.min(Math.max(a,this.min_),this.max_);this.precision_&&isFinite(a)&&(a=Math.round(a/this.precision_)*this.precision_);null!=this.decimalPlaces_&&(a=Number(a.toFixed(this.decimalPlaces_)));return a};
Blockly.FieldNumber.prototype.widgetCreate_=function(){var a=Blockly.FieldNumber.superClass_.widgetCreate_.call(this);-Infinity<this.min_&&Blockly.utils.aria.setState(a,Blockly.utils.aria.State.VALUEMIN,this.min_);Infinity>this.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.FieldNumber.prototype.widgetCreate_=function(){var a=Blockly.FieldNumber.superClass_.widgetCreate_.call(this);-Infinity<this.min_&&Blockly.utils.aria.setState(a,Blockly.utils.aria.State.VALUEMIN,this.min_);Infinity>this.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="string"===typeof a?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.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.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())};
@@ -1180,7 +1206,9 @@ width:"180%",y:"-30%",x:"-40%"},a),b=Blockly.utils.dom.createSvgElement(Blockly.
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: "+this.FIELD_TEXT_FONTWEIGHT+" "+this.FIELD_TEXT_FONTSIZE+"pt "+this.FIELD_TEXT_FONTFAMILY+";","}",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_};
"fill-opacity: .5;","}",a+" .blocklyReplaceable .blocklyPathLight,",a+" .blocklyReplaceable .blocklyPathDark {","display: none;","}",a+" .blocklyInsertionMarker>.blocklyPath {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none;","}"]};Blockly.Events.MarkerMove=function(a,b,c,d){var e=a?a.workspace.id:void 0;d&&d.getType()==Blockly.ASTNode.types.WORKSPACE&&(e=d.getLocation().id);Blockly.Events.MarkerMove.superClass_.constructor.call(this,e);this.blockId=a?a.id:null;this.oldNode=c;this.newNode=d;this.isCursor=b};Blockly.utils.object.inherits(Blockly.Events.MarkerMove,Blockly.Events.UiBase);Blockly.Events.MarkerMove.prototype.type=Blockly.Events.MARKER_MOVE;
Blockly.Events.MarkerMove.prototype.toJson=function(){var a=Blockly.Events.MarkerMove.superClass_.toJson.call(this);a.isCursor=this.isCursor;a.blockId=this.blockId;a.oldNode=this.oldNode;a.newNode=this.newNode;return a};Blockly.Events.MarkerMove.prototype.fromJson=function(a){Blockly.Events.MarkerMove.superClass_.fromJson.call(this,a);this.isCursor=a.isCursor;this.blockId=a.blockId;this.oldNode=a.oldNode;this.newNode=a.newNode};
Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.MARKER_MOVE,Blockly.Events.MarkerMove);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.getMarker=function(){return this.marker_};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(Blockly.utils.Svg.G,{"class":a},null);this.createDomInternal_();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.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_(b);this.showAtLocation_(b);this.fireMarkerEvent_(a,b);a=this.currentMarkerSvg.childNodes[0];void 0!==a&&a.beginElement&&a.beginElement()}else this.hide()};
@@ -1197,7 +1225,7 @@ 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.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.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.fireMarkerEvent_=function(a,b){var c=b.getSourceBlock();a=new Blockly.Events.MarkerMove(c,this.isCursor(),a,b);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(Blockly.utils.Svg.G,{width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT},this.svgGroup_);this.markerSvgLine_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{width:this.constants_.CURSOR_WS_WIDTH,height:this.constants_.WS_CURSOR_HEIGHT,style:"display: none"},this.markerSvg_);this.markerSvgRect_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,
{"class":"blocklyVerticalMarker",rx:10,ry:10,style:"display: none"},this.markerSvg_);this.markerInput_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{transform:"",style:"display: none"},this.markerSvg_);this.markerBlock_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.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(Blockly.utils.Svg.ANIMATE,
@@ -1292,7 +1320,7 @@ Blockly.blockRendering.Renderer.prototype.dispose=function(){this.constants_&&th
Blockly.blockRendering.Renderer.prototype.makeDebugger_=function(){if(!Blockly.blockRendering.Debug)throw Error("Missing require for Blockly.blockRendering.Debug");return new Blockly.blockRendering.Debug(this.getConstants())};Blockly.blockRendering.Renderer.prototype.makeMarkerDrawer=function(a,b){return new Blockly.blockRendering.MarkerSvg(a,this.getConstants(),b)};Blockly.blockRendering.Renderer.prototype.makePathObject=function(a,b){return new Blockly.blockRendering.PathObject(a,b,this.constants_)};
Blockly.blockRendering.Renderer.prototype.getConstants=function(){return this.constants_};Blockly.blockRendering.Renderer.prototype.shouldHighlightConnection=function(a){return!0};Blockly.blockRendering.Renderer.prototype.orphanCanConnectAtEnd=function(a,b,c){c==Blockly.OUTPUT_VALUE?(c=b.outputConnection,a=Blockly.Connection.lastConnectionInRow(a,b)):(c=b.previousConnection,a=a.lastConnectionInStack());return a?c.getConnectionChecker().canConnect(a,c,!1):!1};
Blockly.blockRendering.Renderer.prototype.getConnectionPreviewMethod=function(a,b,c){return b.type==Blockly.OUTPUT_VALUE||b.type==Blockly.PREVIOUS_STATEMENT?!a.isConnected()||this.orphanCanConnectAtEnd(c,a.targetBlock(),b.type)?Blockly.InsertionMarkerManager.PREVIEW_TYPE.INSERTION_MARKER:Blockly.InsertionMarkerManager.PREVIEW_TYPE.REPLACEMENT_FADE:Blockly.InsertionMarkerManager.PREVIEW_TYPE.INSERTION_MARKER};
Blockly.blockRendering.Renderer.prototype.render=function(a){Blockly.blockRendering.useDebugger&&!a.renderingDebugger&&(a.renderingDebugger=this.makeDebugger_());var b=this.makeRenderInfo_(a);b.measure();this.makeDrawer_(a,b).draw()};Blockly.geras={};Blockly.geras.ConstantProvider=function(){Blockly.geras.ConstantProvider.superClass_.constructor.call(this);this.FIELD_TEXT_BASELINE_CENTER=!1;this.DARK_PATH_OFFSET=1;this.MAX_BOTTOM_WIDTH=30};Blockly.utils.object.inherits(Blockly.geras.ConstantProvider,Blockly.blockRendering.ConstantProvider);
Blockly.blockRendering.Renderer.prototype.render=function(a){Blockly.blockRendering.useDebugger&&!a.renderingDebugger&&(a.renderingDebugger=this.makeDebugger_());var b=this.makeRenderInfo_(a);b.measure();this.makeDrawer_(a,b).draw()};Blockly.geras={};Blockly.geras.ConstantProvider=function(){Blockly.geras.ConstantProvider.superClass_.constructor.call(this);this.FIELD_TEXT_BASELINE_CENTER=!1;this.DARK_PATH_OFFSET=1;this.MAX_BOTTOM_WIDTH=30;this.STATEMENT_BOTTOM_SPACER=-this.NOTCH_HEIGHT/2};Blockly.utils.object.inherits(Blockly.geras.ConstantProvider,Blockly.blockRendering.ConstantProvider);
Blockly.geras.ConstantProvider.prototype.getCSS_=function(a){return Blockly.geras.ConstantProvider.superClass_.getCSS_.call(this,a).concat([a+" .blocklyInsertionMarker>.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)?
File diff suppressed because one or more lines are too long
+35 -27
View File
@@ -24,15 +24,13 @@ this.BLOCKLY_BOOT = function(root) {
goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.ASTNode', 'Blockly.Blocks', 'Blockly.Connection', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Tooltip', 'Blockly.Workspace', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.deprecation', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es5'});
goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'], ['Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Procedures', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour'], {});
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Selected', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Procedures', 'Blockly.ShortcutRegistry', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour'], {});
goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {});
goog.addDependency('../../core/bubble.js', ['Blockly.Bubble'], ['Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/bubble_dragger.js', ['Blockly.BubbleDragger'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.CommentMove', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/components/component.js', ['Blockly.Component', 'Blockly.Component.Error'], ['Blockly.utils.IdGenerator', 'Blockly.utils.dom', 'Blockly.utils.style'], {});
goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/connection.js', ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.deprecation'], {});
goog.addDependency('../../core/connection_checker.js', ['Blockly.ConnectionChecker'], ['Blockly.constants', 'Blockly.registry'], {});
goog.addDependency('../../core/connection_db.js', ['Blockly.ConnectionDB'], ['Blockly.RenderedConnection', 'Blockly.constants'], {});
@@ -42,10 +40,24 @@ goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems
goog.addDependency('../../core/contextmenu_registry.js', ['Blockly.ContextMenuRegistry'], ['Blockly.ContextMenuItems'], {'lang': 'es5'});
goog.addDependency('../../core/css.js', ['Blockly.Css'], [], {'lang': 'es5'});
goog.addDependency('../../core/dropdowndiv.js', ['Blockly.DropDownDiv'], ['Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.style'], {});
goog.addDependency('../../core/events.js', ['Blockly.Events'], ['Blockly.registry', 'Blockly.utils'], {});
goog.addDependency('../../core/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {});
goog.addDependency('../../core/events/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/events/events.js', ['Blockly.Events'], ['Blockly.registry', 'Blockly.utils'], {});
goog.addDependency('../../core/events/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {});
goog.addDependency('../../core/events/events_block_drag.js', ['Blockly.Events.BlockDrag'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_bubble_open.js', ['Blockly.Events.BubbleOpen'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_click.js', ['Blockly.Events.Click'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_marker_move.js', ['Blockly.Events.MarkerMove'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_selected.js', ['Blockly.Events.Selected'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_theme_change.js', ['Blockly.Events.ThemeChange'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_toolbox_item_select.js', ['Blockly.Events.ToolboxItemSelect'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_trashcan_open.js', ['Blockly.Events.TrashcanOpen'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/events_viewport.js', ['Blockly.Events.ViewportChange'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/ui_events.js', ['Blockly.Events.Ui', 'Blockly.Events.UiBase'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/variable_events.js', ['Blockly.Events.VarBase', 'Blockly.Events.VarCreate', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/events/workspace_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/events/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/extensions.js', ['Blockly.Extensions'], ['Blockly.utils'], {});
goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.Tooltip', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'});
goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.Tooltip', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'});
goog.addDependency('../../core/field_angle.js', ['Blockly.FieldAngle'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.FieldTextInput', 'Blockly.fieldRegistry', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/field_checkbox.js', ['Blockly.FieldCheckbox'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/field_colour.js', ['Blockly.FieldColour'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils.IdGenerator', 'Blockly.utils.KeyCodes', 'Blockly.utils.Size', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
@@ -64,10 +76,10 @@ goog.addDependency('../../core/flyout_dragger.js', ['Blockly.FlyoutDragger'], ['
goog.addDependency('../../core/flyout_horizontal.js', ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object'], {});
goog.addDependency('../../core/flyout_vertical.js', ['Blockly.VerticalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/generator.js', ['Blockly.Generator'], ['Blockly.Block', 'Blockly.constants'], {});
goog.addDependency('../../core/gesture.js', ['Blockly.Gesture'], ['Blockly.ASTNode', 'Blockly.BlockDragger', 'Blockly.BubbleDragger', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/gesture.js', ['Blockly.Gesture'], ['Blockly.ASTNode', 'Blockly.BlockDragger', 'Blockly.BubbleDragger', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/grid.js', ['Blockly.Grid'], ['Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/icon.js', ['Blockly.Icon'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/inject.js', ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Component', 'Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Grid', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.user.keyMap', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/inject.js', ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Grid', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'Blockly.constants'], {});
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations', 'Blockly.constants'], {'lang': 'es5'});
goog.addDependency('../../core/interfaces/i_accessibility.js', ['Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IBlocklyActionable'], [], {});
@@ -86,22 +98,20 @@ goog.addDependency('../../core/interfaces/i_selectable.js', ['Blockly.ISelectabl
goog.addDependency('../../core/interfaces/i_styleable.js', ['Blockly.IStyleable'], [], {});
goog.addDependency('../../core/interfaces/i_toolbox.js', ['Blockly.IToolbox'], [], {});
goog.addDependency('../../core/interfaces/i_toolbox_item.js', ['Blockly.ICollapsibleToolboxItem', 'Blockly.ISelectableToolboxItem', 'Blockly.IToolboxItem'], [], {});
goog.addDependency('../../core/keyboard_nav/action.js', ['Blockly.Action'], [], {});
goog.addDependency('../../core/keyboard_nav/ast_node.js', ['Blockly.ASTNode'], ['Blockly.constants', 'Blockly.utils.Coordinate'], {'lang': 'es5'});
goog.addDependency('../../core/keyboard_nav/basic_cursor.js', ['Blockly.BasicCursor'], ['Blockly.ASTNode', 'Blockly.Cursor'], {'lang': 'es5'});
goog.addDependency('../../core/keyboard_nav/cursor.js', ['Blockly.Cursor'], ['Blockly.ASTNode', 'Blockly.Action', 'Blockly.Marker', 'Blockly.navigation', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/keyboard_nav/cursor.js', ['Blockly.Cursor'], ['Blockly.ASTNode', 'Blockly.Marker', 'Blockly.navigation', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/keyboard_nav/flyout_cursor.js', ['Blockly.FlyoutCursor'], ['Blockly.Cursor', 'Blockly.navigation', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/keyboard_nav/key_map.js', ['Blockly.user.keyMap'], ['Blockly.utils.KeyCodes', 'Blockly.utils.object'], {});
goog.addDependency('../../core/keyboard_nav/marker.js', ['Blockly.Marker'], ['Blockly.ASTNode', 'Blockly.navigation'], {});
goog.addDependency('../../core/keyboard_nav/navigation.js', ['Blockly.navigation'], ['Blockly.ASTNode', 'Blockly.Action', 'Blockly.constants', 'Blockly.user.keyMap', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/keyboard_nav/navigation.js', ['Blockly.navigation'], ['Blockly.ASTNode', 'Blockly.constants', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/keyboard_nav/tab_navigate_cursor.js', ['Blockly.TabNavigateCursor'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.utils.object'], {});
goog.addDependency('../../core/marker_manager.js', ['Blockly.MarkerManager'], ['Blockly.Cursor', 'Blockly.Marker'], {});
goog.addDependency('../../core/menu.js', ['Blockly.Menu'], ['Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.style'], {});
goog.addDependency('../../core/menuitem.js', ['Blockly.MenuItem'], ['Blockly.utils.IdGenerator', 'Blockly.utils.aria', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/msg.js', ['Blockly.Msg'], ['Blockly.utils.global'], {});
goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.toolbox', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.toolbox', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/names.js', ['Blockly.Names'], ['Blockly.Msg', 'Blockly.constants'], {});
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.registry', 'Blockly.user.keyMap', 'Blockly.utils.IdGenerator', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.IdGenerator', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/procedures.js', ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.Names', 'Blockly.Workspace', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/registry.js', ['Blockly.registry'], [], {});
goog.addDependency('../../core/rendered_connection.js', ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
@@ -111,7 +121,7 @@ goog.addDependency('../../core/renderers/common/debugger.js', ['Blockly.blockRen
goog.addDependency('../../core/renderers/common/drawer.js', ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.svgPaths'], {});
goog.addDependency('../../core/renderers/common/i_path_object.js', ['Blockly.blockRendering.IPathObject'], [], {});
goog.addDependency('../../core/renderers/common/info.js', ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.constants'], {});
goog.addDependency('../../core/renderers/common/marker_svg.js', ['Blockly.blockRendering.MarkerSvg'], ['Blockly.ASTNode', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/renderers/common/marker_svg.js', ['Blockly.blockRendering.MarkerSvg'], ['Blockly.ASTNode', 'Blockly.Events.MarkerMove', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/renderers/common/path_object.js', ['Blockly.blockRendering.PathObject'], ['Blockly.Theme', 'Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.IPathObject', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/renderers/common/renderer.js', ['Blockly.blockRendering.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.IPathObject', 'Blockly.blockRendering.MarkerSvg', 'Blockly.blockRendering.PathObject', 'Blockly.blockRendering.RenderInfo', 'Blockly.constants'], {});
goog.addDependency('../../core/renderers/geras/constants.js', ['Blockly.geras.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.object'], {'lang': 'es5'});
@@ -145,6 +155,8 @@ goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos.
goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.constants', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo'], {});
goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer'], {});
goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.utils.KeyCodes'], {});
goog.addDependency('../../core/shortcut_registry.js', ['Blockly.ShortcutRegistry'], ['Blockly.ShortcutItems', 'Blockly.navigation', 'Blockly.utils.object'], {});
goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.object'], {});
goog.addDependency('../../core/theme/classic.js', ['Blockly.Themes.Classic'], ['Blockly.Theme'], {});
goog.addDependency('../../core/theme/dark.js', ['Blockly.Themes.Dark'], ['Blockly.Theme'], {});
@@ -157,13 +169,12 @@ goog.addDependency('../../core/theme_manager.js', ['Blockly.ThemeManager'], ['Bl
goog.addDependency('../../core/toolbox/category.js', ['Blockly.ToolboxCategory'], ['Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/collapsible_category.js', ['Blockly.CollapsibleToolboxCategory'], ['Blockly.ToolboxCategory', 'Blockly.ToolboxItem', 'Blockly.ToolboxSeparator', 'Blockly.registry', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/toolbox/separator.js', ['Blockly.ToolboxSeparator'], ['Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils.dom'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Touch', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.ToolboxItemSelect', 'Blockly.Touch', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'], [], {});
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.utils.string'], {});
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string'], {});
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {});
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/ui_events.js', ['Blockly.Events.Ui'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events.TrashcanOpen', 'Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {});
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {});
@@ -185,23 +196,20 @@ goog.addDependency('../../core/utils/svg_paths.js', ['Blockly.utils.svgPaths'],
goog.addDependency('../../core/utils/toolbox.js', ['Blockly.utils.toolbox'], ['Blockly.constants'], {});
goog.addDependency('../../core/utils/useragent.js', ['Blockly.utils.userAgent'], ['Blockly.utils.global'], {});
goog.addDependency('../../core/utils/xml.js', ['Blockly.utils.xml'], [], {});
goog.addDependency('../../core/variable_events.js', ['Blockly.Events.VarBase', 'Blockly.Events.VarCreate', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
goog.addDependency('../../core/variable_map.js', ['Blockly.VariableMap'], ['Blockly.Events', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename', 'Blockly.Msg', 'Blockly.utils', 'Blockly.utils.object'], {});
goog.addDependency('../../core/variable_model.js', ['Blockly.VariableModel'], ['Blockly.Events', 'Blockly.Events.VarCreate', 'Blockly.utils'], {});
goog.addDependency('../../core/variables.js', ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/variables_dynamic.js', ['Blockly.VariablesDynamic'], ['Blockly.Blocks', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/warning.js', ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/warning.js', ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/widgetdiv.js', ['Blockly.WidgetDiv'], ['Blockly.utils.style'], {});
goog.addDependency('../../core/workspace.js', ['Blockly.Workspace'], ['Blockly.ConnectionChecker', 'Blockly.Events', 'Blockly.Options', 'Blockly.VariableMap', 'Blockly.utils', 'Blockly.utils.math'], {});
goog.addDependency('../../core/workspace_audio.js', ['Blockly.WorkspaceAudio'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.userAgent'], {'lang': 'es5'});
goog.addDependency('../../core/workspace_comment.js', ['Blockly.WorkspaceComment'], ['Blockly.Events', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/workspace_comment_render_svg.js', ['Blockly.WorkspaceCommentSvg.render'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCommentSvg'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.Events.Ui', 'Blockly.WorkspaceComment', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCommentSvg'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.Events.Selected', 'Blockly.WorkspaceComment', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/workspace_drag_surface_svg.js', ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger'], ['Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/workspace_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.VarCreate', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
goog.addDependency("base.js", [], []);
+1 -1
View File
@@ -176,7 +176,7 @@ Blockly.Blocks['lists_create_with'] = {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
while (itemBlock) {
while (itemBlock && !itemBlock.isInsertionMarker()) {
connections.push(itemBlock.valueConnection_);
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
+1 -1
View File
@@ -365,7 +365,7 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
var valueConnections = [null];
var statementConnections = [null];
var elseStatementConnection = null;
while (clauseBlock) {
while (clauseBlock && !clauseBlock.isInsertionMarker()) {
switch (clauseBlock.type) {
case 'controls_if_elseif':
this.elseifCount_++;
+1 -2
View File
@@ -334,9 +334,8 @@ Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
// Don't change state if:
// * It's at the start of a drag.
// * It's not a move event.
// * Or the moving block is not this block.
if (!this.workspace.isDragging || this.workspace.isDragging() ||
e.type != Blockly.Events.BLOCK_MOVE || e.blockId != this.id) {
e.type != Blockly.Events.BLOCK_MOVE) {
return;
}
var enabled = Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN
+14 -6
View File
@@ -28,7 +28,8 @@ Blockly.Blocks['procedures_defnoreturn'] = {
* @this {Blockly.Block}
*/
init: function() {
var nameField = new Blockly.FieldTextInput('',
var initName = Blockly.Procedures.findLegalName('', this);
var nameField = new Blockly.FieldTextInput(initName,
Blockly.Procedures.rename);
nameField.setSpellcheck(false);
this.appendDummyInput()
@@ -213,7 +214,7 @@ Blockly.Blocks['procedures_defnoreturn'] = {
this.paramIds_ = [];
this.argumentVarModels_ = [];
var paramBlock = containerBlock.getInputTargetBlock('STACK');
while (paramBlock) {
while (paramBlock && !paramBlock.isInsertionMarker()) {
var varName = paramBlock.getFieldValue('NAME');
this.arguments_.push(varName);
var variable = this.workspace.getVariable(varName, '');
@@ -405,7 +406,8 @@ Blockly.Blocks['procedures_defreturn'] = {
* @this {Blockly.Block}
*/
init: function() {
var nameField = new Blockly.FieldTextInput('',
var initName = Blockly.Procedures.findLegalName('', this);
var nameField = new Blockly.FieldTextInput(initName,
Blockly.Procedures.rename);
nameField.setSpellcheck(false);
this.appendDummyInput()
@@ -592,7 +594,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
*/
init: function() {
this.appendDummyInput('TOPROW')
.appendField(this.id, 'NAME');
.appendField('', 'NAME');
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setStyle('procedure_blocks');
@@ -873,8 +875,13 @@ Blockly.Blocks['procedures_callnoreturn'] = {
block.appendChild(mutation);
var field = Blockly.utils.xml.createElement('field');
field.setAttribute('name', 'NAME');
field.appendChild(Blockly.utils.xml.createTextNode(
this.getProcedureCall()));
var callName = this.getProcedureCall();
if (!callName) {
// Rename if name is empty string.
callName = Blockly.Procedures.findLegalName('', this);
this.renameProcedure('', callName);
}
field.appendChild(Blockly.utils.xml.createTextNode(callName));
block.appendChild(field);
xml.appendChild(block);
Blockly.Xml.domToWorkspace(xml, this.workspace);
@@ -955,6 +962,7 @@ Blockly.Blocks['procedures_callreturn'] = {
// Tooltip is set in domToMutation.
this.setHelpUrl(Blockly.Msg['PROCEDURES_CALLRETURN_HELPURL']);
this.arguments_ = [];
this.argumentVarModels_ = [];
this.quarkConnections_ = {};
this.quarkIds_ = null;
this.previousEnabledState_ = true;
+1 -1
View File
@@ -722,7 +722,7 @@ Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
var itemBlock = containerBlock.getInputTargetBlock('STACK');
// Count number of inputs.
var connections = [];
while (itemBlock) {
while (itemBlock && !itemBlock.isInsertionMarker()) {
connections.push(itemBlock.valueConnection_);
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
+24 -24
View File
@@ -18,9 +18,9 @@ Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LI
message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,style:"list_blocks",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",style:"list_blocks",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",message0:"%{BKY_LISTS_LENGTH_TITLE}",
args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",style:"list_blocks",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setStyle("list_blocks");this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b&&!b.isInsertionMarker();)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+
b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||
this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
Blockly.Blocks.lists_create_with_container={init:function(){this.setStyle("list_blocks");this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.lists_create_with_item={init:function(){this.setStyle("list_blocks");this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setStyle("list_blocks");this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
@@ -57,7 +57,7 @@ Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTRO
enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,suppressPrefixSuffix:!0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=Blockly.utils.xml.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.rebuildShape_()},
decompose:function(a){var b=a.newBlock("controls_if_if");b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){a=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;for(var b=[null],c=[null],d=null;a;){switch(a.type){case "controls_if_elseif":this.elseifCount_++;
decompose:function(a){var b=a.newBlock("controls_if_if");b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){a=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;for(var b=[null],c=[null],d=null;a&&!a.isInsertionMarker();){switch(a.type){case "controls_if_elseif":this.elseifCount_++;
b.push(a.valueConnection_);c.push(a.statementConnection_);break;case "controls_if_else":this.elseCount_++;d=a.statementConnection_;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}this.updateShape_();this.reconnectChildBlocks_(b,c,d)},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+b);a.valueConnection_=c&&c.connection.targetConnection;
a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}},rebuildShape_:function(){var a=[null],b=[null],c=null;this.getInput("ELSE")&&(c=this.getInput("ELSE").connection.targetConnection);for(var d=1;this.getInput("IF"+d);){var e=this.getInput("IF"+d),f=this.getInput("DO"+
d);a.push(e.connection.targetConnection);b.push(f.connection.targetConnection);d++}this.updateShape_();this.reconnectChildBlocks_(a,b,c)},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
@@ -76,8 +76,8 @@ extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Co
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 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){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.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){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",
@@ -96,37 +96,37 @@ Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){va
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){a="DIVISIBLE_BY"==a;this.getSourceBlock().updateShape_(a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};
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<this.argumentVarModels_.length;c++){var d=Blockly.utils.xml.createElement("arg"),e=this.argumentVarModels_[c];d.setAttribute("name",
e.name);d.setAttribute("varid",e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varid")||c.getAttribute("varId");this.arguments_.push(d);c=Blockly.Variables.getOrCreateVariablePackage(this.workspace,c,
d,"");null!=c?this.argumentVarModels_.push(c):console.log("Failed to create a variable with name "+d+", ignoring.")}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=Blockly.utils.xml.createElement("block");b.setAttribute("type","procedures_mutatorcontainer");var c=Blockly.utils.xml.createElement("statement");c.setAttribute("name","STACK");b.appendChild(c);for(var d=0;d<this.arguments_.length;d++){var e=
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=Blockly.Procedures.findLegalName("",this);a=new Blockly.FieldTextInput(a,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<this.argumentVarModels_.length;c++){var d=Blockly.utils.xml.createElement("arg"),
e=this.argumentVarModels_[c];d.setAttribute("name",e.name);d.setAttribute("varid",e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varid")||c.getAttribute("varId");this.arguments_.push(d);c=Blockly.Variables.getOrCreateVariablePackage(this.workspace,
c,d,"");null!=c?this.argumentVarModels_.push(c):console.log("Failed to create a variable with name "+d+", ignoring.")}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=Blockly.utils.xml.createElement("block");b.setAttribute("type","procedures_mutatorcontainer");var c=Blockly.utils.xml.createElement("statement");c.setAttribute("name","STACK");b.appendChild(c);for(var d=0;d<this.arguments_.length;d++){var e=
Blockly.utils.xml.createElement("block");e.setAttribute("type","procedures_mutatorarg");var f=Blockly.utils.xml.createElement("field");f.setAttribute("name","NAME");var g=Blockly.utils.xml.createTextNode(this.arguments_[d]);f.appendChild(g);e.appendChild(f);f=Blockly.utils.xml.createElement("next");e.appendChild(f);c.appendChild(e);c=f}a=Blockly.Xml.domToBlock(b,a);"procedures_defreturn"==this.type?a.setFieldValue(this.hasStatements_,"STATEMENTS"):a.removeInput("STATEMENT_INPUT");Blockly.Procedures.mutateCallers(this);
return a},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b;){var c=b.getFieldValue("NAME");this.arguments_.push(c);c=this.workspace.getVariable(c,"");this.argumentVarModels_.push(c);this.paramIds_.push(b.id);b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),
return a},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b&&!b.isInsertionMarker();){var c=b.getFieldValue("NAME");this.arguments_.push(c);c=this.workspace.getVariable(c,"");this.argumentVarModels_.push(c);this.paramIds_.push(b.id);b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),
Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},renameVarById:function(a,b){var c=this.workspace.getVariableById(a);
if(""==c.type){c=c.name;b=this.workspace.getVariableById(b);for(var d=!1,e=0;e<this.argumentVarModels_.length;e++)this.argumentVarModels_[e].getId()==a&&(this.arguments_[e]=b.name,this.argumentVarModels_[e]=b,d=!0);d&&(this.displayRenamedVar_(c,b.name),Blockly.Procedures.mutateCallers(this))}},updateVarName:function(a){for(var b=a.name,c=!1,d=0;d<this.argumentVarModels_.length;d++)if(this.argumentVarModels_[d].getId()==a.getId()){var e=this.arguments_[d];this.arguments_[d]=b;c=!0}c&&(this.displayRenamedVar_(e,
b),Blockly.Procedures.mutateCallers(this))},displayRenamedVar_:function(a,b){this.updateParams_();if(this.mutator&&this.mutator.isVisible())for(var c=this.mutator.workspace_.getAllBlocks(!1),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){if(!this.isInFlyout){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=Blockly.utils.xml.createElement("mutation");
d.setAttribute("name",c);for(c=0;c<this.arguments_.length;c++){var e=Blockly.utils.xml.createElement("arg");e.setAttribute("name",this.arguments_[c]);d.appendChild(e)}c=Blockly.utils.xml.createElement("block");c.setAttribute("type",this.callType_);c.appendChild(d);b.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(b);if(!this.isCollapsed())for(c=0;c<this.argumentVarModels_.length;c++)b={enabled:!0},d=this.argumentVarModels_[c],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",d.name),
d=Blockly.Variables.generateVariableFieldDom(d),e=Blockly.utils.xml.createElement("block"),e.setAttribute("type","variables_get"),e.appendChild(d),b.callback=Blockly.ContextMenu.callbackFactory(this,e),a.push(b)}},callType_:"procedures_callnoreturn"};
Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_defnoreturn.getVarModels,renameVarById:Blockly.Blocks.procedures_defnoreturn.renameVarById,
updateVarName:Blockly.Blocks.procedures_defnoreturn.updateVarName,displayRenamedVar_:Blockly.Blocks.procedures_defnoreturn.displayRenamedVar_,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,callType_:"procedures_callreturn"};
Blockly.Blocks.procedures_defreturn={init:function(){var a=Blockly.Procedures.findLegalName("",this);a=new Blockly.FieldTextInput(a,Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||
this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,
updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_defnoreturn.getVarModels,
renameVarById:Blockly.Blocks.procedures_defnoreturn.renameVarById,updateVarName:Blockly.Blocks.procedures_defnoreturn.updateVarName,displayRenamedVar_:Blockly.Blocks.procedures_defnoreturn.displayRenamedVar_,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,callType_:"procedures_callreturn"};
Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);this.appendStatementInput("STACK");this.appendDummyInput("STATEMENT_INPUT").appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS).appendField(new Blockly.FieldCheckbox("TRUE"),"STATEMENTS");this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput(Blockly.Procedures.DEFAULT_ARG,this.validator_);a.oldShowEditorFn_=a.showEditor_;a.showEditor_=function(){this.createdVariables_=[];this.oldShowEditorFn_()};this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=
!1;a.onFinishEditing_=this.deleteIntermediateVars_;a.createdVariables_=[];a.onFinishEditing_("x")},validator_:function(a){var b=this.getSourceBlock(),c=Blockly.Mutator.findParentWs(b.workspace);a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"");if(!a)return null;for(var d=(b.workspace.targetWorkspace||b.workspace).getAllBlocks(!1),e=a.toLowerCase(),f=0;f<d.length;f++)if(d[f].id!=this.getSourceBlock().id){var g=d[f].getFieldValue("NAME");if(g&&g.toLowerCase()==e)return null}if(b.isInFlyout)return a;
(b=c.getVariable(a,""))&&b.name!=a&&c.renameVariableById(b.getId(),a);b||(b=c.createVariable(a,""))&&this.createdVariables_&&this.createdVariables_.push(b);return a},deleteIntermediateVars_:function(a){var b=Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);if(b)for(var c=0;c<this.createdVariables_.length;c++){var d=this.createdVariables_[c];d.name!=a&&b.deleteVariableById(d.getId())}}};
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,
this.getProcedureCall())&&(this.setFieldValue(b,"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),d=c&&c.mutator&&c.mutator.isVisible();d||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(a.join("\n")==this.arguments_.join("\n"))this.quarkIds_=b;else{if(b.length!=a.length)throw RangeError("paramNames and paramIds must be the same length.");
this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},this.quarkIds_=[]);c=this.rendered;this.rendered=!1;for(var e=0;e<this.arguments_.length;e++){var f=this.getInput("ARG"+e);f&&(f=f.connection.targetConnection,this.quarkConnections_[this.quarkIds_[e]]=f,d&&f&&-1==b.indexOf(this.quarkIds_[e])&&(f.disconnect(),f.getSourceBlock().bumpNeighbours()))}this.arguments_=[].concat(a);this.argumentVarModels_=[];for(e=0;e<this.arguments_.length;e++)a=Blockly.Variables.getOrCreateVariablePackage(this.workspace,
null,this.arguments_[e],""),this.argumentVarModels_.push(a);this.updateShape_();if(this.quarkIds_=b)for(e=0;e<this.arguments_.length;e++)b=this.quarkIds_[e],b in this.quarkConnections_&&(f=this.quarkConnections_[b],Blockly.Mutator.reconnect(f,this,"ARG"+e)||delete this.quarkConnections_[b]);(this.rendered=c)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=
new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("name",this.getProcedureCall());
for(var b=0;b<this.arguments_.length;b++){var c=Blockly.utils.xml.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},
onchange:function(a){if(this.workspace&&!this.workspace.isFlyout&&a.recordUndo)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.getVars())==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=Blockly.utils.xml.createElement("xml");b=Blockly.utils.xml.createElement("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),
d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","NAME");c.appendChild(Blockly.utils.xml.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE?(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,
this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0),Blockly.Events.setGroup(!1))):a.type==Blockly.Events.CHANGE&&"disabled"==a.element&&(b=this.getProcedureCall(),(b=Blockly.Procedures.getDefinition(b,this.workspace))&&b.id==a.blockId&&((b=Blockly.Events.getGroup())&&console.log("Saw an existing group while responding to a definition change"),Blockly.Events.setGroup(a.group),a.newValue?(this.previousEnabledState_=this.isEnabled(),this.setEnabled(!1)):this.setEnabled(this.previousEnabledState_),
Blockly.Events.setGroup(b)))},customContextMenu:function(a){if(this.workspace.isMovable()){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var e=Blockly.Procedures.getDefinition(c,d);e&&(d.centerOnBlock(e.id),e.select())};a.push(b)}},defType_:"procedures_defnoreturn"};
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","NAME");d=this.getProcedureCall();d||(d=Blockly.Procedures.findLegalName("",this),this.renameProcedure("",d));c.appendChild(Blockly.utils.xml.createTextNode(d));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE?
(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0),Blockly.Events.setGroup(!1))):a.type==Blockly.Events.CHANGE&&"disabled"==a.element&&(b=this.getProcedureCall(),(b=Blockly.Procedures.getDefinition(b,this.workspace))&&b.id==a.blockId&&((b=Blockly.Events.getGroup())&&console.log("Saw an existing group while responding to a definition change"),Blockly.Events.setGroup(a.group),a.newValue?(this.previousEnabledState_=this.isEnabled(),
this.setEnabled(!1)):this.setEnabled(this.previousEnabledState_),Blockly.Events.setGroup(b)))},customContextMenu:function(a){if(this.workspace.isMovable()){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var e=Blockly.Procedures.getDefinition(c,d);e&&(d.centerOnBlock(e.id),e.select())};a.push(b)}},defType_:"procedures_defnoreturn"};
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,getVars:Blockly.Blocks.procedures_callnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_callnoreturn.getVarModels,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},mutationToDom:function(){var a=
Blockly.utils.xml.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(a){if(this.workspace.isDragging&&!this.workspace.isDragging()){a=!1;var b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
@@ -156,9 +156,9 @@ Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/p
QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);
c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Extensions.register("text_append_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_TEXT_APPEND_TOOLTIP}","VAR"));
c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b&&!b.isInsertionMarker();)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");
for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);
0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Extensions.register("text_append_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_TEXT_APPEND_TOOLTIP}","VAR"));
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));this.isAt_=a}};
File diff suppressed because one or more lines are too long
+2 -18
View File
@@ -230,7 +230,7 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
// In case init threw, recordUndo flag should still be reset.
Blockly.Events.recordUndo = initialUndoFlag;
}
// Record initial inline state.
/** @type {boolean|undefined} */
this.inputsInlineDefault = this.inputsInline;
@@ -580,8 +580,7 @@ Blockly.Block.prototype.lastConnectionInStack = function() {
* connected should not coincidentally line up on screen.
*/
Blockly.Block.prototype.bumpNeighbours = function() {
console.warn('Not expected to reach Block.bumpNeighbours function. ' +
'BlockSvg.bumpNeighbours was expected to be called instead.');
// noop.
};
/**
@@ -840,7 +839,6 @@ Blockly.Block.prototype.setShadow = function(shadow) {
/**
* Get whether this block is an insertion marker block or not.
* @return {boolean} True if an insertion marker.
* @package
*/
Blockly.Block.prototype.isInsertionMarker = function() {
return this.isInsertionMarker_;
@@ -1262,20 +1260,6 @@ Blockly.Block.prototype.getOutputShape = function() {
return this.outputShape_;
};
/**
* Set whether the block is disabled or not.
* @param {boolean} disabled True if disabled.
* @deprecated May 2019
*/
Blockly.Block.prototype.setDisabled = function(disabled) {
Blockly.utils.deprecation.warn(
'Block.prototype.setDisabled',
'May 2019',
'May 2020',
'Block.prototype.setEnabled');
this.setEnabled(!disabled);
};
/**
* Get whether this block is enabled or not.
* @return {boolean} True if enabled.
+5 -5
View File
@@ -16,7 +16,7 @@ goog.require('Blockly.blockAnimations');
goog.require('Blockly.constants');
goog.require('Blockly.Events');
goog.require('Blockly.Events.BlockMove');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.BlockDrag');
goog.require('Blockly.InsertionMarkerManager');
goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');
@@ -184,8 +184,8 @@ Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY,
* @private
*/
Blockly.BlockDragger.prototype.fireDragStartEvent_ = function() {
var event = new Blockly.Events.Ui(this.draggingBlock_, 'dragStart',
null, this.draggingBlock_.getDescendants(false));
var event = new Blockly.Events.BlockDrag(this.draggingBlock_, true,
this.draggingBlock_.getDescendants(false));
Blockly.Events.fire(event);
};
@@ -261,8 +261,8 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
* @private
*/
Blockly.BlockDragger.prototype.fireDragEndEvent_ = function() {
var event = new Blockly.Events.Ui(this.draggingBlock_, 'dragStop',
this.draggingBlock_.getDescendants(false), null);
var event = new Blockly.Events.BlockDrag(this.draggingBlock_, false,
this.draggingBlock_.getDescendants(false));
Blockly.Events.fire(event);
};
+12 -21
View File
@@ -20,8 +20,8 @@ goog.require('Blockly.constants');
goog.require('Blockly.ContextMenu');
goog.require('Blockly.ContextMenuRegistry');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.BlockMove');
goog.require('Blockly.Events.Selected');
goog.require('Blockly.Msg');
goog.require('Blockly.navigation');
goog.require('Blockly.RenderedConnection');
@@ -34,6 +34,7 @@ goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.userAgent');
goog.requireType('Blockly.IASTNodeLocationSvg');
goog.requireType('Blockly.IBoundedElement');
@@ -117,6 +118,10 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
// Expose this block's ID on its top-level SVG group.
if (this.svgGroup_.dataset) {
this.svgGroup_.dataset['id'] = this.id;
} else if (Blockly.utils.userAgent.IE) {
// SVGElement.dataset is not available on IE11, but data-* properties
// can be set with setAttribute().
this.svgGroup_.setAttribute('data-id', this.id);
}
};
Blockly.utils.object.inherits(Blockly.BlockSvg, Blockly.Block);
@@ -295,8 +300,7 @@ Blockly.BlockSvg.prototype.select = function() {
Blockly.Events.enable();
}
}
var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id);
event.workspaceId = this.workspace.id;
var event = new Blockly.Events.Selected(oldId, this.id, this.workspace.id);
Blockly.Events.fire(event);
Blockly.selected = this;
this.addSelect();
@@ -309,7 +313,7 @@ Blockly.BlockSvg.prototype.unselect = function() {
if (Blockly.selected != this) {
return;
}
var event = new Blockly.Events.Ui(null, 'selected', this.id, null);
var event = new Blockly.Events.Selected(this.id, null, this.workspace.id);
event.workspaceId = this.workspace.id;
Blockly.Events.fire(event);
Blockly.selected = null;
@@ -680,10 +684,11 @@ Blockly.BlockSvg.prototype.tab = function(start, forward) {
var tabCursor = new Blockly.TabNavigateCursor();
tabCursor.setCurNode(Blockly.ASTNode.createFieldNode(start));
var currentNode = tabCursor.getCurNode();
var action = forward ?
Blockly.navigation.ACTION_NEXT : Blockly.navigation.ACTION_PREVIOUS;
var actionName = forward ?
Blockly.navigation.actionNames.NEXT : Blockly.navigation.actionNames.PREVIOUS;
tabCursor.onBlocklyAction(action);
tabCursor.onBlocklyAction(
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */ ({name: actionName}));
var nextNode = tabCursor.getCurNode();
if (nextNode && nextNode !== currentNode) {
@@ -1135,20 +1140,6 @@ Blockly.BlockSvg.prototype.setMutator = function(mutator) {
}
};
/**
* Set whether the block is disabled or not.
* @param {boolean} disabled True if disabled.
* @deprecated May 2019
*/
Blockly.BlockSvg.prototype.setDisabled = function(disabled) {
Blockly.utils.deprecation.warn(
'BlockSvg.prototype.setDisabled',
'May 2019',
'May 2020',
'BlockSvg.prototype.setEnabled');
this.setEnabled(!disabled);
};
/**
* Set whether the block is enabled or not.
* @param {boolean} enabled True if enabled.
+39 -84
View File
@@ -19,9 +19,10 @@ goog.provide('Blockly');
goog.require('Blockly.constants');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.inject');
goog.require('Blockly.navigation');
goog.require('Blockly.Procedures');
goog.require('Blockly.ShortcutRegistry');
goog.require('Blockly.Tooltip');
goog.require('Blockly.Touch');
goog.require('Blockly.utils');
@@ -177,89 +178,18 @@ Blockly.onKeyDown = function(e) {
// hidden.
return;
}
Blockly.ShortcutRegistry.registry.onKeyDown(mainWorkspace, e);
};
if (mainWorkspace.options.readOnly) {
// When in read only mode handle key actions for keyboard navigation.
Blockly.navigation.onKeyPress(e);
return;
}
var deleteBlock = false;
if (e.keyCode == Blockly.utils.KeyCodes.ESC) {
// Pressing esc closes the context menu.
Blockly.hideChaff();
Blockly.navigation.onBlocklyAction(Blockly.navigation.ACTION_EXIT);
} else if (!Blockly.Gesture.inProgress() && Blockly.navigation.onKeyPress(e)) {
// If the keyboard or field handled the key press return.
return;
} else if (e.keyCode == Blockly.utils.KeyCodes.BACKSPACE ||
e.keyCode == Blockly.utils.KeyCodes.DELETE) {
// Delete or backspace.
// Stop the browser from going back to the previous page.
// Do this first to prevent an error in the delete code from resulting in
// data loss.
e.preventDefault();
// Don't delete while dragging. Jeez.
if (Blockly.Gesture.inProgress()) {
return;
}
if (Blockly.selected && Blockly.selected.isDeletable()) {
deleteBlock = true;
}
} else if (e.altKey || e.ctrlKey || e.metaKey) {
// Don't use meta keys during drags.
if (Blockly.Gesture.inProgress()) {
return;
}
if (Blockly.selected &&
Blockly.selected.isDeletable() && Blockly.selected.isMovable()) {
// Don't allow copying immovable or undeletable blocks. The next step
// would be to paste, which would create additional undeletable/immovable
// blocks on the workspace.
if (e.keyCode == Blockly.utils.KeyCodes.C) {
// 'c' for copy.
Blockly.hideChaff();
Blockly.copy_(Blockly.selected);
} else if (e.keyCode == Blockly.utils.KeyCodes.X &&
!Blockly.selected.workspace.isFlyout) {
// 'x' for cut, but not in a flyout.
// Don't even copy the selected item in the flyout.
Blockly.copy_(Blockly.selected);
deleteBlock = true;
}
}
if (e.keyCode == Blockly.utils.KeyCodes.V) {
// 'v' for paste.
if (Blockly.clipboardXml_) {
// Pasting always pastes to the main workspace, even if the copy
// started in a flyout workspace.
var workspace = Blockly.clipboardSource_;
if (workspace.isFlyout) {
workspace = workspace.targetWorkspace;
}
if (Blockly.clipboardTypeCounts_ &&
workspace.isCapacityAvailable(Blockly.clipboardTypeCounts_)) {
Blockly.Events.setGroup(true);
workspace.paste(Blockly.clipboardXml_);
Blockly.Events.setGroup(false);
}
}
} else if (e.keyCode == Blockly.utils.KeyCodes.Z) {
// 'z' for undo 'Z' is for redo.
Blockly.hideChaff();
mainWorkspace.undo(e.shiftKey);
} else if (e.ctrlKey && e.keyCode == Blockly.utils.KeyCodes.Y) {
// Ctrl-y is redo in Windows. Command-y is never valid on Macs.
Blockly.hideChaff();
mainWorkspace.undo(true);
}
}
// Common code for delete and cut.
// Don't delete in the flyout.
if (deleteBlock && !Blockly.selected.workspace.isFlyout) {
/**
* Delete the given block.
* @param {!Blockly.BlockSvg} selected The block to delete.
* @package
*/
Blockly.deleteBlock = function(selected) {
if (!selected.workspace.isFlyout) {
Blockly.Events.setGroup(true);
Blockly.hideChaff();
var selected = /** @type {!Blockly.BlockSvg} */ (Blockly.selected);
selected.dispose(/* heal */ true, true);
Blockly.Events.setGroup(false);
}
@@ -268,9 +198,9 @@ Blockly.onKeyDown = function(e) {
/**
* Copy a block or workspace comment onto the local clipboard.
* @param {!Blockly.ICopyable} toCopy Block or Workspace Comment to be copied.
* @private
* @package
*/
Blockly.copy_ = function(toCopy) {
Blockly.copy = function(toCopy) {
var data = toCopy.toCopyData();
if (data) {
Blockly.clipboardXml_ = data.xml;
@@ -279,6 +209,31 @@ Blockly.copy_ = function(toCopy) {
}
};
/**
* Paste a block or workspace comment on to the main workspace.
* @return {boolean} True if the paste was successful, false otherwise.
* @package
*/
Blockly.paste = function() {
if (!Blockly.clipboardXml_) {
return false;
}
// Pasting always pastes to the main workspace, even if the copy
// started in a flyout workspace.
var workspace = Blockly.clipboardSource_;
if (workspace.isFlyout) {
workspace = workspace.targetWorkspace;
}
if (Blockly.clipboardTypeCounts_ &&
workspace.isCapacityAvailable(Blockly.clipboardTypeCounts_)) {
Blockly.Events.setGroup(true);
workspace.paste(Blockly.clipboardXml_);
Blockly.Events.setGroup(false);
return true;
}
return false;
};
/**
* Duplicate this block and its children, or a workspace comment.
* @param {!Blockly.ICopyable} toDuplicate Block or Workspace Comment to be
@@ -291,7 +246,7 @@ Blockly.duplicate = function(toDuplicate) {
var clipboardSource = Blockly.clipboardSource_;
// Create a duplicate via a copy/paste operation.
Blockly.copy_(toDuplicate);
Blockly.copy(toDuplicate);
toDuplicate.workspace.paste(Blockly.clipboardXml_);
// Restore the clipboard.
+54
View File
@@ -878,3 +878,57 @@ Blockly.Bubble.prototype.getRelativeToSurfaceXY = function() {
Blockly.Bubble.prototype.setAutoLayout = function(enable) {
this.autoLayout_ = enable;
};
/**
* Create the text for a non editable bubble.
* @param {string} text The text to display.
* @return {!SVGTextElement} The top-level node of the text.
* @package
*/
Blockly.Bubble.textToDom = function(text) {
var paragraph = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.TEXT,
{
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
'y': Blockly.Bubble.BORDER_WIDTH
},
null);
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++) {
var tspanElement = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.TSPAN,
{'dy': '1em', 'x': Blockly.Bubble.BORDER_WIDTH}, paragraph);
var textNode = document.createTextNode(lines[i]);
tspanElement.appendChild(textNode);
}
return paragraph;
};
/**
* Creates a bubble that can not be edited.
* @param {!SVGTextElement} paragraphElement The text element for the non editable bubble.
* @param {!Blockly.BlockSvg} block The block that the bubble is attached to.
* @param {!Blockly.utils.Coordinate} iconXY The coordinate of the icon.
* @return {!Blockly.Bubble} The non editable bubble.
* @package
*/
Blockly.Bubble.createNonEditableBubble = function(paragraphElement, block, iconXY) {
var bubble = new Blockly.Bubble(
/** @type {!Blockly.WorkspaceSvg} */ (block.workspace),
paragraphElement, block.pathObject.svgPath,
/** @type {!Blockly.utils.Coordinate} */ (iconXY), null, null);
// Expose this bubble's block's ID on its top-level SVG group.
bubble.setSvgId(block.id);
if (block.RTL) {
// Right-align the paragraph.
// This cannot be done until the bubble is rendered on screen.
var maxWidth = paragraphElement.getBBox().width;
for (var i = 0, textElement;
(textElement = paragraphElement.childNodes[i]); i++) {
textElement.setAttribute('text-anchor', 'end');
textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH);
}
}
return bubble;
};
+9 -45
View File
@@ -16,7 +16,7 @@ goog.require('Blockly.Bubble');
goog.require('Blockly.Css');
goog.require('Blockly.Events');
goog.require('Blockly.Events.BlockChange');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.BubbleOpen');
goog.require('Blockly.Icon');
goog.require('Blockly.utils.deprecation');
goog.require('Blockly.utils.dom');
@@ -236,7 +236,7 @@ Blockly.Comment.prototype.setVisible = function(visible) {
return;
}
Blockly.Events.fire(
new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible));
new Blockly.Events.BubbleOpen(this.block_, visible, 'comment'));
this.model_.pinned = visible;
if (visible) {
this.createBubble_();
@@ -251,7 +251,6 @@ Blockly.Comment.prototype.setVisible = function(visible) {
*/
Blockly.Comment.prototype.createBubble_ = function() {
if (!this.block_.isEditable() || Blockly.utils.userAgent.IE) {
// Steal the code from warnings to make an uneditable text bubble.
// MSIE does not support foreignobject; textareas are impossible.
// https://docs.microsoft.com/en-us/openspecs/ie_standards/ms-svg/56e6e04c-7c8c-44dd-8100-bd745ee42034
// Always treat comments in IE as uneditable.
@@ -284,7 +283,11 @@ Blockly.Comment.prototype.createEditableBubble_ = function() {
*/
Blockly.Comment.prototype.createNonEditableBubble_ = function() {
// TODO (#2917): It would be great if the comment could support line breaks.
Blockly.Warning.prototype.createBubble.call(this);
this.paragraphElement_ = Blockly.Bubble.textToDom(this.block_.getCommentText());
this.bubble_ = Blockly.Bubble.createNonEditableBubble(
this.paragraphElement_, /** @type {!Blockly.BlockSvg} */ (this.block_),
/** @type {!Blockly.utils.Coordinate} */ (this.iconXY_));
this.applyColour();
};
/**
@@ -293,11 +296,6 @@ Blockly.Comment.prototype.createNonEditableBubble_ = function() {
* @suppress {checkTypes} Suppress `this` type mismatch.
*/
Blockly.Comment.prototype.disposeBubble_ = function() {
if (this.paragraphElement_) {
// We're using the warning UI so we have to let it dispose.
Blockly.Warning.prototype.disposeBubble.call(this);
return;
}
if (this.onMouseUpWrapper_) {
Blockly.unbindEvent_(this.onMouseUpWrapper_);
this.onMouseUpWrapper_ = null;
@@ -318,6 +316,7 @@ Blockly.Comment.prototype.disposeBubble_ = function() {
this.bubble_ = null;
this.textarea_ = null;
this.foreignObject_ = null;
this.paragraphElement_ = null;
};
/**
@@ -360,41 +359,6 @@ Blockly.Comment.prototype.setBubbleSize = function(width, height) {
}
};
/**
* Returns this comment's text.
* @return {string} Comment text.
* @deprecated August 2019 Use block.getCommentText() instead.
*/
Blockly.Comment.prototype.getText = function() {
Blockly.utils.deprecation.warn(
'Comment.prototype.getText',
'August 2019',
'December 2020',
'block.getCommentText');
return this.model_.text || '';
};
/**
* Set this comment's text.
*
* If you want to receive a comment change event, then this should not be called
* directly. Instead call block.setCommentText();
* @param {string} text Comment text.
* @deprecated August 2019 Use block.setCommentText() instead.
*/
Blockly.Comment.prototype.setText = function(text) {
Blockly.utils.deprecation.warn(
'Comment.prototype.setText',
'August 2019',
'December 2020',
'block.setCommentText');
if (this.model_.text == text) {
return;
}
this.model_.text = text;
this.updateText();
};
/**
* Update the comment's view to match the model.
* @package
@@ -433,7 +397,7 @@ Blockly.Css.register([
'padding: 3px;',
'resize: none;',
'display: block;',
'overflow: hidden;',
'text-overflow: hidden;',
'}'
/* eslint-enable indent */
]);
-554
View File
@@ -1,554 +0,0 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Definition of the Blockly.Component class.
* This class is similar to Closure's goog.ui.Component class.
* @author samelh@google.com (Sam El-Husseini)
*/
'use strict';
goog.provide('Blockly.Component');
goog.provide('Blockly.Component.Error');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.IdGenerator');
goog.require('Blockly.utils.style');
/**
* Default implementation of a UI component.
* Similar to Closure's goog.ui.Component.
*
* @constructor
*/
Blockly.Component = function() {
/**
* Whether the component is rendered right-to-left.
* @type {boolean}
* @protected
*/
this.rightToLeft_ = Blockly.Component.defaultRightToLeft;
/**
* Unique ID of the component, lazily initialized in {@link
* Blockly.Component#getId} if needed. This property is strictly private and
* must not be accessed directly outside of this class!
* @type {?string}
* @private
*/
this.id_ = null;
/**
* Whether the component is in the document.
* @type {boolean}
* @private
*/
this.inDocument_ = false;
/**
* The DOM element for the component.
* @type {?Element}
* @private
*/
this.element_ = null;
/**
* Parent component to which events will be propagated. This property is
* strictly private and must not be accessed directly outside of this class!
* @type {?Blockly.Component}
* @private
*/
this.parent_ = null;
/**
* Array of child components.
* Must be kept in sync with `childIndex_`. This property is strictly
* private and must not be accessed directly outside of this class!
* @type {?Array.<?Blockly.Component>}
* @private
*/
this.children_ = [];
/**
* Map of child component IDs to child components. Used for constant-time
* random access to child components by ID.
* Must be kept in sync with `children_`. This property is strictly
* private and must not be accessed directly outside of this class!
*
* @type {?Object}
* @private
*/
this.childIndex_ = {};
/**
* Whether or not the component has been disposed.
* @type {boolean}
* @private
*/
this.disposed_ = false;
};
/**
* The default right to left value.
* @type {boolean}
* @package
*/
Blockly.Component.defaultRightToLeft = false;
/**
* Errors thrown by the component.
* @enum {string}
*/
Blockly.Component.Error = {
/**
* Error when the component is already rendered and another render attempt is
* made.
*/
ALREADY_RENDERED: 'Component already rendered',
/**
* Error when an attempt is made to set the parent of a component in a way
* that would result in an inconsistent object graph.
*/
PARENT_UNABLE_TO_BE_SET: 'Unable to set parent component',
/**
* Error when an attempt is made to add a child component at an out-of-bounds
* index. We don't support sparse child arrays.
*/
CHILD_INDEX_OUT_OF_BOUNDS: 'Child component index out of bounds',
/**
* Error when calling an abstract method that should be overriden.
*/
ABSTRACT_METHOD: 'Unimplemented abstract method'
};
/**
* Gets the unique ID for the instance of this component. If the instance
* doesn't already have an ID, generates one on the fly.
* @return {string} Unique component ID.
* @package
*/
Blockly.Component.prototype.getId = function() {
return this.id_ || (this.id_ = Blockly.utils.IdGenerator.getNextUniqueId());
};
/**
* Gets the component's element.
* @return {Element} The element for the component.
* @package
*/
Blockly.Component.prototype.getElement = function() {
return this.element_;
};
/**
* Sets the component's root element to the given element. Considered
* protected and final.
*
* This should generally only be called during createDom. Setting the element
* does not actually change which element is rendered, only the element that is
* associated with this UI component.
*
* This should only be used by subclasses and its associated renderers.
*
* @param {Element} element Root element for the component.
* @protected
*/
Blockly.Component.prototype.setElementInternal = function(element) {
this.element_ = element;
};
/**
* Sets the parent of this component to use for event bubbling. Throws an error
* if the component already has a parent or if an attempt is made to add a
* component to itself as a child.
* @param {Blockly.Component} parent The parent component.
* @protected
*/
Blockly.Component.prototype.setParent = function(parent) {
if (this == parent) {
// Attempting to add a child to itself is an error.
throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);
}
if (parent && this.parent_ && this.id_ && this.parent_.getChild(this.id_) &&
this.parent_ != parent) {
// This component is already the child of some parent.
throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);
}
this.parent_ = parent;
};
/**
* Returns the component's parent, if any.
* @return {?Blockly.Component} The parent component.
* @protected
*/
Blockly.Component.prototype.getParent = function() {
return this.parent_;
};
/**
* Determines whether the component has been added to the document.
* @return {boolean} TRUE if rendered. Otherwise, FALSE.
* @protected
*/
Blockly.Component.prototype.isInDocument = function() {
return this.inDocument_;
};
/**
* Creates the initial DOM representation for the component.
* @protected
*/
Blockly.Component.prototype.createDom = function() {
throw Error(Blockly.Component.Error.ABSTRACT_METHOD);
};
/**
* Renders the component. If a parent element is supplied, the component's
* element will be appended to it. If there is no optional parent element and
* the element doesn't have a parentNode then it will be appended to the
* document body.
*
* If this component has a parent component, and the parent component is
* not in the document already, then this will not call `enterDocument`
* on this component.
*
* Throws an Error if the component is already rendered.
*
* @param {Element=} opt_parentElement Optional parent element to render the
* component into.
* @package
*/
Blockly.Component.prototype.render = function(opt_parentElement) {
this.render_(opt_parentElement);
};
/**
* Renders the component. If a parent element is supplied, the component's
* element will be appended to it. If there is no optional parent element and
* the element doesn't have a parentNode then it will be appended to the
* document body.
*
* If this component has a parent component, and the parent component is
* not in the document already, then this will not call `enterDocument`
* on this component.
*
* Throws an Error if the component is already rendered.
*
* @param {Element=} opt_parentElement Optional parent element to render the
* component into.
* @param {Node=} opt_beforeNode Node before which the component is to
* be rendered. If left out the node is appended to the parent element.
* @private
*/
Blockly.Component.prototype.render_ = function(
opt_parentElement, opt_beforeNode) {
if (this.inDocument_) {
throw Error(Blockly.Component.Error.ALREADY_RENDERED);
}
if (!this.element_) {
this.createDom();
}
if (opt_parentElement) {
opt_parentElement.insertBefore(this.element_, opt_beforeNode || null);
} else {
document.body.appendChild(this.element_);
}
// If this component has a parent component that isn't in the document yet,
// we don't call enterDocument() here. Instead, when the parent component
// enters the document, the enterDocument() call will propagate to its
// children, including this one. If the component doesn't have a parent
// or if the parent is already in the document, we call enterDocument().
if (!this.parent_ || this.parent_.isInDocument()) {
this.enterDocument();
}
};
/**
* Called when the component's element is known to be in the document. Anything
* using document.getElementById etc. should be done at this stage.
*
* If the component contains child components, this call is propagated to its
* children.
* @protected
*/
Blockly.Component.prototype.enterDocument = function() {
this.inDocument_ = true;
// Propagate enterDocument to child components that have a DOM, if any.
// If a child was decorated before entering the document (permitted when
// Blockly.Component.ALLOW_DETACHED_DECORATION is true), its enterDocument
// will be called here.
this.forEachChild(function(child) {
if (!child.isInDocument() && child.getElement()) {
child.enterDocument();
}
});
};
/**
* Called by dispose to clean up the elements and listeners created by a
* component, or by a parent component/application who has removed the
* component from the document but wants to reuse it later.
*
* If the component contains child components, this call is propagated to its
* children.
*
* It should be possible for the component to be rendered again once this method
* has been called.
* @protected
*/
Blockly.Component.prototype.exitDocument = function() {
// Propagate exitDocument to child components that have been rendered, if any.
this.forEachChild(function(child) {
if (child.isInDocument()) {
child.exitDocument();
}
});
this.inDocument_ = false;
};
/**
* Disposes of the object. If the object hasn't already been disposed of, calls
* {@link #disposeInternal}.
* @package
*/
Blockly.Component.prototype.dispose = function() {
if (!this.disposed_) {
// Set disposed_ to true first, in case during the chain of disposal this
// gets disposed recursively.
this.disposed_ = true;
this.disposeInternal();
}
};
/**
* Disposes of the component. Calls `exitDocument`, which is expected to
* remove event handlers and clean up the component. Propagates the call to
* the component's children, if any. Removes the component's DOM from the
* document.
* @protected
*/
Blockly.Component.prototype.disposeInternal = function() {
if (this.inDocument_) {
this.exitDocument();
}
// Disposes of the component's children, if any.
this.forEachChild(function(child) { child.dispose(); });
// Detach the component's element from the DOM.
if (this.element_) {
Blockly.utils.dom.removeNode(this.element_);
}
this.children_ = null;
this.childIndex_ = null;
this.element_ = null;
this.parent_ = null;
};
/**
* Adds the specified component as the last child of this component. See
* {@link Blockly.Component#addChildAt} for detailed semantics.
*
* @see Blockly.Component#addChildAt
* @param {Blockly.Component} child The new child component.
* @param {boolean=} opt_render If true, the child component will be rendered
* into the parent.
* @package
*/
Blockly.Component.prototype.addChild = function(child, opt_render) {
this.addChildAt(child, this.getChildCount(), opt_render);
};
/**
* Adds the specified component as a child of this component at the given
* 0-based index.
*
* Both `addChild` and `addChildAt` assume the following contract
* between parent and child components:
* <ul>
* <li>the child component's element must be a descendant of the parent
* component's element, and
* <li>the DOM state of the child component must be consistent with the DOM
* state of the parent component (see `isInDocument`) in the
* steady state -- the exception is to addChildAt(child, i, false) and
* then immediately decorate/render the child.
* </ul>
*
* In particular, `parent.addChild(child)` will throw an error if the
* child component is already in the document, but the parent isn't.
*
* Clients of this API may call `addChild` and `addChildAt` with
* `opt_render` set to true. If `opt_render` is true, calling these
* methods will automatically render the child component's element into the
* parent component's element. If the parent does not yet have an element, then
* `createDom` will automatically be invoked on the parent before
* rendering the child.
*
* Invoking {@code parent.addChild(child, true)} will throw an error if the
* child component is already in the document, regardless of the parent's DOM
* state.
*
* If `opt_render` is true and the parent component is not already
* in the document, `enterDocument` will not be called on this component
* at this point.
*
* Finally, this method also throws an error if the new child already has a
* different parent, or the given index is out of bounds.
*
* @see Blockly.Component#addChild
* @param {Blockly.Component} child The new child component.
* @param {number} index 0-based index at which the new child component is to be
* added; must be between 0 and the current child count (inclusive).
* @param {boolean=} opt_render If true, the child component will be rendered
* into the parent.
* @protected
*/
Blockly.Component.prototype.addChildAt = function(child, index, opt_render) {
if (child.inDocument_ && (opt_render || !this.inDocument_)) {
// Adding a child that's already in the document is an error, except if the
// parent is also in the document and opt_render is false (e.g. decorate()).
throw Error(Blockly.Component.Error.ALREADY_RENDERED);
}
if (index < 0 || index > this.getChildCount()) {
// Allowing sparse child arrays would lead to strange behavior, so we don't.
throw Error(Blockly.Component.Error.CHILD_INDEX_OUT_OF_BOUNDS);
}
// Moving child within component, remove old reference.
this.childIndex_[child.getId()] = child;
if (child.getParent() == this) {
// Remove from this.children_
var i = this.children_.indexOf(child);
if (i > -1) {
this.children_.splice(i, 1);
}
}
// Set the parent of the child to this component. This throws an error if
// the child is already contained by another component.
child.setParent(this);
this.children_.splice(index, 0, child);
if (child.inDocument_ && this.inDocument_ && child.getParent() == this) {
// Changing the position of an existing child, move the DOM node (if
// necessary).
var contentElement = this.getContentElement();
var insertBeforeElement = contentElement.childNodes[index] || null;
if (insertBeforeElement != child.getElement()) {
contentElement.insertBefore(child.getElement(), insertBeforeElement);
}
} else if (opt_render) {
// If this (parent) component doesn't have a DOM yet, call createDom now
// to make sure we render the child component's element into the correct
// parent element (otherwise render_ with a null first argument would
// render the child into the document body, which is almost certainly not
// what we want).
if (!this.element_) {
this.createDom();
}
// Render the child into the parent at the appropriate location. Note that
// getChildAt(index + 1) returns undefined if inserting at the end.
var sibling = this.getChildAt(index + 1);
// render_() calls enterDocument() if the parent is already in the document.
child.render_(this.getContentElement(), sibling ? sibling.element_ : null);
} else if (this.inDocument_ && !child.inDocument_ && child.element_ &&
child.element_.parentNode &&
// Under some circumstances, IE8 implicitly creates a Document Fragment
// for detached nodes, so ensure the parent is an Element as it should be.
child.element_.parentNode.nodeType ==
Blockly.utils.dom.NodeType.ELEMENT_NODE) {
// We don't touch the DOM, but if the parent is in the document, and the
// child element is in the document but not marked as such, then we call
// enterDocument on the child.
child.enterDocument();
}
};
/**
* Returns the DOM element into which child components are to be rendered,
* or null if the component itself hasn't been rendered yet. This default
* implementation returns the component's root element. Subclasses with
* complex DOM structures must override this method.
* @return {Element} Element to contain child elements (null if none).
* @protected
*/
Blockly.Component.prototype.getContentElement = function() {
return this.element_;
};
/**
* Returns true if the component has children.
* @return {boolean} True if the component has children.
* @protected
*/
Blockly.Component.prototype.hasChildren = function() {
return this.children_.length != 0;
};
/**
* Returns the number of children of this component.
* @return {number} The number of children.
* @protected
*/
Blockly.Component.prototype.getChildCount = function() {
return this.children_.length;
};
/**
* Returns the child with the given ID, or null if no such child exists.
* @param {string} id Child component ID.
* @return {?Blockly.Component} The child with the given ID; null if none.
* @protected
*/
Blockly.Component.prototype.getChild = function(id) {
// Use childIndex_ for O(1) access by ID.
return id ?
/** @type {Blockly.Component} */ (this.childIndex_[id]) || null : null;
};
/**
* Returns the child at the given index, or null if the index is out of bounds.
* @param {number} index 0-based index.
* @return {?Blockly.Component} The child at the given index; null if none.
* @protected
*/
Blockly.Component.prototype.getChildAt = function(index) {
// Use children_ for access by index.
return this.children_[index] || null;
};
/**
* Calls the given function on each of this component's children in order. If
* `opt_obj` is provided, it will be used as the 'this' object in the
* function when called. The function should take two arguments: the child
* component and its 0-based index. The return value is ignored.
* @param {function(this:T,?,number):?} f The function to call for every
* child component; should take 2 arguments (the child and its index).
* @param {T=} opt_obj Used as the 'this' object in f when called.
* @template T
* @protected
*/
Blockly.Component.prototype.forEachChild = function(f, opt_obj) {
for (var i = 0; i < this.children_.length; i++) {
f.call(/** @type {?} */ (opt_obj), this.children_[i], i);
}
};
+13 -13
View File
@@ -38,7 +38,7 @@ Blockly.ContextMenuItems.registerUndo = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'undoWorkspace',
weight: 0,
weight: 1,
};
Blockly.ContextMenuRegistry.registry.register(undoOption);
};
@@ -59,7 +59,7 @@ Blockly.ContextMenuItems.registerRedo = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'redoWorkspace',
weight: 0,
weight: 2,
};
Blockly.ContextMenuRegistry.registry.register(redoOption);
};
@@ -85,7 +85,7 @@ Blockly.ContextMenuItems.registerCleanup = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'cleanWorkspace',
weight: 0,
weight: 3,
};
Blockly.ContextMenuRegistry.registry.register(cleanOption);
};
@@ -137,7 +137,7 @@ Blockly.ContextMenuItems.registerCollapse = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'collapseWorkspace',
weight: 0,
weight: 4,
};
Blockly.ContextMenuRegistry.registry.register(collapseOption);
};
@@ -170,7 +170,7 @@ Blockly.ContextMenuItems.registerExpand = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'expandWorkspace',
weight: 0,
weight: 5,
};
Blockly.ContextMenuRegistry.registry.register(expandOption);
};
@@ -273,7 +273,7 @@ Blockly.ContextMenuItems.registerDeleteAll = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
id: 'workspaceDelete',
weight: 0,
weight: 6,
};
Blockly.ContextMenuRegistry.registry.register(deleteOption);
};
@@ -315,7 +315,7 @@ Blockly.ContextMenuItems.registerDuplicate = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockDuplicate',
weight: 0,
weight: 1,
};
Blockly.ContextMenuRegistry.registry.register(duplicateOption);
};
@@ -351,7 +351,7 @@ Blockly.ContextMenuItems.registerComment = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockComment',
weight: 0,
weight: 2,
};
Blockly.ContextMenuRegistry.registry.register(commentOption);
};
@@ -382,7 +382,7 @@ Blockly.ContextMenuItems.registerInline = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockInline',
weight: 0,
weight: 3,
};
Blockly.ContextMenuRegistry.registry.register(inlineOption);
};
@@ -409,7 +409,7 @@ Blockly.ContextMenuItems.registerCollapseExpandBlock = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockCollapseExpand',
weight: 0,
weight: 4,
};
Blockly.ContextMenuRegistry.registry.register(collapseExpandOption);
};
@@ -445,7 +445,7 @@ Blockly.ContextMenuItems.registerDisable = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockDisable',
weight: 0,
weight: 5,
};
Blockly.ContextMenuRegistry.registry.register(disableOption);
};
@@ -479,7 +479,7 @@ Blockly.ContextMenuItems.registerDelete = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockDelete',
weight: 0,
weight: 6,
};
Blockly.ContextMenuRegistry.registry.register(deleteOption);
};
@@ -505,7 +505,7 @@ Blockly.ContextMenuItems.registerHelp = function() {
},
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
id: 'blockHelp',
weight: 0,
weight: 7,
};
Blockly.ContextMenuRegistry.registry.register(helpOption);
};
+3
View File
@@ -498,8 +498,11 @@ Blockly.Css.CONTENT = [
'}',
'.blocklyDropDownDiv .blocklyMenu {',
'background: inherit;', /* Compatibility with gapi, reset from goog-menu */
'border: inherit;', /* Compatibility with gapi, reset from goog-menu */
'font: normal 13px "Helvetica Neue", Helvetica, sans-serif;',
'outline: none;',
'position: relative;', /* Compatibility with gapi, reset from goog-menu */
'z-index: 20000;', /* Arbitrary, but some apps depend on it... */
'}',
@@ -128,6 +128,7 @@ Blockly.Events.Change.prototype.toJson = function() {
if (this.name) {
json['name'] = this.name;
}
json['oldValue'] = this.oldValue;
json['newValue'] = this.newValue;
return json;
};
@@ -140,6 +141,7 @@ Blockly.Events.Change.prototype.fromJson = function(json) {
Blockly.Events.Change.superClass_.fromJson.call(this, json);
this.element = json['element'];
this.name = json['name'];
this.oldValue = json['oldValue'];
this.newValue = json['newValue'];
};
@@ -255,6 +257,9 @@ Blockly.Events.Create.prototype.toJson = function() {
var json = Blockly.Events.Create.superClass_.toJson.call(this);
json['xml'] = Blockly.Xml.domToText(this.xml);
json['ids'] = this.ids;
if (!this.recordUndo) {
json['recordUndo'] = this.recordUndo;
}
return json;
};
@@ -266,6 +271,9 @@ Blockly.Events.Create.prototype.fromJson = function(json) {
Blockly.Events.Create.superClass_.fromJson.call(this, json);
this.xml = Blockly.Xml.textToDom(json['xml']);
this.ids = json['ids'];
if (json['recordUndo'] !== undefined) {
this.recordUndo = json['recordUndo'];
}
};
/**
@@ -340,7 +348,11 @@ Blockly.Events.Delete.prototype.type = Blockly.Events.DELETE;
*/
Blockly.Events.Delete.prototype.toJson = function() {
var json = Blockly.Events.Delete.superClass_.toJson.call(this);
json['oldXml'] = Blockly.Xml.domToText(this.oldXml);
json['ids'] = this.ids;
if (!this.recordUndo) {
json['recordUndo'] = this.recordUndo;
}
return json;
};
@@ -350,7 +362,11 @@ Blockly.Events.Delete.prototype.toJson = function() {
*/
Blockly.Events.Delete.prototype.fromJson = function(json) {
Blockly.Events.Delete.superClass_.fromJson.call(this, json);
this.oldXml = Blockly.Xml.textToDom(json['oldXml']);
this.ids = json['ids'];
if (json['recordUndo'] !== undefined) {
this.recordUndo = json['recordUndo'];
}
};
/**
@@ -430,6 +446,9 @@ Blockly.Events.Move.prototype.toJson = function() {
json['newCoordinate'] = Math.round(this.newCoordinate.x) + ',' +
Math.round(this.newCoordinate.y);
}
if (!this.recordUndo) {
json['recordUndo'] = this.recordUndo;
}
return json;
};
@@ -446,6 +465,9 @@ Blockly.Events.Move.prototype.fromJson = function(json) {
this.newCoordinate =
new Blockly.utils.Coordinate(Number(xy[0]), Number(xy[1]));
}
if (json['recordUndo'] !== undefined) {
this.recordUndo = json['recordUndo'];
}
};
/**
+79 -19
View File
@@ -107,11 +107,65 @@ Blockly.Events.VAR_DELETE = 'var_delete';
Blockly.Events.VAR_RENAME = 'var_rename';
/**
* Name of event that records a UI change.
* Name of generic event that records a UI change.
* @const
*/
Blockly.Events.UI = 'ui';
/**
* Name of event that record a block drags a block.
* @const
*/
Blockly.Events.BLOCK_DRAG = 'drag';
/**
* Name of event that records a change in selected element.
* @const
*/
Blockly.Events.SELECTED = 'selected';
/**
* Name of event that records a click.
* @const
*/
Blockly.Events.CLICK = 'click';
/**
* Name of event that records a marker move.
* @const
*/
Blockly.Events.MARKER_MOVE = 'marker_move';
/**
* Name of event that records a bubble open.
* @const
*/
Blockly.Events.BUBBLE_OPEN = 'bubble_open';
/**
* Name of event that records a trashcan open.
* @const
*/
Blockly.Events.TRASHCAN_OPEN = 'trashcan_open';
/**
* Name of event that records a toolbox item select.
* @const
*/
Blockly.Events.TOOLBOX_ITEM_SELECT = 'toolbox_item_select';
/**
* Name of event that records a theme change.
* @const
*/
Blockly.Events.THEME_CHANGE = 'theme_change';
/**
* Name of event that records a viewport change.
* @const
*/
Blockly.Events.VIEWPORT_CHANGE = 'viewport_change';
/**
* Name of event that creates a comment.
* @const
@@ -212,7 +266,9 @@ Blockly.Events.filter = function(queueIn, forward) {
// Merge duplicates.
for (var i = 0, event; (event = queue[i]); i++) {
if (!event.isNull()) {
var key = [event.type, event.blockId, event.workspaceId].join(' ');
// Treat all ui events as the same type in hash table.
var eventType = event.isUiEvent ? Blockly.Events.UI : event.type;
var key = [eventType, event.blockId, event.workspaceId].join(' ');
var lastEntry = hash[key];
var lastEvent = lastEntry ? lastEntry.event : null;
@@ -234,16 +290,13 @@ Blockly.Events.filter = function(queueIn, forward) {
event.name == lastEvent.name) {
// Merge change events.
lastEvent.newValue = event.newValue;
} else if (event.type == Blockly.Events.UI &&
event.element == 'click' &&
(lastEvent.element == 'commentOpen' ||
lastEvent.element == 'mutatorOpen' ||
lastEvent.element == 'warningOpen')) {
} else if (event.type == Blockly.Events.CLICK &&
lastEvent.type == Blockly.Events.BUBBLE_OPEN) {
// Drop click events caused by opening/closing bubbles.
} else {
// Collision: newer events should merge into this event to maintain
// order.
hash[key] = {event: event, index: 1};
hash[key] = {event: event, index: i};
mergedQueue.push(event);
}
}
@@ -369,18 +422,25 @@ Blockly.Events.disableOrphans = function(event) {
var workspace = Blockly.Workspace.getById(event.workspaceId);
var block = workspace.getBlockById(event.blockId);
if (block) {
var parent = block.getParent();
if (parent && parent.isEnabled()) {
var children = block.getDescendants(false);
for (var i = 0, child; (child = children[i]); i++) {
child.setEnabled(true);
// Changing blocks as part of this event shouldn't be undoable.
var initialUndoFlag = Blockly.Events.recordUndo;
try {
Blockly.Events.recordUndo = false;
var parent = block.getParent();
if (parent && parent.isEnabled()) {
var children = block.getDescendants(false);
for (var i = 0, child; (child = children[i]); i++) {
child.setEnabled(true);
}
} else if ((block.outputConnection || block.previousConnection) &&
!workspace.isDragging()) {
do {
block.setEnabled(false);
block = block.getNextBlock();
} while (block);
}
} else if ((block.outputConnection || block.previousConnection) &&
!workspace.isDragging()) {
do {
block.setEnabled(false);
block = block.getNextBlock();
} while (block);
} finally {
Blockly.Events.recordUndo = initialUndoFlag;
}
}
}
@@ -49,6 +49,12 @@ Blockly.Events.Abstract = function() {
this.recordUndo = Blockly.Events.recordUndo;
};
/**
* Whether or not the event is a ui event.
* @type {boolean}
*/
Blockly.Events.Abstract.prototype.isUiEvent = false;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
+80
View File
@@ -0,0 +1,80 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a block drag.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.BlockDrag');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a block drag event.
* @param {!Blockly.Block=} opt_block The top block in the stack that is being
* dragged. Undefined for a blank event.
* @param {boolean=} opt_isStart Whether this is the start of a block drag.
* Undefined for a blank event.
* @param {!Array.<!Blockly.Block>=} opt_blocks The blocks affected by this
* drag. Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.BlockDrag = function(opt_block, opt_isStart, opt_blocks) {
var workspaceId = opt_block ? opt_block.workspace.id : undefined;
Blockly.Events.BlockDrag.superClass_.constructor.call(this, workspaceId);
this.blockId = opt_block ? opt_block.id : null;
/**
* Whether this is the start of a block drag.
* @type {boolean|undefined}
*/
this.isStart = opt_isStart;
/**
* The blocks affected by this drag event.
* @type {!Array.<!Blockly.Block>|undefined}
*/
this.blocks = opt_blocks;
};
Blockly.utils.object.inherits(Blockly.Events.BlockDrag, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.BlockDrag.prototype.type = Blockly.Events.BLOCK_DRAG;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.BlockDrag.prototype.toJson = function() {
var json = Blockly.Events.BlockDrag.superClass_.toJson.call(this);
json['isStart'] = this.isStart;
json['blockId'] = this.blockId;
json['blocks'] = this.blocks;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.BlockDrag.prototype.fromJson = function(json) {
Blockly.Events.BlockDrag.superClass_.fromJson.call(this, json);
this.isStart = json['isStart'];
this.blockId = json['blockId'];
this.blocks = json['blocks'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.BLOCK_DRAG, Blockly.Events.BlockDrag);
+80
View File
@@ -0,0 +1,80 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of bubble open.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.BubbleOpen');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a bubble open event.
* @param {Blockly.BlockSvg} opt_block The associated block. Undefined for a
* blank event.
* @param {boolean=} opt_isOpen Whether the bubble is opening (false if
* closing). Undefined for a blank event.
* @param {string=} opt_bubbleType The type of bubble. One of 'mutator', 'comment'
* or 'warning'. Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.BubbleOpen = function(opt_block, opt_isOpen, opt_bubbleType) {
var workspaceId = opt_block ? opt_block.workspace.id : undefined;
Blockly.Events.BubbleOpen.superClass_.constructor.call(this, workspaceId);
this.blockId = opt_block ? opt_block.id : null;
/**
* Whether the bubble is opening (false if closing).
* @type {boolean|undefined}
*/
this.isOpen = opt_isOpen;
/**
* The type of bubble. One of 'mutator', 'comment', or 'warning'.
* @type {string|undefined}
*/
this.bubbleType = opt_bubbleType;
};
Blockly.utils.object.inherits(Blockly.Events.BubbleOpen, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.BubbleOpen.prototype.type = Blockly.Events.BUBBLE_OPEN;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.BubbleOpen.prototype.toJson = function() {
var json = Blockly.Events.BubbleOpen.superClass_.toJson.call(this);
json['isOpen'] = this.isOpen;
json['bubbleType'] = this.bubbleType;
json['blockId'] = this.blockId;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.BubbleOpen.prototype.fromJson = function(json) {
Blockly.Events.BubbleOpen.superClass_.fromJson.call(this, json);
this.isOpen = json['isOpen'];
this.bubbleType = json['bubbleType'];
this.blockId = json['blockId'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.BUBBLE_OPEN, Blockly.Events.BubbleOpen);
+75
View File
@@ -0,0 +1,75 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of UI click in Blockly's editor.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.Click');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a click event.
* @param {?Blockly.Block=} opt_block The affected block. Null for click events
* that do not have an associated block (i.e. workspace click). Undefined
* for a blank event.
* @param {?string=} opt_workspaceId The workspace identifier for this event.
* Not used if block is passed. Undefined for a blank event.
* @param {string=} opt_targetType The type of element targeted by this click
* event. Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.Click = function(opt_block, opt_workspaceId, opt_targetType) {
var workspaceId = opt_block ? opt_block.workspace.id : opt_workspaceId;
Blockly.Events.Click.superClass_.constructor.call(this, workspaceId);
this.blockId = opt_block ? opt_block.id : null;
/**
* The type of element targeted by this click event.
* @type {string|undefined}
*/
this.targetType = opt_targetType;
};
Blockly.utils.object.inherits(Blockly.Events.Click, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.Click.prototype.type = Blockly.Events.CLICK;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.Click.prototype.toJson = function() {
var json = Blockly.Events.Click.superClass_.toJson.call(this);
json['targetType'] = this.targetType;
if (this.blockId) {
json['blockId'] = this.blockId;
}
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.Click.prototype.fromJson = function(json) {
Blockly.Events.Click.superClass_.fromJson.call(this, json);
this.targetType = json['targetType'];
this.blockId = json['blockId'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.CLICK,
Blockly.Events.Click);
+100
View File
@@ -0,0 +1,100 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of a marker move.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.MarkerMove');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a marker move event.
* @param {?Blockly.Block=} opt_block The affected block. Null if current node
* is of type workspace. Undefined for a blank event.
* @param {boolean=} isCursor Whether this is a cursor event. Undefined for a
* blank event.
* @param {?Blockly.ASTNode=} opt_oldNode The old node the marker used to be on.
* Undefined for a blank event.
* @param {!Blockly.ASTNode=} opt_newNode The new node the marker is now on.
* Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.MarkerMove = function(opt_block, isCursor, opt_oldNode,
opt_newNode) {
var workspaceId = opt_block ? opt_block.workspace.id : undefined;
if (opt_newNode && opt_newNode.getType() == Blockly.ASTNode.types.WORKSPACE) {
workspaceId =
(/** @type {!Blockly.Workspace} */ (opt_newNode.getLocation())).id;
}
Blockly.Events.MarkerMove.superClass_.constructor.call(this, workspaceId);
/**
* The workspace identifier for this event.
* @type {?string}
*/
this.blockId = opt_block ? opt_block.id : null;
/**
* The old node the marker used to be on.
* @type {?Blockly.ASTNode|undefined}
*/
this.oldNode = opt_oldNode;
/**
* The new node the marker is now on.
* @type {Blockly.ASTNode|undefined}
*/
this.newNode = opt_newNode;
/**
* Whether this is a cursor event.
* @type {boolean|undefined}
*/
this.isCursor = isCursor;
};
Blockly.utils.object.inherits(Blockly.Events.MarkerMove, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.MarkerMove.prototype.type = Blockly.Events.MARKER_MOVE;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.MarkerMove.prototype.toJson = function() {
var json = Blockly.Events.MarkerMove.superClass_.toJson.call(this);
json['isCursor'] = this.isCursor;
json['blockId'] = this.blockId;
json['oldNode'] = this.oldNode;
json['newNode'] = this.newNode;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.MarkerMove.prototype.fromJson = function(json) {
Blockly.Events.MarkerMove.superClass_.fromJson.call(this, json);
this.isCursor = json['isCursor'];
this.blockId = json['blockId'];
this.oldNode = json['oldNode'];
this.newNode = json['newNode'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.MARKER_MOVE, Blockly.Events.MarkerMove);
+77
View File
@@ -0,0 +1,77 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of element select action.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.Selected');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a selected event.
* @param {?string=} opt_oldElementId The id of the previously selected
* element. Null if no element last selected. Undefined for a blank event.
* @param {?string=} opt_newElementId The id of the selected element. Null if no
* element currently selected (deselect). Undefined for a blank event.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* Null if no element previously selected. Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.Selected = function(opt_oldElementId, opt_newElementId,
opt_workspaceId) {
Blockly.Events.Selected.superClass_.constructor.call(this, opt_workspaceId);
/**
* The id of the last selected element.
* @type {?string|undefined}
*/
this.oldElementId = opt_oldElementId;
/**
* The id of the selected element.
* @type {?string|undefined}
*/
this.newElementId = opt_newElementId;
};
Blockly.utils.object.inherits(Blockly.Events.Selected, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.Selected.prototype.type = Blockly.Events.SELECTED;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.Selected.prototype.toJson = function() {
var json = Blockly.Events.Selected.superClass_.toJson.call(this);
json['oldElementId'] = this.oldElementId;
json['newElementId'] = this.newElementId;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.Selected.prototype.fromJson = function(json) {
Blockly.Events.Selected.superClass_.fromJson.call(this, json);
this.oldElementId = json['oldElementId'];
this.newElementId = json['newElementId'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.SELECTED,
Blockly.Events.Selected);
+65
View File
@@ -0,0 +1,65 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of a theme update.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.ThemeChange');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a theme change event.
* @param {string=} opt_themeName The theme name. Undefined for a blank event.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* event. Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.ThemeChange = function(opt_themeName, opt_workspaceId) {
Blockly.Events.ThemeChange.superClass_.constructor.call(this, opt_workspaceId);
/**
* The theme name.
* @type {string|undefined}
*/
this.themeName = opt_themeName;
};
Blockly.utils.object.inherits(Blockly.Events.ThemeChange, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.ThemeChange.prototype.type = Blockly.Events.THEME_CHANGE;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.ThemeChange.prototype.toJson = function() {
var json = Blockly.Events.ThemeChange.superClass_.toJson.call(this);
json['themeName'] = this.themeName;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.ThemeChange.prototype.fromJson = function(json) {
Blockly.Events.ThemeChange.superClass_.fromJson.call(this, json);
this.themeName = json['themeName'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.THEME_CHANGE, Blockly.Events.ThemeChange);
+78
View File
@@ -0,0 +1,78 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of selecting an item on the toolbox.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.ToolboxItemSelect');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a toolbox item select event.
* @param {?string=} opt_oldItem The previously selected toolbox item. Undefined
* for a blank event.
* @param {?string=} opt_newItem The newly selected toolbox item. Undefined for
* a blank event.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.ToolboxItemSelect = function(opt_oldItem, opt_newItem,
opt_workspaceId) {
Blockly.Events.ToolboxItemSelect.superClass_.constructor.call(
this, opt_workspaceId);
/**
* The previously selected toolbox item.
* @type {?string|undefined}
*/
this.oldItem = opt_oldItem;
/**
* The newly selected toolbox item.
* @type {?string|undefined}
*/
this.newItem = opt_newItem;
};
Blockly.utils.object.inherits(Blockly.Events.ToolboxItemSelect, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.ToolboxItemSelect.prototype.type = Blockly.Events.TOOLBOX_ITEM_SELECT;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.ToolboxItemSelect.prototype.toJson = function() {
var json = Blockly.Events.ToolboxItemSelect.superClass_.toJson.call(this);
json['oldItem'] = this.oldItem;
json['newItem'] = this.newItem;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.ToolboxItemSelect.prototype.fromJson = function(json) {
Blockly.Events.ToolboxItemSelect.superClass_.fromJson.call(this, json);
this.oldItem = json['oldItem'];
this.newItem = json['newItem'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.TOOLBOX_ITEM_SELECT, Blockly.Events.ToolboxItemSelect);
+66
View File
@@ -0,0 +1,66 @@
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of trashcan flyout open and close.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.TrashcanOpen');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a trashcan open event.
* @param {boolean=} opt_isOpen Whether the trashcan flyout is opening (false if
* opening). Undefined for a blank event.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.TrashcanOpen = function(opt_isOpen, opt_workspaceId) {
Blockly.Events.TrashcanOpen.superClass_.constructor.call(this, opt_workspaceId);
/**
* Whether the trashcan flyout is opening (false if closing).
* @type {boolean|undefined}
*/
this.isOpen = opt_isOpen;
};
Blockly.utils.object.inherits(Blockly.Events.TrashcanOpen, Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.TrashcanOpen.prototype.type = Blockly.Events.TRASHCAN_OPEN;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.TrashcanOpen.prototype.toJson = function() {
var json = Blockly.Events.TrashcanOpen.superClass_.toJson.call(this);
json['isOpen'] = this.isOpen;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.TrashcanOpen.prototype.fromJson = function(json) {
Blockly.Events.TrashcanOpen.superClass_.fromJson.call(this, json);
this.isOpen = json['isOpen'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.TRASHCAN_OPEN, Blockly.Events.TrashcanOpen);
+90
View File
@@ -0,0 +1,90 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Events fired as a result of a viewport change.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.Events.ViewportChange');
goog.require('Blockly.Events');
goog.require('Blockly.Events.UiBase');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a viewport change event.
* @param {number=} opt_top Top-edge of the visible portion of the workspace,
* relative to the workspace origin. Undefined for a blank event.
* @param {number=} opt_left Left-edge of the visible portion of the workspace,
* relative to the workspace origin. Undefined for a blank event.
* @param {number=} opt_scale The scale of the workspace. Undefined for a blank
* event.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* Undefined for a blank event.
* @extends {Blockly.Events.UiBase}
* @constructor
*/
Blockly.Events.ViewportChange = function(opt_top, opt_left, opt_scale,
opt_workspaceId) {
Blockly.Events.ViewportChange.superClass_.constructor.call(this, opt_workspaceId);
/**
* Top-edge of the visible portion of the workspace, relative to the workspace
* origin.
* @type {number|undefined}
*/
this.viewTop = opt_top;
/**
* Left-edge of the visible portion of the workspace, relative to the
* workspace origin.
* @type {number|undefined}
*/
this.viewLeft = opt_left;
/**
* The scale of the workspace.
* @type {number|undefined}
*/
this.scale = opt_scale;
};
Blockly.utils.object.inherits(Blockly.Events.ViewportChange,
Blockly.Events.UiBase);
/**
* Type of this event.
* @type {string}
*/
Blockly.Events.ViewportChange.prototype.type = Blockly.Events.VIEWPORT_CHANGE;
/**
* Encode the event as JSON.
* @return {!Object} JSON representation.
*/
Blockly.Events.ViewportChange.prototype.toJson = function() {
var json = Blockly.Events.ViewportChange.superClass_.toJson.call(this);
json['viewTop'] = this.viewTop;
json['viewLeft'] = this.viewLeft;
json['scale'] = this.scale;
return json;
};
/**
* Decode the JSON event.
* @param {!Object} json JSON representation.
*/
Blockly.Events.ViewportChange.prototype.fromJson = function(json) {
Blockly.Events.ViewportChange.superClass_.fromJson.call(this, json);
this.viewTop = json['viewTop'];
this.viewLeft = json['viewLeft'];
this.scale = json['scale'];
};
Blockly.registry.register(Blockly.registry.Type.EVENT,
Blockly.Events.VIEWPORT_CHANGE, Blockly.Events.ViewportChange);
+40 -9
View File
@@ -11,42 +11,73 @@
'use strict';
goog.provide('Blockly.Events.Ui');
goog.provide('Blockly.Events.UiBase');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Abstract');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
/**
* Class for a UI event.
* Base class for a UI event.
* UI events are events that don't need to be sent over the wire for multi-user
* editing to work (e.g. scrolling the workspace, zooming, opening toolbox
* categories).
* UI events do not undo or redo.
* @param {string=} opt_workspaceId The workspace identifier for this event.
* Undefined for a blank event.
* @extends {Blockly.Events.Abstract}
* @constructor
*/
Blockly.Events.UiBase = function(opt_workspaceId) {
Blockly.Events.UiBase.superClass_.constructor.call(this);
/**
* Whether or not the event is blank (to be populated by fromJson).
* @type {boolean}
*/
this.isBlank = typeof opt_workspaceId == 'undefined';
/**
* The workspace identifier for this event.
* @type {string}
*/
this.workspaceId = opt_workspaceId ? opt_workspaceId : '';
// UI events do not undo or redo.
this.recordUndo = false;
};
Blockly.utils.object.inherits(Blockly.Events.UiBase, Blockly.Events.Abstract);
/**
* Whether or not the event is a UI event.
* @type {boolean}
*/
Blockly.Events.UiBase.prototype.isUiEvent = true;
/**
* Class for a UI event.
* @param {?Blockly.Block=} opt_block The affected block. Null for UI events
* that do not have an associated block. Undefined for a blank event.
* @param {string=} opt_element One of 'selected', 'comment', 'mutatorOpen',
* etc.
* @param {*=} opt_oldValue Previous value of element.
* @param {*=} opt_newValue New value of element.
* @extends {Blockly.Events.Abstract}
* @extends {Blockly.Events.UiBase}
* @deprecated December 2020. Instead use a more specific UI event.
* @constructor
*/
Blockly.Events.Ui = function(opt_block, opt_element, opt_oldValue,
opt_newValue) {
Blockly.Events.Ui.superClass_.constructor.call(this);
this.isBlank = typeof opt_block == 'undefined';
var workspaceId = opt_block ? opt_block.workspace.id : undefined;
Blockly.Events.Ui.superClass_.constructor.call(this, workspaceId);
this.blockId = opt_block ? opt_block.id : null;
this.workspaceId = opt_block ? opt_block.workspace.id : undefined;
this.element = typeof opt_element == 'undefined' ? '' : opt_element;
this.oldValue = typeof opt_oldValue == 'undefined' ? '' : opt_oldValue;
this.newValue = typeof opt_newValue == 'undefined' ? '' : opt_newValue;
// UI events do not undo or redo.
this.recordUndo = false;
};
Blockly.utils.object.inherits(Blockly.Events.Ui, Blockly.Events.Abstract);
Blockly.utils.object.inherits(Blockly.Events.Ui, Blockly.Events.UiBase);
/**
* Type of this event.
@@ -13,7 +13,7 @@
goog.provide('Blockly.Events.FinishedLoading');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.Abstract');
goog.require('Blockly.registry');
goog.require('Blockly.utils.object');
@@ -25,7 +25,7 @@ goog.require('Blockly.utils.object');
* Finished loading events do not record undo or redo.
* @param {!Blockly.Workspace=} opt_workspace The workspace that has finished
* loading. Undefined for a blank event.
* @extends {Blockly.Events.Ui}
* @extends {Blockly.Events.Abstract}
* @constructor
*/
Blockly.Events.FinishedLoading = function(opt_workspace) {
@@ -54,7 +54,7 @@ Blockly.Events.FinishedLoading = function(opt_workspace) {
this.recordUndo = false;
};
Blockly.utils.object.inherits(Blockly.Events.FinishedLoading,
Blockly.Events.Ui);
Blockly.Events.Abstract);
/**
* Type of this event.
+4 -84
View File
@@ -19,7 +19,6 @@ goog.require('Blockly.Events.BlockChange');
goog.require('Blockly.Gesture');
goog.require('Blockly.Tooltip');
goog.require('Blockly.utils');
goog.require('Blockly.utils.deprecation');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.Size');
@@ -32,6 +31,7 @@ goog.requireType('Blockly.IASTNodeLocationSvg');
goog.requireType('Blockly.IASTNodeLocationWithBlock');
goog.requireType('Blockly.IBlocklyActionable');
goog.requireType('Blockly.IRegistrable');
goog.requireType('Blockly.ShortcutRegistry');
/**
@@ -532,54 +532,6 @@ Blockly.Field.prototype.getValidator = function() {
return this.validator_;
};
/**
* Validates a change. Does nothing. Subclasses may override this.
* @param {string} text The user's text.
* @return {string} No change needed.
* @deprecated May 2019. Override doClassValidation and other relevant 'do'
* functions instead.
*/
Blockly.Field.prototype.classValidator = function(text) {
Blockly.utils.deprecation.warn(
'Field.prototype.classValidator',
'May 2019',
'December 2020',
'Blockly.Field.prototype.doClassValidation_');
return text;
};
/**
* Calls the validation function for this field, as well as all the validation
* function for the field's class and its parents.
* @param {string} text Proposed text.
* @return {?string} Revised text, or null if invalid.
* @deprecated May 2019. setValue now contains all relevant logic.
*/
Blockly.Field.prototype.callValidator = function(text) {
Blockly.utils.deprecation.warn(
'Field.prototype.callValidator',
'May 2019',
'December 2020');
var classResult = this.classValidator(text);
if (classResult === null) {
// Class validator rejects value. Game over.
return null;
} else if (classResult !== undefined) {
text = classResult;
}
var userValidator = this.getValidator();
if (userValidator) {
var userResult = userValidator.call(this, text);
if (userResult === null) {
// User validator rejects value. Game over.
return null;
} else if (userResult !== undefined) {
text = userResult;
}
}
return text;
};
/**
* Gets the group element for this editable field.
* Used for measuring the size and for positioning.
@@ -624,22 +576,6 @@ Blockly.Field.prototype.showEditor = function(opt_e) {
}
};
/**
* Updates the width of the field. Redirects to updateSize_().
* @deprecated May 2019 Use 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.
*/
Blockly.Field.prototype.updateWidth = function() {
Blockly.utils.deprecation.warn(
'Field.prototype.updateWidth',
'May 2019',
'December 2020',
'Blockly.Field.prototype.updateSize_ or Blockly.utils.dom.getTextWidth');
this.updateSize_();
};
/**
* Updates the size of the field based on the text.
* @param {number=} opt_margin margin to use when positioning the text element.
@@ -817,20 +753,6 @@ Blockly.Field.prototype.getText = function() {
return String(this.getValue());
};
/**
* Set the text in this field. Trigger a rerender of the source block.
* @param {*} _newText New text.
* @deprecated 2019 setText should not be used directly. Use setValue instead.
*/
Blockly.Field.prototype.setText = function(_newText) {
Blockly.utils.deprecation.warn(
'Field.prototype.setText',
'May 2019',
'December 2020',
'Blockly.Field.prototype.setValue');
throw Error('setText method is deprecated');
};
/**
* Force a rerender of the block that this field is installed on, which will
* rerender this field and adjust for any sizing changes.
@@ -898,7 +820,8 @@ Blockly.Field.prototype.setValue = function(newValue) {
}
var oldValue = this.getValue();
if (oldValue === newValue) {
doLogging && console.log('same, return');
doLogging && console.log('same, doValueUpdate_, return');
this.doValueUpdate_(newValue);
return;
}
@@ -949,14 +872,11 @@ Blockly.Field.prototype.getValue = function() {
* @param {*=} opt_newValue The value to be validated.
* @return {*} The validated value, same as input by default.
* @protected
* @suppress {deprecated} Suppress deprecated this.classValidator call.
*/
Blockly.Field.prototype.doClassValidation_ = function(opt_newValue) {
if (opt_newValue === null || opt_newValue === undefined) {
return null;
}
// For backwards compatibility.
opt_newValue = this.classValidator(/** @type {string} */ (opt_newValue));
return opt_newValue;
};
@@ -1106,7 +1026,7 @@ Blockly.Field.prototype.isTabNavigable = function() {
/**
* Handles the given action.
* This is only triggered when keyboard accessibility mode is enabled.
* @param {!Blockly.Action} _action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} _action The action to be handled.
* @return {boolean} True if the field handled the action, false otherwise.
* @package
*/
+17 -13
View File
@@ -27,6 +27,7 @@ goog.require('Blockly.utils.KeyCodes');
goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Size');
goog.requireType('Blockly.ShortcutRegistry');
/**
* Class for a colour input field.
@@ -384,24 +385,27 @@ Blockly.FieldColour.prototype.onKeyDown_ = function(e) {
/**
* Handles the given action.
* This is only triggered when keyboard accessibility mode is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the field handled the action, false otherwise.
* @package
*/
Blockly.FieldColour.prototype.onBlocklyAction = function(action) {
if (this.picker_) {
if (action === Blockly.navigation.ACTION_PREVIOUS) {
this.moveHighlightBy_(0, -1);
return true;
} else if (action === Blockly.navigation.ACTION_NEXT) {
this.moveHighlightBy_(0, 1);
return true;
} else if (action === Blockly.navigation.ACTION_OUT) {
this.moveHighlightBy_(-1, 0);
return true;
} else if (action === Blockly.navigation.ACTION_IN) {
this.moveHighlightBy_(1, 0);
return true;
switch (action.name) {
case Blockly.navigation.actionNames.PREVIOUS:
this.moveHighlightBy_(0, -1);
return true;
case Blockly.navigation.actionNames.NEXT:
this.moveHighlightBy_(0, 1);
return true;
case Blockly.navigation.actionNames.OUT:
this.moveHighlightBy_(-1, 0);
return true;
case Blockly.navigation.actionNames.IN:
this.moveHighlightBy_(1, 0);
return true;
default:
return false;
}
}
return Blockly.FieldColour.superClass_.onBlocklyAction.call(this, action);
+13 -8
View File
@@ -31,6 +31,8 @@ goog.require('Blockly.utils.string');
goog.require('Blockly.utils.Svg');
goog.require('Blockly.utils.userAgent');
goog.requireType('Blockly.ShortcutRegistry');
/**
* Class for an editable dropdown field.
@@ -106,7 +108,7 @@ Blockly.FieldDropdown = function(menuGenerator, opt_validator, opt_config) {
/**
* The dropdown menu.
* @type {Blockly.Menu}
* @private
* @protected
*/
this.menu_ = null;
@@ -739,18 +741,21 @@ Blockly.FieldDropdown.validateOptions_ = function(options) {
/**
* Handles the given action.
* This is only triggered when keyboard accessibility mode is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the field handled the action, false otherwise.
* @package
*/
Blockly.FieldDropdown.prototype.onBlocklyAction = function(action) {
if (this.menu_) {
if (action === Blockly.navigation.ACTION_PREVIOUS) {
this.menu_.highlightPrevious();
return true;
} else if (action === Blockly.navigation.ACTION_NEXT) {
this.menu_.highlightNext();
return true;
switch (action.name) {
case Blockly.navigation.actionNames.PREVIOUS:
this.menu_.highlightPrevious();
return true;
case Blockly.navigation.actionNames.NEXT:
this.menu_.highlightNext();
return true;
default:
return false;
}
}
return Blockly.FieldDropdown.superClass_.onBlocklyAction.call(this, action);
+9 -11
View File
@@ -36,14 +36,12 @@ goog.require('Blockly.utils.userAgent');
* text as an argument and returns either the accepted text, a replacement
* text, or null to abort the change.
* @param {Object=} opt_config A map of options used to configure the field.
* See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/text-input#creation}
* See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/multiline-text-input#creation}
* for a list of properties this parameter supports.
* @extends {Blockly.FieldTextInput}
* @constructor
*/
Blockly.FieldMultilineInput = function(opt_value, opt_validator, opt_config) {
// TODO: Once this field is documented the opt_config link should point to its
// creation documentation, rather than the text input field's.
Blockly.FieldMultilineInput.superClass_.constructor.call(this,
opt_value, opt_validator, opt_config);
@@ -116,13 +114,13 @@ Blockly.FieldMultilineInput.prototype.initView = function() {
* @private
*/
Blockly.FieldMultilineInput.prototype.getDisplayText_ = function() {
var value = this.value_;
if (!value) {
var textLines = this.getText();
if (!textLines) {
// Prevent the field from disappearing if empty.
return Blockly.Field.NBSP;
}
var lines = value.split('\n');
value = '';
var lines = textLines.split('\n');
textLines = '';
for (var i = 0; i < lines.length; i++) {
var text = lines[i];
if (text.length > this.maxDisplayLength) {
@@ -132,16 +130,16 @@ Blockly.FieldMultilineInput.prototype.getDisplayText_ = function() {
// Replace whitespace with non-breaking spaces so the text doesn't collapse.
text = text.replace(/\s/g, Blockly.Field.NBSP);
value += text;
textLines += text;
if (i !== lines.length - 1) {
value += '\n';
textLines += '\n';
}
}
if (this.sourceBlock_.RTL) {
// The SVG is LTR, force value to be RTL.
value += '\u200F';
textLines += '\u200F';
}
return value;
return textLines;
};
/**
+5 -42
View File
@@ -304,11 +304,10 @@ Blockly.FieldTextInput.prototype.showEditor_ = function(_opt_e,
* @private
*/
Blockly.FieldTextInput.prototype.showPromptEditor_ = function() {
var fieldText = this;
Blockly.prompt(Blockly.Msg['CHANGE_VALUE_TITLE'], this.getText(),
function(newValue) {
fieldText.setValue(newValue);
});
function(text) {
this.setValue(this.getValueFromEditorText_(text));
}.bind(this));
};
/**
@@ -385,7 +384,7 @@ Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
/**
* Closes the editor, saves the results, and disposes of any events or
* dom-references belonging to the editor.
* @private
* @protected
*/
Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
// Non-disposal related things that we do when the editor closes.
@@ -430,7 +429,7 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
/**
* Unbind handlers for user input and workspace size changes.
* @private
* @protected
*/
Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() {
if (this.onKeyDownWrapper_) {
@@ -524,42 +523,6 @@ Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
div.style.top = xy.y + 'px';
};
/**
* Ensure that only a number may be entered.
* @param {string} text The user's text.
* @return {?string} A string representing a valid number, or null if invalid.
* @deprecated
*/
Blockly.FieldTextInput.numberValidator = function(text) {
console.warn('Blockly.FieldTextInput.numberValidator is deprecated. ' +
'Use Blockly.FieldNumber instead.');
if (text === null) {
return null;
}
text = String(text);
// TODO: Handle cases like 'ten', '1.203,14', etc.
// 'O' is sometimes mistaken for '0' by inexperienced users.
text = text.replace(/O/ig, '0');
// Strip out thousands separators.
text = text.replace(/,/g, '');
var n = Number(text || 0);
return isNaN(n) ? null : String(n);
};
/**
* Ensure that only a non-negative integer may be entered.
* @param {string} text The user's text.
* @return {?string} A string representing a valid int, or null if invalid.
* @deprecated
*/
Blockly.FieldTextInput.nonnegativeIntegerValidator = function(text) {
var n = Blockly.FieldTextInput.numberValidator(text);
if (n) {
n = String(Math.max(0, Math.floor(n)));
}
return n;
};
/**
* Returns whether or not the field is tab navigable.
* @return {boolean} True if the field is tab navigable.
+1 -1
View File
@@ -65,7 +65,7 @@ Blockly.FieldVariable = function(varName, opt_validator, opt_variableTypes,
* variable.
* @type {string}
*/
this.defaultVariableName = varName || '';
this.defaultVariableName = typeof varName === 'string' ? varName : '';
/**
* The size of the area rendered by the field.
+16 -3
View File
@@ -34,6 +34,7 @@ goog.require('Blockly.Xml');
goog.requireType('Blockly.IBlocklyActionable');
goog.requireType('Blockly.IDeleteArea');
goog.requireType('Blockly.IFlyout');
goog.requireType('Blockly.ShortcutRegistry');
goog.requireType('Blockly.utils.Metrics');
@@ -616,7 +617,7 @@ Blockly.Flyout.prototype.createButton_ = function(btnInfo, isLabel) {
* defined as disabled.
* @param {!Element} blockXml The xml of the block.
* @return {!Blockly.BlockSvg} The block created from the blockXml.
* @private
* @protected
*/
Blockly.Flyout.prototype.createBlock_ = function(blockXml) {
var curBlock = /** @type {!Blockly.BlockSvg} */ (
@@ -683,7 +684,7 @@ Blockly.Flyout.prototype.addSeparatorGap_ = function(sepInfo, gaps, defaultGap)
/**
* Delete blocks, mats and buttons from a previous showing of the flyout.
* @private
* @protected
*/
Blockly.Flyout.prototype.clearOldBlocks_ = function() {
// Delete any blocks from a previous showing.
@@ -997,7 +998,7 @@ Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
/**
* Handles the given action.
* This is only triggered when keyboard accessibility mode is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the flyout handled the action, false otherwise.
* @package
*/
@@ -1069,3 +1070,15 @@ Blockly.Flyout.prototype.wheel_;
* @protected
*/
Blockly.Flyout.prototype.reflowInternal_;
/**
* Calculates the x coordinate for the flyout position.
* @return {number} X coordinate.
*/
Blockly.Flyout.prototype.getX;
/**
* Calculates the y coordinate for the flyout position.
* @return {number} Y coordinate.
*/
Blockly.Flyout.prototype.getY;
+59 -30
View File
@@ -118,6 +118,62 @@ Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
this.workspace_.scrollY + metrics.absoluteTop);
};
/**
* Calculates the x coordinate for the flyout position.
* @return {number} X coordinate.
*/
Blockly.HorizontalFlyout.prototype.getX = function() {
// X is always 0 since this is a horizontal flyout.
return 0;
};
/**
* Calculates the y coordinate for the flyout position.
* @return {number} Y coordinate.
*/
Blockly.HorizontalFlyout.prototype.getY = function() {
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
if (!targetWorkspaceMetrics) {
// Hidden components will return null.
return 0;
}
var y = 0;
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a category toolbox.
if (targetWorkspaceMetrics.toolboxHeight) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
y = targetWorkspaceMetrics.toolboxHeight;
} else {
y = targetWorkspaceMetrics.viewHeight - this.height_;
}
// Simple (flyout-only) toolbox.
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
y = 0;
} else {
// The simple flyout does not cover the workspace.
y = targetWorkspaceMetrics.viewHeight;
}
}
// Trashcan flyout is opposite the main flyout.
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
y = 0;
} else {
// Because the anchor point of the flyout is on the top, but we want
// to align the bottom edge of the flyout with the bottom edge of the
// blocklyDiv, we calculate the full height of the div minus the height
// of the flyout.
y = targetWorkspaceMetrics.viewHeight +
targetWorkspaceMetrics.absoluteTop - this.height_;
}
}
return y;
};
/**
* Move the flyout to the edge of the workspace.
*/
@@ -137,36 +193,9 @@ Blockly.HorizontalFlyout.prototype.position = function() {
var edgeHeight = this.height_ - this.CORNER_RADIUS;
this.setBackgroundPath_(edgeWidth, edgeHeight);
// X is always 0 since this is a horizontal flyout.
var x = 0;
// If this flyout is the toolbox flyout.
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a toolbox.
if (targetWorkspaceMetrics.toolboxHeight) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
var y = targetWorkspaceMetrics.toolboxHeight;
} else {
var y = targetWorkspaceMetrics.viewHeight - this.height_;
}
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
var y = 0;
} else {
var y = targetWorkspaceMetrics.viewHeight;
}
}
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
var y = 0;
} else {
// Because the anchor point of the flyout is on the top, but we want
// to align the bottom edge of the flyout with the bottom edge of the
// blocklyDiv, we calculate the full height of the div minus the height
// of the flyout.
var y = targetWorkspaceMetrics.viewHeight +
targetWorkspaceMetrics.absoluteTop - this.height_;
}
}
var x = this.getX();
var y = this.getY();
this.positionAt_(this.width_, this.height_, x, y);
};
+60 -30
View File
@@ -121,6 +121,63 @@ Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
this.workspace_.scrollY + metrics.absoluteTop);
};
/**
* Calculates the x coordinate for the flyout position.
* @return {number} X coordinate.
*/
Blockly.VerticalFlyout.prototype.getX = function() {
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
if (!targetWorkspaceMetrics) {
// Hidden components will return null.
return 0;
}
var x = 0;
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a category toolbox.
if (targetWorkspaceMetrics.toolboxWidth) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
x = targetWorkspaceMetrics.toolboxWidth;
} else {
x = targetWorkspaceMetrics.viewWidth - this.width_;
}
// Simple (flyout-only) toolbox.
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
x = 0;
} else {
// The simple flyout does not cover the workspace.
x = targetWorkspaceMetrics.viewWidth;
}
}
// Trashcan flyout is opposite the main flyout.
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
x = 0;
} else {
// Because the anchor point of the flyout is on the left, but we want
// to align the right edge of the flyout with the right edge of the
// blocklyDiv, we calculate the full width of the div minus the width
// of the flyout.
x = targetWorkspaceMetrics.viewWidth +
targetWorkspaceMetrics.absoluteLeft - this.width_;
}
}
return x;
};
/**
* Calculates the y coordinate for the flyout position.
* @return {number} Y coordinate.
*/
Blockly.VerticalFlyout.prototype.getY = function() {
// Y is always 0 since this is a vertical flyout.
return 0;
};
/**
* Move the flyout to the edge of the workspace.
*/
@@ -140,36 +197,9 @@ Blockly.VerticalFlyout.prototype.position = function() {
var edgeHeight = targetWorkspaceMetrics.viewHeight - 2 * this.CORNER_RADIUS;
this.setBackgroundPath_(edgeWidth, edgeHeight);
// Y is always 0 since this is a vertical flyout.
var y = 0;
// If this flyout is the toolbox flyout.
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a category toolbox.
if (targetWorkspaceMetrics.toolboxWidth) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
var x = targetWorkspaceMetrics.toolboxWidth;
} else {
var x = targetWorkspaceMetrics.viewWidth - this.width_;
}
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
var x = 0;
} else {
var x = targetWorkspaceMetrics.viewWidth;
}
}
} else {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
var x = 0;
} else {
// Because the anchor point of the flyout is on the left, but we want
// to align the right edge of the flyout with the right edge of the
// blocklyDiv, we calculate the full width of the div minus the width
// of the flyout.
var x = targetWorkspaceMetrics.viewWidth +
targetWorkspaceMetrics.absoluteLeft - this.width_;
}
}
var x = this.getX();
var y = this.getY();
this.positionAt_(this.width_, this.height_, x, y);
};
+14
View File
@@ -77,6 +77,15 @@ Blockly.Generator.prototype.COMMENT_WRAP = 60;
*/
Blockly.Generator.prototype.ORDER_OVERRIDES = [];
/**
* Whether the init method has been called.
* Generators that set this flag to false after creation and true in init
* will cause blockToCode to emit a warning if the generator has not been
* initialized. If this flag is untouched, it will have no effect.
* @type {?boolean}
*/
Blockly.Generator.prototype.isInitialized = null;
/**
* Generate code for all blocks in the workspace to the specified language.
* @param {Blockly.Workspace} workspace Workspace to generate code from.
@@ -159,6 +168,7 @@ Blockly.Generator.prototype.allNestedComments = function(block) {
/**
* Generate code for the specified block (and attached blocks).
* The generator must be initialized before calling this function.
* @param {Blockly.Block} block The block to generate code for.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string|!Array} For statement blocks, the generated code.
@@ -166,6 +176,10 @@ Blockly.Generator.prototype.allNestedComments = function(block) {
* operator order value. Returns '' if block is null.
*/
Blockly.Generator.prototype.blockToCode = function(block, opt_thisOnly) {
if (this.isInitialized === false) {
console.warn(
'Generator init was not called before blockToCode was called.');
}
if (!block) {
return '';
}
+5 -5
View File
@@ -19,7 +19,7 @@ goog.require('Blockly.BlockDragger');
goog.require('Blockly.BubbleDragger');
goog.require('Blockly.constants');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.Click');
goog.require('Blockly.FlyoutDragger');
goog.require('Blockly.navigation');
goog.require('Blockly.Tooltip');
@@ -665,8 +665,7 @@ Blockly.Gesture.prototype.handleWsStart = function(e, ws) {
* @private
*/
Blockly.Gesture.prototype.fireWorkspaceClick_ = function(ws) {
var clickEvent = new Blockly.Events.Ui(null, 'click', null, 'workspace');
clickEvent.workspaceId = ws.id;
var clickEvent = new Blockly.Events.Click(null, ws.id, 'workspace');
Blockly.Events.fire(clickEvent);
};
@@ -757,8 +756,9 @@ Blockly.Gesture.prototype.doBlockClick_ = function() {
}
} else {
// Clicks events are on the start block, even if it was a shadow.
Blockly.Events.fire(
new Blockly.Events.Ui(this.startBlock_, 'click', undefined, 'block'));
var event = new Blockly.Events.Click(
this.startBlock_, this.startWorkspace_.id, 'block');
Blockly.Events.fire(event);
}
this.bringBlockToFront_();
Blockly.Events.setGroup(false);
-5
View File
@@ -13,7 +13,6 @@
goog.provide('Blockly.inject');
goog.require('Blockly.BlockDragSurfaceSvg');
goog.require('Blockly.Component');
goog.require('Blockly.Css');
goog.require('Blockly.DropDownDiv');
goog.require('Blockly.Events');
@@ -22,7 +21,6 @@ goog.require('Blockly.Msg');
goog.require('Blockly.Options');
goog.require('Blockly.ScrollbarPair');
goog.require('Blockly.Tooltip');
goog.require('Blockly.user.keyMap');
goog.require('Blockly.utils');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Svg');
@@ -69,7 +67,6 @@ Blockly.inject = function(container, opt_options) {
var workspace = Blockly.createMainWorkspace_(svg, options, blockDragSurface,
workspaceDragSurface);
Blockly.user.keyMap.setKeyMap(options.keyMap);
Blockly.init_(workspace);
@@ -97,8 +94,6 @@ Blockly.createDom_ = function(container, options) {
// out content in RTL mode. Therefore Blockly forces the use of LTR,
// then manually positions content in RTL as needed.
container.setAttribute('dir', 'LTR');
// Set the default direction for Components to use.
Blockly.Component.defaultRightToLeft = options.RTL;
// Load CSS.
Blockly.Css.inject(options.hasCss, options.pathToMedia);
+2 -1
View File
@@ -15,6 +15,7 @@ goog.provide('Blockly.IASTNodeLocation');
goog.provide('Blockly.IASTNodeLocationSvg');
goog.provide('Blockly.IASTNodeLocationWithBlock');
goog.provide('Blockly.IBlocklyActionable');
goog.requireType('Blockly.ShortcutRegistry');
/**
* An AST node location interface.
@@ -66,7 +67,7 @@ Blockly.IBlocklyActionable = function() {};
/**
* Handles the given action.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the action has been handled, false otherwise.
*/
Blockly.IBlocklyActionable.prototype.onBlocklyAction;
+12
View File
@@ -161,6 +161,18 @@ Blockly.IFlyout.prototype.reflow;
*/
Blockly.IFlyout.prototype.isScrollable;
/**
* Calculates the x coordinate for the flyout position.
* @return {number} X coordinate.
*/
Blockly.IFlyout.prototype.getX;
/**
* Calculates the y coordinate for the flyout position.
* @return {number} Y coordinate.
*/
Blockly.IFlyout.prototype.getY;
/**
* Position the flyout.
* @return {void}
+9
View File
@@ -113,6 +113,15 @@ Blockly.ISelectableToolboxItem.prototype.getContents;
*/
Blockly.ISelectableToolboxItem.prototype.setSelected;
/**
* Gets the html element that is clickable.
* The parent toolbox element receives clicks. The parent toolbox will add an id to this element so
* it can pass the onClick event to the correct toolboxItem.
* @return {!Element} The html element that receives clicks.
* @public
*/
Blockly.ISelectableToolboxItem.prototype.getClickTarget;
/**
* Handles when the toolbox item is clicked.
* @param {!Event} _e Click event to handle.
-26
View File
@@ -1,26 +0,0 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview The class representing an action.
* Used primarily for keyboard navigation.
*/
'use strict';
goog.provide('Blockly.Action');
/**
* Class for a single action.
* An action describes user intent. (ex go to next or go to previous)
* @param {string} name The name of the action.
* @param {string} desc The description of the action.
* @constructor
*/
Blockly.Action = function(name, desc) {
this.name = name;
this.desc = desc;
};
+2 -2
View File
@@ -13,13 +13,13 @@
goog.provide('Blockly.Cursor');
goog.require('Blockly.Action');
goog.require('Blockly.ASTNode');
goog.require('Blockly.Marker');
goog.require('Blockly.navigation');
goog.require('Blockly.utils.object');
goog.requireType('Blockly.IBlocklyActionable');
goog.requireType('Blockly.ShortcutRegistry');
/**
@@ -140,7 +140,7 @@ Blockly.Cursor.prototype.out = function() {
/**
* Handles the given action.
* This is only triggered when keyboard navigation is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the action has been handled, false otherwise.
*/
Blockly.Cursor.prototype.onBlocklyAction = function(action) {
+3 -1
View File
@@ -17,6 +17,8 @@ goog.require('Blockly.Cursor');
goog.require('Blockly.navigation');
goog.require('Blockly.utils.object');
goog.requireType('Blockly.ShortcutRegistry');
/**
* Class for a flyout cursor.
@@ -32,7 +34,7 @@ Blockly.utils.object.inherits(Blockly.FlyoutCursor, Blockly.Cursor);
/**
* Handles the given action.
* This is only triggered when keyboard navigation is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the action has been handled, false otherwise.
* @override
*/
-190
View File
@@ -1,190 +0,0 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview The namespace used to keep track of keyboard actions and the
* key codes used to execute those actions.
* This is used primarily for keyboard navigation.
*/
'use strict';
goog.provide('Blockly.user.keyMap');
// TODO: Fix circular dependency.
// goog.require('Blockly.navigation');
goog.require('Blockly.utils.KeyCodes');
goog.require('Blockly.utils.object');
/**
* Holds the serialized key to key action mapping.
* @type {!Object<string, Blockly.Action>}
* @private
*/
Blockly.user.keyMap.map_ = {};
/**
* Object holding valid modifiers.
* @enum {string}
*/
Blockly.user.keyMap.modifierKeys = {
SHIFT: 'Shift',
CONTROL: 'Control',
ALT: 'Alt',
META: 'Meta'
};
/**
* Update the key map to contain the new action.
* @param {string} keyCode The key code serialized by the serializeKeyEvent.
* @param {!Blockly.Action} action The action to be executed when the keys
* corresponding to the serialized key code is pressed.
*/
Blockly.user.keyMap.setActionForKey = function(keyCode, action) {
var oldKey = Blockly.user.keyMap.getKeyByAction(action);
// If the action already exists in the key map remove it and add the new mapping.
if (oldKey) {
delete Blockly.user.keyMap.map_[oldKey];
}
Blockly.user.keyMap.map_[keyCode] = action;
};
/**
* Creates a new key map.
* @param {!Object<string, Blockly.Action>} keyMap The object holding the key
* to action mapping.
*/
Blockly.user.keyMap.setKeyMap = function(keyMap) {
Blockly.user.keyMap.map_ = keyMap;
};
/**
* Gets the current key map.
* @return {Object<string,Blockly.Action>} The object holding the key to
* action mapping.
*/
Blockly.user.keyMap.getKeyMap = function() {
var map = {};
Blockly.utils.object.mixin(map, Blockly.user.keyMap.map_);
return map;
};
/**
* Get the action by the serialized key code.
* @param {string} keyCode The serialized key code.
* @return {Blockly.Action|undefined} The action holding the function to
* call when the given keyCode is used or undefined if no action exists.
*/
Blockly.user.keyMap.getActionByKeyCode = function(keyCode) {
return Blockly.user.keyMap.map_[keyCode];
};
/**
* Get the serialized key that corresponds to the action.
* @param {!Blockly.Action} action The action for which we want to get
* the key.
* @return {?string} The serialized key or null if the action does not have
* a key mapping.
*/
Blockly.user.keyMap.getKeyByAction = function(action) {
var keys = Object.keys(Blockly.user.keyMap.map_);
for (var i = 0, key; (key = keys[i]); i++) {
if (Blockly.user.keyMap.map_[key].name === action.name) {
return key;
}
}
return null;
};
/**
* Serialize the key event.
* @param {!KeyboardEvent} e A key up event holding the key code.
* @return {string} A string containing the serialized key event.
* @package
*/
Blockly.user.keyMap.serializeKeyEvent = function(e) {
var modifiers = Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys);
var key = '';
for (var i = 0, keyName; (keyName = modifiers[i]); i++) {
if (e.getModifierState(keyName)) {
key += keyName;
}
}
key += e.keyCode;
return key;
};
/**
* Checks whether any of the given modifiers are not valid.
* @param {!Array.<string>} modifiers List of modifiers to be used with the key.
* @param {!Array.<string>} validModifiers List of modifiers we support.
* @throws {Error} if the modifier is not in the valid modifiers list.
* @private
*/
Blockly.user.keyMap.checkModifiers_ = function(modifiers, validModifiers) {
for (var i = 0, modifier; (modifier = modifiers[i]); i++) {
if (validModifiers.indexOf(modifier) < 0) {
throw Error(modifier + ' is not a valid modifier key.');
}
}
};
/**
* Create the serialized key code that will be used in the key map.
* @param {number} keyCode Number code representing the key.
* @param {!Array.<string>} modifiers List of modifiers to be used with the key.
* All valid modifiers can be found in the Blockly.user.keyMap.modifierKeys.
* @return {string} The serialized key code for the given modifiers and key.
*/
Blockly.user.keyMap.createSerializedKey = function(keyCode, modifiers) {
var key = '';
var validModifiers = Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys);
Blockly.user.keyMap.checkModifiers_(modifiers, validModifiers);
for (var i = 0, validModifier; (validModifier = validModifiers[i]); i++) {
if (modifiers.indexOf(validModifier) > -1) {
key += validModifier;
}
}
key += keyCode;
return key;
};
/**
* Creates the default key map.
* @return {!Object<string,Blockly.Action>} An object holding the default key
* to action mapping.
*/
Blockly.user.keyMap.createDefaultKeyMap = function() {
var map = {};
var controlK = Blockly.user.keyMap.createSerializedKey(
Blockly.utils.KeyCodes.K, [Blockly.user.keyMap.modifierKeys.CONTROL,
Blockly.user.keyMap.modifierKeys.SHIFT]);
var shiftW = Blockly.user.keyMap.createSerializedKey(
Blockly.utils.KeyCodes.W, [Blockly.user.keyMap.modifierKeys.SHIFT]);
var shiftA = Blockly.user.keyMap.createSerializedKey(
Blockly.utils.KeyCodes.A, [Blockly.user.keyMap.modifierKeys.SHIFT]);
var shiftS = Blockly.user.keyMap.createSerializedKey(
Blockly.utils.KeyCodes.S, [Blockly.user.keyMap.modifierKeys.SHIFT]);
var shiftD = Blockly.user.keyMap.createSerializedKey(
Blockly.utils.KeyCodes.D, [Blockly.user.keyMap.modifierKeys.SHIFT]);
map[Blockly.utils.KeyCodes.W] = Blockly.navigation.ACTION_PREVIOUS;
map[Blockly.utils.KeyCodes.A] = Blockly.navigation.ACTION_OUT;
map[Blockly.utils.KeyCodes.S] = Blockly.navigation.ACTION_NEXT;
map[Blockly.utils.KeyCodes.D] = Blockly.navigation.ACTION_IN;
map[Blockly.utils.KeyCodes.I] = Blockly.navigation.ACTION_INSERT;
map[Blockly.utils.KeyCodes.ENTER] = Blockly.navigation.ACTION_MARK;
map[Blockly.utils.KeyCodes.X] = Blockly.navigation.ACTION_DISCONNECT;
map[Blockly.utils.KeyCodes.T] = Blockly.navigation.ACTION_TOOLBOX;
map[Blockly.utils.KeyCodes.E] = Blockly.navigation.ACTION_EXIT;
map[Blockly.utils.KeyCodes.ESC] = Blockly.navigation.ACTION_EXIT;
map[controlK] = Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV;
map[shiftW] = Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP;
map[shiftA] = Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT;
map[shiftS] = Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN;
map[shiftD] = Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT;
return map;
};
+399 -260
View File
@@ -13,11 +13,9 @@
goog.provide('Blockly.navigation');
goog.require('Blockly.Action');
goog.require('Blockly.ASTNode');
goog.require('Blockly.constants');
goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.user.keyMap');
/**
@@ -113,6 +111,7 @@ Blockly.navigation.getMarker = function() {
/**
* Get the workspace that is being navigated.
* @return {!Blockly.WorkspaceSvg} The workspace being navigated.
* TODO: Remove this in favor or using passed in workspaces.
*/
Blockly.navigation.getNavigationWorkspace = function() {
return /** @type {!Blockly.WorkspaceSvg} */ (Blockly.getMainWorkspace());
@@ -121,10 +120,11 @@ Blockly.navigation.getNavigationWorkspace = function() {
/**
* If a toolbox exists, set the navigation state to toolbox and select the first
* category in the toolbox.
* @param {!Blockly.WorkspaceSvg} workspace The main workspace.
* @private
*/
Blockly.navigation.focusToolbox_ = function() {
var toolbox = Blockly.navigation.getNavigationWorkspace().getToolbox();
Blockly.navigation.focusToolbox_ = function(workspace) {
var toolbox = workspace.getToolbox();
if (toolbox) {
Blockly.navigation.currentState_ = Blockly.navigation.STATE_TOOLBOX;
Blockly.navigation.resetFlyout_(false /* shouldHide */);
@@ -140,12 +140,12 @@ Blockly.navigation.focusToolbox_ = function() {
/**
* Change focus to the flyout.
* @param {!Blockly.WorkspaceSvg} workspace The main workspace.
* @private
*/
Blockly.navigation.focusFlyout_ = function() {
Blockly.navigation.focusFlyout_ = function(workspace) {
var topBlock = null;
Blockly.navigation.currentState_ = Blockly.navigation.STATE_FLYOUT;
var workspace = Blockly.navigation.getNavigationWorkspace();
var toolbox = workspace.getToolbox();
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
@@ -166,11 +166,11 @@ Blockly.navigation.focusFlyout_ = function() {
/**
* Finds where the cursor should go on the workspace. This is either the top
* block or a set position on the workspace.
* @param {!Blockly.WorkspaceSvg} workspace The main workspace.
* @private
*/
Blockly.navigation.focusWorkspace_ = function() {
Blockly.navigation.focusWorkspace_ = function(workspace) {
Blockly.hideChaff();
var workspace = Blockly.navigation.getNavigationWorkspace();
var cursor = workspace.getCursor();
var reset = !!workspace.getToolbox();
var topBlocks = workspace.getTopBlocks(true);
@@ -211,9 +211,9 @@ Blockly.navigation.getFlyoutCursor_ = function() {
* If there is a marked connection try connecting the block from the flyout to
* that connection. If no connection has been marked then inserting will place
* it on the workspace.
* @param {!Blockly.WorkspaceSvg} workspace The main workspace.
*/
Blockly.navigation.insertFromFlyout = function() {
var workspace = Blockly.navigation.getNavigationWorkspace();
Blockly.navigation.insertFromFlyout = function(workspace) {
var flyout = workspace.getFlyout();
if (!flyout || !flyout.isVisible()) {
Blockly.navigation.warn_('Trying to insert from the flyout when the flyout does not ' +
@@ -241,7 +241,7 @@ Blockly.navigation.insertFromFlyout = function() {
Blockly.navigation.warn_('Something went wrong while inserting a block from the flyout.');
}
Blockly.navigation.focusWorkspace_();
Blockly.navigation.focusWorkspace_(workspace);
workspace.getCursor().setCurNode(Blockly.ASTNode.createTopNode(newBlock));
Blockly.navigation.removeMark_();
};
@@ -562,10 +562,10 @@ Blockly.navigation.insertBlock = function(block, destConnection) {
* Disconnect the connection that the cursor is pointing to, and bump blocks.
* This is a no-op if the connection cannot be broken or if the cursor is not
* pointing to a connection.
* @param {!Blockly.WorkspaceSvg} workspace The main workspace.
* @private
*/
Blockly.navigation.disconnectBlocks_ = function() {
var workspace = Blockly.navigation.getNavigationWorkspace();
Blockly.navigation.disconnectBlocks_ = function(workspace) {
var curNode = workspace.getCursor().getCurNode();
if (!curNode.isConnection()) {
Blockly.navigation.log_('Cannot disconnect blocks when the cursor is not on a connection');
@@ -690,7 +690,7 @@ Blockly.navigation.enableKeyboardAccessibility = function() {
var workspace = Blockly.navigation.getNavigationWorkspace();
if (!workspace.keyboardAccessibilityMode) {
workspace.keyboardAccessibilityMode = true;
Blockly.navigation.focusWorkspace_();
Blockly.navigation.focusWorkspace_(workspace);
}
};
@@ -755,140 +755,15 @@ Blockly.navigation.error_ = function(msg) {
/** Handle Key Press */
/** ***************** */
/**
* Handler for all the keyboard navigation events.
* @param {!KeyboardEvent} e The keyboard event.
* @return {boolean} True if the key was handled false otherwise.
*/
Blockly.navigation.onKeyPress = function(e) {
var key = Blockly.user.keyMap.serializeKeyEvent(e);
var action = Blockly.user.keyMap.getActionByKeyCode(key);
if (action) {
return Blockly.navigation.onBlocklyAction(action);
}
return false;
};
/**
* Decides which actions to handle depending on keyboard navigation and readonly
* states.
* @param {!Blockly.Action} action The current action.
* @return {boolean} True if the action has been handled, false otherwise.
*/
Blockly.navigation.onBlocklyAction = function(action) {
var workspace = Blockly.navigation.getNavigationWorkspace();
var readOnly = workspace.options.readOnly;
var actionHandled = false;
if (workspace.keyboardAccessibilityMode) {
if (!readOnly) {
actionHandled = Blockly.navigation.handleActions_(action);
// If in readonly mode only handle valid actions.
} else if (Blockly.navigation.READONLY_ACTION_LIST.indexOf(action) > -1) {
actionHandled = Blockly.navigation.handleActions_(action);
}
// 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;
}
return actionHandled;
};
/**
* Handles the action or dispatches to the appropriate action handler.
* @param {!Blockly.Action} action The action to handle.
* @return {boolean} True if the action has been handled, false otherwise.
* @private
*/
Blockly.navigation.handleActions_ = function(action) {
if (action.name == Blockly.navigation.actionNames.TOOLBOX ||
Blockly.navigation.currentState_ == Blockly.navigation.STATE_TOOLBOX) {
return Blockly.navigation.toolboxOnAction_(action);
} else if (action.name == Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV) {
Blockly.navigation.disableKeyboardAccessibility();
return true;
} if (Blockly.navigation.currentState_ == Blockly.navigation.STATE_WS) {
return Blockly.navigation.workspaceOnAction_(action);
} else if (Blockly.navigation.currentState_ == Blockly.navigation.STATE_FLYOUT) {
return Blockly.navigation.flyoutOnAction_(action);
}
return false;
};
/**
* Handles the given action for the flyout.
* @param {!Blockly.Action} action The action to handle.
* @return {boolean} True if the action has been handled, false otherwise.
* @private
*/
Blockly.navigation.flyoutOnAction_ = function(action) {
var workspace = Blockly.navigation.getNavigationWorkspace();
var toolbox = workspace.getToolbox();
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
if (flyout && flyout.onBlocklyAction(action)) {
return true;
}
switch (action.name) {
case Blockly.navigation.actionNames.OUT:
Blockly.navigation.focusToolbox_();
return true;
case Blockly.navigation.actionNames.MARK:
Blockly.navigation.insertFromFlyout();
return true;
case Blockly.navigation.actionNames.EXIT:
Blockly.navigation.focusWorkspace_();
return true;
default:
return false;
}
};
/**
* Handles the given action for the toolbox.
* @param {!Blockly.Action} action The action to handle.
* @return {boolean} True if the action has been handled, false otherwise.
* @private
*/
Blockly.navigation.toolboxOnAction_ = function(action) {
var workspace = Blockly.navigation.getNavigationWorkspace();
var toolbox = workspace.getToolbox();
var handled = toolbox && typeof toolbox.onBlocklyAction == 'function' ?
toolbox.onBlocklyAction(action) : false;
if (handled) {
return true;
}
if (action.name === Blockly.navigation.actionNames.TOOLBOX) {
if (!workspace.getToolbox()) {
Blockly.navigation.focusFlyout_();
} else {
Blockly.navigation.focusToolbox_();
}
return true;
} else if (action.name === Blockly.navigation.actionNames.IN) {
Blockly.navigation.focusFlyout_();
return true;
} else if (action.name === Blockly.navigation.actionNames.EXIT) {
Blockly.navigation.focusWorkspace_();
return true;
}
return false;
};
/**
* Move the workspace cursor in the given direction.
* @param {!Blockly.WorkspaceSvg} workspace The workspace the cursor is on.
* @param {number} xDirection -1 to move cursor left. 1 to move cursor right.
* @param {number} yDirection -1 to move cursor up. 1 to move cursor down.
* @return {boolean} True if the current node is a workspace, false otherwise.
* @private
*/
Blockly.navigation.moveWSCursor_ = function(xDirection, yDirection) {
var workspace = Blockly.navigation.getNavigationWorkspace();
Blockly.navigation.moveWSCursor_ = function(workspace, xDirection, yDirection) {
var cursor = workspace.getCursor();
var curNode = workspace.getCursor().getCurNode();
@@ -905,46 +780,14 @@ Blockly.navigation.moveWSCursor_ = function(xDirection, yDirection) {
return true;
};
/**
* Handles the given action for the workspace.
* @param {!Blockly.Action} action The action to handle.
* @return {boolean} True if the action has been handled, false otherwise.
* @private
*/
Blockly.navigation.workspaceOnAction_ = function(action) {
var workspace = Blockly.navigation.getNavigationWorkspace();
if (workspace.getCursor().onBlocklyAction(action)) {
return true;
}
switch (action.name) {
case Blockly.navigation.actionNames.INSERT:
Blockly.navigation.modify_();
return true;
case Blockly.navigation.actionNames.MARK:
Blockly.navigation.handleEnterForWS_();
return true;
case Blockly.navigation.actionNames.DISCONNECT:
Blockly.navigation.disconnectBlocks_();
return true;
case Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP:
return Blockly.navigation.moveWSCursor_(0, -1);
case Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN:
return Blockly.navigation.moveWSCursor_(0, 1);
case Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT:
return Blockly.navigation.moveWSCursor_(-1, 0);
case Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT:
return Blockly.navigation.moveWSCursor_(1, 0);
default:
return false;
}
};
/**
* Handles hitting the enter key on the workspace.
* @param {!Blockly.WorkspaceSvg} workspace The workspace the enter event
* originated from.
* @private
*/
Blockly.navigation.handleEnterForWS_ = function() {
var cursor = Blockly.navigation.getNavigationWorkspace().getCursor();
Blockly.navigation.handleEnterForWS_ = function(workspace) {
var cursor = workspace.getCursor();
var curNode = cursor.getCurNode();
var nodeType = curNode.getType();
if (nodeType == Blockly.ASTNode.types.FIELD) {
@@ -959,127 +802,423 @@ Blockly.navigation.handleEnterForWS_ = function() {
}
};
/** ******************* */
/** Navigation Actions */
/** ******************* */
/** ***************** */
/** Register Items */
/** ***************** */
/**
* The previous action.
* @type {!Blockly.Action}
* Keyboard shortcut to go to the previous location when in keyboard navigation
* mode.
*/
Blockly.navigation.ACTION_PREVIOUS = new Blockly.Action(
Blockly.navigation.actionNames.PREVIOUS, 'Go to the previous location.');
Blockly.navigation.registerPrevious = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var previousShortcut = {
name: Blockly.navigation.actionNames.PREVIOUS,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode;
},
callback: function(workspace, e, action) {
var toolbox = workspace.getToolbox();
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
return workspace.getCursor().onBlocklyAction(action);
case Blockly.navigation.STATE_FLYOUT:
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
return !!(flyout && flyout.onBlocklyAction(action));
case Blockly.navigation.STATE_TOOLBOX:
return toolbox && typeof toolbox.onBlocklyAction == 'function' ?
toolbox.onBlocklyAction(action) :
false;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(previousShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.W, previousShortcut.name);
};
/**
* The out action.
* @type {!Blockly.Action}
* Keyboard shortcut to go to the out location when in keyboard navigation
* mode.
*/
Blockly.navigation.ACTION_OUT = new Blockly.Action(
Blockly.navigation.actionNames.OUT,
'Go to the parent of the current location.');
Blockly.navigation.registerOut = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var outShortcut = {
name: Blockly.navigation.actionNames.OUT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode;
},
callback: function(workspace, e, action) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
return workspace.getCursor().onBlocklyAction(action);
case Blockly.navigation.STATE_FLYOUT:
Blockly.navigation.focusToolbox_(workspace);
return true;
case Blockly.navigation.STATE_TOOLBOX:
var toolbox = workspace.getToolbox();
return toolbox && typeof toolbox.onBlocklyAction == 'function' ?
toolbox.onBlocklyAction(action) :
false;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(outShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.A, outShortcut.name);
};
/**
* The next action.
* @type {!Blockly.Action}
* Keyboard shortcut to go to the next location when in keyboard navigation
* mode.
*/
Blockly.navigation.ACTION_NEXT = new Blockly.Action(
Blockly.navigation.actionNames.NEXT, 'Go to the next location.');
Blockly.navigation.registerNext = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var nextShortcut = {
name: Blockly.navigation.actionNames.NEXT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode;
},
callback: function(workspace, e, action) {
var toolbox = workspace.getToolbox();
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
return workspace.getCursor().onBlocklyAction(action);
case Blockly.navigation.STATE_FLYOUT:
var flyout = toolbox ? toolbox.getFlyout() : workspace.getFlyout();
return !!(flyout && flyout.onBlocklyAction(action));
case Blockly.navigation.STATE_TOOLBOX:
return toolbox && typeof toolbox.onBlocklyAction == 'function' ?
toolbox.onBlocklyAction(action) :
false;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(nextShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.S, nextShortcut.name);
};
/**
* The in action.
* @type {!Blockly.Action}
* Keyboard shortcut to go to the in location when in keyboard navigation mode.
*/
Blockly.navigation.ACTION_IN = new Blockly.Action(
Blockly.navigation.actionNames.IN,
'Go to the first child of the current location.');
Blockly.navigation.registerIn = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var inShortcut = {
name: Blockly.navigation.actionNames.IN,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode;
},
callback: function(workspace, e, action) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
return workspace.getCursor().onBlocklyAction(action);
case Blockly.navigation.STATE_TOOLBOX:
var toolbox = workspace.getToolbox();
var isHandled =
toolbox && typeof toolbox.onBlocklyAction == 'function' ?
toolbox.onBlocklyAction(action) :
false;
if (!isHandled) {
Blockly.navigation.focusFlyout_(workspace);
}
return true;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(inShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.D, inShortcut.name);
};
/**
* The action to try to insert a block.
* @type {!Blockly.Action}
* Keyboard shortcut to connect a block to a marked location when in keyboard
* navigation mode.
*/
Blockly.navigation.ACTION_INSERT = new Blockly.Action(
Blockly.navigation.actionNames.INSERT,
'Connect the current location to the marked location.');
Blockly.navigation.registerInsert = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var insertShortcut = {
name: Blockly.navigation.actionNames.INSERT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function() {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
return Blockly.navigation.modify_();
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(insertShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.I, insertShortcut.name);
};
/** Keyboard shortcut to mark a location when in keyboard navigation mode. */
Blockly.navigation.registerMark = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var markShortcut = {
name: Blockly.navigation.actionNames.MARK,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
Blockly.navigation.handleEnterForWS_(workspace);
return true;
case Blockly.navigation.STATE_FLYOUT:
Blockly.navigation.insertFromFlyout(workspace);
return true;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(markShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.ENTER, markShortcut.name);
};
/**
* The action to mark a certain location.
* @type {!Blockly.Action}
* Keyboard shortcut to disconnect two blocks when in keyboard navigation mode.
*/
Blockly.navigation.ACTION_MARK = new Blockly.Action(
Blockly.navigation.actionNames.MARK, 'Mark the current location.');
Blockly.navigation.registerDisconnect = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var disconnectShortcut = {
name: Blockly.navigation.actionNames.DISCONNECT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
Blockly.navigation.disconnectBlocks_(workspace);
return true;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(disconnectShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.X, disconnectShortcut.name);
};
/**
* The action to disconnect a block.
* @type {!Blockly.Action}
* Keyboard shortcut to focus on the toolbox when in keyboard navigation mode.
*/
Blockly.navigation.ACTION_DISCONNECT = new Blockly.Action(
Blockly.navigation.actionNames.DISCONNECT,
'Disconnect the block at the current location from its parent.');
Blockly.navigation.registerToolboxFocus = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var focusToolboxShortcut = {
name: Blockly.navigation.actionNames.TOOLBOX,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_WS:
if (!workspace.getToolbox()) {
Blockly.navigation.focusFlyout_(workspace);
} else {
Blockly.navigation.focusToolbox_(workspace);
}
return true;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(focusToolboxShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.T, focusToolboxShortcut.name);
};
/**
* The action to open the toolbox.
* @type {!Blockly.Action}
* Keyboard shortcut to exit the current location and focus on the workspace
* when in keyboard navigation mode.
*/
Blockly.navigation.ACTION_TOOLBOX = new Blockly.Action(
Blockly.navigation.actionNames.TOOLBOX, 'Open the toolbox.');
Blockly.navigation.registerExit = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var exitShortcut = {
name: Blockly.navigation.actionNames.EXIT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode;
},
callback: function(workspace) {
switch (Blockly.navigation.currentState_) {
case Blockly.navigation.STATE_FLYOUT:
Blockly.navigation.focusWorkspace_(workspace);
return true;
case Blockly.navigation.STATE_TOOLBOX:
Blockly.navigation.focusWorkspace_(workspace);
return true;
default:
return false;
}
}
};
Blockly.ShortcutRegistry.registry.register(exitShortcut, true);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.ESC, exitShortcut.name, true);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.E, exitShortcut.name, true);
};
/** Keyboard shortcut to turn keyboard navigation on or off. */
Blockly.navigation.registerToggleKeyboardNav = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var toggleKeyboardNavShortcut = {
name: Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV,
callback: function(workspace) {
if (workspace.keyboardAccessibilityMode) {
Blockly.navigation.disableKeyboardAccessibility();
} else {
Blockly.navigation.enableKeyboardAccessibility();
}
return true;
}
};
Blockly.ShortcutRegistry.registry.register(toggleKeyboardNavShortcut);
var ctrlShiftK = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.K,
[Blockly.utils.KeyCodes.CTRL, Blockly.utils.KeyCodes.SHIFT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(
ctrlShiftK, toggleKeyboardNavShortcut.name);
};
/**
* The action to exit the toolbox or flyout.
* @type {!Blockly.Action}
* Keyboard shortcut to move the cursor on the workspace to the left when in
* keyboard navigation mode.
*/
Blockly.navigation.ACTION_EXIT = new Blockly.Action(
Blockly.navigation.actionNames.EXIT,
'Close the current modal, such as a toolbox or field editor.');
Blockly.navigation.registerWorkspaceMoveLeft = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var wsMoveLeftShortcut = {
name: Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
return Blockly.navigation.moveWSCursor_(workspace, -1, 0);
}
};
Blockly.ShortcutRegistry.registry.register(wsMoveLeftShortcut);
var shiftA = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.A, [Blockly.utils.KeyCodes.SHIFT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(
shiftA, wsMoveLeftShortcut.name);
};
/**
* The action to toggle keyboard navigation mode on and off.
* @type {!Blockly.Action}
* Keyboard shortcut to move the cursor on the workspace to the right when in
* keyboard navigation mode.
*/
Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV = new Blockly.Action(
Blockly.navigation.actionNames.TOGGLE_KEYBOARD_NAV,
'Turns on and off keyboard navigation.');
Blockly.navigation.registerWorkspaceMoveRight = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var wsMoveRightShortcut = {
name: Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
return Blockly.navigation.moveWSCursor_(workspace, 1, 0);
}
};
Blockly.ShortcutRegistry.registry.register(wsMoveRightShortcut);
var shiftD = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.D, [Blockly.utils.KeyCodes.SHIFT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(
shiftD, wsMoveRightShortcut.name);
};
/**
* The action to move the cursor to the left on a workspace.
* @type {!Blockly.Action}
* Keyboard shortcut to move the cursor on the workspace up when in keyboard
* navigation mode.
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT = new Blockly.Action(
Blockly.navigation.actionNames.MOVE_WS_CURSOR_LEFT,
'Move the workspace cursor to the lefts.');
Blockly.navigation.registerWorkspaceMoveUp = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var wsMoveUpShortcut = {
name: Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
return Blockly.navigation.moveWSCursor_(workspace, 0, -1);
}
};
Blockly.ShortcutRegistry.registry.register(wsMoveUpShortcut);
var shiftW = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.W, [Blockly.utils.KeyCodes.SHIFT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(
shiftW, wsMoveUpShortcut.name);
};
/**
* The action to move the cursor to the right on a workspace.
* @type {!Blockly.Action}
* Keyboard shortcut to move the cursor on the workspace down when in keyboard
* navigation mode.
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT = new Blockly.Action(
Blockly.navigation.actionNames.MOVE_WS_CURSOR_RIGHT,
'Move the workspace cursor to the right.');
Blockly.navigation.registerWorkspaceMoveDown = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var wsMoveDownShortcut = {
name: Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN,
preconditionFn: function(workspace) {
return workspace.keyboardAccessibilityMode && !workspace.options.readOnly;
},
callback: function(workspace) {
return Blockly.navigation.moveWSCursor_(workspace, 0, 1);
}
};
Blockly.ShortcutRegistry.registry.register(wsMoveDownShortcut);
var shiftW = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.S, [Blockly.utils.KeyCodes.SHIFT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(
shiftW, wsMoveDownShortcut.name);
};
/**
* The action to move the cursor up on a workspace.
* @type {!Blockly.Action}
* Registers all default keyboard shortcut items for keyboard navigation. This
* should be called once per instance of KeyboardShortcutRegistry.
* @package
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP = new Blockly.Action(
Blockly.navigation.actionNames.MOVE_WS_CURSOR_UP,
'Move the workspace cursor up.');
Blockly.navigation.registerNavigationShortcuts = function() {
Blockly.navigation.registerIn();
Blockly.navigation.registerNext();
Blockly.navigation.registerOut();
Blockly.navigation.registerPrevious();
/**
* The action to move the cursor down on a workspace.
* @type {!Blockly.Action}
*/
Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN = new Blockly.Action(
Blockly.navigation.actionNames.MOVE_WS_CURSOR_DOWN,
'Move the workspace cursor down.');
Blockly.navigation.registerWorkspaceMoveDown();
Blockly.navigation.registerWorkspaceMoveLeft();
Blockly.navigation.registerWorkspaceMoveRight();
Blockly.navigation.registerWorkspaceMoveUp();
/**
* List of actions that can be performed in read only mode.
* @type {!Array.<!Blockly.Action>}
*/
Blockly.navigation.READONLY_ACTION_LIST = [
Blockly.navigation.ACTION_PREVIOUS,
Blockly.navigation.ACTION_OUT,
Blockly.navigation.ACTION_IN,
Blockly.navigation.ACTION_NEXT,
Blockly.navigation.ACTION_TOGGLE_KEYBOARD_NAV
];
Blockly.navigation.registerDisconnect();
Blockly.navigation.registerExit();
Blockly.navigation.registerInsert();
Blockly.navigation.registerMark();
Blockly.navigation.registerToggleKeyboardNav();
Blockly.navigation.registerToolboxFocus();
};
+10 -3
View File
@@ -16,7 +16,7 @@ goog.provide('Blockly.Mutator');
goog.require('Blockly.Bubble');
goog.require('Blockly.Events');
goog.require('Blockly.Events.BlockChange');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.BubbleOpen');
goog.require('Blockly.Icon');
goog.require('Blockly.navigation');
goog.require('Blockly.utils');
@@ -286,7 +286,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
return;
}
Blockly.Events.fire(
new Blockly.Events.Ui(this.block_, 'mutatorOpen', !visible, visible));
new Blockly.Events.BubbleOpen(this.block_, visible, 'mutator'));
if (visible) {
// Create the bubble.
this.bubble_ = new Blockly.Bubble(
@@ -363,7 +363,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
* @private
*/
Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
if (e.type == Blockly.Events.UI ||
if (e.isUiEvent ||
(e.type == Blockly.Events.CHANGE && e.element == 'disabled')) {
return;
}
@@ -428,6 +428,13 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
if (oldMutation != newMutation) {
Blockly.Events.fire(new Blockly.Events.BlockChange(
block, 'mutation', null, oldMutation, newMutation));
// Ensure that any bump is part of this mutation's event group.
var group = Blockly.Events.getGroup();
setTimeout(function() {
Blockly.Events.setGroup(group);
block.bumpNeighbours();
Blockly.Events.setGroup(false);
}, Blockly.BUMP_DELAY);
}
// Don't update the bubble until the drag has ended, to avoid moving blocks
-5
View File
@@ -15,7 +15,6 @@ goog.provide('Blockly.Options');
goog.require('Blockly.Theme');
goog.require('Blockly.Themes.Classic');
goog.require('Blockly.registry');
goog.require('Blockly.user.keyMap');
goog.require('Blockly.utils.IdGenerator');
goog.require('Blockly.utils.Metrics');
goog.require('Blockly.utils.toolbox');
@@ -108,8 +107,6 @@ Blockly.Options = function(options) {
} else {
var oneBasedIndex = !!options['oneBasedIndex'];
}
var keyMap = options['keyMap'] || Blockly.user.keyMap.createDefaultKeyMap();
var renderer = options['renderer'] || 'geras';
var plugins = options['plugins'] || {};
@@ -158,8 +155,6 @@ Blockly.Options = function(options) {
this.toolboxPosition = toolboxPosition;
/** @type {!Blockly.Theme} */
this.theme = Blockly.Options.parseThemeOptions_(options);
/** @type {!Object<string,Blockly.Action>} */
this.keyMap = keyMap;
/** @type {string} */
this.renderer = renderer;
/** @type {?Object} */
+2 -2
View File
@@ -293,8 +293,8 @@ Blockly.Procedures.updateMutatorFlyout_ = function(workspace) {
* @package
*/
Blockly.Procedures.mutatorOpenListener = function(e) {
if (e.type != Blockly.Events.UI || e.element != 'mutatorOpen' ||
!e.newValue) {
if (!(e.type == Blockly.Events.BUBBLE_OPEN && e.bubbleType === 'mutator' &&
e.isOpen)) {
return;
}
var workspaceId = /** @type {string} */ (e.workspaceId);
+4 -4
View File
@@ -97,13 +97,13 @@ Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX =
* @param {string} name The plugin's name. (Ex. field_angle, geras)
* @param {?function(new:T, ...?)|Object} registryItem The class or object to
* register.
* @param {boolean=} opt_quiet True to prevent an error when overriding an
* @param {boolean=} opt_allowOverrides True to prevent an error when overriding an
* already registered item.
* @throws {Error} if the type or name is empty, a name with the given type has
* already been registered, or if the given class or object is not valid for it's type.
* @template T
*/
Blockly.registry.register = function(type, name, registryItem, opt_quiet) {
Blockly.registry.register = function(type, name, registryItem, opt_allowOverrides) {
if ((!(type instanceof Blockly.registry.Type) && typeof type != 'string') || String(type).trim() == '') {
throw Error('Invalid type "' + type + '". The type must be a' +
' non-empty string or a Blockly.registry.Type.');
@@ -127,8 +127,8 @@ Blockly.registry.register = function(type, name, registryItem, opt_quiet) {
// Validate that the given class has all the required properties.
Blockly.registry.validate_(type, registryItem);
// Don't throw an error if opt_quiet is true.
if (!opt_quiet && typeRegistry[name]) {
// Don't throw an error if opt_allowOverrides is true.
if (!opt_allowOverrides && typeRegistry[name]) {
throw Error('Name "' + name + '" with type "' + type + '" already registered.');
}
typeRegistry[name] = registryItem;
+3 -6
View File
@@ -15,6 +15,7 @@ goog.provide('Blockly.blockRendering.MarkerSvg');
goog.require('Blockly.ASTNode');
goog.require('Blockly.constants');
goog.require('Blockly.Events.MarkerMove');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Svg');
@@ -551,12 +552,8 @@ Blockly.blockRendering.MarkerSvg.prototype.hide = function() {
Blockly.blockRendering.MarkerSvg.prototype.fireMarkerEvent_ = function(
oldNode, curNode) {
var curBlock = curNode.getSourceBlock();
var eventType = this.isCursor() ? 'cursorMove' : 'markerMove';
var event = new Blockly.Events.Ui(curBlock, eventType, oldNode, curNode);
if (curNode.getType() == Blockly.ASTNode.types.WORKSPACE) {
event.workspaceId =
(/** @type {!Blockly.Workspace} */ (curNode.getLocation())).id;
}
var event = new Blockly.Events.MarkerMove(
curBlock, this.isCursor(), oldNode, curNode);
Blockly.Events.fire(event);
};
+5
View File
@@ -41,6 +41,11 @@ Blockly.geras.ConstantProvider = function() {
* @type {number}
*/
this.MAX_BOTTOM_WIDTH = 30;
/**
* @override
*/
this.STATEMENT_BOTTOM_SPACER = -this.NOTCH_HEIGHT / 2;
};
Blockly.utils.object.inherits(Blockly.geras.ConstantProvider,
Blockly.blockRendering.ConstantProvider);
+263
View File
@@ -0,0 +1,263 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Registers default keyboard shortcuts.
* @author aschmiedt@google.com (Abby Schmiedt)
*/
'use strict';
/**
* @name Blockly.ShortcutItems
* @namespace
*/
goog.provide('Blockly.ShortcutItems');
goog.require('Blockly.utils.KeyCodes');
/**
* Object holding the names of the default shortcut items.
* @enum {string}
*/
Blockly.ShortcutItems.names = {
ESCAPE: 'escape',
DELETE: 'delete',
COPY: 'copy',
CUT: 'cut',
PASTE: 'paste',
UNDO: 'undo',
REDO: 'redo'
};
/** Keyboard shortcut to hide chaff on escape. */
Blockly.ShortcutItems.registerEscape = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var escapeAction = {
name: Blockly.ShortcutItems.names.ESCAPE,
preconditionFn: function(workspace) {
return !workspace.options.readOnly;
},
callback: function() {
Blockly.hideChaff();
return true;
}
};
Blockly.ShortcutRegistry.registry.register(escapeAction);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.ESC, escapeAction.name);
};
/** Keyboard shortcut to delete a block on delete or backspace */
Blockly.ShortcutItems.registerDelete = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var deleteShortcut = {
name: Blockly.ShortcutItems.names.DELETE,
preconditionFn: function(workspace) {
return !workspace.options.readOnly &&
Blockly.selected &&
Blockly.selected.isDeletable();
},
callback: function(workspace, e) {
// Delete or backspace.
// Stop the browser from going back to the previous page.
// Do this first to prevent an error in the delete code from resulting in
// data loss.
e.preventDefault();
// Don't delete while dragging. Jeez.
if (Blockly.Gesture.inProgress()) {
return false;
}
Blockly.deleteBlock(/** @type {!Blockly.BlockSvg} */ (Blockly.selected));
return true;
}
};
Blockly.ShortcutRegistry.registry.register(deleteShortcut);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.DELETE, deleteShortcut.name);
Blockly.ShortcutRegistry.registry.addKeyMapping(
Blockly.utils.KeyCodes.BACKSPACE, deleteShortcut.name);
};
/** Keyboard shortcut to copy a block on ctrl+c, cmd+c, or alt+c. */
Blockly.ShortcutItems.registerCopy = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var copyShortcut = {
name: Blockly.ShortcutItems.names.COPY,
preconditionFn: function(workspace) {
return !workspace.options.readOnly &&
!Blockly.Gesture.inProgress() &&
Blockly.selected &&
Blockly.selected.isDeletable() &&
Blockly.selected.isMovable();
},
callback: function() {
Blockly.hideChaff();
Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected));
return true;
}
};
Blockly.ShortcutRegistry.registry.register(copyShortcut);
var ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlC, copyShortcut.name);
var altC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.ALT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(altC, copyShortcut.name);
var metaC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.META]);
Blockly.ShortcutRegistry.registry.addKeyMapping(metaC, copyShortcut.name);
};
/** Keyboard shortcut to copy and delete a block on ctrl+x, cmd+x, or alt+x. */
Blockly.ShortcutItems.registerCut = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var cutShortcut = {
name: Blockly.ShortcutItems.names.CUT,
preconditionFn: function(workspace) {
return !workspace.options.readOnly &&
!Blockly.Gesture.inProgress() &&
Blockly.selected &&
Blockly.selected.isDeletable() &&
Blockly.selected.isMovable() &&
!Blockly.selected.workspace.isFlyout;
},
callback: function() {
Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected));
Blockly.deleteBlock(/** @type {!Blockly.BlockSvg} */ (Blockly.selected));
return true;
}
};
Blockly.ShortcutRegistry.registry.register(cutShortcut);
var ctrlX = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlX, cutShortcut.name);
var altX = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.ALT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(altX, cutShortcut.name);
var metaX = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.META]);
Blockly.ShortcutRegistry.registry.addKeyMapping(metaX, cutShortcut.name);
};
/** Keyboard shortcut to paste a block on ctrl+v, cmd+v, or alt+v. */
Blockly.ShortcutItems.registerPaste = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var pasteShortcut = {
name: Blockly.ShortcutItems.names.PASTE,
preconditionFn: function(workspace) {
return !workspace.options.readOnly && !Blockly.Gesture.inProgress();
},
callback: function() {
return Blockly.paste();
}
};
Blockly.ShortcutRegistry.registry.register(pasteShortcut);
var ctrlV = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlV, pasteShortcut.name);
var altV = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.ALT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(altV, pasteShortcut.name);
var metaV = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.META]);
Blockly.ShortcutRegistry.registry.addKeyMapping(metaV, pasteShortcut.name);
};
/** Keyboard shortcut to undo the previous action on ctrl+z, cmd+z, or alt+z. */
Blockly.ShortcutItems.registerUndo = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var undoShortcut = {
name: Blockly.ShortcutItems.names.UNDO,
preconditionFn: function(workspace) {
return !workspace.options.readOnly &&
!Blockly.Gesture.inProgress();
},
callback: function(workspace) {
// 'z' for undo 'Z' is for redo.
Blockly.hideChaff();
workspace.undo(false);
return true;
}
};
Blockly.ShortcutRegistry.registry.register(undoShortcut);
var ctrlZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlZ, undoShortcut.name);
var altZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.ALT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(altZ, undoShortcut.name);
var metaZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.META]);
Blockly.ShortcutRegistry.registry.addKeyMapping(metaZ, undoShortcut.name);
};
/** Keyboard shortcut to redo the previous action on ctrl+shift+z, cmd+shift+z, or alt+shift+z. */
Blockly.ShortcutItems.registerRedo = function() {
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
var redoShortcut = {
name: Blockly.ShortcutItems.names.REDO,
preconditionFn: function(workspace) {
return !Blockly.Gesture.inProgress() && !workspace.options.readOnly;
},
callback: function(workspace) {
// 'z' for undo 'Z' is for redo.
Blockly.hideChaff();
workspace.undo(true);
return true;
}
};
Blockly.ShortcutRegistry.registry.register(redoShortcut);
var ctrlShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.SHIFT,
Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlShiftZ, redoShortcut.name);
var altShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.SHIFT,
Blockly.utils.KeyCodes.ALT]);
Blockly.ShortcutRegistry.registry.addKeyMapping(altShiftZ, redoShortcut.name);
var metaShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.SHIFT,
Blockly.utils.KeyCodes.META]);
Blockly.ShortcutRegistry.registry.addKeyMapping(metaShiftZ, redoShortcut.name);
// Ctrl-y is redo in Windows. Command-y is never valid on Macs.
var ctrlY = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.Y, [Blockly.utils.KeyCodes.CTRL]);
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlY, redoShortcut.name);
};
/**
* Registers all default keyboard shortcut item. This should be called once per instance of
* KeyboardShortcutRegistry.
* @package
*/
Blockly.ShortcutItems.registerDefaultShortcuts = function() {
Blockly.ShortcutItems.registerEscape();
Blockly.ShortcutItems.registerDelete();
Blockly.ShortcutItems.registerCopy();
Blockly.ShortcutItems.registerCut();
Blockly.ShortcutItems.registerPaste();
Blockly.ShortcutItems.registerUndo();
Blockly.ShortcutItems.registerRedo();
};
+357
View File
@@ -0,0 +1,357 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview The namespace used to keep track of keyboard shortcuts and the
* key codes used to execute those shortcuts.
* @author aschmiedt@google.com (Abby Schmiedt)
*/
'use strict';
goog.provide('Blockly.ShortcutRegistry');
goog.require('Blockly.navigation');
goog.require('Blockly.ShortcutItems');
goog.require('Blockly.utils.object');
/**
* Class for the registry of keyboard shortcuts. This is intended to be a
* singleton. You should not create a new instance, and only access this class
* from Blockly.ShortcutRegistry.registry.
* @constructor
*/
Blockly.ShortcutRegistry = function() {
// Singleton instance should be registered once.
Blockly.ShortcutRegistry.registry = this;
/**
* Registry of all keyboard shortcuts, keyed by name of shortcut.
* @type {!Object<string, !Blockly.ShortcutRegistry.KeyboardShortcut>}
* @private
*/
this.registry_ = Object.create(null);
/**
* Map of key codes to an array of shortcut names.
* @type {!Object<string, !Array<string>>}
* @private
*/
this.keyMap_ = Object.create(null);
Blockly.ShortcutItems.registerDefaultShortcuts();
Blockly.navigation.registerNavigationShortcuts();
};
/**
* Enum of valid modifiers.
* @enum {!Blockly.utils.KeyCodes<number>}
*/
Blockly.ShortcutRegistry.modifierKeys = {
Shift: Blockly.utils.KeyCodes.SHIFT,
Control: Blockly.utils.KeyCodes.CTRL,
Alt: Blockly.utils.KeyCodes.ALT,
Meta: Blockly.utils.KeyCodes.META
};
/**
* A keyboard shortcut.
* @typedef {{
* callback: ((function(!Blockly.Workspace, Event,
* !Blockly.ShortcutRegistry.KeyboardShortcut):boolean)|undefined),
* name: string,
* preconditionFn: ((function(!Blockly.Workspace):boolean)|undefined),
* metadata: (Object|undefined)
* }}
*/
Blockly.ShortcutRegistry.KeyboardShortcut;
/**
* Registers a keyboard shortcut.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} shortcut The
* shortcut for this key code.
* @param {boolean=} opt_allowOverrides True to prevent a warning when
* overriding an already registered item.
* @throws {Error} if a shortcut with the same name already exists.
* @public
*/
Blockly.ShortcutRegistry.prototype.register = function(
shortcut, opt_allowOverrides) {
var registeredShortcut = this.registry_[shortcut.name];
if (registeredShortcut && !opt_allowOverrides) {
throw new Error(
'Shortcut with name "' + shortcut.name + '" already exists.');
}
this.registry_[shortcut.name] = shortcut;
};
/**
* Unregisters a keyboard shortcut registered with the given key code. This will
* also remove any key mappings that reference this shortcut.
* @param {string} shortcutName The name of the shortcut to unregister.
* @return {boolean} True if an item was unregistered, false otherwise.
* @public
*/
Blockly.ShortcutRegistry.prototype.unregister = function(shortcutName) {
var shortcut = this.registry_[shortcutName];
if (!shortcut) {
console.warn(
'Keyboard shortcut with name "' + shortcutName + '" not found.');
return false;
}
this.removeAllKeyMappings(shortcutName);
delete this.registry_[shortcutName];
return true;
};
/**
* Adds a mapping between a keycode and a keyboard shortcut.
* @param {string} keyCode The key code for the keyboard shortcut. If
* registering a key code with a modifier (ex: ctrl+c) use
* Blockly.ShortcutRegistry.registry.createSerializedKey;
* @param {string} shortcutName The name of the shortcut to execute when the
* given keycode is pressed.
* @param {boolean=} opt_allowCollision True to prevent an error when adding a
* shortcut to a key that is already mapped to a shortcut.
* @throws {Error} if the given key code is already mapped to a shortcut.
* @public
*/
Blockly.ShortcutRegistry.prototype.addKeyMapping = function(
keyCode, shortcutName, opt_allowCollision) {
var shortcutNames = this.keyMap_[keyCode];
if (shortcutNames && !opt_allowCollision) {
throw new Error(
'Shortcut with name "' + shortcutName + '" collides with shortcuts ' +
shortcutNames.toString());
} else if (shortcutNames && opt_allowCollision) {
shortcutNames.unshift(shortcutName);
} else {
this.keyMap_[keyCode] = [shortcutName];
}
};
/**
* Removes a mapping between a keycode and a keyboard shortcut.
* @param {string} keyCode The key code for the keyboard shortcut. If
* registering a key code with a modifier (ex: ctrl+c) use
* Blockly.ShortcutRegistry.registry.createSerializedKey;
* @param {string} shortcutName The name of the shortcut to execute when the
* given keycode is pressed.
* @param {boolean=} opt_quiet True to not console warn when there is no
* shortcut to remove.
* @return {boolean} True if a key mapping was removed, false otherwise.
* @public
*/
Blockly.ShortcutRegistry.prototype.removeKeyMapping = function(
keyCode, shortcutName, opt_quiet) {
var shortcutNames = this.keyMap_[keyCode];
if (!shortcutNames && !opt_quiet) {
console.warn(
'No keyboard shortcut with name "' + shortcutName +
'" registered with key code "' + keyCode + '"');
return false;
}
var shortcutIdx = shortcutNames.indexOf(shortcutName);
if (shortcutIdx > -1) {
shortcutNames.splice(shortcutIdx, 1);
if (shortcutNames.length == 0) {
delete this.keyMap_[keyCode];
}
return true;
} else if (!opt_quiet) {
console.warn(
'No keyboard shortcut with name "' + shortcutName +
'" registered with key code "' + keyCode + '"');
return false;
}
return false;
};
/**
* Removes all the key mappings for a shortcut with the given name.
* Useful when changing the default key mappings and the key codes registered to the shortcut are
* unknown.
* @param {string} shortcutName The name of the shortcut to remove from the key map.
* @public
*/
Blockly.ShortcutRegistry.prototype.removeAllKeyMappings = function(shortcutName) {
for (var keyCode in this.keyMap_) {
this.removeKeyMapping(keyCode, shortcutName, true);
}
};
/**
* Sets the key map. Setting the key map will override any default key mappings.
* @param {!Object<string, !Array<string>>} keyMap The object with key code to
* shortcut names.
* @public
*/
Blockly.ShortcutRegistry.prototype.setKeyMap = function(keyMap) {
this.keyMap_ = keyMap;
};
/**
* Gets the current key map.
* @return {!Object<string,!Array<!Blockly.ShortcutRegistry.KeyboardShortcut>>}
* The object holding key codes to Blockly.ShortcutRegistry.KeyboardShortcut.
* @public
*/
Blockly.ShortcutRegistry.prototype.getKeyMap = function() {
return Blockly.utils.object.deepMerge(Object.create(null), this.keyMap_);
};
/**
* Gets the registry of keyboard shortcuts.
* @return {!Object<string, !Blockly.ShortcutRegistry.KeyboardShortcut>}
* The registry of keyboard shortcuts.
* @public
*/
Blockly.ShortcutRegistry.prototype.getRegistry = function() {
return Blockly.utils.object.deepMerge(Object.create(null), this.registry_);
};
/**
* Handles key down events.
* @param {!Blockly.Workspace} workspace The main workspace where the event was
* captured.
* @param {!Event} e The key down event.
* @return {boolean} True if the event was handled, false otherwise.
* @public
*/
Blockly.ShortcutRegistry.prototype.onKeyDown = function(workspace, e) {
var key = this.serializeKeyEvent_(e);
var shortcutNames = this.getShortcutNamesByKeyCode(key);
if (!shortcutNames) {
return false;
}
for (var i = 0, shortcutName; (shortcutName = shortcutNames[i]); i++) {
var shortcut = this.registry_[shortcutName];
if (!shortcut.preconditionFn || shortcut.preconditionFn(workspace)) {
// If the key has been handled, stop processing shortcuts.
if (shortcut.callback && shortcut.callback(workspace, e, shortcut)) {
return true;
}
}
}
return false;
};
/**
* Gets the shortcuts registered to the given key code.
* @param {string} keyCode The serialized key code.
* @return {!Array<string>|undefined} The list of shortcuts to call when the
* given keyCode is used. Undefined if no shortcuts exist.
* @public
*/
Blockly.ShortcutRegistry.prototype.getShortcutNamesByKeyCode = function(
keyCode) {
return this.keyMap_[keyCode] || [];
};
/**
* Gets the serialized key codes that the shortcut with the given name is
* registered under.
* @param {string} shortcutName The name of the shortcut.
* @return {!Array<string>} An array with all the key codes the shortcut is
* registered under.
* @public
*/
Blockly.ShortcutRegistry.prototype.getKeyCodesByShortcutName = function(
shortcutName) {
var keys = [];
for (var keyCode in this.keyMap_) {
var shortcuts = this.keyMap_[keyCode];
var shortcutIdx = shortcuts.indexOf(shortcutName);
if (shortcutIdx > -1) {
keys.push(keyCode);
}
}
return keys;
};
/**
* Serializes a key event.
* @param {!Event} e A key down event.
* @return {string} The serialized key code for the given event.
* @private
*/
Blockly.ShortcutRegistry.prototype.serializeKeyEvent_ = function(e) {
var serializedKey = '';
for (var modifier in Blockly.ShortcutRegistry.modifierKeys) {
if (e.getModifierState(modifier)) {
if (serializedKey != '') {
serializedKey += '+';
}
serializedKey += modifier;
}
}
if (serializedKey != '' && e.keyCode) {
serializedKey = serializedKey + '+' + e.keyCode;
} else if (e.keyCode) {
serializedKey = e.keyCode.toString();
}
return serializedKey;
};
/**
* Checks whether any of the given modifiers are not valid.
* @param {!Array<string>} modifiers List of modifiers to be used with the key.
* @throws {Error} if the modifier is not in the valid modifiers list.
* @private
*/
Blockly.ShortcutRegistry.prototype.checkModifiers_ = function(
modifiers) {
var validModifiers = Blockly.utils.object.values(
Blockly.ShortcutRegistry.modifierKeys);
for (var i = 0, modifier; (modifier = modifiers[i]); i++) {
if (validModifiers.indexOf(modifier) < 0) {
throw new Error(modifier + ' is not a valid modifier key.');
}
}
};
/**
* Creates the serialized key code that will be used in the key map.
* @param {number} keyCode Number code representing the key.
* @param {?Array.<string>} modifiers List of modifier key codes to be used with
* the key. All valid modifiers can be found in the
* Blockly.ShortcutRegistry.modifierKeys.
* @return {string} The serialized key code for the given modifiers and key.
* @public
*/
Blockly.ShortcutRegistry.prototype.createSerializedKey = function(
keyCode, modifiers) {
var serializedKey = '';
if (modifiers) {
this.checkModifiers_(modifiers);
for (var modifier in Blockly.ShortcutRegistry.modifierKeys) {
var modifierKeyCode =
Blockly.ShortcutRegistry.modifierKeys[modifier];
if (modifiers.indexOf(modifierKeyCode) > -1) {
if (serializedKey != '') {
serializedKey += '+';
}
serializedKey += modifier;
}
}
}
if (serializedKey != '' && keyCode) {
serializedKey = serializedKey + '+' + keyCode;
} else if (keyCode) {
serializedKey = keyCode.toString();
}
return serializedKey;
};
// Creates and assigns the singleton instance.
new Blockly.ShortcutRegistry();
+29 -12
View File
@@ -82,6 +82,13 @@ Blockly.ToolboxCategory = function(categoryDef, toolbox, opt_parent) {
*/
this.iconDom_ = null;
/**
* The html element for the toolbox label.
* @type {?Element}
* @protected
*/
this.labelDom_ = null;
/**
* All the css class names that are used to create a category.
* @type {!Blockly.ToolboxCategory.CssConfig}
@@ -121,14 +128,14 @@ Blockly.utils.object.inherits(Blockly.ToolboxCategory, Blockly.ToolboxItem);
/**
* All the css class names that are used to create a category.
* @typedef {{
* container:?string,
* row:?string,
* rowcontentcontainer:?string,
* icon:?string,
* label:?string,
* selected:?string,
* openicon:?string,
* closedicon:?string
* container:(string|undefined),
* row:(string|undefined),
* rowcontentcontainer:(string|undefined),
* icon:(string|undefined),
* label:(string|undefined),
* selected:(string|undefined),
* openicon:(string|undefined),
* closedicon:(string|undefined)
* }}
*/
Blockly.ToolboxCategory.CssConfig;
@@ -222,7 +229,6 @@ Blockly.ToolboxCategory.prototype.createDom_ = function() {
Blockly.utils.aria.State.LEVEL, this.level_);
this.rowDiv_ = this.createRowContainer_();
this.rowDiv_.setAttribute('id', this.id_);
this.rowDiv_.style.pointerEvents = 'auto';
this.htmlDiv_.appendChild(this.rowDiv_);
@@ -234,10 +240,10 @@ Blockly.ToolboxCategory.prototype.createDom_ = function() {
Blockly.utils.aria.setRole(this.iconDom_, Blockly.utils.aria.Role.PRESENTATION);
this.rowContents_.appendChild(this.iconDom_);
var labelDom = this.createLabelDom_(this.name_);
this.rowContents_.appendChild(labelDom);
this.labelDom_ = this.createLabelDom_(this.name_);
this.rowContents_.appendChild(this.labelDom_);
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
Blockly.utils.aria.State.LABELLEDBY, labelDom.getAttribute('id'));
Blockly.utils.aria.State.LABELLEDBY, this.labelDom_.getAttribute('id'));
this.addColourBorder_(this.colour_);
@@ -383,6 +389,17 @@ Blockly.ToolboxCategory.prototype.getColourfromStyle_ = function(styleName) {
return '';
};
/**
* Gets the html element that is clickable.
* The parent toolbox element receives clicks. The parent toolbox will add an id to this element so
* it can pass the onClick event to the correct toolboxItem.
* @return {!Element} The html element that receives clicks.
* @public
*/
Blockly.ToolboxCategory.prototype.getClickTarget = function() {
return /** @type {!Element} */(this.rowDiv_);
};
/**
* Parses the colour on the category.
* @param {number|string} colourValue HSV hue value (0 to 360), #RRGGBB string,
+3
View File
@@ -200,6 +200,9 @@ Blockly.CollapsibleToolboxCategory.prototype.createSubCategoriesDom_ = function(
newCategory.init();
var newCategoryDiv = newCategory.getDiv();
contentsContainer.appendChild(newCategoryDiv);
if (newCategory.getClickTarget) {
newCategory.getClickTarget().setAttribute('id', newCategory.getId());
}
}
return contentsContainer;
};
+1 -1
View File
@@ -53,7 +53,7 @@ Blockly.utils.object.inherits(Blockly.ToolboxSeparator, Blockly.ToolboxItem);
/**
* All the css class names that are used to create a separator.
* @typedef {{
* container:?string
* container:(string|undefined)
* }}
*/
Blockly.ToolboxSeparator.CssConfig;
+17 -11
View File
@@ -16,7 +16,7 @@ goog.require('Blockly.CollapsibleToolboxCategory');
goog.require('Blockly.constants');
goog.require('Blockly.Css');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.ToolboxItemSelect');
goog.require('Blockly.navigation');
goog.require('Blockly.registry');
goog.require('Blockly.Touch');
@@ -26,7 +26,6 @@ goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.toolbox');
goog.requireType('Blockly.Action');
goog.requireType('Blockly.IBlocklyActionable');
goog.requireType('Blockly.ICollapsibleToolboxItem');
goog.requireType('Blockly.IDeleteArea');
@@ -35,6 +34,7 @@ goog.requireType('Blockly.ISelectableToolboxItem');
goog.requireType('Blockly.IStyleable');
goog.requireType('Blockly.IToolbox');
goog.requireType('Blockly.IToolboxItem');
goog.requireType('Blockly.ShortcutRegistry');
goog.requireType('Blockly.WorkspaceSvg');
@@ -236,7 +236,7 @@ Blockly.Toolbox.prototype.createContentsContainer_ = function() {
Blockly.Toolbox.prototype.attachEvents_ = function(container,
contentsContainer) {
// Clicking on toolbox closes popups.
var clickEvent = Blockly.bindEventWithChecks_(container, 'mousedown', this,
var clickEvent = Blockly.bindEventWithChecks_(container, 'click', this,
this.onClick_, /* opt_noCaptureIdentifier */ false,
/* opt_noPreventDefault */ true);
this.boundEvents_.push(clickEvent);
@@ -257,8 +257,8 @@ Blockly.Toolbox.prototype.onClick_ = function(e) {
// Close flyout.
Blockly.hideChaff(false);
} else {
var srcElement = e.srcElement;
var itemId = srcElement.getAttribute('id');
var targetElement = e.target;
var itemId = targetElement.getAttribute('id');
if (itemId) {
var item = this.getToolboxItemById(itemId);
if (item.isSelectable()) {
@@ -304,6 +304,9 @@ Blockly.Toolbox.prototype.onKeyDown_ = function(e) {
handled = false;
break;
}
if (!handled && this.selectedItem_ && this.selectedItem_.onKeyDown) {
handled = this.selectedItem_.onKeyDown(e);
}
if (handled) {
e.preventDefault();
@@ -387,7 +390,7 @@ Blockly.Toolbox.prototype.renderContents_ = function(toolboxDef) {
/**
* Creates and renders the toolbox item.
* @param {Blockly.utils.toolbox.ToolboxItemInfo} toolboxItemDef Any information
* @param {!Blockly.utils.toolbox.ToolboxItemInfo} toolboxItemDef Any information
* that can be used to create an item in the toolbox.
* @param {!DocumentFragment} fragment The document fragment to add the child
* toolbox elements to.
@@ -414,6 +417,11 @@ Blockly.Toolbox.prototype.createToolboxItem_ = function(toolboxItemDef, fragment
if (toolboxItemDom) {
fragment.appendChild(toolboxItemDom);
}
// Adds the id to the html element that can receive a click.
// This is used in onClick_ to find the toolboxItem that was clicked.
if (toolboxItem.getClickTarget) {
toolboxItem.getClickTarget().setAttribute('id', toolboxItem.getId());
}
}
};
@@ -798,17 +806,15 @@ Blockly.Toolbox.prototype.fireSelectEvent_ = function(oldItem, newItem) {
if (oldItem == newItem) {
newElement = null;
}
// TODO (#4187): Update Toolbox Events.
var event = new Blockly.Events.Ui(null, 'category',
oldElement, newElement);
event.workspaceId = this.workspace_.id;
var event = new Blockly.Events.ToolboxItemSelect(
oldElement, newElement, this.workspace_.id);
Blockly.Events.fire(event);
};
/**
* Handles the given Blockly action on a toolbox.
* This is only triggered when keyboard accessibility mode is enabled.
* @param {!Blockly.Action} action The action to be handled.
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
* @return {boolean} True if the field handled the action, false otherwise.
* @package
*/
+1 -1
View File
@@ -121,7 +121,7 @@ Blockly.Tooltip.DIV = null;
/**
* Returns the tooltip text for the given element.
* @param {?Object} object The object to get the the tooltip text of.
* @param {?Object} object The object to get the tooltip text of.
* @returns {string} The tooltip text of the element.
*/
Blockly.Tooltip.getTooltipOfObject = function(object) {
+19 -3
View File
@@ -13,6 +13,7 @@
goog.provide('Blockly.Trashcan');
goog.require('Blockly.constants');
goog.require('Blockly.Events.TrashcanOpen');
goog.require('Blockly.Scrollbar');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Rect');
@@ -312,9 +313,13 @@ Blockly.Trashcan.prototype.createDom = function() {
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);
// bindEventWithChecks_ quashes events too aggressively. See:
// https://groups.google.com/forum/#!topic/blockly/QF4yB9Wx00s
// Using bindEventWithChecks_ for blocking mousedown causes issue in mobile.
// See #4303
Blockly.bindEvent_(
this.svgGroup_, 'mousedown', this, this.blockMouseDownWhenOpenable_);
Blockly.bindEvent_(this.svgGroup_, 'mouseup', this, this.click);
// Bind to body instead of this.svgGroup_ so that we don't get lid jitters
Blockly.bindEvent_(body, 'mouseover', this, this.mouseOver_);
Blockly.bindEvent_(body, 'mouseout', this, this.mouseOut_);
@@ -560,11 +565,22 @@ Blockly.Trashcan.prototype.click = function() {
* @private
*/
Blockly.Trashcan.prototype.fireUiEvent_ = function(trashcanOpen) {
var uiEvent = new Blockly.Events.Ui(null, 'trashcanOpen', null, trashcanOpen);
uiEvent.workspaceId = this.workspace_.id;
var uiEvent =
new Blockly.Events.TrashcanOpen(trashcanOpen,this.workspace_.id);
Blockly.Events.fire(uiEvent);
};
/**
* Prevents a workspace scroll and click event if the trashcan has blocks.
* @param {!Event} e A mouse down event.
* @private
*/
Blockly.Trashcan.prototype.blockMouseDownWhenOpenable_ = function(e) {
if (!this.contentsIsOpen() && this.hasContents_()) {
e.stopPropagation(); // Don't start a workspace scroll.
}
};
/**
* Indicate that the trashcan can be clicked (by opening it) if it has blocks.
* @private
+23 -22
View File
@@ -22,10 +22,10 @@ goog.requireType('Blockly.ToolboxSeparator');
* The information needed to create a block in the toolbox.
* @typedef {{
* kind:string,
* blockxml:(?string|Node),
* type: ?string,
* gap: (?string|?number),
* disabled: (?string|?boolean)
* blockxml:(string|!Node|undefined),
* type:(string|undefined),
* gap:(string|number|undefined),
* disabled: (string|boolean|undefined)
* }}
*/
Blockly.utils.toolbox.BlockInfo;
@@ -34,9 +34,9 @@ Blockly.utils.toolbox.BlockInfo;
* The information needed to create a separator in the toolbox.
* @typedef {{
* kind:string,
* id:?string,
* gap:?number,
* cssconfig:?Blockly.ToolboxSeparator.CssConfig
* id:(string|undefined),
* gap:(number|undefined),
* cssconfig:(!Blockly.ToolboxSeparator.CssConfig|undefined)
* }}
*/
Blockly.utils.toolbox.SeparatorInfo;
@@ -55,8 +55,8 @@ Blockly.utils.toolbox.ButtonInfo;
* The information needed to create a label in the toolbox.
* @typedef {{
* kind:string,
* id:?string,
* text:string
* text:string,
* id:(string|undefined)
* }}
*/
Blockly.utils.toolbox.LabelInfo;
@@ -73,12 +73,12 @@ Blockly.utils.toolbox.ButtonOrLabelInfo;
* @typedef {{
* kind:string,
* name:string,
* id:?string,
* categorystyle:?string,
* colour:?string,
* cssconfig:?Blockly.ToolboxCategory.CssConfig,
* contents:!Array<Blockly.utils.toolbox.ToolboxItemInfo>,
* hidden:?string
* contents:!Array<!Blockly.utils.toolbox.ToolboxItemInfo>,
* id:(string|undefined),
* categorystyle:(string|undefined),
* colour:(string|undefined),
* cssconfig:(!Blockly.ToolboxCategory.CssConfig|undefined),
* hidden:(string|undefined)
* }}
*/
Blockly.utils.toolbox.StaticCategoryInfo;
@@ -88,11 +88,11 @@ Blockly.utils.toolbox.StaticCategoryInfo;
* @typedef {{
* kind:string,
* custom:string,
* id:?string,
* categorystyle:?string,
* colour:?string,
* cssconfig:?Blockly.ToolboxCategory.CssConfig,
* hidden:?string
* id:(string|undefined),
* categorystyle:(string|undefined),
* colour:(string|undefined),
* cssconfig:(!Blockly.ToolboxCategory.CssConfig|undefined),
* hidden:(string|undefined)
* }}
*/
Blockly.utils.toolbox.DynamicCategoryInfo;
@@ -124,7 +124,8 @@ Blockly.utils.toolbox.FlyoutItemInfo;
/**
* The JSON definition of a toolbox.
* @typedef {{
* contents:!Array<Blockly.utils.toolbox.ToolboxItemInfo>
* kind:(string|undefined),
* contents:!Array<!Blockly.utils.toolbox.ToolboxItemInfo>
* }}
*/
Blockly.utils.toolbox.ToolboxInfo;
@@ -341,7 +342,7 @@ Blockly.utils.toolbox.xmlToJsonArray_ = function(toolboxDef) {
// Store the xml for a block
if (tagName == 'BLOCK') {
obj['blockxml'] = child;
} else if (tagName == 'CATEGORY') {
} else if (child.childNodes && child.childNodes.length > 0) {
// Get the contents of a category
obj['contents'] = Blockly.utils.toolbox.xmlToJsonArray_(child);
}
+12 -56
View File
@@ -14,7 +14,7 @@ goog.provide('Blockly.Warning');
goog.require('Blockly.Bubble');
goog.require('Blockly.Events');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.BubbleOpen');
goog.require('Blockly.Icon');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.object');
@@ -74,31 +74,6 @@ Blockly.Warning.prototype.drawIcon_ = function(group) {
group);
};
/**
* Create the text for the warning's bubble.
* @param {string} text The text to display.
* @return {!SVGTextElement} The top-level node of the text.
* @private
*/
Blockly.Warning.textToDom_ = function(text) {
var paragraph = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.TEXT,
{
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
'y': Blockly.Bubble.BORDER_WIDTH
},
null);
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++) {
var tspanElement = Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.TSPAN,
{'dy': '1em', 'x': Blockly.Bubble.BORDER_WIDTH}, paragraph);
var textNode = document.createTextNode(lines[i]);
tspanElement.appendChild(textNode);
}
return paragraph;
};
/**
* Show or hide the warning bubble.
* @param {boolean} visible True if the bubble should be visible.
@@ -108,52 +83,33 @@ Blockly.Warning.prototype.setVisible = function(visible) {
return;
}
Blockly.Events.fire(
new Blockly.Events.Ui(this.block_, 'warningOpen', !visible, visible));
new Blockly.Events.BubbleOpen(this.block_, visible, 'warning'));
if (visible) {
this.createBubble();
this.createBubble_();
} else {
this.disposeBubble();
this.disposeBubble_();
}
};
/**
* Show the bubble.
* @package
* @private
*/
Blockly.Warning.prototype.createBubble = function() {
// TODO (#2943): This is package because comments steal this UI for
// non-editable comments, but really this should be private.
this.paragraphElement_ = Blockly.Warning.textToDom_(this.getText());
this.bubble_ = new Blockly.Bubble(
/** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace),
this.paragraphElement_, this.block_.pathObject.svgPath,
/** @type {!Blockly.utils.Coordinate} */ (this.iconXY_), null, null);
// Expose this warning's block's ID on its top-level SVG group.
this.bubble_.setSvgId(this.block_.id);
if (this.block_.RTL) {
// Right-align the paragraph.
// This cannot be done until the bubble is rendered on screen.
var maxWidth = this.paragraphElement_.getBBox().width;
for (var i = 0, textElement;
(textElement = this.paragraphElement_.childNodes[i]); i++) {
textElement.setAttribute('text-anchor', 'end');
textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH);
}
}
Blockly.Warning.prototype.createBubble_ = function() {
this.paragraphElement_ = Blockly.Bubble.textToDom(this.getText());
this.bubble_ = Blockly.Bubble.createNonEditableBubble(
this.paragraphElement_, /** @type {!Blockly.BlockSvg} */ (this.block_),
/** @type {!Blockly.utils.Coordinate} */ (this.iconXY_));
this.applyColour();
};
/**
* Dispose of the bubble and references to it.
* @package
* @private
*/
Blockly.Warning.prototype.disposeBubble = function() {
// TODO (#2943): This is package because comments steal this UI for
// non-editable comments, but really this should be private.
Blockly.Warning.prototype.disposeBubble_ = function() {
this.bubble_.dispose();
this.bubble_ = null;
this.body_ = null;
this.paragraphElement_ = null;
};
+12 -7
View File
@@ -17,7 +17,7 @@ goog.require('Blockly.Events');
goog.require('Blockly.Events.CommentCreate');
goog.require('Blockly.Events.CommentDelete');
goog.require('Blockly.Events.CommentMove');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Events.Selected');
goog.require('Blockly.utils');
goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');
@@ -145,9 +145,12 @@ Blockly.WorkspaceCommentSvg.prototype.dispose = function() {
/**
* Create and initialize the SVG representation of a workspace comment.
* May be called more than once.
*
* @param {boolean=} opt_noSelect Text inside text area will be selected if false
*
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.initSvg = function() {
Blockly.WorkspaceCommentSvg.prototype.initSvg = function(opt_noSelect) {
if (!this.workspace.rendered) {
throw TypeError('Workspace is headless.');
}
@@ -163,6 +166,10 @@ Blockly.WorkspaceCommentSvg.prototype.initSvg = function() {
if (!this.getSvgRoot().parentNode) {
this.workspace.getBubbleCanvas().appendChild(this.getSvgRoot());
}
if (!opt_noSelect && this.textarea_) {
this.textarea_.select();
}
};
/**
@@ -217,8 +224,7 @@ Blockly.WorkspaceCommentSvg.prototype.select = function() {
Blockly.Events.enable();
}
}
var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id);
event.workspaceId = this.workspace.id;
var event = new Blockly.Events.Selected(oldId, this.id, this.workspace.id);
Blockly.Events.fire(event);
Blockly.selected = this;
this.addSelect();
@@ -232,8 +238,7 @@ Blockly.WorkspaceCommentSvg.prototype.unselect = function() {
if (Blockly.selected != this) {
return;
}
var event = new Blockly.Events.Ui(null, 'selected', this.id, null);
event.workspaceId = this.workspace.id;
var event = new Blockly.Events.Selected(this.id, null, this.workspace.id);
Blockly.Events.fire(event);
Blockly.selected = null;
this.removeSelect();
@@ -581,7 +586,7 @@ Blockly.WorkspaceCommentSvg.fromXml = function(
var comment = new Blockly.WorkspaceCommentSvg(
workspace, info.content, info.h, info.w, info.id);
if (workspace.rendered) {
comment.initSvg();
comment.initSvg(true);
comment.render(false);
}
// Position the comment correctly, taking into account the width of a
+46 -42
View File
@@ -19,6 +19,8 @@ goog.require('Blockly.constants');
goog.require('Blockly.ContextMenuRegistry');
goog.require('Blockly.Events');
goog.require('Blockly.Events.BlockCreate');
goog.require('Blockly.Events.ThemeChange');
goog.require('Blockly.Events.ViewportChange');
goog.require('Blockly.Gesture');
goog.require('Blockly.Grid');
goog.require('Blockly.MarkerManager');
@@ -324,27 +326,26 @@ Blockly.WorkspaceSvg.prototype.dragDeltaXY_ = null;
*/
Blockly.WorkspaceSvg.prototype.scale = 1;
// TODO(#4203) Enable viewport events after ui events refactor.
// /**
// * Cached scale value. Used to detect changes in viewport.
// * @type {number}
// * @private
// */
// Blockly.WorkspaceSvg.prototype.oldScale_ = 1;
//
// /**
// * Cached viewport top value. Used to detect changes in viewport.
// * @type {number}
// * @private
// */
// Blockly.WorkspaceSvg.prototype.oldTop_ = 0;
//
// /**
// * Cached viewport left value. Used to detect changes in viewport.
// * @type {number}
// * @private
// */
// Blockly.WorkspaceSvg.prototype.oldLeft_ = 0;
/**
* Cached scale value. Used to detect changes in viewport.
* @type {number}
* @private
*/
Blockly.WorkspaceSvg.prototype.oldScale_ = 1;
/**
* Cached viewport top value. Used to detect changes in viewport.
* @type {number}
* @private
*/
Blockly.WorkspaceSvg.prototype.oldTop_ = 0;
/**
* Cached viewport left value. Used to detect changes in viewport.
* @type {number}
* @private
*/
Blockly.WorkspaceSvg.prototype.oldLeft_ = 0;
/**
* The workspace's trashcan (if any).
@@ -576,8 +577,7 @@ Blockly.WorkspaceSvg.prototype.refreshTheme = function() {
this.setVisible(true);
}
var event = new Blockly.Events.Ui(null, 'theme', null, null);
event.workspaceId = this.id;
var event = new Blockly.Events.ThemeChange(this.getTheme().name, this.id);
Blockly.Events.fire(event);
};
@@ -1106,23 +1106,24 @@ Blockly.WorkspaceSvg.prototype.getParentSvg = function() {
* @package
*/
Blockly.WorkspaceSvg.prototype.maybeFireViewportChangeEvent = function() {
// TODO(#4203) Enable viewport events after ui events refactor.
// if (!Blockly.Events.isEnabled()) {
// return;
// }
// var scale = this.scale;
// var top = -this.scrollY;
// var left = -this.scrollX;
// if (scale == this.oldScale_ && top == this.oldTop_ && left == this.oldLeft_) {
// return;
// }
// this.oldScale_ = scale;
// this.oldTop_ = top;
// this.oldLeft_ = left;
// var event = new Blockly.Events.Ui(null, 'viewport', null,
// { scale: scale, top: top, left: left });
// event.workspaceId = this.id;
// Blockly.Events.fire(event);
if (!Blockly.Events.isEnabled()) {
return;
}
var scale = this.scale;
var top = -this.scrollY;
var left = -this.scrollX;
if (scale == this.oldScale_ &&
Math.abs(top - this.oldTop_) < 1 &&
Math.abs(left - this.oldLeft_) < 1) {
// Ignore sub-pixel changes in top and left. Due to #4192 there are a lot of
// negligible changes in viewport top/left.
return;
}
this.oldScale_ = scale;
this.oldTop_ = top;
this.oldLeft_ = left;
var event = new Blockly.Events.ViewportChange(top, left, scale, this.id);
Blockly.Events.fire(event);
};
/**
@@ -1449,7 +1450,7 @@ Blockly.WorkspaceSvg.prototype.pasteWorkspaceComment_ = function(xmlComment) {
Blockly.Events.enable();
}
if (Blockly.Events.isEnabled()) {
// TODO: Fire a Workspace Comment Create event.
Blockly.WorkspaceComment.fireCreateEvent(comment);
}
comment.select();
};
@@ -1813,7 +1814,10 @@ Blockly.WorkspaceSvg.prototype.markFocused = function() {
Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
// Blur whatever was focused since explicitly grabbing focus below does not
// work in Edge.
if (document.activeElement) {
// In IE, SVGs can't be blurred or focused. Check to make sure the current
// focus can be blurred before doing so.
// See https://github.com/google/blockly/issues/4440
if (document.activeElement && document.activeElement.blur) {
document.activeElement.blur();
}
try {
+5 -8
View File
@@ -343,9 +343,8 @@ Blockly.ZoomControls.prototype.createZoomInSvg_ = function(rnd) {
*/
Blockly.ZoomControls.prototype.zoom_ = function(amount, e) {
this.workspace_.markFocused();
var oldZoom = this.workspace_.scale;
this.workspace_.zoomCenter(amount);
this.fireZoomEvent_(oldZoom);
this.fireZoomEvent_();
Blockly.Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
e.preventDefault(); // Stop double-clicking from selecting text.
@@ -408,12 +407,11 @@ Blockly.ZoomControls.prototype.createZoomResetSvg_ = function(rnd) {
*/
Blockly.ZoomControls.prototype.resetZoom_ = function(e) {
this.workspace_.markFocused();
var oldZoom = this.workspace_.scale;
this.workspace_.setScale(this.workspace_.options.zoomOptions.startScale);
this.workspace_.beginCanvasTransition();
this.workspace_.scrollCenter();
setTimeout(this.workspace_.endCanvasTransition.bind(this.workspace_), 500);
this.fireZoomEvent_(oldZoom);
this.fireZoomEvent_();
Blockly.Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
e.preventDefault(); // Stop double-clicking from selecting text.
@@ -421,12 +419,11 @@ Blockly.ZoomControls.prototype.resetZoom_ = function(e) {
/**
* Fires a zoom control ui event.
* @param {number} oldZoom The workspace scale before zoom happened.
* @private
*/
Blockly.ZoomControls.prototype.fireZoomEvent_ = function(oldZoom) {
var uiEvent = new Blockly.Events.Ui(null, 'zoom', oldZoom, this.workspace_.scale);
uiEvent.workspaceId = this.workspace_.id;
Blockly.ZoomControls.prototype.fireZoomEvent_ = function() {
var uiEvent = new Blockly.Events.Click(
null, this.workspace_.id, 'zoom_controls');
Blockly.Events.fire(uiEvent);
};
+11 -11
View File
@@ -12,9 +12,9 @@
}(this, function(Blockly) {
'use strict';Blockly.Dart=new Blockly.Generator("Dart");Blockly.Dart.addReservedWords("assert,break,case,catch,class,const,continue,default,do,else,enum,extends,false,final,finally,for,if,in,is,new,null,rethrow,return,super,switch,this,throw,true,try,var,void,while,with,print,identityHashCode,identical,BidirectionalIterator,Comparable,double,Function,int,Invocation,Iterable,Iterator,List,Map,Match,num,Pattern,RegExp,Set,StackTrace,String,StringSink,Type,bool,DateTime,Deprecated,Duration,Expando,Null,Object,RuneIterator,Runes,Stopwatch,StringBuffer,Symbol,Uri,Comparator,AbstractClassInstantiationError,ArgumentError,AssertionError,CastError,ConcurrentModificationError,CyclicInitializationError,Error,Exception,FallThroughError,FormatException,IntegerDivisionByZeroException,NoSuchMethodError,NullThrownError,OutOfMemoryError,RangeError,StackOverflowError,StateError,TypeError,UnimplementedError,UnsupportedError");
Blockly.Dart.ORDER_ATOMIC=0;Blockly.Dart.ORDER_UNARY_POSTFIX=1;Blockly.Dart.ORDER_UNARY_PREFIX=2;Blockly.Dart.ORDER_MULTIPLICATIVE=3;Blockly.Dart.ORDER_ADDITIVE=4;Blockly.Dart.ORDER_SHIFT=5;Blockly.Dart.ORDER_BITWISE_AND=6;Blockly.Dart.ORDER_BITWISE_XOR=7;Blockly.Dart.ORDER_BITWISE_OR=8;Blockly.Dart.ORDER_RELATIONAL=9;Blockly.Dart.ORDER_EQUALITY=10;Blockly.Dart.ORDER_LOGICAL_AND=11;Blockly.Dart.ORDER_LOGICAL_OR=12;Blockly.Dart.ORDER_IF_NULL=13;Blockly.Dart.ORDER_CONDITIONAL=14;
Blockly.Dart.ORDER_CASCADE=15;Blockly.Dart.ORDER_ASSIGNMENT=16;Blockly.Dart.ORDER_NONE=99;
Blockly.Dart.ORDER_CASCADE=15;Blockly.Dart.ORDER_ASSIGNMENT=16;Blockly.Dart.ORDER_NONE=99;Blockly.Dart.isInitialized=!1;
Blockly.Dart.init=function(a){Blockly.Dart.definitions_=Object.create(null);Blockly.Dart.functionNames_=Object.create(null);Blockly.Dart.variableDB_?Blockly.Dart.variableDB_.reset():Blockly.Dart.variableDB_=new Blockly.Names(Blockly.Dart.RESERVED_WORDS_);Blockly.Dart.variableDB_.setVariableMap(a.getVariableMap());for(var b=[],c=Blockly.Variables.allDeveloperVariables(a),d=0;d<c.length;d++)b.push(Blockly.Dart.variableDB_.getName(c[d],Blockly.Names.DEVELOPER_VARIABLE_TYPE));a=Blockly.Variables.allUsedVarModels(a);
for(d=0;d<a.length;d++)b.push(Blockly.Dart.variableDB_.getName(a[d].getId(),Blockly.VARIABLE_CATEGORY_NAME));b.length&&(Blockly.Dart.definitions_.variables="var "+b.join(", ")+";")};
for(d=0;d<a.length;d++)b.push(Blockly.Dart.variableDB_.getName(a[d].getId(),Blockly.VARIABLE_CATEGORY_NAME));b.length&&(Blockly.Dart.definitions_.variables="var "+b.join(", ")+";");this.isInitialized=!0};
Blockly.Dart.finish=function(a){a&&(a=Blockly.Dart.prefixLines(a,Blockly.Dart.INDENT));a="main() {\n"+a+"}";var b=[],c=[],d;for(d in Blockly.Dart.definitions_){var e=Blockly.Dart.definitions_[d];e.match(/^import\s/)?b.push(e):c.push(e)}delete Blockly.Dart.definitions_;delete Blockly.Dart.functionNames_;Blockly.Dart.variableDB_.reset();return(b.join("\n")+"\n\n"+c.join("\n\n")).replace(/\n\n+/g,"\n\n").replace(/\n*$/,"\n\n\n")+a};Blockly.Dart.scrubNakedValue=function(a){return a+";\n"};
Blockly.Dart.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/\$/g,"\\$").replace(/'/g,"\\'");return"'"+a+"'"};Blockly.Dart.multiline_quote_=function(a){return a.split(/\n/g).map(Blockly.Dart.quote_).join(" + '\\n' + \n")};
Blockly.Dart.scrub_=function(a,b,c){var d="";if(!a.outputConnection||!a.outputConnection.targetConnection){var e=a.getCommentText();e&&(e=Blockly.utils.string.wrap(e,Blockly.Dart.COMMENT_WRAP-3),d=a.getProcedureDef?d+Blockly.Dart.prefixLines(e+"\n","/// "):d+Blockly.Dart.prefixLines(e+"\n","// "));for(var f=0;f<a.inputList.length;f++)a.inputList[f].type==Blockly.INPUT_VALUE&&(e=a.inputList[f].connection.targetBlock())&&(e=Blockly.Dart.allNestedComments(e))&&(d+=Blockly.Dart.prefixLines(e,"// "))}a=
@@ -88,25 +88,25 @@ Blockly.Dart.math_atan2=function(a){Blockly.Dart.definitions_.import_dart_math="
Blockly.Dart.procedures_defreturn=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c="";Blockly.Dart.STATEMENT_PREFIX&&(c+=Blockly.Dart.injectId(Blockly.Dart.STATEMENT_PREFIX,a));Blockly.Dart.STATEMENT_SUFFIX&&(c+=Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX,a));c&&(c=Blockly.Dart.prefixLines(c,Blockly.Dart.INDENT));var d="";Blockly.Dart.INFINITE_LOOP_TRAP&&(d=Blockly.Dart.prefixLines(Blockly.Dart.injectId(Blockly.Dart.INFINITE_LOOP_TRAP,a),
Blockly.Dart.INDENT));var e=Blockly.Dart.statementToCode(a,"STACK"),f=Blockly.Dart.valueToCode(a,"RETURN",Blockly.Dart.ORDER_NONE)||"",g="";e&&f&&(g=c);f&&(f=Blockly.Dart.INDENT+"return "+f+";\n");for(var k=f?"dynamic":"void",l=[],m=a.getVars(),h=0;h<m.length;h++)l[h]=Blockly.Dart.variableDB_.getName(m[h],Blockly.VARIABLE_CATEGORY_NAME);c=k+" "+b+"("+l.join(", ")+") {\n"+c+d+e+g+f+"}";c=Blockly.Dart.scrub_(a,c);Blockly.Dart.definitions_["%"+b]=c;return null};Blockly.Dart.procedures_defnoreturn=Blockly.Dart.procedures_defreturn;
Blockly.Dart.procedures_callreturn=function(a){for(var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c=[],d=a.getVars(),e=0;e<d.length;e++)c[e]=Blockly.Dart.valueToCode(a,"ARG"+e,Blockly.Dart.ORDER_NONE)||"null";return[b+"("+c.join(", ")+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.procedures_callnoreturn=function(a){return Blockly.Dart.procedures_callreturn(a)[0]+";\n"};
Blockly.Dart.procedures_ifreturn=function(a){var b="if ("+(Blockly.Dart.valueToCode(a,"CONDITION",Blockly.Dart.ORDER_NONE)||"false")+") {\n";Blockly.Dart.STATEMENT_SUFFIX&&(b+=Blockly.Dart.prefixLines(Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX,a),Blockly.Dart.INDENT));a.hasReturnValue_?(a=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_NONE)||"null",b+=Blockly.Dart.INDENT+"return "+a+";\n"):b+=Blockly.Dart.INDENT+"return;\n";return b+"}\n"};Blockly.Dart.texts={};Blockly.Dart.addReservedWords("Html,Math");Blockly.Dart.text=function(a){return[Blockly.Dart.quote_(a.getFieldValue("TEXT")),Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.text_multiline=function(a){return[Blockly.Dart.multiline_quote_(a.getFieldValue("TEXT")),Blockly.Dart.ORDER_ATOMIC]};
Blockly.Dart.procedures_ifreturn=function(a){var b="if ("+(Blockly.Dart.valueToCode(a,"CONDITION",Blockly.Dart.ORDER_NONE)||"false")+") {\n";Blockly.Dart.STATEMENT_SUFFIX&&(b+=Blockly.Dart.prefixLines(Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX,a),Blockly.Dart.INDENT));a.hasReturnValue_?(a=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_NONE)||"null",b+=Blockly.Dart.INDENT+"return "+a+";\n"):b+=Blockly.Dart.INDENT+"return;\n";return b+"}\n"};Blockly.Dart.texts={};Blockly.Dart.addReservedWords("Html,Math");Blockly.Dart.text=function(a){return[Blockly.Dart.quote_(a.getFieldValue("TEXT")),Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.text_multiline=function(a){a=Blockly.Dart.multiline_quote_(a.getFieldValue("TEXT"));var b=-1!=a.indexOf("+")?Blockly.Dart.ORDER_ADDITIVE:Blockly.Dart.ORDER_ATOMIC;return[a,b]};
Blockly.Dart.text_join=function(a){switch(a.itemCount_){case 0:return["''",Blockly.Dart.ORDER_ATOMIC];case 1:return[(Blockly.Dart.valueToCode(a,"ADD0",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".toString()",Blockly.Dart.ORDER_UNARY_POSTFIX];default:for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Dart.valueToCode(a,"ADD"+c,Blockly.Dart.ORDER_NONE)||"''";a="["+b.join(",")+"].join()";return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]}};
Blockly.Dart.text_append=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME);a=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''";return b+" = ["+b+", "+a+"].join();\n"};Blockly.Dart.text_length=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".length",Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_isEmpty=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".isEmpty",Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"indexOf":"lastIndexOf",c=Blockly.Dart.valueToCode(a,"FIND",Blockly.Dart.ORDER_NONE)||"''";b=(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.Dart.ORDER_ADDITIVE]:[b,Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''";switch(b){case "FIRST":return[c+"[0]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "FROM_START":return a=Blockly.Dart.getAdjusted(a,"AT"),[c+"["+a+"]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "LAST":case "FROM_END":return a=Blockly.Dart.getAdjusted(a,"AT",1),b=Blockly.Dart.provideFunction_("text_get_from_end",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+
"(String text, num x) {"," return text[text.length - x];","}"]),[b+"("+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX];case "RANDOM":return Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",b=Blockly.Dart.provideFunction_("text_random_letter",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text) {"," int x = new Math.Random().nextInt(text.length);"," return text[x];","}"]),[b+"("+c+")",Blockly.Dart.ORDER_UNARY_POSTFIX]}throw Error("Unhandled option (text_charAt).");
Blockly.Dart.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.Dart.valueToCode(a,"VALUE","FIRST"==b||"FROM_START"==b?Blockly.Dart.ORDER_UNARY_POSTFIX:Blockly.Dart.ORDER_NONE)||"''";switch(b){case "FIRST":return[c+"[0]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "FROM_START":return a=Blockly.Dart.getAdjusted(a,"AT"),[c+"["+a+"]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "LAST":case "FROM_END":return a=Blockly.Dart.getAdjusted(a,"AT",1),b=Blockly.Dart.provideFunction_("text_get_from_end",
["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text, num x) {"," return text[text.length - x];","}"]),[b+"("+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX];case "RANDOM":return Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",b=Blockly.Dart.provideFunction_("text_random_letter",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text) {"," int x = new Math.Random().nextInt(text.length);"," return text[x];","}"]),[b+"("+c+")",Blockly.Dart.ORDER_UNARY_POSTFIX]}throw Error("Unhandled option (text_charAt).");
};
Blockly.Dart.text_getSubstring=function(a){var b=Blockly.Dart.valueToCode(a,"STRING",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if("FIRST"==c&&"LAST"==d)a=b;else if(b.match(/^'?\w+'?$/)||"FROM_END"!=c&&"FROM_START"==d){switch(c){case "FROM_START":var e=Blockly.Dart.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.Dart.getAdjusted(a,"AT1",1,!1,Blockly.Dart.ORDER_ADDITIVE);e=b+".length - "+e;break;case "FIRST":e="0";break;default:throw Error("Unhandled option (text_getSubstring).");}switch(d){case "FROM_START":var f=
Blockly.Dart.getAdjusted(a,"AT2",1);break;case "FROM_END":f=Blockly.Dart.getAdjusted(a,"AT2",0,!1,Blockly.Dart.ORDER_ADDITIVE);f=b+".length - "+f;break;case "LAST":break;default:throw Error("Unhandled option (text_getSubstring).");}a="LAST"==d?b+".substring("+e+")":b+".substring("+e+", "+f+")"}else e=Blockly.Dart.getAdjusted(a,"AT1"),f=Blockly.Dart.getAdjusted(a,"AT2"),a=Blockly.Dart.provideFunction_("text_get_substring",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text, String where1, num at1, String where2, num at2) {",
" int getAt(String where, num at) {"," if (where == 'FROM_END') {"," at = text.length - 1 - at;"," } else if (where == 'FIRST') {"," at = 0;"," } else if (where == 'LAST') {"," at = text.length - 1;"," } else if (where != 'FROM_START') {"," throw 'Unhandled option (text_getSubstring).';"," }"," return at;"," }"," at1 = getAt(where1, at1);"," at2 = getAt(where2, at2) + 1;"," return text.substring(at1, at2);","}"])+"("+b+", '"+c+"', "+e+", '"+d+"', "+f+")";
return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_getSubstring=function(a){var b=a.getFieldValue("WHERE1"),c=a.getFieldValue("WHERE2"),d="FROM_END"!=b&&"FROM_START"==c,e=Blockly.Dart.valueToCode(a,"STRING",d?Blockly.Dart.ORDER_UNARY_POSTFIX:Blockly.Dart.ORDER_NONE)||"''";if("FIRST"==b&&"LAST"==c)return[e,Blockly.Dart.ORDER_NONE];if(e.match(/^'?\w+'?$/)||d){switch(b){case "FROM_START":d=Blockly.Dart.getAdjusted(a,"AT1");break;case "FROM_END":d=Blockly.Dart.getAdjusted(a,"AT1",1,!1,Blockly.Dart.ORDER_ADDITIVE);d=e+".length - "+d;
break;case "FIRST":d="0";break;default:throw Error("Unhandled option (text_getSubstring).");}switch(c){case "FROM_START":var f=Blockly.Dart.getAdjusted(a,"AT2",1);break;case "FROM_END":f=Blockly.Dart.getAdjusted(a,"AT2",0,!1,Blockly.Dart.ORDER_ADDITIVE);f=e+".length - "+f;break;case "LAST":break;default:throw Error("Unhandled option (text_getSubstring).");}a="LAST"==c?e+".substring("+d+")":e+".substring("+d+", "+f+")"}else d=Blockly.Dart.getAdjusted(a,"AT1"),f=Blockly.Dart.getAdjusted(a,"AT2"),a=
Blockly.Dart.provideFunction_("text_get_substring",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text, String where1, num at1, String where2, num at2) {"," int getAt(String where, num at) {"," if (where == 'FROM_END') {"," at = text.length - 1 - at;"," } else if (where == 'FIRST') {"," at = 0;"," } else if (where == 'LAST') {"," at = text.length - 1;"," } else if (where != 'FROM_START') {"," throw 'Unhandled option (text_getSubstring).';"," }"," return at;",
" }"," at1 = getAt(where1, at1);"," at2 = getAt(where2, at2) + 1;"," return text.substring(at1, at2);","}"])+"("+e+", '"+b+"', "+d+", '"+c+"', "+f+")";return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_changeCase=function(a){var b={UPPERCASE:".toUpperCase()",LOWERCASE:".toLowerCase()",TITLECASE:null}[a.getFieldValue("CASE")];a=Blockly.Dart.valueToCode(a,"TEXT",b?Blockly.Dart.ORDER_UNARY_POSTFIX:Blockly.Dart.ORDER_NONE)||"''";return[b?a+b:Blockly.Dart.provideFunction_("text_toTitleCase",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String str) {"," RegExp exp = new RegExp(r'\\b');"," List<String> list = str.split(exp);"," final title = new StringBuffer();"," for (String part in list) {",
" if (part.length > 0) {"," title.write(part[0].toUpperCase());"," if (part.length > 0) {"," title.write(part.substring(1).toLowerCase());"," }"," }"," }"," return title.toString();","}"])+"("+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_trim=function(a){var b={LEFT:".replaceFirst(new RegExp(r'^\\s+'), '')",RIGHT:".replaceFirst(new RegExp(r'\\s+$'), '')",BOTH:".trim()"}[a.getFieldValue("MODE")];return[(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+b,Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_print=function(a){return"print("+(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''")+");\n"};
Blockly.Dart.text_prompt_ext=function(a){Blockly.Dart.definitions_.import_dart_html="import 'dart:html' as Html;";var b="Html.window.prompt("+(a.getField("TEXT")?Blockly.Dart.quote_(a.getFieldValue("TEXT")):Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''")+", '')";"NUMBER"==a.getFieldValue("TYPE")&&(Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",b="Math.parseDouble("+b+")");return[b,Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_prompt=Blockly.Dart.text_prompt_ext;
Blockly.Dart.text_count=function(a){var b=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''";a=Blockly.Dart.valueToCode(a,"SUB",Blockly.Dart.ORDER_NONE)||"''";return[Blockly.Dart.provideFunction_("text_count",["int "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String haystack, String needle) {"," if (needle.length == 0) {"," return haystack.length + 1;"," }"," int index = 0;"," int count = 0;"," while (index != -1) {"," index = haystack.indexOf(needle, index);"," if (index != -1) {",
Blockly.Dart.text_count=function(a){var b=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''";a=Blockly.Dart.valueToCode(a,"SUB",Blockly.Dart.ORDER_NONE)||"''";return[Blockly.Dart.provideFunction_("text_count",["int "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String haystack, String needle) {"," if (needle.length == 0) {"," return haystack.length + 1;"," }"," int index = 0;"," int count = 0;"," while (index != -1) {"," index = haystack.indexOf(needle, index);"," if (index != -1) {",
" count++;"," index += needle.length;"," }"," }"," return count;","}"])+"("+b+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_replace=function(a){var b=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''",c=Blockly.Dart.valueToCode(a,"FROM",Blockly.Dart.ORDER_NONE)||"''";a=Blockly.Dart.valueToCode(a,"TO",Blockly.Dart.ORDER_NONE)||"''";return[b+".replaceAll("+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
Blockly.Dart.text_reverse=function(a){return["new String.fromCharCodes("+(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".runes.toList().reversed)",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.variables={};Blockly.Dart.variables_get=function(a){return[Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME),Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.variables_set=function(a){var b=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_ASSIGNMENT)||"0";return Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME)+" = "+b+";\n"};Blockly.Dart.variablesDynamic={};Blockly.Dart.variables_get_dynamic=Blockly.Dart.variables_get;Blockly.Dart.variables_set_dynamic=Blockly.Dart.variables_set;
Blockly.Dart.text_reverse=function(a){return["new String.fromCharCodes("+(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".runes.toList().reversed)",Blockly.Dart.ORDER_UNARY_PREFIX]};Blockly.Dart.variables={};Blockly.Dart.variables_get=function(a){return[Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME),Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.variables_set=function(a){var b=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_ASSIGNMENT)||"0";return Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME)+" = "+b+";\n"};Blockly.Dart.variablesDynamic={};Blockly.Dart.variables_get_dynamic=Blockly.Dart.variables_get;Blockly.Dart.variables_set_dynamic=Blockly.Dart.variables_set;
return Blockly.Dart;
}));
File diff suppressed because one or more lines are too long
@@ -362,6 +362,11 @@ StandardCategories.categoryMap['variables'] =
StandardCategories.categoryMap['variables'].hue = 330;
StandardCategories.categoryMap['variables'].custom = 'VARIABLE';
StandardCategories.categoryMap['typedvariables'] =
new ListElement(ListElement.TYPE_CATEGORY, 'TypedVariables');
StandardCategories.categoryMap['typedvariables'].custom = 'VARIABLE_DYNAMIC';
StandardCategories.categoryMap['typedvariables'].hue = 290;
// All standard block types in provided in Blockly core.
StandardCategories.coreBlockTypes = ["controls_if", "logic_compare",
"logic_operation", "logic_negate", "logic_boolean", "logic_null",
@@ -550,7 +550,8 @@ WorkspaceFactoryController.prototype.loadCategory = function() {
// Prompt user for the name of the standard category to load.
do {
var name = prompt('Enter the name of the category you would like to import '
+ '(Logic, Loops, Math, Text, Lists, Colour, Variables, or Functions)');
+ '(Logic, Loops, Math, Text, Lists, Colour, Variables, TypedVariables '
+ 'or Functions)');
if (!name) {
return; // Exit if cancelled.
}
@@ -345,8 +345,8 @@ WorkspaceFactoryInit.addWorkspaceFactoryEventListeners_ = function(controller) {
// Only enable "Edit Block" when a block is selected and it has a
// surrounding parent, meaning it is nested in another block (blocks that
// are not nested in parents cannot be shadow blocks).
if (e.type == Blockly.Events.BLOCK_MOVE || (e.type == Blockly.Events.UI &&
e.element == 'selected')) {
if (e.type == Blockly.Events.BLOCK_MOVE ||
e.type == Blockly.Event.SELECTED) {
var selected = Blockly.selected;
// Show shadow button if a block is selected. Show "Add Shadow" if
+1 -3
View File
@@ -51,9 +51,7 @@
<tr>
<td>
<textarea id="importExport"
style="width: 200px; height: 480px;"
onchange="textAreaChange();"
onkeyup="textAreaChange()"></textarea>
style="width: 200px; height: 480px;"></textarea>
</td>
<td>
<div id="blocklyDiv" style="width: 600px; height: 480px;"></div>
+1 -3
View File
@@ -63,9 +63,7 @@
<tr>
<td>
<textarea id="importExport"
style="width: 200px; height: 480px;"
onchange="textAreaChange();"
onkeyup="textAreaChange()"></textarea>
style="width: 200px; height: 480px;"></textarea>s
</td>
<td>
<div id="blocklyDiv" style="width: 600px; height: 480px;"></div>
+5 -565
View File
@@ -1,570 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Blockly Demo: Keyboard Navigation</title>
<script src="../../blockly_compressed.js"></script>
<script src="../../blocks_compressed.js"></script>
<script src="../../javascript_compressed.js"></script>
<script src="../../msg/js/en.js"></script>
<script src="line_cursor.js"></script>
<style>
body {
background-color: #fff;
font-family: sans-serif;
}
h1 {
font-weight: normal;
font-size: 140%;
}
.wrapper {
display: flex;
}
#keyboard_nav {
background-color: #ededed;
border: 1px solid black;
padding: 1em;
}
#keyboard_announce {
font-size: 1.5em;
font-weight: 500;
text-align: center;
}
#keyboard_mappings {
font-size: 1.3em;
font-weight: 400;
}
label {
margin-right: .5em;
min-width: 100px;
}
div[data-actionname] {
display: flex;
width: 100%;
}
select {
font-size: .8em;
}
</style>
</head>
<body>
<h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
<a href="../index.html">Demos</a> &gt; Keyboard Navigation</h1>
<p>Keyboard Navigation is our first step towards an accessible Blockly.<br />
For more information on how the default keyboard navigation works please see
the <a href="https://developers.google.com/blockly/guides/configure/web/keyboard-nav">documentation</a>.
<br />
<br />
<b>Pre Order Traversal</b><br />
Feel free to just play around in accessibility mode or hit the button below to see the demo.
The demo uses <a href="https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_(NLR)">preorder tree traversal</a>
as an alternative way to navigate the blocks,
connections, and fields on the workspace.<br /><br />
<b>Cursors</b><br />
The cursor controls how the user navigates the blocks, inputs, fields and connections on a workspace.
This demo shows three different cursors:<br />
<b>Default Cursor:</b> Explained in <a href="https://developers.google.com/blockly/guides/configure/web/keyboard-nav">documentation</a>.<br />
<b>Basic Cursor:</b> Uses pre order traversal to allow users to navigate
through everything using only the previous and next command.<br />
<b>Line Cursor:</b> We tried to make this cursor mimic a text editor. Navigating
up and down will take the cursor to the next and previous "line" of code.
Navigating in and out will move the cursor through all the fields and inputs
in that "line" of code.
</p>
<p>
<label for="accessibilityModeCheck">Enable Accessibility Mode:</label>
<input type="checkbox" onclick="toggleAccessibilityMode(this.checked)" id="accessibilityModeCheck">
<select id="cursorChanger" name="cursor" onchange="changeCursor(this.value)">
<option value="default">Default Cursor</option>
<option value="basic">Basic Cursor</option>
<option value="line">Line Cursor</option>
</select>
<button onclick="preOrderDemo()">Start Pre-order Demo</button>
<button onclick="stopDemo()">Stop Pre-order Demo</button>
<label for="displayKeyMappings">Open Key Mappings:</label>
<input type="checkbox" onclick="toggleDisplayKeyMappings(this.checked)" id="displayKeyMappings">
</p>
<div class="wrapper">
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
<div id="keyboard_nav" style="display:none">
<p id="keyboard_announce" aria-live="assertive">Set key mappings below</p>
<form id="keyboard_mappings"></form>
</div>
</div>
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
<category name="Logic" colour="%{BKY_LOGIC_HUE}">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_negate"></block>
<block type="logic_boolean"></block>
</category>
<category name="Loops" colour="%{BKY_LOOPS_HUE}">
<block type="controls_repeat_ext">
<value name="TIMES">
<block type="math_number">
<field name="NUM">10</field>
</block>
</value>
</block>
<block type="controls_whileUntil"></block>
</category>
<category name="Math" colour="%{BKY_MATH_HUE}">
<block type="math_number">
<field name="NUM">123</field>
</block>
<block type="math_arithmetic"></block>
<block type="math_single"></block>
</category>
<category name="Text" colour="%{BKY_TEXTS_HUE}">
<block type="text"></block>
<block type="text_length"></block>
<block type="text_print"></block>
</category>
</xml>
<xml xmlns="https://developers.google.com/blockly/xml" id="startBlocks" style="display: none">
<variables>
<variable id="~GNXm@Z(wclI]t3zTf.g">list</variable>
<variable id="8]s[S+Gy+%k7HoFup])m">item</variable>
</variables>
<block type="controls_if" x="37" y="162">
<value name="IF0">
<block type="logic_compare">
<field name="OP">EQ</field>
<value name="A">
<block type="math_arithmetic">
<field name="OP">ADD</field>
<value name="A">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="B">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
</value>
<value name="B">
<block type="math_single">
<field name="OP">ROOT</field>
<value name="NUM">
<shadow type="math_number">
<field name="NUM">9</field>
</shadow>
<block type="math_number">
<field name="NUM">123</field>
</block>
</value>
</block>
</value>
</block>
</value>
<statement name="DO0">
<block type="lists_setIndex">
<mutation at="true"></mutation>
<field name="MODE">SET</field>
<field name="WHERE">FROM_START</field>
<value name="LIST">
<block type="variables_get">
<field name="VAR" id="~GNXm@Z(wclI]t3zTf.g">list</field>
</block>
</value>
<next>
<block type="text_append">
<field name="VAR" id="8]s[S+Gy+%k7HoFup])m">item</field>
<value name="TEXT">
<shadow type="text">
<field name="TEXT"></field>
</shadow>
</value>
</block>
</next>
</block>
</statement>
<next>
<block type="controls_repeat_ext">
<value name="TIMES">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
</next>
</block>
</xml>
<script>
var demoWorkspace = Blockly.inject('blocklyDiv',
{media: '../../media/',
toolbox: document.getElementById('toolbox')});
Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
demoWorkspace);
var timeout;
var actions = [
Blockly.navigation.ACTION_PREVIOUS,
Blockly.navigation.ACTION_OUT,
Blockly.navigation.ACTION_NEXT,
Blockly.navigation.ACTION_IN,
Blockly.navigation.ACTION_INSERT,
Blockly.navigation.ACTION_MARK,
Blockly.navigation.ACTION_DISCONNECT,
Blockly.navigation.ACTION_TOOLBOX,
Blockly.navigation.ACTION_EXIT,
Blockly.navigation.ACTION_MOVE_WS_CURSOR_UP,
Blockly.navigation.ACTION_MOVE_WS_CURSOR_LEFT,
Blockly.navigation.ACTION_MOVE_WS_CURSOR_DOWN,
Blockly.navigation.ACTION_MOVE_WS_CURSOR_RIGHT
];
createKeyMappingList(actions);
/**
* Shows the next node in the tree traversal every second.
* @package
*/
function demo() {
var doNext = function() {
var markerManager = Blockly.getMainWorkspace().getMarkerManager();
var nextNode = markerManager.getCursor().next();
if (nextNode) {
timeout = setTimeout(doNext, 1000);
}
}
doNext();
}
/**
* Stop the running demo.
* @package
*/
function stopDemo() {
clearTimeout(timeout);
document.getElementById('accessibilityModeCheck').disabled = false;
};
/**
* Sets up accessibility mode and change the cursor to basic cursor so that
* the demo can successfully run.
* @package
*/
function preOrderDemo() {
changeCursor('basic');
document.getElementById('accessibilityModeCheck').disabled = true;
setTimeout(demo, 1000);
}
/**
* Turn on/off accessibility mode depending on the state.
* @param {boolean} state True to turn on accessibility mode, false otherwise.
* @package
*/
function toggleAccessibilityMode(state) {
if (state) {
Blockly.navigation.enableKeyboardAccessibility();
} else {
Blockly.navigation.disableKeyboardAccessibility();
}
}
/**
* Change the type of the cursor and set to the location of the old cursor.
* Changing the cursor changes how a user navigates the blocks on the workspace.
* @param {string} cursorType The type of the cursor.
* @package
*/
function changeCursor(cursorType) {
Blockly.navigation.enableKeyboardAccessibility();
document.getElementById('accessibilityModeCheck').checked = true;
document.getElementById('cursorChanger').value = cursorType;
var markerManager = Blockly.getMainWorkspace().getMarkerManager();
var oldCurNode = markerManager.getCursor().getCurNode();
if (cursorType === "basic") {
Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
markerManager.setCursor(new Blockly.BasicCursor());
} else if (cursorType === "line") {
Blockly.ASTNode.NAVIGATE_ALL_FIELDS = true;
markerManager.setCursor(new Blockly.LineCursor());
} else {
Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
markerManager.setCursor(new Blockly.Cursor());
}
if (oldCurNode) {
markerManager.getCursor().setCurNode(oldCurNode);
}
document.activeElement.blur();
}
// Start key mapping demo functions
/**
* Save the current key map in session storage.
* @package
*/
function saveKeyMap() {
var currentMap = Blockly.user.keyMap.getKeyMap();
if (sessionStorage) {
sessionStorage.setItem('keyMap', JSON.stringify(currentMap));
}
}
/**
* Set the key map to the map from session storage.
* @package
*/
function restoreKeyMap() {
var defaultMap = Blockly.user.keyMap.getKeyMap();
var stringifiedMap = sessionStorage.getItem('keyMap');
var restoredMap = {};
if (sessionStorage && stringifiedMap) {
var keyMap = JSON.parse(stringifiedMap);
var keys = Object.keys(keyMap);
for (var i = 0, key; key = keys[i]; i++) {
restoredMap[key] = Object.assign(new Blockly.Action, keyMap[key]);
}
Blockly.user.keyMap.setKeyMap(restoredMap);
}
}
/**
* Given the three dropdowns create the serialized key that will be stored
* in the key map.
* @param {Array.<Element>} selectDivs The three dropdown divs that display
* the key combination.
* @package
*/
function serializeKey(selectDivs) {
var modifiers = Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys);
var newModifiers = [];
var newKeyCode = '';
var keyValue = selectDivs[2].value;
// Get the new modifiers from the first two dropdowns.
for (var i = 0; i < 2; i++) {
var selectDiv = selectDivs[i];
var key = selectDiv.value;
if (key !== 'None') {
newModifiers.push(key);
}
}
// Get the key code from the last dropdown.
if (keyValue !== 'None') {
if (keyValue === 'Escape') {
newKeyCode = Blockly.utils.KeyCodes.ESC;
} else if (keyValue === 'Enter') {
newKeyCode = Blockly.utils.KeyCodes.ENTER;
} else {
newKeyCode = keyValue.toUpperCase().charCodeAt(0);
}
}
return Blockly.user.keyMap.createSerializedKey(newKeyCode, newModifiers);
}
/**
* Set all dropdowns for that action to none.
* We clear dropdowns when a user chooses the same key combination for a
* second action.
* @param {Blockly.Action} action The action that we want to clear the
* dropdowns for.
* @package
*/
function clearDropdown(action) {
var actionDiv = document.querySelectorAll('[data-actionname='+ action.name +']')[0];
var selectDivs = actionDiv.getElementsByTagName('select');
for (var i = 0, selectDiv; selectDiv = selectDivs[i]; i++) {
selectDiv.value = 'None';
}
}
/**
* Given the three dropdowns create a human readable string so the screen reader
* can read it out.
* @param {Array.<Element>} selectDivs The three dropdown divs that display
* the key combination.
* @package
*/
function getReadableKey(selectDivs) {
var readableKey = '';
for (var i = 0, selectDiv; selectDiv = selectDivs[i]; i++) {
if (selectDiv.value !== 'None') {
readableKey += selectDiv.value + ' ';
}
}
return readableKey;
}
/**
* Update the key in the key map when the user selects a new value in one of the
* dropdowns.
* @param {Event} e The event dispatched from changing a dropdown.
* @package
*/
function updateKey(e) {
var keyboardAnnouncerText = '';
var actionDiv = e.srcElement.parentElement;
var action = actionDiv.action;
var selectDivs = actionDiv.getElementsByTagName('select');
var key = serializeKey(selectDivs);
var oldAction = Blockly.user.keyMap.getActionByKeyCode(key);
if (oldAction) {
keyboardAnnouncerText += oldAction.name + ' action key was overwritten. \n';
clearDropdown(oldAction);
}
keyboardAnnouncerText += action.name + ' key was set to ' + getReadableKey(selectDivs);
document.getElementById('keyboard_announce').innerText = keyboardAnnouncerText;
Blockly.user.keyMap.setActionForKey(key, action);
saveKeyMap();
document.activeElement.blur();
}
/**
* Set the key to be the correct value from the key map.
* @param {string} actionKey The serialized key for a given action.
* @param {Element} keyDropdown The dropdown that displays the primary key.
* @package
*/
function setKeyDropdown(actionKey, keyDropdown) {
// Strip off any modifier to just get the key code.
var keyCode = actionKey.match(/\d+/)[0];
var keyValue = String.fromCharCode(keyCode);
if (parseInt(keyCode) === Blockly.utils.KeyCodes.ESC) {
keyValue = 'Escape';
} else if (parseInt(keyCode) === Blockly.utils.KeyCodes.ENTER) {
keyValue = 'Enter';
}
keyDropdown.value = keyValue;
}
/**
* Set the modifiers to be the correct value from the key map.
* @param {string} actionKey The key code holding the modifiers and key.
* @param {Array.<Element>} modifierDropdowns A list of dropdowns for
* the modifier values.
* @package
*/
function setModifiers(actionKey, modifierDropdowns) {
var modifiers = Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys);
for (var i = 0; i < 2; i++) {
var modifierDropdown = modifierDropdowns[i];
for (var j = 0, modifier; modifier = modifiers[j]; j++) {
if (actionKey.indexOf(modifier) > -1) {
modifierDropdown.value = modifier;
actionKey = actionKey.replace(modifier, '');
break;
}
}
}
}
/**
* Set the dropdowns to display the correct combination of modifiers and
* keys for the action key.
* @param {Blockly.Action} action The Blockly action.
* @param {Element} actionDiv The div holding the dropdowns and label for the
* given action.
* @param {string} actionKey The key corresponding to the given action.
* @package
*/
function setDropdowns(action, actionDiv, actionKey) {
var selectDivs = actionDiv.getElementsByTagName('select');
if (actionKey) {
setModifiers(actionKey, selectDivs);
setKeyDropdown(actionKey, selectDivs[selectDivs.length - 1]);
} else {
clearDropdown(action);
}
}
/**
* Create a dropdown with the given list of possible keys.
* @param {Blockly.Action} action The Blockly action.
* @param {Element} actionDiv The div holding the dropdowns and labels for
* a given action.
* @param {Array.<string>} keys The list of keys to add to the dropdown.
* @package
*/
function createDropdown(action, actionDiv, keys) {
var select = document.createElement('select');
select.addEventListener('change', updateKey);
select.setAttribute('aria-labelledby', action.name + '_label');
for (var i = 0, key; key = keys[i]; i++) {
select.options.add(new Option(key, key));
}
actionDiv.appendChild(select);
}
/**
* Create two dropdowns that display possible modifiers and a single dropdown
* displaying a list of keys.
* @param {Blockly.Action} action The Blockly action.
* @param {string} actionKey The key corresponding to the given action.
* @param {Element} actionDiv The div holding the dropdowns and label for the
* given action.
* @package
*/
function createDropdowns(action, actionKey, actionDiv) {
var modifiers = ['None'].concat(Blockly.utils.object.values(Blockly.user.keyMap.modifierKeys));
var keys = ['None', 'Enter', 'Escape'].concat("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split(''));
createDropdown(action, actionDiv, modifiers);
createDropdown(action, actionDiv, modifiers);
createDropdown(action, actionDiv, keys);
setDropdowns(action, actionDiv, actionKey);
}
/**
* For each action create a row of 3 dropdowns and an action label. Update
* the dropdowns to reflect the value in the key map.
* @param {Array.<Blockly.Action>} actions List of blockly actions.
* @package
*/
function createKeyMappingList(actions) {
// Update the key map to reflect the key map saved in session storage.
restoreKeyMap();
var keyMapDiv = document.getElementById('keyboard_mappings');
for (var i = 0, action; action = actions[i]; i++) {
var actionDiv = document.createElement('div');
actionDiv.setAttribute('data-actionname', action.name);
actionDiv.action = action;
var labelDiv = document.createElement('label');
labelDiv.innerText = action.name;
labelDiv.setAttribute('id', action.name + '_label');
actionDiv.appendChild(labelDiv);
keyMapDiv.appendChild(actionDiv);
var actionKey = Blockly.user.keyMap.getKeyByAction(action);
createDropdowns(action, actionKey, actionDiv);
}
}
/**
* Hide/show the key map panel.
* @param {boolean} state The state of the checkbox. True if checked, false
* otherwise.
* @package
*/
function toggleDisplayKeyMappings(state) {
if (state) {
document.getElementById('keyboard_nav').style.display = 'block';
} else {
document.getElementById('keyboard_nav').style.display = 'none';
}
}
// End key mapping demo functions
</script>
<body>
<p>This demo is in the process of moving! When it is available, you will
be able to find it on our <a href="https://google.github.io/blockly-samples/">samples page</a>
by searching for keyboard navigation.</p>
</body>
</body>
</html>
-169
View File
@@ -1,169 +0,0 @@
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview The class representing a line cursor.
* A line cursor traverses the blocks as if they were
* lines of code in a text editor.
* Previous and next go up and down lines. In and out go
* through the elements in a line.
* @author aschmiedt@google.com (Abby Schmiedt)
*/
'use strict';
/**
* Class for a line cursor.
* This will allow the user to get to all nodes in the AST by hitting next or
* previous.
* @constructor
* @extends {Blockly.BasicCursor}
*/
Blockly.LineCursor = function() {
Blockly.LineCursor.superClass_.constructor.call(this);
};
Blockly.utils.object.inherits(Blockly.LineCursor, Blockly.BasicCursor);
/**
* Find the next node in the pre order traversal.
* @return {Blockly.ASTNode} The next node, or null if the current node is
* not set or there is no next value.
* @override
*/
Blockly.LineCursor.prototype.next = function() {
var curNode = this.getCurNode();
if (!curNode) {
return null;
}
var newNode = this.getNextNode_(curNode, this.validLineNode_);
// Skip the input or next value if there is a connected block.
if (newNode && (newNode.getType() == Blockly.ASTNode.types.INPUT ||
newNode.getType() == Blockly.ASTNode.types.NEXT) &&
newNode.getLocation().targetBlock()) {
newNode = this.getNextNode_(newNode, this.validLineNode_);
}
if (newNode) {
this.setCurNode(newNode);
}
return newNode;
};
/**
* For a basic cursor we only have the ability to go next and previous, so
* in will also allow the user to get to the next node in the pre order traversal.
* @return {Blockly.ASTNode} The next node, or null if the current node is
* not set or there is no next value.
* @override
*/
Blockly.LineCursor.prototype.in = function() {
var curNode = this.getCurNode();
if (!curNode) {
return null;
}
var newNode = this.getNextNode_(curNode, this.validInLineNode_);
if (newNode) {
this.setCurNode(newNode);
}
return newNode;
};
/**
* Find 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.
* @override
*/
Blockly.LineCursor.prototype.prev = function() {
var curNode = this.getCurNode();
if (!curNode) {
return null;
}
var newNode = this.getPreviousNode_(curNode, this.validLineNode_);
if (newNode && (newNode.getType() == Blockly.ASTNode.types.INPUT ||
newNode.getType() == Blockly.ASTNode.types.NEXT) &&
newNode.getLocation().targetBlock()) {
newNode = this.getPreviousNode_(newNode, this.validLineNode_);
}
if (newNode) {
this.setCurNode(newNode);
}
return newNode;
};
/**
* 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.
* @override
*/
Blockly.LineCursor.prototype.out = function() {
var curNode = this.getCurNode();
if (!curNode) {
return null;
}
var newNode = this.getPreviousNode_(curNode, this.validInLineNode_);
if (newNode) {
this.setCurNode(newNode);
}
return newNode;
};
/**
* Meant to traverse by lines of code. This is blocks, statement inputs and
* next connections.
* @param {Blockly.ASTNode} node The AST node to check whether it is valid.
* @return {boolean} True if the node should be visited, false otherwise.
* @private
*/
Blockly.LineCursor.prototype.validLineNode_ = function(node) {
if (!node) {
return false;
}
var isValid = false;
var location = node.getLocation();
var type = node && node.getType();
if (type == Blockly.ASTNode.types.BLOCK) {
if (location.outputConnection === null) {
isValid = true;
}
} else if (type == Blockly.ASTNode.types.INPUT &&
location.type == Blockly.NEXT_STATEMENT) {
isValid = true;
} else if (type == Blockly.ASTNode.types.NEXT) {
isValid = true;
}
return isValid;
};
/**
* Meant to traverse within a block. These are fields and input values.
* @param {Blockly.ASTNode} node The AST node to check whether it is valid.
* @return {boolean} True if the node should be visited, false otherwise.
* @private
*/
Blockly.LineCursor.prototype.validInLineNode_ = function(node) {
if (!node) {
return false;
}
var isValid = false;
var location = node.getLocation();
var type = node && node.getType();
if (type == Blockly.ASTNode.types.FIELD) {
isValid = true;
} else if (type == Blockly.ASTNode.types.INPUT &&
location.type == Blockly.INPUT_VALUE) {
isValid = true;
}
return isValid;
};
+3 -2
View File
@@ -133,10 +133,11 @@ Minimap.mousemove = function(e) {
/**
* Run non-UI events from the main workspace on the minimap.
* @param {!Event} event Event that triggered in the main workspace.
* @param {!Blockly.Events.Abstract} event Event that triggered in the main
* workspace.
*/
Minimap.mirrorEvent = function(event) {
if (event.type == Blockly.Events.UI) {
if (event.isUiEvent) {
return; // Don't mirror UI events.
}
// Convert event to JSON. This could then be transmitted across the net.
+11 -5
View File
@@ -50,7 +50,7 @@ Blockly.Dart.addReservedWords(
/**
* Order of operation ENUMs.
* https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operator_table
* https://dart.dev/guides/language/language-tour#operators
*/
Blockly.Dart.ORDER_ATOMIC = 0; // 0 "" ...
Blockly.Dart.ORDER_UNARY_POSTFIX = 1; // expr++ expr-- () [] . ?.
@@ -71,6 +71,12 @@ Blockly.Dart.ORDER_CASCADE = 15; // ..
Blockly.Dart.ORDER_ASSIGNMENT = 16; // = *= /= ~/= %= += -= <<= >>= &= ^= |=
Blockly.Dart.ORDER_NONE = 99; // (...)
/**
* Whether the init method has been called.
* @type {?boolean}
*/
Blockly.Dart.isInitialized = false;
/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
@@ -111,6 +117,7 @@ Blockly.Dart.init = function(workspace) {
Blockly.Dart.definitions_['variables'] =
'var ' + defvars.join(', ') + ';';
}
this.isInitialized = true;
};
/**
@@ -158,7 +165,7 @@ Blockly.Dart.scrubNakedValue = function(line) {
* Encode a string as a properly escaped Dart string, complete with quotes.
* @param {string} string Text to encode.
* @return {string} Dart string.
* @private
* @protected
*/
Blockly.Dart.quote_ = function(string) {
// Can't use goog.string.quote since $ must also be escaped.
@@ -174,7 +181,7 @@ Blockly.Dart.quote_ = function(string) {
* quotes.
* @param {string} string Text to encode.
* @return {string} Dart string.
* @private
* @protected
*/
Blockly.Dart.multiline_quote_ = function (string) {
var lines = string.split(/\n/g).map(Blockly.Dart.quote_);
@@ -183,7 +190,6 @@ Blockly.Dart.multiline_quote_ = function (string) {
return lines.join(' + \'\\n\' + \n');
};
/**
* Common tasks for generating Dart from blocks.
* Handles comments for the specified block and any connected value blocks.
@@ -192,7 +198,7 @@ Blockly.Dart.multiline_quote_ = function (string) {
* @param {string} code The Dart code created for this block.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string} Dart code with comments and subsequent blocks added.
* @private
* @protected
*/
Blockly.Dart.scrub_ = function(block, code, opt_thisOnly) {
var commentCode = '';
+14 -10
View File
@@ -26,7 +26,9 @@ Blockly.Dart['text'] = function(block) {
Blockly.Dart['text_multiline'] = function(block) {
// Text value.
var code = Blockly.Dart.multiline_quote_(block.getFieldValue('TEXT'));
return [code, Blockly.Dart.ORDER_ATOMIC];
var order = code.indexOf('+') != -1 ? Blockly.Dart.ORDER_ADDITIVE :
Blockly.Dart.ORDER_ATOMIC;
return [code, order];
};
Blockly.Dart['text_join'] = function(block) {
@@ -92,8 +94,9 @@ Blockly.Dart['text_charAt'] = function(block) {
// Get letter at index.
// Note: Until January 2013 this block did not have the WHERE input.
var where = block.getFieldValue('WHERE') || 'FROM_START';
var text = Blockly.Dart.valueToCode(block, 'VALUE',
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
var textOrder = (where == 'FIRST' || where == 'FROM_START') ?
Blockly.Dart.ORDER_UNARY_POSTFIX : Blockly.Dart.ORDER_NONE;
var text = Blockly.Dart.valueToCode(block, 'VALUE', textOrder) || '\'\'';
switch (where) {
case 'FIRST':
var code = text + '[0]';
@@ -133,14 +136,16 @@ Blockly.Dart['text_charAt'] = function(block) {
Blockly.Dart['text_getSubstring'] = function(block) {
// Get substring.
var text = Blockly.Dart.valueToCode(block, 'STRING',
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
var requiresLengthCall = (where1 != 'FROM_END' && where2 == 'FROM_START');
var textOrder = requiresLengthCall ? Blockly.Dart.ORDER_UNARY_POSTFIX :
Blockly.Dart.ORDER_NONE;
var text = Blockly.Dart.valueToCode(block, 'STRING', textOrder) || '\'\'';
if (where1 == 'FIRST' && where2 == 'LAST') {
var code = text;
} else if (text.match(/^'?\w+'?$/) ||
(where1 != 'FROM_END' && where2 == 'FROM_START')) {
return [code, Blockly.Dart.ORDER_NONE];
} else if (text.match(/^'?\w+'?$/) || requiresLengthCall) {
// If the text is a variable or literal or doesn't require a call for
// length, don't generate a helper function.
switch (where1) {
@@ -290,7 +295,7 @@ Blockly.Dart['text_prompt'] = Blockly.Dart['text_prompt_ext'];
Blockly.Dart['text_count'] = function(block) {
var text = Blockly.Dart.valueToCode(block, 'TEXT',
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
Blockly.Dart.ORDER_NONE) || '\'\'';
var sub = Blockly.Dart.valueToCode(block, 'SUB',
Blockly.Dart.ORDER_NONE) || '\'\'';
// Substring count is not a native Dart function. Define one.
@@ -334,6 +339,5 @@ Blockly.Dart['text_reverse'] = function(block) {
var text = Blockly.Dart.valueToCode(block, 'TEXT',
Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
var code = 'new String.fromCharCodes(' + text + '.runes.toList().reversed)';
// XXX What should the operator precedence be for a `new`?
return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
return [code, Blockly.Dart.ORDER_UNARY_PREFIX];
};
+10 -3
View File
@@ -113,6 +113,12 @@ Blockly.JavaScript.ORDER_OVERRIDES = [
[Blockly.JavaScript.ORDER_LOGICAL_OR, Blockly.JavaScript.ORDER_LOGICAL_OR]
];
/**
* Whether the init method has been called.
* @type {?boolean}
*/
Blockly.JavaScript.isInitialized = false;
/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
@@ -153,6 +159,7 @@ Blockly.JavaScript.init = function(workspace) {
Blockly.JavaScript.definitions_['variables'] =
'var ' + defvars.join(', ') + ';';
}
this.isInitialized = true;
};
/**
@@ -188,7 +195,7 @@ Blockly.JavaScript.scrubNakedValue = function(line) {
* quotes.
* @param {string} string Text to encode.
* @return {string} JavaScript string.
* @private
* @protected
*/
Blockly.JavaScript.quote_ = function(string) {
// Can't use goog.string.quote since Google's style guide recommends
@@ -204,7 +211,7 @@ Blockly.JavaScript.quote_ = function(string) {
* with quotes.
* @param {string} string Text to encode.
* @return {string} JavaScript string.
* @private
* @protected
*/
Blockly.JavaScript.multiline_quote_ = function(string) {
// Can't use goog.string.quote since Google's style guide recommends
@@ -221,7 +228,7 @@ Blockly.JavaScript.multiline_quote_ = function(string) {
* @param {string} code The JavaScript code created for this block.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string} JavaScript code with comments and subsequent blocks added.
* @private
* @protected
*/
Blockly.JavaScript.scrub_ = function(block, code, opt_thisOnly) {
var commentCode = '';
+6 -6
View File
@@ -36,11 +36,11 @@ Blockly.JavaScript['colour_random'] = function(block) {
Blockly.JavaScript['colour_rgb'] = function(block) {
// Compose a colour from RGB components expressed as percentages.
var red = Blockly.JavaScript.valueToCode(block, 'RED',
Blockly.JavaScript.ORDER_COMMA) || 0;
Blockly.JavaScript.ORDER_NONE) || 0;
var green = Blockly.JavaScript.valueToCode(block, 'GREEN',
Blockly.JavaScript.ORDER_COMMA) || 0;
Blockly.JavaScript.ORDER_NONE) || 0;
var blue = Blockly.JavaScript.valueToCode(block, 'BLUE',
Blockly.JavaScript.ORDER_COMMA) || 0;
Blockly.JavaScript.ORDER_NONE) || 0;
var functionName = Blockly.JavaScript.provideFunction_(
'colourRgb',
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
@@ -60,11 +60,11 @@ Blockly.JavaScript['colour_rgb'] = function(block) {
Blockly.JavaScript['colour_blend'] = function(block) {
// Blend two colours together.
var c1 = Blockly.JavaScript.valueToCode(block, 'COLOUR1',
Blockly.JavaScript.ORDER_COMMA) || '\'#000000\'';
Blockly.JavaScript.ORDER_NONE) || '\'#000000\'';
var c2 = Blockly.JavaScript.valueToCode(block, 'COLOUR2',
Blockly.JavaScript.ORDER_COMMA) || '\'#000000\'';
Blockly.JavaScript.ORDER_NONE) || '\'#000000\'';
var ratio = Blockly.JavaScript.valueToCode(block, 'RATIO',
Blockly.JavaScript.ORDER_COMMA) || 0.5;
Blockly.JavaScript.ORDER_NONE) || 0.5;
var functionName = Blockly.JavaScript.provideFunction_(
'colourBlend',
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
+4 -4
View File
@@ -25,7 +25,7 @@ Blockly.JavaScript['lists_create_with'] = function(block) {
var elements = new Array(block.itemCount_);
for (var i = 0; i < block.itemCount_; i++) {
elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
Blockly.JavaScript.ORDER_COMMA) || 'null';
Blockly.JavaScript.ORDER_NONE) || 'null';
}
var code = '[' + elements.join(', ') + ']';
return [code, Blockly.JavaScript.ORDER_ATOMIC];
@@ -44,9 +44,9 @@ Blockly.JavaScript['lists_repeat'] = function(block) {
' return array;',
'}']);
var element = Blockly.JavaScript.valueToCode(block, 'ITEM',
Blockly.JavaScript.ORDER_COMMA) || 'null';
Blockly.JavaScript.ORDER_NONE) || 'null';
var repeatCount = Blockly.JavaScript.valueToCode(block, 'NUM',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var code = functionName + '(' + element + ', ' + repeatCount + ')';
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
};
@@ -85,7 +85,7 @@ Blockly.JavaScript['lists_getIndex'] = function(block) {
// Note: Until January 2013 this block did not have MODE or WHERE inputs.
var mode = block.getFieldValue('MODE') || 'GET';
var where = block.getFieldValue('WHERE') || 'FROM_START';
var listOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_COMMA :
var listOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_NONE :
Blockly.JavaScript.ORDER_MEMBER;
var list = Blockly.JavaScript.valueToCode(block, 'VALUE', listOrder) || '[]';
+10 -10
View File
@@ -30,7 +30,7 @@ Blockly.JavaScript['math_arithmetic'] = function(block) {
'MINUS': [' - ', Blockly.JavaScript.ORDER_SUBTRACTION],
'MULTIPLY': [' * ', Blockly.JavaScript.ORDER_MULTIPLICATION],
'DIVIDE': [' / ', Blockly.JavaScript.ORDER_DIVISION],
'POWER': [null, Blockly.JavaScript.ORDER_COMMA] // Handle power separately.
'POWER': [null, Blockly.JavaScript.ORDER_NONE] // Handle power separately.
};
var tuple = OPERATORS[block.getFieldValue('OP')];
var operator = tuple[0];
@@ -230,12 +230,12 @@ Blockly.JavaScript['math_on_list'] = function(block) {
break;
case 'MIN':
list = Blockly.JavaScript.valueToCode(block, 'LIST',
Blockly.JavaScript.ORDER_COMMA) || '[]';
Blockly.JavaScript.ORDER_NONE) || '[]';
code = 'Math.min.apply(null, ' + list + ')';
break;
case 'MAX':
list = Blockly.JavaScript.valueToCode(block, 'LIST',
Blockly.JavaScript.ORDER_COMMA) || '[]';
Blockly.JavaScript.ORDER_NONE) || '[]';
code = 'Math.max.apply(null, ' + list + ')';
break;
case 'AVERAGE':
@@ -361,11 +361,11 @@ Blockly.JavaScript['math_modulo'] = function(block) {
Blockly.JavaScript['math_constrain'] = function(block) {
// Constrain a number between two limits.
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var argument1 = Blockly.JavaScript.valueToCode(block, 'LOW',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var argument2 = Blockly.JavaScript.valueToCode(block, 'HIGH',
Blockly.JavaScript.ORDER_COMMA) || 'Infinity';
Blockly.JavaScript.ORDER_NONE) || 'Infinity';
var code = 'Math.min(Math.max(' + argument0 + ', ' + argument1 + '), ' +
argument2 + ')';
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
@@ -374,9 +374,9 @@ Blockly.JavaScript['math_constrain'] = function(block) {
Blockly.JavaScript['math_random_int'] = function(block) {
// Random integer between [X] and [Y].
var argument0 = Blockly.JavaScript.valueToCode(block, 'FROM',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var argument1 = Blockly.JavaScript.valueToCode(block, 'TO',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var functionName = Blockly.JavaScript.provideFunction_(
'mathRandomInt',
['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
@@ -401,9 +401,9 @@ Blockly.JavaScript['math_random_float'] = function(block) {
Blockly.JavaScript['math_atan2'] = function(block) {
// Arctangent of point (X, Y) in degrees from -180 to 180.
var argument0 = Blockly.JavaScript.valueToCode(block, 'X',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
var argument1 = Blockly.JavaScript.valueToCode(block, 'Y',
Blockly.JavaScript.ORDER_COMMA) || '0';
Blockly.JavaScript.ORDER_NONE) || '0';
return ['Math.atan2(' + argument1 + ', ' + argument0 + ') / Math.PI * 180',
Blockly.JavaScript.ORDER_DIVISION];
};
+1 -1
View File
@@ -75,7 +75,7 @@ Blockly.JavaScript['procedures_callreturn'] = function(block) {
var variables = block.getVars();
for (var i = 0; i < variables.length; i++) {
args[i] = Blockly.JavaScript.valueToCode(block, 'ARG' + i,
Blockly.JavaScript.ORDER_COMMA) || 'null';
Blockly.JavaScript.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ')';
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
+29 -24
View File
@@ -24,24 +24,24 @@ Blockly.JavaScript['text'] = function(block) {
Blockly.JavaScript['text_multiline'] = function(block) {
// Text value.
var code = Blockly.JavaScript.multiline_quote_(block.getFieldValue('TEXT'));
if (code.indexOf('\n') != -1) {
code = '(' + code + ')'
}
return [code, Blockly.JavaScript.ORDER_ATOMIC];
var order = code.indexOf('+') != -1 ? Blockly.JavaScript.ORDER_ADDITION :
Blockly.JavaScript.ORDER_ATOMIC;
return [code, order];
};
/**
* Enclose the provided value in 'String(...)' function.
* Leave string literals alone.
* @param {string} value Code evaluating to a value.
* @return {string} Code evaluating to a string.
* @return {[string, number]} Array containing code evaluating to a string and
* the order of the returned code.
* @private
*/
Blockly.JavaScript.text.forceString_ = function(value) {
if (Blockly.JavaScript.text.forceString_.strRegExp.test(value)) {
return value;
return [value, Blockly.JavaScript.ORDER_ATOMIC];
}
return 'String(' + value + ')';
return ['String(' + value + ')', Blockly.JavaScript.ORDER_FUNCTION_CALL];
};
/**
@@ -57,21 +57,21 @@ Blockly.JavaScript['text_join'] = function(block) {
case 1:
var element = Blockly.JavaScript.valueToCode(block, 'ADD0',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var code = Blockly.JavaScript.text.forceString_(element);
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
var codeAndOrder = Blockly.JavaScript.text.forceString_(element);
return codeAndOrder;
case 2:
var element0 = Blockly.JavaScript.valueToCode(block, 'ADD0',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var element1 = Blockly.JavaScript.valueToCode(block, 'ADD1',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var code = Blockly.JavaScript.text.forceString_(element0) + ' + ' +
Blockly.JavaScript.text.forceString_(element1);
var code = Blockly.JavaScript.text.forceString_(element0)[0] +
' + ' + Blockly.JavaScript.text.forceString_(element1)[0];
return [code, Blockly.JavaScript.ORDER_ADDITION];
default:
var elements = new Array(block.itemCount_);
for (var i = 0; i < block.itemCount_; i++) {
elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
Blockly.JavaScript.ORDER_COMMA) || '\'\'';
Blockly.JavaScript.ORDER_NONE) || '\'\'';
}
var code = '[' + elements.join(',') + '].join(\'\')';
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
@@ -84,13 +84,15 @@ Blockly.JavaScript['text_append'] = function(block) {
block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME);
var value = Blockly.JavaScript.valueToCode(block, 'TEXT',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
return varName + ' += ' + Blockly.JavaScript.text.forceString_(value) + ';\n';
var code = varName + ' += ' +
Blockly.JavaScript.text.forceString_(value)[0] + ';\n';
return code;
};
Blockly.JavaScript['text_length'] = function(block) {
// String or array length.
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
return [text + '.length', Blockly.JavaScript.ORDER_MEMBER];
};
@@ -177,15 +179,18 @@ Blockly.JavaScript.text.getIndex_ = function(stringName, where, opt_at) {
Blockly.JavaScript['text_getSubstring'] = function(block) {
// Get substring.
var text = Blockly.JavaScript.valueToCode(block, 'STRING',
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
var requiresLengthCall = (where1 != 'FROM_END' && where1 != 'LAST' &&
where2 != 'FROM_END' && where2 != 'LAST');
var textOrder = requiresLengthCall ? Blockly.JavaScript.ORDER_MEMBER :
Blockly.JavaScript.ORDER_NONE;
var text = Blockly.JavaScript.valueToCode(block, 'STRING',
textOrder) || '\'\'';
if (where1 == 'FIRST' && where2 == 'LAST') {
var code = text;
} else if (text.match(/^'?\w+'?$/) ||
(where1 != 'FROM_END' && where1 != 'LAST' &&
where2 != 'FROM_END' && where2 != 'LAST')) {
return [code, Blockly.JavaScript.ORDER_NONE];
} else if (text.match(/^'?\w+'?$/) || requiresLengthCall) {
// If the text is a variable or literal or doesn't require a call for
// length, don't generate a helper function.
switch (where1) {
@@ -320,7 +325,7 @@ Blockly.JavaScript['text_prompt'] = Blockly.JavaScript['text_prompt_ext'];
Blockly.JavaScript['text_count'] = function(block) {
var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var sub = Blockly.JavaScript.valueToCode(block, 'SUB',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var functionName = Blockly.JavaScript.provideFunction_(
@@ -334,12 +339,12 @@ Blockly.JavaScript['text_count'] = function(block) {
' }',
'}']);
var code = functionName + '(' + text + ', ' + sub + ')';
return [code, Blockly.JavaScript.ORDER_SUBTRACTION];
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
};
Blockly.JavaScript['text_replace'] = function(block) {
var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var from = Blockly.JavaScript.valueToCode(block, 'FROM',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var to = Blockly.JavaScript.valueToCode(block, 'TO',
@@ -356,12 +361,12 @@ Blockly.JavaScript['text_replace'] = function(block) {
' return haystack.replace(new RegExp(needle, \'g\'), replacement);',
'}']);
var code = functionName + '(' + text + ', ' + from + ', ' + to + ')';
return [code, Blockly.JavaScript.ORDER_MEMBER];
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
};
Blockly.JavaScript['text_reverse'] = function(block) {
var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
var code = text + '.split(\'\').reverse().join(\'\')';
return [code, Blockly.JavaScript.ORDER_MEMBER];
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
};
+10 -3
View File
@@ -79,6 +79,12 @@ Blockly.Lua.ORDER_NONE = 99;
* option used for lists and text.
*/
/**
* Whether the init method has been called.
* @type {?boolean}
*/
Blockly.Lua.isInitialized = false;
/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
@@ -97,6 +103,7 @@ Blockly.Lua.init = function(workspace) {
Blockly.Lua.variableDB_.reset();
}
Blockly.Lua.variableDB_.setVariableMap(workspace.getVariableMap());
this.isInitialized = true;
};
/**
@@ -134,7 +141,7 @@ Blockly.Lua.scrubNakedValue = function(line) {
* quotes.
* @param {string} string Text to encode.
* @return {string} Lua string.
* @private
* @protected
*/
Blockly.Lua.quote_ = function(string) {
string = string.replace(/\\/g, '\\\\')
@@ -148,7 +155,7 @@ Blockly.Lua.quote_ = function(string) {
* quotes.
* @param {string} string Text to encode.
* @return {string} Lua string.
* @private
* @protected
*/
Blockly.Lua.multiline_quote_ = function(string) {
var lines = string.split(/\n/g).map(Blockly.Lua.quote_);
@@ -165,7 +172,7 @@ Blockly.Lua.multiline_quote_ = function(string) {
* @param {string} code The Lua code created for this block.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string} Lua code with comments and subsequent blocks added.
* @private
* @protected
*/
Blockly.Lua.scrub_ = function(block, code, opt_thisOnly) {
var commentCode = '';
+4 -2
View File
@@ -24,7 +24,9 @@ Blockly.Lua['text'] = function(block) {
Blockly.Lua['text_multiline'] = function(block) {
// Text value.
var code = Blockly.Lua.multiline_quote_(block.getFieldValue('TEXT'));
return [code, Blockly.Lua.ORDER_ATOMIC];
var order = code.indexOf('..') != -1 ? Blockly.Lua.ORDER_CONCATENATION :
Blockly.Lua.ORDER_ATOMIC;
return [code, order];
};
Blockly.Lua['text_join'] = function(block) {
@@ -347,7 +349,7 @@ Blockly.Lua['text_replace'] = function(block) {
Blockly.Lua['text_reverse'] = function(block) {
var text = Blockly.Lua.valueToCode(block, 'TEXT',
Blockly.Lua.ORDER_HIGH) || '\'\'';
Blockly.Lua.ORDER_NONE) || '\'\'';
var code = 'string.reverse(' + text + ')';
return [code, Blockly.Lua.ORDER_HIGH];
};
+10 -4
View File
@@ -92,7 +92,6 @@ Blockly.PHP.ORDER_ASSIGNMENT = 20; // = += -= *= /= %= <<= >>= ...
Blockly.PHP.ORDER_LOGICAL_AND_WEAK = 21; // and
Blockly.PHP.ORDER_LOGICAL_XOR = 22; // xor
Blockly.PHP.ORDER_LOGICAL_OR_WEAK = 23; // or
Blockly.PHP.ORDER_COMMA = 24; // ,
Blockly.PHP.ORDER_NONE = 99; // (...)
/**
@@ -118,6 +117,12 @@ Blockly.PHP.ORDER_OVERRIDES = [
[Blockly.PHP.ORDER_LOGICAL_OR, Blockly.PHP.ORDER_LOGICAL_OR]
];
/**
* Whether the init method has been called.
* @type {?boolean}
*/
Blockly.PHP.isInitialized = false;
/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
@@ -155,6 +160,7 @@ Blockly.PHP.init = function(workspace) {
// Declare all of the variables.
Blockly.PHP.definitions_['variables'] = defvars.join('\n');
this.isInitialized = true;
};
/**
@@ -190,7 +196,7 @@ Blockly.PHP.scrubNakedValue = function(line) {
* quotes.
* @param {string} string Text to encode.
* @return {string} PHP string.
* @private
* @protected
*/
Blockly.PHP.quote_ = function(string) {
string = string.replace(/\\/g, '\\\\')
@@ -204,7 +210,7 @@ Blockly.PHP.quote_ = function(string) {
* quotes.
* @param {string} string Text to encode.
* @return {string} PHP string.
* @private
* @protected
*/
Blockly.PHP.multiline_quote_ = function (string) {
var lines = string.split(/\n/g).map(Blockly.PHP.quote_);
@@ -222,7 +228,7 @@ Blockly.PHP.multiline_quote_ = function (string) {
* @param {string} code The PHP code created for this block.
* @param {boolean=} opt_thisOnly True to generate code for only this statement.
* @return {string} PHP code with comments and subsequent blocks added.
* @private
* @protected
*/
Blockly.PHP.scrub_ = function(block, code, opt_thisOnly) {
var commentCode = '';
+6 -6
View File
@@ -36,11 +36,11 @@ Blockly.PHP['colour_random'] = function(block) {
Blockly.PHP['colour_rgb'] = function(block) {
// Compose a colour from RGB components expressed as percentages.
var red = Blockly.PHP.valueToCode(block, 'RED',
Blockly.PHP.ORDER_COMMA) || 0;
Blockly.PHP.ORDER_NONE) || 0;
var green = Blockly.PHP.valueToCode(block, 'GREEN',
Blockly.PHP.ORDER_COMMA) || 0;
Blockly.PHP.ORDER_NONE) || 0;
var blue = Blockly.PHP.valueToCode(block, 'BLUE',
Blockly.PHP.ORDER_COMMA) || 0;
Blockly.PHP.ORDER_NONE) || 0;
var functionName = Blockly.PHP.provideFunction_(
'colour_rgb',
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
@@ -61,11 +61,11 @@ Blockly.PHP['colour_rgb'] = function(block) {
Blockly.PHP['colour_blend'] = function(block) {
// Blend two colours together.
var c1 = Blockly.PHP.valueToCode(block, 'COLOUR1',
Blockly.PHP.ORDER_COMMA) || '\'#000000\'';
Blockly.PHP.ORDER_NONE) || '\'#000000\'';
var c2 = Blockly.PHP.valueToCode(block, 'COLOUR2',
Blockly.PHP.ORDER_COMMA) || '\'#000000\'';
Blockly.PHP.ORDER_NONE) || '\'#000000\'';
var ratio = Blockly.PHP.valueToCode(block, 'RATIO',
Blockly.PHP.ORDER_COMMA) || 0.5;
Blockly.PHP.ORDER_NONE) || 0.5;
var functionName = Blockly.PHP.provideFunction_(
'colour_blend',
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
+15 -15
View File
@@ -36,7 +36,7 @@ Blockly.PHP['lists_create_with'] = function(block) {
var code = new Array(block.itemCount_);
for (var i = 0; i < block.itemCount_; i++) {
code[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
Blockly.PHP.ORDER_COMMA) || 'null';
Blockly.PHP.ORDER_NONE) || 'null';
}
code = 'array(' + code.join(', ') + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
@@ -55,9 +55,9 @@ Blockly.PHP['lists_repeat'] = function(block) {
' return $array;',
'}']);
var element = Blockly.PHP.valueToCode(block, 'ITEM',
Blockly.PHP.ORDER_COMMA) || 'null';
Blockly.PHP.ORDER_NONE) || 'null';
var repeatCount = Blockly.PHP.valueToCode(block, 'NUM',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var code = functionName + '(' + element + ', ' + repeatCount + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
};
@@ -177,19 +177,19 @@ Blockly.PHP['lists_getIndex'] = function(block) {
return [code, Blockly.PHP.ORDER_MEMBER];
} else if (mode == 'GET_REMOVE') {
var list = Blockly.PHP.valueToCode(block, 'VALUE',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
var code = 'array_splice(' + list + ', ' + at + ', 1)[0]';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
} else if (mode == 'REMOVE') {
var list = Blockly.PHP.valueToCode(block, 'VALUE',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
return 'array_splice(' + list + ', ' + at + ', 1);\n';
}
break;
case 'FROM_END':
if (mode == 'GET') {
var list = Blockly.PHP.valueToCode(block, 'VALUE',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
var code = 'array_slice(' + list + ', ' + at + ', 1)[0]';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
@@ -271,13 +271,13 @@ Blockly.PHP['lists_setIndex'] = function(block) {
return list + '[0] = ' + value + ';\n';
} else if (mode == 'INSERT') {
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
return 'array_unshift(' + list + ', ' + value + ');\n';
}
break;
case 'LAST':
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
if (mode == 'SET') {
var functionName = Blockly.PHP.provideFunction_(
'lists_set_last_item',
@@ -298,13 +298,13 @@ Blockly.PHP['lists_setIndex'] = function(block) {
return list + '[' + at + '] = ' + value + ';\n';
} else if (mode == 'INSERT') {
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n';
}
break;
case 'FROM_END':
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
var at = Blockly.PHP.getAdjusted(block, 'AT', 1);
if (mode == 'SET') {
var functionName = Blockly.PHP.provideFunction_(
@@ -347,7 +347,7 @@ Blockly.PHP['lists_setIndex'] = function(block) {
Blockly.PHP['lists_getSublist'] = function(block) {
// Get sublist.
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
if (where1 == 'FIRST' && where2 == 'LAST') {
@@ -440,7 +440,7 @@ Blockly.PHP['lists_getSublist'] = function(block) {
Blockly.PHP['lists_sort'] = function(block) {
// Block for sorting a list.
var listCode = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || 'array()';
Blockly.PHP.ORDER_NONE) || 'array()';
var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
var type = block.getFieldValue('TYPE');
var functionName = Blockly.PHP.provideFunction_(
@@ -468,9 +468,9 @@ Blockly.PHP['lists_sort'] = function(block) {
Blockly.PHP['lists_split'] = function(block) {
// Block for splitting text into a list, or joining a list into text.
var value_input = Blockly.PHP.valueToCode(block, 'INPUT',
Blockly.PHP.ORDER_COMMA);
Blockly.PHP.ORDER_NONE);
var value_delim = Blockly.PHP.valueToCode(block, 'DELIM',
Blockly.PHP.ORDER_COMMA) || '\'\'';
Blockly.PHP.ORDER_NONE) || '\'\'';
var mode = block.getFieldValue('MODE');
if (mode == 'SPLIT') {
if (!value_input) {
@@ -492,7 +492,7 @@ Blockly.PHP['lists_split'] = function(block) {
Blockly.PHP['lists_reverse'] = function(block) {
// Block for reversing a list.
var list = Blockly.PHP.valueToCode(block, 'LIST',
Blockly.PHP.ORDER_COMMA) || '[]';
Blockly.PHP.ORDER_NONE) || '[]';
var code = 'array_reverse(' + list + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
};
+7 -7
View File
@@ -325,11 +325,11 @@ Blockly.PHP['math_modulo'] = function(block) {
Blockly.PHP['math_constrain'] = function(block) {
// Constrain a number between two limits.
var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var argument1 = Blockly.PHP.valueToCode(block, 'LOW',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var argument2 = Blockly.PHP.valueToCode(block, 'HIGH',
Blockly.PHP.ORDER_COMMA) || 'Infinity';
Blockly.PHP.ORDER_NONE) || 'Infinity';
var code = 'min(max(' + argument0 + ', ' + argument1 + '), ' +
argument2 + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
@@ -338,9 +338,9 @@ Blockly.PHP['math_constrain'] = function(block) {
Blockly.PHP['math_random_int'] = function(block) {
// Random integer between [X] and [Y].
var argument0 = Blockly.PHP.valueToCode(block, 'FROM',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var argument1 = Blockly.PHP.valueToCode(block, 'TO',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var functionName = Blockly.PHP.provideFunction_(
'math_random_int',
['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
@@ -362,9 +362,9 @@ Blockly.PHP['math_random_float'] = function(block) {
Blockly.PHP['math_atan2'] = function(block) {
// Arctangent of point (X, Y) in degrees from -180 to 180.
var argument0 = Blockly.PHP.valueToCode(block, 'X',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
var argument1 = Blockly.PHP.valueToCode(block, 'Y',
Blockly.PHP.ORDER_COMMA) || '0';
Blockly.PHP.ORDER_NONE) || '0';
return ['atan2(' + argument1 + ', ' + argument0 + ') / pi() * 180',
Blockly.PHP.ORDER_DIVISION];
};
+1 -1
View File
@@ -94,7 +94,7 @@ Blockly.PHP['procedures_callreturn'] = function(block) {
var variables = block.getVars();
for (var i = 0; i < variables.length; i++) {
args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i,
Blockly.PHP.ORDER_COMMA) || 'null';
Blockly.PHP.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
+15 -12
View File
@@ -24,7 +24,9 @@ Blockly.PHP['text'] = function(block) {
Blockly.PHP['text_multiline'] = function(block) {
// Text value.
var code = Blockly.PHP.multiline_quote_(block.getFieldValue('TEXT'));
return [code, Blockly.PHP.ORDER_ATOMIC];
var order = code.indexOf('.') != -1 ? Blockly.PHP.ORDER_STRING_CONCAT :
Blockly.PHP.ORDER_ATOMIC;
return [code, order];
};
Blockly.PHP['text_join'] = function(block) {
@@ -35,19 +37,19 @@ Blockly.PHP['text_join'] = function(block) {
var element = Blockly.PHP.valueToCode(block, 'ADD0',
Blockly.PHP.ORDER_NONE) || '\'\'';
var code = element;
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
return [code, Blockly.PHP.ORDER_NONE];
} else if (block.itemCount_ == 2) {
var element0 = Blockly.PHP.valueToCode(block, 'ADD0',
Blockly.PHP.ORDER_ATOMIC) || '\'\'';
Blockly.PHP.ORDER_STRING_CONCAT) || '\'\'';
var element1 = Blockly.PHP.valueToCode(block, 'ADD1',
Blockly.PHP.ORDER_ATOMIC) || '\'\'';
Blockly.PHP.ORDER_STRING_CONCAT) || '\'\'';
var code = element0 + ' . ' + element1;
return [code, Blockly.PHP.ORDER_STRING_CONCAT];
} else {
var elements = new Array(block.itemCount_);
for (var i = 0; i < block.itemCount_; i++) {
elements[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
Blockly.PHP.ORDER_COMMA) || '\'\'';
Blockly.PHP.ORDER_NONE) || '\'\'';
}
var code = 'implode(\'\', array(' + elements.join(',') + '))';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
@@ -118,7 +120,7 @@ Blockly.PHP['text_charAt'] = function(block) {
// Get letter at index.
var where = block.getFieldValue('WHERE') || 'FROM_START';
var textOrder = (where == 'RANDOM') ? Blockly.PHP.ORDER_NONE :
Blockly.PHP.ORDER_COMMA;
Blockly.PHP.ORDER_NONE;
var text = Blockly.PHP.valueToCode(block, 'VALUE', textOrder) || '\'\'';
switch (where) {
case 'FIRST':
@@ -149,12 +151,13 @@ Blockly.PHP['text_charAt'] = function(block) {
Blockly.PHP['text_getSubstring'] = function(block) {
// Get substring.
var text = Blockly.PHP.valueToCode(block, 'STRING',
Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
var where1 = block.getFieldValue('WHERE1');
var where2 = block.getFieldValue('WHERE2');
var text = Blockly.PHP.valueToCode(block, 'STRING',
Blockly.PHP.ORDER_NONE) || '\'\'';
if (where1 == 'FIRST' && where2 == 'LAST') {
var code = text;
return [code, Blockly.PHP.ORDER_NONE];
} else {
var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
@@ -183,8 +186,8 @@ Blockly.PHP['text_getSubstring'] = function(block) {
'}']);
var code = functionName + '(' + text + ', \'' +
where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
}
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
};
Blockly.PHP['text_changeCase'] = function(block) {
@@ -243,7 +246,7 @@ Blockly.PHP['text_prompt'] = Blockly.PHP['text_prompt_ext'];
Blockly.PHP['text_count'] = function(block) {
var text = Blockly.PHP.valueToCode(block, 'TEXT',
Blockly.PHP.ORDER_MEMBER) || '\'\'';
Blockly.PHP.ORDER_NONE) || '\'\'';
var sub = Blockly.PHP.valueToCode(block, 'SUB',
Blockly.PHP.ORDER_NONE) || '\'\'';
var code = 'strlen(' + sub + ') === 0'
@@ -254,7 +257,7 @@ Blockly.PHP['text_count'] = function(block) {
Blockly.PHP['text_replace'] = function(block) {
var text = Blockly.PHP.valueToCode(block, 'TEXT',
Blockly.PHP.ORDER_MEMBER) || '\'\'';
Blockly.PHP.ORDER_NONE) || '\'\'';
var from = Blockly.PHP.valueToCode(block, 'FROM',
Blockly.PHP.ORDER_NONE) || '\'\'';
var to = Blockly.PHP.valueToCode(block, 'TO',
@@ -265,7 +268,7 @@ Blockly.PHP['text_replace'] = function(block) {
Blockly.PHP['text_reverse'] = function(block) {
var text = Blockly.PHP.valueToCode(block, 'TEXT',
Blockly.PHP.ORDER_MEMBER) || '\'\'';
Blockly.PHP.ORDER_NONE) || '\'\'';
var code = 'strrev(' + text + ')';
return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
};

Some files were not shown because too many files have changed in this diff Show More