namespace XFESystem.Browser;
/// Trusted, interpreter-executed Web API prototypes. Host objects only expose explicit primitive callbacks.
internal static class BrowserDomBootstrap
{
internal const string Source = """
(function() {
const listenerAdded=__xfeListenerAdded,listenerRemoved=__xfeListenerRemoved,eventError=__xfeEventError,observerAdded=__xfeObserverAdded;
const encoding=__xfeEncoding;delete window.__xfeEncoding;
const cssom=__xfeCssom;delete window.__xfeCssom;
delete window.__xfeListenerAdded;delete window.__xfeListenerRemoved;delete window.__xfeEventError;delete window.__xfeObserverAdded;
const listeners = new WeakMap(), state = new WeakMap();
function eventState(e) { const s=state.get(e); if(!s) throw new TypeError('Expected Event'); return s; }
class Event {
constructor(type, init={}) { this.type=String(type); this.bubbles=!!init.bubbles; this.cancelable=!!init.cancelable;
this.composed=!!init.composed; this.isTrusted=false; this.timeStamp=performance.now();
state.set(this,{target:null,current:null,phase:0,canceled:false,stop:false,immediate:false,passive:false,path:[],dispatching:false}); }
get target(){return eventState(this).target;} get currentTarget(){return eventState(this).current;}
get eventPhase(){return eventState(this).phase;} get defaultPrevented(){return eventState(this).canceled;}
preventDefault(){const s=eventState(this);if(this.cancelable&&!s.passive)s.canceled=true;}
stopPropagation(){eventState(this).stop=true;}
stopImmediatePropagation(){const s=eventState(this);s.stop=s.immediate=true;}
composedPath(){return eventState(this).path.slice();}
get cancelBubble(){return eventState(this).stop;} set cancelBubble(v){if(v)this.stopPropagation();}
get returnValue(){return !this.defaultPrevented;} set returnValue(v){if(!v)this.preventDefault();}
initEvent(type,bubbles=false,cancelable=false){if(!eventState(this).dispatching){this.type=String(type);this.bubbles=!!bubbles;this.cancelable=!!cancelable;}}
}
Event.NONE=0;Event.CAPTURING_PHASE=1;Event.AT_TARGET=2;Event.BUBBLING_PHASE=3;
class CustomEvent extends Event {constructor(type,init={}){super(type,init);this.detail=init.detail??null;}}
class UIEvent extends Event {constructor(type,init={}){super(type,init);this.detail=init.detail??0;this.view=window;}}
class MouseEvent extends UIEvent {constructor(type,init={}){super(type,init);for(const k of ['clientX','clientY','screenX','screenY','button','buttons','ctrlKey','shiftKey','altKey','metaKey'])this[k]=init[k]??0;
this.x=this.clientX;this.y=this.clientY;this.pageX=this.clientX+(window.scrollX||0);this.pageY=this.clientY+(window.scrollY||0);this.offsetX=init.offsetX??this.clientX;this.offsetY=init.offsetY??this.clientY;this.relatedTarget=init.relatedTarget??null;}
getModifierState(key){return !!this[{Control:'ctrlKey',Shift:'shiftKey',Alt:'altKey',Meta:'metaKey'}[key]];}}
class PointerEvent extends MouseEvent {constructor(type,init={}){super(type,init);this.pointerId=init.pointerId??1;this.pointerType=init.pointerType??'mouse';this.isPrimary=true;this.width=this.height=1;this.pressure=this.buttons?.5:0;this.tiltX=this.tiltY=0;}}
class WheelEvent extends MouseEvent {constructor(type,init={}){super(type,init);this.deltaX=init.deltaX??0;this.deltaY=init.deltaY??0;this.deltaMode=0;}}
const physicalKeyCodes={Semicolon:186,Equal:187,Comma:188,Minus:189,Period:190,Slash:191,Backquote:192,BracketLeft:219,Backslash:220,BracketRight:221,Quote:222,
NumpadMultiply:106,NumpadAdd:107,NumpadSubtract:109,NumpadDecimal:110,NumpadDivide:111,NumpadEnter:13,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,ContextMenu:93,CapsLock:20,NumLock:144,ScrollLock:145};
class KeyboardEvent extends UIEvent {constructor(type,init={}){super(type,init);this.key=init.key??'';this.code=init.code??'';this.repeat=!!init.repeat;
this.ctrlKey=!!init.ctrlKey;this.shiftKey=!!init.shiftKey;this.altKey=!!init.altKey;this.metaKey=!!init.metaKey;
this.charCode=type==='keypress'&&this.key.length>0?this.key.codePointAt(0):0;
const physical=/^Key[A-Z]$/.test(this.code)?this.code.charCodeAt(3):/^Digit[0-9]$/.test(this.code)?this.code.charCodeAt(5):/^Numpad[0-9]$/.test(this.code)?96+Number(this.code[6]):physicalKeyCodes[this.code];
this.keyCode=init.keyCode??(type==='keypress'?this.charCode:physical??(this.key.length===1?this.key.toUpperCase().charCodeAt(0):({Enter:13,Escape:27,Backspace:8,Tab:9,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Delete:46,Home:36,End:35,Insert:45,PageUp:33,PageDown:34,Shift:16,Control:17,Alt:18,Meta:91,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123}[this.key]??0)));this.which=this.keyCode;this.location=0;this.isComposing=false;}
getModifierState(key){return !!this[{Control:'ctrlKey',Shift:'shiftKey',Alt:'altKey',Meta:'metaKey'}[key]];}}
class InputEvent extends UIEvent {constructor(type,init={}){super(type,init);this.data=init.data??null;this.inputType=init.inputType??'';this.isComposing=false;}}
function add(type,callback,options=false){if(callback==null)return;if(typeof callback!=='function'&&typeof callback.handleEvent!=='function')throw new TypeError('Invalid listener');
type=String(type);const capture=typeof options==='boolean'?options:!!options.capture;
let list=listeners.get(this);if(!list)listeners.set(this,list=[]);else if(list.length>64)listeners.set(this,list=list.filter(x=>!x.removed));
if(!list.some(x=>!x.removed&&x.type===type&&x.callback===callback&&x.capture===capture)){
listenerAdded();list.push({type,callback,capture,once:!!options.once,passive:!!options.passive,removed:false});}}
function remove(type,callback,options=false){const list=listeners.get(this)||[],capture=typeof options==='boolean'?options:!!options.capture;
for(const x of list)if(!x.removed&&x.type===String(type)&&x.callback===callback&&x.capture===capture){x.removed=true;listenerRemoved();}}
function invoke(target,event,capture,phase){const s=eventState(event);s.current=target;s.phase=phase;
for(const l of (listeners.get(target)||[]).slice()){
if(s.immediate)break;if(l.removed||l.type!==event.type||l.capture!==capture)continue;
if(l.once){l.removed=true;listenerRemoved();}s.passive=l.passive;
try{if(typeof l.callback==='function')l.callback.call(target,event);else l.callback.handleEvent(event);}catch(error){eventError(String(error));}
s.passive=false;
}
if(!capture&&!s.immediate){const handler=target['on'+event.type];if(typeof handler==='function'){
try{if(handler.call(target,event)===false)event.preventDefault();}catch(error){eventError(String(error));}}}
}
function dispatch(event){const s=eventState(event);if(s.dispatching)throw new Error('Event is already dispatching');if(!event.type)throw new TypeError('Empty event type');
s.dispatching=true;s.target=this;s.stop=s.immediate=false;s.path=[this];let parent=this.parentNode;
if(event instanceof MouseEvent&&typeof this.getBoundingClientRect==='function'){const rect=this.getBoundingClientRect();event.offsetX=event.clientX-rect.left;event.offsetY=event.clientY-rect.top;}
while(parent){s.path.push(parent);parent=parent.parentNode;}if(s.path[s.path.length-1]===document)s.path.push(window);
try{
for(let i=s.path.length-1;i>0&&!s.stop;i--)invoke(s.path[i],event,true,1);
if(!s.stop){invoke(this,event,true,2);if(!s.immediate)invoke(this,event,false,2);}
if(event.bubbles)for(let i=1;ix.target===target);
if(existing){existing.options=options;return;}if(this.targets.length>=1024)throw new Error('Mutation observer target limit reached');this.targets.push({target,options});observers.add(this);}
disconnect(){observers.delete(this);this.targets=[];this.records=[];}
takeRecords(){const records=this.records;this.records=[];return records;}
}
window.MutationObserver=MutationObserver;
const resizeObservers=new Set();let resizeQueued=false;
function notifyResize(){if(resizeQueued||resizeObservers.size===0)return;resizeQueued=true;requestAnimationFrame(function(){resizeQueued=false;
for(const observer of Array.from(resizeObservers)){const entries=[];
for(const observed of observer.targets){const rect=observed.target.getBoundingClientRect();
if(observed.width===rect.width&&observed.height===rect.height)continue;observed.width=rect.width;observed.height=rect.height;
const css=getComputedStyle(observed.target),edge=name=>parseFloat(css.getPropertyValue(name))||0;
const px=edge('padding-left'),py=edge('padding-top'),width=Math.max(0,rect.width-px-edge('padding-right')-edge('border-left-width')-edge('border-right-width')),
height=Math.max(0,rect.height-py-edge('padding-bottom')-edge('border-top-width')-edge('border-bottom-width'));
const size={inlineSize:width,blockSize:height};entries.push({target:observed.target,contentRect:{x:px,y:py,left:px,top:py,right:px+width,bottom:py+height,width,height},contentBoxSize:[size],borderBoxSize:[{inlineSize:rect.width,blockSize:rect.height}],devicePixelContentBoxSize:[size]});}
if(entries.length)observer.callback(entries,observer);
}
});}
class ResizeObserver {
constructor(callback){if(typeof callback!=='function')throw new TypeError('Expected callback');this.callback=callback;this.targets=[];}
observe(target){if(!target||typeof target.getBoundingClientRect!=='function')throw new TypeError('Expected Element');
if(this.targets.some(x=>x.target===target))return;if(this.targets.length>=1024)throw new Error('Resize observer target limit reached');
if(!resizeObservers.has(this))observerAdded(resizeObservers.size+1);this.targets.push({target,width:null,height:null});resizeObservers.add(this);notifyResize();}
unobserve(target){this.targets=this.targets.filter(x=>x.target!==target);if(!this.targets.length)resizeObservers.delete(this);}
disconnect(){this.targets=[];resizeObservers.delete(this);}
}
window.ResizeObserver=ResizeObserver;
function mutation(target,type,name,oldValue,added,removed){for(const observer of observers){
if(!observer.targets.some(x=>(x.target===target||(x.options.subtree&&x.target.contains(target)))&&!!x.options[type]))continue;
if(observer.records.length>=1024)throw new Error('Mutation record limit reached');
observer.records.push({type,target,attributeName:name,oldValue,addedNodes:added||[],removedNodes:removed||[]});
if(!observer.queued){observer.queued=true;queueMicrotask(function(){observer.queued=false;const records=observer.takeRecords();if(records.length)observer.callback(records,observer);});}
}notifyResize();}
function list(array){Object.defineProperty(array,'item',{value:function(i){return this[i]??null;}});Object.defineProperty(array,'namedItem',{value:function(name){return this.find(e=>e.id===name||e.getAttribute?.('name')===name)??null;}});return array;}
function liveList(read){const target={item(i){return read()[i]??null;},namedItem(name){return read().find(e=>e.id===name||e.getAttribute?.('name')===name)??null;},
forEach(callback,thisArg){read().forEach(callback,thisArg);},[Symbol.iterator](){return read()[Symbol.iterator]();}};
return new Proxy(target,{get(target,name){if(name==='length')return read().length;if(typeof name==='string'&&/^\d+$/.test(name))return read()[+name];return target[name];}});}
function style(node){return new Proxy({getPropertyValue(name){return node.__styleGet(String(name));},setProperty(name,value,priority=''){node.__styleSet(String(name),String(value),String(priority));},
removeProperty(name){const old=node.__styleGet(String(name));node.__styleSet(String(name),'','');return old;},
get cssText(){return node.getAttribute('style')||'';},set cssText(value){node.setAttribute('style',String(value));}},
{get(target,name){if(typeof name==='symbol'||name in target)return target[name];return node.__styleGet(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()));},
set(target,name,value){if(name in target){target[name]=value;return true;}node.__styleSet(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()),String(value),'');return true;}});}
function classList(node){function tokens(){return (node.className||'').trim().split(/\s+/).filter(Boolean);}function put(t){node.className=t.join(' ');}
return {contains(token){return tokens().includes(String(token));},add(...a){const t=tokens();for(const v of a){if(!v||/\s/.test(v))throw new Error('Invalid class token');if(!t.includes(String(v)))t.push(String(v));}put(t);},
remove(...a){put(tokens().filter(v=>!a.includes(v)));},toggle(token,force){const exists=this.contains(token),want=force===undefined?!exists:!!force;if(want)this.add(token);else this.remove(token);return want;},
replace(oldValue,newValue){const t=tokens(),i=t.indexOf(oldValue);if(i<0)return false;t[i]=newValue;put(t);return true;},item(i){return tokens()[i]??null;},
get length(){return tokens().length;},get value(){return node.className;},set value(v){node.className=String(v);},toString(){return node.className;},[Symbol.iterator](){return tokens()[Symbol.iterator]();}};}
class DOMStringMap {constructor(){throw new TypeError('Illegal constructor');}}
Object.defineProperty(DOMStringMap.prototype,Symbol.toStringTag,{value:'DOMStringMap',configurable:true});
window.DOMStringMap=DOMStringMap;
const sheetStates=new WeakMap();
class CSSRule {constructor(text){Object.defineProperty(this,'cssText',{get(){return text;},enumerable:true});Object.defineProperty(this,'type',{value:text.startsWith('@')?0:1,enumerable:true});} }
Object.assign(CSSRule,{STYLE_RULE:1,IMPORT_RULE:3,MEDIA_RULE:4,FONT_FACE_RULE:5,PAGE_RULE:6,KEYFRAMES_RULE:7,KEYFRAME_RULE:8,SUPPORTS_RULE:12});
class CSSStyleSheet {
constructor(){const id=cssom.create(),rules=liveList(()=>cssom.rules(id).map(text=>new CSSRule(text)));sheetStates.set(this,{id,rules});this.disabled=false;}
get cssRules(){return sheetStates.get(this).rules;}
get rules(){return this.cssRules;}
get ownerNode(){return null;}get parentStyleSheet(){return null;}get href(){return null;}
insertRule(rule,index=0){return cssom.insert(sheetStates.get(this).id,String(rule),Number(index));}
deleteRule(index){cssom.delete(sheetStates.get(this).id,Number(index));}
replaceSync(text){cssom.replace(sheetStates.get(this).id,String(text));}
replace(text){return Promise.resolve().then(()=>{this.replaceSync(text);return this;});}
}
window.CSSStyleSheet=CSSStyleSheet;window.CSSRule=CSSRule;
function dataset(node){
const attribute=key=>'data-'+String(key).replace(/[A-Z]/g,c=>'-'+c.toLowerCase());
const names=()=>Array.from(node.attributes).map(a=>a.name).filter(n=>n.startsWith('data-')&&!/[A-Z]/.test(n))
.map(n=>n.slice(5).replace(/-([a-z])/g,(_,c)=>c.toUpperCase()));
const put=(key,value)=>{if(typeof key!=='string')return false;if(/-[a-z]/.test(key)){const error=new Error('A dataset property may not contain a hyphen followed by a lowercase letter');error.name='SyntaxError';throw error;}
node.setAttribute(attribute(key),String(value));return true;};
return new Proxy(Object.create(DOMStringMap.prototype),{
get(target,key,receiver){if(typeof key==='string'){const value=node.getAttribute(attribute(key));if(value!==null)return value;}return Reflect.get(target,key,receiver);},
set(target,key,value){return put(key,value);},
has(target,key){return typeof key==='string'&&node.hasAttribute(attribute(key))||Reflect.has(target,key);},
ownKeys(){return names();},
getOwnPropertyDescriptor(target,key){if(typeof key==='string'&&node.hasAttribute(attribute(key)))return {value:node.getAttribute(attribute(key)),writable:true,enumerable:true,configurable:true};return Reflect.getOwnPropertyDescriptor(target,key);},
defineProperty(target,key,descriptor){if(descriptor.get||descriptor.set||descriptor.configurable===false||descriptor.enumerable===false||descriptor.writable===false)return false;return put(key,descriptor.value);},
deleteProperty(target,key){if(typeof key==='string')node.removeAttribute(attribute(key));return true;}
});}
function init(node,type){Object.setPrototypeOf(node,type===9?Document.prototype:type===11?DocumentFragment.prototype:type===3?Text.prototype:type===8?Comment.prototype:HTMLElement.prototype);
if(type===1){Object.defineProperty(node,'style',{value:style(node)});Object.defineProperty(node,'classList',{value:classList(node)});Object.defineProperty(node,'dataset',{value:dataset(node)});}
return node;}
function computed(node){return new Proxy({getPropertyValue(name){return node.__computed(String(name));}},
{get(target,name){if(typeof name==='symbol'||name in target)return target[name];return node.__computed(String(name).replace(/[A-Z]/g,x=>'-'+x.toLowerCase()));}});}
window.getComputedStyle=computed;
window.matchMedia=function(query){const value=new EventTarget();value.media=String(query);value.matches=/prefers-reduced-motion/.test(query)?true:false;value.onchange=null;value.addListener=value.addEventListener.bind(value,'change');value.removeListener=value.removeEventListener.bind(value,'change');return value;};
window.CSS={supports:function(){return false;},escape:function(value){return String(value).replace(/[^a-zA-Z0-9_-]/g,c=>'\\'+c.codePointAt(0).toString(16)+' ');}};
class TextEncoder {get encoding(){return 'utf-8';}encode(value=''){return encoding.encode(String(value));}
encodeInto(value,destination){if(!(destination instanceof Uint8Array))throw new TypeError('Expected Uint8Array');let read=0,written=0;
for(const character of String(value)){const bytes=this.encode(character);if(written+bytes.length>destination.length)break;destination.set(bytes,written);written+=bytes.length;read+=character.length;}return {read,written};}}
class TextDecoder {constructor(label='utf-8',options={}){label=String(label).trim().toLowerCase();const names={'utf-8':'utf-8',utf8:'utf-8','unicode-1-1-utf-8':'utf-8','utf-16':'utf-16le','utf-16le':'utf-16le','utf-16be':'utf-16be'};
if(!Object.hasOwn(names,label))throw new RangeError('Only UTF-8 and UTF-16 decoding are supported');this.encoding=names[label];this.fatal=!!options.fatal;this.ignoreBOM=!!options.ignoreBOM;this.id=encoding.decoder(this.fatal,this.ignoreBOM,this.encoding);}
decode(value,options={}){return encoding.decode(this.id,value,!!options.stream);}}
window.TextEncoder=TextEncoder;window.TextDecoder=TextDecoder;
return {init,list,liveList,mutation,notifyResize,pixelArray:function(length){return new Uint8ClampedArray(length);},byteArray:function(length){return new Uint8Array(length);},bytesOf:function(value){
if(value===undefined)return new Uint8Array(0);if(ArrayBuffer.isView(value))return new Uint8Array(value.buffer,value.byteOffset,value.byteLength);if(value instanceof ArrayBuffer)return new Uint8Array(value);throw new TypeError('Expected ArrayBuffer or view');},
dispatch:function(target,event){const result=dispatch.call(target,event);if(event.type==='resize'||event.type==='load')notifyResize();return result;},event:function(type,init){
const ctor=/^key/.test(type)?KeyboardEvent:/^(input|beforeinput)$/.test(type)?InputEvent:type==='wheel'?WheelEvent:/^pointer/.test(type)?PointerEvent:/^(mouse|click|dblclick|contextmenu)/.test(type)?MouseEvent:Event;
return new ctor(type,init);}};
})()
""";
}