diff --git a/blockly_compressed.js b/blockly_compressed.js index 77e305a43..742132088 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -10,1502 +10,1893 @@ root.Blockly = factory(); } }(this, function() { - 'use strict';var Blockly={connectionTypes:{INPUT_VALUE:1,OUTPUT_VALUE:2,NEXT_STATEMENT:3,PREVIOUS_STATEMENT:4}};Blockly.constants={};Blockly.LINE_MODE_MULTIPLIER=40;Blockly.PAGE_MODE_MULTIPLIER=125;Blockly.DRAG_RADIUS=5;Blockly.FLYOUT_DRAG_RADIUS=10;Blockly.SNAP_RADIUS=28;Blockly.CONNECTING_SNAP_RADIUS=Blockly.SNAP_RADIUS;Blockly.CURRENT_CONNECTION_PREFERENCE=8;Blockly.BUMP_DELAY=250;Blockly.BUMP_RANDOMNESS=10;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.DRAG_STACK=!0;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;Blockly.SPRITE={width:96,height:124,url:"sprites.png"}; -Blockly.constants.ALIGN={LEFT:-1,CENTRE:0,RIGHT:1};Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.INPUT_VALUE]=Blockly.connectionTypes.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.OUTPUT_VALUE]=Blockly.connectionTypes.INPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.NEXT_STATEMENT]=Blockly.connectionTypes.PREVIOUS_STATEMENT; -Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.PREVIOUS_STATEMENT]=Blockly.connectionTypes.NEXT_STATEMENT;Blockly.VARIABLE_CATEGORY_NAME="VARIABLE";Blockly.VARIABLE_DYNAMIC_CATEGORY_NAME="VARIABLE_DYNAMIC";Blockly.PROCEDURE_CATEGORY_NAME="PROCEDURE";Blockly.RENAME_VARIABLE_ID="RENAME_VARIABLE_ID";Blockly.DELETE_VARIABLE_ID="DELETE_VARIABLE_ID";Blockly.constants.COLLAPSED_INPUT_NAME="_TEMP_COLLAPSED_INPUT";Blockly.constants.COLLAPSED_FIELD_NAME="_TEMP_COLLAPSED_FIELD";Blockly.utils={};Blockly.utils.global=function(){return"object"===typeof self?self:"object"===typeof window?window:"object"===typeof global?global:this}();Blockly.Msg={};Blockly.utils.global.Blockly||(Blockly.utils.global.Blockly={});Blockly.utils.global.Blockly.Msg||(Blockly.utils.global.Blockly.Msg=Blockly.Msg);Blockly.utils.colour={}; -Blockly.utils.colour.parse=function(a){a=String(a).toLowerCase().trim();var b=Blockly.utils.colour.names[a];if(b)return b;b="0x"==a.substring(0,2)?"#"+a.substring(2):a;b="#"==b[0]?b:"#"+b;if(/^#[0-9a-f]{6}$/.test(b))return b;if(/^#[0-9a-f]{3}$/.test(b))return["#",b[1],b[1],b[2],b[2],b[3],b[3]].join("");var c=a.match(/^(?:rgb)?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);return c&&(a=Number(c[1]),b=Number(c[2]),c=Number(c[3]),0<=a&&256>a&&0<=b&&256>b&&0<=c&&256>c)?Blockly.utils.colour.rgbToHex(a,b, -c):null};Blockly.utils.colour.rgbToHex=function(a,b,c){b=a<<16|b<<8|c;return 16>a?"#"+(16777216|b).toString(16).substr(1):"#"+b.toString(16)};Blockly.utils.colour.hexToRgb=function(a){a=Blockly.utils.colour.parse(a);if(!a)return[0,0,0];a=parseInt(a.substr(1),16);return[a>>16,a>>8&255,a&255]}; -Blockly.utils.colour.hsvToHex=function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=c;else{var g=Math.floor(a/60),h=a/60-g;a=c*(1-b);var k=c*(1-b*h);b=c*(1-b*(1-h));switch(g){case 1:d=k;e=c;f=a;break;case 2:d=a;e=c;f=b;break;case 3:d=a;e=k;f=c;break;case 4:d=b;e=a;f=c;break;case 5:d=c;e=a;f=k;break;case 6:case 0:d=c,e=b,f=a}}return Blockly.utils.colour.rgbToHex(Math.floor(d),Math.floor(e),Math.floor(f))}; -Blockly.utils.colour.blend=function(a,b,c){a=Blockly.utils.colour.parse(a);if(!a)return null;b=Blockly.utils.colour.parse(b);if(!b)return null;a=Blockly.utils.colour.hexToRgb(a);b=Blockly.utils.colour.hexToRgb(b);return Blockly.utils.colour.rgbToHex(Math.round(b[0]+c*(a[0]-b[0])),Math.round(b[1]+c*(a[1]-b[1])),Math.round(b[2]+c*(a[2]-b[2])))}; -Blockly.utils.colour.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00"};Blockly.utils.Coordinate=function(a,b){this.x=a;this.y=b};Blockly.utils.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};Blockly.utils.Coordinate.distance=function(a,b){var c=a.x-b.x;a=a.y-b.y;return Math.sqrt(c*c+a*a)};Blockly.utils.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};Blockly.utils.Coordinate.difference=function(a,b){return new Blockly.utils.Coordinate(a.x-b.x,a.y-b.y)}; -Blockly.utils.Coordinate.sum=function(a,b){return new Blockly.utils.Coordinate(a.x+b.x,a.y+b.y)};Blockly.utils.Coordinate.prototype.clone=function(){return new Blockly.utils.Coordinate(this.x,this.y)};Blockly.utils.Coordinate.prototype.scale=function(a){this.x*=a;this.y*=a;return this};Blockly.utils.Coordinate.prototype.translate=function(a,b){this.x+=a;this.y+=b;return this};Blockly.utils.Rect=function(a,b,c,d){this.top=a;this.bottom=b;this.left=c;this.right=d};Blockly.utils.Rect.prototype.contains=function(a,b){return a>=this.left&&a<=this.right&&b>=this.top&&b<=this.bottom};Blockly.utils.Rect.prototype.intersects=function(a){return!(this.left>a.right||this.righta.bottom||this.bottomb&&(b=c[d].length);d=-Infinity;var e=1;do{var f=d;var g=a;a=[];var h=c.length/e,k=1;for(d=0;df);return g}; -Blockly.utils.string.wrapScore_=function(a,b,c){for(var d=[0],e=[],f=0;fd&&(d=h,e=g)}return e?Blockly.utils.string.wrapMutate_(a,e,c):b};Blockly.utils.string.wrapToText_=function(a,b){for(var c=[],d=0;d=h?(e=2,f=h,(h=a.join(""))&&c.push(h),a.length=0):"{"==h?e=3:(a.push("%",h),e=0):2==e?"0"<=h&&"9">=h?f+=h:(c.push(parseInt(f,10)),g--,e=0):3==e&&(""==h?(a.splice(0,0,"%{"),g--,e=0):"}"!=h?a.push(h):(e=a.join(""),/[A-Z]\w*/i.test(e)?(h=e.toUpperCase(), -(h=Blockly.utils.string.startsWith(h,"BKY_")?h.substring(4):null)&&h in Blockly.Msg?(e=Blockly.Msg[h],"string"==typeof e?Array.prototype.push.apply(c,Blockly.utils.tokenizeInterpolation_(e,b)):b?c.push(String(e)):c.push(e)):c.push("%{"+e+"}")):c.push("%{"+e+"}"),e=a.length=0))}(h=a.join(""))&&c.push(h);b=[];for(g=a.length=0;gc;c++)b[c]=Blockly.utils.genUid.soup_.charAt(Math.random()*a);return b.join("")};Blockly.utils.genUid.soup_="!#$%()*+,-./:;=?@[]^_`{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -Blockly.utils.is3dSupported=function(){if(void 0!==Blockly.utils.is3dSupported.cached_)return Blockly.utils.is3dSupported.cached_;if(!Blockly.utils.global.getComputedStyle)return!1;var a=document.createElement("p"),b="none",c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(a,null);for(var d in c)if(void 0!==a.style[d]){a.style[d]="translate3d(1px,1px,1px)";b=Blockly.utils.global.getComputedStyle(a); -if(!b)return document.body.removeChild(a),!1;b=b.getPropertyValue(c[d])}document.body.removeChild(a);Blockly.utils.is3dSupported.cached_="none"!==b;return Blockly.utils.is3dSupported.cached_};Blockly.utils.runAfterPageLoad=function(a){if("object"!=typeof document)throw Error("Blockly.utils.runAfterPageLoad() requires browser document.");if("complete"==document.readyState)a();else var b=setInterval(function(){"complete"==document.readyState&&(clearInterval(b),a())},10)}; -Blockly.utils.getViewportBBox=function(){var a=Blockly.utils.style.getViewportPageOffset();return new Blockly.utils.Rect(a.y,document.documentElement.clientHeight+a.y,a.x,document.documentElement.clientWidth+a.x)};Blockly.utils.arrayRemove=function(a,b){b=a.indexOf(b);if(-1==b)return!1;a.splice(b,1);return!0}; -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.Touch={};Blockly.Touch.TOUCH_ENABLED="ontouchstart"in Blockly.utils.global||!!(Blockly.utils.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!Blockly.utils.global.navigator||!Blockly.utils.global.navigator.maxTouchPoints&&!Blockly.utils.global.navigator.msMaxTouchPoints);Blockly.Touch.touchIdentifier_=null;Blockly.Touch.TOUCH_MAP={}; -Blockly.utils.global.PointerEvent?Blockly.Touch.TOUCH_MAP={mousedown:["pointerdown"],mouseenter:["pointerenter"],mouseleave:["pointerleave"],mousemove:["pointermove"],mouseout:["pointerout"],mouseover:["pointerover"],mouseup:["pointerup","pointercancel"],touchend:["pointerup"],touchcancel:["pointercancel"]}:Blockly.Touch.TOUCH_ENABLED&&(Blockly.Touch.TOUCH_MAP={mousedown:["touchstart"],mousemove:["touchmove"],mouseup:["touchend","touchcancel"]});Blockly.longPid_=0; -Blockly.longStart=function(a,b){Blockly.longStop_();a.changedTouches&&1!=a.changedTouches.length||(Blockly.longPid_=setTimeout(function(){a.changedTouches&&(a.button=2,a.clientX=a.changedTouches[0].clientX,a.clientY=a.changedTouches[0].clientY);b&&b.handleRightClick(a)},Blockly.LONGPRESS))};Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)};Blockly.Touch.clearTouchIdentifier=function(){Blockly.Touch.touchIdentifier_=null}; -Blockly.Touch.shouldHandleEvent=function(a){return!Blockly.Touch.isMouseOrTouchEvent(a)||Blockly.Touch.checkTouchIdentifier(a)};Blockly.Touch.getTouchIdentifierFromEvent=function(a){return void 0!=a.pointerId?a.pointerId:a.changedTouches&&a.changedTouches[0]&&void 0!==a.changedTouches[0].identifier&&null!==a.changedTouches[0].identifier?a.changedTouches[0].identifier:"mouse"}; -Blockly.Touch.checkTouchIdentifier=function(a){var b=Blockly.Touch.getTouchIdentifierFromEvent(a);return void 0!==Blockly.Touch.touchIdentifier_&&null!==Blockly.Touch.touchIdentifier_?Blockly.Touch.touchIdentifier_==b:"mousedown"==a.type||"touchstart"==a.type||"pointerdown"==a.type?(Blockly.Touch.touchIdentifier_=b,!0):!1};Blockly.Touch.setClientFromTouch=function(a){if(Blockly.utils.string.startsWith(a.type,"touch")){var b=a.changedTouches[0];a.clientX=b.clientX;a.clientY=b.clientY}}; -Blockly.Touch.isMouseOrTouchEvent=function(a){return Blockly.utils.string.startsWith(a.type,"touch")||Blockly.utils.string.startsWith(a.type,"mouse")||Blockly.utils.string.startsWith(a.type,"pointer")};Blockly.Touch.isTouchEvent=function(a){return Blockly.utils.string.startsWith(a.type,"touch")||Blockly.utils.string.startsWith(a.type,"pointer")}; -Blockly.Touch.splitEventByTouches=function(a){var b=[];if(a.changedTouches)for(var c=0;ce.top?Blockly.DropDownDiv.getPositionAboveMetrics_(c,d,e,f):b+f.heightdocument.documentElement.clientTop?Blockly.DropDownDiv.getPositionAboveMetrics_(c, -d,e,f):Blockly.DropDownDiv.getPositionTopOfPageMetrics_(a,e,f)};Blockly.DropDownDiv.getPositionBelowMetrics_=function(a,b,c,d){a=Blockly.DropDownDiv.getPositionX(a,c.left,c.right,d.width);return{initialX:a.divX,initialY:b,finalX:a.divX,finalY:b+Blockly.DropDownDiv.PADDING_Y,arrowX:a.arrowX,arrowY:-(Blockly.DropDownDiv.ARROW_SIZE/2+Blockly.DropDownDiv.BORDER_SIZE),arrowAtTop:!0,arrowVisible:!0}}; -Blockly.DropDownDiv.getPositionAboveMetrics_=function(a,b,c,d){a=Blockly.DropDownDiv.getPositionX(a,c.left,c.right,d.width);return{initialX:a.divX,initialY:b-d.height,finalX:a.divX,finalY:b-d.height-Blockly.DropDownDiv.PADDING_Y,arrowX:a.arrowX,arrowY:d.height-2*Blockly.DropDownDiv.BORDER_SIZE-Blockly.DropDownDiv.ARROW_SIZE/2,arrowAtTop:!1,arrowVisible:!0}}; -Blockly.DropDownDiv.getPositionTopOfPageMetrics_=function(a,b,c){a=Blockly.DropDownDiv.getPositionX(a,b.left,b.right,c.width);return{initialX:a.divX,initialY:0,finalX:a.divX,finalY:0,arrowAtTop:null,arrowX:null,arrowY:null,arrowVisible:!1}}; -Blockly.DropDownDiv.getPositionX=function(a,b,c,d){var e=a;a=Blockly.utils.math.clamp(b,a-d/2,c-d);e-=Blockly.DropDownDiv.ARROW_SIZE/2;b=Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING;d=Blockly.utils.math.clamp(b,e-a,d-b-Blockly.DropDownDiv.ARROW_SIZE);return{arrowX:d,divX:a}};Blockly.DropDownDiv.isVisible=function(){return!!Blockly.DropDownDiv.owner_}; -Blockly.DropDownDiv.hideIfOwner=function(a,b){return Blockly.DropDownDiv.owner_===a?(b?Blockly.DropDownDiv.hideWithoutAnimation():Blockly.DropDownDiv.hide(),!0):!1}; -Blockly.DropDownDiv.hide=function(){var a=Blockly.DropDownDiv.DIV_;a.style.transform="translate(0, 0)";a.style.opacity=0;Blockly.DropDownDiv.animateOutTimer_=setTimeout(function(){Blockly.DropDownDiv.hideWithoutAnimation()},1E3*Blockly.DropDownDiv.ANIMATION_TIME);Blockly.DropDownDiv.onHide_&&(Blockly.DropDownDiv.onHide_(),Blockly.DropDownDiv.onHide_=null)}; -Blockly.DropDownDiv.hideWithoutAnimation=function(){if(Blockly.DropDownDiv.isVisible()){Blockly.DropDownDiv.animateOutTimer_&&clearTimeout(Blockly.DropDownDiv.animateOutTimer_);var a=Blockly.DropDownDiv.DIV_;a.style.transform="";a.style.left="";a.style.top="";a.style.opacity=0;a.style.display="none";a.style.backgroundColor="";a.style.borderColor="";Blockly.DropDownDiv.onHide_&&(Blockly.DropDownDiv.onHide_(),Blockly.DropDownDiv.onHide_=null);Blockly.DropDownDiv.clearContent();Blockly.DropDownDiv.owner_= -null;Blockly.DropDownDiv.rendererClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.rendererClassName_),Blockly.DropDownDiv.rendererClassName_="");Blockly.DropDownDiv.themeClassName_&&(Blockly.utils.dom.removeClass(a,Blockly.DropDownDiv.themeClassName_),Blockly.DropDownDiv.themeClassName_="");Blockly.getMainWorkspace().markFocused()}}; -Blockly.DropDownDiv.positionInternal_=function(a,b,c,d){a=Blockly.DropDownDiv.getPositionMetrics_(a,b,c,d);a.arrowVisible?(Blockly.DropDownDiv.arrow_.style.display="",Blockly.DropDownDiv.arrow_.style.transform="translate("+a.arrowX+"px,"+a.arrowY+"px) rotate(45deg)",Blockly.DropDownDiv.arrow_.setAttribute("class",a.arrowAtTop?"blocklyDropDownArrow blocklyArrowTop":"blocklyDropDownArrow blocklyArrowBottom")):Blockly.DropDownDiv.arrow_.style.display="none";b=Math.floor(a.initialX);c=Math.floor(a.initialY); -d=Math.floor(a.finalX);var e=Math.floor(a.finalY),f=Blockly.DropDownDiv.DIV_;f.style.left=b+"px";f.style.top=c+"px";f.style.display="block";f.style.opacity=1;f.style.transform="translate("+(d-b)+"px,"+(e-c)+"px)";return!!a.arrowAtTop}; -Blockly.DropDownDiv.repositionForWindowResize=function(){if(Blockly.DropDownDiv.owner_){var a=Blockly.DropDownDiv.owner_,b=a.getSourceBlock();a=Blockly.DropDownDiv.positionToField_?Blockly.DropDownDiv.getScaledBboxOfField_(a):Blockly.DropDownDiv.getScaledBboxOfBlock_(b);b=a.left+(a.right-a.left)/2;Blockly.DropDownDiv.positionInternal_(b,a.bottom,b,a.top)}else Blockly.DropDownDiv.hide()};Blockly.registry={};Blockly.registry.typeMap_=Object.create(null);Blockly.registry.DEFAULT="default";Blockly.registry.Type=function(a){this.name_=a};Blockly.registry.Type.prototype.toString=function(){return this.name_};Blockly.registry.Type.CONNECTION_CHECKER=new Blockly.registry.Type("connectionChecker");Blockly.registry.Type.CURSOR=new Blockly.registry.Type("cursor");Blockly.registry.Type.EVENT=new Blockly.registry.Type("event");Blockly.registry.Type.FIELD=new Blockly.registry.Type("field"); -Blockly.registry.Type.RENDERER=new Blockly.registry.Type("renderer");Blockly.registry.Type.TOOLBOX=new Blockly.registry.Type("toolbox");Blockly.registry.Type.THEME=new Blockly.registry.Type("theme");Blockly.registry.Type.TOOLBOX_ITEM=new Blockly.registry.Type("toolboxItem");Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX=new Blockly.registry.Type("flyoutsVerticalToolbox");Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX=new Blockly.registry.Type("flyoutsHorizontalToolbox"); -Blockly.registry.Type.METRICS_MANAGER=new Blockly.registry.Type("metricsManager");Blockly.registry.Type.BLOCK_DRAGGER=new Blockly.registry.Type("blockDragger"); -Blockly.registry.register=function(a,b,c,d){if(!(a instanceof Blockly.registry.Type)&&"string"!=typeof a||""==String(a).trim())throw Error('Invalid type "'+a+'". The type must be a non-empty string or a Blockly.registry.Type.');a=String(a).toLowerCase();if("string"!=typeof b||""==b.trim())throw Error('Invalid name "'+b+'". The name must be a non-empty string.');b=b.toLowerCase();if(!c)throw Error("Can not register a null value");var e=Blockly.registry.typeMap_[a];e||(e=Blockly.registry.typeMap_[a]= -Object.create(null));Blockly.registry.validate_(a,c);if(!d&&e[b])throw Error('Name "'+b+'" with type "'+a+'" already registered.');e[b]=c};Blockly.registry.validate_=function(a,b){switch(a){case String(Blockly.registry.Type.FIELD):if("function"!=typeof b.fromJson)throw Error('Type "'+a+'" must have a fromJson function');}}; -Blockly.registry.unregister=function(a,b){a=String(a).toLowerCase();b=b.toLowerCase();var c=Blockly.registry.typeMap_[a];c&&c[b]?delete Blockly.registry.typeMap_[a][b]:console.warn("Unable to unregister ["+b+"]["+a+"] from the registry.")}; -Blockly.registry.getItem_=function(a,b,c){a=String(a).toLowerCase();b=b.toLowerCase();var d=Blockly.registry.typeMap_[a];if(!d||!d[b]){b="Unable to find ["+b+"]["+a+"] in the registry.";if(c)throw Error(b+" You must require or register a "+a+" plugin.");console.warn(b);return null}return d[b]};Blockly.registry.hasItem=function(a,b){a=String(a).toLowerCase();b=b.toLowerCase();return(a=Blockly.registry.typeMap_[a])?!!a[b]:!1}; -Blockly.registry.getClass=function(a,b,c){return Blockly.registry.getItem_(a,b,c)};Blockly.registry.getObject=function(a,b,c){return Blockly.registry.getItem_(a,b,c)};Blockly.registry.getClassFromOptions=function(a,b,c){b=b.plugins[a.toString()]||Blockly.registry.DEFAULT;return"function"==typeof b?b:Blockly.registry.getClass(a,b,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.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.VIEWPORT_CHANGE)k.viewTop=f.viewTop,k.viewLeft=f.viewLeft,k.scale=f.scale,k.oldScale=f.oldScale;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.Events.get(a.type);if(!c)throw Error("Unknown event type.");c=new c;c.fromJson(a);c.workspaceId=b.id;return c};Blockly.Events.get=function(a){return Blockly.registry.getClass(Blockly.registry.Type.EVENT,a)}; -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.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.inputTypes={VALUE:Blockly.connectionTypes.INPUT_VALUE,STATEMENT:Blockly.connectionTypes.NEXT_STATEMENT,DUMMY:5};Blockly.Xml={};Blockly.Xml.workspaceToDom=function(a,b){var c=Blockly.utils.xml.createElement("xml"),d=Blockly.Xml.variablesToDom(Blockly.Variables.allUsedVarModels(a));d.hasChildNodes()&&c.appendChild(d);var e=a.getTopComments(!0);d=0;for(var f;f=e[d];d++)c.appendChild(f.toXmlWithXY(b));a=a.getTopBlocks(!0);for(d=0;e=a[d];d++)c.appendChild(Blockly.Xml.blockToDomWithXY(e,b));return c}; -Blockly.Xml.variablesToDom=function(a){for(var b=Blockly.utils.xml.createElement("variables"),c=0,d;d=a[c];c++){var e=Blockly.utils.xml.createElement("variable");e.appendChild(Blockly.utils.xml.createTextNode(d.name));d.type&&e.setAttribute("type",d.type);e.id=d.getId();b.appendChild(e)}return b}; -Blockly.Xml.blockToDomWithXY=function(a,b){if(a.isInsertionMarker()&&(a=a.getChildren(!1)[0],!a))return new DocumentFragment;var c;a.workspace.RTL&&(c=a.workspace.getWidth());b=Blockly.Xml.blockToDom(a,b);var d=a.getRelativeToSurfaceXY();b.setAttribute("x",Math.round(a.workspace.RTL?c-d.x:d.x));b.setAttribute("y",Math.round(d.y));return b};Blockly.Xml.fieldToDom_=function(a){if(a.isSerializable()){var b=Blockly.utils.xml.createElement("field");b.setAttribute("name",a.name||"");return a.toXml(b)}return null}; -Blockly.Xml.allFieldsToDom_=function(a,b){for(var c=0,d;d=a.inputList[c];c++)for(var e=0,f;f=d.fieldRow[e];e++)(f=Blockly.Xml.fieldToDom_(f))&&b.appendChild(f)}; -Blockly.Xml.blockToDom=function(a,b){if(a.isInsertionMarker())return(a=a.getChildren(!1)[0])?Blockly.Xml.blockToDom(a):new DocumentFragment;var c=Blockly.utils.xml.createElement(a.isShadow()?"shadow":"block");c.setAttribute("type",a.type);b||c.setAttribute("id",a.id);if(a.mutationToDom){var d=a.mutationToDom();d&&(d.hasChildNodes()||d.hasAttributes())&&c.appendChild(d)}Blockly.Xml.allFieldsToDom_(a,c);if(d=a.getCommentText()){var e=a.commentModel.size,f=a.commentModel.pinned,g=Blockly.utils.xml.createElement("comment"); -g.appendChild(Blockly.utils.xml.createTextNode(d));g.setAttribute("pinned",f);g.setAttribute("h",e.height);g.setAttribute("w",e.width);c.appendChild(g)}a.data&&(d=Blockly.utils.xml.createElement("data"),d.appendChild(Blockly.utils.xml.createTextNode(a.data)),c.appendChild(d));for(d=0;e=a.inputList[d];d++){var h;f=!0;if(e.type!=Blockly.inputTypes.DUMMY){var k=e.connection.targetBlock();e.type==Blockly.inputTypes.VALUE?h=Blockly.utils.xml.createElement("value"):e.type==Blockly.inputTypes.STATEMENT&& -(h=Blockly.utils.xml.createElement("statement"));g=e.connection.getShadowDom();!g||k&&k.isShadow()||h.appendChild(Blockly.Xml.cloneShadow_(g,b));k&&(g=Blockly.Xml.blockToDom(k,b),g.nodeType==Blockly.utils.dom.NodeType.ELEMENT_NODE&&(h.appendChild(g),f=!1));h.setAttribute("name",e.name);f||c.appendChild(h)}}void 0!=a.inputsInline&&a.inputsInline!=a.inputsInlineDefault&&c.setAttribute("inline",a.inputsInline);a.isCollapsed()&&c.setAttribute("collapsed",!0);a.isEnabled()||c.setAttribute("disabled",!0); -a.isDeletable()||a.isShadow()||c.setAttribute("deletable",!1);a.isMovable()||a.isShadow()||c.setAttribute("movable",!1);a.isEditable()||c.setAttribute("editable",!1);if(d=a.getNextBlock())g=Blockly.Xml.blockToDom(d,b),g.nodeType==Blockly.utils.dom.NodeType.ELEMENT_NODE&&(h=Blockly.utils.xml.createElement("next"),h.appendChild(g),c.appendChild(h));g=a.nextConnection&&a.nextConnection.getShadowDom();!g||d&&d.isShadow()||h.appendChild(Blockly.Xml.cloneShadow_(g,b));return c}; -Blockly.Xml.cloneShadow_=function(a,b){for(var c=a=a.cloneNode(!0),d;c;)if(b&&"shadow"==c.nodeName&&c.removeAttribute("id"),c.firstChild)c=c.firstChild;else{for(;c&&!c.nextSibling;)d=c,c=c.parentNode,d.nodeType==Blockly.utils.dom.NodeType.TEXT_NODE&&""==d.data.trim()&&c.firstChild!=d&&Blockly.utils.dom.removeNode(d);c&&(d=c,c=c.nextSibling,d.nodeType==Blockly.utils.dom.NodeType.TEXT_NODE&&""==d.data.trim()&&Blockly.utils.dom.removeNode(d))}return a}; -Blockly.Xml.domToText=function(a){return Blockly.utils.xml.domToText(a).replace(/<(\w+)([^<]*)\/>/g,"<$1$2>")};Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1");return a.replace(/^\n/,"")}; -Blockly.Xml.textToDom=function(a){var b=Blockly.utils.xml.textToDomDocument(a);if(!b||!b.documentElement||b.getElementsByTagName("parsererror").length)throw Error("textToDom was unable to parse: "+a);return b.documentElement};Blockly.Xml.clearWorkspaceAndLoadFromXml=function(a,b){b.setResizesEnabled(!1);b.clear();a=Blockly.Xml.domToWorkspace(a,b);b.setResizesEnabled(!0);return a}; -Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];Blockly.utils.dom.startTextWidthCache();var e=Blockly.Events.getGroup();e||Blockly.Events.setGroup(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var f=!0;try{for(var g=0,h;h=a.childNodes[g];g++){var k=h.nodeName.toLowerCase(),l=h;if("block"==k||"shadow"==k&&!Blockly.Events.recordUndo){var m= -Blockly.Xml.domToBlock(l,b);c.push(m.id);var n=l.hasAttribute("x")?parseInt(l.getAttribute("x"),10):10,p=l.hasAttribute("y")?parseInt(l.getAttribute("y"),10):10;isNaN(n)||isNaN(p)||m.moveBy(b.RTL?d-n:n,p);f=!1}else{if("shadow"==k)throw TypeError("Shadow block cannot be a top-level block.");if("comment"==k)b.rendered?Blockly.WorkspaceCommentSvg?Blockly.WorkspaceCommentSvg.fromXml(l,b,d):console.warn("Missing require for Blockly.WorkspaceCommentSvg, ignoring workspace comment."):Blockly.WorkspaceComment? -Blockly.WorkspaceComment.fromXml(l,b):console.warn("Missing require for Blockly.WorkspaceComment, ignoring workspace comment.");else if("variables"==k){if(f)Blockly.Xml.domToVariables(l,b);else throw Error("'variables' tag must exist once before block and shadow tag elements in the workspace XML, but it was found in another location.");f=!1}}}}finally{e||Blockly.Events.setGroup(!1),Blockly.utils.dom.stopTextWidthCache()}b.setResizesEnabled&&b.setResizesEnabled(!0);Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.FINISHED_LOADING))(b)); -return c};Blockly.Xml.appendDomToWorkspace=function(a,b){var c;Object.prototype.hasOwnProperty.call(b,"scale")&&(c=b.getBlocksBoundingBox());a=Blockly.Xml.domToWorkspace(a,b);if(c&&c.top!=c.bottom){var d=c.bottom;var e=b.RTL?c.right:c.left;var f=Infinity,g=-Infinity,h=Infinity;for(c=0;cg&&(g=k.x)}d=d-h+10;e=b.RTL?e-g:e-f;for(c=0;c");b.domToMutation(d)}Blockly.Events.fire(new Blockly.Events.BlockChange(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;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.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));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,f=a?this.newCoordinate:this.oldCoordinate;a=null;if(d&&(a=b.getBlockById(d),!a)){console.warn("Can't connect to non-existent block: "+d);return}c.getParent()&&c.unplug();if(f)e=c.getRelativeToSurfaceXY(),c.moveBy(f.x-e.x,f.y-e.y);else{c=c.outputConnection||c.previousConnection;b=c.type;if(e){if(a=a.getInput(e))var g= -a.connection}else b==Blockly.connectionTypes.PREVIOUS_STATEMENT&&(g=a.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.BlockChange); -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.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.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)}; -Blockly.Events.VarDelete=function(a){Blockly.Events.VarDelete.superClass_.constructor.call(this,a);a&&(this.varType=a.type,this.varName=a.name)};Blockly.utils.object.inherits(Blockly.Events.VarDelete,Blockly.Events.VarBase);Blockly.Events.VarDelete.prototype.type=Blockly.Events.VAR_DELETE;Blockly.Events.VarDelete.prototype.toJson=function(){var a=Blockly.Events.VarDelete.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a}; -Blockly.Events.VarDelete.prototype.fromJson=function(a){Blockly.Events.VarDelete.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};Blockly.Events.VarDelete.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.deleteVariableById(this.varId):b.createVariable(this.varName,this.varType,this.varId)};Blockly.Events.VarRename=function(a,b){Blockly.Events.VarRename.superClass_.constructor.call(this,a);a&&(this.oldName=a.name,this.newName="undefined"==typeof b?"":b)}; -Blockly.utils.object.inherits(Blockly.Events.VarRename,Blockly.Events.VarBase);Blockly.Events.VarRename.prototype.type=Blockly.Events.VAR_RENAME;Blockly.Events.VarRename.prototype.toJson=function(){var a=Blockly.Events.VarRename.superClass_.toJson.call(this);a.oldName=this.oldName;a.newName=this.newName;return a};Blockly.Events.VarRename.prototype.fromJson=function(a){Blockly.Events.VarRename.superClass_.fromJson.call(this,a);this.oldName=a.oldName;this.newName=a.newName}; -Blockly.Events.VarRename.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.renameVariableById(this.varId,this.newName):b.renameVariableById(this.varId,this.oldName)};Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.VAR_CREATE,Blockly.Events.VarCreate);Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.VAR_DELETE,Blockly.Events.VarDelete);Blockly.registry.register(Blockly.registry.Type.EVENT,Blockly.Events.VAR_RENAME,Blockly.Events.VarRename);Blockly.BlockDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.BlockDragSurfaceSvg.prototype.SVG_=null;Blockly.BlockDragSurfaceSvg.prototype.dragGroup_=null;Blockly.BlockDragSurfaceSvg.prototype.container_=null;Blockly.BlockDragSurfaceSvg.prototype.scale_=1;Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_=null;Blockly.BlockDragSurfaceSvg.prototype.childSurfaceXY_=new Blockly.utils.Coordinate(0,0); -Blockly.BlockDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=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":"blocklyBlockDragSurface"},this.container_),this.dragGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{},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.childSurfaceXY_.x=parseInt(a,10);this.childSurfaceXY_.y=parseInt(b,10);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.translateBy=function(a,b){this.surfaceXY_=new Blockly.utils.Coordinate(this.surfaceXY_.x+a,this.surfaceXY_.y+b);this.translateSurfaceInternal_()}; -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.getSvgRoot=function(){return this.SVG_}; -Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock=function(){return this.dragGroup_.firstChild};Blockly.BlockDragSurfaceSvg.prototype.getWsTranslation=function(){return this.childSurfaceXY_.clone()};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(/<<>>/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);", -"color: #000;","display: none;","font: 9pt sans-serif;","opacity: .9;","padding: 2px;","position: absolute;","z-index: 100000;","}",".blocklyDropDownDiv {","position: absolute;","left: 0;","top: 0;","z-index: 1000;","display: none;","border: 1px solid;","border-color: #dadce0;","background-color: #fff;","border-radius: 2px;","padding: 4px;","box-shadow: 0 0 3px 1px rgba(0,0,0,.3);","}",".blocklyDropDownDiv.blocklyFocused {","box-shadow: 0 0 6px 1px rgba(0,0,0,.3);","}",".blocklyDropDownContent {", -"max-height: 300px;","overflow: auto;","overflow-x: hidden;","position: relative;","}",".blocklyDropDownArrow {","position: absolute;","left: 0;","top: 0;","width: 16px;","height: 16px;","z-index: -1;","background-color: inherit;","border-color: inherit;","}",".blocklyDropDownButton {","display: inline-block;","float: left;","padding: 0;","margin: 4px;","border-radius: 4px;","outline: none;","border: 1px solid;","transition: box-shadow .1s;","cursor: pointer;","}",".blocklyArrowTop {","border-top: 1px solid;", -"border-left: 1px solid;","border-top-left-radius: 4px;","border-color: inherit;","}",".blocklyArrowBottom {","border-bottom: 1px solid;","border-right: 1px solid;","border-bottom-right-radius: 4px;","border-color: inherit;","}",".blocklyResizeSE {","cursor: se-resize;","fill: #aaa;","}",".blocklyResizeSW {","cursor: sw-resize;","fill: #aaa;","}",".blocklyResizeLine {","stroke: #515A5A;","stroke-width: 1;","}",".blocklyHighlightedConnectionPath {","fill: none;","stroke: #fc3;","stroke-width: 4px;", -"}",".blocklyPathLight {","fill: none;","stroke-linecap: round;","stroke-width: 1;","}",".blocklySelected>.blocklyPathLight {","display: none;","}",".blocklyDraggable {",'cursor: url("<<>>/handopen.cur"), auto;',"cursor: grab;","cursor: -webkit-grab;","}",".blocklyDragging {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyDraggable:active {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;", -"}",".blocklyBlockDragSurface .blocklyDraggable {",'cursor: url("<<>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","}",".blocklyDragging.blocklyDraggingDelete {",'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {","fill-opacity: .8;","stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {","display: none;","}",".blocklyDisabled>.blocklyPath {","fill-opacity: .5;","stroke-opacity: .5;", -"}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {","display: none;","}",".blocklyInsertionMarker>.blocklyPath,",".blocklyInsertionMarker>.blocklyPathLight,",".blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: .2;","stroke: none;","}",".blocklyMultilineText {","font-family: monospace;","}",".blocklyNonEditableText>text {","pointer-events: none;","}",".blocklyFlyout {","position: absolute;","z-index: 20;","}",".blocklyText text {","cursor: default;","}",".blocklySvg text,", -".blocklyBlockDragSurface text {","user-select: none;","-ms-user-select: none;","-webkit-user-select: none;","cursor: inherit;","}",".blocklyHidden {","display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {","display: block;","}",".blocklyIconGroup {","cursor: default;","}",".blocklyIconGroup:not(:hover),",".blocklyIconGroupReadonly {","opacity: .6;","}",".blocklyIconShape {","fill: #00f;","stroke: #fff;","stroke-width: 1px;","}",".blocklyIconSymbol {","fill: #fff;","}",".blocklyMinimalBody {", -"margin: 0;","padding: 0;","}",".blocklyHtmlInput {","border: none;","border-radius: 4px;","height: 100%;","margin: 0;","outline: none;","padding: 0;","width: 100%;","text-align: center;","display: block;","box-sizing: border-box;","}",".blocklyHtmlInput::-ms-clear {","display: none;","}",".blocklyMainBackground {","stroke-width: 1;","stroke: #c6c6c6;","}",".blocklyMutatorBackground {","fill: #fff;","stroke: #ddd;","stroke-width: 1;","}",".blocklyFlyoutBackground {","fill: #ddd;","fill-opacity: .8;", -"}",".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal,",".blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,", -".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".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 {","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(<<>>/sprites.png) no-repeat -48px -16px;","float: left;","margin-left: -24px;","position: static;","}",".blocklyMenuItemRtl .blocklyMenuItemCheckbox {","float: right;","margin-right: -24px;","}"];Blockly.Grid=function(a,b){this.gridPattern_=a;this.spacing_=b.spacing;this.length_=b.length;this.line2_=(this.line1_=a.firstChild)&&this.line1_.nextSibling;this.snapToGrid_=b.snap};Blockly.Grid.prototype.scale_=1;Blockly.Grid.prototype.dispose=function(){this.gridPattern_=null};Blockly.Grid.prototype.shouldSnap=function(){return this.snapToGrid_};Blockly.Grid.prototype.getSpacing=function(){return this.spacing_};Blockly.Grid.prototype.getPatternId=function(){return this.gridPattern_.id}; -Blockly.Grid.prototype.update=function(a){this.scale_=a;var b=this.spacing_*a||100;this.gridPattern_.setAttribute("width",b);this.gridPattern_.setAttribute("height",b);b=Math.floor(this.spacing_/2)+.5;var c=b-this.length_/2,d=b+this.length_/2;b*=a;c*=a;d*=a;this.setLineAttributes_(this.line1_,a,c,d,b,b);this.setLineAttributes_(this.line2_,a,b,b,c,d)}; -Blockly.Grid.prototype.setLineAttributes_=function(a,b,c,d,e,f){a&&(a.setAttribute("stroke-width",b),a.setAttribute("x1",c),a.setAttribute("y1",e),a.setAttribute("x2",d),a.setAttribute("y2",f))};Blockly.Grid.prototype.moveTo=function(a,b){this.gridPattern_.setAttribute("x",a);this.gridPattern_.setAttribute("y",b);(Blockly.utils.userAgent.IE||Blockly.utils.userAgent.EDGE)&&this.update(this.scale_)}; -Blockly.Grid.createDom=function(a,b,c){a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATTERN,{id:"blocklyGridPattern"+a,patternUnits:"userSpaceOnUse"},c);0 document.");}else a=null;return a};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.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={};void 0===c.scrollbars&&void 0===a.scrollbars?d.scrollbars=b:"object"==typeof c.scrollbars?(d.scrollbars={},d.scrollbars.horizontal=!!c.scrollbars.horizontal,d.scrollbars.vertical=!!c.scrollbars.vertical,d.scrollbars.horizontal&&d.scrollbars.vertical?d.scrollbars=!0:d.scrollbars.horizontal||d.scrollbars.vertical||(d.scrollbars=!1)):d.scrollbars=!!c.scrollbars||!!a.scrollbars;d.wheel=d.scrollbars&&void 0!==c.wheel?!!c.wheel:"object"== -typeof d.scrollbars;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=a||isNaN(a)?0:Math.min(a,this.scrollbarLength_)};Blockly.Scrollbar.prototype.setHandleLength_=function(a){this.handleLength_=a;this.svgHandle_.setAttribute(this.lengthAttribute_,this.handleLength_)};Blockly.Scrollbar.prototype.constrainHandlePosition_=function(a){return a=0>=a||isNaN(a)?0:Math.min(a,this.scrollbarLength_-this.handleLength_)}; -Blockly.Scrollbar.prototype.setHandlePosition=function(a){this.handlePosition_=a;this.svgHandle_.setAttribute(this.positionAttribute_,this.handlePosition_)};Blockly.Scrollbar.prototype.setScrollbarLength_=function(a){this.scrollbarLength_=a;this.outerSvg_.setAttribute(this.lengthAttribute_,this.scrollbarLength_);this.svgBackground_.setAttribute(this.lengthAttribute_,this.scrollbarLength_)}; -Blockly.Scrollbar.prototype.setPosition=function(a,b){this.position.x=a;this.position.y=b;Blockly.utils.dom.setCssTransform(this.outerSvg_,"translate("+(this.position.x+this.origin_.x)+"px,"+(this.position.y+this.origin_.y)+"px)")}; -Blockly.Scrollbar.prototype.resize=function(a){if(!a&&(a=this.workspace_.getMetrics(),!a))return;this.oldHostMetrics_&&Blockly.Scrollbar.metricsAreEquivalent_(a,this.oldHostMetrics_)||(this.horizontal_?this.resizeHorizontal_(a):this.resizeVertical_(a),this.oldHostMetrics_=a,this.updateMetrics_())}; -Blockly.Scrollbar.prototype.requiresViewResize_=function(a){return this.oldHostMetrics_?this.oldHostMetrics_.viewWidth!==a.viewWidth||this.oldHostMetrics_.viewHeight!==a.viewHeight||this.oldHostMetrics_.absoluteLeft!==a.absoluteLeft||this.oldHostMetrics_.absoluteTop!==a.absoluteTop:!0};Blockly.Scrollbar.prototype.resizeHorizontal_=function(a){this.requiresViewResize_(a)?this.resizeViewHorizontal(a):this.resizeContentHorizontal(a)}; -Blockly.Scrollbar.prototype.resizeViewHorizontal=function(a){var b=a.viewWidth-2*this.margin_;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollbarLength_(Math.max(0,b));b=a.absoluteLeft+this.margin_;this.pair_&&this.workspace_.RTL&&(b+=Blockly.Scrollbar.scrollbarThickness);this.setPosition(b,a.absoluteTop+a.viewHeight-Blockly.Scrollbar.scrollbarThickness-this.margin_);this.resizeContentHorizontal(a)}; -Blockly.Scrollbar.prototype.resizeContentHorizontal=function(a){if(a.viewWidth>=a.scrollWidth)this.setHandleLength_(this.scrollbarLength_),this.setHandlePosition(0),this.pair_||this.setVisible(!1);else{this.pair_||this.setVisible(!0);var b=this.scrollbarLength_*a.viewWidth/a.scrollWidth;b=this.constrainHandleLength_(b);this.setHandleLength_(b);b=a.scrollWidth-a.viewWidth;var c=this.scrollbarLength_-this.handleLength_;a=(a.viewLeft-a.scrollLeft)/b*c;a=this.constrainHandlePosition_(a);this.setHandlePosition(a); -this.ratio=c/b}};Blockly.Scrollbar.prototype.resizeVertical_=function(a){this.requiresViewResize_(a)?this.resizeViewVertical(a):this.resizeContentVertical(a)}; -Blockly.Scrollbar.prototype.resizeViewVertical=function(a){var b=a.viewHeight-2*this.margin_;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollbarLength_(Math.max(0,b));this.setPosition(this.workspace_.RTL?a.absoluteLeft+this.margin_:a.absoluteLeft+a.viewWidth-Blockly.Scrollbar.scrollbarThickness-this.margin_,a.absoluteTop+this.margin_);this.resizeContentVertical(a)}; -Blockly.Scrollbar.prototype.resizeContentVertical=function(a){if(a.viewHeight>=a.scrollHeight)this.setHandleLength_(this.scrollbarLength_),this.setHandlePosition(0),this.pair_||this.setVisible(!1);else{this.pair_||this.setVisible(!0);var b=this.scrollbarLength_*a.viewHeight/a.scrollHeight;b=this.constrainHandleLength_(b);this.setHandleLength_(b);b=a.scrollHeight-a.viewHeight;var c=this.scrollbarLength_-this.handleLength_;a=(a.viewTop-a.scrollTop)/b*c;a=this.constrainHandlePosition_(a);this.setHandlePosition(a); -this.ratio=c/b}}; -Blockly.Scrollbar.prototype.createDom_=function(a){var b="blocklyScrollbar"+(this.horizontal_?"Horizontal":"Vertical");a&&(b+=" "+a);this.outerSvg_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.SVG,{"class":b},null);this.svgGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{},this.outerSvg_);this.svgBackground_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyScrollbarBackground"},this.svgGroup_);a=Math.floor((Blockly.Scrollbar.scrollbarThickness-5)/2); -this.svgHandle_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyScrollbarHandle",rx:a,ry:a},this.svgGroup_);this.workspace_.getThemeManager().subscribe(this.svgHandle_,"scrollbarColour","fill");this.workspace_.getThemeManager().subscribe(this.svgHandle_,"scrollbarOpacity","fill-opacity");Blockly.utils.dom.insertAfter(this.outerSvg_,this.workspace_.getParentSvg())};Blockly.Scrollbar.prototype.isVisible=function(){return this.isVisible_}; -Blockly.Scrollbar.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};Blockly.Scrollbar.prototype.setVisible=function(a){var b=a!=this.isVisible();if(this.pair_)throw Error("Unable to toggle visibility of paired scrollbars.");this.isVisible_=a;b&&this.updateDisplay_()}; -Blockly.Scrollbar.prototype.updateDisplay_=function(){this.containerVisible_&&this.isVisible()?this.outerSvg_.setAttribute("display","block"):this.outerSvg_.setAttribute("display","none")}; -Blockly.Scrollbar.prototype.onMouseDownBar_=function(a){this.workspace_.markFocused();Blockly.Touch.clearTouchIdentifier();this.cleanUp_();if(Blockly.utils.isRightButton(a))a.stopPropagation();else{var b=Blockly.utils.mouseToSvg(a,this.workspace_.getParentSvg(),this.workspace_.getInverseScreenCTM());b=this.horizontal_?b.x:b.y;var c=Blockly.utils.getInjectionDivXY_(this.svgHandle_);c=this.horizontal_?c.x:c.y;var d=this.handlePosition_,e=.95*this.handleLength_;b<=c?d-=e:b>=c+this.handleLength_&&(d+= -e);this.setHandlePosition(this.constrainHandlePosition_(d));this.updateMetrics_();a.stopPropagation();a.preventDefault()}}; -Blockly.Scrollbar.prototype.onMouseDownHandle_=function(a){this.workspace_.markFocused();this.cleanUp_();Blockly.utils.isRightButton(a)?a.stopPropagation():(this.startDragHandle=this.handlePosition_,this.workspace_.setupDragSurface(),this.startDragMouse_=this.horizontal_?a.clientX:a.clientY,Blockly.Scrollbar.onMouseUpWrapper_=Blockly.browserEvents.conditionalBind(document,"mouseup",this,this.onMouseUpHandle_),Blockly.Scrollbar.onMouseMoveWrapper_=Blockly.browserEvents.conditionalBind(document,"mousemove", -this,this.onMouseMoveHandle_),a.stopPropagation(),a.preventDefault())};Blockly.Scrollbar.prototype.onMouseMoveHandle_=function(a){this.setHandlePosition(this.constrainHandlePosition_(this.startDragHandle+((this.horizontal_?a.clientX:a.clientY)-this.startDragMouse_)));this.updateMetrics_()};Blockly.Scrollbar.prototype.onMouseUpHandle_=function(){this.workspace_.resetDragSurface();Blockly.Touch.clearTouchIdentifier();this.cleanUp_()}; -Blockly.Scrollbar.prototype.cleanUp_=function(){Blockly.hideChaff(!0);Blockly.Scrollbar.onMouseUpWrapper_&&(Blockly.browserEvents.unbind(Blockly.Scrollbar.onMouseUpWrapper_),Blockly.Scrollbar.onMouseUpWrapper_=null);Blockly.Scrollbar.onMouseMoveWrapper_&&(Blockly.browserEvents.unbind(Blockly.Scrollbar.onMouseMoveWrapper_),Blockly.Scrollbar.onMouseMoveWrapper_=null)}; -Blockly.Scrollbar.prototype.getRatio_=function(){var a=this.handlePosition_/(this.scrollbarLength_-this.handleLength_);isNaN(a)&&(a=0);return a};Blockly.Scrollbar.prototype.updateMetrics_=function(){var a=this.getRatio_(),b={};this.horizontal_?b.x=a:b.y=a;this.workspace_.setMetrics(b)};Blockly.Scrollbar.prototype.set=function(a,b){this.setHandlePosition(this.constrainHandlePosition_(a*this.ratio));(b||void 0===b)&&this.updateMetrics_()}; -Blockly.Scrollbar.prototype.setOrigin=function(a,b){this.origin_=new Blockly.utils.Coordinate(a,b)};Blockly.Tooltip={};Blockly.Tooltip.visible=!1;Blockly.Tooltip.blocked_=!1;Blockly.Tooltip.LIMIT=50;Blockly.Tooltip.mouseOutPid_=0;Blockly.Tooltip.showPid_=0;Blockly.Tooltip.lastX_=0;Blockly.Tooltip.lastY_=0;Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.OFFSET_X=0;Blockly.Tooltip.OFFSET_Y=10;Blockly.Tooltip.RADIUS_OK=10;Blockly.Tooltip.HOVER_MS=750;Blockly.Tooltip.MARGINS=5;Blockly.Tooltip.DIV=null; -Blockly.Tooltip.getTooltipOfObject=function(a){if(a=Blockly.Tooltip.getTargetObject_(a)){for(a=a.tooltip;"function"==typeof a;)a=a();if("string"!=typeof a)throw Error("Tooltip function must return a string.");return a}return""};Blockly.Tooltip.getTargetObject_=function(a){for(;a&&a.tooltip;){if("string"==typeof a.tooltip||"function"==typeof a.tooltip)return a;a=a.tooltip}return null}; -Blockly.Tooltip.createDom=function(){Blockly.Tooltip.DIV||(Blockly.Tooltip.DIV=document.createElement("div"),Blockly.Tooltip.DIV.className="blocklyTooltipDiv",(Blockly.parentContainer||document.body).appendChild(Blockly.Tooltip.DIV))}; -Blockly.Tooltip.bindMouseEvents=function(a){a.mouseOverWrapper_=Blockly.browserEvents.bind(a,"mouseover",null,Blockly.Tooltip.onMouseOver_);a.mouseOutWrapper_=Blockly.browserEvents.bind(a,"mouseout",null,Blockly.Tooltip.onMouseOut_);a.addEventListener("mousemove",Blockly.Tooltip.onMouseMove_,!1)};Blockly.Tooltip.unbindMouseEvents=function(a){a&&(Blockly.browserEvents.unbind(a.mouseOverWrapper_),Blockly.browserEvents.unbind(a.mouseOutWrapper_),a.removeEventListener("mousemove",Blockly.Tooltip.onMouseMove_))}; -Blockly.Tooltip.onMouseOver_=function(a){Blockly.Tooltip.blocked_||(a=Blockly.Tooltip.getTargetObject_(a.currentTarget),Blockly.Tooltip.element_!=a&&(Blockly.Tooltip.hide(),Blockly.Tooltip.poisonedElement_=null,Blockly.Tooltip.element_=a),clearTimeout(Blockly.Tooltip.mouseOutPid_))};Blockly.Tooltip.onMouseOut_=function(a){Blockly.Tooltip.blocked_||(Blockly.Tooltip.mouseOutPid_=setTimeout(function(){Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.hide()},1),clearTimeout(Blockly.Tooltip.showPid_))}; -Blockly.Tooltip.onMouseMove_=function(a){if(Blockly.Tooltip.element_&&Blockly.Tooltip.element_.tooltip&&!Blockly.Tooltip.blocked_)if(Blockly.Tooltip.visible){var b=Blockly.Tooltip.lastX_-a.pageX;a=Blockly.Tooltip.lastY_-a.pageY;Math.sqrt(b*b+a*a)>Blockly.Tooltip.RADIUS_OK&&Blockly.Tooltip.hide()}else Blockly.Tooltip.poisonedElement_!=Blockly.Tooltip.element_&&(clearTimeout(Blockly.Tooltip.showPid_),Blockly.Tooltip.lastX_=a.pageX,Blockly.Tooltip.lastY_=a.pageY,Blockly.Tooltip.showPid_=setTimeout(Blockly.Tooltip.show_, -Blockly.Tooltip.HOVER_MS))};Blockly.Tooltip.dispose=function(){Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.hide()};Blockly.Tooltip.hide=function(){Blockly.Tooltip.visible&&(Blockly.Tooltip.visible=!1,Blockly.Tooltip.DIV&&(Blockly.Tooltip.DIV.style.display="none"));Blockly.Tooltip.showPid_&&clearTimeout(Blockly.Tooltip.showPid_)};Blockly.Tooltip.block=function(){Blockly.Tooltip.hide();Blockly.Tooltip.blocked_=!0}; -Blockly.Tooltip.unblock=function(){Blockly.Tooltip.blocked_=!1}; -Blockly.Tooltip.show_=function(){if(!Blockly.Tooltip.blocked_&&(Blockly.Tooltip.poisonedElement_=Blockly.Tooltip.element_,Blockly.Tooltip.DIV)){Blockly.Tooltip.DIV.textContent="";var a=Blockly.Tooltip.getTooltipOfObject(Blockly.Tooltip.element_);a=Blockly.utils.string.wrap(a,Blockly.Tooltip.LIMIT);a=a.split("\n");for(var b=0;bc+window.scrollY&&(e-=Blockly.Tooltip.DIV.offsetHeight+2*Blockly.Tooltip.OFFSET_Y);a?d=Math.max(Blockly.Tooltip.MARGINS-window.scrollX, -d):d+Blockly.Tooltip.DIV.offsetWidth>b+window.scrollX-2*Blockly.Tooltip.MARGINS&&(d=b-Blockly.Tooltip.DIV.offsetWidth-2*Blockly.Tooltip.MARGINS);Blockly.Tooltip.DIV.style.top=e+"px";Blockly.Tooltip.DIV.style.left=d+"px"}};Blockly.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.IASTNodeLocation=function(){};Blockly.IASTNodeLocationSvg=function(){};Blockly.IASTNodeLocationWithBlock=function(){};Blockly.IKeyboardAccessible=function(){};Blockly.utils.deprecation={};Blockly.utils.deprecation.warn=function(a,b,c,d){a=a+" was deprecated on "+b+" and will be deleted on "+c+".";d&&(a+="\nUse "+d+" instead.");console.warn(a)};Blockly.Connection=function(a,b){this.sourceBlock_=a;this.type=b};Blockly.Connection.CAN_CONNECT=0;Blockly.Connection.REASON_SELF_CONNECTION=1;Blockly.Connection.REASON_WRONG_TYPE=2;Blockly.Connection.REASON_TARGET_NULL=3;Blockly.Connection.REASON_CHECKS_FAILED=4;Blockly.Connection.REASON_DIFFERENT_WORKSPACES=5;Blockly.Connection.REASON_SHADOW_PARENT=6;Blockly.Connection.REASON_DRAG_CHECKS_FAILED=7;Blockly.Connection.prototype.targetConnection=null;Blockly.Connection.prototype.disposed=!1; -Blockly.Connection.prototype.check_=null;Blockly.Connection.prototype.shadowDom_=null;Blockly.Connection.prototype.x=0;Blockly.Connection.prototype.y=0; -Blockly.Connection.prototype.connect_=function(a){var b=Blockly.connectionTypes.INPUT_VALUE,c=this.getSourceBlock(),d=a.getSourceBlock();a.isConnected()&&a.disconnect();if(this.isConnected()){var e=this.getShadowDom(!0);this.shadowDom_=null;var f=this.targetBlock();if(f.isShadow())f.dispose(!1);else{this.disconnect();var g=f}this.shadowDom_=e}var h;Blockly.Events.isEnabled()&&(h=new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(d));Blockly.Connection.connectReciprocally_(this,a);d.setParent(c); -h&&(h.recordNew(),Blockly.Events.fire(h));if(g)if(a=this.type===b?g.outputConnection:g.previousConnection,d=Blockly.Connection.getConnectionForOrphanedConnection(d,a))a.connect(d);else a.onFailedConnect(this)};Blockly.Connection.prototype.dispose=function(){if(this.isConnected()){this.setShadowDom(null);var a=this.targetBlock();a&&a.unplug()}this.disposed=!0};Blockly.Connection.prototype.getSourceBlock=function(){return this.sourceBlock_}; -Blockly.Connection.prototype.isSuperior=function(){return this.type==Blockly.connectionTypes.INPUT_VALUE||this.type==Blockly.connectionTypes.NEXT_STATEMENT};Blockly.Connection.prototype.isConnected=function(){return!!this.targetConnection}; -Blockly.Connection.prototype.canConnectWithReason=function(a){Blockly.utils.deprecation.warn("Connection.prototype.canConnectWithReason","July 2020","July 2021","the workspace's connection checker");return this.getConnectionChecker().canConnectWithReason(this,a,!1)}; -Blockly.Connection.prototype.checkConnection=function(a){Blockly.utils.deprecation.warn("Connection.prototype.checkConnection","July 2020","July 2021","the workspace's connection checker");var b=this.getConnectionChecker(),c=b.canConnectWithReason(this,a,!1);if(c!=Blockly.Connection.CAN_CONNECT)throw Error(b.getErrorMessage(c,this,a));};Blockly.Connection.prototype.getConnectionChecker=function(){return this.sourceBlock_.workspace.connectionChecker}; -Blockly.Connection.prototype.isConnectionAllowed=function(a){Blockly.utils.deprecation.warn("Connection.prototype.isConnectionAllowed","July 2020","July 2021","the workspace's connection checker");return this.getConnectionChecker().canConnect(this,a,!0)};Blockly.Connection.prototype.onFailedConnect=function(a){}; -Blockly.Connection.prototype.connect=function(a){if(this.targetConnection!=a&&this.getConnectionChecker().canConnect(this,a,!1)){var b=Blockly.Events.getGroup();b||Blockly.Events.setGroup(!0);this.isSuperior()?this.connect_(a):a.connect_(this);b||Blockly.Events.setGroup(!1)}};Blockly.Connection.connectReciprocally_=function(a,b){if(!a||!b)throw Error("Cannot connect null connections.");a.targetConnection=b;b.targetConnection=a}; -Blockly.Connection.getSingleConnection_=function(a,b){var c=null;b=b.outputConnection;for(var d=b.getConnectionChecker(),e=0,f;f=a.inputList[e];e++)if((f=f.connection)&&d.canConnect(b,f,!1)){if(c)return null;c=f}return c};Blockly.Connection.getConnectionForOrphanedOutput_=function(a,b){for(var c;c=Blockly.Connection.getSingleConnection_(a,b);)if(a=c.targetBlock(),!a||a.isShadow())return c;return null}; -Blockly.Connection.getConnectionForOrphanedConnection=function(a,b){if(b.type===Blockly.connectionTypes.OUTPUT_VALUE)return Blockly.Connection.getConnectionForOrphanedOutput_(a,b.getSourceBlock());a=a.lastConnectionInStack(!0);var c=b.getConnectionChecker();return a&&c.canConnect(b,a,!1)?a:null}; -Blockly.Connection.prototype.disconnect=function(){var a=this.targetConnection;if(!a)throw Error("Source connection not connected.");if(a.targetConnection!=this)throw Error("Target connection not connected to source connection.");if(this.isSuperior()){var b=this.sourceBlock_;var c=a.getSourceBlock();a=this}else b=a.getSourceBlock(),c=this.sourceBlock_;var d=Blockly.Events.getGroup();d||Blockly.Events.setGroup(!0);this.disconnectInternal_(b,c);c.isShadow()||a.respawnShadow_();d||Blockly.Events.setGroup(!1)}; -Blockly.Connection.prototype.disconnectInternal_=function(a,b){var c;Blockly.Events.isEnabled()&&(c=new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(b));this.targetConnection=this.targetConnection.targetConnection=null;b.setParent(null);c&&(c.recordNew(),Blockly.Events.fire(c))}; -Blockly.Connection.prototype.respawnShadow_=function(){var a=this.getSourceBlock(),b=this.getShadowDom();if(a.workspace&&b)if(a=Blockly.Xml.domToBlock(b,a.workspace),a.outputConnection)this.connect(a.outputConnection);else if(a.previousConnection)this.connect(a.previousConnection);else throw Error("Child block does not have output or previous statement.");};Blockly.Connection.prototype.targetBlock=function(){return this.isConnected()?this.targetConnection.getSourceBlock():null}; -Blockly.Connection.prototype.checkType=function(a){Blockly.utils.deprecation.warn("Connection.prototype.checkType","October 2019","January 2021","the workspace's connection checker");return this.getConnectionChecker().canConnect(this,a,!1)};Blockly.Connection.prototype.checkType_=function(a){Blockly.utils.deprecation.warn("Connection.prototype.checkType_","October 2019","January 2021","the workspace's connection checker");return this.checkType(a)}; -Blockly.Connection.prototype.onCheckChanged_=function(){!this.isConnected()||this.targetConnection&&this.getConnectionChecker().canConnect(this,this.targetConnection,!1)||(this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug()};Blockly.Connection.prototype.setCheck=function(a){a?(Array.isArray(a)||(a=[a]),this.check_=a,this.onCheckChanged_()):this.check_=null;return this};Blockly.Connection.prototype.getCheck=function(){return this.check_}; -Blockly.Connection.prototype.setShadowDom=function(a){this.shadowDom_=a;a=this.targetBlock();a?a.isShadow()&&(a.dispose(!1),this.respawnShadow_()):this.respawnShadow_()};Blockly.Connection.prototype.getShadowDom=function(a){return a&&this.targetBlock().isShadow()?Blockly.Xml.blockToDom(this.targetBlock()):this.shadowDom_};Blockly.Connection.prototype.neighbours=function(a){return[]}; -Blockly.Connection.prototype.getParentInput=function(){for(var a=null,b=this.sourceBlock_.inputList,c=0;cc||b.getSourceBlock().isInsertionMarker())return!1;switch(b.type){case Blockly.connectionTypes.PREVIOUS_STATEMENT:return this.canConnectToPrevious_(a,b);case Blockly.connectionTypes.OUTPUT_VALUE:if(b.isConnected()&&!b.targetBlock().isInsertionMarker()||a.isConnected())return!1;break;case Blockly.connectionTypes.INPUT_VALUE:if(b.isConnected()&&!b.targetBlock().isMovable()&&!b.targetBlock().isShadow())return!1;break; -case Blockly.connectionTypes.NEXT_STATEMENT:if(b.isConnected()&&!a.getSourceBlock().nextConnection&&!b.targetBlock().isShadow()&&b.targetBlock().nextConnection)return!1;break;default:return!1}return-1!=Blockly.draggingConnections.indexOf(b)?!1:!0};Blockly.ConnectionChecker.prototype.canConnectToPrevious_=function(a,b){if(a.targetConnection||-1!=Blockly.draggingConnections.indexOf(b))return!1;if(!b.targetConnection)return!0;a=b.targetBlock();return a.isInsertionMarker()?!a.getPreviousBlock():!1}; -Blockly.registry.register(Blockly.registry.Type.CONNECTION_CHECKER,Blockly.registry.DEFAULT,Blockly.ConnectionChecker);Blockly.VariableMap=function(a){this.variableMap_=Object.create(null);this.workspace=a};Blockly.VariableMap.prototype.clear=function(){this.variableMap_=Object.create(null)};Blockly.VariableMap.prototype.renameVariable=function(a,b){var c=this.getVariable(b,a.type),d=this.workspace.getAllBlocks(!1);Blockly.Events.setGroup(!0);try{c&&c.getId()!=a.getId()?this.renameVariableWithConflict_(a,b,c,d):this.renameVariableAndUses_(a,b,d)}finally{Blockly.Events.setGroup(!1)}}; -Blockly.VariableMap.prototype.renameVariableById=function(a,b){var c=this.getVariableById(a);if(!c)throw Error("Tried to rename a variable that didn't exist. ID: "+a);this.renameVariable(c,b)};Blockly.VariableMap.prototype.renameVariableAndUses_=function(a,b,c){Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.VAR_RENAME))(a,b));a.name=b;for(b=0;bthis.remainingCapacityOfType(c))return!1;b+=a[c]}return b>this.remainingCapacity()?!1:!0}; -Blockly.Workspace.prototype.hasBlockLimits=function(){return Infinity!=this.options.maxBlocks||!!this.options.maxInstances};Blockly.Workspace.prototype.getUndoStack=function(){return this.undoStack_};Blockly.Workspace.prototype.getRedoStack=function(){return this.redoStack_}; -Blockly.Workspace.prototype.undo=function(a){var b=a?this.redoStack_:this.undoStack_,c=a?this.undoStack_:this.redoStack_,d=b.pop();if(d){for(var e=[d];b.length&&d.group&&d.group==b[b.length-1].group;)e.push(b.pop());for(b=0;d=e[b];b++)c.push(d);e=Blockly.Events.filter(e,a);Blockly.Events.recordUndo=!1;try{for(b=0;d=e[b];b++)d.run(a)}finally{Blockly.Events.recordUndo=!0}}};Blockly.Workspace.prototype.clearUndo=function(){this.undoStack_.length=0;this.redoStack_.length=0;Blockly.Events.clearPendingUndo()}; -Blockly.Workspace.prototype.addChangeListener=function(a){this.listeners_.push(a);return a};Blockly.Workspace.prototype.removeChangeListener=function(a){Blockly.utils.arrayRemove(this.listeners_,a)};Blockly.Workspace.prototype.fireChangeListener=function(a){if(a.recordUndo)for(this.undoStack_.push(a),this.redoStack_.length=0;this.undoStack_.length>this.MAX_UNDO&&0<=this.MAX_UNDO;)this.undoStack_.shift();for(var b=0,c;c=this.listeners_[b];b++)c(a)}; -Blockly.Workspace.prototype.getBlockById=function(a){return this.blockDB_[a]||null};Blockly.Workspace.prototype.setBlockById=function(a,b){this.blockDB_[a]=b};Blockly.Workspace.prototype.removeBlockById=function(a){delete this.blockDB_[a]};Blockly.Workspace.prototype.getCommentById=function(a){return this.commentDB_[a]||null};Blockly.Workspace.prototype.allInputsFilled=function(a){for(var b=this.getTopBlocks(!1),c=0,d;d=b[c];c++)if(!d.allInputsFilled(a))return!1;return!0}; -Blockly.Workspace.prototype.getPotentialVariableMap=function(){return this.potentialVariableMap_};Blockly.Workspace.prototype.createPotentialVariableMap=function(){this.potentialVariableMap_=new Blockly.VariableMap(this)};Blockly.Workspace.prototype.getVariableMap=function(){return this.variableMap_};Blockly.Workspace.prototype.setVariableMap=function(a){this.variableMap_=a};Blockly.Workspace.WorkspaceDB_=Object.create(null); -Blockly.Workspace.getById=function(a){return Blockly.Workspace.WorkspaceDB_[a]||null};Blockly.Workspace.getAll=function(){var a=[],b;for(b in Blockly.Workspace.WorkspaceDB_)a.push(Blockly.Workspace.WorkspaceDB_[b]);return a};Blockly.WorkspaceDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.container_=null; -Blockly.WorkspaceDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=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":"blocklyWsDragSurface blocklyOverflowVisible"},null),this.container_.appendChild(this.SVG_))}; -Blockly.WorkspaceDragSurfaceSvg.prototype.translateSurface=function(a,b){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.WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation=function(){return Blockly.utils.getRelativeXY(this.SVG_)}; -Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide=function(a){if(!a)throw Error("Couldn't clear and hide the drag surface: missing new surface.");var b=this.SVG_.childNodes[0],c=this.SVG_.childNodes[1];if(!(b&&c&&Blockly.utils.dom.hasClass(b,"blocklyBlockCanvas")&&Blockly.utils.dom.hasClass(c,"blocklyBubbleCanvas")))throw Error("Couldn't clear and hide the drag surface. A node was missing.");null!=this.previousSibling_?Blockly.utils.dom.insertAfter(b,this.previousSibling_):a.insertBefore(b,a.firstChild); -Blockly.utils.dom.insertAfter(c,b);this.SVG_.style.display="none";if(this.SVG_.childNodes.length)throw Error("Drag surface was not cleared.");Blockly.utils.dom.setCssTransform(this.SVG_,"");this.previousSibling_=null}; -Blockly.WorkspaceDragSurfaceSvg.prototype.setContentsAndShow=function(a,b,c,d,e,f){if(this.SVG_.childNodes.length)throw Error("Already dragging a block.");this.previousSibling_=c;a.setAttribute("transform","translate(0, 0) scale("+f+")");b.setAttribute("transform","translate(0, 0) scale("+f+")");this.SVG_.setAttribute("width",d);this.SVG_.setAttribute("height",e);this.SVG_.appendChild(a);this.SVG_.appendChild(b);this.SVG_.style.display="block"};Blockly.blockRendering={};Blockly.blockRendering.useDebugger=!1;Blockly.blockRendering.register=function(a,b){Blockly.registry.register(Blockly.registry.Type.RENDERER,a,b)};Blockly.blockRendering.unregister=function(a){Blockly.registry.unregister(Blockly.registry.Type.RENDERER,a)};Blockly.blockRendering.startDebugger=function(){Blockly.blockRendering.useDebugger=!0};Blockly.blockRendering.stopDebugger=function(){Blockly.blockRendering.useDebugger=!1}; -Blockly.blockRendering.init=function(a,b,c){a=new (Blockly.registry.getClass(Blockly.registry.Type.RENDERER,a))(a);a.init(b,c);return a};Blockly.ASTNode=function(a,b,c){if(!b)throw Error("Cannot create a node without a location.");this.type_=a;this.isConnection_=Blockly.ASTNode.isConnectionType_(a);this.location_=b;this.wsCoordinate_=null;this.processParams_(c||null)};Blockly.ASTNode.types={FIELD:"field",BLOCK:"block",INPUT:"input",OUTPUT:"output",NEXT:"next",PREVIOUS:"previous",STACK:"stack",WORKSPACE:"workspace"};Blockly.ASTNode.NAVIGATE_ALL_FIELDS=!1;Blockly.ASTNode.DEFAULT_OFFSET_Y=-20;Blockly.ASTNode.isConnectionType_=function(a){switch(a){case Blockly.ASTNode.types.PREVIOUS:case Blockly.ASTNode.types.NEXT:case Blockly.ASTNode.types.INPUT:case Blockly.ASTNode.types.OUTPUT:return!0}return!1}; -Blockly.ASTNode.createFieldNode=function(a){return a?new Blockly.ASTNode(Blockly.ASTNode.types.FIELD,a):null}; -Blockly.ASTNode.createConnectionNode=function(a){if(!a)return null;var b=a.type;return b==Blockly.connectionTypes.INPUT_VALUE||b==Blockly.connectionTypes.NEXT_STATEMENT&&a.getParentInput()?Blockly.ASTNode.createInputNode(a.getParentInput()):b==Blockly.connectionTypes.NEXT_STATEMENT?new Blockly.ASTNode(Blockly.ASTNode.types.NEXT,a):b==Blockly.connectionTypes.OUTPUT_VALUE?new Blockly.ASTNode(Blockly.ASTNode.types.OUTPUT,a):b==Blockly.connectionTypes.PREVIOUS_STATEMENT?new Blockly.ASTNode(Blockly.ASTNode.types.PREVIOUS, -a):null};Blockly.ASTNode.createInputNode=function(a){return a&&a.connection?new Blockly.ASTNode(Blockly.ASTNode.types.INPUT,a.connection):null};Blockly.ASTNode.createBlockNode=function(a){return a?new Blockly.ASTNode(Blockly.ASTNode.types.BLOCK,a):null};Blockly.ASTNode.createStackNode=function(a){return a?new Blockly.ASTNode(Blockly.ASTNode.types.STACK,a):null};Blockly.ASTNode.createWorkspaceNode=function(a,b){return b&&a?new Blockly.ASTNode(Blockly.ASTNode.types.WORKSPACE,a,{wsCoordinate:b}):null}; -Blockly.ASTNode.createTopNode=function(a){var b=a.previousConnection||a.outputConnection;return b?Blockly.ASTNode.createConnectionNode(b):Blockly.ASTNode.createBlockNode(a)};Blockly.ASTNode.prototype.processParams_=function(a){a&&a.wsCoordinate&&(this.wsCoordinate_=a.wsCoordinate)};Blockly.ASTNode.prototype.getLocation=function(){return this.location_};Blockly.ASTNode.prototype.getType=function(){return this.type_};Blockly.ASTNode.prototype.getWsCoordinate=function(){return this.wsCoordinate_}; -Blockly.ASTNode.prototype.isConnection=function(){return this.isConnection_};Blockly.ASTNode.prototype.findNextForInput_=function(){var a=this.location_.getParentInput(),b=a.getSourceBlock();a=b.inputList.indexOf(a)+1;for(var c;c=b.inputList[a];a++){for(var d=c.fieldRow,e=0,f;f=d[e];e++)if(f.isClickable()||Blockly.ASTNode.NAVIGATE_ALL_FIELDS)return Blockly.ASTNode.createFieldNode(f);if(c.connection)return Blockly.ASTNode.createInputNode(c)}return null}; -Blockly.ASTNode.prototype.findNextForField_=function(){var a=this.location_,b=a.getParentInput(),c=a.getSourceBlock(),d=c.inputList.indexOf(b);for(a=b.fieldRow.indexOf(a)+1;b=c.inputList[d];d++){for(var e=b.fieldRow;ac)){var d=b.getSvgXY(a.getSvgRoot());a.outputConnection?(d.x+=(a.RTL?3:-3)*c,d.y+=13*c):a.previousConnection&&(d.x+=(a.RTL?-23:23)*c,d.y+=3*c);a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CIRCLE,{cx:d.x,cy:d.y,r:0,fill:"none",stroke:"#888","stroke-width":10},b.getParentSvg());Blockly.blockAnimations.connectionUiStep_(a,new Date,c)}}; -Blockly.blockAnimations.connectionUiStep_=function(a,b,c){var d=(new Date-b)/150;1a.workspace.scale)){var b=a.getHeightWidth().height;b=Math.atan(10/b)/Math.PI*180;a.RTL||(b*=-1);Blockly.blockAnimations.disconnectUiStep_(a.getSvgRoot(),b,new Date)}}; -Blockly.blockAnimations.disconnectUiStep_=function(a,b,c){var d=(new Date-c)/200;1b-Blockly.CURRENT_CONNECTION_PREFERENCE)}if(this.localConnection_||this.closestConnection_)console.error("Only one of localConnection_ and closestConnection_ was set."); -else return!0}else return!(!this.localConnection_||!this.closestConnection_);console.error("Returning true from shouldUpdatePreviews, but it's not clear why.");return!0};Blockly.InsertionMarkerManager.prototype.getCandidate_=function(a){for(var b=this.getStartRadius_(),c=null,d=null,e=0;ea.width)return b;if(this.workspace_.RTL)var c=this.anchorXY_.x-b,d=c-this.width_,e=a.left+a.width,f=a.left+Blockly.Scrollbar.scrollbarThickness/this.workspace_.scale;else d=b+this.anchorXY_.x,c=d+this.width_,f=a.left,e=a.left+a.width-Blockly.Scrollbar.scrollbarThickness/this.workspace_.scale;this.workspace_.RTL?de&&(b=-(e-this.anchorXY_.x)):de&&(b=e-this.anchorXY_.x-this.width_);return b};Blockly.Bubble.prototype.getOptimalRelativeTop_=function(a){var b=-this.height_/4;if(this.height_>a.height)return b;var c=this.anchorXY_.y+b,d=c+this.height_,e=a.top;a=a.top+a.height-Blockly.Scrollbar.scrollbarThickness/this.workspace_.scale;var f=this.anchorXY_.y;ca&&(b=a-f-this.height_);return b}; -Blockly.Bubble.prototype.positionBubble_=function(){var a=this.anchorXY_.x;a=this.workspace_.RTL?a-(this.relativeLeft_+this.width_):a+this.relativeLeft_;this.moveTo(a,this.relativeTop_+this.anchorXY_.y)};Blockly.Bubble.prototype.moveTo=function(a,b){this.bubbleGroup_.setAttribute("transform","translate("+a+","+b+")")};Blockly.Bubble.prototype.setDragging=function(a){!a&&this.moveCallback_&&this.moveCallback_()}; -Blockly.Bubble.prototype.getBubbleSize=function(){return new Blockly.utils.Size(this.width_,this.height_)}; -Blockly.Bubble.prototype.setBubbleSize=function(a,b){var c=2*Blockly.Bubble.BORDER_WIDTH;a=Math.max(a,c+45);b=Math.max(b,c+20);this.width_=a;this.height_=b;this.bubbleBack_.setAttribute("width",a);this.bubbleBack_.setAttribute("height",b);this.resizeGroup_&&(this.workspace_.RTL?this.resizeGroup_.setAttribute("transform","translate("+2*Blockly.Bubble.BORDER_WIDTH+","+(b-c)+") scale(-1 1)"):this.resizeGroup_.setAttribute("transform","translate("+(a-c)+","+(b-c)+")"));this.autoLayout_&&this.layoutBubble_(); -this.positionBubble_();this.renderArrow_();this.resizeCallback_&&this.resizeCallback_()}; -Blockly.Bubble.prototype.renderArrow_=function(){var a=[],b=this.width_/2,c=this.height_/2,d=-this.relativeLeft_,e=-this.relativeTop_;if(b==d&&c==e)a.push("M "+b+","+c);else{e-=c;d-=b;this.workspace_.RTL&&(d*=-1);var f=Math.sqrt(e*e+d*d),g=Math.acos(d/f);0>e&&(g=2*Math.PI-g);var h=g+Math.PI/2;h>2*Math.PI&&(h-=2*Math.PI);var k=Math.sin(h),l=Math.cos(h),m=this.getBubbleSize();h=(m.width+m.height)/Blockly.Bubble.ARROW_THICKNESS;h=Math.min(h,m.width,m.height)/4;m=1-Blockly.Bubble.ANCHOR_RADIUS/f;d=b+ -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.browserEvents.unbind(this.onMouseDownBubbleWrapper_);this.onMouseDownResizeWrapper_&&Blockly.browserEvents.unbind(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.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(this.flyout_?Blockly.FLYOUT_DRAG_RADIUS:Blockly.DRAG_RADIUS)}; -Blockly.Gesture.prototype.updateIsDraggingFromFlyout_=function(){return this.targetBlock_&&this.flyout_.isBlockCreatable_(this.targetBlock_)?!this.flyout_.isScrollable()||this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)?(this.startWorkspace_=this.flyout_.targetWorkspace,this.startWorkspace_.updateScreenCalculationsIfScrolled(),Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.startBlock_=null,this.targetBlock_=this.flyout_.createBlock(this.targetBlock_),this.targetBlock_.select(), -!0):!1:!1};Blockly.Gesture.prototype.updateIsDraggingBubble_=function(){if(!this.startBubble_)return!1;this.isDraggingBubble_=!0;this.startDraggingBubble_();return!0};Blockly.Gesture.prototype.updateIsDraggingBlock_=function(){if(!this.targetBlock_)return!1;this.flyout_?this.isDraggingBlock_=this.updateIsDraggingFromFlyout_():this.targetBlock_.isMovable()&&(this.isDraggingBlock_=!0);return this.isDraggingBlock_?(this.startDraggingBlock_(),!0):!1}; -Blockly.Gesture.prototype.updateIsDraggingWorkspace_=function(){if(this.flyout_?this.flyout_.isScrollable():this.startWorkspace_&&this.startWorkspace_.isDraggable())this.workspaceDragger_=new Blockly.WorkspaceDragger(this.startWorkspace_),this.isDraggingWorkspace_=!0,this.workspaceDragger_.startDrag()}; -Blockly.Gesture.prototype.updateIsDragging_=function(){if(this.calledUpdateIsDragging_)throw Error("updateIsDragging_ should only be called once per gesture.");this.calledUpdateIsDragging_=!0;this.updateIsDraggingBubble_()||this.updateIsDraggingBlock_()||this.updateIsDraggingWorkspace_()}; -Blockly.Gesture.prototype.startDraggingBlock_=function(){this.blockDragger_=new (Blockly.registry.getClassFromOptions(Blockly.registry.Type.BLOCK_DRAGGER,this.creatorWorkspace_.options,!0))(this.targetBlock_,this.startWorkspace_);this.blockDragger_.startDrag(this.currentDragDeltaXY_,this.healStack_);this.blockDragger_.drag(this.mostRecentEvent_,this.currentDragDeltaXY_)}; -Blockly.Gesture.prototype.startDraggingBubble_=function(){this.bubbleDragger_=new Blockly.BubbleDragger(this.startBubble_,this.startWorkspace_);this.bubbleDragger_.startBubbleDrag();this.bubbleDragger_.dragBubble(this.mostRecentEvent_,this.currentDragDeltaXY_)}; -Blockly.Gesture.prototype.doStart=function(a){Blockly.utils.isTargetInput(a)?this.cancel():(this.hasStarted_=!0,Blockly.blockAnimations.disconnectUiStop(),this.startWorkspace_.updateScreenCalculationsIfScrolled(),this.startWorkspace_.isMutator&&this.startWorkspace_.resize(),Blockly.hideChaff(!!this.flyout_),this.startWorkspace_.markFocused(),this.mostRecentEvent_=a,Blockly.Tooltip.block(),this.targetBlock_&&this.targetBlock_.select(),Blockly.utils.isRightButton(a)?this.handleRightClick(a):("touchstart"!= -a.type.toLowerCase()&&"pointerdown"!=a.type.toLowerCase()||"mouse"==a.pointerType||Blockly.longStart(a,this),this.mouseDownXY_=new Blockly.utils.Coordinate(a.clientX,a.clientY),this.healStack_=a.altKey||a.ctrlKey||a.metaKey,this.bindMouseEvents(a)))}; -Blockly.Gesture.prototype.bindMouseEvents=function(a){this.onMoveWrapper_=Blockly.browserEvents.conditionalBind(document,"mousemove",null,this.handleMove.bind(this));this.onUpWrapper_=Blockly.browserEvents.conditionalBind(document,"mouseup",null,this.handleUp.bind(this));a.preventDefault();a.stopPropagation()}; -Blockly.Gesture.prototype.handleMove=function(a){this.updateFromEvent_(a);this.isDraggingWorkspace_?this.workspaceDragger_.drag(this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.drag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingBubble_&&this.bubbleDragger_.dragBubble(this.mostRecentEvent_,this.currentDragDeltaXY_);a.preventDefault();a.stopPropagation()}; -Blockly.Gesture.prototype.handleUp=function(a){this.updateFromEvent_(a);Blockly.longStop_();this.isEnding_?console.log("Trying to end a gesture recursively."):(this.isEnding_=!0,this.isDraggingBubble_?this.bubbleDragger_.endBubbleDrag(a,this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.endDrag(a,this.currentDragDeltaXY_):this.isDraggingWorkspace_?this.workspaceDragger_.endDrag(this.currentDragDeltaXY_):this.isBubbleClick_()?this.doBubbleClick_():this.isFieldClick_()?this.doFieldClick_(): -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_.endDrag(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)};Blockly.Gesture.prototype.fireWorkspaceClick_=function(a){Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.CLICK))(null,a.id,"workspace"))}; -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(){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.get(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){a=this.creatorWorkspace_;Blockly.selected&&Blockly.selected.unselect();this.fireWorkspaceClick_(this.startWorkspace_||a)};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_}; -Blockly.Gesture.prototype.isBlockClick_=function(){return!!this.startBlock_&&!this.hasExceededDragRadius_&&!this.isFieldClick_()};Blockly.Gesture.prototype.isFieldClick_=function(){return(this.startField_?this.startField_.isClickable():!1)&&!this.hasExceededDragRadius_&&(!this.flyout_||!this.flyout_.autoClose)};Blockly.Gesture.prototype.isWorkspaceClick_=function(){return!this.startBlock_&&!this.startBubble_&&!this.startField_&&!this.hasExceededDragRadius_}; -Blockly.Gesture.prototype.isDragging=function(){return this.isDraggingWorkspace_||this.isDraggingBlock_||this.isDraggingBubble_};Blockly.Gesture.prototype.hasStarted=function(){return this.hasStarted_};Blockly.Gesture.prototype.getInsertionMarkers=function(){return this.blockDragger_?this.blockDragger_.getInsertionMarkers():[]}; -Blockly.Gesture.prototype.getCurrentDragger=function(){return this.isDraggingBlock_?this.blockDragger_:this.isDraggingWorkspace_?this.workspaceDragger_:this.isDraggingBubble_?this.bubbleDragger_:null};Blockly.Gesture.inProgress=function(){for(var a=Blockly.Workspace.getAll(),b=0,c;c=a[b];b++)if(c.currentGesture_)return!0;return!1};Blockly.IRegistrable=function(){};Blockly.Marker=function(){this.drawer_=this.curNode_=this.colour=null;this.type="marker"};Blockly.Marker.prototype.setDrawer=function(a){this.drawer_=a};Blockly.Marker.prototype.getDrawer=function(){return this.drawer_};Blockly.Marker.prototype.getCurNode=function(){return this.curNode_};Blockly.Marker.prototype.setCurNode=function(a){var b=this.curNode_;this.curNode_=a;this.drawer_&&this.drawer_.draw(b,this.curNode_)}; -Blockly.Marker.prototype.draw=function(){this.drawer_&&this.drawer_.draw(this.curNode_,this.curNode_)};Blockly.Marker.prototype.hide=function(){this.drawer_&&this.drawer_.hide()};Blockly.Marker.prototype.dispose=function(){this.getDrawer()&&this.getDrawer().dispose()};Blockly.Cursor=function(){Blockly.Cursor.superClass_.constructor.call(this);this.type="cursor"};Blockly.utils.object.inherits(Blockly.Cursor,Blockly.Marker);Blockly.Cursor.prototype.next=function(){var a=this.getCurNode();if(!a)return null;for(a=a.next();a&&a.next()&&(a.getType()==Blockly.ASTNode.types.NEXT||a.getType()==Blockly.ASTNode.types.BLOCK);)a=a.next();a&&this.setCurNode(a);return a}; -Blockly.Cursor.prototype.in=function(){var a=this.getCurNode();if(!a)return null;if(a.getType()==Blockly.ASTNode.types.PREVIOUS||a.getType()==Blockly.ASTNode.types.OUTPUT)a=a.next();(a=a.in())&&this.setCurNode(a);return a};Blockly.Cursor.prototype.prev=function(){var a=this.getCurNode();if(!a)return null;for(a=a.prev();a&&a.prev()&&(a.getType()==Blockly.ASTNode.types.NEXT||a.getType()==Blockly.ASTNode.types.BLOCK);)a=a.prev();a&&this.setCurNode(a);return a}; -Blockly.Cursor.prototype.out=function(){var a=this.getCurNode();if(!a)return null;(a=a.out())&&a.getType()==Blockly.ASTNode.types.BLOCK&&(a=a.prev()||a);a&&this.setCurNode(a);return a};Blockly.registry.register(Blockly.registry.Type.CURSOR,Blockly.registry.DEFAULT,Blockly.Cursor);Blockly.MarkerManager=function(a){this.cursorSvg_=this.cursor_=null;this.markers_=Object.create(null);this.workspace_=a};Blockly.MarkerManager.LOCAL_MARKER="local_marker_1";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 unregister markers that exist.");};Blockly.MarkerManager.prototype.getCursor=function(){return this.cursor_};Blockly.MarkerManager.prototype.getMarker=function(a){return this.markers_[a]||null}; -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()}; -Blockly.MarkerManager.prototype.dispose=function(){for(var a=Object.keys(this.markers_),b=0,c;c=a[b];b++)this.unregisterMarker(c);this.markers_=null;this.cursor_&&(this.cursor_.dispose(),this.cursor_=null)};Blockly.WidgetDiv={};Blockly.WidgetDiv.owner_=null;Blockly.WidgetDiv.dispose_=null;Blockly.WidgetDiv.rendererClassName_="";Blockly.WidgetDiv.themeClassName_="";Blockly.WidgetDiv.createDom=function(){Blockly.WidgetDiv.DIV||(Blockly.WidgetDiv.DIV=document.createElement("div"),Blockly.WidgetDiv.DIV.className="blocklyWidgetDiv",(Blockly.parentContainer||document.body).appendChild(Blockly.WidgetDiv.DIV))}; -Blockly.WidgetDiv.show=function(a,b,c){Blockly.WidgetDiv.hide();Blockly.WidgetDiv.owner_=a;Blockly.WidgetDiv.dispose_=c;a=Blockly.WidgetDiv.DIV;a.style.direction=b?"rtl":"ltr";a.style.display="block";b=Blockly.getMainWorkspace();Blockly.WidgetDiv.rendererClassName_=b.getRenderer().getClassName();Blockly.WidgetDiv.themeClassName_=b.getTheme().getClassName();Blockly.utils.dom.addClass(a,Blockly.WidgetDiv.rendererClassName_);Blockly.utils.dom.addClass(a,Blockly.WidgetDiv.themeClassName_)}; -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.Field=function(a,b,c){this.value_=this.DEFAULT_VALUE;this.tooltip_=this.validator_=null;this.size_=new Blockly.utils.Size(0,0);this.constants_=this.mouseDownWrapper_=this.textContent_=this.textElement_=this.borderRect_=this.fieldGroup_=this.markerSvg_=this.cursorSvg_=null;c&&this.configure_(c);this.setValue(a);b&&this.setValidator(b)};Blockly.Field.prototype.DEFAULT_VALUE=null;Blockly.Field.prototype.name=void 0;Blockly.Field.prototype.disposed=!1; -Blockly.Field.prototype.maxDisplayLength=50;Blockly.Field.prototype.sourceBlock_=null;Blockly.Field.prototype.isDirty_=!0;Blockly.Field.prototype.visible_=!0;Blockly.Field.prototype.clickTarget_=null;Blockly.Field.NBSP="\u00a0";Blockly.Field.prototype.EDITABLE=!0;Blockly.Field.prototype.SERIALIZABLE=!1;Blockly.Field.prototype.configure_=function(a){var b=a.tooltip;"string"==typeof b&&(b=Blockly.utils.replaceMessageReferences(a.tooltip));b&&this.setTooltip(b)}; -Blockly.Field.prototype.setSourceBlock=function(a){if(this.sourceBlock_)throw Error("Field already bound to a block.");this.sourceBlock_=a};Blockly.Field.prototype.getConstants=function(){!this.constants_&&this.sourceBlock_&&this.sourceBlock_.workspace&&this.sourceBlock_.workspace.rendered&&(this.constants_=this.sourceBlock_.workspace.getRenderer().getConstants());return this.constants_};Blockly.Field.prototype.getSourceBlock=function(){return this.sourceBlock_}; -Blockly.Field.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{},null),this.isVisible()||(this.fieldGroup_.style.display="none"),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),this.initView(),this.updateEditable(),this.setTooltip(this.tooltip_),this.bindEvents_(),this.initModel())};Blockly.Field.prototype.initView=function(){this.createBorderRect_();this.createTextElement_()};Blockly.Field.prototype.initModel=function(){}; -Blockly.Field.prototype.createBorderRect_=function(){this.borderRect_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{rx:this.getConstants().FIELD_BORDER_RECT_RADIUS,ry:this.getConstants().FIELD_BORDER_RECT_RADIUS,x:0,y:0,height:this.size_.height,width:this.size_.width,"class":"blocklyFieldRect"},this.fieldGroup_)}; -Blockly.Field.prototype.createTextElement_=function(){this.textElement_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TEXT,{"class":"blocklyText"},this.fieldGroup_);this.getConstants().FIELD_TEXT_BASELINE_CENTER&&this.textElement_.setAttribute("dominant-baseline","central");this.textContent_=document.createTextNode("");this.textElement_.appendChild(this.textContent_)}; -Blockly.Field.prototype.bindEvents_=function(){Blockly.Tooltip.bindMouseEvents(this.getClickTarget_());this.mouseDownWrapper_=Blockly.browserEvents.conditionalBind(this.getClickTarget_(),"mousedown",this,this.onMouseDown_)};Blockly.Field.prototype.fromXml=function(a){this.setValue(a.textContent)};Blockly.Field.prototype.toXml=function(a){a.textContent=this.getValue();return a}; -Blockly.Field.prototype.dispose=function(){Blockly.DropDownDiv.hideIfOwner(this);Blockly.WidgetDiv.hideIfOwner(this);Blockly.Tooltip.unbindMouseEvents(this.getClickTarget_());this.mouseDownWrapper_&&Blockly.browserEvents.unbind(this.mouseDownWrapper_);Blockly.utils.dom.removeNode(this.fieldGroup_);this.disposed=!0}; -Blockly.Field.prototype.updateEditable=function(){var a=this.fieldGroup_;this.EDITABLE&&a&&(this.sourceBlock_.isEditable()?(Blockly.utils.dom.addClass(a,"blocklyEditableText"),Blockly.utils.dom.removeClass(a,"blocklyNonEditableText"),a.style.cursor=this.CURSOR):(Blockly.utils.dom.addClass(a,"blocklyNonEditableText"),Blockly.utils.dom.removeClass(a,"blocklyEditableText"),a.style.cursor=""))}; -Blockly.Field.prototype.isClickable=function(){return!!this.sourceBlock_&&this.sourceBlock_.isEditable()&&!!this.showEditor_&&"function"===typeof this.showEditor_};Blockly.Field.prototype.isCurrentlyEditable=function(){return this.EDITABLE&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()}; -Blockly.Field.prototype.isSerializable=function(){var a=!1;this.name&&(this.SERIALIZABLE?a=!0:this.EDITABLE&&(console.warn("Detected an editable field that was not serializable. Please define SERIALIZABLE property as true on all editable custom fields. Proceeding with serialization."),a=!0));return a};Blockly.Field.prototype.isVisible=function(){return this.visible_}; -Blockly.Field.prototype.setVisible=function(a){if(this.visible_!=a){this.visible_=a;var b=this.getSvgRoot();b&&(b.style.display=a?"block":"none")}};Blockly.Field.prototype.setValidator=function(a){this.validator_=a};Blockly.Field.prototype.getValidator=function(){return this.validator_};Blockly.Field.prototype.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.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.get(Blockly.Events.BLOCK_CHANGE))(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;da||a>this.fieldRow.length)throw Error("index "+a+" out of bounds.");if(!(b||""==b&&c))return a;"string"==typeof b&&(b=Blockly.fieldRegistry.fromJson({type:"field_label",text:b}));b.setSourceBlock(this.sourceBlock_);this.sourceBlock_.rendered&&(b.init(),b.applyColour());b.name=c;b.setVisible(this.isVisible());b.prefixField&&(a=this.insertFieldAt(a,b.prefixField));this.fieldRow.splice(a,0,b);++a;b.suffixField&&(a=this.insertFieldAt(a,b.suffixField)); -this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours());return a};Blockly.Input.prototype.removeField=function(a,b){for(var c=0,d;d=this.fieldRow[c];c++)if(d.name===a)return d.dispose(),this.fieldRow.splice(c,1),this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours()),!0;if(b)return!1;throw Error('Field "'+a+'" not found.');}; -Blockly.Input.prototype.isVisible=function(){return this.visible_};Blockly.Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;this.visible_=a;for(var c=0,d;d=this.fieldRow[c];c++)d.setVisible(a);this.connection&&(this.connection=this.connection,a?b=this.connection.startTrackingAll():this.connection.stopTrackingAll(),c=this.connection.targetBlock())&&(c.getSvgRoot().style.display=a?"block":"none");return b};Blockly.Input.prototype.markDirty=function(){for(var a=0,b;b=this.fieldRow[a];a++)b.markDirty()}; -Blockly.Input.prototype.setCheck=function(a){if(!this.connection)throw Error("This input does not have a connection.");this.connection.setCheck(a);return this};Blockly.Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render());return this};Blockly.Input.prototype.setShadowDom=function(a){if(!this.connection)throw Error("This input does not have a connection.");this.connection.setShadowDom(a);return this}; -Blockly.Input.prototype.getShadowDom=function(){if(!this.connection)throw Error("This input does not have a connection.");return this.connection.getShadowDom()};Blockly.Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;aa&&(e=e.substring(0,a-3)+"...");return e};Blockly.Block.prototype.appendValueInput=function(a){return this.appendInput_(Blockly.inputTypes.VALUE,a)};Blockly.Block.prototype.appendStatementInput=function(a){return this.appendInput_(Blockly.inputTypes.STATEMENT,a)};Blockly.Block.prototype.appendDummyInput=function(a){return this.appendInput_(Blockly.inputTypes.DUMMY,a||"")}; -Blockly.Block.prototype.jsonInit=function(a){var b=a.type?'Block "'+a.type+'": ':"";if(a.output&&a.previousStatement)throw Error(b+"Must not have both an output and a previousStatement.");a.style&&a.style.hat&&(this.hat=a.style.hat,a.style=null);if(a.style&&a.colour)throw Error(b+"Must not have both a colour and a style.");a.style?this.jsonInitStyle_(a,b):this.jsonInitColour_(a,b);for(var c=0;void 0!==a["message"+c];)this.interpolate_(a["message"+c],a["args"+c]||[],a["lastDummyAlign"+c],b),c++;void 0!== -a.inputsInline&&this.setInputsInline(a.inputsInline);void 0!==a.output&&this.setOutput(!0,a.output);void 0!==a.outputShape&&this.setOutputShape(a.outputShape);void 0!==a.previousStatement&&this.setPreviousStatement(!0,a.previousStatement);void 0!==a.nextStatement&&this.setNextStatement(!0,a.nextStatement);void 0!==a.tooltip&&(c=a.tooltip,c=Blockly.utils.replaceMessageReferences(c),this.setTooltip(c));void 0!==a.enableContextMenu&&(c=a.enableContextMenu,this.contextMenu=!!c);void 0!==a.helpUrl&&(c= -a.helpUrl,c=Blockly.utils.replaceMessageReferences(c),this.setHelpUrl(c));"string"==typeof a.extensions&&(console.warn(b+"JSON attribute 'extensions' should be an array of strings. Found raw string in JSON for '"+a.type+"' block."),a.extensions=[a.extensions]);void 0!==a.mutator&&Blockly.Extensions.apply(a.mutator,this,!0);a=a.extensions;if(Array.isArray(a))for(b=0;bf||f>b)throw Error('Block "'+this.type+'": Message index %'+f+" out of range.");if(c[f])throw Error('Block "'+this.type+'": Message index %'+f+" duplicated.");c[f]=!0;d++}}if(d!=b)throw Error('Block "'+this.type+'": Message does not reference all '+b+" arg(s).");}; -Blockly.Block.prototype.interpolateArguments_=function(a,b,c){for(var d=[],e=0;e=this.inputList.length)throw RangeError("Input index "+a+" out of bounds.");if(b>this.inputList.length)throw RangeError("Reference input "+b+" out of bounds.");var c=this.inputList[a];this.inputList.splice(a,1);aa?this.menuItems_.length:a,-1)};Blockly.Menu.prototype.highlightFirst_=function(){this.highlightHelper_(-1,1)};Blockly.Menu.prototype.highlightLast_=function(){this.highlightHelper_(this.menuItems_.length,-1)};Blockly.Menu.prototype.highlightHelper_=function(a,b){a+=b;for(var c;c=this.menuItems_[a];){if(c.isEnabled()){this.setHighlighted(c);break}a+=b}}; -Blockly.Menu.prototype.handleMouseOver_=function(a){(a=this.getMenuItem_(a.target))&&(a.isEnabled()?this.highlightedItem_!=a&&this.setHighlighted(a):this.setHighlighted(null))};Blockly.Menu.prototype.handleClick_=function(a){var b=this.openingCoords;this.openingCoords=null;if(b&&"number"==typeof a.clientX){var c=new Blockly.utils.Coordinate(a.clientX,a.clientY);if(1>Blockly.utils.Coordinate.distance(b,c))return}(a=this.getMenuItem_(a.target))&&a.performAction()}; -Blockly.Menu.prototype.handleMouseEnter_=function(a){this.focus()};Blockly.Menu.prototype.handleMouseLeave_=function(a){this.getElement()&&(this.blur_(),this.setHighlighted(null))}; -Blockly.Menu.prototype.handleKeyEvent_=function(a){if(this.menuItems_.length&&!(a.shiftKey||a.ctrlKey||a.metaKey||a.altKey)){var b=this.highlightedItem_;switch(a.keyCode){case Blockly.utils.KeyCodes.ENTER:case Blockly.utils.KeyCodes.SPACE:b&&b.performAction();break;case Blockly.utils.KeyCodes.UP:this.highlightPrevious();break;case Blockly.utils.KeyCodes.DOWN:this.highlightNext();break;case Blockly.utils.KeyCodes.PAGE_UP:case Blockly.utils.KeyCodes.HOME:this.highlightFirst_();break;case Blockly.utils.KeyCodes.PAGE_DOWN:case Blockly.utils.KeyCodes.END:this.highlightLast_(); -break;default:return}a.preventDefault();a.stopPropagation()}};Blockly.Menu.prototype.getSize=function(){var a=this.getElement(),b=Blockly.utils.style.getSize(a);b.height=a.scrollHeight;return b};Blockly.MenuItem=function(a,b){this.content_=a;this.value_=b;this.enabled_=!0;this.element_=null;this.rightToLeft_=!1;this.roleName_=null;this.highlight_=this.checked_=this.checkable_=!1;this.actionHandler_=null}; -Blockly.MenuItem.prototype.createDom=function(){var a=document.createElement("div");a.id=Blockly.utils.IdGenerator.getNextUniqueId();this.element_=a;a.className="blocklyMenuItem goog-menuitem "+(this.enabled_?"":"blocklyMenuItemDisabled goog-menuitem-disabled ")+(this.checked_?"blocklyMenuItemSelected goog-option-selected ":"")+(this.highlight_?"blocklyMenuItemHighlight goog-menuitem-highlight ":"")+(this.rightToLeft_?"blocklyMenuItemRtl goog-menuitem-rtl ":"");var b=document.createElement("div"); -b.className="blocklyMenuItemContent goog-menuitem-content";if(this.checkable_){var c=document.createElement("div");c.className="blocklyMenuItemCheckbox goog-menuitem-checkbox";b.appendChild(c)}c=this.content_;"string"==typeof this.content_&&(c=document.createTextNode(this.content_));b.appendChild(c);a.appendChild(b);this.roleName_&&Blockly.utils.aria.setRole(a,this.roleName_);Blockly.utils.aria.setState(a,Blockly.utils.aria.State.SELECTED,this.checkable_&&this.checked_||!1);Blockly.utils.aria.setState(a, -Blockly.utils.aria.State.DISABLED,!this.enabled_);return a};Blockly.MenuItem.prototype.dispose=function(){this.element_=null};Blockly.MenuItem.prototype.getElement=function(){return this.element_};Blockly.MenuItem.prototype.getId=function(){return this.element_.id};Blockly.MenuItem.prototype.getValue=function(){return this.value_};Blockly.MenuItem.prototype.setRightToLeft=function(a){this.rightToLeft_=a};Blockly.MenuItem.prototype.setRole=function(a){this.roleName_=a}; -Blockly.MenuItem.prototype.setCheckable=function(a){this.checkable_=a};Blockly.MenuItem.prototype.setChecked=function(a){this.checked_=a};Blockly.MenuItem.prototype.setHighlighted=function(a){this.highlight_=a;var b=this.getElement();b&&this.isEnabled()&&(a?(Blockly.utils.dom.addClass(b,"blocklyMenuItemHighlight"),Blockly.utils.dom.addClass(b,"goog-menuitem-highlight")):(Blockly.utils.dom.removeClass(b,"blocklyMenuItemHighlight"),Blockly.utils.dom.removeClass(b,"goog-menuitem-highlight")))}; -Blockly.MenuItem.prototype.isEnabled=function(){return this.enabled_};Blockly.MenuItem.prototype.setEnabled=function(a){this.enabled_=a};Blockly.MenuItem.prototype.performAction=function(){this.isEnabled()&&this.actionHandler_&&this.actionHandler_(this)};Blockly.MenuItem.prototype.onAction=function(a,b){this.actionHandler_=a.bind(b)};Blockly.ContextMenu={};Blockly.ContextMenu.currentBlock=null;Blockly.ContextMenu.menu_=null;Blockly.ContextMenu.show=function(a,b,c){Blockly.WidgetDiv.show(Blockly.ContextMenu,c,Blockly.ContextMenu.dispose);if(b.length){var d=Blockly.ContextMenu.populate_(b,c);Blockly.ContextMenu.menu_=d;Blockly.ContextMenu.position_(d,a,c);setTimeout(function(){d.focus()},1);Blockly.ContextMenu.currentBlock=null}else Blockly.ContextMenu.hide()}; -Blockly.ContextMenu.populate_=function(a,b){var c=new Blockly.Menu;c.setRole(Blockly.utils.aria.Role.MENU);for(var d=0,e;e=a[d];d++){var f=new Blockly.MenuItem(e.text);f.setRightToLeft(b);f.setRole(Blockly.utils.aria.Role.MENUITEM);c.addChild(f);f.setEnabled(e.enabled);if(e.enabled)f.onAction(function(g){Blockly.ContextMenu.hide();this.callback(this.scope)},e)}return c}; -Blockly.ContextMenu.position_=function(a,b,c){var d=Blockly.utils.getViewportBBox();b=new Blockly.utils.Rect(b.clientY+d.top,b.clientY+d.top,b.clientX+d.left,b.clientX+d.left);Blockly.ContextMenu.createWidget_(a);var e=a.getSize();c&&(b.left+=e.width,b.right+=e.width,d.left+=e.width,d.right+=e.width);Blockly.WidgetDiv.positionWithAnchor(d,b,e,c);a.focus()}; -Blockly.ContextMenu.createWidget_=function(a){a.render(Blockly.WidgetDiv.DIV);var b=a.getElement();Blockly.utils.dom.addClass(b,"blocklyContextMenu");Blockly.browserEvents.conditionalBind(b,"contextmenu",null,Blockly.utils.noEvent);a.focus()};Blockly.ContextMenu.hide=function(){Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu);Blockly.ContextMenu.currentBlock=null};Blockly.ContextMenu.dispose=function(){Blockly.ContextMenu.menu_&&(Blockly.ContextMenu.menu_.dispose(),Blockly.ContextMenu.menu_=null)}; -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.get(Blockly.Events.BLOCK_CREATE))(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.ContextMenuRegistry=function(){Blockly.ContextMenuRegistry.registry=this;this.registry_=Object.create(null)};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])throw Error('Menu item with ID "'+a+'" not found.');delete this.registry_[a]};Blockly.ContextMenuRegistry.prototype.getItem=function(a){return 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.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.IBoundedElement=function(){};Blockly.ICopyable=function(){};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- -Blockly.SNAP_RADIUS-Math.floor(Math.random()*Blockly.BUMP_RANDOMNESS)-this.x);b.moveBy(e,f);d||b.removeSelect()}}}; -Blockly.RenderedConnection.prototype.moveTo=function(a,b){this.trackedState_==Blockly.RenderedConnection.TrackedState.WILL_TRACK?(this.db_.addConnection(this,b),this.trackedState_=Blockly.RenderedConnection.TrackedState.TRACKED):this.trackedState_==Blockly.RenderedConnection.TrackedState.TRACKED&&(this.db_.removeConnection(this,this.y),this.db_.addConnection(this,b));this.x=a;this.y=b};Blockly.RenderedConnection.prototype.moveBy=function(a,b){this.moveTo(this.x+a,this.y+b)}; -Blockly.RenderedConnection.prototype.moveToOffset=function(a){this.moveTo(a.x+this.offsetInBlock_.x,a.y+this.offsetInBlock_.y)};Blockly.RenderedConnection.prototype.setOffsetInBlock=function(a,b){this.offsetInBlock_.x=a;this.offsetInBlock_.y=b};Blockly.RenderedConnection.prototype.getOffsetInBlock=function(){return this.offsetInBlock_}; -Blockly.RenderedConnection.prototype.tighten=function(){var a=this.targetConnection.x-this.x,b=this.targetConnection.y-this.y;if(0!=a||0!=b){var c=this.targetBlock(),d=c.getSvgRoot();if(!d)throw Error("block is not rendered.");d=Blockly.utils.getRelativeXY(d);c.getSvgRoot().setAttribute("transform","translate("+(d.x-a)+","+(d.y-b)+")");c.moveConnections(-a,-b)}};Blockly.RenderedConnection.prototype.closest=function(a,b){return this.dbOpposite_.searchForClosest(this,a,b)}; -Blockly.RenderedConnection.prototype.highlight=function(){var a=this.sourceBlock_.workspace.getRenderer().getConstants();var b=a.shapeFor(this);this.type==Blockly.connectionTypes.INPUT_VALUE||this.type==Blockly.connectionTypes.OUTPUT_VALUE?(a=a.TAB_OFFSET_FROM_TOP,b=Blockly.utils.svgPaths.moveBy(0,-a)+Blockly.utils.svgPaths.lineOnAxis("v",a)+b.pathDown+Blockly.utils.svgPaths.lineOnAxis("v",a)):(a=a.NOTCH_OFFSET_LEFT-a.CORNER_RADIUS,b=Blockly.utils.svgPaths.moveBy(-a,0)+Blockly.utils.svgPaths.lineOnAxis("h", -a)+b.pathLeft+Blockly.utils.svgPaths.lineOnAxis("h",a));a=this.sourceBlock_.getRelativeToSurfaceXY();Blockly.Connection.highlightedPath_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{"class":"blocklyHighlightedConnectionPath",d:b,transform:"translate("+(this.x-a.x)+","+(this.y-a.y)+")"+(this.sourceBlock_.RTL?" scale(-1 1)":"")},this.sourceBlock_.getSvgRoot())}; -Blockly.RenderedConnection.prototype.unhighlight=function(){Blockly.utils.dom.removeNode(Blockly.Connection.highlightedPath_);delete Blockly.Connection.highlightedPath_}; -Blockly.RenderedConnection.prototype.setTracking=function(a){a&&this.trackedState_==Blockly.RenderedConnection.TrackedState.TRACKED||!a&&this.trackedState_==Blockly.RenderedConnection.TrackedState.UNTRACKED||this.sourceBlock_.isInFlyout||(a?(this.db_.addConnection(this,this.y),this.trackedState_=Blockly.RenderedConnection.TrackedState.TRACKED):(this.trackedState_==Blockly.RenderedConnection.TrackedState.TRACKED&&this.db_.removeConnection(this,this.y),this.trackedState_=Blockly.RenderedConnection.TrackedState.UNTRACKED))}; -Blockly.RenderedConnection.prototype.stopTrackingAll=function(){this.setTracking(!1);if(this.targetConnection)for(var a=this.targetBlock().getDescendants(!1),b=0;bb?!1:Blockly.RenderedConnection.superClass_.isConnectionAllowed.call(this,a)}; -Blockly.RenderedConnection.prototype.onFailedConnect=function(a){var b=this.getSourceBlock();if(Blockly.Events.recordUndo){var c=Blockly.Events.getGroup();setTimeout(function(){b.isDisposed()||b.getParent()||(Blockly.Events.setGroup(c),this.bumpAwayFrom(a),Blockly.Events.setGroup(!1))}.bind(this),Blockly.BUMP_DELAY)}}; -Blockly.RenderedConnection.prototype.disconnectInternal_=function(a,b){Blockly.RenderedConnection.superClass_.disconnectInternal_.call(this,a,b);a.rendered&&a.render();b.rendered&&(b.updateDisabled(),b.render(),b.getSvgRoot().style.display="block")};Blockly.RenderedConnection.prototype.respawnShadow_=function(){Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);var a=this.targetBlock();a&&(a.initSvg(),a.render(!1),a=this.getSourceBlock(),a.rendered&&a.render())}; -Blockly.RenderedConnection.prototype.neighbours=function(a){return this.dbOpposite_.getNeighbours(this,a)}; -Blockly.RenderedConnection.prototype.connect_=function(a){Blockly.RenderedConnection.superClass_.connect_.call(this,a);var b=this.getSourceBlock();a=a.getSourceBlock();var c=b.rendered,d=a.rendered;c&&b.updateDisabled();d&&a.updateDisabled();c&&d&&(this.type==Blockly.connectionTypes.NEXT_STATEMENT||this.type==Blockly.connectionTypes.PREVIOUS_STATEMENT?a.render():b.render());if(b=b.getInputWithBlock(a))b=b.isVisible(),a.getSvgRoot().style.display=b?"block":"none"}; -Blockly.RenderedConnection.prototype.onCheckChanged_=function(){!this.isConnected()||this.targetConnection&&this.getConnectionChecker().canConnect(this,this.targetConnection,!1)||((this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug(),this.sourceBlock_.bumpNeighbours())};Blockly.BasicCursor=function(){Blockly.BasicCursor.superClass_.constructor.call(this)};Blockly.utils.object.inherits(Blockly.BasicCursor,Blockly.Cursor);Blockly.BasicCursor.registrationName="basicCursor";Blockly.BasicCursor.prototype.next=function(){var a=this.getCurNode();if(!a)return null;(a=this.getNextNode_(a,this.validNode_))&&this.setCurNode(a);return a};Blockly.BasicCursor.prototype.in=function(){return this.next()}; -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.registry.register(Blockly.registry.Type.CURSOR,Blockly.BasicCursor.registrationName,Blockly.BasicCursor);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.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=this.connections_.length)return-1;b=a.y;for(var d=c;0<=d&&this.connections_[d].y==b;){if(this.connections_[d]==a)return d;d--}for(d=c;da)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 na)throw Error("Cannot unsubscribe a workspace that hasn't been subscribed.");this.subscribedWorkspaces_.splice(a,1)}; -Blockly.ThemeManager.prototype.subscribe=function(a,b,c){this.componentDB_[b]||(this.componentDB_[b]=[]);this.componentDB_[b].push({element:a,propertyName:c});b=this.theme_&&this.theme_.getComponentStyle(b);a.style[c]=b||""};Blockly.ThemeManager.prototype.unsubscribe=function(a){if(a)for(var b=Object.keys(this.componentDB_),c=0,d;d=b[c];c++){for(var e=this.componentDB_[d],f=e.length-1;0<=f;f--)e[f].element===a&&e.splice(f,1);this.componentDB_[d].length||delete this.componentDB_[d]}}; -Blockly.ThemeManager.prototype.dispose=function(){this.componentDB_=this.subscribedWorkspaces_=this.theme_=this.owner_=null};Blockly.TouchGesture=function(a,b){Blockly.TouchGesture.superClass_.constructor.call(this,a,b);this.isMultiTouch_=!1;this.cachedPoints_=Object.create(null);this.startDistance_=this.previousScale_=0;this.isPinchZoomEnabled_=this.onStartWrapper_=null};Blockly.utils.object.inherits(Blockly.TouchGesture,Blockly.Gesture);Blockly.TouchGesture.ZOOM_IN_MULTIPLIER=5;Blockly.TouchGesture.ZOOM_OUT_MULTIPLIER=6; -Blockly.TouchGesture.prototype.doStart=function(a){this.isPinchZoomEnabled_=this.startWorkspace_.options.zoomOptions&&this.startWorkspace_.options.zoomOptions.pinch;Blockly.TouchGesture.superClass_.doStart.call(this,a);!this.isEnding_&&Blockly.Touch.isTouchEvent(a)&&this.handleTouchStart(a)}; -Blockly.TouchGesture.prototype.bindMouseEvents=function(a){this.onStartWrapper_=Blockly.browserEvents.conditionalBind(document,"mousedown",null,this.handleStart.bind(this),!0);this.onMoveWrapper_=Blockly.browserEvents.conditionalBind(document,"mousemove",null,this.handleMove.bind(this),!0);this.onUpWrapper_=Blockly.browserEvents.conditionalBind(document,"mouseup",null,this.handleUp.bind(this),!0);a.preventDefault();a.stopPropagation()}; -Blockly.TouchGesture.prototype.handleStart=function(a){!this.isDragging()&&Blockly.Touch.isTouchEvent(a)&&(this.handleTouchStart(a),this.isMultiTouch()&&Blockly.longStop_())};Blockly.TouchGesture.prototype.handleMove=function(a){this.isDragging()?Blockly.Touch.shouldHandleEvent(a)&&Blockly.TouchGesture.superClass_.handleMove.call(this,a):this.isMultiTouch()?(Blockly.Touch.isTouchEvent(a)&&this.handleTouchMove(a),Blockly.longStop_()):Blockly.TouchGesture.superClass_.handleMove.call(this,a)}; -Blockly.TouchGesture.prototype.handleUp=function(a){Blockly.Touch.isTouchEvent(a)&&!this.isDragging()&&this.handleTouchEnd(a);!this.isMultiTouch()||this.isDragging()?Blockly.Touch.shouldHandleEvent(a)&&Blockly.TouchGesture.superClass_.handleUp.call(this,a):(a.preventDefault(),a.stopPropagation(),this.dispose())};Blockly.TouchGesture.prototype.isMultiTouch=function(){return this.isMultiTouch_}; -Blockly.TouchGesture.prototype.dispose=function(){Blockly.TouchGesture.superClass_.dispose.call(this);this.onStartWrapper_&&Blockly.browserEvents.unbind(this.onStartWrapper_)}; -Blockly.TouchGesture.prototype.handleTouchStart=function(a){var b=Blockly.Touch.getTouchIdentifierFromEvent(a);this.cachedPoints_[b]=this.getTouchPoint(a);b=Object.keys(this.cachedPoints_);2==b.length&&(this.startDistance_=Blockly.utils.Coordinate.distance(this.cachedPoints_[b[0]],this.cachedPoints_[b[1]]),this.isMultiTouch_=!0,a.preventDefault())}; -Blockly.TouchGesture.prototype.handleTouchMove=function(a){var b=Blockly.Touch.getTouchIdentifierFromEvent(a);this.cachedPoints_[b]=this.getTouchPoint(a);b=Object.keys(this.cachedPoints_);this.isPinchZoomEnabled_&&2===b.length?this.handlePinch_(a):Blockly.TouchGesture.superClass_.handleMove.call(this,a)}; -Blockly.TouchGesture.prototype.handlePinch_=function(a){var b=Object.keys(this.cachedPoints_);b=Blockly.utils.Coordinate.distance(this.cachedPoints_[b[0]],this.cachedPoints_[b[1]])/this.startDistance_;if(0this.previousScale_){var c=b-this.previousScale_;c=0Object.keys(this.cachedPoints_).length&&(this.cachedPoints_=Object.create(null),this.previousScale_=0)};Blockly.TouchGesture.prototype.getTouchPoint=function(a){return this.startWorkspace_?new Blockly.utils.Coordinate(a.pageX?a.pageX:a.changedTouches[0].pageX,a.pageY?a.pageY:a.changedTouches[0].pageY):null};Blockly.WorkspaceAudio=function(a){this.parentWorkspace_=a;this.SOUNDS_=Object.create(null)};Blockly.WorkspaceAudio.prototype.lastSound_=null;Blockly.WorkspaceAudio.prototype.dispose=function(){this.SOUNDS_=this.parentWorkspace_=null}; -Blockly.WorkspaceAudio.prototype.load=function(a,b){if(a.length){try{var c=new Blockly.utils.global.Audio}catch(h){return}for(var d,e=0;eMath.abs(b-this.oldTop_)&&1>Math.abs(c-this.oldLeft_))){var d=new (Blockly.Events.get(Blockly.Events.VIEWPORT_CHANGE))(b,c,a,this.id,this.oldScale_);this.oldScale_=a;this.oldTop_=b;this.oldLeft_=c;Blockly.Events.fire(d)}}}; -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, -d.y)}};Blockly.WorkspaceSvg.prototype.getBlockDragSurface=function(){return this.blockDragSurface_};Blockly.WorkspaceSvg.prototype.getWidth=function(){var a=this.getMetrics();return a?a.viewWidth/this.scale:0}; -Blockly.WorkspaceSvg.prototype.setVisible=function(a){this.isVisible_=a;if(this.svgGroup_)if(this.scrollbar&&this.scrollbar.setContainerVisible(a),this.getFlyout()&&this.getFlyout().setContainerVisible(a),this.getParentSvg().style.display=a?"block":"none",this.toolbox_&&this.toolbox_.setVisible(a),a){a=this.getAllBlocks(!1);for(var b=a.length-1;0<=b;b--)a[b].markDirty();this.render();this.toolbox_&&this.toolbox_.position()}else Blockly.hideChaff(!0)}; -Blockly.WorkspaceSvg.prototype.render=function(){for(var a=this.getAllBlocks(!1),b=a.length-1;0<=b;b--)a[b].render(!1);if(this.currentGesture_)for(a=this.currentGesture_.getInsertionMarkers(),b=0;b=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=parseInt(a.getAttribute("x"),10),d=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(d)){this.RTL&&(c=-c);do{a=!1;for(var e=this.getAllBlocks(!1),f=0,g;g=e[f];f++){var h=g.getRelativeToSurfaceXY();if(1>=Math.abs(c-h.x)&&1>=Math.abs(d-h.y)){a=!0;break}}if(!a){var k=b.getConnections_(!1);f=0;for(var l;l=k[f];f++)if(l.closest(Blockly.SNAP_RADIUS,new Blockly.utils.Coordinate(c, -d)).connection){a=!0;break}}a&&(c=this.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,d+=2*Blockly.SNAP_RADIUS)}while(a);b.moveBy(c,d)}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(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()&&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(){Blockly.utils.deprecation.warn("WorkspaceSvg.prototype.recordDeleteAreas","June 2021","June 2022","WorkspaceSvg.prototype.recordDragTargets");this.recordDragTargets()}; -Blockly.WorkspaceSvg.prototype.recordDragTargets=function(){var a=this.componentManager_.getComponents(Blockly.ComponentManager.Capability.DRAG_TARGET,!0);this.dragTargetAreas_=[];for(var b=0,c;c=a[b];b++){var d=c.getClientRect();d&&this.dragTargetAreas_.push({component:c,clientRect:d})}};Blockly.WorkspaceSvg.prototype.getDragTarget=function(a){for(var b=0,c;c=this.dragTargetAreas_[b];b++)if(c.clientRect.contains(a.clientX,a.clientY))return c.component;return null}; -Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){var b=this.getGesture(a);b&&b.handleWsStart(a,this)};Blockly.WorkspaceSvg.prototype.startDrag=function(a,b){a=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;this.dragDeltaXY_=Blockly.utils.Coordinate.difference(b,a)}; -Blockly.WorkspaceSvg.prototype.moveDrag=function(a){a=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;return Blockly.utils.Coordinate.sum(this.dragDeltaXY_,a)};Blockly.WorkspaceSvg.prototype.isDragging=function(){return null!=this.currentGesture_&&this.currentGesture_.isDragging()};Blockly.WorkspaceSvg.prototype.isDraggable=function(){return this.options.moveOptions&&this.options.moveOptions.drag}; -Blockly.WorkspaceSvg.prototype.isMovable=function(){return this.options.moveOptions&&!!this.options.moveOptions.scrollbars||this.options.moveOptions&&this.options.moveOptions.wheel||this.options.moveOptions&&this.options.moveOptions.drag||this.options.zoomOptions&&this.options.zoomOptions.wheel||this.options.zoomOptions&&this.options.zoomOptions.pinch};Blockly.WorkspaceSvg.prototype.isMovableHorizontally=function(){var a=!!this.scrollbar;return this.isMovable()&&(!a||a&&this.scrollbar.canScrollHorizontally())}; -Blockly.WorkspaceSvg.prototype.isMovableVertically=function(){var a=!!this.scrollbar;return this.isMovable()&&(!a||a&&this.scrollbar.canScrollVertically())}; -Blockly.WorkspaceSvg.prototype.onMouseWheel_=function(a){if(Blockly.Gesture.inProgress())a.preventDefault(),a.stopPropagation();else{var b=this.options.zoomOptions&&this.options.zoomOptions.wheel,c=this.options.moveOptions&&this.options.moveOptions.wheel;if(b||c){var d=Blockly.utils.getScrollDeltaPixels(a);!b||!a.ctrlKey&&c?(b=this.scrollX-d.x,c=this.scrollY-d.y,a.shiftKey&&!d.x&&(b=this.scrollX-d.y,c=this.scrollY),this.scroll(b,c)):(d=-d.y/50,b=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM()), -this.zoom(b.x,b.y,d));a.preventDefault()}}};Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox=function(){var a=this.getTopBoundedElements();if(!a.length)return new Blockly.utils.Rect(0,0,0,0);for(var b=a[0].getBoundingRectangle(),c=1;cb.bottom&&(b.bottom=d.bottom),d.leftb.right&&(b.right=d.right))}return b}; -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&&document.activeElement.blur();try{this.getParentSvg().focus({preventScroll:!0})}catch(a){try{this.getParentSvg().parentNode.setActive()}catch(b){this.getParentSvg().parentNode.focus({preventScroll:!0})}}}; -Blockly.WorkspaceSvg.prototype.zoom=function(a,b,c){c=Math.pow(this.options.zoomOptions.scaleSpeed,c);var d=this.scale*c;if(this.scale!=d){d>this.options.zoomOptions.maxScale?c=this.options.zoomOptions.maxScale/this.scale:dthis.options.zoomOptions.maxScale?a=this.options.zoomOptions.maxScale:this.options.zoomOptions.minScale&&ab.oldScale&&Blockly.bumpTopObjectsIntoBounds_(a)}};Blockly.bumpObjectIntoBounds_=function(a,b,c){var d=c.getBoundingRectangle(),e=d.right-d.left,f=Blockly.utils.math.clamp(b.top,d.top,b.top+b.height-(d.bottom-d.top))-d.top,g=b.left;b=b.left+b.width-e;a.RTL?g=Math.min(b,g):b=Math.max(g,b);return(a=Blockly.utils.math.clamp(g,d.left,b)-d.left)||f?(c.moveBy(a,f),!0):!1}; -Blockly.init_=function(a){var b=a.options,c=a.getParentSvg();Blockly.browserEvents.conditionalBind(c.parentNode,"contextmenu",null,function(e){Blockly.utils.isTargetInput(e)||e.preventDefault()});c=Blockly.browserEvents.conditionalBind(window,"resize",null,function(){Blockly.hideChaff(!0);Blockly.svgResize(a);Blockly.bumpTopObjectsIntoBounds_(a)});a.setResizeHandlerWrapper(c);Blockly.inject.bindDocumentEvents_();if(b.languageTree){c=a.getToolbox();var d=a.getFlyout(!0);c?c.init():d&&(d.init(a),d.show(b.languageTree), -"function"==typeof d.scrollToStart&&d.scrollToStart())}b.hasTrashcan&&a.trashcan.init();b.zoomOptions&&b.zoomOptions.controls&&a.zoomControls_.init();b.moveOptions&&b.moveOptions.scrollbars?(a.scrollbar=new Blockly.ScrollbarPair(a,!0===b.moveOptions.scrollbars||!!b.moveOptions.scrollbars.horizontal,!0===b.moveOptions.scrollbars||!!b.moveOptions.scrollbars.vertical,"blocklyMainWorkspaceScrollbar"),a.scrollbar.resize()):a.setMetrics({x:.5,y:.5});b.hasSounds&&Blockly.inject.loadSounds_(b.pathToMedia, -a)}; -Blockly.inject.bindDocumentEvents_=function(){Blockly.documentEventsBound_||(Blockly.browserEvents.conditionalBind(document,"scroll",null,function(){for(var a=Blockly.Workspace.getAll(),b=0,c;c=a[b];b++)c.updateInverseScreenCTM&&c.updateInverseScreenCTM()}),Blockly.browserEvents.conditionalBind(document,"keydown",null,Blockly.onKeyDown),Blockly.browserEvents.bind(document,"touchend",null,Blockly.longStop_),Blockly.browserEvents.bind(document,"touchcancel",null,Blockly.longStop_),Blockly.utils.userAgent.IPAD&&Blockly.browserEvents.conditionalBind(window, -"orientationchange",document,function(){Blockly.svgResize(Blockly.getMainWorkspace())}));Blockly.documentEventsBound_=!0}; -Blockly.inject.loadSounds_=function(a,b){var c=b.getAudioManager();c.load([a+"click.mp3",a+"click.wav",a+"click.ogg"],"click");c.load([a+"disconnect.wav",a+"disconnect.mp3",a+"disconnect.ogg"],"disconnect");c.load([a+"delete.mp3",a+"delete.ogg",a+"delete.wav"],"delete");var d=[];a=function(){for(;d.length;)Blockly.browserEvents.unbind(d.pop());c.preload()};d.push(Blockly.browserEvents.conditionalBind(document,"mousemove",null,a,!0));d.push(Blockly.browserEvents.conditionalBind(document,"touchstart", -null,a,!0))};Blockly.Names=function(a,b){this.variablePrefix_=b||"";this.reservedDict_=Object.create(null);if(a)for(a=a.split(","),b=0;bb.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)-11'),d.appendChild(c),b.push(d));if(Blockly.Blocks.variables_get){a.sort(Blockly.VariableModel.compareByName);c=0;for(var e;e=a[c];c++)d=Blockly.utils.xml.createElement("block"),d.setAttribute("type","variables_get"),d.setAttribute("gap",8),d.appendChild(Blockly.Variables.generateVariableFieldDom(e)),b.push(d)}}return b}; -Blockly.Variables.VAR_LETTER_OPTIONS="ijkmnopqrstuvwxyzabcdefgh";Blockly.Variables.generateUniqueName=function(a){return Blockly.Variables.generateUniqueNameFromOptions(Blockly.Variables.VAR_LETTER_OPTIONS.charAt(0),a.getAllVariableNames())}; -Blockly.Variables.generateUniqueNameFromOptions=function(a,b){if(!b.length)return a;for(var c=Blockly.Variables.VAR_LETTER_OPTIONS,d="",e=c.indexOf(a);;){for(var f=!1,g=0;g90-b||a>-90-b&&a<-90+b?!0:!1}; -Blockly.HorizontalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_||this.autoClose||!this.isVisible())return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.top;return this.toolboxPosition_==Blockly.utils.toolbox.Position.TOP?new Blockly.utils.Rect(-1E9,b+a.height,-1E9,1E9):new Blockly.utils.Rect(b,1E9,-1E9,1E9)}; -Blockly.HorizontalFlyout.prototype.reflowInternal_=function(){this.workspace_.scale=this.getFlyoutScale();for(var a=0,b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++)a=Math.max(a,d.getHeightWidth().height);a+=1.5*this.MARGIN;a*=this.workspace_.scale;a+=Blockly.Scrollbar.scrollbarThickness;if(this.height_!=a){for(c=0;d=b[c];c++)d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d);this.targetWorkspace.toolboxPosition!=this.toolboxPosition_||this.toolboxPosition_!=Blockly.utils.toolbox.Position.TOP|| -this.targetWorkspace.getToolbox()||this.targetWorkspace.translate(this.targetWorkspace.scrollX,this.targetWorkspace.scrollY+a);this.height_=a;this.position();this.targetWorkspace.recordDragTargets()}};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.setMetrics_=function(a){if(this.isVisible()){var b=this.workspace_.getMetricsManager(),c=b.getScrollMetrics(),d=b.getViewMetrics();b=b.getAbsoluteMetrics();"number"==typeof a.y&&(this.workspace_.scrollY=-(c.top+(c.height-d.height)*a.y));this.workspace_.translate(this.workspace_.scrollX+b.left,this.workspace_.scrollY+b.top)}}; -Blockly.VerticalFlyout.prototype.getX=function(){if(!this.isVisible())return 0;var a=this.targetWorkspace.getMetricsManager(),b=a.getAbsoluteMetrics(),c=a.getViewMetrics();a=a.getToolboxMetrics();return this.targetWorkspace.toolboxPosition==this.toolboxPosition_?this.targetWorkspace.getToolbox()?this.toolboxPosition_==Blockly.utils.toolbox.Position.LEFT?a.width:c.width-this.width_:this.toolboxPosition_==Blockly.utils.toolbox.Position.LEFT?0:c.width:this.toolboxPosition_==Blockly.utils.toolbox.Position.LEFT? -0:c.width+b.left-this.width_};Blockly.VerticalFlyout.prototype.getY=function(){return 0};Blockly.VerticalFlyout.prototype.position=function(){if(this.isVisible()&&this.targetWorkspace.isVisible()){var a=this.targetWorkspace.getMetricsManager().getViewMetrics();this.height_=a.height;this.setBackgroundPath_(this.width_-this.CORNER_RADIUS,a.height-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.utils.toolbox.Position.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.workspace_.scrollbar.setY(0)};Blockly.VerticalFlyout.prototype.wheel_=function(a){var b=Blockly.utils.getScrollDeltaPixels(a);if(b.y){var c=this.workspace_.getMetricsManager(),d=c.getScrollMetrics();b=c.getViewMetrics().top-d.top+b.y;this.workspace_.scrollbar.setY(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, -d,c),c+=f.button.height+b[e])};Blockly.VerticalFlyout.prototype.isDragTowardWorkspace=function(a){a=Math.atan2(a.y,a.x)/Math.PI*180;var b=this.dragAngleRange_;return a-b||a<-180+b||a>180-b?!0:!1}; -Blockly.VerticalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_||this.autoClose||!this.isVisible())return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.left;return this.toolboxPosition_==Blockly.utils.toolbox.Position.LEFT?new Blockly.utils.Rect(-1E9,1E9,-1E9,b+a.width):new Blockly.utils.Rect(-1E9,1E9,b,1E9)}; -Blockly.VerticalFlyout.prototype.reflowInternal_=function(){this.workspace_.scale=this.getFlyoutScale();for(var a=0,b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getHeightWidth().width;d.outputConnection&&(e-=this.tabWidth_);a=Math.max(a,e)}for(c=0;d=this.buttons_[c];c++)a=Math.max(a,d.width);a+=1.5*this.MARGIN+this.tabWidth_;a*=this.workspace_.scale;a+=Blockly.Scrollbar.scrollbarThickness;if(this.width_!=a){for(c=0;d=b[c];c++){if(this.RTL){e=d.getRelativeToSurfaceXY().x;var f=a/this.workspace_.scale- -this.MARGIN;d.outputConnection||(f-=this.tabWidth_);d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}if(this.RTL)for(c=0;d=this.buttons_[c];c++)b=d.getPosition().y,d.moveTo(a/this.workspace_.scale-d.width-this.MARGIN-this.tabWidth_,b);this.targetWorkspace.toolboxPosition!=this.toolboxPosition_||this.toolboxPosition_!=Blockly.utils.toolbox.Position.LEFT||this.targetWorkspace.getToolbox()||this.targetWorkspace.translate(this.targetWorkspace.scrollX+a,this.targetWorkspace.scrollY); -this.width_=a;this.position();this.targetWorkspace.recordDragTargets()}};Blockly.registry.register(Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX,Blockly.registry.DEFAULT,Blockly.VerticalFlyout);Blockly.FlyoutButton=function(a,b,c,d){this.workspace_=a;this.targetWorkspace_=b;this.text_=c.text;this.position_=new Blockly.utils.Coordinate(0,0);this.isLabel_=d;this.callbackKey_=c.callbackKey||c.callbackkey;this.cssClass_=c["web-class"]||null;this.onMouseUpWrapper_=null;this.info=c};Blockly.FlyoutButton.MARGIN_X=5;Blockly.FlyoutButton.MARGIN_Y=2;Blockly.FlyoutButton.prototype.width=0;Blockly.FlyoutButton.prototype.height=0; -Blockly.FlyoutButton.prototype.createDom=function(){var a=this.isLabel_?"blocklyFlyoutLabel":"blocklyFlyoutButton";this.cssClass_&&(a+=" "+this.cssClass_);this.svgGroup_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G,{"class":a},this.workspace_.getCanvas());if(!this.isLabel_)var b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"blocklyFlyoutButtonShadow",rx:4,ry:4,x:1,y:1},this.svgGroup_);a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":this.isLabel_? -"blocklyFlyoutLabelBackground":"blocklyFlyoutButtonBackground",rx:4,ry:4},this.svgGroup_);var c=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TEXT,{"class":this.isLabel_?"blocklyFlyoutLabelText":"blocklyText",x:0,y:0,"text-anchor":"middle"},this.svgGroup_),d=Blockly.utils.replaceMessageReferences(this.text_);this.workspace_.RTL&&(d+="\u200f");c.textContent=d;this.isLabel_&&(this.svgText_=c,this.workspace_.getThemeManager().subscribe(this.svgText_,"flyoutForegroundColour","fill"));var e=Blockly.utils.style.getComputedStyle(c, -"fontSize"),f=Blockly.utils.style.getComputedStyle(c,"fontWeight"),g=Blockly.utils.style.getComputedStyle(c,"fontFamily");this.width=Blockly.utils.dom.getFastTextWidthWithSizeString(c,e,f,g);d=Blockly.utils.dom.measureFontMetrics(d,e,f,g);this.height=d.height;this.isLabel_||(this.width+=2*Blockly.FlyoutButton.MARGIN_X,this.height+=2*Blockly.FlyoutButton.MARGIN_Y,b.setAttribute("width",this.width),b.setAttribute("height",this.height));a.setAttribute("width",this.width);a.setAttribute("height",this.height); -c.setAttribute("x",this.width/2);c.setAttribute("y",this.height/2-d.height/2+d.baseline);this.updateTransform_();this.onMouseUpWrapper_=Blockly.browserEvents.conditionalBind(this.svgGroup_,"mouseup",this,this.onMouseUp_);return this.svgGroup_};Blockly.FlyoutButton.prototype.show=function(){this.updateTransform_();this.svgGroup_.setAttribute("display","block")}; -Blockly.FlyoutButton.prototype.updateTransform_=function(){this.svgGroup_.setAttribute("transform","translate("+this.position_.x+","+this.position_.y+")")};Blockly.FlyoutButton.prototype.moveTo=function(a,b){this.position_.x=a;this.position_.y=b;this.updateTransform_()};Blockly.FlyoutButton.prototype.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.browserEvents.unbind(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.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>>/sprites.png);","height: 16px;","vertical-align: middle;","visibility: hidden;","width: 16px;","}",".blocklyTreeIconClosed {","background-position: -32px -1px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeIconClosed {',"background-position: 0 -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosed {","background-position: -32px -17px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeSelected>.blocklyTreeIconClosed {', -"background-position: 0 -17px;","}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeLabel {","cursor: default;","font: 16px sans-serif;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",'cursor: url("<<>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}"]); -Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,Blockly.ToolboxCategory.registrationName,Blockly.ToolboxCategory);Blockly.ToolboxSeparator=function(a,b){Blockly.ToolboxSeparator.superClass_.constructor.call(this,a,b);this.cssConfig_={container:"blocklyTreeSeparator"};Blockly.utils.object.mixin(this.cssConfig_,a.cssconfig||a.cssConfig)};Blockly.utils.object.inherits(Blockly.ToolboxSeparator,Blockly.ToolboxItem);Blockly.ToolboxSeparator.registrationName="sep";Blockly.ToolboxSeparator.prototype.init=function(){this.createDom_()}; -Blockly.ToolboxSeparator.prototype.createDom_=function(){var a=document.createElement("div");Blockly.utils.dom.addClass(a,this.cssConfig_.container);return this.htmlDiv_=a};Blockly.ToolboxSeparator.prototype.getDiv=function(){return this.htmlDiv_};Blockly.ToolboxSeparator.prototype.dispose=function(){Blockly.utils.dom.removeNode(this.htmlDiv_)};Blockly.Css.register('.blocklyTreeSeparator {,border-bottom: solid #e5e5e5 1px;,height: 0;,margin: 5px 0;,},.blocklyToolboxDiv[layout="h"] .blocklyTreeSeparator {,border-right: solid #e5e5e5 1px;,border-bottom: none;,height: auto;,margin: 0 5px 0 5px;,padding: 5px 0;,width: 0;,}'.split(",")); -Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,Blockly.ToolboxSeparator.registrationName,Blockly.ToolboxSeparator);Blockly.CollapsibleToolboxCategory=function(a,b,c){this.subcategoriesDiv_=null;this.expanded_=!1;this.toolboxItems_=[];Blockly.CollapsibleToolboxCategory.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.CollapsibleToolboxCategory,Blockly.ToolboxCategory);Blockly.CollapsibleToolboxCategory.registrationName="collapsibleCategory"; -Blockly.CollapsibleToolboxCategory.prototype.makeDefaultCssConfig_=function(){var a=Blockly.CollapsibleToolboxCategory.superClass_.makeDefaultCssConfig_.call(this);a.contents="blocklyToolboxContents";return a}; -Blockly.CollapsibleToolboxCategory.prototype.parseContents_=function(a){var b=a.contents,c=!0;if(a.custom)this.flyoutItems_=a.custom;else if(b){a=0;for(var d;d=b[a];a++)!Blockly.registry.hasItem(Blockly.registry.Type.TOOLBOX_ITEM,d.kind)||d.kind.toLowerCase()==Blockly.ToolboxSeparator.registrationName&&c?(this.flyoutItems_.push(d),c=!0):(this.createToolboxItem_(d),c=!1)}}; -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>>/handdelete.cur"), auto;',"}",".blocklyToolboxGrab {",'cursor: url("<<>>/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.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.IPositionable=function(){};Blockly.uiPosition={};Blockly.uiPosition.verticalPosition={TOP:0,BOTTOM:1};Blockly.uiPosition.horizontalPosition={LEFT:0,RIGHT:1};Blockly.uiPosition.bumpDirection={UP:0,DOWN:1}; -Blockly.uiPosition.getStartPositionRect=function(a,b,c,d,e,f){var g=f.scrollbar&&f.scrollbar.canScrollVertically();a.horizontal===Blockly.uiPosition.horizontalPosition.LEFT?(c=e.absoluteMetrics.left+c,g&&f.RTL&&(c+=Blockly.Scrollbar.scrollbarThickness)):(c=e.absoluteMetrics.left+e.viewMetrics.width-b.width-c,g&&!f.RTL&&(c-=Blockly.Scrollbar.scrollbarThickness));a.vertical===Blockly.uiPosition.verticalPosition.TOP?a=e.absoluteMetrics.top+d:(a=e.absoluteMetrics.top+e.viewMetrics.height-b.height-d,f.scrollbar&& -f.scrollbar.canScrollHorizontally()&&(a-=Blockly.Scrollbar.scrollbarThickness));return new Blockly.utils.Rect(a,a+b.height,c,c+b.width)}; -Blockly.uiPosition.getCornerOppositeToolbox=function(a,b){return{horizontal:b.toolboxMetrics.position===Blockly.utils.toolbox.Position.LEFT||a.horizontalLayout&&!a.RTL?Blockly.uiPosition.horizontalPosition.RIGHT:Blockly.uiPosition.horizontalPosition.LEFT,vertical:b.toolboxMetrics.position===Blockly.utils.toolbox.Position.BOTTOM?Blockly.uiPosition.verticalPosition.TOP:Blockly.uiPosition.verticalPosition.BOTTOM}}; -Blockly.uiPosition.bumpPositionRect=function(a,b,c,d){for(var e=a.left,f=a.right-a.left,g=a.bottom-a.top,h=0,k;k=d[h];h++)a.intersects(k)&&(a=c===Blockly.uiPosition.bumpDirection.UP?k.top-g-b:k.bottom+b,a=new Blockly.utils.Rect(a,a+g,e,e+f),h=-1);return a};Blockly.Trashcan=function(a){Blockly.Trashcan.superClass_.constructor.call(this);this.workspace_=a;this.id="trashcan";this.contents_=[];this.flyout=null;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,move:{scrollbars:!0}}),this.workspace_.horizontalLayout? -(a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.utils.toolbox.Position.TOP?Blockly.utils.toolbox.Position.BOTTOM:Blockly.utils.toolbox.Position.TOP,this.flyout=new (Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,this.workspace_.options,!0))(a)):(a.toolboxPosition=this.workspace_.toolboxPosition==Blockly.utils.toolbox.Position.RIGHT?Blockly.utils.toolbox.Position.LEFT:Blockly.utils.toolbox.Position.RIGHT,this.flyout=new (Blockly.registry.getClassFromOptions(Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX, -this.workspace_.options,!0))(a)),this.workspace_.addChangeListener(this.onDelete_.bind(this)))};Blockly.utils.object.inherits(Blockly.Trashcan,Blockly.DeleteArea);Blockly.Trashcan.prototype.WIDTH_=47;Blockly.Trashcan.prototype.BODY_HEIGHT_=44;Blockly.Trashcan.prototype.LID_HEIGHT_=16;Blockly.Trashcan.prototype.MARGIN_VERTICAL_=20;Blockly.Trashcan.prototype.MARGIN_HORIZONTAL_=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.initialized_=!1; -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.browserEvents.bind(this.svgGroup_,"mousedown",this,this.blockMouseDownWhenOpenable_);Blockly.browserEvents.bind(this.svgGroup_,"mouseup",this,this.click);Blockly.browserEvents.bind(c,"mouseover",this,this.mouseOver_); -Blockly.browserEvents.bind(c,"mouseout",this,this.mouseOut_);this.animateLid_();return this.svgGroup_}; -Blockly.Trashcan.prototype.init=function(){0this.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.utils.toolbox.Position.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.get(Blockly.Events.TRASHCAN_OPEN))(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"); -b.push(c);a.registerButtonCallback("CREATE_VARIABLE_STRING",Blockly.VariablesDynamic.onCreateVariableButtonClick_String);a.registerButtonCallback("CREATE_VARIABLE_NUMBER",Blockly.VariablesDynamic.onCreateVariableButtonClick_Number);a.registerButtonCallback("CREATE_VARIABLE_COLOUR",Blockly.VariablesDynamic.onCreateVariableButtonClick_Colour);a=Blockly.VariablesDynamic.flyoutCategoryBlocks(a);return b=b.concat(a)}; -Blockly.VariablesDynamic.flyoutCategoryBlocks=function(a){a=a.getAllVariables();var b=[];if(0image, .blocklyZoom>svg>image {","opacity: .4;","}",".blocklyZoom>image:hover, .blocklyZoom>svg>image:hover {","opacity: .6;","}",".blocklyZoom>image:active, .blocklyZoom>svg>image:active {","opacity: .8;","}"]);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(c,d){d.preventDefault();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.ShortcutItems.registerDefaultShortcuts();Blockly.ContextMenuItems={};Blockly.ContextMenuItems.registerUndo=function(){Blockly.ContextMenuRegistry.registry.register({displayText:function(){return Blockly.Msg.UNDO},preconditionFn:function(a){return 0b.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: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: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;ba||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.workspace_.setCachedParentSvgSize(this.workspaceWidth_,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_.recordDragTargets()}; -Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BUBBLE_OPEN))(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.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();c.rendered&&c.render();b=(b=c.mutationToDom())&&Blockly.Xml.domToText(b);if(a!=b){Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(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.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,d;d=b[c];c++)d.setStyle(d.getStyleName());if(c=a.getFlyout())for(a=c.workspace_.getAllBlocks(!1),c=0;d=a[c];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)}; -Blockly.FieldTextInput.prototype.initView=function(){if(this.getConstants().FULL_BLOCK_FIELDS){for(var a=0,b=0,c=0,d;d=this.sourceBlock_.inputList[c];c++){for(var e=0;d.fieldRow[e];e++)a++;d.connection&&b++}this.fullBlockClickTarget_=1>=a&&this.sourceBlock_.outputConnection&&!b}else this.fullBlockClickTarget_=!1;this.fullBlockClickTarget_?this.clickTarget_=this.sourceBlock_.getSvgRoot():this.createBorderRect_();this.createTextElement_()}; -Blockly.FieldTextInput.prototype.doClassValidation_=function(a){return null===a||void 0===a?null:String(a)};Blockly.FieldTextInput.prototype.doValueInvalid_=function(a){this.isBeingEdited_&&(this.isTextValid_=!1,a=this.value_,this.value_=this.htmlInput_.untypedDefaultValue_,this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(this.sourceBlock_,"field",this.name||null,a,this.value_)))}; -Blockly.FieldTextInput.prototype.doValueUpdate_=function(a){this.isTextValid_=!0;this.value_=a;this.isBeingEdited_||(this.isDirty_=!0)};Blockly.FieldTextInput.prototype.applyColour=function(){this.sourceBlock_&&this.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(){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")}; -Blockly.FieldTextInput.prototype.bindInputEvents_=function(a){this.onKeyDownWrapper_=Blockly.browserEvents.conditionalBind(a,"keydown",this,this.onHtmlInputKeyDown_);this.onKeyInputWrapper_=Blockly.browserEvents.conditionalBind(a,"input",this,this.onHtmlInputChange_)}; -Blockly.FieldTextInput.prototype.unbindInputEvents_=function(){this.onKeyDownWrapper_&&(Blockly.browserEvents.unbind(this.onKeyDownWrapper_),this.onKeyDownWrapper_=null);this.onKeyInputWrapper_&&(Blockly.browserEvents.unbind(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.setValue(this.htmlInput_.untypedDefaultValue_),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.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_=this.editor_=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_()}; -Blockly.FieldAngle.prototype.showEditor_=function(a){Blockly.FieldAngle.superClass_.showEditor_.call(this,a,Blockly.utils.userAgent.MOBILE||Blockly.utils.userAgent.ANDROID||Blockly.utils.userAgent.IPAD);this.dropdownCreate_();Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_);Blockly.DropDownDiv.setColour(this.sourceBlock_.style.colourPrimary,this.sourceBlock_.style.colourTertiary);Blockly.DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.updateGraph_()}; -Blockly.FieldAngle.prototype.dropdownCreate_=function(){var 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",height:2*Blockly.FieldAngle.HALF+"px",width:2*Blockly.FieldAngle.HALF+"px",style:"touch-action: none"},null),b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CIRCLE,{cx:Blockly.FieldAngle.HALF,cy:Blockly.FieldAngle.HALF,r:Blockly.FieldAngle.RADIUS,"class":"blocklyAngleCircle"}, -a);this.gauge_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.PATH,{"class":"blocklyAngleGauge"},a);this.line_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.LINE,{x1:Blockly.FieldAngle.HALF,y1:Blockly.FieldAngle.HALF,"class":"blocklyAngleLine"},a);for(var c=0;360>c;c+=15)Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.LINE,{x1:Blockly.FieldAngle.HALF+Blockly.FieldAngle.RADIUS,y1:Blockly.FieldAngle.HALF,x2:Blockly.FieldAngle.HALF+Blockly.FieldAngle.RADIUS-(0==c%45?10:5),y2:Blockly.FieldAngle.HALF, -"class":"blocklyAngleMarks",transform:"rotate("+c+","+Blockly.FieldAngle.HALF+","+Blockly.FieldAngle.HALF+")"},a);this.clickWrapper_=Blockly.browserEvents.conditionalBind(a,"click",this,this.hide_);this.clickSurfaceWrapper_=Blockly.browserEvents.conditionalBind(b,"click",this,this.onMouseMove_,!0,!0);this.moveSurfaceWrapper_=Blockly.browserEvents.conditionalBind(b,"mousemove",this,this.onMouseMove_,!0,!0);this.editor_=a}; -Blockly.FieldAngle.prototype.dropdownDispose_=function(){this.clickWrapper_&&(Blockly.browserEvents.unbind(this.clickWrapper_),this.clickWrapper_=null);this.clickSurfaceWrapper_&&(Blockly.browserEvents.unbind(this.clickSurfaceWrapper_),this.clickSurfaceWrapper_=null);this.moveSurfaceWrapper_&&(Blockly.browserEvents.unbind(this.moveSurfaceWrapper_),this.moveSurfaceWrapper_=null);this.line_=this.gauge_=null};Blockly.FieldAngle.prototype.hide_=function(){Blockly.DropDownDiv.hideIfOwner(this);Blockly.WidgetDiv.hide()}; -Blockly.FieldAngle.prototype.onMouseMove_=function(a){var b=this.gauge_.ownerSVGElement.getBoundingClientRect(),c=a.clientX-b.left-Blockly.FieldAngle.HALF;a=a.clientY-b.top-Blockly.FieldAngle.HALF;b=Math.atan(-a/c);isNaN(b)||(b=Blockly.utils.math.toDegrees(b),0>c?b+=180:0a&&(a+=360);a>this.wrap_&&(a-=360);return a};Blockly.Css.register(".blocklyAngleCircle {,stroke: #444;,stroke-width: 1;,fill: #ddd;,fill-opacity: .8;,},.blocklyAngleMarks {,stroke: #444;,stroke-width: 1;,},.blocklyAngleGauge {,fill: #f88;,fill-opacity: .8;,pointer-events: none;,},.blocklyAngleLine {,stroke: #f00;,stroke-width: 2;,stroke-linecap: round;,pointer-events: none;,}".split(",")); -Blockly.fieldRegistry.register("field_angle",Blockly.FieldAngle);Blockly.FieldCheckbox=function(a,b,c){this.checkChar_=null;Blockly.FieldCheckbox.superClass_.constructor.call(this,a,b,c)};Blockly.utils.object.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.prototype.DEFAULT_VALUE=!1;Blockly.FieldCheckbox.fromJson=function(a){return new Blockly.FieldCheckbox(a.checked,void 0,a)};Blockly.FieldCheckbox.CHECK_CHAR="\u2713";Blockly.FieldCheckbox.prototype.SERIALIZABLE=!0;Blockly.FieldCheckbox.prototype.CURSOR="default"; -Blockly.FieldCheckbox.prototype.configure_=function(a){Blockly.FieldCheckbox.superClass_.configure_.call(this,a);a.checkCharacter&&(this.checkChar_=a.checkCharacter)};Blockly.FieldCheckbox.prototype.initView=function(){Blockly.FieldCheckbox.superClass_.initView.call(this);Blockly.utils.dom.addClass(this.textElement_,"blocklyCheckbox");this.textElement_.style.display=this.value_?"block":"none"}; -Blockly.FieldCheckbox.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_());this.updateSize_(this.getConstants().FIELD_CHECKBOX_X_OFFSET)};Blockly.FieldCheckbox.prototype.getDisplayText_=function(){return this.checkChar_||Blockly.FieldCheckbox.CHECK_CHAR};Blockly.FieldCheckbox.prototype.setCheckCharacter=function(a){this.checkChar_=a;this.forceRerender()};Blockly.FieldCheckbox.prototype.showEditor_=function(){this.setValue(!this.value_)}; -Blockly.FieldCheckbox.prototype.doClassValidation_=function(a){return!0===a||"TRUE"===a?"TRUE":!1===a||"FALSE"===a?"FALSE":null};Blockly.FieldCheckbox.prototype.doValueUpdate_=function(a){this.value_=this.convertValueToBool_(a);this.textElement_&&(this.textElement_.style.display=this.value_?"block":"none")};Blockly.FieldCheckbox.prototype.getValue=function(){return this.value_?"TRUE":"FALSE"};Blockly.FieldCheckbox.prototype.getValueBoolean=function(){return this.value_}; -Blockly.FieldCheckbox.prototype.getText=function(){return String(this.convertValueToBool_(this.value_))};Blockly.FieldCheckbox.prototype.convertValueToBool_=function(a){return"string"==typeof a?"TRUE"==a:!!a};Blockly.fieldRegistry.register("field_checkbox",Blockly.FieldCheckbox);Blockly.FieldColour=function(a,b,c){Blockly.FieldColour.superClass_.constructor.call(this,a,b,c);this.onKeyDownWrapper_=this.onMouseLeaveWrapper_=this.onMouseEnterWrapper_=this.onMouseMoveWrapper_=this.onClickWrapper_=this.highlightedIndex_=this.picker_=null};Blockly.utils.object.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.fromJson=function(a){return new Blockly.FieldColour(a.colour,void 0,a)};Blockly.FieldColour.prototype.SERIALIZABLE=!0;Blockly.FieldColour.prototype.CURSOR="default"; -Blockly.FieldColour.prototype.isDirty_=!1;Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.titles_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.configure_=function(a){Blockly.FieldColour.superClass_.configure_.call(this,a);a.colourOptions&&(this.colours_=a.colourOptions,this.titles_=a.colourTitles);a.columns&&(this.columns_=a.columns)}; -Blockly.FieldColour.prototype.initView=function(){this.size_=new Blockly.utils.Size(this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);this.getConstants().FIELD_COLOUR_FULL_BLOCK?this.clickTarget_=this.sourceBlock_.getSvgRoot():(this.createBorderRect_(),this.borderRect_.style.fillOpacity="1")}; -Blockly.FieldColour.prototype.applyColour=function(){this.getConstants().FIELD_COLOUR_FULL_BLOCK?(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.getValue()),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff")):this.borderRect_&&(this.borderRect_.style.fill=this.getValue())};Blockly.FieldColour.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:Blockly.utils.colour.parse(a)}; -Blockly.FieldColour.prototype.doValueUpdate_=function(a){this.value_=a;this.borderRect_?this.borderRect_.style.fill=a:this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",a),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff"))};Blockly.FieldColour.prototype.getText=function(){var a=this.value_;/^#(.)\1(.)\2(.)\3$/.test(a)&&(a="#"+a[1]+a[3]+a[5]);return a};Blockly.FieldColour.COLOURS="#ffffff #cccccc #c0c0c0 #999999 #666666 #333333 #000000 #ffcccc #ff6666 #ff0000 #cc0000 #990000 #660000 #330000 #ffcc99 #ff9966 #ff9900 #ff6600 #cc6600 #993300 #663300 #ffff99 #ffff66 #ffcc66 #ffcc33 #cc9933 #996633 #663333 #ffffcc #ffff33 #ffff00 #ffcc00 #999900 #666600 #333300 #99ff99 #66ff99 #33ff33 #33cc00 #009900 #006600 #003300 #99ffff #33ffff #66cccc #00cccc #339999 #336666 #003333 #ccffff #66ffff #33ccff #3366ff #3333ff #000099 #000066 #ccccff #9999ff #6666cc #6633ff #6600cc #333399 #330099 #ffccff #ff99ff #cc66cc #cc33cc #993399 #663366 #330033".split(" "); -Blockly.FieldColour.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.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.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&&0e&&(e=0):0d-1&&fd-1&&e--:0>b?0>f&&(f=0):0Math.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}; -Blockly.FieldColour.prototype.setHighlightedCell_=function(a,b){var c=this.getHighlighted_();c&&Blockly.utils.dom.removeClass(c,"blocklyColourHighlighted");Blockly.utils.dom.addClass(a,"blocklyColourHighlighted");this.highlightedIndex_=b;Blockly.utils.aria.setState(this.picker_,Blockly.utils.aria.State.ACTIVEDESCENDANT,a.getAttribute("id"))}; -Blockly.FieldColour.prototype.dropdownCreate_=function(){var a=this.columns_||Blockly.FieldColour.COLUMNS,b=this.colours_||Blockly.FieldColour.COLOURS,c=this.titles_||Blockly.FieldColour.TITLES,d=this.getValue(),e=document.createElement("table");e.className="blocklyColourTable";e.tabIndex=0;e.dir="ltr";Blockly.utils.aria.setRole(e,Blockly.utils.aria.Role.GRID);Blockly.utils.aria.setState(e,Blockly.utils.aria.State.EXPANDED,!0);Blockly.utils.aria.setState(e,Blockly.utils.aria.State.ROWCOUNT,Math.floor(b.length/ -a));Blockly.utils.aria.setState(e,Blockly.utils.aria.State.COLCOUNT,a);for(var f,g=0;gtr>td {","border: .5px solid #888;","box-sizing: border-box;","cursor: pointer;","display: inline-block;","height: 20px;","padding: 0;","width: 20px;","}",".blocklyColourTable>tr>td.blocklyColourHighlighted {","border-color: #eee;","box-shadow: 2px 2px 7px 2px rgba(0,0,0,.3);","position: relative;","}",".blocklyColourSelected, .blocklyColourSelected:hover {", -"border-color: #eee !important;","outline: 1px solid #333;","position: relative;","}"]);Blockly.fieldRegistry.register("field_colour",Blockly.FieldColour);Blockly.FieldDropdown=function(a,b,c){"function"!=typeof a&&Blockly.FieldDropdown.validateOptions_(a);this.menuGenerator_=a;this.suffixField=this.prefixField=this.generatedOptions_=null;this.trimOptions_();this.selectedOption_=this.getOptions(!1)[0];Blockly.FieldDropdown.superClass_.constructor.call(this,this.selectedOption_[1],b,c);this.svgArrow_=this.arrow_=this.imageElement_=this.menu_=this.selectedMenuItem_=null};Blockly.utils.object.inherits(Blockly.FieldDropdown,Blockly.Field); -Blockly.FieldDropdown.fromJson=function(a){return new Blockly.FieldDropdown(a.options,void 0,a)};Blockly.FieldDropdown.prototype.fromXml=function(a){this.isOptionListDynamic()&&this.getOptions(!1);this.setValue(a.textContent)};Blockly.FieldDropdown.prototype.SERIALIZABLE=!0;Blockly.FieldDropdown.CHECKMARK_OVERHANG=25;Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH=.45;Blockly.FieldDropdown.IMAGE_Y_OFFSET=5;Blockly.FieldDropdown.IMAGE_Y_PADDING=2*Blockly.FieldDropdown.IMAGE_Y_OFFSET; -Blockly.FieldDropdown.ARROW_CHAR=Blockly.utils.userAgent.ANDROID?"\u25bc":"\u25be";Blockly.FieldDropdown.prototype.CURSOR="default"; -Blockly.FieldDropdown.prototype.initView=function(){this.shouldAddBorderRect_()?this.createBorderRect_():this.clickTarget_=this.sourceBlock_.getSvgRoot();this.createTextElement_();this.imageElement_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{},this.fieldGroup_);this.getConstants().FIELD_DROPDOWN_SVG_ARROW?this.createSVGArrow_():this.createTextArrow_();this.borderRect_&&Blockly.utils.dom.addClass(this.borderRect_,"blocklyDropdownRect")}; -Blockly.FieldDropdown.prototype.shouldAddBorderRect_=function(){return!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW&&!this.sourceBlock_.isShadow()}; -Blockly.FieldDropdown.prototype.createTextArrow_=function(){this.arrow_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.TSPAN,{},this.textElement_);this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL?Blockly.FieldDropdown.ARROW_CHAR+" ":" "+Blockly.FieldDropdown.ARROW_CHAR));this.sourceBlock_.RTL?this.textElement_.insertBefore(this.arrow_,this.textContent_):this.textElement_.appendChild(this.arrow_)}; -Blockly.FieldDropdown.prototype.createSVGArrow_=function(){this.svgArrow_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{height:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px",width:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px"},this.fieldGroup_);this.svgArrow_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.getConstants().FIELD_DROPDOWN_SVG_ARROW_DATAURI)}; -Blockly.FieldDropdown.prototype.showEditor_=function(a){this.dropdownCreate_();this.menu_.openingCoords=a&&"number"===typeof a.clientX?new Blockly.utils.Coordinate(a.clientX,a.clientY):null;this.menu_.render(Blockly.DropDownDiv.getContentDiv());a=this.menu_.getElement();Blockly.utils.dom.addClass(a,"blocklyDropdownMenu");if(this.getConstants().FIELD_DROPDOWN_COLOURED_DIV){a=this.sourceBlock_.isShadow()?this.sourceBlock_.getParent().getColour():this.sourceBlock_.getColour();var b=this.sourceBlock_.isShadow()? -this.sourceBlock_.getParent().style.colourTertiary:this.sourceBlock_.style.colourTertiary;Blockly.DropDownDiv.setColour(a,b)}Blockly.DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.menu_.focus();this.selectedMenuItem_&&this.menu_.setHighlighted(this.selectedMenuItem_);this.applyColour()}; -Blockly.FieldDropdown.prototype.dropdownCreate_=function(){var a=new Blockly.Menu;a.setRole(Blockly.utils.aria.Role.LISTBOX);this.menu_=a;var b=this.getOptions(!1);this.selectedMenuItem_=null;for(var c=0;ca.length)){b=[];for(c=0;c=c||0>=b)throw Error("Height and width values of an image field must be greater than 0.");this.flipRtl_=!1;this.altText_="";Blockly.FieldImage.superClass_.constructor.call(this, -a,null,g);g||(this.flipRtl_=!!f,this.altText_=Blockly.utils.replaceMessageReferences(d)||"");this.size_=new Blockly.utils.Size(b,c+Blockly.FieldImage.Y_PADDING);this.imageHeight_=c;this.clickHandler_=null;"function"==typeof e&&(this.clickHandler_=e);this.imageElement_=null};Blockly.utils.object.inherits(Blockly.FieldImage,Blockly.Field);Blockly.FieldImage.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)||""}; -Blockly.FieldImage.prototype.initView=function(){this.imageElement_=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.IMAGE,{height:this.imageHeight_+"px",width:this.size_.width+"px",alt:this.altText_},this.fieldGroup_);this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",this.value_);this.clickHandler_&&(this.imageElement_.style.cursor="pointer")};Blockly.FieldImage.prototype.updateSize_=function(){}; -Blockly.FieldImage.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:a};Blockly.FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,"xlink:href",String(this.value_))};Blockly.FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_};Blockly.FieldImage.prototype.setAlt=function(a){a!=this.altText_&&(this.altText_=a||"",this.imageElement_&&this.imageElement_.setAttribute("alt",this.altText_))}; -Blockly.FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)};Blockly.FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};Blockly.FieldImage.prototype.getText_=function(){return this.altText_};Blockly.fieldRegistry.register("field_image",Blockly.FieldImage);Blockly.FieldMultilineInput=function(a,b,c){Blockly.FieldMultilineInput.superClass_.constructor.call(this,a,b,c);this.textGroup_=null;this.maxLines_=Infinity;this.isOverflowedY_=!1};Blockly.utils.object.inherits(Blockly.FieldMultilineInput,Blockly.FieldTextInput);Blockly.FieldMultilineInput.prototype.configure_=function(a){Blockly.FieldMultilineInput.superClass_.configure_.call(this,a);a.maxLines&&this.setMaxLines(a.maxLines)}; -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," ");return a};Blockly.FieldMultilineInput.prototype.fromXml=function(a){this.setValue(a.textContent.replace(/ /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.getText();if(!a)return Blockly.Field.NBSP;var b=a.split("\n");a="";for(var c=this.isOverflowedY_?this.maxLines_:b.length,d=0;dthis.maxDisplayLength?e=e.substring(0,this.maxDisplayLength-4)+"...":this.isOverflowedY_&&d===c-1&&(e=e.substring(0,e.length-3)+"...");e=e.replace(/\s/g,Blockly.Field.NBSP);a+=e;d!==c-1&&(a+="\n")}this.sourceBlock_.RTL&&(a+="\u200f");return a}; -Blockly.FieldMultilineInput.prototype.doValueUpdate_=function(a){Blockly.FieldMultilineInput.superClass_.doValueUpdate_.call(this,a);this.isOverflowedY_=this.value_.split("\n").length>this.maxLines_}; -Blockly.FieldMultilineInput.prototype.render_=function(){for(var a;a=this.textGroup_.firstChild;)this.textGroup_.removeChild(a);a=this.getDisplayText_().split("\n");for(var b=0,c=0;cb&&(b=e);c+=this.getConstants().FIELD_TEXT_HEIGHT+(0this.maxDisplayLength&&(a[d]=a[d].substring(0,this.maxDisplayLength));e.textContent=a[d];var k=Blockly.utils.dom.getFastTextWidth(e,f,g,h);k>b&&(b=k)}b+=this.htmlInput_.offsetWidth-this.htmlInput_.clientWidth}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= -b;this.size_.height=c;this.positionBorderRect_()};Blockly.FieldMultilineInput.prototype.showEditor_=function(a,b){Blockly.FieldMultilineInput.superClass_.showEditor_.call(this,a,b);this.forceRerender()}; -Blockly.FieldMultilineInput.prototype.widgetCreate_=function(){var a=Blockly.WidgetDiv.DIV,b=this.workspace_.getScale(),c=document.createElement("textarea");c.className="blocklyHtmlInput blocklyHtmlTextAreaInput";c.setAttribute("spellcheck",this.spellcheck_);var d=this.getConstants().FIELD_TEXT_FONTSIZE*b+"pt";a.style.fontSize=d;c.style.fontSize=d;c.style.borderRadius=Blockly.FieldTextInput.BORDERRADIUS*b+"px";d=this.getConstants().FIELD_BORDER_RECT_X_PADDING*b;var e=this.getConstants().FIELD_BORDER_RECT_Y_PADDING* -b/2;c.style.padding=e+"px "+d+"px "+e+"px "+d+"px";d=this.getConstants().FIELD_TEXT_HEIGHT+this.getConstants().FIELD_BORDER_RECT_Y_PADDING;c.style.lineHeight=d*b+"px";a.appendChild(c);c.value=c.defaultValue=this.getEditorText_(this.value_);c.untypedDefaultValue_=this.value_;c.oldValue_=null;Blockly.utils.userAgent.GECKO?setTimeout(this.resizeEditor_.bind(this),0):this.resizeEditor_();this.bindInputEvents_(c);return c}; -Blockly.FieldMultilineInput.prototype.setMaxLines=function(a){"number"===typeof a&&0this.max_&&Blockly.utils.aria.setState(a,Blockly.utils.aria.State.VALUEMAX,this.max_);return a};Blockly.fieldRegistry.register("field_number",Blockly.FieldNumber);Blockly.FieldVariable=function(a,b,c,d,e){this.menuGenerator_=Blockly.FieldVariable.dropdownCreate;this.defaultVariableName="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())}; -Blockly.FieldVariable.prototype.toXml=function(a){this.initModel();a.id=this.variable_.getId();a.textContent=this.variable_.name;this.variable_.type&&a.setAttribute("variabletype",this.variable_.type);return a};Blockly.FieldVariable.prototype.setSourceBlock=function(a){if(a.isShadow())throw Error("Variable fields are not allowed to exist on shadow blocks.");Blockly.FieldVariable.superClass_.setSourceBlock.call(this,a)}; -Blockly.FieldVariable.prototype.getValue=function(){return this.variable_?this.variable_.getId():null};Blockly.FieldVariable.prototype.getText=function(){return this.variable_?this.variable_.name:""};Blockly.FieldVariable.prototype.getVariable=function(){return this.variable_};Blockly.FieldVariable.prototype.getValidator=function(){return this.variable_?this.validator_:null}; -Blockly.FieldVariable.prototype.doClassValidation_=function(a){if(null===a)return null;var b=Blockly.Variables.getVariable(this.sourceBlock_.workspace,a);if(!b)return console.warn("Variable id doesn't point to a real variable! ID was "+a),null;b=b.type;return this.typeIsAllowed_(b)?a:(console.warn("Variable type doesn't match this field! Type was "+b),null)}; -Blockly.FieldVariable.prototype.doValueUpdate_=function(a){this.variable_=Blockly.Variables.getVariable(this.sourceBlock_.workspace,a);Blockly.FieldVariable.superClass_.doValueUpdate_.call(this,a)};Blockly.FieldVariable.prototype.typeIsAllowed_=function(a){var b=this.getVariableTypes_();if(!b)return!0;for(var c=0;crect,",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.Types={NONE:0,FIELD:1,HAT:2,ICON:4,SPACER:8,BETWEEN_ROW_SPACER:16,IN_ROW_SPACER:32,EXTERNAL_VALUE_INPUT:64,INPUT:128,INLINE_INPUT:256,STATEMENT_INPUT:512,CONNECTION:1024,PREVIOUS_CONNECTION:2048,NEXT_CONNECTION:4096,OUTPUT_CONNECTION:8192,CORNER:16384,LEFT_SQUARE_CORNER:32768,LEFT_ROUND_CORNER:65536,RIGHT_SQUARE_CORNER:131072,RIGHT_ROUND_CORNER:262144,JAGGED_EDGE:524288,ROW:1048576,TOP_ROW:2097152,BOTTOM_ROW:4194304,INPUT_ROW:8388608}; -Blockly.blockRendering.Types.LEFT_CORNER=Blockly.blockRendering.Types.LEFT_SQUARE_CORNER|Blockly.blockRendering.Types.LEFT_ROUND_CORNER;Blockly.blockRendering.Types.RIGHT_CORNER=Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER|Blockly.blockRendering.Types.RIGHT_ROUND_CORNER;Blockly.blockRendering.Types.nextTypeValue_=16777216; -Blockly.blockRendering.Types.getType=function(a){Object.prototype.hasOwnProperty.call(Blockly.blockRendering.Types,a)||(Blockly.blockRendering.Types[a]=Blockly.blockRendering.Types.nextTypeValue_,Blockly.blockRendering.Types.nextTypeValue_<<=1);return Blockly.blockRendering.Types[a]};Blockly.blockRendering.Types.isField=function(a){return a.type&Blockly.blockRendering.Types.FIELD};Blockly.blockRendering.Types.isHat=function(a){return a.type&Blockly.blockRendering.Types.HAT}; -Blockly.blockRendering.Types.isIcon=function(a){return a.type&Blockly.blockRendering.Types.ICON};Blockly.blockRendering.Types.isSpacer=function(a){return a.type&Blockly.blockRendering.Types.SPACER};Blockly.blockRendering.Types.isInRowSpacer=function(a){return a.type&Blockly.blockRendering.Types.IN_ROW_SPACER};Blockly.blockRendering.Types.isInput=function(a){return a.type&Blockly.blockRendering.Types.INPUT};Blockly.blockRendering.Types.isExternalInput=function(a){return a.type&Blockly.blockRendering.Types.EXTERNAL_VALUE_INPUT}; -Blockly.blockRendering.Types.isInlineInput=function(a){return a.type&Blockly.blockRendering.Types.INLINE_INPUT};Blockly.blockRendering.Types.isStatementInput=function(a){return a.type&Blockly.blockRendering.Types.STATEMENT_INPUT};Blockly.blockRendering.Types.isPreviousConnection=function(a){return a.type&Blockly.blockRendering.Types.PREVIOUS_CONNECTION};Blockly.blockRendering.Types.isNextConnection=function(a){return a.type&Blockly.blockRendering.Types.NEXT_CONNECTION}; -Blockly.blockRendering.Types.isPreviousOrNextConnection=function(a){return a.type&(Blockly.blockRendering.Types.PREVIOUS_CONNECTION|Blockly.blockRendering.Types.NEXT_CONNECTION)};Blockly.blockRendering.Types.isLeftRoundedCorner=function(a){return a.type&Blockly.blockRendering.Types.LEFT_ROUND_CORNER};Blockly.blockRendering.Types.isRightRoundedCorner=function(a){return a.type&Blockly.blockRendering.Types.RIGHT_ROUND_CORNER}; -Blockly.blockRendering.Types.isLeftSquareCorner=function(a){return a.type&Blockly.blockRendering.Types.LEFT_SQUARE_CORNER};Blockly.blockRendering.Types.isRightSquareCorner=function(a){return a.type&Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER};Blockly.blockRendering.Types.isCorner=function(a){return a.type&Blockly.blockRendering.Types.CORNER};Blockly.blockRendering.Types.isJaggedEdge=function(a){return a.type&Blockly.blockRendering.Types.JAGGED_EDGE}; -Blockly.blockRendering.Types.isRow=function(a){return a.type&Blockly.blockRendering.Types.ROW};Blockly.blockRendering.Types.isBetweenRowSpacer=function(a){return a.type&Blockly.blockRendering.Types.BETWEEN_ROW_SPACER};Blockly.blockRendering.Types.isTopRow=function(a){return a.type&Blockly.blockRendering.Types.TOP_ROW};Blockly.blockRendering.Types.isBottomRow=function(a){return a.type&Blockly.blockRendering.Types.BOTTOM_ROW}; -Blockly.blockRendering.Types.isTopOrBottomRow=function(a){return a.type&(Blockly.blockRendering.Types.TOP_ROW|Blockly.blockRendering.Types.BOTTOM_ROW)};Blockly.blockRendering.Types.isInputRow=function(a){return a.type&Blockly.blockRendering.Types.INPUT_ROW};Blockly.blockRendering.Measurable=function(a){this.height=this.width=0;this.type=Blockly.blockRendering.Types.NONE;this.centerline=this.xPos=0;this.constants_=a;this.notchOffset=this.constants_.NOTCH_OFFSET_LEFT};Blockly.blockRendering.Connection=function(a,b){Blockly.blockRendering.Connection.superClass_.constructor.call(this,a);this.connectionModel=b;this.shape=this.constants_.shapeFor(b);this.isDynamicShape=!!this.shape.isDynamic;this.type|=Blockly.blockRendering.Types.CONNECTION};Blockly.utils.object.inherits(Blockly.blockRendering.Connection,Blockly.blockRendering.Measurable); -Blockly.blockRendering.OutputConnection=function(a,b){Blockly.blockRendering.OutputConnection.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.OUTPUT_CONNECTION;this.height=this.isDynamicShape?0:this.shape.height;this.startX=this.width=this.isDynamicShape?0:this.shape.width;this.connectionOffsetY=this.constants_.TAB_OFFSET_FROM_TOP;this.connectionOffsetX=0};Blockly.utils.object.inherits(Blockly.blockRendering.OutputConnection,Blockly.blockRendering.Connection); -Blockly.blockRendering.PreviousConnection=function(a,b){Blockly.blockRendering.PreviousConnection.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.PREVIOUS_CONNECTION;this.height=this.shape.height;this.width=this.shape.width};Blockly.utils.object.inherits(Blockly.blockRendering.PreviousConnection,Blockly.blockRendering.Connection); -Blockly.blockRendering.NextConnection=function(a,b){Blockly.blockRendering.NextConnection.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.NEXT_CONNECTION;this.height=this.shape.height;this.width=this.shape.width};Blockly.utils.object.inherits(Blockly.blockRendering.NextConnection,Blockly.blockRendering.Connection);Blockly.blockRendering.InputConnection=function(a,b){Blockly.blockRendering.InputConnection.superClass_.constructor.call(this,a,b.connection);this.type|=Blockly.blockRendering.Types.INPUT;this.input=b;this.align=b.align;(this.connectedBlock=b.connection&&b.connection.targetBlock()?b.connection.targetBlock():null)?(a=this.connectedBlock.getHeightWidth(),this.connectedBlockWidth=a.width,this.connectedBlockHeight=a.height):this.connectedBlockHeight=this.connectedBlockWidth=0;this.connectionOffsetY=this.connectionOffsetX= -0};Blockly.utils.object.inherits(Blockly.blockRendering.InputConnection,Blockly.blockRendering.Connection); -Blockly.blockRendering.InlineInput=function(a,b){Blockly.blockRendering.InlineInput.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.INLINE_INPUT;this.connectedBlock?(this.width=this.connectedBlockWidth,this.height=this.connectedBlockHeight):(this.height=this.constants_.EMPTY_INLINE_INPUT_HEIGHT,this.width=this.constants_.EMPTY_INLINE_INPUT_PADDING);this.connectionHeight=this.isDynamicShape?this.shape.height(this.height):this.shape.height;this.connectionWidth=this.isDynamicShape? -this.shape.width(this.height):this.shape.width;this.connectedBlock||(this.width+=this.connectionWidth*(this.isDynamicShape?2:1));this.connectionOffsetY=this.isDynamicShape?this.shape.connectionOffsetY(this.connectionHeight):this.constants_.TAB_OFFSET_FROM_TOP;this.connectionOffsetX=this.isDynamicShape?this.shape.connectionOffsetX(this.connectionWidth):0};Blockly.utils.object.inherits(Blockly.blockRendering.InlineInput,Blockly.blockRendering.InputConnection); -Blockly.blockRendering.StatementInput=function(a,b){Blockly.blockRendering.StatementInput.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.STATEMENT_INPUT;this.height=this.connectedBlock?this.connectedBlockHeight+this.constants_.STATEMENT_BOTTOM_SPACER:this.constants_.EMPTY_STATEMENT_INPUT_HEIGHT;this.width=this.constants_.STATEMENT_INPUT_NOTCH_OFFSET+this.shape.width};Blockly.utils.object.inherits(Blockly.blockRendering.StatementInput,Blockly.blockRendering.InputConnection); -Blockly.blockRendering.ExternalValueInput=function(a,b){Blockly.blockRendering.ExternalValueInput.superClass_.constructor.call(this,a,b);this.type|=Blockly.blockRendering.Types.EXTERNAL_VALUE_INPUT;this.height=this.connectedBlock?this.connectedBlockHeight-this.constants_.TAB_OFFSET_FROM_TOP-this.constants_.MEDIUM_PADDING:this.shape.height;this.width=this.shape.width+this.constants_.EXTERNAL_VALUE_INPUT_PADDING;this.connectionOffsetY=this.constants_.TAB_OFFSET_FROM_TOP;this.connectionHeight=this.shape.height; -this.connectionWidth=this.shape.width};Blockly.utils.object.inherits(Blockly.blockRendering.ExternalValueInput,Blockly.blockRendering.InputConnection);Blockly.blockRendering.Icon=function(a,b){Blockly.blockRendering.Icon.superClass_.constructor.call(this,a);this.icon=b;this.isVisible=b.isVisible();this.type|=Blockly.blockRendering.Types.ICON;a=b.getCorrectedSize();this.height=a.height;this.width=a.width};Blockly.utils.object.inherits(Blockly.blockRendering.Icon,Blockly.blockRendering.Measurable); -Blockly.blockRendering.JaggedEdge=function(a){Blockly.blockRendering.JaggedEdge.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.JAGGED_EDGE;this.height=this.constants_.JAGGED_TEETH.height;this.width=this.constants_.JAGGED_TEETH.width};Blockly.utils.object.inherits(Blockly.blockRendering.JaggedEdge,Blockly.blockRendering.Measurable); -Blockly.blockRendering.Field=function(a,b,c){Blockly.blockRendering.Field.superClass_.constructor.call(this,a);this.field=b;this.isEditable=b.EDITABLE;this.flipRtl=b.getFlipRtl();this.type|=Blockly.blockRendering.Types.FIELD;a=this.field.getSize();this.height=a.height;this.width=a.width;this.parentInput=c};Blockly.utils.object.inherits(Blockly.blockRendering.Field,Blockly.blockRendering.Measurable); -Blockly.blockRendering.Hat=function(a){Blockly.blockRendering.Hat.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.HAT;this.height=this.constants_.START_HAT.height;this.width=this.constants_.START_HAT.width;this.ascenderHeight=this.height};Blockly.utils.object.inherits(Blockly.blockRendering.Hat,Blockly.blockRendering.Measurable); -Blockly.blockRendering.SquareCorner=function(a,b){Blockly.blockRendering.SquareCorner.superClass_.constructor.call(this,a);this.type=(b&&"left"!=b?Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER:Blockly.blockRendering.Types.LEFT_SQUARE_CORNER)|Blockly.blockRendering.Types.CORNER;this.width=this.height=this.constants_.NO_PADDING};Blockly.utils.object.inherits(Blockly.blockRendering.SquareCorner,Blockly.blockRendering.Measurable); -Blockly.blockRendering.RoundCorner=function(a,b){Blockly.blockRendering.RoundCorner.superClass_.constructor.call(this,a);this.type=(b&&"left"!=b?Blockly.blockRendering.Types.RIGHT_ROUND_CORNER:Blockly.blockRendering.Types.LEFT_ROUND_CORNER)|Blockly.blockRendering.Types.CORNER;this.width=this.constants_.CORNER_RADIUS;this.height=this.constants_.CORNER_RADIUS/2};Blockly.utils.object.inherits(Blockly.blockRendering.RoundCorner,Blockly.blockRendering.Measurable); -Blockly.blockRendering.InRowSpacer=function(a,b){Blockly.blockRendering.InRowSpacer.superClass_.constructor.call(this,a);this.type=this.type|Blockly.blockRendering.Types.SPACER|Blockly.blockRendering.Types.IN_ROW_SPACER;this.width=b;this.height=this.constants_.SPACER_DEFAULT_HEIGHT};Blockly.utils.object.inherits(Blockly.blockRendering.InRowSpacer,Blockly.blockRendering.Measurable);Blockly.blockRendering.Row=function(a){this.type=Blockly.blockRendering.Types.ROW;this.elements=[];this.xPos=this.yPos=this.widthWithConnectedBlocks=this.minWidth=this.minHeight=this.width=this.height=0;this.hasJaggedEdge=this.hasDummyInput=this.hasInlineInput=this.hasStatement=this.hasExternalInput=!1;this.constants_=a;this.notchOffset=this.constants_.NOTCH_OFFSET_LEFT;this.align=null}; -Blockly.blockRendering.Row.prototype.measure=function(){throw Error("Unexpected attempt to measure a base Row.");};Blockly.blockRendering.Row.prototype.getLastInput=function(){for(var a=this.elements.length-1,b;b=this.elements[a];a--)if(Blockly.blockRendering.Types.isInput(b))return b;return null};Blockly.blockRendering.Row.prototype.startsWithElemSpacer=function(){return!0};Blockly.blockRendering.Row.prototype.endsWithElemSpacer=function(){return!0}; -Blockly.blockRendering.Row.prototype.getFirstSpacer=function(){for(var a=0,b;b=this.elements[a];a++)if(Blockly.blockRendering.Types.isSpacer(b))return b;return null};Blockly.blockRendering.Row.prototype.getLastSpacer=function(){for(var a=this.elements.length-1,b;b=this.elements[a];a--)if(Blockly.blockRendering.Types.isSpacer(b))return b;return null}; -Blockly.blockRendering.TopRow=function(a){Blockly.blockRendering.TopRow.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.TOP_ROW;this.ascenderHeight=this.capline=0;this.hasPreviousConnection=!1;this.connection=null};Blockly.utils.object.inherits(Blockly.blockRendering.TopRow,Blockly.blockRendering.Row); -Blockly.blockRendering.TopRow.prototype.hasLeftSquareCorner=function(a){var b=(a.hat?"cap"===a.hat:this.constants_.ADD_START_HATS)&&!a.outputConnection&&!a.previousConnection,c=a.getPreviousBlock();return!!a.outputConnection||b||(c?c.getNextBlock()==a:!1)};Blockly.blockRendering.TopRow.prototype.hasRightSquareCorner=function(a){return!0}; -Blockly.blockRendering.TopRow.prototype.measure=function(){for(var a=0,b=0,c=0,d=0,e;e=this.elements[d];d++)b+=e.width,Blockly.blockRendering.Types.isSpacer(e)||(Blockly.blockRendering.Types.isHat(e)?c=Math.max(c,e.ascenderHeight):a=Math.max(a,e.height));this.width=Math.max(this.minWidth,b);this.height=Math.max(this.minHeight,a)+c;this.capline=this.ascenderHeight=c;this.widthWithConnectedBlocks=this.width};Blockly.blockRendering.TopRow.prototype.startsWithElemSpacer=function(){return!1}; -Blockly.blockRendering.TopRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.blockRendering.BottomRow=function(a){Blockly.blockRendering.BottomRow.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.BOTTOM_ROW;this.hasNextConnection=!1;this.connection=null;this.baseline=this.descenderHeight=0};Blockly.utils.object.inherits(Blockly.blockRendering.BottomRow,Blockly.blockRendering.Row); -Blockly.blockRendering.BottomRow.prototype.hasLeftSquareCorner=function(a){return!!a.outputConnection||!!a.getNextBlock()};Blockly.blockRendering.BottomRow.prototype.hasRightSquareCorner=function(a){return!0}; -Blockly.blockRendering.BottomRow.prototype.measure=function(){for(var a=0,b=0,c=0,d=0,e;e=this.elements[d];d++)b+=e.width,Blockly.blockRendering.Types.isSpacer(e)||(Blockly.blockRendering.Types.isNextConnection(e)?c=Math.max(c,e.height):a=Math.max(a,e.height));this.width=Math.max(this.minWidth,b);this.height=Math.max(this.minHeight,a)+c;this.descenderHeight=c;this.widthWithConnectedBlocks=this.width};Blockly.blockRendering.BottomRow.prototype.startsWithElemSpacer=function(){return!1}; -Blockly.blockRendering.BottomRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.blockRendering.SpacerRow=function(a,b,c){Blockly.blockRendering.SpacerRow.superClass_.constructor.call(this,a);this.type=this.type|Blockly.blockRendering.Types.SPACER|Blockly.blockRendering.Types.BETWEEN_ROW_SPACER;this.width=c;this.height=b;this.followsStatement=!1;this.widthWithConnectedBlocks=0;this.elements=[new Blockly.blockRendering.InRowSpacer(this.constants_,c)]}; -Blockly.utils.object.inherits(Blockly.blockRendering.SpacerRow,Blockly.blockRendering.Row);Blockly.blockRendering.SpacerRow.prototype.measure=function(){};Blockly.blockRendering.InputRow=function(a){Blockly.blockRendering.InputRow.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.INPUT_ROW;this.connectedBlockWidths=0};Blockly.utils.object.inherits(Blockly.blockRendering.InputRow,Blockly.blockRendering.Row); -Blockly.blockRendering.InputRow.prototype.measure=function(){this.width=this.minWidth;this.height=this.minHeight;for(var a=0,b=0,c;c=this.elements[b];b++)this.width+=c.width,Blockly.blockRendering.Types.isInput(c)&&(Blockly.blockRendering.Types.isStatementInput(c)?a+=c.connectedBlockWidth:Blockly.blockRendering.Types.isExternalInput(c)&&0!=c.connectedBlockWidth&&(a+=c.connectedBlockWidth-c.connectionWidth)),Blockly.blockRendering.Types.isSpacer(c)||(this.height=Math.max(this.height,c.height));this.connectedBlockWidths= -a;this.widthWithConnectedBlocks=this.width+a};Blockly.blockRendering.InputRow.prototype.endsWithElemSpacer=function(){return!this.hasExternalInput&&!this.hasStatement};Blockly.blockRendering.RenderInfo=function(a,b){this.block_=b;this.renderer_=a;this.constants_=this.renderer_.getConstants();this.outputConnection=b.outputConnection?new Blockly.blockRendering.OutputConnection(this.constants_,b.outputConnection):null;this.isInline=b.getInputsInline()&&!b.isCollapsed();this.isCollapsed=b.isCollapsed();this.isInsertionMarker=b.isInsertionMarker();this.RTL=b.RTL;this.statementEdge=this.width=this.widthWithChildren=this.height=0;this.rows=[];this.inputRows=[];this.hiddenIcons= -[];this.topRow=new Blockly.blockRendering.TopRow(this.constants_);this.bottomRow=new Blockly.blockRendering.BottomRow(this.constants_);this.startY=this.startX=0};Blockly.blockRendering.RenderInfo.prototype.getRenderer=function(){return this.renderer_};Blockly.blockRendering.RenderInfo.prototype.measure=function(){this.createRows_();this.addElemSpacing_();this.addRowSpacing_();this.computeBounds_();this.alignRowElements_();this.finalize_()}; -Blockly.blockRendering.RenderInfo.prototype.createRows_=function(){this.populateTopRow_();this.rows.push(this.topRow);var a=new Blockly.blockRendering.InputRow(this.constants_);this.inputRows.push(a);for(var b=this.block_.getIcons(),c=0,d;d=b[c];c++){var e=new Blockly.blockRendering.Icon(this.constants_,d);this.isCollapsed&&d.collapseHidden?this.hiddenIcons.push(e):a.elements.push(e)}d=null;for(c=0;b=this.block_.inputList[c];c++)if(b.isVisible()){this.shouldStartNewRow_(b,d)&&(this.rows.push(a),a= -new Blockly.blockRendering.InputRow(this.constants_),this.inputRows.push(a));for(d=0;e=b.fieldRow[d];d++)a.elements.push(new Blockly.blockRendering.Field(this.constants_,e,b));this.addInput_(b,a);d=b}this.isCollapsed&&(a.hasJaggedEdge=!0,a.elements.push(new Blockly.blockRendering.JaggedEdge(this.constants_)));(a.elements.length||a.hasDummyInput)&&this.rows.push(a);this.populateBottomRow_();this.rows.push(this.bottomRow)}; -Blockly.blockRendering.RenderInfo.prototype.populateTopRow_=function(){var a=!!this.block_.previousConnection,b=(this.block_.hat?"cap"===this.block_.hat:this.constants_.ADD_START_HATS)&&!this.outputConnection&&!a,c=this.topRow.hasLeftSquareCorner(this.block_)?Blockly.blockRendering.SquareCorner:Blockly.blockRendering.RoundCorner;this.topRow.elements.push(new c(this.constants_));b?(a=new Blockly.blockRendering.Hat(this.constants_),this.topRow.elements.push(a),this.topRow.capline=a.ascenderHeight): -a&&(this.topRow.hasPreviousConnection=!0,this.topRow.connection=new Blockly.blockRendering.PreviousConnection(this.constants_,this.block_.previousConnection),this.topRow.elements.push(this.topRow.connection));this.block_.inputList.length&&this.block_.inputList[0].type==Blockly.inputTypes.STATEMENT&&!this.block_.isCollapsed()?this.topRow.minHeight=this.constants_.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT:this.topRow.minHeight=this.constants_.TOP_ROW_MIN_HEIGHT;c=this.topRow.hasRightSquareCorner(this.block_)? -Blockly.blockRendering.SquareCorner:Blockly.blockRendering.RoundCorner;this.topRow.elements.push(new c(this.constants_,"right"))}; -Blockly.blockRendering.RenderInfo.prototype.populateBottomRow_=function(){this.bottomRow.hasNextConnection=!!this.block_.nextConnection;this.bottomRow.minHeight=this.block_.inputList.length&&this.block_.inputList[this.block_.inputList.length-1].type==Blockly.inputTypes.STATEMENT?this.constants_.BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT:this.constants_.BOTTOM_ROW_MIN_HEIGHT;this.bottomRow.hasLeftSquareCorner(this.block_)?this.bottomRow.elements.push(new Blockly.blockRendering.SquareCorner(this.constants_)): -this.bottomRow.elements.push(new Blockly.blockRendering.RoundCorner(this.constants_));this.bottomRow.hasNextConnection&&(this.bottomRow.connection=new Blockly.blockRendering.NextConnection(this.constants_,this.block_.nextConnection),this.bottomRow.elements.push(this.bottomRow.connection));this.bottomRow.hasRightSquareCorner(this.block_)?this.bottomRow.elements.push(new Blockly.blockRendering.SquareCorner(this.constants_,"right")):this.bottomRow.elements.push(new Blockly.blockRendering.RoundCorner(this.constants_, + 'use strict';var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(a){return a.raw=a};$jscomp.createTemplateTagFirstArgWithRaw=function(a,b){a.raw=b;return a};$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return b>>0,$jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE? +$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+c+"$"+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSymbol[e],{configurable:!0,writable:!0,value:b})))}; +$jscomp.getConstructImplementation=function(){function a(){function c(){}new c;Reflect.construct(c,[],function(){});return new c instanceof c}if($jscomp.TRUST_ES6_POLYFILLS&&"undefined"!=typeof Reflect&&Reflect.construct){if(a())return Reflect.construct;var b=Reflect.construct;return function(c,d,e){c=b(c,d);e&&Reflect.setPrototypeOf(c,e.prototype);return c}}return function(c,d,e){void 0===e&&(e=c);e=$jscomp.objectCreate(e.prototype||Object.prototype);return Function.prototype.apply.call(c,e,d)|| +e}};$jscomp.construct={valueOf:$jscomp.getConstructImplementation}.valueOf();$jscomp.underscoreProtoCanBeSet=function(){var a={a:!0},b={};try{return b.__proto__=a,b.a}catch(c){}return!1};$jscomp.setPrototypeOf=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.setPrototypeOf?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null; +$jscomp.inherits=function(a,b){a.prototype=$jscomp.objectCreate(b.prototype);a.prototype.constructor=a;if($jscomp.setPrototypeOf){var c=$jscomp.setPrototypeOf;c(a,b)}else for(c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.superClass_=b.prototype};$jscomp.polyfill("Reflect",function(a){return a?a:{}},"es6","es3");$jscomp.polyfill("Reflect.construct",function(a){return $jscomp.construct},"es6","es3"); +$jscomp.polyfill("Reflect.setPrototypeOf",function(a){if(a)return a;if($jscomp.setPrototypeOf){var b=$jscomp.setPrototypeOf;return function(c,d){try{return b(c,d),!0}catch(e){return!1}}}return null},"es6","es5");$jscomp.checkStringArgs=function(a,b,c){if(null==a)throw new TypeError("The 'this' value for String.prototype."+c+" must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype."+c+" must not be a regular expression");return a+""}; +$jscomp.polyfill("String.prototype.startsWith",function(a){return a?a:function(b,c){var d=$jscomp.checkStringArgs(this,b,"startsWith");b+="";var e=d.length,f=b.length;c=Math.max(0,Math.min(c|0,d.length));for(var g=0;g=f}},"es6","es3");$jscomp.polyfill("Object.setPrototypeOf",function(a){return a||$jscomp.setPrototypeOf},"es6","es5");$jscomp.initSymbol=function(){}; +$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(f,g){this.$jscomp$symbol$id_=f;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:g})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(f){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(f||"")+"_"+d++,f)};return e},"es6","es3"); +$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;cb&&(b=c[d].length);var e=-Infinity,f=1;do{d=e;var g=a;a=[];e=c.length/f;for(var h=1,k=0;kd);return g}, +module$contents$Blockly$utils$string_wrapScore=function(a,b,c){for(var d=[0],e=[],f=0;fd&&(d=h,e=g)}return e?module$contents$Blockly$utils$string_wrapMutate(a,e,c):b},module$contents$Blockly$utils$string_wrapToText=function(a,b){for(var c=[],d=0;d=this.left&&a<=this.right&&b>=this.top&&b<=this.bottom};module$exports$Blockly$utils$Rect.prototype.intersects=function(a){return!(this.left>a.right||this.righta.bottom||this.bottoma&&0<=b&&256>b&&0<=c&&256> +c)?(0,module$exports$Blockly$utils$colour.rgbToHex)(a,b,c):null},rgbToHex:function(a,b,c){b=a<<16|b<<8|c;return 16>a?"#"+(16777216|b).toString(16).substr(1):"#"+b.toString(16)},hexToRgb:function(a){a=(0,module$exports$Blockly$utils$colour.parse)(a);if(!a)return[0,0,0];a=parseInt(a.substr(1),16);return[a>>16,a>>8&255,a&255]},hsvToHex:function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=c;else{var g=Math.floor(a/60),h=a/60-g;a=c*(1-b);var k=c*(1-b*h);b=c*(1-b*(1-h));switch(g){case 1:d=k;e=c;f=a;break;case 2:d= +a;e=c;f=b;break;case 3:d=a;e=k;f=c;break;case 4:d=b;e=a;f=c;break;case 5:d=c;e=a;f=k;break;case 6:case 0:d=c,e=b,f=a}}return(0,module$exports$Blockly$utils$colour.rgbToHex)(Math.floor(d),Math.floor(e),Math.floor(f))},blend:function(a,b,c){a=(0,module$exports$Blockly$utils$colour.parse)(a);if(!a)return null;b=(0,module$exports$Blockly$utils$colour.parse)(b);if(!b)return null;a=(0,module$exports$Blockly$utils$colour.hexToRgb)(a);b=(0,module$exports$Blockly$utils$colour.hexToRgb)(b);return(0,module$exports$Blockly$utils$colour.rgbToHex)(Math.round(b[0]+ +c*(a[0]-b[0])),Math.round(b[1]+c*(a[1]-b[1])),Math.round(b[2]+c*(a[2]-b[2])))},names:{aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00"},hueToHex:function(a){return(0,module$exports$Blockly$utils$colour.hsvToHex)(a,module$exports$Blockly$internalConstants.HSV_SATURATION,255*module$exports$Blockly$internalConstants.HSV_VALUE)}};var module$exports$Blockly$utils$deprecation={warn:function(a,b,c,d){a=a+" was deprecated on "+b+" and will be deleted on "+c+".";d&&(a+="\nUse "+d+" instead.");console.warn(a)}};var module$exports$Blockly$utils$idGenerator={TEST_ONLY:{}},module$contents$Blockly$utils$idGenerator_nextId=0;module$exports$Blockly$utils$idGenerator.getNextUniqueId=function(){return"blockly-"+(module$contents$Blockly$utils$idGenerator_nextId++).toString(36)};var module$contents$Blockly$utils$idGenerator_soup="!#$%()*+,-./:;=?@[]^_`{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +module$exports$Blockly$utils$idGenerator.TEST_ONLY.genUid=function(){for(var a=module$contents$Blockly$utils$idGenerator_soup.length,b=[],c=0;20>c;c++)b[c]=module$contents$Blockly$utils$idGenerator_soup.charAt(Math.random()*a);return b.join("")};module$exports$Blockly$utils$idGenerator.genUid=function(){return module$exports$Blockly$utils$idGenerator.TEST_ONLY.genUid()};var module$exports$Blockly$utils$math={toRadians:function(a){return a*Math.PI/180},toDegrees:function(a){return 180*a/Math.PI},clamp:function(a,b,c){if(c/g,"<$1$2>")};module$exports$Blockly$Xml.domToPrettyText=function(a){a=(0,module$exports$Blockly$Xml.domToText)(a).split("<");for(var b="",c=1;c"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1");return a.replace(/^\n/,"")}; +module$exports$Blockly$Xml.textToDom=function(a){var b=(0,module$exports$Blockly$utils$xml.textToDomDocument)(a);if(!b||!b.documentElement||b.getElementsByTagName("parsererror").length)throw Error("textToDom was unable to parse: "+a);return b.documentElement};module$exports$Blockly$Xml.clearWorkspaceAndLoadFromXml=function(a,b){b.setResizesEnabled(!1);b.clear();a=(0,module$exports$Blockly$Xml.domToWorkspace)(a,b);b.setResizesEnabled(!0);return a}; +module$exports$Blockly$Xml.domToWorkspace=function(a,b){if(a instanceof module$exports$Blockly$Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];(0,module$exports$Blockly$utils$dom.startTextWidthCache)();var e=(0,module$exports$Blockly$Events$utils.getGroup)();e||(0,module$exports$Blockly$Events$utils.setGroup)(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var f=!0;try{for(var g=0,h=void 0;h=a.childNodes[g];g++){var k= +h.nodeName.toLowerCase(),l=h;if("block"==k||"shadow"==k&&!(0,module$exports$Blockly$Events$utils.getRecordUndo)()){var m=(0,module$exports$Blockly$Xml.domToBlock)(l,b);c.push(m.id);var n=l.hasAttribute("x")?parseInt(l.getAttribute("x"),10):10,p=l.hasAttribute("y")?parseInt(l.getAttribute("y"),10):10;isNaN(n)||isNaN(p)||m.moveBy(b.RTL?d-n:n,p);f=!1}else{if("shadow"==k)throw TypeError("Shadow block cannot be a top-level block.");if("comment"==k)if(b.rendered){var q=module$exports$Blockly$WorkspaceCommentSvg; +q?q.fromXml(l,b,d):console.warn("Missing require for Blockly.WorkspaceCommentSvg, ignoring workspace comment.")}else(q=module$exports$Blockly$WorkspaceComment)?q.fromXml(l,b):console.warn("Missing require for Blockly.WorkspaceComment, ignoring workspace comment.");else if("variables"==k){if(f)(0,module$exports$Blockly$Xml.domToVariables)(l,b);else throw Error("'variables' tag must exist once before block and shadow tag elements in the workspace XML, but it was found in another location.");f=!1}}}}finally{e|| +(0,module$exports$Blockly$Events$utils.setGroup)(!1),(0,module$exports$Blockly$utils$dom.stopTextWidthCache)()}b.setResizesEnabled&&b.setResizesEnabled(!0);(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.FINISHED_LOADING))(b));return c}; +module$exports$Blockly$Xml.appendDomToWorkspace=function(a,b){var c;Object.prototype.hasOwnProperty.call(b,"scale")&&(c=b.getBlocksBoundingBox());a=(0,module$exports$Blockly$Xml.domToWorkspace)(a,b);if(c&&c.top!=c.bottom){var d=c.bottom;c=b.RTL?c.right:c.left;for(var e=Infinity,f=-Infinity,g=Infinity,h=0;hf&&(f=k.x)}d=d-g+10;c=b.RTL?c-f:c-e;for(e=0;e document.");}else a=null;return a};var module$exports$Blockly$utils={aria:module$exports$Blockly$utils$aria,colour:module$exports$Blockly$utils$colour,Coordinate:module$exports$Blockly$utils$Coordinate,deprecation:module$exports$Blockly$utils$deprecation,dom:module$exports$Blockly$utils$dom};module$exports$Blockly$utils.global=module$exports$Blockly$utils$global.globalThis;module$exports$Blockly$utils.idGenerator=module$exports$Blockly$utils$idGenerator;module$exports$Blockly$utils.KeyCodes=module$exports$Blockly$utils$KeyCodes; +module$exports$Blockly$utils.math=module$exports$Blockly$utils$math;module$exports$Blockly$utils.Metrics=module$exports$Blockly$utils$Metrics;module$exports$Blockly$utils.object=module$exports$Blockly$utils$object;module$exports$Blockly$utils.Rect=module$exports$Blockly$utils$Rect;module$exports$Blockly$utils.Size=module$exports$Blockly$utils$Size;module$exports$Blockly$utils.string=module$exports$Blockly$utils$string;module$exports$Blockly$utils.style=module$exports$Blockly$utils$style; +module$exports$Blockly$utils.Svg=module$exports$Blockly$utils$Svg;module$exports$Blockly$utils.svgPaths=module$exports$Blockly$utils$svgPaths;module$exports$Blockly$utils.toolbox=module$exports$Blockly$utils$toolbox;module$exports$Blockly$utils.userAgent=module$exports$Blockly$utils$userAgent;module$exports$Blockly$utils.xml=module$exports$Blockly$utils$xml; +module$exports$Blockly$utils.noEvent=function(a){(0,module$exports$Blockly$utils$deprecation.warn)("Blockly.utils.noEvent","September 2021","September 2022");a.preventDefault();a.stopPropagation()};module$exports$Blockly$utils.isTargetInput=function(a){(0,module$exports$Blockly$utils$deprecation.warn)("Blockly.utils.isTargetInput","September 2021","September 2022","Blockly.browserEvents.isTargetInput");return(0,module$exports$Blockly$browserEvents.isTargetInput)(a)}; +module$exports$Blockly$utils.getRelativeXY=function(a){var b=new module$exports$Blockly$utils$Coordinate(0,0),c=a.getAttribute("x");c&&(b.x=parseInt(c,10));if(c=a.getAttribute("y"))b.y=parseInt(c,10);if(c=(c=a.getAttribute("transform"))&&c.match(module$exports$Blockly$utils.getRelativeXY.XY_REGEX_))b.x+=Number(c[1]),c[3]&&(b.y+=Number(c[3]));(a=a.getAttribute("style"))&&-1=h?(e=2,f=h,(h=a.join(""))&&c.push(h),a.length=0):"{"==h?e=3:(a.push("%",h),e=0):2==e?"0"<=h&&"9">=h?f+=h:(c.push(parseInt(f,10)),g--,e=0):3==e&&(""==h?(a.splice(0,0,"%{"),g--,e=0):"}"!=h?a.push(h):(e=a.join(""),/[A-Z]\w*/i.test(e)? +(h=e.toUpperCase(),(h=(0,module$exports$Blockly$utils$string.startsWith)(h,"BKY_")?h.substring(4):null)&&h in Blockly.Msg?(e=Blockly.Msg[h],"string"==typeof e?Array.prototype.push.apply(c,module$contents$Blockly$utils_tokenizeInterpolation_(e,b)):b?c.push(String(e)):c.push(e)):c.push("%{"+e+"}")):c.push("%{"+e+"}"),e=a.length=0))}(b=a.join(""))&&c.push(b);d=[];for(f=a.length=0;f=c)return{hue:c,hex:(0,module$exports$Blockly$utils$colour.hsvToHex)(c,module$exports$Blockly$internalConstants.HSV_SATURATION,255*module$exports$Blockly$internalConstants.HSV_VALUE)};if(c=(0,module$exports$Blockly$utils$colour.parse)(b))return{hue:null,hex:c};c='Invalid colour: "'+b+'"';a!=b&&(c+=' (from "'+a+'")');throw Error(c); +};var module$exports$Blockly$Scrollbar=function(a,b,c,d,e){this.workspace_=a;this.pair_=c||!1;this.horizontal_=b;this.margin_=void 0!==e?e:module$exports$Blockly$Scrollbar.DEFAULT_SCROLLBAR_MARGIN;this.ratio=this.oldHostMetrics_=null;this.createDom_(d);this.position=new module$exports$Blockly$utils$Coordinate(0,0);a=module$exports$Blockly$Scrollbar.scrollbarThickness;b?(this.svgBackground_.setAttribute("height",a),this.outerSvg_.setAttribute("height",a),this.svgHandle_.setAttribute("height",a-5),this.svgHandle_.setAttribute("y", +2.5),this.lengthAttribute_="width",this.positionAttribute_="x"):(this.svgBackground_.setAttribute("width",a),this.outerSvg_.setAttribute("width",a),this.svgHandle_.setAttribute("width",a-5),this.svgHandle_.setAttribute("x",2.5),this.lengthAttribute_="height",this.positionAttribute_="y");this.onMouseDownBarWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.svgBackground_,"mousedown",this,this.onMouseDownBar_);this.onMouseDownHandleWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.svgHandle_, +"mousedown",this,this.onMouseDownHandle_)};module$exports$Blockly$Scrollbar.prototype.origin_=new module$exports$Blockly$utils$Coordinate(0,0);module$exports$Blockly$Scrollbar.prototype.startDragMouse_=0;module$exports$Blockly$Scrollbar.prototype.scrollbarLength_=0;module$exports$Blockly$Scrollbar.prototype.handleLength_=0;module$exports$Blockly$Scrollbar.prototype.handlePosition_=0;module$exports$Blockly$Scrollbar.prototype.isVisible_=!0; +module$exports$Blockly$Scrollbar.prototype.containerVisible_=!0;module$exports$Blockly$Scrollbar.scrollbarThickness=15;module$exports$Blockly$Touch.TOUCH_ENABLED&&(module$exports$Blockly$Scrollbar.scrollbarThickness=25);module$exports$Blockly$Scrollbar.DEFAULT_SCROLLBAR_MARGIN=.5; +module$exports$Blockly$Scrollbar.metricsAreEquivalent_=function(a,b){return a.viewWidth==b.viewWidth&&a.viewHeight==b.viewHeight&&a.viewLeft==b.viewLeft&&a.viewTop==b.viewTop&&a.absoluteTop==b.absoluteTop&&a.absoluteLeft==b.absoluteLeft&&a.scrollWidth==b.scrollWidth&&a.scrollHeight==b.scrollHeight&&a.scrollLeft==b.scrollLeft&&a.scrollTop==b.scrollTop}; +module$exports$Blockly$Scrollbar.prototype.dispose=function(){this.cleanUp_();(0,module$exports$Blockly$browserEvents.unbind)(this.onMouseDownBarWrapper_);this.onMouseDownBarWrapper_=null;(0,module$exports$Blockly$browserEvents.unbind)(this.onMouseDownHandleWrapper_);this.onMouseDownHandleWrapper_=null;(0,module$exports$Blockly$utils$dom.removeNode)(this.outerSvg_);this.svgBackground_=this.svgGroup_=this.outerSvg_=null;this.svgHandle_&&(this.workspace_.getThemeManager().unsubscribe(this.svgHandle_), +this.svgHandle_=null);this.workspace_=null};module$exports$Blockly$Scrollbar.prototype.constrainHandleLength_=function(a){return a=0>=a||isNaN(a)?0:Math.min(a,this.scrollbarLength_)};module$exports$Blockly$Scrollbar.prototype.setHandleLength_=function(a){this.handleLength_=a;this.svgHandle_.setAttribute(this.lengthAttribute_,this.handleLength_)};module$exports$Blockly$Scrollbar.prototype.constrainHandlePosition_=function(a){return a=0>=a||isNaN(a)?0:Math.min(a,this.scrollbarLength_-this.handleLength_)}; +module$exports$Blockly$Scrollbar.prototype.setHandlePosition=function(a){this.handlePosition_=a;this.svgHandle_.setAttribute(this.positionAttribute_,this.handlePosition_)};module$exports$Blockly$Scrollbar.prototype.setScrollbarLength_=function(a){this.scrollbarLength_=a;this.outerSvg_.setAttribute(this.lengthAttribute_,this.scrollbarLength_);this.svgBackground_.setAttribute(this.lengthAttribute_,this.scrollbarLength_)}; +module$exports$Blockly$Scrollbar.prototype.setPosition=function(a,b){this.position.x=a;this.position.y=b;(0,module$exports$Blockly$utils$dom.setCssTransform)(this.outerSvg_,"translate("+(this.position.x+this.origin_.x)+"px,"+(this.position.y+this.origin_.y)+"px)")}; +module$exports$Blockly$Scrollbar.prototype.resize=function(a){if(!a&&(a=this.workspace_.getMetrics(),!a))return;this.oldHostMetrics_&&module$exports$Blockly$Scrollbar.metricsAreEquivalent_(a,this.oldHostMetrics_)||(this.horizontal_?this.resizeHorizontal_(a):this.resizeVertical_(a),this.oldHostMetrics_=a,this.updateMetrics_())}; +module$exports$Blockly$Scrollbar.prototype.requiresViewResize_=function(a){return this.oldHostMetrics_?this.oldHostMetrics_.viewWidth!==a.viewWidth||this.oldHostMetrics_.viewHeight!==a.viewHeight||this.oldHostMetrics_.absoluteLeft!==a.absoluteLeft||this.oldHostMetrics_.absoluteTop!==a.absoluteTop:!0};module$exports$Blockly$Scrollbar.prototype.resizeHorizontal_=function(a){this.requiresViewResize_(a)?this.resizeViewHorizontal(a):this.resizeContentHorizontal(a)}; +module$exports$Blockly$Scrollbar.prototype.resizeViewHorizontal=function(a){var b=a.viewWidth-2*this.margin_;this.pair_&&(b-=module$exports$Blockly$Scrollbar.scrollbarThickness);this.setScrollbarLength_(Math.max(0,b));b=a.absoluteLeft+this.margin_;this.pair_&&this.workspace_.RTL&&(b+=module$exports$Blockly$Scrollbar.scrollbarThickness);this.setPosition(b,a.absoluteTop+a.viewHeight-module$exports$Blockly$Scrollbar.scrollbarThickness-this.margin_);this.resizeContentHorizontal(a)}; +module$exports$Blockly$Scrollbar.prototype.resizeContentHorizontal=function(a){if(a.viewWidth>=a.scrollWidth)this.setHandleLength_(this.scrollbarLength_),this.setHandlePosition(0),this.pair_||this.setVisible(!1);else{this.pair_||this.setVisible(!0);var b=this.scrollbarLength_*a.viewWidth/a.scrollWidth;b=this.constrainHandleLength_(b);this.setHandleLength_(b);b=a.scrollWidth-a.viewWidth;var c=this.scrollbarLength_-this.handleLength_;a=(a.viewLeft-a.scrollLeft)/b*c;a=this.constrainHandlePosition_(a); +this.setHandlePosition(a);this.ratio=c/b}};module$exports$Blockly$Scrollbar.prototype.resizeVertical_=function(a){this.requiresViewResize_(a)?this.resizeViewVertical(a):this.resizeContentVertical(a)}; +module$exports$Blockly$Scrollbar.prototype.resizeViewVertical=function(a){var b=a.viewHeight-2*this.margin_;this.pair_&&(b-=module$exports$Blockly$Scrollbar.scrollbarThickness);this.setScrollbarLength_(Math.max(0,b));this.setPosition(this.workspace_.RTL?a.absoluteLeft+this.margin_:a.absoluteLeft+a.viewWidth-module$exports$Blockly$Scrollbar.scrollbarThickness-this.margin_,a.absoluteTop+this.margin_);this.resizeContentVertical(a)}; +module$exports$Blockly$Scrollbar.prototype.resizeContentVertical=function(a){if(a.viewHeight>=a.scrollHeight)this.setHandleLength_(this.scrollbarLength_),this.setHandlePosition(0),this.pair_||this.setVisible(!1);else{this.pair_||this.setVisible(!0);var b=this.scrollbarLength_*a.viewHeight/a.scrollHeight;b=this.constrainHandleLength_(b);this.setHandleLength_(b);b=a.scrollHeight-a.viewHeight;var c=this.scrollbarLength_-this.handleLength_;a=(a.viewTop-a.scrollTop)/b*c;a=this.constrainHandlePosition_(a); +this.setHandlePosition(a);this.ratio=c/b}}; +module$exports$Blockly$Scrollbar.prototype.createDom_=function(a){var b="blocklyScrollbar"+(this.horizontal_?"Horizontal":"Vertical");a&&(b+=" "+a);this.outerSvg_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.SVG,{"class":b},null);this.svgGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{},this.outerSvg_);this.svgBackground_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"blocklyScrollbarBackground"}, +this.svgGroup_);a=Math.floor((module$exports$Blockly$Scrollbar.scrollbarThickness-5)/2);this.svgHandle_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"blocklyScrollbarHandle",rx:a,ry:a},this.svgGroup_);this.workspace_.getThemeManager().subscribe(this.svgHandle_,"scrollbarColour","fill");this.workspace_.getThemeManager().subscribe(this.svgHandle_,"scrollbarOpacity","fill-opacity");(0,module$exports$Blockly$utils$dom.insertAfter)(this.outerSvg_, +this.workspace_.getParentSvg())};module$exports$Blockly$Scrollbar.prototype.isVisible=function(){return this.isVisible_};module$exports$Blockly$Scrollbar.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};module$exports$Blockly$Scrollbar.prototype.setVisible=function(a){var b=a!=this.isVisible();if(this.pair_)throw Error("Unable to toggle visibility of paired scrollbars.");this.isVisible_=a;b&&this.updateDisplay_()}; +module$exports$Blockly$Scrollbar.prototype.updateDisplay_=function(){this.containerVisible_&&this.isVisible()?this.outerSvg_.setAttribute("display","block"):this.outerSvg_.setAttribute("display","none")}; +module$exports$Blockly$Scrollbar.prototype.onMouseDownBar_=function(a){this.workspace_.markFocused();(0,module$exports$Blockly$Touch.clearTouchIdentifier)();this.cleanUp_();if((0,module$exports$Blockly$browserEvents.isRightButton)(a))a.stopPropagation();else{var b=(0,module$exports$Blockly$browserEvents.mouseToSvg)(a,this.workspace_.getParentSvg(),this.workspace_.getInverseScreenCTM());b=this.horizontal_?b.x:b.y;var c=(0,module$exports$Blockly$utils.getInjectionDivXY_)(this.svgHandle_);c=this.horizontal_? +c.x:c.y;var d=this.handlePosition_,e=.95*this.handleLength_;b<=c?d-=e:b>=c+this.handleLength_&&(d+=e);this.setHandlePosition(this.constrainHandlePosition_(d));this.updateMetrics_();a.stopPropagation();a.preventDefault()}}; +module$exports$Blockly$Scrollbar.prototype.onMouseDownHandle_=function(a){this.workspace_.markFocused();this.cleanUp_();(0,module$exports$Blockly$browserEvents.isRightButton)(a)?a.stopPropagation():(this.startDragHandle=this.handlePosition_,this.workspace_.setupDragSurface(),this.startDragMouse_=this.horizontal_?a.clientX:a.clientY,module$exports$Blockly$Scrollbar.onMouseUpWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(document,"mouseup",this,this.onMouseUpHandle_),module$exports$Blockly$Scrollbar.onMouseMoveWrapper_= +(0,module$exports$Blockly$browserEvents.conditionalBind)(document,"mousemove",this,this.onMouseMoveHandle_),a.stopPropagation(),a.preventDefault())};module$exports$Blockly$Scrollbar.prototype.onMouseMoveHandle_=function(a){this.setHandlePosition(this.constrainHandlePosition_(this.startDragHandle+((this.horizontal_?a.clientX:a.clientY)-this.startDragMouse_)));this.updateMetrics_()}; +module$exports$Blockly$Scrollbar.prototype.onMouseUpHandle_=function(){this.workspace_.resetDragSurface();(0,module$exports$Blockly$Touch.clearTouchIdentifier)();this.cleanUp_()}; +module$exports$Blockly$Scrollbar.prototype.cleanUp_=function(){this.workspace_.hideChaff(!0);module$exports$Blockly$Scrollbar.onMouseUpWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(module$exports$Blockly$Scrollbar.onMouseUpWrapper_),module$exports$Blockly$Scrollbar.onMouseUpWrapper_=null);module$exports$Blockly$Scrollbar.onMouseMoveWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(module$exports$Blockly$Scrollbar.onMouseMoveWrapper_),module$exports$Blockly$Scrollbar.onMouseMoveWrapper_= +null)};module$exports$Blockly$Scrollbar.prototype.getRatio_=function(){var a=this.handlePosition_/(this.scrollbarLength_-this.handleLength_);isNaN(a)&&(a=0);return a};module$exports$Blockly$Scrollbar.prototype.updateMetrics_=function(){var a=this.getRatio_(),b={};this.horizontal_?b.x=a:b.y=a;this.workspace_.setMetrics(b)};module$exports$Blockly$Scrollbar.prototype.set=function(a,b){this.setHandlePosition(this.constrainHandlePosition_(a*this.ratio));(b||void 0===b)&&this.updateMetrics_()}; +module$exports$Blockly$Scrollbar.prototype.setOrigin=function(a,b){this.origin_=new module$exports$Blockly$utils$Coordinate(a,b)};var module$exports$Blockly$IASTNodeLocation=function(){};var module$exports$Blockly$Theme=function(a,b,c,d){this.name=a;this.blockStyles=b||Object.create(null);this.categoryStyles=c||Object.create(null);this.componentStyles=d||Object.create(null);this.fontStyle=Object.create(null);this.startHats=null;(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.THEME,a,this)};module$exports$Blockly$Theme.prototype.getClassName=function(){return this.name+"-theme"}; +module$exports$Blockly$Theme.prototype.setBlockStyle=function(a,b){this.blockStyles[a]=b};module$exports$Blockly$Theme.prototype.setCategoryStyle=function(a,b){this.categoryStyles[a]=b};module$exports$Blockly$Theme.prototype.getComponentStyle=function(a){return(a=this.componentStyles[a])&&"string"==typeof a&&this.getComponentStyle(a)?this.getComponentStyle(a):a?String(a):null};module$exports$Blockly$Theme.prototype.setComponentStyle=function(a,b){this.componentStyles[a]=b}; +module$exports$Blockly$Theme.prototype.setFontStyle=function(a){this.fontStyle=a};module$exports$Blockly$Theme.prototype.setStartHats=function(a){this.startHats=a}; +module$exports$Blockly$Theme.defineTheme=function(a,b){var c=new module$exports$Blockly$Theme(a),d=b.base;d&&("string"==typeof d&&(d=(0,module$exports$Blockly$registry.getObject)(module$exports$Blockly$registry.Type.THEME,d)),d instanceof module$exports$Blockly$Theme&&((0,module$exports$Blockly$utils$object.deepMerge)(c,d),c.name=a));(0,module$exports$Blockly$utils$object.deepMerge)(c.blockStyles,b.blockStyles);(0,module$exports$Blockly$utils$object.deepMerge)(c.categoryStyles,b.categoryStyles);(0,module$exports$Blockly$utils$object.deepMerge)(c.componentStyles, +b.componentStyles);(0,module$exports$Blockly$utils$object.deepMerge)(c.fontStyle,b.fontStyle);null!=b.startHats&&(c.startHats=b.startHats);return c};var module$contents$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"}},module$contents$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"}},module$exports$Blockly$Themes$Classic=new module$exports$Blockly$Theme("classic",module$contents$Blockly$Themes$Classic_defaultBlockStyles,module$contents$Blockly$Themes$Classic_categoryStyles);var module$exports$Blockly$Options=function(a){var b=null,c=!1,d=!1,e=!1,f=!1,g=!1,h=!1,k=!!a.readOnly;k||(b=(0,module$exports$Blockly$utils$toolbox.convertToolboxDefToJson)(a.toolbox),c=(0,module$exports$Blockly$utils$toolbox.hasCategories)(b),d=a.trashcan,void 0===d&&(d=c),e=a.collapse,void 0===e&&(e=c),f=a.comments,void 0===f&&(f=c),g=a.disable,void 0===g&&(g=c),h=a.sounds,void 0===h&&(h=!0));var l=a.maxTrashcanContents;d?void 0===l&&(l=32):l=0;var m=!!a.rtl,n=a.horizontalLayout;void 0===n&&(n= +!1);var p=a.toolboxPosition;p="end"!==p;p=n?p?module$exports$Blockly$utils$toolbox.Position.TOP:module$exports$Blockly$utils$toolbox.Position.BOTTOM:p==m?module$exports$Blockly$utils$toolbox.Position.RIGHT:module$exports$Blockly$utils$toolbox.Position.LEFT;var q=a.css;void 0===q&&(q=!0);var r="https://blockly-demo.appspot.com/static/media/";a.media?r=a.media:a.path&&(r=a.path+"media/");var t=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex;var u=a.renderer||"geras",v=a.plugins||{};this.RTL=m;this.oneBasedIndex= +t;this.collapse=e;this.comments=f;this.disable=g;this.readOnly=k;this.maxBlocks=a.maxBlocks||Infinity;this.maxInstances=a.maxInstances;this.pathToMedia=r;this.hasCategories=c;this.moveOptions=module$exports$Blockly$Options.parseMoveOptions_(a,c);this.hasScrollbars=!!this.moveOptions.scrollbars;this.hasTrashcan=d;this.maxTrashcanContents=l;this.hasSounds=h;this.hasCss=q;this.horizontalLayout=n;this.languageTree=b;this.gridOptions=module$exports$Blockly$Options.parseGridOptions_(a);this.zoomOptions= +module$exports$Blockly$Options.parseZoomOptions_(a);this.toolboxPosition=p;this.theme=module$exports$Blockly$Options.parseThemeOptions_(a);this.renderer=u;this.rendererOverrides=a.rendererOverrides;this.gridPattern=null;this.parentWorkspace=a.parentWorkspace;this.plugins=v}; +module$exports$Blockly$Options.parseMoveOptions_=function(a,b){var c=a.move||{},d={};void 0===c.scrollbars&&void 0===a.scrollbars?d.scrollbars=b:"object"==typeof c.scrollbars?(d.scrollbars={},d.scrollbars.horizontal=!!c.scrollbars.horizontal,d.scrollbars.vertical=!!c.scrollbars.vertical,d.scrollbars.horizontal&&d.scrollbars.vertical?d.scrollbars=!0:d.scrollbars.horizontal||d.scrollbars.vertical||(d.scrollbars=!1)):d.scrollbars=!!c.scrollbars||!!a.scrollbars;d.wheel=d.scrollbars&&void 0!==c.wheel? +!!c.wheel:"object"==typeof d.scrollbars;d.drag=d.scrollbars?void 0===c.drag?!0:!!c.drag:!1;return d}; +module$exports$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}; +module$exports$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=01'),d.appendChild(c),b.push(d));if(module$exports$Blockly$blocks.Blocks.variables_get)for(a.sort(module$exports$Blockly$VariableModel.compareByName), +c=0;d=a[c];c++){var e=(0,module$exports$Blockly$utils$xml.createElement)("block");e.setAttribute("type","variables_get");e.setAttribute("gap",8);e.appendChild((0,module$exports$Blockly$Variables.generateVariableFieldDom)(d));b.push(e)}}return b};module$exports$Blockly$Variables.VAR_LETTER_OPTIONS="ijkmnopqrstuvwxyzabcdefgh"; +module$exports$Blockly$Variables.generateUniqueName=function(a){return(0,module$exports$Blockly$Variables.generateUniqueNameFromOptions)(module$exports$Blockly$Variables.VAR_LETTER_OPTIONS.charAt(0),a.getAllVariableNames())}; +module$exports$Blockly$Variables.generateUniqueNameFromOptions=function(a,b){if(!b.length)return a;for(var c=module$exports$Blockly$Variables.VAR_LETTER_OPTIONS,d="",e=c.indexOf(a);;){for(var f=!1,g=0;gc||b.getSourceBlock().isInsertionMarker())return!1;switch(b.type){case module$exports$Blockly$ConnectionType.ConnectionType.PREVIOUS_STATEMENT:return this.canConnectToPrevious_(a,b);case module$exports$Blockly$ConnectionType.ConnectionType.OUTPUT_VALUE:if(b.isConnected()&&!b.targetBlock().isInsertionMarker()||a.isConnected())return!1;break;case module$exports$Blockly$ConnectionType.ConnectionType.INPUT_VALUE:if(b.isConnected()&& +!b.targetBlock().isMovable()&&!b.targetBlock().isShadow())return!1;break;case module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT:if(b.isConnected()&&!a.getSourceBlock().nextConnection&&!b.targetBlock().isShadow()&&b.targetBlock().nextConnection)return!1;break;default:return!1}return-1!=module$exports$Blockly$common.draggingConnections.indexOf(b)?!1:!0}; +module$exports$Blockly$ConnectionChecker.prototype.canConnectToPrevious_=function(a,b){if(a.targetConnection||-1!=module$exports$Blockly$common.draggingConnections.indexOf(b))return!1;if(!b.targetConnection)return!0;a=b.targetBlock();return a.isInsertionMarker()?!a.getPreviousBlock():!1};(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.CONNECTION_CHECKER,module$exports$Blockly$registry.DEFAULT,module$exports$Blockly$ConnectionChecker);var module$contents$Blockly$Workspace_WorkspaceDB_=Object.create(null),module$exports$Blockly$Workspace=function(a){this.id=(0,module$exports$Blockly$utils$idGenerator.genUid)();module$contents$Blockly$Workspace_WorkspaceDB_[this.id]=this;this.options=a||new module$exports$Blockly$Options({});this.RTL=!!this.options.RTL;this.horizontalLayout=!!this.options.horizontalLayout;this.toolboxPosition=this.options.toolboxPosition;this.connectionChecker=new ((0,module$exports$Blockly$registry.getClassFromOptions)(module$exports$Blockly$registry.Type.CONNECTION_CHECKER, +this.options,!0))(this);this.topBlocks_=[];this.topComments_=[];this.commentDB_=Object.create(null);this.listeners_=[];this.undoStack_=[];this.redoStack_=[];this.blockDB_=Object.create(null);this.typedBlocksDB_=Object.create(null);this.variableMap_=new module$exports$Blockly$VariableMap(this);this.potentialVariableMap_=null};module$exports$Blockly$Workspace.prototype.rendered=!1;module$exports$Blockly$Workspace.prototype.isClearing=!1;module$exports$Blockly$Workspace.prototype.MAX_UNDO=1024; +module$exports$Blockly$Workspace.prototype.connectionDBList=null;module$exports$Blockly$Workspace.prototype.dispose=function(){this.listeners_.length=0;this.clear();delete module$contents$Blockly$Workspace_WorkspaceDB_[this.id]};module$exports$Blockly$Workspace.SCAN_ANGLE=3; +module$exports$Blockly$Workspace.prototype.sortObjects_=function(a,b){a=a.getRelativeToSurfaceXY();b=b.getRelativeToSurfaceXY();return a.y+module$exports$Blockly$Workspace.prototype.sortObjects_.offset*a.x-(b.y+module$exports$Blockly$Workspace.prototype.sortObjects_.offset*b.x)};module$exports$Blockly$Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a)}; +module$exports$Blockly$Workspace.prototype.removeTopBlock=function(a){if(!(0,module$exports$Blockly$utils.arrayRemove)(this.topBlocks_,a))throw Error("Block not present in workspace's list of top-most blocks.");}; +module$exports$Blockly$Workspace.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);a&&1this.remainingCapacityOfType(c))return!1;b+=a[c]}return b>this.remainingCapacity()?!1:!0};module$exports$Blockly$Workspace.prototype.hasBlockLimits=function(){return Infinity!=this.options.maxBlocks||!!this.options.maxInstances};module$exports$Blockly$Workspace.prototype.getUndoStack=function(){return this.undoStack_}; +module$exports$Blockly$Workspace.prototype.getRedoStack=function(){return this.redoStack_};module$exports$Blockly$Workspace.prototype.undo=function(a){var b=a?this.redoStack_:this.undoStack_,c=a?this.undoStack_:this.redoStack_,d=b.pop();if(d){for(var e=[d];b.length&&d.group&&d.group==b[b.length-1].group;)e.push(b.pop());for(b=0;bthis.MAX_UNDO&&0<=this.MAX_UNDO;)this.undoStack_.shift();for(var b=0;ba.width)return b;if(this.workspace_.RTL){var c=this.anchorXY_.x-b,d=a.left+a.width;a=a.left+module$exports$Blockly$Scrollbar.scrollbarThickness/this.workspace_.scale;c-this.width_d&&(b=-(d-this.anchorXY_.x))}else{c=b+this.anchorXY_.x;d=c+this.width_;var e=a.left;a=a.left+a.width-module$exports$Blockly$Scrollbar.scrollbarThickness/this.workspace_.scale; +ca&&(b=a-this.anchorXY_.x-this.width_)}return b};module$exports$Blockly$Bubble.prototype.getOptimalRelativeTop_=function(a){var b=-this.height_/4;if(this.height_>a.height)return b;var c=this.anchorXY_.y+b,d=c+this.height_,e=a.top;a=a.top+a.height-module$exports$Blockly$Scrollbar.scrollbarThickness/this.workspace_.scale;var f=this.anchorXY_.y;ca&&(b=a-f-this.height_);return b}; +module$exports$Blockly$Bubble.prototype.positionBubble_=function(){var a=this.anchorXY_.x;a=this.workspace_.RTL?a-(this.relativeLeft_+this.width_):a+this.relativeLeft_;this.moveTo(a,this.relativeTop_+this.anchorXY_.y)};module$exports$Blockly$Bubble.prototype.moveTo=function(a,b){this.bubbleGroup_.setAttribute("transform","translate("+a+","+b+")")};module$exports$Blockly$Bubble.prototype.setDragging=function(a){!a&&this.moveCallback_&&this.moveCallback_()}; +module$exports$Blockly$Bubble.prototype.getBubbleSize=function(){return new module$exports$Blockly$utils$Size(this.width_,this.height_)}; +module$exports$Blockly$Bubble.prototype.setBubbleSize=function(a,b){var c=2*module$exports$Blockly$Bubble.BORDER_WIDTH;a=Math.max(a,c+45);b=Math.max(b,c+20);this.width_=a;this.height_=b;this.bubbleBack_.setAttribute("width",a);this.bubbleBack_.setAttribute("height",b);this.resizeGroup_&&(this.workspace_.RTL?this.resizeGroup_.setAttribute("transform","translate("+2*module$exports$Blockly$Bubble.BORDER_WIDTH+","+(b-c)+") scale(-1 1)"):this.resizeGroup_.setAttribute("transform","translate("+(a-c)+","+ +(b-c)+")"));this.autoLayout_&&this.layoutBubble_();this.positionBubble_();this.renderArrow_();this.resizeCallback_&&this.resizeCallback_()}; +module$exports$Blockly$Bubble.prototype.renderArrow_=function(){var a=[],b=this.width_/2,c=this.height_/2,d=-this.relativeLeft_,e=-this.relativeTop_;if(b==d&&c==e)a.push("M "+b+","+c);else{e-=c;d-=b;this.workspace_.RTL&&(d*=-1);var f=Math.sqrt(e*e+d*d),g=Math.acos(d/f);0>e&&(g=2*Math.PI-g);var h=g+Math.PI/2;h>2*Math.PI&&(h-=2*Math.PI);var k=Math.sin(h),l=Math.cos(h),m=this.getBubbleSize();h=(m.width+m.height)/module$exports$Blockly$Bubble.ARROW_THICKNESS;h=Math.min(h,m.width,m.height)/4;m=1-module$exports$Blockly$Bubble.ANCHOR_RADIUS/ +f;d=b+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/module$exports$Blockly$Bubble.ARROW_BEND;f=Math.cos(k)*f/module$exports$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(" "))}; +module$exports$Blockly$Bubble.prototype.setColour=function(a){this.bubbleBack_.setAttribute("fill",a);this.bubbleArrow_.setAttribute("fill",a)}; +module$exports$Blockly$Bubble.prototype.dispose=function(){this.onMouseDownBubbleWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.onMouseDownBubbleWrapper_);this.onMouseDownResizeWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.onMouseDownResizeWrapper_);module$exports$Blockly$Bubble.unbindDragEvents_();(0,module$exports$Blockly$utils$dom.removeNode)(this.bubbleGroup_);this.disposed=!0}; +module$exports$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_()}; +module$exports$Blockly$Bubble.prototype.getRelativeToSurfaceXY=function(){return new module$exports$Blockly$utils$Coordinate(this.workspace_.RTL?-this.relativeLeft_+this.anchorXY_.x-this.width_:this.anchorXY_.x+this.relativeLeft_,this.anchorXY_.y+this.relativeTop_)};module$exports$Blockly$Bubble.prototype.setAutoLayout=function(a){this.autoLayout_=a}; +module$exports$Blockly$Bubble.textToDom=function(a){var b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.TEXT,{"class":"blocklyText blocklyBubbleText blocklyNoPointerEvents",y:module$exports$Blockly$Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c>>/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))}}; +module$exports$Blockly$Css.CONTENT=[".blocklySvg {\n background-color: #fff;\n outline: none;\n overflow: hidden; /* IE overflows by default. */\n position: absolute;\n display: block;\n}",".blocklyWidgetDiv {\n display: none;\n position: absolute;\n z-index: 99999; /* big value for bootstrap3 compatibility */\n}",".injectionDiv {\n height: 100%;\n position: relative;\n overflow: hidden; /* So blocks in drag surface disappear at edges */\n touch-action: none;\n}",".blocklyNonSelectable {\n user-select: none;\n -ms-user-select: none;\n -webkit-user-select: none;\n}", +".blocklyWsDragSurface {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n}",".blocklyWsDragSurface.blocklyOverflowVisible {\n overflow: visible;\n}",".blocklyBlockDragSurface {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: visible !important;\n z-index: 50;', /* Display below toolbox, but above everything else. */\n}",".blocklyBlockCanvas.blocklyCanvasTransitioning,\n.blocklyBubbleCanvas.blocklyCanvasTransitioning {\n transition: transform .5s;\n}", +".blocklyTooltipDiv {\n background-color: #ffffc7;\n border: 1px solid #ddc;\n box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);\n color: #000;\n display: none;\n font: 9pt sans-serif;\n opacity: .9;\n padding: 2px;\n position: absolute;\n z-index: 100000;', /* big value for bootstrap3 compatibility */\n}",".blocklyDropDownDiv {\n position: absolute;\n left: 0;\n top: 0;\n z-index: 1000;\n display: none;\n border: 1px solid;\n border-color: #dadce0;\n background-color: #fff;\n border-radius: 2px;\n padding: 4px;\n box-shadow: 0 0 3px 1px rgba(0,0,0,.3);\n}", +".blocklyDropDownDiv.blocklyFocused {\n box-shadow: 0 0 6px 1px rgba(0,0,0,.3);\n}",".blocklyDropDownContent {\n max-height: 300px;', // @todo: spec for maximum height.\n overflow: auto;\n overflow-x: hidden;\n position: relative;\n}",".blocklyDropDownArrow {\n position: absolute;\n left: 0;\n top: 0;\n width: 16px;\n height: 16px;\n z-index: -1;\n background-color: inherit;\n border-color: inherit;\n}",".blocklyDropDownButton {\n display: inline-block;\n float: left;\n padding: 0;\n margin: 4px;\n border-radius: 4px;\n outline: none;\n border: 1px solid;\n transition: box-shadow .1s;\n cursor: pointer;\n}", +".blocklyArrowTop {\n border-top: 1px solid;\n border-left: 1px solid;\n border-top-left-radius: 4px;\n border-color: inherit;\n}",".blocklyArrowBottom {\n border-bottom: 1px solid;\n border-right: 1px solid;\n border-bottom-right-radius: 4px;\n border-color: inherit;\n}",".blocklyResizeSE {\n cursor: se-resize;\n fill: #aaa;\n}",".blocklyResizeSW {\n cursor: sw-resize;\n fill: #aaa;\n}",".blocklyResizeLine {\n stroke: #515A5A;\n stroke-width: 1;\n}",".blocklyHighlightedConnectionPath {\n fill: none;\n stroke: #fc3;\n stroke-width: 4px;\n}", +".blocklyPathLight {\n fill: none;\n stroke-linecap: round;\n stroke-width: 1;\n}",".blocklySelected>.blocklyPathLight {\n display: none;\n}",'.blocklyDraggable {\n /* backup for browsers (e.g. IE11) that don\'t support grab */\n cursor: url("<<>>/handopen.cur"), auto;\n cursor: grab;\n cursor: -webkit-grab;\n}','.blocklyDragging {\n /* backup for browsers (e.g. IE11) that don\'t support grabbing */\n cursor: url("<<>>/handclosed.cur"), auto;\n cursor: grabbing;\n cursor: -webkit-grabbing;\n}', +'.blocklyDraggable:active {\n /* backup for browsers (e.g. IE11) that don\'t support grabbing */\n cursor: url("<<>>/handclosed.cur"), auto;\n cursor: grabbing;\n cursor: -webkit-grabbing;\n}','.blocklyBlockDragSurface .blocklyDraggable {\n /* backup for browsers (e.g. IE11) that don\'t support grabbing */\n cursor: url("<<>>/handclosed.cur"), auto;\n cursor: grabbing;\n cursor: -webkit-grabbing;\n}','.blocklyDragging.blocklyDraggingDelete {\n cursor: url("<<>>/handdelete.cur"), auto;\n}', +".blocklyDragging>.blocklyPath,\n.blocklyDragging>.blocklyPathLight {\n fill-opacity: .8;\n stroke-opacity: .8;\n}",".blocklyDragging>.blocklyPathDark {\n display: none;\n}",".blocklyDisabled>.blocklyPath {\n fill-opacity: .5;\n stroke-opacity: .5;\n}",".blocklyDisabled>.blocklyPathLight,\n.blocklyDisabled>.blocklyPathDark {\n display: none;\n}",".blocklyInsertionMarker>.blocklyPath,\n.blocklyInsertionMarker>.blocklyPathLight,\n.blocklyInsertionMarker>.blocklyPathDark {\n fill-opacity: .2;\n stroke: none;\n}", +".blocklyMultilineText {\n font-family: monospace;\n}",".blocklyNonEditableText>text {\n pointer-events: none;\n}",".blocklyFlyout {\n position: absolute;\n z-index: 20;\n}",".blocklyText text {\n cursor: default;\n}",".blocklySvg text,\n.blocklyBlockDragSurface text {\n user-select: none;\n -ms-user-select: none;\n -webkit-user-select: none;\n cursor: inherit;\n}",".blocklyHidden {\n display: none;\n}",".blocklyFieldDropdown:not(.blocklyHidden) {\n display: block;\n}",".blocklyIconGroup {\n cursor: default;\n}", +".blocklyIconGroup:not(:hover),\n.blocklyIconGroupReadonly {\n opacity: .6;\n}",".blocklyIconShape {\n fill: #00f;\n stroke: #fff;\n stroke-width: 1px;\n}",".blocklyIconSymbol {\n fill: #fff;\n}",".blocklyMinimalBody {\n margin: 0;\n padding: 0;\n}",".blocklyHtmlInput {\n border: none;\n border-radius: 4px;\n height: 100%;\n margin: 0;\n outline: none;\n padding: 0;\n width: 100%;\n text-align: center;\n display: block;\n box-sizing: border-box;\n}",".blocklyHtmlInput::-ms-clear {\n display: none;\n}", +".blocklyMainBackground {\n stroke-width: 1;\n stroke: #c6c6c6;', /* Equates to #ddd due to border being off-pixel. */\n}",".blocklyMutatorBackground {\n fill: #fff;\n stroke: #ddd;\n stroke-width: 1;\n}",".blocklyFlyoutBackground {\n fill: #ddd;\n fill-opacity: .8;\n}",".blocklyMainWorkspaceScrollbar {\n z-index: 20;\n}",".blocklyFlyoutScrollbar {\n z-index: 30;\n}",".blocklyScrollbarHorizontal,\n.blocklyScrollbarVertical {\n position: absolute;\n outline: none;\n}",".blocklyScrollbarBackground {\n opacity: 0;\n}", +".blocklyScrollbarHandle {\n fill: #ccc;\n}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,\n.blocklyScrollbarHandle:hover {\n fill: #bbb;\n}",".blocklyFlyout .blocklyScrollbarHandle {\n fill: #bbb;\n}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,\n.blocklyFlyout .blocklyScrollbarHandle:hover {\n fill: #aaa;\n}",".blocklyInvalidInput {\n background: #faa;\n}",".blocklyVerticalMarker {\n stroke-width: 3px;\n fill: rgba(255,255,255,.5);\n pointer-events: none;\n}", +".blocklyComputeCanvas {\n position: absolute;\n width: 0;\n height: 0;\n}",".blocklyNoPointerEvents {\n pointer-events: none;\n}",".blocklyContextMenu {\n border-radius: 4px;\n max-height: 100%;\n}",".blocklyDropdownMenu {\n border-radius: 2px;\n padding: 0 !important;\n}",".blocklyDropdownMenu .blocklyMenuItem {\n /* 28px on the left for icon or checkbox. */\n padding-left: 28px;\n}",".blocklyDropdownMenu .blocklyMenuItemRtl {\n /* Flip left/right padding for BiDi. */\n padding-left: 5px;\n padding-right: 28px;\n}", +".blocklyWidgetDiv .blocklyMenu {\n background: #fff;\n border: 1px solid transparent;\n box-shadow: 0 0 3px 1px rgba(0,0,0,.3);\n font: normal 13px Arial, sans-serif;\n margin: 0;\n outline: none;\n padding: 4px 0;\n position: absolute;\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 100%;\n z-index: 20000;', /* Arbitrary, but some apps depend on it... */\n}",".blocklyWidgetDiv .blocklyMenu.blocklyFocused {\n box-shadow: 0 0 6px 1px rgba(0,0,0,.3);\n}",".blocklyDropDownDiv .blocklyMenu {\n background: inherit;', /* Compatibility with gapi, reset from goog-menu */\n border: inherit;', /* Compatibility with gapi, reset from goog-menu */\n font: normal 13px \"Helvetica Neue\", Helvetica, sans-serif;\n outline: none;\n position: relative;', /* Compatibility with gapi, reset from goog-menu */\n z-index: 20000;', /* Arbitrary, but some apps depend on it... */\n}", +".blocklyMenuItem {\n border: none;\n color: #000;\n cursor: pointer;\n list-style: none;\n margin: 0;\n /* 7em on the right for shortcut. */\n min-width: 7em;\n padding: 6px 15px;\n white-space: nowrap;\n}",".blocklyMenuItemDisabled {\n color: #ccc;\n cursor: inherit;\n}",".blocklyMenuItemHighlight {\n background-color: rgba(0,0,0,.1);\n}",".blocklyMenuItemCheckbox {\n height: 16px;\n position: absolute;\n width: 16px;\n}",".blocklyMenuItemSelected .blocklyMenuItemCheckbox {\n background: url(<<>>/sprites.png) no-repeat -48px -16px;\n float: left;\n margin-left: -24px;\n position: static;', /* Scroll with the menu. */\n}", +".blocklyMenuItemRtl .blocklyMenuItemCheckbox {\n float: right;\n margin-right: -24px;\n}"];var module$exports$Blockly$ToolboxItem=function(a,b,c){this.id_=a.toolboxitemid||(0,module$exports$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()};module$exports$Blockly$ToolboxItem.prototype.init=function(){};module$exports$Blockly$ToolboxItem.prototype.getDiv=function(){return null};module$exports$Blockly$ToolboxItem.prototype.getId=function(){return this.id_}; +module$exports$Blockly$ToolboxItem.prototype.getParent=function(){return null};module$exports$Blockly$ToolboxItem.prototype.getLevel=function(){return this.level_};module$exports$Blockly$ToolboxItem.prototype.isSelectable=function(){return!1};module$exports$Blockly$ToolboxItem.prototype.isCollapsible=function(){return!1};module$exports$Blockly$ToolboxItem.prototype.dispose=function(){};var module$exports$Blockly$ToolboxCategory=function(a,b,c){module$exports$Blockly$ToolboxCategory.superClass_.constructor.call(this,a,b,c);this.name_=(0,module$exports$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_();(0,module$exports$Blockly$utils$object.mixin)(this.cssConfig_,a.cssconfig||a.cssConfig);this.isDisabled_=this.isHidden_=!1;this.flyoutItems_= +[];this.parseContents_(a)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$ToolboxCategory,module$exports$Blockly$ToolboxItem);module$exports$Blockly$ToolboxCategory.registrationName="category";module$exports$Blockly$ToolboxCategory.nestedPadding=19;module$exports$Blockly$ToolboxCategory.borderWidth=8;module$exports$Blockly$ToolboxCategory.defaultBackgroundColour="#57e"; +module$exports$Blockly$ToolboxCategory.prototype.makeDefaultCssConfig_=function(){return{container:"blocklyToolboxCategory",row:"blocklyTreeRow",rowcontentcontainer:"blocklyTreeRowContentContainer",icon:"blocklyTreeIcon",label:"blocklyTreeLabel",contents:"blocklyToolboxContents",selected:"blocklyTreeSelected",openicon:"blocklyTreeIconOpen",closedicon:"blocklyTreeIconClosed"}}; +module$exports$Blockly$ToolboxCategory.prototype.parseContents_=function(a){var b=a.contents;if(a.custom)this.flyoutItems_=a.custom;else if(b)for(a=0;a>>/sprites.png);\n height: 16px;\n vertical-align: middle;\n visibility: hidden;\n width: 16px;\n}",".blocklyTreeIconClosed {\n background-position: -32px -1px;\n}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeIconClosed {\n background-position: 0 -1px;\n}',".blocklyTreeSelected>.blocklyTreeIconClosed {\n background-position: -32px -17px;\n}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeSelected>.blocklyTreeIconClosed {\n background-position: 0 -17px;\n}', +".blocklyTreeIconOpen {\n background-position: -16px -1px;\n}",".blocklyTreeSelected>.blocklyTreeIconOpen {\n background-position: -16px -17px;\n}",".blocklyTreeLabel {\n cursor: default;\n font: 16px sans-serif;\n padding: 0 3px;\n vertical-align: middle;\n}",'.blocklyToolboxDelete .blocklyTreeLabel {\n cursor: url("<<>>/handdelete.cur"), auto;\n}',".blocklyTreeSelected .blocklyTreeLabel {\n color: #fff;\n}"]); +(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.TOOLBOX_ITEM,module$exports$Blockly$ToolboxCategory.registrationName,module$exports$Blockly$ToolboxCategory);var module$exports$Blockly$ToolboxSeparator=function(a,b){module$exports$Blockly$ToolboxSeparator.superClass_.constructor.call(this,a,b);this.cssConfig_={container:"blocklyTreeSeparator"};(0,module$exports$Blockly$utils$object.mixin)(this.cssConfig_,a.cssconfig||a.cssConfig)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$ToolboxSeparator,module$exports$Blockly$ToolboxItem);module$exports$Blockly$ToolboxSeparator.registrationName="sep"; +module$exports$Blockly$ToolboxSeparator.prototype.init=function(){this.createDom_()};module$exports$Blockly$ToolboxSeparator.prototype.createDom_=function(){var a=document.createElement("div");(0,module$exports$Blockly$utils$dom.addClass)(a,this.cssConfig_.container);return this.htmlDiv_=a};module$exports$Blockly$ToolboxSeparator.prototype.getDiv=function(){return this.htmlDiv_};module$exports$Blockly$ToolboxSeparator.prototype.dispose=function(){(0,module$exports$Blockly$utils$dom.removeNode)(this.htmlDiv_)}; +(0,module$exports$Blockly$Css.register)([".blocklyTreeSeparator {\n border-bottom: solid #e5e5e5 1px;\n height: 0;\n margin: 5px 0;\n}",'.blocklyToolboxDiv[layout="h"] .blocklyTreeSeparator {\n border-right: solid #e5e5e5 1px;\n border-bottom: none;\n height: auto;\n margin: 0 5px 0 5px;\n padding: 5px 0;\n width: 0;\n}']);(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.TOOLBOX_ITEM,module$exports$Blockly$ToolboxSeparator.registrationName,module$exports$Blockly$ToolboxSeparator);var module$exports$Blockly$CollapsibleToolboxCategory=function(a,b,c){this.subcategoriesDiv_=null;this.expanded_=!1;this.toolboxItems_=[];module$exports$Blockly$CollapsibleToolboxCategory.superClass_.constructor.call(this,a,b,c)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$CollapsibleToolboxCategory,module$exports$Blockly$ToolboxCategory);module$exports$Blockly$CollapsibleToolboxCategory.registrationName="collapsibleCategory"; +module$exports$Blockly$CollapsibleToolboxCategory.prototype.makeDefaultCssConfig_=function(){var a=module$exports$Blockly$CollapsibleToolboxCategory.superClass_.makeDefaultCssConfig_.call(this);a.contents="blocklyToolboxContents";return a}; +module$exports$Blockly$CollapsibleToolboxCategory.prototype.parseContents_=function(a){var b=a.contents,c=!0;if(a.custom)this.flyoutItems_=a.custom;else if(b)for(a=0;a"));(0,module$exports$Blockly$Events$utils.fire)(new module$exports$Blockly$Events$BlockChange(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)}; +module$exports$Blockly$Events$BlockChange.getExtraBlockState_=function(a){return a.saveExtraState?(a=a.saveExtraState())?JSON.stringify(a):"":a.mutationToDom?(a=a.mutationToDom())?(0,module$exports$Blockly$Xml.domToText)(a):"":""};(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.EVENT,module$exports$Blockly$Events$utils.CHANGE,module$exports$Blockly$Events$BlockChange);var module$exports$Blockly$Events$UiBase=function(a){module$exports$Blockly$Events$UiBase.superClass_.constructor.call(this);this.isBlank="undefined"==typeof a;this.workspaceId=a?a:"";this.recordUndo=!1};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Events$UiBase,module$exports$Blockly$Events$Abstract);module$exports$Blockly$Events$UiBase.prototype.isUiEvent=!0;var module$exports$Blockly$Events$BubbleOpen=function(a,b,c){module$exports$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};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Events$BubbleOpen,module$exports$Blockly$Events$UiBase);module$exports$Blockly$Events$BubbleOpen.prototype.type=module$exports$Blockly$Events$utils.BUBBLE_OPEN; +module$exports$Blockly$Events$BubbleOpen.prototype.toJson=function(){var a=module$exports$Blockly$Events$BubbleOpen.superClass_.toJson.call(this);a.isOpen=this.isOpen;a.bubbleType=this.bubbleType;a.blockId=this.blockId;return a};module$exports$Blockly$Events$BubbleOpen.prototype.fromJson=function(a){module$exports$Blockly$Events$BubbleOpen.superClass_.fromJson.call(this,a);this.isOpen=a.isOpen;this.bubbleType=a.bubbleType;this.blockId=a.blockId}; +(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.EVENT,module$exports$Blockly$Events$utils.BUBBLE_OPEN,module$exports$Blockly$Events$BubbleOpen);var module$exports$Blockly$Warning=function(a){module$exports$Blockly$Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_=Object.create(null)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Warning,module$exports$Blockly$Icon);module$exports$Blockly$Warning.prototype.collapseHidden=!1; +module$exports$Blockly$Warning.prototype.drawIcon_=function(a){(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$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);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.PATH,{"class":"blocklyIconSymbol",d:"m7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT, +{"class":"blocklyIconSymbol",x:"7",y:"11",height:"2",width:"2"},a)};module$exports$Blockly$Warning.prototype.setVisible=function(a){a!=this.isVisible()&&((0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.BUBBLE_OPEN))(this.block_,a,"warning")),a?this.createBubble_():this.disposeBubble_())}; +module$exports$Blockly$Warning.prototype.createBubble_=function(){this.paragraphElement_=module$exports$Blockly$Bubble.textToDom(this.getText());this.bubble_=module$exports$Blockly$Bubble.createNonEditableBubble(this.paragraphElement_,this.block_,this.iconXY_);this.applyColour()};module$exports$Blockly$Warning.prototype.disposeBubble_=function(){this.bubble_.dispose();this.paragraphElement_=this.bubble_=null}; +module$exports$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)))};module$exports$Blockly$Warning.prototype.getText=function(){var a=[],b;for(b in this.text_)a.push(this.text_[b]);return a.join("\n")};module$exports$Blockly$Warning.prototype.dispose=function(){this.block_.warning=null;module$exports$Blockly$Icon.prototype.dispose.call(this)};var module$exports$Blockly$Comment=function(a){module$exports$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()};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Comment,module$exports$Blockly$Icon); +module$exports$Blockly$Comment.prototype.drawIcon_=function(a){(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE,{"class":"blocklyIconShape",r:"8",cx:"8",cy:"8"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$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); +(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"blocklyIconSymbol",x:"6.8",y:"10.78",height:"2",width:"2"},a)}; +module$exports$Blockly$Comment.prototype.createEditor_=function(){this.foreignObject_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FOREIGNOBJECT,{x:module$exports$Blockly$Bubble.BORDER_WIDTH,y:module$exports$Blockly$Bubble.BORDER_WIDTH},null);var a=document.createElementNS(module$exports$Blockly$utils$dom.HTML_NS,"body");a.setAttribute("xmlns",module$exports$Blockly$utils$dom.HTML_NS);a.className="blocklyMinimalBody";var b=this.textarea_=document.createElementNS(module$exports$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_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"mouseup",this,this.startEdit_,!0,!0);this.onWheelWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"wheel",this,function(c){c.stopPropagation()});this.onChangeWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b, +"change",this,function(c){this.cachedText_!=this.model_.text&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CHANGE))(this.block_,"comment",null,this.cachedText_,this.model_.text))});this.onInputWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"input",this,function(c){this.model_.text=b.value});setTimeout(b.focus.bind(b),0);return this.foreignObject_}; +module$exports$Blockly$Comment.prototype.updateEditable=function(){module$exports$Blockly$Comment.superClass_.updateEditable.call(this);this.isVisible()&&(this.disposeBubble_(),this.createBubble_())};module$exports$Blockly$Comment.prototype.onBubbleResize_=function(){this.isVisible()&&(this.model_.size=this.bubble_.getBubbleSize(),this.resizeTextarea_())}; +module$exports$Blockly$Comment.prototype.resizeTextarea_=function(){var a=this.model_.size,b=2*module$exports$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"}; +module$exports$Blockly$Comment.prototype.setVisible=function(a){a!=this.isVisible()&&((0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.BUBBLE_OPEN))(this.block_,a,"comment")),(this.model_.pinned=a)?this.createBubble_():this.disposeBubble_())};module$exports$Blockly$Comment.prototype.createBubble_=function(){!this.block_.isEditable()||module$exports$Blockly$utils$userAgent.IE?this.createNonEditableBubble_():this.createEditableBubble_()}; +module$exports$Blockly$Comment.prototype.createEditableBubble_=function(){this.bubble_=new module$exports$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()}; +module$exports$Blockly$Comment.prototype.createNonEditableBubble_=function(){this.paragraphElement_=module$exports$Blockly$Bubble.textToDom(this.block_.getCommentText());this.bubble_=module$exports$Blockly$Bubble.createNonEditableBubble(this.paragraphElement_,this.block_,this.iconXY_);this.applyColour()}; +module$exports$Blockly$Comment.prototype.disposeBubble_=function(){this.onMouseUpWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onMouseUpWrapper_),this.onMouseUpWrapper_=null);this.onWheelWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onWheelWrapper_),this.onWheelWrapper_=null);this.onChangeWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onChangeWrapper_),this.onChangeWrapper_=null);this.onInputWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onInputWrapper_), +this.onInputWrapper_=null);this.bubble_.dispose();this.paragraphElement_=this.foreignObject_=this.textarea_=this.bubble_=null};module$exports$Blockly$Comment.prototype.startEdit_=function(a){this.bubble_.promote()&&this.textarea_.focus();this.cachedText_=this.model_.text};module$exports$Blockly$Comment.prototype.getBubbleSize=function(){return this.model_.size}; +module$exports$Blockly$Comment.prototype.setBubbleSize=function(a,b){this.bubble_?this.bubble_.setBubbleSize(a,b):(this.model_.size.width=a,this.model_.size.height=b)};module$exports$Blockly$Comment.prototype.updateText=function(){this.textarea_?this.textarea_.value=this.model_.text:this.paragraphElement_&&(this.paragraphElement_.firstChild.textContent=this.model_.text)};module$exports$Blockly$Comment.prototype.dispose=function(){this.block_.comment=null;module$exports$Blockly$Icon.prototype.dispose.call(this)}; +(0,module$exports$Blockly$Css.register)(".blocklyCommentTextarea {,background-color: #fef49c;,border: 0;,outline: 0;,margin: 0;,padding: 3px;,resize: none;,display: block;,text-overflow: hidden;,}".split(","));var module$exports$Blockly$ConnectionDB=function(a){this.connections_=[];this.connectionChecker_=a};module$exports$Blockly$ConnectionDB.prototype.addConnection=function(a,b){b=this.calculateIndexForYPos_(b);this.connections_.splice(b,0,a)}; +module$exports$Blockly$ConnectionDB.prototype.findIndexOfConnection_=function(a,b){if(!this.connections_.length)return-1;var c=this.calculateIndexForYPos_(b);if(c>=this.connections_.length)return-1;b=a.y;for(var d=c;0<=d&&this.connections_[d].y==b;){if(this.connections_[d]==a)return d;d--}for(d=c;da)c=d;else{b=d;break}}return b};module$exports$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)}; +module$exports$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 na?this.menuItems_.length:a,-1)};module$exports$Blockly$Menu.prototype.highlightFirst_=function(){this.highlightHelper_(-1,1)}; +module$exports$Blockly$Menu.prototype.highlightLast_=function(){this.highlightHelper_(this.menuItems_.length,-1)};module$exports$Blockly$Menu.prototype.highlightHelper_=function(a,b){a+=b;for(var c;c=this.menuItems_[a];){if(c.isEnabled()){this.setHighlighted(c);break}a+=b}};module$exports$Blockly$Menu.prototype.handleMouseOver_=function(a){(a=this.getMenuItem_(a.target))&&(a.isEnabled()?this.highlightedItem_!=a&&this.setHighlighted(a):this.setHighlighted(null))}; +module$exports$Blockly$Menu.prototype.handleClick_=function(a){var b=this.openingCoords;this.openingCoords=null;if(b&&"number"==typeof a.clientX){var c=new module$exports$Blockly$utils$Coordinate(a.clientX,a.clientY);if(1>module$exports$Blockly$utils$Coordinate.distance(b,c))return}(a=this.getMenuItem_(a.target))&&a.performAction()};module$exports$Blockly$Menu.prototype.handleMouseEnter_=function(a){this.focus()}; +module$exports$Blockly$Menu.prototype.handleMouseLeave_=function(a){this.getElement()&&(this.blur_(),this.setHighlighted(null))}; +module$exports$Blockly$Menu.prototype.handleKeyEvent_=function(a){if(this.menuItems_.length&&!(a.shiftKey||a.ctrlKey||a.metaKey||a.altKey)){var b=this.highlightedItem_;switch(a.keyCode){case module$exports$Blockly$utils$KeyCodes.ENTER:case module$exports$Blockly$utils$KeyCodes.SPACE:b&&b.performAction();break;case module$exports$Blockly$utils$KeyCodes.UP:this.highlightPrevious();break;case module$exports$Blockly$utils$KeyCodes.DOWN:this.highlightNext();break;case module$exports$Blockly$utils$KeyCodes.PAGE_UP:case module$exports$Blockly$utils$KeyCodes.HOME:this.highlightFirst_(); +break;case module$exports$Blockly$utils$KeyCodes.PAGE_DOWN:case module$exports$Blockly$utils$KeyCodes.END:this.highlightLast_();break;default:return}a.preventDefault();a.stopPropagation()}};module$exports$Blockly$Menu.prototype.getSize=function(){var a=this.getElement(),b=(0,module$exports$Blockly$utils$style.getSize)(a);b.height=a.scrollHeight;return b};var module$exports$Blockly$MenuItem=function(a,b){this.content_=a;this.value_=b;this.enabled_=!0;this.element_=null;this.rightToLeft_=!1;this.roleName_=null;this.highlight_=this.checked_=this.checkable_=!1;this.actionHandler_=null}; +module$exports$Blockly$MenuItem.prototype.createDom=function(){var a=document.createElement("div");a.id=(0,module$exports$Blockly$utils$idGenerator.getNextUniqueId)();this.element_=a;a.className="blocklyMenuItem goog-menuitem "+(this.enabled_?"":"blocklyMenuItemDisabled goog-menuitem-disabled ")+(this.checked_?"blocklyMenuItemSelected goog-option-selected ":"")+(this.highlight_?"blocklyMenuItemHighlight goog-menuitem-highlight ":"")+(this.rightToLeft_?"blocklyMenuItemRtl goog-menuitem-rtl ":"");var b= +document.createElement("div");b.className="blocklyMenuItemContent goog-menuitem-content";if(this.checkable_){var c=document.createElement("div");c.className="blocklyMenuItemCheckbox goog-menuitem-checkbox";b.appendChild(c)}c=this.content_;"string"==typeof this.content_&&(c=document.createTextNode(this.content_));b.appendChild(c);a.appendChild(b);this.roleName_&&(0,module$exports$Blockly$utils$aria.setRole)(a,this.roleName_);(0,module$exports$Blockly$utils$aria.setState)(a,module$exports$Blockly$utils$aria.State.SELECTED, +this.checkable_&&this.checked_||!1);(0,module$exports$Blockly$utils$aria.setState)(a,module$exports$Blockly$utils$aria.State.DISABLED,!this.enabled_);return a};module$exports$Blockly$MenuItem.prototype.dispose=function(){this.element_=null};module$exports$Blockly$MenuItem.prototype.getElement=function(){return this.element_};module$exports$Blockly$MenuItem.prototype.getId=function(){return this.element_.id};module$exports$Blockly$MenuItem.prototype.getValue=function(){return this.value_}; +module$exports$Blockly$MenuItem.prototype.setRightToLeft=function(a){this.rightToLeft_=a};module$exports$Blockly$MenuItem.prototype.setRole=function(a){this.roleName_=a};module$exports$Blockly$MenuItem.prototype.setCheckable=function(a){this.checkable_=a};module$exports$Blockly$MenuItem.prototype.setChecked=function(a){this.checked_=a}; +module$exports$Blockly$MenuItem.prototype.setHighlighted=function(a){this.highlight_=a;var b=this.getElement();b&&this.isEnabled()&&(a?((0,module$exports$Blockly$utils$dom.addClass)(b,"blocklyMenuItemHighlight"),(0,module$exports$Blockly$utils$dom.addClass)(b,"goog-menuitem-highlight")):((0,module$exports$Blockly$utils$dom.removeClass)(b,"blocklyMenuItemHighlight"),(0,module$exports$Blockly$utils$dom.removeClass)(b,"goog-menuitem-highlight")))}; +module$exports$Blockly$MenuItem.prototype.isEnabled=function(){return this.enabled_};module$exports$Blockly$MenuItem.prototype.setEnabled=function(a){this.enabled_=a};module$exports$Blockly$MenuItem.prototype.performAction=function(){this.isEnabled()&&this.actionHandler_&&this.actionHandler_(this)};module$exports$Blockly$MenuItem.prototype.onAction=function(a,b){this.actionHandler_=a.bind(b)};var module$exports$Blockly$WidgetDiv={},module$contents$Blockly$WidgetDiv_owner=null,module$contents$Blockly$WidgetDiv_dispose=null,module$contents$Blockly$WidgetDiv_rendererClassName="",module$contents$Blockly$WidgetDiv_themeClassName="",module$contents$Blockly$WidgetDiv_DIV;module$exports$Blockly$WidgetDiv.getDiv=function(){return module$contents$Blockly$WidgetDiv_DIV};module$exports$Blockly$WidgetDiv.testOnly_setDiv=function(a){module$contents$Blockly$WidgetDiv_DIV=a}; +Object.defineProperties(module$exports$Blockly$WidgetDiv,{DIV:{get:function(){(0,module$exports$Blockly$utils$deprecation.warn)("Blockly.WidgetDiv.DIV","September 2021","September 2022","Blockly.WidgetDiv.getDiv()");return(0,module$exports$Blockly$WidgetDiv.getDiv)()}}}); +module$exports$Blockly$WidgetDiv.createDom=function(){module$contents$Blockly$WidgetDiv_DIV||(module$contents$Blockly$WidgetDiv_DIV=document.createElement("div"),module$contents$Blockly$WidgetDiv_DIV.className="blocklyWidgetDiv",((0,module$exports$Blockly$common.getParentContainer)()||document.body).appendChild(module$contents$Blockly$WidgetDiv_DIV))}; +module$exports$Blockly$WidgetDiv.show=function(a,b,c){(0,module$exports$Blockly$WidgetDiv.hide)();module$contents$Blockly$WidgetDiv_owner=a;module$contents$Blockly$WidgetDiv_dispose=c;a=module$contents$Blockly$WidgetDiv_DIV;a.style.direction=b?"rtl":"ltr";a.style.display="block";b=(0,module$exports$Blockly$common.getMainWorkspace)();module$contents$Blockly$WidgetDiv_rendererClassName=b.getRenderer().getClassName();module$contents$Blockly$WidgetDiv_themeClassName=b.getTheme().getClassName();(0,module$exports$Blockly$utils$dom.addClass)(a, +module$contents$Blockly$WidgetDiv_rendererClassName);(0,module$exports$Blockly$utils$dom.addClass)(a,module$contents$Blockly$WidgetDiv_themeClassName)}; +module$exports$Blockly$WidgetDiv.hide=function(){if((0,module$exports$Blockly$WidgetDiv.isVisible)()){module$contents$Blockly$WidgetDiv_owner=null;var a=module$contents$Blockly$WidgetDiv_DIV;a.style.display="none";a.style.left="";a.style.top="";module$contents$Blockly$WidgetDiv_dispose&&module$contents$Blockly$WidgetDiv_dispose();module$contents$Blockly$WidgetDiv_dispose=null;a.textContent="";module$contents$Blockly$WidgetDiv_rendererClassName&&((0,module$exports$Blockly$utils$dom.removeClass)(a, +module$contents$Blockly$WidgetDiv_rendererClassName),module$contents$Blockly$WidgetDiv_rendererClassName="");module$contents$Blockly$WidgetDiv_themeClassName&&((0,module$exports$Blockly$utils$dom.removeClass)(a,module$contents$Blockly$WidgetDiv_themeClassName),module$contents$Blockly$WidgetDiv_themeClassName="");(0,module$exports$Blockly$common.getMainWorkspace)().markFocused()}};module$exports$Blockly$WidgetDiv.isVisible=function(){return!!module$contents$Blockly$WidgetDiv_owner}; +module$exports$Blockly$WidgetDiv.hideIfOwner=function(a){module$contents$Blockly$WidgetDiv_owner==a&&(0,module$exports$Blockly$WidgetDiv.hide)()};var module$contents$Blockly$WidgetDiv_positionInternal=function(a,b,c){module$contents$Blockly$WidgetDiv_DIV.style.left=a+"px";module$contents$Blockly$WidgetDiv_DIV.style.top=b+"px";module$contents$Blockly$WidgetDiv_DIV.style.height=c+"px"}; +module$exports$Blockly$WidgetDiv.positionWithAnchor=function(a,b,c,d){var e=module$contents$Blockly$WidgetDiv_calculateY(a,b,c);a=module$contents$Blockly$WidgetDiv_calculateX(a,b,c,d);0>e?module$contents$Blockly$WidgetDiv_positionInternal(a,0,c.height+e):module$contents$Blockly$WidgetDiv_positionInternal(a,e,c.height)}; +var module$contents$Blockly$WidgetDiv_calculateX=function(a,b,c,d){return d?Math.min(Math.max(b.right-c.width,a.left),a.right-c.width):Math.max(Math.min(b.left,a.right-c.width),a.left)},module$contents$Blockly$WidgetDiv_calculateY=function(a,b,c){return b.bottom+c.height>=a.bottom?b.top-c.height:b.bottom};var module$exports$Blockly$clipboard={},module$contents$Blockly$clipboard_copyData=null;module$exports$Blockly$clipboard.copy=function(a){module$contents$Blockly$clipboard_copyData=a.toCopyData()}; +module$exports$Blockly$clipboard.paste=function(){if(!module$contents$Blockly$clipboard_copyData)return!1;var a=module$contents$Blockly$clipboard_copyData.source;a.isFlyout&&(a=a.targetWorkspace);return module$contents$Blockly$clipboard_copyData.typeCounts&&a.isCapacityAvailable(module$contents$Blockly$clipboard_copyData.typeCounts)?((0,module$exports$Blockly$Events$utils.setGroup)(!0),a.paste(module$contents$Blockly$clipboard_copyData.saveInfo),(0,module$exports$Blockly$Events$utils.setGroup)(!1), +!0):!1};module$exports$Blockly$clipboard.duplicate=function(a){var b=module$contents$Blockly$clipboard_copyData;(0,module$exports$Blockly$clipboard.copy)(a);a.workspace.paste(module$contents$Blockly$clipboard_copyData.saveInfo);module$contents$Blockly$clipboard_copyData=b};var module$exports$Blockly$Events$BlockCreate=function(a){module$exports$Blockly$Events$BlockCreate.superClass_.constructor.call(this,a);a&&(a.isShadow()&&(this.recordUndo=!1),this.xml=(0,module$exports$Blockly$Xml.blockToDomWithXY)(a),this.ids=(0,module$exports$Blockly$Events$utils.getDescendantIds)(a),this.json=Blockly.serialization.blocks.save(a,{addCoordinates:!0}))};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Events$BlockCreate,module$exports$Blockly$Events$BlockBase); +module$exports$Blockly$Events$BlockCreate.prototype.type=module$exports$Blockly$Events$utils.CREATE;module$exports$Blockly$Events$BlockCreate.prototype.toJson=function(){var a=module$exports$Blockly$Events$BlockCreate.superClass_.toJson.call(this);a.xml=(0,module$exports$Blockly$Xml.domToText)(this.xml);a.ids=this.ids;a.json=this.json;this.recordUndo||(a.recordUndo=this.recordUndo);return a}; +module$exports$Blockly$Events$BlockCreate.prototype.fromJson=function(a){module$exports$Blockly$Events$BlockCreate.superClass_.fromJson.call(this,a);this.xml=(0,module$exports$Blockly$Xml.textToDom)(a.xml);this.ids=a.ids;this.json=a.json;void 0!==a.recordUndo&&(this.recordUndo=a.recordUndo)}; +module$exports$Blockly$Events$BlockCreate.prototype.run=function(a){var b=this.getEventWorkspace_();if(a)Blockly.serialization.blocks.append(this.json,b);else for(a=0;ab.length?module$contents$Blockly$ContextMenuItems_deleteNext_(b,c):(0,module$exports$Blockly$dialog.confirm)(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",b.length),function(d){d&&module$contents$Blockly$ContextMenuItems_deleteNext_(b,c)})}},scopeType:module$exports$Blockly$ContextMenuRegistry.ScopeType.WORKSPACE,id:"workspaceDelete",weight:6})}; +var module$contents$Blockly$ContextMenuItems_registerWorkspaceOptions_=function(){(0,module$exports$Blockly$ContextMenuItems.registerUndo)();(0,module$exports$Blockly$ContextMenuItems.registerRedo)();(0,module$exports$Blockly$ContextMenuItems.registerCleanup)();(0,module$exports$Blockly$ContextMenuItems.registerCollapse)();(0,module$exports$Blockly$ContextMenuItems.registerExpand)();(0,module$exports$Blockly$ContextMenuItems.registerDeleteAll)()}; +module$exports$Blockly$ContextMenuItems.registerDuplicate=function(){module$exports$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&&(0,module$exports$Blockly$clipboard.duplicate)(a.block)},scopeType:module$exports$Blockly$ContextMenuRegistry.ScopeType.BLOCK,id:"blockDuplicate", +weight:1})}; +module$exports$Blockly$ContextMenuItems.registerComment=function(){module$exports$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 module$exports$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:module$exports$Blockly$ContextMenuRegistry.ScopeType.BLOCK,id:"blockComment",weight:2})}; +module$exports$Blockly$ContextMenuItems.registerInline=function(){module$exports$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;be.top?module$contents$Blockly$DropDownDiv_getPositionAboveMetrics(c,d,e,f):b+f.heightdocument.documentElement.clientTop?module$contents$Blockly$DropDownDiv_getPositionAboveMetrics(c,d,e,f):module$contents$Blockly$DropDownDiv_getPositionTopOfPageMetrics(a,e,f)}; +var module$contents$Blockly$DropDownDiv_getPositionBelowMetrics=function(a,b,c,d){a=module$exports$Blockly$DropDownDiv.getPositionX(a,c.left,c.right,d.width);return{initialX:a.divX,initialY:b,finalX:a.divX,finalY:b+module$exports$Blockly$DropDownDiv.PADDING_Y,arrowX:a.arrowX,arrowY:-(module$exports$Blockly$DropDownDiv.ARROW_SIZE/2+module$exports$Blockly$DropDownDiv.BORDER_SIZE),arrowAtTop:!0,arrowVisible:!0}},module$contents$Blockly$DropDownDiv_getPositionAboveMetrics=function(a,b,c,d){a=module$exports$Blockly$DropDownDiv.getPositionX(a, +c.left,c.right,d.width);return{initialX:a.divX,initialY:b-d.height,finalX:a.divX,finalY:b-d.height-module$exports$Blockly$DropDownDiv.PADDING_Y,arrowX:a.arrowX,arrowY:d.height-2*module$exports$Blockly$DropDownDiv.BORDER_SIZE-module$exports$Blockly$DropDownDiv.ARROW_SIZE/2,arrowAtTop:!1,arrowVisible:!0}},module$contents$Blockly$DropDownDiv_getPositionTopOfPageMetrics=function(a,b,c){a=module$exports$Blockly$DropDownDiv.getPositionX(a,b.left,b.right,c.width);return{initialX:a.divX,initialY:0,finalX:a.divX, +finalY:0,arrowAtTop:null,arrowX:null,arrowY:null,arrowVisible:!1}};module$exports$Blockly$DropDownDiv.getPositionX=function(a,b,c,d){var e=a;a=(0,module$exports$Blockly$utils$math.clamp)(b,a-d/2,c-d);e-=module$exports$Blockly$DropDownDiv.ARROW_SIZE/2;b=module$exports$Blockly$DropDownDiv.ARROW_HORIZONTAL_PADDING;d=(0,module$exports$Blockly$utils$math.clamp)(b,e-a,d-b-module$exports$Blockly$DropDownDiv.ARROW_SIZE);return{arrowX:d,divX:a}};module$exports$Blockly$DropDownDiv.isVisible=function(){return!!module$exports$Blockly$DropDownDiv.owner_}; +module$exports$Blockly$DropDownDiv.hideIfOwner=function(a,b){return module$exports$Blockly$DropDownDiv.owner_===a?(b?module$exports$Blockly$DropDownDiv.hideWithoutAnimation():module$exports$Blockly$DropDownDiv.hide(),!0):!1}; +module$exports$Blockly$DropDownDiv.hide=function(){module$exports$Blockly$DropDownDiv.DIV_.style.transform="translate(0, 0)";module$exports$Blockly$DropDownDiv.DIV_.style.opacity=0;module$exports$Blockly$DropDownDiv.animateOutTimer_=setTimeout(function(){module$exports$Blockly$DropDownDiv.hideWithoutAnimation()},1E3*module$exports$Blockly$DropDownDiv.ANIMATION_TIME);module$exports$Blockly$DropDownDiv.onHide_&&(module$exports$Blockly$DropDownDiv.onHide_(),module$exports$Blockly$DropDownDiv.onHide_= +null)}; +module$exports$Blockly$DropDownDiv.hideWithoutAnimation=function(){if(module$exports$Blockly$DropDownDiv.isVisible()){module$exports$Blockly$DropDownDiv.animateOutTimer_&&clearTimeout(module$exports$Blockly$DropDownDiv.animateOutTimer_);var a=module$exports$Blockly$DropDownDiv.DIV_;a.style.transform="";a.style.left="";a.style.top="";a.style.opacity=0;a.style.display="none";a.style.backgroundColor="";a.style.borderColor="";module$exports$Blockly$DropDownDiv.onHide_&&(module$exports$Blockly$DropDownDiv.onHide_(),module$exports$Blockly$DropDownDiv.onHide_= +null);module$exports$Blockly$DropDownDiv.clearContent();module$exports$Blockly$DropDownDiv.owner_=null;module$exports$Blockly$DropDownDiv.rendererClassName_&&((0,module$exports$Blockly$utils$dom.removeClass)(a,module$exports$Blockly$DropDownDiv.rendererClassName_),module$exports$Blockly$DropDownDiv.rendererClassName_="");module$exports$Blockly$DropDownDiv.themeClassName_&&((0,module$exports$Blockly$utils$dom.removeClass)(a,module$exports$Blockly$DropDownDiv.themeClassName_),module$exports$Blockly$DropDownDiv.themeClassName_= +"");(0,module$exports$Blockly$common.getMainWorkspace)().markFocused()}}; +var module$contents$Blockly$DropDownDiv_positionInternal=function(a,b,c,d){a=module$contents$Blockly$DropDownDiv_internal.getPositionMetrics(a,b,c,d);a.arrowVisible?(module$exports$Blockly$DropDownDiv.arrow_.style.display="",module$exports$Blockly$DropDownDiv.arrow_.style.transform="translate("+a.arrowX+"px,"+a.arrowY+"px) rotate(45deg)",module$exports$Blockly$DropDownDiv.arrow_.setAttribute("class",a.arrowAtTop?"blocklyDropDownArrow blocklyArrowTop":"blocklyDropDownArrow blocklyArrowBottom")):module$exports$Blockly$DropDownDiv.arrow_.style.display= +"none";b=Math.floor(a.initialX);c=Math.floor(a.initialY);d=Math.floor(a.finalX);var e=Math.floor(a.finalY),f=module$exports$Blockly$DropDownDiv.DIV_;f.style.left=b+"px";f.style.top=c+"px";f.style.display="block";f.style.opacity=1;f.style.transform="translate("+(d-b)+"px,"+(e-c)+"px)";return!!a.arrowAtTop}; +module$exports$Blockly$DropDownDiv.repositionForWindowResize=function(){if(module$exports$Blockly$DropDownDiv.owner_){var a=module$exports$Blockly$DropDownDiv.owner_,b=a.getSourceBlock();a=module$exports$Blockly$DropDownDiv.positionToField_?module$contents$Blockly$DropDownDiv_getScaledBboxOfField(a):module$contents$Blockly$DropDownDiv_getScaledBboxOfBlock(b);b=a.left+(a.right-a.left)/2;module$contents$Blockly$DropDownDiv_positionInternal(b,a.bottom,b,a.top)}else module$exports$Blockly$DropDownDiv.hide()}; +module$exports$Blockly$DropDownDiv.TEST_ONLY=module$contents$Blockly$DropDownDiv_internal;var module$exports$Blockly$IASTNodeLocationSvg=function(){};var module$exports$Blockly$IKeyboardAccessible=function(){};var module$exports$Blockly$IRegistrable=function(){};var module$exports$Blockly$MarkerManager=function(a){this.cursorSvg_=this.cursor_=null;this.markers_=Object.create(null);this.workspace_=a};module$exports$Blockly$MarkerManager.LOCAL_MARKER="local_marker_1";module$exports$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}; +module$exports$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 unregister markers that exist.");};module$exports$Blockly$MarkerManager.prototype.getCursor=function(){return this.cursor_};module$exports$Blockly$MarkerManager.prototype.getMarker=function(a){return this.markers_[a]||null}; +module$exports$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())};module$exports$Blockly$MarkerManager.prototype.setCursorSvg=function(a){a?(this.workspace_.getBlockCanvas().appendChild(a),this.cursorSvg_=a):this.cursorSvg_=null}; +module$exports$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};module$exports$Blockly$MarkerManager.prototype.updateMarkers=function(){this.workspace_.keyboardAccessibilityMode&&this.cursorSvg_&&this.workspace_.getCursor().draw()}; +module$exports$Blockly$MarkerManager.prototype.dispose=function(){for(var a=Object.keys(this.markers_),b=0,c;c=a[b];b++)this.unregisterMarker(c);this.markers_=null;this.cursor_&&(this.cursor_.dispose(),this.cursor_=null)};var module$exports$Blockly$Tooltip={},module$contents$Blockly$Tooltip_visible=!1;module$exports$Blockly$Tooltip.isVisible=function(){return module$contents$Blockly$Tooltip_visible};Object.defineProperties(module$exports$Blockly$Tooltip,{visible:{get:function(){(0,module$exports$Blockly$utils$deprecation.warn)("Blockly.Tooltip.visible","September 2021","September 2022","Blockly.Tooltip.isVisible()");return(0,module$exports$Blockly$Tooltip.isVisible)()}}}); +var module$contents$Blockly$Tooltip_blocked=!1;module$exports$Blockly$Tooltip.LIMIT=50;var module$contents$Blockly$Tooltip_mouseOutPid=0,module$contents$Blockly$Tooltip_showPid=0,module$contents$Blockly$Tooltip_lastX=0,module$contents$Blockly$Tooltip_lastY=0,module$contents$Blockly$Tooltip_element=null,module$contents$Blockly$Tooltip_poisonedElement=null;module$exports$Blockly$Tooltip.OFFSET_X=0;module$exports$Blockly$Tooltip.OFFSET_Y=10;module$exports$Blockly$Tooltip.RADIUS_OK=10; +module$exports$Blockly$Tooltip.HOVER_MS=750;module$exports$Blockly$Tooltip.MARGINS=5;var module$contents$Blockly$Tooltip_DIV=null;module$exports$Blockly$Tooltip.getDiv=function(){return module$contents$Blockly$Tooltip_DIV};Object.defineProperties(module$exports$Blockly$Tooltip,{DIV:{get:function(){(0,module$exports$Blockly$utils$deprecation.warn)("Blockly.Tooltip.DIV","September 2021","September 2022","Blockly.Tooltip.getDiv()");return(0,module$exports$Blockly$Tooltip.getDiv)()}}}); +module$exports$Blockly$Tooltip.getTooltipOfObject=function(a){if(a=module$contents$Blockly$Tooltip_getTargetObject(a)){for(a=a.tooltip;"function"==typeof a;)a=a();if("string"!=typeof a)throw Error("Tooltip function must return a string.");return a}return""};var module$contents$Blockly$Tooltip_getTargetObject=function(a){for(;a&&a.tooltip;){if("string"==typeof a.tooltip||"function"==typeof a.tooltip)return a;a=a.tooltip}return null}; +module$exports$Blockly$Tooltip.createDom=function(){module$contents$Blockly$Tooltip_DIV||(module$contents$Blockly$Tooltip_DIV=document.createElement("div"),module$contents$Blockly$Tooltip_DIV.className="blocklyTooltipDiv",((0,module$exports$Blockly$common.getParentContainer)()||document.body).appendChild(module$contents$Blockly$Tooltip_DIV))}; +module$exports$Blockly$Tooltip.bindMouseEvents=function(a){a.mouseOverWrapper_=(0,module$exports$Blockly$browserEvents.bind)(a,"mouseover",null,module$contents$Blockly$Tooltip_onMouseOver);a.mouseOutWrapper_=(0,module$exports$Blockly$browserEvents.bind)(a,"mouseout",null,module$contents$Blockly$Tooltip_onMouseOut);a.addEventListener("mousemove",module$contents$Blockly$Tooltip_onMouseMove,!1)}; +module$exports$Blockly$Tooltip.unbindMouseEvents=function(a){a&&((0,module$exports$Blockly$browserEvents.unbind)(a.mouseOverWrapper_),(0,module$exports$Blockly$browserEvents.unbind)(a.mouseOutWrapper_),a.removeEventListener("mousemove",module$contents$Blockly$Tooltip_onMouseMove))}; +var module$contents$Blockly$Tooltip_onMouseOver=function(a){module$contents$Blockly$Tooltip_blocked||(a=module$contents$Blockly$Tooltip_getTargetObject(a.currentTarget),module$contents$Blockly$Tooltip_element!=a&&((0,module$exports$Blockly$Tooltip.hide)(),module$contents$Blockly$Tooltip_poisonedElement=null,module$contents$Blockly$Tooltip_element=a),clearTimeout(module$contents$Blockly$Tooltip_mouseOutPid))},module$contents$Blockly$Tooltip_onMouseOut=function(a){module$contents$Blockly$Tooltip_blocked|| +(module$contents$Blockly$Tooltip_mouseOutPid=setTimeout(function(){module$contents$Blockly$Tooltip_poisonedElement=module$contents$Blockly$Tooltip_element=null;(0,module$exports$Blockly$Tooltip.hide)()},1),clearTimeout(module$contents$Blockly$Tooltip_showPid))},module$contents$Blockly$Tooltip_onMouseMove=function(a){if(module$contents$Blockly$Tooltip_element&&module$contents$Blockly$Tooltip_element.tooltip&&!module$contents$Blockly$Tooltip_blocked)if(module$contents$Blockly$Tooltip_visible){var b= +module$contents$Blockly$Tooltip_lastX-a.pageX;a=module$contents$Blockly$Tooltip_lastY-a.pageY;Math.sqrt(b*b+a*a)>module$exports$Blockly$Tooltip.RADIUS_OK&&(0,module$exports$Blockly$Tooltip.hide)()}else module$contents$Blockly$Tooltip_poisonedElement!=module$contents$Blockly$Tooltip_element&&(clearTimeout(module$contents$Blockly$Tooltip_showPid),module$contents$Blockly$Tooltip_lastX=a.pageX,module$contents$Blockly$Tooltip_lastY=a.pageY,module$contents$Blockly$Tooltip_showPid=setTimeout(module$contents$Blockly$Tooltip_show, +module$exports$Blockly$Tooltip.HOVER_MS))};module$exports$Blockly$Tooltip.dispose=function(){module$contents$Blockly$Tooltip_poisonedElement=module$contents$Blockly$Tooltip_element=null;(0,module$exports$Blockly$Tooltip.hide)()};module$exports$Blockly$Tooltip.hide=function(){module$contents$Blockly$Tooltip_visible&&(module$contents$Blockly$Tooltip_visible=!1,module$contents$Blockly$Tooltip_DIV&&(module$contents$Blockly$Tooltip_DIV.style.display="none"));module$contents$Blockly$Tooltip_showPid&&clearTimeout(module$contents$Blockly$Tooltip_showPid)}; +module$exports$Blockly$Tooltip.block=function(){(0,module$exports$Blockly$Tooltip.hide)();module$contents$Blockly$Tooltip_blocked=!0};module$exports$Blockly$Tooltip.unblock=function(){module$contents$Blockly$Tooltip_blocked=!1}; +var module$contents$Blockly$Tooltip_show=function(){if(!module$contents$Blockly$Tooltip_blocked&&(module$contents$Blockly$Tooltip_poisonedElement=module$contents$Blockly$Tooltip_element,module$contents$Blockly$Tooltip_DIV)){module$contents$Blockly$Tooltip_DIV.textContent="";var a=(0,module$exports$Blockly$Tooltip.getTooltipOfObject)(module$contents$Blockly$Tooltip_element);a=(0,module$exports$Blockly$utils$string.wrap)(a,module$exports$Blockly$Tooltip.LIMIT);a=a.split("\n");for(var b=0;bc+window.scrollY&&(e-=module$contents$Blockly$Tooltip_DIV.offsetHeight+2*module$exports$Blockly$Tooltip.OFFSET_Y);a?d=Math.max(module$exports$Blockly$Tooltip.MARGINS-window.scrollX,d):d+module$contents$Blockly$Tooltip_DIV.offsetWidth>b+window.scrollX-2*module$exports$Blockly$Tooltip.MARGINS&& +(d=b-module$contents$Blockly$Tooltip_DIV.offsetWidth-2*module$exports$Blockly$Tooltip.MARGINS);module$contents$Blockly$Tooltip_DIV.style.top=e+"px";module$contents$Blockly$Tooltip_DIV.style.left=d+"px"}};var module$exports$Blockly$WorkspaceDragger=function(a){this.workspace_=a;this.horizontalScrollEnabled_=this.workspace_.isMovableHorizontally();this.verticalScrollEnabled_=this.workspace_.isMovableVertically();this.startScrollXY_=new module$exports$Blockly$utils$Coordinate(a.scrollX,a.scrollY)};module$exports$Blockly$WorkspaceDragger.prototype.dispose=function(){this.workspace_=null}; +module$exports$Blockly$WorkspaceDragger.prototype.startDrag=function(){(0,module$exports$Blockly$common.getSelected)()&&(0,module$exports$Blockly$common.getSelected)().unselect();this.workspace_.setupDragSurface()};module$exports$Blockly$WorkspaceDragger.prototype.endDrag=function(a){this.drag(a);this.workspace_.resetDragSurface()}; +module$exports$Blockly$WorkspaceDragger.prototype.drag=function(a){a=module$exports$Blockly$utils$Coordinate.sum(this.startScrollXY_,a);if(this.horizontalScrollEnabled_&&this.verticalScrollEnabled_)this.workspace_.scroll(a.x,a.y);else if(this.horizontalScrollEnabled_)this.workspace_.scroll(a.x,this.workspace_.scrollY);else if(this.verticalScrollEnabled_)this.workspace_.scroll(this.workspace_.scrollX,a.y);else throw new TypeError("Invalid state.");};var module$exports$Blockly$blockAnimations={},module$contents$Blockly$blockAnimations_disconnectPid=0,module$contents$Blockly$blockAnimations_disconnectGroup=null; +module$exports$Blockly$blockAnimations.disposeUiEffect=function(a){var b=a.workspace,c=a.getSvgRoot();b.getAudioManager().play("delete");a=b.getSvgXY(c);c=c.cloneNode(!0);c.translateX_=a.x;c.translateY_=a.y;c.setAttribute("transform","translate("+a.x+","+a.y+")");b.getParentSvg().appendChild(c);c.bBox_=c.getBBox();module$contents$Blockly$blockAnimations_disposeUiStep(c,b.RTL,new Date,b.scale)}; +var module$contents$Blockly$blockAnimations_disposeUiStep=function(a,b,c,d){var e=(new Date-c)/150;1c)){var d=b.getSvgXY(a.getSvgRoot());a.outputConnection?(d.x+=(a.RTL?3:-3)*c,d.y+=13*c):a.previousConnection&&(d.x+=(a.RTL?-23:23)*c,d.y+=3*c);a=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE,{cx:d.x,cy:d.y,r:0,fill:"none",stroke:"#888","stroke-width":10},b.getParentSvg());module$contents$Blockly$blockAnimations_connectionUiStep(a, +new Date,c)}};var module$contents$Blockly$blockAnimations_connectionUiStep=function(a,b,c){var d=(new Date-b)/150;1a.workspace.scale)){var b=a.getHeightWidth().height;b=Math.atan(10/b)/Math.PI*180;a.RTL||(b*=-1);module$contents$Blockly$blockAnimations_disconnectUiStep(a.getSvgRoot(),b,new Date)}}; +var module$contents$Blockly$blockAnimations_disconnectUiStep=function(a,b,c){var d=(new Date-c)/200;1b-module$exports$Blockly$internalConstants.CURRENT_CONNECTION_PREFERENCE)}if(this.localConnection_||this.closestConnection_)console.error("Only one of localConnection_ and closestConnection_ was set."); +else return!0}else return!(!this.localConnection_||!this.closestConnection_);console.error("Returning true from shouldUpdatePreviews, but it's not clear why.");return!0};module$exports$Blockly$InsertionMarkerManager.prototype.getCandidate_=function(a){for(var b=this.getStartRadius_(),c=null,d=null,e=0;eb.oldScale&&(0,module$exports$Blockly$bumpObjects.bumpTopObjectsIntoBounds)(a)}}},module$contents$Blockly$bumpObjects_extractObjectFromEvent=function(a,b){var c=null;switch(b.type){case module$exports$Blockly$Events$utils.CREATE:case module$exports$Blockly$Events$utils.MOVE:(c=a.getBlockById(b.blockId))&&(c=c.getRootBlock());break;case module$exports$Blockly$Events$utils.COMMENT_CREATE:case module$exports$Blockly$Events$utils.COMMENT_MOVE:c= +a.getCommentById(b.commentId)}return c};module$exports$Blockly$bumpObjects.bumpTopObjectsIntoBounds=function(a){var b=a.getMetricsManager();if(b.hasFixedEdges()&&!a.isDragging()){b=b.getScrollMetrics(!0);for(var c=a.getTopBoundedElements(),d=0,e;e=c[d];d++)(0,module$exports$Blockly$bumpObjects.bumpIntoBounds)(a,b,e)}};var module$exports$Blockly$Events$BlockDrag=function(a,b,c){module$exports$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};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Events$BlockDrag,module$exports$Blockly$Events$UiBase);module$exports$Blockly$Events$BlockDrag.prototype.type=module$exports$Blockly$Events$utils.BLOCK_DRAG; +module$exports$Blockly$Events$BlockDrag.prototype.toJson=function(){var a=module$exports$Blockly$Events$BlockDrag.superClass_.toJson.call(this);a.isStart=this.isStart;a.blockId=this.blockId;a.blocks=this.blocks;return a};module$exports$Blockly$Events$BlockDrag.prototype.fromJson=function(a){module$exports$Blockly$Events$BlockDrag.superClass_.fromJson.call(this,a);this.isStart=a.isStart;this.blockId=a.blockId;this.blocks=a.blocks}; +(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.EVENT,module$exports$Blockly$Events$utils.BLOCK_DRAG,module$exports$Blockly$Events$BlockDrag);var module$exports$Blockly$BlockDragger={BlockDragger:function(a,b){this.draggingBlock_=a;this.workspace_=b;this.draggedConnectionManager_=new module$exports$Blockly$InsertionMarkerManager(this.draggingBlock_);this.dragTarget_=null;this.wouldDeleteBlock_=!1;this.startXY_=this.draggingBlock_.getRelativeToSurfaceXY();this.dragIconData_=module$contents$Blockly$BlockDragger_initIconData(a)}}; +module$exports$Blockly$BlockDragger.BlockDragger.prototype.dispose=function(){this.dragIconData_.length=0;this.draggedConnectionManager_&&this.draggedConnectionManager_.dispose()};var module$contents$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(this.flyout_?module$exports$Blockly$internalConstants.FLYOUT_DRAG_RADIUS:module$exports$Blockly$internalConstants.DRAG_RADIUS)}; +module$exports$Blockly$Gesture.prototype.updateIsDraggingFromFlyout_=function(){return this.targetBlock_&&this.flyout_.isBlockCreatable_(this.targetBlock_)?!this.flyout_.isScrollable()||this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)?(this.startWorkspace_=this.flyout_.targetWorkspace,this.startWorkspace_.updateScreenCalculationsIfScrolled(),(0,module$exports$Blockly$Events$utils.getGroup)()||(0,module$exports$Blockly$Events$utils.setGroup)(!0),this.startBlock_=null,this.targetBlock_= +this.flyout_.createBlock(this.targetBlock_),this.targetBlock_.select(),!0):!1:!1};module$exports$Blockly$Gesture.prototype.updateIsDraggingBubble_=function(){if(!this.startBubble_)return!1;this.isDraggingBubble_=!0;this.startDraggingBubble_();return!0}; +module$exports$Blockly$Gesture.prototype.updateIsDraggingBlock_=function(){if(!this.targetBlock_)return!1;this.flyout_?this.isDraggingBlock_=this.updateIsDraggingFromFlyout_():this.targetBlock_.isMovable()&&(this.isDraggingBlock_=!0);return this.isDraggingBlock_?(this.startDraggingBlock_(),!0):!1}; +module$exports$Blockly$Gesture.prototype.updateIsDraggingWorkspace_=function(){if(this.flyout_?this.flyout_.isScrollable():this.startWorkspace_&&this.startWorkspace_.isDraggable())this.workspaceDragger_=new module$exports$Blockly$WorkspaceDragger(this.startWorkspace_),this.isDraggingWorkspace_=!0,this.workspaceDragger_.startDrag()}; +module$exports$Blockly$Gesture.prototype.updateIsDragging_=function(){if(this.calledUpdateIsDragging_)throw Error("updateIsDragging_ should only be called once per gesture.");this.calledUpdateIsDragging_=!0;this.updateIsDraggingBubble_()||this.updateIsDraggingBlock_()||this.updateIsDraggingWorkspace_()}; +module$exports$Blockly$Gesture.prototype.startDraggingBlock_=function(){this.blockDragger_=new ((0,module$exports$Blockly$registry.getClassFromOptions)(module$exports$Blockly$registry.Type.BLOCK_DRAGGER,this.creatorWorkspace_.options,!0))(this.targetBlock_,this.startWorkspace_);this.blockDragger_.startDrag(this.currentDragDeltaXY_,this.healStack_);this.blockDragger_.drag(this.mostRecentEvent_,this.currentDragDeltaXY_)}; +module$exports$Blockly$Gesture.prototype.startDraggingBubble_=function(){this.bubbleDragger_=new module$exports$Blockly$BubbleDragger(this.startBubble_,this.startWorkspace_);this.bubbleDragger_.startBubbleDrag();this.bubbleDragger_.dragBubble(this.mostRecentEvent_,this.currentDragDeltaXY_)}; +module$exports$Blockly$Gesture.prototype.doStart=function(a){(0,module$exports$Blockly$browserEvents.isTargetInput)(a)?this.cancel():(this.hasStarted_=!0,(0,module$exports$Blockly$blockAnimations.disconnectUiStop)(),this.startWorkspace_.updateScreenCalculationsIfScrolled(),this.startWorkspace_.isMutator&&this.startWorkspace_.resize(),this.startWorkspace_.hideChaff(!!this.flyout_),this.startWorkspace_.markFocused(),this.mostRecentEvent_=a,(0,module$exports$Blockly$Tooltip.block)(),this.targetBlock_&& +this.targetBlock_.select(),(0,module$exports$Blockly$browserEvents.isRightButton)(a)?this.handleRightClick(a):("touchstart"!=a.type.toLowerCase()&&"pointerdown"!=a.type.toLowerCase()||"mouse"==a.pointerType||(0,module$exports$Blockly$Touch.longStart)(a,this),this.mouseDownXY_=new module$exports$Blockly$utils$Coordinate(a.clientX,a.clientY),this.healStack_=a.altKey||a.ctrlKey||a.metaKey,this.bindMouseEvents(a)))}; +module$exports$Blockly$Gesture.prototype.bindMouseEvents=function(a){this.onMoveWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(document,"mousemove",null,this.handleMove.bind(this));this.onUpWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(document,"mouseup",null,this.handleUp.bind(this));a.preventDefault();a.stopPropagation()}; +module$exports$Blockly$Gesture.prototype.handleMove=function(a){this.updateFromEvent_(a);this.isDraggingWorkspace_?this.workspaceDragger_.drag(this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.drag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingBubble_&&this.bubbleDragger_.dragBubble(this.mostRecentEvent_,this.currentDragDeltaXY_);a.preventDefault();a.stopPropagation()}; +module$exports$Blockly$Gesture.prototype.handleUp=function(a){this.updateFromEvent_(a);(0,module$exports$Blockly$Touch.longStop)();this.isEnding_?console.log("Trying to end a gesture recursively."):(this.isEnding_=!0,this.isDraggingBubble_?this.bubbleDragger_.endBubbleDrag(a,this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.endDrag(a,this.currentDragDeltaXY_):this.isDraggingWorkspace_?this.workspaceDragger_.endDrag(this.currentDragDeltaXY_):this.isBubbleClick_()?this.doBubbleClick_(): +this.isFieldClick_()?this.doFieldClick_():this.isBlockClick_()?this.doBlockClick_():this.isWorkspaceClick_()&&this.doWorkspaceClick_(a),a.preventDefault(),a.stopPropagation(),this.dispose())}; +module$exports$Blockly$Gesture.prototype.cancel=function(){this.isEnding_||((0,module$exports$Blockly$Touch.longStop)(),this.isDraggingBubble_?this.bubbleDragger_.endBubbleDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingBlock_?this.blockDragger_.endDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingWorkspace_&&this.workspaceDragger_.endDrag(this.currentDragDeltaXY_),this.dispose())}; +module$exports$Blockly$Gesture.prototype.handleRightClick=function(a){this.targetBlock_?(this.bringBlockToFront_(),this.targetBlock_.workspace.hideChaff(!!this.flyout_),this.targetBlock_.showContextMenu(a)):this.startBubble_?this.startBubble_.showContextMenu(a):this.startWorkspace_&&!this.flyout_&&(this.startWorkspace_.hideChaff(),this.startWorkspace_.showContextMenu(a));a.preventDefault();a.stopPropagation();this.dispose()}; +module$exports$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)};module$exports$Blockly$Gesture.prototype.fireWorkspaceClick_=function(a){(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CLICK))(null,a.id,"workspace"))}; +module$exports$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())};module$exports$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}; +module$exports$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};module$exports$Blockly$Gesture.prototype.doBubbleClick_=function(){this.startBubble_.setFocus&&this.startBubble_.setFocus();this.startBubble_.select&&this.startBubble_.select()}; +module$exports$Blockly$Gesture.prototype.doFieldClick_=function(){this.startField_.showEditor(this.mostRecentEvent_);this.bringBlockToFront_()}; +module$exports$Blockly$Gesture.prototype.doBlockClick_=function(){if(this.flyout_&&this.flyout_.autoClose)this.targetBlock_.isEnabled()&&((0,module$exports$Blockly$Events$utils.getGroup)()||(0,module$exports$Blockly$Events$utils.setGroup)(!0),this.flyout_.createBlock(this.targetBlock_).scheduleSnapAndBump());else{var a=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CLICK))(this.startBlock_,this.startWorkspace_.id,"block");(0,module$exports$Blockly$Events$utils.fire)(a)}this.bringBlockToFront_(); +(0,module$exports$Blockly$Events$utils.setGroup)(!1)};module$exports$Blockly$Gesture.prototype.doWorkspaceClick_=function(a){a=this.creatorWorkspace_;(0,module$exports$Blockly$common.getSelected)()&&(0,module$exports$Blockly$common.getSelected)().unselect();this.fireWorkspaceClick_(this.startWorkspace_||a)};module$exports$Blockly$Gesture.prototype.bringBlockToFront_=function(){this.targetBlock_&&!this.flyout_&&this.targetBlock_.bringToFront()}; +module$exports$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)};module$exports$Blockly$Gesture.prototype.setStartBubble=function(a){this.startBubble_||(this.startBubble_=a)}; +module$exports$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))};module$exports$Blockly$Gesture.prototype.setTargetBlock_=function(a){a.isShadow()?this.setTargetBlock_(a.getParent()):this.targetBlock_=a};module$exports$Blockly$Gesture.prototype.setStartWorkspace_=function(a){this.startWorkspace_||(this.startWorkspace_=a)}; +module$exports$Blockly$Gesture.prototype.setStartFlyout_=function(a){this.flyout_||(this.flyout_=a)};module$exports$Blockly$Gesture.prototype.isBubbleClick_=function(){return!!this.startBubble_&&!this.hasExceededDragRadius_};module$exports$Blockly$Gesture.prototype.isBlockClick_=function(){return!!this.startBlock_&&!this.hasExceededDragRadius_&&!this.isFieldClick_()}; +module$exports$Blockly$Gesture.prototype.isFieldClick_=function(){return(this.startField_?this.startField_.isClickable():!1)&&!this.hasExceededDragRadius_&&(!this.flyout_||!this.flyout_.autoClose)};module$exports$Blockly$Gesture.prototype.isWorkspaceClick_=function(){return!this.startBlock_&&!this.startBubble_&&!this.startField_&&!this.hasExceededDragRadius_};module$exports$Blockly$Gesture.prototype.isDragging=function(){return this.isDraggingWorkspace_||this.isDraggingBlock_||this.isDraggingBubble_}; +module$exports$Blockly$Gesture.prototype.hasStarted=function(){return this.hasStarted_};module$exports$Blockly$Gesture.prototype.getInsertionMarkers=function(){return this.blockDragger_?this.blockDragger_.getInsertionMarkers():[]};module$exports$Blockly$Gesture.prototype.getCurrentDragger=function(){return this.isDraggingBlock_?this.blockDragger_:this.isDraggingWorkspace_?this.workspaceDragger_:this.isDraggingBubble_?this.bubbleDragger_:null}; +module$exports$Blockly$Gesture.inProgress=function(){for(var a=module$exports$Blockly$Workspace.getAll(),b=0,c;c=a[b];b++)if(c.currentGesture_)return!0;return!1};var module$exports$Blockly$Field=function(a,b,c){this.value_=this.DEFAULT_VALUE;this.tooltip_=this.validator_=null;this.size_=new module$exports$Blockly$utils$Size(0,0);this.constants_=this.mouseDownWrapper_=this.textContent_=this.textElement_=this.borderRect_=this.fieldGroup_=this.markerSvg_=this.cursorSvg_=null;c&&this.configure_(c);this.setValue(a);b&&this.setValidator(b)};module$exports$Blockly$Field.prototype.DEFAULT_VALUE=null;module$exports$Blockly$Field.prototype.name=void 0; +module$exports$Blockly$Field.prototype.disposed=!1;module$exports$Blockly$Field.prototype.maxDisplayLength=50;module$exports$Blockly$Field.prototype.sourceBlock_=null;module$exports$Blockly$Field.prototype.isDirty_=!0;module$exports$Blockly$Field.prototype.visible_=!0;module$exports$Blockly$Field.prototype.enabled_=!0;module$exports$Blockly$Field.prototype.clickTarget_=null;module$exports$Blockly$Field.NBSP="\u00a0";module$exports$Blockly$Field.prototype.EDITABLE=!0; +module$exports$Blockly$Field.prototype.SERIALIZABLE=!1;module$exports$Blockly$Field.prototype.configure_=function(a){var b=a.tooltip;"string"==typeof b&&(b=(0,module$exports$Blockly$utils.replaceMessageReferences)(a.tooltip));b&&this.setTooltip(b)};module$exports$Blockly$Field.prototype.setSourceBlock=function(a){if(this.sourceBlock_)throw Error("Field already bound to a block");this.sourceBlock_=a}; +module$exports$Blockly$Field.prototype.getConstants=function(){!this.constants_&&this.sourceBlock_&&this.sourceBlock_.workspace&&this.sourceBlock_.workspace.rendered&&(this.constants_=this.sourceBlock_.workspace.getRenderer().getConstants());return this.constants_};module$exports$Blockly$Field.prototype.getSourceBlock=function(){return this.sourceBlock_}; +module$exports$Blockly$Field.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{},null),this.isVisible()||(this.fieldGroup_.style.display="none"),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),this.initView(),this.updateEditable(),this.setTooltip(this.tooltip_),this.bindEvents_(),this.initModel())};module$exports$Blockly$Field.prototype.initView=function(){this.createBorderRect_();this.createTextElement_()}; +module$exports$Blockly$Field.prototype.initModel=function(){};module$exports$Blockly$Field.prototype.createBorderRect_=function(){this.borderRect_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{rx:this.getConstants().FIELD_BORDER_RECT_RADIUS,ry:this.getConstants().FIELD_BORDER_RECT_RADIUS,x:0,y:0,height:this.size_.height,width:this.size_.width,"class":"blocklyFieldRect"},this.fieldGroup_)}; +module$exports$Blockly$Field.prototype.createTextElement_=function(){this.textElement_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.TEXT,{"class":"blocklyText"},this.fieldGroup_);this.getConstants().FIELD_TEXT_BASELINE_CENTER&&this.textElement_.setAttribute("dominant-baseline","central");this.textContent_=document.createTextNode("");this.textElement_.appendChild(this.textContent_)}; +module$exports$Blockly$Field.prototype.bindEvents_=function(){(0,module$exports$Blockly$Tooltip.bindMouseEvents)(this.getClickTarget_());this.mouseDownWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.getClickTarget_(),"mousedown",this,this.onMouseDown_)};module$exports$Blockly$Field.prototype.fromXml=function(a){this.setValue(a.textContent)};module$exports$Blockly$Field.prototype.toXml=function(a){a.textContent=this.getValue();return a}; +module$exports$Blockly$Field.prototype.saveState=function(a){a=this.saveLegacyState(module$exports$Blockly$Field);return null!==a?a:this.getValue()};module$exports$Blockly$Field.prototype.loadState=function(a){this.loadLegacyState(module$exports$Blockly$Field,a)||this.setValue(a)}; +module$exports$Blockly$Field.prototype.saveLegacyState=function(a){return a.prototype.saveState===this.saveState&&a.prototype.toXml!==this.toXml?(a=(0,module$exports$Blockly$utils$xml.createElement)("field"),a.setAttribute("name",this.name||""),(0,module$exports$Blockly$Xml.domToText)(this.toXml(a)).replace(' xmlns="https://developers.google.com/blockly/xml"',"")):null}; +module$exports$Blockly$Field.prototype.loadLegacyState=function(a,b){return a.prototype.loadState===this.loadState&&a.prototype.fromXml!==this.fromXml?(this.fromXml((0,module$exports$Blockly$Xml.textToDom)(b)),!0):!1}; +module$exports$Blockly$Field.prototype.dispose=function(){module$exports$Blockly$DropDownDiv.hideIfOwner(this);(0,module$exports$Blockly$WidgetDiv.hideIfOwner)(this);(0,module$exports$Blockly$Tooltip.unbindMouseEvents)(this.getClickTarget_());this.mouseDownWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.mouseDownWrapper_);(0,module$exports$Blockly$utils$dom.removeNode)(this.fieldGroup_);this.disposed=!0}; +module$exports$Blockly$Field.prototype.updateEditable=function(){var a=this.fieldGroup_;this.EDITABLE&&a&&(this.enabled_&&this.sourceBlock_.isEditable()?((0,module$exports$Blockly$utils$dom.addClass)(a,"blocklyEditableText"),(0,module$exports$Blockly$utils$dom.removeClass)(a,"blocklyNonEditableText"),a.style.cursor=this.CURSOR):((0,module$exports$Blockly$utils$dom.addClass)(a,"blocklyNonEditableText"),(0,module$exports$Blockly$utils$dom.removeClass)(a,"blocklyEditableText"),a.style.cursor=""))}; +module$exports$Blockly$Field.prototype.setEnabled=function(a){this.enabled_=a;this.updateEditable()};module$exports$Blockly$Field.prototype.isEnabled=function(){return this.enabled_};module$exports$Blockly$Field.prototype.isClickable=function(){return this.enabled_&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()&&!!this.showEditor_&&"function"===typeof this.showEditor_}; +module$exports$Blockly$Field.prototype.isCurrentlyEditable=function(){return this.enabled_&&this.EDITABLE&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()};module$exports$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}; +module$exports$Blockly$Field.prototype.isVisible=function(){return this.visible_};module$exports$Blockly$Field.prototype.setVisible=function(a){if(this.visible_!=a){this.visible_=a;var b=this.getSvgRoot();b&&(b.style.display=a?"block":"none")}};module$exports$Blockly$Field.prototype.setValidator=function(a){this.validator_=a};module$exports$Blockly$Field.prototype.getValidator=function(){return this.validator_};module$exports$Blockly$Field.prototype.getSvgRoot=function(){return this.fieldGroup_}; +module$exports$Blockly$Field.prototype.applyColour=function(){};module$exports$Blockly$Field.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_());this.updateSize_()};module$exports$Blockly$Field.prototype.showEditor=function(a){this.isClickable()&&this.showEditor_(a)}; +module$exports$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=(0,module$exports$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_()};module$exports$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)}}; +module$exports$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))}; +module$exports$Blockly$Field.prototype.getSize=function(){if(!this.isVisible())return new module$exports$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_}; +module$exports$Blockly$Field.prototype.getScaledBBox=function(){if(this.borderRect_){var a=this.borderRect_.getBoundingClientRect();var b=(0,module$exports$Blockly$utils$style.getPageOffset)(this.borderRect_);var c=a.width;var d=a.height}else d=this.sourceBlock_.getHeightWidth(),a=this.sourceBlock_.workspace.scale,b=this.getAbsoluteXY_(),c=d.width*a,d=d.height*a,module$exports$Blockly$utils$userAgent.GECKO?(b.x+=1.5*a,b.y+=1.5*a):module$exports$Blockly$utils$userAgent.EDGE||module$exports$Blockly$utils$userAgent.IE|| +(b.x-=.5*a,b.y-=.5*a),c+=1*a,d+=1*a;return new module$exports$Blockly$utils$Rect(b.y,b.y+d,b.x,b.x+c)};module$exports$Blockly$Field.prototype.getDisplayText_=function(){var a=this.getText();if(!a)return module$exports$Blockly$Field.NBSP;a.length>this.maxDisplayLength&&(a=a.substring(0,this.maxDisplayLength-2)+"\u2026");a=a.replace(/\s/g,module$exports$Blockly$Field.NBSP);this.sourceBlock_&&this.sourceBlock_.RTL&&(a+="\u200f");return a}; +module$exports$Blockly$Field.prototype.getText=function(){if(this.getText_){var a=this.getText_.call(this);if(null!==a)return String(a)}return String(this.getValue())};module$exports$Blockly$Field.prototype.markDirty=function(){this.isDirty_=!0;this.constants_=null};module$exports$Blockly$Field.prototype.forceRerender=function(){this.isDirty_=!0;this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours(),this.updateMarkers_())}; +module$exports$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):(this.doValueUpdate_(a),b&&(0,module$exports$Blockly$Events$utils.isEnabled)()&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CHANGE))(b, +"field",this.name||null,c,a)),this.isDirty_&&this.forceRerender())}}}};module$exports$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};module$exports$Blockly$Field.prototype.getValue=function(){return this.value_};module$exports$Blockly$Field.prototype.doClassValidation_=function(a){return null===a||void 0===a?null:a}; +module$exports$Blockly$Field.prototype.doValueUpdate_=function(a){this.value_=a;this.isDirty_=!0};module$exports$Blockly$Field.prototype.doValueInvalid_=function(a){};module$exports$Blockly$Field.prototype.onMouseDown_=function(a){this.sourceBlock_&&this.sourceBlock_.workspace&&(a=this.sourceBlock_.workspace.getGesture(a))&&a.setStartField(this)}; +module$exports$Blockly$Field.prototype.setTooltip=function(a){a||""===a||(a=this.sourceBlock_);var b=this.getClickTarget_();b?b.tooltip=a:this.tooltip_=a};module$exports$Blockly$Field.prototype.getTooltip=function(){var a=this.getClickTarget_();return a?(0,module$exports$Blockly$Tooltip.getTooltipOfObject)(a):(0,module$exports$Blockly$Tooltip.getTooltipOfObject)({tooltip:this.tooltip_})};module$exports$Blockly$Field.prototype.getClickTarget_=function(){return this.clickTarget_||this.getSvgRoot()}; +module$exports$Blockly$Field.prototype.getAbsoluteXY_=function(){return(0,module$exports$Blockly$utils$style.getPageOffset)(this.getClickTarget_())};module$exports$Blockly$Field.prototype.referencesVariables=function(){return!1};module$exports$Blockly$Field.prototype.getParentInput=function(){for(var a=null,b=this.sourceBlock_,c=b.inputList,d=0;db?!1:module$exports$Blockly$RenderedConnection.superClass_.isConnectionAllowed.call(this,a)}; +module$exports$Blockly$RenderedConnection.prototype.onFailedConnect=function(a){var b=this.getSourceBlock();if((0,module$exports$Blockly$Events$utils.getRecordUndo)()){var c=(0,module$exports$Blockly$Events$utils.getGroup)();setTimeout(function(){b.isDisposed()||b.getParent()||((0,module$exports$Blockly$Events$utils.setGroup)(c),this.bumpAwayFrom(a),(0,module$exports$Blockly$Events$utils.setGroup)(!1))}.bind(this),module$exports$Blockly$internalConstants.BUMP_DELAY)}}; +module$exports$Blockly$RenderedConnection.prototype.disconnectInternal_=function(a,b){module$exports$Blockly$RenderedConnection.superClass_.disconnectInternal_.call(this,a,b);a.rendered&&a.render();b.rendered&&(b.updateDisabled(),b.render(),b.getSvgRoot().style.display="block")}; +module$exports$Blockly$RenderedConnection.prototype.respawnShadow_=function(){module$exports$Blockly$RenderedConnection.superClass_.respawnShadow_.call(this);var a=this.targetBlock();a&&(a.initSvg(),a.render(!1),a=this.getSourceBlock(),a.rendered&&a.render())};module$exports$Blockly$RenderedConnection.prototype.neighbours=function(a){return this.dbOpposite_.getNeighbours(this,a)}; +module$exports$Blockly$RenderedConnection.prototype.connect_=function(a){module$exports$Blockly$RenderedConnection.superClass_.connect_.call(this,a);var b=this.getSourceBlock();a=a.getSourceBlock();var c=b.rendered,d=a.rendered;c&&b.updateDisabled();d&&a.updateDisabled();c&&d&&(this.type==module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT||this.type==module$exports$Blockly$ConnectionType.ConnectionType.PREVIOUS_STATEMENT?a.render():b.render());if(b=b.getInputWithBlock(a))b=b.isVisible(), +a.getSvgRoot().style.display=b?"block":"none"};module$exports$Blockly$RenderedConnection.prototype.onCheckChanged_=function(){!this.isConnected()||this.targetConnection&&this.getConnectionChecker().canConnect(this,this.targetConnection,!1)||((this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug(),this.sourceBlock_.bumpNeighbours())};var module$exports$Blockly$ASTNode={ASTNode:function(a,b,c){if(!b)throw Error("Cannot create a node without a location.");this.type_=a;this.isConnection_=module$exports$Blockly$ASTNode.ASTNode.isConnectionType_(a);this.location_=b;this.wsCoordinate_=null;this.processParams_(c||null)}};module$exports$Blockly$ASTNode.ASTNode.types={FIELD:"field",BLOCK:"block",INPUT:"input",OUTPUT:"output",NEXT:"next",PREVIOUS:"previous",STACK:"stack",WORKSPACE:"workspace"}; +module$exports$Blockly$ASTNode.ASTNode.NAVIGATE_ALL_FIELDS=!1;module$exports$Blockly$ASTNode.ASTNode.DEFAULT_OFFSET_Y=-20;module$exports$Blockly$ASTNode.ASTNode.isConnectionType_=function(a){switch(a){case module$exports$Blockly$ASTNode.ASTNode.types.PREVIOUS:case module$exports$Blockly$ASTNode.ASTNode.types.NEXT:case module$exports$Blockly$ASTNode.ASTNode.types.INPUT:case module$exports$Blockly$ASTNode.ASTNode.types.OUTPUT:return!0}return!1}; +module$exports$Blockly$ASTNode.ASTNode.createFieldNode=function(a){return a?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.FIELD,a):null}; +module$exports$Blockly$ASTNode.ASTNode.createConnectionNode=function(a){if(!a)return null;var b=a.type;return b==module$exports$Blockly$ConnectionType.ConnectionType.INPUT_VALUE||b==module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT&&a.getParentInput()?module$exports$Blockly$ASTNode.ASTNode.createInputNode(a.getParentInput()):b==module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.NEXT, +a):b==module$exports$Blockly$ConnectionType.ConnectionType.OUTPUT_VALUE?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.OUTPUT,a):b==module$exports$Blockly$ConnectionType.ConnectionType.PREVIOUS_STATEMENT?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.PREVIOUS,a):null}; +module$exports$Blockly$ASTNode.ASTNode.createInputNode=function(a){return a&&a.connection?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.INPUT,a.connection):null};module$exports$Blockly$ASTNode.ASTNode.createBlockNode=function(a){return a?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.BLOCK,a):null}; +module$exports$Blockly$ASTNode.ASTNode.createStackNode=function(a){return a?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.STACK,a):null};module$exports$Blockly$ASTNode.ASTNode.createWorkspaceNode=function(a,b){return b&&a?new module$exports$Blockly$ASTNode.ASTNode(module$exports$Blockly$ASTNode.ASTNode.types.WORKSPACE,a,{wsCoordinate:b}):null}; +module$exports$Blockly$ASTNode.ASTNode.createTopNode=function(a){var b=a.previousConnection||a.outputConnection;return b?module$exports$Blockly$ASTNode.ASTNode.createConnectionNode(b):module$exports$Blockly$ASTNode.ASTNode.createBlockNode(a)};module$exports$Blockly$ASTNode.ASTNode.prototype.processParams_=function(a){a&&a.wsCoordinate&&(this.wsCoordinate_=a.wsCoordinate)};module$exports$Blockly$ASTNode.ASTNode.prototype.getLocation=function(){return this.location_}; +module$exports$Blockly$ASTNode.ASTNode.prototype.getType=function(){return this.type_};module$exports$Blockly$ASTNode.ASTNode.prototype.getWsCoordinate=function(){return this.wsCoordinate_};module$exports$Blockly$ASTNode.ASTNode.prototype.isConnection=function(){return this.isConnection_}; +module$exports$Blockly$ASTNode.ASTNode.prototype.findNextForInput_=function(){var a=this.location_.getParentInput(),b=a.getSourceBlock();for(a=b.inputList.indexOf(a)+1;aa||a>this.fieldRow.length)throw Error("index "+a+" out of bounds.");if(!(b||""==b&&c))return a;"string"==typeof b&&(b=(0,module$exports$Blockly$fieldRegistry.fromJson)({type:"field_label",text:b}));b.setSourceBlock(this.sourceBlock_);this.sourceBlock_.rendered&&(b.init(),b.applyColour());b.name=c;b.setVisible(this.isVisible());b.prefixField&&(a=this.insertFieldAt(a,b.prefixField));this.fieldRow.splice(a,0,b);++a;b.suffixField&& +(a=this.insertFieldAt(a,b.suffixField));this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours());return a}; +module$exports$Blockly$Input.prototype.removeField=function(a,b){for(var c=0,d;d=this.fieldRow[c];c++)if(d.name===a)return d.dispose(),this.fieldRow.splice(c,1),this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours()),!0;if(b)return!1;throw Error('Field "'+a+'" not found.');};module$exports$Blockly$Input.prototype.isVisible=function(){return this.visible_}; +module$exports$Blockly$Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;this.visible_=a;for(var c=0,d;d=this.fieldRow[c];c++)d.setVisible(a);this.connection&&(this.connection=this.connection,a?b=this.connection.startTrackingAll():this.connection.stopTrackingAll(),c=this.connection.targetBlock())&&(c.getSvgRoot().style.display=a?"block":"none");return b};module$exports$Blockly$Input.prototype.markDirty=function(){for(var a=0,b;b=this.fieldRow[a];a++)b.markDirty()}; +module$exports$Blockly$Input.prototype.setCheck=function(a){if(!this.connection)throw Error("This input does not have a connection.");this.connection.setCheck(a);return this};module$exports$Blockly$Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&(this.sourceBlock_=this.sourceBlock_,this.sourceBlock_.render());return this}; +module$exports$Blockly$Input.prototype.setShadowDom=function(a){if(!this.connection)throw Error("This input does not have a connection.");this.connection.setShadowDom(a);return this};module$exports$Blockly$Input.prototype.getShadowDom=function(){if(!this.connection)throw Error("This input does not have a connection.");return this.connection.getShadowDom()};module$exports$Blockly$Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;aa&&(e=e.substring(0,a-3)+"...");return e};module$exports$Blockly$Block.Block.prototype.appendValueInput=function(a){return this.appendInput_(module$exports$Blockly$inputTypes.VALUE,a)}; +module$exports$Blockly$Block.Block.prototype.appendStatementInput=function(a){return this.appendInput_(module$exports$Blockly$inputTypes.STATEMENT,a)};module$exports$Blockly$Block.Block.prototype.appendDummyInput=function(a){return this.appendInput_(module$exports$Blockly$inputTypes.DUMMY,a||"")}; +module$exports$Blockly$Block.Block.prototype.jsonInit=function(a){var b=a.type?'Block "'+a.type+'": ':"";if(a.output&&a.previousStatement)throw Error(b+"Must not have both an output and a previousStatement.");a.style&&a.style.hat&&(this.hat=a.style.hat,a.style=null);if(a.style&&a.colour)throw Error(b+"Must not have both a colour and a style.");a.style?this.jsonInitStyle_(a,b):this.jsonInitColour_(a,b);for(var c=0;void 0!==a["message"+c];)this.interpolate_(a["message"+c],a["args"+c]||[],a["lastDummyAlign"+ +c],b),c++;void 0!==a.inputsInline&&this.setInputsInline(a.inputsInline);void 0!==a.output&&this.setOutput(!0,a.output);void 0!==a.outputShape&&this.setOutputShape(a.outputShape);void 0!==a.previousStatement&&this.setPreviousStatement(!0,a.previousStatement);void 0!==a.nextStatement&&this.setNextStatement(!0,a.nextStatement);void 0!==a.tooltip&&(c=(0,module$exports$Blockly$utils.replaceMessageReferences)(a.tooltip),this.setTooltip(c));void 0!==a.enableContextMenu&&(this.contextMenu=!!a.enableContextMenu); +void 0!==a.suppressPrefixSuffix&&(this.suppressPrefixSuffix=!!a.suppressPrefixSuffix);void 0!==a.helpUrl&&(c=(0,module$exports$Blockly$utils.replaceMessageReferences)(a.helpUrl),this.setHelpUrl(c));"string"==typeof a.extensions&&(console.warn(b+"JSON attribute 'extensions' should be an array of strings. Found raw string in JSON for '"+a.type+"' block."),a.extensions=[a.extensions]);void 0!==a.mutator&&(0,module$exports$Blockly$Extensions.apply)(a.mutator,this,!0);a=a.extensions;if(Array.isArray(a))for(b= +0;bf||f>b)throw Error('Block "'+this.type+'": Message index %'+f+" out of range.");if(c[f])throw Error('Block "'+this.type+'": Message index %'+f+" duplicated.");c[f]=!0;d++}}if(d!=b)throw Error('Block "'+this.type+'": Message does not reference all '+b+" arg(s).");}; +module$exports$Blockly$Block.Block.prototype.interpolateArguments_=function(a,b,c){for(var d=[],e=0;e=this.inputList.length)throw RangeError("Input index "+a+" out of bounds.");if(b>this.inputList.length)throw RangeError("Reference input "+b+" out of bounds.");var c=this.inputList[a];this.inputList.splice(a,1);a=a&&this.sourceBlock_.outputConnection&&!b}else this.fullBlockClickTarget_=!1;this.fullBlockClickTarget_?this.clickTarget_=this.sourceBlock_.getSvgRoot():this.createBorderRect_();this.createTextElement_()}; +module$exports$Blockly$FieldTextInput.prototype.doClassValidation_=function(a){return null===a||void 0===a?null:String(a)}; +module$exports$Blockly$FieldTextInput.prototype.doValueInvalid_=function(a){this.isBeingEdited_&&(this.isTextValid_=!1,a=this.value_,this.value_=this.htmlInput_.untypedDefaultValue_,this.sourceBlock_&&(0,module$exports$Blockly$Events$utils.isEnabled)()&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CHANGE))(this.sourceBlock_,"field",this.name||null,a,this.value_)))}; +module$exports$Blockly$FieldTextInput.prototype.doValueUpdate_=function(a){this.isTextValid_=!0;this.value_=a;this.isBeingEdited_||(this.isDirty_=!0)};module$exports$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))}; +module$exports$Blockly$FieldTextInput.prototype.render_=function(){module$exports$Blockly$FieldTextInput.superClass_.render_.call(this);if(this.isBeingEdited_){this.resizeEditor_();var a=this.htmlInput_;this.isTextValid_?((0,module$exports$Blockly$utils$dom.removeClass)(a,"blocklyInvalidInput"),(0,module$exports$Blockly$utils$aria.setState)(a,module$exports$Blockly$utils$aria.State.INVALID,!1)):((0,module$exports$Blockly$utils$dom.addClass)(a,"blocklyInvalidInput"),(0,module$exports$Blockly$utils$aria.setState)(a, +module$exports$Blockly$utils$aria.State.INVALID,!0))}};module$exports$Blockly$FieldTextInput.prototype.setSpellcheck=function(a){a!=this.spellcheck_&&(this.spellcheck_=a,this.htmlInput_&&this.htmlInput_.setAttribute("spellcheck",this.spellcheck_))}; +module$exports$Blockly$FieldTextInput.prototype.showEditor_=function(a,b){this.workspace_=this.sourceBlock_.workspace;a=b||!1;!a&&(module$exports$Blockly$utils$userAgent.MOBILE||module$exports$Blockly$utils$userAgent.ANDROID||module$exports$Blockly$utils$userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};module$exports$Blockly$FieldTextInput.prototype.showPromptEditor_=function(){(0,module$exports$Blockly$dialog.prompt)(Blockly.Msg.CHANGE_VALUE_TITLE,this.getText(),function(a){this.setValue(this.getValueFromEditorText_(a))}.bind(this))}; +module$exports$Blockly$FieldTextInput.prototype.showInlineEditor_=function(a){(0,module$exports$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())}; +module$exports$Blockly$FieldTextInput.prototype.widgetCreate_=function(){(0,module$exports$Blockly$Events$utils.setGroup)(!0);var a=(0,module$exports$Blockly$WidgetDiv.getDiv)();(0,module$exports$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=module$exports$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) 0 0 0 "+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}; +module$exports$Blockly$FieldTextInput.prototype.widgetDispose_=function(){this.isBeingEdited_=!1;this.isTextValid_=!0;this.forceRerender();if(this.onFinishEditing_)this.onFinishEditing_(this.value_);(0,module$exports$Blockly$Events$utils.setGroup)(!1);this.unbindInputEvents_();var a=(0,module$exports$Blockly$WidgetDiv.getDiv)().style;a.width="auto";a.height="auto";a.fontSize="";a.transition="";a.boxShadow="";this.htmlInput_=null;(0,module$exports$Blockly$utils$dom.removeClass)(this.getClickTarget_(), +"editing")};module$exports$Blockly$FieldTextInput.prototype.bindInputEvents_=function(a){this.onKeyDownWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(a,"keydown",this,this.onHtmlInputKeyDown_);this.onKeyInputWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(a,"input",this,this.onHtmlInputChange_)}; +module$exports$Blockly$FieldTextInput.prototype.unbindInputEvents_=function(){this.onKeyDownWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onKeyDownWrapper_),this.onKeyDownWrapper_=null);this.onKeyInputWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onKeyInputWrapper_),this.onKeyInputWrapper_=null)}; +module$exports$Blockly$FieldTextInput.prototype.onHtmlInputKeyDown_=function(a){a.keyCode==module$exports$Blockly$utils$KeyCodes.ENTER?((0,module$exports$Blockly$WidgetDiv.hide)(),module$exports$Blockly$DropDownDiv.hideWithoutAnimation()):a.keyCode==module$exports$Blockly$utils$KeyCodes.ESC?(this.setValue(this.htmlInput_.untypedDefaultValue_),(0,module$exports$Blockly$WidgetDiv.hide)(),module$exports$Blockly$DropDownDiv.hideWithoutAnimation()):a.keyCode==module$exports$Blockly$utils$KeyCodes.TAB&& +((0,module$exports$Blockly$WidgetDiv.hide)(),module$exports$Blockly$DropDownDiv.hideWithoutAnimation(),this.sourceBlock_.tab(this,!a.shiftKey),a.preventDefault())};module$exports$Blockly$FieldTextInput.prototype.onHtmlInputChange_=function(a){a=this.htmlInput_.value;a!==this.htmlInput_.oldValue_&&(this.htmlInput_.oldValue_=a,a=this.getValueFromEditorText_(a),this.setValue(a),this.forceRerender(),this.resizeEditor_())}; +module$exports$Blockly$FieldTextInput.prototype.setEditorValue_=function(a){this.isDirty_=!0;this.isBeingEdited_&&(this.htmlInput_.value=this.getEditorText_(a));this.setValue(a)}; +module$exports$Blockly$FieldTextInput.prototype.resizeEditor_=function(){var a=(0,module$exports$Blockly$WidgetDiv.getDiv)(),b=this.getScaledBBox();a.style.width=b.right-b.left+"px";a.style.height=b.bottom-b.top+"px";b=new module$exports$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"};module$exports$Blockly$FieldTextInput.prototype.isTabNavigable=function(){return!0}; +module$exports$Blockly$FieldTextInput.prototype.getText_=function(){return this.isBeingEdited_&&this.htmlInput_?this.htmlInput_.value:null};module$exports$Blockly$FieldTextInput.prototype.getEditorText_=function(a){return String(a)};module$exports$Blockly$FieldTextInput.prototype.getValueFromEditorText_=function(a){return a};(0,module$exports$Blockly$fieldRegistry.register)("field_input",module$exports$Blockly$FieldTextInput);var module$exports$Blockly$FieldAngle=function(a,b,c){this.clockwise_=module$exports$Blockly$FieldAngle.CLOCKWISE;this.offset_=module$exports$Blockly$FieldAngle.OFFSET;this.wrap_=module$exports$Blockly$FieldAngle.WRAP;this.round_=module$exports$Blockly$FieldAngle.ROUND;module$exports$Blockly$FieldAngle.superClass_.constructor.call(this,a,b,c);this.moveSurfaceWrapper_=this.clickSurfaceWrapper_=this.clickWrapper_=this.line_=this.gauge_=this.editor_=null}; +(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldAngle,module$exports$Blockly$FieldTextInput);module$exports$Blockly$FieldAngle.prototype.DEFAULT_VALUE=0;module$exports$Blockly$FieldAngle.fromJson=function(a){return new this(a.angle,void 0,a)};module$exports$Blockly$FieldAngle.prototype.SERIALIZABLE=!0;module$exports$Blockly$FieldAngle.ROUND=15;module$exports$Blockly$FieldAngle.HALF=50;module$exports$Blockly$FieldAngle.CLOCKWISE=!1; +module$exports$Blockly$FieldAngle.OFFSET=0;module$exports$Blockly$FieldAngle.WRAP=360;module$exports$Blockly$FieldAngle.RADIUS=module$exports$Blockly$FieldAngle.HALF-1; +module$exports$Blockly$FieldAngle.prototype.configure_=function(a){module$exports$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))}; +module$exports$Blockly$FieldAngle.prototype.initView=function(){module$exports$Blockly$FieldAngle.superClass_.initView.call(this);this.symbol_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.TSPAN,{},null);this.symbol_.appendChild(document.createTextNode("\u00b0"));this.textElement_.appendChild(this.symbol_)};module$exports$Blockly$FieldAngle.prototype.render_=function(){module$exports$Blockly$FieldAngle.superClass_.render_.call(this);this.updateGraph_()}; +module$exports$Blockly$FieldAngle.prototype.showEditor_=function(a){module$exports$Blockly$FieldAngle.superClass_.showEditor_.call(this,a,module$exports$Blockly$utils$userAgent.MOBILE||module$exports$Blockly$utils$userAgent.ANDROID||module$exports$Blockly$utils$userAgent.IPAD);this.dropdownCreate_();module$exports$Blockly$DropDownDiv.getContentDiv().appendChild(this.editor_);module$exports$Blockly$DropDownDiv.setColour(this.sourceBlock_.style.colourPrimary,this.sourceBlock_.style.colourTertiary); +module$exports$Blockly$DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.updateGraph_()}; +module$exports$Blockly$FieldAngle.prototype.dropdownCreate_=function(){var a=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.SVG,{xmlns:module$exports$Blockly$utils$dom.SVG_NS,"xmlns:html":module$exports$Blockly$utils$dom.HTML_NS,"xmlns:xlink":module$exports$Blockly$utils$dom.XLINK_NS,version:"1.1",height:2*module$exports$Blockly$FieldAngle.HALF+"px",width:2*module$exports$Blockly$FieldAngle.HALF+"px",style:"touch-action: none"},null),b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE, +{cx:module$exports$Blockly$FieldAngle.HALF,cy:module$exports$Blockly$FieldAngle.HALF,r:module$exports$Blockly$FieldAngle.RADIUS,"class":"blocklyAngleCircle"},a);this.gauge_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.PATH,{"class":"blocklyAngleGauge"},a);this.line_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE,{x1:module$exports$Blockly$FieldAngle.HALF,y1:module$exports$Blockly$FieldAngle.HALF,"class":"blocklyAngleLine"}, +a);for(var c=0;360>c;c+=15)(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE,{x1:module$exports$Blockly$FieldAngle.HALF+module$exports$Blockly$FieldAngle.RADIUS,y1:module$exports$Blockly$FieldAngle.HALF,x2:module$exports$Blockly$FieldAngle.HALF+module$exports$Blockly$FieldAngle.RADIUS-(0==c%45?10:5),y2:module$exports$Blockly$FieldAngle.HALF,"class":"blocklyAngleMarks",transform:"rotate("+c+","+module$exports$Blockly$FieldAngle.HALF+","+module$exports$Blockly$FieldAngle.HALF+ +")"},a);this.clickWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(a,"click",this,this.hide_);this.clickSurfaceWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"click",this,this.onMouseMove_,!0,!0);this.moveSurfaceWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"mousemove",this,this.onMouseMove_,!0,!0);this.editor_=a}; +module$exports$Blockly$FieldAngle.prototype.dropdownDispose_=function(){this.clickWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.clickWrapper_),this.clickWrapper_=null);this.clickSurfaceWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.clickSurfaceWrapper_),this.clickSurfaceWrapper_=null);this.moveSurfaceWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.moveSurfaceWrapper_),this.moveSurfaceWrapper_=null);this.line_=this.gauge_=null}; +module$exports$Blockly$FieldAngle.prototype.hide_=function(){module$exports$Blockly$DropDownDiv.hideIfOwner(this);(0,module$exports$Blockly$WidgetDiv.hide)()}; +module$exports$Blockly$FieldAngle.prototype.onMouseMove_=function(a){var b=this.gauge_.ownerSVGElement.getBoundingClientRect(),c=a.clientX-b.left-module$exports$Blockly$FieldAngle.HALF;a=a.clientY-b.top-module$exports$Blockly$FieldAngle.HALF;b=Math.atan(-a/c);isNaN(b)||(b=(0,module$exports$Blockly$utils$math.toDegrees)(b),0>c?b+=180:0a&&(a+=360);a>this.wrap_&&(a-=360);return a}; +(0,module$exports$Blockly$Css.register)([".blocklyAngleCircle {\n stroke: #444;\n stroke-width: 1;\n fill: #ddd;\n fill-opacity: .8;\n}",".blocklyAngleMarks {\n stroke: #444;\n stroke-width: 1;\n}",".blocklyAngleGauge {\n fill: #f88;\n fill-opacity: .8;\n pointer-events: none;\n}",".blocklyAngleLine {\n stroke: #f00;\n stroke-width: 2;\n stroke-linecap: round;\n pointer-events: none;\n}"]);(0,module$exports$Blockly$fieldRegistry.register)("field_angle",module$exports$Blockly$FieldAngle);var module$exports$Blockly$FieldCheckbox=function(a,b,c){this.checkChar_=null;module$exports$Blockly$FieldCheckbox.superClass_.constructor.call(this,a,b,c)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldCheckbox,module$exports$Blockly$Field);module$exports$Blockly$FieldCheckbox.prototype.DEFAULT_VALUE=!1;module$exports$Blockly$FieldCheckbox.fromJson=function(a){return new this(a.checked,void 0,a)};module$exports$Blockly$FieldCheckbox.CHECK_CHAR="\u2713"; +module$exports$Blockly$FieldCheckbox.prototype.SERIALIZABLE=!0;module$exports$Blockly$FieldCheckbox.prototype.CURSOR="default";module$exports$Blockly$FieldCheckbox.prototype.configure_=function(a){module$exports$Blockly$FieldCheckbox.superClass_.configure_.call(this,a);a.checkCharacter&&(this.checkChar_=a.checkCharacter)};module$exports$Blockly$FieldCheckbox.prototype.saveState=function(){var a=this.saveLegacyState(module$exports$Blockly$FieldCheckbox);return null!==a?a:this.getValueBoolean()}; +module$exports$Blockly$FieldCheckbox.prototype.initView=function(){module$exports$Blockly$FieldCheckbox.superClass_.initView.call(this);(0,module$exports$Blockly$utils$dom.addClass)(this.textElement_,"blocklyCheckbox");this.textElement_.style.display=this.value_?"block":"none"};module$exports$Blockly$FieldCheckbox.prototype.render_=function(){this.textContent_&&(this.textContent_.nodeValue=this.getDisplayText_());this.updateSize_(this.getConstants().FIELD_CHECKBOX_X_OFFSET)}; +module$exports$Blockly$FieldCheckbox.prototype.getDisplayText_=function(){return this.checkChar_||module$exports$Blockly$FieldCheckbox.CHECK_CHAR};module$exports$Blockly$FieldCheckbox.prototype.setCheckCharacter=function(a){this.checkChar_=a;this.forceRerender()};module$exports$Blockly$FieldCheckbox.prototype.showEditor_=function(){this.setValue(!this.value_)}; +module$exports$Blockly$FieldCheckbox.prototype.doClassValidation_=function(a){return!0===a||"TRUE"===a?"TRUE":!1===a||"FALSE"===a?"FALSE":null};module$exports$Blockly$FieldCheckbox.prototype.doValueUpdate_=function(a){this.value_=this.convertValueToBool_(a);this.textElement_&&(this.textElement_.style.display=this.value_?"block":"none")};module$exports$Blockly$FieldCheckbox.prototype.getValue=function(){return this.value_?"TRUE":"FALSE"}; +module$exports$Blockly$FieldCheckbox.prototype.getValueBoolean=function(){return this.value_};module$exports$Blockly$FieldCheckbox.prototype.getText=function(){return String(this.convertValueToBool_(this.value_))};module$exports$Blockly$FieldCheckbox.prototype.convertValueToBool_=function(a){return"string"==typeof a?"TRUE"==a:!!a};(0,module$exports$Blockly$fieldRegistry.register)("field_checkbox",module$exports$Blockly$FieldCheckbox);var module$exports$Blockly$FieldColour=function(a,b,c){module$exports$Blockly$FieldColour.superClass_.constructor.call(this,a,b,c);this.onKeyDownWrapper_=this.onMouseLeaveWrapper_=this.onMouseEnterWrapper_=this.onMouseMoveWrapper_=this.onClickWrapper_=this.highlightedIndex_=this.picker_=null};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldColour,module$exports$Blockly$Field);module$exports$Blockly$FieldColour.fromJson=function(a){return new this(a.colour,void 0,a)}; +module$exports$Blockly$FieldColour.prototype.SERIALIZABLE=!0;module$exports$Blockly$FieldColour.prototype.CURSOR="default";module$exports$Blockly$FieldColour.prototype.isDirty_=!1;module$exports$Blockly$FieldColour.prototype.colours_=null;module$exports$Blockly$FieldColour.prototype.titles_=null;module$exports$Blockly$FieldColour.prototype.columns_=0; +module$exports$Blockly$FieldColour.prototype.configure_=function(a){module$exports$Blockly$FieldColour.superClass_.configure_.call(this,a);a.colourOptions&&(this.colours_=a.colourOptions,this.titles_=a.colourTitles);a.columns&&(this.columns_=a.columns)}; +module$exports$Blockly$FieldColour.prototype.initView=function(){this.size_=new module$exports$Blockly$utils$Size(this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);this.getConstants().FIELD_COLOUR_FULL_BLOCK?this.clickTarget_=this.sourceBlock_.getSvgRoot():(this.createBorderRect_(),this.borderRect_.style.fillOpacity="1")}; +module$exports$Blockly$FieldColour.prototype.applyColour=function(){this.getConstants().FIELD_COLOUR_FULL_BLOCK?(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",this.getValue()),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff")):this.borderRect_&&(this.borderRect_.style.fill=this.getValue())};module$exports$Blockly$FieldColour.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:(0,module$exports$Blockly$utils$colour.parse)(a)}; +module$exports$Blockly$FieldColour.prototype.doValueUpdate_=function(a){this.value_=a;this.borderRect_?this.borderRect_.style.fill=a:this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.pathObject.svgPath.setAttribute("fill",a),this.sourceBlock_.pathObject.svgPath.setAttribute("stroke","#fff"))};module$exports$Blockly$FieldColour.prototype.getText=function(){var a=this.value_;/^#(.)\1(.)\2(.)\3$/.test(a)&&(a="#"+a[1]+a[3]+a[5]);return a};module$exports$Blockly$FieldColour.COLOURS="#ffffff #cccccc #c0c0c0 #999999 #666666 #333333 #000000 #ffcccc #ff6666 #ff0000 #cc0000 #990000 #660000 #330000 #ffcc99 #ff9966 #ff9900 #ff6600 #cc6600 #993300 #663300 #ffff99 #ffff66 #ffcc66 #ffcc33 #cc9933 #996633 #663333 #ffffcc #ffff33 #ffff00 #ffcc00 #999900 #666600 #333300 #99ff99 #66ff99 #33ff33 #33cc00 #009900 #006600 #003300 #99ffff #33ffff #66cccc #00cccc #339999 #336666 #003333 #ccffff #66ffff #33ccff #3366ff #3333ff #000099 #000066 #ccccff #9999ff #6666cc #6633ff #6600cc #333399 #330099 #ffccff #ff99ff #cc66cc #cc33cc #993399 #663366 #330033".split(" "); +module$exports$Blockly$FieldColour.prototype.DEFAULT_VALUE=module$exports$Blockly$FieldColour.COLOURS[0];module$exports$Blockly$FieldColour.TITLES=[];module$exports$Blockly$FieldColour.COLUMNS=7;module$exports$Blockly$FieldColour.prototype.setColours=function(a,b){this.colours_=a;b&&(this.titles_=b);return this};module$exports$Blockly$FieldColour.prototype.setColumns=function(a){this.columns_=a;return this}; +module$exports$Blockly$FieldColour.prototype.showEditor_=function(){this.dropdownCreate_();module$exports$Blockly$DropDownDiv.getContentDiv().appendChild(this.picker_);module$exports$Blockly$DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.picker_.focus({preventScroll:!0})};module$exports$Blockly$FieldColour.prototype.onClick_=function(a){a=(a=a.target)&&a.label;null!==a&&(this.setValue(a),module$exports$Blockly$DropDownDiv.hideIfOwner(this))}; +module$exports$Blockly$FieldColour.prototype.onKeyDown_=function(a){var b=!1;if(a.keyCode===module$exports$Blockly$utils$KeyCodes.UP)this.moveHighlightBy_(0,-1),b=!0;else if(a.keyCode===module$exports$Blockly$utils$KeyCodes.DOWN)this.moveHighlightBy_(0,1),b=!0;else if(a.keyCode===module$exports$Blockly$utils$KeyCodes.LEFT)this.moveHighlightBy_(-1,0),b=!0;else if(a.keyCode===module$exports$Blockly$utils$KeyCodes.RIGHT)this.moveHighlightBy_(1,0),b=!0;else if(a.keyCode===module$exports$Blockly$utils$KeyCodes.ENTER){if(b= +this.getHighlighted_())b=b&&b.label,null!==b&&this.setValue(b);module$exports$Blockly$DropDownDiv.hideWithoutAnimation();b=!0}b&&a.stopPropagation()}; +module$exports$Blockly$FieldColour.prototype.moveHighlightBy_=function(a,b){var c=this.colours_||module$exports$Blockly$FieldColour.COLOURS,d=this.columns_||module$exports$Blockly$FieldColour.COLUMNS,e=this.highlightedIndex_%d,f=Math.floor(this.highlightedIndex_/d);e+=a;f+=b;0>a?0>e&&0e&&(e=0):0d-1&&fd-1&&e--:0>b?0>f&&(f=0):0Math.floor(c.length/d)-1&&(f=Math.floor(c.length/d)-1);this.setHighlightedCell_(this.picker_.childNodes[f].childNodes[e], +f*d+e)};module$exports$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)};module$exports$Blockly$FieldColour.prototype.onMouseEnter_=function(){this.picker_.focus({preventScroll:!0})};module$exports$Blockly$FieldColour.prototype.onMouseLeave_=function(){this.picker_.blur();var a=this.getHighlighted_();a&&(0,module$exports$Blockly$utils$dom.removeClass)(a,"blocklyColourHighlighted")}; +module$exports$Blockly$FieldColour.prototype.getHighlighted_=function(){var a=this.columns_||module$exports$Blockly$FieldColour.COLUMNS,b=this.picker_.childNodes[Math.floor(this.highlightedIndex_/a)];return b?b.childNodes[this.highlightedIndex_%a]:null}; +module$exports$Blockly$FieldColour.prototype.setHighlightedCell_=function(a,b){var c=this.getHighlighted_();c&&(0,module$exports$Blockly$utils$dom.removeClass)(c,"blocklyColourHighlighted");(0,module$exports$Blockly$utils$dom.addClass)(a,"blocklyColourHighlighted");this.highlightedIndex_=b;(0,module$exports$Blockly$utils$aria.setState)(this.picker_,module$exports$Blockly$utils$aria.State.ACTIVEDESCENDANT,a.getAttribute("id"))}; +module$exports$Blockly$FieldColour.prototype.dropdownCreate_=function(){var a=this.columns_||module$exports$Blockly$FieldColour.COLUMNS,b=this.colours_||module$exports$Blockly$FieldColour.COLOURS,c=this.titles_||module$exports$Blockly$FieldColour.TITLES,d=this.getValue(),e=document.createElement("table");e.className="blocklyColourTable";e.tabIndex=0;e.dir="ltr";(0,module$exports$Blockly$utils$aria.setRole)(e,module$exports$Blockly$utils$aria.Role.GRID);(0,module$exports$Blockly$utils$aria.setState)(e, +module$exports$Blockly$utils$aria.State.EXPANDED,!0);(0,module$exports$Blockly$utils$aria.setState)(e,module$exports$Blockly$utils$aria.State.ROWCOUNT,Math.floor(b.length/a));(0,module$exports$Blockly$utils$aria.setState)(e,module$exports$Blockly$utils$aria.State.COLCOUNT,a);for(var f,g=0;gtr>td {","border: .5px solid #888;","box-sizing: border-box;","cursor: pointer;","display: inline-block;","height: 20px;","padding: 0;","width: 20px;","}",".blocklyColourTable>tr>td.blocklyColourHighlighted {","border-color: #eee;","box-shadow: 2px 2px 7px 2px rgba(0,0,0,.3);","position: relative;","}",".blocklyColourSelected, .blocklyColourSelected:hover {", +"border-color: #eee !important;","outline: 1px solid #333;","position: relative;","}"]);(0,module$exports$Blockly$fieldRegistry.register)("field_colour",module$exports$Blockly$FieldColour);var module$exports$Blockly$FieldDropdown=function(a,b,c){"function"!=typeof a&&module$contents$Blockly$FieldDropdown_validateOptions(a);this.menuGenerator_=a;this.suffixField=this.prefixField=this.generatedOptions_=null;this.trimOptions_();this.selectedOption_=this.getOptions(!1)[0];module$exports$Blockly$FieldDropdown.superClass_.constructor.call(this,this.selectedOption_[1],b,c);this.svgArrow_=this.arrow_=this.imageElement_=this.menu_=this.selectedMenuItem_=null}; +(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldDropdown,module$exports$Blockly$Field);module$exports$Blockly$FieldDropdown.fromJson=function(a){return new this(a.options,void 0,a)};module$exports$Blockly$FieldDropdown.prototype.fromXml=function(a){this.isOptionListDynamic()&&this.getOptions(!1);this.setValue(a.textContent)}; +module$exports$Blockly$FieldDropdown.prototype.loadState=function(a){this.loadLegacyState(module$exports$Blockly$FieldDropdown,a)||(this.isOptionListDynamic()&&this.getOptions(!1),this.setValue(a))};module$exports$Blockly$FieldDropdown.prototype.SERIALIZABLE=!0;module$exports$Blockly$FieldDropdown.CHECKMARK_OVERHANG=25;module$exports$Blockly$FieldDropdown.MAX_MENU_HEIGHT_VH=.45;var module$contents$Blockly$FieldDropdown_IMAGE_Y_OFFSET=5,module$contents$Blockly$FieldDropdown_IMAGE_Y_PADDING=2*module$contents$Blockly$FieldDropdown_IMAGE_Y_OFFSET; +module$exports$Blockly$FieldDropdown.ARROW_CHAR=module$exports$Blockly$utils$userAgent.ANDROID?"\u25bc":"\u25be";module$exports$Blockly$FieldDropdown.prototype.CURSOR="default"; +module$exports$Blockly$FieldDropdown.prototype.initView=function(){this.shouldAddBorderRect_()?this.createBorderRect_():this.clickTarget_=this.sourceBlock_.getSvgRoot();this.createTextElement_();this.imageElement_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE,{},this.fieldGroup_);this.getConstants().FIELD_DROPDOWN_SVG_ARROW?this.createSVGArrow_():this.createTextArrow_();this.borderRect_&&(0,module$exports$Blockly$utils$dom.addClass)(this.borderRect_, +"blocklyDropdownRect")};module$exports$Blockly$FieldDropdown.prototype.shouldAddBorderRect_=function(){return!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW&&!this.sourceBlock_.isShadow()}; +module$exports$Blockly$FieldDropdown.prototype.createTextArrow_=function(){this.arrow_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.TSPAN,{},this.textElement_);this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL?module$exports$Blockly$FieldDropdown.ARROW_CHAR+" ":" "+module$exports$Blockly$FieldDropdown.ARROW_CHAR));this.sourceBlock_.RTL?this.textElement_.insertBefore(this.arrow_,this.textContent_):this.textElement_.appendChild(this.arrow_)}; +module$exports$Blockly$FieldDropdown.prototype.createSVGArrow_=function(){this.svgArrow_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE,{height:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px",width:this.getConstants().FIELD_DROPDOWN_SVG_ARROW_SIZE+"px"},this.fieldGroup_);this.svgArrow_.setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.getConstants().FIELD_DROPDOWN_SVG_ARROW_DATAURI)}; +module$exports$Blockly$FieldDropdown.prototype.showEditor_=function(a){this.dropdownCreate_();this.menu_.openingCoords=a&&"number"===typeof a.clientX?new module$exports$Blockly$utils$Coordinate(a.clientX,a.clientY):null;this.menu_.render(module$exports$Blockly$DropDownDiv.getContentDiv());a=this.menu_.getElement();(0,module$exports$Blockly$utils$dom.addClass)(a,"blocklyDropdownMenu");if(this.getConstants().FIELD_DROPDOWN_COLOURED_DIV){a=this.sourceBlock_.isShadow()?this.sourceBlock_.getParent().getColour(): +this.sourceBlock_.getColour();var b=this.sourceBlock_.isShadow()?this.sourceBlock_.getParent().style.colourTertiary:this.sourceBlock_.style.colourTertiary;module$exports$Blockly$DropDownDiv.setColour(a,b)}module$exports$Blockly$DropDownDiv.showPositionedByField(this,this.dropdownDispose_.bind(this));this.menu_.focus();this.selectedMenuItem_&&this.menu_.setHighlighted(this.selectedMenuItem_);this.applyColour()}; +module$exports$Blockly$FieldDropdown.prototype.dropdownCreate_=function(){var a=new module$exports$Blockly$Menu;a.setRole(module$exports$Blockly$utils$aria.Role.LISTBOX);this.menu_=a;var b=this.getOptions(!1);this.selectedMenuItem_=null;for(var c=0;ca.length)){b=[];for(c=0;c=c||0>=b)throw Error("Height and width values of an image field must be greater than 0."); +this.flipRtl_=!1;this.altText_="";module$exports$Blockly$FieldImage.superClass_.constructor.call(this,a,null,g);g||(this.flipRtl_=!!f,this.altText_=(0,module$exports$Blockly$utils.replaceMessageReferences)(d)||"");this.size_=new module$exports$Blockly$utils$Size(b,c+module$exports$Blockly$FieldImage.Y_PADDING);this.imageHeight_=c;this.clickHandler_=null;"function"==typeof e&&(this.clickHandler_=e);this.imageElement_=null}; +(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldImage,module$exports$Blockly$Field);module$exports$Blockly$FieldImage.prototype.DEFAULT_VALUE="";module$exports$Blockly$FieldImage.fromJson=function(a){return new this(a.src,a.width,a.height,void 0,void 0,void 0,a)};module$exports$Blockly$FieldImage.Y_PADDING=1;module$exports$Blockly$FieldImage.prototype.EDITABLE=!1;module$exports$Blockly$FieldImage.prototype.isDirty_=!1; +module$exports$Blockly$FieldImage.prototype.configure_=function(a){module$exports$Blockly$FieldImage.superClass_.configure_.call(this,a);this.flipRtl_=!!a.flipRtl;this.altText_=(0,module$exports$Blockly$utils.replaceMessageReferences)(a.alt)||""}; +module$exports$Blockly$FieldImage.prototype.initView=function(){this.imageElement_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE,{height:this.imageHeight_+"px",width:this.size_.width+"px",alt:this.altText_},this.fieldGroup_);this.imageElement_.setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.value_);this.clickHandler_&&(this.imageElement_.style.cursor="pointer")};module$exports$Blockly$FieldImage.prototype.updateSize_=function(){}; +module$exports$Blockly$FieldImage.prototype.doClassValidation_=function(a){return"string"!=typeof a?null:a};module$exports$Blockly$FieldImage.prototype.doValueUpdate_=function(a){this.value_=a;this.imageElement_&&this.imageElement_.setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",String(this.value_))};module$exports$Blockly$FieldImage.prototype.getFlipRtl=function(){return this.flipRtl_}; +module$exports$Blockly$FieldImage.prototype.setAlt=function(a){a!=this.altText_&&(this.altText_=a||"",this.imageElement_&&this.imageElement_.setAttribute("alt",this.altText_))};module$exports$Blockly$FieldImage.prototype.showEditor_=function(){this.clickHandler_&&this.clickHandler_(this)};module$exports$Blockly$FieldImage.prototype.setOnClickHandler=function(a){this.clickHandler_=a};module$exports$Blockly$FieldImage.prototype.getText_=function(){return this.altText_}; +(0,module$exports$Blockly$fieldRegistry.register)("field_image",module$exports$Blockly$FieldImage);var module$exports$Blockly$FieldLabelSerializable=function(a,b,c){module$exports$Blockly$FieldLabelSerializable.superClass_.constructor.call(this,a,b,c)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldLabelSerializable,module$exports$Blockly$FieldLabel);module$exports$Blockly$FieldLabelSerializable.fromJson=function(a){return new this((0,module$exports$Blockly$utils.replaceMessageReferences)(a.text),void 0,a)}; +module$exports$Blockly$FieldLabelSerializable.prototype.EDITABLE=!1;module$exports$Blockly$FieldLabelSerializable.prototype.SERIALIZABLE=!0;(0,module$exports$Blockly$fieldRegistry.register)("field_label_serializable",module$exports$Blockly$FieldLabelSerializable);var module$exports$Blockly$FieldMultilineInput=function(a,b,c){module$exports$Blockly$FieldMultilineInput.superClass_.constructor.call(this,a,b,c);this.textGroup_=null;this.maxLines_=Infinity;this.isOverflowedY_=!1};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldMultilineInput,module$exports$Blockly$FieldTextInput); +module$exports$Blockly$FieldMultilineInput.prototype.configure_=function(a){module$exports$Blockly$FieldMultilineInput.superClass_.configure_.call(this,a);a.maxLines&&this.setMaxLines(a.maxLines)};module$exports$Blockly$FieldMultilineInput.fromJson=function(a){return new this((0,module$exports$Blockly$utils.replaceMessageReferences)(a.text),void 0,a)};module$exports$Blockly$FieldMultilineInput.prototype.toXml=function(a){a.textContent=this.getValue().replace(/\n/g," ");return a}; +module$exports$Blockly$FieldMultilineInput.prototype.fromXml=function(a){this.setValue(a.textContent.replace(/ /g,"\n"))};module$exports$Blockly$FieldMultilineInput.prototype.saveState=function(){var a=this.saveLegacyState(module$exports$Blockly$FieldMultilineInput);return null!==a?a:this.getValue()};module$exports$Blockly$FieldMultilineInput.prototype.loadState=function(a){this.loadLegacyState(module$exports$Blockly$Field,a)||this.setValue(a)}; +module$exports$Blockly$FieldMultilineInput.prototype.initView=function(){this.createBorderRect_();this.textGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyEditableText"},this.fieldGroup_)}; +module$exports$Blockly$FieldMultilineInput.prototype.getDisplayText_=function(){var a=this.getText();if(!a)return module$exports$Blockly$Field.NBSP;var b=a.split("\n");a="";for(var c=this.isOverflowedY_?this.maxLines_:b.length,d=0;dthis.maxDisplayLength?e=e.substring(0,this.maxDisplayLength-4)+"...":this.isOverflowedY_&&d===c-1&&(e=e.substring(0,e.length-3)+"...");e=e.replace(/\s/g,module$exports$Blockly$Field.NBSP);a+=e;d!==c-1&&(a+="\n")}this.sourceBlock_.RTL&&(a+="\u200f"); +return a};module$exports$Blockly$FieldMultilineInput.prototype.doValueUpdate_=function(a){module$exports$Blockly$FieldMultilineInput.superClass_.doValueUpdate_.call(this,a);this.isOverflowedY_=this.value_.split("\n").length>this.maxLines_}; +module$exports$Blockly$FieldMultilineInput.prototype.render_=function(){for(var a;a=this.textGroup_.firstChild;)this.textGroup_.removeChild(a);a=this.getDisplayText_().split("\n");for(var b=0,c=0;cb&&(b=e);c+=this.getConstants().FIELD_TEXT_HEIGHT+(0this.maxDisplayLength&&(a[d]=a[d].substring(0,this.maxDisplayLength));e.textContent=a[d];var k=(0,module$exports$Blockly$utils$dom.getFastTextWidth)(e,f,g,h);k>b&&(b=k)}b+=this.htmlInput_.offsetWidth-this.htmlInput_.clientWidth}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=b;this.size_.height=c;this.positionBorderRect_()};module$exports$Blockly$FieldMultilineInput.prototype.showEditor_=function(a,b){module$exports$Blockly$FieldMultilineInput.superClass_.showEditor_.call(this,a,b);this.forceRerender()}; +module$exports$Blockly$FieldMultilineInput.prototype.widgetCreate_=function(){var a=(0,module$exports$Blockly$WidgetDiv.getDiv)(),b=this.workspace_.getScale(),c=document.createElement("textarea");c.className="blocklyHtmlInput blocklyHtmlTextAreaInput";c.setAttribute("spellcheck",this.spellcheck_);var d=this.getConstants().FIELD_TEXT_FONTSIZE*b+"pt";a.style.fontSize=d;c.style.fontSize=d;c.style.borderRadius=module$exports$Blockly$FieldTextInput.BORDERRADIUS*b+"px";d=this.getConstants().FIELD_BORDER_RECT_X_PADDING* +b;var e=this.getConstants().FIELD_BORDER_RECT_Y_PADDING*b/2;c.style.padding=e+"px "+d+"px "+e+"px "+d+"px";d=this.getConstants().FIELD_TEXT_HEIGHT+this.getConstants().FIELD_BORDER_RECT_Y_PADDING;c.style.lineHeight=d*b+"px";a.appendChild(c);c.value=c.defaultValue=this.getEditorText_(this.value_);c.untypedDefaultValue_=this.value_;c.oldValue_=null;module$exports$Blockly$utils$userAgent.GECKO?setTimeout(this.resizeEditor_.bind(this),0):this.resizeEditor_();this.bindInputEvents_(c);return c}; +module$exports$Blockly$FieldMultilineInput.prototype.setMaxLines=function(a){"number"===typeof a&&0this.max_&&(0,module$exports$Blockly$utils$aria.setState)(a,module$exports$Blockly$utils$aria.State.VALUEMAX,this.max_);return a};(0,module$exports$Blockly$fieldRegistry.register)("field_number",module$exports$Blockly$FieldNumber);var module$exports$Blockly$FieldVariable=function(a,b,c,d,e){this.menuGenerator_=module$exports$Blockly$FieldVariable.dropdownCreate;this.defaultVariableName="string"===typeof a?a:"";this.size_=new module$exports$Blockly$utils$Size(0,0);e&&this.configure_(e);b&&this.setValidator(b);e||this.setTypes_(c,d)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$FieldVariable,module$exports$Blockly$FieldDropdown); +module$exports$Blockly$FieldVariable.fromJson=function(a){return new this((0,module$exports$Blockly$utils.replaceMessageReferences)(a.variable),void 0,void 0,void 0,a)};module$exports$Blockly$FieldVariable.prototype.SERIALIZABLE=!0;module$exports$Blockly$FieldVariable.prototype.configure_=function(a){module$exports$Blockly$FieldVariable.superClass_.configure_.call(this,a);this.setTypes_(a.variableTypes,a.defaultType)}; +module$exports$Blockly$FieldVariable.prototype.initModel=function(){if(!this.variable_){var a=(0,module$exports$Blockly$Variables.getOrCreateVariablePackage)(this.sourceBlock_.workspace,null,this.defaultVariableName,this.defaultType_);this.doValueUpdate_(a.getId())}}; +module$exports$Blockly$FieldVariable.prototype.shouldAddBorderRect_=function(){return module$exports$Blockly$FieldVariable.superClass_.shouldAddBorderRect_.call(this)&&(!this.getConstants().FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW||"variables_get"!=this.sourceBlock_.type)}; +module$exports$Blockly$FieldVariable.prototype.fromXml=function(a){var b=a.getAttribute("id"),c=a.textContent,d=a.getAttribute("variabletype")||a.getAttribute("variableType")||"";b=(0,module$exports$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: "+(0,module$exports$Blockly$Xml.domToText)(a)+".");this.setValue(b.getId())}; +module$exports$Blockly$FieldVariable.prototype.toXml=function(a){this.initModel();a.id=this.variable_.getId();a.textContent=this.variable_.name;this.variable_.type&&a.setAttribute("variabletype",this.variable_.type);return a};module$exports$Blockly$FieldVariable.prototype.saveState=function(a){var b=this.saveLegacyState(module$exports$Blockly$FieldVariable);if(null!==b)return b;this.initModel();b={id:this.variable_.getId()};a&&(b.name=this.variable_.name,b.type=this.variable_.type);return b}; +module$exports$Blockly$FieldVariable.prototype.loadState=function(a){this.loadLegacyState(module$exports$Blockly$FieldVariable,a)||(a=(0,module$exports$Blockly$Variables.getOrCreateVariablePackage)(this.sourceBlock_.workspace,a.id||null,a.name,a.type||""),this.setValue(a.getId()))}; +module$exports$Blockly$FieldVariable.prototype.setSourceBlock=function(a){if(a.isShadow())throw Error("Variable fields are not allowed to exist on shadow blocks.");module$exports$Blockly$FieldVariable.superClass_.setSourceBlock.call(this,a)};module$exports$Blockly$FieldVariable.prototype.getValue=function(){return this.variable_?this.variable_.getId():null};module$exports$Blockly$FieldVariable.prototype.getText=function(){return this.variable_?this.variable_.name:""}; +module$exports$Blockly$FieldVariable.prototype.getVariable=function(){return this.variable_};module$exports$Blockly$FieldVariable.prototype.getValidator=function(){return this.variable_?this.validator_:null}; +module$exports$Blockly$FieldVariable.prototype.doClassValidation_=function(a){if(null===a)return null;var b=(0,module$exports$Blockly$Variables.getVariable)(this.sourceBlock_.workspace,a);if(!b)return console.warn("Variable id doesn't point to a real variable! ID was "+a),null;b=b.type;return this.typeIsAllowed_(b)?a:(console.warn("Variable type doesn't match this field! Type was "+b),null)}; +module$exports$Blockly$FieldVariable.prototype.doValueUpdate_=function(a){this.variable_=(0,module$exports$Blockly$Variables.getVariable)(this.sourceBlock_.workspace,a);module$exports$Blockly$FieldVariable.superClass_.doValueUpdate_.call(this,a)};module$exports$Blockly$FieldVariable.prototype.typeIsAllowed_=function(a){var b=this.getVariableTypes_();if(!b)return!0;for(var c=0;cthis.previousScale_){var c=b-this.previousScale_;c=0Object.keys(this.cachedPoints_).length&&(this.cachedPoints_=Object.create(null),this.previousScale_=0)}; +module$exports$Blockly$TouchGesture.prototype.getTouchPoint=function(a){return this.startWorkspace_?new module$exports$Blockly$utils$Coordinate(a.pageX?a.pageX:a.changedTouches[0].pageX,a.pageY?a.pageY:a.changedTouches[0].pageY):null};var module$exports$Blockly$WorkspaceAudio=function(a){this.parentWorkspace_=a;this.SOUNDS_=Object.create(null)};module$exports$Blockly$WorkspaceAudio.prototype.lastSound_=null;module$exports$Blockly$WorkspaceAudio.prototype.dispose=function(){this.SOUNDS_=this.parentWorkspace_=null}; +module$exports$Blockly$WorkspaceAudio.prototype.load=function(a,b){if(a.length){try{var c=new module$exports$Blockly$utils$global.globalThis.Audio}catch(h){return}for(var d,e=0;erect,",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;","}"]};var module$exports$Blockly$blockRendering$Debug=function(a){this.debugElements_=[];this.svgRoot_=null;this.constants_=a};module$exports$Blockly$blockRendering$Debug.config={rowSpacers:!0,elemSpacers:!0,rows:!0,elems:!0,connections:!0,blockBounds:!0,connectedBlockBounds:!0,render:!0};module$exports$Blockly$blockRendering$Debug.prototype.clearElems=function(){for(var a=0;aa.height;e&&(b-=d);this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"rowSpacerRect blockRenderDebug",x:c?-(a.xPos+a.width):a.xPos,y:b,width:a.width,height:d,stroke:e?"black":"blue",fill:"blue","fill-opacity":"0.5","stroke-width":"1px"},this.svgRoot_))}}; +module$exports$Blockly$blockRendering$Debug.prototype.drawSpacerElem=function(a,b,c){if(module$exports$Blockly$blockRendering$Debug.config.elemSpacers){b=Math.abs(a.width);var d=0>a.width,e=d?a.xPos-b:a.xPos;c&&(e=-(e+b));this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"elemSpacerRect blockRenderDebug",x:e,y:a.centerline-a.height/2,width:b,height:a.height,stroke:"pink",fill:d?"black":"pink","fill-opacity":"0.5","stroke-width":"1px"}, +this.svgRoot_))}}; +module$exports$Blockly$blockRendering$Debug.prototype.drawRenderedElem=function(a,b){if(module$exports$Blockly$blockRendering$Debug.config.elems){var c=a.xPos;b&&(c=-(c+a.width));b=a.centerline-a.height/2;this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"rowRenderingRect blockRenderDebug",x:c,y:b,width:a.width,height:a.height,stroke:"black",fill:"none","stroke-width":"1px"},this.svgRoot_));module$exports$Blockly$blockRendering$Types.isField(a)&&a.field instanceof +module$exports$Blockly$FieldLabel&&this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"rowRenderingRect blockRenderDebug",x:c,y:b+this.constants_.FIELD_TEXT_BASELINE,width:a.width,height:"0.1px",stroke:"red",fill:"none","stroke-width":"0.5px"},this.svgRoot_))}module$exports$Blockly$blockRendering$Types.isInput(a)&&module$exports$Blockly$blockRendering$Debug.config.connections&&this.drawConnection(a.connectionModel)}; +module$exports$Blockly$blockRendering$Debug.prototype.drawConnection=function(a){if(module$exports$Blockly$blockRendering$Debug.config.connections){if(a.type==module$exports$Blockly$ConnectionType.ConnectionType.INPUT_VALUE){var b=4;var c="magenta";var d="none"}else a.type==module$exports$Blockly$ConnectionType.ConnectionType.OUTPUT_VALUE?(b=2,d=c="magenta"):a.type==module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT?(b=4,c="goldenrod",d="none"):a.type==module$exports$Blockly$ConnectionType.ConnectionType.PREVIOUS_STATEMENT&& +(b=2,d=c="goldenrod");this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE,{"class":"blockRenderDebug",cx:a.offsetInBlock_.x,cy:a.offsetInBlock_.y,r:b,fill:d,stroke:c},this.svgRoot_))}}; +module$exports$Blockly$blockRendering$Debug.prototype.drawRenderedRow=function(a,b,c){module$exports$Blockly$blockRendering$Debug.config.rows&&(this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"elemRenderingRect blockRenderDebug",x:c?-(a.xPos+a.width):a.xPos,y:a.yPos,width:a.width,height:a.height,stroke:"red",fill:"none","stroke-width":"1px"},this.svgRoot_)),module$exports$Blockly$blockRendering$Types.isTopOrBottomRow(a)|| +module$exports$Blockly$blockRendering$Debug.config.connectedBlockBounds&&this.debugElements_.push((0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"connectedBlockWidth blockRenderDebug",x:c?-(a.xPos+a.widthWithConnectedBlocks):a.xPos,y:a.yPos,width:a.widthWithConnectedBlocks,height:a.height,stroke:this.randomColour_,fill:"none","stroke-width":"1px","stroke-dasharray":"3,3"},this.svgRoot_)))}; +module$exports$Blockly$blockRendering$Debug.prototype.drawRowWithElements=function(a,b,c){for(var d=0;da.height;e&&(b-=d);this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"rowSpacerRect blockRenderDebug",x:c?-(a.xPos+a.width):a.xPos,y:b,width:a.width,height:d,stroke:e?"black":"blue",fill:"blue","fill-opacity":"0.5","stroke-width":"1px"},this.svgRoot_))}}; -Blockly.blockRendering.Debug.prototype.drawSpacerElem=function(a,b,c){if(Blockly.blockRendering.Debug.config.elemSpacers){b=Math.abs(a.width);var d=0>a.width,e=d?a.xPos-b:a.xPos;c&&(e=-(e+b));this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"elemSpacerRect blockRenderDebug",x:e,y:a.centerline-a.height/2,width:b,height:a.height,stroke:"pink",fill:d?"black":"pink","fill-opacity":"0.5","stroke-width":"1px"},this.svgRoot_))}}; -Blockly.blockRendering.Debug.prototype.drawRenderedElem=function(a,b){if(Blockly.blockRendering.Debug.config.elems){var c=a.xPos;b&&(c=-(c+a.width));b=a.centerline-a.height/2;this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"rowRenderingRect blockRenderDebug",x:c,y:b,width:a.width,height:a.height,stroke:"black",fill:"none","stroke-width":"1px"},this.svgRoot_));Blockly.blockRendering.Types.isField(a)&&a.field instanceof Blockly.FieldLabel&&this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT, -{"class":"rowRenderingRect blockRenderDebug",x:c,y:b+this.constants_.FIELD_TEXT_BASELINE,width:a.width,height:"0.1px",stroke:"red",fill:"none","stroke-width":"0.5px"},this.svgRoot_))}Blockly.blockRendering.Types.isInput(a)&&Blockly.blockRendering.Debug.config.connections&&this.drawConnection(a.connectionModel)}; -Blockly.blockRendering.Debug.prototype.drawConnection=function(a){if(Blockly.blockRendering.Debug.config.connections){if(a.type==Blockly.connectionTypes.INPUT_VALUE){var b=4;var c="magenta";var d="none"}else a.type==Blockly.connectionTypes.OUTPUT_VALUE?(b=2,d=c="magenta"):a.type==Blockly.connectionTypes.NEXT_STATEMENT?(b=4,c="goldenrod",d="none"):a.type==Blockly.connectionTypes.PREVIOUS_STATEMENT&&(b=2,d=c="goldenrod");this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.CIRCLE, -{"class":"blockRenderDebug",cx:a.offsetInBlock_.x,cy:a.offsetInBlock_.y,r:b,fill:d,stroke:c},this.svgRoot_))}}; -Blockly.blockRendering.Debug.prototype.drawRenderedRow=function(a,b,c){Blockly.blockRendering.Debug.config.rows&&(this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT,{"class":"elemRenderingRect blockRenderDebug",x:c?-(a.xPos+a.width):a.xPos,y:a.yPos,width:a.width,height:a.height,stroke:"red",fill:"none","stroke-width":"1px"},this.svgRoot_)),Blockly.blockRendering.Types.isTopOrBottomRow(a)||Blockly.blockRendering.Debug.config.connectedBlockBounds&&this.debugElements_.push(Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.RECT, -{"class":"connectedBlockWidth blockRenderDebug",x:c?-(a.xPos+a.widthWithConnectedBlocks):a.xPos,y:a.yPos,width:a.widthWithConnectedBlocks,height:a.height,stroke:this.randomColour_,fill:"none","stroke-width":"1px","stroke-dasharray":"3,3"},this.svgRoot_)))}; -Blockly.blockRendering.Debug.prototype.drawRowWithElements=function(a,b,c){for(var d=0,e=a.elements.length;d.blocklyPathLight,",a+" .blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none;","}"])};Blockly.geras.Highlighter=function(a){this.info_=a;this.inlineSteps_=this.steps_="";this.RTL_=this.info_.RTL;a=a.getRenderer();this.constants_=a.getConstants();this.highlightConstants_=a.getHighlightConstants();this.highlightOffset_=this.highlightConstants_.OFFSET;this.outsideCornerPaths_=this.highlightConstants_.OUTSIDE_CORNER;this.insideCornerPaths_=this.highlightConstants_.INSIDE_CORNER;this.puzzleTabPaths_=this.highlightConstants_.PUZZLE_TAB;this.notchPaths_=this.highlightConstants_.NOTCH;this.startPaths_= -this.highlightConstants_.START_HAT;this.jaggedTeethPaths_=this.highlightConstants_.JAGGED_TEETH};Blockly.geras.Highlighter.prototype.getPath=function(){return this.steps_+"\n"+this.inlineSteps_}; -Blockly.geras.Highlighter.prototype.drawTopCorner=function(a){this.steps_+=Blockly.utils.svgPaths.moveBy(a.xPos,this.info_.startY);for(var b=0,c;c=a.elements[b];b++)Blockly.blockRendering.Types.isLeftSquareCorner(c)?this.steps_+=this.highlightConstants_.START_POINT:Blockly.blockRendering.Types.isLeftRoundedCorner(c)?this.steps_+=this.outsideCornerPaths_.topLeft(this.RTL_):Blockly.blockRendering.Types.isPreviousConnection(c)?this.steps_+=this.notchPaths_.pathLeft:Blockly.blockRendering.Types.isHat(c)? -this.steps_+=this.startPaths_.path(this.RTL_):Blockly.blockRendering.Types.isSpacer(c)&&0!=c.width&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",c.xPos+c.width-this.highlightOffset_));this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",a.xPos+a.width-this.highlightOffset_)};Blockly.geras.Highlighter.prototype.drawJaggedEdge_=function(a){this.info_.RTL&&(this.steps_+=this.jaggedTeethPaths_.pathLeft+Blockly.utils.svgPaths.lineOnAxis("v",a.height-this.jaggedTeethPaths_.height-this.highlightOffset_))}; -Blockly.geras.Highlighter.prototype.drawValueInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-b.connectionHeight;this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos+b.width-this.highlightOffset_,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)+Blockly.utils.svgPaths.lineOnAxis("v",c)}else this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos+b.width,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)}; -Blockly.geras.Highlighter.prototype.drawStatementInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-2*this.insideCornerPaths_.height;this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos,a.yPos)+this.insideCornerPaths_.pathTop(this.RTL_)+Blockly.utils.svgPaths.lineOnAxis("v",c)+this.insideCornerPaths_.pathBottom(this.RTL_)+Blockly.utils.svgPaths.lineTo(a.width-b.xPos-this.insideCornerPaths_.width,0)}else this.steps_+=Blockly.utils.svgPaths.moveTo(b.xPos,a.yPos+a.height)+this.insideCornerPaths_.pathBottom(this.RTL_)+ -Blockly.utils.svgPaths.lineTo(a.width-b.xPos-this.insideCornerPaths_.width,0)};Blockly.geras.Highlighter.prototype.drawRightSideRow=function(a){var b=a.xPos+a.width-this.highlightOffset_;a.followsStatement&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",b));this.RTL_&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("H",b),a.height>this.highlightOffset_&&(this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",a.yPos+a.height-this.highlightOffset_)))}; -Blockly.geras.Highlighter.prototype.drawBottomRow=function(a){if(this.RTL_)this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",a.baseline-this.highlightOffset_);else{var b=this.info_.bottomRow.elements[0];Blockly.blockRendering.Types.isLeftSquareCorner(b)?this.steps_+=Blockly.utils.svgPaths.moveTo(a.xPos+this.highlightOffset_,a.baseline-this.highlightOffset_):Blockly.blockRendering.Types.isLeftRoundedCorner(b)&&(this.steps_+=Blockly.utils.svgPaths.moveTo(a.xPos,a.baseline),this.steps_+=this.outsideCornerPaths_.bottomLeft())}}; -Blockly.geras.Highlighter.prototype.drawLeft=function(){var a=this.info_.outputConnection;a&&(a=a.connectionOffsetY+a.height,this.RTL_?this.steps_+=Blockly.utils.svgPaths.moveTo(this.info_.startX,a):(this.steps_+=Blockly.utils.svgPaths.moveTo(this.info_.startX+this.highlightOffset_,this.info_.bottomRow.baseline-this.highlightOffset_),this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",a)),this.steps_+=this.puzzleTabPaths_.pathUp(this.RTL_));this.RTL_||(a=this.info_.topRow,Blockly.blockRendering.Types.isLeftRoundedCorner(a.elements[0])? -this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",this.outsideCornerPaths_.height):this.steps_+=Blockly.utils.svgPaths.lineOnAxis("V",a.capline+this.highlightOffset_))}; -Blockly.geras.Highlighter.prototype.drawInlineInput=function(a){var b=this.highlightOffset_,c=a.xPos+a.connectionWidth,d=a.centerline-a.height/2,e=a.width-a.connectionWidth,f=d+b;this.RTL_?(d=a.connectionOffsetY-b,a=a.height-(a.connectionOffsetY+a.connectionHeight)+b,this.inlineSteps_+=Blockly.utils.svgPaths.moveTo(c-b,f)+Blockly.utils.svgPaths.lineOnAxis("v",d)+this.puzzleTabPaths_.pathDown(this.RTL_)+Blockly.utils.svgPaths.lineOnAxis("v",a)+Blockly.utils.svgPaths.lineOnAxis("h",e)):this.inlineSteps_+= -Blockly.utils.svgPaths.moveTo(a.xPos+a.width+b,f)+Blockly.utils.svgPaths.lineOnAxis("v",a.height)+Blockly.utils.svgPaths.lineOnAxis("h",-e)+Blockly.utils.svgPaths.moveTo(c,d+a.connectionOffsetY)+this.puzzleTabPaths_.pathDown(this.RTL_)};Blockly.geras.InlineInput=function(a,b){Blockly.geras.InlineInput.superClass_.constructor.call(this,a,b);this.connectedBlock&&(this.width+=this.constants_.DARK_PATH_OFFSET,this.height+=this.constants_.DARK_PATH_OFFSET)};Blockly.utils.object.inherits(Blockly.geras.InlineInput,Blockly.blockRendering.InlineInput);Blockly.geras.StatementInput=function(a,b){Blockly.geras.StatementInput.superClass_.constructor.call(this,a,b);this.connectedBlock&&(this.height+=this.constants_.DARK_PATH_OFFSET)}; -Blockly.utils.object.inherits(Blockly.geras.StatementInput,Blockly.blockRendering.StatementInput);Blockly.geras.RenderInfo=function(a,b){Blockly.geras.RenderInfo.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.geras.RenderInfo,Blockly.blockRendering.RenderInfo);Blockly.geras.RenderInfo.prototype.getRenderer=function(){return this.renderer_}; -Blockly.geras.RenderInfo.prototype.populateBottomRow_=function(){Blockly.geras.RenderInfo.superClass_.populateBottomRow_.call(this);this.block_.inputList.length&&this.block_.inputList[this.block_.inputList.length-1].type==Blockly.inputTypes.STATEMENT||(this.bottomRow.minHeight=this.constants_.MEDIUM_PADDING-this.constants_.DARK_PATH_OFFSET)}; -Blockly.geras.RenderInfo.prototype.addInput_=function(a,b){this.isInline&&a.type==Blockly.inputTypes.VALUE?(b.elements.push(new Blockly.geras.InlineInput(this.constants_,a)),b.hasInlineInput=!0):a.type==Blockly.inputTypes.STATEMENT?(b.elements.push(new Blockly.geras.StatementInput(this.constants_,a)),b.hasStatement=!0):a.type==Blockly.inputTypes.VALUE?(b.elements.push(new Blockly.blockRendering.ExternalValueInput(this.constants_,a)),b.hasExternalInput=!0):a.type==Blockly.inputTypes.DUMMY&&(b.minHeight= -Math.max(b.minHeight,this.constants_.DUMMY_INPUT_MIN_HEIGHT),b.hasDummyInput=!0);this.isInline||null!=b.align||(b.align=a.align)}; -Blockly.geras.RenderInfo.prototype.addElemSpacing_=function(){for(var a=!1,b=0,c;c=this.rows[b];b++)c.hasExternalInput&&(a=!0);for(b=0;c=this.rows[b];b++){var d=c.elements;c.elements=[];c.startsWithElemSpacer()&&c.elements.push(new Blockly.blockRendering.InRowSpacer(this.constants_,this.getInRowSpacing_(null,d[0])));if(d.length){for(var e=0;eb?b:f;e=e?-1:1;c=(d?-1:1)*c/2;return Blockly.utils.svgPaths.lineTo(-e*f,c)+Blockly.utils.svgPaths.lineTo(e*f,c)}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;return{type:this.SHAPES.HEXAGONAL,isDynamic:!0,width:function(c){c/=2;return c>b?b:c},height:function(c){return c},connectionOffsetY:function(c){return c/2},connectionOffsetX:function(c){return-c},pathDown:function(c){return a(c,!1,!1)},pathUp:function(c){return a(c, -!0,!1)},pathRightDown:function(c){return a(c,!1,!0)},pathRightUp:function(c){return a(c,!1,!0)}}}; -Blockly.zelos.ConstantProvider.prototype.makeRounded=function(){function a(d,e,f){var g=d>c?d-c:0;d=(d>c?c:d)/2;return Blockly.utils.svgPaths.arc("a","0 0,1",d,Blockly.utils.svgPaths.point((e?-1:1)*d,(e?-1:1)*d))+Blockly.utils.svgPaths.lineOnAxis("v",(f?1:-1)*g)+Blockly.utils.svgPaths.arc("a","0 0,1",d,Blockly.utils.svgPaths.point((e?1:-1)*d,(e?-1:1)*d))}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH,c=2*b;return{type:this.SHAPES.ROUND,isDynamic:!0,width:function(d){d/=2;return d>b?b:d},height:function(d){return d}, -connectionOffsetY:function(d){return d/2},connectionOffsetX:function(d){return-d},pathDown:function(d){return a(d,!1,!1)},pathUp:function(d){return a(d,!0,!1)},pathRightDown:function(d){return a(d,!1,!0)},pathRightUp:function(d){return a(d,!1,!0)}}}; -Blockly.zelos.ConstantProvider.prototype.makeSquared=function(){function a(c,d,e){c-=2*b;return Blockly.utils.svgPaths.arc("a","0 0,1",b,Blockly.utils.svgPaths.point((d?-1:1)*b,(d?-1:1)*b))+Blockly.utils.svgPaths.lineOnAxis("v",(e?1:-1)*c)+Blockly.utils.svgPaths.arc("a","0 0,1",b,Blockly.utils.svgPaths.point((d?1:-1)*b,(d?-1:1)*b))}var b=this.CORNER_RADIUS;return{type:this.SHAPES.SQUARE,isDynamic:!0,width:function(c){return b},height:function(c){return c},connectionOffsetY:function(c){return c/2}, -connectionOffsetX:function(c){return-c},pathDown:function(c){return a(c,!1,!1)},pathUp:function(c){return a(c,!0,!1)},pathRightDown:function(c){return a(c,!1,!0)},pathRightUp:function(c){return a(c,!1,!0)}}}; -Blockly.zelos.ConstantProvider.prototype.shapeFor=function(a){var b=a.getCheck();!b&&a.targetConnection&&(b=a.targetConnection.getCheck());switch(a.type){case Blockly.connectionTypes.INPUT_VALUE:case Blockly.connectionTypes.OUTPUT_VALUE:a=a.getSourceBlock().getOutputShape();if(null!=a)switch(a){case this.SHAPES.HEXAGONAL:return this.HEXAGONAL;case this.SHAPES.ROUND:return this.ROUNDED;case this.SHAPES.SQUARE:return this.SQUARED}if(b&&-1!=b.indexOf("Boolean"))return this.HEXAGONAL;if(b&&-1!=b.indexOf("Number"))return this.ROUNDED; -b&&b.indexOf("String");return this.ROUNDED;case Blockly.connectionTypes.PREVIOUS_STATEMENT:case Blockly.connectionTypes.NEXT_STATEMENT:return this.NOTCH;default:throw Error("Unknown type");}}; -Blockly.zelos.ConstantProvider.prototype.makeNotch=function(){function a(l){return Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(l*e/2,0),Blockly.utils.svgPaths.point(l*e*3/4,g/2),Blockly.utils.svgPaths.point(l*e,g)])+Blockly.utils.svgPaths.line([Blockly.utils.svgPaths.point(l*e,f)])+Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(l*e/4,g/2),Blockly.utils.svgPaths.point(l*e/2,g),Blockly.utils.svgPaths.point(l*e,g)])+Blockly.utils.svgPaths.lineOnAxis("h",l*d)+Blockly.utils.svgPaths.curve("c", -[Blockly.utils.svgPaths.point(l*e/2,0),Blockly.utils.svgPaths.point(l*e*3/4,-(g/2)),Blockly.utils.svgPaths.point(l*e,-g)])+Blockly.utils.svgPaths.line([Blockly.utils.svgPaths.point(l*e,-f)])+Blockly.utils.svgPaths.curve("c",[Blockly.utils.svgPaths.point(l*e/4,-(g/2)),Blockly.utils.svgPaths.point(l*e/2,-g),Blockly.utils.svgPaths.point(l*e,-g)])}var b=this.NOTCH_WIDTH,c=this.NOTCH_HEIGHT,d=b/3,e=d/3,f=c/2,g=f/2,h=a(1),k=a(-1);return{type:this.SHAPES.NOTCH,width:b,height:c,pathLeft:h,pathRight:k}}; -Blockly.zelos.ConstantProvider.prototype.makeInsideCorners=function(){var a=this.CORNER_RADIUS,b=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(-a,a)),c=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(-a,a)),d=Blockly.utils.svgPaths.arc("a","0 0,0",a,Blockly.utils.svgPaths.point(a,a)),e=Blockly.utils.svgPaths.arc("a","0 0,1",a,Blockly.utils.svgPaths.point(a,a));return{width:a,height:a,pathTop:b,pathBottom:d,rightWidth:a,rightHeight:a,pathTopRight:c,pathBottomRight:e}}; -Blockly.zelos.ConstantProvider.prototype.generateSecondaryColour_=function(a){return Blockly.utils.colour.blend("#000",a,.15)||a};Blockly.zelos.ConstantProvider.prototype.generateTertiaryColour_=function(a){return Blockly.utils.colour.blend("#000",a,.25)||a}; -Blockly.zelos.ConstantProvider.prototype.createDom=function(a,b,c){Blockly.zelos.ConstantProvider.superClass_.createDom.call(this,a,b,c);a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.DEFS,{},a);b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FILTER,{id:"blocklySelectedGlowFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEGAUSSIANBLUR,{"in":"SourceGraphic",stdDeviation:this.SELECTED_GLOW_SIZE},b);c= -Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FECOMPONENTTRANSFER,{result:"outBlur"},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEFUNCA,{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},c);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEFLOOD,{"flood-color":this.SELECTED_GLOW_COLOUR,"flood-opacity":1,result:"outColor"},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FECOMPOSITE,{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},b);this.selectedGlowFilterId= -b.id;this.selectedGlowFilter_=b;a=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FILTER,{id:"blocklyReplacementGlowFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEGAUSSIANBLUR,{"in":"SourceGraphic",stdDeviation:this.REPLACEMENT_GLOW_SIZE},a);b=Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FECOMPONENTTRANSFER,{result:"outBlur"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEFUNCA,{type:"table", -tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},b);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FEFLOOD,{"flood-color":this.REPLACEMENT_GLOW_COLOUR,"flood-opacity":1,result:"outColor"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FECOMPOSITE,{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},a);Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.FECOMPOSITE,{"in":"SourceGraphic",in2:"outGlow",operator:"over"},a);this.replacementGlowFilterId=a.id;this.replacementGlowFilter_= -a}; -Blockly.zelos.ConstantProvider.prototype.getCSS_=function(a){return[a+" .blocklyText,",a+" .blocklyFlyoutLabelText {","font: "+this.FIELD_TEXT_FONTWEIGHT+" "+this.FIELD_TEXT_FONTSIZE+"pt "+this.FIELD_TEXT_FONTFAMILY+";","}",a+" .blocklyText {","fill: #fff;","}",a+" .blocklyNonEditableText>rect:not(.blocklyDropdownRect),",a+" .blocklyEditableText>rect:not(.blocklyDropdownRect) {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","}",a+" .blocklyNonEditableText>text,",a+" .blocklyEditableText>text,",a+" .blocklyNonEditableText>g>text,", -a+" .blocklyEditableText>g>text {","fill: #575E75;","}",a+" .blocklyFlyoutLabelText {","fill: #575E75;","}",a+" .blocklyText.blocklyBubbleText {","fill: #575E75;","}",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>rect,",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>.blocklyPath {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+ -";","color: #575E75;","}",a+" .blocklyDropdownText {","fill: #fff !important;","}",a+".blocklyWidgetDiv .goog-menuitem,",a+".blocklyDropDownDiv .goog-menuitem {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","}",a+".blocklyDropDownDiv .goog-menuitem-content {","color: #fff;","}",a+" .blocklyHighlightedConnectionPath {","stroke: "+this.SELECTED_GLOW_COLOUR+";","}",a+" .blocklyDisabled > .blocklyOutlinePath {","fill: url(#blocklyDisabledPattern"+this.randomIdentifier+")","}",a+" .blocklyInsertionMarker>.blocklyPath {", -"fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none;","}"]};Blockly.zelos.TopRow=function(a){Blockly.zelos.TopRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.TopRow,Blockly.blockRendering.TopRow);Blockly.zelos.TopRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.TopRow.prototype.hasLeftSquareCorner=function(a){var b=(a.hat?"cap"===a.hat:this.constants_.ADD_START_HATS)&&!a.outputConnection&&!a.previousConnection;return!!a.outputConnection||b}; -Blockly.zelos.TopRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection&&!a.statementInputCount&&!a.nextConnection};Blockly.zelos.BottomRow=function(a){Blockly.zelos.BottomRow.superClass_.constructor.call(this,a)};Blockly.utils.object.inherits(Blockly.zelos.BottomRow,Blockly.blockRendering.BottomRow);Blockly.zelos.BottomRow.prototype.endsWithElemSpacer=function(){return!1};Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner=function(a){return!!a.outputConnection}; -Blockly.zelos.BottomRow.prototype.hasRightSquareCorner=function(a){return!!a.outputConnection&&!a.statementInputCount&&!a.nextConnection};Blockly.zelos.RightConnectionShape=function(a){Blockly.zelos.RightConnectionShape.superClass_.constructor.call(this,a);this.type|=Blockly.blockRendering.Types.getType("RIGHT_CONNECTION");this.width=this.height=0};Blockly.utils.object.inherits(Blockly.zelos.RightConnectionShape,Blockly.blockRendering.Measurable);Blockly.zelos.RenderInfo=function(a,b){Blockly.zelos.RenderInfo.superClass_.constructor.call(this,a,b);this.topRow=new Blockly.zelos.TopRow(this.constants_);this.bottomRow=new Blockly.zelos.BottomRow(this.constants_);this.isInline=!0;this.isMultiRow=!b.getInputsInline()||b.isCollapsed();this.hasStatementInput=0=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!f.precedesStatement;if(Blockly.blockRendering.Types.isInputRow(e)&&e.hasStatement)e.measure(),b=e.width-e.getLastInput().width+a;else if(d&&(2==c||f)&& -Blockly.blockRendering.Types.isInputRow(e)&&!e.hasStatement){f=e.xPos;d=null;for(var g=0,h;h=e.elements[g];g++)Blockly.blockRendering.Types.isSpacer(h)&&(d=h),!(d&&(Blockly.blockRendering.Types.isField(h)||Blockly.blockRendering.Types.isInput(h))&&fc?c:this.height/2,b-c*(1-Math.sin(Math.acos((c-this.constants_.SMALL_PADDING)/c)));default:return 0}if(Blockly.blockRendering.Types.isInlineInput(a)){var e=a.connectedBlock;a=e?e.pathObject.outputShapeType: -a.shape.type;return e&&e.outputConnection&&(e.statementInputCount||e.nextConnection)||c==d.SHAPES.HEXAGONAL&&c!=a?0:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][a]}return Blockly.blockRendering.Types.isField(a)?c==d.SHAPES.ROUND&&a.field instanceof Blockly.FieldTextInput?b-2.75*d.GRID_UNIT:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][0]:Blockly.blockRendering.Types.isIcon(a)?this.constants_.SMALL_PADDING:0}; -Blockly.zelos.RenderInfo.prototype.finalizeVerticalAlignment_=function(){if(!this.outputConnection)for(var a=2;a=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!d.precedesStatement;if(e?this.topRow.hasPreviousConnection:b.followsStatement){var g=3==c.elements.length&&(c.elements[1].field instanceof Blockly.FieldLabel||c.elements[1].field instanceof Blockly.FieldImage);if(!e&&g)b.height-=this.constants_.SMALL_PADDING, -d.height-=this.constants_.SMALL_PADDING,c.height-=this.constants_.MEDIUM_PADDING;else if(!e&&!f)b.height+=this.constants_.SMALL_PADDING;else if(f){e=!1;for(f=0;g=c.elements[f];f++)if(Blockly.blockRendering.Types.isInlineInput(g)&&g.connectedBlock&&!g.connectedBlock.isShadow()&&40<=g.connectedBlock.getHeightWidth().height){e=!0;break}e&&(b.height-=this.constants_.SMALL_PADDING,d.height-=this.constants_.SMALL_PADDING)}}}}; -Blockly.zelos.RenderInfo.prototype.finalize_=function(){this.finalizeOutputConnection_();this.finalizeHorizontalAlignment_();this.finalizeVerticalAlignment_();Blockly.zelos.RenderInfo.superClass_.finalize_.call(this);this.rightSide&&(this.widthWithChildren+=this.rightSide.width)};Blockly.zelos.Drawer=function(a,b){Blockly.zelos.Drawer.superClass_.constructor.call(this,a,b)};Blockly.utils.object.inherits(Blockly.zelos.Drawer,Blockly.blockRendering.Drawer); -Blockly.zelos.Drawer.prototype.draw=function(){var a=this.block_.pathObject;a.beginDrawing();this.hideHiddenIcons_();this.drawOutline_();this.drawInternals_();a.setPath(this.outlinePath_+"\n"+this.inlinePath_);this.info_.RTL&&a.flipRTL();Blockly.blockRendering.useDebugger&&this.block_.renderingDebugger.drawDebug(this.block_,this.info_);this.recordSizeOnBlock_();this.info_.outputConnection&&(a.outputShapeType=this.info_.outputConnection.shape.type);a.endDrawing()}; -Blockly.zelos.Drawer.prototype.drawOutline_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape&&!this.info_.hasStatementInput&&!this.info_.bottomRow.hasNextConnection?(this.drawFlatTop_(),this.drawRightDynamicConnection_(),this.drawFlatBottom_(),this.drawLeftDynamicConnection_()):Blockly.zelos.Drawer.superClass_.drawOutline_.call(this)}; -Blockly.zelos.Drawer.prototype.drawLeft_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape?this.drawLeftDynamicConnection_():Blockly.zelos.Drawer.superClass_.drawLeft_.call(this)}; -Blockly.zelos.Drawer.prototype.drawRightSideRow_=function(a){if(!(0>=a.height))if(a.precedesStatement||a.followsStatement){var b=this.constants_.INSIDE_CORNERS.rightHeight;b=a.height-(a.precedesStatement?b:0);this.outlinePath_+=(a.followsStatement?this.constants_.INSIDE_CORNERS.pathBottomRight:"")+(0Math.abs(b-this.oldTop_)&&1>Math.abs(c-this.oldLeft_))){var d=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.VIEWPORT_CHANGE))(b,c,a,this.id,this.oldScale_);this.oldScale_=a;this.oldTop_=b;this.oldLeft_=c;(0,module$exports$Blockly$Events$utils.fire)(d)}}}; +module$exports$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()}; +module$exports$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)}}; +module$exports$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=(0,module$exports$Blockly$utils.getRelativeXY)(this.getCanvas());this.workspaceDragSurface_.setContentsAndShow(this.getCanvas(),this.getBubbleCanvas(),a,b,c,this.scale);this.workspaceDragSurface_.translateSurface(d.x, +d.y)}};module$exports$Blockly$WorkspaceSvg.prototype.getBlockDragSurface=function(){return this.blockDragSurface_};module$exports$Blockly$WorkspaceSvg.prototype.getWidth=function(){var a=this.getMetrics();return a?a.viewWidth/this.scale:0}; +module$exports$Blockly$WorkspaceSvg.prototype.setVisible=function(a){this.isVisible_=a;if(this.svgGroup_)if(this.scrollbar&&this.scrollbar.setContainerVisible(a),this.getFlyout()&&this.getFlyout().setContainerVisible(a),this.getParentSvg().style.display=a?"block":"none",this.toolbox_&&this.toolbox_.setVisible(a),a){a=this.getAllBlocks(!1);for(var b=a.length-1;0<=b;b--)a[b].markDirty();this.render();this.toolbox_&&this.toolbox_.position()}else this.hideChaff(!0)}; +module$exports$Blockly$WorkspaceSvg.prototype.render=function(){for(var a=this.getAllBlocks(!1),b=a.length-1;0<=b;b--)a[b].render(!1);if(this.currentGesture_)for(a=this.currentGesture_.getInsertionMarkers(),b=0;b=Math.abs(c-h.x)&&1>=Math.abs(d-h.y)){f=!0;break}}if(!f){var k=e.getConnections_(!1);a=0;for(b=void 0;b=k[a];a++)if(b.closest(module$exports$Blockly$internalConstants.SNAP_RADIUS,new module$exports$Blockly$utils$Coordinate(c,d)).connection){f=!0;break}}f&&(c=this.RTL?c-module$exports$Blockly$internalConstants.SNAP_RADIUS:c+module$exports$Blockly$internalConstants.SNAP_RADIUS,d+=2*module$exports$Blockly$internalConstants.SNAP_RADIUS)}while(f);e.moveTo(new module$exports$Blockly$utils$Coordinate(c, +d))}}finally{(0,module$exports$Blockly$Events$utils.enable)()}(0,module$exports$Blockly$Events$utils.isEnabled)()&&!e.isShadow()&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CREATE))(e));e.select()}; +module$exports$Blockly$WorkspaceSvg.prototype.pasteWorkspaceComment_=function(a){(0,module$exports$Blockly$Events$utils.disable)();try{var b=module$exports$Blockly$WorkspaceCommentSvg.fromXml(a,this);var 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{(0,module$exports$Blockly$Events$utils.enable)()}(0,module$exports$Blockly$Events$utils.isEnabled)()&&module$exports$Blockly$WorkspaceComment.fireCreateEvent(b); +b.select()};module$exports$Blockly$WorkspaceSvg.prototype.refreshToolboxSelection=function(){var a=this.isFlyout?this.targetWorkspace:this;a&&!a.currentGesture_&&a.toolbox_&&a.toolbox_.getFlyout()&&a.toolbox_.refreshSelection()};module$exports$Blockly$WorkspaceSvg.prototype.renameVariableById=function(a,b){module$exports$Blockly$WorkspaceSvg.superClass_.renameVariableById.call(this,a,b);this.refreshToolboxSelection()}; +module$exports$Blockly$WorkspaceSvg.prototype.deleteVariableById=function(a){module$exports$Blockly$WorkspaceSvg.superClass_.deleteVariableById.call(this,a);this.refreshToolboxSelection()};module$exports$Blockly$WorkspaceSvg.prototype.createVariable=function(a,b,c){a=module$exports$Blockly$WorkspaceSvg.superClass_.createVariable.call(this,a,b,c);this.refreshToolboxSelection();return a}; +module$exports$Blockly$WorkspaceSvg.prototype.recordDeleteAreas=function(){module$exports$Blockly$utils.deprecation.warn("WorkspaceSvg.prototype.recordDeleteAreas","June 2021","June 2022","WorkspaceSvg.prototype.recordDragTargets");this.recordDragTargets()}; +module$exports$Blockly$WorkspaceSvg.prototype.recordDragTargets=function(){var a=this.componentManager_.getComponents(module$exports$Blockly$ComponentManager.Capability.DRAG_TARGET,!0);this.dragTargetAreas_=[];for(var b=0,c;c=a[b];b++){var d=c.getClientRect();d&&this.dragTargetAreas_.push({component:c,clientRect:d})}}; +module$exports$Blockly$WorkspaceSvg.prototype.getDragTarget=function(a){for(var b=0,c;c=this.dragTargetAreas_[b];b++)if(c.clientRect.contains(a.clientX,a.clientY))return c.component;return null};module$exports$Blockly$WorkspaceSvg.prototype.onMouseDown_=function(a){var b=this.getGesture(a);b&&b.handleWsStart(a,this)}; +module$exports$Blockly$WorkspaceSvg.prototype.startDrag=function(a,b){a=(0,module$exports$Blockly$browserEvents.mouseToSvg)(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;this.dragDeltaXY_=module$exports$Blockly$utils$Coordinate.difference(b,a)}; +module$exports$Blockly$WorkspaceSvg.prototype.moveDrag=function(a){a=(0,module$exports$Blockly$browserEvents.mouseToSvg)(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;return module$exports$Blockly$utils$Coordinate.sum(this.dragDeltaXY_,a)};module$exports$Blockly$WorkspaceSvg.prototype.isDragging=function(){return null!=this.currentGesture_&&this.currentGesture_.isDragging()}; +module$exports$Blockly$WorkspaceSvg.prototype.isDraggable=function(){return this.options.moveOptions&&this.options.moveOptions.drag};module$exports$Blockly$WorkspaceSvg.prototype.isMovable=function(){return this.options.moveOptions&&!!this.options.moveOptions.scrollbars||this.options.moveOptions&&this.options.moveOptions.wheel||this.options.moveOptions&&this.options.moveOptions.drag||this.options.zoomOptions&&this.options.zoomOptions.wheel||this.options.zoomOptions&&this.options.zoomOptions.pinch}; +module$exports$Blockly$WorkspaceSvg.prototype.isMovableHorizontally=function(){var a=!!this.scrollbar;return this.isMovable()&&(!a||a&&this.scrollbar.canScrollHorizontally())};module$exports$Blockly$WorkspaceSvg.prototype.isMovableVertically=function(){var a=!!this.scrollbar;return this.isMovable()&&(!a||a&&this.scrollbar.canScrollVertically())}; +module$exports$Blockly$WorkspaceSvg.prototype.onMouseWheel_=function(a){if(module$exports$Blockly$Gesture.inProgress())a.preventDefault(),a.stopPropagation();else{var b=this.options.zoomOptions&&this.options.zoomOptions.wheel,c=this.options.moveOptions&&this.options.moveOptions.wheel;if(b||c){var d=(0,module$exports$Blockly$browserEvents.getScrollDeltaPixels)(a);if(module$exports$Blockly$utils$userAgent.MAC)var e=a.metaKey;b&&(a.ctrlKey||e||!c)?(d=-d.y/50,b=(0,module$exports$Blockly$browserEvents.mouseToSvg)(a, +this.getParentSvg(),this.getInverseScreenCTM()),this.zoom(b.x,b.y,d)):(b=this.scrollX-d.x,c=this.scrollY-d.y,a.shiftKey&&!d.x&&(b=this.scrollX-d.y,c=this.scrollY),this.scroll(b,c));a.preventDefault()}}}; +module$exports$Blockly$WorkspaceSvg.prototype.getBlocksBoundingBox=function(){var a=this.getTopBoundedElements();if(!a.length)return new module$exports$Blockly$utils$Rect(0,0,0,0);for(var b=a[0].getBoundingRectangle(),c=1;cb.bottom&&(b.bottom=d.bottom),d.leftb.right&&(b.right=d.right))}return b}; +module$exports$Blockly$WorkspaceSvg.prototype.cleanUp=function(){this.setResizesEnabled(!1);(0,module$exports$Blockly$Events$utils.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}(0,module$exports$Blockly$Events$utils.setGroup)(!1);this.setResizesEnabled(!0)}; +module$exports$Blockly$WorkspaceSvg.prototype.showContextMenu=function(a){if(!this.options.readOnly&&!this.isFlyout){var b=module$exports$Blockly$ContextMenuRegistry.registry.getContextMenuOptions(module$exports$Blockly$ContextMenuRegistry.ScopeType.WORKSPACE,{workspace:this});this.configureContextMenu&&this.configureContextMenu(b,a);(0,module$exports$Blockly$ContextMenu.show)(a,b,this.RTL)}}; +module$exports$Blockly$WorkspaceSvg.prototype.updateToolbox=function(a){if(a=(0,module$exports$Blockly$utils$toolbox.convertToolboxDefToJson)(a)){if(!this.options.languageTree)throw Error("Existing toolbox is null. Can't create new toolbox.");if((0,module$exports$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.");};module$exports$Blockly$WorkspaceSvg.prototype.markFocused=function(){this.options.parentWorkspace?this.options.parentWorkspace.markFocused():((0,module$exports$Blockly$common.setMainWorkspace)(this),this.setBrowserFocus())}; +module$exports$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})}}}; +module$exports$Blockly$WorkspaceSvg.prototype.zoom=function(a,b,c){c=Math.pow(this.options.zoomOptions.scaleSpeed,c);var d=this.scale*c;if(this.scale!=d){d>this.options.zoomOptions.maxScale?c=this.options.zoomOptions.maxScale/this.scale:dthis.options.zoomOptions.maxScale?a=this.options.zoomOptions.maxScale:this.options.zoomOptions.minScale&&a90-b||a>-90-b&&a<-90+b?!0:!1}; +module$exports$Blockly$HorizontalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_||this.autoClose||!this.isVisible())return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.top;return this.toolboxPosition_==module$exports$Blockly$utils$toolbox.Position.TOP?new module$exports$Blockly$utils$Rect(-1E9,b+a.height,-1E9,1E9):new module$exports$Blockly$utils$Rect(b,1E9,-1E9,1E9)}; +module$exports$Blockly$HorizontalFlyout.prototype.reflowInternal_=function(){this.workspace_.scale=this.getFlyoutScale();for(var a=0,b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++)a=Math.max(a,d.getHeightWidth().height);c=this.buttons_;d=0;for(var e;e=c[d];d++)a=Math.max(a,e.height);a+=1.5*this.MARGIN;a*=this.workspace_.scale;a+=module$exports$Blockly$Scrollbar.scrollbarThickness;if(this.height_!=a){for(c=0;d=b[c];c++)d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d);this.targetWorkspace.toolboxPosition!= +this.toolboxPosition_||this.toolboxPosition_!=module$exports$Blockly$utils$toolbox.Position.TOP||this.targetWorkspace.getToolbox()||this.targetWorkspace.translate(this.targetWorkspace.scrollX,this.targetWorkspace.scrollY+a);this.height_=a;this.position();this.targetWorkspace.recordDragTargets()}};(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,module$exports$Blockly$registry.DEFAULT,module$exports$Blockly$HorizontalFlyout);var module$exports$Blockly$IAutoHideable=function(){};var module$exports$Blockly$IPositionable=function(){};var module$exports$Blockly$IRegistrableField={};var module$exports$Blockly$IStyleable=function(){};var module$exports$Blockly$IToolbox=function(){};var module$exports$Blockly$Mutator=function(a){module$exports$Blockly$Mutator.superClass_.constructor.call(this,null);this.quarkNames_=a};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Mutator,module$exports$Blockly$Icon);module$exports$Blockly$Mutator.prototype.workspace_=null;module$exports$Blockly$Mutator.prototype.workspaceWidth_=0;module$exports$Blockly$Mutator.prototype.workspaceHeight_=0;module$exports$Blockly$Mutator.prototype.setBlock=function(a){this.block_=a}; +module$exports$Blockly$Mutator.prototype.getWorkspace=function(){return this.workspace_}; +module$exports$Blockly$Mutator.prototype.drawIcon_=function(a){(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"blocklyIconShape",rx:"4",ry:"4",height:"16",width:"16"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$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); +(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE,{"class":"blocklyIconShape",r:"2.7",cx:"8",cy:"8"},a)};module$exports$Blockly$Mutator.prototype.iconClick_=function(a){this.block_.isEditable()&&module$exports$Blockly$Icon.prototype.iconClick_.call(this,a)}; +module$exports$Blockly$Mutator.prototype.createEditor_=function(){this.svgDialog_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.SVG,{x:module$exports$Blockly$Bubble.BORDER_WIDTH,y:module$exports$Blockly$Bubble.BORDER_WIDTH},null);if(this.quarkNames_.length){var a=(0,module$exports$Blockly$utils$xml.createElement)("xml");for(var b=0,c;c=this.quarkNames_[b];b++){var d=(0,module$exports$Blockly$utils$xml.createElement)("block");d.setAttribute("type",c);a.appendChild(d)}}else a= +null;b=new module$exports$Blockly$Options({disable:!1,parentWorkspace:this.block_.workspace,media:this.block_.workspace.options.pathToMedia,rtl:this.block_.RTL,horizontalLayout:!1,renderer:this.block_.workspace.options.renderer,rendererOverrides:this.block_.workspace.options.rendererOverrides});b.toolboxPosition=this.block_.RTL?module$exports$Blockly$utils$toolbox.Position.RIGHT:module$exports$Blockly$utils$toolbox.Position.LEFT;if(c=!!a)b.languageTree=(0,module$exports$Blockly$utils$toolbox.convertToolboxDefToJson)(a); +this.workspace_=new module$exports$Blockly$WorkspaceSvg(b);this.workspace_.isMutator=!0;this.workspace_.addChangeListener(module$exports$Blockly$Events$utils.disableOrphans);a=c?this.workspace_.addFlyout(module$exports$Blockly$utils$Svg.G):null;b=this.workspace_.createDom("blocklyMutatorBackground");a&&b.insertBefore(a,this.workspace_.svgBlockCanvas_);this.svgDialog_.appendChild(b);return this.svgDialog_}; +module$exports$Blockly$Mutator.prototype.updateEditable=function(){module$exports$Blockly$Mutator.superClass_.updateEditable.call(this);this.block_.isInFlyout||(this.block_.isEditable()?this.iconGroup_&&(0,module$exports$Blockly$utils$dom.removeClass)(this.iconGroup_,"blocklyIconGroupReadonly"):(this.setVisible(!1),this.iconGroup_&&(0,module$exports$Blockly$utils$dom.addClass)(this.iconGroup_,"blocklyIconGroupReadonly")))}; +module$exports$Blockly$Mutator.prototype.resizeBubble_=function(){var a=2*module$exports$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.getWorkspace().getMetricsManager().getScrollMetrics();d=Math.max(d,f.height+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.workspace_.setCachedParentSvgSize(this.workspaceWidth_,this.workspaceHeight_);this.block_.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a));this.workspace_.resize()};module$exports$Blockly$Mutator.prototype.onBubbleMove_=function(){this.workspace_&&this.workspace_.recordDragTargets()}; +module$exports$Blockly$Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if((0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.BUBBLE_OPEN))(this.block_,a,"mutator")),a){this.bubble_=new module$exports$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=void 0;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.updateWorkspace_();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)};module$exports$Blockly$Mutator.prototype.workspaceChanged_=function(a){a.isUiEvent||a.type==module$exports$Blockly$Events$utils.CHANGE&&"disabled"==a.element||a.type==module$exports$Blockly$Events$utils.CREATE||this.updateWorkspace_()}; +module$exports$Blockly$Mutator.prototype.updateWorkspace_=function(){if(!this.workspace_.isDragging())for(var a=this.workspace_.getTopBlocks(!1),b=0,c=void 0;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_){(0,module$exports$Blockly$Events$utils.setGroup)(!0);var g=this.block_;a=module$exports$Blockly$Events$BlockChange.getExtraBlockState_(g); +b=g.rendered;g.rendered=!1;g.compose(this.rootBlock_);g.rendered=b;g.initSvg();g.rendered&&g.render();b=module$exports$Blockly$Events$BlockChange.getExtraBlockState_(g);if(a!=b){(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CHANGE))(g,"mutation",null,a,b));var h=(0,module$exports$Blockly$Events$utils.getGroup)();setTimeout(function(){(0,module$exports$Blockly$Events$utils.setGroup)(h);g.bumpNeighbours();(0,module$exports$Blockly$Events$utils.setGroup)(!1)}, +module$exports$Blockly$internalConstants.BUMP_DELAY)}this.workspace_.isDragging()||this.resizeBubble_();(0,module$exports$Blockly$Events$utils.setGroup)(!1)}};module$exports$Blockly$Mutator.prototype.dispose=function(){this.block_.mutator=null;module$exports$Blockly$Icon.prototype.dispose.call(this)}; +module$exports$Blockly$Mutator.prototype.updateBlockStyle=function(){var a=this.workspace_;if(a&&a.getAllBlocks(!1)){for(var b=a.getAllBlocks(!1),c=0,d;d=b[c];c++)d.setStyle(d.getStyleName());if(a=a.getFlyout())for(a=a.workspace_.getAllBlocks(!1),b=0;c=a[b];b++)c.setStyle(c.getStyleName())}}; +module$exports$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)};module$exports$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};var module$exports$Blockly$Procedures={DEFAULT_ARG:"x",allProcedures:function(a){var b=a.getBlocksByType("procedures_defnoreturn",!1).map(function(c){return c.getProcedureDef()});a=a.getBlocksByType("procedures_defreturn",!1).map(function(c){return c.getProcedureDef()});b.sort(module$contents$Blockly$Procedures_procTupleComparator);a.sort(module$contents$Blockly$Procedures_procTupleComparator);return[b,a]}},module$contents$Blockly$Procedures_procTupleComparator=function(a,b){return a[0].localeCompare(b[0], +void 0,{sensitivity:"base"})};module$exports$Blockly$Procedures.findLegalName=function(a,b){if(b.isInFlyout)return a;for(a=a||Blockly.Msg.UNNAMED_KEY||"unnamed";!module$contents$Blockly$Procedures_isLegalName(a,b.workspace,b);){var c=a.match(/^(.*?)(\d+)$/);a=c?c[1]+(parseInt(c[2],10)+1):a+"2"}return a};var module$contents$Blockly$Procedures_isLegalName=function(a,b,c){return!(0,module$exports$Blockly$Procedures.isNameUsed)(a,b,c)}; +module$exports$Blockly$Procedures.isNameUsed=function(a,b,c){b=b.getAllBlocks(!1);for(var d=0;db.indexOf(d))throw Error(d+" is not a valid modifier key.");}; +module$exports$Blockly$ShortcutRegistry.prototype.createSerializedKey=function(a,b){var c="";if(b){this.checkModifiers_(b);for(var d in module$exports$Blockly$ShortcutRegistry.modifierKeys)-1>>/handdelete.cur"), auto;',"}",".blocklyToolboxGrab {",'cursor: url("<<>>/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;","}"]);(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.TOOLBOX,module$exports$Blockly$registry.DEFAULT,module$exports$Blockly$Toolbox);var module$exports$Blockly$uiPosition={verticalPosition:{TOP:0,BOTTOM:1},horizontalPosition:{LEFT:0,RIGHT:1},bumpDirection:{UP:0,DOWN:1},getStartPositionRect:function(a,b,c,d,e,f){var g=f.scrollbar&&f.scrollbar.canScrollVertically();a.horizontal===module$exports$Blockly$uiPosition.horizontalPosition.LEFT?(c=e.absoluteMetrics.left+c,g&&f.RTL&&(c+=module$exports$Blockly$Scrollbar.scrollbarThickness)):(c=e.absoluteMetrics.left+e.viewMetrics.width-b.width-c,g&&!f.RTL&&(c-=module$exports$Blockly$Scrollbar.scrollbarThickness)); +a.vertical===module$exports$Blockly$uiPosition.verticalPosition.TOP?a=e.absoluteMetrics.top+d:(a=e.absoluteMetrics.top+e.viewMetrics.height-b.height-d,f.scrollbar&&f.scrollbar.canScrollHorizontally()&&(a-=module$exports$Blockly$Scrollbar.scrollbarThickness));return new module$exports$Blockly$utils$Rect(a,a+b.height,c,c+b.width)},getCornerOppositeToolbox:function(a,b){return{horizontal:b.toolboxMetrics.position===module$exports$Blockly$utils$toolbox.Position.LEFT||a.horizontalLayout&&!a.RTL?module$exports$Blockly$uiPosition.horizontalPosition.RIGHT: +module$exports$Blockly$uiPosition.horizontalPosition.LEFT,vertical:b.toolboxMetrics.position===module$exports$Blockly$utils$toolbox.Position.BOTTOM?module$exports$Blockly$uiPosition.verticalPosition.TOP:module$exports$Blockly$uiPosition.verticalPosition.BOTTOM}},bumpPositionRect:function(a,b,c,d){for(var e=a.left,f=a.right-a.left,g=a.bottom-a.top,h=0;h=this.workspace_.options.maxTrashcanContents||(a=new module$exports$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,move:{scrollbars:!0}}), +this.workspace_.horizontalLayout?(a.toolboxPosition=this.workspace_.toolboxPosition==module$exports$Blockly$utils$toolbox.Position.TOP?module$exports$Blockly$utils$toolbox.Position.BOTTOM:module$exports$Blockly$utils$toolbox.Position.TOP,this.flyout=new ((0,module$exports$Blockly$registry.getClassFromOptions)(module$exports$Blockly$registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX,this.workspace_.options,!0))(a)):(a.toolboxPosition=this.workspace_.toolboxPosition==module$exports$Blockly$utils$toolbox.Position.RIGHT? +module$exports$Blockly$utils$toolbox.Position.LEFT:module$exports$Blockly$utils$toolbox.Position.RIGHT,this.flyout=new ((0,module$exports$Blockly$registry.getClassFromOptions)(module$exports$Blockly$registry.Type.FLYOUTS_VERTICAL_TOOLBOX,this.workspace_.options,!0))(a)),this.workspace_.addChangeListener(this.onDelete_.bind(this)))};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$Trashcan,module$exports$Blockly$DeleteArea); +var module$contents$Blockly$Trashcan_WIDTH=47,module$contents$Blockly$Trashcan_BODY_HEIGHT=44,module$contents$Blockly$Trashcan_LID_HEIGHT=16,module$contents$Blockly$Trashcan_MARGIN_VERTICAL=20,module$contents$Blockly$Trashcan_MARGIN_HORIZONTAL=20,module$contents$Blockly$Trashcan_MARGIN_HOTSPOT=10,module$contents$Blockly$Trashcan_SPRITE_LEFT=0,module$contents$Blockly$Trashcan_SPRITE_TOP=32,module$contents$Blockly$Trashcan_HAS_BLOCKS_LID_ANGLE=.1,module$contents$Blockly$Trashcan_ANIMATION_LENGTH=80, +module$contents$Blockly$Trashcan_ANIMATION_FRAMES=4,module$contents$Blockly$Trashcan_OPACITY_MIN=.4,module$contents$Blockly$Trashcan_OPACITY_MAX=.8,module$contents$Blockly$Trashcan_MAX_LID_ANGLE=45;module$exports$Blockly$Trashcan.prototype.isLidOpen=!1;module$exports$Blockly$Trashcan.prototype.minOpenness_=0;module$exports$Blockly$Trashcan.prototype.svgGroup_=null;module$exports$Blockly$Trashcan.prototype.svgLid_=null;module$exports$Blockly$Trashcan.prototype.lidTask_=0; +module$exports$Blockly$Trashcan.prototype.lidOpen_=0;module$exports$Blockly$Trashcan.prototype.left_=0;module$exports$Blockly$Trashcan.prototype.top_=0;module$exports$Blockly$Trashcan.prototype.initialized_=!1; +module$exports$Blockly$Trashcan.prototype.createDom=function(){this.svgGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyTrash"},null);var a=String(Math.random()).substring(2);var b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CLIPPATH,{id:"blocklyTrashBodyClipPath"+a},this.svgGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{width:module$contents$Blockly$Trashcan_WIDTH, +height:module$contents$Blockly$Trashcan_BODY_HEIGHT,y:module$contents$Blockly$Trashcan_LID_HEIGHT},b);var c=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE,{width:module$exports$Blockly$internalConstants.SPRITE.width,x:-module$contents$Blockly$Trashcan_SPRITE_LEFT,height:module$exports$Blockly$internalConstants.SPRITE.height,y:-module$contents$Blockly$Trashcan_SPRITE_TOP,"clip-path":"url(#blocklyTrashBodyClipPath"+a+")"},this.svgGroup_);c.setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS, +"xlink:href",this.workspace_.options.pathToMedia+module$exports$Blockly$internalConstants.SPRITE.url);b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CLIPPATH,{id:"blocklyTrashLidClipPath"+a},this.svgGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{width:module$contents$Blockly$Trashcan_WIDTH,height:module$contents$Blockly$Trashcan_LID_HEIGHT},b);this.svgLid_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE, +{width:module$exports$Blockly$internalConstants.SPRITE.width,x:-module$contents$Blockly$Trashcan_SPRITE_LEFT,height:module$exports$Blockly$internalConstants.SPRITE.height,y:-module$contents$Blockly$Trashcan_SPRITE_TOP,"clip-path":"url(#blocklyTrashLidClipPath"+a+")"},this.svgGroup_);this.svgLid_.setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+module$exports$Blockly$internalConstants.SPRITE.url);(0,module$exports$Blockly$browserEvents.bind)(this.svgGroup_, +"mousedown",this,this.blockMouseDownWhenOpenable_);(0,module$exports$Blockly$browserEvents.bind)(this.svgGroup_,"mouseup",this,this.click);(0,module$exports$Blockly$browserEvents.bind)(c,"mouseover",this,this.mouseOver_);(0,module$exports$Blockly$browserEvents.bind)(c,"mouseout",this,this.mouseOut_);this.animateLid_();return this.svgGroup_}; +module$exports$Blockly$Trashcan.prototype.init=function(){0 +this.minOpenness_&&1>this.lidOpen_&&(this.lidTask_=setTimeout(this.animateLid_.bind(this),module$contents$Blockly$Trashcan_ANIMATION_LENGTH/a))}; +module$exports$Blockly$Trashcan.prototype.setLidAngle_=function(a){var b=this.workspace_.toolboxPosition==module$exports$Blockly$utils$toolbox.Position.RIGHT||this.workspace_.horizontalLayout&&this.workspace_.RTL;this.svgLid_.setAttribute("transform","rotate("+(b?-a:a)+","+(b?4:module$contents$Blockly$Trashcan_WIDTH-4)+","+(module$contents$Blockly$Trashcan_LID_HEIGHT-2)+")")}; +module$exports$Blockly$Trashcan.prototype.setMinOpenness_=function(a){this.minOpenness_=a;this.isLidOpen||this.setLidAngle_(a*module$contents$Blockly$Trashcan_MAX_LID_ANGLE)};module$exports$Blockly$Trashcan.prototype.closeLid=function(){this.setLidOpen(!1)};module$exports$Blockly$Trashcan.prototype.click=function(){this.hasContents_()&&this.openFlyout()}; +module$exports$Blockly$Trashcan.prototype.fireUiEvent_=function(a){a=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.TRASHCAN_OPEN))(a,this.workspace_.id);(0,module$exports$Blockly$Events$utils.fire)(a)};module$exports$Blockly$Trashcan.prototype.blockMouseDownWhenOpenable_=function(a){!this.contentsIsOpen()&&this.hasContents_()&&a.stopPropagation()};module$exports$Blockly$Trashcan.prototype.mouseOver_=function(){this.hasContents_()&&this.setLidOpen(!0)}; +module$exports$Blockly$Trashcan.prototype.mouseOut_=function(){this.setLidOpen(!1)};module$exports$Blockly$Trashcan.prototype.onDelete_=function(a){if(!(0>=this.workspace_.options.maxTrashcanContents||a.type!=module$exports$Blockly$Events$utils.DELETE||a.wasShadow)&&(a=this.cleanBlockJson_(a.oldJson),-1==this.contents_.indexOf(a))){for(this.contents_.unshift(a);this.contents_.length>this.workspace_.options.maxTrashcanContents;)this.contents_.pop();this.setMinOpenness_(module$contents$Blockly$Trashcan_HAS_BLOCKS_LID_ANGLE)}}; +module$exports$Blockly$Trashcan.prototype.cleanBlockJson_=function(a){function b(c){if(c){delete c.id;delete c.x;delete c.y;delete c.enabled;if(c.icons&&c.icons.comment){var d=c.icons.comment;delete d.height;delete d.width;delete d.pinned}d=c.inputs;for(var e in d){var f=d[e];b(f.block);b(f.shadow)}c.next&&(c=c.next,b(c.block),b(c.shadow))}}a=JSON.parse(JSON.stringify(a));b(a);a.kind="BLOCK";return JSON.stringify(a)};var module$exports$Blockly$VariablesDynamic={onCreateVariableButtonClick_String:function(a){(0,module$exports$Blockly$Variables.createVariableButtonHandler)(a.getTargetWorkspace(),void 0,"String")},onCreateVariableButtonClick_Number:function(a){(0,module$exports$Blockly$Variables.createVariableButtonHandler)(a.getTargetWorkspace(),void 0,"Number")},onCreateVariableButtonClick_Colour:function(a){(0,module$exports$Blockly$Variables.createVariableButtonHandler)(a.getTargetWorkspace(),void 0,"Colour")}, +flyoutCategory:function(a){var b=[],c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_STRING_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_STRING");b.push(c);c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_NUMBER_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_NUMBER");b.push(c);c=document.createElement("button");c.setAttribute("text",Blockly.Msg.NEW_COLOUR_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE_COLOUR");b.push(c); +a.registerButtonCallback("CREATE_VARIABLE_STRING",module$exports$Blockly$VariablesDynamic.onCreateVariableButtonClick_String);a.registerButtonCallback("CREATE_VARIABLE_NUMBER",module$exports$Blockly$VariablesDynamic.onCreateVariableButtonClick_Number);a.registerButtonCallback("CREATE_VARIABLE_COLOUR",module$exports$Blockly$VariablesDynamic.onCreateVariableButtonClick_Colour);a=(0,module$exports$Blockly$VariablesDynamic.flyoutCategoryBlocks)(a);return b=b.concat(a)},flyoutCategoryBlocks:function(a){a= +a.getAllVariables();var b=[];if(0-b||a<-180+b||a>180-b?!0:!1}; +module$exports$Blockly$VerticalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_||this.autoClose||!this.isVisible())return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.left;return this.toolboxPosition_==module$exports$Blockly$utils$toolbox.Position.LEFT?new module$exports$Blockly$utils$Rect(-1E9,1E9,-1E9,b+a.width):new module$exports$Blockly$utils$Rect(-1E9,1E9,b,1E9)}; +module$exports$Blockly$VerticalFlyout.prototype.reflowInternal_=function(){this.workspace_.scale=this.getFlyoutScale();for(var a=0,b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getHeightWidth().width;d.outputConnection&&(e-=this.tabWidth_);a=Math.max(a,e)}for(c=0;d=this.buttons_[c];c++)a=Math.max(a,d.width);a+=1.5*this.MARGIN+this.tabWidth_;a*=this.workspace_.scale;a+=module$exports$Blockly$Scrollbar.scrollbarThickness;if(this.width_!=a){for(c=0;d=b[c];c++){if(this.RTL){e=d.getRelativeToSurfaceXY().x; +var f=a/this.workspace_.scale-this.MARGIN;d.outputConnection||(f-=this.tabWidth_);d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}if(this.RTL)for(b=0;c=this.buttons_[b];b++)d=c.getPosition().y,c.moveTo(a/this.workspace_.scale-c.width-this.MARGIN-this.tabWidth_,d);this.targetWorkspace.toolboxPosition!=this.toolboxPosition_||this.toolboxPosition_!=module$exports$Blockly$utils$toolbox.Position.LEFT||this.targetWorkspace.getToolbox()||this.targetWorkspace.translate(this.targetWorkspace.scrollX+ +a,this.targetWorkspace.scrollY);this.width_=a;this.position();this.targetWorkspace.recordDragTargets()}};(0,module$exports$Blockly$registry.register)(module$exports$Blockly$registry.Type.FLYOUTS_VERTICAL_TOOLBOX,module$exports$Blockly$registry.DEFAULT,module$exports$Blockly$VerticalFlyout);var module$exports$Blockly$WorkspaceComment=function(a,b,c,d,e){this.id=e&&!a.getCommentById(e)?e:(0,module$exports$Blockly$utils$idGenerator.genUid)();a.addTopComment(this);this.xy_=new module$exports$Blockly$utils$Coordinate(0,0);this.height_=c;this.width_=d;this.workspace=a;this.RTL=a.RTL;this.editable_=this.movable_=this.deletable_=!0;this.content_=b;this.disposed_=!1;this.isComment=!0;module$exports$Blockly$WorkspaceComment.fireCreateEvent(this)}; +module$exports$Blockly$WorkspaceComment.prototype.dispose=function(){this.disposed_||((0,module$exports$Blockly$Events$utils.isEnabled)()&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_DELETE))(this)),this.workspace.removeTopComment(this),this.disposed_=!0)};module$exports$Blockly$WorkspaceComment.prototype.getHeight=function(){return this.height_}; +module$exports$Blockly$WorkspaceComment.prototype.setHeight=function(a){this.height_=a};module$exports$Blockly$WorkspaceComment.prototype.getWidth=function(){return this.width_};module$exports$Blockly$WorkspaceComment.prototype.setWidth=function(a){this.width_=a};module$exports$Blockly$WorkspaceComment.prototype.getXY=function(){return new module$exports$Blockly$utils$Coordinate(this.xy_.x,this.xy_.y)}; +module$exports$Blockly$WorkspaceComment.prototype.moveBy=function(a,b){var c=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_MOVE))(this);this.xy_.translate(a,b);c.recordNew();(0,module$exports$Blockly$Events$utils.fire)(c)};module$exports$Blockly$WorkspaceComment.prototype.isDeletable=function(){return this.deletable_&&!(this.workspace&&this.workspace.options.readOnly)}; +module$exports$Blockly$WorkspaceComment.prototype.setDeletable=function(a){this.deletable_=a};module$exports$Blockly$WorkspaceComment.prototype.isMovable=function(){return this.movable_&&!(this.workspace&&this.workspace.options.readOnly)};module$exports$Blockly$WorkspaceComment.prototype.setMovable=function(a){this.movable_=a};module$exports$Blockly$WorkspaceComment.prototype.isEditable=function(){return this.editable_&&!(this.workspace&&this.workspace.options.readOnly)}; +module$exports$Blockly$WorkspaceComment.prototype.setEditable=function(a){this.editable_=a};module$exports$Blockly$WorkspaceComment.prototype.getContent=function(){return this.content_};module$exports$Blockly$WorkspaceComment.prototype.setContent=function(a){this.content_!=a&&((0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_CHANGE))(this,this.content_,a)),this.content_=a)}; +module$exports$Blockly$WorkspaceComment.prototype.toXmlWithXY=function(a){a=this.toXml(a);a.setAttribute("x",Math.round(this.xy_.x));a.setAttribute("y",Math.round(this.xy_.y));a.setAttribute("h",this.height_);a.setAttribute("w",this.width_);return a};module$exports$Blockly$WorkspaceComment.prototype.toXml=function(a){var b=(0,module$exports$Blockly$utils$xml.createElement)("comment");a||(b.id=this.id);b.textContent=this.getContent();return b}; +module$exports$Blockly$WorkspaceComment.fireCreateEvent=function(a){if((0,module$exports$Blockly$Events$utils.isEnabled)()){var b=(0,module$exports$Blockly$Events$utils.getGroup)();b||(0,module$exports$Blockly$Events$utils.setGroup)(!0);try{(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_CREATE))(a))}finally{b||(0,module$exports$Blockly$Events$utils.setGroup)(!1)}}}; +module$exports$Blockly$WorkspaceComment.fromXml=function(a,b){var c=module$exports$Blockly$WorkspaceComment.parseAttributes(a);b=new module$exports$Blockly$WorkspaceComment(b,c.content,c.h,c.w,c.id);c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);isNaN(c)||isNaN(a)||b.moveBy(c,a);module$exports$Blockly$WorkspaceComment.fireCreateEvent(b);return b}; +module$exports$Blockly$WorkspaceComment.parseAttributes=function(a){var b=a.getAttribute("h"),c=a.getAttribute("w");return{id:a.getAttribute("id"),h:b?parseInt(b,10):100,w:c?parseInt(c,10):100,x:parseInt(a.getAttribute("x"),10),y:parseInt(a.getAttribute("y"),10),content:a.textContent}};var module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE=8,module$contents$Blockly$WorkspaceCommentSvg_BORDER_RADIUS=3,module$contents$Blockly$WorkspaceCommentSvg_TEXTAREA_OFFSET=2,module$exports$Blockly$WorkspaceCommentSvg=function(a,b,c,d,e){this.onMouseMoveWrapper_=this.onMouseUpWrapper_=null;this.svgGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyComment"},null);this.svgGroup_.translate_="";this.svgRect_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT, +{"class":"blocklyCommentRect",x:0,y:0,rx:module$contents$Blockly$WorkspaceCommentSvg_BORDER_RADIUS,ry:module$contents$Blockly$WorkspaceCommentSvg_BORDER_RADIUS});this.svgGroup_.appendChild(this.svgRect_);this.rendered_=!1;this.useDragSurface_=(0,module$exports$Blockly$utils.is3dSupported)()&&!!a.getBlockDragSurface();module$exports$Blockly$WorkspaceCommentSvg.superClass_.constructor.call(this,a,b,c,d,e);this.render()}; +(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$WorkspaceCommentSvg,module$exports$Blockly$WorkspaceComment);module$exports$Blockly$WorkspaceCommentSvg.DEFAULT_SIZE=100;module$exports$Blockly$WorkspaceCommentSvg.TOP_OFFSET=10; +module$exports$Blockly$WorkspaceCommentSvg.prototype.dispose=function(){this.disposed_||((0,module$exports$Blockly$common.getSelected)()==this&&(this.unselect(),this.workspace.cancelCurrentGesture()),(0,module$exports$Blockly$Events$utils.isEnabled)()&&(0,module$exports$Blockly$Events$utils.fire)(new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_DELETE))(this)),(0,module$exports$Blockly$utils$dom.removeNode)(this.svgGroup_),this.disposeInternal_(),(0,module$exports$Blockly$Events$utils.disable)(), +module$exports$Blockly$WorkspaceCommentSvg.superClass_.dispose.call(this),(0,module$exports$Blockly$Events$utils.enable)())}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.initSvg=function(a){if(!this.workspace.rendered)throw TypeError("Workspace is headless.");this.workspace.options.readOnly||this.eventsInit_||((0,module$exports$Blockly$browserEvents.conditionalBind)(this.svgRectTarget_,"mousedown",this,this.pathMouseDown_),(0,module$exports$Blockly$browserEvents.conditionalBind)(this.svgHandleTarget_,"mousedown",this,this.pathMouseDown_));this.eventsInit_=!0;this.updateMovable();this.getSvgRoot().parentNode||this.workspace.getBubbleCanvas().appendChild(this.getSvgRoot()); +!a&&this.textarea_&&this.textarea_.select()};module$exports$Blockly$WorkspaceCommentSvg.prototype.pathMouseDown_=function(a){var b=this.workspace.getGesture(a);b&&b.handleBubbleStart(a,this)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.showContextMenu=function(a){if(!this.workspace.options.readOnly){var b=[];this.isDeletable()&&this.isMovable()&&(b.push((0,module$exports$Blockly$ContextMenu.commentDuplicateOption)(this)),b.push((0,module$exports$Blockly$ContextMenu.commentDeleteOption)(this)));(0,module$exports$Blockly$ContextMenu.show)(a,b,this.RTL)}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.select=function(){if((0,module$exports$Blockly$common.getSelected)()!=this){var a=null;if((0,module$exports$Blockly$common.getSelected)()){a=(0,module$exports$Blockly$common.getSelected)().id;(0,module$exports$Blockly$Events$utils.disable)();try{(0,module$exports$Blockly$common.getSelected)().unselect()}finally{(0,module$exports$Blockly$Events$utils.enable)()}}a=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.SELECTED))(a, +this.id,this.workspace.id);(0,module$exports$Blockly$Events$utils.fire)(a);(0,module$exports$Blockly$common.setSelected)(this);this.addSelect()}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.unselect=function(){if((0,module$exports$Blockly$common.getSelected)()==this){var a=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.SELECTED))(this.id,null,this.workspace.id);(0,module$exports$Blockly$Events$utils.fire)(a);(0,module$exports$Blockly$common.setSelected)(null);this.removeSelect();this.blurFocus()}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.addSelect=function(){(0,module$exports$Blockly$utils$dom.addClass)(this.svgGroup_,"blocklySelected");this.setFocus()};module$exports$Blockly$WorkspaceCommentSvg.prototype.removeSelect=function(){(0,module$exports$Blockly$utils$dom.removeClass)(this.svgGroup_,"blocklySelected");this.blurFocus()};module$exports$Blockly$WorkspaceCommentSvg.prototype.addFocus=function(){(0,module$exports$Blockly$utils$dom.addClass)(this.svgGroup_,"blocklyFocused")}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.removeFocus=function(){(0,module$exports$Blockly$utils$dom.removeClass)(this.svgGroup_,"blocklyFocused")}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0,c=this.useDragSurface_?this.workspace.getBlockDragSurface().getGroup():null,d=this.getSvgRoot();if(d){do{var e=(0,module$exports$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.getBubbleCanvas()&&d!=c)}return this.xy_= +new module$exports$Blockly$utils$Coordinate(a,b)};module$exports$Blockly$WorkspaceCommentSvg.prototype.moveBy=function(a,b){var c=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.COMMENT_MOVE))(this),d=this.getRelativeToSurfaceXY();this.translate(d.x+a,d.y+b);this.xy_=new module$exports$Blockly$utils$Coordinate(d.x+a,d.y+b);c.recordNew();(0,module$exports$Blockly$Events$utils.fire)(c);this.workspace.resizeContents()}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.translate=function(a,b){this.xy_=new module$exports$Blockly$utils$Coordinate(a,b);this.getSvgRoot().setAttribute("transform","translate("+a+","+b+")")};module$exports$Blockly$WorkspaceCommentSvg.prototype.moveToDragSurface=function(){if(this.useDragSurface_){var a=this.getRelativeToSurfaceXY();this.clearTransformAttributes_();this.workspace.getBlockDragSurface().translateSurface(a.x,a.y);this.workspace.getBlockDragSurface().setBlocksAndShow(this.getSvgRoot())}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.moveDuringDrag=function(a,b){a?a.translateSurface(b.x,b.y):(this.svgGroup_.translate_="translate("+b.x+","+b.y+")",this.svgGroup_.setAttribute("transform",this.svgGroup_.translate_+this.svgGroup_.skew_))};module$exports$Blockly$WorkspaceCommentSvg.prototype.moveTo=function(a,b){this.translate(a,b)};module$exports$Blockly$WorkspaceCommentSvg.prototype.clearTransformAttributes_=function(){this.getSvgRoot().removeAttribute("transform")}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.getBoundingRectangle=function(){var a=this.getRelativeToSurfaceXY(),b=this.getHeightWidth(),c=a.y,d=a.y+b.height;if(this.RTL){var e=a.x-b.width;a=a.x}else e=a.x,a=a.x+b.width;return new module$exports$Blockly$utils$Rect(c,d,e,a)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.updateMovable=function(){this.isMovable()?(0,module$exports$Blockly$utils$dom.addClass)(this.svgGroup_,"blocklyDraggable"):(0,module$exports$Blockly$utils$dom.removeClass)(this.svgGroup_,"blocklyDraggable")};module$exports$Blockly$WorkspaceCommentSvg.prototype.setMovable=function(a){module$exports$Blockly$WorkspaceCommentSvg.superClass_.setMovable.call(this,a);this.updateMovable()}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.setEditable=function(a){module$exports$Blockly$WorkspaceCommentSvg.superClass_.setEditable.call(this,a);this.textarea_&&(this.textarea_.readOnly=!a)};module$exports$Blockly$WorkspaceCommentSvg.prototype.setDragging=function(a){a?(a=this.getSvgRoot(),a.translate_="",a.skew_="",(0,module$exports$Blockly$utils$dom.addClass)(this.svgGroup_,"blocklyDragging")):(0,module$exports$Blockly$utils$dom.removeClass)(this.svgGroup_,"blocklyDragging")}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.getSvgRoot=function(){return this.svgGroup_};module$exports$Blockly$WorkspaceCommentSvg.prototype.getContent=function(){return this.textarea_?this.textarea_.value:this.content_};module$exports$Blockly$WorkspaceCommentSvg.prototype.setContent=function(a){module$exports$Blockly$WorkspaceCommentSvg.superClass_.setContent.call(this,a);this.textarea_&&(this.textarea_.value=a)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.setDeleteStyle=function(a){a?(0,module$exports$Blockly$utils$dom.addClass)(this.svgGroup_,"blocklyDraggingDelete"):(0,module$exports$Blockly$utils$dom.removeClass)(this.svgGroup_,"blocklyDraggingDelete")};module$exports$Blockly$WorkspaceCommentSvg.prototype.setAutoLayout=function(a){}; +module$exports$Blockly$WorkspaceCommentSvg.fromXml=function(a,b,c){(0,module$exports$Blockly$Events$utils.disable)();try{var d=module$exports$Blockly$WorkspaceComment.parseAttributes(a);var e=new module$exports$Blockly$WorkspaceCommentSvg(b,d.content,d.h,d.w,d.id);b.rendered&&(e.initSvg(!0),e.render());if(!isNaN(d.x)&&!isNaN(d.y))if(b.RTL){var f=c||b.getWidth();e.moveBy(f-d.x,d.y)}else e.moveBy(d.x,d.y)}finally{(0,module$exports$Blockly$Events$utils.enable)()}module$exports$Blockly$WorkspaceComment.fireCreateEvent(e); +return e};module$exports$Blockly$WorkspaceCommentSvg.prototype.toXmlWithXY=function(a){var b;this.workspace.RTL&&(b=this.workspace.getWidth());a=this.toXml(a);var c=this.getRelativeToSurfaceXY();a.setAttribute("x",Math.round(this.workspace.RTL?b-c.x:c.x));a.setAttribute("y",Math.round(c.y));a.setAttribute("h",this.getHeight());a.setAttribute("w",this.getWidth());return a}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.toCopyData=function(){return{saveInfo:this.toXmlWithXY(),source:this.workspace,typeCounts:null}};module$exports$Blockly$WorkspaceCommentSvg.prototype.getHeightWidth=function(){return{width:this.getWidth(),height:this.getHeight()}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.render=function(){if(!this.rendered_){var a=this.getHeightWidth();this.createEditor_();this.svgGroup_.appendChild(this.foreignObject_);this.svgHandleTarget_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{"class":"blocklyCommentHandleTarget",x:0,y:0});this.svgGroup_.appendChild(this.svgHandleTarget_);this.svgRectTarget_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT, +{"class":"blocklyCommentTarget",x:0,y:0,rx:module$contents$Blockly$WorkspaceCommentSvg_BORDER_RADIUS,ry:module$contents$Blockly$WorkspaceCommentSvg_BORDER_RADIUS});this.svgGroup_.appendChild(this.svgRectTarget_);this.addResizeDom_();this.isDeletable()&&this.addDeleteDom_();this.setSize_(a.width,a.height);this.textarea_.value=this.content_;this.rendered_=!0;this.resizeGroup_&&(0,module$exports$Blockly$browserEvents.conditionalBind)(this.resizeGroup_,"mousedown",this,this.resizeMouseDown_);this.isDeletable()&& +((0,module$exports$Blockly$browserEvents.conditionalBind)(this.deleteGroup_,"mousedown",this,this.deleteMouseDown_),(0,module$exports$Blockly$browserEvents.conditionalBind)(this.deleteGroup_,"mouseout",this,this.deleteMouseOut_),(0,module$exports$Blockly$browserEvents.conditionalBind)(this.deleteGroup_,"mouseup",this,this.deleteMouseUp_))}}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.createEditor_=function(){this.foreignObject_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FOREIGNOBJECT,{x:0,y:module$exports$Blockly$WorkspaceCommentSvg.TOP_OFFSET,"class":"blocklyCommentForeignObject"},null);var a=document.createElementNS(module$exports$Blockly$utils$dom.HTML_NS,"body");a.setAttribute("xmlns",module$exports$Blockly$utils$dom.HTML_NS);a.className="blocklyMinimalBody";var b=document.createElementNS(module$exports$Blockly$utils$dom.HTML_NS, +"textarea");b.className="blocklyCommentTextarea";b.setAttribute("dir",this.RTL?"RTL":"LTR");b.readOnly=!this.isEditable();a.appendChild(b);this.textarea_=b;this.foreignObject_.appendChild(a);(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"wheel",this,function(c){c.stopPropagation()});(0,module$exports$Blockly$browserEvents.conditionalBind)(b,"change",this,function(c){this.setContent(b.value)});return this.foreignObject_}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.addResizeDom_=function(){this.resizeGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":this.RTL?"blocklyResizeSW":"blocklyResizeSE"},this.svgGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.POLYGON,{points:"0,x x,x x,0".replace(/x/g,module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE.toString())},this.resizeGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE, +{"class":"blocklyResizeLine",x1:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE/3,y1:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE-1,x2:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE-1,y2:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE/3},this.resizeGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE,{"class":"blocklyResizeLine",x1:2*module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE/3,y1:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE- +1,x2:module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE-1,y2:2*module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE/3},this.resizeGroup_)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.addDeleteDom_=function(){this.deleteGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyCommentDeleteIcon"},this.svgGroup_);this.deleteIconBorder_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CIRCLE,{"class":"blocklyDeleteIconShape",r:"7",cx:"7.5",cy:"7.5"},this.deleteGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE, +{x1:"5",y1:"10",x2:"10",y2:"5",stroke:"#fff","stroke-width":"2"},this.deleteGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.LINE,{x1:"5",y1:"5",x2:"10",y2:"10",stroke:"#fff","stroke-width":"2"},this.deleteGroup_)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.resizeMouseDown_=function(a){this.unbindDragEvents_();(0,module$exports$Blockly$browserEvents.isRightButton)(a)||(this.workspace.startDrag(a,new module$exports$Blockly$utils$Coordinate(this.workspace.RTL?-this.width_:this.width_,this.height_)),this.onMouseUpWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(document,"mouseup",this,this.resizeMouseUp_),this.onMouseMoveWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(document, +"mousemove",this,this.resizeMouseMove_),this.workspace.hideChaff());a.stopPropagation()};module$exports$Blockly$WorkspaceCommentSvg.prototype.deleteMouseDown_=function(a){(0,module$exports$Blockly$utils$dom.addClass)(this.deleteIconBorder_,"blocklyDeleteIconHighlighted");a.stopPropagation()};module$exports$Blockly$WorkspaceCommentSvg.prototype.deleteMouseOut_=function(a){(0,module$exports$Blockly$utils$dom.removeClass)(this.deleteIconBorder_,"blocklyDeleteIconHighlighted")}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.deleteMouseUp_=function(a){this.dispose();a.stopPropagation()};module$exports$Blockly$WorkspaceCommentSvg.prototype.unbindDragEvents_=function(){this.onMouseUpWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onMouseUpWrapper_),this.onMouseUpWrapper_=null);this.onMouseMoveWrapper_&&((0,module$exports$Blockly$browserEvents.unbind)(this.onMouseMoveWrapper_),this.onMouseMoveWrapper_=null)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.resizeMouseUp_=function(a){(0,module$exports$Blockly$Touch.clearTouchIdentifier)();this.unbindDragEvents_()};module$exports$Blockly$WorkspaceCommentSvg.prototype.resizeMouseMove_=function(a){this.autoLayout_=!1;a=this.workspace.moveDrag(a);this.setSize_(this.RTL?-a.x:a.x,a.y)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.resizeComment_=function(){var a=this.getHeightWidth(),b=module$exports$Blockly$WorkspaceCommentSvg.TOP_OFFSET,c=2*module$contents$Blockly$WorkspaceCommentSvg_TEXTAREA_OFFSET;this.foreignObject_.setAttribute("width",a.width);this.foreignObject_.setAttribute("height",a.height-b);this.RTL&&this.foreignObject_.setAttribute("x",-a.width);this.textarea_.style.width=a.width-c+"px";this.textarea_.style.height=a.height-c-b+"px"}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.setSize_=function(a,b){a=Math.max(a,45);b=Math.max(b,20+module$exports$Blockly$WorkspaceCommentSvg.TOP_OFFSET);this.width_=a;this.height_=b;this.svgRect_.setAttribute("width",a);this.svgRect_.setAttribute("height",b);this.svgRectTarget_.setAttribute("width",a);this.svgRectTarget_.setAttribute("height",b);this.svgHandleTarget_.setAttribute("width",a);this.svgHandleTarget_.setAttribute("height",module$exports$Blockly$WorkspaceCommentSvg.TOP_OFFSET); +this.RTL&&(this.svgRect_.setAttribute("transform","scale(-1 1)"),this.svgRectTarget_.setAttribute("transform","scale(-1 1)"));this.resizeGroup_&&(this.RTL?(this.resizeGroup_.setAttribute("transform","translate("+(-a+module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+","+(b-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+") scale(-1 1)"),this.deleteGroup_.setAttribute("transform","translate("+(-a+module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+","+-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE+ +") scale(-1 1)")):(this.resizeGroup_.setAttribute("transform","translate("+(a-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+","+(b-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+")"),this.deleteGroup_.setAttribute("transform","translate("+(a-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE)+","+-module$contents$Blockly$WorkspaceCommentSvg_RESIZE_SIZE+")")));this.resizeComment_()}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.disposeInternal_=function(){this.svgHandleTarget_=this.svgRectTarget_=this.foreignObject_=this.textarea_=null;this.disposed_=!0}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.setFocus=function(){var a=this;this.focused_=!0;setTimeout(function(){a.disposed_||(a.textarea_.focus(),a.addFocus(),(0,module$exports$Blockly$utils$dom.addClass)(a.svgRectTarget_,"blocklyCommentTargetFocused"),(0,module$exports$Blockly$utils$dom.addClass)(a.svgHandleTarget_,"blocklyCommentHandleTargetFocused"))},0)}; +module$exports$Blockly$WorkspaceCommentSvg.prototype.blurFocus=function(){var a=this;this.focused_=!1;setTimeout(function(){a.disposed_||(a.textarea_.blur(),a.removeFocus(),(0,module$exports$Blockly$utils$dom.removeClass)(a.svgRectTarget_,"blocklyCommentTargetFocused"),(0,module$exports$Blockly$utils$dom.removeClass)(a.svgHandleTarget_,"blocklyCommentHandleTargetFocused"))},0)};(0,module$exports$Blockly$Css.register)(".blocklyCommentForeignObject {,position: relative;,z-index: 0;,},.blocklyCommentRect {,fill: #E7DE8E;,stroke: #bcA903;,stroke-width: 1px;,},.blocklyCommentTarget {,fill: transparent;,stroke: #bcA903;,},.blocklyCommentTargetFocused {,fill: none;,},.blocklyCommentHandleTarget {,fill: none;,},.blocklyCommentHandleTargetFocused {,fill: transparent;,},.blocklyFocused>.blocklyCommentRect {,fill: #B9B272;,stroke: #B9B272;,},.blocklySelected>.blocklyCommentTarget {,stroke: #fc3;,stroke-width: 3px;,},.blocklyCommentDeleteIcon {,cursor: pointer;,fill: #000;,display: none;,},.blocklySelected > .blocklyCommentDeleteIcon {,display: block;,},.blocklyDeleteIconShape {,fill: #000;,stroke: #000;,stroke-width: 1px;,},.blocklyDeleteIconShape.blocklyDeleteIconHighlighted {,stroke: #fc3;,}".split(","));var module$exports$Blockly$WorkspaceDragSurfaceSvg=function(a){this.container_=a;this.createDom()};module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.SVG_=null;module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.container_=null; +module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.SVG,{xmlns:module$exports$Blockly$utils$dom.SVG_NS,"xmlns:html":module$exports$Blockly$utils$dom.HTML_NS,"xmlns:xlink":module$exports$Blockly$utils$dom.XLINK_NS,version:"1.1","class":"blocklyWsDragSurface blocklyOverflowVisible"},null),this.container_.appendChild(this.SVG_))}; +module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.translateSurface=function(a,b){a=a.toFixed(0);b=b.toFixed(0);this.SVG_.style.display="block";(0,module$exports$Blockly$utils$dom.setCssTransform)(this.SVG_,"translate3d("+a+"px, "+b+"px, 0)")};module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation=function(){return(0,module$exports$Blockly$utils.getRelativeXY)(this.SVG_)}; +module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.clearAndHide=function(a){if(!a)throw Error("Couldn't clear and hide the drag surface: missing new surface.");var b=this.SVG_.childNodes[0],c=this.SVG_.childNodes[1];if(!(b&&c&&(0,module$exports$Blockly$utils$dom.hasClass)(b,"blocklyBlockCanvas")&&(0,module$exports$Blockly$utils$dom.hasClass)(c,"blocklyBubbleCanvas")))throw Error("Couldn't clear and hide the drag surface. A node was missing.");null!=this.previousSibling_?(0,module$exports$Blockly$utils$dom.insertAfter)(b, +this.previousSibling_):a.insertBefore(b,a.firstChild);(0,module$exports$Blockly$utils$dom.insertAfter)(c,b);this.SVG_.style.display="none";if(this.SVG_.childNodes.length)throw Error("Drag surface was not cleared.");(0,module$exports$Blockly$utils$dom.setCssTransform)(this.SVG_,"");this.previousSibling_=null}; +module$exports$Blockly$WorkspaceDragSurfaceSvg.prototype.setContentsAndShow=function(a,b,c,d,e,f){if(this.SVG_.childNodes.length)throw Error("Already dragging a block.");this.previousSibling_=c;a.setAttribute("transform","translate(0, 0) scale("+f+")");b.setAttribute("transform","translate(0, 0) scale("+f+")");this.SVG_.setAttribute("width",d);this.SVG_.setAttribute("height",e);this.SVG_.appendChild(a);this.SVG_.appendChild(b);this.SVG_.style.display="block"};var module$exports$Blockly$ZoomControls=function(a){this.workspace_=a;this.id="zoomControls";this.zoomResetGroup_=this.zoomOutGroup_=this.zoomInGroup_=this.onZoomOutWrapper_=this.onZoomInWrapper_=this.onZoomResetWrapper_=null};module$exports$Blockly$ZoomControls.prototype.WIDTH_=32;module$exports$Blockly$ZoomControls.prototype.HEIGHT_=32;module$exports$Blockly$ZoomControls.prototype.SMALL_SPACING_=2;module$exports$Blockly$ZoomControls.prototype.LARGE_SPACING_=11; +module$exports$Blockly$ZoomControls.prototype.MARGIN_VERTICAL_=20;module$exports$Blockly$ZoomControls.prototype.MARGIN_HORIZONTAL_=20;module$exports$Blockly$ZoomControls.prototype.svgGroup_=null;module$exports$Blockly$ZoomControls.prototype.left_=0;module$exports$Blockly$ZoomControls.prototype.top_=0;module$exports$Blockly$ZoomControls.prototype.initialized_=!1; +module$exports$Blockly$ZoomControls.prototype.createDom=function(){this.svgGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{},null);var a=String(Math.random()).substring(2);this.createZoomOutSvg_(a);this.createZoomInSvg_(a);this.workspace_.isMovable()&&this.createZoomResetSvg_(a);return this.svgGroup_}; +module$exports$Blockly$ZoomControls.prototype.init=function(){this.workspace_.getComponentManager().addComponent({component:this,weight:2,capabilities:[module$exports$Blockly$ComponentManager.Capability.POSITIONABLE]});this.initialized_=!0}; +module$exports$Blockly$ZoomControls.prototype.dispose=function(){this.workspace_.getComponentManager().removeComponent("zoomControls");this.svgGroup_&&(0,module$exports$Blockly$utils$dom.removeNode)(this.svgGroup_);this.onZoomResetWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.onZoomResetWrapper_);this.onZoomInWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.onZoomInWrapper_);this.onZoomOutWrapper_&&(0,module$exports$Blockly$browserEvents.unbind)(this.onZoomOutWrapper_)}; +module$exports$Blockly$ZoomControls.prototype.getBoundingRectangle=function(){var a=this.SMALL_SPACING_+2*this.HEIGHT_;this.zoomResetGroup_&&(a+=this.LARGE_SPACING_+this.HEIGHT_);return new module$exports$Blockly$utils$Rect(this.top_,this.top_+a,this.left_,this.left_+this.WIDTH_)}; +module$exports$Blockly$ZoomControls.prototype.position=function(a,b){if(this.initialized_){var c=(0,module$exports$Blockly$uiPosition.getCornerOppositeToolbox)(this.workspace_,a),d=this.SMALL_SPACING_+2*this.HEIGHT_;this.zoomResetGroup_&&(d+=this.LARGE_SPACING_+this.HEIGHT_);a=(0,module$exports$Blockly$uiPosition.getStartPositionRect)(c,new module$exports$Blockly$utils$Size(this.WIDTH_,d),this.MARGIN_HORIZONTAL_,this.MARGIN_VERTICAL_,a,this.workspace_);c=c.vertical;b=(0,module$exports$Blockly$uiPosition.bumpPositionRect)(a, +this.MARGIN_VERTICAL_,c===module$exports$Blockly$uiPosition.verticalPosition.TOP?module$exports$Blockly$uiPosition.bumpDirection.DOWN:module$exports$Blockly$uiPosition.bumpDirection.UP,b);c===module$exports$Blockly$uiPosition.verticalPosition.TOP?(c=this.SMALL_SPACING_+this.HEIGHT_,this.zoomInGroup_.setAttribute("transform","translate(0, "+c+")"),this.zoomResetGroup_&&this.zoomResetGroup_.setAttribute("transform","translate(0, "+(c+this.LARGE_SPACING_+this.HEIGHT_)+")")):(c=this.zoomResetGroup_?this.LARGE_SPACING_+ +this.HEIGHT_:0,this.zoomInGroup_.setAttribute("transform","translate(0, "+c+")"),this.zoomOutGroup_.setAttribute("transform","translate(0, "+(c+this.SMALL_SPACING_+this.HEIGHT_)+")"));this.top_=b.top;this.left_=b.left;this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")")}}; +module$exports$Blockly$ZoomControls.prototype.createZoomOutSvg_=function(a){this.zoomOutGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CLIPPATH,{id:"blocklyZoomoutClipPath"+a},this.zoomOutGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{width:32,height:32},b);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE, +{width:module$exports$Blockly$internalConstants.SPRITE.width,height:module$exports$Blockly$internalConstants.SPRITE.height,x:-64,y:-92,"clip-path":"url(#blocklyZoomoutClipPath"+a+")"},this.zoomOutGroup_).setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+module$exports$Blockly$internalConstants.SPRITE.url);this.onZoomOutWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.zoomOutGroup_,"mousedown",null,this.zoom_.bind(this,-1))}; +module$exports$Blockly$ZoomControls.prototype.createZoomInSvg_=function(a){this.zoomInGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CLIPPATH,{id:"blocklyZoominClipPath"+a},this.zoomInGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{width:32,height:32},b);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE, +{width:module$exports$Blockly$internalConstants.SPRITE.width,height:module$exports$Blockly$internalConstants.SPRITE.height,x:-32,y:-92,"clip-path":"url(#blocklyZoominClipPath"+a+")"},this.zoomInGroup_).setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+module$exports$Blockly$internalConstants.SPRITE.url);this.onZoomInWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.zoomInGroup_,"mousedown",null,this.zoom_.bind(this,1))}; +module$exports$Blockly$ZoomControls.prototype.zoom_=function(a,b){this.workspace_.markFocused();this.workspace_.zoomCenter(a);this.fireZoomEvent_();(0,module$exports$Blockly$Touch.clearTouchIdentifier)();b.stopPropagation();b.preventDefault()}; +module$exports$Blockly$ZoomControls.prototype.createZoomResetSvg_=function(a){this.zoomResetGroup_=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.G,{"class":"blocklyZoom"},this.svgGroup_);var b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.CLIPPATH,{id:"blocklyZoomresetClipPath"+a},this.zoomResetGroup_);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.RECT,{width:32,height:32},b); +(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.IMAGE,{width:module$exports$Blockly$internalConstants.SPRITE.width,height:module$exports$Blockly$internalConstants.SPRITE.height,y:-92,"clip-path":"url(#blocklyZoomresetClipPath"+a+")"},this.zoomResetGroup_).setAttributeNS(module$exports$Blockly$utils$dom.XLINK_NS,"xlink:href",this.workspace_.options.pathToMedia+module$exports$Blockly$internalConstants.SPRITE.url);this.onZoomResetWrapper_=(0,module$exports$Blockly$browserEvents.conditionalBind)(this.zoomResetGroup_, +"mousedown",null,this.resetZoom_.bind(this))}; +module$exports$Blockly$ZoomControls.prototype.resetZoom_=function(a){this.workspace_.markFocused();var b=Math.log(this.workspace_.options.zoomOptions.startScale/this.workspace_.scale)/Math.log(this.workspace_.options.zoomOptions.scaleSpeed);this.workspace_.beginCanvasTransition();this.workspace_.zoomCenter(b);this.workspace_.scrollCenter();setTimeout(this.workspace_.endCanvasTransition.bind(this.workspace_),500);this.fireZoomEvent_();(0,module$exports$Blockly$Touch.clearTouchIdentifier)();a.stopPropagation(); +a.preventDefault()};module$exports$Blockly$ZoomControls.prototype.fireZoomEvent_=function(){var a=new ((0,module$exports$Blockly$Events$utils.get)(module$exports$Blockly$Events$utils.CLICK))(null,this.workspace_.id,"zoom_controls");(0,module$exports$Blockly$Events$utils.fire)(a)};(0,module$exports$Blockly$Css.register)([".blocklyZoom>image, .blocklyZoom>svg>image {\n opacity: .4;\n}",".blocklyZoom>image:hover, .blocklyZoom>svg>image:hover {\n opacity: .6;\n}",".blocklyZoom>image:active, .blocklyZoom>svg>image:active {\n 'opacity: .8;\n}"]);var module$exports$Blockly$geras$ConstantProvider=function(){module$exports$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};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$ConstantProvider,module$exports$Blockly$blockRendering$ConstantProvider); +module$exports$Blockly$geras$ConstantProvider.prototype.getCSS_=function(a){return module$exports$Blockly$geras$ConstantProvider.superClass_.getCSS_.call(this,a).concat([a+" .blocklyInsertionMarker>.blocklyPathLight,",a+" .blocklyInsertionMarker>.blocklyPathDark {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none;","}"])};var module$exports$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};module$exports$Blockly$geras$Highlighter.prototype.getPath=function(){return this.steps_+"\n"+this.inlineSteps_}; +module$exports$Blockly$geras$Highlighter.prototype.drawTopCorner=function(a){this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveBy)(a.xPos,this.info_.startY);for(var b=0,c;c=a.elements[b];b++)module$exports$Blockly$blockRendering$Types.isLeftSquareCorner(c)?this.steps_+=this.highlightConstants_.START_POINT:module$exports$Blockly$blockRendering$Types.isLeftRoundedCorner(c)?this.steps_+=this.outsideCornerPaths_.topLeft(this.RTL_):module$exports$Blockly$blockRendering$Types.isPreviousConnection(c)? +this.steps_+=this.notchPaths_.pathLeft:module$exports$Blockly$blockRendering$Types.isHat(c)?this.steps_+=this.startPaths_.path(this.RTL_):module$exports$Blockly$blockRendering$Types.isSpacer(c)&&0!=c.width&&(this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("H",c.xPos+c.width-this.highlightOffset_));this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("H",a.xPos+a.width-this.highlightOffset_)}; +module$exports$Blockly$geras$Highlighter.prototype.drawJaggedEdge_=function(a){this.info_.RTL&&(this.steps_+=this.jaggedTeethPaths_.pathLeft+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",a.height-this.jaggedTeethPaths_.height-this.highlightOffset_))}; +module$exports$Blockly$geras$Highlighter.prototype.drawValueInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-b.connectionHeight;this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(b.xPos+b.width-this.highlightOffset_,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",c)}else this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(b.xPos+b.width,a.yPos)+this.puzzleTabPaths_.pathDown(this.RTL_)}; +module$exports$Blockly$geras$Highlighter.prototype.drawStatementInput=function(a){var b=a.getLastInput();if(this.RTL_){var c=a.height-2*this.insideCornerPaths_.height;this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(b.xPos,a.yPos)+this.insideCornerPaths_.pathTop(this.RTL_)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",c)+this.insideCornerPaths_.pathBottom(this.RTL_)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(a.width-b.xPos-this.insideCornerPaths_.width,0)}else this.steps_+= +(0,module$exports$Blockly$utils$svgPaths.moveTo)(b.xPos,a.yPos+a.height)+this.insideCornerPaths_.pathBottom(this.RTL_)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(a.width-b.xPos-this.insideCornerPaths_.width,0)}; +module$exports$Blockly$geras$Highlighter.prototype.drawRightSideRow=function(a){var b=a.xPos+a.width-this.highlightOffset_;a.followsStatement&&(this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("H",b));this.RTL_&&(this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("H",b),a.height>this.highlightOffset_&&(this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",a.yPos+a.height-this.highlightOffset_)))}; +module$exports$Blockly$geras$Highlighter.prototype.drawBottomRow=function(a){if(this.RTL_)this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",a.baseline-this.highlightOffset_);else{var b=this.info_.bottomRow.elements[0];module$exports$Blockly$blockRendering$Types.isLeftSquareCorner(b)?this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(a.xPos+this.highlightOffset_,a.baseline-this.highlightOffset_):module$exports$Blockly$blockRendering$Types.isLeftRoundedCorner(b)&&(this.steps_+= +(0,module$exports$Blockly$utils$svgPaths.moveTo)(a.xPos,a.baseline),this.steps_+=this.outsideCornerPaths_.bottomLeft())}}; +module$exports$Blockly$geras$Highlighter.prototype.drawLeft=function(){var a=this.info_.outputConnection;a&&(a=a.connectionOffsetY+a.height,this.RTL_?this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(this.info_.startX,a):(this.steps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(this.info_.startX+this.highlightOffset_,this.info_.bottomRow.baseline-this.highlightOffset_),this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",a)),this.steps_+=this.puzzleTabPaths_.pathUp(this.RTL_)); +this.RTL_||(a=this.info_.topRow,module$exports$Blockly$blockRendering$Types.isLeftRoundedCorner(a.elements[0])?this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",this.outsideCornerPaths_.height):this.steps_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",a.capline+this.highlightOffset_))}; +module$exports$Blockly$geras$Highlighter.prototype.drawInlineInput=function(a){var b=this.highlightOffset_,c=a.xPos+a.connectionWidth,d=a.centerline-a.height/2,e=a.width-a.connectionWidth,f=d+b;this.RTL_?(d=a.connectionOffsetY-b,a=a.height-(a.connectionOffsetY+a.connectionHeight)+b,this.inlineSteps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(c-b,f)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",d)+this.puzzleTabPaths_.pathDown(this.RTL_)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v", +a)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("h",e)):this.inlineSteps_+=(0,module$exports$Blockly$utils$svgPaths.moveTo)(a.xPos+a.width+b,f)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",a.height)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("h",-e)+(0,module$exports$Blockly$utils$svgPaths.moveTo)(c,d+a.connectionOffsetY)+this.puzzleTabPaths_.pathDown(this.RTL_)};var module$exports$Blockly$geras$Drawer=function(a,b){module$exports$Blockly$geras$Drawer.superClass_.constructor.call(this,a,b);this.highlighter_=new module$exports$Blockly$geras$Highlighter(b)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$Drawer,module$exports$Blockly$blockRendering$Drawer); +module$exports$Blockly$geras$Drawer.prototype.draw=function(){this.hideHiddenIcons_();this.drawOutline_();this.drawInternals_();var a=this.block_.pathObject;a.setPath(this.outlinePath_+"\n"+this.inlinePath_);a.setHighlightPath(this.highlighter_.getPath());this.info_.RTL&&a.flipRTL();(0,module$exports$Blockly$blockRendering$debug.isDebuggerEnabled)()&&this.block_.renderingDebugger.drawDebug(this.block_,this.info_);this.recordSizeOnBlock_()}; +module$exports$Blockly$geras$Drawer.prototype.drawTop_=function(){this.highlighter_.drawTopCorner(this.info_.topRow);this.highlighter_.drawRightSideRow(this.info_.topRow);module$exports$Blockly$geras$Drawer.superClass_.drawTop_.call(this)};module$exports$Blockly$geras$Drawer.prototype.drawJaggedEdge_=function(a){this.highlighter_.drawJaggedEdge_(a);module$exports$Blockly$geras$Drawer.superClass_.drawJaggedEdge_.call(this,a)}; +module$exports$Blockly$geras$Drawer.prototype.drawValueInput_=function(a){this.highlighter_.drawValueInput(a);module$exports$Blockly$geras$Drawer.superClass_.drawValueInput_.call(this,a)};module$exports$Blockly$geras$Drawer.prototype.drawStatementInput_=function(a){this.highlighter_.drawStatementInput(a);module$exports$Blockly$geras$Drawer.superClass_.drawStatementInput_.call(this,a)}; +module$exports$Blockly$geras$Drawer.prototype.drawRightSideRow_=function(a){this.highlighter_.drawRightSideRow(a);this.outlinePath_+=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("H",a.xPos+a.width)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("V",a.yPos+a.height)};module$exports$Blockly$geras$Drawer.prototype.drawBottom_=function(){this.highlighter_.drawBottomRow(this.info_.bottomRow);module$exports$Blockly$geras$Drawer.superClass_.drawBottom_.call(this)}; +module$exports$Blockly$geras$Drawer.prototype.drawLeft_=function(){this.highlighter_.drawLeft();module$exports$Blockly$geras$Drawer.superClass_.drawLeft_.call(this)};module$exports$Blockly$geras$Drawer.prototype.drawInlineInput_=function(a){this.highlighter_.drawInlineInput(a);module$exports$Blockly$geras$Drawer.superClass_.drawInlineInput_.call(this,a)}; +module$exports$Blockly$geras$Drawer.prototype.positionInlineInputConnection_=function(a){var b=a.centerline-a.height/2;if(a.connectionModel){var c=a.xPos+a.connectionWidth+this.constants_.DARK_PATH_OFFSET;this.info_.RTL&&(c*=-1);a.connectionModel.setOffsetInBlock(c,b+a.connectionOffsetY+this.constants_.DARK_PATH_OFFSET)}}; +module$exports$Blockly$geras$Drawer.prototype.positionStatementInputConnection_=function(a){var b=a.getLastInput();if(b.connectionModel){var c=a.xPos+a.statementEdge+b.notchOffset;c=this.info_.RTL?-1*c:c+this.constants_.DARK_PATH_OFFSET;b.connectionModel.setOffsetInBlock(c,a.yPos+this.constants_.DARK_PATH_OFFSET)}}; +module$exports$Blockly$geras$Drawer.prototype.positionExternalValueConnection_=function(a){var b=a.getLastInput();if(b.connectionModel){var c=a.xPos+a.width+this.constants_.DARK_PATH_OFFSET;this.info_.RTL&&(c*=-1);b.connectionModel.setOffsetInBlock(c,a.yPos)}}; +module$exports$Blockly$geras$Drawer.prototype.positionNextConnection_=function(){var a=this.info_.bottomRow;if(a.connection){var b=a.connection,c=b.xPos;b.connectionModel.setOffsetInBlock((this.info_.RTL?-c:c)+this.constants_.DARK_PATH_OFFSET/2,a.baseline+this.constants_.DARK_PATH_OFFSET)}};var module$exports$Blockly$geras$HighlightConstantProvider=function(a){this.constantProvider=a;this.OFFSET=.5;this.START_POINT=(0,module$exports$Blockly$utils$svgPaths.moveBy)(this.OFFSET,this.OFFSET)};module$exports$Blockly$geras$HighlightConstantProvider.prototype.init=function(){this.INSIDE_CORNER=this.makeInsideCorner();this.OUTSIDE_CORNER=this.makeOutsideCorner();this.PUZZLE_TAB=this.makePuzzleTab();this.NOTCH=this.makeNotch();this.JAGGED_TEETH=this.makeJaggedTeeth();this.START_HAT=this.makeStartHat()}; +module$exports$Blockly$geras$HighlightConstantProvider.prototype.makeInsideCorner=function(){var a=this.constantProvider.CORNER_RADIUS,b=this.OFFSET,c=(1-Math.SQRT1_2)*(a+b)-b,d=(0,module$exports$Blockly$utils$svgPaths.moveBy)(c,c)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,0",a,(0,module$exports$Blockly$utils$svgPaths.point)(-c-b,a-c)),e=(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,0",a+b,(0,module$exports$Blockly$utils$svgPaths.point)(a+b,a+b)),f=(0,module$exports$Blockly$utils$svgPaths.moveBy)(c, +-c)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,0",a+b,(0,module$exports$Blockly$utils$svgPaths.point)(a-c,c+b));return{width:a+b,height:a,pathTop:function(g){return g?d:""},pathBottom:function(g){return g?e:f}}}; +module$exports$Blockly$geras$HighlightConstantProvider.prototype.makeOutsideCorner=function(){var a=this.constantProvider.CORNER_RADIUS,b=this.OFFSET,c=(1-Math.SQRT1_2)*(a-b)+b,d=(0,module$exports$Blockly$utils$svgPaths.moveBy)(c,c)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",a-b,(0,module$exports$Blockly$utils$svgPaths.point)(a-c,-c+b)),e=(0,module$exports$Blockly$utils$svgPaths.moveBy)(b,a)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",a-b,(0,module$exports$Blockly$utils$svgPaths.point)(a, +-a+b)),f=-c,g=(0,module$exports$Blockly$utils$svgPaths.moveBy)(c,f)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",a-b,(0,module$exports$Blockly$utils$svgPaths.point)(-c+b,-f-a));return{height:a,topLeft:function(h){return h?d:e},bottomLeft:function(){return g}}}; +module$exports$Blockly$geras$HighlightConstantProvider.prototype.makePuzzleTab=function(){var a=this.constantProvider.TAB_WIDTH,b=this.constantProvider.TAB_HEIGHT,c=(0,module$exports$Blockly$utils$svgPaths.moveBy)(-2,-b+3.4)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(-.45*a,-2.1),d=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",2.5)+(0,module$exports$Blockly$utils$svgPaths.moveBy)(.97*-a,2.5)+(0,module$exports$Blockly$utils$svgPaths.curve)("q",[(0,module$exports$Blockly$utils$svgPaths.point)(.05* +-a,10),(0,module$exports$Blockly$utils$svgPaths.point)(.3*a,9.5)])+(0,module$exports$Blockly$utils$svgPaths.moveBy)(.67*a,-1.9)+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",2.5),e=(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",-1.5)+(0,module$exports$Blockly$utils$svgPaths.moveBy)(-.92*a,-.5)+(0,module$exports$Blockly$utils$svgPaths.curve)("q",[(0,module$exports$Blockly$utils$svgPaths.point)(-.19*a,-5.5),(0,module$exports$Blockly$utils$svgPaths.point)(0,-11)])+(0,module$exports$Blockly$utils$svgPaths.moveBy)(.92* +a,1),f=(0,module$exports$Blockly$utils$svgPaths.moveBy)(-5,b-.7)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(.46*a,-2.1);return{width:a,height:b,pathUp:function(g){return g?c:e},pathDown:function(g){return g?d:f}}};module$exports$Blockly$geras$HighlightConstantProvider.prototype.makeNotch=function(){return{pathLeft:(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("h",this.OFFSET)+this.constantProvider.NOTCH.pathLeft}}; +module$exports$Blockly$geras$HighlightConstantProvider.prototype.makeJaggedTeeth=function(){return{pathLeft:(0,module$exports$Blockly$utils$svgPaths.lineTo)(5.1,2.6)+(0,module$exports$Blockly$utils$svgPaths.moveBy)(-10.2,6.8)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(5.1,2.6),height:12,width:10.2}}; +module$exports$Blockly$geras$HighlightConstantProvider.prototype.makeStartHat=function(){var a=this.constantProvider.START_HAT.height,b=(0,module$exports$Blockly$utils$svgPaths.moveBy)(25,-8.7)+(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(29.7,-6.2),(0,module$exports$Blockly$utils$svgPaths.point)(57.2,-.5),(0,module$exports$Blockly$utils$svgPaths.point)(75,8.7)]),c=(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(17.8, +-9.2),(0,module$exports$Blockly$utils$svgPaths.point)(45.3,-14.9),(0,module$exports$Blockly$utils$svgPaths.point)(75,-8.7)])+(0,module$exports$Blockly$utils$svgPaths.moveTo)(100.5,a+.5);return{path:function(d){return d?b:c}}};var module$exports$Blockly$geras$InlineInput=function(a,b){module$exports$Blockly$geras$InlineInput.superClass_.constructor.call(this,a,b);this.connectedBlock&&(this.width+=this.constants_.DARK_PATH_OFFSET,this.height+=this.constants_.DARK_PATH_OFFSET)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$InlineInput,module$exports$Blockly$blockRendering$InlineInput);var module$exports$Blockly$geras$PathObject=function(a,b,c){this.constants=c;this.svgRoot=a;this.svgPathDark=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.PATH,{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgRoot);this.svgPath=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.PATH,{"class":"blocklyPath"},this.svgRoot);this.svgPathLight=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.PATH, +{"class":"blocklyPathLight"},this.svgRoot);this.colourDark="#000000";this.style=b};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$PathObject,module$exports$Blockly$blockRendering$PathObject);module$exports$Blockly$geras$PathObject.prototype.setPath=function(a){this.svgPath.setAttribute("d",a);this.svgPathDark.setAttribute("d",a)};module$exports$Blockly$geras$PathObject.prototype.setHighlightPath=function(a){this.svgPathLight.setAttribute("d",a)}; +module$exports$Blockly$geras$PathObject.prototype.flipRTL=function(){this.svgPath.setAttribute("transform","scale(-1 1)");this.svgPathLight.setAttribute("transform","scale(-1 1)");this.svgPathDark.setAttribute("transform","translate(1,1) scale(-1 1)")}; +module$exports$Blockly$geras$PathObject.prototype.applyColour=function(a){this.svgPathLight.style.display="";this.svgPathDark.style.display="";this.svgPathLight.setAttribute("stroke",this.style.colourTertiary);this.svgPathDark.setAttribute("fill",this.colourDark);module$exports$Blockly$geras$PathObject.superClass_.applyColour.call(this,a);this.svgPath.setAttribute("stroke","none")}; +module$exports$Blockly$geras$PathObject.prototype.setStyle=function(a){this.style=a;this.colourDark=(0,module$exports$Blockly$utils$colour.blend)("#000",this.style.colourPrimary,.2)||this.colourDark};module$exports$Blockly$geras$PathObject.prototype.updateHighlighted=function(a){a?(this.svgPath.setAttribute("filter","url(#"+this.constants.embossFilterId+")"),this.svgPathLight.style.display="none"):(this.svgPath.setAttribute("filter","none"),this.svgPathLight.style.display="inline")}; +module$exports$Blockly$geras$PathObject.prototype.updateShadow_=function(a){a&&(this.svgPathLight.style.display="none",this.svgPathDark.setAttribute("fill",this.style.colourSecondary),this.svgPath.setAttribute("stroke","none"),this.svgPath.setAttribute("fill",this.style.colourSecondary))};module$exports$Blockly$geras$PathObject.prototype.updateDisabled_=function(a){module$exports$Blockly$geras$PathObject.superClass_.updateDisabled_.call(this,a);a&&this.svgPath.setAttribute("stroke","none")};var module$exports$Blockly$geras$StatementInput=function(a,b){module$exports$Blockly$geras$StatementInput.superClass_.constructor.call(this,a,b);this.connectedBlock&&(this.height+=this.constants_.DARK_PATH_OFFSET)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$StatementInput,module$exports$Blockly$blockRendering$StatementInput);var module$exports$Blockly$geras$RenderInfo=function(a,b){module$exports$Blockly$geras$RenderInfo.superClass_.constructor.call(this,a,b)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$geras$RenderInfo,module$exports$Blockly$blockRendering$RenderInfo);module$exports$Blockly$geras$RenderInfo.prototype.getRenderer=function(){return this.renderer_}; +module$exports$Blockly$geras$RenderInfo.prototype.populateBottomRow_=function(){module$exports$Blockly$geras$RenderInfo.superClass_.populateBottomRow_.call(this);this.block_.inputList.length&&this.block_.inputList[this.block_.inputList.length-1].type==module$exports$Blockly$inputTypes.STATEMENT||(this.bottomRow.minHeight=this.constants_.MEDIUM_PADDING-this.constants_.DARK_PATH_OFFSET)}; +module$exports$Blockly$geras$RenderInfo.prototype.addInput_=function(a,b){this.isInline&&a.type==module$exports$Blockly$inputTypes.VALUE?(b.elements.push(new module$exports$Blockly$geras$InlineInput(this.constants_,a)),b.hasInlineInput=!0):a.type==module$exports$Blockly$inputTypes.STATEMENT?(b.elements.push(new module$exports$Blockly$geras$StatementInput(this.constants_,a)),b.hasStatement=!0):a.type==module$exports$Blockly$inputTypes.VALUE?(b.elements.push(new module$exports$Blockly$blockRendering$ExternalValueInput(this.constants_, +a)),b.hasExternalInput=!0):a.type==module$exports$Blockly$inputTypes.DUMMY&&(b.minHeight=Math.max(b.minHeight,this.constants_.DUMMY_INPUT_MIN_HEIGHT),b.hasDummyInput=!0);this.isInline||null!=b.align||(b.align=a.align)}; +module$exports$Blockly$geras$RenderInfo.prototype.addElemSpacing_=function(){for(var a=!1,b=0,c;c=this.rows[b];b++)c.hasExternalInput&&(a=!0);for(b=0;c=this.rows[b];b++){var d=c.elements;c.elements=[];c.startsWithElemSpacer()&&c.elements.push(new module$exports$Blockly$blockRendering$InRowSpacer(this.constants_,this.getInRowSpacing_(null,d[0])));if(d.length){for(var e=0;eb?b:f;e=e?-1:1;c=(d?-1:1)*c/2;return(0,module$exports$Blockly$utils$svgPaths.lineTo)(-e*f,c)+(0,module$exports$Blockly$utils$svgPaths.lineTo)(e*f,c)}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;return{type:this.SHAPES.HEXAGONAL,isDynamic:!0,width:function(c){c/=2;return c>b?b:c},height:function(c){return c},connectionOffsetY:function(c){return c/2},connectionOffsetX:function(c){return-c}, +pathDown:function(c){return a(c,!1,!1)},pathUp:function(c){return a(c,!0,!1)},pathRightDown:function(c){return a(c,!1,!0)},pathRightUp:function(c){return a(c,!1,!0)}}}; +module$exports$Blockly$zelos$ConstantProvider.prototype.makeRounded=function(){function a(d,e,f){var g=d>c?d-c:0;d=(d>c?c:d)/2;return(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",d,(0,module$exports$Blockly$utils$svgPaths.point)((e?-1:1)*d,(e?-1:1)*d))+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",(f?1:-1)*g)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",d,(0,module$exports$Blockly$utils$svgPaths.point)((e?1:-1)*d,(e?-1:1)*d))}var b=this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH, +c=2*b;return{type:this.SHAPES.ROUND,isDynamic:!0,width:function(d){d/=2;return d>b?b:d},height:function(d){return d},connectionOffsetY:function(d){return d/2},connectionOffsetX:function(d){return-d},pathDown:function(d){return a(d,!1,!1)},pathUp:function(d){return a(d,!0,!1)},pathRightDown:function(d){return a(d,!1,!0)},pathRightUp:function(d){return a(d,!1,!0)}}}; +module$exports$Blockly$zelos$ConstantProvider.prototype.makeSquared=function(){function a(c,d,e){c-=2*b;return(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",b,(0,module$exports$Blockly$utils$svgPaths.point)((d?-1:1)*b,(d?-1:1)*b))+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("v",(e?1:-1)*c)+(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",b,(0,module$exports$Blockly$utils$svgPaths.point)((d?1:-1)*b,(d?-1:1)*b))}var b=this.CORNER_RADIUS;return{type:this.SHAPES.SQUARE,isDynamic:!0, +width:function(c){return b},height:function(c){return c},connectionOffsetY:function(c){return c/2},connectionOffsetX:function(c){return-c},pathDown:function(c){return a(c,!1,!1)},pathUp:function(c){return a(c,!0,!1)},pathRightDown:function(c){return a(c,!1,!0)},pathRightUp:function(c){return a(c,!1,!0)}}}; +module$exports$Blockly$zelos$ConstantProvider.prototype.shapeFor=function(a){var b=a.getCheck();!b&&a.targetConnection&&(b=a.targetConnection.getCheck());switch(a.type){case module$exports$Blockly$ConnectionType.ConnectionType.INPUT_VALUE:case module$exports$Blockly$ConnectionType.ConnectionType.OUTPUT_VALUE:a=a.getSourceBlock().getOutputShape();if(null!=a)switch(a){case this.SHAPES.HEXAGONAL:return this.HEXAGONAL;case this.SHAPES.ROUND:return this.ROUNDED;case this.SHAPES.SQUARE:return this.SQUARED}if(b&& +-1!=b.indexOf("Boolean"))return this.HEXAGONAL;if(b&&-1!=b.indexOf("Number"))return this.ROUNDED;b&&b.indexOf("String");return this.ROUNDED;case module$exports$Blockly$ConnectionType.ConnectionType.PREVIOUS_STATEMENT:case module$exports$Blockly$ConnectionType.ConnectionType.NEXT_STATEMENT:return this.NOTCH;default:throw Error("Unknown type");}}; +module$exports$Blockly$zelos$ConstantProvider.prototype.makeNotch=function(){function a(l){return(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(l*e/2,0),(0,module$exports$Blockly$utils$svgPaths.point)(l*e*3/4,g/2),(0,module$exports$Blockly$utils$svgPaths.point)(l*e,g)])+(0,module$exports$Blockly$utils$svgPaths.line)([(0,module$exports$Blockly$utils$svgPaths.point)(l*e,f)])+(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(l* +e/4,g/2),(0,module$exports$Blockly$utils$svgPaths.point)(l*e/2,g),(0,module$exports$Blockly$utils$svgPaths.point)(l*e,g)])+(0,module$exports$Blockly$utils$svgPaths.lineOnAxis)("h",l*d)+(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(l*e/2,0),(0,module$exports$Blockly$utils$svgPaths.point)(l*e*3/4,-(g/2)),(0,module$exports$Blockly$utils$svgPaths.point)(l*e,-g)])+(0,module$exports$Blockly$utils$svgPaths.line)([(0,module$exports$Blockly$utils$svgPaths.point)(l* +e,-f)])+(0,module$exports$Blockly$utils$svgPaths.curve)("c",[(0,module$exports$Blockly$utils$svgPaths.point)(l*e/4,-(g/2)),(0,module$exports$Blockly$utils$svgPaths.point)(l*e/2,-g),(0,module$exports$Blockly$utils$svgPaths.point)(l*e,-g)])}var b=this.NOTCH_WIDTH,c=this.NOTCH_HEIGHT,d=b/3,e=d/3,f=c/2,g=f/2,h=a(1),k=a(-1);return{type:this.SHAPES.NOTCH,width:b,height:c,pathLeft:h,pathRight:k}}; +module$exports$Blockly$zelos$ConstantProvider.prototype.makeInsideCorners=function(){var a=this.CORNER_RADIUS,b=(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,0",a,(0,module$exports$Blockly$utils$svgPaths.point)(-a,a)),c=(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,1",a,(0,module$exports$Blockly$utils$svgPaths.point)(-a,a)),d=(0,module$exports$Blockly$utils$svgPaths.arc)("a","0 0,0",a,(0,module$exports$Blockly$utils$svgPaths.point)(a,a)),e=(0,module$exports$Blockly$utils$svgPaths.arc)("a", +"0 0,1",a,(0,module$exports$Blockly$utils$svgPaths.point)(a,a));return{width:a,height:a,pathTop:b,pathBottom:d,rightWidth:a,rightHeight:a,pathTopRight:c,pathBottomRight:e}};module$exports$Blockly$zelos$ConstantProvider.prototype.generateSecondaryColour_=function(a){return(0,module$exports$Blockly$utils$colour.blend)("#000",a,.15)||a};module$exports$Blockly$zelos$ConstantProvider.prototype.generateTertiaryColour_=function(a){return(0,module$exports$Blockly$utils$colour.blend)("#000",a,.25)||a}; +module$exports$Blockly$zelos$ConstantProvider.prototype.createDom=function(a,b,c){module$exports$Blockly$zelos$ConstantProvider.superClass_.createDom.call(this,a,b,c);a=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.DEFS,{},a);b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FILTER,{id:"blocklySelectedGlowFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEGAUSSIANBLUR, +{"in":"SourceGraphic",stdDeviation:this.SELECTED_GLOW_SIZE},b);c=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FECOMPONENTTRANSFER,{result:"outBlur"},b);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEFUNCA,{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},c);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEFLOOD,{"flood-color":this.SELECTED_GLOW_COLOUR,"flood-opacity":1, +result:"outColor"},b);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FECOMPOSITE,{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},b);this.selectedGlowFilterId=b.id;this.selectedGlowFilter_=b;a=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FILTER,{id:"blocklyReplacementGlowFilter"+this.randomIdentifier,height:"160%",width:"180%",y:"-30%",x:"-40%"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEGAUSSIANBLUR, +{"in":"SourceGraphic",stdDeviation:this.REPLACEMENT_GLOW_SIZE},a);b=(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FECOMPONENTTRANSFER,{result:"outBlur"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEFUNCA,{type:"table",tableValues:"0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},b);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FEFLOOD,{"flood-color":this.REPLACEMENT_GLOW_COLOUR,"flood-opacity":1, +result:"outColor"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FECOMPOSITE,{"in":"outColor",in2:"outBlur",operator:"in",result:"outGlow"},a);(0,module$exports$Blockly$utils$dom.createSvgElement)(module$exports$Blockly$utils$Svg.FECOMPOSITE,{"in":"SourceGraphic",in2:"outGlow",operator:"over"},a);this.replacementGlowFilterId=a.id;this.replacementGlowFilter_=a}; +module$exports$Blockly$zelos$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:not(.blocklyDropdownRect),",a+" .blocklyEditableText>rect:not(.blocklyDropdownRect) {","fill: "+this.FIELD_BORDER_RECT_COLOUR+";","}",a+" .blocklyNonEditableText>text,",a+" .blocklyEditableText>text,", +a+" .blocklyNonEditableText>g>text,",a+" .blocklyEditableText>g>text {","fill: #575E75;","}",a+" .blocklyFlyoutLabelText {","fill: #575E75;","}",a+" .blocklyText.blocklyBubbleText {","fill: #575E75;","}",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>rect,",a+" .blocklyDraggable:not(.blocklyDisabled)"," .blocklyEditableText:not(.editing):hover>.blocklyPath {","stroke: #fff;","stroke-width: 2;","}",a+" .blocklyHtmlInput {","font-family: "+this.FIELD_TEXT_FONTFAMILY+ +";","font-weight: "+this.FIELD_TEXT_FONTWEIGHT+";","color: #575E75;","}",a+" .blocklyDropdownText {","fill: #fff !important;","}",a+".blocklyWidgetDiv .goog-menuitem,",a+".blocklyDropDownDiv .goog-menuitem {","font-family: "+this.FIELD_TEXT_FONTFAMILY+";","}",a+".blocklyDropDownDiv .goog-menuitem-content {","color: #fff;","}",a+" .blocklyHighlightedConnectionPath {","stroke: "+this.SELECTED_GLOW_COLOUR+";","}",a+" .blocklyDisabled > .blocklyOutlinePath {","fill: url(#blocklyDisabledPattern"+this.randomIdentifier+ +")","}",a+" .blocklyInsertionMarker>.blocklyPath {","fill-opacity: "+this.INSERTION_MARKER_OPACITY+";","stroke: none;","}"]};var module$exports$Blockly$zelos$Drawer=function(a,b){module$exports$Blockly$zelos$Drawer.superClass_.constructor.call(this,a,b)};(0,module$exports$Blockly$utils$object.inherits)(module$exports$Blockly$zelos$Drawer,module$exports$Blockly$blockRendering$Drawer); +module$exports$Blockly$zelos$Drawer.prototype.draw=function(){var a=this.block_.pathObject;a.beginDrawing();this.hideHiddenIcons_();this.drawOutline_();this.drawInternals_();a.setPath(this.outlinePath_+"\n"+this.inlinePath_);this.info_.RTL&&a.flipRTL();(0,module$exports$Blockly$blockRendering$debug.isDebuggerEnabled)()&&this.block_.renderingDebugger.drawDebug(this.block_,this.info_);this.recordSizeOnBlock_();this.info_.outputConnection&&(a.outputShapeType=this.info_.outputConnection.shape.type);a.endDrawing()}; +module$exports$Blockly$zelos$Drawer.prototype.drawOutline_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape&&!this.info_.hasStatementInput&&!this.info_.bottomRow.hasNextConnection?(this.drawFlatTop_(),this.drawRightDynamicConnection_(),this.drawFlatBottom_(),this.drawLeftDynamicConnection_()):module$exports$Blockly$zelos$Drawer.superClass_.drawOutline_.call(this)}; +module$exports$Blockly$zelos$Drawer.prototype.drawLeft_=function(){this.info_.outputConnection&&this.info_.outputConnection.isDynamicShape?this.drawLeftDynamicConnection_():module$exports$Blockly$zelos$Drawer.superClass_.drawLeft_.call(this)}; +module$exports$Blockly$zelos$Drawer.prototype.drawRightSideRow_=function(a){if(!(0>=a.height))if(a.precedesStatement||a.followsStatement){var b=this.constants_.INSIDE_CORNERS.rightHeight;b=a.height-(a.precedesStatement?b:0);this.outlinePath_+=(a.followsStatement?this.constants_.INSIDE_CORNERS.pathBottomRight:"")+(0=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!f.precedesStatement;if(module$exports$Blockly$blockRendering$Types.isInputRow(e)&&e.hasStatement)e.measure(),b=e.width-e.getLastInput().width+ +a;else if(d&&(2==c||f)&&module$exports$Blockly$blockRendering$Types.isInputRow(e)&&!e.hasStatement){f=e.xPos;d=null;for(var g=0;cc?c:this.height/2,b-c*(1-Math.sin(Math.acos((c-this.constants_.SMALL_PADDING)/c)));default:return 0}if(module$exports$Blockly$blockRendering$Types.isInlineInput(a)){var e= +a.connectedBlock;a=e?e.pathObject.outputShapeType:a.shape.type;return e&&e.outputConnection&&(e.statementInputCount||e.nextConnection)||c==d.SHAPES.HEXAGONAL&&c!=a?0:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][a]}return module$exports$Blockly$blockRendering$Types.isField(a)?c==d.SHAPES.ROUND&&a.field instanceof module$exports$Blockly$FieldTextInput?b-2.75*d.GRID_UNIT:b-this.constants_.SHAPE_IN_SHAPE_PADDING[c][0]:module$exports$Blockly$blockRendering$Types.isIcon(a)?this.constants_.SMALL_PADDING: +0}; +module$exports$Blockly$zelos$RenderInfo.prototype.finalizeVerticalAlignment_=function(){if(!this.outputConnection)for(var a=2;a=this.rows.length-1?!!this.bottomRow.hasNextConnection:!!d.precedesStatement;if(e?this.topRow.hasPreviousConnection:b.followsStatement){var g=3==c.elements.length&&(c.elements[1].field instanceof module$exports$Blockly$FieldLabel||c.elements[1].field instanceof module$exports$Blockly$FieldImage);if(!e&& +g)b.height-=this.constants_.SMALL_PADDING,d.height-=this.constants_.SMALL_PADDING,c.height-=this.constants_.MEDIUM_PADDING;else if(!e&&!f)b.height+=this.constants_.SMALL_PADDING;else if(f){e=!1;for(f=0;f>>0,$jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE? +$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+c+"$"+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSymbol[e],{configurable:!0,writable:!0,value:b})))};$jscomp.polyfill("Array.prototype.fill",function(a){return a?a:function(b,c,d){var e=this.length||0;0>c&&(c=Math.max(0,e+c));if(null==d||d>e)d=e;d=Number(d);0>d&&(d=Math.max(0,e+d));for(c=Number(c||0);c","GT"],["\u200f\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare", -"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Boolean"},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:"Boolean"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL", -check:"Boolean"}],output:"Boolean",style:"logic_blocks",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}],message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1", -args2:[{type:"input_value",name:"ELSE"}],output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]); +name:"DO0"}],previousStatement:null,nextStatement:null,style:"logic_blocks",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",suppressPrefixSuffix:!0,mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null, +nextStatement:null,style:"logic_blocks",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",suppressPrefixSuffix:!0,extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["\u200f<","LT"],["\u200f\u2264","LTE"],["\u200f>","GT"],["\u200f\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}", +extensions:["logic_compare","logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Boolean"},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:"Boolean"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value", +name:"BOOL",check:"Boolean"}],output:"Boolean",style:"logic_blocks",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}], +message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1",args2:[{type:"input_value",name:"ELSE"}],output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]); Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null, 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&&!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); -this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},reconnectChildBlocks_:function(a,b,c){for(var d=1;d<=this.elseifCount_;d++)Blockly.Mutator.reconnect(a[d],this,"IF"+d),Blockly.Mutator.reconnect(b[d],this,"DO"+d);Blockly.Mutator.reconnect(c,this,"ELSE")}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]); +Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_: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_()},saveExtraState:function(){if(!this.elseifCount_&& +!this.elseCount_)return null;var a=Object.create(null);this.elseifCount_&&(a.elseIfCount=this.elseifCount_);this.elseCount_&&(a.hasElse=!0);return a},loadExtraState:function(a){this.elseifCount_=a.elseIfCount||0;this.elseCount_=a.hasElse?1:0;this.updateShape_()},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);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},reconnectChildBlocks_:function(a,b,c){for(var d=1;d<=this.elseifCount_;d++)Blockly.Mutator.reconnect(a[d],this,"IF"+d),Blockly.Mutator.reconnect(b[d], +this,"DO"+d);Blockly.Mutator.reconnect(c,this,"ELSE")}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]); Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION); Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={onchange:function(a){this.prevBlocks_||(this.prevBlocks_=[null,null]);var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");b&&c&&!this.workspace.connectionChecker.doTypeChecks(b.outputConnection,c.outputConnection)&&(Blockly.Events.setGroup(a.group),a=this.prevBlocks_[0],a!==b&&(b.unplug(),!a||a.isDisposed()||a.isShadow()||this.getInput("A").connection.connect(a.outputConnection)),b=this.prevBlocks_[1],b!==c&&(c.unplug(),!b||b.isDisposed()|| b.isShadow()||this.getInput("B").connection.connect(b.outputConnection)),this.bumpNeighbours(),Blockly.Events.setGroup(!1));this.prevBlocks_[0]=this.getInputTargetBlock("A");this.prevBlocks_[1]=this.getInputTargetBlock("B")}};Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION); @@ -72,11 +80,11 @@ min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:" message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",name:"BY", check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],inputsInline:!0,previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOR_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_for_tooltip"]},{type:"controls_forEach",message0:"%{BKY_CONTROLS_FOREACH_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"LIST",check:"Array"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}", -extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"}; +suppressPrefixSuffix:!0,extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"}; Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS)); Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var 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){var b=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this); +Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],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"]]}, @@ -100,18 +108,19 @@ Blockly.Blocks.procedures_defnoreturn={init:function(){var a=Blockly.Procedures. 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>>0,$jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE? +$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+c+"$"+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSymbol[e],{configurable:!0,writable:!0,value:b})))};$jscomp.initSymbol=function(){}; +$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(f,g){this.$jscomp$symbol$id_=f;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:g})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(f){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(f||"")+"_"+d++,f)};return e},"es6","es3"); +$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c>>0,$jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE? +$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+c+"$"+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSymbol[e],{configurable:!0,writable:!0,value:b})))};$jscomp.initSymbol=function(){}; +$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(f,g){this.$jscomp$symbol$id_=f;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:g})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(f){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(f||"")+"_"+d++,f)};return e},"es6","es3"); +$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c>>0,$jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE? +$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+c+"$"+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSymbol[e],{configurable:!0,writable:!0,value:b})))};$jscomp.initSymbol=function(){}; +$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(f,g){this.$jscomp$symbol$id_=f;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:g})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(f){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(f||"")+"_"+d++,f)};return e},"es6","es3"); +$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c} */ - inputList: Blockly.Input[]; - - /** @type {boolean|undefined} */ - inputsInline: boolean|any /*undefined*/; - - /** @type {!Blockly.Tooltip.TipInfo} */ - tooltip: Blockly.Tooltip.TipInfo; - - /** @type {boolean} */ - contextMenu: boolean; - - /** - * @type {Blockly.Block} - * @protected - */ - parentBlock_: Blockly.Block; - - /** - * @type {!Array} - * @protected - */ - childBlocks_: Blockly.Block[]; - - /** - * @type {boolean} - * @protected - */ - collapsed_: boolean; - - /** - * @type {?number} - * @protected - */ - outputShape_: number; - - /** - * A string representing the comment attached to this block. - * @type {string|Blockly.Comment} - * @deprecated August 2019. Use getCommentText instead. - */ - comment: string|Blockly.Comment; - - /** - * A model of the comment attached to this block. - * @type {!Blockly.Block.CommentModel} - * @package - */ - commentModel: Blockly.Block.CommentModel; - - /** @type {!Blockly.Workspace} */ - workspace: Blockly.Workspace; - - /** @type {boolean} */ - isInFlyout: boolean; - - /** @type {boolean} */ - isInMutator: boolean; - - /** @type {boolean} */ - RTL: boolean; - - /** - * True if this block is an insertion marker. - * @type {boolean} - * @protected - */ - isInsertionMarker_: boolean; - - /** - * Name of the type of hat. - * @type {string|undefined} - */ - hat: string|any /*undefined*/; - - /** @type {?boolean} */ - rendered: boolean; - - /** - * A count of statement inputs on the block. - * @type {number} - * @package - */ - statementInputCount: number; - - /** @type {string} */ - type: string; - - /** @type {boolean|undefined} */ - inputsInlineDefault: boolean|any /*undefined*/; - - /** - * Optional text data that round-trips between blocks and XML. - * Has no effect. May be used by 3rd parties for meta information. - * @type {?string} - */ - data: string; - - /** - * Has this block been disposed of? - * @type {boolean} - * @package - */ - disposed: boolean; - - /** - * Colour of the block in '#RRGGBB' format. - * @type {string} - * @protected - */ - colour_: string; - - /** - * Name of the block style. - * @type {string} - * @protected - */ - styleName_: string; - - /** - * An optional method called during initialization. - * @type {?function()} - */ - init: { (): any /*missing*/ }; - - /** - * An optional callback method to use whenever the block's parent workspace - * changes. This is usually only called from the constructor, the block type - * initializer function, or an extension initializer function. - * @type {?function(Blockly.Events.Abstract)} - */ - onchange: { (_0: Blockly.Events.Abstract): any /*missing*/ }; - - /** - * An optional serialization method for defining how to serialize the - * mutation state. This must be coupled with defining `domToMutation`. - * @type {?function(...):!Element} - */ - mutationToDom: any /*missing*/; - - /** - * An optional deserialization method for defining how to deserialize the - * mutation state. This must be coupled with defining `mutationToDom`. - * @type {?function(!Element)} - */ - domToMutation: { (_0: Element): any /*missing*/ }; - - /** - * An optional property for suppressing adding STATEMENT_PREFIX and - * STATEMENT_SUFFIX to generated code. - * @type {?boolean} - */ - suppressPrefixSuffix: boolean; - - /** - * An optional property for declaring developer variables. Return a list of - * variable names for use by generators. Developer variables are never shown to - * the user, but are declared as global variables in the generated code. - * @type {?function():!Array} - */ - getDeveloperVariables: { (): string[] }; - - /** - * Dispose of this block. - * @param {boolean} healStack If true, then try to heal any gap by connecting - * the next statement with the previous statement. Otherwise, dispose of - * all children of this block. - * @suppress {checkTypes} - */ - dispose(healStack: boolean): void; - - /** - * Call initModel on all fields on the block. - * May be called more than once. - * Either initModel or initSvg must be called after creating a block and before - * the first interaction with it. Interactions include UI actions - * (e.g. clicking and dragging) and firing events (e.g. create, delete, and - * change). - * @public - */ - initModel(): void; - - /** - * Unplug this block from its superior block. If this block is a statement, - * optionally reconnect the block underneath with the block on top. - * @param {boolean=} opt_healStack Disconnect child statement and reconnect - * stack. Defaults to false. - */ - unplug(opt_healStack?: boolean): void; - - /** - * Returns all connections originating from this block. - * @param {boolean} _all If true, return all connections even hidden ones. - * @return {!Array} Array of connections. - * @package - */ - getConnections_(_all: boolean): Blockly.Connection[]; - - /** - * Walks down a stack of blocks and finds the last next connection on the stack. - * @param {boolean} ignoreShadows If true,the last connection on a non-shadow - * block will be returned. If false, this will follow shadows to find the - * last connection. - * @return {?Blockly.Connection} The last next connection on the stack, or null. - * @package - */ - lastConnectionInStack(ignoreShadows: boolean): Blockly.Connection; - - /** - * Bump unconnected blocks out of alignment. Two blocks which aren't actually - * connected should not coincidentally line up on screen. - */ - bumpNeighbours(): void; - - /** - * Return the parent block or null if this block is at the top level. The parent - * block is either the block connected to the previous connection (for a statement - * block) or the block connected to the output connection (for a value block). - * @return {?Blockly.Block} The block (if any) that holds the current block. - */ - getParent(): Blockly.Block; - - /** - * Return the input that connects to the specified block. - * @param {!Blockly.Block} block A block connected to an input on this block. - * @return {?Blockly.Input} The input (if any) that connects to the specified - * block. - */ - getInputWithBlock(block: Blockly.Block): Blockly.Input; - - /** - * Return the parent block that surrounds the current block, or null if this - * block has no surrounding block. A parent block might just be the previous - * statement, whereas the surrounding block is an if statement, while loop, etc. - * @return {?Blockly.Block} The block (if any) that surrounds the current block. - */ - getSurroundParent(): Blockly.Block; - - /** - * Return the next statement block directly connected to this block. - * @return {?Blockly.Block} The next statement block or null. - */ - getNextBlock(): Blockly.Block; - - /** - * Returns the block connected to the previous connection. - * @return {?Blockly.Block} The previous statement block or null. - */ - getPreviousBlock(): Blockly.Block; - - /** - * Return the connection on the first statement input on this block, or null if - * there are none. - * @return {?Blockly.Connection} The first statement connection or null. - * @package - */ - getFirstStatementConnection(): Blockly.Connection; - - /** - * Return the top-most block in this block's tree. - * This will return itself if this block is at the top level. - * @return {!Blockly.Block} The root block. - */ - getRootBlock(): Blockly.Block; - - /** - * Walk up from the given block up through the stack of blocks to find - * the top block of the sub stack. If we are nested in a statement input only - * find the top-most nested block. Do not go all the way to the root block. - * @return {!Blockly.Block} The top block in a stack. - * @package - */ - getTopStackBlock(): Blockly.Block; - - /** - * Find all the blocks that are directly nested inside this one. - * Includes value and statement inputs, as well as any following statement. - * Excludes any connection on an output tab or any preceding statement. - * Blocks are optionally sorted by position; top to bottom. - * @param {boolean} ordered Sort the list if true. - * @return {!Array} Array of blocks. - */ - getChildren(ordered: boolean): Blockly.Block[]; - - /** - * Set parent of this block to be a new block or null. - * @param {Blockly.Block} newParent New parent block. - */ - setParent(newParent: Blockly.Block): void; - - /** - * Find all the blocks that are directly or indirectly nested inside this one. - * Includes this block in the list. - * Includes value and statement inputs, as well as any following statements. - * Excludes any connection on an output tab or any preceding statements. - * Blocks are optionally sorted by position; top to bottom. - * @param {boolean} ordered Sort the list if true. - * @return {!Array} Flattened array of blocks. - */ - getDescendants(ordered: boolean): Blockly.Block[]; - - /** - * Get whether this block is deletable or not. - * @return {boolean} True if deletable. - */ - isDeletable(): boolean; - - /** - * Set whether this block is deletable or not. - * @param {boolean} deletable True if deletable. - */ - setDeletable(deletable: boolean): void; - - /** - * Get whether this block is movable or not. - * @return {boolean} True if movable. - */ - isMovable(): boolean; - - /** - * Set whether this block is movable or not. - * @param {boolean} movable True if movable. - */ - setMovable(movable: boolean): void; - - /** - * Get whether is block is duplicatable or not. If duplicating this block and - * descendants will put this block over the workspace's capacity this block is - * not duplicatable. If duplicating this block and descendants will put any - * type over their maxInstances this block is not duplicatable. - * @return {boolean} True if duplicatable. - */ - isDuplicatable(): boolean; - - /** - * Get whether this block is a shadow block or not. - * @return {boolean} True if a shadow. - */ - isShadow(): boolean; - - /** - * Set whether this block is a shadow block or not. - * @param {boolean} shadow True if a shadow. - */ - setShadow(shadow: boolean): void; - - /** - * Get whether this block is an insertion marker block or not. - * @return {boolean} True if an insertion marker. - */ - isInsertionMarker(): boolean; - - /** - * Set whether this block is an insertion marker block or not. - * Once set this cannot be unset. - * @param {boolean} insertionMarker True if an insertion marker. - * @package - */ - setInsertionMarker(insertionMarker: boolean): void; - - /** - * Get whether this block is editable or not. - * @return {boolean} True if editable. - */ - isEditable(): boolean; - - /** - * Set whether this block is editable or not. - * @param {boolean} editable True if editable. - */ - setEditable(editable: boolean): void; - - /** - * Returns if this block has been disposed of / deleted. - * @return {boolean} True if this block has been disposed of / deleted. - */ - isDisposed(): boolean; - - /** - * Find the connection on this block that corresponds to the given connection - * on the other block. - * Used to match connections between a block and its insertion marker. - * @param {!Blockly.Block} otherBlock The other block to match against. - * @param {!Blockly.Connection} conn The other connection to match. - * @return {?Blockly.Connection} The matching connection on this block, or null. - * @package - */ - getMatchingConnection(otherBlock: Blockly.Block, conn: Blockly.Connection): Blockly.Connection; - - /** - * Set the URL of this block's help page. - * @param {string|Function} url URL string for block help, or function that - * returns a URL. Null for no help. - */ - setHelpUrl(url: string|Function): void; - - /** - * Sets the tooltip for this block. - * @param {!Blockly.Tooltip.TipInfo} newTip The text for the tooltip, a function - * that returns the text for the tooltip, or a parent object whose tooltip - * will be used. To not display a tooltip pass the empty string. - */ - setTooltip(newTip: Blockly.Tooltip.TipInfo): void; - - /** - * Returns the tooltip text for this block. - * @return {!string} The tooltip text for this block. - */ - getTooltip(): string; - - /** - * Get the colour of a block. - * @return {string} #RRGGBB string. - */ - getColour(): string; - - /** - * Get the name of the block style. - * @return {string} Name of the block style. - */ - getStyleName(): string; - - /** - * Get the HSV hue value of a block. Null if hue not set. - * @return {?number} Hue value (0-360). - */ - getHue(): number; - - /** - * Change the colour of a block. - * @param {number|string} colour HSV hue value (0 to 360), #RRGGBB string, - * or a message reference string pointing to one of those two values. - */ - setColour(colour: number|string): void; - - /** - * Set the style and colour values of a block. - * @param {string} blockStyleName Name of the block style. - */ - setStyle(blockStyleName: string): void; - - /** - * Sets a callback function to use whenever the block's parent workspace - * changes, replacing any prior onchange handler. This is usually only called - * from the constructor, the block type initializer function, or an extension - * initializer function. - * @param {function(Blockly.Events.Abstract)} onchangeFn The callback to call - * when the block's workspace changes. - * @throws {Error} if onchangeFn is not falsey and not a function. - */ - setOnChange(onchangeFn: { (_0: Blockly.Events.Abstract): any /*missing*/ }): void; - - /** - * Returns the named field from a block. - * @param {string} name The name of the field. - * @return {?Blockly.Field} Named field, or null if field does not exist. - */ - getField(name: string): Blockly.Field; - - /** - * Return all variables referenced by this block. - * @return {!Array} List of variable names. - */ - getVars(): string[]; - - /** - * Return all variables referenced by this block. - * @return {!Array} List of variable models. - * @package - */ - getVarModels(): Blockly.VariableModel[]; - - /** - * Notification that a variable is renaming but keeping the same ID. If the - * variable is in use on this block, rerender to show the new name. - * @param {!Blockly.VariableModel} variable The variable being renamed. - * @package - */ - updateVarName(variable: Blockly.VariableModel): void; - - /** - * Notification that a variable is renaming. - * If the ID matches one of this block's variables, rename it. - * @param {string} oldId ID of variable to rename. - * @param {string} newId ID of new variable. May be the same as oldId, but with - * an updated name. - */ - renameVarById(oldId: string, newId: string): void; - - /** - * Returns the language-neutral value of the given field. - * @param {string} name The name of the field. - * @return {*} Value of the field or null if field does not exist. - */ - getFieldValue(name: string): any; - - /** - * Sets the value of the given field for this block. - * @param {*} newValue The value to set. - * @param {string} name The name of the field to set the value of. - */ - setFieldValue(newValue: any, name: string): void; - - /** - * Set whether this block can chain onto the bottom of another block. - * @param {boolean} newBoolean True if there can be a previous statement. - * @param {(string|Array|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ - setPreviousStatement(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether another block can chain onto the bottom of this block. - * @param {boolean} newBoolean True if there can be a next statement. - * @param {(string|Array|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ - setNextStatement(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether this block returns a value. - * @param {boolean} newBoolean True if there is an output. - * @param {(string|Array|null)=} opt_check Returned type or list - * of returned types. Null or undefined if any type could be returned - * (e.g. variable get). - */ - setOutput(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether value inputs are arranged horizontally or vertically. - * @param {boolean} newBoolean True if inputs are horizontal. - */ - setInputsInline(newBoolean: boolean): void; - - /** - * Get whether value inputs are arranged horizontally or vertically. - * @return {boolean} True if inputs are horizontal. - */ - getInputsInline(): boolean; - - /** - * Set the block's output shape. - * @param {?number} outputShape Value representing an output shape. - */ - setOutputShape(outputShape: number): void; - - /** - * Get the block's output shape. - * @return {?number} Value representing output shape if one exists. - */ - getOutputShape(): number; - - /** - * Get whether this block is enabled or not. - * @return {boolean} True if enabled. - */ - isEnabled(): boolean; - - /** - * Set whether the block is enabled or not. - * @param {boolean} enabled True if enabled. - */ - setEnabled(enabled: boolean): void; - - /** - * Get whether the block is disabled or not due to parents. - * The block's own disabled property is not considered. - * @return {boolean} True if disabled. - */ - getInheritedDisabled(): boolean; - - /** - * Get whether the block is collapsed or not. - * @return {boolean} True if collapsed. - */ - isCollapsed(): boolean; - - /** - * Set whether the block is collapsed or not. - * @param {boolean} collapsed True if collapsed. - */ - setCollapsed(collapsed: boolean): void; - - /** - * Create a human-readable text representation of this block and any children. - * @param {number=} opt_maxLength Truncate the string to this length. - * @param {string=} opt_emptyToken The placeholder string used to denote an - * empty field. If not specified, '?' is used. - * @return {string} Text of block. - */ - toString(opt_maxLength?: number, opt_emptyToken?: string): string; - - /** - * Shortcut for appending a value input row. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ - appendValueInput(name: string): Blockly.Input; - - /** - * Shortcut for appending a statement input row. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ - appendStatementInput(name: string): Blockly.Input; - - /** - * Shortcut for appending a dummy input row. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - */ - appendDummyInput(opt_name?: string): Blockly.Input; - - /** - * Initialize this block using a cross-platform, internationalization-friendly - * JSON description. - * @param {!Object} json Structured data describing the block. - */ - jsonInit(json: Object): void; - - /** - * Add key/values from mixinObj to this block object. By default, this method - * will check that the keys in mixinObj will not overwrite existing values in - * the block, including prototype values. This provides some insurance against - * mixin / extension incompatibilities with future block features. This check - * can be disabled by passing true as the second argument. - * @param {!Object} mixinObj The key/values pairs to add to this block object. - * @param {boolean=} opt_disableCheck Option flag to disable overwrite checks. - */ - mixin(mixinObj: Object, opt_disableCheck?: boolean): void; - - /** - * Add a value input, statement input or local variable to this block. - * @param {number} type One of Blockly.inputTypes. - * @param {string} name Language-neutral identifier which may used to find this - * input again. Should be unique to this block. - * @return {!Blockly.Input} The input object created. - * @protected - */ - appendInput_(type: number, name: string): Blockly.Input; - - /** - * Move a named input to a different location on this block. - * @param {string} name The name of the input to move. - * @param {?string} refName Name of input that should be after the moved input, - * or null to be the input at the end. - */ - moveInputBefore(name: string, refName: string): void; - - /** - * Move a numbered input to a different location on this block. - * @param {number} inputIndex Index of the input to move. - * @param {number} refIndex Index of input that should be after the moved input. - */ - moveNumberedInputBefore(inputIndex: number, refIndex: number): void; - - /** - * Remove an input from this block. - * @param {string} name The name of the input. - * @param {boolean=} opt_quiet True to prevent an error if input is not present. - * @return {boolean} True if operation succeeds, false if input is not present and opt_quiet is true - * @throws {Error} if the input is not present and opt_quiet is not true. - */ - removeInput(name: string, opt_quiet?: boolean): boolean; - - /** - * Fetches the named input object. - * @param {string} name The name of the input. - * @return {?Blockly.Input} The input object, or null if input does not exist. - */ - getInput(name: string): Blockly.Input; - - /** - * Fetches the block attached to the named input. - * @param {string} name The name of the input. - * @return {?Blockly.Block} The attached value block, or null if the input is - * either disconnected or if the input does not exist. - */ - getInputTargetBlock(name: string): Blockly.Block; - - /** - * Returns the comment on this block (or null if there is no comment). - * @return {?string} Block's comment. - */ - getCommentText(): string; - - /** - * Set this block's comment text. - * @param {?string} text The text, or null to delete. - */ - setCommentText(text: string): void; - - /** - * Set this block's warning text. - * @param {?string} _text The text, or null to delete. - * @param {string=} _opt_id An optional ID for the warning text to be able to - * maintain multiple warnings. - */ - setWarningText(_text: string, _opt_id?: string): void; - - /** - * Give this block a mutator dialog. - * @param {Blockly.Mutator} _mutator A mutator dialog instance or null to - * remove. - */ - setMutator(_mutator: Blockly.Mutator): void; - - /** - * Return the coordinates of the top-left corner of this block relative to the - * drawing surface's origin (0,0), in workspace units. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - */ - getRelativeToSurfaceXY(): Blockly.utils.Coordinate; - - /** - * Move a block by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - */ - moveBy(dx: number, dy: number): void; - - /** - * Create a connection of the specified type. - * @param {number} type The type of the connection to create. - * @return {!Blockly.Connection} A new connection of the specified type. - * @protected - */ - makeConnection_(type: number): Blockly.Connection; - - /** - * Recursively checks whether all statement and value inputs are filled with - * blocks. Also checks all following statement blocks in this stack. - * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling - * whether shadow blocks are counted as filled. Defaults to true. - * @return {boolean} True if all inputs are filled, false otherwise. - */ - allInputsFilled(opt_shadowBlocksAreFilled?: boolean): boolean; - - /** - * This method returns a string describing this Block in developer terms (type - * name and ID; English only). - * - * Intended to on be used in console logs and errors. If you need a string that - * uses the user's native language (including block text, field values, and - * child blocks), use [toString()]{@link Blockly.Block#toString}. - * @return {string} The description. - */ - toDevString(): string; - } - -} - -declare module Blockly.Block { +declare module Block { /** * @typedef {{ * text:?string, * pinned:boolean, - * size:Blockly.utils.Size + * size:Size * }} */ interface CommentModel { text: string; pinned: boolean; - size: Blockly.utils.Size + size: Size } /** @@ -912,957 +124,10 @@ declare module Blockly.Block { } -declare module Blockly.blockAnimations { - - /** - * Play some UI effects (sound, animation) when disposing of a block. - * @param {!Blockly.BlockSvg} block The block being disposed of. - * @package - */ - function disposeUiEffect(block: Blockly.BlockSvg): void; - - /** - * Play some UI effects (sound, ripple) after a connection has been established. - * @param {!Blockly.BlockSvg} block The block being connected. - * @package - */ - function connectionUiEffect(block: Blockly.BlockSvg): void; - - /** - * Play some UI effects (sound, animation) when disconnecting a block. - * @param {!Blockly.BlockSvg} block The block being disconnected. - * @package - */ - function disconnectUiEffect(block: Blockly.BlockSvg): void; - - /** - * Stop the disconnect UI animation immediately. - * @package - */ - function disconnectUiStop(): void; -} -declare module Blockly { - class BlockDragSurfaceSvg extends BlockDragSurfaceSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockDragSurfaceSvg__Class { - - /** - * Class for a drag surface for the currently dragged block. This is a separate - * SVG that contains only the currently moving block, or nothing. - * @param {!Element} container Containing element. - * @constructor - */ - constructor(container: Element); - - /** - * Create the drag surface and inject it into the container. - */ - createDom(): void; - - /** - * Set the SVG blocks on the drag surface's group and show the surface. - * Only one block group should be on the drag surface at a time. - * @param {!SVGElement} blocks Block or group of blocks to place on the drag - * surface. - */ - setBlocksAndShow(blocks: SVGElement): void; - - /** - * Translate and scale the entire drag surface group to the given position, to - * keep in sync with the workspace. - * @param {number} x X translation in pixel coordinates. - * @param {number} y Y translation in pixel coordinates. - * @param {number} scale Scale of the group. - */ - translateAndScaleGroup(x: number, y: number, scale: number): void; - - /** - * Translates the entire surface by a relative offset. - * @param {number} deltaX Horizontal offset in pixel units. - * @param {number} deltaY Vertical offset in pixel units. - */ - translateBy(deltaX: number, deltaY: number): void; - - /** - * Translate the entire drag surface during a drag. - * We translate the drag surface instead of the blocks inside the surface - * so that the browser avoids repainting the SVG. - * Because of this, the drag coordinates must be adjusted by scale. - * @param {number} x X translation for the entire surface. - * @param {number} y Y translation for the entire surface. - */ - translateSurface(x: number, y: number): void; - - /** - * Reports the surface translation in scaled workspace coordinates. - * Use this when finishing a drag to return blocks to the correct position. - * @return {!Blockly.utils.Coordinate} Current translation of the surface. - */ - getSurfaceTranslation(): Blockly.utils.Coordinate; - - /** - * Provide a reference to the drag group (primarily for - * BlockSvg.getRelativeToSurfaceXY). - * @return {?SVGElement} Drag surface group element. - */ - getGroup(): SVGElement; - - /** - * Returns the SVG drag surface. - * @returns {?SVGElement} The SVG drag surface. - */ - getSvgRoot(): SVGElement; - - /** - * Get the current blocks on the drag surface, if any (primarily - * for BlockSvg.getRelativeToSurfaceXY). - * @return {?Element} Drag surface block DOM element, or null if no blocks exist. - */ - getCurrentBlock(): Element; - - /** - * Gets the translation of the child block surface - * This surface is in charge of keeping track of how much the workspace has - * moved. - * @return {!Blockly.utils.Coordinate} The amount the workspace has been moved. - */ - getWsTranslation(): Blockly.utils.Coordinate; - - /** - * Clear the group and hide the surface; move the blocks off onto the provided - * element. - * If the block is being deleted it doesn't need to go back to the original - * surface, since it would be removed immediately during dispose. - * @param {Element=} opt_newSurface Surface the dragging blocks should be moved - * to, or null if the blocks should be removed from this surface without - * being moved to a different surface. - */ - clearAndHide(opt_newSurface?: Element): void; - } - -} - - -declare module Blockly { - - class BlockDragger extends BlockDragger__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockDragger__Class implements Blockly.IBlockDragger { - - /** - * Class for a block dragger. It moves blocks around the workspace when they - * are being dragged by a mouse or touch. - * @param {!Blockly.BlockSvg} block The block to drag. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on. - * @constructor - * @implements {Blockly.IBlockDragger} - */ - constructor(block: Blockly.BlockSvg, workspace: Blockly.WorkspaceSvg); - - /** - * The top block in the stack that is being dragged. - * @type {!Blockly.BlockSvg} - * @protected - */ - draggingBlock_: Blockly.BlockSvg; - - /** - * The workspace on which the block is being dragged. - * @type {!Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * Object that keeps track of connections on dragged blocks. - * @type {!Blockly.InsertionMarkerManager} - * @protected - */ - draggedConnectionManager_: Blockly.InsertionMarkerManager; - - /** - * Whether the block would be deleted if dropped immediately. - * @type {boolean} - * @protected - */ - wouldDeleteBlock_: boolean; - - /** - * The location of the top left corner of the dragging block at the beginning - * of the drag in workspace coordinates. - * @type {!Blockly.utils.Coordinate} - * @protected - */ - startXY_: Blockly.utils.Coordinate; - - /** - * A list of all of the icons (comment, warning, and mutator) that are - * on this block and its descendants. Moving an icon moves the bubble that - * extends from it if that bubble is open. - * @type {Array} - * @protected - */ - dragIconData_: Object[]; - - /** - * Sever all links from this object. - * @package - */ - dispose(): void; - - /** - * Start dragging a block. This includes moving it to the drag surface. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @param {boolean} healStack Whether or not to heal the stack after - * disconnecting. - * @public - */ - startDrag(currentDragDeltaXY: Blockly.utils.Coordinate, healStack: boolean): void; - - /** - * Whether or not we should disconnect the block when a drag is started. - * @param {boolean} healStack Whether or not to heal the stack after - * disconnecting. - * @return {boolean} True to disconnect the block, false otherwise. - * @protected - */ - shouldDisconnect_(healStack: boolean): boolean; - - /** - * Disconnects the block and moves it to a new location. - * @param {boolean} healStack Whether or not to heal the stack after - * disconnecting. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @protected - */ - disconnectBlock_(healStack: boolean, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Fire a UI event at the start of a block drag. - * @protected - */ - fireDragStartEvent_(): void; - - /** - * Execute a step of block dragging, based on the given event. Update the - * display accordingly. - * @param {!Event} e The most recent move event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @public - */ - drag(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Finish a block drag and put the block back on the workspace. - * @param {!Event} e The mouseup/touchend event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @public - */ - endDrag(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Calculates the drag delta and new location values after a block is dragged. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the start of the drag, in pixel units. - * @return {{delta: !Blockly.utils.Coordinate, newLocation: - * !Blockly.utils.Coordinate}} New location after drag. delta is in - * workspace units. newLocation is the new coordinate where the block should - * end up. - * @protected - */ - getNewLocationAfterDrag_(currentDragDeltaXY: Blockly.utils.Coordinate): { delta: Blockly.utils.Coordinate; newLocation: Blockly.utils.Coordinate }; - - /** - * May delete the dragging block, if allowed. If `this.wouldDeleteBlock_` is not - * true, the block will not be deleted. This should be called at the end of a - * block drag. - * @return {boolean} True if the block was deleted. - * @protected - */ - maybeDeleteBlock_(): boolean; - - /** - * Updates the necessary information to place a block at a certain location. - * @param {!Blockly.utils.Coordinate} delta The change in location from where - * the block started the drag to where it ended the drag. - * @protected - */ - updateBlockAfterMove_(delta: Blockly.utils.Coordinate): void; - - /** - * Fire a UI event at the end of a block drag. - * @protected - */ - fireDragEndEvent_(): void; - - /** - * Adds or removes the style of the cursor for the toolbox. - * This is what changes the cursor to display an x when a deletable block is - * held over the toolbox. - * @param {boolean} isEnd True if we are at the end of a drag, false otherwise. - * @protected - */ - updateToolboxStyle_(isEnd: boolean): void; - - /** - * Fire a move event at the end of a block drag. - * @protected - */ - fireMoveEvent_(): void; - - /** - * Update the cursor (and possibly the trash can lid) to reflect whether the - * dragging block would be deleted if released immediately. - * @protected - */ - updateCursorDuringBlockDrag_(): void; - - /** - * Convert a coordinate object from pixels to workspace units, including a - * correction for mutator workspaces. - * This function does not consider differing origins. It simply scales the - * input's x and y values. - * @param {!Blockly.utils.Coordinate} pixelCoord A coordinate with x and y - * values in CSS pixel units. - * @return {!Blockly.utils.Coordinate} The input coordinate divided by the - * workspace scale. - * @protected - */ - pixelsToWorkspaceUnits_(pixelCoord: Blockly.utils.Coordinate): Blockly.utils.Coordinate; - - /** - * Move all of the icons connected to this drag. - * @param {!Blockly.utils.Coordinate} dxy How far to move the icons from their - * original positions, in workspace units. - * @protected - */ - dragIcons_(dxy: Blockly.utils.Coordinate): void; - - /** - * Get a list of the insertion markers that currently exist. Drags have 0, 1, - * or 2 insertion markers. - * @return {!Array} A possibly empty list of insertion - * marker blocks. - * @public - */ - getInsertionMarkers(): Blockly.BlockSvg[]; - } - -} - - -declare module Blockly { - - class BlockSvg extends BlockSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockSvg__Class extends Blockly.Block__Class implements Blockly.IASTNodeLocationSvg, Blockly.IBoundedElement, Blockly.ICopyable, Blockly.IDraggable { - - /** - * Class for a block's SVG representation. - * Not normally called directly, workspace.newBlock() is preferred. - * @param {!Blockly.WorkspaceSvg} workspace The block's workspace. - * @param {?string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @extends {Blockly.Block} - * @implements {Blockly.IASTNodeLocationSvg} - * @implements {Blockly.IBoundedElement} - * @implements {Blockly.ICopyable} - * @implements {Blockly.IDraggable} - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, prototypeName: string, opt_id?: string); - - /** - * A block style object. - * @type {!Blockly.Theme.BlockStyle} - */ - style: Blockly.Theme.BlockStyle; - - /** - * The renderer's path object. - * @type {Blockly.blockRendering.IPathObject} - * @package - */ - pathObject: Blockly.blockRendering.IPathObject; - - /** @type {boolean} */ - rendered: boolean; - - /** @type {!Blockly.WorkspaceSvg} */ - workspace: Blockly.WorkspaceSvg; - - /** @type {Blockly.RenderedConnection} */ - outputConnection: Blockly.RenderedConnection; - - /** @type {Blockly.RenderedConnection} */ - nextConnection: Blockly.RenderedConnection; - - /** @type {Blockly.RenderedConnection} */ - previousConnection: Blockly.RenderedConnection; - - /** - * Height of this block, not including any statement blocks above or below. - * Height is in workspace units. - */ - height: any /*missing*/; - - /** - * Width of this block, including any connected value blocks. - * Width is in workspace units. - */ - width: any /*missing*/; - - /** - * An optional method called when a mutator dialog is first opened. - * This function must create and initialize a top-level block for the mutator - * dialog, and return it. This function should also populate this top-level - * block with any sub-blocks which are appropriate. This method must also be - * coupled with defining a `compose` method for the default mutation dialog - * button and UI to appear. - * @type {?function(Blockly.WorkspaceSvg):!Blockly.BlockSvg} - */ - decompose: { (_0: Blockly.WorkspaceSvg): Blockly.BlockSvg }; - - /** - * An optional method called when a mutator dialog saves its content. - * This function is called to modify the original block according to new - * settings. This method must also be coupled with defining a `decompose` - * method for the default mutation dialog button and UI to appear. - * @type {?function(!Blockly.BlockSvg)} - */ - compose: { (_0: Blockly.BlockSvg): any /*missing*/ }; - - /** - * An optional method for defining custom block context menu items. - * @type {?function(!Array)} - */ - customContextMenu: { (_0: Object[]): any /*missing*/ }; - - /** - * An property used internally to reference the block's rendering debugger. - * @type {?Blockly.blockRendering.Debug} - * @package - */ - renderingDebugger: Blockly.blockRendering.Debug; - - /** - * Create and initialize the SVG representation of the block. - * May be called more than once. - */ - initSvg(): void; - - /** - * Get the secondary colour of a block. - * @return {?string} #RRGGBB string. - */ - getColourSecondary(): string; - - /** - * Get the tertiary colour of a block. - * @return {?string} #RRGGBB string. - */ - getColourTertiary(): string; - - /** - * Get the shadow colour of a block. - * @return {?string} #RRGGBB string. - * @deprecated Use style.colourSecondary. (2020 January 21) - */ - getColourShadow(): string; - - /** - * Get the border colour(s) of a block. - * @return {{colourDark, colourLight, colourBorder}} An object containing - * colour values for the border(s) of the block. If the block is using a - * style the colourBorder will be defined and equal to the tertiary colour - * of the style (#RRGGBB string). Otherwise the colourDark and colourLight - * attributes will be defined (#RRGGBB strings). - * @deprecated Use style.colourTertiary. (2020 January 21) - */ - getColourBorder(): { colourDark: any /*missing*/; colourLight: any /*missing*/; colourBorder: any /*missing*/ }; - - /** - * Select this block. Highlight it visually. - */ - select(): void; - - /** - * Unselect this block. Remove its highlighting. - */ - unselect(): void; - - /** - * Block's mutator icon (if any). - * @type {?Blockly.Mutator} - */ - mutator: Blockly.Mutator; - - /** - * Block's comment icon (if any). - * @type {?Blockly.Comment} - * @deprecated August 2019. Use getCommentIcon instead. - */ - comment: Blockly.Comment; - - /** - * Block's warning icon (if any). - * @type {?Blockly.Warning} - */ - warning: Blockly.Warning; - - /** - * Returns a list of mutator, comment, and warning icons. - * @return {!Array} List of icons. - */ - getIcons(): Blockly.Icon[]; - - /** - * Return the coordinates of the top-left corner of this block relative to the - * drawing surface's origin (0,0), in workspace units. - * If the block is on the workspace, (0, 0) is the origin of the workspace - * coordinate system. - * This does not change with workspace scale. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties in - * workspace coordinates. - */ - getRelativeToSurfaceXY(): Blockly.utils.Coordinate; - - /** - * Move a block by a relative offset. - * @param {number} dx Horizontal offset in workspace units. - * @param {number} dy Vertical offset in workspace units. - */ - moveBy(dx: number, dy: number): void; - - /** - * Transforms a block by setting the translation on the transform attribute - * of the block's SVG. - * @param {number} x The x coordinate of the translation in workspace units. - * @param {number} y The y coordinate of the translation in workspace units. - */ - translate(x: number, y: number): void; - - /** - * Move this block to its workspace's drag surface, accounting for positioning. - * Generally should be called at the same time as setDragging_(true). - * Does nothing if useDragSurface_ is false. - * @package - */ - moveToDragSurface(): void; - - /** - * Move a block to a position. - * @param {Blockly.utils.Coordinate} xy The position to move to in workspace units. - */ - moveTo(xy: Blockly.utils.Coordinate): void; - - /** - * Move this block back to the workspace block canvas. - * Generally should be called at the same time as setDragging_(false). - * Does nothing if useDragSurface_ is false. - * @param {!Blockly.utils.Coordinate} newXY The position the block should take on - * on the workspace canvas, in workspace coordinates. - * @package - */ - moveOffDragSurface(newXY: Blockly.utils.Coordinate): void; - - /** - * Move this block during a drag, taking into account whether we are using a - * drag surface to translate blocks. - * This block must be a top-level block. - * @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ - moveDuringDrag(newLoc: Blockly.utils.Coordinate): void; - - /** - * Snap this block to the nearest grid point. - */ - snapToGrid(): void; - - /** - * Returns the coordinates of a bounding box describing the dimensions of this - * block and any blocks stacked below it. - * Coordinate system: workspace coordinates. - * @return {!Blockly.utils.Rect} Object with coordinates of the bounding box. - */ - getBoundingRectangle(): Blockly.utils.Rect; - - /** - * Notify every input on this block to mark its fields as dirty. - * A dirty field is a field that needs to be re-rendered. - */ - markDirty(): void; - - /** - * Set whether the block is collapsed or not. - * @param {boolean} collapsed True if collapsed. - */ - setCollapsed(collapsed: boolean): void; - - /** - * Open the next (or previous) FieldTextInput. - * @param {!Blockly.Field} start Current field. - * @param {boolean} forward If true go forward, otherwise backward. - */ - tab(start: Blockly.Field, forward: boolean): void; - - /** - * Load the block's help page in a new window. - * @package - */ - showHelp(): void; - - /** - * Generate the context menu for this block. - * @protected - * @return {?Array} Context menu options or null if no menu. - */ - generateContextMenu(): Object[]; - - /** - * Show the context menu for this block. - * @param {!Event} e Mouse event. - * @package - */ - showContextMenu(e: Event): void; - - /** - * Move the connections for this block and all blocks attached under it. - * Also update any attached bubbles. - * @param {number} dx Horizontal offset from current location, in workspace - * units. - * @param {number} dy Vertical offset from current location, in workspace - * units. - * @package - */ - moveConnections(dx: number, dy: number): void; - - /** - * Recursively adds or removes the dragging class to this node and its children. - * @param {boolean} adding True if adding, false if removing. - * @package - */ - setDragging(adding: boolean): void; - - /** - * Set whether this block is movable or not. - * @param {boolean} movable True if movable. - */ - setMovable(movable: boolean): void; - - /** - * Set whether this block is editable or not. - * @param {boolean} editable True if editable. - */ - setEditable(editable: boolean): void; - - /** - * Set whether this block is a shadow block or not. - * @param {boolean} shadow True if a shadow. - */ - setShadow(shadow: boolean): void; - - /** - * Set whether this block is an insertion marker block or not. - * Once set this cannot be unset. - * @param {boolean} insertionMarker True if an insertion marker. - * @package - */ - setInsertionMarker(insertionMarker: boolean): void; - - /** - * Return the root node of the SVG or null if none exists. - * @return {!SVGGElement} The root SVG node (probably a group). - */ - getSvgRoot(): SVGGElement; - - /** - * Dispose of this block. - * @param {boolean=} healStack If true, then try to heal any gap by connecting - * the next statement with the previous statement. Otherwise, dispose of - * all children of this block. - * @param {boolean=} animate If true, show a disposal animation and sound. - * @suppress {checkTypes} - */ - dispose(healStack?: boolean, animate?: boolean): void; - - /** - * Encode a block for copying. - * @return {?Blockly.ICopyable.CopyData} Copy metadata, or null if the block is - * an insertion marker. - * @package - */ - toCopyData(): Blockly.ICopyable.CopyData; - - /** - * Change the colour of a block. - * @package - */ - applyColour(): void; - - /** - * Enable or disable a block. - */ - updateDisabled(): void; - - /** - * Get the comment icon attached to this block, or null if the block has no - * comment. - * @return {?Blockly.Comment} The comment icon attached to this block, or null. - */ - getCommentIcon(): Blockly.Comment; - - /** - * Set this block's comment text. - * @param {?string} text The text, or null to delete. - */ - setCommentText(text: string): void; - - /** - * Set this block's warning text. - * @param {?string} text The text, or null to delete. - * @param {string=} opt_id An optional ID for the warning text to be able to - * maintain multiple warnings. - */ - setWarningText(text: string, opt_id?: string): void; - - /** - * Give this block a mutator dialog. - * @param {?Blockly.Mutator} mutator A mutator dialog instance or null to remove. - */ - setMutator(mutator: Blockly.Mutator): void; - - /** - * Set whether the block is enabled or not. - * @param {boolean} enabled True if enabled. - */ - setEnabled(enabled: boolean): void; - - /** - * Set whether the block is highlighted or not. Block highlighting is - * often used to visually mark blocks currently being executed. - * @param {boolean} highlighted True if highlighted. - */ - setHighlighted(highlighted: boolean): void; - - /** - * Select this block. Highlight it visually. - */ - addSelect(): void; - - /** - * Unselect this block. Remove its highlighting. - */ - removeSelect(): void; - - /** - * Update the cursor over this block by adding or removing a class. - * @param {boolean} enable True if the delete cursor should be shown, false - * otherwise. - * @package - */ - setDeleteStyle(enable: boolean): void; - - /** - * Get the colour of a block. - * @return {string} #RRGGBB string. - */ - getColour(): string; - - /** - * Change the colour of a block. - * @param {number|string} colour HSV hue value, or #RRGGBB string. - */ - setColour(colour: number|string): void; - - /** - * Set the style and colour values of a block. - * @param {string} blockStyleName Name of the block style. - * @throws {Error} if the block style does not exist. - */ - setStyle(blockStyleName: string): void; - - /** - * Move this block to the front of the visible workspace. - * tags do not respect z-index so SVG renders them in the - * order that they are in the DOM. By placing this block first within the - * block group's , it will render on top of any other blocks. - * @package - */ - bringToFront(): void; - - /** - * Set whether this block can chain onto the bottom of another block. - * @param {boolean} newBoolean True if there can be a previous statement. - * @param {(string|Array|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ - setPreviousStatement(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether another block can chain onto the bottom of this block. - * @param {boolean} newBoolean True if there can be a next statement. - * @param {(string|Array|null)=} opt_check Statement type or - * list of statement types. Null/undefined if any type could be connected. - */ - setNextStatement(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether this block returns a value. - * @param {boolean} newBoolean True if there is an output. - * @param {(string|Array|null)=} opt_check Returned type or list - * of returned types. Null or undefined if any type could be returned - * (e.g. variable get). - */ - setOutput(newBoolean: boolean, opt_check?: string|string[]|any /*null*/): void; - - /** - * Set whether value inputs are arranged horizontally or vertically. - * @param {boolean} newBoolean True if inputs are horizontal. - */ - setInputsInline(newBoolean: boolean): void; - - /** - * Remove an input from this block. - * @param {string} name The name of the input. - * @param {boolean=} opt_quiet True to prevent error if input is not present. - * @return {boolean} True if operation succeeds, false if input is not present and opt_quiet is true - * @throws {Error} if the input is not present and - * opt_quiet is not true. - */ - removeInput(name: string, opt_quiet?: boolean): boolean; - - /** - * Move a numbered input to a different location on this block. - * @param {number} inputIndex Index of the input to move. - * @param {number} refIndex Index of input that should be after the moved input. - */ - moveNumberedInputBefore(inputIndex: number, refIndex: number): void; - - /** - * Sets whether this block's connections are tracked in the database or not. - * - * Used by the deserializer to be more efficient. Setting a connection's - * tracked_ value to false keeps it from adding itself to the db when it - * gets its first moveTo call, saving expensive ops for later. - * @param {boolean} track If true, start tracking. If false, stop tracking. - * @package - */ - setConnectionTracking(track: boolean): void; - - /** - * Returns connections originating from this block. - * @param {boolean} all If true, return all connections even hidden ones. - * Otherwise, for a non-rendered block return an empty list, and for a - * collapsed block don't return inputs connections. - * @return {!Array} Array of connections. - * @package - */ - getConnections_(all: boolean): Blockly.RenderedConnection[]; - - /** - * Create a connection of the specified type. - * @param {number} type The type of the connection to create. - * @return {!Blockly.RenderedConnection} A new connection of the specified type. - * @protected - */ - makeConnection_(type: number): Blockly.RenderedConnection; - - /** - * Bump unconnected blocks out of alignment. Two blocks which aren't actually - * connected should not coincidentally line up on screen. - */ - bumpNeighbours(): void; - - /** - * Schedule snapping to grid and bumping neighbours to occur after a brief - * delay. - * @package - */ - scheduleSnapAndBump(): void; - - /** - * Position a block so that it doesn't move the target block when connected. - * The block to position is usually either the first block in a dragged stack or - * an insertion marker. - * @param {!Blockly.RenderedConnection} sourceConnection The connection on the - * moving block's stack. - * @param {!Blockly.RenderedConnection} targetConnection The connection that - * should stay stationary as this block is positioned. - * @package - */ - positionNearConnection(sourceConnection: Blockly.RenderedConnection, targetConnection: Blockly.RenderedConnection): void; - - /** - * Lays out and reflows a block based on its contents and settings. - * @param {boolean=} opt_bubble If false, just render this block. - * If true, also render block's parent, grandparent, etc. Defaults to true. - */ - render(opt_bubble?: boolean): void; - - /** - * Redraw any attached marker or cursor svgs if needed. - * @protected - */ - updateMarkers_(): void; - - /** - * Add the cursor SVG to this block's SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * block SVG group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this block's SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * block SVG group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Returns a bounding box describing the dimensions of this block - * and any blocks stacked below it. - * @return {!{height: number, width: number}} Object with height and width - * properties in workspace units. - * @package - */ - getHeightWidth(): { height: number; width: number }; - - /** - * Visual effect to show that if the dragging block is dropped, this block will - * be replaced. If a shadow block, it will disappear. Otherwise it will bump. - * @param {boolean} add True if highlighting should be added. - * @package - */ - fadeForReplacement(add: boolean): void; - - /** - * Visual effect to show that if the dragging block is dropped it will connect - * to this input. - * @param {Blockly.Connection} conn The connection on the input to highlight. - * @param {boolean} add True if highlighting should be added. - * @package - */ - highlightShapeForInput(conn: Blockly.Connection, add: boolean): void; - } - -} - -declare module Blockly.BlockSvg { +declare module BlockSvg { /** * Constant for identifying rows that are to be rendered inline. @@ -1882,7 +147,7 @@ declare module Blockly.BlockSvg { } -declare module Blockly { +declare module exports { /** * Blockly core version. @@ -1892,167 +157,43 @@ declare module Blockly { * For local builds, you can pass --define='Blockly.VERSION=X.Y.Z' to the * compiler to override this constant. * @define {string} + * @alias Blockly.VERSION */ var VERSION: any /*missing*/; - /** - * The main workspace most recently used. - * Set by Blockly.WorkspaceSvg.prototype.markFocused - * @type {Blockly.Workspace} - */ - var mainWorkspace: Blockly.Workspace; - - /** - * Currently selected block. - * @type {?Blockly.ICopyable} - */ - var selected: Blockly.ICopyable; - - /** - * All of the connections on blocks that are currently being dragged. - * @type {!Array} - * @package - */ - var draggingConnections: Blockly.Connection[]; - - /** - * Container element to render the WidgetDiv, DropDownDiv and Tooltip. - * @type {?Element} - * @package - */ - var parentContainer: Element; - - /** - * Returns the dimensions of the specified SVG image. - * @param {!SVGElement} svg SVG image. - * @return {!Blockly.utils.Size} Contains width and height properties. - * @deprecated Use workspace.setCachedParentSvgSize. (2021 March 5) - */ - function svgSize(svg: SVGElement): Blockly.utils.Size; - - /** - * Size the workspace when the contents change. This also updates - * scrollbars accordingly. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to resize. - */ - function resizeSvgContents(workspace: Blockly.WorkspaceSvg): void; - - /** - * Size the SVG image to completely fill its container. Call this when the view - * actually changes sizes (e.g. on a window resize/device orientation change). - * See Blockly.resizeSvgContents to resize the workspace when the contents - * change (e.g. when a block is added or removed). - * Record the height/width of the SVG image. - * @param {!Blockly.WorkspaceSvg} workspace Any workspace in the SVG. - */ - function svgResize(workspace: Blockly.WorkspaceSvg): void; - - /** - * Handle a key-down on SVG drawing surface. Does nothing if the main workspace - * is not visible. - * @param {!KeyboardEvent} e Key down event. - * @package - */ - function onKeyDown(e: KeyboardEvent): void; - - /** - * Delete the given block. - * @param {!Blockly.BlockSvg} selected The block to delete. - * @package - */ - function deleteBlock(selected: Blockly.BlockSvg): void; - /** * Copy a block or workspace comment onto the local clipboard. - * @param {!Blockly.ICopyable} toCopy Block or Workspace Comment to be copied. + * @param {!ICopyable} toCopy Block or Workspace Comment to be copied. * @package + * @alias Blockly.copy */ - function copy(toCopy: Blockly.ICopyable): void; + function copy(toCopy: ICopyable): void; /** * Paste a block or workspace comment on to the main workspace. * @return {boolean} True if the paste was successful, false otherwise. * @package + * @alias Blockly.paste */ function paste(): boolean; /** * Duplicate this block and its children, or a workspace comment. - * @param {!Blockly.ICopyable} toDuplicate Block or Workspace Comment to be + * @param {!ICopyable} toDuplicate Block or Workspace Comment to be * copied. * @package + * @alias Blockly.duplicate */ - function duplicate(toDuplicate: Blockly.ICopyable): void; - - /** - * Close tooltips, context menus, dropdown selections, etc. - * @param {boolean=} opt_onlyClosePopups Whether only popups should be closed. - */ - function hideChaff(opt_onlyClosePopups?: boolean): void; + function duplicate(toDuplicate: ICopyable): void; /** * Returns the main workspace. Returns the last used main workspace (based on * focus). Try not to use this function, particularly if there are multiple * Blockly instances on a page. - * @return {!Blockly.Workspace} The main workspace. + * @return {!Workspace} The main workspace. + * @alias Blockly.getMainWorkspace */ - function getMainWorkspace(): Blockly.Workspace; - - /** - * Wrapper to window.alert() that app developers may override to - * provide alternatives to the modal browser window. - * @param {string} message The message to display to the user. - * @param {function()=} opt_callback The callback when the alert is dismissed. - */ - function alert(message: string, opt_callback?: { (): any /*missing*/ }): void; - - /** - * Wrapper to window.confirm() that app developers may override to - * provide alternatives to the modal browser window. - * @param {string} message The message to display to the user. - * @param {!function(boolean)} callback The callback for handling user response. - */ - function confirm(message: string, callback: { (_0: boolean): any /*missing*/ }): void; - - /** - * Wrapper to window.prompt() that app developers may override to provide - * alternatives to the modal browser window. Built-in browser prompts are - * often used for better text input experience on mobile device. We strongly - * recommend testing mobile when overriding this. - * @param {string} message The message to display to the user. - * @param {string} defaultValue The value to initialize the prompt with. - * @param {!function(?string)} callback The callback for handling user response. - */ - function prompt(message: string, defaultValue: string, callback: { (_0: string): any /*missing*/ }): void; - - /** - * Define blocks from an array of JSON block definitions, as might be generated - * by the Blockly Developer Tools. - * @param {!Array} jsonArray An array of JSON block definitions. - */ - function defineBlocksWithJsonArray(jsonArray: Object[]): void; - - /** - * Is the given string a number (includes negative and decimals). - * @param {string} str Input string. - * @return {boolean} True if number, false otherwise. - */ - function isNumber(str: string): boolean; - - /** - * Convert a hue (HSV model) into an RGB hex triplet. - * @param {number} hue Hue on a colour wheel (0-360). - * @return {string} RGB code, e.g. '#5ba65b'. - */ - function hueToHex(hue: number): string; - - /** - * Checks old colour constants are not overwritten by the host application. - * If a constant is overwritten, it prints a console warning directing the - * developer to use the equivalent Msg constant. - * @package - */ - function checkBlockColourConstants(): void; + function getMainWorkspace(): Workspace; /** * Set the parent container. This is the container element that the WidgetDiv, @@ -2060,313 +201,121 @@ declare module Blockly { * is called. * This method is a NOP if called after the first ``Blockly.inject``. * @param {!Element} container The container element. + * @alias Blockly.setParentContainer */ function setParentContainer(container: Element): void; /** - * @see Blockly.browserEvents.bind + * @see colour.hueToHex + * @deprecated Use Blockly.utils.colour.hueToHex (September 2021). + * @alias Blockly.hueToHex + */ + var hueToHex: any /*missing*/; + + /** + * @see browserEvents.bind + * @alias Blockly.bindEvent_ */ var bindEvent_: any /*missing*/; /** - * @see Blockly.browserEvents.unbind + * @see browserEvents.unbind + * @alias Blockly.unbindEvent_ */ var unbindEvent_: any /*missing*/; /** - * @see Blockly.browserEvents.conditionalBind + * @see browserEvents.conditionalBind + * @alias Blockly.bindEventWithChecks_ */ var bindEventWithChecks_: any /*missing*/; /** - * @see Blockly.constants.ALIGN.LEFT + * @see constants.ALIGN.LEFT + * @alias Blockly.ALIGN_LEFT */ var ALIGN_LEFT: any /*missing*/; /** - * @see Blockly.constants.ALIGN.CENTRE + * @see constants.ALIGN.CENTRE + * @alias Blockly.ALIGN_CENTRE */ var ALIGN_CENTRE: any /*missing*/; /** - * @see Blockly.constants.ALIGN.RIGHT + * @see constants.ALIGN.RIGHT + * @alias Blockly.ALIGN_RIGHT */ var ALIGN_RIGHT: any /*missing*/; /** - * @see Blockly.connectionTypes.INPUT_VALUE + * @see common.svgResize + */ + var svgResize: any /*missing*/; + + /** + * @see ConnectionType.INPUT_VALUE + * @alias Blockly.INPUT_VALUE */ var INPUT_VALUE: any /*missing*/; /** - * @see Blockly.connectionTypes.OUTPUT_VALUE + * @see ConnectionType.OUTPUT_VALUE + * @alias Blockly.OUTPUT_VALUE */ var OUTPUT_VALUE: any /*missing*/; /** - * @see Blockly.connectionTypes.NEXT_STATEMENT + * @see ConnectionType.NEXT_STATEMENT + * @alias Blockly.NEXT_STATEMENT */ var NEXT_STATEMENT: any /*missing*/; /** - * @see Blockly.connectionTypes.PREVIOUS_STATEMENT + * @see ConnectionType.PREVIOUS_STATEMENT + * @alias Blockly.PREVIOUS_STATEMENT */ var PREVIOUS_STATEMENT: any /*missing*/; /** - * @see Blockly.inputTypes.DUMMY_INPUT + * @see inputTypes.DUMMY_INPUT + * @alias Blockly.DUMMY_INPUT */ var DUMMY_INPUT: any /*missing*/; /** - * @see Blockly.utils.toolbox.Position.TOP + * @see toolbox.Position.TOP + * @alias Blockly.TOOLBOX_AT_TOP */ var TOOLBOX_AT_TOP: any /*missing*/; /** - * @see Blockly.utils.toolbox.Position.BOTTOM + * @see toolbox.Position.BOTTOM + * @alias Blockly.TOOLBOX_AT_BOTTOM */ var TOOLBOX_AT_BOTTOM: any /*missing*/; /** - * @see Blockly.utils.toolbox.Position.LEFT + * @see toolbox.Position.LEFT + * @alias Blockly.TOOLBOX_AT_LEFT */ var TOOLBOX_AT_LEFT: any /*missing*/; /** - * @see Blockly.utils.toolbox.Position.RIGHT + * @see toolbox.Position.RIGHT + * @alias Blockly.TOOLBOX_AT_RIGHT */ var TOOLBOX_AT_RIGHT: any /*missing*/; + + /** @deprecated Use Blockly.ConnectionType instead. */ + var connectionTypes: any /*missing*/; } -declare module Blockly { - - /** - * A mapping of block type names to block prototype objects. - * @type {!Object} - */ - var Blocks: { [key: string]: Object }; -} -declare module Blockly.browserEvents { - /** - * Blockly opaque event data used to unbind events when using - * `Blockly.browserEvents.bind` and - * `Blockly.browserEvents.conditionalBind`. - * @typedef {!Array} - */ - interface Data extends Array { } - - /** - * Bind an event handler that can be ignored if it is not part of the active - * touch stream. - * Use this for events that either start or continue a multi-part gesture (e.g. - * mousedown or mousemove, which may be part of a drag or click). - * @param {!EventTarget} node Node upon which to listen. - * @param {string} name Event name to listen to (e.g. 'mousedown'). - * @param {?Object} thisObject The value of 'this' in the function. - * @param {!Function} func Function to call when event is triggered. - * @param {boolean=} opt_noCaptureIdentifier True if triggering on this event - * should not block execution of other event handlers on this touch or - * other simultaneous touches. False by default. - * @param {boolean=} opt_noPreventDefault True if triggering on this event - * should prevent the default handler. False by default. If - * opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be - * provided. - * @return {!Blockly.browserEvents.Data} Opaque data that can be passed to - * unbindEvent_. - * @public - */ - function conditionalBind(node: EventTarget, name: string, thisObject: Object, func: Function, opt_noCaptureIdentifier?: boolean, opt_noPreventDefault?: boolean): Blockly.browserEvents.Data; - - /** - * Bind an event handler that should be called regardless of whether it is part - * of the active touch stream. - * Use this for events that are not part of a multi-part gesture (e.g. - * mouseover for tooltips). - * @param {!EventTarget} node Node upon which to listen. - * @param {string} name Event name to listen to (e.g. 'mousedown'). - * @param {?Object} thisObject The value of 'this' in the function. - * @param {!Function} func Function to call when event is triggered. - * @return {!Blockly.browserEvents.Data} Opaque data that can be passed to - * unbindEvent_. - * @public - */ - function bind(node: EventTarget, name: string, thisObject: Object, func: Function): Blockly.browserEvents.Data; - - /** - * Unbind one or more events event from a function call. - * @param {!Blockly.browserEvents.Data} bindData Opaque data from bindEvent_. - * This list is emptied during the course of calling this function. - * @return {!Function} The function call. - * @public - */ - function unbind(bindData: Blockly.browserEvents.Data): Function; -} - - -declare module Blockly { - - class Bubble extends Bubble__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Bubble__Class implements Blockly.IBubble { - - /** - * Class for UI bubble. - * @param {!Blockly.WorkspaceSvg} workspace The workspace on which to draw the - * bubble. - * @param {!Element} content SVG content for the bubble. - * @param {!Element} shape SVG element to avoid eclipsing. - * @param {!Blockly.utils.Coordinate} anchorXY Absolute position of bubble's - * anchor point. - * @param {?number} bubbleWidth Width of bubble, or null if not resizable. - * @param {?number} bubbleHeight Height of bubble, or null if not resizable. - * @implements {Blockly.IBubble} - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, content: Element, shape: Element, anchorXY: Blockly.utils.Coordinate, bubbleWidth: number, bubbleHeight: number); - - /** - * Describes whether this bubble has been disposed of (nodes and event - * listeners removed from the page) or not. - * @type {boolean} - * @package - */ - disposed: boolean; - - /** - * Return the root node of the bubble's SVG group. - * @return {!SVGElement} The root SVG node of the bubble's group. - */ - getSvgRoot(): SVGElement; - - /** - * Expose the block's ID on the bubble's top-level SVG group. - * @param {string} id ID of block. - */ - setSvgId(id: string): void; - - /** - * Show the context menu for this bubble. - * @param {!Event} _e Mouse event. - * @package - */ - showContextMenu(_e: Event): void; - - /** - * Get whether this bubble is deletable or not. - * @return {boolean} True if deletable. - * @package - */ - isDeletable(): boolean; - - /** - * Update the style of this bubble when it is dragged over a delete area. - * @param {boolean} _enable True if the bubble is about to be deleted, false - * otherwise. - */ - setDeleteStyle(_enable: boolean): void; - - /** - * Register a function as a callback event for when the bubble is resized. - * @param {!Function} callback The function to call on resize. - */ - registerResizeEvent(callback: Function): void; - - /** - * Register a function as a callback event for when the bubble is moved. - * @param {!Function} callback The function to call on move. - */ - registerMoveEvent(callback: Function): void; - - /** - * Move this bubble to the top of the stack. - * @return {boolean} Whether or not the bubble has been moved. - * @package - */ - promote(): boolean; - - /** - * Notification that the anchor has moved. - * Update the arrow and bubble accordingly. - * @param {!Blockly.utils.Coordinate} xy Absolute location. - */ - setAnchorLocation(xy: Blockly.utils.Coordinate): void; - - /** - * Move the bubble group to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - * @package - */ - moveTo(x: number, y: number): void; - - /** - * Triggers a move callback if one exists at the end of a drag. - * @param {boolean} adding True if adding, false if removing. - * @package - */ - setDragging(adding: boolean): void; - - /** - * Get the dimensions of this bubble. - * @return {!Blockly.utils.Size} The height and width of the bubble. - */ - getBubbleSize(): Blockly.utils.Size; - - /** - * Size this bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - */ - setBubbleSize(width: number, height: number): void; - - /** - * Change the colour of a bubble. - * @param {string} hexColour Hex code of colour. - */ - setColour(hexColour: string): void; - - /** - * Dispose of this bubble. - */ - dispose(): void; - - /** - * Move this bubble during a drag, taking into account whether or not there is - * a drag surface. - * @param {Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ - moveDuringDrag(dragSurface: Blockly.BlockDragSurfaceSvg, newLoc: Blockly.utils.Coordinate): void; - - /** - * Return the coordinates of the top-left corner of this bubble's body relative - * to the drawing surface's origin (0,0), in workspace units. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - */ - getRelativeToSurfaceXY(): Blockly.utils.Coordinate; - - /** - * Set whether auto-layout of this bubble is enabled. The first time a bubble - * is shown it positions itself to not cover any blocks. Once a user has - * dragged it to reposition, it renders where the user put it. - * @param {boolean} enable True if auto-layout should be enabled, false - * otherwise. - * @package - */ - setAutoLayout(enable: boolean): void; - } - -} - -declare module Blockly.Bubble { +declare module Bubble { /** * Width of the border around the bubble. @@ -2406,202 +355,30 @@ declare module Blockly.Bubble { * 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. + * @param {!BlockSvg} block The block that the bubble is attached to. + * @param {!Coordinate} iconXY The coordinate of the icon. + * @return {!Bubble} The non editable bubble. * @package */ - function createNonEditableBubble(paragraphElement: SVGTextElement, block: Blockly.BlockSvg, iconXY: Blockly.utils.Coordinate): Blockly.Bubble; + function createNonEditableBubble(paragraphElement: SVGTextElement, block: BlockSvg, iconXY: Coordinate): Bubble; } -declare module Blockly { - class BubbleDragger extends BubbleDragger__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BubbleDragger__Class { - - /** - * Class for a bubble dragger. It moves things on the bubble canvas around the - * workspace when they are being dragged by a mouse or touch. These can be - * block comments, mutators, warnings, or workspace comments. - * @param {!Blockly.IBubble} bubble The item on the bubble canvas to drag. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on. - * @constructor - */ - constructor(bubble: Blockly.IBubble, workspace: Blockly.WorkspaceSvg); - - /** - * Sever all links from this object. - * @package - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Start dragging a bubble. This includes moving it to the drag surface. - * @package - */ - startBubbleDrag(): void; - - /** - * Execute a step of bubble dragging, based on the given event. Update the - * display accordingly. - * @param {!Event} e The most recent move event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - */ - dragBubble(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Finish a bubble drag and put the bubble back on the workspace. - * @param {!Event} e The mouseup/touchend event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - * @package - */ - endBubbleDrag(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - } - + + + +declare module exports { + + /** + * All of the connections on blocks that are currently being dragged. + * @type {!Array} + */ + var draggingConnections: Connection[]; } -declare module Blockly { - - class Comment extends Comment__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Comment__Class extends Blockly.Icon__Class { - - /** - * Class for a comment. - * @param {!Blockly.Block} block The block associated with this comment. - * @extends {Blockly.Icon} - * @constructor - */ - constructor(block: Blockly.Block); - - /** - * Draw the comment icon. - * @param {!Element} group The icon group. - * @protected - */ - drawIcon_(group: Element): void; - - /** - * Show or hide the comment bubble. - * @param {boolean} visible True if the bubble should be visible. - */ - setVisible(visible: boolean): void; - - /** - * Get the dimensions of this comment's bubble. - * @return {Blockly.utils.Size} Object with width and height properties. - */ - getBubbleSize(): Blockly.utils.Size; - - /** - * Size this comment's bubble. - * @param {number} width Width of the bubble. - * @param {number} height Height of the bubble. - */ - setBubbleSize(width: number, height: number): void; - - /** - * Update the comment's view to match the model. - * @package - */ - updateText(): void; - - /** - * Dispose of this comment. - * - * If you want to receive a comment "delete" event (newValue: null), then this - * should not be called directly. Instead call block.setCommentText(null); - */ - dispose(): void; - } - -} - - -declare module Blockly { - - class ComponentManager extends ComponentManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ComponentManager__Class { - - /** - * Manager for all items registered with the workspace. - * @constructor - */ - constructor(); - - /** - * Adds a component. - * @param {!Blockly.ComponentManager.ComponentDatum} componentInfo The data for - * the component to register. - * @param {boolean=} opt_allowOverrides True to prevent an error when overriding - * an already registered item. - */ - addComponent(componentInfo: Blockly.ComponentManager.ComponentDatum, opt_allowOverrides?: boolean): void; - - /** - * Removes a component. - * @param {string} id The ID of the component to remove. - */ - removeComponent(id: string): void; - - /** - * Adds a capability to a existing registered component. - * @param {string} id The ID of the component to add the capability to. - * @param {string|!Blockly.ComponentManager.Capability} capability The - * capability to add. - * @template T - */ - addCapability(id: string, capability: string|Blockly.ComponentManager.Capability): void; - - /** - * Removes a capability from an existing registered component. - * @param {string} id The ID of the component to remove the capability from. - * @param {string|!Blockly.ComponentManager.Capability} capability The - * capability to remove. - * @template T - */ - removeCapability(id: string, capability: string|Blockly.ComponentManager.Capability): void; - - /** - * Returns whether the component with this id has the specified capability. - * @param {string} id The ID of the component to check. - * @param {string|!Blockly.ComponentManager.Capability} capability The - * capability to check for. - * @return {boolean} Whether the component has the capability. - * @template T - */ - hasCapability(id: string, capability: string|Blockly.ComponentManager.Capability): boolean; - - /** - * Gets the component with the given ID. - * @param {string} id The ID of the component to get. - * @return {!Blockly.IComponent|undefined} The component with the given name - * or undefined if not found. - */ - getComponent(id: string): Blockly.IComponent|any /*undefined*/; - - /** - * Gets all the components with the specified capability. - * @param {string|!Blockly.ComponentManager.Capability - * } capability The capability of the component. - * @param {boolean} sorted Whether to return list ordered by weights. - * @return {!Array} The components that match the specified capability. - * @template T - */ - getComponents(capability: string|Blockly.ComponentManager.Capability, sorted: boolean): T[]; - } - -} - -declare module Blockly.ComponentManager { +declare module ComponentManager { class Capability extends Capability__Class { } /** Fake class which should be extended to avoid inheriting static properties */ @@ -2620,280 +397,37 @@ declare module Blockly.ComponentManager { /** * An object storing component information. * @typedef {{ - * component: !Blockly.IComponent, + * component: !IComponent, * capabilities: ( - * !Array> + * !Array> * ), * weight: number * }} */ interface ComponentDatum { - component: Blockly.IComponent; - capabilities: string|Blockly.ComponentManager.Capability[]; + component: IComponent; + capabilities: string|ComponentManager.Capability[]; weight: number } } -declare module Blockly.ComponentManager.Capability { +declare module ComponentManager.Capability { - /** @type {!Blockly.ComponentManager.Capability} */ - var POSITIONABLE: Blockly.ComponentManager.Capability; + /** @type {!ComponentManager.Capability} */ + var POSITIONABLE: ComponentManager.Capability; - /** @type {!Blockly.ComponentManager.Capability} */ - var DRAG_TARGET: Blockly.ComponentManager.Capability; + /** @type {!ComponentManager.Capability} */ + var DRAG_TARGET: ComponentManager.Capability; - /** @type {!Blockly.ComponentManager.Capability} */ - var DELETE_AREA: Blockly.ComponentManager.Capability; + /** @type {!ComponentManager.Capability} */ + var DELETE_AREA: ComponentManager.Capability; - /** @type {!Blockly.ComponentManager.Capability} */ - var AUTOHIDEABLE: Blockly.ComponentManager.Capability; + /** @type {!ComponentManager.Capability} */ + var AUTOHIDEABLE: ComponentManager.Capability; } -declare module Blockly { - - class Connection extends Connection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Connection__Class implements Blockly.IASTNodeLocationWithBlock { - - /** - * Class for a connection between blocks. - * @param {!Blockly.Block} source The block establishing this connection. - * @param {number} type The type of the connection. - * @constructor - * @implements {Blockly.IASTNodeLocationWithBlock} - */ - constructor(source: Blockly.Block, type: number); - - /** - * @type {!Blockly.Block} - * @protected - */ - sourceBlock_: Blockly.Block; - - /** @type {number} */ - type: number; - - /** - * Connection this connection connects to. Null if not connected. - * @type {Blockly.Connection} - */ - targetConnection: Blockly.Connection; - - /** - * Has this connection been disposed of? - * @type {boolean} - * @package - */ - disposed: boolean; - - /** - * Horizontal location of this connection. - * @type {number} - * @package - */ - x: number; - - /** - * Vertical location of this connection. - * @type {number} - * @package - */ - y: number; - - /** - * Connect two connections together. This is the connection on the superior - * block. - * @param {!Blockly.Connection} childConnection Connection on inferior block. - * @protected - */ - connect_(childConnection: Blockly.Connection): void; - - /** - * Dispose of this connection and deal with connected blocks. - * @package - */ - dispose(): void; - - /** - * Get the source block for this connection. - * @return {!Blockly.Block} The source block. - */ - getSourceBlock(): Blockly.Block; - - /** - * Does the connection belong to a superior block (higher in the source stack)? - * @return {boolean} True if connection faces down or right. - */ - isSuperior(): boolean; - - /** - * Is the connection connected? - * @return {boolean} True if connection is connected to another connection. - */ - isConnected(): boolean; - - /** - * Checks whether the current connection can connect with the target - * connection. - * @param {Blockly.Connection} target Connection to check compatibility with. - * @return {number} Blockly.Connection.CAN_CONNECT if the connection is legal, - * an error code otherwise. - * @deprecated July 2020. Will be deleted July 2021. Use the workspace's - * connectionChecker instead. - */ - canConnectWithReason(target: Blockly.Connection): number; - - /** - * Checks whether the current connection and target connection are compatible - * and throws an exception if they are not. - * @param {Blockly.Connection} target The connection to check compatibility - * with. - * @package - * @deprecated July 2020. Will be deleted July 2021. Use the workspace's - * connectionChecker instead. - */ - checkConnection(target: Blockly.Connection): void; - - /** - * Get the workspace's connection type checker object. - * @return {!Blockly.IConnectionChecker} The connection type checker for the - * source block's workspace. - * @package - */ - getConnectionChecker(): Blockly.IConnectionChecker; - - /** - * Check if the two connections can be dragged to connect to each other. - * @param {!Blockly.Connection} candidate A nearby connection to check. - * @return {boolean} True if the connection is allowed, false otherwise. - * @deprecated July 2020. Will be deleted July 2021. Use the workspace's - * connectionChecker instead. - */ - isConnectionAllowed(candidate: Blockly.Connection): boolean; - - /** - * Called when an attempted connection fails. NOP by default (i.e. for headless - * workspaces). - * @param {!Blockly.Connection} _otherConnection Connection that this connection - * failed to connect to. - * @package - */ - onFailedConnect(_otherConnection: Blockly.Connection): void; - - /** - * Connect this connection to another connection. - * @param {!Blockly.Connection} otherConnection Connection to connect to. - */ - connect(otherConnection: Blockly.Connection): void; - - /** - * Disconnect this connection. - */ - disconnect(): void; - - /** - * Disconnect two blocks that are connected by this connection. - * @param {!Blockly.Block} parentBlock The superior block. - * @param {!Blockly.Block} childBlock The inferior block. - * @protected - */ - disconnectInternal_(parentBlock: Blockly.Block, childBlock: Blockly.Block): void; - - /** - * Respawn the shadow block if there was one connected to the this connection. - * @protected - */ - respawnShadow_(): void; - - /** - * Returns the block that this connection connects to. - * @return {?Blockly.Block} The connected block or null if none is connected. - */ - targetBlock(): Blockly.Block; - - /** - * Is this connection compatible with another connection with respect to the - * value type system. E.g. square_root("Hello") is not compatible. - * @param {!Blockly.Connection} otherConnection Connection to compare against. - * @return {boolean} True if the connections share a type. - * @deprecated July 2020. Will be deleted July 2021. Use the workspace's - * connectionChecker instead. - */ - checkType(otherConnection: Blockly.Connection): boolean; - - /** - * Function to be called when this connection's compatible types have changed. - * @protected - */ - onCheckChanged_(): void; - - /** - * Change a connection's compatibility. - * @param {?(string|!Array)} check Compatible value type or list of - * value types. Null if all types are compatible. - * @return {!Blockly.Connection} The connection being modified - * (to allow chaining). - */ - setCheck(check: string|string[]): Blockly.Connection; - - /** - * Get a connection's compatibility. - * @return {?Array} List of compatible value types. - * Null if all types are compatible. - * @public - */ - getCheck(): any[]; - - /** - * Changes the connection's shadow block. - * @param {?Element} shadow DOM representation of a block or null. - */ - setShadowDom(shadow: Element): void; - - /** - * Returns the xml representation of the connection's shadow block. - * @param {boolean=} returnCurrent If true, and the shadow block is currently - * attached to this connection, this serializes the state of that block - * and returns it (so that field values are correct). Otherwise the saved - * shadowDom is just returned. - * @return {?Element} Shadow DOM representation of a block or null. - */ - getShadowDom(returnCurrent?: boolean): Element; - - /** - * Find all nearby compatible connections to this connection. - * Type checking does not apply, since this function is used for bumping. - * - * Headless configurations (the default) do not have neighboring connection, - * and always return an empty list (the default). - * {@link Blockly.RenderedConnection} overrides this behavior with a list - * computed from the rendered positioning. - * @param {number} _maxLimit The maximum radius to another connection. - * @return {!Array} List of connections. - * @package - */ - neighbours(_maxLimit: number): Blockly.Connection[]; - - /** - * Get the parent input of a connection. - * @return {?Blockly.Input} The input that the connection belongs to or null if - * no parent exists. - * @package - */ - getParentInput(): Blockly.Input; - - /** - * This method returns a string describing this Connection in developer terms - * (English only). Intended to on be used in console logs and errors. - * @return {string} The description. - */ - toString(): string; - } - -} - -declare module Blockly.Connection { +declare module Connection { /** * Constants for checking whether two connections are compatible. @@ -2904,588 +438,73 @@ declare module Blockly.Connection { * Returns the connection (starting at the startBlock) which will accept * the given connection. This includes compatible connection types and * connection checks. - * @param {!Blockly.Block} startBlock The block on which to start the search. - * @param {!Blockly.Connection} orphanConnection The connection that is looking + * @param {!Block} startBlock The block on which to start the search. + * @param {!Connection} orphanConnection The connection that is looking * for a home. - * @return {?Blockly.Connection} The suitable connection point on the chain of + * @return {?Connection} The suitable connection point on the chain of * blocks, or null. */ - function getConnectionForOrphanedConnection(startBlock: Blockly.Block, orphanConnection: Blockly.Connection): Blockly.Connection; + function getConnectionForOrphanedConnection(startBlock: Block, orphanConnection: Connection): Connection; } -declare module Blockly { - class ConnectionChecker extends ConnectionChecker__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ConnectionChecker__Class implements Blockly.IConnectionChecker { - - /** - * Class for connection type checking logic. - * @implements {Blockly.IConnectionChecker} - * @constructor - */ - constructor(); - - /** - * Check whether the current connection can connect with the target - * connection. - * @param {Blockly.Connection} a Connection to check compatibility with. - * @param {Blockly.Connection} b Connection to check compatibility with. - * @param {boolean} isDragging True if the connection is being made by dragging - * a block. - * @param {number=} opt_distance The max allowable distance between the - * connections for drag checks. - * @return {boolean} Whether the connection is legal. - * @public - */ - canConnect(a: Blockly.Connection, b: Blockly.Connection, isDragging: boolean, opt_distance?: number): boolean; - - /** - * Checks whether the current connection can connect with the target - * connection, and return an error code if there are problems. - * @param {Blockly.Connection} a Connection to check compatibility with. - * @param {Blockly.Connection} b Connection to check compatibility with. - * @param {boolean} isDragging True if the connection is being made by dragging - * a block. - * @param {number=} opt_distance The max allowable distance between the - * connections for drag checks. - * @return {number} Blockly.Connection.CAN_CONNECT if the connection is legal, - * an error code otherwise. - * @public - */ - canConnectWithReason(a: Blockly.Connection, b: Blockly.Connection, isDragging: boolean, opt_distance?: number): number; - - /** - * Helper method that translates a connection error code into a string. - * @param {number} errorCode The error code. - * @param {Blockly.Connection} a One of the two connections being checked. - * @param {Blockly.Connection} b The second of the two connections being - * checked. - * @return {string} A developer-readable error string. - * @public - */ - getErrorMessage(errorCode: number, a: Blockly.Connection, b: Blockly.Connection): string; - - /** - * Check that connecting the given connections is safe, meaning that it would - * not break any of Blockly's basic assumptions (e.g. no self connections). - * @param {Blockly.Connection} a The first of the connections to check. - * @param {Blockly.Connection} b The second of the connections to check. - * @return {number} An enum with the reason this connection is safe or unsafe. - * @public - */ - doSafetyChecks(a: Blockly.Connection, b: Blockly.Connection): number; - - /** - * Check whether this connection is compatible with another connection with - * respect to the value type system. E.g. square_root("Hello") is not - * compatible. - * @param {!Blockly.Connection} a Connection to compare. - * @param {!Blockly.Connection} b Connection to compare against. - * @return {boolean} True if the connections share a type. - * @public - */ - doTypeChecks(a: Blockly.Connection, b: Blockly.Connection): boolean; - - /** - * Check whether this connection can be made by dragging. - * @param {!Blockly.RenderedConnection} a Connection to compare. - * @param {!Blockly.RenderedConnection} b Connection to compare against. - * @param {number} distance The maximum allowable distance between connections. - * @return {boolean} True if the connection is allowed during a drag. - * @public - */ - doDragChecks(a: Blockly.RenderedConnection, b: Blockly.RenderedConnection, distance: number): boolean; - - /** - * Helper function for drag checking. - * @param {!Blockly.Connection} a The connection to check, which must be a - * statement input or next connection. - * @param {!Blockly.Connection} b A nearby connection to check, which - * must be a previous connection. - * @return {boolean} True if the connection is allowed, false otherwise. - * @protected - */ - canConnectToPrevious_(a: Blockly.Connection, b: Blockly.Connection): boolean; - } - -} - - -declare module Blockly { - - class ConnectionDB extends ConnectionDB__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ConnectionDB__Class { - - /** - * Database of connections. - * Connections are stored in order of their vertical component. This way - * connections in an area may be looked up quickly using a binary search. - * @param {!Blockly.IConnectionChecker} checker The workspace's - * connection type checker, used to decide if connections are valid during a - * drag. - * @constructor - */ - constructor(checker: Blockly.IConnectionChecker); - - /** - * Add a connection to the database. Should not already exist in the database. - * @param {!Blockly.RenderedConnection} connection The connection to be added. - * @param {number} yPos The y position used to decide where to insert the - * connection. - * @package - */ - addConnection(connection: Blockly.RenderedConnection, yPos: number): void; - - /** - * Remove a connection from the database. Must already exist in DB. - * @param {!Blockly.RenderedConnection} connection The connection to be removed. - * @param {number} yPos The y position used to find the index of the connection. - * @throws {Error} If the connection cannot be found in the database. - */ - removeConnection(connection: Blockly.RenderedConnection, yPos: number): void; - - /** - * Find all nearby connections to the given connection. - * Type checking does not apply, since this function is used for bumping. - * @param {!Blockly.RenderedConnection} connection The connection whose - * neighbours should be returned. - * @param {number} maxRadius The maximum radius to another connection. - * @return {!Array} List of connections. - */ - getNeighbours(connection: Blockly.RenderedConnection, maxRadius: number): Blockly.RenderedConnection[]; - - /** - * Find the closest compatible connection to this connection. - * @param {!Blockly.RenderedConnection} conn The connection searching for a compatible - * mate. - * @param {number} maxRadius The maximum radius to another connection. - * @param {!Blockly.utils.Coordinate} dxy Offset between this connection's - * location in the database and the current location (as a result of - * dragging). - * @return {!{connection: Blockly.RenderedConnection, radius: number}} - * Contains two properties: 'connection' which is either another - * connection or null, and 'radius' which is the distance. - */ - searchForClosest(conn: Blockly.RenderedConnection, maxRadius: number, dxy: Blockly.utils.Coordinate): { connection: Blockly.RenderedConnection; radius: number }; - } - -} - -declare module Blockly.ConnectionDB { +declare module ConnectionDB { /** * Initialize a set of connection DBs for a workspace. - * @param {!Blockly.IConnectionChecker} checker The workspace's - * connection checker, used to decide if connections are valid during a drag. - * @return {!Array} Array of databases. + * @param {!IConnectionChecker} checker The workspace's + * connection checker, used to decide if connections are valid during a + * drag. + * @return {!Array} Array of databases. */ - function init(checker: Blockly.IConnectionChecker): Blockly.ConnectionDB[]; + function init(checker: IConnectionChecker): ConnectionDB[]; } -declare module Blockly { + + + + +declare module ContextMenuRegistry { /** - * Enum for the type of a connection or input. - * @enum {number} - */ - enum connectionTypes { INPUT_VALUE, OUTPUT_VALUE, NEXT_STATEMENT, PREVIOUS_STATEMENT } -} - - -declare module Blockly { - - /** - * The multiplier for scroll wheel deltas using the line delta mode. - * @type {number} - */ - var LINE_MODE_MULTIPLIER: number; - - /** - * The multiplier for scroll wheel deltas using the page delta mode. - * @type {number} - */ - var PAGE_MODE_MULTIPLIER: number; - - /** - * Number of pixels the mouse must move before a drag starts. - */ - var DRAG_RADIUS: any /*missing*/; - - /** - * Number of pixels the mouse must move before a drag/scroll starts from the - * flyout. Because the drag-intention is determined when this is reached, it is - * larger than Blockly.DRAG_RADIUS so that the drag-direction is clearer. - */ - var FLYOUT_DRAG_RADIUS: any /*missing*/; - - /** - * Maximum misalignment between connections for them to snap together. - */ - var SNAP_RADIUS: any /*missing*/; - - /** - * Maximum misalignment between connections for them to snap together, - * when a connection is already highlighted. - */ - var CONNECTING_SNAP_RADIUS: any /*missing*/; - - /** - * How much to prefer staying connected to the current connection over moving to - * a new connection. The current previewed connection is considered to be this - * much closer to the matching connection on the block than it actually is. - */ - var CURRENT_CONNECTION_PREFERENCE: any /*missing*/; - - /** - * Delay in ms between trigger and bumping unconnected block out of alignment. - */ - var BUMP_DELAY: any /*missing*/; - - /** - * Maximum randomness in workspace units for bumping a block. - */ - var BUMP_RANDOMNESS: any /*missing*/; - - /** - * Number of characters to truncate a collapsed block to. - */ - var COLLAPSE_CHARS: any /*missing*/; - - /** - * Length in ms for a touch to become a long press. - */ - var LONGPRESS: any /*missing*/; - - /** - * Prevent a sound from playing if another sound preceded it within this many - * milliseconds. - */ - var SOUND_LIMIT: any /*missing*/; - - /** - * When dragging a block out of a stack, split the stack in two (true), or drag - * out the block healing the stack (false). - */ - var DRAG_STACK: any /*missing*/; - - /** - * The richness of block colours, regardless of the hue. - * Must be in the range of 0 (inclusive) to 1 (exclusive). - */ - var HSV_SATURATION: any /*missing*/; - - /** - * The intensity of block colours, regardless of the hue. - * Must be in the range of 0 (inclusive) to 1 (exclusive). - */ - var HSV_VALUE: any /*missing*/; - - /** - * Sprited icons and images. - */ - var SPRITE: any /*missing*/; - - /** - * ENUM for no drag operation. - * @const - */ - var DRAG_NONE: any /*missing*/; - - /** - * ENUM for inside the sticky DRAG_RADIUS. - * @const - */ - var DRAG_STICKY: any /*missing*/; - - /** - * ENUM for inside the non-sticky DRAG_RADIUS, for differentiating between - * clicks and drags. - * @const - */ - var DRAG_BEGIN: any /*missing*/; - - /** - * ENUM for freely draggable (outside the DRAG_RADIUS, if one applies). - * @const - */ - var DRAG_FREE: any /*missing*/; - - /** - * Lookup table for determining the opposite type of a connection. - * @const - */ - var OPPOSITE_TYPE: any /*missing*/; - - /** - * String for use in the "custom" attribute of a category in toolbox XML. - * This string indicates that the category should be dynamically populated with - * variable blocks. - * @const {string} - */ - var VARIABLE_CATEGORY_NAME: any /*missing*/; - - /** - * String for use in the "custom" attribute of a category in toolbox XML. - * This string indicates that the category should be dynamically populated with - * variable blocks. - * @const {string} - */ - var VARIABLE_DYNAMIC_CATEGORY_NAME: any /*missing*/; - - /** - * String for use in the "custom" attribute of a category in toolbox XML. - * This string indicates that the category should be dynamically populated with - * procedure blocks. - * @const {string} - */ - var PROCEDURE_CATEGORY_NAME: any /*missing*/; - - /** - * String for use in the dropdown created in field_variable. - * This string indicates that this option in the dropdown is 'Rename - * variable...' and if selected, should trigger the prompt to rename a variable. - * @const {string} - */ - var RENAME_VARIABLE_ID: any /*missing*/; - - /** - * String for use in the dropdown created in field_variable. - * This string indicates that this option in the dropdown is 'Delete the "%1" - * variable' and if selected, should trigger the prompt to delete a variable. - * @const {string} - */ - var DELETE_VARIABLE_ID: any /*missing*/; -} - -declare module Blockly.constants { - - /** - * Enum for alignment of inputs. - * @enum {number} - */ - enum ALIGN { LEFT, CENTRE, RIGHT } - - /** - * The language-neutral ID given to the collapsed input. - * @const {string} - */ - var COLLAPSED_INPUT_NAME: any /*missing*/; - - /** - * The language-neutral ID given to the collapsed field. - * @const {string} - */ - var COLLAPSED_FIELD_NAME: any /*missing*/; -} - - -declare module Blockly.ContextMenu { - - /** - * Which block is the context menu attached to? - * @type {Blockly.Block} - */ - var currentBlock: Blockly.Block; - - /** - * Construct the menu based on the list of options and show the menu. - * @param {!Event} e Mouse event. - * @param {!Array} options Array of menu options. - * @param {boolean} rtl True if RTL, false if LTR. - */ - function show(e: Event, options: Object[], rtl: boolean): void; - - /** - * Hide the context menu. - */ - function hide(): void; - - /** - * Dispose of the menu. - */ - function dispose(): void; - - /** - * Create a callback function that creates and configures a block, - * then places the new block next to the original. - * @param {!Blockly.Block} block Original block. - * @param {!Element} xml XML representation of new block. - * @return {!Function} Function that creates a block. - */ - function callbackFactory(block: Blockly.Block, xml: Element): Function; - - /** - * Make a context menu option for deleting the current workspace comment. - * @param {!Blockly.WorkspaceCommentSvg} comment The workspace comment where the - * right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ - function commentDeleteOption(comment: Blockly.WorkspaceCommentSvg): Object; - - /** - * Make a context menu option for duplicating the current workspace comment. - * @param {!Blockly.WorkspaceCommentSvg} comment The workspace comment where the - * right-click originated. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - */ - function commentDuplicateOption(comment: Blockly.WorkspaceCommentSvg): Object; - - /** - * Make a context menu option for adding a comment on the workspace. - * @param {!Blockly.WorkspaceSvg} ws The workspace where the right-click - * originated. - * @param {!Event} e The right-click mouse event. - * @return {!Object} A menu option, containing text, enabled, and a callback. - * @package - * @suppress {strictModuleDepCheck,checkTypes} Suppress checks while workspace - * comments are not bundled in. - */ - function workspaceCommentOption(ws: Blockly.WorkspaceSvg, e: Event): Object; -} - - -declare module Blockly.ContextMenuItems { - - /** Option to undo previous action. */ - function registerUndo(): void; - - /** Option to redo previous action. */ - function registerRedo(): void; - - /** Option to clean up blocks. */ - function registerCleanup(): void; - - /** Option to collapse all blocks. */ - function registerCollapse(): void; - - /** Option to expand all blocks. */ - function registerExpand(): void; - - /** Option to delete all blocks. */ - function registerDeleteAll(): void; - - /** Option to duplicate a block. */ - function registerDuplicate(): void; - - /** Option to add or remove block-level comment. */ - function registerComment(): void; - - /** Option to inline variables. */ - function registerInline(): void; - - /** Option to collapse or expand a block. */ - function registerCollapseExpandBlock(): void; - - /** Option to disable or enable a block. */ - function registerDisable(): void; - - /** Option to delete a block. */ - function registerDelete(): void; - - /** Option to open help for a block. */ - function registerHelp(): void; - - /** - * Registers all default context menu items. This should be called once per instance of - * ContextMenuRegistry. - * @package - */ - function registerDefaultOptions(): void; -} - - -declare module Blockly { - - class ContextMenuRegistry extends ContextMenuRegistry__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ContextMenuRegistry__Class { - - /** - * Class for the registry of context menu items. This is intended to be a - * singleton. You should not create a new instance, and only access this class - * from Blockly.ContextMenuRegistry.registry. - * @constructor - */ - constructor(); - - /** - * Registers a RegistryItem. - * @param {!Blockly.ContextMenuRegistry.RegistryItem} item Context menu item to register. - * @throws {Error} if an item with the given ID already exists. - */ - register(item: Blockly.ContextMenuRegistry.RegistryItem): void; - - /** - * Unregisters a RegistryItem with the given ID. - * @param {string} id The ID of the RegistryItem to remove. - * @throws {Error} if an item with the given ID does not exist. - */ - unregister(id: string): void; - - /** - * @param {string} id The ID of the RegistryItem to get. - * @return {?Blockly.ContextMenuRegistry.RegistryItem} RegistryItem or null if not found - */ - getItem(id: string): Blockly.ContextMenuRegistry.RegistryItem; - - /** - * Gets the valid context menu options for the given scope type (e.g. block or workspace) and scope. - * Blocks are only shown if the preconditionFn shows they should not be hidden. - * @param {!Blockly.ContextMenuRegistry.ScopeType} scopeType Type of scope where menu should be - * shown (e.g. on a block or on a workspace) - * @param {!Blockly.ContextMenuRegistry.Scope} scope Current scope of context menu - * (i.e., the exact workspace or block being clicked on) - * @return {!Array} the list of ContextMenuOptions - */ - getContextMenuOptions(scopeType: Blockly.ContextMenuRegistry.ScopeType, scope: Blockly.ContextMenuRegistry.Scope): Blockly.ContextMenuRegistry.ContextMenuOption[]; - } - -} - -declare module Blockly.ContextMenuRegistry { - - /** - * Where this menu item should be rendered. If the menu item should be rendered in multiple - * scopes, e.g. on both a block and a workspace, it should be registered for each scope. + * Where this menu item should be rendered. If the menu item should be rendered + * in multiple scopes, e.g. on both a block and a workspace, it should be + * registered for each scope. * @enum {string} */ enum ScopeType { BLOCK, WORKSPACE } /** - * The actual workspace/block where the menu is being rendered. This is passed to callback and - * displayText functions that depend on this information. + * The actual workspace/block where the menu is being rendered. This is passed + * to callback and displayText functions that depend on this information. * @typedef {{ - * block: (Blockly.BlockSvg|undefined), - * workspace: (Blockly.WorkspaceSvg|undefined) + * block: (BlockSvg|undefined), + * workspace: (WorkspaceSvg|undefined) * }} */ interface Scope { - block: Blockly.BlockSvg|any /*undefined*/; - workspace: Blockly.WorkspaceSvg|any /*undefined*/ + block: BlockSvg|any /*undefined*/; + workspace: WorkspaceSvg|any /*undefined*/ } /** * A menu item as entered in the registry. * @typedef {{ - * callback: function(!Blockly.ContextMenuRegistry.Scope), - * scopeType: !Blockly.ContextMenuRegistry.ScopeType, - * displayText: ((function(!Blockly.ContextMenuRegistry.Scope):string)|string), - * preconditionFn: function(!Blockly.ContextMenuRegistry.Scope):string, + * callback: function(!ContextMenuRegistry.Scope), + * scopeType: !ContextMenuRegistry.ScopeType, + * displayText: ((function(!ContextMenuRegistry.Scope):string)|string), + * preconditionFn: function(!ContextMenuRegistry.Scope):string, * weight: number, * id: string * }} - */ + */ interface RegistryItem { - callback: { (_0: Blockly.ContextMenuRegistry.Scope): any /*missing*/ }; - scopeType: Blockly.ContextMenuRegistry.ScopeType; - displayText: { (_0: Blockly.ContextMenuRegistry.Scope): string }|string; - preconditionFn: { (_0: Blockly.ContextMenuRegistry.Scope): string }; + callback: { (_0: ContextMenuRegistry.Scope): any /*missing*/ }; + scopeType: ContextMenuRegistry.ScopeType; + displayText: { (_0: ContextMenuRegistry.Scope): string }|string; + preconditionFn: { (_0: ContextMenuRegistry.Scope): string }; weight: number; id: string } @@ -3495,190 +514,33 @@ declare module Blockly.ContextMenuRegistry { * @typedef {{ * text: string, * enabled: boolean, - * callback: function(!Blockly.ContextMenuRegistry.Scope), - * scope: !Blockly.ContextMenuRegistry.Scope, + * callback: function(!ContextMenuRegistry.Scope), + * scope: !ContextMenuRegistry.Scope, * weight: number * }} */ interface ContextMenuOption { text: string; enabled: boolean; - callback: { (_0: Blockly.ContextMenuRegistry.Scope): any /*missing*/ }; - scope: Blockly.ContextMenuRegistry.Scope; + callback: { (_0: ContextMenuRegistry.Scope): any /*missing*/ }; + scope: ContextMenuRegistry.Scope; weight: number } /** * Singleton instance of this class. All interactions with this class should be * done on this object. - * @type {?Blockly.ContextMenuRegistry} + * @type {?ContextMenuRegistry} */ - var registry: Blockly.ContextMenuRegistry; + var registry: ContextMenuRegistry; } -declare module Blockly.Css { - - /** - * Add some CSS to the blob that will be injected later. Allows optional - * components such as fields and the toolbox to store separate CSS. - * The provided array of CSS will be destroyed by this function. - * @param {!Array} cssArray Array of CSS strings. - */ - function register(cssArray: string[]): void; - - /** - * Inject the CSS into the DOM. This is preferable over using a regular CSS - * file since: - * a) It loads synchronously and doesn't force a redraw later. - * b) It speeds up loading by not blocking on a separate HTTP transfer. - * c) The CSS content may be made dynamic depending on init options. - * @param {boolean} hasCss If false, don't inject CSS - * (providing CSS becomes the document's responsibility). - * @param {string} pathToMedia Path from page to the Blockly media directory. - */ - function inject(hasCss: boolean, pathToMedia: string): void; - - /** - * Array making up the CSS content for Blockly. - */ - var CONTENT: any /*missing*/; -} -declare module Blockly { - - class DeleteArea extends DeleteArea__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class DeleteArea__Class extends Blockly.DragTarget__Class implements Blockly.IDeleteArea { - - /** - * Abstract class for a component that can delete a block or bubble that is - * dropped on top of it. - * @extends {Blockly.DragTarget} - * @implements {Blockly.IDeleteArea} - * @constructor - */ - constructor(); - - /** - * Whether the last block or bubble dragged over this delete area would be - * deleted if dropped on this component. - * This property is not updated after the block or bubble is deleted. - * @type {boolean} - * @protected - */ - wouldDelete_: boolean; - - /** - * Returns whether the provided block or bubble would be deleted if dropped on - * this area. - * This method should check if the element is deletable and is always called - * before onDragEnter/onDragOver/onDragExit. - * @param {!Blockly.IDraggable} element The block or bubble currently being - * dragged. - * @param {boolean} couldConnect Whether the element could could connect to - * another. - * @return {boolean} Whether the element provided would be deleted if dropped on - * this area. - */ - wouldDelete(element: Blockly.IDraggable, couldConnect: boolean): boolean; - - /** - * Updates the internal wouldDelete_ state. - * @param {boolean} wouldDelete The new value for the wouldDelete state. - * @protected - */ - updateWouldDelete_(wouldDelete: boolean): void; - } - -} -declare module Blockly { - - class DragTarget extends DragTarget__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class DragTarget__Class implements Blockly.IDragTarget { - - /** - * Abstract class for a component with custom behaviour when a block or bubble - * is dragged over or dropped on top of it. - * @implements {Blockly.IDragTarget} - * @constructor - */ - constructor(); - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to the Blockly injection div. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Handles when a cursor with a block or bubble enters this drag target. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being - * dragged. - */ - onDragEnter(_dragElement: Blockly.IDraggable): void; - - /** - * Handles when a cursor with a block or bubble is dragged over this drag - * target. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being - * dragged. - */ - onDragOver(_dragElement: Blockly.IDraggable): void; - - /** - * Handles when a cursor with a block or bubble exits this drag target. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being - * dragged. - */ - onDragExit(_dragElement: Blockly.IDraggable): void; - - /** - * Handles when a block or bubble is dropped on this component. - * Should not handle delete here. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being - * dragged. - */ - onDrop(_dragElement: Blockly.IDraggable): void; - - /** - * Returns whether the provided block or bubble should not be moved after being - * dropped on this component. If true, the element will return to where it was - * when the drag started. - * @param {!Blockly.IDraggable} _dragElement The block or bubble currently being - * dragged. - * @return {boolean} Whether the block or bubble provided should be returned to - * drag start. - */ - shouldPreventMove(_dragElement: Blockly.IDraggable): boolean; - } - -} - - -declare module Blockly { - - class DropDownDiv extends DropDownDiv__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class DropDownDiv__Class { - - /** - * Class for drop-down div. - * @constructor - * @package - */ - constructor(); - } - -} - -declare module Blockly.DropDownDiv { +declare module DropDownDiv { /** * Arrow size in px. Should match the value in CSS @@ -3772,7 +634,7 @@ declare module Blockly.DropDownDiv { /** * Set an element to maintain bounds within. Drop-downs will appear * within the box of this element if possible. - * @param {Element} boundsElement Element to bind drop-down to. + * @param {?Element} boundsElement Element to bind drop-down to. */ function setBoundsElement(boundsElement: Element): void; @@ -3799,29 +661,29 @@ declare module Blockly.DropDownDiv { * by a particular block. The primary position will be below the block, * and the secondary position above the block. Drop-down will be * constrained to the block's workspace. - * @param {!Blockly.Field} field The field showing the drop-down. - * @param {!Blockly.BlockSvg} block Block to position the drop-down around. + * @param {!Field} field The field showing the drop-down. + * @param {!BlockSvg} block Block to position the drop-down around. * @param {Function=} opt_onHide Optional callback for when the drop-down is * hidden. * @param {number=} opt_secondaryYOffset Optional Y offset for above-block * positioning. * @return {boolean} True if the menu rendered below block; false if above. */ - function showPositionedByBlock(field: Blockly.Field, block: Blockly.BlockSvg, opt_onHide?: Function, opt_secondaryYOffset?: number): boolean; + function showPositionedByBlock(field: Field, block: BlockSvg, opt_onHide?: Function, opt_secondaryYOffset?: number): boolean; /** * Shortcut to show and place the drop-down with positioning determined * by a particular field. The primary position will be below the field, * and the secondary position above the field. Drop-down will be * constrained to the block's workspace. - * @param {!Blockly.Field} field The field to position the dropdown against. + * @param {!Field} field The field to position the dropdown against. * @param {Function=} opt_onHide Optional callback for when the drop-down is * hidden. * @param {number=} opt_secondaryYOffset Optional Y offset for above-block * positioning. * @return {boolean} True if the menu rendered below block; false if above. */ - function showPositionedByField(field: Blockly.Field, opt_onHide?: Function, opt_secondaryYOffset?: number): boolean; + function showPositionedByField(field: Field, opt_onHide?: Function, opt_secondaryYOffset?: number): boolean; /** * Show and place the drop-down. @@ -3831,7 +693,7 @@ declare module Blockly.DropDownDiv { * will point there, and the container will be positioned below it. * If we can't maintain the container bounds at the primary point, fall-back to * the secondary point and position above. - * @param {Object} owner The object showing the drop-down + * @param {?Object} owner The object showing the drop-down * @param {boolean} rtl Right-to-left (true) or left-to-right (false). * @param {number} primaryX Desired origin point x, in absolute px. * @param {number} primaryY Desired origin point y, in absolute px. @@ -3869,7 +731,7 @@ declare module Blockly.DropDownDiv { /** * Hide the menu only if it is owned by the provided object. - * @param {Object} owner Object which must be owning the drop-down to hide. + * @param {?Object} owner Object which must be owning the drop-down to hide. * @param {boolean=} opt_withoutAnimation True if we should hide the dropdown * without animating. * @return {boolean} True if hidden. @@ -3894,668 +756,33 @@ declare module Blockly.DropDownDiv { function repositionForWindowResize(): void; } - -declare module Blockly.Extensions { +declare module internal { /** - * Registers a new extension function. Extensions are functions that help - * initialize blocks, usually adding dynamic behavior such as onchange - * handlers and mutators. These are applied using Block.applyExtension(), or - * the JSON "extensions" array attribute. - * @param {string} name The name of this extension. - * @param {Function} initFn The function to initialize an extended block. - * @throws {Error} if the extension name is empty, the extension is already - * registered, or extensionFn is not a function. + * Get sizing info about the bounding element. + * @return {!DropDownDiv.BoundsInfo} An object containing size + * information about the bounding element (bounding box and width/height). */ - function register(name: string, initFn: Function): void; + function getBoundsInfo(): DropDownDiv.BoundsInfo; /** - * Registers a new extension function that adds all key/value of mixinObj. - * @param {string} name The name of this extension. - * @param {!Object} mixinObj The values to mix in. - * @throws {Error} if the extension name is empty or the extension is already - * registered. + * Helper to position the drop-down and the arrow, maintaining bounds. + * See explanation of origin points in DropDownDiv.show. + * @param {number} primaryX Desired origin point x, in absolute px. + * @param {number} primaryY Desired origin point y, in absolute px. + * @param {number} secondaryX Secondary/alternative origin point x, + * in absolute px. + * @param {number} secondaryY Secondary/alternative origin point y, + * in absolute px. + * @return {!DropDownDiv.PositionMetrics} Various final metrics, + * including rendered positions for drop-down and arrow. */ - function registerMixin(name: string, mixinObj: Object): void; - - /** - * Registers a new extension function that adds a mutator to the block. - * At register time this performs some basic sanity checks on the mutator. - * The wrapper may also add a mutator dialog to the block, if both compose and - * decompose are defined on the mixin. - * @param {string} name The name of this mutator extension. - * @param {!Object} mixinObj The values to mix in. - * @param {(function())=} opt_helperFn An optional function to apply after - * mixing in the object. - * @param {!Array=} opt_blockList A list of blocks to appear in the - * flyout of the mutator dialog. - * @throws {Error} if the mutation is invalid or can't be applied to the block. - */ - function registerMutator(name: string, mixinObj: Object, opt_helperFn?: { (): any /*missing*/ }, opt_blockList?: string[]): void; - - /** - * Unregisters the extension registered with the given name. - * @param {string} name The name of the extension to unregister. - */ - function unregister(name: string): void; - - /** - * Applies an extension method to a block. This should only be called during - * block construction. - * @param {string} name The name of the extension. - * @param {!Blockly.Block} block The block to apply the named extension to. - * @param {boolean} isMutator True if this extension defines a mutator. - * @throws {Error} if the extension is not found. - */ - function apply(name: string, block: Blockly.Block, isMutator: boolean): void; - - /** - * Builds an extension function that will map a dropdown value to a tooltip - * string. - * - * This method includes multiple checks to ensure tooltips, dropdown options, - * and message references are aligned. This aims to catch errors as early as - * possible, without requiring developers to manually test tooltips under each - * option. After the page is loaded, each tooltip text string will be checked - * for matching message keys in the internationalized string table. Deferring - * this until the page is loaded decouples loading dependencies. Later, upon - * loading the first block of any given type, the extension will validate every - * dropdown option has a matching tooltip in the lookupTable. Errors are - * reported as warnings in the console, and are never fatal. - * @param {string} dropdownName The name of the field whose value is the key - * to the lookup table. - * @param {!Object} lookupTable The table of field values to - * tooltip text. - * @return {!Function} The extension function. - */ - function buildTooltipForDropdown(dropdownName: string, lookupTable: { [key: string]: string }): Function; - - /** - * Builds an extension function that will install a dynamic tooltip. The - * tooltip message should include the string '%1' and that string will be - * replaced with the text of the named field. - * @param {string} msgTemplate The template form to of the message text, with - * %1 placeholder. - * @param {string} fieldName The field with the replacement text. - * @return {!Function} The extension function. - */ - function buildTooltipWithFieldText(msgTemplate: string, fieldName: string): Function; + function getPositionMetrics(primaryX: number, primaryY: number, secondaryX: number, secondaryY: number): DropDownDiv.PositionMetrics; } -declare module Blockly { - class Field extends Field__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Field__Class implements Blockly.IASTNodeLocationSvg, Blockly.IASTNodeLocationWithBlock, Blockly.IKeyboardAccessible, Blockly.IRegistrable { - - /** - * Abstract class for an editable field. - * @param {*} value The initial value of the field. - * @param {?Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a value & returns a validated - * value, or null to abort the change. - * @param {Object=} opt_config A map of options used to configure the field. See - * the individual field's documentation for a list of properties this - * parameter supports. - * @constructor - * @implements {Blockly.IASTNodeLocationSvg} - * @implements {Blockly.IASTNodeLocationWithBlock} - * @implements {Blockly.IKeyboardAccessible} - * @implements {Blockly.IRegistrable} - */ - constructor(value: any, opt_validator?: Function, opt_config?: Object); - - /** - * A generic value possessed by the field. - * Should generally be non-null, only null when the field is created. - * @type {*} - * @protected - */ - value_: any; - - /** - * Validation function called when user edits an editable field. - * @type {Function} - * @protected - */ - validator_: Function; - - /** - * The size of the area rendered by the field. - * @type {!Blockly.utils.Size} - * @protected - */ - size_: Blockly.utils.Size; - - /** - * The rendered field's SVG group element. - * @type {SVGGElement} - * @protected - */ - fieldGroup_: SVGGElement; - - /** - * The rendered field's SVG border element. - * @type {SVGRectElement} - * @protected - */ - borderRect_: SVGRectElement; - - /** - * The rendered field's SVG text element. - * @type {SVGTextElement} - * @protected - */ - textElement_: SVGTextElement; - - /** - * The rendered field's text content element. - * @type {Text} - * @protected - */ - textContent_: Text; - - /** - * Constants associated with the source block's renderer. - * @type {Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Name of field. Unique within each block. - * Static labels are usually unnamed. - * @type {string|undefined} - */ - name: string|any /*undefined*/; - - /** - * Has this field been disposed of? - * @type {boolean} - * @package - */ - disposed: boolean; - - /** - * Maximum characters of text to display before adding an ellipsis. - * @type {number} - */ - maxDisplayLength: number; - - /** - * Block this field is attached to. Starts as null, then set in init. - * @type {Blockly.Block} - * @protected - */ - sourceBlock_: Blockly.Block; - - /** - * Does this block need to be re-rendered? - * @type {boolean} - * @protected - */ - isDirty_: boolean; - - /** - * Is the field visible, or hidden due to the block being collapsed? - * @type {boolean} - * @protected - */ - visible_: boolean; - - /** - * The element the click handler is bound to. - * @type {Element} - * @protected - */ - clickTarget_: Element; - - /** - * A developer hook to override the returned text of this field. - * Override if the text representation of the value of this field - * is not just a string cast of its value. - * Return null to resort to a string cast. - * @return {?string} Current text. Return null to resort to a string cast. - * @protected - */ - getText_(): string; - - /** - * An optional method that can be defined to show an editor when the field is - * clicked. Blockly will automatically set the field as clickable if this - * method is defined. - * @param {Event=} opt_e Optional mouse event that triggered the field to open, - * or undefined if triggered programmatically. - * @return {void} - * @protected - */ - showEditor_(opt_e?: Event): void; - - /** - * Editable fields usually show some sort of UI indicating they are editable. - * They will also be saved by the XML renderer. - * @type {boolean} - */ - EDITABLE: boolean; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. This is not the - * case by default so that SERIALIZABLE is backwards compatible. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Process the configuration map passed to the field. - * @param {!Object} config A map of options used to configure the field. See - * the individual field's documentation for a list of properties this - * parameter supports. - * @protected - */ - configure_(config: Object): void; - - /** - * Attach this field to a block. - * @param {!Blockly.Block} block The block containing this field. - */ - setSourceBlock(block: Blockly.Block): void; - - /** - * Get the renderer constant provider. - * @return {?Blockly.blockRendering.ConstantProvider} The renderer constant - * provider. - */ - getConstants(): Blockly.blockRendering.ConstantProvider; - - /** - * Get the block this field is attached to. - * @return {Blockly.Block} The block containing this field. - */ - getSourceBlock(): Blockly.Block; - - /** - * Initialize everything to render this field. Override - * methods initModel and initView rather than this method. - * @package - */ - init(): void; - - /** - * Create the block UI for this field. - * @package - */ - initView(): void; - - /** - * Initializes the model of the field after it has been installed on a block. - * No-op by default. - * @package - */ - initModel(): void; - - /** - * Create a field border rect element. Not to be overridden by subclasses. - * Instead modify the result of the function inside initView, or create a - * separate function to call. - * @protected - */ - createBorderRect_(): void; - - /** - * Create a field text element. Not to be overridden by subclasses. Instead - * modify the result of the function inside initView, or create a separate - * function to call. - * @protected - */ - createTextElement_(): void; - - /** - * Bind events to the field. Can be overridden by subclasses if they need to do - * custom input handling. - * @protected - */ - bindEvents_(): void; - - /** - * Sets the field's value based on the given XML element. Should only be - * called by Blockly.Xml. - * @param {!Element} fieldElement The element containing info about the - * field's state. - * @package - */ - fromXml(fieldElement: Element): void; - - /** - * Serializes this field's value to XML. Should only be called by Blockly.Xml. - * @param {!Element} fieldElement The element to populate with info about the - * field's state. - * @return {!Element} The element containing info about the field's state. - * @package - */ - toXml(fieldElement: Element): Element; - - /** - * Dispose of all DOM objects and events belonging to this editable field. - * @package - */ - dispose(): void; - - /** - * Add or remove the UI indicating if this field is editable or not. - */ - updateEditable(): void; - - /** - * Check whether this field defines the showEditor_ function. - * @return {boolean} Whether this field is clickable. - */ - isClickable(): boolean; - - /** - * Check whether this field is currently editable. Some fields are never - * EDITABLE (e.g. text labels). Other fields may be EDITABLE but may exist on - * non-editable blocks. - * @return {boolean} Whether this field is editable and on an editable block - */ - isCurrentlyEditable(): boolean; - - /** - * Check whether this field should be serialized by the XML renderer. - * Handles the logic for backwards compatibility and incongruous states. - * @return {boolean} Whether this field should be serialized or not. - */ - isSerializable(): boolean; - - /** - * Gets whether this editable field is visible or not. - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Sets whether this editable field is visible or not. Should only be called - * by input.setVisible. - * @param {boolean} visible True if visible. - * @package - */ - setVisible(visible: boolean): void; - - /** - * Sets a new validation function for editable fields, or clears a previously - * set validator. - * - * The validator function takes in the new field value, and returns - * validated value. The validated value could be the input value, a modified - * version of the input value, or null to abort the change. - * - * If the function does not return anything (or returns undefined) the new - * value is accepted as valid. This is to allow for fields using the - * validated function as a field-level change event notification. - * - * @param {Function} handler The validator function - * or null to clear a previous validator. - */ - setValidator(handler: Function): void; - - /** - * Gets the validation function for editable fields, or null if not set. - * @return {?Function} Validation function, or null. - */ - getValidator(): Function; - - /** - * Gets the group element for this editable field. - * Used for measuring the size and for positioning. - * @return {!SVGGElement} The group element. - */ - getSvgRoot(): SVGGElement; - - /** - * Updates the field to match the colour/style of the block. Should only be - * called by BlockSvg.applyColour(). - * @package - */ - applyColour(): void; - - /** - * Used by getSize() to move/resize any DOM elements, and get the new size. - * - * All rendering that has an effect on the size/shape of the block should be - * done here, and should be triggered by getSize(). - * @protected - */ - render_(): void; - - /** - * Show an editor when the field is clicked only if the field is clickable. - * @param {Event=} opt_e Optional mouse event that triggered the field to open, - * or undefined if triggered programmatically. - * @package - */ - showEditor(opt_e?: Event): void; - - /** - * Updates the size of the field based on the text. - * @param {number=} opt_margin margin to use when positioning the text element. - * @protected - */ - updateSize_(opt_margin?: number): void; - - /** - * Position a field's text element after a size change. This handles both LTR - * and RTL positioning. - * @param {number} xOffset x offset to use when positioning the text element. - * @param {number} contentWidth The content width. - * @protected - */ - positionTextElement_(xOffset: number, contentWidth: number): void; - - /** - * Position a field's border rect after a size change. - * @protected - */ - positionBorderRect_(): void; - - /** - * Returns the height and width of the field. - * - * This should *in general* be the only place render_ gets called from. - * @return {!Blockly.utils.Size} Height and width. - */ - getSize(): Blockly.utils.Size; - - /** - * Returns the bounding box of the rendered field, accounting for workspace - * scaling. - * @return {!Blockly.utils.Rect} An object with top, bottom, left, and right in - * pixels relative to the top left corner of the page (window coordinates). - * @package - */ - getScaledBBox(): Blockly.utils.Rect; - - /** - * Get the text from this field to display on the block. May differ from - * ``getText`` due to ellipsis, and other formatting. - * @return {string} Text to display. - * @protected - */ - getDisplayText_(): string; - - /** - * Get the text from this field. - * @return {string} Current text. - */ - getText(): string; - - /** - * Force a rerender of the block that this field is installed on, which will - * rerender this field and adjust for any sizing changes. - * Other fields on the same block will not rerender, because their sizes have - * already been recorded. - * @package - */ - markDirty(): void; - - /** - * Force a rerender of the block that this field is installed on, which will - * rerender this field and adjust for any sizing changes. - * Other fields on the same block will not rerender, because their sizes have - * already been recorded. - * @package - */ - forceRerender(): void; - - /** - * Used to change the value of the field. Handles validation and events. - * Subclasses should override doClassValidation_ and doValueUpdate_ rather - * than this method. - * @param {*} newValue New value. - */ - setValue(newValue: any): void; - - /** - * Get the current value of the field. - * @return {*} Current value. - */ - getValue(): any; - - /** - * Used to validate a value. Returns input by default. Can be overridden by - * subclasses, see FieldDropdown. - * @param {*=} opt_newValue The value to be validated. - * @return {*} The validated value, same as input by default. - * @protected - */ - doClassValidation_(opt_newValue?: any): any; - - /** - * Used to update the value of a field. Can be overridden by subclasses to do - * custom storage of values/updating of external things. - * @param {*} newValue The value to be saved. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Used to notify the field an invalid value was input. Can be overridden by - * subclasses, see FieldTextInput. - * No-op by default. - * @param {*} _invalidValue The input value that was determined to be invalid. - * @protected - */ - doValueInvalid_(_invalidValue: any): void; - - /** - * Handle a mouse down event on a field. - * @param {!Event} e Mouse down event. - * @protected - */ - onMouseDown_(e: Event): void; - - /** - * Sets the tooltip for this field. - * @param {?Blockly.Tooltip.TipInfo} newTip The - * text for the tooltip, a function that returns the text for the tooltip, a - * parent object whose tooltip will be used, or null to display the tooltip - * of the parent block. To not display a tooltip pass the empty string. - */ - setTooltip(newTip: Blockly.Tooltip.TipInfo): void; - - /** - * Returns the tooltip text for this field. - * @return {string} The tooltip text for this field. - */ - getTooltip(): string; - - /** - * The element to bind the click handler to. If not set explicitly, defaults - * to the SVG root of the field. When this element is - * clicked on an editable field, the editor will open. - * @return {!Element} Element to bind click handler to. - * @protected - */ - getClickTarget_(): Element; - - /** - * Return the absolute coordinates of the top-left corner of this field. - * The origin (0,0) is the top-left corner of the page body. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - * @protected - */ - getAbsoluteXY_(): Blockly.utils.Coordinate; - - /** - * Whether this field references any Blockly variables. If true it may need to - * be handled differently during serialization and deserialization. Subclasses - * may override this. - * @return {boolean} True if this field has any variable references. - * @package - */ - referencesVariables(): boolean; - - /** - * Search through the list of inputs and their fields in order to find the - * parent input of a field. - * @return {Blockly.Input} The input that the field belongs to. - * @package - */ - getParentInput(): Blockly.Input; - - /** - * Returns whether or not we should flip the field in RTL. - * @return {boolean} True if we should flip in RTL. - */ - getFlipRtl(): boolean; - - /** - * Returns whether or not the field is tab navigable. - * @return {boolean} True if the field is tab navigable. - */ - isTabNavigable(): boolean; - - /** - * Handles the given keyboard shortcut. - * @param {!Blockly.ShortcutRegistry.KeyboardShortcut} _shortcut The shortcut to be handled. - * @return {boolean} True if the shortcut has been handled, false otherwise. - * @public - */ - onShortcut(_shortcut: Blockly.ShortcutRegistry.KeyboardShortcut): boolean; - - /** - * Add the cursor SVG to this fields SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * field group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this fields SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * field group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Redraw any attached marker or cursor svgs if needed. - * @protected - */ - updateMarkers_(): void; - } - -} - -declare module Blockly.Field { +declare module Field { /** * Non-breaking space. @@ -4565,87 +792,16 @@ declare module Blockly.Field { } -declare module Blockly { - - class FieldAngle extends FieldAngle__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldAngle__Class extends Blockly.FieldTextInput__Class { - - /** - * Class for an editable angle field. - * @param {string|number=} opt_value The initial value of the field. Should cast - * to a number. Defaults to 0. - * @param {Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a number & returns a - * validated number, 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/angle#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.FieldTextInput} - * @constructor - */ - constructor(opt_value?: string|number, opt_validator?: Function, opt_config?: Object); - - /** - * The angle picker's gauge path depending on the value. - * @type {?SVGElement} - */ - gauge_: SVGElement; - - /** - * The angle picker's line drawn representing the value's angle. - * @type {?SVGElement} - */ - line_: SVGElement; - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Create the block UI for this field. - * @package - */ - initView(): void; - - /** - * Create and show the angle field's editor. - * @param {Event=} opt_e Optional mouse event that triggered the field to open, - * or undefined if triggered programmatically. - * @protected - */ - showEditor_(opt_e?: Event): void; - - /** - * Set the angle to match the mouse's position. - * @param {!Event} e Mouse move event. - * @protected - */ - onMouseMove_(e: Event): void; - } - -} - -declare module Blockly.FieldAngle { +declare module FieldAngle { /** * Construct a FieldAngle from a JSON arg object. * @param {!Object} options A JSON object with options (angle). - * @return {!Blockly.FieldAngle} The new field instance. + * @return {!FieldAngle} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldAngle; + function fromJson(options: Object): FieldAngle; /** * The default amount to round angles to when using a mouse or keyboard nav @@ -4691,114 +847,16 @@ declare module Blockly.FieldAngle { } -declare module Blockly { - - class FieldCheckbox extends FieldCheckbox__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldCheckbox__Class extends Blockly.Field__Class { - - /** - * Class for a checkbox field. - * @param {string|boolean=} opt_value The initial value of the field. Should - * either be 'TRUE', 'FALSE' or a boolean. Defaults to 'FALSE'. - * @param {Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a value ('TRUE' or 'FALSE') & - * returns a validated value ('TRUE' or 'FALSE'), 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/checkbox#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - */ - constructor(opt_value?: string|boolean, opt_validator?: Function, opt_config?: Object); - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Mouse cursor style when over the hotspot that initiates editability. - */ - CURSOR: any /*missing*/; - - /** - * Create the block UI for this checkbox. - * @package - */ - initView(): void; - - /** - * Set the character used for the check mark. - * @param {?string} character The character to use for the check mark, or - * null to use the default. - */ - setCheckCharacter(character: string): void; - - /** - * Toggle the state of the checkbox on click. - * @protected - */ - showEditor_(): void; - - /** - * Ensure that the input value is valid ('TRUE' or 'FALSE'). - * @param {*=} opt_newValue The input value. - * @return {?string} A valid value ('TRUE' or 'FALSE), or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Update the value of the field, and update the checkElement. - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is a either 'TRUE' or 'FALSE'. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Get the value of this field, either 'TRUE' or 'FALSE'. - * @return {string} The value of this field. - */ - getValue(): string; - - /** - * Get the boolean value of this field. - * @return {boolean} The boolean value of this field. - */ - getValueBoolean(): boolean; - - /** - * Get the text of this field. Used when the block is collapsed. - * @return {string} Text representing the value of this field - * ('true' or 'false'). - */ - getText(): string; - } - -} - -declare module Blockly.FieldCheckbox { +declare module FieldCheckbox { /** * Construct a FieldCheckbox from a JSON arg object. * @param {!Object} options A JSON object with options (checked). - * @return {!Blockly.FieldCheckbox} The new field instance. + * @return {!FieldCheckbox} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldCheckbox; + function fromJson(options: Object): FieldCheckbox; /** * Default character for the checkmark. @@ -4809,120 +867,16 @@ declare module Blockly.FieldCheckbox { } -declare module Blockly { - - class FieldColour extends FieldColour__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldColour__Class extends Blockly.Field__Class { - - /** - * Class for a colour input field. - * @param {string=} opt_value The initial value of the field. Should be in - * '#rrggbb' format. Defaults to the first value in the default colour array. - * @param {Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a colour string & returns a - * validated colour string ('#rrggbb' format), 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/colour} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - */ - constructor(opt_value?: string, opt_validator?: Function, opt_config?: Object); - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Mouse cursor style when over the hotspot that initiates the editor. - */ - CURSOR: any /*missing*/; - - /** - * Used to tell if the field needs to be rendered the next time the block is - * rendered. Colour fields are statically sized, and only need to be - * rendered at initialization. - * @type {boolean} - * @protected - */ - isDirty_: boolean; - - /** - * Create the block UI for this colour field. - * @package - */ - initView(): void; - - /** - * Ensure that the input value is a valid colour. - * @param {*=} opt_newValue The input value. - * @return {?string} A valid colour, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Update the value of this colour field, and update the displayed colour. - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is a colour in '#rrggbb' format. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Get the text for this field. Used when the block is collapsed. - * @return {string} Text representing the value of this field. - */ - getText(): string; - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Set a custom colour grid for this field. - * @param {Array} colours Array of colours for this block, - * or null to use default (Blockly.FieldColour.COLOURS). - * @param {Array=} opt_titles Optional array of colour tooltips, - * or null to use default (Blockly.FieldColour.TITLES). - * @return {!Blockly.FieldColour} Returns itself (for method chaining). - */ - setColours(colours: string[], opt_titles?: string[]): Blockly.FieldColour; - - /** - * Set a custom grid size for this field. - * @param {number} columns Number of columns for this block, - * or 0 to use default (Blockly.FieldColour.COLUMNS). - * @return {!Blockly.FieldColour} Returns itself (for method chaining). - */ - setColumns(columns: number): Blockly.FieldColour; - - /** - * Create and show the colour field's editor. - * @protected - */ - showEditor_(): void; - } - -} - -declare module Blockly.FieldColour { +declare module FieldColour { /** * Construct a FieldColour from a JSON arg object. * @param {!Object} options A JSON object with options (colour). - * @return {!Blockly.FieldColour} The new field instance. + * @return {!FieldColour} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldColour; + function fromJson(options: Object): FieldColour; /** * An array of colour strings for the palette. @@ -4948,179 +902,17 @@ declare module Blockly.FieldColour { } -declare module Blockly { - - class FieldDropdown extends FieldDropdown__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldDropdown__Class extends Blockly.Field__Class { - - /** - * Class for an editable dropdown field. - * @param {(!Array|!Function)} menuGenerator A non-empty array of - * options for a dropdown list, or a function which generates these options. - * @param {Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a language-neutral dropdown - * option & returns a validated language-neutral dropdown option, 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/dropdown#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - * @throws {TypeError} If `menuGenerator` options are incorrectly structured. - */ - constructor(menuGenerator: any[][]|Function, opt_validator?: Function, opt_config?: Object); - - /** - * An array of options for a dropdown list, - * or a function which generates these options. - * @type {(!Array| - * !function(this:Blockly.FieldDropdown): !Array)} - * @protected - */ - menuGenerator_: any[][]|{ (): any[][] }; - - /** - * The prefix field label, of common words set after options are trimmed. - * @type {?string} - * @package - */ - prefixField: string; - - /** - * The suffix field label, of common words set after options are trimmed. - * @type {?string} - * @package - */ - suffixField: string; - - /** - * The dropdown menu. - * @type {?Blockly.Menu} - * @protected - */ - menu_: Blockly.Menu; - - /** - * Sets the field's value based on the given XML element. Should only be - * called by Blockly.Xml. - * @param {!Element} fieldElement The element containing info about the - * field's state. - * @package - */ - fromXml(fieldElement: Element): void; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Mouse cursor style when over the hotspot that initiates the editor. - */ - CURSOR: any /*missing*/; - - /** - * Create the block UI for this dropdown. - * @package - */ - initView(): void; - - /** - * Whether or not the dropdown should add a border rect. - * @return {boolean} True if the dropdown field should add a border rect. - * @protected - */ - shouldAddBorderRect_(): boolean; - - /** - * Create a tspan based arrow. - * @protected - */ - createTextArrow_(): void; - - /** - * Create an SVG based arrow. - * @protected - */ - createSVGArrow_(): void; - - /** - * Create a dropdown menu under the text. - * @param {Event=} opt_e Optional mouse event that triggered the field to open, - * or undefined if triggered programmatically. - * @protected - */ - showEditor_(opt_e?: Event): void; - - /** - * Handle the selection of an item in the dropdown menu. - * @param {!Blockly.Menu} menu The Menu component clicked. - * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu. - * @protected - */ - onItemSelected_(menu: Blockly.Menu, menuItem: Blockly.MenuItem): void; - - /** - * @return {boolean} True if the option list is generated by a function. - * Otherwise false. - */ - isOptionListDynamic(): boolean; - - /** - * Return a list of the options for this dropdown. - * @param {boolean=} opt_useCache For dynamic options, whether or not to use the - * cached options or to re-generate them. - * @return {!Array} A non-empty array of option tuples: - * (human-readable text or image, language-neutral name). - * @throws {TypeError} If generated options are incorrectly structured. - */ - getOptions(opt_useCache?: boolean): any[][]; - - /** - * Ensure that the input value is a valid language-neutral option. - * @param {*=} opt_newValue The input value. - * @return {?string} A valid language-neutral option, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Update the value of this dropdown field. - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is one of the valid dropdown options. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Updates the dropdown arrow to match the colour/style of the block. - * @package - */ - applyColour(): void; - - /** - * Draws the border with the correct width. - * @protected - */ - render_(): void; - } - -} - -declare module Blockly.FieldDropdown { +declare module FieldDropdown { /** * Dropdown image properties. * @typedef {{ - * src:string, - * alt:string, - * width:number, - * height:number - * }} - */ + * src:string, + * alt:string, + * width:number, + * height:number + * }} + */ interface ImageProperties { src: string; alt: string; @@ -5131,11 +923,11 @@ declare module Blockly.FieldDropdown { /** * Construct a FieldDropdown from a JSON arg object. * @param {!Object} options A JSON object with options (options). - * @return {!Blockly.FieldDropdown} The new field instance. + * @return {!FieldDropdown} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldDropdown; + function fromJson(options: Object): FieldDropdown; /** * Horizontal distance that a checkmark overhangs the dropdown. @@ -5165,749 +957,89 @@ declare module Blockly.FieldDropdown { } -declare module Blockly { - - class FieldImage extends FieldImage__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldImage__Class extends Blockly.Field__Class { - - /** - * Class for an image on a block. - * @param {string} src The URL of the image. - * @param {!(string|number)} width Width of the image. - * @param {!(string|number)} height Height of the image. - * @param {string=} opt_alt Optional alt text for when block is collapsed. - * @param {function(!Blockly.FieldImage)=} opt_onClick Optional function to be - * called when the image is clicked. If opt_onClick is defined, opt_alt must - * also be defined. - * @param {boolean=} opt_flipRtl Whether to flip the icon in RTL. - * @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/image#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - */ - constructor(src: string, width: string|number, height: string|number, opt_alt?: string, opt_onClick?: { (_0: Blockly.FieldImage): any /*missing*/ }, opt_flipRtl?: boolean, opt_config?: Object); - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Editable fields usually show some sort of UI indicating they are - * editable. This field should not. - * @type {boolean} - */ - EDITABLE: boolean; - - /** - * Used to tell if the field needs to be rendered the next time the block is - * rendered. Image fields are statically sized, and only need to be - * rendered at initialization. - * @type {boolean} - * @protected - */ - isDirty_: boolean; - - /** - * Create the block UI for this image. - * @package - */ - initView(): void; - - /** - * Ensure that the input value (the source URL) is a string. - * @param {*=} opt_newValue The input value. - * @return {?string} A string, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Update the value of this image field, and update the displayed image. - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is a string. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Set the alt text of this image. - * @param {?string} alt New alt text. - * @public - */ - setAlt(alt: string): void; - - /** - * If field click is called, and click handler defined, - * call the handler. - * @protected - */ - showEditor_(): void; - - /** - * Set the function that is called when this image is clicked. - * @param {?function(!Blockly.FieldImage)} func The function that is called - * when the image is clicked, or null to remove. - */ - setOnClickHandler(func: { (_0: Blockly.FieldImage): any /*missing*/ }): void; - } - -} - -declare module Blockly.FieldImage { +declare module FieldImage { /** * Construct a FieldImage from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (src, width, height, * alt, and flipRtl). - * @return {!Blockly.FieldImage} The new field instance. + * @return {!FieldImage} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldImage; + function fromJson(options: Object): FieldImage; } -declare module Blockly { - - class FieldLabel extends FieldLabel__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldLabel__Class extends Blockly.Field__Class { - - /** - * Class for a non-editable, non-serializable text field. - * @param {string=} opt_value The initial value of the field. Should cast to a - * string. Defaults to an empty string if null or undefined. - * @param {string=} opt_class Optional CSS class for the field's text. - * @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/label#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - */ - constructor(opt_value?: string, opt_class?: string, opt_config?: Object); - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Editable fields usually show some sort of UI indicating they are - * editable. This field should not. - * @type {boolean} - */ - EDITABLE: boolean; - - /** - * Create block UI for this label. - * @package - */ - initView(): void; - - /** - * Ensure that the input value casts to a valid string. - * @param {*=} opt_newValue The input value. - * @return {?string} A valid string, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Set the CSS class applied to the field's textElement_. - * @param {?string} cssClass The new CSS class name, or null to remove. - */ - setClass(cssClass: string): void; - } - -} - -declare module Blockly.FieldLabel { +declare module FieldLabel { /** * Construct a FieldLabel from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (text, and class). - * @return {!Blockly.FieldLabel} The new field instance. + * @return {!FieldLabel} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldLabel; + function fromJson(options: Object): FieldLabel; } -declare module Blockly { - - class FieldLabelSerializable extends FieldLabelSerializable__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldLabelSerializable__Class extends Blockly.FieldLabel__Class { - - /** - * Class for a non-editable, serializable text field. - * @param {*} opt_value The initial value of the field. Should cast to a - * string. Defaults to an empty string if null or undefined. - * @param {string=} opt_class Optional CSS class for the field's text. - * @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/label-serializable#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.FieldLabel} - * @constructor - * - */ - constructor(opt_value: any, opt_class?: string, opt_config?: Object); - - /** - * Editable fields usually show some sort of UI indicating they are - * editable. This field should not. - * @type {boolean} - */ - EDITABLE: boolean; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. This field should be serialized, but only edited programmatically. - * @type {boolean} - */ - SERIALIZABLE: boolean; - } - -} - -declare module Blockly.FieldLabelSerializable { +declare module FieldLabelSerializable { /** * Construct a FieldLabelSerializable from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (text, and class). - * @return {!Blockly.FieldLabelSerializable} The new field instance. + * @return {!FieldLabelSerializable} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldLabelSerializable; + function fromJson(options: Object): FieldLabelSerializable; } -declare module Blockly { - - class FieldMultilineInput extends FieldMultilineInput__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldMultilineInput__Class extends Blockly.FieldTextInput__Class { - - /** - * Class for an editable text area field. - * @param {string=} opt_value The initial content of the field. Should cast to a - * string. Defaults to an empty string if null or undefined. - * @param {Function=} opt_validator An optional function that is called - * to validate any constraints on what the user entered. Takes the new - * 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/multiline-text-input#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.FieldTextInput} - * @constructor - */ - constructor(opt_value?: string, opt_validator?: Function, opt_config?: Object); - - /** - * The SVG group element that will contain a text element for each text row - * when initialized. - * @type {SVGGElement} - */ - textGroup_: SVGGElement; - - /** - * Defines the maximum number of lines of field. - * If exceeded, scrolling functionality is enabled. - * @type {number} - * @protected - */ - maxLines_: number; - - /** - * Whether Y overflow is currently occurring. - * @type {boolean} - * @protected - */ - isOverflowedY_: boolean; - - /** - * Serializes this field's value to XML. Should only be called by Blockly.Xml. - * @param {!Element} fieldElement The element to populate with info about the - * field's state. - * @return {!Element} The element containing info about the field's state. - * @package - */ - toXml(fieldElement: Element): Element; - - /** - * Sets the field's value based on the given XML element. Should only be - * called by Blockly.Xml. - * @param {!Element} fieldElement The element containing info about the - * field's state. - * @package - */ - fromXml(fieldElement: Element): void; - - /** - * Create the block UI for this field. - * @package - */ - initView(): void; - - /** - * Called by setValue if the text input is valid. Updates the value of the - * field, and updates the text of the field if it is not currently being - * edited (i.e. handled by the htmlInput_). Is being redefined here to update - * overflow state of the field. - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is a string. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Updates the text of the textElement. - * @protected - */ - render_(): void; - - /** - * Updates the size of the field based on the text. - * @protected - */ - updateSize_(): void; - - /** - * Create the text input editor widget. - * @return {!HTMLTextAreaElement} The newly created text input editor. - * @protected - */ - widgetCreate_(): HTMLTextAreaElement; - - /** - * Sets the maxLines config for this field. - * @param {number} maxLines Defines the maximum number of lines allowed, - * before scrolling functionality is enabled. - */ - setMaxLines(maxLines: number): void; - - /** - * Returns the maxLines config of this field. - * @return {number} The maxLines config value. - */ - getMaxLines(): number; - - /** - * Handle key down to the editor. Override the text input definition of this - * so as to not close the editor when enter is typed in. - * @param {!Event} e Keyboard event. - * @protected - */ - onHtmlInputKeyDown_(e: Event): void; - } - -} - -declare module Blockly.FieldMultilineInput { +declare module FieldMultilineInput { /** * Construct a FieldMultilineInput from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (text, and spellcheck). - * @return {!Blockly.FieldMultilineInput} The new field instance. + * @return {!FieldMultilineInput} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldMultilineInput; + function fromJson(options: Object): FieldMultilineInput; } -declare module Blockly { - - class FieldNumber extends FieldNumber__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldNumber__Class extends Blockly.FieldTextInput__Class { - - /** - * Class for an editable number field. - * @param {string|number=} opt_value The initial value of the field. Should cast - * to a number. Defaults to 0. - * @param {?(string|number)=} opt_min Minimum value. - * @param {?(string|number)=} opt_max Maximum value. - * @param {?(string|number)=} opt_precision Precision for value. - * @param {?Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a number & returns a validated - * number, 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/number#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.FieldTextInput} - * @constructor - */ - constructor(opt_value?: string|number, opt_min?: string|number, opt_max?: string|number, opt_precision?: string|number, opt_validator?: Function, opt_config?: Object); - - /** - * The minimum value this number field can contain. - * @type {number} - * @protected - */ - min_: number; - - /** - * The maximum value this number field can contain. - * @type {number} - * @protected - */ - max_: number; - - /** - * The multiple to which this fields value is rounded. - * @type {number} - * @protected - */ - precision_: number; - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Set the maximum, minimum and precision constraints on this field. - * Any of these properties may be undefined or NaN to be disabled. - * Setting precision (usually a power of 10) enforces a minimum step between - * values. That is, the user's value will rounded to the closest multiple of - * precision. The least significant digit place is inferred from the precision. - * Integers values can be enforces by choosing an integer precision. - * @param {?(number|string|undefined)} min Minimum value. - * @param {?(number|string|undefined)} max Maximum value. - * @param {?(number|string|undefined)} precision Precision for value. - */ - setConstraints(min: number|string|any /*undefined*/, max: number|string|any /*undefined*/, precision: number|string|any /*undefined*/): void; - - /** - * Sets the minimum value this field can contain. Updates the value to reflect. - * @param {?(number|string|undefined)} min Minimum value. - */ - setMin(min: number|string|any /*undefined*/): void; - - /** - * Returns the current minimum value this field can contain. Default is - * -Infinity. - * @return {number} The current minimum value this field can contain. - */ - getMin(): number; - - /** - * Sets the maximum value this field can contain. Updates the value to reflect. - * @param {?(number|string|undefined)} max Maximum value. - */ - setMax(max: number|string|any /*undefined*/): void; - - /** - * Returns the current maximum value this field can contain. Default is - * Infinity. - * @return {number} The current maximum value this field can contain. - */ - getMax(): number; - - /** - * Sets the precision of this field's value, i.e. the number to which the - * value is rounded. Updates the field to reflect. - * @param {?(number|string|undefined)} precision The number to which the - * field's value is rounded. - */ - setPrecision(precision: number|string|any /*undefined*/): void; - - /** - * Returns the current precision of this field. The precision being the - * number to which the field's value is rounded. A precision of 0 means that - * the value is not rounded. - * @return {number} The number to which this field's value is rounded. - */ - getPrecision(): number; - } - -} - -declare module Blockly.FieldNumber { +declare module FieldNumber { /** * Construct a FieldNumber from a JSON arg object. * @param {!Object} options A JSON object with options (value, min, max, and * precision). - * @return {!Blockly.FieldNumber} The new field instance. + * @return {!FieldNumber} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldNumber; + function fromJson(options: Object): FieldNumber; } -declare module Blockly.fieldRegistry { - /** - * Registers a field type. - * Blockly.fieldRegistry.fromJson uses this registry to - * find the appropriate field type. - * @param {string} type The field type name as used in the JSON definition. - * @param {!Blockly.IRegistrableField} fieldClass The field class containing a - * fromJson function that can construct an instance of the field. - * @throws {Error} if the type name is empty, the field is already - * registered, or the fieldClass is not an object containing a fromJson - * function. - */ - function register(type: string, fieldClass: Blockly.IRegistrableField): void; - - /** - * Unregisters the field registered with the given type. - * @param {string} type The field type name as used in the JSON definition. - */ - function unregister(type: string): void; - - /** - * Construct a Field from a JSON arg object. - * Finds the appropriate registered field by the type name as registered using - * Blockly.fieldRegistry.register. - * @param {!Object} options A JSON object with a type and options specific - * to the field type. - * @return {?Blockly.Field} The new field instance or null if a field wasn't - * found with the given type name - * @package - */ - function fromJson(options: Object): Blockly.Field; -} - - -declare module Blockly { - - class FieldTextInput extends FieldTextInput__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldTextInput__Class extends Blockly.Field__Class { - - /** - * Class for an editable text field. - * @param {string=} opt_value The initial value of the field. Should cast to a - * string. Defaults to an empty string if null or undefined. - * @param {?Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a string & returns a validated - * string, 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} - * for a list of properties this parameter supports. - * @extends {Blockly.Field} - * @constructor - */ - constructor(opt_value?: string, opt_validator?: Function, opt_config?: Object); - - /** - * Allow browser to spellcheck this field. - * @type {boolean} - * @protected - */ - spellcheck_: boolean; - - /** - * The HTML input element. - * @type {HTMLElement} - */ - htmlInput_: HTMLElement; - - /** - * Whether the field should consider the whole parent block to be its click - * target. - * @type {?boolean} - */ - fullBlockClickTarget_: boolean; - - /** - * The workspace that this field belongs to. - * @type {?Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * The default value for this field. - * @type {*} - * @protected - */ - DEFAULT_VALUE: any; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Mouse cursor style when over the hotspot that initiates the editor. - */ - CURSOR: any /*missing*/; - - /** - * Ensure that the input value casts to a valid string. - * @param {*=} opt_newValue The input value. - * @return {*} A valid string, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): any; - - /** - * Called by setValue if the text input is not valid. If the field is - * currently being edited it reverts value of the field to the previous - * value while allowing the display text to be handled by the htmlInput_. - * @param {*} _invalidValue The input value that was determined to be invalid. - * This is not used by the text input because its display value is stored on - * the htmlInput_. - * @protected - */ - doValueInvalid_(_invalidValue: any): void; - - /** - * Called by setValue if the text input is valid. Updates the value of the - * field, and updates the text of the field if it is not currently being - * edited (i.e. handled by the htmlInput_). - * @param {*} newValue The value to be saved. The default validator guarantees - * that this is a string. - * @protected - */ - doValueUpdate_(newValue: any): void; - - /** - * Updates text field to match the colour/style of the block. - * @package - */ - applyColour(): void; - - /** - * Updates the colour of the htmlInput given the current validity of the - * field's value. - * @protected - */ - render_(): void; - - /** - * Set whether this field is spellchecked by the browser. - * @param {boolean} check True if checked. - */ - setSpellcheck(check: boolean): void; - - /** - * Show the inline free-text editor on top of the text. - * @param {Event=} _opt_e Optional mouse event that triggered the field to open, - * or undefined if triggered programmatically. - * @param {boolean=} opt_quietInput True if editor should be created without - * focus. Defaults to false. - * @protected - */ - showEditor_(_opt_e?: Event, opt_quietInput?: boolean): void; - - /** - * Create the text input editor widget. - * @return {!HTMLElement} The newly created text input editor. - * @protected - */ - widgetCreate_(): HTMLElement; - - /** - * Closes the editor, saves the results, and disposes of any events or - * DOM-references belonging to the editor. - * @protected - */ - widgetDispose_(): void; - - /** - * Bind handlers for user input on the text input field's editor. - * @param {!HTMLElement} htmlInput The htmlInput to which event - * handlers will be bound. - * @protected - */ - bindInputEvents_(htmlInput: HTMLElement): void; - - /** - * Unbind handlers for user input and workspace size changes. - * @protected - */ - unbindInputEvents_(): void; - - /** - * Handle key down to the editor. - * @param {!Event} e Keyboard event. - * @protected - */ - onHtmlInputKeyDown_(e: Event): void; - - /** - * Set the HTML input value and the field's internal value. The difference - * between this and ``setValue`` is that this also updates the HTML input - * value whilst editing. - * @param {*} newValue New value. - * @protected - */ - setEditorValue_(newValue: any): void; - - /** - * Resize the editor to fit the text. - * @protected - */ - resizeEditor_(): void; - - /** - * Transform the provided value into a text to show in the HTML input. - * Override this method if the field's HTML input representation is different - * than the field's value. This should be coupled with an override of - * `getValueFromEditorText_`. - * @param {*} value The value stored in this field. - * @return {string} The text to show on the HTML input. - * @protected - */ - getEditorText_(value: any): string; - - /** - * Transform the text received from the HTML input into a value to store - * in this field. - * Override this method if the field's HTML input representation is different - * than the field's value. This should be coupled with an override of - * `getEditorText_`. - * @param {string} text Text received from the HTML input. - * @return {*} The value to store. - * @protected - */ - getValueFromEditorText_(text: string): any; - } - -} - -declare module Blockly.FieldTextInput { +declare module FieldTextInput { /** * Construct a FieldTextInput from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (text, and spellcheck). - * @return {!Blockly.FieldTextInput} The new field instance. + * @return {!FieldTextInput} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldTextInput; + function fromJson(options: Object): FieldTextInput; /** * Pixel size of input border radius. @@ -5917,674 +1049,31 @@ declare module Blockly.FieldTextInput { } -declare module Blockly { - - class FieldVariable extends FieldVariable__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FieldVariable__Class extends Blockly.FieldDropdown__Class { - - /** - * Class for a variable's dropdown field. - * @param {?string} varName The default name for the variable. If null, - * a unique variable name will be generated. - * @param {Function=} opt_validator A function that is called to validate - * changes to the field's value. Takes in a variable ID & returns a - * validated variable ID, or null to abort the change. - * @param {Array=} opt_variableTypes A list of the types of variables - * to include in the dropdown. - * @param {string=} opt_defaultType The type of variable to create if this - * field's value is not explicitly set. Defaults to ''. - * @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/variable#creation} - * for a list of properties this parameter supports. - * @extends {Blockly.FieldDropdown} - * @constructor - */ - constructor(varName: string, opt_validator?: Function, opt_variableTypes?: string[], opt_defaultType?: string, opt_config?: Object); - - /** - * An array of options for a dropdown list, - * or a function which generates these options. - * @type {(!Array| - * !function(this:Blockly.FieldDropdown): !Array)} - * @protected - */ - menuGenerator_: any[][]|{ (): any[][] }; - - /** - * The initial variable name passed to this field's constructor, or an - * empty string if a name wasn't provided. Used to create the initial - * variable. - * @type {string} - */ - defaultVariableName: string; - - /** - * Serializable fields are saved by the XML renderer, non-serializable fields - * are not. Editable fields should also be serializable. - * @type {boolean} - */ - SERIALIZABLE: boolean; - - /** - * Configure the field based on the given map of options. - * @param {!Object} config A map of options to configure the field based on. - * @protected - */ - configure_(config: Object): void; - - /** - * Initialize the model for this field if it has not already been initialized. - * If the value has not been set to a variable by the first render, we make up a - * variable rather than let the value be invalid. - * @package - */ - initModel(): void; - - /** - * Initialize this field based on the given XML. - * @param {!Element} fieldElement The element containing information about the - * variable field's state. - */ - fromXml(fieldElement: Element): void; - - /** - * Serialize this field to XML. - * @param {!Element} fieldElement The element to populate with info about the - * field's state. - * @return {!Element} The element containing info about the field's state. - */ - toXml(fieldElement: Element): Element; - - /** - * Attach this field to a block. - * @param {!Blockly.Block} block The block containing this field. - */ - setSourceBlock(block: Blockly.Block): void; - - /** - * Get the variable's ID. - * @return {string} Current variable's ID. - */ - getValue(): string; - - /** - * Get the text from this field, which is the selected variable's name. - * @return {string} The selected variable's name, or the empty string if no - * variable is selected. - */ - getText(): string; - - /** - * Get the variable model for the selected variable. - * Not guaranteed to be in the variable map on the workspace (e.g. if accessed - * after the variable has been deleted). - * @return {?Blockly.VariableModel} The selected variable, or null if none was - * selected. - * @package - */ - getVariable(): Blockly.VariableModel; - - /** - * Gets the validation function for this field, or null if not set. - * Returns null if the variable is not set, because validators should not - * run on the initial setValue call, because the field won't be attached to - * a block and workspace at that point. - * @return {?Function} Validation function, or null. - */ - getValidator(): Function; - - /** - * Ensure that the ID belongs to a valid variable of an allowed type. - * @param {*=} opt_newValue The ID of the new variable to set. - * @return {?string} The validated ID, or null if invalid. - * @protected - */ - doClassValidation_(opt_newValue?: any): string; - - /** - * Update the value of this variable field, as well as its variable and text. - * - * The variable ID should be valid at this point, but if a variable field - * validator returns a bad ID, this could break. - * @param {*} newId The value to be saved. - * @protected - */ - doValueUpdate_(newId: any): void; - - /** - * Refreshes the name of the variable by grabbing the name of the model. - * Used when a variable gets renamed, but the ID stays the same. Should only - * be called by the block. - * @package - */ - refreshVariableName(): void; - - /** - * Handle the selection of an item in the variable dropdown menu. - * Special case the 'Rename variable...' and 'Delete variable...' options. - * In the rename case, prompt the user for a new name. - * @param {!Blockly.Menu} menu The Menu component clicked. - * @param {!Blockly.MenuItem} menuItem The MenuItem selected within menu. - * @protected - */ - onItemSelected_(menu: Blockly.Menu, menuItem: Blockly.MenuItem): void; - } - -} - -declare module Blockly.FieldVariable { +declare module FieldVariable { /** * Construct a FieldVariable from a JSON arg object, * dereferencing any string table references. * @param {!Object} options A JSON object with options (variable, * variableTypes, and defaultType). - * @return {!Blockly.FieldVariable} The new field instance. + * @return {!FieldVariable} The new field instance. * @package * @nocollapse */ - function fromJson(options: Object): Blockly.FieldVariable; + function fromJson(options: Object): FieldVariable; /** * Return a sorted list of variable names for variable dropdown menus. * Include a special option at the end for creating a new variable name. * @return {!Array} Array of variable names/id tuples. - * @this {Blockly.FieldVariable} + * @this {FieldVariable} */ function dropdownCreate(): any[][]; } -declare module Blockly { - class Flyout extends Flyout__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Flyout__Class extends Blockly.DeleteArea__Class implements Blockly.IFlyout { - - /** - * Class for a flyout. - * @param {!Blockly.Options} workspaceOptions Dictionary of options for the - * workspace. - * @constructor - * @abstract - * @implements {Blockly.IFlyout} - * @extends {Blockly.DeleteArea} - */ - constructor(workspaceOptions: Blockly.Options); - - /** - * @type {!Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * The unique id for this component that is used to register with the - * ComponentManager. - * @type {string} - */ - id: string; - - /** - * Is RTL vs LTR. - * @type {boolean} - */ - RTL: boolean; - - /** - * Whether the flyout should be laid out horizontally or not. - * @type {boolean} - * @package - */ - horizontalLayout: boolean; - - /** - * Position of the toolbox and flyout relative to the workspace. - * @type {number} - * @protected - */ - toolboxPosition_: number; - - /** - * List of visible buttons. - * @type {!Array} - * @protected - */ - buttons_: Blockly.FlyoutButton[]; - - /** - * Width of output tab. - * @type {number} - * @protected - * @const - */ - tabWidth_: number; - - /** - * The target workspace - * @type {?Blockly.WorkspaceSvg} - * @package - */ - targetWorkspace: Blockly.WorkspaceSvg; - - /** - * Does the flyout automatically close when a block is created? - * @type {boolean} - */ - autoClose: boolean; - - /** - * Corner radius of the flyout background. - * @type {number} - * @const - */ - CORNER_RADIUS: number; - - /** - * Margin around the edges of the blocks in the flyout. - * @type {number} - * @const - */ - MARGIN: number; - - /** - * Gap between items in horizontal flyouts. Can be overridden with the "sep" - * element. - * @const {number} - */ - GAP_X: any /*missing*/; - - /** - * Gap between items in vertical flyouts. Can be overridden with the "sep" - * element. - * @const {number} - */ - GAP_Y: any /*missing*/; - - /** - * Top/bottom padding between scrollbar and edge of flyout background. - * @type {number} - * @const - */ - SCROLLBAR_MARGIN: number; - - /** - * Width of flyout. - * @type {number} - * @protected - */ - width_: number; - - /** - * Height of flyout. - * @type {number} - * @protected - */ - height_: number; - - /** - * Range of a drag angle from a flyout considered "dragging toward workspace". - * Drags that are within the bounds of this many degrees from the orthogonal - * line to the flyout edge are considered to be "drags toward the workspace". - * Example: - * Flyout Edge Workspace - * [block] / <-within this angle, drags "toward workspace" | - * [block] ---- orthogonal to flyout boundary ---- | - * [block] \ | - * The angle is given in degrees from the orthogonal. - * - * This is used to know when to create a new block and when to scroll the - * flyout. Setting it to 360 means that all drags create a new block. - * @type {number} - * @protected - */ - dragAngleRange_: number; - - /** - * Creates the flyout's DOM. Only needs to be called once. The flyout can - * either exist as its own SVG element or be a g element nested inside a - * separate SVG element. - * @param {string| - * !Blockly.utils.Svg| - * !Blockly.utils.Svg} tagName The type of tag to - * put the flyout in. This should be or . - * @return {!SVGElement} The flyout's SVG group. - */ - createDom(tagName: string|Blockly.utils.Svg|Blockly.utils.Svg): SVGElement; - - /** - * Initializes the flyout. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The workspace in which to - * create new blocks. - */ - init(targetWorkspace: Blockly.WorkspaceSvg): void; - - /** - * Dispose of this flyout. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Get the width of the flyout. - * @return {number} The width of the flyout. - */ - getWidth(): number; - - /** - * Get the height of the flyout. - * @return {number} The width of the flyout. - */ - getHeight(): number; - - /** - * Get the scale (zoom level) of the flyout. By default, - * this matches the target workspace scale, but this can be overridden. - * @return {number} Flyout workspace scale. - */ - getFlyoutScale(): number; - - /** - * Get the workspace inside the flyout. - * @return {!Blockly.WorkspaceSvg} The workspace inside the flyout. - * @package - */ - getWorkspace(): Blockly.WorkspaceSvg; - - /** - * Is the flyout visible? - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Set whether the flyout is visible. A value of true does not necessarily mean - * that the flyout is shown. It could be hidden because its container is hidden. - * @param {boolean} visible True if visible. - */ - setVisible(visible: boolean): void; - - /** - * Set whether this flyout's container is visible. - * @param {boolean} visible Whether the container is visible. - */ - setContainerVisible(visible: boolean): void; - - /** - * Update the view based on coordinates calculated in position(). - * @param {number} width The computed width of the flyout's SVG group - * @param {number} height The computed height of the flyout's SVG group. - * @param {number} x The computed x origin of the flyout's SVG group. - * @param {number} y The computed y origin of the flyout's SVG group. - * @protected - */ - positionAt_(width: number, height: number, x: number, y: number): void; - - /** - * Hide and empty the flyout. - */ - hide(): void; - - /** - * Show and populate the flyout. - * @param {!Blockly.utils.toolbox.FlyoutDefinition|string} flyoutDef Contents to display - * in the flyout. This is either an array of Nodes, a NodeList, a - * toolbox definition, or a string with the name of the dynamic category. - */ - show(flyoutDef: Blockly.utils.toolbox.FlyoutDefinition|string): void; - - /** - * Create a block from the xml and permanently disable any blocks that were - * defined as disabled. - * @param {!Element} blockXml The xml of the block. - * @return {!Blockly.BlockSvg} The block created from the blockXml. - * @protected - */ - createBlock_(blockXml: Element): Blockly.BlockSvg; - - /** - * Delete blocks, mats and buttons from a previous showing of the flyout. - * @protected - */ - clearOldBlocks_(): void; - - /** - * Add listeners to a block that has been added to the flyout. - * @param {!SVGElement} root The root node of the SVG group the block is in. - * @param {!Blockly.BlockSvg} block The block to add listeners for. - * @param {!SVGElement} rect The invisible rectangle under the block that acts - * as a mat for that block. - * @protected - */ - addBlockListeners_(root: SVGElement, block: Blockly.BlockSvg, rect: SVGElement): void; - - /** - * Does this flyout allow you to create a new instance of the given block? - * Used for deciding if a block can be "dragged out of" the flyout. - * @param {!Blockly.BlockSvg} block The block to copy from the flyout. - * @return {boolean} True if you can create a new instance of the block, false - * otherwise. - * @package - */ - isBlockCreatable_(block: Blockly.BlockSvg): boolean; - - /** - * Create a copy of this block on the workspace. - * @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout. - * @return {!Blockly.BlockSvg} The newly created block. - * @throws {Error} if something went wrong with deserialization. - * @package - */ - createBlock(originalBlock: Blockly.BlockSvg): Blockly.BlockSvg; - - /** - * Initialize the given button: move it to the correct location, - * add listeners, etc. - * @param {!Blockly.FlyoutButton} button The button to initialize and place. - * @param {number} x The x position of the cursor during this layout pass. - * @param {number} y The y position of the cursor during this layout pass. - * @protected - */ - initFlyoutButton_(button: Blockly.FlyoutButton, x: number, y: number): void; - - /** - * Create and place a rectangle corresponding to the given block. - * @param {!Blockly.BlockSvg} block The block to associate the rect to. - * @param {number} x The x position of the cursor during this layout pass. - * @param {number} y The y position of the cursor during this layout pass. - * @param {!{height: number, width: number}} blockHW The height and width of the - * block. - * @param {number} index The index into the mats list where this rect should be - * placed. - * @return {!SVGElement} Newly created SVG element for the rectangle behind the - * block. - * @protected - */ - createRect_(block: Blockly.BlockSvg, x: number, y: number, blockHW: { height: number; width: number }, index: number): SVGElement; - - /** - * Move a rectangle to sit exactly behind a block, taking into account tabs, - * hats, and any other protrusions we invent. - * @param {!SVGElement} rect The rectangle to move directly behind the block. - * @param {!Blockly.BlockSvg} block The block the rectangle should be behind. - * @protected - */ - moveRectToBlock_(rect: SVGElement, block: Blockly.BlockSvg): void; - - /** - * Reflow blocks and their mats. - */ - reflow(): void; - - /** - * @return {boolean} True if this flyout may be scrolled with a scrollbar or by - * dragging. - * @package - */ - isScrollable(): boolean; - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {Blockly.utils.Rect} The component's bounding box. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Position the flyout. - * @return {void} - */ - position(): void; - - /** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This is used in determineDragIntention_ to - * determine if a new block should be created or if the flyout should scroll. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} True if the drag is toward the workspace. - * @package - */ - isDragTowardWorkspace(currentDragDeltaXY: Blockly.utils.Coordinate): boolean; - - /** - * Sets the translation of the flyout to match the scrollbars. - * @param {!{x:number,y:number}} xyRatio Contains a y property which is a float - * between 0 and 1 specifying the degree of scrolling and a - * similar x property. - * @protected - */ - setMetrics_(xyRatio: { x: number; y: number }): void; - - /** - * Lay out the blocks in the flyout. - * @param {!Array} contents The blocks and buttons to lay out. - * @param {!Array} gaps The visible gaps between blocks. - * @protected - */ - layout_(contents: Object[], gaps: number[]): void; - - /** - * Scroll the flyout. - * @param {!Event} e Mouse wheel scroll event. - * @protected - */ - wheel_(e: Event): void; - - /** - * Compute height of flyout. Position mat under each block. - * For RTL: Lay out the blocks right-aligned. - * @return {void} - * @protected - */ - reflowInternal_(): void; - - /** - * Calculates the x coordinate for the flyout position. - * @return {number} X coordinate. - */ - getX(): number; - - /** - * Calculates the y coordinate for the flyout position. - * @return {number} Y coordinate. - */ - getY(): number; - } - -} - - -declare module Blockly { - - class FlyoutButton extends FlyoutButton__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FlyoutButton__Class { - - /** - * Class for a button in the flyout. - * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this - * button. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace. - * @param {!Blockly.utils.toolbox.ButtonOrLabelInfo} json - * The JSON specifying the label/button. - * @param {boolean} isLabel Whether this button should be styled as a label. - * @constructor - * @package - */ - constructor(workspace: Blockly.WorkspaceSvg, targetWorkspace: Blockly.WorkspaceSvg, json: Blockly.utils.toolbox.ButtonOrLabelInfo, isLabel: boolean); - - /** - * The JSON specifying the label / button. - * @type {!Blockly.utils.toolbox.ButtonOrLabelInfo} - */ - info: Blockly.utils.toolbox.ButtonOrLabelInfo; - - /** - * The width of the button's rect. - * @type {number} - */ - width: number; - - /** - * The height of the button's rect. - * @type {number} - */ - height: number; - - /** - * Create the button elements. - * @return {!SVGElement} The button's SVG group. - */ - createDom(): SVGElement; - - /** - * Correctly position the flyout button and make it visible. - */ - show(): void; - - /** - * Move the button to the given x, y coordinates. - * @param {number} x The new x coordinate. - * @param {number} y The new y coordinate. - */ - moveTo(x: number, y: number): void; - - /** - * @return {boolean} Whether or not the button is a label. - */ - isLabel(): boolean; - - /** - * Location of the button. - * @return {!Blockly.utils.Coordinate} x, y coordinates. - * @package - */ - getPosition(): Blockly.utils.Coordinate; - - /** - * @return {string} Text of the button. - */ - getButtonText(): string; - - /** - * Get the button's target workspace. - * @return {!Blockly.WorkspaceSvg} The target workspace of the flyout where this - * button resides. - */ - getTargetWorkspace(): Blockly.WorkspaceSvg; - - /** - * Dispose of this button. - */ - dispose(): void; - } - -} - -declare module Blockly.FlyoutButton { +declare module FlyoutButton { /** * The horizontal margin around the text in the button. @@ -6598,188 +1087,9 @@ declare module Blockly.FlyoutButton { } -declare module Blockly { - - class HorizontalFlyout extends HorizontalFlyout__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class HorizontalFlyout__Class extends Blockly.Flyout__Class { - - /** - * Class for a flyout. - * @param {!Blockly.Options} workspaceOptions Dictionary of options for the - * workspace. - * @extends {Blockly.Flyout} - * @constructor - */ - constructor(workspaceOptions: Blockly.Options); - - /** - * Sets the translation of the flyout to match the scrollbars. - * @param {!{x:number,y:number}} xyRatio Contains a y property which is a float - * between 0 and 1 specifying the degree of scrolling and a - * similar x property. - * @protected - */ - setMetrics_(xyRatio: { x: number; y: number }): void; - - /** - * Calculates the x coordinate for the flyout position. - * @return {number} X coordinate. - */ - getX(): number; - - /** - * Calculates the y coordinate for the flyout position. - * @return {number} Y coordinate. - */ - getY(): number; - - /** - * Move the flyout to the edge of the workspace. - */ - position(): void; - - /** - * Scroll the flyout to the top. - */ - scrollToStart(): void; - - /** - * Scroll the flyout. - * @param {!Event} e Mouse wheel scroll event. - * @protected - */ - wheel_(e: Event): void; - - /** - * Lay out the blocks in the flyout. - * @param {!Array} contents The blocks and buttons to lay out. - * @param {!Array} gaps The visible gaps between blocks. - * @protected - */ - layout_(contents: Object[], gaps: number[]): void; - - /** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This is used in determineDragIntention_ to - * determine if a new block should be created or if the flyout should scroll. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} True if the drag is toward the workspace. - * @package - */ - isDragTowardWorkspace(currentDragDeltaXY: Blockly.utils.Coordinate): boolean; - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Compute height of flyout. Position mat under each block. - * For RTL: Lay out the blocks right-aligned. - * @protected - */ - reflowInternal_(): void; - } - -} -declare module Blockly { - - class VerticalFlyout extends VerticalFlyout__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VerticalFlyout__Class extends Blockly.Flyout__Class { - - /** - * Class for a flyout. - * @param {!Blockly.Options} workspaceOptions Dictionary of options for the - * workspace. - * @extends {Blockly.Flyout} - * @constructor - */ - constructor(workspaceOptions: Blockly.Options); - - /** - * Sets the translation of the flyout to match the scrollbars. - * @param {!{x:number,y:number}} xyRatio Contains a y property which is a float - * between 0 and 1 specifying the degree of scrolling and a - * similar x property. - * @protected - */ - setMetrics_(xyRatio: { x: number; y: number }): void; - - /** - * Calculates the x coordinate for the flyout position. - * @return {number} X coordinate. - */ - getX(): number; - - /** - * Calculates the y coordinate for the flyout position. - * @return {number} Y coordinate. - */ - getY(): number; - - /** - * Move the flyout to the edge of the workspace. - */ - position(): void; - - /** - * Scroll the flyout to the top. - */ - scrollToStart(): void; - - /** - * Scroll the flyout. - * @param {!Event} e Mouse wheel scroll event. - * @protected - */ - wheel_(e: Event): void; - - /** - * Lay out the blocks in the flyout. - * @param {!Array} contents The blocks and buttons to lay out. - * @param {!Array} gaps The visible gaps between blocks. - * @protected - */ - layout_(contents: Object[], gaps: number[]): void; - - /** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This is used in determineDragIntention_ to - * determine if a new block should be created or if the flyout should scroll. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} True if the drag is toward the workspace. - * @package - */ - isDragTowardWorkspace(currentDragDeltaXY: Blockly.utils.Coordinate): boolean; - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Compute width of flyout. Position mat under each block. - * For RTL: Lay out the blocks and buttons to be right-aligned. - * @protected - */ - reflowInternal_(): void; - } - -} - -declare module Blockly.VerticalFlyout { +declare module VerticalFlyout { /** * The name of the vertical flyout in the registry. @@ -6789,452 +1099,8 @@ declare module Blockly.VerticalFlyout { } -declare module Blockly { - class Generator extends Generator__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Generator__Class { - - /** - * Class for a code generator that translates the blocks into a language. - * @param {string} name Language name of this generator. - * @constructor - */ - constructor(name: string); - - /** - * Arbitrary code to inject into locations that risk causing infinite loops. - * Any instances of '%1' will be replaced by the block ID that failed. - * E.g. ' checkTimeout(%1);\n' - * @type {?string} - */ - INFINITE_LOOP_TRAP: string; - - /** - * Arbitrary code to inject before every statement. - * Any instances of '%1' will be replaced by the block ID of the statement. - * E.g. 'highlight(%1);\n' - * @type {?string} - */ - STATEMENT_PREFIX: string; - - /** - * Arbitrary code to inject after every statement. - * Any instances of '%1' will be replaced by the block ID of the statement. - * E.g. 'highlight(%1);\n' - * @type {?string} - */ - STATEMENT_SUFFIX: string; - - /** - * The method of indenting. Defaults to two spaces, but language generators - * may override this to increase indent or change to tabs. - * @type {string} - */ - INDENT: string; - - /** - * Maximum length for a comment before wrapping. Does not account for - * indenting level. - * @type {number} - */ - COMMENT_WRAP: number; - - /** - * List of outer-inner pairings that do NOT require parentheses. - * @type {!Array>} - */ - ORDER_OVERRIDES: number[][]; - - /** - * 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} - */ - isInitialized: boolean; - - /** - * Generate code for all blocks in the workspace to the specified language. - * @param {!Blockly.Workspace=} workspace Workspace to generate code from. - * @return {string} Generated code. - */ - workspaceToCode(workspace?: Blockly.Workspace): string; - - /** - * Prepend a common prefix onto each line of code. - * Intended for indenting code or adding comment markers. - * @param {string} text The lines of code. - * @param {string} prefix The common prefix. - * @return {string} The prefixed lines of code. - */ - prefixLines(text: string, prefix: string): string; - - /** - * Recursively spider a tree of blocks, returning all their comments. - * @param {!Blockly.Block} block The block from which to start spidering. - * @return {string} Concatenated list of comments. - */ - allNestedComments(block: Blockly.Block): string; - - /** - * 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. - * For value blocks, an array containing the generated code and an - * operator order value. Returns '' if block is null. - */ - blockToCode(block: Blockly.Block, opt_thisOnly?: boolean): string|any[]; - - /** - * Generate code representing the specified value input. - * @param {!Blockly.Block} block The block containing the input. - * @param {string} name The name of the input. - * @param {number} outerOrder The maximum binding strength (minimum order value) - * of any operators adjacent to "block". - * @return {string} Generated code or '' if no blocks are connected or the - * specified input does not exist. - */ - valueToCode(block: Blockly.Block, name: string, outerOrder: number): string; - - /** - * Generate a code string representing the blocks attached to the named - * statement input. Indent the code. - * This is mainly used in generators. When trying to generate code to evaluate - * look at using workspaceToCode or blockToCode. - * @param {!Blockly.Block} block The block containing the input. - * @param {string} name The name of the input. - * @return {string} Generated code or '' if no blocks are connected. - */ - statementToCode(block: Blockly.Block, name: string): string; - - /** - * Add an infinite loop trap to the contents of a loop. - * Add statement suffix at the start of the loop block (right after the loop - * statement executes), and a statement prefix to the end of the loop block - * (right before the loop statement executes). - * @param {string} branch Code for loop contents. - * @param {!Blockly.Block} block Enclosing block. - * @return {string} Loop contents, with infinite loop trap added. - */ - addLoopTrap(branch: string, block: Blockly.Block): string; - - /** - * Inject a block ID into a message to replace '%1'. - * Used for STATEMENT_PREFIX, STATEMENT_SUFFIX, and INFINITE_LOOP_TRAP. - * @param {string} msg Code snippet with '%1'. - * @param {!Blockly.Block} block Block which has an ID. - * @return {string} Code snippet with ID. - */ - injectId(msg: string, block: Blockly.Block): string; - - /** - * Comma-separated list of reserved words. - * @type {string} - * @protected - */ - RESERVED_WORDS_: string; - - /** - * Add one or more words to the list of reserved words for this language. - * @param {string} words Comma-separated list of words to add to the list. - * No spaces. Duplicates are ok. - */ - addReservedWords(words: string): void; - - /** - * This is used as a placeholder in functions defined using - * Blockly.Generator.provideFunction_. It must not be legal code that could - * legitimately appear in a function definition (or comment), and it must - * not confuse the regular expression parser. - * @type {string} - * @protected - */ - FUNCTION_NAME_PLACEHOLDER_: string; - - /** - * A dictionary of definitions to be printed before the code. - * @type {!Object|undefined} - * @protected - */ - definitions_: Object|any /*undefined*/; - - /** - * A dictionary mapping desired function names in definitions_ to actual - * function names (to avoid collisions with user functions). - * @type {!Object|undefined} - * @protected - */ - functionNames_: Object|any /*undefined*/; - - /** - * A database of variable and procedure names. - * @type {!Blockly.Names|undefined} - * @protected - */ - nameDB_: Blockly.Names|any /*undefined*/; - - /** - * Define a developer-defined function (not a user-defined procedure) to be - * included in the generated code. Used for creating private helper functions. - * The first time this is called with a given desiredName, the code is - * saved and an actual name is generated. Subsequent calls with the - * same desiredName have no effect but have the same return value. - * - * It is up to the caller to make sure the same desiredName is not - * used for different helper functions (e.g. use "colourRandom" and - * "listRandom", not "random"). There is no danger of colliding with reserved - * words, or user-defined variable or procedure names. - * - * The code gets output when Blockly.Generator.finish() is called. - * - * @param {string} desiredName The desired name of the function - * (e.g. mathIsPrime). - * @param {!Array} code A list of statements. Use ' ' for indents. - * @return {string} The actual name of the new function. This may differ - * from desiredName if the former has already been taken by the user. - * @protected - */ - provideFunction_(desiredName: string, code: string[]): string; - - /** - * Hook for code to run before code generation starts. - * Subclasses may override this, e.g. to initialise the database of variable - * names. - * @param {!Blockly.Workspace} _workspace Workspace to generate code from. - */ - init(_workspace: Blockly.Workspace): void; - - /** - * Common tasks for generating code from blocks. This is called from - * blockToCode and is called on every block, not just top level blocks. - * Subclasses may override this, e.g. to generate code for statements following - * the block, or to handle comments for the specified block and any connected - * value blocks. - * @param {!Blockly.Block} _block The current block. - * @param {string} code The code created for this block. - * @param {boolean=} _opt_thisOnly True to generate code for only this - * statement. - * @return {string} Code with comments and subsequent blocks added. - * @protected - */ - scrub_(_block: Blockly.Block, code: string, _opt_thisOnly?: boolean): string; - - /** - * Hook for code to run at end of code generation. - * Subclasses may override this, e.g. to prepend the generated code with import - * statements or variable definitions. - * @param {string} code Generated code. - * @return {string} Completed code. - */ - finish(code: string): string; - - /** - * Naked values are top-level blocks with outputs that aren't plugged into - * anything. - * Subclasses may override this, e.g. if their language does not allow - * naked values. - * @param {string} line Line of generated code. - * @return {string} Legal line of code. - */ - scrubNakedValue(line: string): string; - } - -} - - -declare module Blockly { - - class Gesture extends Gesture__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Gesture__Class { - - /** - * Class for one gesture. - * @param {!Event} e The event that kicked off this gesture. - * @param {!Blockly.WorkspaceSvg} creatorWorkspace The workspace that created - * this gesture and has a reference to it. - * @constructor - */ - constructor(e: Event, creatorWorkspace: Blockly.WorkspaceSvg); - - /** - * The workspace that the gesture started on. There may be multiple - * workspaces on a page; this is more accurate than using - * Blockly.getMainWorkspace(). - * @type {Blockly.WorkspaceSvg} - * @protected - */ - startWorkspace_: Blockly.WorkspaceSvg; - - /** - * A handle to use to unbind a mouse move listener at the end of a drag. - * Opaque data returned from Blockly.bindEventWithChecks_. - * @type {?Blockly.browserEvents.Data} - * @protected - */ - onMoveWrapper_: Blockly.browserEvents.Data; - - /** - * A handle to use to unbind a mouse up listener at the end of a drag. - * Opaque data returned from Blockly.bindEventWithChecks_. - * @type {?Blockly.browserEvents.Data} - * @protected - */ - onUpWrapper_: Blockly.browserEvents.Data; - - /** - * Boolean used internally to break a cycle in disposal. - * @type {boolean} - * @protected - */ - isEnding_: boolean; - - /** - * Sever all links from this object. - * @package - */ - dispose(): void; - - /** - * Start a gesture: update the workspace to indicate that a gesture is in - * progress and bind mousemove and mouseup handlers. - * @param {!Event} e A mouse down or touch start event. - * @package - */ - doStart(e: Event): void; - - /** - * Bind gesture events. - * @param {!Event} e A mouse down or touch start event. - * @package - */ - bindMouseEvents(e: Event): void; - - /** - * Handle a mouse move or touch move event. - * @param {!Event} e A mouse move or touch move event. - * @package - */ - handleMove(e: Event): void; - - /** - * Handle a mouse up or touch end event. - * @param {!Event} e A mouse up or touch end event. - * @package - */ - handleUp(e: Event): void; - - /** - * Cancel an in-progress gesture. If a workspace or block drag is in progress, - * end the drag at the most recent location. - * @package - */ - cancel(): void; - - /** - * Handle a real or faked right-click event by showing a context menu. - * @param {!Event} e A mouse move or touch move event. - * @package - */ - handleRightClick(e: Event): void; - - /** - * Handle a mousedown/touchstart event on a workspace. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.WorkspaceSvg} ws The workspace the event hit. - * @package - */ - handleWsStart(e: Event, ws: Blockly.WorkspaceSvg): void; - - /** - * Handle a mousedown/touchstart event on a flyout. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.IFlyout} flyout The flyout the event hit. - * @package - */ - handleFlyoutStart(e: Event, flyout: Blockly.IFlyout): void; - - /** - * Handle a mousedown/touchstart event on a block. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.BlockSvg} block The block the event hit. - * @package - */ - handleBlockStart(e: Event, block: Blockly.BlockSvg): void; - - /** - * Handle a mousedown/touchstart event on a bubble. - * @param {!Event} e A mouse down or touch start event. - * @param {!Blockly.IBubble} bubble The bubble the event hit. - * @package - */ - handleBubbleStart(e: Event, bubble: Blockly.IBubble): void; - - /** - * Record the field that a gesture started on. - * @param {Blockly.Field} field The field the gesture started on. - * @package - */ - setStartField(field: Blockly.Field): void; - - /** - * Record the bubble that a gesture started on - * @param {Blockly.IBubble} bubble The bubble the gesture started on. - * @package - */ - setStartBubble(bubble: Blockly.IBubble): void; - - /** - * Record the block that a gesture started on, and set the target block - * appropriately. - * @param {Blockly.BlockSvg} block The block the gesture started on. - * @package - */ - setStartBlock(block: Blockly.BlockSvg): void; - - /** - * Whether this gesture is a drag of either a workspace or block. - * This function is called externally to block actions that cannot be taken - * mid-drag (e.g. using the keyboard to delete the selected blocks). - * @return {boolean} True if this gesture is a drag of a workspace or block. - * @package - */ - isDragging(): boolean; - - /** - * Whether this gesture has already been started. In theory every mouse down - * has a corresponding mouse up, but in reality it is possible to lose a - * mouse up, leaving an in-process gesture hanging. - * @return {boolean} Whether this gesture was a click on a workspace. - * @package - */ - hasStarted(): boolean; - - /** - * Get a list of the insertion markers that currently exist. Block drags have - * 0, 1, or 2 insertion markers. - * @return {!Array} A possibly empty list of insertion - * marker blocks. - * @package - */ - getInsertionMarkers(): Blockly.BlockSvg[]; - - /** - * Gets the current dragger if an item is being dragged. Null if nothing is - * being dragged. - * @return {!Blockly.WorkspaceDragger|!Blockly.BubbleDragger|!Blockly.IBlockDragger|null} - * The dragger that is currently in use or null if no drag is in progress. - */ - getCurrentDragger(): Blockly.WorkspaceDragger|Blockly.BubbleDragger|Blockly.IBlockDragger|any /*null*/; - } - -} - -declare module Blockly.Gesture { +declare module Gesture { /** * Is a drag or other gesture currently in progress on any workspace? @@ -7244,72 +1110,7 @@ declare module Blockly.Gesture { } -declare module Blockly { - - class Grid extends Grid__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Grid__Class { - - /** - * Class for a workspace's grid. - * @param {!SVGElement} pattern The grid's SVG pattern, created during - * injection. - * @param {!Object} options A dictionary of normalized options for the grid. - * See grid documentation: - * https://developers.google.com/blockly/guides/configure/web/grid - * @constructor - */ - constructor(pattern: SVGElement, options: Object); - - /** - * Dispose of this grid and unlink from the DOM. - * @package - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Whether blocks should snap to the grid, based on the initial configuration. - * @return {boolean} True if blocks should snap, false otherwise. - * @package - */ - shouldSnap(): boolean; - - /** - * Get the spacing of the grid points (in px). - * @return {number} The spacing of the grid points. - * @package - */ - getSpacing(): number; - - /** - * Get the ID of the pattern element, which should be randomized to avoid - * conflicts with other Blockly instances on the page. - * @return {string} The pattern ID. - * @package - */ - getPatternId(): string; - - /** - * Update the grid with a new scale. - * @param {number} scale The new workspace scale. - * @package - */ - update(scale: number): void; - - /** - * Move the grid to a new x and y position, and make sure that change is - * visible. - * @param {number} x The new x position of the grid (in px). - * @param {number} y The new y position of the grid (in px). - * @package - */ - moveTo(x: number, y: number): void; - } - -} - -declare module Blockly.Grid { +declare module Grid { /** * Create the DOM for the grid described by options. @@ -7323,380 +1124,11 @@ declare module Blockly.Grid { } -declare module Blockly { - - class Icon extends Icon__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Icon__Class { - - /** - * Class for an icon. - * @param {Blockly.BlockSvg} block The block associated with this icon. - * @constructor - * @abstract - */ - constructor(block: Blockly.BlockSvg); - - /** - * The block this icon is attached to. - * @type {Blockly.BlockSvg} - * @protected - */ - block_: Blockly.BlockSvg; - - /** - * The icon SVG group. - * @type {?SVGGElement} - */ - iconGroup_: SVGGElement; - - /** - * Does this icon get hidden when the block is collapsed. - */ - collapseHidden: any /*missing*/; - - /** - * Height and width of icons. - */ - SIZE: any /*missing*/; - - /** - * Bubble UI (if visible). - * @type {?Blockly.Bubble} - * @protected - */ - bubble_: Blockly.Bubble; - - /** - * Absolute coordinate of icon's center. - * @type {?Blockly.utils.Coordinate} - * @protected - */ - iconXY_: Blockly.utils.Coordinate; - - /** - * Create the icon on the block. - */ - createIcon(): void; - - /** - * Dispose of this icon. - */ - dispose(): void; - - /** - * Add or remove the UI indicating if this icon may be clicked or not. - */ - updateEditable(): void; - - /** - * Is the associated bubble visible? - * @return {boolean} True if the bubble is visible. - */ - isVisible(): boolean; - - /** - * Clicking on the icon toggles if the bubble is visible. - * @param {!Event} e Mouse click event. - * @protected - */ - iconClick_(e: Event): void; - - /** - * Change the colour of the associated bubble to match its block. - */ - applyColour(): void; - - /** - * Notification that the icon has moved. Update the arrow accordingly. - * @param {!Blockly.utils.Coordinate} xy Absolute location in workspace coordinates. - */ - setIconLocation(xy: Blockly.utils.Coordinate): void; - - /** - * Notification that the icon has moved, but we don't really know where. - * Recompute the icon's location from scratch. - */ - computeIconLocation(): void; - - /** - * Returns the center of the block's icon relative to the surface. - * @return {?Blockly.utils.Coordinate} Object with x and y properties in - * workspace coordinates. - */ - getIconLocation(): Blockly.utils.Coordinate; - - /** - * Get the size of the icon as used for rendering. - * This differs from the actual size of the icon, because it bulges slightly - * out of its row rather than increasing the height of its row. - * @return {!Blockly.utils.Size} Height and width. - */ - getCorrectedSize(): Blockly.utils.Size; - - /** - * Draw the icon. - * @param {!Element} group The icon group. - * @protected - */ - drawIcon_(group: Element): void; - - /** - * Show or hide the icon. - * @param {boolean} visible True if the icon should be visible. - */ - setVisible(visible: boolean): void; - } - -} -declare module Blockly { - - /** - * Inject a Blockly editor into the specified container element (usually a div). - * @param {Element|string} container Containing element, or its ID, - * or a CSS selector. - * @param {Blockly.BlocklyOptions=} opt_options Optional dictionary of options. - * @return {!Blockly.WorkspaceSvg} Newly created main workspace. - */ - function inject(container: Element|string, opt_options?: Blockly.BlocklyOptions): Blockly.WorkspaceSvg; - - /** - * Bumps the given object that has passed out of bounds. - * @param {!Blockly.WorkspaceSvg} workspace The workspace containing the object. - * @param {!Blockly.MetricsManager.ContainerRegion} scrollMetrics Scroll metrics - * in workspace coordinates. - * @param {!Blockly.IBoundedElement} object The object to bump. - * @return {boolean} True if block was bumped. - * @package - */ - function bumpObjectIntoBounds_(workspace: Blockly.WorkspaceSvg, scrollMetrics: Blockly.MetricsManager.ContainerRegion, object: Blockly.IBoundedElement): boolean; -} -declare module Blockly { - - class Input extends Input__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Input__Class { - - /** - * Class for an input with an optional field. - * @param {number} type The type of the input. - * @param {string} name Language-neutral identifier which may used to find this - * input again. - * @param {!Blockly.Block} block The block containing this input. - * @param {Blockly.Connection} connection Optional connection for this input. - * @constructor - */ - constructor(type: number, name: string, block: Blockly.Block, connection: Blockly.Connection); - - /** @type {number} */ - type: number; - - /** @type {string} */ - name: string; - - /** @type {Blockly.Connection} */ - connection: Blockly.Connection; - - /** @type {!Array} */ - fieldRow: Blockly.Field[]; - - /** - * Alignment of input's fields (left, right or centre). - * @type {number} - */ - align: number; - - /** - * Get the source block for this input. - * @return {?Blockly.Block} The source block, or null if there is none. - */ - getSourceBlock(): Blockly.Block; - - /** - * Add a field (or label from string), and all prefix and suffix fields, to the - * end of the input's field row. - * @param {string|!Blockly.Field} field Something to add as a field. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this field again. Should be unique to the host block. - * @return {!Blockly.Input} The input being append to (to allow chaining). - */ - appendField(field: string|Blockly.Field, opt_name?: string): Blockly.Input; - - /** - * Inserts a field (or label from string), and all prefix and suffix fields, at - * the location of the input's field row. - * @param {number} index The index at which to insert field. - * @param {string|!Blockly.Field} field Something to add as a field. - * @param {string=} opt_name Language-neutral identifier which may used to find - * this field again. Should be unique to the host block. - * @return {number} The index following the last inserted field. - */ - insertFieldAt(index: number, field: string|Blockly.Field, opt_name?: string): number; - - /** - * Remove a field from this input. - * @param {string} name The name of the field. - * @param {boolean=} opt_quiet True to prevent an error if field is not present. - * @return {boolean} True if operation succeeds, false if field is not present - * and opt_quiet is true. - * @throws {Error} if the field is not present and opt_quiet is false. - */ - removeField(name: string, opt_quiet?: boolean): boolean; - - /** - * Gets whether this input is visible or not. - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Sets whether this input is visible or not. - * Should only be used to collapse/uncollapse a block. - * @param {boolean} visible True if visible. - * @return {!Array} List of blocks to render. - * @package - */ - setVisible(visible: boolean): Blockly.BlockSvg[]; - - /** - * Mark all fields on this input as dirty. - * @package - */ - markDirty(): void; - - /** - * Change a connection's compatibility. - * @param {string|Array|null} check Compatible value type or - * list of value types. Null if all types are compatible. - * @return {!Blockly.Input} The input being modified (to allow chaining). - */ - setCheck(check: string|string[]|any /*null*/): Blockly.Input; - - /** - * Change the alignment of the connection's field(s). - * @param {number} align One of the values of Blockly.constants.ALIGN. - * In RTL mode directions are reversed, and ALIGN.RIGHT aligns to the left. - * @return {!Blockly.Input} The input being modified (to allow chaining). - */ - setAlign(align: number): Blockly.Input; - - /** - * Changes the connection's shadow block. - * @param {?Element} shadow DOM representation of a block or null. - * @return {!Blockly.Input} The input being modified (to allow chaining). - */ - setShadowDom(shadow: Element): Blockly.Input; - - /** - * Returns the XML representation of the connection's shadow block. - * @return {?Element} Shadow DOM representation of a block or null. - */ - getShadowDom(): Element; - - /** - * Initialize the fields on this input. - */ - init(): void; - - /** - * Sever all links to this input. - * @suppress {checkTypes} - */ - dispose(): void; - } - -} - - -declare module Blockly { - - /** - * Enum for the type of a connection or input. - * @enum {number} - */ - enum inputTypes { VALUE, STATEMENT, DUMMY } -} - - -declare module Blockly { - - class InsertionMarkerManager extends InsertionMarkerManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class InsertionMarkerManager__Class { - - /** - * Class that controls updates to connections during drags. It is primarily - * responsible for finding the closest eligible connection and highlighting or - * unhiglighting it as needed during a drag. - * @param {!Blockly.BlockSvg} block The top block in the stack being dragged. - * @constructor - */ - constructor(block: Blockly.BlockSvg); - - /** - * Sever all links from this object. - * @package - */ - dispose(): void; - - /** - * Update the available connections for the top block. These connections can - * change if a block is unplugged and the stack is healed. - * @package - */ - updateAvailableConnections(): void; - - /** - * Return whether the block would be deleted if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} True if the block would be deleted if dropped immediately. - * @package - */ - wouldDeleteBlock(): boolean; - - /** - * Return whether the block would be connected if dropped immediately, based on - * information from the most recent move event. - * @return {boolean} True if the block would be connected if dropped - * immediately. - * @package - */ - wouldConnectBlock(): boolean; - - /** - * Connect to the closest connection and render the results. - * This should be called at the end of a drag. - * @package - */ - applyConnections(): void; - - /** - * Update connections based on the most recent move location. - * @param {!Blockly.utils.Coordinate} dxy Position relative to drag start, - * in workspace units. - * @param {?Blockly.IDragTarget} dragTarget The drag target that the block is - * currently over. - * @package - */ - update(dxy: Blockly.utils.Coordinate, dragTarget: Blockly.IDragTarget): void; - - /** - * Get a list of the insertion markers that currently exist. Drags have 0, 1, - * or 2 insertion markers. - * @return {!Array} A possibly empty list of insertion - * marker blocks. - * @package - */ - getInsertionMarkers(): Blockly.BlockSvg[]; - } - -} - -declare module Blockly.InsertionMarkerManager { +declare module InsertionMarkerManager { /** * An enum describing different kinds of previews the InsertionMarkerManager @@ -7715,87 +1147,8 @@ declare module Blockly.InsertionMarkerManager { } -declare module Blockly { - class MarkerManager extends MarkerManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class MarkerManager__Class { - - /** - * Class to manage the multiple markers and the cursor on a workspace. - * @param {!Blockly.WorkspaceSvg} workspace The workspace for the marker manager. - * @constructor - * @package - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * Register the marker by adding it to the map of markers. - * @param {string} id A unique identifier for the marker. - * @param {!Blockly.Marker} marker The marker to register. - */ - registerMarker(id: string, marker: Blockly.Marker): void; - - /** - * Unregister the marker by removing it from the map of markers. - * @param {string} id The ID of the marker to unregister. - */ - unregisterMarker(id: string): void; - - /** - * Get the cursor for the workspace. - * @return {?Blockly.Cursor} The cursor for this workspace. - */ - getCursor(): Blockly.Cursor; - - /** - * Get a single marker that corresponds to the given ID. - * @param {string} id A unique identifier for the marker. - * @return {?Blockly.Marker} The marker that corresponds to the given ID, - * or null if none exists. - */ - getMarker(id: string): Blockly.Marker; - - /** - * Sets the cursor and initializes the drawer for use with keyboard navigation. - * @param {Blockly.Cursor} cursor The cursor used to move around this workspace. - */ - setCursor(cursor: Blockly.Cursor): void; - - /** - * Add the cursor SVG to this workspace SVG group. - * @param {?SVGElement} cursorSvg The SVG root of the cursor to be added to the - * workspace SVG group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this workspaces SVG group. - * @param {?SVGElement} markerSvg The SVG root of the marker to be added to the - * workspace SVG group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Redraw the attached cursor SVG if needed. - * @package - */ - updateMarkers(): void; - - /** - * Dispose of the marker manager. - * Go through and delete all markers associated with this marker manager. - * @suppress {checkTypes} - * @package - */ - dispose(): void; - } - -} - -declare module Blockly.MarkerManager { +declare module MarkerManager { /** * The name of the local marker. @@ -7806,427 +1159,9 @@ declare module Blockly.MarkerManager { } -declare module Blockly { - - class Menu extends Menu__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Menu__Class { - - /** - * A basic menu class. - * @constructor - */ - constructor(); - - /** - * Coordinates of the mousedown event that caused this menu to open. Used to - * prevent the consequent mouseup event due to a simple click from activating - * a menu item immediately. - * @type {?Blockly.utils.Coordinate} - * @package - */ - openingCoords: Blockly.utils.Coordinate; - - /** - * Add a new menu item to the bottom of this menu. - * @param {!Blockly.MenuItem} menuItem Menu item to append. - */ - addChild(menuItem: Blockly.MenuItem): void; - - /** - * Creates the menu DOM. - * @param {!Element} container Element upon which to append this menu. - */ - render(container: Element): void; - - /** - * Gets the menu's element. - * @return {?Element} The DOM element. - * @package - */ - getElement(): Element; - - /** - * Focus the menu element. - * @package - */ - focus(): void; - - /** - * Set the menu accessibility role. - * @param {!Blockly.utils.aria.Role} roleName role name. - * @package - */ - setRole(roleName: Blockly.utils.aria.Role): void; - - /** - * Dispose of this menu. - */ - dispose(): void; - - /** - * Highlights the given menu item, or clears highlighting if null. - * @param {?Blockly.MenuItem} item Item to highlight, or null. - * @package - */ - setHighlighted(item: Blockly.MenuItem): void; - - /** - * Highlights the next highlightable item (or the first if nothing is currently - * highlighted). - * @package - */ - highlightNext(): void; - - /** - * Highlights the previous highlightable item (or the last if nothing is - * currently highlighted). - * @package - */ - highlightPrevious(): void; - - /** - * Get the size of a rendered menu. - * @return {!Blockly.utils.Size} Object with width and height properties. - * @package - */ - getSize(): Blockly.utils.Size; - } - -} -declare module Blockly { - - class MenuItem extends MenuItem__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class MenuItem__Class { - - /** - * Class representing an item in a menu. - * - * @param {string|!HTMLElement} content Text caption to display as the content - * of the item, or a HTML element to display. - * @param {string=} opt_value Data/model associated with the menu item. - * @constructor - */ - constructor(content: string|HTMLElement, opt_value?: string); - - /** - * Creates the menuitem's DOM. - * @return {!Element} Completed DOM. - */ - createDom(): Element; - - /** - * Dispose of this menu item. - */ - dispose(): void; - - /** - * Gets the menu item's element. - * @return {?Element} The DOM element. - * @package - */ - getElement(): Element; - - /** - * Gets the unique ID for this menu item. - * @return {string} Unique component ID. - * @package - */ - getId(): string; - - /** - * Gets the value associated with the menu item. - * @return {*} value Value associated with the menu item. - * @package - */ - getValue(): any; - - /** - * Set menu item's rendering direction. - * @param {boolean} rtl True if RTL, false if LTR. - * @package - */ - setRightToLeft(rtl: boolean): void; - - /** - * Set the menu item's accessibility role. - * @param {!Blockly.utils.aria.Role} roleName Role name. - * @package - */ - setRole(roleName: Blockly.utils.aria.Role): void; - - /** - * Sets the menu item to be checkable or not. Set to true for menu items - * that represent checkable options. - * @param {boolean} checkable Whether the menu item is checkable. - * @package - */ - setCheckable(checkable: boolean): void; - - /** - * Checks or unchecks the component. - * @param {boolean} checked Whether to check or uncheck the component. - * @package - */ - setChecked(checked: boolean): void; - - /** - * Highlights or unhighlights the component. - * @param {boolean} highlight Whether to highlight or unhighlight the component. - * @package - */ - setHighlighted(highlight: boolean): void; - - /** - * Returns true if the menu item is enabled, false otherwise. - * @return {boolean} Whether the menu item is enabled. - * @package - */ - isEnabled(): boolean; - - /** - * Enables or disables the menu item. - * @param {boolean} enabled Whether to enable or disable the menu item. - * @package - */ - setEnabled(enabled: boolean): void; - - /** - * Performs the appropriate action when the menu item is activated - * by the user. - * @package - */ - performAction(): void; - - /** - * Set the handler that's called when the menu item is activated by the user. - * `obj` will be used as the 'this' object in the function when called. - * @param {function(!Blockly.MenuItem)} fn The handler. - * @param {!Object} obj Used as the 'this' object in fn when called. - * @package - */ - onAction(fn: { (_0: Blockly.MenuItem): any /*missing*/ }, obj: Object): void; - } - -} - - -declare module Blockly { - - class MetricsManager extends MetricsManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class MetricsManager__Class implements Blockly.IMetricsManager { - - /** - * The manager for all workspace metrics calculations. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to calculate metrics - * for. - * @implements {Blockly.IMetricsManager} - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * The workspace to calculate metrics for. - * @type {!Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * Gets the dimensions of the given workspace component, in pixel coordinates. - * @param {?Blockly.IToolbox|?Blockly.IFlyout} elem The element to get the - * dimensions of, or null. It should be a toolbox or flyout, and should - * implement getWidth() and getHeight(). - * @return {!Blockly.utils.Size} An object containing width and height - * attributes, which will both be zero if elem did not exist. - * @protected - */ - getDimensionsPx_(elem: Blockly.IToolbox|Blockly.IFlyout): Blockly.utils.Size; - - /** - * Gets the width and the height of the flyout on the workspace in pixel - * coordinates. Returns 0 for the width and height if the workspace has a - * category toolbox instead of a simple toolbox. - * @param {boolean=} opt_own Whether to only return the workspace's own flyout. - * @return {!Blockly.MetricsManager.ToolboxMetrics} The width and height of the - * flyout. - * @public - */ - getFlyoutMetrics(opt_own?: boolean): Blockly.MetricsManager.ToolboxMetrics; - - /** - * Gets the width, height and position of the toolbox on the workspace in pixel - * coordinates. Returns 0 for the width and height if the workspace has a simple - * toolbox instead of a category toolbox. To get the width and height of a - * simple toolbox @see {@link getFlyoutMetrics}. - * @return {!Blockly.MetricsManager.ToolboxMetrics} The object with the width, - * height and position of the toolbox. - * @public - */ - getToolboxMetrics(): Blockly.MetricsManager.ToolboxMetrics; - - /** - * Gets the width and height of the workspace's parent SVG element in pixel - * coordinates. This area includes the toolbox and the visible workspace area. - * @return {!Blockly.utils.Size} The width and height of the workspace's parent - * SVG element. - * @public - */ - getSvgMetrics(): Blockly.utils.Size; - - /** - * Gets the absolute left and absolute top in pixel coordinates. - * This is where the visible workspace starts in relation to the SVG container. - * @return {!Blockly.MetricsManager.AbsoluteMetrics} The absolute metrics for - * the workspace. - * @public - */ - getAbsoluteMetrics(): Blockly.MetricsManager.AbsoluteMetrics; - - /** - * Gets the metrics for the visible workspace in either pixel or workspace - * coordinates. The visible workspace does not include the toolbox or flyout. - * @param {boolean=} opt_getWorkspaceCoordinates True to get the view metrics in - * workspace coordinates, false to get them in pixel coordinates. - * @return {!Blockly.MetricsManager.ContainerRegion} The width, height, top and - * left of the viewport in either workspace coordinates or pixel - * coordinates. - * @public - */ - getViewMetrics(opt_getWorkspaceCoordinates?: boolean): Blockly.MetricsManager.ContainerRegion; - - /** - * Gets content metrics in either pixel or workspace coordinates. - * The content area is a rectangle around all the top bounded elements on the - * workspace (workspace comments and blocks). - * @param {boolean=} opt_getWorkspaceCoordinates True to get the content metrics - * in workspace coordinates, false to get them in pixel coordinates. - * @return {!Blockly.MetricsManager.ContainerRegion} The - * metrics for the content container. - * @public - */ - getContentMetrics(opt_getWorkspaceCoordinates?: boolean): Blockly.MetricsManager.ContainerRegion; - - /** - * Returns whether the scroll area has fixed edges. - * @return {boolean} Whether the scroll area has fixed edges. - * @package - */ - hasFixedEdges(): boolean; - - /** - * Computes the fixed edges of the scroll area. - * @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view - * metrics if they have been previously computed. Passing in null may cause - * the view metrics to be computed again, if it is needed. - * @return {!Blockly.MetricsManager.FixedEdges} The fixed edges of the scroll - * area. - * @protected - */ - getComputedFixedEdges_(opt_viewMetrics?: Blockly.MetricsManager.ContainerRegion): Blockly.MetricsManager.FixedEdges; - - /** - * Returns the content area with added padding. - * @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The view - * metrics. - * @param {!Blockly.MetricsManager.ContainerRegion} contentMetrics The content - * metrics. - * @return {{top: number, bottom: number, left: number, right: number}} The - * padded content area. - * @protected - */ - getPaddedContent_(viewMetrics: Blockly.MetricsManager.ContainerRegion, contentMetrics: Blockly.MetricsManager.ContainerRegion): { top: number; bottom: number; left: number; right: number }; - - /** - * Returns the metrics for the scroll area of the workspace. - * @param {boolean=} opt_getWorkspaceCoordinates True to get the scroll metrics - * in workspace coordinates, false to get them in pixel coordinates. - * @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view - * metrics if they have been previously computed. Passing in null may cause - * the view metrics to be computed again, if it is needed. - * @param {!Blockly.MetricsManager.ContainerRegion=} opt_contentMetrics The - * content metrics if they have been previously computed. Passing in null - * may cause the content metrics to be computed again, if it is needed. - * @return {!Blockly.MetricsManager.ContainerRegion} The metrics for the scroll - * container. - */ - getScrollMetrics(opt_getWorkspaceCoordinates?: boolean, opt_viewMetrics?: Blockly.MetricsManager.ContainerRegion, opt_contentMetrics?: Blockly.MetricsManager.ContainerRegion): Blockly.MetricsManager.ContainerRegion; - - /** - * Returns common metrics used by UI elements. - * @return {!Blockly.MetricsManager.UiMetrics} The UI metrics. - */ - getUiMetrics(): Blockly.MetricsManager.UiMetrics; - - /** - * Returns an object with all the metrics required to size scrollbars for a - * top level workspace. The following properties are computed: - * Coordinate system: pixel coordinates, -left, -up, +right, +down - * .viewHeight: Height of the visible portion of the workspace. - * .viewWidth: Width of the visible portion of the workspace. - * .contentHeight: Height of the content. - * .contentWidth: Width of the content. - * .scrollHeight: Height of the scroll area. - * .scrollWidth: Width of the scroll area. - * .svgHeight: Height of the Blockly div (the view + the toolbox, - * simple or otherwise), - * .svgWidth: Width of the Blockly div (the view + the toolbox, - * simple or otherwise), - * .viewTop: Top-edge of the visible portion of the workspace, relative to - * the workspace origin. - * .viewLeft: Left-edge of the visible portion of the workspace, relative to - * the workspace origin. - * .contentTop: Top-edge of the content, relative to the workspace origin. - * .contentLeft: Left-edge of the content relative to the workspace origin. - * .scrollTop: Top-edge of the scroll area, relative to the workspace origin. - * .scrollLeft: Left-edge of the scroll area relative to the workspace origin. - * .absoluteTop: Top-edge of the visible portion of the workspace, relative - * to the blocklyDiv. - * .absoluteLeft: Left-edge of the visible portion of the workspace, relative - * to the blocklyDiv. - * .toolboxWidth: Width of the toolbox, if it exists. Otherwise zero. - * .toolboxHeight: Height of the toolbox, if it exists. Otherwise zero. - * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. - * .flyoutHeight: Height of the flyout if it is always open. Otherwise zero. - * .toolboxPosition: Top, bottom, left or right. Use TOOLBOX_AT constants to - * compare. - * @return {!Blockly.utils.Metrics} Contains size and position metrics of a top - * level workspace. - * @public - */ - getMetrics(): Blockly.utils.Metrics; - } - - - class FlyoutMetricsManager extends FlyoutMetricsManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FlyoutMetricsManager__Class extends Blockly.MetricsManager__Class { - - /** - * Calculates metrics for a flyout's workspace. - * The metrics are mainly used to size scrollbars for the flyout. - * @param {!Blockly.WorkspaceSvg} workspace The flyout's workspace. - * @param {!Blockly.IFlyout} flyout The flyout. - * @extends {Blockly.MetricsManager} - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, flyout: Blockly.IFlyout); - - /** - * The flyout that owns the workspace to calculate metrics for. - * @type {!Blockly.IFlyout} - * @protected - */ - flyout_: Blockly.IFlyout; - } - -} - -declare module Blockly.MetricsManager { +declare module MetricsManager { /** * Describes the width, height and location of the toolbox on the main @@ -8234,13 +1169,13 @@ declare module Blockly.MetricsManager { * @typedef {{ * width: number, * height: number, - * position: !Blockly.utils.toolbox.Position + * position: !toolboxUtils.Position * }} */ interface ToolboxMetrics { width: number; height: number; - position: Blockly.utils.toolbox.Position + position: toolboxUtils.Position } /** @@ -8290,175 +1225,42 @@ declare module Blockly.MetricsManager { /** * Common metrics used for UI elements. * @typedef {{ - * viewMetrics: !Blockly.MetricsManager.ContainerRegion, - * absoluteMetrics: !Blockly.MetricsManager.AbsoluteMetrics, - * toolboxMetrics: !Blockly.MetricsManager.ToolboxMetrics + * viewMetrics: !MetricsManager.ContainerRegion, + * absoluteMetrics: !MetricsManager.AbsoluteMetrics, + * toolboxMetrics: !MetricsManager.ToolboxMetrics * }} */ interface UiMetrics { - viewMetrics: Blockly.MetricsManager.ContainerRegion; - absoluteMetrics: Blockly.MetricsManager.AbsoluteMetrics; - toolboxMetrics: Blockly.MetricsManager.ToolboxMetrics + viewMetrics: MetricsManager.ContainerRegion; + absoluteMetrics: MetricsManager.AbsoluteMetrics; + toolboxMetrics: MetricsManager.ToolboxMetrics } } -declare module Blockly { - - class Mutator extends Mutator__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Mutator__Class extends Blockly.Icon__Class { - - /** - * Class for a mutator dialog. - * @param {!Array} quarkNames List of names of sub-blocks for flyout. - * @extends {Blockly.Icon} - * @constructor - */ - constructor(quarkNames: string[]); - - /** - * Set the block this mutator is associated with. - * @param {!Blockly.BlockSvg} block The block associated with this mutator. - * @package - */ - setBlock(block: Blockly.BlockSvg): void; - - /** - * Returns the workspace inside this mutator icon's bubble. - * @return {?Blockly.WorkspaceSvg} The workspace inside this mutator icon's - * bubble or null if the mutator isn't open. - * @package - */ - getWorkspace(): Blockly.WorkspaceSvg; - - /** - * Draw the mutator icon. - * @param {!Element} group The icon group. - * @protected - */ - drawIcon_(group: Element): void; - - /** - * Add or remove the UI indicating if this icon may be clicked or not. - */ - updateEditable(): void; - - /** - * Show or hide the mutator bubble. - * @param {boolean} visible True if the bubble should be visible. - */ - setVisible(visible: boolean): void; - - /** - * Dispose of this mutator. - */ - dispose(): void; - - /** - * Update the styles on all blocks in the mutator. - * @public - */ - updateBlockStyle(): void; - } - -} - -declare module Blockly.Mutator { +declare module Mutator { /** * Reconnect an block to a mutated input. - * @param {Blockly.Connection} connectionChild Connection on child block. - * @param {!Blockly.Block} block Parent block. + * @param {Connection} connectionChild Connection on child block. + * @param {!Block} block Parent block. * @param {string} inputName Name of input on parent block. * @return {boolean} True iff a reconnection was made, false otherwise. */ - function reconnect(connectionChild: Blockly.Connection, block: Blockly.Block, inputName: string): boolean; + function reconnect(connectionChild: Connection, block: Block, inputName: string): boolean; /** * Get the parent workspace of a workspace that is inside a mutator, taking into * account whether it is a flyout. - * @param {Blockly.Workspace} workspace The workspace that is inside a mutator. - * @return {?Blockly.Workspace} The mutator's parent workspace or null. + * @param {Workspace} workspace The workspace that is inside a mutator. + * @return {?Workspace} The mutator's parent workspace or null. * @public */ - function findParentWs(workspace: Blockly.Workspace): Blockly.Workspace; + function findParentWs(workspace: Workspace): Workspace; } -declare module Blockly { - - class Names extends Names__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Names__Class { - - /** - * Class for a database of entity names (variables, procedures, etc). - * @param {string} reservedWords A comma-separated string of words that are - * illegal for use as names in a language (e.g. 'new,if,this,...'). - * @param {string=} opt_variablePrefix Some languages need a '$' or a namespace - * before all variable names (but not procedure names). - * @constructor - */ - constructor(reservedWords: string, opt_variablePrefix?: string); - - /** - * Empty the database and start from scratch. The reserved words are kept. - */ - reset(): void; - - /** - * Set the variable map that maps from variable name to variable object. - * @param {!Blockly.VariableMap} map The map to track. - */ - setVariableMap(map: Blockly.VariableMap): void; - - /** - * Generate names for user variables, but only ones that are being used. - * @param {!Blockly.Workspace} workspace Workspace to generate variables from. - */ - populateVariables(workspace: Blockly.Workspace): void; - - /** - * Generate names for procedures. - * @param {!Blockly.Workspace} workspace Workspace to generate procedures from. - */ - populateProcedures(workspace: Blockly.Workspace): void; - - /** - * Convert a Blockly entity name to a legal exportable entity name. - * @param {string} nameOrId The Blockly entity name (no constraints) or - * variable ID. - * @param {string} realm The realm of entity in Blockly - * ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...). - * @return {string} An entity name that is legal in the exported language. - */ - getName(nameOrId: string, realm: string): string; - - /** - * Return a list of all known user-created names in a specified realm. - * @param {string} realm The realm of entity in Blockly - * ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...). - * @return {!Array} A list of Blockly entity names (no constraints). - */ - getUserNames(realm: string): string[]; - - /** - * Convert a Blockly entity name to a legal exportable entity name. - * Ensure that this is a new name not overlapping any previously defined name. - * Also check against list of reserved words for the current language and - * ensure name doesn't collide. - * @param {string} name The Blockly entity name (no constraints). - * @param {string} realm The realm of entity in Blockly - * ('VARIABLE', 'PROCEDURE', 'DEVELOPER_VARIABLE', etc...). - * @return {string} An entity name that is legal in the exported language. - */ - getDistinctName(name: string, realm: string): string; - } - -} - -declare module Blockly.Names { +declare module Names { /** * Constant to separate developer variable names from user-defined variable @@ -8480,135 +1282,7 @@ declare module Blockly.Names { } -declare module Blockly { - - class Options extends Options__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Options__Class { - - /** - * Parse the user-specified options, using reasonable defaults where behaviour - * is unspecified. - * @param {!Blockly.BlocklyOptions} options Dictionary of options. - * Specification: https://developers.google.com/blockly/guides/get-started/web#configuration - * @constructor - */ - constructor(options: Blockly.BlocklyOptions); - - /** @type {boolean} */ - RTL: boolean; - - /** @type {boolean} */ - oneBasedIndex: boolean; - - /** @type {boolean} */ - collapse: boolean; - - /** @type {boolean} */ - comments: boolean; - - /** @type {boolean} */ - disable: boolean; - - /** @type {boolean} */ - readOnly: boolean; - - /** @type {number} */ - maxBlocks: number; - - /** @type {?Object} */ - maxInstances: { [key: string]: number }; - - /** @type {string} */ - pathToMedia: string; - - /** @type {boolean} */ - hasCategories: boolean; - - /** @type {!Blockly.Options.MoveOptions} */ - moveOptions: Blockly.Options.MoveOptions; - - /** @deprecated January 2019 */ - hasScrollbars: any /*missing*/; - - /** @type {boolean} */ - hasTrashcan: boolean; - - /** @type {number} */ - maxTrashcanContents: number; - - /** @type {boolean} */ - hasSounds: boolean; - - /** @type {boolean} */ - hasCss: boolean; - - /** @type {boolean} */ - horizontalLayout: boolean; - - /** @type {?Blockly.utils.toolbox.ToolboxInfo} */ - languageTree: Blockly.utils.toolbox.ToolboxInfo; - - /** @type {!Blockly.Options.GridOptions} */ - gridOptions: Blockly.Options.GridOptions; - - /** @type {!Blockly.Options.ZoomOptions} */ - zoomOptions: Blockly.Options.ZoomOptions; - - /** @type {!Blockly.utils.toolbox.Position} */ - toolboxPosition: Blockly.utils.toolbox.Position; - - /** @type {!Blockly.Theme} */ - theme: Blockly.Theme; - - /** @type {string} */ - renderer: string; - - /** @type {?Object} */ - rendererOverrides: Object; - - /** - * The SVG element for the grid pattern. - * Created during injection. - * @type {?SVGElement} - */ - gridPattern: SVGElement; - - /** - * The parent of the current workspace, or null if there is no parent - * workspace. We can assert that this is of type WorkspaceSvg as opposed to - * Workspace as this is only used in a rendered workspace. - * @type {Blockly.WorkspaceSvg} - */ - parentWorkspace: Blockly.WorkspaceSvg; - - /** - * Map of plugin type to name of registered plugin or plugin class. - * @type {!Object} - */ - plugins: any /*missing*/; - - /** - * If set, sets the translation of the workspace to match the scrollbars. - * @param {!{x:number,y:number}} xyRatio Contains an x and/or y property which - * is a float between 0 and 1 specifying the degree of scrolling. - * @return {void} - */ - setMetrics(xyRatio: { x: number; y: number }): void; - - /** - * Return an object with the metrics required to size the workspace. - * @return {!Blockly.utils.Metrics} Contains size and position metrics. - */ - getMetrics(): Blockly.utils.Metrics; - } - - - interface BlocklyOptions { - } -} - -declare module Blockly.Options { +declare module Options { /** * Grid Options. @@ -8630,13 +1304,13 @@ declare module Blockly.Options { * Move Options. * @typedef {{ * drag: boolean, - * scrollbars: (boolean | !Blockly.Options.ScrollbarOptions), + * scrollbars: (boolean | !Options.ScrollbarOptions), * wheel: boolean * }} */ interface MoveOptions { drag: boolean; - scrollbars: boolean|Blockly.Options.ScrollbarOptions; + scrollbars: boolean|Options.ScrollbarOptions; wheel: boolean } @@ -8673,544 +1347,58 @@ declare module Blockly.Options { startScale: number; wheel: boolean } - - /** - * Parse the provided toolbox tree into a consistent DOM format. - * @param {?Node|?string} toolboxDef DOM tree of blocks, or text representation - * of same. - * @return {?Node} DOM tree of blocks, or null. - * @deprecated Use Blockly.utils.toolbox.parseToolboxTree. (2020 September 28) - */ - function parseToolboxTree(toolboxDef: Node|string): Node; } -declare module Blockly.uiPosition { + + +declare module Type { + + /** @type {!Type} */ + var CONNECTION_CHECKER: Type; + + /** @type {!Type} */ + var CURSOR: Type; + + /** @type {!Type} */ + var EVENT: Type; + + /** @type {!Type} */ + var FIELD: Type; + + /** @type {!Type} */ + var RENDERER: Type; + + /** @type {!Type} */ + var TOOLBOX: Type; + + /** @type {!Type} */ + var THEME: Type; + + /** @type {!Type} */ + var TOOLBOX_ITEM: Type; + + /** @type {!Type} */ + var FLYOUTS_VERTICAL_TOOLBOX: Type; + + /** @type {!Type} */ + var FLYOUTS_HORIZONTAL_TOOLBOX: Type; + + /** @type {!Type} */ + var METRICS_MANAGER: Type; + + /** @type {!Type} */ + var BLOCK_DRAGGER: Type; /** - * Enum for vertical positioning. - * @enum {number} + * @type {!Type} * @package */ - enum verticalPosition { TOP, BOTTOM } - - /** - * Enum for horizontal positioning. - * @enum {number} - * @package - */ - enum horizontalPosition { LEFT, RIGHT } - - /** - * An object defining a horizontal and vertical positioning. - * @typedef {{ - * horizontal: !Blockly.uiPosition.horizontalPosition, - * vertical: !Blockly.uiPosition.verticalPosition - * }} - * @package - */ - interface Position { - horizontal: Blockly.uiPosition.horizontalPosition; - vertical: Blockly.uiPosition.verticalPosition - } - - /** - * Enum for bump rules to use for dealing with collisions. - * @enum {number} - * @package - */ - enum bumpDirection { UP, DOWN } - - /** - * Returns a rectangle representing reasonable position for where to place a UI - * element of the specified size given the restraints and locations of the - * scrollbars. This method does not take into account any already placed UI - * elements. - * @param {!Blockly.uiPosition.Position} position The starting - * horizontal and vertical position. - * @param {!Blockly.utils.Size} size the size of the UI element to get a start - * position for. - * @param {number} horizontalPadding The horizontal padding to use. - * @param {number} verticalPadding The vertical padding to use. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace UI metrics. - * @param {!Blockly.WorkspaceSvg} workspace The workspace. - * @return {!Blockly.utils.Rect} The suggested start position. - * @package - */ - function getStartPositionRect(position: Blockly.uiPosition.Position, size: Blockly.utils.Size, horizontalPadding: number, verticalPadding: number, metrics: Blockly.MetricsManager.UiMetrics, workspace: Blockly.WorkspaceSvg): Blockly.utils.Rect; - - /** - * Returns a corner position that is on the opposite side of the workspace from - * the toolbox. - * If in horizontal orientation, defaults to the bottom corner. If in vertical - * orientation, defaults to the right corner. - * @param {!Blockly.WorkspaceSvg} workspace The workspace. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics. - * @return {!Blockly.uiPosition.Position} The suggested corner position. - * @package - */ - function getCornerOppositeToolbox(workspace: Blockly.WorkspaceSvg, metrics: Blockly.MetricsManager.UiMetrics): Blockly.uiPosition.Position; - - /** - * Returns a position Rect based on a starting position that is bumped - * so that it doesn't intersect with any of the provided savedPositions. This - * method does not check that the bumped position is still within bounds. - * @param {!Blockly.utils.Rect} startRect The starting position to use. - * @param {number} margin The margin to use between elements when bumping. - * @param {!Blockly.uiPosition.bumpDirection} bumpDirection The direction - * to bump if there is a collision with an existing UI element. - * @param {!Array} savedPositions List of rectangles that - * represent the positions of UI elements already placed. - * @return {!Blockly.utils.Rect} The suggested position rectangle. - * @package - */ - function bumpPositionRect(startRect: Blockly.utils.Rect, margin: number, bumpDirection: Blockly.uiPosition.bumpDirection, savedPositions: Blockly.utils.Rect[]): Blockly.utils.Rect; + var SERIALIZER: Type; } -declare module Blockly.Procedures { - - /** - * Constant to separate procedure names from variables and generated functions - * when running generators. - * @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME - */ - var NAME_TYPE: any /*missing*/; - - /** - * The default argument for a procedures_mutatorarg block. - * @type {string} - */ - var DEFAULT_ARG: string; - - /** - * Procedure block type. - * @typedef {{ - * getProcedureCall: function():string, - * renameProcedure: function(string,string), - * getProcedureDef: function():!Array - * }} - */ - interface ProcedureBlock { - getProcedureCall: { (): string }; - renameProcedure: { (_0: string, _1: string): any /*missing*/ }; - getProcedureDef: { (): any[] } - } - - /** - * Find all user-created procedure definitions in a workspace. - * @param {!Blockly.Workspace} root Root workspace. - * @return {!Array>} Pair of arrays, the - * first contains procedures without return variables, the second with. - * Each procedure is defined by a three-element list of name, parameter - * list, and return value boolean. - */ - function allProcedures(root: Blockly.Workspace): any[][][]; - - /** - * Ensure two identically-named procedures don't exist. - * Take the proposed procedure name, and return a legal name i.e. one that - * is not empty and doesn't collide with other procedures. - * @param {string} name Proposed procedure name. - * @param {!Blockly.Block} block Block to disambiguate. - * @return {string} Non-colliding name. - */ - function findLegalName(name: string, block: Blockly.Block): string; - - /** - * Return if the given name is already a procedure name. - * @param {string} name The questionable name. - * @param {!Blockly.Workspace} workspace The workspace to scan for collisions. - * @param {Blockly.Block=} opt_exclude Optional block to exclude from - * comparisons (one doesn't want to collide with oneself). - * @return {boolean} True if the name is used, otherwise return false. - */ - function isNameUsed(name: string, workspace: Blockly.Workspace, opt_exclude?: Blockly.Block): boolean; - - /** - * Rename a procedure. Called by the editable field. - * @param {string} name The proposed new name. - * @return {string} The accepted name. - * @this {Blockly.Field} - */ - function rename(name: string): string; - - /** - * Construct the blocks required by the flyout for the procedure category. - * @param {!Blockly.Workspace} workspace The workspace containing procedures. - * @return {!Array} Array of XML block elements. - */ - function flyoutCategory(workspace: Blockly.Workspace): Element[]; - - /** - * Listens for when a procedure mutator is opened. Then it triggers a flyout - * update and adds a mutator change listener to the mutator workspace. - * @param {!Blockly.Events.Abstract} e The event that triggered this listener. - * @package - */ - function mutatorOpenListener(e: Blockly.Events.Abstract): void; - - /** - * Find all the callers of a named procedure. - * @param {string} name Name of procedure. - * @param {!Blockly.Workspace} workspace The workspace to find callers in. - * @return {!Array} Array of caller blocks. - */ - function getCallers(name: string, workspace: Blockly.Workspace): Blockly.Block[]; - - /** - * When a procedure definition changes its parameters, find and edit all its - * callers. - * @param {!Blockly.Block} defBlock Procedure definition block. - */ - function mutateCallers(defBlock: Blockly.Block): void; - - /** - * Find the definition block for the named procedure. - * @param {string} name Name of procedure. - * @param {!Blockly.Workspace} workspace The workspace to search. - * @return {?Blockly.Block} The procedure definition block, or null not found. - */ - function getDefinition(name: string, workspace: Blockly.Workspace): Blockly.Block; -} - - -declare module Blockly.registry { - - class Type extends Type__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Type__Class { - - /** - * A name with the type of the element stored in the generic. - * @param {string} name The name of the registry type. - * @constructor - * @template T - */ - constructor(name: string); - } - - - /** - * A map of maps. With the keys being the type and name of the class we are - * registering and the value being the constructor function. - * e.g. {'field': {'field_angle': Blockly.FieldAngle}} - * - * @type {Object>} - */ - var typeMap_: any /*missing*/; - - /** - * The string used to register the default class for a type of plugin. - * @type {string} - */ - var DEFAULT: string; - - /** - * Registers a class based on a type and name. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Field, Renderer) - * @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_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 - */ - function register(type: string|Blockly.registry.Type, name: string, registryItem: { (_0: any[]): any /*missing*/ }|Object, opt_allowOverrides?: boolean): void; - - /** - * Unregisters the registry item with the given type and name. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Field, Renderer) - * @param {string} name The plugin's name. (Ex. field_angle, geras) - * @template T - */ - function unregister(type: string|Blockly.registry.Type, name: string): void; - - /** - * Gets the registry item for the given name and type. This can be either a - * class or an object. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Field, Renderer) - * @param {string} name The plugin's name. (Ex. field_angle, geras) - * @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we - * are unable to find the plugin. - * @return {?function(new:T, ...?)|Object} The class or object with the given - * name and type or null if none exists. - * @template T - */ - function getItem_(type: string|Blockly.registry.Type, name: string, opt_throwIfMissing?: boolean): { (_0: any[]): any /*missing*/ }|Object; - - /** - * Returns whether or not the registry contains an item with the given type and - * name. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Field, Renderer) - * @param {string} name The plugin's name. (Ex. field_angle, geras) - * @return {boolean} True if the registry has an item with the given type and - * name, false otherwise. - * @template T - */ - function hasItem(type: string|Blockly.registry.Type, name: string): boolean; - - /** - * Gets the class for the given name and type. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Field, Renderer) - * @param {string} name The plugin's name. (Ex. field_angle, geras) - * @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we - * are unable to find the plugin. - * @return {?function(new:T, ...?)} The class with the given name and type or - * null if none exists. - * @template T - */ - function getClass(type: string|Blockly.registry.Type, name: string, opt_throwIfMissing?: boolean): { (_0: any[]): any /*missing*/ }; - - /** - * Gets the object for the given name and type. - * @param {string|!Blockly.registry.Type} type The type of the plugin. - * (e.g. Category) - * @param {string} name The plugin's name. (Ex. logic_category) - * @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we - * are unable to find the object. - * @return {?T} The object with the given name and type or null if none exists. - * @template T - */ - function getObject(type: string|Blockly.registry.Type, name: string, opt_throwIfMissing?: boolean): T; - - /** - * Gets the class from Blockly options for the given type. - * This is used for plugins that override a built in feature. (e.g. Toolbox) - * @param {!Blockly.registry.Type} type The type of the plugin. - * @param {!Blockly.Options} options The option object to check for the given - * plugin. - * @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we - * are unable to find the plugin. - * @return {?function(new:T, ...?)} The class for the plugin. - * @template T - */ - function getClassFromOptions(type: Blockly.registry.Type, options: Blockly.Options, opt_throwIfMissing?: boolean): { (_0: any[]): any /*missing*/ }; -} - -declare module Blockly.registry.Type { - - /** @type {!Blockly.registry.Type} */ - var CONNECTION_CHECKER: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var CURSOR: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var EVENT: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var FIELD: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var RENDERER: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var TOOLBOX: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var THEME: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var TOOLBOX_ITEM: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var FLYOUTS_VERTICAL_TOOLBOX: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var FLYOUTS_HORIZONTAL_TOOLBOX: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var METRICS_MANAGER: Blockly.registry.Type; - - /** @type {!Blockly.registry.Type} */ - var BLOCK_DRAGGER: Blockly.registry.Type; -} - - -declare module Blockly { - - class RenderedConnection extends RenderedConnection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class RenderedConnection__Class extends Blockly.Connection__Class { - - /** - * Class for a connection between blocks that may be rendered on screen. - * @param {!Blockly.BlockSvg} source The block establishing this connection. - * @param {number} type The type of the connection. - * @extends {Blockly.Connection} - * @constructor - */ - constructor(source: Blockly.BlockSvg, type: number); - - /** - * Connection this connection connects to. Null if not connected. - * @type {Blockly.RenderedConnection} - */ - targetConnection: Blockly.RenderedConnection; - - /** - * Returns the distance between this connection and another connection in - * workspace units. - * @param {!Blockly.Connection} otherConnection The other connection to measure - * the distance to. - * @return {number} The distance between connections, in workspace units. - */ - distanceFrom(otherConnection: Blockly.Connection): number; - - /** - * Move the block(s) belonging to the connection to a point where they don't - * visually interfere with the specified connection. - * @param {!Blockly.Connection} staticConnection The connection to move away - * from. - * @package - */ - bumpAwayFrom(staticConnection: Blockly.Connection): void; - - /** - * Change the connection's coordinates. - * @param {number} x New absolute x coordinate, in workspace coordinates. - * @param {number} y New absolute y coordinate, in workspace coordinates. - */ - moveTo(x: number, y: number): void; - - /** - * Change the connection's coordinates. - * @param {number} dx Change to x coordinate, in workspace units. - * @param {number} dy Change to y coordinate, in workspace units. - */ - moveBy(dx: number, dy: number): void; - - /** - * Move this connection to the location given by its offset within the block and - * the location of the block's top left corner. - * @param {!Blockly.utils.Coordinate} blockTL The location of the top left - * corner of the block, in workspace coordinates. - */ - moveToOffset(blockTL: Blockly.utils.Coordinate): void; - - /** - * Set the offset of this connection relative to the top left of its block. - * @param {number} x The new relative x, in workspace units. - * @param {number} y The new relative y, in workspace units. - */ - setOffsetInBlock(x: number, y: number): void; - - /** - * Get the offset of this connection relative to the top left of its block. - * @return {!Blockly.utils.Coordinate} The offset of the connection. - * @package - */ - getOffsetInBlock(): Blockly.utils.Coordinate; - - /** - * Move the blocks on either side of this connection right next to each other. - * @package - */ - tighten(): void; - - /** - * Find the closest compatible connection to this connection. - * All parameters are in workspace units. - * @param {number} maxLimit The maximum radius to another connection. - * @param {!Blockly.utils.Coordinate} dxy Offset between this connection's location - * in the database and the current location (as a result of dragging). - * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two - * properties: 'connection' which is either another connection or null, - * and 'radius' which is the distance. - */ - closest(maxLimit: number, dxy: Blockly.utils.Coordinate): { connection: Blockly.Connection; radius: number }; - - /** - * Add highlighting around this connection. - */ - highlight(): void; - - /** - * Remove the highlighting around this connection. - */ - unhighlight(): void; - - /** - * Set whether this connections is tracked in the database or not. - * @param {boolean} doTracking If true, start tracking. If false, stop tracking. - * @package - */ - setTracking(doTracking: boolean): void; - - /** - * Stop tracking this connection, as well as all down-stream connections on - * any block attached to this connection. This happens when a block is - * collapsed. - * - * Also closes down-stream icons/bubbles. - * @package - */ - stopTrackingAll(): void; - - /** - * Start tracking this connection, as well as all down-stream connections on - * any block attached to this connection. This happens when a block is expanded. - * @return {!Array} List of blocks to render. - */ - startTrackingAll(): Blockly.Block[]; - - /** - * Check if the two connections can be dragged to connect to each other. - * @param {!Blockly.Connection} candidate A nearby connection to check. - * @param {number=} maxRadius The maximum radius allowed for connections, in - * workspace units. - * @return {boolean} True if the connection is allowed, false otherwise. - * @deprecated July 2020 - */ - isConnectionAllowed(candidate: Blockly.Connection, maxRadius?: number): boolean; - - /** - * Behavior after a connection attempt fails. - * Bumps this connection away from the other connection. Called when an - * attempted connection fails. - * @param {!Blockly.Connection} otherConnection Connection that this connection - * failed to connect to. - * @package - */ - onFailedConnect(otherConnection: Blockly.Connection): void; - - /** - * Find all nearby compatible connections to this connection. - * Type checking does not apply, since this function is used for bumping. - * @param {number} maxLimit The maximum radius to another connection, in - * workspace units. - * @return {!Array} List of connections. - * @package - */ - neighbours(maxLimit: number): Blockly.Connection[]; - - /** - * Connect two connections together. This is the connection on the superior - * block. Rerender blocks as needed. - * @param {!Blockly.Connection} childConnection Connection on inferior block. - * @protected - */ - connect_(childConnection: Blockly.Connection): void; - - /** - * Function to be called when this connection's compatible types have changed. - * @protected - */ - onCheckChanged_(): void; - } - -} - -declare module Blockly.RenderedConnection { +declare module RenderedConnection { /** * Enum for different kinds of tracked states. @@ -9229,272 +1417,7 @@ declare module Blockly.RenderedConnection { -declare module Blockly { - - class ScrollbarPair extends ScrollbarPair__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ScrollbarPair__Class { - - /** - * Class for a pair of scrollbars. Horizontal and vertical. - * @param {!Blockly.WorkspaceSvg} workspace Workspace to bind the scrollbars to. - * @param {boolean=} addHorizontal Whether to add a horizontal scrollbar. - * Defaults to true. - * @param {boolean=} addVertical Whether to add a vertical scrollbar. Defaults - * to true. - * @param {string=} opt_class A class to be applied to these scrollbars. - * @param {number=} opt_margin The margin to apply to these scrollbars. - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, addHorizontal?: boolean, addVertical?: boolean, opt_class?: string, opt_margin?: number); - - /** - * Dispose of this pair of scrollbars. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Recalculate both of the scrollbars' locations and lengths. - * Also reposition the corner rectangle. - */ - resize(): void; - - /** - * Returns whether scrolling horizontally is enabled. - * @return {boolean} True if horizontal scroll is enabled. - */ - canScrollHorizontally(): boolean; - - /** - * Returns whether scrolling vertically is enabled. - * @return {boolean} True if vertical scroll is enabled. - */ - canScrollVertically(): boolean; - - /** - * Record the origin of the workspace that the scrollbar is in, in pixels - * relative to the injection div origin. This is for times when the scrollbar is - * used in an object whose origin isn't the same as the main workspace - * (e.g. in a flyout.) - * @param {number} x The x coordinate of the scrollbar's origin, in CSS pixels. - * @param {number} y The y coordinate of the scrollbar's origin, in CSS pixels. - * @package - */ - setOrigin(x: number, y: number): void; - - /** - * Set the handles of both scrollbars. - * @param {number} x The horizontal content displacement, relative to the view - * in pixels. - * @param {number} y The vertical content displacement, relative to the view in - * pixels. - * @param {boolean} updateMetrics Whether to update metrics on this set call. - * Defaults to true. - */ - set(x: number, y: number, updateMetrics: boolean): void; - - /** - * Set the handle of the horizontal scrollbar to be at a certain position in - * CSS pixels relative to its parents. - * @param {number} x Horizontal scroll value. - */ - setX(x: number): void; - - /** - * Set the handle of the vertical scrollbar to be at a certain position in - * CSS pixels relative to its parents. - * @param {number} y Vertical scroll value. - */ - setY(y: number): void; - - /** - * Set whether this scrollbar's container is visible. - * @param {boolean} visible Whether the container is visible. - */ - setContainerVisible(visible: boolean): void; - - /** - * If any of the scrollbars are visible. Non-paired scrollbars may disappear - * when they aren't needed. - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Recalculates the scrollbars' locations within their path and length. - * This should be called when the contents of the workspace have changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeContent(hostMetrics: Blockly.utils.Metrics): void; - - /** - * Recalculates the scrollbars' locations on the screen and path length. - * This should be called when the layout or size of the window has changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeView(hostMetrics: Blockly.utils.Metrics): void; - } - - - class Scrollbar extends Scrollbar__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Scrollbar__Class { - - /** - * Class for a pure SVG scrollbar. - * This technique offers a scrollbar that is guaranteed to work, but may not - * look or behave like the system's scrollbars. - * @param {!Blockly.WorkspaceSvg} workspace Workspace to bind the scrollbar to. - * @param {boolean} horizontal True if horizontal, false if vertical. - * @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair. - * @param {string=} opt_class A class to be applied to this scrollbar. - * @param {number=} opt_margin The margin to apply to this scrollbar. - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, horizontal: boolean, opt_pair?: boolean, opt_class?: string, opt_margin?: number); - - /** - * The ratio of handle position offset to workspace content displacement. - * @type {?number} - * @package - */ - ratio: number; - - /** - * The upper left corner of the scrollbar's SVG group in CSS pixels relative - * to the scrollbar's origin. This is usually relative to the injection div - * origin. - * @type {Blockly.utils.Coordinate} - * @package - */ - position: Blockly.utils.Coordinate; - - /** - * Dispose of this scrollbar. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Set the offset of the scrollbar's handle from the scrollbar's position, and - * change the SVG attribute accordingly. - * @param {number} newPosition The new scrollbar handle offset in CSS pixels. - */ - setHandlePosition(newPosition: number): void; - - /** - * Set the position of the scrollbar's SVG group in CSS pixels relative to the - * scrollbar's origin. This sets the scrollbar's location within the workspace. - * @param {number} x The new x coordinate. - * @param {number} y The new y coordinate. - * @package - */ - setPosition(x: number, y: number): void; - - /** - * Recalculate the scrollbar's location and its length. - * @param {Blockly.utils.Metrics=} opt_metrics A data structure of from the - * describing all the required dimensions. If not provided, it will be - * fetched from the host object. - */ - resize(opt_metrics?: Blockly.utils.Metrics): void; - - /** - * Recalculate a horizontal scrollbar's location on the screen and path length. - * This should be called when the layout or size of the window has changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeViewHorizontal(hostMetrics: Blockly.utils.Metrics): void; - - /** - * Recalculate a horizontal scrollbar's location within its path and length. - * This should be called when the contents of the workspace have changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeContentHorizontal(hostMetrics: Blockly.utils.Metrics): void; - - /** - * Recalculate a vertical scrollbar's location on the screen and path length. - * This should be called when the layout or size of the window has changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeViewVertical(hostMetrics: Blockly.utils.Metrics): void; - - /** - * Recalculate a vertical scrollbar's location within its path and length. - * This should be called when the contents of the workspace have changed. - * @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all - * the required dimensions, possibly fetched from the host object. - */ - resizeContentVertical(hostMetrics: Blockly.utils.Metrics): void; - - /** - * Is the scrollbar visible. Non-paired scrollbars disappear when they aren't - * needed. - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Set whether the scrollbar's container is visible and update - * display accordingly if visibility has changed. - * @param {boolean} visible Whether the container is visible - */ - setContainerVisible(visible: boolean): void; - - /** - * Set whether the scrollbar is visible. - * Only applies to non-paired scrollbars. - * @param {boolean} visible True if visible. - */ - setVisible(visible: boolean): void; - - /** - * Update visibility of scrollbar based on whether it thinks it should - * be visible and whether its containing workspace is visible. - * We cannot rely on the containing workspace being hidden to hide us - * because it is not necessarily our parent in the DOM. - */ - updateDisplay_(): void; - - /** - * Helper to calculate the ratio of handle position to scrollbar view size. - * @return {number} Ratio. - * @protected - */ - getRatio_(): number; - - /** - * Set the scrollbar handle's position. - * @param {number} value The content displacement, relative to the view in - * pixels. - * @param {boolean=} updateMetrics Whether to update metrics on this set call. - * Defaults to true. - */ - set(value: number, updateMetrics?: boolean): void; - - /** - * Record the origin of the workspace that the scrollbar is in, in pixels - * relative to the injection div origin. This is for times when the scrollbar is - * used in an object whose origin isn't the same as the main workspace - * (e.g. in a flyout.) - * @param {number} x The x coordinate of the scrollbar's origin, in CSS pixels. - * @param {number} y The y coordinate of the scrollbar's origin, in CSS pixels. - */ - setOrigin(x: number, y: number): void; - } - -} - -declare module Blockly.Scrollbar { +declare module Scrollbar { /** * Width of vertical scrollbar or height of horizontal scrollbar in CSS pixels. @@ -9513,324 +1436,36 @@ declare module Blockly.Scrollbar { } -declare module Blockly.ShortcutItems { - - /** - * Object holding the names of the default shortcut items. - * @enum {string} - */ - enum names { ESCAPE, DELETE, COPY, CUT, PASTE, UNDO, REDO } - - /** Keyboard shortcut to hide chaff on escape. */ - function registerEscape(): void; - - /** Keyboard shortcut to delete a block on delete or backspace */ - function registerDelete(): void; - - /** Keyboard shortcut to copy a block on ctrl+c, cmd+c, or alt+c. */ - function registerCopy(): void; - - /** Keyboard shortcut to copy and delete a block on ctrl+x, cmd+x, or alt+x. */ - function registerCut(): void; - - /** Keyboard shortcut to paste a block on ctrl+v, cmd+v, or alt+v. */ - function registerPaste(): void; - - /** Keyboard shortcut to undo the previous action on ctrl+z, cmd+z, or alt+z. */ - function registerUndo(): void; - - /** Keyboard shortcut to redo the previous action on ctrl+shift+z, cmd+shift+z, or alt+shift+z. */ - function registerRedo(): void; - - /** - * Registers all default keyboard shortcut item. This should be called once per instance of - * KeyboardShortcutRegistry. - * @package - */ - function registerDefaultShortcuts(): void; -} -declare module Blockly { - - class ShortcutRegistry extends ShortcutRegistry__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ShortcutRegistry__Class { - - /** - * 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 - */ - constructor(); - - /** - * 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 - */ - register(shortcut: Blockly.ShortcutRegistry.KeyboardShortcut, opt_allowOverrides?: boolean): void; - - /** - * 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 - */ - unregister(shortcutName: string): boolean; - - /** - * Adds a mapping between a keycode and a keyboard shortcut. - * @param {string|Blockly.utils.KeyCodes} 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 - */ - addKeyMapping(keyCode: string|Blockly.utils.KeyCodes, shortcutName: string, opt_allowCollision?: boolean): void; - - /** - * 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 - */ - removeKeyMapping(keyCode: string, shortcutName: string, opt_quiet?: boolean): boolean; - - /** - * 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 - */ - removeAllKeyMappings(shortcutName: string): void; - - /** - * Sets the key map. Setting the key map will override any default key mappings. - * @param {!Object>} keyMap The object with key code to - * shortcut names. - * @public - */ - setKeyMap(keyMap: { [key: string]: string[] }): void; - - /** - * Gets the current key map. - * @return {!Object>} - * The object holding key codes to Blockly.ShortcutRegistry.KeyboardShortcut. - * @public - */ - getKeyMap(): { [key: string]: Blockly.ShortcutRegistry.KeyboardShortcut[] }; - - /** - * Gets the registry of keyboard shortcuts. - * @return {!Object} - * The registry of keyboard shortcuts. - * @public - */ - getRegistry(): { [key: string]: Blockly.ShortcutRegistry.KeyboardShortcut }; - - /** - * 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 - */ - onKeyDown(workspace: Blockly.Workspace, e: Event): boolean; - - /** - * Gets the shortcuts registered to the given key code. - * @param {string} keyCode The serialized key code. - * @return {!Array|undefined} The list of shortcuts to call when the - * given keyCode is used. Undefined if no shortcuts exist. - * @public - */ - getShortcutNamesByKeyCode(keyCode: string): string[]|any /*undefined*/; - - /** - * 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} An array with all the key codes the shortcut is - * registered under. - * @public - */ - getKeyCodesByShortcutName(shortcutName: string): string[]; - - /** - * Creates the serialized key code that will be used in the key map. - * @param {number} keyCode Number code representing the key. - * @param {?Array} 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 - */ - createSerializedKey(keyCode: number, modifiers: string[]): string; - } - -} - -declare module Blockly.ShortcutRegistry { +declare module ShortcutRegistry { /** * Enum of valid modifiers. - * @enum {!Blockly.utils.KeyCodes} + * @enum {!KeyCodes} */ enum modifierKeys { Shift, Control, Alt, Meta } /** * A keyboard shortcut. * @typedef {{ - * callback: ((function(!Blockly.Workspace, Event, - * !Blockly.ShortcutRegistry.KeyboardShortcut):boolean)|undefined), + * callback: ((function(!Workspace, Event, + * !ShortcutRegistry.KeyboardShortcut):boolean)|undefined), * name: string, - * preconditionFn: ((function(!Blockly.Workspace):boolean)|undefined), + * preconditionFn: ((function(!Workspace):boolean)|undefined), * metadata: (Object|undefined) * }} */ interface KeyboardShortcut { - callback: { (_0: Blockly.Workspace, _1: Event, _2: Blockly.ShortcutRegistry.KeyboardShortcut): boolean }|any /*undefined*/; + callback: { (_0: Workspace, _1: Event, _2: ShortcutRegistry.KeyboardShortcut): boolean }|any /*undefined*/; name: string; - preconditionFn: { (_0: Blockly.Workspace): boolean }|any /*undefined*/; + preconditionFn: { (_0: Workspace): boolean }|any /*undefined*/; metadata: Object|any /*undefined*/ } } -declare module Blockly { - - class Theme extends Theme__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Theme__Class { - - /** - * Class for a theme. - * @param {string} name Theme name. - * @param {!Object=} opt_blockStyles A map - * from style names (strings) to objects with style attributes for blocks. - * @param {!Object=} opt_categoryStyles A - * map from style names (strings) to objects with style attributes for - * categories. - * @param {!Blockly.Theme.ComponentStyle=} opt_componentStyles A map of Blockly - * component names to style value. - * @constructor - */ - constructor(name: string, opt_blockStyles?: { [key: string]: Blockly.Theme.BlockStyle }, opt_categoryStyles?: { [key: string]: Blockly.Theme.CategoryStyle }, opt_componentStyles?: Blockly.Theme.ComponentStyle); - - /** - * The theme name. This can be used to reference a specific theme in CSS. - * @type {string} - */ - name: string; - - /** - * The block styles map. - * @type {!Object} - * @package - */ - blockStyles: { [key: string]: Blockly.Theme.BlockStyle }; - - /** - * The category styles map. - * @type {!Object} - * @package - */ - categoryStyles: { [key: string]: Blockly.Theme.CategoryStyle }; - - /** - * The UI components styles map. - * @type {!Blockly.Theme.ComponentStyle} - * @package - */ - componentStyles: Blockly.Theme.ComponentStyle; - - /** - * The font style. - * @type {!Blockly.Theme.FontStyle} - * @package - */ - fontStyle: Blockly.Theme.FontStyle; - - /** - * Whether or not to add a 'hat' on top of all blocks with no previous or - * output connections. - * @type {?boolean} - * @package - */ - startHats: boolean; - - /** - * Gets the class name that identifies this theme. - * @return {string} The CSS class name. - * @package - */ - getClassName(): string; - - /** - * Overrides or adds a style to the blockStyles map. - * @param {string} blockStyleName The name of the block style. - * @param {Blockly.Theme.BlockStyle} blockStyle The block style. - */ - setBlockStyle(blockStyleName: string, blockStyle: Blockly.Theme.BlockStyle): void; - - /** - * Overrides or adds a style to the categoryStyles map. - * @param {string} categoryStyleName The name of the category style. - * @param {Blockly.Theme.CategoryStyle} categoryStyle The category style. - */ - setCategoryStyle(categoryStyleName: string, categoryStyle: Blockly.Theme.CategoryStyle): void; - - /** - * Gets the style for a given Blockly UI component. If the style value is a - * string, we attempt to find the value of any named references. - * @param {string} componentName The name of the component. - * @return {?string} The style value. - */ - getComponentStyle(componentName: string): string; - - /** - * Configure a specific Blockly UI component with a style value. - * @param {string} componentName The name of the component. - * @param {*} styleValue The style value. - */ - setComponentStyle(componentName: string, styleValue: any): void; - - /** - * Configure a theme's font style. - * @param {Blockly.Theme.FontStyle} fontStyle The font style. - */ - setFontStyle(fontStyle: Blockly.Theme.FontStyle): void; - - /** - * Configure a theme's start hats. - * @param {boolean} startHats True if the theme enables start hats, false - * otherwise. - */ - setStartHats(startHats: boolean): void; - } - -} - -declare module Blockly.Theme { +declare module Theme { /** * A block style. @@ -9916,93 +1551,21 @@ declare module Blockly.Theme { * Define a new Blockly theme. * @param {string} name The name of the theme. * @param {!Object} themeObj An object containing theme properties. - * @return {!Blockly.Theme} A new Blockly theme. - */ - function defineTheme(name: string, themeObj: Object): Blockly.Theme; + * @return {!Theme} A new Blockly theme. + */ + function defineTheme(name: string, themeObj: Object): Theme; } -declare module Blockly { - - class ThemeManager extends ThemeManager__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ThemeManager__Class { - - /** - * Class for storing and updating a workspace's theme and UI components. - * @param {!Blockly.WorkspaceSvg} workspace The main workspace. - * @param {!Blockly.Theme} theme The workspace theme. - * @constructor - * @package - */ - constructor(workspace: Blockly.WorkspaceSvg, theme: Blockly.Theme); - - /** - * Get the workspace theme. - * @return {!Blockly.Theme} The workspace theme. - * @package - */ - getTheme(): Blockly.Theme; - - /** - * Set the workspace theme, and refresh the workspace and all components. - * @param {!Blockly.Theme} theme The workspace theme. - * @package - */ - setTheme(theme: Blockly.Theme): void; - - /** - * Subscribe a workspace to changes to the selected theme. If a new theme is - * set, the workspace is called to refresh its blocks. - * @param {!Blockly.Workspace} workspace The workspace to subscribe. - * @package - */ - subscribeWorkspace(workspace: Blockly.Workspace): void; - - /** - * Unsubscribe a workspace to changes to the selected theme. - * @param {!Blockly.Workspace} workspace The workspace to unsubscribe. - * @package - */ - unsubscribeWorkspace(workspace: Blockly.Workspace): void; - - /** - * Subscribe an element to changes to the selected theme. If a new theme is - * selected, the element's style is refreshed with the new theme's style. - * @param {!Element} element The element to subscribe. - * @param {string} componentName The name used to identify the component. This - * must be the same name used to configure the style in the Theme object. - * @param {string} propertyName The inline style property name to update. - * @package - */ - subscribe(element: Element, componentName: string, propertyName: string): void; - - /** - * Unsubscribe an element to changes to the selected theme. - * @param {Element} element The element to unsubscribe. - * @package - */ - unsubscribe(element: Element): void; - - /** - * Dispose of this theme manager. - * @package - * @suppress {checkTypes} - */ - dispose(): void; - } - -} - -declare module Blockly.ThemeManager { +declare module ThemeManager { /** * A Blockly UI component type. * @typedef {{ - * element:!Element, - * propertyName:string - * }} - */ + * element:!Element, + * propertyName:string + * }} + */ interface Component { element: Element; propertyName: string @@ -10010,323 +1573,9 @@ declare module Blockly.ThemeManager { } -declare module Blockly.Tooltip { - - /** - * A type which can define a tooltip. - * Either a string, an object containing a tooltip property, or a function which - * returns either a string, or another arbitrarily nested function which - * eventually unwinds to a string. - * @typedef {string|{tooltip}|function(): (string|!Function)} - */ - type TipInfo = string|{ tooltip: any /*missing*/ }|{ (): string|Function }; - - /** - * Is a tooltip currently showing? - */ - var visible: any /*missing*/; - - /** - * Maximum width (in characters) of a tooltip. - */ - var LIMIT: any /*missing*/; - - /** - * Horizontal offset between mouse cursor and tooltip. - */ - var OFFSET_X: any /*missing*/; - - /** - * Vertical offset between mouse cursor and tooltip. - */ - var OFFSET_Y: any /*missing*/; - - /** - * Radius mouse can move before killing tooltip. - */ - var RADIUS_OK: any /*missing*/; - - /** - * Delay before tooltip appears. - */ - var HOVER_MS: any /*missing*/; - - /** - * Horizontal padding between tooltip and screen edge. - */ - var MARGINS: any /*missing*/; - - /** - * The HTML container. Set once by Blockly.Tooltip.createDom. - * @type {Element} - */ - var DIV: Element; - - /** - * Returns the tooltip text for the given element. - * @param {?Object} object The object to get the tooltip text of. - * @return {string} The tooltip text of the element. - */ - function getTooltipOfObject(object: Object): string; - - /** - * Create the tooltip div and inject it onto the page. - */ - function createDom(): void; - - /** - * Binds the required mouse events onto an SVG element. - * @param {!Element} element SVG element onto which tooltip is to be bound. - */ - function bindMouseEvents(element: Element): void; - - /** - * Unbinds tooltip mouse events from the SVG element. - * @param {!Element} element SVG element onto which tooltip is bound. - */ - function unbindMouseEvents(element: Element): void; - - /** - * Dispose of the tooltip. - * @package - */ - function dispose(): void; - - /** - * Hide the tooltip. - */ - function hide(): void; - - /** - * Hide any in-progress tooltips and block showing new tooltips until the next - * call to unblock(). - * @package - */ - function block(): void; - - /** - * Unblock tooltips: allow them to be scheduled and shown according to their own - * logic. - * @package - */ - function unblock(): void; -} -declare module Blockly.Touch { - - /** - * Whether touch is enabled in the browser. - * Copied from Closure's goog.events.BrowserFeature.TOUCH_ENABLED - */ - var TOUCH_ENABLED: any /*missing*/; - - /** - * The TOUCH_MAP lookup dictionary specifies additional touch events to fire, - * in conjunction with mouse events. - * @type {Object} - */ - var TOUCH_MAP: Object; - - /** - * Clear the touch identifier that tracks which touch stream to pay attention - * to. This ends the current drag/gesture and allows other pointers to be - * captured. - */ - function clearTouchIdentifier(): void; - - /** - * Decide whether Blockly should handle or ignore this event. - * Mouse and touch events require special checks because we only want to deal - * with one touch stream at a time. All other events should always be handled. - * @param {!Event} e The event to check. - * @return {boolean} True if this event should be passed through to the - * registered handler; false if it should be blocked. - */ - function shouldHandleEvent(e: Event): boolean; - - /** - * Get the touch identifier from the given event. If it was a mouse event, the - * identifier is the string 'mouse'. - * @param {!Event} e Mouse event or touch event. - * @return {string} The touch identifier from the first changed touch, if - * defined. Otherwise 'mouse'. - */ - function getTouchIdentifierFromEvent(e: Event): string; - - /** - * Check whether the touch identifier on the event matches the current saved - * identifier. If there is no identifier, that means it's a mouse event and - * we'll use the identifier "mouse". This means we won't deal well with - * multiple mice being used at the same time. That seems okay. - * If the current identifier was unset, save the identifier from the - * event. This starts a drag/gesture, during which touch events with other - * identifiers will be silently ignored. - * @param {!Event} e Mouse event or touch event. - * @return {boolean} Whether the identifier on the event matches the current - * saved identifier. - */ - function checkTouchIdentifier(e: Event): boolean; - - /** - * Set an event's clientX and clientY from its first changed touch. Use this to - * make a touch event work in a mouse event handler. - * @param {!Event} e A touch event. - */ - function setClientFromTouch(e: Event): void; - - /** - * Check whether a given event is a mouse or touch event. - * @param {!Event} e An event. - * @return {boolean} True if it is a mouse or touch event; false otherwise. - */ - function isMouseOrTouchEvent(e: Event): boolean; - - /** - * Check whether a given event is a touch event or a pointer event. - * @param {!Event} e An event. - * @return {boolean} True if it is a touch event; false otherwise. - */ - function isTouchEvent(e: Event): boolean; - - /** - * Split an event into an array of events, one per changed touch or mouse - * point. - * @param {!Event} e A mouse event or a touch event with one or more changed - * touches. - * @return {!Array} An array of mouse or touch events. Each touch - * event will have exactly one changed touch. - */ - function splitEventByTouches(e: Event): Event[]; -} - -declare module Blockly { - - /** - * Context menus on touch devices are activated using a long-press. - * Unfortunately the contextmenu touch event is currently (2015) only supported - * by Chrome. This function is fired on any touchstart event, queues a task, - * which after about a second opens the context menu. The tasks is killed - * if the touch event terminates early. - * @param {!Event} e Touch start event. - * @param {Blockly.Gesture} gesture The gesture that triggered this longStart. - * @package - */ - function longStart(e: Event, gesture: Blockly.Gesture): void; - - /** - * Nope, that's not a long-press. Either touchend or touchcancel was fired, - * or a drag hath begun. Kill the queued long-press task. - * @package - */ - function longStop_(): void; -} - - -declare module Blockly { - - class TouchGesture extends TouchGesture__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class TouchGesture__Class extends Blockly.Gesture__Class { - - /** - * Class for one gesture. - * @param {!Event} e The event that kicked off this gesture. - * @param {!Blockly.WorkspaceSvg} creatorWorkspace The workspace that created - * this gesture and has a reference to it. - * @extends {Blockly.Gesture} - * @constructor - */ - constructor(e: Event, creatorWorkspace: Blockly.WorkspaceSvg); - - /** - * Start a gesture: update the workspace to indicate that a gesture is in - * progress and bind mousemove and mouseup handlers. - * @param {!Event} e A mouse down, touch start or pointer down event. - * @package - */ - doStart(e: Event): void; - - /** - * Bind gesture events. - * Overriding the gesture definition of this function, binding the same - * functions for onMoveWrapper_ and onUpWrapper_ but passing - * opt_noCaptureIdentifier. - * In addition, binding a second mouse down event to detect multi-touch events. - * @param {!Event} e A mouse down or touch start event. - * @package - */ - bindMouseEvents(e: Event): void; - - /** - * Handle a mouse down, touch start, or pointer down event. - * @param {!Event} e A mouse down, touch start, or pointer down event. - * @package - */ - handleStart(e: Event): void; - - /** - * Handle a mouse move, touch move, or pointer move event. - * @param {!Event} e A mouse move, touch move, or pointer move event. - * @package - */ - handleMove(e: Event): void; - - /** - * Handle a mouse up, touch end, or pointer up event. - * @param {!Event} e A mouse up, touch end, or pointer up event. - * @package - */ - handleUp(e: Event): void; - - /** - * Whether this gesture is part of a multi-touch gesture. - * @return {boolean} Whether this gesture is part of a multi-touch gesture. - * @package - */ - isMultiTouch(): boolean; - - /** - * Sever all links from this object. - * @package - */ - dispose(): void; - - /** - * Handle a touch start or pointer down event and keep track of current - * pointers. - * @param {!Event} e A touch start, or pointer down event. - * @package - */ - handleTouchStart(e: Event): void; - - /** - * Handle a touch move or pointer move event and zoom in/out if two pointers - * are on the screen. - * @param {!Event} e A touch move, or pointer move event. - * @package - */ - handleTouchMove(e: Event): void; - - /** - * Handle a touch end or pointer end event and end the gesture. - * @param {!Event} e A touch end, or pointer end event. - * @package - */ - handleTouchEnd(e: Event): void; - - /** - * Helper function returning the current touch point coordinate. - * @param {!Event} e A touch or pointer event. - * @return {?Blockly.utils.Coordinate} The current touch point coordinate - * @package - */ - getTouchPoint(e: Event): Blockly.utils.Coordinate; - } - -} - -declare module Blockly.TouchGesture { +declare module TouchGesture { /** * A multiplier used to convert the gesture scale to a zoom in delta. @@ -10342,1239 +1591,28 @@ declare module Blockly.TouchGesture { } -declare module Blockly { - - class Trashcan extends Trashcan__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Trashcan__Class extends Blockly.DeleteArea__Class implements Blockly.IAutoHideable, Blockly.IPositionable { - - /** - * Class for a trash can. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in. - * @constructor - * @implements {Blockly.IAutoHideable} - * @implements {Blockly.IPositionable} - * @extends {Blockly.DeleteArea} - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * The unique id for this component that is used to register with the - * ComponentManager. - * @type {string} - */ - id: string; - - /** - * The trashcan flyout. - * @type {Blockly.IFlyout} - * @package - */ - flyout: Blockly.IFlyout; - - /** - * Current open/close state of the lid. - * @type {boolean} - */ - isLidOpen: boolean; - - /** - * Create the trash can elements. - * @return {!SVGElement} The trash can's SVG group. - */ - createDom(): SVGElement; - - /** - * Initializes the trash can. - */ - init(): void; - - /** - * Dispose of this trash can. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Returns true if the trashcan contents-flyout is currently open. - * @return {boolean} True if the trashcan contents-flyout is currently open. - */ - contentsIsOpen(): boolean; - - /** - * Opens the trashcan flyout. - */ - openFlyout(): void; - - /** - * Closes the trashcan flyout. - */ - closeFlyout(): void; - - /** - * Hides the component. Called in Blockly.hideChaff. - * @param {boolean} onlyClosePopups Whether only popups should be closed. - * Flyouts should not be closed if this is true. - */ - autoHide(onlyClosePopups: boolean): void; - - /** - * Empties the trashcan's contents. If the contents-flyout is currently open - * it will be closed. - */ - emptyContents(): void; - - /** - * Positions the trashcan. - * It is positioned in the opposite corner to the corner the - * categories/toolbox starts at. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics. - * @param {!Array} savedPositions List of rectangles that - * are already on the workspace. - */ - position(metrics: Blockly.MetricsManager.UiMetrics, savedPositions: Blockly.utils.Rect[]): void; - - /** - * Returns the bounding rectangle of the UI element in pixel units relative to - * the Blockly injection div. - * @return {?Blockly.utils.Rect} The UI elements’s bounding box. Null if - * bounding box should be ignored by other UI elements. - */ - getBoundingRectangle(): Blockly.utils.Rect; - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Flip the lid open or shut. - * @param {boolean} state True if open. - * @package - */ - setLidOpen(state: boolean): void; - - /** - * Flip the lid shut. - * Called externally after a drag. - */ - closeLid(): void; - - /** - * Inspect the contents of the trash. - */ - click(): void; - } - -} -declare module Blockly.utils { - /** - * Don't do anything for this event, just halt propagation. - * @param {!Event} e An event. - */ - function noEvent(e: Event): void; - - /** - * Is this event targeting a text input widget? - * @param {!Event} e An event. - * @return {boolean} True if text input. - */ - function isTargetInput(e: Event): boolean; - - /** - * Return the coordinates of the top-left corner of this element relative to - * its parent. Only for SVG elements and children (e.g. rect, g, path). - * @param {!Element} element SVG element to find the coordinates of. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - */ - function getRelativeXY(element: Element): Blockly.utils.Coordinate; - - /** - * Return the coordinates of the top-left corner of this element relative to - * the div Blockly was injected into. - * @param {!Element} element SVG element to find the coordinates of. If this is - * not a child of the div Blockly was injected into, the behaviour is - * undefined. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - */ - function getInjectionDivXY_(element: Element): Blockly.utils.Coordinate; - - /** - * Is this event a right-click? - * @param {!Event} e Mouse event. - * @return {boolean} True if right-click. - */ - function isRightButton(e: Event): boolean; - - /** - * Return the converted coordinates of the given mouse event. - * The origin (0,0) is the top-left corner of the Blockly SVG. - * @param {!Event} e Mouse event. - * @param {!Element} svg SVG element. - * @param {?SVGMatrix} matrix Inverted screen CTM to use. - * @return {!SVGPoint} Object with .x and .y properties. - */ - function mouseToSvg(e: Event, svg: Element, matrix: SVGMatrix): SVGPoint; - - /** - * Get the scroll delta of a mouse event in pixel units. - * @param {!Event} e Mouse event. - * @return {{x: number, y: number}} Scroll delta object with .x and .y - * properties. - */ - function getScrollDeltaPixels(e: Event): { x: number; y: number }; - - /** - * Parse a string with any number of interpolation tokens (%1, %2, ...). - * It will also replace string table references (e.g., %{bky_my_msg} and - * %{BKY_MY_MSG} will both be replaced with the value in - * Blockly.Msg['MY_MSG']). Percentage sign characters '%' may be self-escaped - * (e.g., '%%'). - * @param {string} message Text which might contain string table references and - * interpolation tokens. - * @return {!Array} Array of strings and numbers. - */ - function tokenizeInterpolation(message: string): string|number[]; - - /** - * Replaces string table references in a message, if the message is a string. - * For example, "%{bky_my_msg}" and "%{BKY_MY_MSG}" will both be replaced with - * the value in Blockly.Msg['MY_MSG']. - * @param {string|?} message Message, which may be a string that contains - * string table references. - * @return {string} String with message references replaced. - */ - function replaceMessageReferences(message: string|any): string; - - /** - * Validates that any %{MSG_KEY} references in the message refer to keys of - * the Blockly.Msg string table. - * @param {string} message Text which might contain string table references. - * @return {boolean} True if all message references have matching values. - * Otherwise, false. - */ - function checkMessageReferences(message: string): boolean; - - /** - * Generate a unique ID. This should be globally unique. - * 87 characters ^ 20 length > 128 bits (better than a UUID). - * @return {string} A globally unique ID string. - */ - function genUid(): string; - - /** - * Check if 3D transforms are supported by adding an element - * and attempting to set the property. - * @return {boolean} True if 3D transforms are supported. - */ - function is3dSupported(): boolean; - - /** - * Calls a function after the page has loaded, possibly immediately. - * @param {function()} fn Function to run. - * @throws Error Will throw if no global document can be found (e.g., Node.js). - */ - function runAfterPageLoad(fn: { (): any /*missing*/ }): void; - - /** - * Get the position of the current viewport in window coordinates. This takes - * scroll into account. - * @return {!Blockly.utils.Rect} An object containing window width, height, and - * scroll position in window coordinates. - * @package - */ - function getViewportBBox(): Blockly.utils.Rect; - - /** - * Removes the first occurrence of a particular value from an array. - * @param {!Array} arr Array from which to remove - * value. - * @param {*} obj Object to remove. - * @return {boolean} True if an element was removed. - * @package - */ - function arrayRemove(arr: any[], obj: any): boolean; - - /** - * Gets the document scroll distance as a coordinate object. - * Copied from Closure's goog.dom.getDocumentScroll. - * @return {!Blockly.utils.Coordinate} Object with values 'x' and 'y'. - */ - function getDocumentScroll(): Blockly.utils.Coordinate; - - /** - * Get a map of all the block's descendants mapping their type to the number of - * children with that type. - * @param {!Blockly.Block} block The block to map. - * @param {boolean=} opt_stripFollowing Optionally ignore all following - * statements (blocks that are not inside a value or statement input - * of the block). - * @return {!Object} Map of types to type counts for descendants of the bock. - */ - function getBlockTypeCounts(block: Blockly.Block, opt_stripFollowing?: boolean): Object; - - /** - * Converts screen coordinates to workspace coordinates. - * @param {!Blockly.WorkspaceSvg} ws The workspace to find the coordinates on. - * @param {!Blockly.utils.Coordinate} screenCoordinates The screen coordinates to - * be converted to workspace coordinates - * @return {!Blockly.utils.Coordinate} The workspace coordinates. - * @package - */ - function screenToWsCoordinates(ws: Blockly.WorkspaceSvg, screenCoordinates: Blockly.utils.Coordinate): Blockly.utils.Coordinate; - - /** - * Parse a block colour from a number or string, as provided in a block - * definition. - * @param {number|string} colour HSV hue value (0 to 360), #RRGGBB string, - * or a message reference string pointing to one of those two values. - * @return {{hue: ?number, hex: string}} An object containing the colour as - * a #RRGGBB string, and the hue if the input was an HSV hue value. - * @throws {Error} If the colour cannot be parsed. - */ - function parseBlockColour(colour: number|string): { hue: number; hex: string }; -} - - -declare module Blockly { - - class VariableMap extends VariableMap__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VariableMap__Class { - - /** - * Class for a variable map. This contains a dictionary data structure with - * variable types as keys and lists of variables as values. The list of - * variables are the type indicated by the key. - * @param {!Blockly.Workspace} workspace The workspace this map belongs to. - * @constructor - */ - constructor(workspace: Blockly.Workspace); - - /** - * The workspace this map belongs to. - * @type {!Blockly.Workspace} - */ - workspace: Blockly.Workspace; - - /** - * Clear the variable map. - */ - clear(): void; - - /** - * Rename the given variable by updating its name in the variable map. - * @param {!Blockly.VariableModel} variable Variable to rename. - * @param {string} newName New variable name. - * @package - */ - renameVariable(variable: Blockly.VariableModel, newName: string): void; - - /** - * Rename a variable by updating its name in the variable map. Identify the - * variable to rename with the given ID. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - */ - renameVariableById(id: string, newName: string): void; - - /** - * Create a variable with a given name, optional type, and optional ID. - * @param {string} name The name of the variable. This must be unique across - * variables and procedures. - * @param {?string=} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {?string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @return {!Blockly.VariableModel} The newly created variable. - */ - createVariable(name: string, opt_type?: string, opt_id?: string): Blockly.VariableModel; - - /** - * Delete a variable. - * @param {!Blockly.VariableModel} variable Variable to delete. - */ - deleteVariable(variable: Blockly.VariableModel): void; - - /** - * Delete a variables by the passed in ID and all of its uses from this - * workspace. May prompt the user for confirmation. - * @param {string} id ID of variable to delete. - */ - deleteVariableById(id: string): void; - - /** - * Deletes a variable and all of its uses from this workspace without asking the - * user for confirmation. - * @param {!Blockly.VariableModel} variable Variable to delete. - * @param {!Array} uses An array of uses of the variable. - * @package - */ - deleteVariableInternal(variable: Blockly.VariableModel, uses: Blockly.Block[]): void; - - /** - * Find the variable by the given name and type and return it. Return null if - * it is not found. - * @param {string} name The name to check for. - * @param {?string=} opt_type The type of the variable. If not provided it - * defaults to the empty string, which is a specific type. - * @return {?Blockly.VariableModel} The variable with the given name, or null if - * it was not found. - */ - getVariable(name: string, opt_type?: string): Blockly.VariableModel; - - /** - * Find the variable by the given ID and return it. Return null if not found. - * @param {string} id The ID to check for. - * @return {?Blockly.VariableModel} The variable with the given ID. - */ - getVariableById(id: string): Blockly.VariableModel; - - /** - * Get a list containing all of the variables of a specified type. If type is - * null, return list of variables with empty string type. - * @param {?string} type Type of the variables to find. - * @return {!Array} The sought after variables of the - * passed in type. An empty array if none are found. - */ - getVariablesOfType(type: string): Blockly.VariableModel[]; - - /** - * Return all variable and potential variable types. This list always contains - * the empty string. - * @param {?Blockly.Workspace} ws The workspace used to look for potential - * variables. This can be different than the workspace stored on this object - * if the passed in ws is a flyout workspace. - * @return {!Array} List of variable types. - * @package - */ - getVariableTypes(ws: Blockly.Workspace): string[]; - - /** - * Return all variables of all types. - * @return {!Array} List of variable models. - */ - getAllVariables(): Blockly.VariableModel[]; - - /** - * Returns all of the variable names of all types. - * @return {!Array} All of the variable names of all types. - */ - getAllVariableNames(): string[]; - - /** - * Find all the uses of a named variable. - * @param {string} id ID of the variable to find. - * @return {!Array} Array of block usages. - */ - getVariableUsesById(id: string): Blockly.Block[]; - } - -} - - -declare module Blockly { - - class VariableModel extends VariableModel__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VariableModel__Class { - - /** - * Class for a variable model. - * Holds information for the variable including name, ID, and type. - * @param {!Blockly.Workspace} workspace The variable's workspace. - * @param {string} name The name of the variable. This is the user-visible name - * (e.g. 'my var' or '私の変数'), not the generated name. - * @param {string=} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @see {Blockly.FieldVariable} - * @constructor - */ - constructor(workspace: Blockly.Workspace, name: string, opt_type?: string, opt_id?: string); - - /** - * The workspace the variable is in. - * @type {!Blockly.Workspace} - */ - workspace: Blockly.Workspace; - - /** - * The name of the variable, typically defined by the user. It may be - * changed by the user. - * @type {string} - */ - name: string; - - /** - * The type of the variable, such as 'int' or 'sound_effect'. This may be - * used to build a list of variables of a specific type. By default this is - * the empty string '', which is a specific type. - * @see {Blockly.FieldVariable} - * @type {string} - */ - type: string; - - /** - * @return {string} The ID for the variable. - */ - getId(): string; - } - -} - -declare module Blockly.VariableModel { +declare module VariableModel { /** * A custom compare function for the VariableModel objects. - * @param {Blockly.VariableModel} var1 First variable to compare. - * @param {Blockly.VariableModel} var2 Second variable to compare. + * @param {VariableModel} var1 First variable to compare. + * @param {VariableModel} var2 Second variable to compare. * @return {number} -1 if name of var1 is less than name of var2, 0 if equal, * and 1 if greater. * @package */ - function compareByName(var1: Blockly.VariableModel, var2: Blockly.VariableModel): number; + function compareByName(var1: VariableModel, var2: VariableModel): number; } -declare module Blockly.Variables { - - /** - * Constant to separate variable names from procedures and generated functions - * when running generators. - * @deprecated Use Blockly.VARIABLE_CATEGORY_NAME - */ - var NAME_TYPE: any /*missing*/; - - /** - * Find all user-created variables that are in use in the workspace. - * For use by generators. - * To get a list of all variables on a workspace, including unused variables, - * call Workspace.getAllVariables. - * @param {!Blockly.Workspace} ws The workspace to search for variables. - * @return {!Array} Array of variable models. - */ - function allUsedVarModels(ws: Blockly.Workspace): Blockly.VariableModel[]; - - /** - * Find all developer variables used by blocks in the workspace. - * Developer variables are never shown to the user, but are declared as global - * variables in the generated code. - * To declare developer variables, define the getDeveloperVariables function on - * your block and return a list of variable names. - * For use by generators. - * @param {!Blockly.Workspace} workspace The workspace to search. - * @return {!Array} A list of non-duplicated variable names. - */ - function allDeveloperVariables(workspace: Blockly.Workspace): string[]; - - /** - * Construct the elements (blocks and button) required by the flyout for the - * variable category. - * @param {!Blockly.Workspace} workspace The workspace containing variables. - * @return {!Array} Array of XML elements. - */ - function flyoutCategory(workspace: Blockly.Workspace): Element[]; - - /** - * Construct the blocks required by the flyout for the variable category. - * @param {!Blockly.Workspace} workspace The workspace containing variables. - * @return {!Array} Array of XML block elements. - */ - function flyoutCategoryBlocks(workspace: Blockly.Workspace): Element[]; - - /** - * Return a new variable name that is not yet being used. This will try to - * generate single letter variable names in the range 'i' to 'z' to start with. - * If no unique name is located it will try 'i' to 'z', 'a' to 'h', - * then 'i2' to 'z2' etc. Skip 'l'. - * @param {!Blockly.Workspace} workspace The workspace to be unique in. - * @return {string} New variable name. - */ - function generateUniqueName(workspace: Blockly.Workspace): string; - - /** - * Returns a unique name that is not present in the usedNames array. This - * will try to generate single letter names in the range a -> z (skip l). It - * will start with the character passed to startChar. - * @param {string} startChar The character to start the search at. - * @param {!Array} usedNames A list of all of the used names. - * @return {string} A unique name that is not present in the usedNames array. - */ - function generateUniqueNameFromOptions(startChar: string, usedNames: string[]): string; - - /** - * Handles "Create Variable" button in the default variables toolbox category. - * It will prompt the user for a variable name, including re-prompts if a name - * is already in use among the workspace's variables. - * - * Custom button handlers can delegate to this function, allowing variables - * types and after-creation processing. More complex customization (e.g., - * prompting for variable type) is beyond the scope of this function. - * - * @param {!Blockly.Workspace} workspace The workspace on which to create the - * variable. - * @param {function(?string=)=} opt_callback A callback. It will be passed an - * acceptable new variable name, or null if change is to be aborted (cancel - * button), or undefined if an existing variable was chosen. - * @param {string=} opt_type The type of the variable like 'int', 'string', or - * ''. This will default to '', which is a specific type. - */ - function createVariableButtonHandler(workspace: Blockly.Workspace, opt_callback?: { (_0: string): any /*missing*/ }, opt_type?: string): void; - - /** - * Original name of Blockly.Variables.createVariableButtonHandler(..). - * @deprecated Use Blockly.Variables.createVariableButtonHandler(..). - * - * @param {!Blockly.Workspace} workspace The workspace on which to create the - * variable. - * @param {function(?string=)=} opt_callback A callback. It will be passed an - * acceptable new variable name, or null if change is to be aborted (cancel - * button), or undefined if an existing variable was chosen. - * @param {string=} opt_type The type of the variable like 'int', 'string', or - * ''. This will default to '', which is a specific type. - */ - function createVariable(workspace: Blockly.Workspace, opt_callback?: { (_0: string): any /*missing*/ }, opt_type?: string): void; - - /** - * Opens a prompt that allows the user to enter a new name for a variable. - * Triggers a rename if the new name is valid. Or re-prompts if there is a - * collision. - * @param {!Blockly.Workspace} workspace The workspace on which to rename the - * variable. - * @param {!Blockly.VariableModel} variable Variable to rename. - * @param {function(?string=)=} opt_callback A callback. It will - * be passed an acceptable new variable name, or null if change is to be - * aborted (cancel button), or undefined if an existing variable was chosen. - */ - function renameVariable(workspace: Blockly.Workspace, variable: Blockly.VariableModel, opt_callback?: { (_0: string): any /*missing*/ }): void; - - /** - * Prompt the user for a new variable name. - * @param {string} promptText The string of the prompt. - * @param {string} defaultText The default value to show in the prompt's field. - * @param {function(?string)} callback A callback. It will return the new - * variable name, or null if the user picked something illegal. - */ - function promptName(promptText: string, defaultText: string, callback: { (_0: string): any /*missing*/ }): void; - - /** - * Check whether there exists a variable with the given name of any type. - * @param {string} name The name to search for. - * @param {!Blockly.Workspace} workspace The workspace to search for the - * variable. - * @return {?Blockly.VariableModel} The variable with the given name, - * or null if none was found. - */ - function nameUsedWithAnyType(name: string, workspace: Blockly.Workspace): Blockly.VariableModel; - - /** - * Generate DOM objects representing a variable field. - * @param {!Blockly.VariableModel} variableModel The variable model to - * represent. - * @return {?Element} The generated DOM. - * @public - */ - function generateVariableFieldDom(variableModel: Blockly.VariableModel): Element; - - /** - * Helper function to look up or create a variable on the given workspace. - * If no variable exists, creates and returns it. - * @param {!Blockly.Workspace} workspace The workspace to search for the - * variable. It may be a flyout workspace or main workspace. - * @param {?string} id The ID to use to look up or create the variable, or null. - * @param {string=} opt_name The string to use to look up or create the - * variable. - * @param {string=} opt_type The type to use to look up or create the variable. - * @return {!Blockly.VariableModel} The variable corresponding to the given ID - * or name + type combination. - */ - function getOrCreateVariablePackage(workspace: Blockly.Workspace, id: string, opt_name?: string, opt_type?: string): Blockly.VariableModel; - - /** - * Look up a variable on the given workspace. - * Always looks in the main workspace before looking in the flyout workspace. - * Always prefers lookup by ID to lookup by name + type. - * @param {!Blockly.Workspace} workspace The workspace to search for the - * variable. It may be a flyout workspace or main workspace. - * @param {?string} id The ID to use to look up the variable, or null. - * @param {string=} opt_name The string to use to look up the variable. - * Only used if lookup by ID fails. - * @param {string=} opt_type The type to use to look up the variable. - * Only used if lookup by ID fails. - * @return {?Blockly.VariableModel} The variable corresponding to the given ID - * or name + type combination, or null if not found. - * @public - */ - function getVariable(workspace: Blockly.Workspace, id: string, opt_name?: string, opt_type?: string): Blockly.VariableModel; - - /** - * Helper function to get the list of variables that have been added to the - * workspace after adding a new block, using the given list of variables that - * were in the workspace before the new block was added. - * @param {!Blockly.Workspace} workspace The workspace to inspect. - * @param {!Array} originalVariables The array of - * variables that existed in the workspace before adding the new block. - * @return {!Array} The new array of variables that - * were freshly added to the workspace after creating the new block, - * or [] if no new variables were added to the workspace. - * @package - */ - function getAddedVariables(workspace: Blockly.Workspace, originalVariables: Blockly.VariableModel[]): Blockly.VariableModel[]; -} -declare module Blockly.VariablesDynamic { - - /** - * Construct the elements (blocks and button) required by the flyout for the - * variable category. - * @param {!Blockly.Workspace} workspace The workspace containing variables. - * @return {!Array} Array of XML elements. - */ - function flyoutCategory(workspace: Blockly.Workspace): Element[]; - - /** - * Construct the blocks required by the flyout for the variable category. - * @param {!Blockly.Workspace} workspace The workspace containing variables. - * @return {!Array} Array of XML block elements. - */ - function flyoutCategoryBlocks(workspace: Blockly.Workspace): Element[]; -} -declare module Blockly { - - class Warning extends Warning__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Warning__Class extends Blockly.Icon__Class { - - /** - * Class for a warning. - * @param {!Blockly.Block} block The block associated with this warning. - * @extends {Blockly.Icon} - * @constructor - */ - constructor(block: Blockly.Block); - - /** - * Does this icon get hidden when the block is collapsed. - */ - collapseHidden: any /*missing*/; - - /** - * Draw the warning icon. - * @param {!Element} group The icon group. - * @protected - */ - drawIcon_(group: Element): void; - - /** - * Show or hide the warning bubble. - * @param {boolean} visible True if the bubble should be visible. - */ - setVisible(visible: boolean): void; - - /** - * Set this warning's text. - * @param {string} text Warning text (or '' to delete). This supports - * linebreaks. - * @param {string} id An ID for this text entry to be able to maintain - * multiple warnings. - */ - setText(text: string, id: string): void; - - /** - * Get this warning's texts. - * @return {string} All texts concatenated into one string. - */ - getText(): string; - - /** - * Dispose of this warning. - */ - dispose(): void; - } - -} - - -declare module Blockly.WidgetDiv { - - /** - * Create the widget div and inject it onto the page. - */ - function createDom(): void; - - /** - * The HTML container for popup overlays (e.g. editor widgets). - * @type {!Element} - */ - var DIV: Element; - - /** - * Initialize and display the widget div. Close the old one if needed. - * @param {!Object} newOwner The object that will be using this container. - * @param {boolean} rtl Right-to-left (true) or left-to-right (false). - * @param {Function} dispose Optional cleanup function to be run when the - * widget is closed. - */ - function show(newOwner: Object, rtl: boolean, dispose: Function): void; - - /** - * Destroy the widget and hide the div. - */ - function hide(): void; - - /** - * Is the container visible? - * @return {boolean} True if visible. - */ - function isVisible(): boolean; - - /** - * Destroy the widget and hide the div if it is being used by the specified - * object. - * @param {!Object} oldOwner The object that was using this container. - */ - function hideIfOwner(oldOwner: Object): void; - - /** - * Position the widget div based on an anchor rectangle. - * The widget should be placed adjacent to but not overlapping the anchor - * rectangle. The preferred position is directly below and aligned to the left - * (LTR) or right (RTL) side of the anchor. - * @param {!Blockly.utils.Rect} viewportBBox The bounding rectangle of the - * current viewport, in window coordinates. - * @param {!Blockly.utils.Rect} anchorBBox The bounding rectangle of the anchor, - * in window coordinates. - * @param {!Blockly.utils.Size} widgetSize The size of the widget that is inside - * the widget div, in window coordinates. - * @param {boolean} rtl Whether the workspace is in RTL mode. This determines - * horizontal alignment. - * @package - */ - function positionWithAnchor(viewportBBox: Blockly.utils.Rect, anchorBBox: Blockly.utils.Rect, widgetSize: Blockly.utils.Size, rtl: boolean): void; -} - - -declare module Blockly { - - class Workspace extends Workspace__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Workspace__Class implements Blockly.IASTNodeLocation { - - /** - * Class for a workspace. This is a data structure that contains blocks. - * There is no UI, and can be created headlessly. - * @param {!Blockly.Options=} opt_options Dictionary of options. - * @constructor - * @implements {Blockly.IASTNodeLocation} - */ - constructor(opt_options?: Blockly.Options); - - /** @type {string} */ - id: string; - - /** @type {!Blockly.Options} */ - options: Blockly.Options; - - /** @type {boolean} */ - RTL: boolean; - - /** @type {boolean} */ - horizontalLayout: boolean; - - /** @type {Blockly.utils.toolbox.Position} */ - toolboxPosition: Blockly.utils.toolbox.Position; - - /** - * An object that encapsulates logic for safety, type, and dragging checks. - * @type {!Blockly.IConnectionChecker} - */ - connectionChecker: Blockly.IConnectionChecker; - - /** - * @type {!Array} - * @protected - */ - undoStack_: Blockly.Events.Abstract[]; - - /** - * @type {!Array} - * @protected - */ - redoStack_: Blockly.Events.Abstract[]; - - /** - * Returns `true` if the workspace is visible and `false` if it's headless. - * @type {boolean} - */ - rendered: boolean; - - /** - * Returns `true` if the workspace is currently in the process of a bulk clear. - * @type {boolean} - * @package - */ - isClearing: boolean; - - /** - * Maximum number of undo events in stack. `0` turns off undo, `Infinity` sets - * it to unlimited. - * @type {number} - */ - MAX_UNDO: number; - - /** - * Set of databases for rapid lookup of connection locations. - * @type {Array} - */ - connectionDBList: Blockly.ConnectionDB[]; - - /** - * Dispose of this workspace. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Adds a block to the list of top blocks. - * @param {!Blockly.Block} block Block to add. - */ - addTopBlock(block: Blockly.Block): void; - - /** - * Removes a block from the list of top blocks. - * @param {!Blockly.Block} block Block to remove. - */ - removeTopBlock(block: Blockly.Block): void; - - /** - * Finds the top-level blocks and returns them. Blocks are optionally sorted - * by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array} The top-level block objects. - */ - getTopBlocks(ordered: boolean): Blockly.Block[]; - - /** - * Add a block to the list of blocks keyed by type. - * @param {!Blockly.Block} block Block to add. - */ - addTypedBlock(block: Blockly.Block): void; - - /** - * Remove a block from the list of blocks keyed by type. - * @param {!Blockly.Block} block Block to remove. - */ - removeTypedBlock(block: Blockly.Block): void; - - /** - * Finds the blocks with the associated type and returns them. Blocks are - * optionally sorted by position; top to bottom (with slight LTR or RTL bias). - * @param {string} type The type of block to search for. - * @param {boolean} ordered Sort the list if true. - * @return {!Array} The blocks of the given type. - */ - getBlocksByType(type: string, ordered: boolean): Blockly.Block[]; - - /** - * Adds a comment to the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to add. - * @package - */ - addTopComment(comment: Blockly.WorkspaceComment): void; - - /** - * Removes a comment from the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to remove. - * @package - */ - removeTopComment(comment: Blockly.WorkspaceComment): void; - - /** - * Finds the top-level comments and returns them. Comments are optionally - * sorted by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array} The top-level comment objects. - * @package - */ - getTopComments(ordered: boolean): Blockly.WorkspaceComment[]; - - /** - * Find all blocks in workspace. Blocks are optionally sorted - * by position; top to bottom (with slight LTR or RTL bias). - * @param {boolean} ordered Sort the list if true. - * @return {!Array} Array of blocks. - */ - getAllBlocks(ordered: boolean): Blockly.Block[]; - - /** - * Dispose of all blocks and comments in workspace. - */ - clear(): void; - - /** - * Rename a variable by updating its name in the variable map. Identify the - * variable to rename with the given ID. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - */ - renameVariableById(id: string, newName: string): void; - - /** - * Create a variable with a given name, optional type, and optional ID. - * @param {string} name The name of the variable. This must be unique across - * variables and procedures. - * @param {?string=} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {?string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @return {!Blockly.VariableModel} The newly created variable. - */ - createVariable(name: string, opt_type?: string, opt_id?: string): Blockly.VariableModel; - - /** - * Find all the uses of the given variable, which is identified by ID. - * @param {string} id ID of the variable to find. - * @return {!Array} Array of block usages. - */ - getVariableUsesById(id: string): Blockly.Block[]; - - /** - * Delete a variables by the passed in ID and all of its uses from this - * workspace. May prompt the user for confirmation. - * @param {string} id ID of variable to delete. - */ - deleteVariableById(id: string): void; - - /** - * Find the variable by the given name and return it. Return null if not found. - * @param {string} name The name to check for. - * @param {string=} opt_type The type of the variable. If not provided it - * defaults to the empty string, which is a specific type. - * @return {?Blockly.VariableModel} The variable with the given name. - */ - getVariable(name: string, opt_type?: string): Blockly.VariableModel; - - /** - * Find the variable by the given ID and return it. Return null if not found. - * @param {string} id The ID to check for. - * @return {?Blockly.VariableModel} The variable with the given ID. - */ - getVariableById(id: string): Blockly.VariableModel; - - /** - * Find the variable with the specified type. If type is null, return list of - * variables with empty string type. - * @param {?string} type Type of the variables to find. - * @return {!Array} The sought after variables of the - * passed in type. An empty array if none are found. - */ - getVariablesOfType(type: string): Blockly.VariableModel[]; - - /** - * Return all variable types. - * @return {!Array} List of variable types. - * @package - */ - getVariableTypes(): string[]; - - /** - * Return all variables of all types. - * @return {!Array} List of variable models. - */ - getAllVariables(): Blockly.VariableModel[]; - - /** - * Returns all variable names of all types. - * @return {!Array} List of all variable names of all types. - */ - getAllVariableNames(): string[]; - - /** - * Returns the horizontal offset of the workspace. - * Intended for LTR/RTL compatibility in XML. - * Not relevant for a headless workspace. - * @return {number} Width. - */ - getWidth(): number; - - /** - * Obtain a newly created block. - * @param {!string} prototypeName Name of the language object containing - * type-specific functions for this block. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @return {!Blockly.Block} The created block. - */ - newBlock(prototypeName: string, opt_id?: string): Blockly.Block; - - /** - * The number of blocks that may be added to the workspace before reaching - * the maxBlocks. - * @return {number} Number of blocks left. - */ - remainingCapacity(): number; - - /** - * The number of blocks of the given type that may be added to the workspace - * before reaching the maxInstances allowed for that type. - * @param {string} type Type of block to return capacity for. - * @return {number} Number of blocks of type left. - */ - remainingCapacityOfType(type: string): number; - - /** - * Check if there is remaining capacity for blocks of the given counts to be - * created. If the total number of blocks represented by the map is more than - * the total remaining capacity, it returns false. If a type count is more - * than the remaining capacity for that type, it returns false. - * @param {!Object} typeCountsMap A map of types to counts (usually representing - * blocks to be created). - * @return {boolean} True if there is capacity for the given map, - * false otherwise. - */ - isCapacityAvailable(typeCountsMap: Object): boolean; - - /** - * Checks if the workspace has any limits on the maximum number of blocks, - * or the maximum number of blocks of specific types. - * @return {boolean} True if it has block limits, false otherwise. - */ - hasBlockLimits(): boolean; - - /** - * Gets the undo stack for workplace. - * @return {!Array} undo stack - * @package - */ - getUndoStack(): Blockly.Events.Abstract[]; - - /** - * Gets the redo stack for workplace. - * @return {!Array} redo stack - * @package - */ - getRedoStack(): Blockly.Events.Abstract[]; - - /** - * Undo or redo the previous action. - * @param {boolean} redo False if undo, true if redo. - */ - undo(redo: boolean): void; - - /** - * Clear the undo/redo stacks. - */ - clearUndo(): void; - - /** - * When something in this workspace changes, call a function. - * Note that there may be a few recent events already on the stack. Thus the - * new change listener might be called with events that occurred a few - * milliseconds before the change listener was added. - * @param {!Function} func Function to call. - * @return {!Function} Obsolete return value, ignore. - */ - addChangeListener(func: Function): Function; - - /** - * Stop listening for this workspace's changes. - * @param {!Function} func Function to stop calling. - */ - removeChangeListener(func: Function): void; - - /** - * Fire a change event. - * @param {!Blockly.Events.Abstract} event Event to fire. - */ - fireChangeListener(event: Blockly.Events.Abstract): void; - - /** - * Find the block on this workspace with the specified ID. - * @param {string} id ID of block to find. - * @return {?Blockly.Block} The sought after block, or null if not found. - */ - getBlockById(id: string): Blockly.Block; - - /** - * Set a block on this workspace with the specified ID. - * @param {string} id ID of block to set. - * @param {Blockly.Block} block The block to set. - * @package - */ - setBlockById(id: string, block: Blockly.Block): void; - - /** - * Delete a block off this workspace with the specified ID. - * @param {string} id ID of block to delete. - * @package - */ - removeBlockById(id: string): void; - - /** - * Find the comment on this workspace with the specified ID. - * @param {string} id ID of comment to find. - * @return {?Blockly.WorkspaceComment} The sought after comment, or null if not - * found. - * @package - */ - getCommentById(id: string): Blockly.WorkspaceComment; - - /** - * Checks whether all value and statement inputs in the workspace are filled - * with blocks. - * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling - * whether shadow blocks are counted as filled. Defaults to true. - * @return {boolean} True if all inputs are filled, false otherwise. - */ - allInputsFilled(opt_shadowBlocksAreFilled?: boolean): boolean; - - /** - * Return the variable map that contains "potential" variables. - * These exist in the flyout but not in the workspace. - * @return {?Blockly.VariableMap} The potential variable map. - * @package - */ - getPotentialVariableMap(): Blockly.VariableMap; - - /** - * Create and store the potential variable map for this workspace. - * @package - */ - createPotentialVariableMap(): void; - - /** - * Return the map of all variables on the workspace. - * @return {!Blockly.VariableMap} The variable map. - */ - getVariableMap(): Blockly.VariableMap; - - /** - * Set the map of all variables on the workspace. - * @param {!Blockly.VariableMap} variableMap The variable map. - * @package - */ - setVariableMap(variableMap: Blockly.VariableMap): void; - } - -} - -declare module Blockly.Workspace { +declare module Workspace { /** * Angle away from the horizontal to sweep for blocks. Order of execution is @@ -11587,259 +1625,36 @@ declare module Blockly.Workspace { /** * Find the workspace with the specified ID. * @param {string} id ID of workspace to find. - * @return {?Blockly.Workspace} The sought after workspace or null if not found. + * @return {?Workspace} The sought after workspace or null if not found. */ - function getById(id: string): Blockly.Workspace; + function getById(id: string): Workspace; /** * Find all workspaces. - * @return {!Array} Array of workspaces. + * @return {!Array} Array of workspaces. */ - function getAll(): Blockly.Workspace[]; + function getAll(): Workspace[]; } -declare module Blockly { - class WorkspaceAudio extends WorkspaceAudio__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceAudio__Class { - - /** - * Class for loading, storing, and playing audio for a workspace. - * @param {Blockly.WorkspaceSvg} parentWorkspace The parent of the workspace - * this audio object belongs to, or null. - * @constructor - */ - constructor(parentWorkspace: Blockly.WorkspaceSvg); - - /** - * Dispose of this audio manager. - * @package - */ - dispose(): void; - - /** - * Load an audio file. Cache it, ready for instantaneous playing. - * @param {!Array} filenames List of file types in decreasing order of - * preference (i.e. increasing size). E.g. ['media/go.mp3', 'media/go.wav'] - * Filenames include path from Blockly's root. File extensions matter. - * @param {string} name Name of sound. - */ - load(filenames: string[], name: string): void; - - /** - * Preload all the audio files so that they play quickly when asked for. - * @package - */ - preload(): void; - - /** - * Play a named sound at specified volume. If volume is not specified, - * use full volume (1). - * @param {string} name Name of sound. - * @param {number=} opt_volume Volume of sound (0-1). - */ - play(name: string, opt_volume?: number): void; - } - -} - - -declare module Blockly { - - class WorkspaceComment extends WorkspaceComment__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceComment__Class { - - /** - * Class for a workspace comment. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {string} content The content of this workspace comment. - * @param {number} height Height of the comment. - * @param {number} width Width of the comment. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @constructor - */ - constructor(workspace: Blockly.Workspace, content: string, height: number, width: number, opt_id?: string); - - /** @type {string} */ - id: string; - - /** - * The comment's position in workspace units. (0, 0) is at the workspace's - * origin; scale does not change this value. - * @type {!Blockly.utils.Coordinate} - * @protected - */ - xy_: Blockly.utils.Coordinate; - - /** - * @type {!Blockly.Workspace} - */ - workspace: Blockly.Workspace; - - /** - * @protected - * @type {boolean} - */ - RTL: boolean; - - /** - * @protected - * @type {string} - */ - content_: string; - - /** - * @package - * @type {boolean} - */ - isComment: boolean; - - /** - * Dispose of this comment. - * @package - */ - dispose(): void; - - /** - * Get comment height. - * @return {number} Comment height. - * @package - */ - getHeight(): number; - - /** - * Set comment height. - * @param {number} height Comment height. - * @package - */ - setHeight(height: number): void; - - /** - * Get comment width. - * @return {number} Comment width. - * @package - */ - getWidth(): number; - - /** - * Set comment width. - * @param {number} width comment width. - * @package - */ - setWidth(width: number): void; - - /** - * Get stored location. - * @return {!Blockly.utils.Coordinate} The comment's stored location. - * This is not valid if the comment is currently being dragged. - * @package - */ - getXY(): Blockly.utils.Coordinate; - - /** - * Move a comment by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - * @package - */ - moveBy(dx: number, dy: number): void; - - /** - * Get whether this comment is deletable or not. - * @return {boolean} True if deletable. - * @package - */ - isDeletable(): boolean; - - /** - * Set whether this comment is deletable or not. - * @param {boolean} deletable True if deletable. - * @package - */ - setDeletable(deletable: boolean): void; - - /** - * Get whether this comment is movable or not. - * @return {boolean} True if movable. - * @package - */ - isMovable(): boolean; - - /** - * Set whether this comment is movable or not. - * @param {boolean} movable True if movable. - * @package - */ - setMovable(movable: boolean): void; - - /** - * Get whether this comment is editable or not. - * @return {boolean} True if editable. - */ - isEditable(): boolean; - - /** - * Set whether this comment is editable or not. - * @param {boolean} editable True if editable. - */ - setEditable(editable: boolean): void; - - /** - * Returns this comment's text. - * @return {string} Comment text. - * @package - */ - getContent(): string; - - /** - * Set this comment's content. - * @param {string} content Comment content. - * @package - */ - setContent(content: string): void; - - /** - * Encode a comment subtree as XML with XY coordinates. - * @param {boolean=} opt_noId True if the encoder should skip the comment ID. - * @return {!Element} Tree of XML elements. - * @package - */ - toXmlWithXY(opt_noId?: boolean): Element; - - /** - * Encode a comment subtree as XML, but don't serialize the XY coordinates. - * This method avoids some expensive metrics-related calls that are made in - * toXmlWithXY(). - * @param {boolean=} opt_noId True if the encoder should skip the comment ID. - * @return {!Element} Tree of XML elements. - * @package - */ - toXml(opt_noId?: boolean): Element; - } - -} - -declare module Blockly.WorkspaceComment { +declare module WorkspaceComment { /** * Fire a create event for the given workspace comment, if comments are enabled. - * @param {!Blockly.WorkspaceComment} comment The comment that was just created. + * @param {!WorkspaceComment} comment The comment that was just created. * @package */ - function fireCreateEvent(comment: Blockly.WorkspaceComment): void; + function fireCreateEvent(comment: WorkspaceComment): void; /** * Decode an XML comment tag and create a comment on the workspace. * @param {!Element} xmlComment XML comment element. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Blockly.WorkspaceComment} The created workspace comment. + * @param {!Workspace} workspace The workspace. + * @return {!WorkspaceComment} The created workspace comment. * @package */ - function fromXml(xmlComment: Element, workspace: Blockly.Workspace): Blockly.WorkspaceComment; + function fromXml(xmlComment: Element, workspace: Workspace): WorkspaceComment; /** * Decode an XML comment tag and return the results in an object. @@ -11852,237 +1667,7 @@ declare module Blockly.WorkspaceComment { } - -declare module Blockly { - - class WorkspaceCommentSvg extends WorkspaceCommentSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceCommentSvg__Class extends Blockly.WorkspaceComment__Class implements Blockly.IBoundedElement, Blockly.IBubble, Blockly.ICopyable { - - /** - * Class for a workspace comment's SVG representation. - * @param {!Blockly.Workspace} workspace The block's workspace. - * @param {string} content The content of this workspace comment. - * @param {number} height Height of the comment. - * @param {number} width Width of the comment. - * @param {string=} opt_id Optional ID. Use this ID if provided, otherwise - * create a new ID. - * @extends {Blockly.WorkspaceComment} - * @implements {Blockly.IBoundedElement} - * @implements {Blockly.IBubble} - * @implements {Blockly.ICopyable} - * @constructor - */ - constructor(workspace: Blockly.Workspace, content: string, height: number, width: number, opt_id?: string); - - /** - * Dispose of this comment. - * @package - */ - dispose(): void; - - /** - * 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 - */ - initSvg(opt_noSelect?: boolean): void; - - /** - * Show the context menu for this workspace comment. - * @param {!Event} e Mouse event. - * @package - */ - showContextMenu(e: Event): void; - - /** - * Select this comment. Highlight it visually. - * @package - */ - select(): void; - - /** - * Unselect this comment. Remove its highlighting. - * @package - */ - unselect(): void; - - /** - * Select this comment. Highlight it visually. - * @package - */ - addSelect(): void; - - /** - * Unselect this comment. Remove its highlighting. - * @package - */ - removeSelect(): void; - - /** - * Focus this comment. Highlight it visually. - * @package - */ - addFocus(): void; - - /** - * Unfocus this comment. Remove its highlighting. - * @package - */ - removeFocus(): void; - - /** - * Return the coordinates of the top-left corner of this comment relative to - * the drawing surface's origin (0,0), in workspace units. - * If the comment is on the workspace, (0, 0) is the origin of the workspace - * coordinate system. - * This does not change with workspace scale. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties in - * workspace coordinates. - * @package - */ - getRelativeToSurfaceXY(): Blockly.utils.Coordinate; - - /** - * Move a comment by a relative offset. - * @param {number} dx Horizontal offset, in workspace units. - * @param {number} dy Vertical offset, in workspace units. - * @package - */ - moveBy(dx: number, dy: number): void; - - /** - * Transforms a comment by setting the translation on the transform attribute - * of the block's SVG. - * @param {number} x The x coordinate of the translation in workspace units. - * @param {number} y The y coordinate of the translation in workspace units. - * @package - */ - translate(x: number, y: number): void; - - /** - * Move this comment to its workspace's drag surface, accounting for - * positioning. Generally should be called at the same time as - * setDragging(true). Does nothing if useDragSurface_ is false. - * @package - */ - moveToDragSurface(): void; - - /** - * Move this comment during a drag, taking into account whether we are using a - * drag surface to translate blocks. - * @param {Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - * @package - */ - moveDuringDrag(dragSurface: Blockly.BlockDragSurfaceSvg, newLoc: Blockly.utils.Coordinate): void; - - /** - * Move the bubble group to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - * @package - */ - moveTo(x: number, y: number): void; - - /** - * Returns the coordinates of a bounding box describing the dimensions of this - * comment. - * Coordinate system: workspace coordinates. - * @return {!Blockly.utils.Rect} Object with coordinates of the bounding box. - * @package - */ - getBoundingRectangle(): Blockly.utils.Rect; - - /** - * Add or remove the UI indicating if this comment is movable or not. - * @package - */ - updateMovable(): void; - - /** - * Set whether this comment is movable or not. - * @param {boolean} movable True if movable. - * @package - */ - setMovable(movable: boolean): void; - - /** - * Set whether this comment is editable or not. - * @param {boolean} editable True if editable. - */ - setEditable(editable: boolean): void; - - /** - * Recursively adds or removes the dragging class to this node and its children. - * @param {boolean} adding True if adding, false if removing. - * @package - */ - setDragging(adding: boolean): void; - - /** - * Return the root node of the SVG or null if none exists. - * @return {!SVGElement} The root SVG node (probably a group). - * @package - */ - getSvgRoot(): SVGElement; - - /** - * Returns this comment's text. - * @return {string} Comment text. - * @package - */ - getContent(): string; - - /** - * Set this comment's content. - * @param {string} content Comment content. - * @package - */ - setContent(content: string): void; - - /** - * Update the cursor over this comment by adding or removing a class. - * @param {boolean} enable True if the delete cursor should be shown, false - * otherwise. - * @package - */ - setDeleteStyle(enable: boolean): void; - - /** - * Set whether auto-layout of this bubble is enabled. The first time a bubble - * is shown it positions itself to not cover any blocks. Once a user has - * dragged it to reposition, it renders where the user put it. - * @param {boolean} _enable True if auto-layout should be enabled, false - * otherwise. - * @package - */ - setAutoLayout(_enable: boolean): void; - - /** - * Encode a comment subtree as XML with XY coordinates. - * @param {boolean=} opt_noId True if the encoder should skip the comment ID. - * @return {!Element} Tree of XML elements. - * @package - */ - toXmlWithXY(opt_noId?: boolean): Element; - - /** - * Encode a comment for copying. - * @return {!Blockly.ICopyable.CopyData} Copy metadata. - * @package - */ - toCopyData(): Blockly.ICopyable.CopyData; - } - -} - -declare module Blockly.WorkspaceCommentSvg { +declare module WorkspaceCommentSvg { /** * The width and height to use to size a workspace comment when it is first @@ -12095,3148 +1680,82 @@ declare module Blockly.WorkspaceCommentSvg { /** * Decode an XML comment tag and create a rendered comment on the workspace. * @param {!Element} xmlComment XML comment element. - * @param {!Blockly.Workspace} workspace The workspace. + * @param {!WorkspaceSvg} workspace The workspace. * @param {number=} opt_wsWidth The width of the workspace, which is used to * position comments correctly in RTL. - * @return {!Blockly.WorkspaceCommentSvg} The created workspace comment. + * @return {!WorkspaceCommentSvg} The created workspace comment. * @package */ - function fromXml(xmlComment: Element, workspace: Blockly.Workspace, opt_wsWidth?: number): Blockly.WorkspaceCommentSvg; + function fromXml(xmlComment: Element, workspace: WorkspaceSvg, opt_wsWidth?: number): WorkspaceCommentSvg; } -declare module Blockly { - - class WorkspaceDragSurfaceSvg extends WorkspaceDragSurfaceSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceDragSurfaceSvg__Class { - - /** - * Blocks are moved into this SVG during a drag, improving performance. - * The entire SVG is translated using CSS transforms instead of SVG so the - * blocks are never repainted during drag improving performance. - * @param {!Element} container Containing element. - * @constructor - */ - constructor(container: Element); - - /** - * Dom structure when the workspace is being dragged. If there is no drag in - * progress, the SVG is empty and display: none. - * - * - * /g> - * - */ - SVG_: any /*missing*/; - - /** - * Create the drag surface and inject it into the container. - */ - createDom(): void; - - /** - * Translate the entire drag surface during a drag. - * We translate the drag surface instead of the blocks inside the surface - * so that the browser avoids repainting the SVG. - * Because of this, the drag coordinates must be adjusted by scale. - * @param {number} x X translation for the entire surface - * @param {number} y Y translation for the entire surface - * @package - */ - translateSurface(x: number, y: number): void; - - /** - * Reports the surface translation in scaled workspace coordinates. - * Use this when finishing a drag to return blocks to the correct position. - * @return {!Blockly.utils.Coordinate} Current translation of the surface - * @package - */ - getSurfaceTranslation(): Blockly.utils.Coordinate; - - /** - * Move the blockCanvas and bubbleCanvas out of the surface SVG and on to - * newSurface. - * @param {SVGElement} newSurface The element to put the drag surface contents - * into. - * @package - */ - clearAndHide(newSurface: SVGElement): void; - - /** - * Set the SVG to have the block canvas and bubble canvas in it and then - * show the surface. - * @param {!SVGElement} blockCanvas The block canvas element from the - * workspace. - * @param {!SVGElement} bubbleCanvas The element that contains the bubbles. - * @param {Element} previousSibling The element to insert the block canvas and - bubble canvas after when it goes back in the DOM at the end of a drag. - * @param {number} width The width of the workspace SVG element. - * @param {number} height The height of the workspace SVG element. - * @param {number} scale The scale of the workspace being dragged. - * @package - */ - setContentsAndShow(blockCanvas: SVGElement, bubbleCanvas: SVGElement, previousSibling: Element, width: number, height: number, scale: number): void; - } - -} -declare module Blockly { - - class WorkspaceDragger extends WorkspaceDragger__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceDragger__Class { - - /** - * Class for a workspace dragger. It moves the workspace around when it is - * being dragged by a mouse or touch. - * Note that the workspace itself manages whether or not it has a drag surface - * and how to do translations based on that. This simply passes the right - * commands based on events. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag. - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * The scroll position of the workspace at the beginning of the drag. - * Coordinate system: pixel coordinates. - * @type {!Blockly.utils.Coordinate} - * @protected - */ - startScrollXY_: Blockly.utils.Coordinate; - - /** - * Sever all links from this object. - * @package - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Start dragging the workspace. - * @package - */ - startDrag(): void; - - /** - * Finish dragging the workspace and put everything back where it belongs. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel coordinates. - * @package - */ - endDrag(currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Move the workspace based on the most recent mouse movements. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel coordinates. - * @package - */ - drag(currentDragDeltaXY: Blockly.utils.Coordinate): void; - } - -} -declare module Blockly { - - class WorkspaceSvg extends WorkspaceSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class WorkspaceSvg__Class extends Blockly.Workspace__Class implements Blockly.IASTNodeLocationSvg { - - /** - * Class for a workspace. This is an onscreen area with optional trashcan, - * scrollbars, bubbles, and dragging. - * @param {!Blockly.Options} options Dictionary of options. - * @param {Blockly.BlockDragSurfaceSvg=} opt_blockDragSurface Drag surface for - * blocks. - * @param {Blockly.WorkspaceDragSurfaceSvg=} opt_wsDragSurface Drag surface for - * the workspace. - * @extends {Blockly.Workspace} - * @implements {Blockly.IASTNodeLocationSvg} - * @constructor - */ - constructor(options: Blockly.Options, opt_blockDragSurface?: Blockly.BlockDragSurfaceSvg, opt_wsDragSurface?: Blockly.WorkspaceDragSurfaceSvg); - - /** - * Method to get all the metrics that have to do with a workspace. - * @type {function():!Blockly.utils.Metrics} - * @package - */ - getMetrics: { (): Blockly.utils.Metrics }; - - /** - * Translates the workspace. - * @type {function(!{x:number, y:number}):void} - * @package - */ - setMetrics: { (_0: { x: number; y: number }): void }; - - /** - * Object in charge of storing and updating the workspace theme. - * @type {!Blockly.ThemeManager} - * @protected - */ - themeManager_: Blockly.ThemeManager; - - /** - * True if keyboard accessibility mode is on, false otherwise. - * @type {boolean} - */ - keyboardAccessibilityMode: boolean; - - /** - * The render status of an SVG workspace. - * Returns `false` for headless workspaces and true for instances of - * `Blockly.WorkspaceSvg`. - * @type {boolean} - */ - rendered: boolean; - - /** - * Is this workspace the surface for a flyout? - * @type {boolean} - */ - isFlyout: boolean; - - /** - * Is this workspace the surface for a mutator? - * @type {boolean} - * @package - */ - isMutator: boolean; - - /** - * Current horizontal scrolling offset in pixel units, relative to the - * workspace origin. - * - * It is useful to think about a view, and a canvas moving beneath that - * view. As the canvas moves right, this value becomes more positive, and - * the view is now "seeing" the left side of the canvas. As the canvas moves - * left, this value becomes more negative, and the view is now "seeing" the - * right side of the canvas. - * - * The confusing thing about this value is that it does not, and must not - * include the absoluteLeft offset. This is because it is used to calculate - * the viewLeft value. - * - * The viewLeft is relative to the workspace origin (although in pixel - * units). The workspace origin is the top-left corner of the workspace (at - * least when it is enabled). It is shifted from the top-left of the blocklyDiv - * so as not to be beneath the toolbox. - * - * When the workspace is enabled the viewLeft and workspace origin are at - * the same X location. As the canvas slides towards the right beneath the view - * this value (scrollX) becomes more positive, and the viewLeft becomes more - * negative relative to the workspace origin (imagine the workspace origin - * as a dot on the canvas sliding to the right as the canvas moves). - * - * So if the scrollX were to include the absoluteLeft this would in a way - * "unshift" the workspace origin. This means that the viewLeft would be - * representing the left edge of the blocklyDiv, rather than the left edge - * of the workspace. - * - * @type {number} - */ - scrollX: number; - - /** - * Current vertical scrolling offset in pixel units, relative to the - * workspace origin. - * - * It is useful to think about a view, and a canvas moving beneath that - * view. As the canvas moves down, this value becomes more positive, and the - * view is now "seeing" the upper part of the canvas. As the canvas moves - * up, this value becomes more negative, and the view is "seeing" the lower - * part of the canvas. - * - * This confusing thing about this value is that it does not, and must not - * include the absoluteTop offset. This is because it is used to calculate - * the viewTop value. - * - * The viewTop is relative to the workspace origin (although in pixel - * units). The workspace origin is the top-left corner of the workspace (at - * least when it is enabled). It is shifted from the top-left of the - * blocklyDiv so as not to be beneath the toolbox. - * - * When the workspace is enabled the viewTop and workspace origin are at the - * same Y location. As the canvas slides towards the bottom this value - * (scrollY) becomes more positive, and the viewTop becomes more negative - * relative to the workspace origin (image in the workspace origin as a dot - * on the canvas sliding downwards as the canvas moves). - * - * So if the scrollY were to include the absoluteTop this would in a way - * "unshift" the workspace origin. This means that the viewTop would be - * representing the top edge of the blocklyDiv, rather than the top edge of - * the workspace. - * - * @type {number} - */ - scrollY: number; - - /** - * Horizontal scroll value when scrolling started in pixel units. - * @type {number} - */ - startScrollX: number; - - /** - * Vertical scroll value when scrolling started in pixel units. - * @type {number} - */ - startScrollY: number; - - /** - * Current scale. - * @type {number} - */ - scale: number; - - /** @type {Blockly.Trashcan} */ - trashcan: Blockly.Trashcan; - - /** - * This workspace's scrollbars, if they exist. - * @type {Blockly.ScrollbarPair} - */ - scrollbar: Blockly.ScrollbarPair; - - /** - * Developers may define this function to add custom menu options to the - * workspace's context menu or edit the workspace-created set of menu options. - * @param {!Array} options List of menu options to add to. - * @param {!Event} e The right-click event that triggered the context menu. - */ - configureContextMenu(options: Object[], e: Event): void; - - /** - * In a flyout, the target workspace where blocks should be placed after a drag. - * Otherwise null. - * @type {Blockly.WorkspaceSvg} - * @package - */ - targetWorkspace: Blockly.WorkspaceSvg; - - /** - * Get the marker manager for this workspace. - * @return {!Blockly.MarkerManager} The marker manager. - */ - getMarkerManager(): Blockly.MarkerManager; - - /** - * Gets the metrics manager for this workspace. - * @return {!Blockly.IMetricsManager} The metrics manager. - * @public - */ - getMetricsManager(): Blockly.IMetricsManager; - - /** - * Sets the metrics manager for the workspace. - * @param {!Blockly.IMetricsManager} metricsManager The metrics manager. - * @package - */ - setMetricsManager(metricsManager: Blockly.IMetricsManager): void; - - /** - * Gets the component manager for this workspace. - * @return {!Blockly.ComponentManager} The component manager. - * @public - */ - getComponentManager(): Blockly.ComponentManager; - - /** - * Add the cursor SVG to this workspaces SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * workspace SVG group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this workspaces SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * workspace SVG group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Get the marker with the given ID. - * @param {string} id The ID of the marker. - * @return {?Blockly.Marker} The marker with the given ID or null if no marker - * with the given ID exists. - * @package - */ - getMarker(id: string): Blockly.Marker; - - /** - * The cursor for this workspace. - * @return {?Blockly.Cursor} The cursor for the workspace. - */ - getCursor(): Blockly.Cursor; - - /** - * Get the block renderer attached to this workspace. - * @return {!Blockly.blockRendering.Renderer} The renderer attached to this - * workspace. - */ - getRenderer(): Blockly.blockRendering.Renderer; - - /** - * Get the theme manager for this workspace. - * @return {!Blockly.ThemeManager} The theme manager for this workspace. - * @package - */ - getThemeManager(): Blockly.ThemeManager; - - /** - * Get the workspace theme object. - * @return {!Blockly.Theme} The workspace theme object. - */ - getTheme(): Blockly.Theme; - - /** - * Set the workspace theme object. - * If no theme is passed, default to the `Blockly.Themes.Classic` theme. - * @param {Blockly.Theme} theme The workspace theme object. - */ - setTheme(theme: Blockly.Theme): void; - - /** - * Refresh all blocks on the workspace after a theme update. - * @package - */ - refreshTheme(): void; - - /** - * Getter for the inverted screen CTM. - * @return {?SVGMatrix} The matrix to use in mouseToSvg - */ - getInverseScreenCTM(): SVGMatrix; - - /** - * Mark the inverse screen CTM as dirty. - */ - updateInverseScreenCTM(): void; - - /** - * Getter for isVisible - * @return {boolean} Whether the workspace is visible. - * False if the workspace has been hidden by calling `setVisible(false)`. - */ - isVisible(): boolean; - - /** - * Return the absolute coordinates of the top-left corner of this element, - * scales that after canvas SVG element, if it's a descendant. - * The origin (0,0) is the top-left corner of the Blockly SVG. - * @param {!SVGElement} element SVG element to find the coordinates of. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - * @package - */ - getSvgXY(element: SVGElement): Blockly.utils.Coordinate; - - /** - * Gets the size of the workspace's parent SVG element. - * @return {!Blockly.utils.Size} The cached width and height of the workspace's - * parent SVG element. - * @package - */ - getCachedParentSvgSize(): Blockly.utils.Size; - - /** - * Return the position of the workspace origin relative to the injection div - * origin in pixels. - * The workspace origin is where a block would render at position (0, 0). - * It is not the upper left corner of the workspace SVG. - * @return {!Blockly.utils.Coordinate} Offset in pixels. - * @package - */ - getOriginOffsetInPixels(): Blockly.utils.Coordinate; - - /** - * Return the injection div that is a parent of this workspace. - * Walks the DOM the first time it's called, then returns a cached value. - * Note: We assume this is only called after the workspace has been injected - * into the DOM. - * @return {!Element} The first parent div with 'injectionDiv' in the name. - * @package - */ - getInjectionDiv(): Element; - - /** - * Get the SVG block canvas for the workspace. - * @return {?SVGElement} The SVG group for the workspace. - * @package - */ - getBlockCanvas(): SVGElement; - - /** - * Save resize handler data so we can delete it later in dispose. - * @param {!Blockly.browserEvents.Data} handler Data that can be passed to - * eventHandling.unbind. - */ - setResizeHandlerWrapper(handler: Blockly.browserEvents.Data): void; - - /** - * Create the workspace DOM elements. - * @param {string=} opt_backgroundClass Either 'blocklyMainBackground' or - * 'blocklyMutatorBackground'. - * @return {!Element} The workspace's SVG group. - */ - createDom(opt_backgroundClass?: string): Element; - - /** - * - * - * [Trashcan and/or flyout may go here] - * - * - * - * @type {SVGElement} - */ - svgGroup_: SVGElement; - - /** @type {SVGElement} */ - svgBackground_: SVGElement; - - /** @type {SVGElement} */ - svgBlockCanvas_: SVGElement; - - /** @type {SVGElement} */ - svgBubbleCanvas_: SVGElement; - - /** - * Dispose of this workspace. - * Unlink from all DOM elements to prevent memory leaks. - * @suppress {checkTypes} - */ - dispose(): void; - - /** - * Add a trashcan. - * @package - */ - addTrashcan(): void; - - /** - * Add zoom controls. - * @package - */ - addZoomControls(): void; - - /** @type {Blockly.ZoomControls} */ - zoomControls_: Blockly.ZoomControls; - - /** - * Add a flyout element in an element with the given tag name. - * @param {string| - * !Blockly.utils.Svg| - * !Blockly.utils.Svg} tagName What type of tag the - * flyout belongs in. - * @return {!Element} The element containing the flyout DOM. - * @package - */ - addFlyout(tagName: string|Blockly.utils.Svg|Blockly.utils.Svg): Element; - - /** - * Getter for the flyout associated with this workspace. This flyout may be - * owned by either the toolbox or the workspace, depending on toolbox - * configuration. It will be null if there is no flyout. - * @param {boolean=} opt_own Whether to only return the workspace's own flyout. - * @return {?Blockly.IFlyout} The flyout on this workspace. - * @package - */ - getFlyout(opt_own?: boolean): Blockly.IFlyout; - - /** - * Getter for the toolbox associated with this workspace, if one exists. - * @return {?Blockly.IToolbox} The toolbox on this workspace. - * @package - */ - getToolbox(): Blockly.IToolbox; - - /** - * If enabled, resize the parts of the workspace that change when the workspace - * contents (e.g. block positions) change. This will also scroll the - * workspace contents if needed. - * @package - */ - resizeContents(): void; - - /** - * Resize and reposition all of the workspace chrome (toolbox, - * trash, scrollbars etc.) - * This should be called when something changes that - * requires recalculating dimensions and positions of the - * trash, zoom, toolbox, etc. (e.g. window resize). - */ - resize(): void; - - /** - * Resizes and repositions workspace chrome if the page has a new - * scroll position. - * @package - */ - updateScreenCalculationsIfScrolled(): void; - - /** - * Get the SVG element that forms the drawing surface. - * @return {!SVGGElement} SVG group element. - */ - getCanvas(): SVGGElement; - - /** - * Caches the width and height of the workspace's parent SVG element for use - * with getSvgMetrics. - * @param {?number} width The width of the parent SVG element. - * @param {?number} height The height of the parent SVG element - * @package - */ - setCachedParentSvgSize(width: number, height: number): void; - - /** - * Get the SVG element that forms the bubble surface. - * @return {!SVGGElement} SVG group element. - */ - getBubbleCanvas(): SVGGElement; - - /** - * Get the SVG element that contains this workspace. - * Note: We assume this is only called after the workspace has been injected - * into the DOM. - * @return {!SVGElement} SVG element. - */ - getParentSvg(): SVGElement; - - /** - * Fires a viewport event if events are enabled and there is a change in - * viewport values. - * @package - */ - maybeFireViewportChangeEvent(): void; - - /** - * Translate this workspace to new coordinates. - * @param {number} x Horizontal translation, in pixel units relative to the - * top left of the Blockly div. - * @param {number} y Vertical translation, in pixel units relative to the - * top left of the Blockly div. - */ - translate(x: number, y: number): void; - - /** - * Called at the end of a workspace drag to take the contents - * out of the drag surface and put them back into the workspace SVG. - * Does nothing if the workspace drag surface is not enabled. - * @package - */ - resetDragSurface(): void; - - /** - * Called at the beginning of a workspace drag to move contents of - * the workspace to the drag surface. - * Does nothing if the drag surface is not enabled. - * @package - */ - setupDragSurface(): void; - - /** - * Gets the drag surface blocks are moved to when a drag is started. - * @return {?Blockly.BlockDragSurfaceSvg} This workspace's block drag surface, - * if one is in use. - * @package - */ - getBlockDragSurface(): Blockly.BlockDragSurfaceSvg; - - /** - * Returns the horizontal offset of the workspace. - * Intended for LTR/RTL compatibility in XML. - * @return {number} Width. - */ - getWidth(): number; - - /** - * Toggles the visibility of the workspace. - * Currently only intended for main workspace. - * @param {boolean} isVisible True if workspace should be visible. - */ - setVisible(isVisible: boolean): void; - - /** - * Render all blocks in workspace. - */ - render(): void; - - /** - * Highlight or unhighlight a block in the workspace. Block highlighting is - * often used to visually mark blocks currently being executed. - * @param {?string} id ID of block to highlight/unhighlight, - * or null for no block (used to unhighlight all blocks). - * @param {boolean=} opt_state If undefined, highlight specified block and - * automatically unhighlight all others. If true or false, manually - * highlight/unhighlight the specified block. - */ - highlightBlock(id: string, opt_state?: boolean): void; - - /** - * Paste the provided block onto the workspace. - * @param {!Element|!DocumentFragment} xmlBlock XML block element or an empty - * DocumentFragment if the block was an insertion marker. - */ - paste(xmlBlock: Element|DocumentFragment): void; - - /** - * Refresh the toolbox unless there's a drag in progress. - * @package - */ - refreshToolboxSelection(): void; - - /** - * Rename a variable by updating its name in the variable map. Update the - * flyout to show the renamed variable immediately. - * @param {string} id ID of the variable to rename. - * @param {string} newName New variable name. - */ - renameVariableById(id: string, newName: string): void; - - /** - * Delete a variable by the passed in ID. Update the flyout to show - * immediately that the variable is deleted. - * @param {string} id ID of variable to delete. - */ - deleteVariableById(id: string): void; - - /** - * Create a new variable with the given name. Update the flyout to show the - * new variable immediately. - * @param {string} name The new variable's name. - * @param {?string=} opt_type The type of the variable like 'int' or 'string'. - * Does not need to be unique. Field_variable can filter variables based on - * their type. This will default to '' which is a specific type. - * @param {?string=} opt_id The unique ID of the variable. This will default to - * a UUID. - * @return {!Blockly.VariableModel} The newly created variable. - */ - createVariable(name: string, opt_type?: string, opt_id?: string): Blockly.VariableModel; - - /** - * Make a list of all the delete areas for this workspace. - * @deprecated Use workspace.recordDragTargets. (2021 June) - */ - recordDeleteAreas(): void; - - /** - * Make a list of all the delete areas for this workspace. - */ - recordDragTargets(): void; - - /** - * Returns the drag target the mouse event is over. - * @param {!Event} e Mouse move event. - * @return {?Blockly.IDragTarget} Null if not over a drag target, or the drag - * target the event is over. - */ - getDragTarget(e: Event): Blockly.IDragTarget; - - /** - * Start tracking a drag of an object on this workspace. - * @param {!Event} e Mouse down event. - * @param {!Blockly.utils.Coordinate} xy Starting location of object. - */ - startDrag(e: Event, xy: Blockly.utils.Coordinate): void; - - /** - * Track a drag of an object on this workspace. - * @param {!Event} e Mouse move event. - * @return {!Blockly.utils.Coordinate} New location of object. - */ - moveDrag(e: Event): Blockly.utils.Coordinate; - - /** - * Is the user currently dragging a block or scrolling the flyout/workspace? - * @return {boolean} True if currently dragging or scrolling. - */ - isDragging(): boolean; - - /** - * Is this workspace draggable? - * @return {boolean} True if this workspace may be dragged. - */ - isDraggable(): boolean; - - /** - * Is this workspace movable? - * - * This means the user can reposition the X Y coordinates of the workspace - * through input. This can be through scrollbars, scroll wheel, dragging, or - * through zooming with the scroll wheel or pinch (since the zoom is centered on - * the mouse position). This does not include zooming with the zoom controls - * since the X Y coordinates are decided programmatically. - * @return {boolean} True if the workspace is movable, false otherwise. - */ - isMovable(): boolean; - - /** - * Is this workspace movable horizontally? - * @return {boolean} True if the workspace is movable horizontally, false - * otherwise. - */ - isMovableHorizontally(): boolean; - - /** - * Is this workspace movable vertically? - * @return {boolean} True if the workspace is movable vertically, false - * otherwise. - */ - isMovableVertically(): boolean; - - /** - * Calculate the bounding box for the blocks on the workspace. - * Coordinate system: workspace coordinates. - * - * @return {!Blockly.utils.Rect} Contains the position and size of the - * bounding box containing the blocks on the workspace. - */ - getBlocksBoundingBox(): Blockly.utils.Rect; - - /** - * Clean up the workspace by ordering all the blocks in a column. - */ - cleanUp(): void; - - /** - * Show the context menu for the workspace. - * @param {!Event} e Mouse event. - * @package - */ - showContextMenu(e: Event): void; - - /** - * Modify the block tree on the existing toolbox. - * @param {?Blockly.utils.toolbox.ToolboxDefinition} toolboxDef - * DOM tree of toolbox contents, string of toolbox contents, or JSON - * representing toolbox definition. - */ - updateToolbox(toolboxDef: Blockly.utils.toolbox.ToolboxDefinition): void; - - /** - * Mark this workspace as the currently focused main workspace. - */ - markFocused(): void; - - /** - * Zooms the workspace in or out relative to/centered on the given (x, y) - * coordinate. - * @param {number} x X coordinate of center, in pixel units relative to the - * top-left corner of the parentSVG. - * @param {number} y Y coordinate of center, in pixel units relative to the - * top-left corner of the parentSVG. - * @param {number} amount Amount of zooming. The formula for the new scale - * is newScale = currentScale * (scaleSpeed^amount). scaleSpeed is set in - * the workspace options. Negative amount values zoom out, and positive - * amount values zoom in. - */ - zoom(x: number, y: number, amount: number): void; - - /** - * Zooming the blocks centered in the center of view with zooming in or out. - * @param {number} type Type of zooming (-1 zooming out and 1 zooming in). - */ - zoomCenter(type: number): void; - - /** - * Zoom the blocks to fit in the workspace if possible. - */ - zoomToFit(): void; - - /** - * Add a transition class to the block and bubble canvas, to animate any - * transform changes. - * @package - */ - beginCanvasTransition(): void; - - /** - * Remove transition class from the block and bubble canvas. - * @package - */ - endCanvasTransition(): void; - - /** - * Center the workspace. - */ - scrollCenter(): void; - - /** - * Scroll the workspace to center on the given block. - * @param {?string} id ID of block center on. - * @public - */ - centerOnBlock(id: string): void; - - /** - * Set the workspace's zoom factor. - * @param {number} newScale Zoom factor. Units: (pixels / workspaceUnit). - */ - setScale(newScale: number): void; - - /** - * Get the workspace's zoom factor. If the workspace has a parent, we call into - * the parent to get the workspace scale. - * @return {number} The workspace zoom factor. Units: (pixels / workspaceUnit). - */ - getScale(): number; - - /** - * Scroll the workspace to a specified offset (in pixels), keeping in the - * workspace bounds. See comment on workspaceSvg.scrollX for more detail on - * the meaning of these values. - * @param {number} x Target X to scroll to. - * @param {number} y Target Y to scroll to. - * @package - */ - scroll(x: number, y: number): void; - - /** - * Adds a block to the list of top blocks. - * @param {!Blockly.Block} block Block to add. - */ - addTopBlock(block: Blockly.Block): void; - - /** - * Removes a block from the list of top blocks. - * @param {!Blockly.Block} block Block to remove. - */ - removeTopBlock(block: Blockly.Block): void; - - /** - * Adds a comment to the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to add. - */ - addTopComment(comment: Blockly.WorkspaceComment): void; - - /** - * Removes a comment from the list of top comments. - * @param {!Blockly.WorkspaceComment} comment comment to remove. - */ - removeTopComment(comment: Blockly.WorkspaceComment): void; - - /** - * Adds a bounded element to the list of top bounded elements. - * @param {!Blockly.IBoundedElement} element Bounded element to add. - */ - addTopBoundedElement(element: Blockly.IBoundedElement): void; - - /** - * Removes a bounded element from the list of top bounded elements. - * @param {!Blockly.IBoundedElement} element Bounded element to remove. - */ - removeTopBoundedElement(element: Blockly.IBoundedElement): void; - - /** - * Finds the top-level bounded elements and returns them. - * @return {!Array} The top-level bounded elements. - */ - getTopBoundedElements(): Blockly.IBoundedElement[]; - - /** - * Update whether this workspace has resizes enabled. - * If enabled, workspace will resize when appropriate. - * If disabled, workspace will not resize until re-enabled. - * Use to avoid resizing during a batch operation, for performance. - * @param {boolean} enabled Whether resizes should be enabled. - */ - setResizesEnabled(enabled: boolean): void; - - /** - * Dispose of all blocks in workspace, with an optimization to prevent resizes. - */ - clear(): void; - - /** - * Register a callback function associated with a given key, for clicks on - * buttons and labels in the flyout. - * For instance, a button specified by the XML - * - * should be matched by a call to - * registerButtonCallback("CREATE_VARIABLE", yourCallbackFunction). - * @param {string} key The name to use to look up this function. - * @param {function(!Blockly.FlyoutButton)} func The function to call when the - * given button is clicked. - */ - registerButtonCallback(key: string, func: { (_0: Blockly.FlyoutButton): any /*missing*/ }): void; - - /** - * Get the callback function associated with a given key, for clicks on buttons - * and labels in the flyout. - * @param {string} key The name to use to look up the function. - * @return {?function(!Blockly.FlyoutButton)} The function corresponding to the - * given key for this workspace; null if no callback is registered. - */ - getButtonCallback(key: string): { (_0: Blockly.FlyoutButton): any /*missing*/ }; - - /** - * Remove a callback for a click on a button in the flyout. - * @param {string} key The name associated with the callback function. - */ - removeButtonCallback(key: string): void; - - /** - * Register a callback function associated with a given key, for populating - * custom toolbox categories in this workspace. See the variable and procedure - * categories as an example. - * @param {string} key The name to use to look up this function. - * @param {function(!Blockly.Workspace):!Array} func The function to - * call when the given toolbox category is opened. - */ - registerToolboxCategoryCallback(key: string, func: { (_0: Blockly.Workspace): Element[] }): void; - - /** - * Get the callback function associated with a given key, for populating - * custom toolbox categories in this workspace. - * @param {string} key The name to use to look up the function. - * @return {?function(!Blockly.Workspace):!Array} The function - * corresponding to the given key for this workspace, or null if no function - * is registered. - */ - getToolboxCategoryCallback(key: string): { (_0: Blockly.Workspace): Element[] }; - - /** - * Remove a callback for a click on a custom category's name in the toolbox. - * @param {string} key The name associated with the callback function. - */ - removeToolboxCategoryCallback(key: string): void; - - /** - * Look up the gesture that is tracking this touch stream on this workspace. - * May create a new gesture. - * @param {!Event} e Mouse event or touch event. - * @return {?Blockly.TouchGesture} The gesture that is tracking this touch - * stream, or null if no valid gesture exists. - * @package - */ - getGesture(e: Event): Blockly.TouchGesture; - - /** - * Clear the reference to the current gesture. - * @package - */ - clearGesture(): void; - - /** - * Cancel the current gesture, if one exists. - * @package - */ - cancelCurrentGesture(): void; - - /** - * Get the audio manager for this workspace. - * @return {!Blockly.WorkspaceAudio} The audio manager for this workspace. - */ - getAudioManager(): Blockly.WorkspaceAudio; - - /** - * Get the grid object for this workspace, or null if there is none. - * @return {?Blockly.Grid} The grid object for this workspace. - * @package - */ - getGrid(): Blockly.Grid; - } - -} -declare module Blockly.Xml { + + +declare module BlockChange { /** - * Encode a block tree as XML. - * @param {!Blockly.Workspace} workspace The workspace containing blocks. - * @param {boolean=} opt_noId True if the encoder should skip the block IDs. - * @return {!Element} XML DOM element. - */ - function workspaceToDom(workspace: Blockly.Workspace, opt_noId?: boolean): Element; - - /** - * Encode a list of variables as XML. - * @param {!Array} variableList List of all variable - * models. - * @return {!Element} Tree of XML elements. - */ - function variablesToDom(variableList: Blockly.VariableModel[]): Element; - - /** - * Encode a block subtree as XML with XY coordinates. - * @param {!Blockly.Block} block The root block to encode. - * @param {boolean=} opt_noId True if the encoder should skip the block ID. - * @return {!Element|!DocumentFragment} Tree of XML elements or an empty document - * fragment if the block was an insertion marker. - */ - function blockToDomWithXY(block: Blockly.Block, opt_noId?: boolean): Element|DocumentFragment; - - /** - * Encode a block subtree as XML. - * @param {!Blockly.Block} block The root block to encode. - * @param {boolean=} opt_noId True if the encoder should skip the block ID. - * @return {!Element|!DocumentFragment} Tree of XML elements or an empty document - * fragment if the block was an insertion marker. - */ - function blockToDom(block: Blockly.Block, opt_noId?: boolean): Element|DocumentFragment; - - /** - * Converts a DOM structure into plain text. - * Currently the text format is fairly ugly: all one line with no whitespace, - * unless the DOM itself has whitespace built-in. - * @param {!Node} dom A tree of XML nodes. - * @return {string} Text representation. - */ - function domToText(dom: Node): string; - - /** - * Converts a DOM structure into properly indented text. - * @param {!Node} dom A tree of XML elements. - * @return {string} Text representation. - */ - function domToPrettyText(dom: Node): string; - - /** - * Converts an XML string into a DOM structure. - * @param {string} text An XML string. - * @return {!Element} A DOM object representing the singular child of the - * document element. - * @throws if the text doesn't parse. - */ - function textToDom(text: string): Element; - - /** - * Clear the given workspace then decode an XML DOM and - * create blocks on the workspace. - * @param {!Element} xml XML DOM. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Array} An array containing new block IDs. - */ - function clearWorkspaceAndLoadFromXml(xml: Element, workspace: Blockly.Workspace): string[]; - - /** - * Decode an XML DOM and create blocks on the workspace. - * @param {!Element} xml XML DOM. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Array} An array containing new block IDs. - * @suppress {strictModuleDepCheck} Suppress module check while workspace - * comments are not bundled in. - */ - function domToWorkspace(xml: Element, workspace: Blockly.Workspace): string[]; - - /** - * Decode an XML DOM and create blocks on the workspace. Position the new - * blocks immediately below prior blocks, aligned by their starting edge. - * @param {!Element} xml The XML DOM. - * @param {!Blockly.Workspace} workspace The workspace to add to. - * @return {!Array} An array containing new block IDs. - */ - function appendDomToWorkspace(xml: Element, workspace: Blockly.Workspace): string[]; - - /** - * Decode an XML block tag and create a block (and possibly sub blocks) on the - * workspace. - * @param {!Element} xmlBlock XML block element. - * @param {!Blockly.Workspace} workspace The workspace. - * @return {!Blockly.Block} The root block created. - */ - function domToBlock(xmlBlock: Element, workspace: Blockly.Workspace): Blockly.Block; - - /** - * Decode an XML list of variables and add the variables to the workspace. - * @param {!Element} xmlVariables List of XML variable elements. - * @param {!Blockly.Workspace} workspace The workspace to which the variable - * should be added. - */ - function domToVariables(xmlVariables: Element, workspace: Blockly.Workspace): void; - - /** - * A mapping of nodeName to node for child nodes of xmlBlock. - * @typedef {{ - * mutation: !Array, - * comment: !Array, - * data: !Array, - * field: !Array, - * input: !Array, - * next: !Array - * }} - */ - interface childNodeTagMap { - mutation: Element[]; - comment: Element[]; - data: Element[]; - field: Element[]; - input: Element[]; - next: Element[] - } - - /** - * Creates a mapping of childNodes for each supported XML tag for the provided - * xmlBlock. Logs a warning for any encountered unsupported tags. - * @param {!Element} xmlBlock XML block element. - * @return {!Blockly.Xml.childNodeTagMap} The childNode map from nodeName to - * node. - */ - function mapSupportedXmlTags_(xmlBlock: Element): Blockly.Xml.childNodeTagMap; - - /** - * Remove any 'next' block (statements in a stack). - * @param {!Element|!DocumentFragment} xmlBlock XML block element or an empty - * DocumentFragment if the block was an insertion marker. - */ - function deleteNext(xmlBlock: Element|DocumentFragment): void; -} - - -declare module Blockly { - - class ZoomControls extends ZoomControls__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ZoomControls__Class implements Blockly.IPositionable { - - /** - * Class for a zoom controls. - * @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in. - * @constructor - * @implements {Blockly.IPositionable} - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * The unique id for this component that is used to register with the - * ComponentManager. - * @type {string} - */ - id: string; - - /** - * Create the zoom controls. - * @return {!SVGElement} The zoom controls SVG group. - */ - createDom(): SVGElement; - - /** - * Initializes the zoom controls. - */ - init(): void; - - /** - * Disposes of this zoom controls. - * Unlink from all DOM elements to prevent memory leaks. - */ - dispose(): void; - - /** - * Returns the bounding rectangle of the UI element in pixel units relative to - * the Blockly injection div. - * @return {?Blockly.utils.Rect} The UI elements’s bounding box. Null if - * bounding box should be ignored by other UI elements. - */ - getBoundingRectangle(): Blockly.utils.Rect; - - /** - * Positions the zoom controls. - * It is positioned in the opposite corner to the corner the - * categories/toolbox starts at. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics. - * @param {!Array} savedPositions List of rectangles that - * are already on the workspace. - */ - position(metrics: Blockly.MetricsManager.UiMetrics, savedPositions: Blockly.utils.Rect[]): void; - } - -} - - -declare module Blockly.Events { - - class BlockBase extends BlockBase__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockBase__Class extends Blockly.Events.Abstract__Class { - - /** - * Abstract class for a block event. - * @param {!Blockly.Block=} opt_block The block this event corresponds to. - * Undefined for a blank event. - * @extends {Blockly.Events.Abstract} - * @constructor - */ - constructor(opt_block?: Blockly.Block); - - /** - * The block ID for the block this event pertains to - * @type {string} - */ - blockId: string; - - /** - * The workspace identifier for this event. - * @type {string} - */ - workspaceId: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - - - class BlockChange extends BlockChange__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockChange__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block change event. - * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank - * event. - * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. - * @param {?string=} opt_name Name of input or field affected, or null. - * @param {*=} opt_oldValue Previous value of element. - * @param {*=} opt_newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block, opt_element?: string, opt_name?: string, opt_oldValue?: any, opt_newValue?: any); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ - isNull(): boolean; - - /** - * Run a change event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class Change extends Change__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Change__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block change event. - * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank - * event. - * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. - * @param {?string=} opt_name Name of input or field affected, or null. - * @param {*=} opt_oldValue Previous value of element. - * @param {*=} opt_newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block, opt_element?: string, opt_name?: string, opt_oldValue?: any, opt_newValue?: any); - } - - - class Create extends Create__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Create__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block creation event. - * @param {!Blockly.Block=} opt_block The created block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class BlockCreate extends BlockCreate__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockCreate__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block creation event. - * @param {!Blockly.Block=} block The created block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(block?: Blockly.Block); - } - - - class Delete extends Delete__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Delete__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block deletion event. - * @param {!Blockly.Block=} opt_block The deleted block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a deletion event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class BlockDelete extends BlockDelete__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockDelete__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block deletion event. - * @param {?Blockly.Block} block The deleted block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(block: Blockly.Block); - } - - - class Move extends Move__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Move__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block move event. Created before the move. - * @param {!Blockly.Block=} opt_block The moved block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Record the block's new location. Called after the move. - */ - recordNew(): void; - - /** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ - isNull(): boolean; - - /** - * Run a move event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class BlockMove extends BlockMove__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockMove__Class extends Blockly.Events.BlockBase__Class { - - /** - * Class for a block move event. Created before the move. - * @param {?Blockly.Block} block The moved block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ - constructor(block: Blockly.Block); - } - -} - - -declare module Blockly.Events { - - /** - * Sets whether the next event should be added to the undo stack. - * @type {boolean} - */ - var recordUndo: boolean; - - /** - * Name of event that creates a block. Will be deprecated for BLOCK_CREATE. - * @const - */ - var CREATE: any /*missing*/; - - /** - * Name of event that creates a block. - * @const - */ - var BLOCK_CREATE: any /*missing*/; - - /** - * Name of event that deletes a block. Will be deprecated for BLOCK_DELETE. - * @const - */ - var DELETE: any /*missing*/; - - /** - * Name of event that deletes a block. - * @const - */ - var BLOCK_DELETE: any /*missing*/; - - /** - * Name of event that changes a block. Will be deprecated for BLOCK_CHANGE. - * @const - */ - var CHANGE: any /*missing*/; - - /** - * Name of event that changes a block. - * @const - */ - var BLOCK_CHANGE: any /*missing*/; - - /** - * Name of event that moves a block. Will be deprecated for BLOCK_MOVE. - * @const - */ - var MOVE: any /*missing*/; - - /** - * Name of event that moves a block. - * @const - */ - var BLOCK_MOVE: any /*missing*/; - - /** - * Name of event that creates a variable. - * @const - */ - var VAR_CREATE: any /*missing*/; - - /** - * Name of event that deletes a variable. - * @const - */ - var VAR_DELETE: any /*missing*/; - - /** - * Name of event that renames a variable. - * @const - */ - var VAR_RENAME: any /*missing*/; - - /** - * Name of generic event that records a UI change. - * @const - */ - var UI: any /*missing*/; - - /** - * Name of event that record a block drags a block. - * @const - */ - var BLOCK_DRAG: any /*missing*/; - - /** - * Name of event that records a change in selected element. - * @const - */ - var SELECTED: any /*missing*/; - - /** - * Name of event that records a click. - * @const - */ - var CLICK: any /*missing*/; - - /** - * Name of event that records a marker move. - * @const - */ - var MARKER_MOVE: any /*missing*/; - - /** - * Name of event that records a bubble open. - * @const - */ - var BUBBLE_OPEN: any /*missing*/; - - /** - * Name of event that records a trashcan open. - * @const - */ - var TRASHCAN_OPEN: any /*missing*/; - - /** - * Name of event that records a toolbox item select. - * @const - */ - var TOOLBOX_ITEM_SELECT: any /*missing*/; - - /** - * Name of event that records a theme change. - * @const - */ - var THEME_CHANGE: any /*missing*/; - - /** - * Name of event that records a viewport change. - * @const - */ - var VIEWPORT_CHANGE: any /*missing*/; - - /** - * Name of event that creates a comment. - * @const - */ - var COMMENT_CREATE: any /*missing*/; - - /** - * Name of event that deletes a comment. - * @const - */ - var COMMENT_DELETE: any /*missing*/; - - /** - * Name of event that changes a comment. - * @const - */ - var COMMENT_CHANGE: any /*missing*/; - - /** - * Name of event that moves a comment. - * @const - */ - var COMMENT_MOVE: any /*missing*/; - - /** - * Name of event that records a workspace load. - */ - var FINISHED_LOADING: any /*missing*/; - - /** - * Type of events that cause objects to be bumped back into the visible - * portion of the workspace. - * - * Not to be confused with bumping so that disconnected connections do not - * appear connected. - * @typedef {!Blockly.Events.BlockCreate|!Blockly.Events.BlockMove| - * !Blockly.Events.CommentCreate|!Blockly.Events.CommentMove} - */ - type BumpEvent = Blockly.Events.BlockCreate|Blockly.Events.BlockMove|Blockly.Events.CommentCreate|Blockly.Events.CommentMove; - - /** - * List of events that cause objects to be bumped back into the visible - * portion of the workspace. - * - * Not to be confused with bumping so that disconnected connections do not - * appear connected. - * @const - */ - var BUMP_EVENTS: any /*missing*/; - - /** - * Create a custom event and fire it. - * @param {!Blockly.Events.Abstract} event Custom data for event. - */ - function fire(event: Blockly.Events.Abstract): void; - - /** - * Filter the queued events and merge duplicates. - * @param {!Array} queueIn Array of events. - * @param {boolean} forward True if forward (redo), false if backward (undo). - * @return {!Array} Array of filtered events. - */ - function filter(queueIn: Blockly.Events.Abstract[], forward: boolean): Blockly.Events.Abstract[]; - - /** - * Modify pending undo events so that when they are fired they don't land - * in the undo stack. Called by Blockly.Workspace.clearUndo. - */ - function clearPendingUndo(): void; - - /** - * Stop sending events. Every call to this function MUST also call enable. - */ - function disable(): void; - - /** - * Start sending events. Unless events were already disabled when the - * corresponding call to disable was made. - */ - function enable(): void; - - /** - * Returns whether events may be fired or not. - * @return {boolean} True if enabled. - */ - function isEnabled(): boolean; - - /** - * Current group. - * @return {string} ID string. - */ - function getGroup(): string; - - /** - * Start or stop a group. - * @param {boolean|string} state True to start new group, false to end group. - * String to set group explicitly. - */ - function setGroup(state: boolean|string): void; - - /** - * Compute a list of the IDs of the specified block and all its descendants. - * @param {!Blockly.Block} block The root block. - * @return {!Array} List of block IDs. + * Returns the extra state of the given block (either as XML or a JSO, depending + * on the block's definition). + * @param {!BlockSvg} block The block to get the extra state of. + * @return {string} A stringified version of the extra state of the given block. * @package */ - function getDescendantIds(block: Blockly.Block): string[]; - - /** - * Decode the JSON into an event. - * @param {!Object} json JSON representation. - * @param {!Blockly.Workspace} workspace Target workspace for event. - * @return {!Blockly.Events.Abstract} The event represented by the JSON. - * @throws {Error} if an event type is not found in the registry. - */ - function fromJson(json: Object, workspace: Blockly.Workspace): Blockly.Events.Abstract; - - /** - * Gets the class for a specific event type from the registry. - * @param {string} eventType The type of the event to get. - * @return {?function(new:Blockly.Events.Abstract, ...?)} The event class with - * the given type or null if none exists. - */ - function get(eventType: string): { (_0: any[]): any /*missing*/ }; - - /** - * Enable/disable a block depending on whether it is properly connected. - * Use this on applications where all blocks should be connected to a top block. - * Recommend setting the 'disable' option to 'false' in the config so that - * users don't try to re-enable disabled orphan blocks. - * @param {!Blockly.Events.Abstract} event Custom data for event. - */ - function disableOrphans(event: Blockly.Events.Abstract): void; + function getExtraBlockState_(block: BlockSvg): string; } -declare module Blockly.Events { - - class Abstract extends Abstract__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Abstract__Class { - - /** - * Abstract class for an event. - * @constructor - */ - constructor(); - - /** - * Whether or not the event is blank (to be populated by fromJson). - * @type {?boolean} - */ - isBlank: boolean; - - /** - * The workspace identifier for this event. - * @type {string|undefined} - */ - workspaceId: string|any /*undefined*/; - - /** - * The event group id for the group this event belongs to. Groups define - * events that should be treated as an single action from the user's - * perspective, and should be undone together. - * @type {string} - */ - group: string; - - /** - * Sets whether the event should be added to the undo stack. - * @type {boolean} - */ - recordUndo: boolean; - - /** - * Whether or not the event is a UI event. - * @type {boolean} - */ - isUiEvent: boolean; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Does this event record any change of state? - * @return {boolean} True if null, false if something changed. - */ - isNull(): boolean; - - /** - * Run an event. - * @param {boolean} _forward True if run forward, false if run backward (undo). - */ - run(_forward: boolean): void; - - /** - * Get workspace the event belongs to. - * @return {!Blockly.Workspace} The workspace the event belongs to. - * @throws {Error} if workspace is null. - * @protected - */ - getEventWorkspace_(): Blockly.Workspace; - } - -} -declare module Blockly.Events { - - class BlockDrag extends BlockDrag__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BlockDrag__Class extends Blockly.Events.UiBase__Class { - - /** - * 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=} opt_blocks The blocks affected by this - * drag. Undefined for a blank event. - * @extends {Blockly.Events.UiBase} - * @constructor - */ - constructor(opt_block?: Blockly.Block, opt_isStart?: boolean, opt_blocks?: Blockly.Block[]); - - /** - * Whether this is the start of a block drag. - * @type {boolean|undefined} - */ - isStart: boolean|any /*undefined*/; - - /** - * The blocks affected by this drag event. - * @type {!Array|undefined} - */ - blocks: Blockly.Block[]|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} -declare module Blockly.Events { - - class BubbleOpen extends BubbleOpen__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BubbleOpen__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_block: Blockly.BlockSvg, opt_isOpen?: boolean, opt_bubbleType?: string); - - /** - * Whether the bubble is opening (false if closing). - * @type {boolean|undefined} - */ - isOpen: boolean|any /*undefined*/; - - /** - * The type of bubble. One of 'mutator', 'comment', or 'warning'. - * @type {string|undefined} - */ - bubbleType: string|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} -declare module Blockly.Events { - - class Click extends Click__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Click__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_block?: Blockly.Block, opt_workspaceId?: string, opt_targetType?: string); - - /** - * The type of element targeted by this click event. - * @type {string|undefined} - */ - targetType: string|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class MarkerMove extends MarkerMove__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class MarkerMove__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_block?: Blockly.Block, isCursor?: boolean, opt_oldNode?: Blockly.ASTNode, opt_newNode?: Blockly.ASTNode); - - /** - * The workspace identifier for this event. - * @type {?string} - */ - blockId: string; - - /** - * The old node the marker used to be on. - * @type {?Blockly.ASTNode|undefined} - */ - oldNode: Blockly.ASTNode|any /*undefined*/; - - /** - * The new node the marker is now on. - * @type {Blockly.ASTNode|undefined} - */ - newNode: Blockly.ASTNode|any /*undefined*/; - - /** - * Whether this is a cursor event. - * @type {boolean|undefined} - */ - isCursor: boolean|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class Selected extends Selected__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Selected__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_oldElementId?: string, opt_newElementId?: string, opt_workspaceId?: string); - - /** - * The id of the last selected element. - * @type {?string|undefined} - */ - oldElementId: string|any /*undefined*/; - - /** - * The id of the selected element. - * @type {?string|undefined} - */ - newElementId: string|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class ThemeChange extends ThemeChange__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ThemeChange__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_themeName?: string, opt_workspaceId?: string); - - /** - * The theme name. - * @type {string|undefined} - */ - themeName: string|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class ToolboxItemSelect extends ToolboxItemSelect__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ToolboxItemSelect__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_oldItem?: string, opt_newItem?: string, opt_workspaceId?: string); - - /** - * The previously selected toolbox item. - * @type {?string|undefined} - */ - oldItem: string|any /*undefined*/; - - /** - * The newly selected toolbox item. - * @type {?string|undefined} - */ - newItem: string|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class TrashcanOpen extends TrashcanOpen__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class TrashcanOpen__Class extends Blockly.Events.UiBase__Class { - - /** - * 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 - */ - constructor(opt_isOpen?: boolean, opt_workspaceId?: string); - - /** - * Whether the trashcan flyout is opening (false if closing). - * @type {boolean|undefined} - */ - isOpen: boolean|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class ViewportChange extends ViewportChange__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ViewportChange__Class extends Blockly.Events.UiBase__Class { - - /** - * 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. - * @param {number=} opt_oldScale The old scale of the workspace. Undefined for a - * blank event. - * @extends {Blockly.Events.UiBase} - * @constructor - */ - constructor(opt_top?: number, opt_left?: number, opt_scale?: number, opt_workspaceId?: string, opt_oldScale?: number); - - /** - * Top-edge of the visible portion of the workspace, relative to the workspace - * origin. - * @type {number|undefined} - */ - viewTop: number|any /*undefined*/; - - /** - * Left-edge of the visible portion of the workspace, relative to the - * workspace origin. - * @type {number|undefined} - */ - viewLeft: number|any /*undefined*/; - - /** - * The scale of the workspace. - * @type {number|undefined} - */ - scale: number|any /*undefined*/; - - /** - * The old scale of the workspace. - * @type {number|undefined} - */ - oldScale: number|any /*undefined*/; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class UiBase extends UiBase__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class UiBase__Class extends Blockly.Events.Abstract__Class { - - /** - * 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 - */ - constructor(opt_workspaceId?: string); - - /** - * Whether or not the event is blank (to be populated by fromJson). - * @type {boolean} - */ - isBlank: boolean; - - /** - * The workspace identifier for this event. - * @type {string} - */ - workspaceId: string; - - /** - * Whether or not the event is a UI event. - * @type {boolean} - */ - isUiEvent: boolean; - } - - - class Ui extends Ui__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Ui__Class extends Blockly.Events.UiBase__Class { - - /** - * 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.UiBase} - * @deprecated December 2020. Instead use a more specific UI event. - * @constructor - */ - constructor(opt_block?: Blockly.Block, opt_element?: string, opt_oldValue?: any, opt_newValue?: any); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class VarBase extends VarBase__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VarBase__Class extends Blockly.Events.Abstract__Class { - - /** - * Abstract class for a variable event. - * @param {!Blockly.VariableModel=} opt_variable The variable this event - * corresponds to. Undefined for a blank event. - * @extends {Blockly.Events.Abstract} - * @constructor - */ - constructor(opt_variable?: Blockly.VariableModel); - - /** - * The variable id for the variable this event pertains to. - * @type {string} - */ - varId: string; - - /** - * The workspace identifier for this event. - * @type {string} - */ - workspaceId: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - - - class VarCreate extends VarCreate__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VarCreate__Class extends Blockly.Events.VarBase__Class { - - /** - * Class for a variable creation event. - * @param {!Blockly.VariableModel=} opt_variable The created variable. Undefined - * for a blank event. - * @extends {Blockly.Events.VarBase} - * @constructor - */ - constructor(opt_variable?: Blockly.VariableModel); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a variable creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class VarDelete extends VarDelete__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VarDelete__Class extends Blockly.Events.VarBase__Class { - - /** - * Class for a variable deletion event. - * @param {!Blockly.VariableModel=} opt_variable The deleted variable. Undefined - * for a blank event. - * @extends {Blockly.Events.VarBase} - * @constructor - */ - constructor(opt_variable?: Blockly.VariableModel); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a variable deletion event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class VarRename extends VarRename__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class VarRename__Class extends Blockly.Events.VarBase__Class { - - /** - * Class for a variable rename event. - * @param {!Blockly.VariableModel=} opt_variable The renamed variable. Undefined - * for a blank event. - * @param {string=} newName The new name the variable will be changed to. - * @extends {Blockly.Events.VarBase} - * @constructor - */ - constructor(opt_variable?: Blockly.VariableModel, newName?: string); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a variable rename event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - -} - - -declare module Blockly.Events { - - class FinishedLoading extends FinishedLoading__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class FinishedLoading__Class extends Blockly.Events.Abstract__Class { - - /** - * Class for a finished loading event. - * Used to notify the developer when the workspace has finished loading (i.e - * domToWorkspace). - * 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.Abstract} - * @constructor - */ - constructor(opt_workspace?: Blockly.Workspace); - - /** - * Whether or not the event is blank (to be populated by fromJson). - * @type {boolean} - */ - isBlank: boolean; - - /** - * The workspace identifier for this event. - * @type {string} - */ - workspaceId: string; - - /** - * The event group ID for the group this event belongs to. Groups define - * events that should be treated as an single action from the user's - * perspective, and should be undone together. - * @type {string} - */ - group: string; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - -} - - -declare module Blockly.Events { - - class CommentBase extends CommentBase__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CommentBase__Class extends Blockly.Events.Abstract__Class { - - /** - * Abstract class for a comment event. - * @param {!Blockly.WorkspaceComment=} opt_comment The comment this event - * corresponds to. Undefined for a blank event. - * @extends {Blockly.Events.Abstract} - * @constructor - */ - constructor(opt_comment?: Blockly.WorkspaceComment); - - /** - * Whether or not an event is blank. - * @type {boolean} - */ - isBlank: boolean; - - /** - * The ID of the comment this event pertains to. - * @type {string} - */ - commentId: string; - - /** - * The workspace identifier for this event. - * @type {string} - */ - workspaceId: string; - - /** - * The event group id for the group this event belongs to. Groups define - * events that should be treated as an single action from the user's - * perspective, and should be undone together. - * @type {string} - */ - group: string; - - /** - * Sets whether the event should be added to the undo stack. - * @type {boolean} - */ - recordUndo: boolean; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - } - - - class CommentChange extends CommentChange__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CommentChange__Class extends Blockly.Events.CommentBase__Class { - - /** - * Class for a comment change event. - * @param {!Blockly.WorkspaceComment=} opt_comment The comment that is being - * changed. Undefined for a blank event. - * @param {string=} opt_oldContents Previous contents of the comment. - * @param {string=} opt_newContents New contents of the comment. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ - constructor(opt_comment?: Blockly.WorkspaceComment, opt_oldContents?: string, opt_newContents?: string); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ - isNull(): boolean; - - /** - * Run a change event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class CommentCreate extends CommentCreate__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CommentCreate__Class extends Blockly.Events.CommentBase__Class { - - /** - * Class for a comment creation event. - * @param {!Blockly.WorkspaceComment=} opt_comment The created comment. - * Undefined for a blank event. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ - constructor(opt_comment?: Blockly.WorkspaceComment); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class CommentDelete extends CommentDelete__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CommentDelete__Class extends Blockly.Events.CommentBase__Class { - - /** - * Class for a comment deletion event. - * @param {!Blockly.WorkspaceComment=} opt_comment The deleted comment. - * Undefined for a blank event. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ - constructor(opt_comment?: Blockly.WorkspaceComment); - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - - - class CommentMove extends CommentMove__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CommentMove__Class extends Blockly.Events.CommentBase__Class { - - /** - * Class for a comment move event. Created before the move. - * @param {!Blockly.WorkspaceComment=} opt_comment The comment that is being - * moved. Undefined for a blank event. - * @extends {Blockly.Events.CommentBase} - * @constructor - */ - constructor(opt_comment?: Blockly.WorkspaceComment); - - /** - * The comment that is being moved. Will be cleared after recording the new - * location. - * @type {Blockly.WorkspaceComment} - */ - comment_: Blockly.WorkspaceComment; - - /** - * The location before the move, in workspace coordinates. - * @type {!Blockly.utils.Coordinate} - */ - oldCoordinate_: Blockly.utils.Coordinate; - - /** - * The location after the move, in workspace coordinates. - * @type {Blockly.utils.Coordinate} - */ - newCoordinate_: Blockly.utils.Coordinate; - - /** - * Record the comment's new location. Called after the move. Can only be - * called once. - */ - recordNew(): void; - - /** - * Type of this event. - * @type {string} - */ - type: string; - - /** - * Override the location before the move. Use this if you don't create the - * event until the end of the move, but you know the original location. - * @param {!Blockly.utils.Coordinate} xy The location before the move, - * in workspace coordinates. - */ - setOldCoordinate(xy: Blockly.utils.Coordinate): void; - - /** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ - toJson(): Object; - - /** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ - fromJson(json: Object): void; - - /** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ - isNull(): boolean; - - /** - * Run a move event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ - run(forward: boolean): void; - } - +declare module CommentBase { /** * Helper function for Comment[Create|Delete] - * @param {!Blockly.Events.CommentCreate|!Blockly.Events.CommentDelete} event + * @param {!CommentCreate|!CommentDelete} event * The event to run. * @param {boolean} create if True then Create, if False then Delete */ - function CommentCreateDeleteHelper(event: Blockly.Events.CommentCreate|Blockly.Events.CommentDelete, create: boolean): void; + function CommentCreateDeleteHelper(event: CommentCreate|CommentDelete, create: boolean): void; } -declare module Blockly { - - interface IASTNodeLocation { - } - - interface IASTNodeLocationSvg extends Blockly.IASTNodeLocation { - - /** - * Add the marker SVG to this node's SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * SVG group. - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Add the cursor SVG to this node's SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * SVG group. - */ - setCursorSvg(cursorSvg: SVGElement): void; - } - - interface IASTNodeLocationWithBlock extends Blockly.IASTNodeLocation { - - /** - * Get the source block associated with this node. - * @return {Blockly.Block} The source block. - */ - getSourceBlock(): Blockly.Block; - } - - interface IKeyboardAccessible { - - /** - * Handles the given keyboard shortcut. - * @param {!Blockly.ShortcutRegistry.KeyboardShortcut} shortcut The shortcut to be handled. - * @return {boolean} True if the shortcut has been handled, false otherwise. - */ - onShortcut(shortcut: Blockly.ShortcutRegistry.KeyboardShortcut): boolean; - } -} -declare module Blockly { - - interface IAutoHideable extends Blockly.IComponent { - - /** - * Hides the component. Called in Blockly.hideChaff. - * @param {boolean} onlyClosePopups Whether only popups should be closed. - * Flyouts should not be closed if this is true. - */ - autoHide(onlyClosePopups: boolean): void; - } -} -declare module Blockly { - - interface IBlockDragger { - - /** - * Start dragging a block. This includes moving it to the drag surface. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @param {boolean} healStack Whether or not to heal the stack after - * disconnecting. - */ - startDrag(currentDragDeltaXY: Blockly.utils.Coordinate, healStack: boolean): void; - - /** - * Execute a step of block dragging, based on the given event. Update the - * display accordingly. - * @param {!Event} e The most recent move event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - */ - drag(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Finish a block drag and put the block back on the workspace. - * @param {!Event} e The mouseup/touchend event. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at the start of the drag, in pixel units. - */ - endDrag(e: Event, currentDragDeltaXY: Blockly.utils.Coordinate): void; - - /** - * Get a list of the insertion markers that currently exist. Drags have 0, 1, - * or 2 insertion markers. - * @return {!Array.} A possibly empty list of insertion - * marker blocks. - */ - getInsertionMarkers(): Blockly.BlockSvg[]; - } -} -declare module Blockly { - - interface IBoundedElement { - - /** - * Returns the coordinates of a bounded element describing the dimensions of the - * element. - * Coordinate system: workspace coordinates. - * @return {!Blockly.utils.Rect} Object with coordinates of the bounded element. - */ - getBoundingRectangle(): Blockly.utils.Rect; - - /** - * Move the element by a relative offset. - * @param {number} dx Horizontal offset in workspace units. - * @param {number} dy Vertical offset in workspace units. - */ - moveBy(dx: number, dy: number): void; - } -} -declare module Blockly { - - interface IBubble extends Blockly.IDraggable, Blockly.IContextMenu { - - /** - * Return the coordinates of the top-left corner of this bubble's body relative - * to the drawing surface's origin (0,0), in workspace units. - * @return {!Blockly.utils.Coordinate} Object with .x and .y properties. - */ - getRelativeToSurfaceXY(): Blockly.utils.Coordinate; - - /** - * Return the root node of the bubble's SVG group. - * @return {!SVGElement} The root SVG node of the bubble's group. - */ - getSvgRoot(): SVGElement; - - /** - * Set whether auto-layout of this bubble is enabled. The first time a bubble - * is shown it positions itself to not cover any blocks. Once a user has - * dragged it to reposition, it renders where the user put it. - * @param {boolean} enable True if auto-layout should be enabled, false - * otherwise. - */ - setAutoLayout(enable: boolean): void; - - /** - * Triggers a move callback if one exists at the end of a drag. - * @param {boolean} adding True if adding, false if removing. - */ - setDragging(adding: boolean): void; - - /** - * Move this bubble during a drag, taking into account whether or not there is - * a drag surface. - * @param {Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries - * rendered items during a drag, or null if no drag surface is in use. - * @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in - * workspace coordinates. - */ - moveDuringDrag(dragSurface: Blockly.BlockDragSurfaceSvg, newLoc: Blockly.utils.Coordinate): void; - - /** - * Move the bubble to the specified location in workspace coordinates. - * @param {number} x The x position to move to. - * @param {number} y The y position to move to. - */ - moveTo(x: number, y: number): void; - - /** - * Update the style of this bubble when it is dragged over a delete area. - * @param {boolean} enable True if the bubble is about to be deleted, false - * otherwise. - */ - setDeleteStyle(enable: boolean): void; - - /** - * Dispose of this bubble. - */ - dispose: any /*missing*/; - } -} -declare module Blockly { - interface IComponent { - } -} -declare module Blockly.IComponent { + + + + + + + + + + + + + + +declare module IComponent { /** * The unique id for this component that is used to register with the @@ -15247,969 +1766,62 @@ declare module Blockly.IComponent { } -declare module Blockly { - - interface IConnectionChecker { - - /** - * Check whether the current connection can connect with the target - * connection. - * @param {Blockly.Connection} a Connection to check compatibility with. - * @param {Blockly.Connection} b Connection to check compatibility with. - * @param {boolean} isDragging True if the connection is being made by dragging - * a block. - * @param {number=} opt_distance The max allowable distance between the - * connections for drag checks. - * @return {boolean} Whether the connection is legal. - * @public - */ - canConnect(a: Blockly.Connection, b: Blockly.Connection, isDragging: boolean, opt_distance?: number): boolean; - - /** - * Checks whether the current connection can connect with the target - * connection, and return an error code if there are problems. - * @param {Blockly.Connection} a Connection to check compatibility with. - * @param {Blockly.Connection} b Connection to check compatibility with. - * @param {boolean} isDragging True if the connection is being made by dragging - * a block. - * @param {number=} opt_distance The max allowable distance between the - * connections for drag checks. - * @return {number} Blockly.Connection.CAN_CONNECT if the connection is legal, - * an error code otherwise. - * @public - */ - canConnectWithReason(a: Blockly.Connection, b: Blockly.Connection, isDragging: boolean, opt_distance?: number): number; - - /** - * Helper method that translates a connection error code into a string. - * @param {number} errorCode The error code. - * @param {Blockly.Connection} a One of the two connections being checked. - * @param {Blockly.Connection} b The second of the two connections being - * checked. - * @return {string} A developer-readable error string. - * @public - */ - getErrorMessage(errorCode: number, a: Blockly.Connection, b: Blockly.Connection): string; - - /** - * Check that connecting the given connections is safe, meaning that it would - * not break any of Blockly's basic assumptions (e.g. no self connections). - * @param {Blockly.Connection} a The first of the connections to check. - * @param {Blockly.Connection} b The second of the connections to check. - * @return {number} An enum with the reason this connection is safe or unsafe. - * @public - */ - doSafetyChecks(a: Blockly.Connection, b: Blockly.Connection): number; - - /** - * Check whether this connection is compatible with another connection with - * respect to the value type system. E.g. square_root("Hello") is not - * compatible. - * @param {!Blockly.Connection} a Connection to compare. - * @param {!Blockly.Connection} b Connection to compare against. - * @return {boolean} True if the connections share a type. - * @public - */ - doTypeChecks(a: Blockly.Connection, b: Blockly.Connection): boolean; - - /** - * Check whether this connection can be made by dragging. - * @param {!Blockly.RenderedConnection} a Connection to compare. - * @param {!Blockly.RenderedConnection} b Connection to compare against. - * @param {number} distance The maximum allowable distance between connections. - * @return {boolean} True if the connection is allowed during a drag. - * @public - */ - doDragChecks(a: Blockly.RenderedConnection, b: Blockly.RenderedConnection, distance: number): boolean; - } -} -declare module Blockly { - - interface IContextMenu { - - /** - * Show the context menu for this object. - * @param {!Event} e Mouse event. - */ - showContextMenu(e: Event): void; - } -} - - -declare module Blockly { - - interface ICopyable extends Blockly.ISelectable { - - /** - * Encode for copying. - * @return {?Blockly.ICopyable.CopyData} Copy metadata. - */ - toCopyData(): Blockly.ICopyable.CopyData; - } -} - -declare module Blockly.ICopyable { +declare module ICopyable { /** * Copy Metadata. * @typedef {{ - * xml:!Element, - * source:Blockly.WorkspaceSvg, + * saveInfo:(!Object|!Element), + * source:WorkspaceSvg, * typeCounts:?Object * }} */ interface CopyData { - xml: Element; - source: Blockly.WorkspaceSvg; + saveInfo: Object|Element; + source: WorkspaceSvg; typeCounts: Object } } -declare module Blockly { - - interface IDeletable { - - /** - * Get whether this object is deletable or not. - * @return {boolean} True if deletable. - */ - isDeletable(): boolean; - } -} -declare module Blockly { - - interface IDeleteArea extends Blockly.IDragTarget { - - /** - * Returns whether the provided block or bubble would be deleted if dropped on - * this area. - * This method should check if the element is deletable and is always called - * before onDragEnter/onDragOver/onDragExit. - * @param {!Blockly.IDraggable} element The block or bubble currently being - * dragged. - * @param {boolean} couldConnect Whether the element could could connect to - * another. - * @return {boolean} Whether the element provided would be deleted if dropped on - * this area. - */ - wouldDelete(element: Blockly.IDraggable, couldConnect: boolean): boolean; - } -} -declare module Blockly { - - interface IDragTarget extends Blockly.IComponent { - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Handles when a cursor with a block or bubble enters this drag target. - * @param {!Blockly.IDraggable} dragElement The block or bubble currently being - * dragged. - */ - onDragEnter(dragElement: Blockly.IDraggable): void; - - /** - * Handles when a cursor with a block or bubble is dragged over this drag - * target. - * @param {!Blockly.IDraggable} dragElement The block or bubble currently being - * dragged. - */ - onDragOver(dragElement: Blockly.IDraggable): void; - - /** - * Handles when a cursor with a block or bubble exits this drag target. - * @param {!Blockly.IDraggable} dragElement The block or bubble currently being - * dragged. - */ - onDragExit(dragElement: Blockly.IDraggable): void; - - /** - * Handles when a block or bubble is dropped on this component. - * Should not handle delete here. - * @param {!Blockly.IDraggable} dragElement The block or bubble currently being - * dragged. - */ - onDrop(dragElement: Blockly.IDraggable): void; - - /** - * Returns whether the provided block or bubble should not be moved after being - * dropped on this component. If true, the element will return to where it was - * when the drag started. - * @param {!Blockly.IDraggable} dragElement The block or bubble currently being - * dragged. - * @return {boolean} Whether the block or bubble provided should be returned to - * drag start. - */ - shouldPreventMove(dragElement: Blockly.IDraggable): boolean; - } -} -declare module Blockly { - - interface IDraggable extends Blockly.IDeletable { - } -} -declare module Blockly { - - interface IFlyout extends Blockly.IRegistrable { - - /** - * Whether the flyout is laid out horizontally or not. - * @type {boolean} - */ - horizontalLayout: boolean; - - /** - * Is RTL vs LTR. - * @type {boolean} - */ - RTL: boolean; - - /** - * The target workspace - * @type {?Blockly.WorkspaceSvg} - */ - targetWorkspace: Blockly.WorkspaceSvg; - - /** - * Margin around the edges of the blocks in the flyout. - * @type {number} - * @const - */ - MARGIN: number; - - /** - * Does the flyout automatically close when a block is created? - * @type {boolean} - */ - autoClose: boolean; - - /** - * Corner radius of the flyout background. - * @type {number} - * @const - */ - CORNER_RADIUS: number; - - /** - * Creates the flyout's DOM. Only needs to be called once. The flyout can - * either exist as its own svg element or be a g element nested inside a - * separate svg element. - * @param {string| - * !Blockly.utils.Svg| - * !Blockly.utils.Svg} tagName The type of tag to - * put the flyout in. This should be or . - * @return {!SVGElement} The flyout's SVG group. - */ - createDom(tagName: string|Blockly.utils.Svg|Blockly.utils.Svg): SVGElement; - - /** - * Initializes the flyout. - * @param {!Blockly.WorkspaceSvg} targetWorkspace The workspace in which to - * create new blocks. - */ - init(targetWorkspace: Blockly.WorkspaceSvg): void; - - /** - * Dispose of this flyout. - * Unlink from all DOM elements to prevent memory leaks. - */ - dispose: any /*missing*/; - - /** - * Get the width of the flyout. - * @return {number} The width of the flyout. - */ - getWidth(): number; - - /** - * Get the height of the flyout. - * @return {number} The width of the flyout. - */ - getHeight(): number; - - /** - * Get the workspace inside the flyout. - * @return {!Blockly.WorkspaceSvg} The workspace inside the flyout. - */ - getWorkspace(): Blockly.WorkspaceSvg; - - /** - * Is the flyout visible? - * @return {boolean} True if visible. - */ - isVisible(): boolean; - - /** - * Set whether the flyout is visible. A value of true does not necessarily mean - * that the flyout is shown. It could be hidden because its container is hidden. - * @param {boolean} visible True if visible. - */ - setVisible(visible: boolean): void; - - /** - * Set whether this flyout's container is visible. - * @param {boolean} visible Whether the container is visible. - */ - setContainerVisible(visible: boolean): void; - - /** - * Hide and empty the flyout. - */ - hide: any /*missing*/; - - /** - * Show and populate the flyout. - * @param {!Blockly.utils.toolbox.FlyoutDefinition|string} flyoutDef Contents to - * display in the flyout. This is either an array of Nodes, a NodeList, a - * toolbox definition, or a string with the name of the dynamic category. - */ - show(flyoutDef: Blockly.utils.toolbox.FlyoutDefinition|string): void; - - /** - * Create a copy of this block on the workspace. - * @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout. - * @return {!Blockly.BlockSvg} The newly created block. - * @throws {Error} if something went wrong with deserialization. - */ - createBlock(originalBlock: Blockly.BlockSvg): Blockly.BlockSvg; - - /** - * Reflow blocks and their mats. - */ - reflow: any /*missing*/; - - /** - * @return {boolean} True if this flyout may be scrolled with a scrollbar or by - * dragging. - */ - isScrollable(): boolean; - - /** - * Calculates the x coordinate for the flyout position. - * @return {number} X coordinate. - */ - getX(): number; - - /** - * Calculates the y coordinate for the flyout position. - * @return {number} Y coordinate. - */ - getY(): number; - - /** - * Position the flyout. - * @return {void} - */ - position(): void; - - /** - * Determine if a drag delta is toward the workspace, based on the position - * and orientation of the flyout. This is used in determineDragIntention_ to - * determine if a new block should be created or if the flyout should scroll. - * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has - * moved from the position at mouse down, in pixel units. - * @return {boolean} True if the drag is toward the workspace. - */ - isDragTowardWorkspace(currentDragDeltaXY: Blockly.utils.Coordinate): boolean; - } -} -declare module Blockly { - - interface IMetricsManager { - - /** - * Returns whether the scroll area has fixed edges. - * @return {boolean} Whether the scroll area has fixed edges. - * @package - */ - hasFixedEdges(): boolean; - - /** - * Returns the metrics for the scroll area of the workspace. - * @param {boolean=} opt_getWorkspaceCoordinates True to get the scroll metrics - * in workspace coordinates, false to get them in pixel coordinates. - * @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view - * metrics if they have been previously computed. Passing in null may cause - * the view metrics to be computed again, if it is needed. - * @param {!Blockly.MetricsManager.ContainerRegion=} opt_contentMetrics The - * content metrics if they have been previously computed. Passing in null - * may cause the content metrics to be computed again, if it is needed. - * @return {!Blockly.MetricsManager.ContainerRegion} The metrics for the scroll - * container - */ - getScrollMetrics(opt_getWorkspaceCoordinates?: boolean, opt_viewMetrics?: Blockly.MetricsManager.ContainerRegion, opt_contentMetrics?: Blockly.MetricsManager.ContainerRegion): Blockly.MetricsManager.ContainerRegion; - - /** - * Gets the width and the height of the flyout on the workspace in pixel - * coordinates. Returns 0 for the width and height if the workspace has a - * category toolbox instead of a simple toolbox. - * @param {boolean=} opt_own Whether to only return the workspace's own flyout. - * @return {!Blockly.MetricsManager.ToolboxMetrics} The width and height of the - * flyout. - * @public - */ - getFlyoutMetrics(opt_own?: boolean): Blockly.MetricsManager.ToolboxMetrics; - - /** - * Gets the width, height and position of the toolbox on the workspace in pixel - * coordinates. Returns 0 for the width and height if the workspace has a simple - * toolbox instead of a category toolbox. To get the width and height of a - * simple toolbox @see {@link getFlyoutMetrics}. - * @return {!Blockly.MetricsManager.ToolboxMetrics} The object with the width, - * height and position of the toolbox. - * @public - */ - getToolboxMetrics(): Blockly.MetricsManager.ToolboxMetrics; - - /** - * Gets the width and height of the workspace's parent SVG element in pixel - * coordinates. This area includes the toolbox and the visible workspace area. - * @return {!Blockly.utils.Size} The width and height of the workspace's parent - * SVG element. - * @public - */ - getSvgMetrics(): Blockly.utils.Size; - - /** - * Gets the absolute left and absolute top in pixel coordinates. - * This is where the visible workspace starts in relation to the SVG container. - * @return {!Blockly.MetricsManager.AbsoluteMetrics} The absolute metrics for - * the workspace. - * @public - */ - getAbsoluteMetrics(): Blockly.MetricsManager.AbsoluteMetrics; - - /** - * Gets the metrics for the visible workspace in either pixel or workspace - * coordinates. The visible workspace does not include the toolbox or flyout. - * @param {boolean=} opt_getWorkspaceCoordinates True to get the view metrics in - * workspace coordinates, false to get them in pixel coordinates. - * @return {!Blockly.MetricsManager.ContainerRegion} The width, height, top and - * left of the viewport in either workspace coordinates or pixel - * coordinates. - * @public - */ - getViewMetrics(opt_getWorkspaceCoordinates?: boolean): Blockly.MetricsManager.ContainerRegion; - - /** - * Gets content metrics in either pixel or workspace coordinates. - * The content area is a rectangle around all the top bounded elements on the - * workspace (workspace comments and blocks). - * @param {boolean=} opt_getWorkspaceCoordinates True to get the content metrics - * in workspace coordinates, false to get them in pixel coordinates. - * @return {!Blockly.MetricsManager.ContainerRegion} The - * metrics for the content container. - * @public - */ - getContentMetrics(opt_getWorkspaceCoordinates?: boolean): Blockly.MetricsManager.ContainerRegion; - - /** - * Returns an object with all the metrics required to size scrollbars for a - * top level workspace. The following properties are computed: - * Coordinate system: pixel coordinates, -left, -up, +right, +down - * .viewHeight: Height of the visible portion of the workspace. - * .viewWidth: Width of the visible portion of the workspace. - * .contentHeight: Height of the content. - * .contentWidth: Width of the content. - * .svgHeight: Height of the Blockly div (the view + the toolbox, - * simple or otherwise), - * .svgWidth: Width of the Blockly div (the view + the toolbox, - * simple or otherwise), - * .viewTop: Top-edge of the visible portion of the workspace, relative to - * the workspace origin. - * .viewLeft: Left-edge of the visible portion of the workspace, relative to - * the workspace origin. - * .contentTop: Top-edge of the content, relative to the workspace origin. - * .contentLeft: Left-edge of the content relative to the workspace origin. - * .absoluteTop: Top-edge of the visible portion of the workspace, relative - * to the blocklyDiv. - * .absoluteLeft: Left-edge of the visible portion of the workspace, relative - * to the blocklyDiv. - * .toolboxWidth: Width of the toolbox, if it exists. Otherwise zero. - * .toolboxHeight: Height of the toolbox, if it exists. Otherwise zero. - * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. - * .flyoutHeight: Height of the flyout if it is always open. Otherwise zero. - * .toolboxPosition: Top, bottom, left or right. Use TOOLBOX_AT constants to - * compare. - * @return {!Blockly.utils.Metrics} Contains size and position metrics of a top - * level workspace. - * @public - */ - getMetrics(): Blockly.utils.Metrics; - } -} - - -declare module Blockly { - - interface IMovable { - - /** - * Get whether this is movable or not. - * @return {boolean} True if movable. - */ - isMovable(): boolean; - } -} - - -declare module Blockly { - - interface IPositionable extends Blockly.IComponent { - - /** - * Positions the element. Called when the window is resized. - * @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics. - * @param {!Array} savedPositions List of rectangles that - * are already on the workspace. - */ - position(metrics: Blockly.MetricsManager.UiMetrics, savedPositions: Blockly.utils.Rect[]): void; - - /** - * Returns the bounding rectangle of the UI element in pixel units relative to - * the Blockly injection div. - * @return {?Blockly.utils.Rect} The UI elements’s bounding box. Null if - * bounding box should be ignored by other UI elements. - */ - getBoundingRectangle(): Blockly.utils.Rect; - } -} - - -declare module Blockly { - - interface IRegistrable { - } -} - - -declare module Blockly { +declare module IRegistrableField { /** - * A registrable field. - * Note: We are not using an interface here as we are interested in defining the - * static methods of a field rather than the instance methods. - * @typedef {{ - * fromJson:Blockly.IRegistrableField.fromJson - * }} - */ - interface IRegistrableField { - fromJson: Blockly.IRegistrableField.fromJson - } -} - -declare module Blockly.IRegistrableField { - - /** - * @typedef {function(!Object): Blockly.Field} + * @typedef {function(!Object): Field} */ interface fromJson { - (_0: Object): Blockly.Field + (_0: Object): Field } } -declare module Blockly { - - interface ISelectable extends Blockly.IDeletable, Blockly.IMovable { - - /** - * @type {string} - */ - id: string; - - /** - * Select this. Highlight it visually. - * @return {void} - */ - select(): void; - - /** - * Unselect this. Unhighlight it visually. - * @return {void} - */ - unselect(): void; - } -} -declare module Blockly { - - interface IStyleable { - - /** - * Adds a style on the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to add. - */ - addStyle(style: string): void; - - /** - * Removes a style from the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to remove. - */ - removeStyle(style: string): void; - } -} -declare module Blockly { - - interface IToolbox extends Blockly.IRegistrable { - - /** - * Initializes the toolbox. - * @return {void} - */ - init(): void; - - /** - * Fills the toolbox with new toolbox items and removes any old contents. - * @param {!Blockly.utils.toolbox.ToolboxInfo} toolboxDef Object holding information - * for creating a toolbox. - */ - render(toolboxDef: Blockly.utils.toolbox.ToolboxInfo): void; - - /** - * Gets the width of the toolbox. - * @return {number} The width of the toolbox. - */ - getWidth(): number; - - /** - * Gets the height of the toolbox. - * @return {number} The width of the toolbox. - */ - getHeight(): number; - - /** - * Gets the toolbox flyout. - * @return {?Blockly.IFlyout} The toolbox flyout. - */ - getFlyout(): Blockly.IFlyout; - - /** - * Gets the workspace for the toolbox. - * @return {!Blockly.WorkspaceSvg} The parent workspace for the toolbox. - */ - getWorkspace(): Blockly.WorkspaceSvg; - - /** - * Gets whether or not the toolbox is horizontal. - * @return {boolean} True if the toolbox is horizontal, false if the toolbox is - * vertical. - */ - isHorizontal(): boolean; - - /** - * Positions the toolbox based on whether it is a horizontal toolbox and whether - * the workspace is in rtl. - * @return {void} - */ - position(): void; - - /** - * Handles resizing the toolbox when a toolbox item resizes. - * @return {void} - */ - handleToolboxItemResize(): void; - - /** - * Unhighlights any previously selected item. - * @return {void} - */ - clearSelection(): void; - - /** - * Updates the category colours and background colour of selected categories. - * @return {void} - */ - refreshTheme(): void; - - /** - * Updates the flyout's content without closing it. Should be used in response - * to a change in one of the dynamic categories, such as variables or - * procedures. - * @return {void} - */ - refreshSelection(): void; - - /** - * Sets the visibility of the toolbox. - * @param {boolean} isVisible True if toolbox should be visible. - */ - setVisible(isVisible: boolean): void; - - /** - * Selects the toolbox item by it's position in the list of toolbox items. - * @param {number} position The position of the item to select. - * @return {void} - */ - selectItemByPosition(position: number): void; - - /** - * Gets the selected item. - * @return {?Blockly.IToolboxItem} The selected item, or null if no item is - * currently selected. - */ - getSelectedItem(): Blockly.IToolboxItem; - - /** - * Disposes of this toolbox. - * @return {void} - */ - dispose(): void; - } -} -declare module Blockly { - - interface IToolboxItem { - - /** - * Initializes the toolbox item. - * This includes creating the DOM and updating the state of any items based - * on the info object. - * @return {void} - * @public - */ - init(): void; - - /** - * Gets the div for the toolbox item. - * @return {?Element} The div for the toolbox item. - * @public - */ - getDiv(): Element; - - /** - * Gets a unique identifier for this toolbox item. - * @return {string} The ID for the toolbox item. - * @public - */ - getId(): string; - - /** - * Gets the parent if the toolbox item is nested. - * @return {?Blockly.IToolboxItem} The parent toolbox item, or null if - * this toolbox item is not nested. - * @public - */ - getParent(): Blockly.IToolboxItem; - - /** - * Gets the nested level of the category. - * @return {number} The nested level of the category. - * @package - */ - getLevel(): number; - - /** - * Whether the toolbox item is selectable. - * @return {boolean} True if the toolbox item can be selected. - * @public - */ - isSelectable(): boolean; - - /** - * Whether the toolbox item is collapsible. - * @return {boolean} True if the toolbox item is collapsible. - * @public - */ - isCollapsible(): boolean; - - /** - * Dispose of this toolbox item. No-op by default. - * @public - */ - dispose: any /*missing*/; - } - - interface ISelectableToolboxItem extends Blockly.IToolboxItem { - - /** - * Gets the name of the toolbox item. Used for emitting events. - * @return {string} The name of the toolbox item. - * @public - */ - getName(): string; - - /** - * Gets the contents of the toolbox item. These are items that are meant to be - * displayed in the flyout. - * @return {!Blockly.utils.toolbox.FlyoutItemInfoArray|string} The definition - * of items to be displayed in the flyout. - * @public - */ - getContents(): Blockly.utils.toolbox.FlyoutItemInfoArray|string; - - /** - * Sets the current toolbox item as selected. - * @param {boolean} _isSelected True if this category is selected, false - * otherwise. - * @public - */ - setSelected(_isSelected: boolean): void; - - /** - * 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 - */ - getClickTarget(): Element; - - /** - * Handles when the toolbox item is clicked. - * @param {!Event} _e Click event to handle. - * @public - */ - onClick(_e: Event): void; - } - - interface ICollapsibleToolboxItem extends Blockly.ISelectableToolboxItem { - - /** - * Gets any children toolbox items. (ex. Gets the subcategories) - * @return {!Array} The child toolbox items. - */ - getChildToolboxItems(): Blockly.IToolboxItem[]; - - /** - * Whether the toolbox item is expanded to show its child subcategories. - * @return {boolean} True if the toolbox item shows its children, false if it - * is collapsed. - * @public - */ - isExpanded(): boolean; - - /** - * Toggles whether or not the toolbox item is expanded. - * @public - */ - toggleExpanded: any /*missing*/; - } -} - - -declare module Blockly { - - class ASTNode extends ASTNode__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ASTNode__Class { - - /** - * Class for an AST node. - * It is recommended that you use one of the createNode methods instead of - * creating a node directly. - * @param {string} type The type of the location. - * Must be in Blockly.ASTNode.types. - * @param {!Blockly.IASTNodeLocation} location The position in the AST. - * @param {!Blockly.ASTNode.Params=} opt_params Optional dictionary of options. - * @constructor - */ - constructor(type: string, location: Blockly.IASTNodeLocation, opt_params?: Blockly.ASTNode.Params); - - /** - * Gets the value pointed to by this node. - * It is the callers responsibility to check the node type to figure out what - * type of object they get back from this. - * @return {!Blockly.IASTNodeLocation} The current field, connection, workspace, or - * block the cursor is on. - */ - getLocation(): Blockly.IASTNodeLocation; - - /** - * The type of the current location. - * One of Blockly.ASTNode.types - * @return {string} The type of the location. - */ - getType(): string; - - /** - * The coordinate on the workspace. - * @return {Blockly.utils.Coordinate} The workspace coordinate or null if the - * location is not a workspace. - */ - getWsCoordinate(): Blockly.utils.Coordinate; - - /** - * Whether the node points to a connection. - * @return {boolean} [description] - * @package - */ - isConnection(): boolean; - - /** - * Finds the source block of the location of this node. - * @return {Blockly.Block} The source block of the location, or null if the node - * is of type workspace. - */ - getSourceBlock(): Blockly.Block; - - /** - * Find the element to the right of the current element in the AST. - * @return {Blockly.ASTNode} An AST node that wraps the next field, connection, - * block, or workspace. Or null if there is no node to the right. - */ - next(): Blockly.ASTNode; - - /** - * Find the element one level below and all the way to the left of the current - * location. - * @return {Blockly.ASTNode} An AST node that wraps the next field, connection, - * workspace, or block. Or null if there is nothing below this node. - */ - in(): Blockly.ASTNode; - - /** - * Find the element to the left of the current element in the AST. - * @return {Blockly.ASTNode} An AST node that wraps the previous field, - * connection, workspace or block. Or null if no node exists to the left. - * null. - */ - prev(): Blockly.ASTNode; - - /** - * Find the next element that is one position above and all the way to the left - * of the current location. - * @return {Blockly.ASTNode} An AST node that wraps the next field, connection, - * workspace or block. Or null if we are at the workspace level. - */ - out(): Blockly.ASTNode; - } - -} - -declare module Blockly.ASTNode { +declare module ASTNode { /** * @typedef {{ - * wsCoordinate: Blockly.utils.Coordinate + * wsCoordinate: Coordinate * }} */ interface Params { - wsCoordinate: Blockly.utils.Coordinate + wsCoordinate: Coordinate } /** @@ -16226,119 +1838,67 @@ declare module Blockly.ASTNode { /** * Create an AST node pointing to a field. - * @param {Blockly.Field} field The location of the AST node. - * @return {Blockly.ASTNode} An AST node pointing to a field. + * @param {Field} field The location of the AST node. + * @return {ASTNode} An AST node pointing to a field. */ - function createFieldNode(field: Blockly.Field): Blockly.ASTNode; + function createFieldNode(field: Field): ASTNode; /** * Creates an AST node pointing to a connection. If the connection has a parent * input then create an AST node of type input that will hold the connection. - * @param {Blockly.Connection} connection This is the connection the node will + * @param {Connection} connection This is the connection the node will * point to. - * @return {Blockly.ASTNode} An AST node pointing to a connection. + * @return {ASTNode} An AST node pointing to a connection. */ - function createConnectionNode(connection: Blockly.Connection): Blockly.ASTNode; + function createConnectionNode(connection: Connection): ASTNode; /** * Creates an AST node pointing to an input. Stores the input connection as the * location. - * @param {Blockly.Input} input The input used to create an AST node. - * @return {Blockly.ASTNode} An AST node pointing to a input. + * @param {Input} input The input used to create an AST node. + * @return {ASTNode} An AST node pointing to a input. */ - function createInputNode(input: Blockly.Input): Blockly.ASTNode; + function createInputNode(input: Input): ASTNode; /** * Creates an AST node pointing to a block. - * @param {Blockly.Block} block The block used to create an AST node. - * @return {Blockly.ASTNode} An AST node pointing to a block. + * @param {Block} block The block used to create an AST node. + * @return {ASTNode} An AST node pointing to a block. */ - function createBlockNode(block: Blockly.Block): Blockly.ASTNode; + function createBlockNode(block: Block): ASTNode; /** * Create an AST node of type stack. A stack, represented by its top block, is * the set of all blocks connected to a top block, including the top block. - * @param {Blockly.Block} topBlock A top block has no parent and can be found + * @param {Block} topBlock A top block has no parent and can be found * in the list returned by workspace.getTopBlocks(). - * @return {Blockly.ASTNode} An AST node of type stack that points to the top + * @return {ASTNode} An AST node of type stack that points to the top * block on the stack. */ - function createStackNode(topBlock: Blockly.Block): Blockly.ASTNode; + function createStackNode(topBlock: Block): ASTNode; /** * Creates an AST node pointing to a workspace. - * @param {!Blockly.Workspace} workspace The workspace that we are on. - * @param {Blockly.utils.Coordinate} wsCoordinate The position on the workspace + * @param {!Workspace} workspace The workspace that we are on. + * @param {Coordinate} wsCoordinate The position on the workspace * for this node. - * @return {Blockly.ASTNode} An AST node pointing to a workspace and a position + * @return {ASTNode} An AST node pointing to a workspace and a position * on the workspace. */ - function createWorkspaceNode(workspace: Blockly.Workspace, wsCoordinate: Blockly.utils.Coordinate): Blockly.ASTNode; + function createWorkspaceNode(workspace: Workspace, wsCoordinate: Coordinate): ASTNode; /** * Creates an AST node for the top position on a block. * This is either an output connection, previous connection, or block. - * @param {!Blockly.Block} block The block to find the top most AST node on. - * @return {Blockly.ASTNode} The AST node holding the top most position on the + * @param {!Block} block The block to find the top most AST node on. + * @return {ASTNode} The AST node holding the top most position on the * block. */ - function createTopNode(block: Blockly.Block): Blockly.ASTNode; + function createTopNode(block: Block): ASTNode; } -declare module Blockly { - - class BasicCursor extends BasicCursor__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BasicCursor__Class extends Blockly.Cursor__Class { - - /** - * Class for a basic cursor. - * This will allow the user to get to all nodes in the AST by hitting next or - * previous. - * @constructor - * @extends {Blockly.Cursor} - */ - constructor(); - - /** - * Uses pre order traversal to navigate the Blockly AST. This will allow - * a user to easily navigate the entire Blockly AST without having to go in - * and out levels on the tree. - * @param {Blockly.ASTNode} node The current position in the AST. - * @param {!function(Blockly.ASTNode) : boolean} isValid A function true/false - * depending on whether the given node should be traversed. - * @return {Blockly.ASTNode} The next node in the traversal. - * @protected - */ - getNextNode_(node: Blockly.ASTNode, isValid: { (_0: Blockly.ASTNode): boolean }): Blockly.ASTNode; - - /** - * Reverses the pre order traversal in order to find the previous node. This - * will allow a user to easily navigate the entire Blockly AST without having to - * go in and out levels on the tree. - * @param {Blockly.ASTNode} node The current position in the AST. - * @param {!function(Blockly.ASTNode) : boolean} isValid A function true/false - * depending on whether the given node should be traversed. - * @return {Blockly.ASTNode} The previous node in the traversal or null if no - * previous node exists. - * @protected - */ - getPreviousNode_(node: Blockly.ASTNode, isValid: { (_0: Blockly.ASTNode): boolean }): Blockly.ASTNode; - - /** - * Decides what nodes to traverse and which ones to skip. Currently, it - * skips output, stack and workspace nodes. - * @param {Blockly.ASTNode} node The AST node to check whether it is valid. - * @return {boolean} True if the node should be visited, false otherwise. - * @protected - */ - validNode_(node: Blockly.ASTNode): boolean; - } - -} - -declare module Blockly.BasicCursor { +declare module BasicCursor { /** * Name used for registering a basic cursor. @@ -16348,144 +1908,28 @@ declare module Blockly.BasicCursor { } -declare module Blockly { - - class Cursor extends Cursor__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Cursor__Class extends Blockly.Marker__Class { - - /** - * Class for a cursor. - * A cursor controls how a user navigates the Blockly AST. - * @constructor - * @extends {Blockly.Marker} - */ - constructor(); - - /** - * Find the next connection, field, or block. - * @return {Blockly.ASTNode} The next element, or null if the current node is - * not set or there is no next value. - * @public - */ - next(): Blockly.ASTNode; - - /** - * Find the in connection or field. - * @return {Blockly.ASTNode} The in element, or null if the current node is - * not set or there is no in value. - * @public - */ - in(): Blockly.ASTNode; - - /** - * Find the previous connection, field, or block. - * @return {Blockly.ASTNode} The previous element, or null if the current node - * is not set or there is no previous value. - * @public - */ - prev(): Blockly.ASTNode; - - /** - * Find the out connection, field, or block. - * @return {Blockly.ASTNode} The out element, or null if the current node is - * not set or there is no out value. - * @public - */ - out(): Blockly.ASTNode; - } - -} -declare module Blockly { - - class Marker extends Marker__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Marker__Class { - - /** - * Class for a marker. - * This is used in keyboard navigation to save a location in the Blockly AST. - * @constructor - */ - constructor(); - - /** - * The colour of the marker. - * @type {?string} - */ - colour: string; - - /** - * The type of the marker. - * @type {string} - */ - type: string; - - /** - * Sets the object in charge of drawing the marker. - * @param {Blockly.blockRendering.MarkerSvg} drawer The object in charge of - * drawing the marker. - */ - setDrawer(drawer: Blockly.blockRendering.MarkerSvg): void; - - /** - * Get the current drawer for the marker. - * @return {Blockly.blockRendering.MarkerSvg} The object in charge of drawing - * the marker. - */ - getDrawer(): Blockly.blockRendering.MarkerSvg; - - /** - * Gets the current location of the marker. - * @return {Blockly.ASTNode} The current field, connection, or block the marker - * is on. - */ - getCurNode(): Blockly.ASTNode; - - /** - * Set the location of the marker and call the update method. - * Setting isStack to true will only work if the newLocation is the top most - * output or previous connection on a stack. - * @param {Blockly.ASTNode} newNode The new location of the marker. - */ - setCurNode(newNode: Blockly.ASTNode): void; - - /** - * Redraw the current marker. - * @package - */ - draw(): void; - - /** - * Hide the marker SVG. - */ - hide(): void; - - /** - * Dispose of this marker. - */ - dispose(): void; - } - -} -declare module Blockly { - class TabNavigateCursor extends TabNavigateCursor__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class TabNavigateCursor__Class extends Blockly.BasicCursor__Class { - - /** - * A cursor for navigating between tab navigable fields. - * @constructor - * @extends {Blockly.BasicCursor} - */ - constructor(); - } - +declare module exports { + + /** + * The priority for deserializing variables. + * @type {number} + * @const + * @alias Blockly.serialization.priorities.VARIABLES + */ + var VARIABLES: number; + + /** + * The priority for deserializing blocks. + * @type {number} + * @const + * @alias Blockly.serialization.priorities.BLOCKS + */ + var BLOCKS: number; } @@ -16495,297 +1939,7 @@ declare module Blockly { - -declare module Blockly { - - class ToolboxCategory extends ToolboxCategory__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ToolboxCategory__Class extends Blockly.ToolboxItem__Class implements Blockly.ISelectableToolboxItem { - - /** - * Class for a category in a toolbox. - * @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed - * to create a category in the toolbox. - * @param {!Blockly.IToolbox} toolbox The parent toolbox for the category. - * @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent category or null if - * the category does not have a parent. - * @constructor - * @extends {Blockly.ToolboxItem} - * @implements {Blockly.ISelectableToolboxItem} - */ - constructor(categoryDef: Blockly.utils.toolbox.CategoryInfo, toolbox: Blockly.IToolbox, opt_parent?: Blockly.ICollapsibleToolboxItem); - - /** - * The name that will be displayed on the category. - * @type {string} - * @protected - */ - name_: string; - - /** - * The colour of the category. - * @type {string} - * @protected - */ - colour_: string; - - /** - * The html container for the category. - * @type {?Element} - * @protected - */ - htmlDiv_: Element; - - /** - * The html element for the category row. - * @type {?Element} - * @protected - */ - rowDiv_: Element; - - /** - * The html element that holds children elements of the category row. - * @type {?Element} - * @protected - */ - rowContents_: Element; - - /** - * The html element for the toolbox icon. - * @type {?Element} - * @protected - */ - iconDom_: Element; - - /** - * The html element for the toolbox label. - * @type {?Element} - * @protected - */ - labelDom_: Element; - - /** - * All the css class names that are used to create a category. - * @type {!Blockly.ToolboxCategory.CssConfig} - * @protected - */ - cssConfig_: Blockly.ToolboxCategory.CssConfig; - - /** - * True if the category is meant to be hidden, false otherwise. - * @type {boolean} - * @protected - */ - isHidden_: boolean; - - /** - * True if this category is disabled, false otherwise. - * @type {boolean} - * @protected - */ - isDisabled_: boolean; - - /** - * The flyout items for this category. - * @type {string|!Blockly.utils.toolbox.FlyoutItemInfoArray} - * @protected - */ - flyoutItems_: string|Blockly.utils.toolbox.FlyoutItemInfoArray; - - /** - * Creates an object holding the default classes for a category. - * @return {!Blockly.ToolboxCategory.CssConfig} The configuration object holding - * all the CSS classes for a category. - * @protected - */ - makeDefaultCssConfig_(): Blockly.ToolboxCategory.CssConfig; - - /** - * Parses the contents array depending on if the category is a dynamic category, - * or if its contents are meant to be shown in the flyout. - * @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed - * to create a category. - * @protected - */ - parseContents_(categoryDef: Blockly.utils.toolbox.CategoryInfo): void; - - /** - * Creates the DOM for the category. - * @return {!Element} The parent element for the category. - * @protected - */ - createDom_(): Element; - - /** - * Creates the container that holds the row and any subcategories. - * @return {!Element} The div that holds the icon and the label. - * @protected - */ - createContainer_(): Element; - - /** - * Creates the parent of the contents container. All clicks will happen on this - * div. - * @return {!Element} The div that holds the contents container. - * @protected - */ - createRowContainer_(): Element; - - /** - * Creates the container for the label and icon. - * This is necessary so we can set all subcategory pointer events to none. - * @return {!Element} The div that holds the icon and the label. - * @protected - */ - createRowContentsContainer_(): Element; - - /** - * Creates the span that holds the category icon. - * @return {!Element} The span that holds the category icon. - * @protected - */ - createIconDom_(): Element; - - /** - * Creates the span that holds the category label. - * This should have an ID for accessibility purposes. - * @param {string} name The name of the category. - * @return {!Element} The span that holds the category label. - * @protected - */ - createLabelDom_(name: string): Element; - - /** - * Updates the colour for this category. - * @public - */ - refreshTheme(): void; - - /** - * Add the strip of colour to the toolbox category. - * @param {string} colour The category colour. - * @protected - */ - addColourBorder_(colour: string): void; - - /** - * Gets either the colour or the style for a category. - * @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The object holding - * information on the category. - * @return {string} The hex colour for the category. - * @protected - */ - getColour_(categoryDef: Blockly.utils.toolbox.CategoryInfo): string; - - /** - * 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 - */ - getClickTarget(): Element; - - /** - * Adds appropriate classes to display an open icon. - * @param {?Element} iconDiv The div that holds the icon. - * @protected - */ - openIcon_(iconDiv: Element): void; - - /** - * Adds appropriate classes to display a closed icon. - * @param {?Element} iconDiv The div that holds the icon. - * @protected - */ - closeIcon_(iconDiv: Element): void; - - /** - * Sets whether the category is visible or not. - * For a category to be visible its parent category must also be expanded. - * @param {boolean} isVisible True if category should be visible. - * @protected - */ - setVisible_(isVisible: boolean): void; - - /** - * Hide the category. - */ - hide(): void; - - /** - * Show the category. Category will only appear if its parent category is also - * expanded. - */ - show(): void; - - /** - * Whether the category is visible. - * A category is only visible if all of its ancestors are expanded and isHidden_ is false. - * @return {boolean} True if the category is visible, false otherwise. - * @public - */ - isVisible(): boolean; - - /** - * Whether all ancestors of a category (parent and parent's parent, etc.) are expanded. - * @return {boolean} True only if every ancestor is expanded - * @protected - */ - allAncestorsExpanded_(): boolean; - - /** - * Handles when the toolbox item is clicked. - * @param {!Event} _e Click event to handle. - * @public - */ - onClick(_e: Event): void; - - /** - * Sets the current category as selected. - * @param {boolean} isSelected True if this category is selected, false - * otherwise. - * @public - */ - setSelected(isSelected: boolean): void; - - /** - * Sets whether the category is disabled. - * @param {boolean} isDisabled True to disable the category, false otherwise. - */ - setDisabled(isDisabled: boolean): void; - - /** - * Gets the name of the category. Used for emitting events. - * @return {string} The name of the toolbox item. - * @public - */ - getName(): string; - - /** - * Gets the contents of the category. These are items that are meant to be - * displayed in the flyout. - * @return {!Blockly.utils.toolbox.FlyoutItemInfoArray|string} The definition - * of items to be displayed in the flyout. - * @public - */ - getContents(): Blockly.utils.toolbox.FlyoutItemInfoArray|string; - - /** - * Updates the contents to be displayed in the flyout. - * If the flyout is open when the contents are updated, refreshSelection on the - * toolbox must also be called. - * @param {!Blockly.utils.toolbox.FlyoutDefinition|string} contents The contents - * to be displayed in the flyout. A string can be supplied to create a - * dynamic category. - * @public - */ - updateFlyoutContents(contents: Blockly.utils.toolbox.FlyoutDefinition|string): void; - } - -} - -declare module Blockly.ToolboxCategory { +declare module ToolboxCategory { /** * All the CSS class names that are used to create a category. @@ -16838,85 +1992,7 @@ declare module Blockly.ToolboxCategory { } -declare module Blockly { - - class CollapsibleToolboxCategory extends CollapsibleToolboxCategory__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class CollapsibleToolboxCategory__Class extends Blockly.ToolboxCategory__Class implements Blockly.ICollapsibleToolboxItem { - - /** - * Class for a category in a toolbox that can be collapsed. - * @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed - * to create a category in the toolbox. - * @param {!Blockly.IToolbox} toolbox The parent toolbox for the category. - * @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent category or null if - * the category does not have a parent. - * @constructor - * @extends {Blockly.ToolboxCategory} - * @implements {Blockly.ICollapsibleToolboxItem} - */ - constructor(categoryDef: Blockly.utils.toolbox.CategoryInfo, toolbox: Blockly.IToolbox, opt_parent?: Blockly.ICollapsibleToolboxItem); - - /** - * Container for any child categories. - * @type {?Element} - * @protected - */ - subcategoriesDiv_: Element; - - /** - * Whether or not the category should display its subcategories. - * @type {boolean} - * @protected - */ - expanded_: boolean; - - /** - * The child toolbox items for this category. - * @type {!Array} - * @protected - */ - toolboxItems_: Blockly.ToolboxItem[]; - - /** - * Create the DOM for all subcategories. - * @param {!Array} subcategories The subcategories. - * @return {!Element} The div holding all the subcategories. - * @protected - */ - createSubCategoriesDom_(subcategories: Blockly.ToolboxItem[]): Element; - - /** - * Opens or closes the current category. - * @param {boolean} isExpanded True to expand the category, false to close. - * @public - */ - setExpanded(isExpanded: boolean): void; - - /** - * Whether the category is expanded to show its child subcategories. - * @return {boolean} True if the toolbox item shows its children, false if it - * is collapsed. - * @public - */ - isExpanded(): boolean; - - /** - * Toggles whether or not the category is expanded. - * @public - */ - toggleExpanded(): void; - - /** - * Gets any children toolbox items. (ex. Gets the subcategories) - * @return {!Array} The child toolbox items. - */ - getChildToolboxItems(): Blockly.IToolboxItem[]; - } - -} - -declare module Blockly.CollapsibleToolboxCategory { +declare module CollapsibleToolboxCategory { /** * All the CSS class names that are used to create a collapsible @@ -16953,42 +2029,7 @@ declare module Blockly.CollapsibleToolboxCategory { } -declare module Blockly { - - class ToolboxSeparator extends ToolboxSeparator__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ToolboxSeparator__Class extends Blockly.ToolboxItem__Class implements Blockly.IToolboxItem { - - /** - * Class for a toolbox separator. This is the thin visual line that appears on - * the toolbox. This item is not interactable. - * @param {!Blockly.utils.toolbox.SeparatorInfo} separatorDef The information - * needed to create a separator. - * @param {!Blockly.IToolbox} toolbox The parent toolbox for the separator. - * @constructor - * @extends {Blockly.ToolboxItem} - * @implements {Blockly.IToolboxItem} - */ - constructor(separatorDef: Blockly.utils.toolbox.SeparatorInfo, toolbox: Blockly.IToolbox); - - /** - * All the CSS class names that are used to create a separator. - * @type {!Blockly.ToolboxSeparator.CssConfig} - * @protected - */ - cssConfig_: Blockly.ToolboxSeparator.CssConfig; - - /** - * Creates the DOM for a separator. - * @return {!Element} The parent element for the separator. - * @protected - */ - createDom_(): Element; - } - -} - -declare module Blockly.ToolboxSeparator { +declare module ToolboxSeparator { /** * All the CSS class names that are used to create a separator. @@ -17008,2733 +2049,324 @@ declare module Blockly.ToolboxSeparator { } -declare module Blockly { - - class Toolbox extends Toolbox__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Toolbox__Class extends Blockly.DeleteArea__Class implements Blockly.IAutoHideable, Blockly.IKeyboardAccessible, Blockly.IStyleable, Blockly.IToolbox { - - /** - * Class for a Toolbox. - * Creates the toolbox's DOM. - * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to create new - * blocks. - * @constructor - * @implements {Blockly.IAutoHideable} - * @implements {Blockly.IKeyboardAccessible} - * @implements {Blockly.IStyleable} - * @implements {Blockly.IToolbox} - * @extends {Blockly.DeleteArea} - */ - constructor(workspace: Blockly.WorkspaceSvg); - - /** - * The workspace this toolbox is on. - * @type {!Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * The unique id for this component that is used to register with the - * ComponentManager. - * @type {string} - */ - id: string; - - /** - * The JSON describing the contents of this toolbox. - * @type {!Blockly.utils.toolbox.ToolboxInfo} - * @protected - */ - toolboxDef_: Blockly.utils.toolbox.ToolboxInfo; - - /** - * The html container for the toolbox. - * @type {?Element} - */ - HtmlDiv: Element; - - /** - * The html container for the contents of a toolbox. - * @type {?Element} - * @protected - */ - contentsDiv_: Element; - - /** - * Whether the Toolbox is visible. - * @type {boolean} - * @protected - */ - isVisible_: boolean; - - /** - * The list of items in the toolbox. - * @type {!Array} - * @protected - */ - contents_: Blockly.IToolboxItem[]; - - /** - * The width of the toolbox. - * @type {number} - * @protected - */ - width_: number; - - /** - * The height of the toolbox. - * @type {number} - * @protected - */ - height_: number; - - /** - * Is RTL vs LTR. - * @type {boolean} - */ - RTL: boolean; - - /** - * A map from toolbox item IDs to toolbox items. - * @type {!Object} - * @protected - */ - contentMap_: { [key: string]: Blockly.IToolboxItem }; - - /** - * Position of the toolbox and flyout relative to the workspace. - * @type {!Blockly.utils.toolbox.Position} - */ - toolboxPosition: Blockly.utils.toolbox.Position; - - /** - * The currently selected item. - * @type {?Blockly.ISelectableToolboxItem} - * @protected - */ - selectedItem_: Blockly.ISelectableToolboxItem; - - /** - * The previously selected item. - * @type {?Blockly.ISelectableToolboxItem} - * @protected - */ - previouslySelectedItem_: Blockly.ISelectableToolboxItem; - - /** - * Array holding info needed to unbind event handlers. - * Used for disposing. - * Ex: [[node, name, func], [node, name, func]]. - * @type {!Array} - * @protected - */ - boundEvents_: Blockly.browserEvents.Data[]; - - /** - * Handles the given keyboard shortcut. - * @param {!Blockly.ShortcutRegistry.KeyboardShortcut} _shortcut The shortcut to be handled. - * @return {boolean} True if the shortcut has been handled, false otherwise. - * @public - */ - onShortcut(_shortcut: Blockly.ShortcutRegistry.KeyboardShortcut): boolean; - - /** - * Initializes the toolbox - * @public - */ - init(): void; - - /** - * Creates the DOM for the toolbox. - * @param {!Blockly.WorkspaceSvg} workspace The workspace this toolbox is on. - * @return {!Element} The HTML container for the toolbox. - * @protected - */ - createDom_(workspace: Blockly.WorkspaceSvg): Element; - - /** - * Creates the container div for the toolbox. - * @return {!Element} The HTML container for the toolbox. - * @protected - */ - createContainer_(): Element; - - /** - * Creates the container for all the contents in the toolbox. - * @return {!Element} The HTML container for the toolbox contents. - * @protected - */ - createContentsContainer_(): Element; - - /** - * Adds event listeners to the toolbox container div. - * @param {!Element} container The HTML container for the toolbox. - * @param {!Element} contentsContainer The HTML container for the contents - * of the toolbox. - * @protected - */ - attachEvents_(container: Element, contentsContainer: Element): void; - - /** - * Handles on click events for when the toolbox or toolbox items are clicked. - * @param {!Event} e Click event to handle. - * @protected - */ - onClick_(e: Event): void; - - /** - * Handles key down events for the toolbox. - * @param {!KeyboardEvent} e The key down event. - * @protected - */ - onKeyDown_(e: KeyboardEvent): void; - - /** - * Creates the flyout based on the toolbox layout. - * @return {!Blockly.IFlyout} The flyout for the toolbox. - * @throws {Error} If missing a require for `Blockly.HorizontalFlyout`, - * `Blockly.VerticalFlyout`, and no flyout plugin is specified. - * @protected - */ - createFlyout_(): Blockly.IFlyout; - - /** - * Fills the toolbox with new toolbox items and removes any old contents. - * @param {!Blockly.utils.toolbox.ToolboxInfo} toolboxDef Object holding information - * for creating a toolbox. - * @package - */ - render(toolboxDef: Blockly.utils.toolbox.ToolboxInfo): void; - - /** - * Adds all the toolbox items to the toolbox. - * @param {!Array} toolboxDef Array - * holding objects containing information on the contents of the toolbox. - * @protected - */ - renderContents_(toolboxDef: Blockly.utils.toolbox.ToolboxItemInfo[]): void; - - /** - * Adds an item to the toolbox. - * @param {!Blockly.IToolboxItem} toolboxItem The item in the toolbox. - * @protected - */ - addToolboxItem_(toolboxItem: Blockly.IToolboxItem): void; - - /** - * Gets the items in the toolbox. - * @return {!Array} The list of items in the toolbox. - * @public - */ - getToolboxItems(): Blockly.IToolboxItem[]; - - /** - * Adds a style on the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to add. - * @package - */ - addStyle(style: string): void; - - /** - * Removes a style from the toolbox. Usually used to change the cursor. - * @param {string} style The name of the class to remove. - * @package - */ - removeStyle(style: string): void; - - /** - * Returns the bounding rectangle of the drag target area in pixel units - * relative to viewport. - * @return {?Blockly.utils.Rect} The component's bounding box. Null if drag - * target area should be ignored. - */ - getClientRect(): Blockly.utils.Rect; - - /** - * Adds or removes the CSS style of the cursor over the toolbox based whether - * the block or bubble over it is expected to be deleted if dropped (using the - * internal this.wouldDelete_ property). - * @param {boolean} addStyle Whether the style should be added or removed. - * @protected - */ - updateCursorDeleteStyle_(addStyle: boolean): void; - - /** - * Gets the toolbox item with the given ID. - * @param {string} id The ID of the toolbox item. - * @return {?Blockly.IToolboxItem} The toolbox item with the given ID, or null - * if no item exists. - * @public - */ - getToolboxItemById(id: string): Blockly.IToolboxItem; - - /** - * Gets the width of the toolbox. - * @return {number} The width of the toolbox. - * @public - */ - getWidth(): number; - - /** - * Gets the height of the toolbox. - * @return {number} The width of the toolbox. - * @public - */ - getHeight(): number; - - /** - * Gets the toolbox flyout. - * @return {?Blockly.IFlyout} The toolbox flyout. - * @public - */ - getFlyout(): Blockly.IFlyout; - - /** - * Gets the workspace for the toolbox. - * @return {!Blockly.WorkspaceSvg} The parent workspace for the toolbox. - * @public - */ - getWorkspace(): Blockly.WorkspaceSvg; - - /** - * Gets the selected item. - * @return {?Blockly.ISelectableToolboxItem} The selected item, or null if no item is - * currently selected. - * @public - */ - getSelectedItem(): Blockly.ISelectableToolboxItem; - - /** - * Gets the previously selected item. - * @return {?Blockly.ISelectableToolboxItem} The previously selected item, or null if no - * item was previously selected. - * @public - */ - getPreviouslySelectedItem(): Blockly.ISelectableToolboxItem; - - /** - * Gets whether or not the toolbox is horizontal. - * @return {boolean} True if the toolbox is horizontal, false if the toolbox is - * vertical. - * @public - */ - isHorizontal(): boolean; - - /** - * Positions the toolbox based on whether it is a horizontal toolbox and whether - * the workspace is in rtl. - * @public - */ - position(): void; - - /** - * Handles resizing the toolbox when a toolbox item resizes. - * @package - */ - handleToolboxItemResize(): void; - - /** - * Unhighlights any previously selected item. - * @public - */ - clearSelection(): void; - - /** - * Updates the category colours and background colour of selected categories. - * @package - */ - refreshTheme(): void; - - /** - * Updates the flyout's content without closing it. Should be used in response - * to a change in one of the dynamic categories, such as variables or - * procedures. - * @public - */ - refreshSelection(): void; - - /** - * Shows or hides the toolbox. - * @param {boolean} isVisible True if toolbox should be visible. - * @public - */ - setVisible(isVisible: boolean): void; - - /** - * Hides the component. Called in Blockly.hideChaff. - * @param {boolean} onlyClosePopups Whether only popups should be closed. - * Flyouts should not be closed if this is true. - */ - autoHide(onlyClosePopups: boolean): void; - - /** - * Sets the given item as selected. - * No-op if the item is not selectable. - * @param {?Blockly.IToolboxItem} newItem The toolbox item to select. - * @public - */ - setSelectedItem(newItem: Blockly.IToolboxItem): void; - - /** - * Decides whether the old item should be deselected. - * @param {?Blockly.ISelectableToolboxItem} oldItem The previously selected - * toolbox item. - * @param {?Blockly.ISelectableToolboxItem} newItem The newly selected toolbox - * item. - * @return {boolean} True if the old item should be deselected, false otherwise. - * @protected - */ - shouldDeselectItem_(oldItem: Blockly.ISelectableToolboxItem, newItem: Blockly.ISelectableToolboxItem): boolean; - - /** - * Decides whether the new item should be selected. - * @param {?Blockly.ISelectableToolboxItem} oldItem The previously selected - * toolbox item. - * @param {?Blockly.ISelectableToolboxItem} newItem The newly selected toolbox - * item. - * @return {boolean} True if the new item should be selected, false otherwise. - * @protected - */ - shouldSelectItem_(oldItem: Blockly.ISelectableToolboxItem, newItem: Blockly.ISelectableToolboxItem): boolean; - - /** - * Deselects the given item, marks it as unselected, and updates aria state. - * @param {!Blockly.ISelectableToolboxItem} item The previously selected - * toolbox item which should be deselected. - * @protected - */ - deselectItem_(item: Blockly.ISelectableToolboxItem): void; - - /** - * Selects the given item, marks it selected, and updates aria state. - * @param {?Blockly.ISelectableToolboxItem} oldItem The previously selected - * toolbox item. - * @param {!Blockly.ISelectableToolboxItem} newItem The newly selected toolbox - * item. - * @protected - */ - selectItem_(oldItem: Blockly.ISelectableToolboxItem, newItem: Blockly.ISelectableToolboxItem): void; - - /** - * Selects the toolbox item by its position in the list of toolbox items. - * @param {number} position The position of the item to select. - * @public - */ - selectItemByPosition(position: number): void; - - /** - * Decides whether to hide or show the flyout depending on the selected item. - * @param {?Blockly.ISelectableToolboxItem} oldItem The previously selected toolbox item. - * @param {?Blockly.ISelectableToolboxItem} newItem The newly selected toolbox item. - * @protected - */ - updateFlyout_(oldItem: Blockly.ISelectableToolboxItem, newItem: Blockly.ISelectableToolboxItem): void; - - /** - * Disposes of this toolbox. - * @public - */ - dispose(): void; - } - -} -declare module Blockly { - - class ToolboxItem extends ToolboxItem__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ToolboxItem__Class implements Blockly.IToolboxItem { - - /** - * Class for an item in the toolbox. - * @param {!Blockly.utils.toolbox.ToolboxItemInfo} toolboxItemDef The JSON defining the - * toolbox item. - * @param {!Blockly.IToolbox} toolbox The toolbox that holds the toolbox item. - * @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent toolbox item - * or null if the category does not have a parent. - * @constructor - * @implements {Blockly.IToolboxItem} - */ - constructor(toolboxItemDef: Blockly.utils.toolbox.ToolboxItemInfo, toolbox: Blockly.IToolbox, opt_parent?: Blockly.ICollapsibleToolboxItem); - - /** - * The id for the category. - * @type {string} - * @protected - */ - id_: string; - - /** - * The parent of the category. - * @type {?Blockly.ICollapsibleToolboxItem} - * @protected - */ - parent_: Blockly.ICollapsibleToolboxItem; - - /** - * The level that the category is nested at. - * @type {number} - * @protected - */ - level_: number; - - /** - * The JSON definition of the toolbox item. - * @type {!Blockly.utils.toolbox.ToolboxItemInfo} - * @protected - */ - toolboxItemDef_: Blockly.utils.toolbox.ToolboxItemInfo; - - /** - * The toolbox this category belongs to. - * @type {!Blockly.IToolbox} - * @protected - */ - parentToolbox_: Blockly.IToolbox; - - /** - * The workspace of the parent toolbox. - * @type {!Blockly.WorkspaceSvg} - * @protected - */ - workspace_: Blockly.WorkspaceSvg; - - /** - * Initializes the toolbox item. - * This includes creating the DOM and updating the state of any items based - * on the info object. - * @public - */ - init(): void; - - /** - * Gets the div for the toolbox item. - * @return {?Element} The div for the toolbox item. - * @public - */ - getDiv(): Element; - - /** - * Gets a unique identifier for this toolbox item. - * @return {string} The ID for the toolbox item. - * @public - */ - getId(): string; - - /** - * Gets the parent if the toolbox item is nested. - * @return {?Blockly.IToolboxItem} The parent toolbox item, or null if - * this toolbox item is not nested. - * @public - */ - getParent(): Blockly.IToolboxItem; - - /** - * Gets the nested level of the category. - * @return {number} The nested level of the category. - * @package - */ - getLevel(): number; - - /** - * Whether the toolbox item is selectable. - * @return {boolean} True if the toolbox item can be selected. - * @public - */ - isSelectable(): boolean; - - /** - * Whether the toolbox item is collapsible. - * @return {boolean} True if the toolbox item is collapsible. - * @public - */ - isCollapsible(): boolean; - - /** - * Dispose of this toolbox item. No-op by default. - * @public - */ - dispose(): void; - } - -} -declare module Blockly.utils.aria { - - /** - * ARIA role values. - * Copied from Closure's goog.a11y.aria.Role - * @enum {string} - */ - enum Role { GRID, GRIDCELL, GROUP, LISTBOX, MENU, MENUITEM, MENUITEMCHECKBOX, OPTION, PRESENTATION, ROW, TREE, TREEITEM } - - /** - * ARIA states and properties. - * Copied from Closure's goog.a11y.aria.State - * @enum {string} - */ - enum State { ACTIVEDESCENDANT, COLCOUNT, DISABLED, EXPANDED, INVALID, LABEL, LABELLEDBY, LEVEL, ORIENTATION, POSINSET, ROWCOUNT, SELECTED, SETSIZE, VALUEMAX, VALUEMIN } - - /** - * Sets the role of an element. - * - * Similar to Closure's goog.a11y.aria - * - * @param {!Element} element DOM node to set role of. - * @param {!Blockly.utils.aria.Role} roleName Role name. - */ - function setRole(element: Element, roleName: Blockly.utils.aria.Role): void; - - /** - * Sets the state or property of an element. - * Copied from Closure's goog.a11y.aria - * @param {!Element} element DOM node where we set state. - * @param {!Blockly.utils.aria.State} stateName State attribute being set. - * Automatically adds prefix 'aria-' to the state name if the attribute is - * not an extra attribute. - * @param {string|boolean|number|!Array} value Value - * for the state attribute. - */ - function setState(element: Element, stateName: Blockly.utils.aria.State, value: string|boolean|number|string[]): void; -} - - -declare module Blockly.utils.colour { - - /** - * Parses a colour from a string. - * .parse('red') -> '#ff0000' - * .parse('#f00') -> '#ff0000' - * .parse('#ff0000') -> '#ff0000' - * .parse('0xff0000') -> '#ff0000' - * .parse('rgb(255, 0, 0)') -> '#ff0000' - * @param {string|number} str Colour in some CSS format. - * @return {?string} A string containing a hex representation of the colour, - * or null if can't be parsed. - */ - function parse(str: string|number): string; - - /** - * Converts a colour from RGB to hex representation. - * @param {number} r Amount of red, int between 0 and 255. - * @param {number} g Amount of green, int between 0 and 255. - * @param {number} b Amount of blue, int between 0 and 255. - * @return {string} Hex representation of the colour. - */ - function rgbToHex(r: number, g: number, b: number): string; - - /** - * Converts a colour to RGB. - * @param {string} colour String representing colour in any - * colour format ('#ff0000', 'red', '0xff000', etc). - * @return {!Array} RGB representation of the colour. - */ - function hexToRgb(colour: string): number[]; - - /** - * Converts an HSV triplet to hex representation. - * @param {number} h Hue value in [0, 360]. - * @param {number} s Saturation value in [0, 1]. - * @param {number} v Brightness in [0, 255]. - * @return {string} Hex representation of the colour. - */ - function hsvToHex(h: number, s: number, v: number): string; - - /** - * Blend two colours together, using the specified factor to indicate the - * weight given to the first colour. - * @param {string} colour1 First colour. - * @param {string} colour2 Second colour. - * @param {number} factor The weight to be given to colour1 over colour2. - * Values should be in the range [0, 1]. - * @return {?string} Combined colour represented in hex. - */ - function blend(colour1: string, colour2: string, factor: number): string; - - /** - * A map that contains the 16 basic colour keywords as defined by W3C: - * https://www.w3.org/TR/2018/REC-css-color-3-20180619/#html4 - * The keys of this map are the lowercase "readable" names of the colours, - * while the values are the "hex" values. - * - * @type {!Object} - */ - var names: { [key: string]: string }; -} - - -declare module Blockly.utils { - - class Coordinate extends Coordinate__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Coordinate__Class { - - /** - * Class for representing coordinates and positions. - * @param {number} x Left. - * @param {number} y Top. - * @struct - * @constructor - */ - constructor(x: number, y: number); - - /** - * X-value - * @type {number} - */ - x: number; - - /** - * Y-value - * @type {number} - */ - y: number; - - /** - * Creates a new copy of this coordinate. - * @return {!Blockly.utils.Coordinate} A copy of this coordinate. - */ - clone(): Blockly.utils.Coordinate; - - /** - * Scales this coordinate by the given scale factor. - * @param {number} s The scale factor to use for both x and y dimensions. - * @return {!Blockly.utils.Coordinate} This coordinate after scaling. - */ - scale(s: number): Blockly.utils.Coordinate; - - /** - * Translates this coordinate by the given offsets. - * respectively. - * @param {number} tx The value to translate x by. - * @param {number} ty The value to translate y by. - * @return {!Blockly.utils.Coordinate} This coordinate after translating. - */ - translate(tx: number, ty: number): Blockly.utils.Coordinate; - } - -} - -declare module Blockly.utils.Coordinate { +declare module Coordinate { /** * Compares coordinates for equality. - * @param {?Blockly.utils.Coordinate} a A Coordinate. - * @param {?Blockly.utils.Coordinate} b A Coordinate. + * @param {?Coordinate} a A Coordinate. + * @param {?Coordinate} b A Coordinate. * @return {boolean} True iff the coordinates are equal, or if both are null. */ - function equals(a: Blockly.utils.Coordinate, b: Blockly.utils.Coordinate): boolean; + function equals(a: Coordinate, b: Coordinate): boolean; /** * Returns the distance between two coordinates. - * @param {!Blockly.utils.Coordinate} a A Coordinate. - * @param {!Blockly.utils.Coordinate} b A Coordinate. + * @param {!Coordinate} a A Coordinate. + * @param {!Coordinate} b A Coordinate. * @return {number} The distance between `a` and `b`. */ - function distance(a: Blockly.utils.Coordinate, b: Blockly.utils.Coordinate): number; + function distance(a: Coordinate, b: Coordinate): number; /** * Returns the magnitude of a coordinate. - * @param {!Blockly.utils.Coordinate} a A Coordinate. + * @param {!Coordinate} a A Coordinate. * @return {number} The distance between the origin and `a`. */ - function magnitude(a: Blockly.utils.Coordinate): number; + function magnitude(a: Coordinate): number; /** * Returns the difference between two coordinates as a new - * Blockly.utils.Coordinate. - * @param {!Blockly.utils.Coordinate|!SVGPoint} a An x/y coordinate. - * @param {!Blockly.utils.Coordinate|!SVGPoint} b An x/y coordinate. - * @return {!Blockly.utils.Coordinate} A Coordinate representing the difference + * Coordinate. + * @param {!Coordinate|!SVGPoint} a An x/y coordinate. + * @param {!Coordinate|!SVGPoint} b An x/y coordinate. + * @return {!Coordinate} A Coordinate representing the difference * between `a` and `b`. */ - function difference(a: Blockly.utils.Coordinate|SVGPoint, b: Blockly.utils.Coordinate|SVGPoint): Blockly.utils.Coordinate; + function difference(a: Coordinate|SVGPoint, b: Coordinate|SVGPoint): Coordinate; /** - * Returns the sum of two coordinates as a new Blockly.utils.Coordinate. - * @param {!Blockly.utils.Coordinate|!SVGPoint} a An x/y coordinate. - * @param {!Blockly.utils.Coordinate|!SVGPoint} b An x/y coordinate. - * @return {!Blockly.utils.Coordinate} A Coordinate representing the sum of + * Returns the sum of two coordinates as a new Coordinate. + * @param {!Coordinate|!SVGPoint} a An x/y coordinate. + * @param {!Coordinate|!SVGPoint} b An x/y coordinate. + * @return {!Coordinate} A Coordinate representing the sum of * the two coordinates. */ - function sum(a: Blockly.utils.Coordinate|SVGPoint, b: Blockly.utils.Coordinate|SVGPoint): Blockly.utils.Coordinate; + function sum(a: Coordinate|SVGPoint, b: Coordinate|SVGPoint): Coordinate; } -declare module Blockly.utils.deprecation { - - /** - * Warn developers that a function or property is deprecated. - * @param {string} name The name of the function or property. - * @param {string} deprecationDate The date of deprecation. - * Prefer 'month yyyy' or 'quarter yyyy' format. - * @param {string} deletionDate The date of deletion, in the same format as the - * deprecation date. - * @param {string=} opt_use The name of a function or property to use instead, - * if any. - * @package - */ - function warn(name: string, deprecationDate: string, deletionDate: string, opt_use?: string): void; -} -declare module Blockly.utils.dom { - - /** - * Required name space for SVG elements. - * @const - */ - var SVG_NS: any /*missing*/; - - /** - * Required name space for HTML elements. - * @const - */ - var HTML_NS: any /*missing*/; - - /** - * Required name space for XLINK elements. - * @const - */ - var XLINK_NS: any /*missing*/; - - /** - * Node type constants. - * https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType - * @enum {number} - */ - enum NodeType { ELEMENT_NODE, TEXT_NODE, COMMENT_NODE, DOCUMENT_POSITION_CONTAINED_BY } - - /** - * Helper method for creating SVG elements. - * @param {string|Blockly.utils.Svg} name Element's tag name. - * @param {!Object} attrs Dictionary of attribute names and values. - * @param {Element=} opt_parent Optional parent on which to append the element. - * @return {T} Newly created SVG element. The return type is {!SVGElement} if - * name is a string or a more specific type if it a member of - * Blockly.utils.Svg - * @template T - */ - function createSvgElement(name: string|Blockly.utils.Svg, attrs: Object, opt_parent?: Element): T; - - /** - * Add a CSS class to a element. - * Similar to Closure's goog.dom.classes.add, except it handles SVG elements. - * @param {!Element} element DOM element to add class to. - * @param {string} className Name of class to add. - * @return {boolean} True if class was added, false if already present. - */ - function addClass(element: Element, className: string): boolean; - - /** - * Removes multiple calsses from an element. - * @param {!Element} element DOM element to remove classes from. - * @param {string} classNames A string of one or multiple class names for an - * element. - */ - function removeClasses(element: Element, classNames: string): void; - - /** - * Remove a CSS class from a element. - * Similar to Closure's goog.dom.classes.remove, except it handles SVG elements. - * @param {!Element} element DOM element to remove class from. - * @param {string} className Name of class to remove. - * @return {boolean} True if class was removed, false if never present. - */ - function removeClass(element: Element, className: string): boolean; - - /** - * Checks if an element has the specified CSS class. - * Similar to Closure's goog.dom.classes.has, except it handles SVG elements. - * @param {!Element} element DOM element to check. - * @param {string} className Name of class to check. - * @return {boolean} True if class exists, false otherwise. - */ - function hasClass(element: Element, className: string): boolean; - - /** - * Removes a node from its parent. No-op if not attached to a parent. - * @param {?Node} node The node to remove. - * @return {?Node} The node removed if removed; else, null. - */ - function removeNode(node: Node): Node; - - /** - * Insert a node after a reference node. - * Contrast with node.insertBefore function. - * @param {!Element} newNode New element to insert. - * @param {!Element} refNode Existing element to precede new node. - */ - function insertAfter(newNode: Element, refNode: Element): void; - - /** - * Whether a node contains another node. - * @param {!Node} parent The node that should contain the other node. - * @param {!Node} descendant The node to test presence of. - * @return {boolean} Whether the parent node contains the descendant node. - */ - function containsNode(parent: Node, descendant: Node): boolean; - - /** - * Sets the CSS transform property on an element. This function sets the - * non-vendor-prefixed and vendor-prefixed versions for backwards compatibility - * with older browsers. See https://caniuse.com/#feat=transforms2d - * @param {!Element} element Element to which the CSS transform will be applied. - * @param {string} transform The value of the CSS `transform` property. - */ - function setCssTransform(element: Element, transform: string): void; - - /** - * Start caching text widths. Every call to this function MUST also call - * stopTextWidthCache. Caches must not survive between execution threads. - */ - function startTextWidthCache(): void; - - /** - * Stop caching field widths. Unless caching was already on when the - * corresponding call to startTextWidthCache was made. - */ - function stopTextWidthCache(): void; - - /** - * Gets the width of a text element, caching it in the process. - * @param {!Element} textElement An SVG 'text' element. - * @return {number} Width of element. - */ - function getTextWidth(textElement: Element): number; - - /** - * Gets the width of a text element using a faster method than `getTextWidth`. - * This method requires that we know the text element's font family and size in - * advance. Similar to `getTextWidth`, we cache the width we compute. - * @param {!Element} textElement An SVG 'text' element. - * @param {number} fontSize The font size to use. - * @param {string} fontWeight The font weight to use. - * @param {string} fontFamily The font family to use. - * @return {number} Width of element. - */ - function getFastTextWidth(textElement: Element, fontSize: number, fontWeight: string, fontFamily: string): number; - - /** - * Gets the width of a text element using a faster method than `getTextWidth`. - * This method requires that we know the text element's font family and size in - * advance. Similar to `getTextWidth`, we cache the width we compute. - * This method is similar to ``getFastTextWidth`` but expects the font size - * parameter to be a string. - * @param {!Element} textElement An SVG 'text' element. - * @param {string} fontSize The font size to use. - * @param {string} fontWeight The font weight to use. - * @param {string} fontFamily The font family to use. - * @return {number} Width of element. - */ - function getFastTextWidthWithSizeString(textElement: Element, fontSize: string, fontWeight: string, fontFamily: string): number; - - /** - * Measure a font's metrics. The height and baseline values. - * @param {string} text Text to measure the font dimensions of. - * @param {string} fontSize The font size to use. - * @param {string} fontWeight The font weight to use. - * @param {string} fontFamily The font family to use. - * @return {{height: number, baseline: number}} Font measurements. - */ - function measureFontMetrics(text: string, fontSize: string, fontWeight: string, fontFamily: string): { height: number; baseline: number }; -} - - -declare module Blockly.utils { +declare module exports { /** * Reference to the global object. * * More info on this implementation here: - * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit + * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI */ - var global: any /*missing*/; + var globalThis: any /*missing*/; } -declare module Blockly.utils.IdGenerator { +declare module internal { /** - * Gets the next unique ID. - * IDs are compatible with the HTML4 id attribute restrictions: - * Use only ASCII letters, digits, '_', '-' and '.' - * @return {string} The next unique identifier. + * Generate a random unique ID. This should be globally unique. + * 87 characters ^ 20 length > 128 bits (better than a UUID). + * @return {string} A globally unique ID string. */ - function getNextUniqueId(): string; + function genUid(): string; } -declare module Blockly.utils { - - /** - * Key codes for common characters. - * - * Copied from Closure's goog.events.KeyCodes - * - * This list is not localized and therefore some of the key codes are not - * correct for non US keyboard layouts. See comments below. - * - * @enum {number} - */ - enum KeyCodes { WIN_KEY_FF_LINUX, MAC_ENTER, BACKSPACE, TAB, NUM_CENTER, ENTER, SHIFT, CTRL, ALT, PAUSE, CAPS_LOCK, ESC, SPACE, PAGE_UP, PAGE_DOWN, END, HOME, LEFT, UP, RIGHT, DOWN, PLUS_SIGN, PRINT_SCREEN, INSERT, DELETE, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, FF_SEMICOLON, FF_EQUALS, FF_DASH, FF_HASH, QUESTION_MARK, AT_SIGN, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, META, WIN_KEY_RIGHT, CONTEXT_MENU, NUM_ZERO, NUM_ONE, NUM_TWO, NUM_THREE, NUM_FOUR, NUM_FIVE, NUM_SIX, NUM_SEVEN, NUM_EIGHT, NUM_NINE, NUM_MULTIPLY, NUM_PLUS, NUM_MINUS, NUM_PERIOD, NUM_DIVISION, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, NUMLOCK, SCROLL_LOCK, FIRST_MEDIA_KEY, LAST_MEDIA_KEY, SEMICOLON, DASH, EQUALS, COMMA, PERIOD, SLASH, APOSTROPHE, TILDE, SINGLE_QUOTE, OPEN_SQUARE_BRACKET, BACKSLASH, CLOSE_SQUARE_BRACKET, WIN_KEY, MAC_FF_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, WIN_IME, VK_NONAME, PHANTOM } -} -declare module Blockly.utils.math { - - /** - * Converts degrees to radians. - * Copied from Closure's goog.math.toRadians. - * @param {number} angleDegrees Angle in degrees. - * @return {number} Angle in radians. - */ - function toRadians(angleDegrees: number): number; - - /** - * Converts radians to degrees. - * Copied from Closure's goog.math.toDegrees. - * @param {number} angleRadians Angle in radians. - * @return {number} Angle in degrees. - */ - function toDegrees(angleRadians: number): number; - - /** - * Clamp the provided number between the lower bound and the upper bound. - * @param {number} lowerBound The desired lower bound. - * @param {number} number The number to clamp. - * @param {number} upperBound The desired upper bound. - * @return {number} The clamped number. - */ - function clamp(lowerBound: number, number: number, upperBound: number): number; -} -declare module Blockly.utils { - /** - * @record - */ - function Metrics(): void; -} - - -declare module Blockly.utils.object { - - /** - * Inherit the prototype methods from one constructor into another. - * - * @param {!Function} childCtor Child class. - * @param {!Function} parentCtor Parent class. - * @suppress {strictMissingProperties} superClass_ is not defined on Function. - */ - function inherits(childCtor: Function, parentCtor: Function): void; - - /** - * Copies all the members of a source object to a target object. - * @param {!Object} target Target. - * @param {!Object} source Source. - */ - function mixin(target: Object, source: Object): void; - - /** - * Complete a deep merge of all members of a source object with a target object. - * @param {!Object} target Target. - * @param {!Object} source Source. - * @return {!Object} The resulting object. - */ - function deepMerge(target: Object, source: Object): Object; - - /** - * Returns an array of a given object's own enumerable property values. - * @param {!Object} obj Object containing values. - * @return {!Array} Array of values. - */ - function values(obj: Object): any[]; -} - - -declare module Blockly.utils { - - class Rect extends Rect__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Rect__Class { - - /** - * Class for representing rectangular regions. - * @param {number} top Top. - * @param {number} bottom Bottom. - * @param {number} left Left. - * @param {number} right Right. - * @struct - * @constructor - */ - constructor(top: number, bottom: number, left: number, right: number); - - /** @type {number} */ - top: number; - - /** @type {number} */ - bottom: number; - - /** @type {number} */ - left: number; - - /** @type {number} */ - right: number; - - /** - * Tests whether this rectangle contains a x/y coordinate. - * - * @param {number} x The x coordinate to test for containment. - * @param {number} y The y coordinate to test for containment. - * @return {boolean} Whether this rectangle contains given coordinate. - */ - contains(x: number, y: number): boolean; - - /** - * Tests whether this rectangle intersects the provided rectangle. - * Assumes that the coordinate system increases going down and left. - * @param {!Blockly.utils.Rect} other The other rectangle to check for - * intersection with. - * @return {boolean} Whether this rectangle intersects the provided rectangle. - */ - intersects(other: Blockly.utils.Rect): boolean; - } - -} - - -declare module Blockly.utils { - - class Size extends Size__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Size__Class { - - /** - * Class for representing sizes consisting of a width and height. - * @param {number} width Width. - * @param {number} height Height. - * @struct - * @constructor - */ - constructor(width: number, height: number); - - /** - * Width - * @type {number} - */ - width: number; - - /** - * Height - * @type {number} - */ - height: number; - } - -} - -declare module Blockly.utils.Size { +declare module Size { /** * Compares sizes for equality. - * @param {?Blockly.utils.Size} a A Size. - * @param {?Blockly.utils.Size} b A Size. + * @param {?Size} a A Size. + * @param {?Size} b A Size. * @return {boolean} True iff the sizes have equal widths and equal * heights, or if both are null. */ - function equals(a: Blockly.utils.Size, b: Blockly.utils.Size): boolean; + function equals(a: Size, b: Size): boolean; } -declare module Blockly.utils._string { + + +declare module Svg { /** - * Fast prefix-checker. - * Copied from Closure's goog.string.startsWith. - * @param {string} str The string to check. - * @param {string} prefix A string to look for at the start of `str`. - * @return {boolean} True if `str` begins with `prefix`. + * @type {!Svg} + * @package */ - function startsWith(str: string, prefix: string): boolean; + var ANIMATE: Svg; /** - * Given an array of strings, return the length of the shortest one. - * @param {!Array} array Array of strings. - * @return {number} Length of shortest string. + * @type {!Svg} + * @package */ - function shortestStringLength(array: string[]): number; + var CIRCLE: Svg; /** - * Given an array of strings, return the length of the common prefix. - * Words may not be split. Any space after a word is included in the length. - * @param {!Array} array Array of strings. - * @param {number=} opt_shortest Length of shortest string. - * @return {number} Length of common prefix. + * @type {!Svg} + * @package */ - function commonWordPrefix(array: string[], opt_shortest?: number): number; + var CLIPPATH: Svg; /** - * Given an array of strings, return the length of the common suffix. - * Words may not be split. Any space after a word is included in the length. - * @param {!Array} array Array of strings. - * @param {number=} opt_shortest Length of shortest string. - * @return {number} Length of common suffix. + * @type {!Svg} + * @package */ - function commonWordSuffix(array: string[], opt_shortest?: number): number; + var DEFS: Svg; /** - * Wrap text to the specified width. - * @param {string} text Text to wrap. - * @param {number} limit Width to wrap each line. - * @return {string} Wrapped text. + * @type {!Svg} + * @package */ - function wrap(text: string, limit: number): string; + var FECOMPOSITE: Svg; + + /** + * @type {!Svg} + * @package + */ + var FECOMPONENTTRANSFER: Svg; + + /** + * @type {!Svg} + * @package + */ + var FEFLOOD: Svg; + + /** + * @type {!Svg} + * @package + */ + var FEFUNCA: Svg; + + /** + * @type {!Svg} + * @package + */ + var FEGAUSSIANBLUR: Svg; + + /** + * @type {!Svg} + * @package + */ + var FEPOINTLIGHT: Svg; + + /** + * @type {!Svg} + * @package + */ + var FESPECULARLIGHTING: Svg; + + /** + * @type {!Svg} + * @package + */ + var FILTER: Svg; + + /** + * @type {!Svg} + * @package + */ + var FOREIGNOBJECT: Svg; + + /** + * @type {!Svg} + * @package + */ + var G: Svg; + + /** + * @type {!Svg} + * @package + */ + var IMAGE: Svg; + + /** + * @type {!Svg} + * @package + */ + var LINE: Svg; + + /** + * @type {!Svg} + * @package + */ + var PATH: Svg; + + /** + * @type {!Svg} + * @package + */ + var PATTERN: Svg; + + /** + * @type {!Svg} + * @package + */ + var POLYGON: Svg; + + /** + * @type {!Svg} + * @package + */ + var RECT: Svg; + + /** + * @type {!Svg} + * @package + */ + var SVG: Svg; + + /** + * @type {!Svg} + * @package + */ + var TEXT: Svg; + + /** + * @type {!Svg} + * @package + */ + var TSPAN: Svg; } -declare module Blockly.utils.style { - /** - * Gets the height and width of an element. - * Similar to Closure's goog.style.getSize - * @param {!Element} element Element to get size of. - * @return {!Blockly.utils.Size} Object with width/height properties. + +declare module exports { + + /** @const {string} + * @alias Blockly.utils.userAgent.raw */ - function getSize(element: Element): Blockly.utils.Size; + var raw: any /*missing*/; - /** - * Retrieves a computed style value of a node. It returns empty string if the - * value cannot be computed (which will be the case in Internet Explorer) or - * "none" if the property requested is an SVG one and it has not been - * explicitly set (firefox and webkit). - * - * Copied from Closure's goog.style.getComputedStyle - * - * @param {!Element} element Element to get style of. - * @param {string} property Property to get (camel-case). - * @return {string} Style value. + /** @const {boolean} + * @alias Blockly.utils.userAgent.IE */ - function getComputedStyle(element: Element, property: string): string; - - /** - * Gets the cascaded style value of a node, or null if the value cannot be - * computed (only Internet Explorer can do this). - * - * Copied from Closure's goog.style.getCascadedStyle - * - * @param {!Element} element Element to get style of. - * @param {string} style Property to get (camel-case). - * @return {string} Style value. - */ - function getCascadedStyle(element: Element, style: string): string; - - /** - * Returns a Coordinate object relative to the top-left of the HTML document. - * Similar to Closure's goog.style.getPageOffset - * @param {!Element} el Element to get the page offset for. - * @return {!Blockly.utils.Coordinate} The page offset. - */ - function getPageOffset(el: Element): Blockly.utils.Coordinate; - - /** - * Calculates the viewport coordinates relative to the document. - * Similar to Closure's goog.style.getViewportPageOffset - * @return {!Blockly.utils.Coordinate} The page offset of the viewport. - */ - function getViewportPageOffset(): Blockly.utils.Coordinate; - - /** - * Shows or hides an element from the page. Hiding the element is done by - * setting the display property to "none", removing the element from the - * rendering hierarchy so it takes up no space. To show the element, the default - * inherited display property is restored (defined either in stylesheets or by - * the browser's default style rules). - * Copied from Closure's goog.style.getViewportPageOffset - * - * @param {!Element} el Element to show or hide. - * @param {*} isShown True to render the element in its default style, - * false to disable rendering the element. - */ - function setElementShown(el: Element, isShown: any): void; - - /** - * Returns true if the element is using right to left (RTL) direction. - * Copied from Closure's goog.style.isRightToLeft - * - * @param {!Element} el The element to test. - * @return {boolean} True for right to left, false for left to right. - */ - function isRightToLeft(el: Element): boolean; - - /** - * Gets the computed border widths (on all sides) in pixels - * Copied from Closure's goog.style.getBorderBox - * @param {!Element} element The element to get the border widths for. - * @return {!Object} The computed border widths. - */ - function getBorderBox(element: Element): Object; - - /** - * Changes the scroll position of `container` with the minimum amount so - * that the content and the borders of the given `element` become visible. - * If the element is bigger than the container, its top left corner will be - * aligned as close to the container's top left corner as possible. - * Copied from Closure's goog.style.scrollIntoContainerView - * - * @param {!Element} element The element to make visible. - * @param {!Element} container The container to scroll. If not set, then the - * document scroll element will be used. - * @param {boolean=} opt_center Whether to center the element in the container. - * Defaults to false. - */ - function scrollIntoContainerView(element: Element, container: Element, opt_center?: boolean): void; - - /** - * Calculate the scroll position of `container` with the minimum amount so - * that the content and the borders of the given `element` become visible. - * If the element is bigger than the container, its top left corner will be - * aligned as close to the container's top left corner as possible. - * Copied from Closure's goog.style.getContainerOffsetToScrollInto - * - * @param {!Element} element The element to make visible. - * @param {!Element} container The container to scroll. If not set, then the - * document scroll element will be used. - * @param {boolean=} opt_center Whether to center the element in the container. - * Defaults to false. - * @return {!Blockly.utils.Coordinate} The new scroll position of the container, - * in form of goog.math.Coordinate(scrollLeft, scrollTop). - */ - function getContainerOffsetToScrollInto(element: Element, container: Element, opt_center?: boolean): Blockly.utils.Coordinate; -} - - -declare module Blockly.utils { - - class Svg extends Svg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Svg__Class { - - /** - * A name with the type of the SVG element stored in the generic. - * @param {string} tagName The SVG element tag name. - * @constructor - * @template T - * @private - */ - constructor(tagName: string); - } - -} - -declare module Blockly.utils.Svg { - - /** @type {!Blockly.utils.Svg} - * @package - */ - var ANIMATE: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var CIRCLE: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var CLIPPATH: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var DEFS: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FECOMPOSITE: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FECOMPONENTTRANSFER: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FEFLOOD: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FEFUNCA: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FEGAUSSIANBLUR: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FEPOINTLIGHT: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FESPECULARLIGHTING: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FILTER: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var FOREIGNOBJECT: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var G: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var IMAGE: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var LINE: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var PATH: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var PATTERN: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var POLYGON: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var RECT: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var SVG: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var TEXT: Blockly.utils.Svg; - - /** @type {!Blockly.utils.Svg} - * @package - */ - var TSPAN: Blockly.utils.Svg; -} - - -declare module Blockly.utils.svgPaths { - - /** - * Create a string representing the given x, y pair. It does not matter whether - * the coordinate is relative or absolute. The result has leading - * and trailing spaces, and separates the x and y coordinates with a comma but - * no space. - * @param {number} x The x coordinate. - * @param {number} y The y coordinate. - * @return {string} A string of the format ' x,y ' - * @public - */ - function point(x: number, y: number): string; - - /** - * Draw a cubic or quadratic curve. See - * developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Cubic_B%C3%A9zier_Curve - * These coordinates are unitless and hence in the user coordinate system. - * @param {string} command The command to use. - * Should be one of: c, C, s, S, q, Q. - * @param {!Array} points An array containing all of the points to pass to the - * curve command, in order. The points are represented as strings of the - * format ' x, y '. - * @return {string} A string defining one or more Bezier curves. See the MDN - * documentation for exact format. - * @public - */ - function curve(command: string, points: string[]): string; - - /** - * Move the cursor to the given position without drawing a line. - * The coordinates are absolute. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands - * @param {number} x The absolute x coordinate. - * @param {number} y The absolute y coordinate. - * @return {string} A string of the format ' M x,y ' - * @public - */ - function moveTo(x: number, y: number): string; - - /** - * Move the cursor to the given position without drawing a line. - * Coordinates are relative. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands - * @param {number} dx The relative x coordinate. - * @param {number} dy The relative y coordinate. - * @return {string} A string of the format ' m dx,dy ' - * @public - */ - function moveBy(dx: number, dy: number): string; - - /** - * Draw a line from the current point to the end point, which is the current - * point shifted by dx along the x-axis and dy along the y-axis. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands - * @param {number} dx The relative x coordinate. - * @param {number} dy The relative y coordinate. - * @return {string} A string of the format ' l dx,dy ' - * @public - */ - function lineTo(dx: number, dy: number): string; - - /** - * Draw multiple lines connecting all of the given points in order. This is - * equivalent to a series of 'l' commands. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands - * @param {!Array} points An array containing all of the points to - * draw lines to, in order. The points are represented as strings of the - * format ' dx,dy '. - * @return {string} A string of the format ' l (dx,dy)+ ' - * @public - */ - function line(points: string[]): string; - - /** - * Draw a horizontal or vertical line. - * The first argument specifies the direction and whether the given position is - * relative or absolute. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#LineTo_path_commands - * @param {string} command The command to prepend to the coordinate. This - * should be one of: V, v, H, h. - * @param {number} val The coordinate to pass to the command. It may be - * absolute or relative. - * @return {string} A string of the format ' command val ' - * @public - */ - function lineOnAxis(command: string, val: number): string; - - /** - * Draw an elliptical arc curve. - * These coordinates are unitless and hence in the user coordinate system. - * See developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#Elliptical_Arc_Curve - * @param {string} command The command string. Either 'a' or 'A'. - * @param {string} flags The flag string. See the MDN documentation for a - * description and examples. - * @param {number} radius The radius of the arc to draw. - * @param {string} point The point to move the cursor to after drawing the arc, - * specified either in absolute or relative coordinates depending on the - * command. - * @return {string} A string of the format 'command radius radius flags point' - * @public - */ - function arc(command: string, flags: string, radius: number, point: string): string; -} - - -declare module Blockly.utils.toolbox { - - /** - * The information needed to create a block in the toolbox. - * @typedef {{ - * kind:string, - * blockxml:(string|!Node|undefined), - * type:(string|undefined), - * gap:(string|number|undefined), - * disabled: (string|boolean|undefined) - * }} - */ - interface BlockInfo { - kind: string; - blockxml: string|Node|any /*undefined*/; - type: string|any /*undefined*/; - gap: string|number|any /*undefined*/; - disabled: string|boolean|any /*undefined*/ - } - - /** - * The information needed to create a separator in the toolbox. - * @typedef {{ - * kind:string, - * id:(string|undefined), - * gap:(number|undefined), - * cssconfig:(!Blockly.ToolboxSeparator.CssConfig|undefined) - * }} - */ - interface SeparatorInfo { - kind: string; - id: string|any /*undefined*/; - gap: number|any /*undefined*/; - cssconfig: Blockly.ToolboxSeparator.CssConfig|any /*undefined*/ - } - - /** - * The information needed to create a button in the toolbox. - * @typedef {{ - * kind:string, - * text:string, - * callbackkey:string - * }} - */ - interface ButtonInfo { - kind: string; - text: string; - callbackkey: string - } - - /** - * The information needed to create a label in the toolbox. - * @typedef {{ - * kind:string, - * text:string, - * id:(string|undefined) - * }} - */ - interface LabelInfo { - kind: string; - text: string; - id: string|any /*undefined*/ - } - - /** - * The information needed to create either a button or a label in the flyout. - * @typedef {Blockly.utils.toolbox.ButtonInfo| - * Blockly.utils.toolbox.LabelInfo} - */ - type ButtonOrLabelInfo = Blockly.utils.toolbox.ButtonInfo|Blockly.utils.toolbox.LabelInfo; - - /** - * The information needed to create a category in the toolbox. - * @typedef {{ - * kind:string, - * name:string, - * contents:!Array, - * id:(string|undefined), - * categorystyle:(string|undefined), - * colour:(string|undefined), - * cssconfig:(!Blockly.ToolboxCategory.CssConfig|undefined), - * hidden:(string|undefined) - * }} - */ - interface StaticCategoryInfo { - kind: string; - name: string; - contents: Blockly.utils.toolbox.ToolboxItemInfo[]; - id: string|any /*undefined*/; - categorystyle: string|any /*undefined*/; - colour: string|any /*undefined*/; - cssconfig: Blockly.ToolboxCategory.CssConfig|any /*undefined*/; - hidden: string|any /*undefined*/ - } - - /** - * The information needed to create a custom category. - * @typedef {{ - * kind:string, - * custom:string, - * id:(string|undefined), - * categorystyle:(string|undefined), - * colour:(string|undefined), - * cssconfig:(!Blockly.ToolboxCategory.CssConfig|undefined), - * hidden:(string|undefined) - * }} - */ - interface DynamicCategoryInfo { - kind: string; - custom: string; - id: string|any /*undefined*/; - categorystyle: string|any /*undefined*/; - colour: string|any /*undefined*/; - cssconfig: Blockly.ToolboxCategory.CssConfig|any /*undefined*/; - hidden: string|any /*undefined*/ - } - - /** - * The information needed to create either a dynamic or static category. - * @typedef {Blockly.utils.toolbox.StaticCategoryInfo| - * Blockly.utils.toolbox.DynamicCategoryInfo} - */ - type CategoryInfo = Blockly.utils.toolbox.StaticCategoryInfo|Blockly.utils.toolbox.DynamicCategoryInfo; - - /** - * Any information that can be used to create an item in the toolbox. - * @typedef {Blockly.utils.toolbox.FlyoutItemInfo| - * Blockly.utils.toolbox.StaticCategoryInfo} - */ - type ToolboxItemInfo = Blockly.utils.toolbox.FlyoutItemInfo|Blockly.utils.toolbox.StaticCategoryInfo; - - /** - * All the different types that can be displayed in a flyout. - * @typedef {Blockly.utils.toolbox.BlockInfo| - * Blockly.utils.toolbox.SeparatorInfo| - * Blockly.utils.toolbox.ButtonInfo| - * Blockly.utils.toolbox.LabelInfo| - * Blockly.utils.toolbox.DynamicCategoryInfo} - */ - type FlyoutItemInfo = Blockly.utils.toolbox.BlockInfo|Blockly.utils.toolbox.SeparatorInfo|Blockly.utils.toolbox.ButtonInfo|Blockly.utils.toolbox.LabelInfo|Blockly.utils.toolbox.DynamicCategoryInfo; - - /** - * The JSON definition of a toolbox. - * @typedef {{ - * kind:(string|undefined), - * contents:!Array - * }} - */ - interface ToolboxInfo { - kind: string|any /*undefined*/; - contents: Blockly.utils.toolbox.ToolboxItemInfo[] - } - - /** - * An array holding flyout items. - * @typedef { - * Array - * } - */ - interface FlyoutItemInfoArray extends Array { } - - /** - * All of the different types that can create a toolbox. - * @typedef {Node| - * Blockly.utils.toolbox.ToolboxInfo| - * string} - */ - type ToolboxDefinition = Node|Blockly.utils.toolbox.ToolboxInfo|string; - - /** - * All of the different types that can be used to show items in a flyout. - * @typedef {Blockly.utils.toolbox.FlyoutItemInfoArray| - * NodeList| - * Blockly.utils.toolbox.ToolboxInfo| - * Array} - */ - type FlyoutDefinition = Blockly.utils.toolbox.FlyoutItemInfoArray|NodeList|Blockly.utils.toolbox.ToolboxInfo|Node[]; - - /** - * The name used to identify a toolbox that has category like items. - * This only needs to be used if a toolbox wants to be treated like a category - * toolbox but does not actually contain any toolbox items with the kind - * 'category'. - * @const {string} - */ - var CATEGORY_TOOLBOX_KIND: any /*missing*/; - - /** - * The name used to identify a toolbox that has no categories and is displayed - * as a simple flyout displaying blocks, buttons, or labels. - * @const {string} - */ - var FLYOUT_TOOLBOX_KIND: any /*missing*/; - - /** - * Position of the the toolbox and/or flyout relative to the workspace. - * @enum {number} - */ - enum Position { TOP, BOTTOM, LEFT, RIGHT } - - /** - * Converts the toolbox definition into toolbox JSON. - * @param {?Blockly.utils.toolbox.ToolboxDefinition} toolboxDef The definition - * of the toolbox in one of its many forms. - * @return {?Blockly.utils.toolbox.ToolboxInfo} Object holding information - * for creating a toolbox. - * @package - */ - function convertToolboxDefToJson(toolboxDef: Blockly.utils.toolbox.ToolboxDefinition): Blockly.utils.toolbox.ToolboxInfo; - - /** - * Converts the flyout definition into a list of flyout items. - * @param {?Blockly.utils.toolbox.FlyoutDefinition} flyoutDef The definition of - * the flyout in one of its many forms. - * @return {!Blockly.utils.toolbox.FlyoutItemInfoArray} A list of flyout items. - * @package - */ - function convertFlyoutDefToJsonArray(flyoutDef: Blockly.utils.toolbox.FlyoutDefinition): Blockly.utils.toolbox.FlyoutItemInfoArray; - - /** - * Whether or not the toolbox definition has categories. - * @param {?Blockly.utils.toolbox.ToolboxInfo} toolboxJson Object holding - * information for creating a toolbox. - * @return {boolean} True if the toolbox has categories. - * @package - */ - function hasCategories(toolboxJson: Blockly.utils.toolbox.ToolboxInfo): boolean; - - /** - * Whether or not the category is collapsible. - * @param {!Blockly.utils.toolbox.CategoryInfo} categoryInfo Object holing - * information for creating a category. - * @return {boolean} True if the category has subcategories. - * @package - */ - function isCategoryCollapsible(categoryInfo: Blockly.utils.toolbox.CategoryInfo): boolean; - - /** - * Parse the provided toolbox tree into a consistent DOM format. - * @param {?Node|?string} toolboxDef DOM tree of blocks, or text representation - * of same. - * @return {?Node} DOM tree of blocks, or null. - */ - function parseToolboxTree(toolboxDef: Node|string): Node; -} - - -declare module Blockly.utils.userAgent { - - /** @const {boolean} */ var IE: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.EDGE + */ var EDGE: any /*missing*/; - /** @const {boolean} */ - var JAVA_FX: any /*missing*/; + /** @const {boolean} + * @alias Blockly.utils.userAgent.JavaFx + */ + var JavaFx: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.CHROME + */ var CHROME: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.WEBKIT + */ var WEBKIT: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.GECKO + */ var GECKO: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.ANDROID + */ var ANDROID: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.IPAD + */ var IPAD: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.IPOD + */ var IPOD: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.IPHONE + */ var IPHONE: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.MAC + */ var MAC: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.TABLET + */ var TABLET: any /*missing*/; - /** @const {boolean} */ + /** @const {boolean} + * @alias Blockly.utils.userAgent.MOBILE + */ var MOBILE: any /*missing*/; } -declare module Blockly.utils.xml { - - /** - * Namespace for Blockly's XML. - */ - var NAME_SPACE: any /*missing*/; - - /** - * Get the document object. This method is overridden in the Node.js build of - * Blockly. See gulpfile.js, package-blockly-node task. - * @return {!Document} The document object. - * @public - */ - function document(): Document; - - /** - * Create DOM element for XML. - * @param {string} tagName Name of DOM element. - * @return {!Element} New DOM element. - * @public - */ - function createElement(tagName: string): Element; - - /** - * Create text element for XML. - * @param {string} text Text content. - * @return {!Text} New DOM text node. - * @public - */ - function createTextNode(text: string): Text; - - /** - * Converts an XML string into a DOM tree. - * @param {string} text XML string. - * @return {Document} The DOM document. - * @throws if XML doesn't parse. - * @public - */ - function textToDomDocument(text: string): Document; - - /** - * Converts a DOM structure into plain text. - * Currently the text format is fairly ugly: all one line with no whitespace. - * @param {!Node} dom A tree of XML nodes. - * @return {string} Text representation. - * @public - */ - function domToText(dom: Node): string; -} -declare module Blockly.blockRendering { - - /** - * Whether or not the debugger is turned on. - * @type {boolean} - * @package - */ - var useDebugger: boolean; - - /** - * Registers a new renderer. - * @param {string} name The name of the renderer. - * @param {!Function} rendererClass The new renderer class - * to register. - * @throws {Error} if a renderer with the same name has already been registered. - */ - function register(name: string, rendererClass: Function): void; - - /** - * Unregisters the renderer registered with the given name. - * @param {string} name The name of the renderer. - */ - function unregister(name: string): void; - - /** - * Turn on the blocks debugger. - * @package - */ - function startDebugger(): void; - - /** - * Turn off the blocks debugger. - * @package - */ - function stopDebugger(): void; - - /** - * Initialize anything needed for rendering (constants, etc). - * @param {!string} name Name of the renderer to initialize. - * @param {!Blockly.Theme} theme The workspace theme object. - * @param {Object=} opt_rendererOverrides Rendering constant overrides. - * @return {!Blockly.blockRendering.Renderer} The new instance of a renderer. - * Already initialized. - * @package - */ - function init(name: string, theme: Blockly.Theme, opt_rendererOverrides?: Object): Blockly.blockRendering.Renderer; -} -declare module Blockly.blockRendering { - - class ConstantProvider extends ConstantProvider__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ConstantProvider__Class { - - /** - * An object that provides constants for rendering blocks. - * @constructor - * @package - */ - constructor(); - - /** - * The size of an empty spacer. - * @type {number} - */ - NO_PADDING: number; - - /** - * The size of small padding. - * @type {number} - */ - SMALL_PADDING: number; - - /** - * The size of medium padding. - * @type {number} - */ - MEDIUM_PADDING: number; - - /** - * The size of medium-large padding. - * @type {number} - */ - MEDIUM_LARGE_PADDING: number; - - /** - * The size of large padding. - * @type {number} - */ - LARGE_PADDING: number; - - /** - * Offset from the top of the row for placing fields on inline input rows - * and statement input rows. - * Matches existing rendering (in 2019). - * @type {number} - */ - TALL_INPUT_FIELD_OFFSET_Y: number; - - /** - * The height of the puzzle tab used for input and output connections. - * @type {number} - */ - TAB_HEIGHT: number; - - /** - * The offset from the top of the block at which a puzzle tab is positioned. - * @type {number} - */ - TAB_OFFSET_FROM_TOP: number; - - /** - * Vertical overlap of the puzzle tab, used to make it look more like a puzzle - * piece. - * @type {number} - */ - TAB_VERTICAL_OVERLAP: number; - - /** - * The width of the puzzle tab used for input and output connections. - * @type {number} - */ - TAB_WIDTH: number; - - /** - * The width of the notch used for previous and next connections. - * @type {number} - */ - NOTCH_WIDTH: number; - - /** - * The height of the notch used for previous and next connections. - * @type {number} - */ - NOTCH_HEIGHT: number; - - /** - * The minimum width of the block. - * @type {number} - */ - MIN_BLOCK_WIDTH: number; - - /** - * The minimum height of a dummy input row. - * @type {number} - */ - DUMMY_INPUT_MIN_HEIGHT: number; - - /** - * The minimum height of a dummy input row in a shadow block. - * @type {number} - */ - DUMMY_INPUT_SHADOW_MIN_HEIGHT: number; - - /** - * Rounded corner radius. - * @type {number} - */ - CORNER_RADIUS: number; - - /** - * Offset from the left side of a block or the inside of a statement input to - * the left side of the notch. - * @type {number} - */ - NOTCH_OFFSET_LEFT: number; - - /** - * Additional offset added to the statement input's width to account for the - * notch. - * @type {number} - */ - STATEMENT_INPUT_NOTCH_OFFSET: number; - - /** - * Vertical padding between consecutive statement inputs. - * @type {number} - */ - BETWEEN_STATEMENT_PADDING_Y: number; - - /** - * The top row's minimum height. - * @type {number} - */ - TOP_ROW_MIN_HEIGHT: number; - - /** - * The top row's minimum height if it precedes a statement. - * @type {number} - */ - TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT: number; - - /** - * The bottom row's minimum height. - * @type {number} - */ - BOTTOM_ROW_MIN_HEIGHT: number; - - /** - * The bottom row's minimum height if it follows a statement input. - * @type {number} - */ - BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT: number; - - /** - * Whether to add a 'hat' on top of all blocks with no previous or output - * connections. Can be overridden by 'hat' property on Theme.BlockStyle. - * @type {boolean} - */ - ADD_START_HATS: boolean; - - /** - * Height of the top hat. - * @type {number} - */ - START_HAT_HEIGHT: number; - - /** - * Width of the top hat. - * @type {number} - */ - START_HAT_WIDTH: number; - - /** - * The height of an empty inline input. - * @type {number} - */ - EMPTY_INLINE_INPUT_HEIGHT: number; - - /** - * The height of an empty statement input. Note that in the old rendering this - * varies slightly depending on whether the block has external or inline inputs. - * In the new rendering this is consistent. It seems unlikely that the old - * behaviour was intentional. - * @type {number} - */ - EMPTY_STATEMENT_INPUT_HEIGHT: number; - - /** - * Height of SVG path for jagged teeth at the end of collapsed blocks. - * @type {number} - */ - JAGGED_TEETH_HEIGHT: number; - - /** - * Width of SVG path for jagged teeth at the end of collapsed blocks. - * @type {number} - */ - JAGGED_TEETH_WIDTH: number; - - /** - * Point size of text. - * @type {number} - */ - FIELD_TEXT_FONTSIZE: number; - - /** - * Text font weight. - * @type {string} - */ - FIELD_TEXT_FONTWEIGHT: string; - - /** - * Text font family. - * @type {string} - */ - FIELD_TEXT_FONTFAMILY: string; - - /** - * Height of text. This constant is dynamically set in ``setFontConstants_`` - * to be the height of the text based on the font used. - * @type {number} - */ - FIELD_TEXT_HEIGHT: number; - - /** - * Text baseline. This constant is dynamically set in ``setFontConstants_`` - * to be the baseline of the text based on the font used. - * @type {number} - */ - FIELD_TEXT_BASELINE: number; - - /** - * A field's border rect corner radius. - * @type {number} - */ - FIELD_BORDER_RECT_RADIUS: number; - - /** - * A field's border rect default height. - * @type {number} - */ - FIELD_BORDER_RECT_HEIGHT: number; - - /** - * A field's border rect X padding. - * @type {number} - */ - FIELD_BORDER_RECT_X_PADDING: number; - - /** - * A field's border rect Y padding. - * @type {number} - */ - FIELD_BORDER_RECT_Y_PADDING: number; - - /** - * The backing colour of a field's border rect. - * @type {string} - * @package - */ - FIELD_BORDER_RECT_COLOUR: string; - - /** - * A field's text element's dominant baseline. - * @type {boolean} - */ - FIELD_TEXT_BASELINE_CENTER: boolean; - - /** - * A dropdown field's border rect height. - * @type {number} - */ - FIELD_DROPDOWN_BORDER_RECT_HEIGHT: number; - - /** - * Whether or not a dropdown field should add a border rect when in a shadow - * block. - * @type {boolean} - */ - FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW: boolean; - - /** - * Whether or not a dropdown field's div should be coloured to match the - * block colours. - * @type {boolean} - */ - FIELD_DROPDOWN_COLOURED_DIV: boolean; - - /** - * Whether or not a dropdown field uses a text or SVG arrow. - * @type {boolean} - */ - FIELD_DROPDOWN_SVG_ARROW: boolean; - - /** - * A dropdown field's SVG arrow padding. - * @type {number} - */ - FIELD_DROPDOWN_SVG_ARROW_PADDING: number; - - /** - * A dropdown field's SVG arrow size. - * @type {number} - */ - FIELD_DROPDOWN_SVG_ARROW_SIZE: number; - - /** - * A dropdown field's SVG arrow datauri. - * @type {string} - */ - FIELD_DROPDOWN_SVG_ARROW_DATAURI: string; - - /** - * Whether or not to show a box shadow around the widget div. This is only a - * feature of full block fields. - * @type {boolean} - */ - FIELD_TEXTINPUT_BOX_SHADOW: boolean; - - /** - * Whether or not the colour field should display its colour value on the - * entire block. - * @type {boolean} - */ - FIELD_COLOUR_FULL_BLOCK: boolean; - - /** - * A colour field's default width. - * @type {number} - */ - FIELD_COLOUR_DEFAULT_WIDTH: number; - - /** - * A colour field's default height. - * @type {number} - */ - FIELD_COLOUR_DEFAULT_HEIGHT: number; - - /** - * A checkbox field's X offset. - * @type {number} - */ - FIELD_CHECKBOX_X_OFFSET: number; - - /** - * A random identifier used to ensure a unique ID is used for each - * filter/pattern for the case of multiple Blockly instances on a page. - * @type {string} - * @package - */ - randomIdentifier: string; - - /** - * The ID of the emboss filter, or the empty string if no filter is set. - * @type {string} - * @package - */ - embossFilterId: string; - - /** - * The ID of the disabled pattern, or the empty string if no pattern is set. - * @type {string} - * @package - */ - disabledPatternId: string; - - /** - * The ID of the debug filter, or the empty string if no pattern is set. - * @type {string} - * @package - */ - debugFilterId: string; - - /** - * Cursor colour. - * @type {string} - * @package - */ - CURSOR_COLOUR: string; - - /** - * Immovable marker colour. - * @type {string} - * @package - */ - MARKER_COLOUR: string; - - /** - * Width of the horizontal cursor. - * @type {number} - * @package - */ - CURSOR_WS_WIDTH: number; - - /** - * Height of the horizontal cursor. - * @type {number} - * @package - */ - WS_CURSOR_HEIGHT: number; - - /** - * Padding around a stack. - * @type {number} - * @package - */ - CURSOR_STACK_PADDING: number; - - /** - * Padding around a block. - * @type {number} - * @package - */ - CURSOR_BLOCK_PADDING: number; - - /** - * Stroke of the cursor. - * @type {number} - * @package - */ - CURSOR_STROKE_WIDTH: number; - - /** - * Whether text input and colour fields fill up the entire source block. - * @type {boolean} - * @package - */ - FULL_BLOCK_FIELDS: boolean; - - /** - * The main colour of insertion markers, in hex. The block is rendered a - * transparent grey by changing the fill opacity in CSS. - * @type {string} - * @package - */ - INSERTION_MARKER_COLOUR: string; - - /** - * The insertion marker opacity. - * @type {number} - * @package - */ - INSERTION_MARKER_OPACITY: number; - - /** - * Enum for connection shapes. - * @enum {number} - */ - SHAPES: any /*missing*/; - - /** - * Initialize shape objects based on the constants set in the constructor. - * @package - */ - init(): void; - - /** - * An object containing sizing and path information about collapsed block - * indicators. - * @type {!Object} - */ - JAGGED_TEETH: Object; - - /** - * An object containing sizing and path information about notches. - * @type {!Object} - */ - NOTCH: Object; - - /** - * An object containing sizing and path information about start hats - * @type {!Object} - */ - START_HAT: Object; - - /** - * An object containing sizing and path information about puzzle tabs. - * @type {!Object} - */ - PUZZLE_TAB: Object; - - /** - * An object containing sizing and path information about inside corners - * @type {!Object} - */ - INSIDE_CORNERS: Object; - - /** - * An object containing sizing and path information about outside corners. - * @type {!Object} - */ - OUTSIDE_CORNERS: Object; - - /** - * Refresh constants properties that depend on the theme. - * @param {!Blockly.Theme} theme The current workspace theme. - * @package - */ - setTheme(theme: Blockly.Theme): void; - - /** - * The block styles map. - * @type {Object} - * @package - */ - blockStyles: { [key: string]: Blockly.Theme.BlockStyle }; - - /** - * Sets dynamic properties that depend on other values or theme properties. - * @param {!Blockly.Theme} theme The current workspace theme. - * @protected - */ - setDynamicProperties_(theme: Blockly.Theme): void; - - /** - * Set constants related to fonts. - * @param {!Blockly.Theme} theme The current workspace theme. - * @protected - */ - setFontConstants_(theme: Blockly.Theme): void; - - /** - * Set constants from a theme's component styles. - * @param {!Blockly.Theme} theme The current workspace theme. - * @protected - */ - setComponentConstants_(theme: Blockly.Theme): void; - - /** - * Get or create a block style based on a single colour value. Generate a name - * for the style based on the colour. - * @param {string} colour #RRGGBB colour string. - * @return {{style: !Blockly.Theme.BlockStyle, name: string}} An object - * containing the style and an autogenerated name for that style. - * @package - */ - getBlockStyleForColour(colour: string): { style: Blockly.Theme.BlockStyle; name: string }; - - /** - * Gets the BlockStyle for the given block style name. - * @param {?string} blockStyleName The name of the block style. - * @return {!Blockly.Theme.BlockStyle} The named block style, or a default style - * if no style with the given name was found. - */ - getBlockStyle(blockStyleName: string): Blockly.Theme.BlockStyle; - - /** - * Create a block style object based on the given colour. - * @param {string} colour #RRGGBB colour string. - * @return {!Blockly.Theme.BlockStyle} A populated block style based on the - * given colour. - * @protected - */ - createBlockStyle_(colour: string): Blockly.Theme.BlockStyle; - - /** - * Get a full block style object based on the input style object. Populate - * any missing values. - * @param {{ - * colourPrimary:string, - * colourSecondary:(string|undefined), - * colourTertiary:(string|undefined), - * hat:(string|undefined) - * }} blockStyle A full or partial block style object. - - * @return {!Blockly.Theme.BlockStyle} A full block style object, with all - * required properties populated. - * @protected - */ - validatedBlockStyle_(blockStyle: { colourPrimary: string; colourSecondary: string|any /*undefined*/; colourTertiary: string|any /*undefined*/; hat: string|any /*undefined*/ }): Blockly.Theme.BlockStyle; - - /** - * Generate a secondary colour from the passed in primary colour. - * @param {string} colour Primary colour. - * @return {string} The generated secondary colour. - * @protected - */ - generateSecondaryColour_(colour: string): string; - - /** - * Generate a tertiary colour from the passed in primary colour. - * @param {string} colour Primary colour. - * @return {string} The generated tertiary colour. - * @protected - */ - generateTertiaryColour_(colour: string): string; - - /** - * Dispose of this constants provider. - * Delete all DOM elements that this provider created. - * @package - */ - dispose(): void; - - /** - * @return {!Object} An object containing sizing and path information about - * collapsed block indicators. - * @package - */ - makeJaggedTeeth(): Object; - - /** - * @return {!Object} An object containing sizing and path information about - * start hats. - * @package - */ - makeStartHat(): Object; - - /** - * @return {!Object} An object containing sizing and path information about - * puzzle tabs. - * @package - */ - makePuzzleTab(): Object; - - /** - * @return {!Object} An object containing sizing and path information about - * notches. - * @package - */ - makeNotch(): Object; - - /** - * @return {!Object} An object containing sizing and path information about - * inside corners. - * @package - */ - makeInsideCorners(): Object; - - /** - * @return {!Object} An object containing sizing and path information about - * outside corners. - * @package - */ - makeOutsideCorners(): Object; - - /** - * Get an object with connection shape and sizing information based on the type - * of the connection. - * @param {!Blockly.RenderedConnection} connection The connection to find a - * shape object for - * @return {!Object} The shape object for the connection. - * @package - */ - shapeFor(connection: Blockly.RenderedConnection): Object; - - /** - * Create any DOM elements that this renderer needs (filters, patterns, etc). - * @param {!SVGElement} svg The root of the workspace's SVG. - * @param {string} tagName The name to use for the CSS style tag. - * @param {string} selector The CSS selector to use. - * @suppress {strictModuleDepCheck} Debug renderer only included in playground. - * @package - */ - createDom(svg: SVGElement, tagName: string, selector: string): void; - - /** - * Inject renderer specific CSS into the page. - * @param {string} tagName The name of the style tag to use. - * @param {string} selector The CSS selector to use. - * @protected - */ - injectCSS_(tagName: string, selector: string): void; - - /** - * Get any renderer specific CSS to inject when the renderer is initialized. - * @param {string} selector CSS selector to use. - * @return {!Array} Array of CSS strings. - * @protected - */ - getCSS_(selector: string): string[]; - } - -} - - -declare module Blockly.blockRendering { - - class Debug extends Debug__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Debug__Class { - - /** - * An object that renders rectangles and dots for debugging rendering code. - * @param {!Blockly.blockRendering.ConstantProvider} constants The renderer's - * constants. - * @package - * @constructor - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * Remove all elements the this object created on the last pass. - * @package - */ - clearElems(): void; - - /** - * Draw a debug rectangle for a spacer (empty) row. - * @param {!Blockly.blockRendering.Row} row The row to render. - * @param {number} cursorY The y position of the top of the row. - * @param {boolean} isRtl Whether the block is rendered RTL. - * @package - */ - drawSpacerRow(row: Blockly.blockRendering.Row, cursorY: number, isRtl: boolean): void; - - /** - * Draw a debug rectangle for a horizontal spacer. - * @param {!Blockly.blockRendering.InRowSpacer} elem The spacer to render. - * @param {number} rowHeight The height of the container row. - * @param {boolean} isRtl Whether the block is rendered RTL. - * @package - */ - drawSpacerElem(elem: Blockly.blockRendering.InRowSpacer, rowHeight: number, isRtl: boolean): void; - - /** - * Draw a debug rectangle for an in-row element. - * @param {!Blockly.blockRendering.Measurable} elem The element to render. - * @param {boolean} isRtl Whether the block is rendered RTL. - * @package - */ - drawRenderedElem(elem: Blockly.blockRendering.Measurable, isRtl: boolean): void; - - /** - * Draw a circle at the location of the given connection. Inputs and outputs - * share the same colours, as do previous and next. When positioned correctly - * a connected pair will look like a bullseye. - * @param {Blockly.RenderedConnection} conn The connection to circle. - * @suppress {visibility} Suppress visibility of conn.offsetInBlock_ since this - * is a debug module. - * @package - */ - drawConnection(conn: Blockly.RenderedConnection): void; - - /** - * Draw a debug rectangle for a non-empty row. - * @param {!Blockly.blockRendering.Row} row The non-empty row to render. - * @param {number} cursorY The y position of the top of the row. - * @param {boolean} isRtl Whether the block is rendered RTL. - * @package - */ - drawRenderedRow(row: Blockly.blockRendering.Row, cursorY: number, isRtl: boolean): void; - - /** - * Draw debug rectangles for a non-empty row and all of its subcomponents. - * @param {!Blockly.blockRendering.Row} row The non-empty row to render. - * @param {number} cursorY The y position of the top of the row. - * @param {boolean} isRtl Whether the block is rendered RTL. - * @package - */ - drawRowWithElements(row: Blockly.blockRendering.Row, cursorY: number, isRtl: boolean): void; - - /** - * Draw a debug rectangle around the entire block. - * @param {!Blockly.blockRendering.RenderInfo} info Rendering information about - * the block to debug. - * @package - */ - drawBoundingBox(info: Blockly.blockRendering.RenderInfo): void; - - /** - * Do all of the work to draw debug information for the whole block. - * @param {!Blockly.BlockSvg} block The block to draw debug information for. - * @param {!Blockly.blockRendering.RenderInfo} info Rendering information about - * the block to debug. - * @package - */ - drawDebug(block: Blockly.BlockSvg, info: Blockly.blockRendering.RenderInfo): void; - - /** - * Show a debug filter to highlight that a block has been rendered. - * @param {!SVGElement} svgPath The block's SVG path. - * @package - */ - drawRender(svgPath: SVGElement): void; - } - -} - -declare module Blockly.blockRendering.Debug { +declare module Debug { /** * Configuration object containing booleans to enable and disable debug @@ -19745,1928 +2377,34 @@ declare module Blockly.blockRendering.Debug { } -declare module Blockly.blockRendering { - - class Drawer extends Drawer__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Drawer__Class { - - /** - * An object that draws a block based on the given rendering information. - * @param {!Blockly.BlockSvg} block The block to render. - * @param {!Blockly.blockRendering.RenderInfo} info An object containing all - * information needed to render this block. - * @package - * @constructor - */ - constructor(block: Blockly.BlockSvg, info: Blockly.blockRendering.RenderInfo); - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - - /** - * Draw the block to the workspace. Here "drawing" means setting SVG path - * elements and moving fields, icons, and connections on the screen. - * - * The pieces of the paths are pushed into arrays of "steps", which are then - * joined with spaces and set directly on the block. This guarantees that - * the steps are separated by spaces for improved readability, but isn't - * required. - * @package - */ - draw(): void; - - /** - * Save sizing information back to the block - * Most of the rendering information can be thrown away at the end of the - * render. Anything that needs to be kept around should be set in this function. - * @protected - */ - recordSizeOnBlock_(): void; - - /** - * Hide icons that were marked as hidden. - * @protected - */ - hideHiddenIcons_(): void; - - /** - * Create the outline of the block. This is a single continuous path. - * @protected - */ - drawOutline_(): void; - - /** - * Add steps for the top corner of the block, taking into account - * details such as hats and rounded corners. - * @protected - */ - drawTop_(): void; - - /** - * Add steps for the jagged edge of a row on a collapsed block. - * @param {!Blockly.blockRendering.Row} row The row to draw the side of. - * @protected - */ - drawJaggedEdge_(row: Blockly.blockRendering.Row): void; - - /** - * Add steps for an external value input, rendered as a notch in the side - * of the block. - * @param {!Blockly.blockRendering.Row} row The row that this input - * belongs to. - * @protected - */ - drawValueInput_(row: Blockly.blockRendering.Row): void; - - /** - * Add steps for a statement input. - * @param {!Blockly.blockRendering.Row} row The row that this input - * belongs to. - * @protected - */ - drawStatementInput_(row: Blockly.blockRendering.Row): void; - - /** - * Add steps for the right side of a row that does not have value or - * statement input connections. - * @param {!Blockly.blockRendering.Row} row The row to draw the - * side of. - * @protected - */ - drawRightSideRow_(row: Blockly.blockRendering.Row): void; - - /** - * Add steps for the bottom edge of a block, possibly including a notch - * for the next connection. - * @protected - */ - drawBottom_(): void; - - /** - * Add steps for the left side of the block, which may include an output - * connection - * @protected - */ - drawLeft_(): void; - - /** - * Draw the internals of the block: inline inputs, fields, and icons. These do - * not depend on the outer path for placement. - * @protected - */ - drawInternals_(): void; - - /** - * Push a field or icon's new position to its SVG root. - * @param {!Blockly.blockRendering.Icon|!Blockly.blockRendering.Field} fieldInfo - * The rendering information for the field or icon. - * @protected - */ - layoutField_(fieldInfo: Blockly.blockRendering.Icon|Blockly.blockRendering.Field): void; - - /** - * Add steps for an inline input. - * @param {!Blockly.blockRendering.InlineInput} input The information about the - * input to render. - * @protected - */ - drawInlineInput_(input: Blockly.blockRendering.InlineInput): void; - - /** - * Position the connection on an inline value input, taking into account - * RTL and the small gap between the parent block and child block which lets the - * parent block's dark path show through. - * @param {Blockly.blockRendering.InlineInput} input The information about - * the input that the connection is on. - * @protected - */ - positionInlineInputConnection_(input: Blockly.blockRendering.InlineInput): void; - - /** - * Position the connection on a statement input, taking into account - * RTL and the small gap between the parent block and child block which lets the - * parent block's dark path show through. - * @param {!Blockly.blockRendering.Row} row The row that the connection is on. - * @protected - */ - positionStatementInputConnection_(row: Blockly.blockRendering.Row): void; - - /** - * Position the connection on an external value input, taking into account - * RTL and the small gap between the parent block and child block which lets the - * parent block's dark path show through. - * @param {!Blockly.blockRendering.Row} row The row that the connection is on. - * @protected - */ - positionExternalValueConnection_(row: Blockly.blockRendering.Row): void; - - /** - * Position the previous connection on a block. - * @protected - */ - positionPreviousConnection_(): void; - - /** - * Position the next connection on a block. - * @protected - */ - positionNextConnection_(): void; - - /** - * Position the output connection on a block. - * @protected - */ - positionOutputConnection_(): void; - } - -} -declare module Blockly.blockRendering { - - interface IPathObject { - - /** - * The primary path of the block. - * @type {!SVGElement} - */ - svgPath: SVGElement; - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - */ - constants: Blockly.blockRendering.ConstantProvider; - - /** - * The primary path of the block. - * @type {!Blockly.Theme.BlockStyle} - */ - style: Blockly.Theme.BlockStyle; - - /** - * Holds the cursors SVG element when the cursor is attached to the block. - * This is null if there is no cursor on the block. - * @type {SVGElement} - */ - cursorSvg: SVGElement; - - /** - * Holds the markers SVG element when the marker is attached to the block. - * This is null if there is no marker on the block. - * @type {SVGElement} - */ - markerSvg: SVGElement; - - /** - * Set the path generated by the renderer onto the respective SVG element. - * @param {string} pathString The path. - * @package - */ - setPath(pathString: string): void; - - /** - * Apply the stored colours to the block's path, taking into account whether - * the paths belong to a shadow block. - * @param {!Blockly.Block} block The source block. - * @package - */ - applyColour(block: Blockly.Block): void; - - /** - * Update the style. - * @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use. - * @package - */ - setStyle(blockStyle: Blockly.Theme.BlockStyle): void; - - /** - * Flip the SVG paths in RTL. - * @package - */ - flipRTL: any /*missing*/; - - /** - * Add the cursor SVG to this block's SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * block SVG group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this block's SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * block SVG group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Set whether the block shows a highlight or not. Block highlighting is - * often used to visually mark blocks currently being executed. - * @param {boolean} highlighted True if highlighted. - * @package - */ - updateHighlighted(highlighted: boolean): void; - - /** - * Add or remove styling showing that a block is selected. - * @param {boolean} enable True if selection is enabled, false otherwise. - * @package - */ - updateSelected(enable: boolean): void; - - /** - * Add or remove styling showing that a block is dragged over a delete area. - * @param {boolean} enable True if the block is being dragged over a delete - * area, false otherwise. - * @package - */ - updateDraggingDelete(enable: boolean): void; - - /** - * Add or remove styling showing that a block is an insertion marker. - * @param {boolean} enable True if the block is an insertion marker, false - * otherwise. - * @package - */ - updateInsertionMarker(enable: boolean): void; - - /** - * Add or remove styling showing that a block is movable. - * @param {boolean} enable True if the block is movable, false otherwise. - * @package - */ - updateMovable(enable: boolean): void; - - /** - * Add or remove styling that shows that if the dragging block is dropped, this - * block will be replaced. If a shadow block, it will disappear. Otherwise it - * will bump. - * @param {boolean} enable True if styling should be added. - * @package - */ - updateReplacementFade(enable: boolean): void; - } -} -declare module Blockly.blockRendering { - - class RenderInfo extends RenderInfo__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class RenderInfo__Class { - - /** - * An object containing all sizing information needed to draw this block. - * - * This measure pass does not propagate changes to the block (although fields - * may choose to rerender when getSize() is called). However, calling it - * repeatedly may be expensive. - * - * @param {!Blockly.blockRendering.Renderer} renderer The renderer in use. - * @param {!Blockly.BlockSvg} block The block to measure. - * @constructor - * @package - */ - constructor(renderer: Blockly.blockRendering.Renderer, block: Blockly.BlockSvg); - - /** - * The block renderer in use. - * @type {!Blockly.blockRendering.Renderer} - * @protected - */ - renderer_: Blockly.blockRendering.Renderer; - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - - /** - * A measurable representing the output connection if the block has one. - * Otherwise null. - * @type {Blockly.blockRendering.OutputConnection} - */ - outputConnection: Blockly.blockRendering.OutputConnection; - - /** - * Whether the block should be rendered as a single line, either because it's - * inline or because it has been collapsed. - * @type {boolean} - */ - isInline: boolean; - - /** - * Whether the block is collapsed. - * @type {boolean} - */ - isCollapsed: boolean; - - /** - * Whether the block is an insertion marker. Insertion markers are the same - * shape as normal blocks, but don't show fields. - * @type {boolean} - */ - isInsertionMarker: boolean; - - /** - * True if the block should be rendered right-to-left. - * @type {boolean} - */ - RTL: boolean; - - /** - * The height of the rendered block, including child blocks. - * @type {number} - */ - height: number; - - /** - * The width of the rendered block, including child blocks. - * @type {number} - */ - widthWithChildren: number; - - /** - * The width of the rendered block, excluding child blocks. This is the right - * edge of the block when rendered LTR. - * @type {number} - */ - width: number; - - /** - * - * @type {number} - */ - statementEdge: number; - - /** - * An array of Row objects containing sizing information. - * @type {!Array} - */ - rows: Blockly.blockRendering.Row[]; - - /** - * An array of input rows on the block. - * @type {!Array} - */ - inputRows: Blockly.blockRendering.InputRow[]; - - /** - * An array of measurable objects containing hidden icons. - * @type {!Array} - */ - hiddenIcons: Blockly.blockRendering.Icon[]; - - /** - * An object with rendering information about the top row of the block. - * @type {!Blockly.blockRendering.TopRow} - */ - topRow: Blockly.blockRendering.TopRow; - - /** - * An object with rendering information about the bottom row of the block. - * @type {!Blockly.blockRendering.BottomRow} - */ - bottomRow: Blockly.blockRendering.BottomRow; - - /** - * Get the block renderer in use. - * @return {!Blockly.blockRendering.Renderer} The block renderer in use. - * @package - */ - getRenderer(): Blockly.blockRendering.Renderer; - - /** - * Populate and return an object containing all sizing information needed to - * draw this block. - * - * This measure pass does not propagate changes to the block (although fields - * may choose to rerender when getSize() is called). However, calling it - * repeatedly may be expensive. - * - * @package - */ - measure(): void; - - /** - * Create rows of Measurable objects representing all renderable parts of the - * block. - * @protected - */ - createRows_(): void; - - /** - * Create all non-spacer elements that belong on the top row. - * @package - */ - populateTopRow_(): void; - - /** - * Create all non-spacer elements that belong on the bottom row. - * @package - */ - populateBottomRow_(): void; - - /** - * Add an input element to the active row, if needed, and record the type of the - * input on the row. - * @param {!Blockly.Input} input The input to record information about. - * @param {!Blockly.blockRendering.Row} activeRow The row that is currently being - * populated. - * @protected - */ - addInput_(input: Blockly.Input, activeRow: Blockly.blockRendering.Row): void; - - /** - * Decide whether to start a new row between the two Blockly.Inputs. - * @param {!Blockly.Input} input The first input to consider - * @param {Blockly.Input} lastInput The input that follows. - * @return {boolean} True if the next input should be rendered on a new row. - * @protected - */ - shouldStartNewRow_(input: Blockly.Input, lastInput: Blockly.Input): boolean; - - /** - * Add horizontal spacing between and around elements within each row. - * @protected - */ - addElemSpacing_(): void; - - /** - * Calculate the width of a spacer element in a row based on the previous and - * next elements in that row. For instance, extra padding is added between two - * editable fields. - * @param {Blockly.blockRendering.Measurable} prev The element before the - * spacer. - * @param {Blockly.blockRendering.Measurable} next The element after the spacer. - * @return {number} The size of the spacing between the two elements. - * @protected - */ - getInRowSpacing_(prev: Blockly.blockRendering.Measurable, next: Blockly.blockRendering.Measurable): number; - - /** - * Figure out where the right edge of the block and right edge of statement inputs - * should be placed. - * @protected - */ - computeBounds_(): void; - - /** - * Extra spacing may be necessary to make sure that the right sides of all - * rows line up. This can only be calculated after a first pass to calculate - * the sizes of all rows. - * @protected - */ - alignRowElements_(): void; - - /** - * Calculate the desired width of an input row. - * @param {!Blockly.blockRendering.Row} _row The input row. - * @return {number} The desired width of the input row. - * @protected - */ - getDesiredRowWidth_(_row: Blockly.blockRendering.Row): number; - - /** - * Modify the given row to add the given amount of padding around its fields. - * The exact location of the padding is based on the alignment property of the - * last input in the field. - * @param {Blockly.blockRendering.Row} row The row to add padding to. - * @param {number} missingSpace How much padding to add. - * @protected - */ - addAlignmentPadding_(row: Blockly.blockRendering.Row, missingSpace: number): void; - - /** - * Align the elements of a statement row based on computed bounds. - * Unlike other types of rows, statement rows add space in multiple places. - * @param {!Blockly.blockRendering.InputRow} row The statement row to resize. - * @protected - */ - alignStatementRow_(row: Blockly.blockRendering.InputRow): void; - - /** - * Add spacers between rows and set their sizes. - * @protected - */ - addRowSpacing_(): void; - - /** - * Create a spacer row to go between prev and next, and set its size. - * @param {!Blockly.blockRendering.Row} prev The previous row. - * @param {!Blockly.blockRendering.Row} next The next row. - * @return {!Blockly.blockRendering.SpacerRow} The newly created spacer row. - * @protected - */ - makeSpacerRow_(prev: Blockly.blockRendering.Row, next: Blockly.blockRendering.Row): Blockly.blockRendering.SpacerRow; - - /** - * Calculate the width of a spacer row. - * @param {!Blockly.blockRendering.Row} _prev The row before the spacer. - * @param {!Blockly.blockRendering.Row} _next The row after the spacer. - * @return {number} The desired width of the spacer row between these two rows. - * @protected - */ - getSpacerRowWidth_(_prev: Blockly.blockRendering.Row, _next: Blockly.blockRendering.Row): number; - - /** - * Calculate the height of a spacer row. - * @param {!Blockly.blockRendering.Row} _prev The row before the spacer. - * @param {!Blockly.blockRendering.Row} _next The row after the spacer. - * @return {number} The desired height of the spacer row between these two rows. - * @protected - */ - getSpacerRowHeight_(_prev: Blockly.blockRendering.Row, _next: Blockly.blockRendering.Row): number; - - /** - * Calculate the centerline of an element in a rendered row. - * This base implementation puts the centerline at the middle of the row - * vertically, with no special cases. You will likely need extra logic to - * handle (at minimum) top and bottom rows. - * @param {!Blockly.blockRendering.Row} row The row containing the element. - * @param {!Blockly.blockRendering.Measurable} elem The element to place. - * @return {number} The desired centerline of the given element, as an offset - * from the top left of the block. - * @protected - */ - getElemCenterline_(row: Blockly.blockRendering.Row, elem: Blockly.blockRendering.Measurable): number; - - /** - * Record final position information on elements on the given row, for use in - * drawing. At minimum this records xPos and centerline on each element. - * @param {!Blockly.blockRendering.Row} row The row containing the elements. - * @protected - */ - recordElemPositions_(row: Blockly.blockRendering.Row): void; - - /** - * Make any final changes to the rendering information object. In particular, - * store the y position of each row, and record the height of the full block. - * @protected - */ - finalize_(): void; - } - -} -declare module Blockly.blockRendering { - - class MarkerSvg extends MarkerSvg__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class MarkerSvg__Class { - - /** - * Class for a marker. - * @param {!Blockly.WorkspaceSvg} workspace The workspace the marker belongs to. - * @param {!Blockly.blockRendering.ConstantProvider} constants The constants for - * the renderer. - * @param {!Blockly.Marker} marker The marker to draw. - * @constructor - */ - constructor(workspace: Blockly.WorkspaceSvg, constants: Blockly.blockRendering.ConstantProvider, marker: Blockly.Marker); - - /** - * The constants necessary to draw the marker. - * @type {Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - - /** - * The current SVG element for the marker. - * @type {Element} - */ - currentMarkerSvg: Element; - - /** - * The colour of the marker. - * @type {string} - */ - colour_: string; - - /** - * Return the root node of the SVG or null if none exists. - * @return {SVGElement} The root SVG node. - */ - getSvgRoot(): SVGElement; - - /** - * Get the marker. - * @return {!Blockly.Marker} The marker to draw for. - */ - getMarker(): Blockly.Marker; - - /** - * True if the marker should be drawn as a cursor, false otherwise. - * A cursor is drawn as a flashing line. A marker is drawn as a solid line. - * @return {boolean} True if the marker is a cursor, false otherwise. - */ - isCursor(): boolean; - - /** - * Create the DOM element for the marker. - * @return {!SVGElement} The marker controls SVG group. - * @package - */ - createDom(): SVGElement; - - /** - * Attaches the SVG root of the marker to the SVG group of the parent. - * @param {!Blockly.IASTNodeLocationSvg} newParent The workspace, field, or - * block that the marker SVG element should be attached to. - * @protected - */ - setParent_(newParent: Blockly.IASTNodeLocationSvg): void; - - /** - * Update the marker. - * @param {Blockly.ASTNode} oldNode The previous node the marker was on or null. - * @param {Blockly.ASTNode} curNode The node that we want to draw the marker for. - */ - draw(oldNode: Blockly.ASTNode, curNode: Blockly.ASTNode): void; - - /** - * Update the marker's visible state based on the type of curNode.. - * @param {!Blockly.ASTNode} curNode The node that we want to draw the marker for. - * @protected - */ - showAtLocation_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a block. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithBlock_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a previous connection. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithPrevious_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for an output connection. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithOutput_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a workspace coordinate. - * This is a horizontal line. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithCoordinates_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a field. - * This is a box around the field. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithField_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for an input. - * This is a puzzle piece. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithInput_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a next connection. - * This is a horizontal line. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithNext_(curNode: Blockly.ASTNode): void; - - /** - * Position and display the marker for a stack. - * This is a box with extra padding around the entire stack of blocks. - * @param {!Blockly.ASTNode} curNode The node to draw the marker for. - * @protected - */ - showWithStack_(curNode: Blockly.ASTNode): void; - - /** - * Show the current marker. - * @protected - */ - showCurrent_(): void; - - /** - * Position the marker for a block. - * Displays an outline of the top half of a rectangle around a block. - * @param {number} width The width of the block. - * @param {number} markerOffset The extra padding for around the block. - * @param {number} markerHeight The height of the marker. - * @protected - */ - positionBlock_(width: number, markerOffset: number, markerHeight: number): void; - - /** - * Position the marker for an input connection. - * Displays a filled in puzzle piece. - * @param {!Blockly.RenderedConnection} connection The connection to position - * marker around. - * @protected - */ - positionInput_(connection: Blockly.RenderedConnection): void; - - /** - * Move and show the marker at the specified coordinate in workspace units. - * Displays a horizontal line. - * @param {number} x The new x, in workspace units. - * @param {number} y The new y, in workspace units. - * @param {number} width The new width, in workspace units. - * @protected - */ - positionLine_(x: number, y: number, width: number): void; - - /** - * Position the marker for an output connection. - * Displays a puzzle outline and the top and bottom path. - * @param {number} width The width of the block. - * @param {number} height The height of the block. - * @param {!Object} connectionShape The shape object for the connection. - * @protected - */ - positionOutput_(width: number, height: number, connectionShape: Object): void; - - /** - * Position the marker for a previous connection. - * Displays a half rectangle with a notch in the top to represent the previous - * connection. - * @param {number} width The width of the block. - * @param {number} markerOffset The offset of the marker from around the block. - * @param {number} markerHeight The height of the marker. - * @param {!Object} connectionShape The shape object for the connection. - * @protected - */ - positionPrevious_(width: number, markerOffset: number, markerHeight: number, connectionShape: Object): void; - - /** - * Move and show the marker at the specified coordinate in workspace units. - * Displays a filled in rectangle. - * @param {number} x The new x, in workspace units. - * @param {number} y The new y, in workspace units. - * @param {number} width The new width, in workspace units. - * @param {number} height The new height, in workspace units. - * @protected - */ - positionRect_(x: number, y: number, width: number, height: number): void; - - /** - * Hide the marker. - */ - hide(): void; - - /** - * Get the properties to make a marker blink. - * @return {!Object} The object holding attributes to make the marker blink. - * @protected - */ - getBlinkProperties_(): Object; - - /** - * Create the marker SVG. - * @return {Element} The SVG node created. - * @protected - */ - createDomInternal_(): Element; - - /** - * Apply the marker's colour. - * @param {!Blockly.ASTNode} _curNode The node that we want to draw the marker - * for. - * @protected - */ - applyColour_(_curNode: Blockly.ASTNode): void; - - /** - * Dispose of this marker. - */ - dispose(): void; - } - -} - -declare module Blockly.blockRendering.MarkerSvg { - - /** - * The name of the CSS class for a cursor. - * @const {string} - */ - var CURSOR_CLASS: any /*missing*/; - - /** - * The name of the CSS class for a marker. - * @const {string} - */ - var MARKER_CLASS: any /*missing*/; - - /** - * What we multiply the height by to get the height of the marker. - * Only used for the block and block connections. - * @const {number} - */ - var HEIGHT_MULTIPLIER: any /*missing*/; -} -declare module Blockly.blockRendering { - - class PathObject extends PathObject__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class PathObject__Class implements Blockly.blockRendering.IPathObject { - - /** - * An object that handles creating and setting each of the SVG elements - * used by the renderer. - * @param {!SVGElement} root The root SVG element. - * @param {!Blockly.Theme.BlockStyle} style The style object to use for - * colouring. - * @param {!Blockly.blockRendering.ConstantProvider} constants The renderer's - * constants. - * @constructor - * @implements {Blockly.blockRendering.IPathObject} - * @package - */ - constructor(root: SVGElement, style: Blockly.Theme.BlockStyle, constants: Blockly.blockRendering.ConstantProvider); - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - * @package - */ - constants: Blockly.blockRendering.ConstantProvider; - - /** - * The primary path of the block. - * @type {!SVGElement} - * @package - */ - svgPath: SVGElement; - - /** - * The style object to use when colouring block paths. - * @type {!Blockly.Theme.BlockStyle} - * @package - */ - style: Blockly.Theme.BlockStyle; - - /** - * Holds the cursors svg element when the cursor is attached to the block. - * This is null if there is no cursor on the block. - * @type {SVGElement} - * @package - */ - cursorSvg: SVGElement; - - /** - * Holds the markers svg element when the marker is attached to the block. - * This is null if there is no marker on the block. - * @type {SVGElement} - * @package - */ - markerSvg: SVGElement; - - /** - * Set the path generated by the renderer onto the respective SVG element. - * @param {string} pathString The path. - * @package - */ - setPath(pathString: string): void; - - /** - * Flip the SVG paths in RTL. - * @package - */ - flipRTL(): void; - - /** - * Add the cursor SVG to this block's SVG group. - * @param {SVGElement} cursorSvg The SVG root of the cursor to be added to the - * block SVG group. - * @package - */ - setCursorSvg(cursorSvg: SVGElement): void; - - /** - * Add the marker SVG to this block's SVG group. - * @param {SVGElement} markerSvg The SVG root of the marker to be added to the - * block SVG group. - * @package - */ - setMarkerSvg(markerSvg: SVGElement): void; - - /** - * Apply the stored colours to the block's path, taking into account whether - * the paths belong to a shadow block. - * @param {!Blockly.Block} block The source block. - * @package - */ - applyColour(block: Blockly.Block): void; - - /** - * Set the style. - * @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use. - * @package - */ - setStyle(blockStyle: Blockly.Theme.BlockStyle): void; - - /** - * Add or remove the given CSS class on the path object's root SVG element. - * @param {string} className The name of the class to add or remove - * @param {boolean} add True if the class should be added. False if it should - * be removed. - * @protected - */ - setClass_(className: string, add: boolean): void; - - /** - * Set whether the block shows a highlight or not. Block highlighting is - * often used to visually mark blocks currently being executed. - * @param {boolean} enable True if highlighted. - * @package - */ - updateHighlighted(enable: boolean): void; - - /** - * Updates the look of the block to reflect a shadow state. - * @param {boolean} shadow True if the block is a shadow block. - * @protected - */ - updateShadow_(shadow: boolean): void; - - /** - * Updates the look of the block to reflect a disabled state. - * @param {boolean} disabled True if disabled. - * @protected - */ - updateDisabled_(disabled: boolean): void; - - /** - * Add or remove styling showing that a block is selected. - * @param {boolean} enable True if selection is enabled, false otherwise. - * @package - */ - updateSelected(enable: boolean): void; - - /** - * Add or remove styling showing that a block is dragged over a delete area. - * @param {boolean} enable True if the block is being dragged over a delete - * area, false otherwise. - * @package - */ - updateDraggingDelete(enable: boolean): void; - - /** - * Add or remove styling showing that a block is an insertion marker. - * @param {boolean} enable True if the block is an insertion marker, false - * otherwise. - * @package - */ - updateInsertionMarker(enable: boolean): void; - - /** - * Add or remove styling showing that a block is movable. - * @param {boolean} enable True if the block is movable, false otherwise. - * @package - */ - updateMovable(enable: boolean): void; - - /** - * Add or remove styling that shows that if the dragging block is dropped, this - * block will be replaced. If a shadow block, it will disappear. Otherwise it - * will bump. - * @param {boolean} enable True if styling should be added. - * @package - */ - updateReplacementFade(enable: boolean): void; - - /** - * Add or remove styling that shows that if the dragging block is dropped, this - * block will be connected to the input. - * @param {Blockly.Connection} _conn The connection on the input to highlight. - * @param {boolean} _enable True if styling should be added. - * @package - */ - updateShapeForInputHighlight(_conn: Blockly.Connection, _enable: boolean): void; - } - -} -declare module Blockly.blockRendering { - - class Renderer extends Renderer__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Renderer__Class implements Blockly.IRegistrable { - - /** - * The base class for a block renderer. - * @param {string} name The renderer name. - * @package - * @constructor - * @implements {Blockly.IRegistrable} - */ - constructor(name: string); - - /** - * The renderer name. - * @type {string} - * @package - */ - name: string; - - /** - * Rendering constant overrides, passed in through options. - * @type {?Object} - * @package - */ - overrides: Object; - - /** - * Gets the class name that identifies this renderer. - * @return {string} The CSS class name. - * @package - */ - getClassName(): string; - - /** - * Initialize the renderer. - * @param {!Blockly.Theme} theme The workspace theme object. - * @param {Object=} opt_rendererOverrides Rendering constant overrides. - * @package - */ - init(theme: Blockly.Theme, opt_rendererOverrides?: Object): void; - - /** - * Create any DOM elements that this renderer needs. - * @param {!SVGElement} svg The root of the workspace's SVG. - * @param {!Blockly.Theme} theme The workspace theme object. - * @package - */ - createDom(svg: SVGElement, theme: Blockly.Theme): void; - - /** - * Refresh the renderer after a theme change. - * @param {!SVGElement} svg The root of the workspace's SVG. - * @param {!Blockly.Theme} theme The workspace theme object. - * @package - */ - refreshDom(svg: SVGElement, theme: Blockly.Theme): void; - - /** - * Dispose of this renderer. - * Delete all DOM elements that this renderer and its constants created. - * @package - */ - dispose(): void; - - /** - * Create a new instance of the renderer's constant provider. - * @return {!Blockly.blockRendering.ConstantProvider} The constant provider. - * @protected - */ - makeConstants_(): Blockly.blockRendering.ConstantProvider; - - /** - * Create a new instance of the renderer's render info object. - * @param {!Blockly.BlockSvg} block The block to measure. - * @return {!Blockly.blockRendering.RenderInfo} The render info object. - * @protected - */ - makeRenderInfo_(block: Blockly.BlockSvg): Blockly.blockRendering.RenderInfo; - - /** - * Create a new instance of the renderer's drawer. - * @param {!Blockly.BlockSvg} block The block to render. - * @param {!Blockly.blockRendering.RenderInfo} info An object containing all - * information needed to render this block. - * @return {!Blockly.blockRendering.Drawer} The drawer. - * @protected - */ - makeDrawer_(block: Blockly.BlockSvg, info: Blockly.blockRendering.RenderInfo): Blockly.blockRendering.Drawer; - - /** - * Create a new instance of the renderer's debugger. - * @return {!Blockly.blockRendering.Debug} The renderer debugger. - * @suppress {strictModuleDepCheck} Debug renderer only included in playground. - * @protected - */ - makeDebugger_(): Blockly.blockRendering.Debug; - - /** - * Create a new instance of the renderer's marker drawer. - * @param {!Blockly.WorkspaceSvg} workspace The workspace the marker belongs to. - * @param {!Blockly.Marker} marker The marker. - * @return {!Blockly.blockRendering.MarkerSvg} The object in charge of drawing - * the marker. - * @package - */ - makeMarkerDrawer(workspace: Blockly.WorkspaceSvg, marker: Blockly.Marker): Blockly.blockRendering.MarkerSvg; - - /** - * Create a new instance of a renderer path object. - * @param {!SVGElement} root The root SVG element. - * @param {!Blockly.Theme.BlockStyle} style The style object to use for - * colouring. - * @return {!Blockly.blockRendering.IPathObject} The renderer path object. - * @package - */ - makePathObject(root: SVGElement, style: Blockly.Theme.BlockStyle): Blockly.blockRendering.IPathObject; - - /** - * Get the current renderer's constant provider. We assume that when this is - * called, the renderer has already been initialized. - * @return {!Blockly.blockRendering.ConstantProvider} The constant provider. - * @package - */ - getConstants(): Blockly.blockRendering.ConstantProvider; - - /** - * Determine whether or not to highlight a connection. - * @param {Blockly.Connection} _conn The connection to determine whether or not - * to highlight. - * @return {boolean} True if we should highlight the connection. - * @package - */ - shouldHighlightConnection(_conn: Blockly.Connection): boolean; - - /** - * Checks if an orphaned block can connect to the "end" of the topBlock's - * block-clump. If the clump is a row the end is the last input. If the clump - * is a stack, the end is the last next connection. If the clump is neither, - * then this returns false. - * @param {!Blockly.BlockSvg} topBlock The top block of the block clump we want to try and - * connect to. - * @param {!Blockly.BlockSvg} orphanBlock The orphan block that wants to find - * a home. - * @param {number} localType The type of the connection being dragged. - * @return {boolean} Whether there is a home for the orphan or not. - * @package - */ - orphanCanConnectAtEnd(topBlock: Blockly.BlockSvg, orphanBlock: Blockly.BlockSvg, localType: number): boolean; - - /** - * Chooses a connection preview method based on the available connection, the - * current dragged connection, and the block being dragged. - * @param {!Blockly.RenderedConnection} closest The available connection. - * @param {!Blockly.RenderedConnection} local The connection currently being - * dragged. - * @param {!Blockly.BlockSvg} topBlock The block currently being dragged. - * @return {!Blockly.InsertionMarkerManager.PREVIEW_TYPE} The preview type - * to display. - * @package - */ - getConnectionPreviewMethod(closest: Blockly.RenderedConnection, local: Blockly.RenderedConnection, topBlock: Blockly.BlockSvg): Blockly.InsertionMarkerManager.PREVIEW_TYPE; - - /** - * Render the block. - * @param {!Blockly.BlockSvg} block The block to render. - * @package - */ - render(block: Blockly.BlockSvg): void; - } - -} -declare module Blockly.blockRendering { - - class Measurable extends Measurable__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Measurable__Class { - - /** - * The base class to represent a part of a block that takes up space during - * rendering. The constructor for each non-spacer Measurable records the size - * of the block element (e.g. field, statement input). - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - } - -} -declare module Blockly.blockRendering { - - class Connection extends Connection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Connection__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * The base class to represent a connection and the space that it takes up on - * the block. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.RenderedConnection} connectionModel The connection object on - * the block that this represents. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, connectionModel: Blockly.RenderedConnection); - } - - - class OutputConnection extends OutputConnection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class OutputConnection__Class extends Blockly.blockRendering.Connection__Class { - - /** - * An object containing information about the space an output connection takes - * up during rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {Blockly.RenderedConnection} connectionModel The connection object on - * the block that this represents. - * @package - * @constructor - * @extends {Blockly.blockRendering.Connection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, connectionModel: Blockly.RenderedConnection); - } - - - class PreviousConnection extends PreviousConnection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class PreviousConnection__Class extends Blockly.blockRendering.Connection__Class { - - /** - * An object containing information about the space a previous connection takes - * up during rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {Blockly.RenderedConnection} connectionModel The connection object on - * the block that this represents. - * @package - * @constructor - * @extends {Blockly.blockRendering.Connection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, connectionModel: Blockly.RenderedConnection); - } - - - class NextConnection extends NextConnection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class NextConnection__Class extends Blockly.blockRendering.Connection__Class { - - /** - * An object containing information about the space a next connection takes - * up during rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {Blockly.RenderedConnection} connectionModel The connection object on - * the block that this represents. - * @package - * @constructor - * @extends {Blockly.blockRendering.Connection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, connectionModel: Blockly.RenderedConnection); - } - -} -declare module Blockly.blockRendering { - - class InputConnection extends InputConnection__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class InputConnection__Class extends Blockly.blockRendering.Connection__Class { - - /** - * The base class to represent an input that takes up space on a block - * during rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Input} input The input to measure and store information for. - * @package - * @constructor - * @extends {Blockly.blockRendering.Connection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, input: Blockly.Input); - } - - - class InlineInput extends InlineInput__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class InlineInput__Class extends Blockly.blockRendering.InputConnection__Class { - - /** - * An object containing information about the space an inline input takes up - * during rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Input} input The inline input to measure and store - * information for. - * @package - * @constructor - * @extends {Blockly.blockRendering.InputConnection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, input: Blockly.Input); - } - - - class StatementInput extends StatementInput__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class StatementInput__Class extends Blockly.blockRendering.InputConnection__Class { - - /** - * An object containing information about the space a statement input takes up - * during rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Input} input The statement input to measure and store - * information for. - * @package - * @constructor - * @extends {Blockly.blockRendering.InputConnection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, input: Blockly.Input); - } - - - class ExternalValueInput extends ExternalValueInput__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class ExternalValueInput__Class extends Blockly.blockRendering.InputConnection__Class { - - /** - * An object containing information about the space an external value input - * takes up during rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Input} input The external value input to measure and store - * information for. - * @package - * @constructor - * @extends {Blockly.blockRendering.InputConnection} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, input: Blockly.Input); - } - -} -declare module Blockly.blockRendering { - - class Icon extends Icon__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Icon__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the space an icon takes up during - * rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Icon} icon The icon to measure and store information for. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, icon: Blockly.Icon); - } - - - class JaggedEdge extends JaggedEdge__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class JaggedEdge__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the jagged edge of a collapsed block - * takes up during rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - } - - - class Field extends Field__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Field__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the space a field takes up during - * rendering - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {!Blockly.Field} field The field to measure and store information for. - * @param {!Blockly.Input} parentInput The parent input for the field. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, field: Blockly.Field, parentInput: Blockly.Input); - } - - - class Hat extends Hat__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Hat__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the space a hat takes up during - * rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - } - - - class SquareCorner extends SquareCorner__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class SquareCorner__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the space a square corner takes up - * during rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {string=} opt_position The position of this corner. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, opt_position?: string); - } - - - class RoundCorner extends RoundCorner__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class RoundCorner__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about the space a rounded corner takes up - * during rendering. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {string=} opt_position The position of this corner. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, opt_position?: string); - } - - - class InRowSpacer extends InRowSpacer__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class InRowSpacer__Class extends Blockly.blockRendering.Measurable__Class { - - /** - * An object containing information about a spacer between two elements on a - * row. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {number} width The width of the spacer. - * @package - * @constructor - * @extends {Blockly.blockRendering.Measurable} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, width: number); - } - -} -declare module Blockly.blockRendering { - - class Row extends Row__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class Row__Class { - - /** - * An object representing a single row on a rendered block and all of its - * subcomponents. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * The type of this rendering object. - * @package - * @type {number} - */ - type: number; - - /** - * An array of elements contained in this row. - * @package - * @type {!Array} - */ - elements: Blockly.blockRendering.Measurable[]; - - /** - * The height of the row. - * @package - * @type {number} - */ - height: number; - - /** - * The width of the row, from the left edge of the block to the right. - * Does not include child blocks unless they are inline. - * @package - * @type {number} - */ - width: number; - - /** - * The minimum height of the row. - * @package - * @type {number} - */ - minHeight: number; - - /** - * The minimum width of the row, from the left edge of the block to the right. - * Does not include child blocks unless they are inline. - * @package - * @type {number} - */ - minWidth: number; - - /** - * The width of the row, from the left edge of the block to the edge of the - * block or any connected child blocks. - * @package - * @type {number} - */ - widthWithConnectedBlocks: number; - - /** - * The Y position of the row relative to the origin of the block's svg group. - * @package - * @type {number} - */ - yPos: number; - - /** - * The X position of the row relative to the origin of the block's svg group. - * @package - * @type {number} - */ - xPos: number; - - /** - * Whether the row has any external inputs. - * @package - * @type {boolean} - */ - hasExternalInput: boolean; - - /** - * Whether the row has any statement inputs. - * @package - * @type {boolean} - */ - hasStatement: boolean; - - /** - * Whether the row has any inline inputs. - * @package - * @type {boolean} - */ - hasInlineInput: boolean; - - /** - * Whether the row has any dummy inputs. - * @package - * @type {boolean} - */ - hasDummyInput: boolean; - - /** - * Whether the row has a jagged edge. - * @package - * @type {boolean} - */ - hasJaggedEdge: boolean; - - /** - * The renderer's constant provider. - * @type {!Blockly.blockRendering.ConstantProvider} - * @protected - */ - constants_: Blockly.blockRendering.ConstantProvider; - - /** - * Alignment of the row. - * @package - * @type {?number} - */ - align: number; - - /** - * Inspect all subcomponents and populate all size properties on the row. - * @package - */ - measure(): void; - - /** - * Get the last input on this row, if it has one. - * @return {Blockly.blockRendering.InputConnection} The last input on the row, - * or null. - * @package - */ - getLastInput(): Blockly.blockRendering.InputConnection; - - /** - * Determines whether this row should start with an element spacer. - * @return {boolean} Whether the row should start with a spacer. - * @package - */ - startsWithElemSpacer(): boolean; - - /** - * Determines whether this row should end with an element spacer. - * @return {boolean} Whether the row should end with a spacer. - * @package - */ - endsWithElemSpacer(): boolean; - - /** - * Convenience method to get the first spacer element on this row. - * @return {Blockly.blockRendering.InRowSpacer} The first spacer element on - * this row. - * @package - */ - getFirstSpacer(): Blockly.blockRendering.InRowSpacer; - - /** - * Convenience method to get the last spacer element on this row. - * @return {Blockly.blockRendering.InRowSpacer} The last spacer element on - * this row. - * @package - */ - getLastSpacer(): Blockly.blockRendering.InRowSpacer; - } - - - class TopRow extends TopRow__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class TopRow__Class extends Blockly.blockRendering.Row__Class { - - /** - * An object containing information about what elements are in the top row of a - * block as well as sizing information for the top row. - * Elements in a top row can consist of corners, hats, spacers, and previous - * connections. - * After this constructor is called, the row will contain all non-spacer - * elements it needs. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - * @extends {Blockly.blockRendering.Row} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * The starting point for drawing the row, in the y direction. - * This allows us to draw hats and similar shapes that don't start at the - * origin. Must be non-negative (see #2820). - * @package - * @type {number} - */ - capline: number; - - /** - * How much the row extends up above its capline. - * @type {number} - */ - ascenderHeight: number; - - /** - * Whether the block has a previous connection. - * @package - * @type {boolean} - */ - hasPreviousConnection: boolean; - - /** - * The previous connection on the block, if any. - * @type {Blockly.blockRendering.PreviousConnection} - */ - connection: Blockly.blockRendering.PreviousConnection; - - /** - * Returns whether or not the top row has a left square corner. - * @param {!Blockly.BlockSvg} block The block whose top row this represents. - * @return {boolean} Whether or not the top row has a left square corner. - */ - hasLeftSquareCorner(block: Blockly.BlockSvg): boolean; - - /** - * Returns whether or not the top row has a right square corner. - * @param {!Blockly.BlockSvg} _block The block whose top row this represents. - * @return {boolean} Whether or not the top row has a right square corner. - */ - hasRightSquareCorner(_block: Blockly.BlockSvg): boolean; - } - - - class BottomRow extends BottomRow__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class BottomRow__Class extends Blockly.blockRendering.Row__Class { - - /** - * An object containing information about what elements are in the bottom row of - * a block as well as spacing information for the top row. - * Elements in a bottom row can consist of corners, spacers and next - * connections. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - * @extends {Blockly.blockRendering.Row} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * Whether this row has a next connection. - * @package - * @type {boolean} - */ - hasNextConnection: boolean; - - /** - * The next connection on the row, if any. - * @package - * @type {Blockly.blockRendering.NextConnection} - */ - connection: Blockly.blockRendering.NextConnection; - - /** - * The amount that the bottom of the block extends below the horizontal edge, - * e.g. because of a next connection. Must be non-negative (see #2820). - * @package - * @type {number} - */ - descenderHeight: number; - - /** - * The Y position of the bottom edge of the block, relative to the origin - * of the block rendering. - * @type {number} - */ - baseline: number; - - /** - * Returns whether or not the bottom row has a left square corner. - * @param {!Blockly.BlockSvg} block The block whose bottom row this represents. - * @return {boolean} Whether or not the bottom row has a left square corner. - */ - hasLeftSquareCorner(block: Blockly.BlockSvg): boolean; - - /** - * Returns whether or not the bottom row has a right square corner. - * @param {!Blockly.BlockSvg} _block The block whose bottom row this represents. - * @return {boolean} Whether or not the bottom row has a right square corner. - */ - hasRightSquareCorner(_block: Blockly.BlockSvg): boolean; - } - - - class SpacerRow extends SpacerRow__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class SpacerRow__Class extends Blockly.blockRendering.Row__Class { - - /** - * An object containing information about a spacer between two rows. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @param {number} height The height of the spacer. - * @param {number} width The width of the spacer. - * @package - * @constructor - * @extends {Blockly.blockRendering.Row} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider, height: number, width: number); - } - - - class InputRow extends InputRow__Class { } - /** Fake class which should be extended to avoid inheriting static properties */ - class InputRow__Class extends Blockly.blockRendering.Row__Class { - - /** - * An object containing information about a row that holds one or more inputs. - * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering - * constants provider. - * @package - * @constructor - * @extends {Blockly.blockRendering.Row} - */ - constructor(constants: Blockly.blockRendering.ConstantProvider); - - /** - * The total width of all blocks connected to this row. - * @type {number} - * @package - */ - connectedBlockWidths: number; - - /** - * Inspect all subcomponents and populate all size properties on the row. - * @package - */ - measure(): void; - } - -} -declare module Blockly.blockRendering { - /** - * Types of rendering elements. - * @enum {number} - */ - enum Types { NONE, FIELD, HAT, ICON, SPACER, BETWEEN_ROW_SPACER, IN_ROW_SPACER, EXTERNAL_VALUE_INPUT, INPUT, INLINE_INPUT, STATEMENT_INPUT, CONNECTION, PREVIOUS_CONNECTION, NEXT_CONNECTION, OUTPUT_CONNECTION, CORNER, LEFT_SQUARE_CORNER, LEFT_ROUND_CORNER, RIGHT_SQUARE_CORNER, RIGHT_ROUND_CORNER, JAGGED_EDGE, ROW, TOP_ROW, BOTTOM_ROW, INPUT_ROW } -} -declare module Blockly.blockRendering.Types { + + + +declare module Types { /** * A Left Corner Union Type. @@ -21694,210 +2432,210 @@ declare module Blockly.blockRendering.Types { /** * Whether a measurable stores information about a field. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a field. * @package */ - function isField(elem: Blockly.blockRendering.Measurable): number; + function isField(elem: Measurable): number; /** * Whether a measurable stores information about a hat. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a hat. * @package */ - function isHat(elem: Blockly.blockRendering.Measurable): number; + function isHat(elem: Measurable): number; /** * Whether a measurable stores information about an icon. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about an icon. * @package */ - function isIcon(elem: Blockly.blockRendering.Measurable): number; + function isIcon(elem: Measurable): number; /** * Whether a measurable stores information about a spacer. - * @param {!Blockly.blockRendering.Measurable|!Blockly.blockRendering.Row} elem + * @param {!Measurable|!Row} elem * The element to check. * @return {number} 1 if the object stores information about a spacer. * @package */ - function isSpacer(elem: Blockly.blockRendering.Measurable|Blockly.blockRendering.Row): number; + function isSpacer(elem: Measurable|Row): number; /** * Whether a measurable stores information about an in-row spacer. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about an * in-row spacer. * @package */ - function isInRowSpacer(elem: Blockly.blockRendering.Measurable): number; + function isInRowSpacer(elem: Measurable): number; /** * Whether a measurable stores information about an input. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about an input. * @package */ - function isInput(elem: Blockly.blockRendering.Measurable): number; + function isInput(elem: Measurable): number; /** * Whether a measurable stores information about an external input. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about an * external input. * @package */ - function isExternalInput(elem: Blockly.blockRendering.Measurable): number; + function isExternalInput(elem: Measurable): number; /** * Whether a measurable stores information about an inline input. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about an * inline input. * @package */ - function isInlineInput(elem: Blockly.blockRendering.Measurable): number; + function isInlineInput(elem: Measurable): number; /** * Whether a measurable stores information about a statement input. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * statement input. * @package */ - function isStatementInput(elem: Blockly.blockRendering.Measurable): number; + function isStatementInput(elem: Measurable): number; /** * Whether a measurable stores information about a previous connection. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * previous connection. * @package */ - function isPreviousConnection(elem: Blockly.blockRendering.Measurable): number; + function isPreviousConnection(elem: Measurable): number; /** * Whether a measurable stores information about a next connection. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * next connection. * @package */ - function isNextConnection(elem: Blockly.blockRendering.Measurable): number; + function isNextConnection(elem: Measurable): number; /** * Whether a measurable stores information about a previous or next connection. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a previous or * next connection. * @package */ - function isPreviousOrNextConnection(elem: Blockly.blockRendering.Measurable): number; + function isPreviousOrNextConnection(elem: Measurable): number; /** * Whether a measurable stores information about a left round corner. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * left round corner. * @package */ - function isLeftRoundedCorner(elem: Blockly.blockRendering.Measurable): number; + function isLeftRoundedCorner(elem: Measurable): number; /** * Whether a measurable stores information about a right round corner. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * right round corner. * @package */ - function isRightRoundedCorner(elem: Blockly.blockRendering.Measurable): number; + function isRightRoundedCorner(elem: Measurable): number; /** * Whether a measurable stores information about a left square corner. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * left square corner. * @package */ - function isLeftSquareCorner(elem: Blockly.blockRendering.Measurable): number; + function isLeftSquareCorner(elem: Measurable): number; /** * Whether a measurable stores information about a right square corner. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * right square corner. * @package */ - function isRightSquareCorner(elem: Blockly.blockRendering.Measurable): number; + function isRightSquareCorner(elem: Measurable): number; /** * Whether a measurable stores information about a corner. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a * corner. * @package */ - function isCorner(elem: Blockly.blockRendering.Measurable): number; + function isCorner(elem: Measurable): number; /** * Whether a measurable stores information about a jagged edge. - * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @param {!Measurable} elem The element to check. * @return {number} 1 if the object stores information about a jagged edge. * @package */ - function isJaggedEdge(elem: Blockly.blockRendering.Measurable): number; + function isJaggedEdge(elem: Measurable): number; /** * Whether a measurable stores information about a row. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about a row. * @package */ - function isRow(row: Blockly.blockRendering.Row): number; + function isRow(row: Row): number; /** * Whether a measurable stores information about a between-row spacer. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about a * between-row spacer. * @package */ - function isBetweenRowSpacer(row: Blockly.blockRendering.Row): number; + function isBetweenRowSpacer(row: Row): number; /** * Whether a measurable stores information about a top row. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about a top row. * @package */ - function isTopRow(row: Blockly.blockRendering.Row): number; + function isTopRow(row: Row): number; /** * Whether a measurable stores information about a bottom row. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about a bottom row. * @package */ - function isBottomRow(row: Blockly.blockRendering.Row): number; + function isBottomRow(row: Row): number; /** * Whether a measurable stores information about a top or bottom row. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about a top or * bottom row. * @package */ - function isTopOrBottomRow(row: Blockly.blockRendering.Row): number; + function isTopOrBottomRow(row: Row): number; /** * Whether a measurable stores information about an input row. - * @param {!Blockly.blockRendering.Row} row The row to check. + * @param {!Row} row The row to check. * @return {number} 1 if the object stores information about an input row. * @package */ - function isInputRow(row: Blockly.blockRendering.Row): number; + function isInputRow(row: Row): number; } @@ -22206,45 +2944,6 @@ declare module Blockly.Msg { /** @type {string} */ var CONTROLS_IF_ELSE_TOOLTIP: string; - /** @type {string} */ - var IOS_OK: string; - - /** @type {string} */ - var IOS_CANCEL: string; - - /** @type {string} */ - var IOS_ERROR: string; - - /** @type {string} */ - var IOS_PROCEDURES_INPUTS: string; - - /** @type {string} */ - var IOS_PROCEDURES_ADD_INPUT: string; - - /** @type {string} */ - var IOS_PROCEDURES_ALLOW_STATEMENTS: string; - - /** @type {string} */ - var IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR: string; - - /** @type {string} */ - var IOS_VARIABLES_ADD_VARIABLE: string; - - /** @type {string} */ - var IOS_VARIABLES_ADD_BUTTON: string; - - /** @type {string} */ - var IOS_VARIABLES_RENAME_BUTTON: string; - - /** @type {string} */ - var IOS_VARIABLES_DELETE_BUTTON: string; - - /** @type {string} */ - var IOS_VARIABLES_VARIABLE_NAME: string; - - /** @type {string} */ - var IOS_VARIABLES_EMPTY_NAME_ERROR: string; - /** @type {string} */ var LOGIC_COMPARE_HELPURL: string; @@ -23189,6 +3888,12 @@ declare module Blockly.Msg { /** @type {string} */ var COLLAPSED_WARNINGS_WARNING: string; + + /** @type {string} */ + var DIALOG_OK: string; + + /** @type {string} */ + var DIALOG_CANCEL: string; } @@ -23259,6 +3964,38 @@ declare module Blockly.Msg { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +