From 7e58a64013b810430cb9bcefc35b32ba0ecd8304 Mon Sep 17 00:00:00 2001 From: sehugg Date: Mon, 14 Sep 2026 12:07:44 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20sehugg/8?= =?UTF-8?q?bitworkshop@c5d86635f2ca1ed4bd18db54388a95c08151c1ad=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/ui.css | 66 +++++++-- gen/{basic-MKJYKTQV.js => basic-IDLJKEQQ.js} | 4 +- ...-MKJYKTQV.js.map => basic-IDLJKEQQ.js.map} | 0 gen/chunk-22ZJCPEG.js | 12 ++ gen/chunk-22ZJCPEG.js.map | 7 + gen/chunk-CZNGOAGP.js | 27 ---- gen/chunk-CZNGOAGP.js.map | 7 - gen/{chunk-Y4RZDW4X.js => chunk-F6OOEJJR.js} | 4 +- ...-Y4RZDW4X.js.map => chunk-F6OOEJJR.js.map} | 0 gen/{chunk-42RNKHZX.js => chunk-YP6JMRCE.js} | 126 +++++++++--------- ...-42RNKHZX.js.map => chunk-YP6JMRCE.js.map} | 6 +- gen/{devel-XDQ6ZFXO.js => devel-QD6D3GJV.js} | 4 +- ...-XDQ6ZFXO.js.map => devel-QD6D3GJV.js.map} | 0 gen/embedui.js | 2 +- gen/ide/layout.js | 2 +- gen/ide/layout.js.map | 2 +- gen/ide/shortcutbar.js | 1 - gen/ide/shortcutbar.js.map | 2 +- gen/ide/windows.js | 1 - gen/ide/windows.js.map | 2 +- gen/src/ide/layout.js | 2 +- gen/src/ide/layout.js.map | 2 +- gen/src/ide/shortcutbar.js | 1 - gen/src/ide/shortcutbar.js.map | 2 +- gen/src/ide/windows.js | 1 - gen/src/ide/windows.js.map | 2 +- gen/ui.js | 2 +- ...erilog-JCME67ZZ.js => verilog-JBFUZPVO.js} | 4 +- ...CME67ZZ.js.map => verilog-JBFUZPVO.js.map} | 0 index.html | 18 ++- package-lock.json | 5 +- package.json | 4 +- src/ide/layout.ts | 2 +- src/ide/settings.ts | 2 +- src/ide/shortcutbar.ts | 2 +- src/ide/windows.ts | 2 +- 36 files changed, 182 insertions(+), 144 deletions(-) rename gen/{basic-MKJYKTQV.js => basic-IDLJKEQQ.js} (99%) rename gen/{basic-MKJYKTQV.js.map => basic-IDLJKEQQ.js.map} (100%) create mode 100644 gen/chunk-22ZJCPEG.js create mode 100644 gen/chunk-22ZJCPEG.js.map delete mode 100644 gen/chunk-CZNGOAGP.js delete mode 100644 gen/chunk-CZNGOAGP.js.map rename gen/{chunk-Y4RZDW4X.js => chunk-F6OOEJJR.js} (96%) rename gen/{chunk-Y4RZDW4X.js.map => chunk-F6OOEJJR.js.map} (100%) rename gen/{chunk-42RNKHZX.js => chunk-YP6JMRCE.js} (84%) rename gen/{chunk-42RNKHZX.js.map => chunk-YP6JMRCE.js.map} (73%) rename gen/{devel-XDQ6ZFXO.js => devel-QD6D3GJV.js} (93%) rename gen/{devel-XDQ6ZFXO.js.map => devel-QD6D3GJV.js.map} (100%) rename gen/{verilog-JCME67ZZ.js => verilog-JBFUZPVO.js} (99%) rename gen/{verilog-JCME67ZZ.js.map => verilog-JBFUZPVO.js.map} (100%) diff --git a/css/ui.css b/css/ui.css index ff143e88..d4d03531 100644 --- a/css/ui.css +++ b/css/ui.css @@ -13,6 +13,12 @@ padding-bottom: 2px; min-width: 160px; } +#compile_spinner { + visibility: hidden; + margin-left: 0.5em; + margin-right: 0.5em; + height: 1.5em; +} .tooltipbox { position: relative; display: inline-block; @@ -69,15 +75,26 @@ body { #controls_top { flex:0 0 auto; min-height:3em; - padding:0.5em; + padding:0.25em; width:100%; background-color:#999; } -/* contain the floated logo/menus so wrapped content counts toward the height */ -#controls_top::after { - content:""; - display:table; - clear:both; +/* the inline controls are a wrapping flex row so they squish and flow onto + extra rows on narrow screens instead of overflowing the viewport */ +#controls_dynamic { + display:flex; + flex-wrap:wrap; + align-items:center; + row-gap:0.2em; +} +/* push the Books menu (and the logo after it) to the right edge */ +#controls_dynamic > .dropdown.pull-right { + margin-left:auto; +} +/* let the project picker shrink with the row instead of forcing overflow */ +#controls_dynamic > #preset_select { + flex:0 1 auto; + min-width:0; } #notebook { position:relative; @@ -141,6 +158,34 @@ body.tab-layout #notebook > #emulator.active { body.tab-layout #notebook > .gutter { display:none; } +/* no button-group background on mobile tab layout */ +body.tab-layout .btn_group { + background-color:transparent; + padding:1px; + margin-left:2px; +} +body.tab-layout #controls_top { + padding:0.25em; +} +body.tab-layout .btn_toolbar { + margin:2px; +} +/* on mobile the toolbar drops to its own row(s), leaving the menu, + platform picker and project picker sharing the first row */ +body.tab-layout #controls_dynamic > #toolbar { + flex-basis:100%; +} +body.tab-layout #platformsMenuButton { + min-width:0 !important; + max-width:9em; +} +body.tab-layout #platformsMenuButton .platform_name { + display:inline-block; + max-width:6.5em; + overflow:hidden; + text-overflow:ellipsis; + vertical-align:bottom; +} #workspace { background-color:#333; overflow:hidden; @@ -259,8 +304,10 @@ div.mem_info button { text-align:right; } .btn_group { + display:flex; + align-items:center; border-radius:8px; - padding:8px; + padding:4px; margin-left:8px; background-color: #666; } @@ -286,7 +333,10 @@ div.mem_info button { color: #ff6666 !important; } .btn_toolbar { - margin:4px; + display:flex; + flex-wrap:wrap; + align-items:center; + margin:2px; } span.hilite { color: #ff66ff; diff --git a/gen/basic-MKJYKTQV.js b/gen/basic-IDLJKEQQ.js similarity index 99% rename from gen/basic-MKJYKTQV.js rename to gen/basic-IDLJKEQQ.js index b28c3718..3eb3b22c 100644 --- a/gen/basic-MKJYKTQV.js +++ b/gen/basic-IDLJKEQQ.js @@ -1,4 +1,4 @@ -import{b as S}from"./chunk-3FIVEUG2.js";import{y as E}from"./chunk-42RNKHZX.js";import"./chunk-CZNGOAGP.js";import"./chunk-T6VURU5O.js";import"./chunk-A7SWO6EA.js";import"./chunk-Y4RZDW4X.js";import"./chunk-ELRBFCEX.js";import{B as c,K as f,T as d,U as v,a as g}from"./chunk-TYDI7JZQ.js";import"./chunk-VSC4MAII.js";function k(u){return u.value!=null}function y(u){return u.name!=null}function O(u){return u.op!=null&&u.left!=null&&u.right!=null}function N(u){return u.op!=null&&u.expr!=null}var m=class{randomize(){this.seed(Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647)}constructor(){(()=>{var r,e,i,n;this.seed=function(s,a,h,o){r=s,e=a,i=h,n=o},this.seedfloat=function(s){this.seed(s,s*4294,s*429496,s*4294967296),this.next(),this.next(),this.next()},this.next=function(){r>>>=0,e>>>=0,i>>>=0,n>>>=0;var s=r+e|0;return r=e^e>>>9,e=i+(i<<3)|0,i=i<<21|i>>>11,n=n+1|0,s=s+n|0,i=i+s|0,(s>>>0)/4294967296}})(),this.seedfloat(-1)}},I=1024*1024,l=class u{constructor(){this.margin=80;this.running=!1;this.exited=!0;this.trace=!1}load(t){let r=null,e=0;if(this.pc2label!=null){let s=this.curpc;for(;s>0&&(r=this.pc2label.get(s))==null;)s--;e=this.curpc-s,console.log("oldpc=",this.curpc,"restart @ label",r,"+",e)}this.program=t,this.opts=t.opts,this.opts.maxArrayElements||(this.opts.maxArrayElements=I),this.allstmts=t.stmts,this.label2pc=t.labels,this.label2dataptr={},this.pc2label=new Map,this.datums=[],this.subroutines={},this.builtins=this.getBuiltinFunctions();for(var i in t.labels){var n=t.labels[i];this.pc2label.set(n,i)}return this.allstmts.forEach((s,a)=>{this.curpc=a+1,this.compileStatement(s),s.command=="DATA"&&(this.label2dataptr[s.$loc.label]=this.datums.length,s.datums.forEach(h=>{this.curpc=s.$loc.offset,this.datums.push(h)}))}),this.label2pc[r]!=null?(this.curpc=this.label2pc[r]+e,!0):(this.curpc=0,!1)}reset(){this.curpc=0,this.dataptr=0,this.clearVars(),this.returnStack=[],this.column=0,this.running=!0,this.exited=!1}clearVars(){this.globals=this.vars={},this.arrays={},this.defs={},this.forLoops={},this.forLoopStack=[],this.whileLoops=[],this.rng=new m,this.opts&&this.opts.staticArrays&&this.allstmts.filter(t=>t.command=="DIM").forEach(t=>{t.args.forEach(r=>this.compileJS(this._DIM(r))())})}saveState(){return $.extend(!0,{},this)}loadState(t){$.extend(!0,this,t)}getBuiltinFunctions(){var t=this.program&&this.opts.validFunctions;t||(t=Object.getOwnPropertyNames(u.prototype).filter(i=>/^[A-Z]{3,}[$]?$/.test(i)));var r={};for(var e of t)this.supportsFunction(e)&&(r[e]=this[e].bind(this));return r}supportsFunction(t){return typeof this[t]=="function"}runtimeError(t){throw this.curpc--,new d(t,this.getCurrentSourceLocation())}dialectError(t){this.runtimeError(`I can't ${t} in this dialect of BASIC.`)}getLineForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.line}getLabelForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.label}getCurrentSourceLocation(){var t=this.getStatement();return t&&t.$loc}getCurrentLabel(){var t=this.getCurrentSourceLocation();return t&&t.label}getStatement(){return this.allstmts[this.curpc]}step(){if(!this.running)return!1;var t=this.getStatement();return t?(this.trace&&console.log(this.curpc,t,this.vars,Object.keys(this.arrays)),this.curpc++,this.executeStatement(t),this.running):(this.running=!1,this.exited=!0,!1)}compileStatement(t){if(t.$run==null)try{var r=this["do__"+t.command];r==null&&this.runtimeError(`I don't know how to "${t.command}".`);var e=r.bind(this)(t);this.trace&&console.log(e),t.$run=this.compileJS(e)}catch(i){throw e&&console.log(e),i}}compileJS(t){return new Function(t).bind(this)}executeStatement(t){this.compileStatement(t),t.$run()}skipToEOL(){do this.curpc++;while(this.curpc=0?this.curpc=r:this.runtimeError(`I tried to go to the label "${t}" but couldn't find it.`)}newLocalScope(){this.vars=Object.create(this.vars)}popLocalScope(){this.vars!==this.globals&&(this.vars=Object.getPrototypeOf(this.vars))}gosubLabel(t){this.returnStack.length>32767&&this.runtimeError("I did too many GOSUBs without a RETURN."),this.returnStack.push(this.curpc),this.gotoLabel(t)}returnFromGosub(){this.returnStack.length==0&&this.runtimeError("I tried to RETURN, but there wasn't a corresponding GOSUB.");var t=this.returnStack.pop();this.curpc=t,this.popLocalScope()}popReturnStack(){this.returnStack.length==0&&this.runtimeError("I tried to POP, but there wasn't a corresponding GOSUB."),this.returnStack.pop()}valueToString(t,r){var e;if(typeof t=="number"){var i=this.float2str(t,this.opts.printZoneLength-4);return r?i.startsWith("-")?`${i} `:` ${i} `:i}else if(t==` +import{b as S}from"./chunk-3FIVEUG2.js";import{y as E}from"./chunk-YP6JMRCE.js";import"./chunk-22ZJCPEG.js";import"./chunk-T6VURU5O.js";import"./chunk-A7SWO6EA.js";import"./chunk-F6OOEJJR.js";import"./chunk-ELRBFCEX.js";import{B as c,K as f,T as d,U as v,a as g}from"./chunk-TYDI7JZQ.js";import"./chunk-VSC4MAII.js";function k(u){return u.value!=null}function y(u){return u.name!=null}function O(u){return u.op!=null&&u.left!=null&&u.right!=null}function N(u){return u.op!=null&&u.expr!=null}var m=class{randomize(){this.seed(Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647)}constructor(){(()=>{var r,e,i,n;this.seed=function(s,a,h,o){r=s,e=a,i=h,n=o},this.seedfloat=function(s){this.seed(s,s*4294,s*429496,s*4294967296),this.next(),this.next(),this.next()},this.next=function(){r>>>=0,e>>>=0,i>>>=0,n>>>=0;var s=r+e|0;return r=e^e>>>9,e=i+(i<<3)|0,i=i<<21|i>>>11,n=n+1|0,s=s+n|0,i=i+s|0,(s>>>0)/4294967296}})(),this.seedfloat(-1)}},I=1024*1024,l=class u{constructor(){this.margin=80;this.running=!1;this.exited=!0;this.trace=!1}load(t){let r=null,e=0;if(this.pc2label!=null){let s=this.curpc;for(;s>0&&(r=this.pc2label.get(s))==null;)s--;e=this.curpc-s,console.log("oldpc=",this.curpc,"restart @ label",r,"+",e)}this.program=t,this.opts=t.opts,this.opts.maxArrayElements||(this.opts.maxArrayElements=I),this.allstmts=t.stmts,this.label2pc=t.labels,this.label2dataptr={},this.pc2label=new Map,this.datums=[],this.subroutines={},this.builtins=this.getBuiltinFunctions();for(var i in t.labels){var n=t.labels[i];this.pc2label.set(n,i)}return this.allstmts.forEach((s,a)=>{this.curpc=a+1,this.compileStatement(s),s.command=="DATA"&&(this.label2dataptr[s.$loc.label]=this.datums.length,s.datums.forEach(h=>{this.curpc=s.$loc.offset,this.datums.push(h)}))}),this.label2pc[r]!=null?(this.curpc=this.label2pc[r]+e,!0):(this.curpc=0,!1)}reset(){this.curpc=0,this.dataptr=0,this.clearVars(),this.returnStack=[],this.column=0,this.running=!0,this.exited=!1}clearVars(){this.globals=this.vars={},this.arrays={},this.defs={},this.forLoops={},this.forLoopStack=[],this.whileLoops=[],this.rng=new m,this.opts&&this.opts.staticArrays&&this.allstmts.filter(t=>t.command=="DIM").forEach(t=>{t.args.forEach(r=>this.compileJS(this._DIM(r))())})}saveState(){return $.extend(!0,{},this)}loadState(t){$.extend(!0,this,t)}getBuiltinFunctions(){var t=this.program&&this.opts.validFunctions;t||(t=Object.getOwnPropertyNames(u.prototype).filter(i=>/^[A-Z]{3,}[$]?$/.test(i)));var r={};for(var e of t)this.supportsFunction(e)&&(r[e]=this[e].bind(this));return r}supportsFunction(t){return typeof this[t]=="function"}runtimeError(t){throw this.curpc--,new d(t,this.getCurrentSourceLocation())}dialectError(t){this.runtimeError(`I can't ${t} in this dialect of BASIC.`)}getLineForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.line}getLabelForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.label}getCurrentSourceLocation(){var t=this.getStatement();return t&&t.$loc}getCurrentLabel(){var t=this.getCurrentSourceLocation();return t&&t.label}getStatement(){return this.allstmts[this.curpc]}step(){if(!this.running)return!1;var t=this.getStatement();return t?(this.trace&&console.log(this.curpc,t,this.vars,Object.keys(this.arrays)),this.curpc++,this.executeStatement(t),this.running):(this.running=!1,this.exited=!0,!1)}compileStatement(t){if(t.$run==null)try{var r=this["do__"+t.command];r==null&&this.runtimeError(`I don't know how to "${t.command}".`);var e=r.bind(this)(t);this.trace&&console.log(e),t.$run=this.compileJS(e)}catch(i){throw e&&console.log(e),i}}compileJS(t){return new Function(t).bind(this)}executeStatement(t){this.compileStatement(t),t.$run()}skipToEOL(){do this.curpc++;while(this.curpc=0?this.curpc=r:this.runtimeError(`I tried to go to the label "${t}" but couldn't find it.`)}newLocalScope(){this.vars=Object.create(this.vars)}popLocalScope(){this.vars!==this.globals&&(this.vars=Object.getPrototypeOf(this.vars))}gosubLabel(t){this.returnStack.length>32767&&this.runtimeError("I did too many GOSUBs without a RETURN."),this.returnStack.push(this.curpc),this.gotoLabel(t)}returnFromGosub(){this.returnStack.length==0&&this.runtimeError("I tried to RETURN, but there wasn't a corresponding GOSUB.");var t=this.returnStack.pop();this.curpc=t,this.popLocalScope()}popReturnStack(){this.returnStack.length==0&&this.runtimeError("I tried to POP, but there wasn't a corresponding GOSUB."),this.returnStack.pop()}valueToString(t,r){var e;if(typeof t=="number"){var i=this.float2str(t,this.opts.printZoneLength-4);return r?i.startsWith("-")?`${i} `:` ${i} `:i}else if(t==` `)this.column=0,e=t;else if(t==" "){var n=this.opts.printZoneLength,s=Math.floor(this.column/n),a=(s+1)*this.opts.printZoneLength;a+n>this.margin?(this.column=0,e=` `):e=this.TAB(a)}else e=`${t}`;return e}float2str(t,r){var e=t.toString().toUpperCase();if(r>0){for(var i=r;e.length>r;)e=t.toPrecision(i--);e.startsWith("0.")?e=e.substr(1):e.startsWith("-0.")&&(e="-"+e.substr(2))}return e}printExpr(t){var r=this.valueToString(t,this.opts.numericPadding);this.column+=r.length,this.print(r)}print(t){console.log(t)}async input(t,r){return{line:"",vals:[]}}resume(){}expr2js(t,r){if(r||(r={}),k(t))return JSON.stringify(t.value);if(y(t)){if(!t.args&&r.locals&&r.locals.indexOf(t.name)>=0)return t.name;{r.isconst&&this.runtimeError("I expected a constant value here.");var e="",i=JSON.stringify(t.name);let h=t.args?t.args.map(o=>this.expr2js(o,r)).join(", "):[];return t.name.startsWith("FN")?e+=`this.getDef(${i})(${h})`:this.builtins[t.name]?(this.checkFuncArgs(t,this.builtins[t.name]),e+=`this.builtins.${t.name}(${h})`):t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?e+=`this.getStringSlice(this.vars.${t.name}, ${h})`:e+=`this.arrayGet(${i}, ${h})`:e+=`this.vars.${t.name}`,r.novalid?e:`this.checkValue(${e}, ${i})`}}else if(O(t)){var n=this.expr2js(t.left,r),s=this.expr2js(t.right,r);return`this.${t.op}(${n}, ${s})`}else if(N(t)){var a=this.expr2js(t.expr,r);return`this.${t.op}(${a})`}}assign2js(t,r){r||(r={});var e="";return(t.name.startsWith("FN")||this.builtins[t.name])&&this.runtimeError("I can't call a function here."),t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?this.runtimeError("I can't set array slices via this command yet."):e+=this.array2js(t,r):e=`this.globals.${t.name}`,e}array2js(t,r){var e=JSON.stringify(t.name),i=t.args||[];return this.expr2js(t,{novalid:!0})+`;this.getArray(${e}, ${i.length})`+i.map(n=>"[this.ROUND("+this.expr2js(n,r)+")]").join("")}checkFuncArgs(t,r){var e=t.args?t.args.length:0;t.name=="RND"&&e==0||t.name=="MID$"&&e==2||t.name=="INSTR"&&e==2||r.length!=e&&this.runtimeError(`I expected ${r.length} arguments for the ${t.name} function, but I got ${e}.`)}startForLoop(t,r,e,i,n){var s=this.curpc-1,a=this.pc2label.get(s);i||(i=1),this.vars[t]=r,this.trace&&console.log(`FOR ${t} = ${r} TO ${e} STEP ${i}`);var h=()=>i>=0?this.vars[t]>e:this.vars[t]o==t)),this.forLoopStack.push(t),this.forLoops[t]={$next:o=>{o&&t!=o&&this.runtimeError(`I executed NEXT "${o}", but the last FOR was for "${t}".`),this.vars[t]+=i;var b=h();b?(this.forLoopStack.pop(),delete this.forLoops[t]):this.curpc=(a!=null&&this.label2pc[a]||s)+1,this.trace&&console.log(`NEXT ${t}: ${this.vars[t]} TO ${e} STEP ${i} DONE=${b}`)}}}nextForLoop(t){var r=this.forLoops[t||this.opts.optionalNextVar&&this.forLoopStack[this.forLoopStack.length-1]];r||this.runtimeError("I couldn't find a matching FOR for this NEXT."),r.$next(t)}whileLoop(t){t?this.whileLoops.push(this.curpc-1):this.skipToAfterWend()}nextWhileLoop(){var t=this.whileLoops.pop();t==null?this.runtimeError("I couldn't find a matching WHILE for this WEND."):this.curpc=t}assign(t,r,e){return e&&t.endsWith("$")?this.checkValue(this.convert(t,r),t):t.endsWith("$")?this.convertToString(r,t):this.convertToNumber(r,t)}convert(t,r){return t.endsWith("$")?r==null?"":r.toString():typeof r=="number"?r:parseFloat(r+"")}convertToString(t,r){if(typeof t!="string")this.runtimeError(`I can't convert ${t} to a string.`);else return t}convertToNumber(t,r){if(typeof t!="number")this.runtimeError(`I can't convert ${t} to a number.`);else return this.checkNum(t)}dimArray(t,...r){if(r=r.map(Math.round),this.arrays[t]!=null){if(this.opts.staticArrays)return;this.runtimeError(`I already dimensioned this array (${t}) earlier.`)}var e=this.getTotalArrayLength(r);e>this.opts.maxArrayElements&&this.runtimeError("I can't create an array with this many elements.");var i=t.endsWith("$"),n=i?Array:Float64Array;if(r.length==1)this.arrays[t]=new n(r[0]+1);else if(r.length==2){this.arrays[t]=new Array(r[0]+1);for(var s=0;s=i.length&&this.runtimeError(`I tried to lookup ${t}(${r}) but it exceeded the dimensions of the array.`),i=i[r[n]]}return c(i)&&this.runtimeError(`I tried to lookup ${t}(${r}) but used too few dimensions.`),i}modifyStringSlice(t,r,e,i){return t=t||"",this.checkString(t),this.checkString(r),i||(i=e),e=this.ROUND(e),i=this.ROUND(i),e<1&&this.dialectError("accept a string slice index less than 1"),ir.length)&&this.runtimeError(`I needed a number between 1 and ${r.length}, but I got ${t}.`),t<1||t>r.length?0:t}onGotoLabel(t,...r){t=this.checkOnGoto(t,r),t&&this.gotoLabel(r[t-1])}onGosubLabel(t,...r){t=this.checkOnGoto(t,r),t&&this.gosubLabel(r[t-1])}nextDatum(){return this.dataptr>=this.datums.length&&this.runtimeError("I tried to READ, but ran out of data."),this.datums[this.dataptr++].value}do__PRINT(t){var r="";for(var e of t.args){var i=this.expr2js(e),n=i.name;r+=`this.printExpr(this.checkValue(${i}, ${JSON.stringify(n)}));`}return r}preInput(){this.running=!1,this.curpc--}postInput(t){t&&this.curpc++,this.running=!0,this.resume()}do__INPUT(t){var r=t.prompt!=null?this.expr2js(t.prompt):'""',e=t.elapsed!=null?this.assign2js(t.elapsed):"let ___",i="";return t.args.forEach((n,s)=>{var a=this.assign2js(n);i+=` var value = this.convert(${JSON.stringify(n.name)}, response.vals[${s}]); @@ -34,4 +34,4 @@ import{b as S}from"./chunk-3FIVEUG2.js";import{y as E}from"./chunk-42RNKHZX.js"; `),this.tty.addtext("*** END OF PROGRAM ***",1),this.tty.showPrintHead(!1)}loadROM(t,r){var e=this.runtime.exited;this.program=r;var i=this.runtime.load(r);this.tty.uppercaseOnly=!0,(!this.hotReload||e||!i)&&this.reset()}getROMExtension(){return".json"}reset(){this.tty.clear(),this.runtime.reset(),this.clock=0,this.transcript=[]}pause(){this.timer.stop()}resume(){this.isBlocked()||(this.animcount=0,this.timer.start())}isBlocked(){return this.tty.waitingfor!=null||this.runtime.exited}isRunning(){return this.timer.isRunning()}getDefaultExtensions(){return[".bas"]}getToolForFilename(){return"basic"}getPresets(){return L}getPC(){return this.runtime.curpc}getSP(){return 4096-this.runtime.returnStack.length}isStable(){return!0}getCPUState(){return{PC:this.getPC(),SP:this.getSP()}}saveState(){return{c:this.getCPUState(),rt:this.runtime.saveState()}}loadState(t){this.runtime.loadState(t)}getDebugTree(){return{CurrentLine:this.runtime.getCurrentLabel(),Variables:this.runtime.vars,Arrays:this.runtime.arrays,Functions:this.runtime.defs,ForLoops:this.runtime.forLoops,WhileLoops:this.runtime.whileLoops,ReturnStack:this.runtime.returnStack,NextDatum:this.runtime.datums[this.runtime.dataptr],Clock:this.clock,Options:this.runtime.opts,Internals:this.runtime}}inspect(t){let r=this.runtime.vars[t];if(r!=null)return`${t} = ${r}`}showHelp(){return"https://8bitworkshop.com/docs/platforms/basic/"}getDebugCategories(){return["Variables"]}getDebugInfo(t,r){if(t==="Variables")return this.varsToLongString()}varsToLongString(){var t="",r=Object.keys(this.runtime.vars);r.sort();for(var e of r){var i=this.runtime.vars[e],n=JSON.stringify(i);n.length>24&&(n=`${n.substr(0,24)}...(${n.length})`),t+=g(e,3)+" = "+n+` `}return t}setupDebug(t){this.onBreakpointHit=t}clearDebug(){this.onBreakpointHit=null,this.debugTrap=null}checkDebugTrap(){return this.debugTrap&&this.debugTrap()?(this.pause(),this.break(),!0):!1}break(){this.onBreakpointHit&&this.onBreakpointHit(this.saveState())}step(){var t=this.clock;this.debugTrap=()=>this.clock>t,this.resume()}stepOver(){var t=this.runtime.getStatement();if(t&&(t.command=="GOSUB"||t.command=="ONGOSUB")){var r=this.getPC()+1;this.runEval(()=>this.getPC()==r)}else this.step()}hasCustomStepOver(){return!0}runUntilReturn(){var t=this.getSP();this.runEval(()=>this.getSP()>t)}runEval(t){this.debugTrap=()=>t(this.getCPUState()),this.resume()}restartAtPC(t){return t=Math.round(t),t>=0&&t{(function(e,n){typeof Fe=="object"&&typeof Ue!="undefined"?Ue.exports=n():typeof define=="function"&&define.amd?define(n):(e=typeof globalThis!="undefined"?globalThis:e||self,e.Split=n())})(Fe,(function(){"use strict";var e=typeof window!="undefined"?window:null,n=e===null,i=n?void 0:e.document,o="addEventListener",c="removeEventListener",p="getBoundingClientRect",S="_a",O="_b",v="_c",k="horizontal",G=function(){return!1},Z=n?"calc":["","-webkit-","-moz-","-o-"].filter(function(A){var y=i.createElement("div");return y.style.cssText="width:"+A+"calc(9px)",!!y.style.length}).shift()+"calc",F=function(A){return typeof A=="string"||A instanceof String},ut=function(A){if(F(A)){var y=i.querySelector(A);if(!y)throw new Error("Selector "+A+" did not match a DOM element");return y}return A},I=function(A,y,_){var L=A[y];return L!==void 0?L:_},Tt=function(A,y,_,L){if(y){if(L==="end")return 0;if(L==="center")return A/2}else if(_){if(L==="start")return 0;if(L==="center")return A/2}return A},Te=function(A,y){var _=i.createElement("div");return _.className="gutter gutter-"+y,_},pt=function(A,y,_){var L={};return F(y)?L[A]=y:L[A]=Z+"("+y+"% - "+_+"px)",L},mt=function(A,y){var _;return _={},_[A]=y+"px",_},ee=function(A,y){if(y===void 0&&(y={}),n)return{};var _=A,L,ot,_t,H,nt,D;Array.from&&(_=Array.from(_));var ne=ut(_[0]),rt=ne.parentNode,Ht=getComputedStyle?getComputedStyle(rt):null,ft=Ht?Ht.flexDirection:null,Bt=I(y,"sizes")||_.map(function(){return 100/_.length}),Gt=I(y,"minSize",100),ht=Array.isArray(Gt)?Gt:_.map(function(){return Gt}),Et=I(y,"maxSize",1/0),re=Array.isArray(Et)?Et:_.map(function(){return Et}),_e=I(y,"expandToMin",!1),bt=I(y,"gutterSize",10),Ct=I(y,"gutterAlign","center"),b=I(y,"snapOffset",30),Ee=Array.isArray(b)?b:_.map(function(){return b}),Wt=I(y,"dragInterval",1),gt=I(y,"direction",k),Kt=I(y,"cursor",gt===k?"col-resize":"row-resize"),be=I(y,"gutter",Te),ie=I(y,"elementStyle",pt),oe=I(y,"gutterStyle",mt);gt===k?(L="width",ot="clientX",_t="left",H="right",nt="clientWidth"):gt==="vertical"&&(L="height",ot="clientY",_t="top",H="bottom",nt="clientHeight");function vt(d,a,u,h){var x=ie(L,a,u,h);Object.keys(x).forEach(function(M){d.style[M]=x[M]})}function se(d,a,u){var h=oe(L,a,u);Object.keys(h).forEach(function(x){d.style[x]=h[x]})}function E(){return D.map(function(d){return d.size})}function Dt(d){return"touches"in d?d.touches[0][ot]:d[ot]}function w(d){var a=D[this.a],u=D[this.b],h=a.size+u.size;a.size=d/this.size*h,u.size=h-d/this.size*h,vt(a.element,a.size,this[O],a.i),vt(u.element,u.size,this[v],u.i)}function jt(d){var a,u=D[this.a],h=D[this.b];this.dragging&&(a=Dt(d)-this.start+(this[O]-this.dragOffset),Wt>1&&(a=Math.round(a/Wt)*Wt),a<=u.minSize+u.snapOffset+this[O]?a=u.minSize+this[O]:a>=this.size-(h.minSize+h.snapOffset+this[v])&&(a=this.size-(h.minSize+this[v])),a>=u.maxSize-u.snapOffset+this[O]?a=u.maxSize+this[O]:a<=this.size-(h.maxSize-h.snapOffset+this[v])&&(a=this.size-(h.maxSize+this[v])),w.call(this,a),I(y,"onDrag",G)(E()))}function q(){var d=D[this.a].element,a=D[this.b].element,u=d[p](),h=a[p]();this.size=u[L]+h[L]+this[O]+this[v],this.start=u[_t],this.end=u[H]}function At(d){if(!getComputedStyle)return null;var a=getComputedStyle(d);if(!a)return null;var u=d[nt];return u===0?null:(gt===k?u-=parseFloat(a.paddingLeft)+parseFloat(a.paddingRight):u-=parseFloat(a.paddingTop)+parseFloat(a.paddingBottom),u)}function Yt(d){var a=At(rt);if(a===null||ht.reduce(function(M,z){return M+z},0)>a)return d;var u=0,h=[],x=d.map(function(M,z){var tt=a*M/100,dt=Tt(bt,z===0,z===d.length-1,Ct),wt=ht[z]+dt;return tt0&&h[z]-u>0){var dt=Math.min(u,h[z]-u);u-=dt,tt=M-dt}return tt/a*100})}function st(){var d=this,a=D[d.a].element,u=D[d.b].element;d.dragging&&I(y,"onDragEnd",G)(E()),d.dragging=!1,e[c]("mouseup",d.stop),e[c]("touchend",d.stop),e[c]("touchcancel",d.stop),e[c]("mousemove",d.move),e[c]("touchmove",d.move),d.stop=null,d.move=null,a[c]("selectstart",G),a[c]("dragstart",G),u[c]("selectstart",G),u[c]("dragstart",G),a.style.userSelect="",a.style.webkitUserSelect="",a.style.MozUserSelect="",a.style.pointerEvents="",u.style.userSelect="",u.style.webkitUserSelect="",u.style.MozUserSelect="",u.style.pointerEvents="",d.gutter.style.cursor="",d.parent.style.cursor="",i.body.style.cursor=""}function ae(d){if(!("button"in d&&d.button!==0)){var a=this,u=D[a.a].element,h=D[a.b].element;a.dragging||I(y,"onDragStart",G)(E()),d.preventDefault(),a.dragging=!0,a.move=jt.bind(a),a.stop=st.bind(a),e[o]("mouseup",a.stop),e[o]("touchend",a.stop),e[o]("touchcancel",a.stop),e[o]("mousemove",a.move),e[o]("touchmove",a.move),u[o]("selectstart",G),u[o]("dragstart",G),h[o]("selectstart",G),h[o]("dragstart",G),u.style.userSelect="none",u.style.webkitUserSelect="none",u.style.MozUserSelect="none",u.style.pointerEvents="none",h.style.userSelect="none",h.style.webkitUserSelect="none",h.style.MozUserSelect="none",h.style.pointerEvents="none",a.gutter.style.cursor=Kt,a.parent.style.cursor=Kt,i.body.style.cursor=Kt,q.call(a),a.dragOffset=Dt(d)-a.end}}Bt=Yt(Bt);var it=[];D=_.map(function(d,a){var u={element:ut(d),size:Bt[a],minSize:ht[a],maxSize:re[a],snapOffset:Ee[a],i:a},h;if(a>0&&(h={a:a-1,b:a,dragging:!1,direction:gt,parent:rt},h[O]=Tt(bt,a-1===0,!1,Ct),h[v]=Tt(bt,!1,a===_.length-1,Ct),ft==="row-reverse"||ft==="column-reverse")){var x=h.a;h.a=h.b,h.b=x}if(a>0){var M=be(a,gt,u.element);se(M,bt,a),h[S]=ae.bind(h),M[o]("mousedown",h[S]),M[o]("touchstart",h[S]),rt.insertBefore(M,u.element),h.gutter=M}return vt(u.element,u.size,Tt(bt,a===0,a===_.length-1,Ct),a),a>0&&it.push(h),u});function $t(d){var a=d.i===it.length,u=a?it[d.i-1]:it[d.i];q.call(u);var h=a?u.size-d.minSize-u[v]:d.minSize+u[O];w.call(u,h)}D.forEach(function(d){var a=d.element[p]()[L];a0){var x=it[h-1],M=D[x.a],z=D[x.b];M.size=a[h-1],z.size=u,vt(M.element,M.size,x[O],M.i),vt(z.element,z.size,x[v],z.i)}})}function at(d,a){it.forEach(function(u){if(a!==!0?u.parent.removeChild(u.gutter):(u.gutter[c]("mousedown",u[S]),u.gutter[c]("touchstart",u[S])),d!==!0){var h=ie(L,u.a.size,u[O]);Object.keys(h).forEach(function(x){D[u.a].element.style[x]="",D[u.b].element.style[x]=""})}})}return{setSizes:le,getSizes:E,collapse:function(a){$t(D[a])},destroy:at,parent:rt,pairs:it}};return ee}))});var lr={left:"arrowleft",right:"arrowright",up:"arrowup",down:"arrowdown"},Ie=null;function Pt(){if(Ie===null){var e=typeof navigator!="undefined"?navigator:null;Ie=!!e&&/mac|iphone|ipad|ipod/i.test(e.platform||e.userAgent||"")}return Ie}function ke(e){var n=e.toLowerCase().split("+"),i=n.pop(),o={mod:!1,shift:!1,key:""};for(var c of n)if(c=="mod"||c=="ctrl"||c=="meta"||c=="cmd")o.mod=!0;else if(c=="shift")o.shift=!0;else return console.warn('Keyboard shortcut "'+e+'": unsupported modifier "'+c+'" (alt is layout-dependent), skipping'),null;i=lr[i]||i;var p=/^[a-z]$/.test(i),S=/^f([1-9]|1[0-2])$/.test(i);return!p&&!S&&!/^[0-9]$/.test(i)&&!/^arrow/.test(i)?(console.warn('Keyboard shortcut "'+e+'": key "'+i+'" is layout-dependent (use a-z, 0-9, f1-f12), skipping'),null):o.shift&&!p&&!/^arrow/.test(i)?(console.warn('Keyboard shortcut "'+e+'": shift is only allowed with letters and arrows, skipping'),null):(o.key=i,o)}function cr(e,n){if(n.altKey)return!1;var i=Pt(),o=i?n.metaKey:n.ctrlKey,c=i?n.ctrlKey:n.metaKey;return e.mod!==o||c||e.shift!==n.shiftKey?!1:(n.key||"").toLowerCase()===e.key}var ye=class{constructor(){this.bindings=[];this.handler=n=>{if(!n.defaultPrevented)for(var i=0;in.indexOf(k)>=0);for(var S of n)p.indexOf(S)<0&&p.push(S);var O=p.map(k=>o?pr[k]||k:mr[k]||k).join(o?"":"+"),v=/^[a-z][0-9]?$/.test(i)?i.toUpperCase():hr[i]||(o?i:i.charAt(0).toUpperCase()+i.slice(1));return(O?O+(o?"":"+"):"")+v}var ze=class{constructor(n){this.shortcutsSig="";this.status={};this.visible=!0;this.pendingShortcuts=null;this.pendingStatus=!1;this.div=n,this.shortcutsZone=$(document.createElement("span")).addClass("shortcuts_zone"),this.statusZone=$(document.createElement("span")).addClass("status_zone"),$(n).append(this.shortcutsZone).append(this.statusZone)}setShortcuts(n){if(this.visible){var i=n.map(p=>p.key+""+p.label).join("");if(i!==this.shortcutsSig){if(Zt){this.pendingShortcuts=n;return}this.shortcutsSig=i,this.shortcutsZone.empty();for(var o of n){var c=$(document.createElement("span")).addClass("shortcut");c.append($(document.createElement("kbd")).text(Pe(o.key))),c.append(document.createTextNode(" "+o.label)),o.fn&&Tn(c,o.fn),this.shortcutsZone.append(c)}}}}setStatus(n,i){i?this.status[n]=i:delete this.status[n],this.renderStatus()}renderStatus(){if(this.visible){if(Zt){this.pendingStatus=!0;return}this.statusZone.empty();for(var n of Object.keys(this.status)){var i=this.status[n],o=$(document.createElement("span")).addClass("status_item");i.cls&&o.addClass(i.cls),i.title&&o.prop("title",i.title),o.text(i.text),i.fn&&Tn(o,i.fn),this.statusZone.append(o)}}}};function Tn(e,n){e.addClass("clickable"),e.mousedown(i=>i.preventDefault()),e.click(n)}var Zt=!1;function _n(){if(j){if(j.pendingShortcuts){var e=j.pendingShortcuts;j.pendingShortcuts=null,j.setShortcuts(e)}j.pendingStatus&&(j.pendingStatus=!1,j.renderStatus())}}function gr(){$(document).on("mousedown.shortcutbar",()=>{Zt=!0}),$(document).on("mouseup.shortcutbar",()=>{Zt=!1,_n()}),$(window).on("blur.shortcutbar",()=>{Zt=!1,_n()})}var j=null;function ai(e){j=new ze(e),gr()}var En=()=>[],bn=()=>[];function li(e){En=e}function ci(e){bn=e}function ui(e){$(document.body).toggleClass("statusbar-hidden",!e),j&&(j.visible=e,e&&(j.shortcutsSig="",j.renderStatus(),yr()))}function yr(){if(j){var e=[...En(),...bn()],n=document.activeElement;for(var i of vn)n&&i.div.contains(n)&&(e=e.concat(i.fn()));j.setShortcuts(e.filter(o=>!Sr(o.key)))}}var vn=[];function fi(e,n){vn.push({div:e,fn:n})}function Sr(e){var n=e.toLowerCase();return!Pt()&&(n=="mod+shift+i"||n=="mod+shift+j"||n=="mod+shift+k"||n=="ctrl+alt+t"||n=="ctrl+alt+l")}function Tr(){return ar()}function _r(e){if(e._8bwPatched)return e;var n=e.stopCallback;return e.stopCallback=function(i,o,c,p){return i&&(i.ctrlKey||i.altKey||i.metaKey)?i.getModifierState&&i.getModifierState("AltGraph")?n.call(this,i,o,c,p):!1:n.call(this,i,o,c,p)},e._8bwPatched=!0,e}var An=class{constructor(n,i){this.boundkeys=[];let o=_r(Tr());this.focusDiv=i,this.keybinder=new ye,this.keybinder.attach(),this.mousetrap=i?new o(i):o,this.span=$(document.createElement("span")).addClass("btn_toolbar"),n.appendChild(this.span[0]),this.newGroup()}destroy(){if(this.span&&(this.span.remove(),this.span=null),this.keybinder&&(this.keybinder.detach(),this.keybinder.unbindAll(),this.keybinder=null),this.mousetrap){for(var n of this.boundkeys)this.mousetrap.unbind(n);this.mousetrap=null}}newGroup(){return this.grp=$(document.createElement("span")).addClass("btn_group").appendTo(this.span).hide()}add(n,i,o,c){var p=null;return o&&(p=$(document.createElement("button")).addClass("btn"),o.startsWith("glyphicon")&&(o=''),p.html(o),p.prop("title",n?i+" ("+Pe(n)+")":i),p.click(c),this.grp.append(p).show()),n&&(!this.focusDiv&&ke(n)?this.keybinder.bind(n,c):(this.mousetrap.bind(n,(S,O)=>(c(S,O),!1)),this.boundkeys.push(n))),p}};function Rt(e){var n=e&&e.w+"px"||"100%",i=e&&e.h+"px"||"100%",o=this.itemHeight=e.itemHeight;this.items=e.items,this.generatorFn=e.generatorFn,this.totalRows=e.totalRows||e.items&&e.items.length;var c=Rt.createScroller(o*this.totalRows);this.container=Rt.createContainer(n,i),this.container.appendChild(c);var p=Math.ceil(e.h/o);this.cachedItemsLen=p*3,this._renderChunk(this.container,0);var S=this,O,v=p*o,k=0;this.rmNodeInterval=setInterval(function(){if(Date.now()-k>100)for(var Z=document.querySelectorAll('[data-rm="1"]'),F=0,ut=Z.length;Fv){var ut=Math.floor(F/o)-p;S._renderChunk(S.container,ut<0?0:ut),O=F}k=Date.now(),Z.preventDefault&&Z.preventDefault()}this.container.addEventListener("scroll",G)}Rt.prototype.createRow=function(e){var n;if(this.generatorFn)n=this.generatorFn(e);else if(this.items)if(typeof this.items[e]=="string"){var i=document.createTextNode(this.items[e]);n=document.createElement("div"),n.style.height=this.itemHeight+"px",n.appendChild(i)}else n=this.items[e];return n.classList.add("vrow"),n.setAttribute("data-index",""+e),n.style.position="absolute",n.style.top=e*this.itemHeight+"px",n};Rt.prototype._renderChunk=function(e,n){var i=n+this.cachedItemsLen;i>this.totalRows&&(i=this.totalRows);for(var o=document.createDocumentFragment(),c=n;ce.length)&&(n=e.length);for(var i=0,o=Array(n);i2?o-2:0),p=2;p1?i-1:0),c=1;c1?i-1:0),c=1;c2&&arguments[2]!==void 0?arguments[2]:te;if(On&&On(e,null),!Ut(n))return e;let o=n.length;for(;o--;){let c=n[o];if(typeof c=="string"){let p=i(c);p!==c&&(Rr(n)||(n[o]=p),c=p)}e[c]=!0}return e}function zr(e){for(let n=0;n/g),Wr=B(/\${[\w\W]*/g),Kr=B(/^data-[\-\w.\u00B7-\uFFFF]+$/),jr=B(/^aria-[\-\w]+$/),zn=B(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Yr=B(/^(?:\w+script|data):/i),$r=B(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Vr=B(/^html$/i),Xr=B(/^[a-z][.\w]*(-[.\w]+)+$/i),Pn=B(/<[/\w!]/g),Fn=B(/<[/\w]/g),Zr=B(/<\/no(script|embed|frames)/i),qr=B(/\/>/i),J={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,processingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},Gn=["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"],Jr=U(T({},Gn)),Qr=(function(){let e={};return Mt(Gn,n=>{e[n]=B(new RegExp("])","i"))}),U(e)})(),ti=function(){return typeof window=="undefined"?null:window},ei=function(n,i){if(typeof n!="object"||typeof n.createPolicy!="function")return null;let o=null,c="data-tt-policy-suffix";i&&i.hasAttribute(c)&&(o=i.getAttribute(c));let p="dompurify"+(o?"#"+o:"");try{return n.createPolicy(p,{createHTML(S){return S},createScriptURL(S){return S}})}catch(S){return console.warn("TrustedTypes policy "+p+" could not be created."),null}},Un=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},St=function(n,i,o,c){return X(n,i)&&Ut(n[i])?T(c.base?Q(c.base):{},n[i],c.transform):o},je=function(n,i,o){let c=X(n,i)?n[i]:void 0;return c&&typeof c=="object"?Q(c):o()};function Wn(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ti(),n=l=>Wn(l);if(n.version="3.4.15",n.removed=[],!e||!e.document||e.document.nodeType!==J.document||!e.Element)return n.isSupported=!1,n;let i=e.document,o=i,c=o.currentScript;e.DocumentFragment;let p=e.HTMLTemplateElement,S=e.Node,O=e.Element,v=e.NodeFilter,k=e.NamedNodeMap;k===void 0&&(e.NamedNodeMap||e.MozNamedAttrMap),e.HTMLFormElement;let G=e.DOMParser,Z=e.trustedTypes,F=O.prototype,ut=et(F,"cloneNode"),I=et(F,"remove"),Tt=et(F,"removeAttributeNode"),Te=et(F,"nextSibling"),pt=et(F,"childNodes"),mt=et(F,"parentNode"),ee=et(F,"shadowRoot"),A=et(F,"attributes"),y=S&&S.prototype?et(S.prototype,"nodeType"):null,_=S&&S.prototype?et(S.prototype,"nodeName"):null,L=S&&S.prototype?et(S.prototype,"ownerDocument"):null,ot=function(t){return y?y(t):t.nodeType},_t=function(t){return _?_(t):t.nodeName};if(typeof p=="function"){let l=i.createElement("template");l.content&&l.content.ownerDocument&&(i=l.content.ownerDocument)}let H,nt="",D,ne=!1,rt=0,Ht=function(){if(rt>0)throw Lt('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},ft=function(t){Ht(),rt++;try{return H.createHTML(t)}finally{rt--}},Bt=function(t){Ht(),rt++;try{return H.createScriptURL(t)}finally{rt--}},Gt=function(){return ne||(D=ei(Z,c),ne=!0),D},ht=i,Et=ht.implementation,re=ht.createNodeIterator,_e=ht.createDocumentFragment,bt=ht.getElementsByTagName,Ct=o.importNode,b=Un();n.isSupported=typeof Hn=="function"&&typeof mt=="function"&&Et&&Et.createHTMLDocument!==void 0;let Ee=Br,Wt=Gr,gt=Wr,Kt=Kr,be=jr,ie=Yr,oe=$r,vt=Xr,se=zn,E=null,Dt=T({},[...xn,...Be,...Ge,...We,...In]),w=null,jt=T({},[...Nn,...Ke,...kn,...Se]),q=Object.seal(Ft(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),At=null,Yt=null,st=Object.seal(Ft(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}})),ae=!0,it=!0,$t=!1,le=!0,at=!1,d=!0,a=!1,u=!1,h=null,x=null,M=!1,z=!1,tt=!1,dt=!1,wt=!0,Ve=!1,Xe="user-content-",ve=!0,Ae=!1,xt={},It=null,Ze=T({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]),qe=null,Je=T({},["audio","video","img","source","image","track"]),Qe=null,tn=T({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ce="http://www.w3.org/1998/Math/MathML",ue="http://www.w3.org/2000/svg",lt="http://www.w3.org/1999/xhtml",Nt=lt,we=!1,Oe=null,Kn=T({},[ce,ue,lt],He),en=U(["mi","mo","mn","ms","mtext"]),Re=T({},en),nn=U(["annotation-xml"]),Le=T({},nn),jn=T({},["title","style","font","a","script"]),Vt=null,Yn=["application/xhtml+xml","text/html"],$n="text/html",N=null,kt=null,Vn=i.createElement("form"),rn=function(t){return t instanceof RegExp||t instanceof Function},Me=function(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(kt&&kt===t)return;(!t||typeof t!="object")&&(t={}),t=Q(t),Vt=Yn.indexOf(t.PARSER_MEDIA_TYPE)===-1?$n:t.PARSER_MEDIA_TYPE,N=Vt==="application/xhtml+xml"?He:te,E=St(t,"ALLOWED_TAGS",Dt,{transform:N}),w=St(t,"ALLOWED_ATTR",jt,{transform:N}),Oe=St(t,"ALLOWED_NAMESPACES",Kn,{transform:He}),Qe=St(t,"ADD_URI_SAFE_ATTR",tn,{transform:N,base:tn}),qe=St(t,"ADD_DATA_URI_TAGS",Je,{transform:N,base:Je}),It=St(t,"FORBID_CONTENTS",Ze,{transform:N}),At=St(t,"FORBID_TAGS",Q({}),{transform:N}),Yt=St(t,"FORBID_ATTR",Q({}),{transform:N}),xt=X(t,"USE_PROFILES")?t.USE_PROFILES&&typeof t.USE_PROFILES=="object"?Q(t.USE_PROFILES):t.USE_PROFILES:!1,ae=t.ALLOW_ARIA_ATTR!==!1,it=t.ALLOW_DATA_ATTR!==!1,$t=t.ALLOW_UNKNOWN_PROTOCOLS||!1,le=t.ALLOW_SELF_CLOSE_IN_ATTR!==!1,at=t.SAFE_FOR_TEMPLATES||!1,d=t.SAFE_FOR_XML!==!1,a=t.WHOLE_DOCUMENT||!1,z=t.RETURN_DOM||!1,tt=t.RETURN_DOM_FRAGMENT||!1,dt=t.RETURN_TRUSTED_TYPE||!1,M=t.FORCE_BODY||!1,wt=t.SANITIZE_DOM!==!1,Ve=t.SANITIZE_NAMED_PROPS||!1,ve=t.KEEP_CONTENT!==!1,Ae=t.IN_PLACE||!1,se=Fr(t.ALLOWED_URI_REGEXP)?t.ALLOWED_URI_REGEXP:zn,Nt=typeof t.NAMESPACE=="string"?t.NAMESPACE:lt,Re=je(t,"MATHML_TEXT_INTEGRATION_POINTS",()=>T({},en)),Le=je(t,"HTML_INTEGRATION_POINTS",()=>T({},nn));let r=je(t,"CUSTOM_ELEMENT_HANDLING",()=>Ft(null));if(q=Ft(null),X(r,"tagNameCheck")&&rn(r.tagNameCheck)&&(q.tagNameCheck=r.tagNameCheck),X(r,"attributeNameCheck")&&rn(r.attributeNameCheck)&&(q.attributeNameCheck=r.attributeNameCheck),X(r,"allowCustomizedBuiltInElements")&&typeof r.allowCustomizedBuiltInElements=="boolean"&&(q.allowCustomizedBuiltInElements=r.allowCustomizedBuiltInElements),B(q),at&&(it=!1),tt&&(z=!0),xt&&(E=T({},In),w=Ft(null),xt.html===!0&&(T(E,xn),T(w,Nn)),xt.svg===!0&&(T(E,Be),T(w,Ke),T(w,Se)),xt.svgFilters===!0&&(T(E,Ge),T(w,Ke),T(w,Se)),xt.mathMl===!0&&(T(E,We),T(w,kn),T(w,Se))),st.tagCheck=null,st.attributeCheck=null,X(t,"ADD_TAGS")&&(typeof t.ADD_TAGS=="function"?st.tagCheck=t.ADD_TAGS:Ut(t.ADD_TAGS)&&(E===Dt&&(E=Q(E)),T(E,t.ADD_TAGS,N))),X(t,"ADD_ATTR")&&(typeof t.ADD_ATTR=="function"?st.attributeCheck=t.ADD_ATTR:Ut(t.ADD_ATTR)&&(w===jt&&(w=Q(w)),T(w,t.ADD_ATTR,N))),X(t,"ADD_FORBID_CONTENTS")&&Ut(t.ADD_FORBID_CONTENTS)&&(It===Ze&&(It=Q(It)),T(It,t.ADD_FORBID_CONTENTS,N)),ve&&(E["#text"]=!0),a&&T(E,["html","head","body"]),E.table&&(T(E,["tbody"]),delete At.tbody),t.TRUSTED_TYPES_POLICY){if(typeof t.TRUSTED_TYPES_POLICY.createHTML!="function")throw Lt('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof t.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Lt('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');let s=H;H=t.TRUSTED_TYPES_POLICY;try{nt=ft("")}catch(f){throw H=s,f}}else t.TRUSTED_TYPES_POLICY===null?(H=void 0,nt=""):(H===void 0&&(H=Gt()),H&&typeof nt=="string"&&(nt=ft("")));U&&U(t),kt=t},on=T({},[...Be,...Ge,...Ur]),sn=T({},[...We,...Hr]),Xn=function(t,r,s){return r.namespaceURI===lt?t==="svg":r.namespaceURI===ce?t==="svg"&&(s==="annotation-xml"||Re[s]):!!on[t]},Zn=function(t,r,s){return r.namespaceURI===lt?t==="math":r.namespaceURI===ue?t==="math"&&Le[s]:!!sn[t]},qn=function(t,r,s){return r.namespaceURI===ue&&!Le[s]||r.namespaceURI===ce&&!Re[s]?!1:!sn[t]&&(jn[t]||!on[t])},Jn=function(t){let r=mt(t);(!r||!r.tagName)&&(r={namespaceURI:Nt,tagName:"template"});let s=te(t.tagName),f=te(r.tagName);return Oe[t.namespaceURI]?t.namespaceURI===ue?Xn(s,r,f):t.namespaceURI===ce?Zn(s,r,f):t.namespaceURI===lt?qn(s,r,f):!!(Vt==="application/xhtml+xml"&&Oe[t.namespaceURI]):!1},yt=function(t){qt(n.removed,{element:t});try{mt(t).removeChild(t)}catch(r){if(I(t),!mt(t))throw Lt("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},an=function(t,r,s){try{Tt(t,r)}catch(f){try{t.removeAttribute(s)}catch(m){}}},fe=function(t){de(t);let r=pt(t);if(r){let f=[];Mt(r,m=>{qt(f,m)}),Mt(f,m=>{try{I(m)}catch(g){}})}let s=A(t);if(s)for(let f=s.length-1;f>=0;--f){let m=s[f],g=m&&m.name;typeof g=="string"&&an(t,m,g)}},Ot=function(t,r,s){if(!s)try{s=r.getAttributeNode(t)}catch(f){s=null}qt(n.removed,{attribute:s||null,from:r});try{s?Tt(r,s):r.removeAttribute(t)}catch(f){try{r.removeAttribute(t)}catch(m){}}if(t==="is")if(z||tt)try{yt(r)}catch(f){}else try{r.setAttribute(t,"")}catch(f){}},Qn=function(t){let r=A(t);if(r)for(let s=r.length-1;s>=0;--s){let f=r[s],m=f&&f.name;typeof m!="string"||w[N(m)]||an(t,f,m)}},de=function(t){let r=[t];for(;r.length>0;){let s=r.pop();ot(s)===J.element&&Qn(s);let m=pt(s);if(m)for(let g=m.length-1;g>=0;--g)r.push(m[g])}},ln=function(t,r){return d?t==="patchsrc"?!0:t==="for"&&r!=="label"&&r!=="output":!1},tr=function(t){if(!d)return;let r=[t];for(;r.length>0;){let s=r.pop(),f=ot(s);if(f===J.processingInstruction||f===J.comment&&W(Fn,s.data)){try{I(s)}catch(g){}continue}if(f===J.element){let g=s,R=N(_t(s));try{g.hasAttribute&&g.hasAttribute("patchsrc")&&g.removeAttribute("patchsrc"),g.hasAttribute&&g.hasAttribute("for")&&ln("for",R)&&g.removeAttribute("for")}catch(C){}}let m=pt(s);if(m)for(let g=m.length-1;g>=0;--g)r.push(m[g])}},cn=function(t){let r=null,s=null;if(M)t=""+t;else{let g=Ln(t,/^[\r\n\t ]+/);s=g&&g[0]}Vt==="application/xhtml+xml"&&Nt===lt&&(t=''+t+"");let f=H?ft(t):t;if(Nt===lt)try{r=new G().parseFromString(f,Vt)}catch(g){}if(!r||!r.documentElement){r=Et.createDocument(Nt,"template",null);try{r.documentElement.innerHTML=we?nt:f}catch(g){}}let m=r.body||r.documentElement;return t&&s&&m.insertBefore(i.createTextNode(s),m.childNodes[0]||null),Nt===lt?bt.call(r,a?"html":"body")[0]:a?r.documentElement:m},un=function(t){let r=L?L(t):t.ownerDocument;return re.call(r||t,t,v.SHOW_ELEMENT|v.SHOW_COMMENT|v.SHOW_TEXT|v.SHOW_PROCESSING_INSTRUCTION|v.SHOW_CDATA_SECTION,null)},pe=function(t){return t=Jt(t,Ee," "),t=Jt(t,Wt," "),t=Jt(t,gt," "),t},Ce=function(t){var r;t.normalize();let s=L?L(t):t.ownerDocument,f=re.call(s||t,t,v.SHOW_TEXT|v.SHOW_COMMENT|v.SHOW_CDATA_SECTION|v.SHOW_PROCESSING_INSTRUCTION,null),m=f.nextNode();for(;m;)m.data=pe(m.data),m=f.nextNode();let g=(r=t.querySelectorAll)===null||r===void 0?void 0:r.call(t,"template");g&&Mt(g,R=>{zt(R.content)&&Ce(R.content)})},me=function(t){let r=_?_(t):null;return typeof r!="string"||N(r)!=="form"?!1:typeof t.nodeName!="string"||typeof t.textContent!="string"||typeof t.removeChild!="function"||t.attributes!==A(t)||typeof t.removeAttribute!="function"||typeof t.removeAttributeNode!="function"||typeof t.getAttributeNode!="function"||typeof t.setAttribute!="function"||typeof t.namespaceURI!="string"||typeof t.insertBefore!="function"||typeof t.hasChildNodes!="function"||t.nodeType!==y(t)||t.childNodes!==pt(t)},zt=function(t){if(!y||typeof t!="object"||t===null)return!1;try{return y(t)===J.documentFragment}catch(r){return!1}},Xt=function(t){if(!y||typeof t!="object"||t===null)return!1;try{return typeof y(t)=="number"}catch(r){return!1}};function ct(l,t,r){l.length!==0&&Mt(l,s=>{s.call(n,t,r,kt)})}let er=function(t,r){return!!(d&&t.hasChildNodes()&&!Xt(t.firstElementChild)&&W(Pn,t.textContent)&&W(Pn,t.innerHTML)||d&&t.namespaceURI===lt&&Jr[r]&&(Xt(t.firstElementChild)||typeof t.textContent=="string"&&W(Qr[r],t.textContent))||t.nodeType===J.processingInstruction||d&&t.nodeType===J.comment&&W(Fn,t.data))},he=function(t,r){if(t instanceof RegExp)return W(t,r);if(t instanceof Function){for(var s=arguments.length,f=new Array(s>2?s-2:0),m=2;m=0;--R){let C=t===s?ut(m[R],!0):m[R];f.insertBefore(C,Te(t))}}}return yt(t),!0},fn=function(t,r,s,f){return t.length===0?r:r===s||r===f?Q(r):r},dn=function(t,r){return t===r||mt(t)!==null?!1:(Ae&&de(t),!0)},pn=function(t,r){if(ct(b.beforeSanitizeElements,t,null),dn(t,r))return!0;if(me(t))return yt(t),!0;let s=N(_t(t));if(E=fn(b.uponSanitizeElement,E,Dt,h),ct(b.uponSanitizeElement,t,{tagName:s,allowedTags:E}),dn(t,r))return!0;if(er(t,s))return yt(t),!0;if(At[s]||!(st.tagCheck instanceof Function&&st.tagCheck(s))&&!E[s]){let m=nr(t,s,r);return m===!1&&ct(b.afterSanitizeElements,t,null),m}if(ot(t)===J.element&&!Jn(t)||(s==="noscript"||s==="noembed"||s==="noframes")&&W(Zr,t.innerHTML))return yt(t),!0;if(at&&t.nodeType===J.text){let m=pe(t.textContent);t.textContent!==m&&(qt(n.removed,{element:t.cloneNode()}),t.textContent=m)}return ct(b.afterSanitizeElements,t,null),!1},mn=function(t,r,s){if(Yt[r]||ln(r,t)||wt&&(r==="id"||r==="name")&&(s in i||s in Vn))return!1;let f=w[r]||st.attributeCheck instanceof Function&&st.attributeCheck(r,t);return it&&W(Kt,r)||ae&&W(be,r)?!0:f?Qe[r]||W(se,Jt(s,oe,""))||(r==="src"||r==="xlink:href"||r==="href")&&t!=="script"&&Mn(s,"data:")===0&&qe[t]||$t&&!W(ie,Jt(s,oe,""))?!0:!s:hn(t)&&he(q.tagNameCheck,t)&&he(q.attributeNameCheck,r,t)||r==="is"&&q.allowCustomizedBuiltInElements&&he(q.tagNameCheck,s)},rr=T({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),hn=function(t){return!rr[te(t)]&&W(vt,t)},ir=function(t,r,s,f){if(H&&typeof Z=="object"&&typeof Z.getAttributeType=="function"&&!s)switch(Z.getAttributeType(t,r)){case"TrustedHTML":return ft(f);case"TrustedScriptURL":return Bt(f)}return f},or=function(t,r,s,f){try{return s?t.setAttributeNS(s,r,f):t.setAttribute(r,f),me(t)?(yt(t),!1):!0}catch(m){return Ot(r,t),!1}},gn=function(t){ct(b.beforeSanitizeAttributes,t,null);let r=t.attributes;if(!r||me(t))return;w=fn(b.uponSanitizeAttribute,w,jt,x);let s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:w,forceKeepAttr:void 0},f=r.length,m=N(t.nodeName);for(;f--;){let g=r[f],R=g.name,C=g.namespaceURI,Y=g.value,V=N(R),xe=Y,K=R==="value"?xe:xr(xe),yn=!1;if(s.attrName=V,s.attrValue=K,s.keepAttr=!0,s.forceKeepAttr=void 0,ct(b.uponSanitizeAttribute,t,s),K=s.attrValue,Ve&&(V==="id"||V==="name")&&Mn(K,Xe)!==0&&(Ot(R,t,g),K=Xe+K,yn=!0),d&&W(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,K)){Ot(R,t,g);continue}if(V==="attributename"&&Ln(K,"href")){Ot(R,t,g);continue}if(!s.forceKeepAttr){if(!s.keepAttr){Ot(R,t,g);continue}if(!le&&W(qr,K)){Ot(R,t,g);continue}if(at&&(K=pe(K)),!mn(m,V,K)){Ot(R,t,g);continue}K=ir(m,V,C,K),K!==xe&&or(t,R,C,K)&&yn&&Rn(n.removed)}}ct(b.afterSanitizeAttributes,t,null)},ge=function(t){let r=null,s=un(t);for(ct(b.beforeSanitizeShadowDOM,t,null);r=s.nextNode();)if(ct(b.uponSanitizeShadowNode,r,null),pn(r,t),gn(r),zt(r.content)&&ge(r.content),ot(r)===J.element){let f=ee(r);zt(f)&&(De(f),ge(f))}ct(b.afterSanitizeShadowDOM,t,null)},De=function(t){let r=[{node:t,shadow:null}];for(;r.length>0;){let s=r.pop();if(s.shadow){ge(s.shadow);continue}let f=s.node,g=ot(f)===J.element,R=pt(f);if(R)for(let C=R.length-1;C>=0;--C)r.push({node:R[C],shadow:null});if(g){let C=_?_(f):null;if(typeof C=="string"&&N(C)==="template"){let Y=f.content;zt(Y)&&r.push({node:Y,shadow:null})}}if(g){let C=ee(f);zt(C)&&r.push({node:null,shadow:C},{node:C,shadow:null})}}};return n.sanitize=function(l){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=null,s=null,f=null,m=null;if(we=!l,we&&(l=""),typeof l!="string"&&!Xt(l)&&(l=Pr(l),typeof l!="string"))throw Lt("dirty is not a string, aborting");if(!n.isSupported)return l;u?(E=h,w=x):Me(t),(b.uponSanitizeElement.length>0||b.uponSanitizeAttribute.length>0)&&(E=Q(E)),b.uponSanitizeAttribute.length>0&&(w=Q(w)),n.removed=[];let g=Ae&&typeof l!="string"&&Xt(l);if(g){tr(l);let Y=_t(l);if(typeof Y=="string"){let V=N(Y);if(!E[V]||At[V])throw fe(l),Lt("root node is forbidden and cannot be sanitized in-place")}if(me(l))throw fe(l),Lt("root node is clobbered and cannot be sanitized in-place");try{De(l)}catch(V){throw fe(l),V}}else if(Xt(l))r=cn(""),s=r.ownerDocument.importNode(l,!0),s.nodeType===J.element&&s.nodeName==="BODY"||s.nodeName==="HTML"?r=s:r.appendChild(s),De(r);else{if(!z&&!at&&!a&&l.indexOf("<")===-1)return H&&dt?ft(l):l;if(r=cn(l),!r)return z?null:dt?nt:""}r&&M&&yt(r.firstChild);let R=g?l:r;try{let Y=un(R);for(;f=Y.nextNode();)pn(f,R),gn(f),zt(f.content)&&ge(f.content)}catch(Y){throw g&&(fe(l),Mt(n.removed,V=>{V.element&&de(V.element)})),Y}if(g)return Mt(n.removed,Y=>{Y.element&&de(Y.element)}),at&&Ce(l),l;if(z){if(at&&Ce(r),tt)for(m=_e.call(r.ownerDocument);r.firstChild;)m.appendChild(r.firstChild);else m=r;return(w.shadowroot||w.shadowrootmode)&&(m=Ct.call(o,m,!0)),m}let C=a?r.outerHTML:r.innerHTML;return a&&E["!doctype"]&&r.ownerDocument&&r.ownerDocument.doctype&&r.ownerDocument.doctype.name&&W(Vr,r.ownerDocument.doctype.name)&&(C=" +`+C),at&&(C=pe(C)),H&&dt?ft(C):C},n.setConfig=function(){let l=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Me(l),u=!0,h=E,x=w},n.clearConfig=function(){kt=null,u=!1,h=null,x=null,H=D,nt=""},n.isValidAttribute=function(l,t,r){kt||Me({});let s=N(l),f=N(t);return mn(s,f,r)},n.addHook=function(l,t){typeof t=="function"&&X(b,l)&&qt(b[l],t)},n.removeHook=function(l,t){if(X(b,l)){if(t!==void 0){let r=Cr(b[l],t);return r===-1?void 0:Dr(b[l],r,1)[0]}return Rn(b[l])}},n.removeHooks=function(l){X(b,l)&&(b[l]=[])},n.removeAllHooks=function(){b=Un()},n}var yi=Wn();export{ri as a,ii as b,ai as c,li as d,ci as e,ui as f,yr as g,fi as h,An as i,Rt as j,yi as k,Er as l}; +/*! Bundled license information: + +split.js/dist/split.js: + (*! Split.js - v1.6.5 *) + +dompurify/dist/purify.es.mjs: + (*! @license DOMPurify 3.4.15 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.15/LICENSE *) +*/ +//# sourceMappingURL=chunk-22ZJCPEG.js.map diff --git a/gen/chunk-22ZJCPEG.js.map b/gen/chunk-22ZJCPEG.js.map new file mode 100644 index 00000000..efe05ce3 --- /dev/null +++ b/gen/chunk-22ZJCPEG.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../node_modules/split.js/dist/split.js", "../src/ide/keys.ts", "../src/ide/shortcutbar.ts", "../src/ide/toolbar.ts", "../src/common/vlist.ts", "../node_modules/dompurify/src/utils.ts", "../node_modules/dompurify/src/tags.ts", "../node_modules/dompurify/src/attrs.ts", "../node_modules/dompurify/src/regexp.ts", "../node_modules/dompurify/src/purify.ts"], + "sourcesContent": ["/*! Split.js - v1.6.5 */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Split = factory());\n}(this, (function () { 'use strict';\n\n // The programming goals of Split.js are to deliver readable, understandable and\n // maintainable code, while at the same time manually optimizing for tiny minified file size,\n // browser compatibility without additional requirements\n // and very few assumptions about the user's page layout.\n var global = typeof window !== 'undefined' ? window : null;\n var ssr = global === null;\n var document = !ssr ? global.document : undefined;\n\n // Save a couple long function names that are used frequently.\n // This optimization saves around 400 bytes.\n var addEventListener = 'addEventListener';\n var removeEventListener = 'removeEventListener';\n var getBoundingClientRect = 'getBoundingClientRect';\n var gutterStartDragging = '_a';\n var aGutterSize = '_b';\n var bGutterSize = '_c';\n var HORIZONTAL = 'horizontal';\n var NOOP = function () { return false; };\n\n // Helper function determines which prefixes of CSS calc we need.\n // We only need to do this once on startup, when this anonymous function is called.\n //\n // Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:\n // http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167\n var calc = ssr\n ? 'calc'\n : ((['', '-webkit-', '-moz-', '-o-']\n .filter(function (prefix) {\n var el = document.createElement('div');\n el.style.cssText = \"width:\" + prefix + \"calc(9px)\";\n\n return !!el.style.length\n })\n .shift()) + \"calc\");\n\n // Helper function checks if its argument is a string-like type\n var isString = function (v) { return typeof v === 'string' || v instanceof String; };\n\n // Helper function allows elements and string selectors to be used\n // interchangeably. In either case an element is returned. This allows us to\n // do `Split([elem1, elem2])` as well as `Split(['#id1', '#id2'])`.\n var elementOrSelector = function (el) {\n if (isString(el)) {\n var ele = document.querySelector(el);\n if (!ele) {\n throw new Error((\"Selector \" + el + \" did not match a DOM element\"))\n }\n return ele\n }\n\n return el\n };\n\n // Helper function gets a property from the properties object, with a default fallback\n var getOption = function (options, propName, def) {\n var value = options[propName];\n if (value !== undefined) {\n return value\n }\n return def\n };\n\n var getGutterSize = function (gutterSize, isFirst, isLast, gutterAlign) {\n if (isFirst) {\n if (gutterAlign === 'end') {\n return 0\n }\n if (gutterAlign === 'center') {\n return gutterSize / 2\n }\n } else if (isLast) {\n if (gutterAlign === 'start') {\n return 0\n }\n if (gutterAlign === 'center') {\n return gutterSize / 2\n }\n }\n\n return gutterSize\n };\n\n // Default options\n var defaultGutterFn = function (i, gutterDirection) {\n var gut = document.createElement('div');\n gut.className = \"gutter gutter-\" + gutterDirection;\n return gut\n };\n\n var defaultElementStyleFn = function (dim, size, gutSize) {\n var style = {};\n\n if (!isString(size)) {\n style[dim] = calc + \"(\" + size + \"% - \" + gutSize + \"px)\";\n } else {\n style[dim] = size;\n }\n\n return style\n };\n\n var defaultGutterStyleFn = function (dim, gutSize) {\n var obj;\n\n return (( obj = {}, obj[dim] = (gutSize + \"px\"), obj ));\n };\n\n // The main function to initialize a split. Split.js thinks about each pair\n // of elements as an independant pair. Dragging the gutter between two elements\n // only changes the dimensions of elements in that pair. This is key to understanding\n // how the following functions operate, since each function is bound to a pair.\n //\n // A pair object is shaped like this:\n //\n // {\n // a: DOM element,\n // b: DOM element,\n // aMin: Number,\n // bMin: Number,\n // dragging: Boolean,\n // parent: DOM element,\n // direction: 'horizontal' | 'vertical'\n // }\n //\n // The basic sequence:\n //\n // 1. Set defaults to something sane. `options` doesn't have to be passed at all.\n // 2. Initialize a bunch of strings based on the direction we're splitting.\n // A lot of the behavior in the rest of the library is paramatized down to\n // rely on CSS strings and classes.\n // 3. Define the dragging helper functions, and a few helpers to go with them.\n // 4. Loop through the elements while pairing them off. Every pair gets an\n // `pair` object and a gutter.\n // 5. Actually size the pair elements, insert gutters and attach event listeners.\n var Split = function (idsOption, options) {\n if ( options === void 0 ) options = {};\n\n if (ssr) { return {} }\n\n var ids = idsOption;\n var dimension;\n var clientAxis;\n var position;\n var positionEnd;\n var clientSize;\n var elements;\n\n // Allow HTMLCollection to be used as an argument when supported\n if (Array.from) {\n ids = Array.from(ids);\n }\n\n // All DOM elements in the split should have a common parent. We can grab\n // the first elements parent and hope users read the docs because the\n // behavior will be whacky otherwise.\n var firstElement = elementOrSelector(ids[0]);\n var parent = firstElement.parentNode;\n var parentStyle = getComputedStyle ? getComputedStyle(parent) : null;\n var parentFlexDirection = parentStyle ? parentStyle.flexDirection : null;\n\n // Set default options.sizes to equal percentages of the parent element.\n var sizes = getOption(options, 'sizes') || ids.map(function () { return 100 / ids.length; });\n\n // Standardize minSize and maxSize to an array if it isn't already.\n // This allows minSize and maxSize to be passed as a number.\n var minSize = getOption(options, 'minSize', 100);\n var minSizes = Array.isArray(minSize) ? minSize : ids.map(function () { return minSize; });\n var maxSize = getOption(options, 'maxSize', Infinity);\n var maxSizes = Array.isArray(maxSize) ? maxSize : ids.map(function () { return maxSize; });\n\n // Get other options\n var expandToMin = getOption(options, 'expandToMin', false);\n var gutterSize = getOption(options, 'gutterSize', 10);\n var gutterAlign = getOption(options, 'gutterAlign', 'center');\n var snapOffset = getOption(options, 'snapOffset', 30);\n var snapOffsets = Array.isArray(snapOffset) ? snapOffset : ids.map(function () { return snapOffset; });\n var dragInterval = getOption(options, 'dragInterval', 1);\n var direction = getOption(options, 'direction', HORIZONTAL);\n var cursor = getOption(\n options,\n 'cursor',\n direction === HORIZONTAL ? 'col-resize' : 'row-resize'\n );\n var gutter = getOption(options, 'gutter', defaultGutterFn);\n var elementStyle = getOption(\n options,\n 'elementStyle',\n defaultElementStyleFn\n );\n var gutterStyle = getOption(options, 'gutterStyle', defaultGutterStyleFn);\n\n // 2. Initialize a bunch of strings based on the direction we're splitting.\n // A lot of the behavior in the rest of the library is paramatized down to\n // rely on CSS strings and classes.\n if (direction === HORIZONTAL) {\n dimension = 'width';\n clientAxis = 'clientX';\n position = 'left';\n positionEnd = 'right';\n clientSize = 'clientWidth';\n } else if (direction === 'vertical') {\n dimension = 'height';\n clientAxis = 'clientY';\n position = 'top';\n positionEnd = 'bottom';\n clientSize = 'clientHeight';\n }\n\n // 3. Define the dragging helper functions, and a few helpers to go with them.\n // Each helper is bound to a pair object that contains its metadata. This\n // also makes it easy to store references to listeners that that will be\n // added and removed.\n //\n // Even though there are no other functions contained in them, aliasing\n // this to self saves 50 bytes or so since it's used so frequently.\n //\n // The pair object saves metadata like dragging state, position and\n // event listener references.\n\n function setElementSize(el, size, gutSize, i) {\n // Split.js allows setting sizes via numbers (ideally), or if you must,\n // by string, like '300px'. This is less than ideal, because it breaks\n // the fluid layout that `calc(% - px)` provides. You're on your own if you do that,\n // make sure you calculate the gutter size by hand.\n var style = elementStyle(dimension, size, gutSize, i);\n\n Object.keys(style).forEach(function (prop) {\n // eslint-disable-next-line no-param-reassign\n el.style[prop] = style[prop];\n });\n }\n\n function setGutterSize(gutterElement, gutSize, i) {\n var style = gutterStyle(dimension, gutSize, i);\n\n Object.keys(style).forEach(function (prop) {\n // eslint-disable-next-line no-param-reassign\n gutterElement.style[prop] = style[prop];\n });\n }\n\n function getSizes() {\n return elements.map(function (element) { return element.size; })\n }\n\n // Supports touch events, but not multitouch, so only the first\n // finger `touches[0]` is counted.\n function getMousePosition(e) {\n if ('touches' in e) { return e.touches[0][clientAxis] }\n return e[clientAxis]\n }\n\n // Actually adjust the size of elements `a` and `b` to `offset` while dragging.\n // calc is used to allow calc(percentage + gutterpx) on the whole split instance,\n // which allows the viewport to be resized without additional logic.\n // Element a's size is the same as offset. b's size is total size - a size.\n // Both sizes are calculated from the initial parent percentage,\n // then the gutter size is subtracted.\n function adjust(offset) {\n var a = elements[this.a];\n var b = elements[this.b];\n var percentage = a.size + b.size;\n\n a.size = (offset / this.size) * percentage;\n b.size = percentage - (offset / this.size) * percentage;\n\n setElementSize(a.element, a.size, this[aGutterSize], a.i);\n setElementSize(b.element, b.size, this[bGutterSize], b.i);\n }\n\n // drag, where all the magic happens. The logic is really quite simple:\n //\n // 1. Ignore if the pair is not dragging.\n // 2. Get the offset of the event.\n // 3. Snap offset to min if within snappable range (within min + snapOffset).\n // 4. Actually adjust each element in the pair to offset.\n //\n // ---------------------------------------------------------------------\n // | | <- a.minSize || b.minSize -> | |\n // | | | <- this.snapOffset || this.snapOffset -> | | |\n // | | | || | | |\n // | | | || | | |\n // ---------------------------------------------------------------------\n // | <- this.start this.size -> |\n function drag(e) {\n var offset;\n var a = elements[this.a];\n var b = elements[this.b];\n\n if (!this.dragging) { return }\n\n // Get the offset of the event from the first side of the\n // pair `this.start`. Then offset by the initial position of the\n // mouse compared to the gutter size.\n offset =\n getMousePosition(e) -\n this.start +\n (this[aGutterSize] - this.dragOffset);\n\n if (dragInterval > 1) {\n offset = Math.round(offset / dragInterval) * dragInterval;\n }\n\n // If within snapOffset of min or max, set offset to min or max.\n // snapOffset buffers a.minSize and b.minSize, so logic is opposite for both.\n // Include the appropriate gutter sizes to prevent overflows.\n if (offset <= a.minSize + a.snapOffset + this[aGutterSize]) {\n offset = a.minSize + this[aGutterSize];\n } else if (\n offset >=\n this.size - (b.minSize + b.snapOffset + this[bGutterSize])\n ) {\n offset = this.size - (b.minSize + this[bGutterSize]);\n }\n\n if (offset >= a.maxSize - a.snapOffset + this[aGutterSize]) {\n offset = a.maxSize + this[aGutterSize];\n } else if (\n offset <=\n this.size - (b.maxSize - b.snapOffset + this[bGutterSize])\n ) {\n offset = this.size - (b.maxSize + this[bGutterSize]);\n }\n\n // Actually adjust the size.\n adjust.call(this, offset);\n\n // Call the drag callback continously. Don't do anything too intensive\n // in this callback.\n getOption(options, 'onDrag', NOOP)(getSizes());\n }\n\n // Cache some important sizes when drag starts, so we don't have to do that\n // continously:\n //\n // `size`: The total size of the pair. First + second + first gutter + second gutter.\n // `start`: The leading side of the first element.\n //\n // ------------------------------------------------\n // | aGutterSize -> ||| |\n // | ||| |\n // | ||| |\n // | ||| <- bGutterSize |\n // ------------------------------------------------\n // | <- start size -> |\n function calculateSizes() {\n // Figure out the parent size minus padding.\n var a = elements[this.a].element;\n var b = elements[this.b].element;\n\n var aBounds = a[getBoundingClientRect]();\n var bBounds = b[getBoundingClientRect]();\n\n this.size =\n aBounds[dimension] +\n bBounds[dimension] +\n this[aGutterSize] +\n this[bGutterSize];\n this.start = aBounds[position];\n this.end = aBounds[positionEnd];\n }\n\n function innerSize(element) {\n // Return nothing if getComputedStyle is not supported (< IE9)\n // Or if parent element has no layout yet\n if (!getComputedStyle) { return null }\n\n var computedStyle = getComputedStyle(element);\n\n if (!computedStyle) { return null }\n\n var size = element[clientSize];\n\n if (size === 0) { return null }\n\n if (direction === HORIZONTAL) {\n size -=\n parseFloat(computedStyle.paddingLeft) +\n parseFloat(computedStyle.paddingRight);\n } else {\n size -=\n parseFloat(computedStyle.paddingTop) +\n parseFloat(computedStyle.paddingBottom);\n }\n\n return size\n }\n\n // When specifying percentage sizes that are less than the computed\n // size of the element minus the gutter, the lesser percentages must be increased\n // (and decreased from the other elements) to make space for the pixels\n // subtracted by the gutters.\n function trimToMin(sizesToTrim) {\n // Try to get inner size of parent element.\n // If it's no supported, return original sizes.\n var parentSize = innerSize(parent);\n if (parentSize === null) {\n return sizesToTrim\n }\n\n if (minSizes.reduce(function (a, b) { return a + b; }, 0) > parentSize) {\n return sizesToTrim\n }\n\n // Keep track of the excess pixels, the amount of pixels over the desired percentage\n // Also keep track of the elements with pixels to spare, to decrease after if needed\n var excessPixels = 0;\n var toSpare = [];\n\n var pixelSizes = sizesToTrim.map(function (size, i) {\n // Convert requested percentages to pixel sizes\n var pixelSize = (parentSize * size) / 100;\n var elementGutterSize = getGutterSize(\n gutterSize,\n i === 0,\n i === sizesToTrim.length - 1,\n gutterAlign\n );\n var elementMinSize = minSizes[i] + elementGutterSize;\n\n // If element is too smal, increase excess pixels by the difference\n // and mark that it has no pixels to spare\n if (pixelSize < elementMinSize) {\n excessPixels += elementMinSize - pixelSize;\n toSpare.push(0);\n return elementMinSize\n }\n\n // Otherwise, mark the pixels it has to spare and return it's original size\n toSpare.push(pixelSize - elementMinSize);\n return pixelSize\n });\n\n // If nothing was adjusted, return the original sizes\n if (excessPixels === 0) {\n return sizesToTrim\n }\n\n return pixelSizes.map(function (pixelSize, i) {\n var newPixelSize = pixelSize;\n\n // While there's still pixels to take, and there's enough pixels to spare,\n // take as many as possible up to the total excess pixels\n if (excessPixels > 0 && toSpare[i] - excessPixels > 0) {\n var takenPixels = Math.min(\n excessPixels,\n toSpare[i] - excessPixels\n );\n\n // Subtract the amount taken for the next iteration\n excessPixels -= takenPixels;\n newPixelSize = pixelSize - takenPixels;\n }\n\n // Return the pixel size adjusted as a percentage\n return (newPixelSize / parentSize) * 100\n })\n }\n\n // stopDragging is very similar to startDragging in reverse.\n function stopDragging() {\n var self = this;\n var a = elements[self.a].element;\n var b = elements[self.b].element;\n\n if (self.dragging) {\n getOption(options, 'onDragEnd', NOOP)(getSizes());\n }\n\n self.dragging = false;\n\n // Remove the stored event listeners. This is why we store them.\n global[removeEventListener]('mouseup', self.stop);\n global[removeEventListener]('touchend', self.stop);\n global[removeEventListener]('touchcancel', self.stop);\n global[removeEventListener]('mousemove', self.move);\n global[removeEventListener]('touchmove', self.move);\n\n // Clear bound function references\n self.stop = null;\n self.move = null;\n\n a[removeEventListener]('selectstart', NOOP);\n a[removeEventListener]('dragstart', NOOP);\n b[removeEventListener]('selectstart', NOOP);\n b[removeEventListener]('dragstart', NOOP);\n\n a.style.userSelect = '';\n a.style.webkitUserSelect = '';\n a.style.MozUserSelect = '';\n a.style.pointerEvents = '';\n\n b.style.userSelect = '';\n b.style.webkitUserSelect = '';\n b.style.MozUserSelect = '';\n b.style.pointerEvents = '';\n\n self.gutter.style.cursor = '';\n self.parent.style.cursor = '';\n document.body.style.cursor = '';\n }\n\n // startDragging calls `calculateSizes` to store the inital size in the pair object.\n // It also adds event listeners for mouse/touch events,\n // and prevents selection while dragging so avoid the selecting text.\n function startDragging(e) {\n // Right-clicking can't start dragging.\n if ('button' in e && e.button !== 0) {\n return\n }\n\n // Alias frequently used variables to save space. 200 bytes.\n var self = this;\n var a = elements[self.a].element;\n var b = elements[self.b].element;\n\n // Call the onDragStart callback.\n if (!self.dragging) {\n getOption(options, 'onDragStart', NOOP)(getSizes());\n }\n\n // Don't actually drag the element. We emulate that in the drag function.\n e.preventDefault();\n\n // Set the dragging property of the pair object.\n self.dragging = true;\n\n // Create two event listeners bound to the same pair object and store\n // them in the pair object.\n self.move = drag.bind(self);\n self.stop = stopDragging.bind(self);\n\n // All the binding. `window` gets the stop events in case we drag out of the elements.\n global[addEventListener]('mouseup', self.stop);\n global[addEventListener]('touchend', self.stop);\n global[addEventListener]('touchcancel', self.stop);\n global[addEventListener]('mousemove', self.move);\n global[addEventListener]('touchmove', self.move);\n\n // Disable selection. Disable!\n a[addEventListener]('selectstart', NOOP);\n a[addEventListener]('dragstart', NOOP);\n b[addEventListener]('selectstart', NOOP);\n b[addEventListener]('dragstart', NOOP);\n\n a.style.userSelect = 'none';\n a.style.webkitUserSelect = 'none';\n a.style.MozUserSelect = 'none';\n a.style.pointerEvents = 'none';\n\n b.style.userSelect = 'none';\n b.style.webkitUserSelect = 'none';\n b.style.MozUserSelect = 'none';\n b.style.pointerEvents = 'none';\n\n // Set the cursor at multiple levels\n self.gutter.style.cursor = cursor;\n self.parent.style.cursor = cursor;\n document.body.style.cursor = cursor;\n\n // Cache the initial sizes of the pair.\n calculateSizes.call(self);\n\n // Determine the position of the mouse compared to the gutter\n self.dragOffset = getMousePosition(e) - self.end;\n }\n\n // adjust sizes to ensure percentage is within min size and gutter.\n sizes = trimToMin(sizes);\n\n // 5. Create pair and element objects. Each pair has an index reference to\n // elements `a` and `b` of the pair (first and second elements).\n // Loop through the elements while pairing them off. Every pair gets a\n // `pair` object and a gutter.\n //\n // Basic logic:\n //\n // - Starting with the second element `i > 0`, create `pair` objects with\n // `a = i - 1` and `b = i`\n // - Set gutter sizes based on the _pair_ being first/last. The first and last\n // pair have gutterSize / 2, since they only have one half gutter, and not two.\n // - Create gutter elements and add event listeners.\n // - Set the size of the elements, minus the gutter sizes.\n //\n // -----------------------------------------------------------------------\n // | i=0 | i=1 | i=2 | i=3 |\n // | | | | |\n // | pair 0 pair 1 pair 2 |\n // | | | | |\n // -----------------------------------------------------------------------\n var pairs = [];\n elements = ids.map(function (id, i) {\n // Create the element object.\n var element = {\n element: elementOrSelector(id),\n size: sizes[i],\n minSize: minSizes[i],\n maxSize: maxSizes[i],\n snapOffset: snapOffsets[i],\n i: i,\n };\n\n var pair;\n\n if (i > 0) {\n // Create the pair object with its metadata.\n pair = {\n a: i - 1,\n b: i,\n dragging: false,\n direction: direction,\n parent: parent,\n };\n\n pair[aGutterSize] = getGutterSize(\n gutterSize,\n i - 1 === 0,\n false,\n gutterAlign\n );\n pair[bGutterSize] = getGutterSize(\n gutterSize,\n false,\n i === ids.length - 1,\n gutterAlign\n );\n\n // if the parent has a reverse flex-direction, switch the pair elements.\n if (\n parentFlexDirection === 'row-reverse' ||\n parentFlexDirection === 'column-reverse'\n ) {\n var temp = pair.a;\n pair.a = pair.b;\n pair.b = temp;\n }\n }\n\n // Determine the size of the current element. IE8 is supported by\n // staticly assigning sizes without draggable gutters. Assigns a string\n // to `size`.\n //\n // Create gutter elements for each pair.\n if (i > 0) {\n var gutterElement = gutter(i, direction, element.element);\n setGutterSize(gutterElement, gutterSize, i);\n\n // Save bound event listener for removal later\n pair[gutterStartDragging] = startDragging.bind(pair);\n\n // Attach bound event listener\n gutterElement[addEventListener](\n 'mousedown',\n pair[gutterStartDragging]\n );\n gutterElement[addEventListener](\n 'touchstart',\n pair[gutterStartDragging]\n );\n\n parent.insertBefore(gutterElement, element.element);\n\n pair.gutter = gutterElement;\n }\n\n setElementSize(\n element.element,\n element.size,\n getGutterSize(\n gutterSize,\n i === 0,\n i === ids.length - 1,\n gutterAlign\n ),\n i\n );\n\n // After the first iteration, and we have a pair object, append it to the\n // list of pairs.\n if (i > 0) {\n pairs.push(pair);\n }\n\n return element\n });\n\n function adjustToMin(element) {\n var isLast = element.i === pairs.length;\n var pair = isLast ? pairs[element.i - 1] : pairs[element.i];\n\n calculateSizes.call(pair);\n\n var size = isLast\n ? pair.size - element.minSize - pair[bGutterSize]\n : element.minSize + pair[aGutterSize];\n\n adjust.call(pair, size);\n }\n\n elements.forEach(function (element) {\n var computedSize = element.element[getBoundingClientRect]()[dimension];\n\n if (computedSize < element.minSize) {\n if (expandToMin) {\n adjustToMin(element);\n } else {\n // eslint-disable-next-line no-param-reassign\n element.minSize = computedSize;\n }\n }\n });\n\n function setSizes(newSizes) {\n var trimmed = trimToMin(newSizes);\n trimmed.forEach(function (newSize, i) {\n if (i > 0) {\n var pair = pairs[i - 1];\n\n var a = elements[pair.a];\n var b = elements[pair.b];\n\n a.size = trimmed[i - 1];\n b.size = newSize;\n\n setElementSize(a.element, a.size, pair[aGutterSize], a.i);\n setElementSize(b.element, b.size, pair[bGutterSize], b.i);\n }\n });\n }\n\n function destroy(preserveStyles, preserveGutter) {\n pairs.forEach(function (pair) {\n if (preserveGutter !== true) {\n pair.parent.removeChild(pair.gutter);\n } else {\n pair.gutter[removeEventListener](\n 'mousedown',\n pair[gutterStartDragging]\n );\n pair.gutter[removeEventListener](\n 'touchstart',\n pair[gutterStartDragging]\n );\n }\n\n if (preserveStyles !== true) {\n var style = elementStyle(\n dimension,\n pair.a.size,\n pair[aGutterSize]\n );\n\n Object.keys(style).forEach(function (prop) {\n elements[pair.a].element.style[prop] = '';\n elements[pair.b].element.style[prop] = '';\n });\n }\n });\n }\n\n return {\n setSizes: setSizes,\n getSizes: getSizes,\n collapse: function collapse(i) {\n adjustToMin(elements[i]);\n },\n destroy: destroy,\n parent: parent,\n pairs: pairs,\n }\n };\n\n return Split;\n\n})));\n", "// MINIMAL KEYBOARD SHORTCUT MATCHER\n//\n// Follows the rules from \"All JavaScript keyboard shortcut libraries are\n// broken\" (Hazel Duvall, 2025-01-10):\n// - match on KeyboardEvent.key (layout-aware), never code/keyCode/which\n// (mousetrap and most libraries use which -> wrong keys on Dvorak etc.)\n// - only roman letters (A-Z), digits, and named navigation keys\n// - normalize case, so Shift never changes what is matched\n// - Shift is only allowed with letters (Shift mutates digits/punctuation)\n// - never use Alt (macOS Option mutates letters, e.g. Alt+R = '\u00AE';\n// AltGr = Ctrl+Alt on international PC layouts)\n// - 'mod' = Cmd on macOS, Ctrl on Windows/Linux\n\nexport interface KeyBinding {\n mod: boolean; // Cmd on macOS, Ctrl on Windows/Linux\n shift: boolean;\n key: string; // normalized: 'a'-'z', '0'-'9', or 'arrowleft' etc.\n}\n\nconst NAMED_KEYS: { [k: string]: string } = {\n left: 'arrowleft', right: 'arrowright', up: 'arrowup', down: 'arrowdown',\n};\n\nvar _isMac: boolean | null = null;\n\nexport function isMacOS(): boolean {\n if (_isMac === null) {\n var nav = typeof navigator !== 'undefined' ? navigator : null;\n _isMac = !!nav && /mac|iphone|ipad|ipod/i.test(nav.platform || nav.userAgent || '');\n }\n return _isMac;\n}\n\nexport function parseKeyBinding(spec: string): KeyBinding | null {\n var parts = spec.toLowerCase().split('+');\n var key = parts.pop() as string;\n var b: KeyBinding = { mod: false, shift: false, key: '' };\n for (var p of parts) {\n if (p == 'mod' || p == 'ctrl' || p == 'meta' || p == 'cmd') b.mod = true;\n else if (p == 'shift') b.shift = true;\n else {\n console.warn('Keyboard shortcut \"' + spec + '\": unsupported modifier \"' + p + '\" (alt is layout-dependent), skipping');\n return null;\n }\n }\n key = NAMED_KEYS[key] || key;\n var isLetter = /^[a-z]$/.test(key);\n var isFKey = /^f([1-9]|1[0-2])$/.test(key);\n if (!isLetter && !isFKey && !/^[0-9]$/.test(key) && !/^arrow/.test(key)) {\n console.warn('Keyboard shortcut \"' + spec + '\": key \"' + key + '\" is layout-dependent (use a-z, 0-9, f1-f12), skipping');\n return null;\n }\n if (b.shift && !isLetter && !/^arrow/.test(key)) {\n console.warn('Keyboard shortcut \"' + spec + '\": shift is only allowed with letters and arrows, skipping');\n return null;\n }\n b.key = key;\n return b;\n}\n\nexport function matchesKeyBinding(b: KeyBinding, e: KeyboardEvent): boolean {\n if (e.altKey) return false; // we never bind alt; avoids AltGr ghosts while typing\n var mac = isMacOS();\n var modPressed = mac ? e.metaKey : e.ctrlKey;\n var otherPressed = mac ? e.ctrlKey : e.metaKey;\n if (b.mod !== modPressed || otherPressed) return false;\n if (b.shift !== e.shiftKey) return false;\n return (e.key || '').toLowerCase() === b.key;\n}\n\nexport class KeyBinder {\n bindings: { binding: KeyBinding; fn: (e?: any, combo?: any) => void }[] = [];\n private handler = (e: KeyboardEvent) => {\n // defer to any handler that already claimed this event (CodeMirror\n // keymaps, browser UI, ...) -- they call preventDefault when handled\n if (e.defaultPrevented) return;\n for (var i = 0; i < this.bindings.length; i++) {\n var bind = this.bindings[i];\n if (matchesKeyBinding(bind.binding, e)) {\n e.preventDefault();\n e.stopPropagation();\n bind.fn(e);\n return;\n }\n }\n };\n bind(spec: string, fn: (e?: any, combo?: any) => void) {\n var b = parseKeyBinding(spec);\n if (b) this.bindings.push({ binding: b, fn });\n }\n unbindAll() {\n this.bindings = [];\n }\n attach() {\n window.addEventListener('keydown', this.handler);\n }\n detach() {\n window.removeEventListener('keydown', this.handler);\n }\n}\n\n// --- CodeMirror keymap interop ---\n//\n// CodeMirror calls preventDefault() on any key one of its keymaps handles, and\n// KeyBinder (above) deliberately defers to that, so a key CodeMirror binds can\n// never reach the IDE while an editor is focused. Handing a key over to the IDE\n// therefore means removing CodeMirror's binding for it.\n//\n// The specs can't be compared as strings: CodeMirror writes modifiers in\n// whatever order each binding's author chose (\"Shift-Mod-k\" for deleteLine,\n// \"Mod-Shift-l\" for selectSelectionMatches), and a binding may carry\n// per-platform specs that override its default one.\n\nexport interface CMKeyBinding {\n key?: string;\n mac?: string;\n win?: string;\n linux?: string;\n}\n\nconst CM_MODIFIERS: { [k: string]: string } = {\n mod: 'Mod', cmd: 'Mod', meta: 'Mod', ctrl: 'Ctrl', control: 'Ctrl',\n shift: 'Shift', alt: 'Alt', option: 'Alt',\n};\n\nvar _isWin: boolean | null = null;\n\nfunction isWindows(): boolean {\n if (_isWin === null) {\n var nav = typeof navigator !== 'undefined' ? navigator : null;\n _isWin = !!nav && /win/i.test(nav.platform || nav.userAgent || '');\n }\n return _isWin;\n}\n\n// \"Shift-Mod-k\" and \"Mod-Shift-K\" both become \"Mod-Shift-k\"\nexport function normalizeCMKeySpec(spec: string): string {\n var parts = spec.split('-');\n var key = parts.pop() as string;\n if (key === '') key = '-'; // trailing dash means the key itself is '-'\n var mods: string[] = [];\n for (var p of parts) {\n if (p === '') continue; // \"Mod--\" splits to ['Mod', '', '']\n var m = CM_MODIFIERS[p.toLowerCase()] || p;\n if (m == 'Ctrl' && !isMacOS()) m = 'Mod'; // off macOS, Ctrl *is* Mod\n if (mods.indexOf(m) < 0) mods.push(m);\n }\n mods.sort();\n return mods.concat([key.toLowerCase()]).join('-');\n}\n\n// the spec CodeMirror will actually use on this platform\nexport function effectiveCMKeySpec(b: CMKeyBinding): string | undefined {\n var platform = isMacOS() ? b.mac : (isWindows() ? b.win : b.linux);\n return platform || b.key;\n}\n\n// every mod+shift+ the IDE binds -- see the shortcuts in ui.ts, which\n// testkeys.ts checks this list against\nexport const IDE_RESERVED_KEYS = [\n 'Mod-Shift-a', 'Mod-Shift-d', 'Mod-Shift-e', 'Mod-Shift-f', 'Mod-Shift-g',\n 'Mod-Shift-h', 'Mod-Shift-i', 'Mod-Shift-j', 'Mod-Shift-k', 'Mod-Shift-l',\n 'Mod-Shift-r', 'Mod-Shift-x', 'Mod-Shift-y',\n];\n\n// drop the bindings that would swallow one of the IDE's own shortcuts\nexport function stripCMKeymap(keymap: readonly T[], specs: string[]): T[] {\n var freed = specs.map(normalizeCMKeySpec);\n return keymap.filter(function (b) {\n var spec = effectiveCMKeySpec(b);\n return !spec || freed.indexOf(normalizeCMKeySpec(spec)) < 0;\n });\n}\n", "declare var $: JQueryStatic; // use browser jquery\nimport { isMacOS } from \"./keys\";\n\n// KEYBOARD SHORTCUTS / STATUS BAR\n//\n// Display-only bar with two zones:\n// left: context-sensitive keyboard shortcuts (chips of form \" Ctrl+Alt+R Reset\")\n// right: status items (errors, debug state, etc.)\n//\n// The bar does NOT bind any keys -- actual key handling lives where it\n// always has (mousetrap in Toolbar, CodeMirror keymaps). The bar reflects\n// what is available in the current context; chips are clickable where an\n// obvious action exists.\n\nexport interface Shortcut {\n key: string; // display combo, e.g. \"Ctrl+Alt+R\"\n label: string;\n fn?: (e?, combo?) => void; // optional: makes the chip clickable\n}\n\nexport interface StatusItem {\n text: string;\n cls?: string; // extra css class, e.g. 'error' 'ok' 'running'\n title?: string; // tooltip\n fn?: (e?) => void; // optional: makes the chip clickable\n}\n\n// display a mousetrap-style key spec for the current platform:\n// mac: 'mod+shift+r' -> '\u21E7\u2318R', 'ctrl+alt+r' -> '\u2303\u2325R'\n// win/linux: 'mod+shift+r' -> 'Ctrl+Shift+R'\n// unknown parts (e.g. punctuation keys) pass through unchanged\nconst MAC_SYMBOLS: { [mod: string]: string } = { shift: '\u21E7', ctrl: '\u2303', alt: '\u2325', meta: '\u2318', mod: '\u2318', cmd: '\u2318' };\nconst PC_NAMES: { [mod: string]: string } = { shift: 'Shift', ctrl: 'Ctrl', alt: 'Alt', meta: 'Win', mod: 'Ctrl', cmd: 'Cmd' };\nconst KEY_SYMBOLS: { [k: string]: string } = { arrowleft: '\u2190', arrowright: '\u2192', arrowup: '\u2191', arrowdown: '\u2193', backspace: '\u232B', enter: '\u21A9', tab: '\u21E5', escape: '\u238B', space: '\u2423' };\n\nexport function formatKey(key: string): string {\n var parts = key.toLowerCase().split('+');\n var main = parts.pop() as string;\n var isMac = isMacOS();\n // canonical display order: shift first on mac (HIG), ctrl first on PC\n var order = isMac ? ['shift', 'ctrl', 'alt', 'meta', 'mod', 'cmd'] : ['mod', 'ctrl', 'shift', 'alt', 'meta', 'cmd'];\n var uniq = order.filter((p) => parts.indexOf(p) >= 0);\n for (var p of parts) if (uniq.indexOf(p) < 0) uniq.push(p);\n var modStr = uniq.map((p) => isMac ? (MAC_SYMBOLS[p] || p) : (PC_NAMES[p] || p)).join(isMac ? '' : '+');\n var mainDisp = /^[a-z][0-9]?$/.test(main) ? main.toUpperCase() : (KEY_SYMBOLS[main] || (isMac ? main : main.charAt(0).toUpperCase() + main.slice(1)));\n return (modStr ? modStr + (isMac ? '' : '+') : '') + mainDisp;\n}\n\nexport class ShortcutBar {\n div: HTMLElement;\n shortcutsSig: string = \"\";\n status: { [id: string]: StatusItem } = {};\n shortcutsZone: JQuery;\n statusZone: JQuery;\n visible: boolean = true;\n // re-renders deferred while a mouse button is down (see trackMousePress)\n pendingShortcuts: Shortcut[] | null = null;\n pendingStatus: boolean = false;\n\n constructor(div: HTMLElement) {\n this.div = div;\n this.shortcutsZone = $(document.createElement(\"span\")).addClass(\"shortcuts_zone\");\n this.statusZone = $(document.createElement(\"span\")).addClass(\"status_zone\");\n $(div).append(this.shortcutsZone).append(this.statusZone);\n }\n\n setShortcuts(shortcuts: Shortcut[]) {\n if (!this.visible) return;\n // skip re-render if nothing changed\n var sig = shortcuts.map((s) => s.key + \"\\u0001\" + s.label).join(\"\\u0002\");\n if (sig === this.shortcutsSig) return;\n if (mouseDown) {\n this.pendingShortcuts = shortcuts;\n return;\n }\n this.shortcutsSig = sig;\n this.shortcutsZone.empty();\n for (var s of shortcuts) {\n var span = $(document.createElement(\"span\")).addClass(\"shortcut\");\n span.append($(document.createElement(\"kbd\")).text(formatKey(s.key)));\n span.append(document.createTextNode(\" \" + s.label));\n if (s.fn) {\n makeClickable(span, s.fn);\n }\n this.shortcutsZone.append(span);\n }\n }\n\n setStatus(id: string, item: StatusItem | null) {\n if (item) this.status[id] = item;\n else delete this.status[id];\n this.renderStatus();\n }\n\n renderStatus() {\n if (!this.visible) return;\n if (mouseDown) {\n this.pendingStatus = true;\n return;\n }\n this.statusZone.empty();\n for (var key of Object.keys(this.status)) {\n var s = this.status[key];\n var span = $(document.createElement(\"span\")).addClass(\"status_item\");\n if (s.cls) span.addClass(s.cls);\n if (s.title) span.prop(\"title\", s.title);\n span.text(s.text);\n if (s.fn) {\n makeClickable(span, s.fn);\n }\n this.statusZone.append(span);\n }\n }\n}\n\nfunction makeClickable(span: JQuery, fn: (e?) => void) {\n // don't steal focus on mousedown: clicking a chip would blur the active\n // view and re-render the bar (removing the chip) before the click lands\n span.addClass(\"clickable\");\n span.mousedown((e) => e.preventDefault());\n span.click(fn);\n}\n\n// while a mouse button is down, defer bar re-renders until mouseup:\n// focus changes fire during mousedown (widgets focus() their container,\n// chips can blur the active view), and re-rendering mid-press would swap\n// the chips out from under the cursor before the click event lands\nvar mouseDown = false;\n\nfunction flushPendingRenders() {\n if (!shortcutBar) return;\n if (shortcutBar.pendingShortcuts) {\n var shortcuts = shortcutBar.pendingShortcuts;\n shortcutBar.pendingShortcuts = null;\n shortcutBar.setShortcuts(shortcuts);\n }\n if (shortcutBar.pendingStatus) {\n shortcutBar.pendingStatus = false;\n shortcutBar.renderStatus();\n }\n}\n\nfunction trackMousePress() {\n $(document).on('mousedown.shortcutbar', () => { mouseDown = true; });\n $(document).on('mouseup.shortcutbar', () => { mouseDown = false; flushPendingRenders(); });\n // released outside the window: no mouseup fires, so flush on blur instead\n $(window).on('blur.shortcutbar', () => { mouseDown = false; flushPendingRenders(); });\n}\n\n// module-level singleton + provider wiring\n// (avoids circular imports between ui.ts / windows.ts / views)\n\nexport var shortcutBar: ShortcutBar = null;\n\nexport function initShortcutBar(div: HTMLElement) {\n shortcutBar = new ShortcutBar(div);\n trackMousePress();\n}\n\nvar globalShortcutsFn: () => Shortcut[] = () => [];\nvar viewShortcutsFn: () => Shortcut[] = () => [];\n\n// global/debug shortcuts are composed by ui.ts (knows debug state)\nexport function setGlobalShortcutsFn(fn: () => Shortcut[]) { globalShortcutsFn = fn; }\n// view-specific shortcuts come from the active ProjectView's getShortcuts()\nexport function setViewShortcutsFn(fn: () => Shortcut[]) { viewShortcutsFn = fn; }\n\n// status items are updated directly by the subsystem that owns them\nexport function setBarStatus(id: string, item: StatusItem | null) {\n if (shortcutBar) shortcutBar.setStatus(id, item);\n}\n\n// show/hide the whole bar (driven by the IDE setting); also collapses\n// the bottom spacing via the body class (see css/ui.css)\nexport function setBarVisible(visible: boolean) {\n $(document.body).toggleClass(\"statusbar-hidden\", !visible);\n if (shortcutBar) {\n shortcutBar.visible = visible;\n if (visible) {\n shortcutBar.shortcutsSig = \"\"; // force re-render on next refresh\n shortcutBar.renderStatus();\n refreshShortcutBar();\n }\n }\n}\n\nexport function refreshShortcutBar() {\n if (!shortcutBar) return;\n var shortcuts = [...globalShortcutsFn(), ...viewShortcutsFn()];\n // widget-scoped providers (e.g. the waveform viewer): show chips while\n // the widget's container has focus\n var ae = document.activeElement;\n for (var es of elementShortcuts) {\n if (ae && es.div.contains(ae)) shortcuts = shortcuts.concat(es.fn());\n }\n shortcutBar.setShortcuts(shortcuts.filter((s) => !isBrowserEaten(s.key)));\n}\n\nvar elementShortcuts: { div: HTMLElement; fn: () => Shortcut[] }[] = [];\n\nexport function registerElementShortcuts(div: HTMLElement, fn: () => Shortcut[]) {\n elementShortcuts.push({ div, fn });\n}\n\nexport function unregisterElementShortcuts(div: HTMLElement) {\n elementShortcuts = elementShortcuts.filter((es) => es.div !== div);\n}\n\n// combos the browser/OS reserves and won't let a page intercept:\n// hide them from the bar rather than advertise dead keys\n// (the underlying bindings stay in place for platforms where they work)\nfunction isBrowserEaten(key: string): boolean {\n var k = key.toLowerCase();\n if (!isMacOS()) {\n // Chrome/Firefox devtools on Windows/Linux: Ctrl+Shift+I/J/K\n if (k == 'mod+shift+i' || k == 'mod+shift+j' || k == 'mod+shift+k') return true;\n // GNOME desktop: terminal / lock screen\n if (k == 'ctrl+alt+t' || k == 'ctrl+alt+l') return true;\n }\n return false;\n}\n", "\n/// TOOLBAR\n\nimport { formatKey } from \"./shortcutbar\";\nimport { KeyBinder, parseKeyBinding } from \"./keys\";\n\n// Lazy mousetrap require: mousetrap references `document` at module load time,\n// which crashes in Node-based tests (window is polyfilled, document is not).\nfunction getMousetrap() {\n return require('mousetrap');\n}\n\n// Patch mousetrap's default stopCallback, which blocks ALL bound shortcuts\n// when the event target is an input or contenteditable element -- which\n// includes the CodeMirror editor. Allow combos with ctrl/alt/meta modifiers\n// through so app commands keep working while typing in the editor.\n// (AltGraph = AltGr on international keyboards: treat as character input.)\nfunction patchMousetrap(Mousetrap: any) {\n if (Mousetrap._8bwPatched) return Mousetrap;\n var origStop = Mousetrap.stopCallback;\n Mousetrap.stopCallback = function (e, element, combo, sequence) {\n if (e && (e.ctrlKey || e.altKey || e.metaKey)) {\n if (e.getModifierState && e.getModifierState('AltGraph')) {\n return origStop.call(this, e, element, combo, sequence);\n }\n return false;\n }\n return origStop.call(this, e, element, combo, sequence);\n };\n Mousetrap._8bwPatched = true;\n return Mousetrap;\n}\n\nexport class Toolbar {\n span : JQuery;\n grp : JQuery;\n mousetrap;\n boundkeys = [];\n keybinder: KeyBinder;\n focusDiv: HTMLElement;\n\n constructor(parentDiv:HTMLElement, focusDiv:HTMLElement) {\n const Mousetrap = patchMousetrap(getMousetrap());\n // article-compliant bindings (match on KeyboardEvent.key) go through\n // KeyBinder; non-compliant specs (punctuation, alt, shift+digit) fall\n // back to mousetrap's positional matching\n this.focusDiv = focusDiv;\n this.keybinder = new KeyBinder();\n this.keybinder.attach();\n this.mousetrap = focusDiv ? new Mousetrap(focusDiv) : Mousetrap;\n this.span = $(document.createElement(\"span\")).addClass(\"btn_toolbar\");\n parentDiv.appendChild(this.span[0]);\n this.newGroup();\n }\n destroy() {\n if (this.span) {\n this.span.remove();\n this.span = null;\n }\n if (this.keybinder) {\n this.keybinder.detach();\n this.keybinder.unbindAll();\n this.keybinder = null;\n }\n if (this.mousetrap) {\n for (var key of this.boundkeys) {\n this.mousetrap.unbind(key);\n }\n this.mousetrap = null;\n }\n }\n newGroup() {\n return this.grp = $(document.createElement(\"span\")).addClass(\"btn_group\").appendTo(this.span).hide();\n }\n add(key:string, alttext:string, icon:string, fn:(e,combo) => void) {\n var btn = null;\n if (icon) {\n btn = $(document.createElement(\"button\")).addClass(\"btn\");\n if (icon.startsWith('glyphicon')) {\n icon = '';\n }\n btn.html(icon);\n btn.prop(\"title\", key ? (alttext+\" (\"+formatKey(key)+\")\") : alttext);\n btn.click(fn);\n this.grp.append(btn).show();\n }\n if (key) {\n if (!this.focusDiv && parseKeyBinding(key)) {\n // layout-safe global binding: fires even when the editor has focus\n this.keybinder.bind(key, fn);\n } else {\n // legacy fallback: mousetrap (positional matching, input-scoped)\n this.mousetrap.bind(key, (e, combo) => { fn(e, combo); return false; });\n this.boundkeys.push(key);\n }\n }\n return btn;\n }\n \n }\n ", "/**\n * The MIT License (MIT)\n *\n * Copyright (C) 2013 Sergi Mansilla\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the 'Software'), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/**\n * Creates a virtually-rendered scrollable list.\n * @param {object} config\n * @constructor\n */\nexport function VirtualList(config) {\n var width = (config && config.w + 'px') || '100%';\n var height = (config && config.h + 'px') || '100%';\n var itemHeight = this.itemHeight = config.itemHeight;\n\n this.items = config.items;\n this.generatorFn = config.generatorFn;\n this.totalRows = config.totalRows || (config.items && config.items.length);\n\n var scroller = VirtualList.createScroller(itemHeight * this.totalRows);\n this.container = VirtualList.createContainer(width, height);\n this.container.appendChild(scroller);\n\n var screenItemsLen = Math.ceil(config.h / itemHeight);\n // Cache 4 times the number of items that fit in the container viewport\n this.cachedItemsLen = screenItemsLen * 3;\n this._renderChunk(this.container, 0);\n\n var self = this;\n var lastRepaintY;\n var maxBuffer = screenItemsLen * itemHeight;\n var lastScrolled = 0;\n\n // As soon as scrolling has stopped, this interval asynchronouslyremoves all\n // the nodes that are not used anymore\n this.rmNodeInterval = setInterval(function() {\n if (Date.now() - lastScrolled > 100) {\n var badNodes = document.querySelectorAll('[data-rm=\"1\"]');\n for (var i = 0, l = badNodes.length; i < l; i++) {\n try {\n self.container.removeChild(badNodes[i]);\n } catch (e) {\n //\n }\n }\n }\n }, 300);\n\n function onScroll(e) {\n var scrollTop = e.target.scrollTop; // Triggers reflow\n if (!lastRepaintY || Math.abs(scrollTop - lastRepaintY) > maxBuffer) {\n var first = Math.floor(scrollTop / itemHeight) - screenItemsLen;\n self._renderChunk(self.container, first < 0 ? 0 : first);\n lastRepaintY = scrollTop;\n }\n\n lastScrolled = Date.now();\n e.preventDefault && e.preventDefault();\n }\n\n this.container.addEventListener('scroll', onScroll);\n}\n\nVirtualList.prototype.createRow = function(i) {\n var item;\n if (this.generatorFn)\n item = this.generatorFn(i);\n else if (this.items) {\n if (typeof this.items[i] === 'string') {\n var itemText = document.createTextNode(this.items[i]);\n item = document.createElement('div');\n item.style.height = this.itemHeight + 'px';\n item.appendChild(itemText);\n } else {\n item = this.items[i];\n }\n }\n\n item.classList.add('vrow');\n item.setAttribute('data-index', ''+i);\n item.style.position = 'absolute';\n item.style.top = (i * this.itemHeight) + 'px';\n return item;\n};\n\n/**\n * Renders a particular, consecutive chunk of the total rows in the list. To\n * keep acceleration while scrolling, we mark the nodes that are candidate for\n * deletion instead of deleting them right away, which would suddenly stop the\n * acceleration. We delete them once scrolling has finished.\n *\n * @param {Node} node Parent node where we want to append the children chunk.\n * @param {Number} from Starting position, i.e. first children index.\n * @return {void}\n */\nVirtualList.prototype._renderChunk = function(node, from) {\n var finalItem = from + this.cachedItemsLen;\n if (finalItem > this.totalRows)\n finalItem = this.totalRows;\n\n // Append all the new rows in a document fragment that we will later append to\n // the parent node\n var fragment = document.createDocumentFragment();\n for (var i = from; i < finalItem; i++) {\n fragment.appendChild(this.createRow(i));\n }\n\n // Hide and mark obsolete nodes for deletion.\n for (var j = 1, l = node.childNodes.length; j < l; j++) {\n node.childNodes[j].style.display = 'none';\n node.childNodes[j].setAttribute('data-rm', '1');\n }\n node.appendChild(fragment);\n};\n\nVirtualList.createContainer = function(w, h) {\n var c = document.createElement('div');\n c.classList.add('vlist');\n c.style.width = w;\n c.style.height = h;\n c.style.overflow = 'auto';\n c.style.position = 'relative';\n c.style.padding = '0';\n c.style.border = '1px solid black';\n return c;\n};\n\nVirtualList.createScroller = function(h) {\n var scroller = document.createElement('div');\n scroller.style.opacity = '0';\n scroller.style.position = 'absolute';\n scroller.style.top = '0';\n scroller.style.left = '0';\n scroller.style.width = '1px';\n scroller.style.height = h + 'px';\n return scroller;\n};\n\nVirtualList.prototype.scrollToItem = function(index) {\n this.container.scrollTop = this.itemHeight * index;\n};\n\n", "const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function (x: T): T {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x: T): T {\n return x;\n };\n}\n\nif (!apply) {\n apply = function (\n func: (thisArg: any, ...args: any[]) => T,\n thisArg: any,\n ...args: any[]\n ): T {\n return func.apply(thisArg, args);\n };\n}\n\nif (!construct) {\n construct = function (Func: new (...args: any[]) => T, ...args: any[]): T {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\nconst arraySplice = unapply(Array.prototype.splice);\nconst arrayIsArray = Array.isArray;\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst numberToString = unapply(Number.prototype.toString);\nconst booleanToString = unapply(Boolean.prototype.toString);\nconst bigintToString =\n typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);\nconst symbolToString =\n typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);\n\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst objectToString = unapply(Object.prototype.toString);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(\n func: (thisArg: any, ...args: any[]) => T\n): (thisArg: any, ...args: any[]) => T {\n return (thisArg: any, ...args: any[]): T => {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n\n return apply(func, thisArg, args);\n };\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(\n Func: new (...args: any[]) => T\n): (...args: any[]) => T {\n return (...args: any[]): T => construct(Func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(\n set: Record,\n array: readonly unknown[],\n transformCaseFunc: ReturnType> = stringToLowerCase\n): Record {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n if (!arrayIsArray(array)) {\n return set;\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n (array as unknown[])[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element as string] = true;\n }\n\n return set;\n}\n\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array: T[]): Array {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n\n return array;\n}\n\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone>(object: T): T {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n\n if (isPropertyExist) {\n if (arrayIsArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (\n value &&\n typeof value === 'object' &&\n value.constructor === Object\n ) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n\n return newObject;\n}\n\n/**\n * Convert non-node values into strings without depending on direct property access.\n *\n * @param value - The value to stringify.\n * @returns A string representation of the provided value.\n */\nfunction stringifyValue(value: unknown): string {\n switch (typeof value) {\n case 'string': {\n return value;\n }\n\n case 'number': {\n return numberToString(value);\n }\n\n case 'boolean': {\n return booleanToString(value);\n }\n\n case 'bigint': {\n return bigintToString ? bigintToString(value) : '0';\n }\n\n case 'symbol': {\n return symbolToString ? symbolToString(value) : 'Symbol()';\n }\n\n case 'undefined': {\n return objectToString(value);\n }\n\n case 'function':\n case 'object': {\n if (value === null) {\n return objectToString(value);\n }\n\n const valueAsRecord = value as Record;\n const valueToString = lookupGetter(valueAsRecord, 'toString');\n\n if (typeof valueToString === 'function') {\n const stringified = valueToString(valueAsRecord);\n\n return typeof stringified === 'string'\n ? stringified\n : objectToString(stringified);\n }\n\n return objectToString(value);\n }\n\n default: {\n return objectToString(value);\n }\n }\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter>(\n object: T,\n prop: string\n): ReturnType> | (() => null) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(): null {\n return null;\n }\n\n return fallbackValue;\n}\n\nfunction isRegex(value: unknown): value is RegExp {\n try {\n regExpTest(value as RegExp, '');\n return true;\n } catch {\n return false;\n }\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n arraySplice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n clone,\n create,\n objectHasOwnProperty,\n objectToString,\n // RegExp\n regExpTest,\n isRegex,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Other conversion\n stringifyValue,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'search',\n 'section',\n 'select',\n 'shadow',\n 'slot',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n] as const);\n\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'enterkeyhint',\n 'exportparts',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'inputmode',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'part',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n] as const);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n] as const);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n] as const);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n] as const);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n] as const);\n\nexport const text = freeze(['#text'] as const);\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'command',\n 'commandfor',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'exportparts',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inert',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'part',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'popover',\n 'popovertarget',\n 'popovertargetaction',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'slot',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'wrap',\n 'xmlns',\n] as const);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'amplitude',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dominant-baseline',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'exponent',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'intercept',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'mask-type',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'pointer-events',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'slope',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'tablevalues',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-orientation',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'vector-effect',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n] as const);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnalign',\n 'columnlines',\n 'columnspacing',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lquote',\n 'lspace',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n] as const);\n", "import { seal } from './utils.js';\n\nexport const MUSTACHE_EXPR = seal(/{{[\\w\\W]*|^[\\w\\W]*}}/g);\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|^[\\w\\W]*%>/g);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*/g);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\nexport const CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\n// Markup-significant character probes used by _sanitizeElements.\n// Shared module-level instances are safe despite the sticky /g flags:\n// unapply() resets lastIndex for RegExp receivers before every call.\nexport const ELEMENT_MARKUP_PROBE = seal(/<[/\\w!]/g);\nexport const COMMENT_MARKUP_PROBE = seal(/<[/\\w]/g);\nexport const FALLBACK_TAG_CLOSE = seal(/<\\/no(script|embed|frames)/i);\nexport const SELF_CLOSING_TAG = seal(/\\/>/i);\n", "import type { Config, UseProfilesConfig } from './config';\nimport type { DOMPurify, HooksMap, HookFunction, WindowLike } from './types';\nimport * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n seal,\n arrayForEach,\n arrayIsArray,\n arrayLastIndexOf,\n arrayPop,\n arrayPush,\n arraySplice,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n isRegex,\n typeErrorCreate,\n lookupGetter,\n create,\n objectHasOwnProperty,\n stringifyValue,\n} from './utils.js';\n\nexport type { Config } from './config';\n\nexport type {\n DOMPurify,\n RemovedElement,\n RemovedAttribute,\n HookName,\n NodeHook,\n ElementHook,\n DocumentFragmentHook,\n UponSanitizeElementHook,\n UponSanitizeAttributeHook,\n UponSanitizeElementHookEvent,\n UponSanitizeAttributeHookEvent,\n WindowLike,\n} from './types';\n\ndeclare const VERSION: string;\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5, // Deprecated\n entityNode: 6, // Deprecated\n processingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12, // Deprecated\n};\n\n/* HTML-namespace elements whose child text nodes are serialized *literally*\n (unescaped) by the HTML fragment-serialization algorithm. Two reparse-mXSS\n shapes ride on that literal serialization:\n (a) an element child - a tree the HTML parser can never build, but the DOM\n API and an XML/XHTML parse can - after which a ``-bearing text\n sibling breaks the element open on reparse; and\n (b) text-only content that already carries the element's OWN end tag, e.g.\n `` built as a node, which the literal\n serializer emits verbatim for the HTML parser to re-open.\n Shape (a) is handled by the firstElementChild branch in _isUnsafeNode; shape\n (b) by the LITERAL_TEXT_CLOSE probe. Both read textContent (the raw-serialized\n form for these elements) rather than innerHTML, because an XML/XHTML working\n document serializes innerHTML with `<` escaped, which silently blinds the\n innerHTML-based probes (rule 1's second probe and FALLBACK_TAG_CLOSE) there.\n `script` is never allow-listed, but is kept here so the guard matches the\n serializer's own literal-text list exactly. */\nconst LITERAL_TEXT_ELEMENT_NAMES = [\n 'style',\n 'script',\n 'xmp',\n 'iframe',\n 'noembed',\n 'noframes',\n 'plaintext',\n 'noscript',\n];\nconst LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));\n\n/* Per-element end-tag matcher. On an HTML reparse the ONLY token that\n terminates a literal-text element's raw content is its own end tag; a foreign\n literal-text close (e.g. `` sitting inside `` built as a node, which the literal\n serializer emits verbatim for the HTML parser to re-open.\n Shape (a) is handled by the firstElementChild branch in _isUnsafeNode; shape\n (b) by the LITERAL_TEXT_CLOSE probe. Both read textContent (the raw-serialized\n form for these elements) rather than innerHTML, because an XML/XHTML working\n document serializes innerHTML with `<` escaped, which silently blinds the\n innerHTML-based probes (rule 1's second probe and FALLBACK_TAG_CLOSE) there.\n `script` is never allow-listed, but is kept here so the guard matches the\n serializer's own literal-text list exactly. */\nconst LITERAL_TEXT_ELEMENT_NAMES = [\n 'style',\n 'script',\n 'xmp',\n 'iframe',\n 'noembed',\n 'noframes',\n 'plaintext',\n 'noscript',\n];\nconst LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));\n\n/* Per-element end-tag matcher. On an HTML reparse the ONLY token that\n terminates a literal-text element's raw content is its own end tag; a foreign\n literal-text close (e.g. `` sitting inside `` built as a node, which the literal\n serializer emits verbatim for the HTML parser to re-open.\n Shape (a) is handled by the firstElementChild branch in _isUnsafeNode; shape\n (b) by the LITERAL_TEXT_CLOSE probe. Both read textContent (the raw-serialized\n form for these elements) rather than innerHTML, because an XML/XHTML working\n document serializes innerHTML with `<` escaped, which silently blinds the\n innerHTML-based probes (rule 1's second probe and FALLBACK_TAG_CLOSE) there.\n `script` is never allow-listed, but is kept here so the guard matches the\n serializer's own literal-text list exactly. */\nconst LITERAL_TEXT_ELEMENT_NAMES = [\n 'style',\n 'script',\n 'xmp',\n 'iframe',\n 'noembed',\n 'noframes',\n 'plaintext',\n 'noscript',\n];\nconst LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));\n\n/* Per-element end-tag matcher. On an HTML reparse the ONLY token that\n terminates a literal-text element's raw content is its own end tag; a foreign\n literal-text close (e.g. `` sitting inside `` built as a node, which the literal\n serializer emits verbatim for the HTML parser to re-open.\n Shape (a) is handled by the firstElementChild branch in _isUnsafeNode; shape\n (b) by the LITERAL_TEXT_CLOSE probe. Both read textContent (the raw-serialized\n form for these elements) rather than innerHTML, because an XML/XHTML working\n document serializes innerHTML with `<` escaped, which silently blinds the\n innerHTML-based probes (rule 1's second probe and FALLBACK_TAG_CLOSE) there.\n `script` is never allow-listed, but is kept here so the guard matches the\n serializer's own literal-text list exactly. */\nconst LITERAL_TEXT_ELEMENT_NAMES = [\n 'style',\n 'script',\n 'xmp',\n 'iframe',\n 'noembed',\n 'noframes',\n 'plaintext',\n 'noscript',\n];\nconst LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));\n\n/* Per-element end-tag matcher. On an HTML reparse the ONLY token that\n terminates a literal-text element's raw content is its own end tag; a foreign\n literal-text close (e.g. `` sitting inside `