UNPKG

@blockly/keyboard-navigation

Version:
2 lines 55 kB
/*! For license information please see index.js.LICENSE.txt */ !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("blockly/core"),require("blockly"));else if("function"==typeof define&&define.amd)define(["blockly/core","blockly"],e);else{var o="object"==typeof exports?e(require("blockly/core"),require("blockly")):e(t.Blockly,t.Blockly);for(var n in o)("object"==typeof exports?exports:t)[n]=o[n]}}(this,((t,e)=>(()=>{"use strict";var o={826:t=>{t.exports=e},370:e=>{e.exports=t}},n={};function i(t){var e=n[t];if(void 0!==e)return e.exports;var r=n[t]={exports:{}};return o[t](r,r.exports,i),r.exports}i.d=(t,e)=>{for(var o in e)i.o(e,o)&&!i.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};i.r(r),i.d(r,{KeyboardNavigation:()=>lt});var s,a,c,l=i(370);l.Toolbox.prototype.onKeyDown_=function(){},function(t){t.NOWHERE="nowhere",t.WORKSPACE="workspace",t.FLYOUT="flyout",t.TOOLBOX="toolbox"}(s||(s={})),function(t){t.UP="up",t.DOWN="down",t.RIGHT="right",t.LEFT="left",t.INSERT="insert",t.EDIT_OR_CONFIRM="edit_or_confirm",t.DISCONNECT="disconnect",t.TOOLBOX="toolbox",t.EXIT="exit",t.MENU="menu",t.COPY="keyboard_nav_copy",t.CUT="keyboard_nav_cut",t.PASTE="keyboard_nav_paste",t.MOVE_WS_CURSOR_UP="workspace_up",t.MOVE_WS_CURSOR_DOWN="workspace_down",t.MOVE_WS_CURSOR_LEFT="workspace_left",t.MOVE_WS_CURSOR_RIGHT="workspace_right",t.CREATE_WS_CURSOR="to_workspace",t.LIST_SHORTCUTS="list_shortcuts",t.CLEAN_UP="clean_up_workspace"}(a||(a={})),function(t){t.ERROR="error",t.WARN="warn",t.LOG="log"}(c||(c={}));const u={};u[l.Msg.SHORTCUTS_GENERAL]=[a.MENU,a.EDIT_OR_CONFIRM,a.EXIT,a.TOOLBOX,a.CLEAN_UP,a.LIST_SHORTCUTS],u[l.Msg.SHORTCUTS_EDITING]=[a.INSERT,"delete",a.DISCONNECT,"cut","copy","paste","undo","redo"],u[l.Msg.SHORTCUTS_CODE_NAVIGATION]=[a.UP,a.DOWN,a.RIGHT,a.LEFT];var d=i(826);const g={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"caps-lock",27:"esc",32:"space",33:"pg-up",34:"pg-down",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"delete",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:"semicolon",61:"equals",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",93:"context",96:"num-0",97:"num-1",98:"num-2",99:"num-3",100:"num-4",101:"num-5",102:"num-6",103:"num-7",104:"num-8",105:"num-9",106:"num-multiply",107:"num-plus",109:"num-minus",110:"num-period",111:"num-division",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",186:"semicolon",187:"equals",189:"dash",188:",",190:".",191:"/",192:"`",219:"open-square-bracket",220:"\\",221:"close-square-bracket",222:"single-quote",224:"win"},h=navigator.platform.startsWith("Mac");function p(t){return y(t,v)[0].join(h?" ":" + ")}const C={Control:d.Msg.CONTROL_KEY,Meta:d.Msg.COMMAND_KEY,Alt:h?d.Msg.OPTION_KEY:d.Msg.ALT_KEY},v={Control:d.Msg.CONTROL_KEY,Meta:"⌘",Alt:h?"⌥":d.Msg.ALT_KEY};function y(t,e){const o=d.ShortcutRegistry.registry.getKeyCodesByShortcutName(t).map((t=>t.split("+").map((t=>{var e;return null!==(e=g[t])&&void 0!==e?e:t})).map((t=>{var o;return f(null!==(o=e[t])&&void 0!==o?o:t)})))),n=e.Meta,i=e.Alt,r=e.Control;o.sort(((t,e)=>{const o=t.includes(n)?1:0;return(e.includes(n)?1:0)-o}));let s=o.filter((t=>(t.includes(n)||t.includes(i))===h));return s=0===s.length?o:s,s.some((t=>t.some((t=>n===t||i===t||r===t))))?[s[0]]:s}function f(t){return t.charAt(0).toUpperCase()+t.substring(1)}const k="unconstrainedMoveHint",m="constrainedMoveHint",b="copiedHint",S="cutHint",T="helpHint";function w(t,e=!1){const o=p(a.EDIT_OR_CONFIRM),n=`Hold ${navigator.platform.startsWith("Mac")?"⌥":"Ctrl"} and use arrow keys to move freely, then ${o} to accept the position`;d.Toast.show(t,{message:n,id:k,oncePerSession:!e})}class R{constructor(t){this.navigation=t,this.copyWorkspace=null}install(){this.registerCopyShortcut(),this.registerCopyContextMenuAction(),this.registerPasteShortcut(),this.registerPasteContextMenuAction(),this.registerCutShortcut(),this.registerCutContextMenuAction()}uninstall(){d.ContextMenuRegistry.registry.unregister("blockCutFromContextMenu"),d.ContextMenuRegistry.registry.unregister("blockCopyFromContextMenu"),d.ContextMenuRegistry.registry.unregister("blockPasteFromContextMenu"),d.ShortcutRegistry.registry.unregister(a.CUT),d.ShortcutRegistry.registry.unregister(a.COPY),d.ShortcutRegistry.registry.unregister(a.PASTE)}registerCutShortcut(){if(this.oldCutShortcut=d.ShortcutRegistry.registry.getRegistry()[d.ShortcutItems.names.CUT],!this.oldCutShortcut)throw new Error("No cut keyboard shortcut registered initially");const t={name:a.CUT,preconditionFn:this.oldCutShortcut.preconditionFn,callback:this.cutCallback.bind(this),keyCodes:this.oldCutShortcut.keyCodes,allowCollision:!1};d.ShortcutRegistry.registry.unregister(d.ShortcutItems.names.CUT),d.ShortcutRegistry.registry.register(t)}registerCutContextMenuAction(){const t={displayText:t=>d.Msg.CUT_SHORTCUT.replace("%1",p(a.CUT)),preconditionFn:t=>this.cutPrecondition(t),callback:(t,e)=>{if(!(0,d.isCopyable)(t.focusedNode))return!1;const o=t.focusedNode.workspace;return o instanceof d.WorkspaceSvg&&this.cutCallback(o,e,void 0,t)},id:"blockCutFromContextMenu",weight:12};d.ContextMenuRegistry.registry.register(t)}cutPrecondition(t){var e;const o=t.focusedNode;if(!o||!(0,d.isCopyable)(o))return"hidden";const n=o.workspace;return n instanceof d.WorkspaceSvg?(null===(e=this.oldCutShortcut)||void 0===e?void 0:e.preconditionFn)&&this.oldCutShortcut.preconditionFn(n,t)?"enabled":"disabled":"hidden"}copyPrecondition(t){var e;const o=t.focusedNode;if(!o||!(0,d.isCopyable)(o))return"hidden";const n=o.workspace;return n instanceof d.WorkspaceSvg?(null===(e=this.oldCopyShortcut)||void 0===e?void 0:e.preconditionFn)&&this.oldCopyShortcut.preconditionFn(n,t)?"enabled":"disabled":"hidden"}pastePrecondition(t){var e;return this.copyWorkspace&&(null===(e=this.oldPasteShortcut)||void 0===e?void 0:e.preconditionFn)&&this.oldPasteShortcut.preconditionFn(this.copyWorkspace,t)?"enabled":"disabled"}cutCallback(t,e,o={name:a.CUT},n){var i;const r=!!(null===(i=this.oldCutShortcut)||void 0===i?void 0:i.callback)&&this.oldCutShortcut.callback(t,e,o,n);return r&&(this.copyWorkspace=t,function(t){d.Toast.show(t,{message:`Cut. Press ${p(a.PASTE)} to paste.`,duration:7,id:S})}(t)),r}registerCopyShortcut(){if(this.oldCopyShortcut=d.ShortcutRegistry.registry.getRegistry()[d.ShortcutItems.names.COPY],!this.oldCopyShortcut)throw new Error("No copy keyboard shortcut registered initially");const t={name:a.COPY,preconditionFn:this.oldCopyShortcut.preconditionFn,callback:this.copyCallback.bind(this),keyCodes:this.oldCopyShortcut.keyCodes,allowCollision:!1};d.ShortcutRegistry.registry.unregister(d.ShortcutItems.names.COPY),d.ShortcutRegistry.registry.register(t)}registerCopyContextMenuAction(){const t={displayText:t=>d.Msg.COPY_SHORTCUT.replace("%1",p(a.COPY)),preconditionFn:t=>this.copyPrecondition(t),callback:(t,e)=>{if(!(0,d.isCopyable)(t.focusedNode))return!1;const o=t.focusedNode.workspace;return o instanceof d.WorkspaceSvg&&this.copyCallback(o,e,void 0,t)},id:"blockCopyFromContextMenu",weight:13};d.ContextMenuRegistry.registry.register(t)}copyCallback(t,e,o={name:a.CUT},n){var i;const r=!!(null===(i=this.oldCopyShortcut)||void 0===i?void 0:i.callback)&&this.oldCopyShortcut.callback(t,e,o,n);return r&&(this.copyWorkspace=t,function(t){d.Toast.show(t,{message:`Copied. Press ${p(a.PASTE)} to paste.`,duration:7,id:b})}(t)),r}registerPasteShortcut(){if(this.oldPasteShortcut=d.ShortcutRegistry.registry.getRegistry()[d.ShortcutItems.names.PASTE],!this.oldPasteShortcut)throw new Error("No paste keyboard shortcut registered initially");const t={name:a.PASTE,preconditionFn:this.oldPasteShortcut.preconditionFn,callback:this.pasteCallback.bind(this),keyCodes:this.oldPasteShortcut.keyCodes,allowCollision:!1};d.ShortcutRegistry.registry.unregister(d.ShortcutItems.names.PASTE),d.ShortcutRegistry.registry.register(t)}registerPasteContextMenuAction(){const t={displayText:t=>d.Msg.PASTE_SHORTCUT.replace("%1",p(a.PASTE)),preconditionFn:t=>this.pastePrecondition(t),callback:(t,e)=>{const o=this.copyWorkspace;if(o)return this.pasteCallback(o,e,void 0,t)},id:"blockPasteFromContextMenu",weight:14};d.ContextMenuRegistry.registry.register(t)}pasteCallback(t,e,o={name:a.CUT},n){var i;const r=!!(null===(i=this.oldPasteShortcut)||void 0===i?void 0:i.callback)&&this.oldPasteShortcut.callback(t,e,o,n);return function(t){d.Toast.hide(t,S),d.Toast.hide(t,b)}(t),r}}class E{constructor(){this.oldDisplayText=void 0,this.oldContextMenuItem=null}install(){this.registerContextMenuAction()}uninstall(){this.oldContextMenuItem&&this.oldDisplayText&&(this.oldContextMenuItem.displayText=this.oldDisplayText)}registerContextMenuAction(){this.oldContextMenuItem=d.ContextMenuRegistry.registry.getItem("blockDelete"),this.oldContextMenuItem&&(this.oldDisplayText=this.oldContextMenuItem.displayText,this.oldContextMenuItem.displayText=t=>{const e=p(d.ShortcutItems.names.DELETE);return"function"==typeof this.oldDisplayText?this.oldDisplayText(t)+` (${e})`:"string"==typeof this.oldDisplayText?this.oldDisplayText+` (${e})`:d.Msg.DELETE_BLOCK.replace("%1",e)})}}class M{constructor(t){this.navigation=t}install(){this.registerContextMenuAction()}uninstall(){d.ContextMenuRegistry.registry.unregister("edit")}registerContextMenuAction(){const t={displayText:d.Msg.EDIT_BLOCK_CONTENTS.replace("%1",p(a.RIGHT)),preconditionFn:(t,e)=>{var o;if(e instanceof PointerEvent)return"hidden";const n=null===(o=t.block)||void 0===o?void 0:o.workspace;if(!n||!this.navigation.canCurrentlyNavigate(n))return"disabled";const i=n.getCursor();return i?i.atEndOfLine()?"hidden":"enabled":"disabled"},callback:t=>{var e,o;d.keyboardNavigationController.setIsActive(!0);const n=null===(e=t.block)||void 0===e?void 0:e.workspace;return!!n&&(null===(o=n.getCursor())||void 0===o||o.in(),!0)},scopeType:d.ContextMenuRegistry.ScopeType.BLOCK,id:"edit",weight:10};d.ContextMenuRegistry.registry.register(t)}}class N extends l.LineCursor{constructor(t){super(t.getWorkspace()),this.flyout=t}next(){const t=this.getCurNode();if(!t)return null;const e=this.workspace.getNavigator().getNextSibling(t);return e&&this.setCurNode(e),e}prev(){const t=this.getCurNode();if(!t)return null;const e=this.workspace.getNavigator().getPreviousSibling(t);return e&&this.setCurNode(e),e}setCurNode(t){let e;if(super.setCurNode(t),t&&"getBoundingRectangle"in t&&"function"==typeof t.getBoundingRectangle)e=t.getBoundingRectangle();else if(t instanceof l.FlyoutButton){const{x:o,y:n}=t.getPosition();e=new l.utils.Rect(n,n+t.height,o,o+t.width)}e instanceof l.utils.Rect&&function(t,e){if(l.Gesture.inProgress())return;const o=e.getScale(),n=e.getMetricsManager().getViewMetrics(!0),i=new l.utils.Rect(n.top,n.top+n.height,n.left,n.left+n.width);if(t.left>=i.left&&t.top>=i.top&&t.right<=i.right&&t.bottom<=i.bottom)return;(t=t.clone()).top-=10,t.bottom+=10,t.left-=10,t.right+=10;let r=0,s=0;t.left<i.left?r=i.left-t.left:t.right>i.right&&(r=i.right-t.right),t.top<i.top?s=i.top-t.top:t.bottom>i.bottom&&(s=i.bottom-t.bottom),r*=o,s*=o,e.scroll(e.scrollX+r,e.scrollY+s)}(e,this.flyout.getWorkspace())}}const O=l.registry.Type.CURSOR,F="FlyoutCursor";l.registry.register(O,F,N),O.toString();class I{constructor(){this.workspaces=[],this.wsChangeWrapper=this.workspaceChangeListener.bind(this),this.flyoutChangeWrapper=this.flyoutChangeListener.bind(this)}addWorkspace(t){this.workspaces.push(t);const e=t.getFlyout();t.addChangeListener(this.wsChangeWrapper),e&&this.addFlyout(e)}removeWorkspace(t){const e=this.workspaces.indexOf(t),o=t.getFlyout();t.getCursor()&&this.disableKeyboardAccessibility(t),e>-1&&this.workspaces.splice(e,1),t.removeChangeListener(this.wsChangeWrapper),o&&this.removeFlyout(o)}getState(t){const e=l.getFocusManager().getFocusedTree();if(e instanceof l.WorkspaceSvg)return e.isFlyout?s.FLYOUT:s.WORKSPACE;if(e instanceof l.Toolbox){if(t===e.getWorkspace())return s.TOOLBOX}else if(e instanceof l.Flyout)return s.FLYOUT;return s.NOWHERE}addFlyout(t){const e=t.getWorkspace();e.addChangeListener(this.flyoutChangeWrapper);const o=l.registry.getClass(O,F);o&&e.getMarkerManager().setCursor(new o(t))}removeFlyout(t){t.getWorkspace().removeChangeListener(this.flyoutChangeWrapper)}workspaceChangeListener(t){if(!t.workspaceId)return;const e=l.Workspace.getById(t.workspaceId);e&&e.keyboardAccessibilityMode&&t.type===l.Events.BLOCK_CHANGE&&"mutation"===t.element&&this.handleBlockMutation(e,t)}flyoutChangeListener(t){if(!t.workspaceId)return;const e=l.Workspace.getById(t.workspaceId),o=null==e?void 0:e.targetWorkspace;if(!o)return;const n=o.getFlyout();if(n)if(o&&o.keyboardAccessibilityMode&&!n.autoClose){if(t.type===l.Events.CLICK&&"block"===t.targetType){const{blockId:n}=t;if(n){const t=e.getBlockById(n);t&&this.handleBlockClickInFlyout(o,t)}}else if(t.type===l.Events.SELECTED){const{newElementId:n}=t;if(n){const t=e.getBlockById(n);t&&this.handleBlockClickInFlyout(o,t)}}}else t.type===l.Events.BLOCK_CREATE&&this.getState(o)===s.FLYOUT&&this.defaultFlyoutCursorIfNeeded(o)}isFlyoutItemDisposed(t,e){return!!(null==e?void 0:e.disposed)||t instanceof l.FlyoutButton&&null===t.getSvgRoot().parentNode}handleBlockMutation(t,e){const o=e.blockId,n=t.getCursor(),i=null==n?void 0:n.getSourceBlock();i&&i.id===o&&(null==n||n.setCurNode(i))}handleBlockClickInFlyout(t,e){var o;if(!e)return;const n=e.isShadow()?e:e.getParent();n&&(null===(o=this.getFlyoutCursor(t))||void 0===o||o.setCurNode(n));const i=t.getFlyout();i&&l.getFocusManager().focusTree(i.getWorkspace())}defaultFlyoutCursorIfNeeded(t,e="first"){const o=t.getFlyout();if(!o)return!1;const n=this.getFlyoutCursor(t);if(!n)return!1;const i=n.getCurNode(),r=n.getSourceBlock();if(i&&!this.isFlyoutItemDisposed(i,r))return!1;const s=o.getContents(),a="first"===e?s[0]:s[s.length-1];if(!a)return!1;const c=a.getElement();return n.setCurNode(c),!0}defaultWorkspaceCursorPositionIfNeeded(t,e="first"){var o;const n=t.getTopBlocks(!0),i=t.getCursor();if(!i)return;const r=null===(o=i.getSourceBlock())||void 0===o?void 0:o.disposed;return!(i.getCurNode()&&!r||(n.length>0?i.setCurNode(n["first"===e?0:n.length-1]):i.setCurNode(t),0))}getFlyoutCursor(t){const e=t.getFlyout();return e?e.getWorkspace().getCursor():null}findInsertStartPoint(t,e){var o;const n=!!e.outputConnection;if(t instanceof l.Field){const o=t.getSourceBlock();return o?this.findInsertStartPoint(o,e):null}if(t instanceof l.RenderedConnection){if(!n&&t.type===l.ConnectionType.INPUT_VALUE){const o=t.getSourceBlock();return o?this.findInsertStartPoint(o,e):null}return t}if(t instanceof l.WorkspaceSvg)return null;if(t instanceof l.BlockSvg){const i=n?l.inputs.inputTypes.VALUE:l.inputs.inputTypes.STATEMENT,r=t.inputList.filter((t=>t.type===i)),s=r.length>0?r[0]:null;let a=null==s?void 0:s.connection;if(a){if(i===l.inputs.inputTypes.STATEMENT)for(;null===(o=a.targetBlock())||void 0===o?void 0:o.nextConnection;)a=a.targetBlock().nextConnection;return a}if(t.nextConnection&&!n)return t.nextConnection;if(t.outputConnection){const o=t.outputConnection.targetConnection;if(n&&o)return this.findInsertStartPoint(o,e);if(!n){const o=t.getParent();return o?this.findInsertStartPoint(o,e):null}return t.outputConnection}}return this.warn(`Unexpected case in findInsertStartPoint ${t}.`),null}tryToConnectBlock(t,e){const o=this.findInsertStartPoint(t,e);return!!o&&this.insertBlock(e,o)}disconnectChild(t,e){const o=t.getSourceBlock(),n=e.getSourceBlock();let i;o.getRootBlock()===n.getRootBlock()&&(o.getDescendants(!1).includes(n)?(i=this.getInferiorConnection(e),i&&i.disconnect()):(i=this.getInferiorConnection(t),i&&i.disconnect()))}connect(t,e){if(!t||!e)return!1;const o=this.getInferiorConnection(t),n=this.getSuperiorConnection(e),i=this.getSuperiorConnection(t),r=this.getInferiorConnection(e);if(o&&n&&this.moveAndConnect(o,n))return!0;if(i&&r&&this.moveAndConnect(i,r))return!0;if(this.moveAndConnect(t,e))return!0;{const o=t.getConnectionChecker(),n=o.canConnectWithReason(t,e,!1);return this.warn("Connection failed with error: "+o.getErrorMessage(n,t,e)),!1}}getInferiorConnection(t){if(!t)return null;const e=t.getSourceBlock();return t.isSuperior()?e.previousConnection?e.previousConnection:e.outputConnection?e.outputConnection:null:t}getSuperiorConnection(t){return t?t.isSuperior()?t:t.targetConnection?t.targetConnection:null:null}moveAndConnect(t,e){if(!t||!e)return!1;const o=t.getSourceBlock();if(t.getConnectionChecker().canConnect(t,e,!1)&&!e.getSourceBlock().isShadow()){if(this.disconnectChild(t,e),!e.isSuperior()){const n=o.getRootBlock(),i={x:e.x-t.x,y:e.y-t.y},r=t.getOffsetInBlock().clone();n.positionNearConnection(t,i,r)}return e.connect(t),!0}return!1}insertBlock(t,e){switch(e.type){case l.PREVIOUS_STATEMENT:if(this.connect(t.nextConnection,e))return!0;break;case l.NEXT_STATEMENT:if(this.connect(t.previousConnection,e))return!0;break;case l.INPUT_VALUE:if(this.connect(t.outputConnection,e))return!0;break;case l.OUTPUT_VALUE:for(let o=0;o<t.inputList.length;o++){const n=t.inputList[o].connection;if(n&&n.type===l.INPUT_VALUE&&this.connect(n,e))return!0}if(t.outputConnection&&this.connect(t.outputConnection,e))return!0}return this.warn("This block can not be inserted at the marked location."),!1}enableKeyboardAccessibility(t){this.workspaces.includes(t)&&!t.keyboardAccessibilityMode&&(t.keyboardAccessibilityMode=!0)}disableKeyboardAccessibility(t){this.workspaces.includes(t)&&t.keyboardAccessibilityMode&&(t.keyboardAccessibilityMode=!1)}log(t){console.log(t)}warn(t){console.warn(t)}error(t){console.error(t)}openToolboxOrFlyout(t){const e=t.getToolbox(),o=t.getFlyout();e?l.getFocusManager().focusTree(e):o&&l.getFocusManager().focusTree(o.getWorkspace())}paste(t,e){var o;const n=null===(o=e.getCursor())||void 0===o?void 0:o.getCurNode();l.Events.setGroup(!0);const i=l.clipboard.paste(t,e);return i?(n&&this.tryToConnectBlock(n,i),!0):(l.Events.setGroup(!1),!1)}canCurrentlyNavigate(t){var e;return!!(t.isFlyout?null===(e=t.targetWorkspace)||void 0===e?void 0:e.keyboardAccessibilityMode:t.keyboardAccessibilityMode)&&this.getState(t)!==s.NOWHERE&&!l.getFocusManager().ephemeralFocusTaken()}canCurrentlyEdit(t){return this.canCurrentlyNavigate(t)&&!t.options.readOnly}dispose(){for(const t of this.workspaces)this.removeWorkspace(t)}}class x{constructor(){this.outputDiv=document.getElementById("shortcuts"),this.open=!1,this.modalContainer=null,this.shortcutDialog=null,this.closeButton=null}getPlatform(){const{platform:t,userAgent:e}=navigator;return t.startsWith("Win")?l.Msg.WINDOWS:t.startsWith("Mac")?l.Msg.MAC_OS:/\bCrOS\b/.test(e)?l.Msg.CHROME_OS:t.includes("Linux")?l.Msg.LINUX:l.Msg.UNKNOWN}updatePlatformName(){const t=this.getPlatform(),e=this.outputDiv?this.outputDiv.querySelector(".platform"):null;e&&(e.textContent=t)}toggle(t){!function(t){d.Toast.hide(t,T)}(t),this.toggleInternal()}toggleInternal(){this.modalContainer&&this.shortcutDialog&&(this.shortcutDialog.hasAttribute("open")?this.shortcutDialog.close():this.shortcutDialog.showModal())}getReadableShortcutName(t){return f(t.replace(/_/gi," "))}createModalContent(){let t='<div class="modal-container">\n <dialog class="shortcut-modal">\n <div class="shortcut-container" tabindex="0">\n <div class="header">\n <button class="close-modal">\n <span class="material-symbols-outlined">close</span>\n </button>\n <h1>Keyboard shortcuts – <span class="platform">Windows</span></h1>\n </div>\n <div class="shortcut-tables">';for(const[e,o]of Object.entries(u)){t+=`\n <table class="shortcut-table">\n <tbody>\n <tr class="category"><th colspan="3"><h2>${e}</h2></th></tr>\n <tr>\n `;for(const e of o)t+=`\n <td>${this.getReadableShortcutName(e)}</td>\n <td>${this.actionShortcutsToHTML(e)}</td>\n </tr>`;t+="</tr></tbody></table>"}this.outputDiv&&(this.outputDiv.innerHTML=t+"</div>\n </dialog>\n </div>",this.modalContainer=this.outputDiv.querySelector(".modal-container"),this.shortcutDialog=this.outputDiv.querySelector(".shortcut-modal"),this.closeButton=this.outputDiv.querySelector(".close-modal"),this.updatePlatformName(),this.closeButton&&this.closeButton.addEventListener("click",(t=>{this.toggleInternal()})))}actionShortcutsToHTML(t){const e=function(t){return y(t,C)}(t);return e.map((t=>this.actionShortcutToHTML(t))).join(" / ")}actionShortcutToHTML(t){const e=navigator.platform.startsWith("Mac")?"":" + ";return['<span class="shortcut-combo">',...t.map(((o,n)=>`<span class="key">${o}</span>${n<t.length-1?e:""}`)),"</span>"].join("")}install(){const t={name:a.LIST_SHORTCUTS,callback:t=>(this.toggle(t),!0),keyCodes:[l.utils.KeyCodes.SLASH]};l.ShortcutRegistry.registry.register(t)}uninstall(){l.ShortcutRegistry.registry.unregister(a.LIST_SHORTCUTS)}}l.Css.register("\n:root {\n --divider-border-color: #eee;\n --key-border-color: #ccc;\n --shortcut-modal-border-color: #9aa0a6;\n}\n\n.shortcut-modal {\n border: 1px solid var(--shortcut-modal-border-color);\n border-radius: 12px;\n box-shadow: 6px 6px 32px rgba(0,0,0,.5);\n flex-direction: column;\n gap: 12px;\n margin: auto;\n max-height: 82vh;\n max-width: calc(100% - 10em);\n padding: 24px 12px 24px 32px;\n position: relative;\n z-index: 99;\n}\n\n.shortcut-modal[open] {\n display: flex;\n}\n\n.shortcut-modal .close-modal {\n border: 0;\n background: transparent;\n float: inline-end;\n margin: 0 0 0 0;\n position: absolute;\n top: 16px;\n right: 24px;\n}\n\n.shortcut-modal h1 {\n font-weight: 600;\n font-size: 1.2em;\n}\n\n.shortcut-modal:before {\n background: radial-gradient(rgba(244, 244, 244, 0.43), rgba(75, 75, 75, 0.51));\n align-items: center;\n display: block;\n font-family: Roboto;\n height: 100%;\n justify-content: center;\n left: 0;\n position: absolute;\n top: 0;\n width: 100%;\n}\n\n.shortcut-tables {\n display: grid;\n align-items: start;\n grid-template-columns: 1fr;\n row-gap: 1em;\n column-gap: 2em;\n}\n\n@media (min-width: 950px) {\n .shortcut-tables {\n grid-template-columns: 1fr 1fr\n }\n}\n\n@media (min-width: 1360px) {\n .shortcut-tables {\n grid-template-columns: 1fr 1fr 1fr\n }\n}\n\n.shortcut-table {\n border-collapse: collapse;\n font-family: Roboto;\n font-size: .9em;\n}\n\n.shortcut-table th {\n padding-inline-end: 0.5em;\n text-align: left;\n text-wrap: nowrap;\n vertical-align: baseline;\n}\n\n.shortcut-table td:first-child {\n text-wrap: auto;\n width: 40%;\n}\n\n.shortcut-table tr:has(+ .category) {\n --divider-border-color: transparent;\n margin-end: 1em;\n}\n\n.shortcut-table tr:not(.category, :last-child) {\n border-bottom: 1px solid var(--divider-border-color);\n}\n\n.shortcut-table td {\n padding: 0.2em 1em 0.3em 0;\n text-wrap: nowrap;\n}\n\n.shortcut-table h2 {\n border-bottom: 1px solid #999;\n font-size: 1em;\n padding-block-end: 0.5em;\n}\n\n.shortcut-table .key {\n border: 1px solid var(--key-border-color);\n border-radius: 8px;\n display: inline-block;\n margin: 0 4px;\n min-width: 2em;\n padding: .3em .5em;\n text-align: center;\n}\n\n.shortcut-table .separator {\n color: gray;\n display: inline-block;\n padding: 0 0.5em;\n}\n\n.shortcut-container {\n font-size: 0.95em;\n overflow: auto;\n padding: 0.5em;\n}\n\n.shortcut-combo {\n display: inline-block;\n padding: 0.25em 0;\n text-wrap: nowrap;\n}\n\n");const D=d.utils.KeyCodes,A=d.ShortcutRegistry.registry.createSerializedKey.bind(d.ShortcutRegistry.registry);class L{constructor(t){this.navigation=t,this.shortcuts=[{name:a.MOVE_WS_CURSOR_LEFT,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>this.moveWSCursor(t,-1,0),keyCodes:[A(D.A,[D.SHIFT])]},{name:a.MOVE_WS_CURSOR_RIGHT,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>this.moveWSCursor(t,1,0),keyCodes:[A(D.D,[D.SHIFT])]},{name:a.MOVE_WS_CURSOR_UP,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>this.moveWSCursor(t,0,-1),keyCodes:[A(D.W,[D.SHIFT])]},{name:a.MOVE_WS_CURSOR_DOWN,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>this.moveWSCursor(t,0,1),keyCodes:[A(D.S,[D.SHIFT])]},{name:a.CREATE_WS_CURSOR,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>(d.keyboardNavigationController.setIsActive(!0),this.createWSCursor(t)),keyCodes:[D.W]}]}install(){for(const t of this.shortcuts)d.ShortcutRegistry.registry.register(t)}uninstall(){for(const t of this.shortcuts)d.ShortcutRegistry.registry.unregister(t.name)}moveWSCursor(t,e,o){return!1}createWSCursor(t){const e=t.getCursor();return!!e&&(e.setCurNode(t),!0)}}const B=l.utils.KeyCodes;class P{constructor(t){this.navigation=t}fieldShortcutHandler(t,e){const o=t.getCursor();if(!o||!o.getCurNode())return!1;const n=o.getCurNode();return n instanceof l.Field&&n.onShortcut(e)}install(){const t=(t,e,o)=>{var n;const i=t.getToolbox(),r=t.getFlyout();let a=!1;switch(this.navigation.getState(t)){case s.WORKSPACE:return a=this.fieldShortcutHandler(t,o),!a&&t&&(this.navigation.defaultWorkspaceCursorPositionIfNeeded(t)||null===(n=t.getCursor())||void 0===n||n.in(),a=!0),a;case s.TOOLBOX:return a=i&&i.selectChild(),!a&&r&&(l.getFocusManager().focusTree(r.getWorkspace()),this.navigation.defaultFlyoutCursorIfNeeded(t)),!0;default:return!1}},e=(t,e,o)=>{var n;const i=t.getToolbox();let r=!1;switch(this.navigation.getState(t)){case s.WORKSPACE:return r=this.fieldShortcutHandler(t,o),!r&&t&&(this.navigation.defaultWorkspaceCursorPositionIfNeeded(t)||null===(n=t.getCursor())||void 0===n||n.out(),r=!0),r;case s.FLYOUT:return i&&l.getFocusManager().focusTree(i),!0;case s.TOOLBOX:return i&&i.selectParent();default:return!1}},o={right:{name:a.RIGHT,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t),callback:(o,n,i)=>(l.keyboardNavigationController.setIsActive(!0),o.RTL?e(o,0,i):t(o,0,i)),keyCodes:[B.RIGHT]},left:{name:a.LEFT,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t),callback:(o,n,i)=>(l.keyboardNavigationController.setIsActive(!0),o.RTL?t(o,0,i):e(o,0,i)),keyCodes:[B.LEFT]},down:{name:a.DOWN,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t),callback:(t,e,o)=>{var n,i,r,a;l.keyboardNavigationController.setIsActive(!0);const c=t.getToolbox(),u=t.getFlyout();let d=!1;switch(this.navigation.getState(t)){case s.WORKSPACE:return d=this.fieldShortcutHandler(t,o),!d&&t&&(this.navigation.defaultWorkspaceCursorPositionIfNeeded(t)||null===(n=t.getCursor())||void 0===n||n.next(),d=!0),d;case s.FLYOUT:return d=this.fieldShortcutHandler(t,o),!d&&u&&(this.navigation.defaultFlyoutCursorIfNeeded(t)||null===(r=null===(i=u.getWorkspace())||void 0===i?void 0:i.getCursor())||void 0===r||r.next(),d=!0),d;case s.TOOLBOX:if(c){if(c.getSelectedItem())d=c.selectNext();else{const t=null!==(a=c.getToolboxItems().find((t=>t.isSelectable())))&&void 0!==a?a:null;c.setSelectedItem(t),d=!0}const t=c.getSelectedItem();t&&l.getFocusManager().focusNode(t)}return d;default:return!1}},keyCodes:[B.DOWN]},up:{name:a.UP,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t),callback:(t,e,o)=>{var n,i,r;l.keyboardNavigationController.setIsActive(!0);const a=t.getFlyout(),c=t.getToolbox();let u=!1;switch(this.navigation.getState(t)){case s.WORKSPACE:return u=this.fieldShortcutHandler(t,o),u||(this.navigation.defaultWorkspaceCursorPositionIfNeeded(t,"last")||null===(n=t.getCursor())||void 0===n||n.prev(),u=!0),u;case s.FLYOUT:return u=this.fieldShortcutHandler(t,o),!u&&a&&(this.navigation.defaultFlyoutCursorIfNeeded(t,"last")||null===(r=null===(i=a.getWorkspace())||void 0===i?void 0:i.getCursor())||void 0===r||r.prev(),u=!0),u;case s.TOOLBOX:if(c){u=c.selectPrevious();const t=c.getSelectedItem();t&&l.getFocusManager().focusNode(t)}return u;default:return!1}},keyCodes:[B.UP]}};for(const t of Object.values(o))l.ShortcutRegistry.registry.register(t)}uninstall(){l.ShortcutRegistry.registry.unregister(a.LEFT),l.ShortcutRegistry.registry.unregister(a.RIGHT),l.ShortcutRegistry.registry.unregister(a.DOWN),l.ShortcutRegistry.registry.unregister(a.UP)}}const W=l.utils.KeyCodes;class _{constructor(t){this.navigation=t}install(){l.ShortcutRegistry.registry.register({name:a.EXIT,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t),callback:t=>{switch(this.navigation.getState(t)){case s.FLYOUT:case s.TOOLBOX:return(0,l.getFocusManager)().focusTree(t),l.Gesture.inProgress()||t.hideChaff(),!0;default:return!1}},keyCodes:[W.ESC],allowCollision:!0})}uninstall(){l.ShortcutRegistry.registry.unregister(a.EXIT)}}const U=l.utils.KeyCodes;class H{constructor(t,e){this.mover=t,this.navigation=e}install(){l.ShortcutRegistry.registry.register({name:a.EDIT_OR_CONFIRM,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:(t,e)=>{let o,n;switch(e.preventDefault(),this.navigation.getState(t)){case s.WORKSPACE:return this.handleEnterForWS(t),!0;case s.FLYOUT:return o=this.navigation.getFlyoutCursor(t),!!o&&(n=o.getCurNode(),n instanceof l.BlockSvg?this.insertFromFlyout(t):n instanceof l.FlyoutButton&&this.triggerButtonCallback(t),!0);default:return!1}},keyCodes:[U.ENTER,U.SPACE]})}handleEnterForWS(t){const e=t.getCursor();if(!e)return;const o=e.getCurNode();o&&(o instanceof l.Field?o.showEditor():o instanceof l.BlockSvg?this.tryShowFullBlockFieldEditor(o)||function(t){const e=p("list_shortcuts"),o=d.Msg.HELP_PROMPT.replace("%1",e),n=T;d.Toast.show(t,{message:o,id:n})}(t):o instanceof l.RenderedConnection||o instanceof l.WorkspaceSvg?this.navigation.openToolboxOrFlyout(t):o instanceof l.icons.Icon&&o.onClick())}insertFromFlyout(t){var e;t.setResizesEnabled(!1),l.Events.getGroup()||l.Events.setGroup(!0);const o=l.FocusableTreeTraverser.findFocusedNode(t),n=this.createNewBlock(t);if(!n)return;const i=o?this.navigation.findInsertStartPoint(o,n):null;t.getTopBlocks().includes(n)&&this.positionNewTopLevelBlock(t,n),t.setResizesEnabled(!0),(0,l.getFocusManager)().focusTree(t),null===(e=t.getCursor())||void 0===e||e.setCurNode(n),this.mover.startMove(t,n,i),n.outputConnection||n.nextConnection||n.previousConnection?function(t){const e=`Use the arrow keys to move, then ${p(a.EDIT_OR_CONFIRM)} to accept the position`;d.Toast.show(t,{message:e,id:m,oncePerSession:!0})}(t):w(t,!1)}positionNewTopLevelBlock(t,e){var o;const n=t.getTopBlocks(!0).filter((t=>t.id!==e.id)).map((t=>t.getBoundingRectangle())),i=null===(o=t.getToolbox())||void 0===o?void 0:o.getWidth(),r=t.getParentSvg().clientWidth-(null!=i?i:0),{height:s,width:a}=(t.getParentSvg().clientHeight,e.getHeightWidth()),c=function(t){for(const e of n)if(t.intersects(e))return e;return null};let l=10,u=10;const d=t.getRenderer().getConstants().MIN_BLOCK_HEIGHT;let g=e.getBoundingRectangle();e.moveBy(u-g.left,l-g.top,["cleanup"]),e.snapToGrid(),g=e.getBoundingRectangle();let h=c(g);for(;null!=h;){const t=h.left+h.getWidth()+80,o=h.top+h.getHeight()+d;t+a<=r?u=t:(l=o,u=10),e.moveBy(u-g.left,l-g.top,["cleanup"]),e.snapToGrid(),g=e.getBoundingRectangle(),h=c(g)}e.bringToFront()}triggerButtonCallback(t){var e;const o=null===(e=this.navigation.getFlyoutCursor(t))||void 0===e?void 0:e.getCurNode();if(!(o instanceof l.FlyoutButton))return;const n=t.flyoutButtonCallbacks,i=o.info;if("callbackkey"in i){const t=n.get(i.callbackkey);if(!t)throw new Error("No callback function found for flyout button.");t(o)}}tryShowFullBlockFieldEditor(t){if(t.isSimpleReporter())for(const e of t.inputList)for(const t of e.fieldRow)if(t.isClickable()&&t.isFullBlockField())return t.showEditor(),!0;return!1}createNewBlock(t){var e;const o=t.getFlyout();if(!o||!o.isVisible())return console.warn("Trying to insert from the flyout when the flyout does not exist or is not visible"),null;const n=null===(e=this.navigation.getFlyoutCursor(t))||void 0===e?void 0:e.getCurNode();if(!(n instanceof l.BlockSvg&&n.isEnabled()))return console.warn("Can't insert a disabled block."),null;const i=o.createBlock(n);return i.render(),i.setConnectionTracking(!0),i}uninstall(){l.ShortcutRegistry.registry.unregister(a.EDIT_OR_CONFIRM)}}const K=d.utils.KeyCodes;class V{constructor(t){this.navigation=t,this.shortcutName=a.DISCONNECT}install(){this.registerShortcut()}uninstall(){d.ShortcutRegistry.registry.unregister(this.shortcutName)}registerShortcut(){const t={name:this.shortcutName,preconditionFn:t=>this.navigation.canCurrentlyEdit(t),callback:t=>(d.keyboardNavigationController.setIsActive(!0),this.navigation.getState(t)===s.WORKSPACE&&(this.disconnectBlocks(t),!0)),keyCodes:[K.X]};d.ShortcutRegistry.registry.register(t)}disconnectBlocks(t){var e;const o=t.getCursor();if(!o)return;const n=o.getCurNode();if(!(n instanceof d.BlockSvg))return;const i=!(null===(e=n.outputConnection)||void 0===e?void 0:e.isConnected());d.Events.setGroup(!0),n.unplug(i),d.Events.setGroup(!1),o.setCurNode(n)}}const G=d.utils.KeyCodes,Y=d.ShortcutRegistry.registry.createSerializedKey.bind(d.ShortcutRegistry.registry);class z{constructor(t){this.navigation=t,this.shortcutName=a.MENU}install(){this.registerShortcut()}uninstall(){d.ShortcutRegistry.registry.unregister(this.shortcutName)}registerShortcut(){const t={name:a.MENU,preconditionFn:t=>this.navigation.canCurrentlyNavigate(t)&&!t.isDragging(),callback:t=>{var e;switch(this.navigation.getState(t)){case s.WORKSPACE:return this.openActionMenu(t);case s.FLYOUT:{const o=null===(e=t.getFlyout())||void 0===e?void 0:e.getWorkspace();return!!o&&this.openActionMenu(o)}default:return!1}},keyCodes:[Y(G.ENTER,[G.CTRL]),Y(G.ENTER,[G.ALT]),Y(G.ENTER,[G.META])]};d.ShortcutRegistry.registry.register(t)}openActionMenu(t){const e=new KeyboardEvent("keydown"),o=t.getCursor();if(!o)throw new Error("workspace has no cursor");const n=o.getCurNode();return!!n&&("showContextMenu"in n&&"function"==typeof n.showContextMenu?(n.showContextMenu(e),setTimeout((()=>{var t,e;null===(e=null===(t=d.WidgetDiv.getDiv())||void 0===t?void 0:t.querySelector(".blocklyMenu"))||void 0===e||e.dispatchEvent(new KeyboardEvent("keydown",{key:"ArrowDown",code:"ArrowDown",keyCode:G.DOWN,which:G.DOWN,bubbles:!0,cancelable:!0}))}),10),!0):(console.info(`No action menu for node ${n}`),!1))}}var X;function j(t){if(!t)return{x:0,y:0};switch(t){case X.Up:return{x:0,y:-1};case X.Down:return{x:0,y:1};case X.Left:return{x:-1,y:0};case X.Right:return{x:1,y:0}}}!function(t){t[t.Up=1]="Up",t[t.Down=2]="Down",t[t.Left=3]="Left",t[t.Right=4]="Right"}(X||(X={}));const $=d.utils.KeyCodes,q=d.ShortcutRegistry.registry.createSerializedKey.bind(d.ShortcutRegistry.registry);class J{constructor(t){this.mover=t,this.shortcutNames=[],this.menuItemNames=[]}registerShortcuts(){const t=[{name:d.Msg.START_MOVE,preconditionFn:t=>{const e=this.getCurrentBlock(t);return!!e&&this.mover.canMove(t,e)},callback:t=>{d.keyboardNavigationController.setIsActive(!0);const e=this.getCurrentBlock(t);return e&&(0,d.getFocusManager)().focusNode(e),!!e&&this.mover.startMove(t,e,null)},keyCodes:[$.M]},{name:d.Msg.FINISH_MOVE,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.finishMove(t),keyCodes:[$.ENTER,$.SPACE],allowCollision:!0},{name:d.Msg.ABORT_MOVE,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.abortMove(t),keyCodes:[$.ESC],allowCollision:!0},{name:d.Msg.MOVE_LEFT_CONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveConstrained(t,X.Left),keyCodes:[$.LEFT],allowCollision:!0},{name:d.Msg.MOVE_RIGHT_CONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveConstrained(t,X.Right),keyCodes:[$.RIGHT],allowCollision:!0},{name:d.Msg.MOVE_UP_CONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveConstrained(t,X.Up),keyCodes:[$.UP],allowCollision:!0},{name:d.Msg.MOVE_DOWN_CONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveConstrained(t,X.Down),keyCodes:[$.DOWN],allowCollision:!0},{name:d.Msg.MOVE_LEFT_UNCONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveUnconstrained(t,X.Left),keyCodes:[q($.LEFT,[$.ALT]),q($.LEFT,[$.CTRL])]},{name:d.Msg.MOVE_RIGHT_UNCONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveUnconstrained(t,X.Right),keyCodes:[q($.RIGHT,[$.ALT]),q($.RIGHT,[$.CTRL])]},{name:d.Msg.MOVE_UP_UNCONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveUnconstrained(t,X.Up),keyCodes:[q($.UP,[$.ALT]),q($.UP,[$.CTRL])]},{name:d.Msg.MOVE_DOWN_UNCONSTRAINED,preconditionFn:t=>this.mover.isMoving(t),callback:t=>this.mover.moveUnconstrained(t,X.Down),keyCodes:[q($.DOWN,[$.ALT]),q($.DOWN,[$.CTRL])]}];for(const e of t)d.ShortcutRegistry.registry.register(e),this.shortcutNames.push(e.name)}registerMenuItems(){const t=[{displayText:d.Msg.MOVE_BLOCK.replace("%1",p(d.Msg.START_MOVE)),preconditionFn:(t,e)=>{var o;const n=null===(o=t.block)||void 0===o?void 0:o.workspace;if(!n||e instanceof PointerEvent)return"hidden";const i=this.getCurrentBlock(n);return i&&this.mover.canMove(n,i)?"enabled":"disabled"},callback:t=>{var e;const o=null===(e=t.block)||void 0===e?void 0:e.workspace;if(!o)return!1;const n=this.getCurrentBlock(o);return n&&(0,d.getFocusManager)().focusNode(n),!!n&&this.mover.startMove(o,n,null)},scopeType:d.ContextMenuRegistry.ScopeType.BLOCK,id:"move",weight:8.5}];for(const e of t)d.ContextMenuRegistry.registry.register(e),this.menuItemNames.push(e.id)}install(){this.registerShortcuts(),this.registerMenuItems()}uninstall(){for(const t of this.shortcutNames)d.ShortcutRegistry.registry.unregister(t);for(const t of this.menuItemNames)d.ContextMenuRegistry.registry.unregister(t)}getCurrentBlock(t){var e;let o=null===(e=null==t?void 0:t.getCursor())||void 0===e?void 0:e.getSourceBlock();if(o){for(;o.isShadow();)if(o=o.getParent(),!o)throw new Error("Tried to drag a shadow block with no parent. Shadow blocks should always have parents.");return o}}}class Q{constructor(t){this.sourceBlock=t,this.location=new l.utils.Coordinate(0,0),this.svgRoot=l.utils.dom.createSvgElement(l.utils.Svg.G,{},this.sourceBlock.workspace.getBubbleCanvas());const e=this.sourceBlock.workspace.RTL;l.utils.dom.createSvgElement(l.utils.Svg.CIRCLE,{fill:"white","fill-opacity":"0.8",stroke:"grey","stroke-width":"1",r:20,cx:20*(e?-1:1),cy:20},this.svgRoot),l.utils.dom.createSvgElement(l.utils.Svg.PATH,{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m18 9l3 3l-3 3m-3-3h6M6 9l-3 3l3 3m-3-3h6m0 6l3 3l3-3m-3-3v6m3-15l-3-3l-3 3m3-3v6",transform:`translate(${8*(e?-4:1)} 8)`},this.svgRoot),this.updateLocation()}isMovable(){return!1}getSvgRoot(){return this.svgRoot}updateLocation(){var t;const e=this.sourceBlock.getBoundingRectangleWithoutChildren(),o=this.sourceBlock.workspace.RTL?e.left+20:e.right-20,n=e.top-20;this.moveTo(o,n),null===(t=this.sourceBlock.workspace.getLayerManager())||void 0===t||t.moveToDragLayer(this)}moveTo(t,e){this.location.x=t,this.location.y=e,this.svgRoot.setAttribute("transform",`translate(${t}, ${e})`)}getRelativeToSurfaceXY(){return this.location}dispose(){l.utils.dom.removeNode(this.svgRoot)}showContextMenu(){}setDragging(t){}startDrag(t){}drag(t,e){}moveDuringDrag(t){}endDrag(){}revertDrag(){}setDeleteStyle(t){}getFocusableElement(){throw new Error("This node is not focusable.")}getFocusableTree(){throw new Error("This node is not focusable.")}onNodeFocus(){}onNodeBlur(){}canBeFocused(){return!1}}class Z{constructor(t){this.sourceBlock=t,this.moveIndicator=new Q(this.sourceBlock)}getType(){return Z.type}getWeight(){return-1}getSize(){return new l.utils.Size(-8,0)}isShownWhenCollapsed(){return!1}isClickableInFlyout(){return!1}bubbleIsVisible(){return!0}getBubble(){return this.moveIndicator}onLocationChange(t){var e;null===(e=this.moveIndicator)||void 0===e||e.updateLocation()}dispose(){var t;null===(t=this.moveIndicator)||void 0===t||t.dispose()}applyColour(){}hideForInsertionMarker(){}updateEditable(){}updateCollapsed(){}setOffsetInBlock(){}onClick(){}setBubbleVisible(t){return e=this,o=void 0,i=function*(){},new((n=void 0)||(n=Promise))((function(t,r){function s(t){try{c(i.next(t))}catch(t){r(t)}}function a(t){try{c(i.throw(t))}catch(t){r(t)}}function c(e){var o;e.done?t(e.value):(o=e.value,o instanceof n?o:new n((function(t){t(o)}))).then(s,a)}c((i=i.apply(e,o||[])).next())}));var e,o,n,i}initView(t){}getFocusableElement(){throw new Error("This node is not focusable.")}getFocusableTree(){throw new Error("This node is not focusable.")}onNodeFocus(){}onNodeBlur(){}canBeFocused(){return!1}}Z.type=new l.icons.IconType("moveIndicator");class tt extends d.dragging.BlockDragStrategy{constructor(t,e){super(t),this.block=t,this.insertStartPoint=e,this.currentDragDirection=null,this.searchNode=null,this.isNewBlock=!!this.insertStartPoint}startDrag(t){super.startDrag(t),this.block.moveDuringDrag(this.startLoc),this.connectionCandidate=this.createInitialCandidate(),this.forceShowPreview(),this.block.addIcon(new Z(this.block))}drag(t,e){if(e)if(this.currentDragDirection=function(t){const{x:e,y:o}=t;if(0==e){if(-1==o)return X.Up;if(1==o)return X.Down}else if(0==o){if(-1==e)return X.Left;if(1==e)return X.Right}return null}({x:e.tiltX,y:e.tiltY}),super.drag(t),this.connectionCandidate){const t=this.connectionCandidate.neighbour;this.searchNode=t,this.isConstrainedMovement()&&this.block.moveDuringDrag(new d.utils.Coordinate(t.x+10,t.y+10))}else this.searchNode=null,this.isConstrainedMovement()&&w(this.workspace,!0)}endDrag(t){super.endDrag(t),this.block.removeIcon(Z.type)}getConstrainedConnectionCandidate(t){const e=this.getLocalConnections(t);if(0==e.length)return null;let o=this.findTraversalCandidate(t,e);return o||this.searchNode||(o=this.findNearestCandidate(e)),o}findNearestCandidate(t){let e=1/0,o=null;const n=new d.utils.Coordinate(0,0);for(const i of t){const{connection:t,radius:r}=i.closest(e,n);t&&(o={local:i,neighbour:t,distance:r},e=r)}return o}findTraversalCandidate(t,e){var o,n;const i=t.workspace.connectionChecker;let r=null,s=this.searchNode;const a=[];for(const e of t.workspace.getTopBlocks(!0))a.push(...e.getDescendants(!0).flatMap((t=>t.getConnections_(!1))).sort(((t,e)=>{let o=t.y-e.y;return 0===o&&(o=t.x-e.x),o})));const c=this.currentDragDirection;for(;s&&!r;){const t=a.indexOf(s);if(c===X.Up||c===X.Left?s=null!==(o=a[t-1])&&void 0!==o?o:a[a.length-1]:c!==X.Down&&c!==X.Right||(s=null!==(n=a[t+1])&&void 0!==n?n:a[0]),e.forEach((t=>{s&&i.canConnect(t,s,!0,1/0)&&(r={local:t,neighbour:s,distance:0})})),s==this.searchNode)break}return r}currCandidateIsBetter(t,e,o){return!this.isConstrainedMovement()&&super.currCandidateIsBetter(t,e,o)}getConnectionCandidate(t,e){return this.isConstrainedMovement()?this.getConstrainedConnectionCandidate(t):super.getConnectionCandidate(t,e)}isConstrainedMovement(){return!!this.currentDragDirection}forceShowPreview(){const t=this.connectionPreviewer,e=this.connectionCandidate;if(!e||!t)return;const o=this.block,{local:n,neighbour:i}=e,r=n.type===d.ConnectionType.OUTPUT_VALUE||n.type===d.ConnectionType.PREVIOUS_STATEMENT,s=i.targetBlock(),a=s&&!s.isInsertionMarker(),c=s&&this.orphanCanConnectAtEnd(o,s,n.type);r&&a&&!c?t.previewReplacement(n,i,s):t.previewConnection(n,i),o.moveDuringDrag(new d.utils.Coordinate(i.x+10,i.y+10))}createInitialCandidate(){var t;const e=null!==(t=this.insertStartPoint)&&void 0!==t?t:this.startParentConn;if(e)switch(this.searchNode=e,e.type){case d.ConnectionType.INPUT_VALUE:if(this.block.outputConnection)return{neighbour:e,local:this.block.outputConnection,distance:0};break;case d.ConnectionType.NEXT_STATEMENT:if(this.block.previousConnection)return{neighbour:e,local:this.block.previousConnection,distance:0}}return null}shouldHealStack(t){return Boolean(this.block.previousConnection)}}const et="commitMove";class ot{constructor(t){this.navigation=t,this.moves=new Map,this.oldIsDragging=null,this.oldGetGesture=null,this.oldDragStrategy=null}canMove(t,e){return!(this.navigation.getState(t)!==s.WORKSPACE||!this.navigation.canCurrentlyEdit(t)||this.moves.has(t)||!(null==e?void 0:e.isMovable()))}isMoving(t){return this.navigation.canCurrentlyEdit(t)&&this.moves.has(t)}startMove(t,e,o){this.patchDragStrategy(e,o);const n=d.registry.getClassFromOptions(d.registry.Type.BLOCK_DRAGGER,t.options,!0);if(!n)throw new Error("no Dragger registered");const i=new n(e,t),r=()=>{this.finishMove(t)};t.setKeyboardMoveInProgress(!0);const s=new nt(e,i,r);this.moves.set(t,s),i.onDragStart(s.fakePointerEvent("pointerdown")),s.updateTotalDelta(),(0,d.getFocusManager)().focusNode(e),e.getFocusableElement().addEventListener("blur",r);const a=Object.values(d.ShortcutRegistry.registry.getRegistry()).flatMap((t=>t.keyCodes)).filter((t=>t&&![d.utils.KeyCodes.RIGHT,d.utils.KeyCodes.LEFT,d.utils.KeyCodes.UP,d.utils.KeyCodes.DOWN,d.utils.KeyCodes.ENTER,d.utils.KeyCodes.ESC].includes("number"==typeof t?t:parseInt(`${t.split("+").pop()}`)))).filter((t=>!!t)),c={name:et,preconditionFn:t=>!!this.moves.get(t),callback:t=>(this.finishMove(t),!1),keyCodes:a,allowCollision:!0};return d.ShortcutRegistry.registry.register(c),!0}finishMove(t){const e=this.preDragEndCleanup(t);return e.dragger.onDragEnd(e.fakePointerEvent("pointerup"),new d.utils.Coordinate(0,0)),this.postDragEndCleanup(t,e),!0}abortMove(t){var e,o;const n=this.preDragEndCleanup(t),i=n.block.getDragStrategy();this.patchDragger(n.dragger,i.isNewBlock);const r=null===(e=i.connectionCandidate)||void 0===e?void 0:e.neighbour;return i.connectionCandidate=null,n.dragger.onDragEnd(n.fakePointerEvent("pointerup"),n.startLocation),i.isNewBlock&&r&&(null===(o=t.getCursor())||void 0===o||o.setCurNode(r)),this.postDragEndCleanup(t,n),!0}preDragEndCleanup(t){d.ShortcutRegistry.registry.unregister(et),function(t){d.Toast.hide(t,m),d.Toast.hide(t,k)}(t);const e=this.moves.get(t);if(!e)throw new Error("no move info for workspace");return e.block.getFocusableElement().removeEventListener("blur",e.blurListener),e}postDragEndCleanup(t,e){this.unpatchDragStrategy(e.block),this.moves.delete(t),t.setKeyboardMoveInProgress(!1),setTimeout((()=>this.scrollCurrentBlockIntoView(t)),0),(0,d.getFocusManager)().focusNode(e.block)}moveConstrained(t,e){if(!t)return!1;const o=this.moves.get(t);if(!o)throw new Error("no move info for workspace");return o.dragger.onDrag(o.fakePointerEvent("pointermove",e),o.totalDelta),o.updateTotalDelta(),this.scrollCurrentBlockIntoView(t,70),!0}moveUnconstrained(t,e){if(!t)return!1;const o=this.moves.get(t);if(!o)throw new Error("no move info for workspace");const{x:n,y:i}=j(e);return o.totalDelta.x+=20*n*t.scale,o.totalDelta.y+=20*i*t.scale,o.dragger.onDrag(o.fakePointerEvent("pointermove"),o.totalDelta),this.scrollCurrentBlockIntoView(t),!0}patchDragStrategy(t,e){this.oldDragStrategy=t.dragStrategy,t.setDragStrategy(new tt(t,e))}unpatchDragStrategy(t){this.oldDragStrategy&&(t.setDragStrategy(this.oldDragStrategy),this.oldDragStrategy=null)}scrollCurrentBlockIntoView(t,e=0){var o;const n=null===(o=this.moves.get(t))||void 0===o?void 0:o.block;if(n){const o=n.getBoundingRectangleWithoutChildren().clone();o.top-=e,o.bottom+=e,o.left-=e,o.right+=e,t.scrollBoundsIntoView(o)}}patchDragger(t,e){e?t.wouldDeleteDraggable=()=>!0:t.shouldReturnToStart=()=>!0}}class nt{constructor(t,e,o){var n,i,r,s;this.block=t,this.dragger=e,this.blurListener=o,this.totalDelta=new d.utils.Coordinate(0,0),this.parentNext=null!==(i=null===(n=t.previousConnection)||void 0===n?void 0:n.targetConnection)&&void 0!==i?i:null,this.parentInput=null!==(s=null===(r=t.outputConnection)||void 0===r?void 0:r.targetConnection)&&void 0!==s?s:null,this.startLocation=t.getRelativeToSurfaceXY()}fakePointerEvent(t,e){const o=this.block.workspace;if(!(o instanceof d.WorkspaceSvg))throw new TypeError;const n=d.utils.svgMath.wsToScreenCoordinates(o,new d.utils.Coordinate(this.startLocation.x+this.totalDelta.x,this.startLocation.y+this.totalDelta.y)),i=j(e);return new PointerEvent(t,{clientX:n.x,clientY:n.y,tiltX:i.x,tiltY:i.y})}updateTotalDelta(){if(!(this.block.workspace instanceof d.WorkspaceSvg))throw new TypeError;this.totalDelta=new d.utils.Coordinate(this.block.relativeCoords.x-this.startLocation.x,this.block.relativeCoords.y-this.startLocation.y)}}class it{install(){const t=l.ShortcutRegistry.registry.getRegistry()[l.ShortcutItems.names.UNDO];if(t){this.originalUndo=t;const e=Object.assign(Object.assign({},this.originalUndo),{preconditionFn:(e,o)=>{var n;return!(e.isDragging()||!(null===(n=t.preconditionFn)||void 0===n?void 0:n.call(t,e,o)))},allowCollision:!0});l.ShortcutRegistry.registry.register(e,!0)}const e=l.ShortcutRegistry.registry.getRegistry()[l.ShortcutItems.names.REDO];if(e){this.originalRedo=e;const t=Object.assign(Object.assign({},this.originalRedo),{preconditionFn:(t,o)=>{var n;return!(t.isDragging()||!(null===(n=e.preconditionFn)||void 0===n?void 0:n.call(e,t,o)))},allowCollision:!0});l.ShortcutRegistry.registry.register(t,!0)}}uninstall(){this.originalUndo&&(l.ShortcutRegistry.registry.register(this.originalUndo,!0),this.originalUndo=void 0),this.originalRedo&&(l.ShortcutRegistry.registry.register(this.originalRedo,!0),this.originalRedo=void 0)}}const rt=l.utils.KeyCodes;class st{constructor(){this.navigation=new I,this.mover=new ot(this.navigation),this.shortcutDialog=new x,this.deleteAction=new E,this.editAction=new M(this.navigation),this.disconnectAction=new V(this.navigation),this.clipboard=new R(this.navigation),this.workspaceMovement=new L(this.navigation),this.arrowNavigation=new P(this.navigation),this.exitAction=new _(this.navigation),this.enterAction=new H(this.mover,this.navigation),this.undoRedoAction=new it,this.actionMenu=new z(this.navigation),this.moveActions=new J(this.mover),this.ori