///|
/// QuickJS runtime JavaScript FFI
///
/// This file owns the embedded JavaScript VM/mock-DOM source. Runtime state
/// and DOM operation application stay in sibling files.
///|
/// FFI: Initialize QuickJS runtime (must be called before execution)
/// Returns true if initialization succeeded
/// Note: QuickJS requires async init, so we fall back to Node.js vm if not pre-initialized
extern "js" fn quickjs_init() -> Bool =
#| () => {
#| // Check if QuickJS was pre-initialized
#| if (globalThis.__quickjs_initialized && globalThis.__quickjs) {
#| return true;
#| }
#| // QuickJS requires async init - fall back to Node.js vm for now
#| // To use QuickJS, call initQuickJS() before using the runtime
#| globalThis.__use_nodejs_vm = true;
#| return true;
#| }
///|
/// FFI: Execute JavaScript code with DOM mock
/// Uses QuickJS if initialized, otherwise falls back to Node.js vm
/// Returns JSON: { success, value, logs, domOps, error? }
extern "js" fn quickjs_execute_with_mock_dom(
context_id : Int,
init_code : String,
code : String,
flush_async : Bool,
) -> String =
#| (contextId, initCode, code, flushAsync) => {
#| const persistentContexts = globalThis.__craterPersistentJsContexts || (globalThis.__craterPersistentJsContexts = new Map());
#| // Mock DOM setup code (shared between QuickJS and Node.js vm)
#| const setupCode = `
#| const logs = [];
#| const domOps = [];
#| let nodeIdCounter = 1000;
#| const mockElements = new Map();
#|
#| // Microtask queue for queueMicrotask()
#| const _microtaskQueue = [];
#| function queueMicrotask(callback) {
#| if (typeof callback !== 'function') {
#| throw new TypeError('queueMicrotask requires a function argument');
#| }
#| _microtaskQueue.push(callback);
#| }
#| // Process all queued microtasks (called after script execution)
#| function _flushMicrotasks() {
#| let count = 0;
#| const limit = 10000; // Prevent infinite loops
#| while (_microtaskQueue.length > 0 && count < limit) {
#| const task = _microtaskQueue.shift();
#| try { task(); } catch (e) { logs.push('[ERROR] Microtask: ' + e); }
#| count++;
#| }
#| if (count >= limit) {
#| logs.push('[ERROR] Microtask limit exceeded (possible infinite loop)');
#| }
#| }
#|
#| // Custom Promise implementation that uses _microtaskQueue for synchronous control
#| // This ensures Promise.then callbacks run during _flushMicrotasks()
#| const _PromiseState = { PENDING: 0, FULFILLED: 1, REJECTED: 2 };
#| function _SyncPromise(executor) {
#| this._state = _PromiseState.PENDING;
#| this._value = undefined;
#| this._handlers = [];
#| const resolve = (value) => {
#| if (this._state !== _PromiseState.PENDING) return;
#| if (value && typeof value.then === 'function') {
#| value.then(resolve, reject);
#| return;
#| }
#| this._state = _PromiseState.FULFILLED;
#| this._value = value;
#| this._handlers.forEach(h => queueMicrotask(() => h.onFulfilled(value)));
#| this._handlers = [];
#| };
#| const reject = (reason) => {
#| if (this._state !== _PromiseState.PENDING) return;
#| this._state = _PromiseState.REJECTED;
#| this._value = reason;
#| this._handlers.forEach(h => queueMicrotask(() => h.onRejected(reason)));
#| this._handlers = [];
#| };
#| try { executor(resolve, reject); } catch (e) { reject(e); }
#| }
#| _SyncPromise.prototype.then = function(onFulfilled, onRejected) {
#| return new _SyncPromise((resolve, reject) => {
#| const handle = (handler, value, fallback) => {
#| try {
#| if (typeof handler === 'function') {
#| resolve(handler(value));
#| } else {
#| fallback(value);
#| }
#| } catch (e) { reject(e); }
#| };
#| if (this._state === _PromiseState.FULFILLED) {
#| queueMicrotask(() => handle(onFulfilled, this._value, resolve));
#| } else if (this._state === _PromiseState.REJECTED) {
#| queueMicrotask(() => handle(onRejected, this._value, reject));
#| } else {
#| this._handlers.push({
#| onFulfilled: (v) => handle(onFulfilled, v, resolve),
#| onRejected: (r) => handle(onRejected, r, reject)
#| });
#| }
#| });
#| };
#| _SyncPromise.prototype.catch = function(onRejected) {
#| return this.then(undefined, onRejected);
#| };
#| _SyncPromise.prototype.finally = function(onFinally) {
#| return this.then(
#| v => { onFinally(); return v; },
#| r => { onFinally(); throw r; }
#| );
#| };
#| _SyncPromise.resolve = function(value) {
#| return new _SyncPromise(resolve => resolve(value));
#| };
#| _SyncPromise.reject = function(reason) {
#| return new _SyncPromise((_, reject) => reject(reason));
#| };
#| _SyncPromise.all = function(promises) {
#| return new _SyncPromise((resolve, reject) => {
#| const results = [];
#| let count = 0;
#| const arr = Array.from(promises);
#| if (arr.length === 0) { resolve([]); return; }
#| arr.forEach((p, i) => {
#| _SyncPromise.resolve(p).then(v => {
#| results[i] = v;
#| if (++count === arr.length) resolve(results);
#| }, reject);
#| });
#| });
#| };
#| _SyncPromise.race = function(promises) {
#| return new _SyncPromise((resolve, reject) => {
#| Array.from(promises).forEach(p => _SyncPromise.resolve(p).then(resolve, reject));
#| });
#| };
#| // Replace native Promise with our sync version
#| const Promise = _SyncPromise;
#|
#| // Fetch API implementation with mock support
#| const _fetchMocks = new Map();
#|
#| // Response class
#| class Response {
#| constructor(body, init) {
#| this._body = body || '';
#| this._init = init || {};
#| this.status = this._init.status || 200;
#| this.statusText = this._init.statusText || (this.status === 200 ? 'OK' : '');
#| this.ok = this.status >= 200 && this.status < 300;
#| this.headers = new Headers(this._init.headers);
#| this.type = 'basic';
#| this.url = this._init.url || '';
#| this._bodyUsed = false;
#| }
#| get bodyUsed() { return this._bodyUsed; }
#| _consumeBody() {
#| if (this._bodyUsed) throw new TypeError('Body already consumed');
#| this._bodyUsed = true;
#| return this._body;
#| }
#| text() {
#| return Promise.resolve(this._consumeBody());
#| }
#| json() {
#| return this.text().then(text => JSON.parse(text));
#| }
#| blob() {
#| return Promise.resolve(new Blob([this._consumeBody()]));
#| }
#| arrayBuffer() {
#| const text = this._consumeBody();
#| const buf = new ArrayBuffer(text.length);
#| const view = new Uint8Array(buf);
#| for (let i = 0; i < text.length; i++) view[i] = text.charCodeAt(i);
#| return Promise.resolve(buf);
#| }
#| clone() {
#| if (this._bodyUsed) throw new TypeError('Body already consumed');
#| return new Response(this._body, this._init);
#| }
#| }
#|
#| // Headers class
#| class Headers {
#| constructor(init) {
#| this._headers = {};
#| if (init) {
#| if (init instanceof Headers) {
#| init.forEach((v, k) => this.set(k, v));
#| } else if (Array.isArray(init)) {
#| init.forEach(([k, v]) => this.set(k, v));
#| } else {
#| Object.keys(init).forEach(k => this.set(k, init[k]));
#| }
#| }
#| }
#| get(name) { return this._headers[name.toLowerCase()] || null; }
#| set(name, value) { this._headers[name.toLowerCase()] = String(value); }
#| has(name) { return name.toLowerCase() in this._headers; }
#| delete(name) { delete this._headers[name.toLowerCase()]; }
#| append(name, value) {
#| const key = name.toLowerCase();
#| if (this._headers[key]) this._headers[key] += ', ' + value;
#| else this._headers[key] = String(value);
#| }
#| forEach(callback, thisArg) {
#| Object.keys(this._headers).forEach(k => callback.call(thisArg, this._headers[k], k, this));
#| }
#| keys() { return Object.keys(this._headers)[Symbol.iterator](); }
#| values() { return Object.values(this._headers)[Symbol.iterator](); }
#| entries() { return Object.entries(this._headers)[Symbol.iterator](); }
#| [Symbol.iterator]() { return this.entries(); }
#| }
#|
#| // Request class (simplified)
#| class Request {
#| constructor(input, init) {
#| this.url = typeof input === 'string' ? input : input.url;
#| this.method = (init && init.method) || 'GET';
#| this.headers = new Headers((init && init.headers) || {});
#| this._body = (init && init.body) || null;
#| }
#| text() { return Promise.resolve(this._body || ''); }
#| json() { return this.text().then(t => JSON.parse(t)); }
#| }
#|
#| // Blob class (simplified)
#| class Blob {
#| constructor(parts, options) {
#| this._parts = parts || [];
#| this.type = (options && options.type) || '';
#| this.size = this._parts.reduce((acc, p) => acc + (p.length || 0), 0);
#| }
#| text() { return Promise.resolve(this._parts.join('')); }
#| arrayBuffer() {
#| const text = this._parts.join('');
#| const buf = new ArrayBuffer(text.length);
#| const view = new Uint8Array(buf);
#| for (let i = 0; i < text.length; i++) view[i] = text.charCodeAt(i);
#| return Promise.resolve(buf);
#| }
#| }
#|
#| // fetch function
#| function fetch(input, init) {
#| return new Promise((resolve, reject) => {
#| const url = typeof input === 'string' ? input : input.url;
#| const mock = _fetchMocks.get(url);
#| if (mock) {
#| // Use mock response
#| queueMicrotask(() => {
#| const response = new Response(mock.body, {
#| status: mock.status || 200,
#| statusText: mock.statusText || '',
#| headers: mock.headers || {},
#| url: url
#| });
#| resolve(response);
#| });
#| } else {
#| // No mock - reject with network error
#| queueMicrotask(() => {
#| reject(new TypeError('Network request failed: no mock for ' + url));
#| });
#| }
#| });
#| }
#|
#| // Task queue for setTimeout/setInterval (populated by window.setTimeout)
#| // Note: _timers is defined later with window object
#| // Run one pending timeout and return true if there was one
#| function _runOneTimeout() {
#| const ids = Object.keys(_timers.timeouts);
#| if (ids.length === 0) return false;
#| // Sort by timeout value to run shorter timeouts first (simplified model)
#| ids.sort((a, b) => (_timers.timeouts[a].timeout || 0) - (_timers.timeouts[b].timeout || 0));
#| const id = ids[0];
#| const entry = _timers.timeouts[id];
#| delete _timers.timeouts[id];
#| try { entry.handler(); } catch (e) { logs.push('[ERROR] setTimeout: ' + e); }
#| return true;
#| }
#| // Run all pending timeouts (for testing - runs until queue is empty)
#| function _runAllTimeouts(maxIterations) {
#| let count = 0;
#| const limit = maxIterations || 100;
#| while (count < limit && _runOneTimeout()) { count++; }
#| return count;
#| }
#| function _runOneAnimationFrame() {
#| const ids = Object.keys(_animationFrames.callbacks);
#| if (ids.length === 0) return false;
#| ids.sort((a, b) => Number(a) - Number(b));
#| const id = ids[0];
#| const callback = _animationFrames.callbacks[id];
#| delete _animationFrames.callbacks[id];
#| try { callback(Date.now()); } catch (e) { logs.push('[ERROR] requestAnimationFrame: ' + e); }
#| return true;
#| }
#| // Check if there are pending timers
#| function _hasPendingTimers() {
#| return Object.keys(_timers.timeouts).length > 0 || Object.keys(_timers.intervals).length > 0;
#| }
#|
#| // DOMException class
#| function DOMException(message, name) {
#| Error.call(this, message);
#| this.message = message || '';
#| this.name = name || 'Error';
#| this.code = DOMException[name] || 0;
#| }
#| DOMException.prototype = Object.create(Error.prototype);
#| DOMException.prototype.constructor = DOMException;
#| DOMException.INDEX_SIZE_ERR = 1;
#| DOMException.HIERARCHY_REQUEST_ERR = 3;
#| DOMException.WRONG_DOCUMENT_ERR = 4;
#| DOMException.INVALID_CHARACTER_ERR = 5;
#| DOMException.NOT_FOUND_ERR = 8;
#| DOMException.NOT_SUPPORTED_ERR = 9;
#| DOMException.INUSE_ATTRIBUTE_ERR = 10;
#| DOMException.INVALID_STATE_ERR = 11;
#| DOMException.SYNTAX_ERR = 12;
#| DOMException.INVALID_MODIFICATION_ERR = 13;
#| DOMException.NAMESPACE_ERR = 14;
#| DOMException.IndexSizeError = 1;
#| DOMException.HierarchyRequestError = 3;
#| DOMException.WrongDocumentError = 4;
#| DOMException.InvalidCharacterError = 5;
#| DOMException.NotFoundError = 8;
#| DOMException.NotSupportedError = 9;
#| DOMException.InUseAttributeError = 10;
#| DOMException.InvalidStateError = 11;
#| DOMException.SyntaxError = 12;
#| DOMException.InvalidModificationError = 13;
#| DOMException.NamespaceError = 14;
#|
#| // DOMImplementation class
#| function DOMImplementation() {}
#|
#| // DOM interface classes for prototype chain
#| function Node() {}
#| Node.ELEMENT_NODE = 1;
#| Node.ATTRIBUTE_NODE = 2;
#| Node.TEXT_NODE = 3;
#| Node.CDATA_SECTION_NODE = 4;
#| Node.PROCESSING_INSTRUCTION_NODE = 7;
#| Node.COMMENT_NODE = 8;
#| Node.DOCUMENT_NODE = 9;
#| Node.DOCUMENT_TYPE_NODE = 10;
#| Node.DOCUMENT_FRAGMENT_NODE = 11;
#| Node.DOCUMENT_POSITION_DISCONNECTED = 1;
#| Node.DOCUMENT_POSITION_PRECEDING = 2;
#| Node.DOCUMENT_POSITION_FOLLOWING = 4;
#| Node.DOCUMENT_POSITION_CONTAINS = 8;
#| Node.DOCUMENT_POSITION_CONTAINED_BY = 16;
#| Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
#| Node.prototype.ELEMENT_NODE = 1;
#| Node.prototype.ATTRIBUTE_NODE = 2;
#| Node.prototype.TEXT_NODE = 3;
#| Node.prototype.CDATA_SECTION_NODE = 4;
#| Node.prototype.PROCESSING_INSTRUCTION_NODE = 7;
#| Node.prototype.COMMENT_NODE = 8;
#| Node.prototype.DOCUMENT_NODE = 9;
#| Node.prototype.DOCUMENT_TYPE_NODE = 10;
#| Node.prototype.DOCUMENT_FRAGMENT_NODE = 11;
#| Node.prototype.DOCUMENT_POSITION_DISCONNECTED = 1;
#| Node.prototype.DOCUMENT_POSITION_PRECEDING = 2;
#| Node.prototype.DOCUMENT_POSITION_FOLLOWING = 4;
#| Node.prototype.DOCUMENT_POSITION_CONTAINS = 8;
#| Node.prototype.DOCUMENT_POSITION_CONTAINED_BY = 16;
#| Node.prototype.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
#| if (typeof globalThis !== 'undefined') {
#| globalThis.Node = Node;
#| }
#|
#| function Attr() {}
#| Attr.prototype = Object.create(Node.prototype);
#| Attr.prototype.constructor = Attr;
#| if (typeof globalThis !== 'undefined') {
#| globalThis.Attr = Attr;
#| }
#|
#| Node.prototype.appendChild = function(child) {
#| if (typeof this.appendChild === 'function' && this.appendChild !== Node.prototype.appendChild) {
#| return this.appendChild(child);
#| }
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| }
#| throw new DOMException('Cannot append child to this node type', 'HierarchyRequestError');
#| };
#| Node.prototype.insertBefore = function(newChild, refChild) {
#| if (typeof this.insertBefore === 'function' && this.insertBefore !== Node.prototype.insertBefore) {
#| return this.insertBefore(newChild, refChild);
#| }
#| if (arguments.length < 2) {
#| throw new TypeError('Failed to execute insertBefore: 2 arguments required');
#| }
#| if (!isNodeLike(newChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| }
#| if (refChild !== null && refChild !== undefined && !isNodeLike(refChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 2 is not of type Node');
#| }
#| throw new DOMException('Cannot insert child into this node type', 'HierarchyRequestError');
#| };
#| Node.prototype.removeChild = function(child) {
#| if (typeof this.removeChild === 'function' && this.removeChild !== Node.prototype.removeChild) {
#| return this.removeChild(child);
#| }
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute removeChild: parameter 1 is not of type Node');
#| }
#| throw new DOMException('The node to be removed is not a child of this node', 'NotFoundError');
#| };
#| Node.prototype.replaceChild = function(newChild, oldChild) {
#| if (typeof this.replaceChild === 'function' && this.replaceChild !== Node.prototype.replaceChild) {
#| return this.replaceChild(newChild, oldChild);
#| }
#| if (!isNodeLike(newChild) || !isNodeLike(oldChild)) {
#| throw new TypeError('Failed to execute replaceChild: parameters are not of type Node');
#| }
#| throw new DOMException('Cannot replace child on this node type', 'HierarchyRequestError');
#| };
#| Object.defineProperty(Node.prototype, 'parentNode', {
#| get() { return this._parent === undefined ? null : this._parent; },
#| set(v) { this._parent = v; },
#| configurable: true
#| });
#| // assignedSlot belongs to the Slottable mixin (Element + Text), not all
#| // Nodes; it is installed on Element.prototype / Text.prototype below
#| // (near the Text constructor) so comment / PI / document nodes do not
#| // expose it.
#| Object.defineProperty(Node.prototype, 'parentElement', {
#| get() {
#| const p = this.parentNode;
#| return p && __craterGetNodeType(p) === 1 ? p : null;
#| },
#| configurable: true
#| });
#| Object.defineProperty(Node.prototype, 'nextSibling', {
#| get() {
#| const parent = getParentNode(this);
#| if (!parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx >= 0 ? (siblings[idx + 1] || null) : null;
#| },
#| configurable: true
#| });
#| Object.defineProperty(Node.prototype, 'previousSibling', {
#| get() {
#| const parent = getParentNode(this);
#| if (!parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx > 0 ? siblings[idx - 1] : null;
#| },
#| configurable: true
#| });
#| Node.prototype.hasChildNodes = function() {
#| const nodes = getChildNodesArray(this);
#| return nodes && nodes.length > 0;
#| };
#| Node.prototype.normalize = function() {
#| if (typeof this.normalize === 'function' && this.normalize !== Node.prototype.normalize) {
#| return this.normalize();
#| }
#| if (!this._children) return;
#| normalizeChildArray(this._children);
#| };
#| Node.prototype.contains = function(other) {
#| return nodeContains(this, other);
#| };
#| Node.prototype.compareDocumentPosition = function(other) {
#| return compareDocumentPositionImpl(this, other);
#| };
#| Node.prototype.lookupNamespaceURI = function(prefix) {
#| return lookupNamespaceURIImpl(this, prefix);
#| };
#| Node.prototype.isDefaultNamespace = function(namespace) {
#| const ns = namespace === undefined || namespace === null || namespace === '' ? null : String(namespace);
#| const nodeType = __craterGetNodeType(this);
#| if ((nodeType === 10 || nodeType === 11) && !getParentNode(this)) {
#| return ns === null;
#| }
#| const current = lookupNamespaceURIImpl(this, null);
#| return current === ns;
#| };
#| function getListenerStore(target) {
#| if (!target._listeners) target._listeners = Object.create(null);
#| return target._listeners;
#| }
#| const _persistedListenerAttrPrefix = 'data-crater-listeners-';
#| const _persistedListenerTypes = ['click', 'beforeinput', 'input', 'change', 'submit', 'copy', 'cut', 'paste', 'keydown', 'keypress', 'keyup', 'focus', 'blur', 'focusin', 'focusout', 'pointerdown', 'pointermove', 'pointerup', 'pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave', 'dragstart', 'drag', 'dragenter', 'dragover', 'dragleave', 'drop', 'dragend', 'compositionstart', 'compositionupdate', 'compositionend'];
#| function _shouldPersistListener(target, eventType, listener) {
#| return _persistedListenerTypes.includes(eventType) &&
#| target &&
#| typeof target.getAttribute === 'function' &&
#| typeof target.setAttribute === 'function' &&
#| typeof listener === 'function' &&
#| target._mockId !== undefined &&
#| !target.__craterRestoringListeners;
#| }
#| function _getPersistedListenerAttrName(eventType) {
#| return _persistedListenerAttrPrefix + eventType;
#| }
#| function _getPersistedListenerSources(target, eventType) {
#| const raw = target.getAttribute(_getPersistedListenerAttrName(eventType));
#| if (!raw) return [];
#| try {
#| const parsed = JSON.parse(raw);
#| return Array.isArray(parsed) ? parsed.filter(v => typeof v === 'string') : [];
#| } catch (e) {
#| return [];
#| }
#| }
#| function _setPersistedListenerSources(target, eventType, sources) {
#| const attrName = _getPersistedListenerAttrName(eventType);
#| if (!sources || sources.length === 0) {
#| if (target.hasAttribute(attrName)) target.removeAttribute(attrName);
#| return;
#| }
#| const encoded = JSON.stringify(sources);
#| if (target.getAttribute(attrName) !== encoded) {
#| target.setAttribute(attrName, encoded);
#| }
#| }
#| function _persistEventListener(target, eventType, listener) {
#| if (!_shouldPersistListener(target, eventType, listener)) return;
#| let source = '';
#| try { source = Function.prototype.toString.call(listener); } catch (e) { source = ''; }
#| if (!source || source.indexOf('[native code]') >= 0) return;
#| const sources = _getPersistedListenerSources(target, eventType);
#| if (!sources.includes(source)) {
#| sources.push(source);
#| _setPersistedListenerSources(target, eventType, sources);
#| }
#| }
#| function _removePersistedEventListener(target, eventType, listener) {
#| if (!_shouldPersistListener(target, eventType, listener)) return;
#| let source = '';
#| try { source = Function.prototype.toString.call(listener); } catch (e) { source = ''; }
#| if (!source) return;
#| const sources = _getPersistedListenerSources(target, eventType).filter(v => v !== source);
#| _setPersistedListenerSources(target, eventType, sources);
#| }
#| function _restorePersistedListenersForNode(target) {
#| if (!target || typeof target.getAttribute !== 'function') return;
#| target.__craterRestoringListeners = true;
#| try {
#| const store = getListenerStore(target);
#| for (const eventType of _persistedListenerTypes) {
#| const sources = _getPersistedListenerSources(target, eventType);
#| if (sources.length === 0) continue;
#| if (!store[eventType]) store[eventType] = [];
#| for (const source of sources) {
#| try {
#| const listener = eval('(' + source + ')');
#| const hasListener = store[eventType].some((entry) => {
#| const callback = entry && typeof entry === 'object' && 'callback' in entry
#| ? entry.callback
#| : entry;
#| const capture = !!(entry && typeof entry === 'object' && entry.capture);
#| return callback === listener && !capture;
#| });
#| if (!hasListener) store[eventType].push({ callback: listener, capture: false });
#| } catch (e) {
#| logs.push('[WARN] restore ' + eventType + ' listener failed: ' + e);
#| }
#| }
#| }
#| } finally {
#| target.__craterRestoringListeners = false;
#| }
#| }
#| function _restorePersistedListenersTree(root) {
#| if (!root) return;
#| _restorePersistedListenersForNode(root);
#| const children = root.childNodes || [];
#| for (let i = 0; i < children.length; i++) {
#| _restorePersistedListenersTree(children[i]);
#| }
#| }
#| function parseCaptureOption(options) {
#| if (options === true) return true;
#| if (options === false || options === undefined || options === null) return false;
#| if (typeof options === 'object') return !!options.capture;
#| return false;
#| }
#| function addEventListenerImpl(target, type, listener, options) {
#| if (listener === null || listener === undefined) return;
#| const eventType = String(type);
#| const capture = parseCaptureOption(options);
#| const store = getListenerStore(target);
#| if (!store[eventType]) store[eventType] = [];
#| const hasListener = store[eventType].some((entry) => {
#| const callback = entry && typeof entry === 'object' && 'callback' in entry
#| ? entry.callback
#| : entry;
#| const existingCapture = !!(entry && typeof entry === 'object' && entry.capture);
#| return callback === listener && existingCapture === capture;
#| });
#| if (!hasListener) store[eventType].push({ callback: listener, capture });
#| if (!capture) _persistEventListener(target, eventType, listener);
#| }
#| function removeEventListenerImpl(target, type, listener, options) {
#| if (listener === null || listener === undefined || !target._listeners) return;
#| const eventType = String(type);
#| const capture = parseCaptureOption(options);
#| const list = target._listeners[eventType];
#| if (!list) return;
#| const index = list.findIndex((entry) => {
#| const callback = entry && typeof entry === 'object' && 'callback' in entry
#| ? entry.callback
#| : entry;
#| const existingCapture = !!(entry && typeof entry === 'object' && entry.capture);
#| return callback === listener && existingCapture === capture;
#| });
#| if (index >= 0) list.splice(index, 1);
#| if (!capture) _removePersistedEventListener(target, eventType, listener);
#| }
#| function getContainingShadowRoot(node) {
#| let current = node;
#| while (current) {
#| if (current._isShadowRoot) return current;
#| current = getParentNode(current);
#| }
#| return null;
#| }
#| function getDeepActiveElement(doc) {
#| if (!doc) return null;
#| let current = doc._activeElement || null;
#| const visited = new Set();
#| while (current && !visited.has(current)) {
#| visited.add(current);
#| const shadowRoot = current._shadowRoot || current.shadowRoot || null;
#| if (shadowRoot && shadowRoot._activeElement) {
#| current = shadowRoot._activeElement;
#| continue;
#| }
#| break;
#| }
#| return current;
#| }
#| function clearDocumentActiveChain(doc) {
#| if (!doc) return;
#| let current = doc._activeElement || null;
#| const visited = new Set();
#| while (current && !visited.has(current)) {
#| visited.add(current);
#| const shadowRoot = current._shadowRoot || current.shadowRoot || null;
#| if (shadowRoot && shadowRoot._activeElement) {
#| const next = shadowRoot._activeElement;
#| shadowRoot._activeElement = null;
#| current = next;
#| continue;
#| }
#| break;
#| }
#| doc._activeElement = null;
#| }
#| function dispatchFocusFamilyEvent(target, type, bubbles, relatedTarget) {
#| if (!target) return;
#| const event = new FocusEvent(type, {
#| bubbles: !!bubbles,
#| composed: true,
#| relatedTarget: relatedTarget || null,
#| });
#| dispatchEventImpl(target, event);
#| }
#| function focusNodeImpl(node) {
#| const delegatedTarget = getDelegatesFocusTarget(node);
#| if (delegatedTarget && delegatedTarget !== node) {
#| focusNodeImpl(delegatedTarget);
#| return;
#| }
#| const doc = getOwnerDocument(node) || (typeof document !== 'undefined' ? document : null);
#| const shadowRoot = getContainingShadowRoot(node);
#| const isConnected =
#| isConnectedToDocument(node) ||
#| (shadowRoot && isConnectedToDocument(shadowRoot));
#| if (!doc || !isConnected) return;
#| const previous = getDeepActiveElement(doc);
#| if (previous === node) return;
#| if (previous) {
#| dispatchFocusFamilyEvent(previous, 'blur', false, node);
#| dispatchFocusFamilyEvent(previous, 'focusout', true, node);
#| }
#| clearDocumentActiveChain(doc);
#| if (shadowRoot && shadowRoot.host) {
#| shadowRoot._activeElement = node;
#| doc._activeElement = shadowRoot.host;
#| } else {
#| doc._activeElement = node;
#| }
#| dispatchFocusFamilyEvent(node, 'focus', false, previous);
#| dispatchFocusFamilyEvent(node, 'focusin', true, previous);
#| }
#| function blurNodeImpl(node) {
#| const doc = getOwnerDocument(node) || (typeof document !== 'undefined' ? document : null);
#| if (!doc) return;
#| let target = node;
#| const ownShadowRoot = node && (node._shadowRoot || node.shadowRoot || null);
#| if (ownShadowRoot && ownShadowRoot._activeElement) {
#| target = ownShadowRoot._activeElement;
#| }
#| const active = getDeepActiveElement(doc);
#| if (active && active !== target && active !== node) return;
#| const shadowRoot = getContainingShadowRoot(target);
#| dispatchFocusFamilyEvent(target, 'blur', false, null);
#| dispatchFocusFamilyEvent(target, 'focusout', true, null);
#| if (shadowRoot && shadowRoot._activeElement === target) {
#| shadowRoot._activeElement = null;
#| if (doc._activeElement === shadowRoot.host) {
#| doc._activeElement = null;
#| }
#| }
#| if (doc._activeElement === target || doc._activeElement === node) {
#| doc._activeElement = null;
#| }
#| if (!doc._activeElement) {
#| doc._activeElement = doc.body || null;
#| }
#| }
#| function clearFocusWithinSubtree(root) {
#| const doc = getOwnerDocument(root) || (typeof document !== 'undefined' ? document : null);
#| if (!doc) return;
#| const active = getDeepActiveElement(doc);
#| if (!active || !nodeContains(root, active)) return;
#| clearDocumentActiveChain(doc);
#| doc._activeElement = doc.body || null;
#| }
#| function getSequentialFocusChildren(node) {
#| if (!node) return [];
#| if (isSlotElementNode(node)) return getAssignedNodesForSlot(node);
#| const shadowRoot = node._shadowRoot || node.shadowRoot || null;
#| if (shadowRoot) return getChildNodesArray(shadowRoot);
#| return getChildNodesArray(node);
#| }
#| function hasExplicitSequentialTabIndex(node) {
#| if (!node || node._nodeType !== 1) return false;
#| try {
#| if (typeof node.hasAttribute === 'function' && node.hasAttribute('tabindex')) return true;
#| } catch (_e) {}
#| return !!(node._attrs && Object.prototype.hasOwnProperty.call(node._attrs, 'tabindex'));
#| }
#| function isSequentiallyFocusableNode(node) {
#| if (!node || node._nodeType !== 1) return false;
#| if (node.disabled || node.hidden) return false;
#| const style = node.style || {};
#| if (style.display === 'none' || style.visibility === 'hidden') return false;
#| if (hasExplicitSequentialTabIndex(node)) {
#| return Number(node.tabIndex) >= 0;
#| }
#| const tag = asciiLowercase(String(node.localName || node._tagName || ''));
#| if (tag === 'a') {
#| try { return !!(typeof node.getAttribute === 'function' ? node.getAttribute('href') : null); } catch (_e) { return false; }
#| }
#| if (tag === 'input' || tag === 'textarea' || tag === 'select' || tag === 'button') return true;
#| return !!node.isContentEditable;
#| }
#| function collectSequentialFocusableNodes(node, results) {
#| const children = getSequentialFocusChildren(node);
#| for (const child of children) {
#| if (!child || child._nodeType !== 1) continue;
#| if (isSequentiallyFocusableNode(child)) results.push(child);
#| collectSequentialFocusableNodes(child, results);
#| }
#| }
#| function moveSequentialFocus(doc, backward) {
#| if (!doc) return false;
#| const root = doc.body || doc.documentElement || doc;
#| const order = [];
#| collectSequentialFocusableNodes(root, order);
#| if (order.length === 0) return false;
#| const current = getDeepActiveElement(doc) || doc.activeElement || null;
#| const currentIndex = order.indexOf(current);
#| let nextIndex = 0;
#| if (currentIndex >= 0) {
#| nextIndex = currentIndex + (backward ? -1 : 1);
#| if (nextIndex < 0 || nextIndex >= order.length) return false;
#| } else if (backward) {
#| nextIndex = order.length - 1;
#| }
#| const next = order[nextIndex];
#| if (!next || typeof next.focus !== 'function') return false;
#| try { next.focus(); } catch (_e) { return false; }
#| return true;
#| }
#| function getDelegatesFocusTarget(node) {
#| if (!node) return null;
#| const shadowRoot = node._shadowRoot || node.shadowRoot || null;
#| if (!shadowRoot || !shadowRoot.delegatesFocus) return null;
#| const order = [];
#| collectSequentialFocusableNodes(shadowRoot, order);
#| return order.length > 0 ? order[0] : null;
#| }
#| function applySyntheticClickFocus(node) {
#| if (!node) return;
#| const delegatedTarget = getDelegatesFocusTarget(node);
#| if (delegatedTarget && delegatedTarget !== node) {
#| focusNodeImpl(delegatedTarget);
#| }
#| }
#| function getEventParent(node, event) {
#| if (!node) return null;
#| if (typeof window !== 'undefined' && node === window) return null;
#| if (node._nodeType === 9) {
#| return typeof window !== 'undefined' ? window : null;
#| }
#| if (node._isShadowRoot) {
#| if (event && event.composed && node.host) return node.host;
#| return null;
#| }
#| return getParentNode(node);
#| }
#| function buildEventPath(target, event) {
#| const path = [];
#| let current = target;
#| while (current) {
#| path.push(current);
#| current = getEventParent(current, event);
#| }
#| return path;
#| }
#| function retargetEventTarget(originalTarget, currentTarget) {
#| let candidate = originalTarget;
#| while (candidate) {
#| const shadowRoot = getContainingShadowRoot(candidate);
#| if (!shadowRoot) return candidate;
#| if (currentTarget === shadowRoot || nodeContains(shadowRoot, currentTarget)) {
#| return candidate;
#| }
#| candidate = shadowRoot.host || candidate;
#| if (!shadowRoot.host) return candidate;
#| }
#| return originalTarget;
#| }
#| function invokeEventListeners(currentTarget, event, eventType, originalTarget, capturePhase, includeInlineHandlers) {
#| const adjustedTarget = retargetEventTarget(originalTarget, currentTarget);
#| const originalRelatedTarget =
#| event._originalRelatedTarget !== undefined
#| ? event._originalRelatedTarget
#| : (event.relatedTarget || null);
#| event._originalRelatedTarget = originalRelatedTarget;
#| const adjustedRelatedTarget = originalRelatedTarget
#| ? retargetEventTarget(originalRelatedTarget, currentTarget)
#| : null;
#| event._target = adjustedTarget;
#| event.target = adjustedTarget;
#| event._relatedTarget = adjustedRelatedTarget;
#| event.relatedTarget = adjustedRelatedTarget;
#| event._currentTarget = currentTarget;
#| event.currentTarget = currentTarget;
#| if (adjustedTarget && adjustedRelatedTarget && adjustedTarget === adjustedRelatedTarget) {
#| return;
#| }
#| if (includeInlineHandlers) {
#| const propName = 'on' + eventType;
#| const inlineHandler = currentTarget.getAttribute ? currentTarget.getAttribute(propName) : null;
#| if (inlineHandler !== null && inlineHandler !== undefined) {
#| const handler = Function('event', 'with(globalThis){ with(this){ ' + String(inlineHandler) + ' } }');
#| handler.call(currentTarget, event);
#| if (event._immediatePropagationStopped) return;
#| }
#| const propHandler = currentTarget[propName];
#| if (typeof propHandler === 'function') {
#| propHandler.call(currentTarget, event);
#| if (event._immediatePropagationStopped) return;
#| }
#| }
#| const listeners = currentTarget._listeners && currentTarget._listeners[eventType]
#| ? currentTarget._listeners[eventType].slice()
#| : [];
#| for (const entry of listeners) {
#| const callback = entry && typeof entry === 'object' && 'callback' in entry
#| ? entry.callback
#| : entry;
#| const listenerCapture = !!(entry && typeof entry === 'object' && entry.capture);
#| if (listenerCapture !== capturePhase) continue;
#| if (typeof callback === 'function') {
#| callback.call(currentTarget, event);
#| } else if (callback && typeof callback.handleEvent === 'function') {
#| callback.handleEvent(event);
#| }
#| if (event._immediatePropagationStopped) return;
#| }
#| }
#| function dispatchEventImpl(target, event) {
#| if (!event || typeof event !== 'object') {
#| throw new TypeError('Failed to execute dispatchEvent: parameter 1 is not of type Event');
#| }
#| const eventType = String(event.type || event._type || '');
#| event._type = eventType;
#| event._originalTarget = target;
#| event._path = buildEventPath(target, event);
#| event._propagationStopped = false;
#| event._immediatePropagationStopped = false;
#| for (let i = event._path.length - 1; i >= 1; i--) {
#| const currentTarget = event._path[i];
#| event._immediatePropagationStopped = false;
#| event._eventPhase = Event.CAPTURING_PHASE;
#| invokeEventListeners(currentTarget, event, eventType, target, true, false);
#| if (event._propagationStopped) break;
#| }
#| if (!event._propagationStopped) {
#| event._eventPhase = Event.AT_TARGET;
#| event._immediatePropagationStopped = false;
#| invokeEventListeners(target, event, eventType, target, true, false);
#| if (!event._immediatePropagationStopped) {
#| invokeEventListeners(target, event, eventType, target, false, true);
#| }
#| }
#| if (event.bubbles && !event._propagationStopped) {
#| for (let i = 1; i < event._path.length; i++) {
#| const currentTarget = event._path[i];
#| event._immediatePropagationStopped = false;
#| event._eventPhase = Event.BUBBLING_PHASE;
#| invokeEventListeners(currentTarget, event, eventType, target, false, true);
#| if (event._propagationStopped) break;
#| }
#| }
#| event._target = target;
#| event.target = target;
#| const originalRelatedTarget =
#| event._originalRelatedTarget !== undefined
#| ? event._originalRelatedTarget
#| : (event.relatedTarget || null);
#| event._relatedTarget = originalRelatedTarget;
#| event.relatedTarget = originalRelatedTarget;
#| event._currentTarget = null;
#| event.currentTarget = null;
#| event._eventPhase = Event.NONE;
#| if (!event.defaultPrevented && eventType === 'keydown' && String(event.key || '') === 'Tab') {
#| const doc = getOwnerDocument(target) || (typeof document !== 'undefined' ? document : null);
#| moveSequentialFocus(doc, !!event.shiftKey);
#| }
#| return !event.defaultPrevented;
#| }
#| Node.prototype.addEventListener = function(type, listener, options) { addEventListenerImpl(this, type, listener, options); };
#| Node.prototype.removeEventListener = function(type, listener, options) { removeEventListenerImpl(this, type, listener, options); };
#| Node.prototype.dispatchEvent = function(event) { return dispatchEventImpl(this, event); };
#|
#| function CharacterData() {}
#| CharacterData.prototype = Object.create(Node.prototype);
#| CharacterData.prototype.constructor = CharacterData;
#|
#| function Element() {}
#| Element.prototype = Object.create(Node.prototype);
#| Element.prototype.constructor = Element;
#| Object.defineProperty(Element.prototype, 'fetchPriority', {
#| get() {
#| const value = this.getAttribute ? String(this.getAttribute('fetchpriority') || '').toLowerCase() : '';
#| return value === 'high' || value === 'low' || value === 'auto' ? value : 'auto';
#| },
#| set(v) {
#| const value = String(v || '').toLowerCase();
#| const normalized = value === 'high' || value === 'low' || value === 'auto' ? value : 'auto';
#| if (this.setAttribute) this.setAttribute('fetchpriority', normalized);
#| },
#| configurable: true
#| });
#| Element.prototype[Symbol.unscopables] = {
#| before: true,
#| after: true,
#| replaceWith: true,
#| remove: true,
#| prepend: true,
#| append: true,
#| };
#|
#| function NodeList() {}
#| NodeList.prototype = Object.create(Array.prototype);
#| NodeList.prototype.constructor = NodeList;
#| NodeList.prototype.item = function(i) {
#| const items = this._itemsFn ? this._itemsFn() : this;
#| return items[i] || null;
#| };
#| Object.defineProperty(NodeList.prototype, 'length', {
#| get() {
#| const items = this._itemsFn ? this._itemsFn() : (this._items || this);
#| return (items && typeof items.length === 'number') ? items.length : 0;
#| },
#| configurable: true
#| });
#|
#| function HTMLCollection() {}
#| HTMLCollection.prototype = Object.create(Array.prototype);
#| HTMLCollection.prototype.constructor = HTMLCollection;
#| HTMLCollection.prototype.item = function(i) {
#| const items = this._itemsFn ? this._itemsFn() : this;
#| if (arguments.length === 0) return null;
#| const index = Number(i) >>> 0;
#| return items[index] || null;
#| };
#| HTMLCollection.prototype.namedItem = function(name) {
#| const items = this._itemsFn ? this._itemsFn() : this;
#| for (const el of items) {
#| if (!el || !el._attrs) continue;
#| if (el._attrs.id === name) return el;
#| if (el._namespaceURI === 'http://www.w3.org/1999/xhtml' && el._attrs.name === name) return el;
#| }
#| return null;
#| };
#|
#| function NamedNodeMap() {}
#| NamedNodeMap.prototype.item = function(i) {
#| const element = this._element;
#| if (!element) return null;
#| return element._attrList[i] || null;
#| };
#| NamedNodeMap.prototype.getNamedItem = function(name) {
#| const element = this._element;
#| if (!element) return null;
#| return getAttrNodeByExactName(element, name);
#| };
#| NamedNodeMap.prototype.getNamedItemNS = function(ns, localName) {
#| const element = this._element;
#| if (!element) return null;
#| return getAttrNodeByNSLocalName(element, ns, localName);
#| };
#| NamedNodeMap.prototype.setNamedItem = function(attr) {
#| const element = this._element;
#| if (!element || !attr || attr._nodeType !== 2) {
#| throw new TypeError('Failed to execute setNamedItem: parameter 1 is not of type Attr');
#| }
#| if (attr.ownerElement && attr.ownerElement !== element) {
#| throw new DOMException('Attribute already in use', 'InUseAttributeError');
#| }
#| const oldClassValue = attr.localName === 'class' && (attr.namespaceURI === null || attr.namespaceURI === '') ? element.getAttribute('class') : null;
#| const existing = attr.namespaceURI !== null && attr.namespaceURI !== ''
#| ? getAttrNodeByNSLocalName(element, attr.namespaceURI, attr.localName)
#| : getAttrNodeByExactName(element, attr.name);
#| if (existing) {
#| if (existing === attr) return attr;
#| const idx = element._attrList.indexOf(existing);
#| if (idx >= 0) element._attrList.splice(idx, 1, attr);
#| existing.ownerElement = null;
#| } else {
#| element._attrList.push(attr);
#| }
#| attr.ownerElement = element;
#| attr.ownerDocument = element.ownerDocument || getGlobalDocument();
#| if (oldClassValue !== null) updateClassIndex(element, oldClassValue, attr.value);
#| return existing || null;
#| };
#| NamedNodeMap.prototype.removeNamedItem = function(name) {
#| const element = this._element;
#| if (!element) {
#| throw new DOMException('Attribute not found', 'NotFoundError');
#| }
#| const existing = getAttrNodeByExactName(element, name);
#| if (!existing) {
#| throw new DOMException('Attribute not found', 'NotFoundError');
#| }
#| const oldClassValue = existing.localName === 'class' && (existing.namespaceURI === null || existing.namespaceURI === '') ? element.getAttribute('class') : null;
#| const idx = element._attrList.indexOf(existing);
#| if (idx >= 0) element._attrList.splice(idx, 1);
#| existing.ownerElement = null;
#| if (oldClassValue !== null) updateClassIndex(element, oldClassValue, null);
#| return existing;
#| };
#|
#| function makeLiveList(ctor, itemsFn, withNamedItem) {
#| const target = { _itemsFn: itemsFn };
#| Object.setPrototypeOf(target, ctor.prototype);
#| const isIndexProp = (prop) => typeof prop === 'string' && /^[0-9]+$/.test(prop);
#| const getItems = () => itemsFn();
#| const getNamedElement = (name) => {
#| if (!withNamedItem) return undefined;
#| const items = getItems();
#| for (const el of items) {
#| if (!el || !el._attrs) continue;
#| if (el._attrs.id === name) return el;
#| if (el._namespaceURI === 'http://www.w3.org/1999/xhtml' && el._attrs.name === name) return el;
#| }
#| return undefined;
#| };
#| const getNamedKeys = () => {
#| if (!withNamedItem) return [];
#| const items = getItems();
#| const seen = new Set();
#| const keys = [];
#| for (const el of items) {
#| if (!el || !el._attrs) continue;
#| const id = el._attrs.id;
#| if (id && !seen.has(id)) { keys.push(id); seen.add(id); }
#| const name = el._attrs.name;
#| if (name && el._namespaceURI === 'http://www.w3.org/1999/xhtml' && !seen.has(name)) {
#| keys.push(name);
#| seen.add(name);
#| }
#| }
#| return keys;
#| };
#| return new Proxy(target, {
#| get(obj, prop) {
#| if (prop === '_itemsFn') return obj._itemsFn;
#| if (prop === 'length') return getItems().length;
#| if (prop in obj) return obj[prop];
#| if (isIndexProp(prop)) {
#| const items = getItems();
#| return items[Number(prop)];
#| }
#| if (withNamedItem && typeof prop === 'string') {
#| const named = getNamedElement(prop);
#| if (named !== undefined) return named;
#| }
#| return undefined;
#| },
#| set(obj, prop, value) {
#| if (prop === 'length') return false;
#| if (isIndexProp(prop)) return false;
#| obj[prop] = value;
#| return true;
#| },
#| has(obj, prop) {
#| if (prop in obj) return true;
#| if (prop === 'length') return true;
#| if (isIndexProp(prop)) return Number(prop) < getItems().length;
#| if (withNamedItem && typeof prop === 'string') return getNamedElement(prop) !== undefined;
#| return false;
#| },
#| ownKeys(obj) {
#| const keys = [];
#| const items = getItems();
#| for (let i = 0; i < items.length; i++) keys.push(String(i));
#| for (const name of getNamedKeys()) keys.push(name);
#| for (const name of Object.getOwnPropertyNames(obj)) {
#| if (name === '_itemsFn' || name === 'length') continue;
#| if (!keys.includes(name)) keys.push(name);
#| }
#| return keys;
#| },
#| getOwnPropertyDescriptor(obj, prop) {
#| if (Object.prototype.hasOwnProperty.call(obj, prop)) {
#| return Object.getOwnPropertyDescriptor(obj, prop);
#| }
#| if (isIndexProp(prop)) {
#| const idx = Number(prop);
#| const items = getItems();
#| if (idx < items.length) {
#| return { configurable: true, enumerable: true, writable: false, value: items[idx] };
#| }
#| return undefined;
#| }
#| if (withNamedItem && typeof prop === 'string') {
#| const named = getNamedElement(prop);
#| if (named !== undefined) {
#| return { configurable: true, enumerable: false, writable: false, value: named };
#| }
#| }
#| return undefined;
#| }
#| });
#| }
#| function makeNodeList(items) {
#| if (typeof items === 'function') return makeLiveList(NodeList, items, false);
#| const list = {};
#| Object.setPrototypeOf(list, NodeList.prototype);
#| Object.defineProperty(list, '_items', { value: items.slice(), writable: false, enumerable: false, configurable: true });
#| for (let i = 0; i < items.length; i++) {
#| Object.defineProperty(list, i, { value: items[i], writable: false, enumerable: true, configurable: true });
#| }
#| return list;
#| }
#| function makeHTMLCollection(items) {
#| if (typeof items === 'function') return makeLiveList(HTMLCollection, items, true);
#| const list = items.slice();
#| Object.setPrototypeOf(list, HTMLCollection.prototype);
#| return list;
#| }
#|
#| const emptyNodeList = makeNodeList([]);
#|
#| function getParentNode(node) {
#| if (!node) return null;
#| if ('parentNode' in node) return node.parentNode;
#| if ('_parent' in node) return node._parent;
#| return null;
#| }
#| function getChildNodesArray(node) {
#| if (!node) return [];
#| if (node._children) return node._children;
#| if ('childNodes' in node && node.childNodes) {
#| try { return Array.from(node.childNodes); } catch (e) { return []; }
#| }
#| return [];
#| }
#| function getSiblingArray(node) {
#| if (!node || !node._parent) return [];
#| if (node._parent._children) return node._parent._children;
#| return getChildNodesArray(node._parent);
#| }
#| function traverseTree(root, visit) {
#| if (!root) return false;
#| if (visit(root) === false) return false;
#| if (root._children) {
#| for (const child of root._children) {
#| if (traverseTree(child, visit) === false) return false;
#| }
#| }
#| return true;
#| }
#| function normalizeChildArray(children) {
#| let i = 0;
#| while (i < children.length) {
#| const child = children[i];
#| if (child && child._nodeType === 3) {
#| if (child._textContent === '') {
#| children.splice(i, 1);
#| child._parent = null;
#| if ('parentNode' in child) child.parentNode = null;
#| continue;
#| }
#| while (i + 1 < children.length && children[i + 1] && children[i + 1]._nodeType === 3) {
#| const next = children[i + 1];
#| if (next._textContent !== '') {
#| child._textContent += next._textContent;
#| }
#| children.splice(i + 1, 1);
#| next._parent = null;
#| if ('parentNode' in next) next.parentNode = null;
#| }
#| i += 1;
#| continue;
#| }
#| if (child && typeof child.normalize === 'function') {
#| child.normalize();
#| }
#| i += 1;
#| }
#| }
#| function lookupNamespaceURIImpl(node, prefix) {
#| if (!node) return null;
#| const pref = prefix === undefined || prefix === null || prefix === '' ? null : String(prefix);
#| const nodeType = __craterGetNodeType(node);
#| if (nodeType === 10) {
#| return null;
#| }
#| if (nodeType === 1) {
#| const ns = node._namespaceURI || node.namespaceURI || null;
#| const pfx = node._prefix !== undefined ? node._prefix : (node.prefix || null);
#| if (pref === 'xml') return 'http://www.w3.org/XML/1998/namespace';
#| if (pref === 'xmlns') return 'http://www.w3.org/2000/xmlns/';
#| if (ns && pfx === pref) return ns;
#| if (ns && pref === null && (pfx === null || pfx === undefined)) return ns;
#| if (node._attrList) {
#| for (const attr of node._attrList) {
#| const attrNs = attr.ns === undefined ? null : attr.ns;
#| const attrPrefix = attr.prefix === undefined ? null : attr.prefix;
#| const attrLocal = attr.localName;
#| if (attrNs === 'http://www.w3.org/2000/xmlns/') {
#| if (attrPrefix === 'xmlns' && attrLocal === pref) return attr.value || null;
#| if ((attrLocal === 'xmlns' || attr.name === 'xmlns') && pref === null) return attr.value || null;
#| }
#| if (attrPrefix === 'xmlns' && attrLocal === pref) return attr.value || null;
#| if ((attrLocal === 'xmlns' || attr.name === 'xmlns') && pref === null) return attr.value || null;
#| }
#| }
#| const parent = getParentNode(node);
#| if (parent && __craterGetNodeType(parent) === 9) return null;
#| return parent ? lookupNamespaceURIImpl(parent, pref) : null;
#| }
#| if (nodeType === 9) {
#| const root = node.documentElement || (node._children ? node._children.find(n => n._nodeType === 1) : null);
#| return root ? lookupNamespaceURIImpl(root, pref) : null;
#| }
#| if (nodeType === 2) {
#| return node.ownerElement ? lookupNamespaceURIImpl(node.ownerElement, pref) : null;
#| }
#| const parent = getParentNode(node);
#| if (parent && __craterGetNodeType(parent) === 9) return null;
#| return parent ? lookupNamespaceURIImpl(parent, pref) : null;
#| }
#| function isNodeLike(node) {
#| return !!(node && typeof node === 'object' && (node._nodeType !== undefined || typeof node.nodeType === 'number'));
#| }
#| function isAllowedChildNodeTypeForElement(nodeType) {
#| return nodeType === 1 || nodeType === 3 || nodeType === 4 || nodeType === 7 || nodeType === 8 || nodeType === 11;
#| }
#| function nodeContains(reference, other) {
#| if (!other) return false;
#| let node = other;
#| while (node) {
#| if (node === reference) return true;
#| node = getParentNode(node);
#| }
#| return false;
#| }
#| function getRootNodeInternal(node) {
#| let n = node;
#| let parent = getParentNode(n);
#| while (parent) {
#| n = parent;
#| if (n && n._isShadowRoot) break;
#| parent = getParentNode(n);
#| }
#| return n;
#| }
#| function getRootNodePublic(node, options) {
#| const root = getRootNodeInternal(node);
#| if (options && options.composed && root && root._isShadowRoot && root.host) {
#| return getRootNodePublic(root.host, options);
#| }
#| return root;
#| }
#| function isConnectedToDocument(node) {
#| const root = getRootNodeInternal(node);
#| return root && __craterGetNodeType(root) === 9;
#| }
#| const __craterMutationObservers = [];
#| function matchesObservedTarget(target, observedTarget, options) {
#| if (target === observedTarget) return true;
#| return !!(options && options.subtree && nodeContains(observedTarget, target));
#| }
#| function normalizeMutationRecord(record) {
#| return {
#| type: record.type,
#| target: record.target,
#| addedNodes: record.addedNodes || [],
#| removedNodes: record.removedNodes || [],
#| previousSibling: record.previousSibling === undefined ? null : record.previousSibling,
#| nextSibling: record.nextSibling === undefined ? null : record.nextSibling,
#| attributeName: record.attributeName === undefined ? null : record.attributeName,
#| attributeNamespace: record.attributeNamespace === undefined ? null : record.attributeNamespace,
#| oldValue: record.oldValue === undefined ? null : record.oldValue
#| };
#| }
#| function enqueueMutationCallback(observer) {
#| if (observer._scheduled) return;
#| observer._scheduled = true;
#| queueMicrotask(function() {
#| observer._scheduled = false;
#| if (observer._records.length === 0) return;
#| const records = observer.takeRecords();
#| if (records.length === 0) return;
#| try {
#| observer._callback(records, observer);
#| } catch (error) {
#| const callbackRealm = observer._callback && observer._callback.__craterRealm
#| ? observer._callback.__craterRealm
#| : null;
#| if (callbackRealm && typeof callbackRealm.onerror === 'function') {
#| callbackRealm.onerror(error && error.message ? error.message : String(error), '', 0, 0, error);
#| return;
#| }
#| throw error;
#| }
#| });
#| }
#| function queueMutationRecord(target, record) {
#| for (const observer of __craterMutationObservers) {
#| if (!observer || !observer._targets || observer._targets.length === 0) continue;
#| for (const observation of observer._targets) {
#| if (!matchesObservedTarget(target, observation.target, observation.options)) continue;
#| const options = observation.options || {};
#| if (record.type === 'attributes') {
#| if (!options.attributes) continue;
#| if (options.attributeFilter !== undefined) {
#| const filter = Array.isArray(options.attributeFilter)
#| ? options.attributeFilter.map(String)
#| : [String(options.attributeFilter)];
#| if (!filter.includes(record.attributeName)) continue;
#| }
#| observer._records.push(normalizeMutationRecord({
#| type: 'attributes',
#| target: target,
#| attributeName: record.attributeName,
#| attributeNamespace: record.attributeNamespace,
#| oldValue: options.attributeOldValue ? record.oldValue : null
#| }));
#| enqueueMutationCallback(observer);
#| continue;
#| }
#| if (record.type === 'characterData') {
#| if (!options.characterData) continue;
#| observer._records.push(normalizeMutationRecord({
#| type: 'characterData',
#| target: target,
#| oldValue: options.characterDataOldValue ? record.oldValue : null
#| }));
#| enqueueMutationCallback(observer);
#| continue;
#| }
#| if (record.type === 'childList') {
#| if (!options.childList) continue;
#| observer._records.push(normalizeMutationRecord({
#| type: 'childList',
#| target: target,
#| addedNodes: record.addedNodes || [],
#| removedNodes: record.removedNodes || [],
#| previousSibling: record.previousSibling,
#| nextSibling: record.nextSibling
#| }));
#| enqueueMutationCallback(observer);
#| }
#| }
#| }
#| }
#| function maybeExecuteScriptElement(el) {
#| if (!el || String(el._tagName || '').toLowerCase() !== 'script' || el.__craterManualExecution) return;
#| if (el._alreadyStarted) return;
#| const type = el.getAttribute ? String(el.getAttribute('type') || '').trim().toLowerCase() : '';
#| if (type && type !== 'text/javascript' && type !== 'application/javascript' && type !== 'module') return;
#| const src = el.getAttribute ? el.getAttribute('src') : null;
#| if (src) return;
#| const code = el.textContent || '';
#| if (!code.trim()) return;
#| el._alreadyStarted = true;
#| globalThis.__craterCurrentScript = el;
#| try {
#| (0, eval)(code);
#| } finally {
#| globalThis.__craterCurrentScript = null;
#| if (typeof _flushMicrotasks === 'function') _flushMicrotasks();
#| }
#| }
#| function compareDocumentPositionImpl(reference, other) {
#| if (!isNodeLike(other)) {
#| throw new TypeError('Failed to execute compareDocumentPosition: parameter 1 is not of type Node');
#| }
#| if (reference === other) return 0;
#| const refRoot = getRootNodeInternal(reference);
#| const otherRoot = getRootNodeInternal(other);
#| if (refRoot !== otherRoot) {
#| return Node.DOCUMENT_POSITION_DISCONNECTED |
#| Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
#| Node.DOCUMENT_POSITION_PRECEDING;
#| }
#| if (nodeContains(other, reference)) {
#| return Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING;
#| }
#| if (nodeContains(reference, other)) {
#| return Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING;
#| }
#| const order = [];
#| const walk = (node) => {
#| order.push(node);
#| const children = getChildNodesArray(node);
#| for (const child of children) walk(child);
#| };
#| walk(refRoot);
#| const refIndex = order.indexOf(reference);
#| const otherIndex = order.indexOf(other);
#| if (refIndex === -1 || otherIndex === -1) {
#| return Node.DOCUMENT_POSITION_DISCONNECTED |
#| Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
#| Node.DOCUMENT_POSITION_PRECEDING;
#| }
#| return otherIndex < refIndex
#| ? Node.DOCUMENT_POSITION_PRECEDING
#| : Node.DOCUMENT_POSITION_FOLLOWING;
#| }
#| function documentHasElement(doc, exclude) {
#| return (doc._children || []).some(n => n._nodeType === 1 && n !== exclude);
#| }
#| function documentHasDoctype(doc, exclude) {
#| return (doc._children || []).some(n => n._nodeType === 10 && n !== exclude);
#| }
#| function documentDoctype(doc, exclude) {
#| return (doc._children || []).find(n => n._nodeType === 10 && n !== exclude) || null;
#| }
#| function validateDocumentInsert(doc, node, refChild, excludeChild) {
#| const exclude = (excludeChild === undefined) ? null : excludeChild;
#| const excludeType = exclude ? __craterGetNodeType(exclude) : null;
#| const excludeElement = excludeType === 1 ? exclude : null;
#| const excludeDoctype = excludeType === 10 ? exclude : null;
#| const nodeType = __craterGetNodeType(node);
#| if (nodeType === 9 || nodeType === 2) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| if (nodeType === 3) {
#| throw new DOMException('Cannot insert a text node into document', 'HierarchyRequestError');
#| }
#| if (nodeType === 10) {
#| if (documentHasDoctype(doc, excludeDoctype)) throw new DOMException('Document already has a doctype', 'HierarchyRequestError');
#| const element = (doc._children || []).find(n => n._nodeType === 1 && n !== excludeElement) || null;
#| if (element) {
#| if (refChild) {
#| const elemIdx = doc._children.indexOf(element);
#| const refIdx = doc._children.indexOf(refChild);
#| if (refIdx > elemIdx) {
#| throw new DOMException('Cannot insert doctype after element', 'HierarchyRequestError');
#| }
#| } else {
#| throw new DOMException('Cannot insert doctype after element', 'HierarchyRequestError');
#| }
#| }
#| return;
#| }
#| if (nodeType === 11) {
#| const children = node._children || [];
#| let elementCount = 0;
#| let hasText = false;
#| let hasDoctype = false;
#| for (const child of children) {
#| const ctype = __craterGetNodeType(child);
#| if (ctype === 1) elementCount++;
#| else if (ctype === 3) hasText = true;
#| else if (ctype === 10) hasDoctype = true;
#| }
#| if (hasText || hasDoctype || elementCount > 1) {
#| throw new DOMException('Invalid DocumentFragment for document', 'HierarchyRequestError');
#| }
#| if (elementCount === 1) {
#| if (documentHasElement(doc, excludeElement)) {
#| throw new DOMException('Document already has an element', 'HierarchyRequestError');
#| }
#| const doctype = documentDoctype(doc, excludeDoctype);
#| if (doctype && refChild) {
#| const doctypeIdx = doc._children.indexOf(doctype);
#| const refIdx = doc._children.indexOf(refChild);
#| if (refIdx <= doctypeIdx) {
#| throw new DOMException('Cannot insert element before doctype', 'HierarchyRequestError');
#| }
#| }
#| }
#| return;
#| }
#| if (nodeType === 1) {
#| if (documentHasElement(doc, excludeElement)) {
#| throw new DOMException('Document already has an element', 'HierarchyRequestError');
#| }
#| const doctype = documentDoctype(doc, excludeDoctype);
#| if (doctype && refChild) {
#| const doctypeIdx = doc._children.indexOf(doctype);
#| const refIdx = doc._children.indexOf(refChild);
#| if (refIdx <= doctypeIdx) {
#| throw new DOMException('Cannot insert element before doctype', 'HierarchyRequestError');
#| }
#| }
#| return;
#| }
#| if (nodeType === 7 || nodeType === 8) {
#| return;
#| }
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| function convertParentNodeInputNode(doc, input) {
#| return isNodeLike(input) ? input : doc.createTextNode(String(input));
#| }
#| function convertParentNodeNodes(doc, nodes) {
#| if (!doc || nodes.length === 0) return null;
#| if (nodes.length === 1) {
#| return convertParentNodeInputNode(doc, nodes[0]);
#| }
#| const frag = doc.createDocumentFragment();
#| for (const node of nodes) {
#| frag.appendChild(convertParentNodeInputNode(doc, node));
#| }
#| return frag;
#| }
#| function validateDocumentReplaceChildren(doc, replacement) {
#| if (!replacement) return;
#| const nodeType = __craterGetNodeType(replacement);
#| if (nodeType === 9 || nodeType === 2) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| if (nodeType === 3) {
#| throw new DOMException('Cannot insert a text node into document', 'HierarchyRequestError');
#| }
#| if (nodeType === 7 || nodeType === 8 || nodeType === 10 || nodeType === 1) {
#| return;
#| }
#| if (nodeType !== 11) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| let elementCount = 0;
#| let doctypeCount = 0;
#| let seenElement = false;
#| for (const child of replacement._children || []) {
#| const childType = __craterGetNodeType(child);
#| if (childType === 1) {
#| elementCount++;
#| seenElement = true;
#| } else if (childType === 10) {
#| doctypeCount++;
#| if (seenElement) {
#| throw new DOMException('Cannot insert doctype after element', 'HierarchyRequestError');
#| }
#| } else if (childType === 3) {
#| throw new DOMException('Cannot insert a text node into document', 'HierarchyRequestError');
#| } else if (childType !== 7 && childType !== 8) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| }
#| if (elementCount > 1 || doctypeCount > 1) {
#| throw new DOMException('Invalid DocumentFragment for document', 'HierarchyRequestError');
#| }
#| }
#| function parentNodeAppend(parent, ownerDoc, nodes) {
#| const node = convertParentNodeNodes(ownerDoc, nodes);
#| if (!node) return;
#| parent.appendChild(node);
#| }
#| function parentNodePrepend(parent, ownerDoc, nodes) {
#| const node = convertParentNodeNodes(ownerDoc, nodes);
#| if (!node) return;
#| parent.insertBefore(node, parent.firstChild);
#| }
#| function parentNodeReplaceChildren(parent, ownerDoc, nodes) {
#| const replacement = convertParentNodeNodes(ownerDoc, nodes);
#| if (__craterGetNodeType(parent) === 9) {
#| if (replacement) {
#| if ((parent._children || []).length > 0) {
#| validateDocumentInsert(parent, replacement, null, null);
#| } else {
#| validateDocumentReplaceChildren(parent, replacement);
#| }
#| }
#| }
#| while (parent._children.length > 0) parent.removeChild(parent._children[0]);
#| if (replacement) {
#| parent.appendChild(replacement);
#| }
#| }
#| function getGlobalDocument() {
#| if (typeof globalThis !== 'undefined' && globalThis.document) return globalThis.document;
#| return null;
#| }
#| function __craterGetNodeType(node) {
#| return node && node._nodeType !== undefined ? node._nodeType : (node ? node.nodeType : undefined);
#| }
#| function getOwnerDocument(node) {
#| if (!node) return getGlobalDocument();
#| if (node._nodeType === 9) return node;
#| if (node._ownerDocument) return node._ownerDocument;
#| const globalDoc = getGlobalDocument();
#| if (globalDoc) return globalDoc;
#| return null;
#| }
#| function adoptSubtree(node, doc) {
#| if (!node || !doc) return;
#| if (node._nodeType === 9) return;
#| if ('ownerDocument' in node) node.ownerDocument = doc;
#| if ('_ownerDocument' in node) node._ownerDocument = doc;
#| if (node._attrList) {
#| for (const attr of node._attrList) {
#| attr.ownerDocument = doc;
#| }
#| }
#| if (node._children) {
#| for (const child of node._children) {
#| adoptSubtree(child, doc);
#| }
#| }
#| }
#| function insertAdjacentNode(target, position, node) {
#| const pos = String(position).toLowerCase();
#| switch (pos) {
#| case 'beforebegin':
#| if (!target._parent) return null;
#| target._parent.insertBefore(node, target);
#| return node;
#| case 'afterbegin':
#| target.insertBefore(node, target.firstChild);
#| return node;
#| case 'beforeend':
#| target.appendChild(node);
#| return node;
#| case 'afterend':
#| if (!target._parent) return null;
#| target._parent.insertBefore(node, target.nextSibling);
#| return node;
#| default:
#| throw new DOMException("Invalid position: " + position, "SyntaxError");
#| }
#| }
#| function insertAdjacentNodes(target, position, nodes) {
#| const pos = String(position).toLowerCase();
#| const list = Array.isArray(nodes) ? nodes : [];
#| switch (pos) {
#| case 'beforebegin':
#| if (!target._parent) return null;
#| for (const node of list) {
#| target._parent.insertBefore(node, target);
#| }
#| return null;
#| case 'afterbegin':
#| for (const node of list) {
#| target.insertBefore(node, target.firstChild);
#| }
#| return null;
#| case 'beforeend':
#| for (const node of list) {
#| target.appendChild(node);
#| }
#| return null;
#| case 'afterend':
#| if (!target._parent) return null;
#| for (const node of list) {
#| target._parent.insertBefore(node, target.nextSibling);
#| }
#| return null;
#| default:
#| throw new DOMException("Invalid position: " + position, "SyntaxError");
#| }
#| }
#| function detachNode(node) {
#| if (!node) return;
#| const doc = getOwnerDocument(node);
#| if (doc && isConnectedToDocument(node)) unindexSubtree(node, doc);
#| if (!node._parent) return;
#| if (typeof node._parent.removeChild === 'function') {
#| node._parent.removeChild(node);
#| } else if (Array.isArray(node._parent._children)) {
#| const idx = node._parent._children.indexOf(node);
#| if (idx >= 0) node._parent._children.splice(idx, 1);
#| }
#| node._parent = null;
#| if ('parentNode' in node) node.parentNode = null;
#| }
#| function collectElements(root, includeRoot, predicate) {
#| const results = [];
#| if (!root) return results;
#| traverseTree(root, (node) => {
#| if (node._nodeType !== 1) return;
#| if (!includeRoot && node === root) return;
#| if (predicate(node)) results.push(node);
#| });
#| return results;
#| }
#| function ensureDocumentIndexes(doc) {
#| if (!doc) return null;
#| if (!doc._classIndex) doc._classIndex = new Map();
#| if (!doc._tagIndex) doc._tagIndex = new Map();
#| if (doc._elementCount === undefined) doc._elementCount = 0;
#| return doc;
#| }
#| function tagKeyForElement(el) {
#| if (!el) return '';
#| if (el._namespaceURI === 'http://www.w3.org/1999/xhtml') {
#| return asciiLowercase(el._tagName || '');
#| }
#| return el._tagName || '';
#| }
#| function getClassTokensFromValue(value) {
#| if (value === null || value === undefined) return [];
#| const str = String(value);
#| return splitAsciiWhitespace(str);
#| }
#| function indexElement(el, doc) {
#| if (!el || el._nodeType !== 1) return;
#| const targetDoc = ensureDocumentIndexes(doc);
#| if (!targetDoc) return;
#| if (el._indexed) return;
#| el._indexed = true;
#| targetDoc._elementCount = (targetDoc._elementCount || 0) + 1;
#| const tagKey = tagKeyForElement(el);
#| if (tagKey) {
#| let set = targetDoc._tagIndex.get(tagKey);
#| if (!set) { set = new Set(); targetDoc._tagIndex.set(tagKey, set); }
#| set.add(el);
#| }
#| const classAttr = el.getAttribute ? el.getAttribute('class') : null;
#| const tokens = getClassTokensFromValue(classAttr);
#| for (const token of tokens) {
#| let set = targetDoc._classIndex.get(token);
#| if (!set) { set = new Set(); targetDoc._classIndex.set(token, set); }
#| set.add(el);
#| }
#| }
#| function unindexElement(el, doc) {
#| if (!el || el._nodeType !== 1 || !doc) return;
#| if (!el._indexed) return;
#| el._indexed = false;
#| doc._elementCount = Math.max(0, (doc._elementCount || 0) - 1);
#| const classIndex = doc._classIndex;
#| const tagIndex = doc._tagIndex;
#| if (tagIndex) {
#| const tagKey = tagKeyForElement(el);
#| const set = tagIndex.get(tagKey);
#| if (set) {
#| set.delete(el);
#| if (set.size === 0) tagIndex.delete(tagKey);
#| }
#| }
#| if (classIndex) {
#| const classAttr = el.getAttribute ? el.getAttribute('class') : null;
#| const tokens = getClassTokensFromValue(classAttr);
#| for (const token of tokens) {
#| const set = classIndex.get(token);
#| if (!set) continue;
#| set.delete(el);
#| if (set.size === 0) classIndex.delete(token);
#| }
#| }
#| }
#| function indexSubtree(node, doc) {
#| if (!node) return;
#| const targetDoc = ensureDocumentIndexes(doc);
#| if (!targetDoc) return;
#| traverseTree(node, (n) => {
#| if (n._nodeType === 1) indexElement(n, targetDoc);
#| });
#| }
#| function unindexSubtree(node, doc) {
#| if (!node || !doc) return;
#| traverseTree(node, (n) => {
#| if (n._nodeType === 1) unindexElement(n, doc);
#| });
#| }
#| function updateClassIndex(el, oldValue, newValue) {
#| if (!el || el._nodeType !== 1) return;
#| if (!isConnectedToDocument(el)) return;
#| const doc = ensureDocumentIndexes(getOwnerDocument(el));
#| if (!doc) return;
#| const oldTokens = new Set(getClassTokensFromValue(oldValue));
#| const newTokens = new Set(getClassTokensFromValue(newValue));
#| for (const token of oldTokens) {
#| if (!newTokens.has(token)) {
#| const set = doc._classIndex.get(token);
#| if (set) {
#| set.delete(el);
#| if (set.size === 0) doc._classIndex.delete(token);
#| }
#| }
#| }
#| for (const token of newTokens) {
#| if (!oldTokens.has(token)) {
#| let set = doc._classIndex.get(token);
#| if (!set) { set = new Set(); doc._classIndex.set(token, set); }
#| set.add(el);
#| }
#| }
#| }
#| function isNameStartCharCode(code) {
#| return (
#| (code >= 65 && code <= 90) ||
#| (code >= 97 && code <= 122) ||
#| code === 95 ||
#| code === 58 ||
#| code >= 0x80
#| );
#| }
#| function isNameCharCode(code) {
#| return (
#| isNameStartCharCode(code) ||
#| (code >= 48 && code <= 57) ||
#| code === 45 ||
#| code === 46
#| );
#| }
#| function isForbiddenAttributeCharCode(code) {
#| return (
#| code === 0 ||
#| code === 9 ||
#| code === 10 ||
#| code === 12 ||
#| code === 13 ||
#| code === 32 ||
#| code === 47 ||
#| code === 62 ||
#| code === 61
#| );
#| }
#| function isForbiddenDoctypeCharCode(code) {
#| return (
#| code === 0 ||
#| code === 9 ||
#| code === 10 ||
#| code === 12 ||
#| code === 13 ||
#| code === 32 ||
#| code === 62
#| );
#| }
#| function isForbiddenNamespacePrefixCharCode(code) {
#| return (
#| code === 0 ||
#| code === 9 ||
#| code === 10 ||
#| code === 12 ||
#| code === 13 ||
#| code === 32 ||
#| code === 47 ||
#| code === 62
#| );
#| }
#| function isValidElementName(name) {
#| if (name === '') return false;
#| const first = name.charCodeAt(0);
#| if ((first >= 65 && first <= 90) || (first >= 97 && first <= 122)) {
#| for (let i = 1; i < name.length; i++) {
#| const code = name.charCodeAt(i);
#| if (
#| code === 0 ||
#| code === 9 ||
#| code === 10 ||
#| code === 12 ||
#| code === 13 ||
#| code === 32 ||
#| code === 47 ||
#| code === 62
#| ) {
#| return false;
#| }
#| }
#| return true;
#| }
#| if (first !== 58 && first !== 95 && first < 0x80) return false;
#| for (let i = 1; i < name.length; i++) {
#| const code = name.charCodeAt(i);
#| if (!isNameCharCode(code)) {
#| return false;
#| }
#| }
#| return true;
#| }
#| function isValidAttributeName(name) {
#| if (name === '') return false;
#| for (let i = 0; i < name.length; i++) {
#| if (isForbiddenAttributeCharCode(name.charCodeAt(i))) return false;
#| }
#| return true;
#| }
#| function isValidNamespacePrefix(name) {
#| if (name === '') return false;
#| for (let i = 0; i < name.length; i++) {
#| if (isForbiddenNamespacePrefixCharCode(name.charCodeAt(i))) return false;
#| }
#| return true;
#| }
#| function isValidDoctypeName(name) {
#| if (name === '') return true;
#| for (let i = 0; i < name.length; i++) {
#| if (isForbiddenDoctypeCharCode(name.charCodeAt(i))) return false;
#| }
#| return true;
#| }
#| function parseQualifiedName(name) {
#| const firstColon = name.indexOf(':');
#| if (firstColon < 0) return { prefix: null, localName: name };
#| const prefix = name.slice(0, firstColon);
#| const remainder = name.slice(firstColon + 1);
#| const secondColon = remainder.indexOf(':');
#| const localName = secondColon >= 0 ? remainder.slice(0, secondColon) : remainder;
#| if (prefix === '' || localName === '') return null;
#| return { prefix, localName };
#| }
#| function validateElementQualifiedName(namespace, qualifiedName) {
#| const name = String(qualifiedName);
#| const parsed = parseQualifiedName(name);
#| const nsNormalized = namespace === undefined || namespace === '' ? null : namespace;
#| if (parsed === null) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| if (parsed.prefix === null) {
#| if (!isValidElementName(name)) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| } else {
#| if (!isValidNamespacePrefix(parsed.prefix) || !isValidElementName(parsed.localName)) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| }
#| if (parsed.prefix !== null && nsNormalized === null) {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if (parsed.prefix === 'xml' && nsNormalized !== 'http://www.w3.org/XML/1998/namespace') {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if ((parsed.prefix === 'xmlns' || name === 'xmlns') && nsNormalized !== 'http://www.w3.org/2000/xmlns/') {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if (nsNormalized === 'http://www.w3.org/2000/xmlns/' && !(parsed.prefix === 'xmlns' || name === 'xmlns')) {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| return parsed;
#| }
#| function validateAttributeQualifiedName(namespace, qualifiedName) {
#| const name = String(qualifiedName);
#| const parsed = parseQualifiedName(name);
#| const nsNormalized = namespace === undefined || namespace === '' ? null : namespace;
#| if (parsed === null) {
#| throw new DOMException('Invalid character in attribute name', 'InvalidCharacterError');
#| }
#| if (parsed.prefix === null) {
#| if (!isValidAttributeName(name)) {
#| throw new DOMException('Invalid character in attribute name', 'InvalidCharacterError');
#| }
#| } else {
#| if (!isValidNamespacePrefix(parsed.prefix) || !isValidAttributeName(parsed.localName)) {
#| throw new DOMException('Invalid character in attribute name', 'InvalidCharacterError');
#| }
#| }
#| if (parsed.prefix !== null && nsNormalized === null) {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if (parsed.prefix === 'xml' && nsNormalized !== 'http://www.w3.org/XML/1998/namespace') {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if ((parsed.prefix === 'xmlns' || name === 'xmlns') && nsNormalized !== 'http://www.w3.org/2000/xmlns/') {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| if (nsNormalized === 'http://www.w3.org/2000/xmlns/' && !(parsed.prefix === 'xmlns' || name === 'xmlns')) {
#| throw new DOMException('Invalid namespace', 'NamespaceError');
#| }
#| return parsed;
#| }
#| function validateDoctypeQualifiedName(qualifiedName) {
#| const name = String(qualifiedName);
#| if (!isValidDoctypeName(name)) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| return name;
#| }
#| function createAttrNode(ownerDoc, namespace, qualifiedName, value, ownerElement, lowercase) {
#| const rawName = String(qualifiedName);
#| const nsNormalized = namespace === undefined || namespace === '' ? null : namespace;
#| const parsed = nsNormalized === null
#| ? (function() {
#| if (!isValidAttributeName(rawName)) {
#| throw new DOMException('Invalid character in attribute name', 'InvalidCharacterError');
#| }
#| return { prefix: null, localName: lowercase ? asciiLowercase(rawName) : rawName };
#| })()
#| : validateAttributeQualifiedName(nsNormalized, rawName);
#| const attrName = lowercase && parsed.prefix === null ? asciiLowercase(rawName) : rawName;
#| const attr = {
#| _nodeType: 2,
#| nodeType: 2,
#| name: attrName,
#| localName: parsed.localName,
#| nodeName: attrName,
#| value: value === undefined ? '' : String(value),
#| get nodeValue() { return this.value; },
#| set nodeValue(v) { this.value = v === null ? '' : String(v); },
#| get textContent() { return this.value; },
#| set textContent(v) { this.value = v === null ? '' : String(v); },
#| get baseURI() {
#| const doc = this.ownerDocument || getGlobalDocument();
#| return doc && doc.baseURI ? doc.baseURI : 'about:blank';
#| },
#| namespaceURI: nsNormalized,
#| prefix: parsed.prefix,
#| ownerDocument: ownerDoc || getGlobalDocument(),
#| ownerElement: ownerElement || null,
#| specified: true,
#| isSameNode(other) { return this === other; },
#| isEqualNode(other) {
#| return other && other._nodeType === 2 &&
#| other.name === this.name &&
#| other.value === this.value &&
#| other.namespaceURI === this.namespaceURI;
#| },
#| cloneNode() {
#| const doc = this.ownerDocument || getGlobalDocument();
#| const cloned = this.namespaceURI
#| ? (doc && doc.createAttributeNS ? doc.createAttributeNS(this.namespaceURI, this.name) : document.createAttributeNS(this.namespaceURI, this.name))
#| : (doc && doc.createAttribute ? doc.createAttribute(this.name) : document.createAttribute(this.name));
#| cloned.value = this.value;
#| return cloned;
#| }
#| };
#| Object.setPrototypeOf(attr, Attr.prototype);
#| return attr;
#| }
#| function normalizeElementAttrLookupName(el, name) {
#| const rawName = String(name);
#| return el && el._namespaceURI === 'http://www.w3.org/1999/xhtml' ? asciiLowercase(rawName) : rawName;
#| }
#| function getAttrNodeByExactName(el, name) {
#| const searchName = String(name);
#| return el._attrList.find(a => a.name === searchName) || null;
#| }
#| function getAttrNodeByName(el, name) {
#| const searchName = normalizeElementAttrLookupName(el, name);
#| return el._attrList.find(a => a.name === searchName) || null;
#| }
#| function getAttrNodeByNSLocalName(el, ns, localName) {
#| const normalNs = ns === '' || ns === null || ns === undefined ? null : ns;
#| return el._attrList.find(a => {
#| const attrNs = a.namespaceURI === '' || a.namespaceURI === null || a.namespaceURI === undefined ? null : a.namespaceURI;
#| return attrNs === normalNs && a.localName === localName;
#| }) || null;
#| }
#| function shouldExposeNamedNodeMapProperty(element, attr) {
#| if (!element || !attr) return false;
#| const ownerDoc = element.ownerDocument || getGlobalDocument();
#| const isHtmlDoc = ownerDoc && ownerDoc.contentType === 'text/html';
#| const isHtmlElement = element._namespaceURI === 'http://www.w3.org/1999/xhtml';
#| if (isHtmlElement && isHtmlDoc) {
#| return attr.name === asciiLowercase(attr.name);
#| }
#| return true;
#| }
#| function getNamedNodeMapPropertyNames(element) {
#| const names = [];
#| for (const attr of element._attrList) {
#| if (!shouldExposeNamedNodeMapProperty(element, attr)) continue;
#| if (!names.includes(attr.name)) names.push(attr.name);
#| }
#| return names;
#| }
#| function getNamedNodeMapPropertyAttr(element, prop) {
#| if (typeof prop !== 'string') return undefined;
#| for (const attr of element._attrList) {
#| if (!shouldExposeNamedNodeMapProperty(element, attr)) continue;
#| if (attr.name === prop) return attr;
#| }
#| return undefined;
#| }
#| function makeNamedNodeMap(element) {
#| const target = {};
#| Object.defineProperty(target, '_element', {
#| value: element,
#| writable: false,
#| configurable: true,
#| enumerable: false,
#| });
#| Object.setPrototypeOf(target, NamedNodeMap.prototype);
#| const getItems = () => element._attrList;
#| const getNamed = (prop) => {
#| if (typeof prop !== 'string') return undefined;
#| if (prop in target || prop in NamedNodeMap.prototype) return undefined;
#| return getNamedNodeMapPropertyAttr(element, prop);
#| };
#| return new Proxy(target, {
#| get(obj, prop, receiver) {
#| if (prop === 'length') return getItems().length;
#| if (typeof prop === 'string' && /^[0-9]+$/.test(prop)) return getItems()[Number(prop)];
#| if (prop in obj || prop in NamedNodeMap.prototype) return Reflect.get(obj, prop, receiver);
#| return getNamed(prop);
#| },
#| has(obj, prop) {
#| if (prop === 'length') return true;
#| if (typeof prop === 'string' && /^[0-9]+$/.test(prop)) return Number(prop) < getItems().length;
#| if (prop in obj || prop in NamedNodeMap.prototype) return true;
#| return getNamed(prop) !== undefined;
#| },
#| ownKeys(obj) {
#| const keys = [];
#| for (let i = 0; i < getItems().length; i++) keys.push(String(i));
#| for (const name of getNamedNodeMapPropertyNames(element)) {
#| if (!keys.includes(name)) keys.push(name);
#| }
#| return keys;
#| },
#| getOwnPropertyDescriptor(obj, prop) {
#| if (prop === 'length') return { configurable: true, enumerable: false, writable: false, value: getItems().length };
#| if (typeof prop === 'string' && /^[0-9]+$/.test(prop)) {
#| const idx = Number(prop);
#| if (idx < getItems().length) {
#| return { configurable: true, enumerable: true, writable: false, value: getItems()[idx] };
#| }
#| }
#| if (prop in obj) return Object.getOwnPropertyDescriptor(obj, prop);
#| const named = getNamed(prop);
#| if (named !== undefined) {
#| return { configurable: true, enumerable: false, writable: false, value: named };
#| }
#| return undefined;
#| }
#| });
#| }
#| function getCandidatesByFilter(root, includeRoot, filter, allowLarge) {
#| if (!filter) return null;
#| if (!isConnectedToDocument(root) && __craterGetNodeType(root) !== 9) return null;
#| const doc = ensureDocumentIndexes(getOwnerDocument(root));
#| if (!doc) return null;
#| let candidates = null;
#| if (filter.kind === 'class') {
#| const tokens = filter.tokens || [];
#| if (tokens.length === 1) {
#| const set = doc._classIndex.get(tokens[0]);
#| if (!set) return [];
#| candidates = set;
#| } else {
#| for (const token of tokens) {
#| const set = doc._classIndex.get(token);
#| if (!set) return [];
#| if (candidates === null) {
#| candidates = new Set(set);
#| } else {
#| for (const el of Array.from(candidates)) {
#| if (!set.has(el)) candidates.delete(el);
#| }
#| }
#| if (candidates.size === 0) return [];
#| }
#| }
#| } else if (filter.kind === 'tag') {
#| const name = String(filter.name);
#| if (name === '*') return null;
#| const lower = asciiLowercase(name);
#| const set1 = doc._tagIndex.get(name);
#| const set2 = lower === name ? null : doc._tagIndex.get(lower);
#| if (!set1 && !set2) return [];
#| if (set1 && !set2) {
#| candidates = set1;
#| } else if (!set1 && set2) {
#| candidates = set2;
#| } else {
#| candidates = new Set();
#| if (set1) for (const el of set1) candidates.add(el);
#| if (set2) for (const el of set2) candidates.add(el);
#| }
#| } else if (filter.kind === 'id') {
#| const el = doc.getElementById ? doc.getElementById(filter.id) : null;
#| candidates = new Set(el ? [el] : []);
#| }
#| if (!candidates) return null;
#| if (!allowLarge && filter.kind !== 'id') {
#| const total = doc._elementCount || 0;
#| if (total > 0 && candidates.size > total * 0.7) return null;
#| }
#| const list = [];
#| if (candidates.size > 64) {
#| traverseTree(root, (node) => {
#| if (node._nodeType !== 1) return;
#| if (!includeRoot && node === root) return;
#| if (!candidates.has(node)) return;
#| if (!applySimpleFilter(node, filter)) return;
#| list.push(node);
#| });
#| return list;
#| }
#| for (const el of candidates) {
#| if (!includeRoot && el === root) continue;
#| if (!nodeContains(root, el)) continue;
#| if (!applySimpleFilter(el, filter)) continue;
#| list.push(el);
#| }
#| if (list.length > 1) {
#| list.sort((a, b) => {
#| if (a === b) return 0;
#| const pos = compareDocumentPositionImpl(a, b);
#| return (pos & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1;
#| });
#| }
#| return list;
#| }
#| function normalizeNamespace(ns) {
#| if (ns === undefined || ns === null || ns === '') return null;
#| return ns;
#| }
#| function asciiLowercase(value) {
#| return String(value).replace(/[A-Z]/g, c => c.toLowerCase());
#| }
#| function matchesNamespace(node, ns) {
#| if (ns === '*' || ns === undefined) return true;
#| return node._namespaceURI === normalizeNamespace(ns);
#| }
#| function matchesTagName(node, tag) {
#| if (tag === '*') return true;
#| const name = String(tag);
#| const ownerDoc = node._ownerDocument || getGlobalDocument();
#| if (node._namespaceURI === 'http://www.w3.org/1999/xhtml' && ownerDoc && ownerDoc.contentType === 'text/html') {
#| return node._tagName === asciiLowercase(name);
#| }
#| return node._tagName === name;
#| }
#| function matchesTagNameNS(node, tag) {
#| if (tag === '*') return true;
#| const name = String(tag);
#| return node.localName === name;
#| }
#| function isAsciiWhitespaceChar(ch) {
#| return ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\f' || ch === '\\r';
#| }
#| function splitAsciiWhitespace(str) {
#| const tokens = [];
#| let current = '';
#| for (let i = 0; i < str.length; i++) {
#| const ch = str[i];
#| if (isAsciiWhitespaceChar(ch)) {
#| if (current !== '') { tokens.push(current); current = ''; }
#| } else {
#| current += ch;
#| }
#| }
#| if (current !== '') tokens.push(current);
#| return tokens;
#| }
#| function containsAsciiWhitespace(str) {
#| for (let i = 0; i < str.length; i++) {
#| if (isAsciiWhitespaceChar(str[i])) return true;
#| }
#| return false;
#| }
#| function isHexDigit(ch) {
#| return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
#| }
#| function isCssIdentDelimiter(ch) {
#| return isAsciiWhitespaceChar(ch) || ch === '.' || ch === '#' || ch === '[' || ch === ']' || ch === ':' ||
#| ch === '>' || ch === '+' || ch === '~' || ch === ',' || ch === ')';
#| }
#| function consumeCssEscape(str, index) {
#| if (index + 1 >= str.length) {
#| return { char: '\\uFFFD', nextIndex: str.length };
#| }
#| const next = str[index + 1];
#| if (next === '\\n' || next === '\\f') {
#| return { char: '', nextIndex: index + 2 };
#| }
#| if (next === '\\r') {
#| let nextIndex = index + 2;
#| if (str[nextIndex] === '\\n') nextIndex += 1;
#| return { char: '', nextIndex };
#| }
#| if (isHexDigit(next)) {
#| let hex = '';
#| let j = index + 1;
#| for (let count = 0; count < 6 && j < str.length && isHexDigit(str[j]); count++, j++) {
#| hex += str[j];
#| }
#| let code = parseInt(hex, 16);
#| if (j < str.length && isAsciiWhitespaceChar(str[j])) {
#| if (str[j] === '\\r' && str[j + 1] === '\\n') {
#| j += 2;
#| } else {
#| j += 1;
#| }
#| }
#| if (!code || code > 0x10FFFF || (code >= 0xD800 && code <= 0xDFFF)) {
#| code = 0xFFFD;
#| }
#| return { char: String.fromCodePoint(code), nextIndex: j };
#| }
#| return { char: next, nextIndex: index + 2 };
#| }
#| function readCssIdentifier(str, start) {
#| let value = '';
#| let i = start;
#| while (i < str.length) {
#| const ch = str[i];
#| if (ch === '\\u0000') {
#| value += '\\uFFFD';
#| i += 1;
#| continue;
#| }
#| if (ch === '\\\\') {
#| const esc = consumeCssEscape(str, i);
#| value += esc.char;
#| i = esc.nextIndex;
#| continue;
#| }
#| if (isCssIdentDelimiter(ch)) break;
#| value += ch;
#| i += 1;
#| }
#| return { value, end: i };
#| }
#| function bufEndsWithHexEscape(buf) {
#| let i = buf.length - 1;
#| let count = 0;
#| while (i >= 0 && count < 6 && isHexDigit(buf[i])) {
#| i -= 1;
#| count += 1;
#| }
#| if (count === 0) return false;
#| return i >= 0 && buf[i] === '\\\\';
#| }
#| function isWhitespaceAfterHexEscape(str, index) {
#| let i = index - 1;
#| let count = 0;
#| while (i >= 0 && count < 6 && isHexDigit(str[i])) {
#| i -= 1;
#| count += 1;
#| }
#| if (count === 0) return false;
#| return i >= 0 && str[i] === '\\\\';
#| }
#| function normalizeSelectorEscapes(selector) {
#| let str = String(selector);
#| // Consume a single whitespace after hex escapes, per CSS syntax.
#| str = str.replace(/\\\\([0-9a-fA-F]{1,6})(\\r\\n|[\\t\\n\\r\\f ])/g, '\\\\$1');
#| return str;
#| }
#| function parseClassTokens(input) {
#| const str = String(input);
#| return splitAsciiWhitespace(str);
#| }
#| function matchesClassTokens(node, tokens) {
#| if (tokens.length === 0) return false;
#| for (const token of tokens) {
#| if (!node.classList || !node.classList.contains(token)) return false;
#| }
#| return true;
#| }
#| function findAttributeForSelector(el, name) {
#| if (!el || !el._attrList) return null;
#| const rawName = String(name);
#| const isHtml = el._namespaceURI === 'http://www.w3.org/1999/xhtml';
#| const pipeIdx = rawName.indexOf('|');
#| if (pipeIdx >= 0) {
#| const prefix = rawName.slice(0, pipeIdx);
#| const local = rawName.slice(pipeIdx + 1);
#| const matchLocal = isHtml ? asciiLowercase(local) : local;
#| if (prefix === '*') {
#| return el._attrList.find(a => {
#| const aLocal = (a.localName !== undefined && a.localName !== null) ? a.localName : a.name;
#| return (isHtml ? asciiLowercase(aLocal) : aLocal) === matchLocal;
#| }) || null;
#| }
#| return el._attrList.find(a => {
#| const aLocal = (a.localName !== undefined && a.localName !== null) ? a.localName : a.name;
#| const aPrefix = a.prefix || '';
#| return aPrefix === prefix && (isHtml ? asciiLowercase(aLocal) : aLocal) === matchLocal;
#| }) || null;
#| }
#| if (isHtml) {
#| const lower = asciiLowercase(rawName);
#| return el._attrList.find(a => asciiLowercase(a.name) === lower) || null;
#| }
#| return el._attrList.find(a => a.name === rawName) || null;
#| }
#| function parseAttributeSelector(segment) {
#| const inner = segment.slice(1, -1).trim();
#| if (!inner) return null;
#| let name = '';
#| let operator = null;
#| let value = null;
#| let flag = null;
#| let inQuote = null;
#| let eqIdx = -1;
#| for (let i = 0; i < inner.length; i++) {
#| const ch = inner[i];
#| if (inQuote) {
#| if (ch === inQuote) inQuote = null;
#| continue;
#| }
#| if (ch === '"' || ch === "'") { inQuote = ch; continue; }
#| if (ch === '=') { eqIdx = i; break; }
#| }
#| if (eqIdx < 0) {
#| name = inner;
#| return { name: name.trim(), operator: null, value: null, flag: null };
#| }
#| const prev = inner[eqIdx - 1];
#| if (prev === '~' || prev === '|' || prev === '^' || prev === '$' || prev === '*') {
#| operator = prev + '=';
#| name = inner.slice(0, eqIdx - 1).trim();
#| } else {
#| operator = '=';
#| name = inner.slice(0, eqIdx).trim();
#| }
#| let rest = inner.slice(eqIdx + 1).trim();
#| if (!rest) return { name, operator, value: '', flag: null };
#| if (rest[0] === '"' || rest[0] === "'") {
#| const quote = rest[0];
#| let end = 1;
#| for (; end < rest.length; end++) {
#| if (rest[end] === quote) break;
#| }
#| value = rest.slice(1, end);
#| rest = rest.slice(end + 1).trim();
#| } else {
#| let end = 0;
#| while (end < rest.length && !isAsciiWhitespaceChar(rest[end]) && rest[end] !== ']') end++;
#| value = rest.slice(0, end);
#| rest = rest.slice(end).trim();
#| }
#| if (rest.length > 0) {
#| const ch = rest[0];
#| if (ch === 'i' || ch === 'I' || ch === 's' || ch === 'S') {
#| flag = ch.toLowerCase();
#| }
#| }
#| return { name, operator, value, flag };
#| }
#| function decodeHtmlEntities(value) {
#| const named = {
#| 'lt': '<',
#| 'gt': '>',
#| 'amp': '&',
#| 'quot': '"',
#| 'apos': "'",
#| 'nbsp': '\\u00A0'
#| };
#| return String(value).replace(/&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z]+);/g, function(_, inner) {
#| if (!inner) return '&' + inner + ';';
#| if (inner[0] === '#') {
#| const hex = inner[1] === 'x' || inner[1] === 'X';
#| const num = hex ? parseInt(inner.slice(2), 16) : parseInt(inner.slice(1), 10);
#| if (!num || num > 0x10FFFF || (num >= 0xD800 && num <= 0xDFFF)) return '\\uFFFD';
#| return String.fromCodePoint(num);
#| }
#| return named[inner] || ('&' + inner + ';');
#| });
#| }
#| function parseHtmlAttributes(text) {
#| const attrs = [];
#| const re = /([^\\s=\\/>]+)(?:\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s"'>]+)))?/g;
#| let m;
#| while ((m = re.exec(text)) !== null) {
#| const name = m[1];
#| const value = m[2] !== undefined ? m[2] : (m[3] !== undefined ? m[3] : (m[4] !== undefined ? m[4] : ''));
#| attrs.push({ name, value: decodeHtmlEntities(value) });
#| }
#| return attrs;
#| }
#| function serializeHtmlAttribute(attr) {
#| if (!attr) return '';
#| return ' ' + attr.name + '="' + String(attr.value || '') + '"';
#| }
#| function serializeChildrenForHtml(node, options) {
#| let html = '';
#| const children = getChildNodesArray(node);
#| for (const child of children) {
#| html += serializeNodeForHtml(child, options);
#| }
#| return html;
#| }
#| function serializeShadowRootTemplate(shadowRoot, options) {
#| if (!shadowRoot || !shadowRoot.serializable) return '';
#| if (!(options && options.serializableShadowRoots)) return '';
#| const attrs = [' shadowrootmode="' + String(shadowRoot.mode || 'open') + '"'];
#| if (shadowRoot.delegatesFocus) attrs.push(' shadowrootdelegatesfocus');
#| if (shadowRoot.clonable) attrs.push(' shadowrootclonable');
#| if (shadowRoot.serializable) attrs.push(' shadowrootserializable');
#| return '' + serializeChildrenForHtml(shadowRoot, options) + '';
#| }
#| function serializeNodeForHtml(node, options) {
#| if (!node) return '';
#| if (node._nodeType === 3) return node._textContent || '';
#| if (node._nodeType === 8) return '';
#| if (node._nodeType === 11) return serializeChildrenForHtml(node, options);
#| if (node._nodeType !== 1) return '';
#| const attrs = (node._attrList || []).map(serializeHtmlAttribute).join('');
#| const tag = String(node._tagName || node.tagName || '').toLowerCase();
#| const shadowHtml = serializeShadowRootTemplate(node._shadowRoot || null, options);
#| const childHtml = serializeChildrenForHtml(node, options);
#| const textHtml = childHtml === '' ? (node._textContent || '') : '';
#| return '<' + tag + attrs + '>' + shadowHtml + childHtml + textHtml + '' + tag + '>';
#| }
#| function setUnsafeHtmlForNode(target, value) {
#| const html = value === null || value === undefined ? '' : String(value);
#| clearChildNodes(target);
#| if (html === '') return;
#| const owner = getOwnerDocument(target) || document;
#| const contextHost = target && target._isShadowRoot ? null : target;
#| const nodes = parseHtmlFragment(html, owner, contextHost);
#| for (const node of nodes) {
#| target.appendChild(node);
#| }
#| }
#| function parseHtmlFragment(html, ownerDoc, contextHost) {
#| const doc = ownerDoc || document;
#| const frag = doc.createDocumentFragment();
#| const voidTags = {
#| area: true, base: true, br: true, col: true, embed: true, hr: true,
#| img: true, input: true, link: true, meta: true, param: true, source: true,
#| track: true, wbr: true
#| };
#| const stack = [frag];
#| const tokenRe = /|<\\/?[A-Za-z0-9:_-]+[^>]*>|[^<]+/g;
#| let match;
#| while ((match = tokenRe.exec(String(html))) !== null) {
#| const token = match[0];
#| const current = stack[stack.length - 1];
#| if (token.startsWith(''; },
#| get parentNode() { return this._parent; },
#| get parentElement() { return this._parent && this._parent._nodeType === 1 ? this._parent : null; },
#| get firstChild() { return null; },
#| get lastChild() { return null; },
#| get childNodes() { return emptyNodeList; },
#| hasChildNodes() { return false; },
#| appendChild(child) {
#| if (child === null) throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot appendChild to a Comment node', 'HierarchyRequestError');
#| },
#| insertBefore(child, ref) {
#| if (child === null) throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| throw new DOMException('Cannot insertBefore on a Comment node', 'HierarchyRequestError');
#| },
#| removeChild(child) {
#| if (child === null) throw new TypeError('Failed to execute removeChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot removeChild from a Comment node', 'NotFoundError');
#| },
#| replaceChild(newChild, oldChild) {
#| if (newChild === null) throw new TypeError('Failed to execute replaceChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot replaceChild on a Comment node', 'HierarchyRequestError');
#| },
#| get isConnected() {
#| let n = this;
#| while (n._parent) n = n._parent;
#| return n._tagName === 'HTML';
#| },
#| getRootNode(options) { return getRootNodePublic(this, options); },
#| get nextSibling() {
#| if (!this._parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx >= 0 ? (siblings[idx + 1] || null) : null;
#| },
#| get previousSibling() {
#| if (!this._parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx > 0 ? siblings[idx - 1] : null;
#| },
#| substringData(offset, count) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'substringData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| return this._textContent.substr(offset, count);
#| },
#| appendData(data) {
#| if (arguments.length < 1) throw new TypeError("Failed to execute 'appendData': 1 argument required");
#| this._textContent = this._textContent + String(data);
#| },
#| insertData(offset, data) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'insertData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| this._textContent = this._textContent.slice(0, offset) + String(data) + this._textContent.slice(offset);
#| },
#| deleteData(offset, count) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'deleteData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| if (count > this._textContent.length - offset) count = this._textContent.length - offset;
#| this._textContent = this._textContent.slice(0, offset) + this._textContent.slice(offset + count);
#| },
#| replaceData(offset, count, data) {
#| if (arguments.length < 3) throw new TypeError("Failed to execute 'replaceData': 3 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| if (count > this._textContent.length - offset) count = this._textContent.length - offset;
#| this._textContent = this._textContent.slice(0, offset) + String(data) + this._textContent.slice(offset + count);
#| },
#| cloneNode() {
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createComment', id, text: this._textContent });
#| return createMockComment(this._textContent, id);
#| },
#| remove() { if (this._parent) this._parent.removeChild(this); },
#| before(...nodes) {
#| if (!this._parent) return;
#| const parent = this._parent;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viablePreviousSibling = this.previousSibling;
#| while (viablePreviousSibling && actualNodes.includes(viablePreviousSibling)) {
#| viablePreviousSibling = viablePreviousSibling.previousSibling;
#| }
#| let ref = viablePreviousSibling ? viablePreviousSibling.nextSibling : parent.firstChild;
#| for (let i = actualNodes.length - 1; i >= 0; i--) {
#| parent.insertBefore(actualNodes[i], ref);
#| ref = actualNodes[i];
#| }
#| },
#| after(...nodes) {
#| if (!this._parent) return;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viableNextSibling = this.nextSibling;
#| while (viableNextSibling && actualNodes.includes(viableNextSibling)) {
#| viableNextSibling = viableNextSibling.nextSibling;
#| }
#| for (const node of actualNodes) {
#| this._parent.insertBefore(node, viableNextSibling);
#| }
#| },
#| replaceWith(...nodes) {
#| if (!this._parent) return;
#| const parent = this._parent;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viableNextSibling = this.nextSibling;
#| while (viableNextSibling && actualNodes.includes(viableNextSibling)) {
#| viableNextSibling = viableNextSibling.nextSibling;
#| }
#| parent.removeChild(this);
#| for (const node of actualNodes) {
#| parent.insertBefore(node, viableNextSibling);
#| }
#| },
#| isEqualNode(other) { return other && other._nodeType === 8 && other._textContent === this._textContent; },
#| isSameNode(other) { return this === other; }
#| };
#| mockElements.set(mockId, node);
#| return node;
#| }
#|
#| function createMockProcessingInstruction(target, data, mockId) {
#| const node = {
#| _mockId: mockId,
#| _tagName: target,
#| _textContent: data,
#| _target: target,
#| _parent: null,
#| _nodeType: 7,
#| _children: [],
#| get nodeType() { return 7; },
#| get nodeName() { return this._target; },
#| get target() { return this._target; },
#| get ownerDocument() { return this._ownerDocument || getGlobalDocument(); },
#| set ownerDocument(v) { this._ownerDocument = v; },
#| get textContent() { return this._textContent; },
#| set textContent(v) { this.data = v; },
#| get nodeValue() { return this._textContent; },
#| set nodeValue(v) { this.data = v; },
#| get data() { return this._textContent; },
#| set data(v) { this._textContent = v === null ? '' : String(v); },
#| get length() { return this._textContent.length; },
#| get parentNode() { return this._parent; },
#| get parentElement() { return this._parent && this._parent._nodeType === 1 ? this._parent : null; },
#| get isConnected() {
#| let n = this;
#| while (n._parent) n = n._parent;
#| return n._tagName === 'HTML';
#| },
#| getRootNode(options) { return getRootNodePublic(this, options); },
#| get firstChild() { return null; },
#| get lastChild() { return null; },
#| get childNodes() { return emptyNodeList; },
#| hasChildNodes() { return false; },
#| get nextSibling() {
#| if (!this._parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx >= 0 ? (siblings[idx + 1] || null) : null;
#| },
#| get previousSibling() {
#| if (!this._parent) return null;
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx > 0 ? siblings[idx - 1] : null;
#| },
#| appendChild(child) {
#| if (child === null) throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot appendChild to a ProcessingInstruction node', 'HierarchyRequestError');
#| },
#| insertBefore(child, ref) {
#| if (child === null) throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| throw new DOMException('Cannot insertBefore on a ProcessingInstruction node', 'HierarchyRequestError');
#| },
#| removeChild(child) {
#| throw new DOMException('Cannot removeChild from a ProcessingInstruction node', 'NotFoundError');
#| },
#| replaceChild(newChild, oldChild) {
#| if (newChild === null) throw new TypeError('Failed to execute replaceChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot replaceChild on a ProcessingInstruction node', 'HierarchyRequestError');
#| },
#| substringData(offset, count) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'substringData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| return this._textContent.substr(offset, count);
#| },
#| appendData(data) {
#| if (arguments.length < 1) throw new TypeError("Failed to execute 'appendData': 1 argument required");
#| this._textContent = this._textContent + String(data);
#| },
#| insertData(offset, data) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'insertData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| this._textContent = this._textContent.slice(0, offset) + String(data) + this._textContent.slice(offset);
#| },
#| deleteData(offset, count) {
#| if (arguments.length < 2) throw new TypeError("Failed to execute 'deleteData': 2 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| if (count > this._textContent.length - offset) count = this._textContent.length - offset;
#| this._textContent = this._textContent.slice(0, offset) + this._textContent.slice(offset + count);
#| },
#| replaceData(offset, count, data) {
#| if (arguments.length < 3) throw new TypeError("Failed to execute 'replaceData': 3 arguments required");
#| offset = offset >>> 0;
#| if (offset > this._textContent.length) throw new DOMException('Index out of bounds', 'IndexSizeError');
#| count = count >>> 0;
#| if (count > this._textContent.length - offset) count = this._textContent.length - offset;
#| this._textContent = this._textContent.slice(0, offset) + String(data) + this._textContent.slice(offset + count);
#| },
#| cloneNode() {
#| const id = nodeIdCounter++;
#| return createMockProcessingInstruction(this._target, this._textContent, id);
#| },
#| remove() { if (this._parent) this._parent.removeChild(this); },
#| before(...nodes) {
#| if (!this._parent) return;
#| const parent = this._parent;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viablePreviousSibling = this.previousSibling;
#| while (viablePreviousSibling && actualNodes.includes(viablePreviousSibling)) {
#| viablePreviousSibling = viablePreviousSibling.previousSibling;
#| }
#| let ref = viablePreviousSibling ? viablePreviousSibling.nextSibling : parent.firstChild;
#| for (let i = actualNodes.length - 1; i >= 0; i--) {
#| parent.insertBefore(actualNodes[i], ref);
#| ref = actualNodes[i];
#| }
#| },
#| after(...nodes) {
#| if (!this._parent) return;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viableNextSibling = this.nextSibling;
#| while (viableNextSibling && actualNodes.includes(viableNextSibling)) {
#| viableNextSibling = viableNextSibling.nextSibling;
#| }
#| for (const node of actualNodes) {
#| this._parent.insertBefore(node, viableNextSibling);
#| }
#| },
#| replaceWith(...nodes) {
#| if (!this._parent) return;
#| const parent = this._parent;
#| const actualNodes = nodes.map(n => (n && n._mockId !== undefined) ? n : document.createTextNode(String(n)));
#| let viableNextSibling = this.nextSibling;
#| while (viableNextSibling && actualNodes.includes(viableNextSibling)) {
#| viableNextSibling = viableNextSibling.nextSibling;
#| }
#| parent.removeChild(this);
#| for (const node of actualNodes) {
#| parent.insertBefore(node, viableNextSibling);
#| }
#| },
#| isEqualNode(other) { return other && other._nodeType === 7 && other._target === this._target && other._textContent === this._textContent; },
#| isSameNode(other) { return this === other; }
#| };
#| mockElements.set(mockId, node);
#| return node;
#| }
#|
#| function createMockDocumentFragment(mockId) {
#| const frag = {
#| _mockId: mockId,
#| _tagName: '#document-fragment',
#| _children: [],
#| _parent: null,
#| _nodeType: 11,
#| _ownerDocument: null,
#| _activeElement: null,
#| get nodeType() { return 11; },
#| get nodeName() { return '#document-fragment'; },
#| get nodeValue() { return null; },
#| set nodeValue(v) { /* ignore */ },
#| get ownerDocument() { return this._ownerDocument || getGlobalDocument(); },
#| set ownerDocument(v) { this._ownerDocument = v; },
#| get activeElement() { return this._activeElement || null; },
#| get textContent() {
#| // Collect text content from Text node descendants only
#| const collectText = (node) => {
#| if (node._nodeType === 3 || node._nodeType === 4) return node._textContent;
#| if (!node._children) return '';
#| return node._children.map(collectText).join('');
#| };
#| return collectText(this);
#| },
#| set textContent(v) {
#| const str = (v === null || v === undefined) ? '' : String(v);
#| clearChildNodes(this);
#| if (str !== '') {
#| const textNode = document.createTextNode(str);
#| textNode._parent = this;
#| this._children.push(textNode);
#| domOps.push({ op: 'appendChild', parentId: this._mockId, childId: textNode._mockId });
#| }
#| },
#| get firstChild() { return this._children[0] || null; },
#| get lastChild() { return this._children[this._children.length - 1] || null; },
#| get childNodes() {
#| if (!this._childNodesList) {
#| this._childNodesList = makeNodeList(() => this._children.slice());
#| }
#| return this._childNodesList;
#| },
#| get children() {
#| if (!this._childrenCollection) {
#| this._childrenCollection = makeHTMLCollection(() => this._children.filter(c => c._nodeType === 1));
#| }
#| return this._childrenCollection;
#| },
#| get childElementCount() { return this._children.filter(c => c._nodeType === 1).length; },
#| hasChildNodes() { return this._children.length > 0; },
#| appendChild(child) {
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| }
#| const childType = __craterGetNodeType(child);
#| if (childType === 9 || childType === 10) {
#| throw new DOMException('Cannot append this node type', 'HierarchyRequestError');
#| }
#| if (childType === 11) {
#| const nodes = child._children ? child._children.slice() : [];
#| for (const node of nodes) this.appendChild(node);
#| if (child._children) child._children = [];
#| return child;
#| }
#| detachNode(child);
#| adoptSubtree(child, getOwnerDocument(this));
#| this._children.push(child);
#| child._parent = this;
#| if (isConnectedToDocument(this)) {
#| const doc = getOwnerDocument(this);
#| if (doc) indexSubtree(child, doc);
#| notifyConnectedSubtree(child);
#| }
#| domOps.push({ op: 'appendChild', parentId: this._mockId, childId: child._mockId });
#| return child;
#| },
#| insertBefore(newChild, refChild) {
#| if (arguments.length < 2) {
#| throw new TypeError('Failed to execute insertBefore: 2 arguments required');
#| }
#| if (!isNodeLike(newChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| }
#| if (refChild !== null && refChild !== undefined && !isNodeLike(refChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 2 is not of type Node');
#| }
#| if (refChild !== null && refChild !== undefined && refChild._parent !== this) {
#| throw new DOMException('The node before which the new node is to be inserted is not a child of this node', 'NotFoundError');
#| }
#| const newType = __craterGetNodeType(newChild);
#| if (newType === 9 || newType === 10) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| if (refChild === null || refChild === undefined) return this.appendChild(newChild);
#| if (newType === 11) {
#| const nodes = newChild._children ? newChild._children.slice() : [];
#| for (const node of nodes) this.insertBefore(node, refChild);
#| if (newChild._children) newChild._children = [];
#| return newChild;
#| }
#| let actualRef = refChild;
#| if (refChild === newChild) {
#| actualRef = newChild.nextSibling;
#| }
#| detachNode(newChild);
#| adoptSubtree(newChild, getOwnerDocument(this));
#| if (actualRef === null || actualRef === undefined) {
#| return this.appendChild(newChild);
#| }
#| const idx = this._children.indexOf(actualRef);
#| if (idx >= 0) {
#| this._children.splice(idx, 0, newChild);
#| newChild._parent = this;
#| if (isConnectedToDocument(this)) {
#| const doc = getOwnerDocument(this);
#| if (doc) indexSubtree(newChild, doc);
#| notifyConnectedSubtree(newChild);
#| }
#| domOps.push({ op: 'insertBefore', parentId: this._mockId, childId: newChild._mockId, refId: actualRef._mockId });
#| }
#| else { return this.appendChild(newChild); }
#| return newChild;
#| },
#| removeChild(child) {
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute removeChild: parameter 1 is not of type Node');
#| }
#| const idx = this._children.indexOf(child);
#| if (idx < 0) {
#| throw new DOMException('The node to be removed is not a child of this node', 'NotFoundError');
#| }
#| this._children.splice(idx, 1);
#| child._parent = null;
#| if (isConnectedToDocument(this)) {
#| const doc = getOwnerDocument(this);
#| if (doc) unindexSubtree(child, doc);
#| notifyDisconnectedSubtree(child);
#| }
#| domOps.push({ op: 'removeChild', parentId: this._mockId, childId: child._mockId });
#| return child;
#| },
#| replaceChild(newChild, oldChild) {
#| if (!isNodeLike(newChild) || !isNodeLike(oldChild)) {
#| throw new TypeError('Failed to execute replaceChild: parameters are not of type Node');
#| }
#| if (newChild === this || (newChild.contains && newChild.contains(this))) {
#| throw new DOMException('The new child is an ancestor of the parent', 'HierarchyRequestError');
#| }
#| const idx = this._children.indexOf(oldChild);
#| if (idx < 0) {
#| throw new DOMException('The node to be replaced is not a child of this node', 'NotFoundError');
#| }
#| if (newChild === oldChild) return oldChild;
#| const newType = __craterGetNodeType(newChild);
#| if (newType === 9 || newType === 10) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| if (newType === 11) {
#| const ref = oldChild.nextSibling;
#| const nodes = newChild._children ? newChild._children.slice() : [];
#| for (const node of nodes) this.insertBefore(node, ref);
#| if (newChild._children) newChild._children = [];
#| this.removeChild(oldChild);
#| return oldChild;
#| }
#| detachNode(newChild);
#| adoptSubtree(newChild, getOwnerDocument(this));
#| this._children.splice(idx, 1, newChild);
#| oldChild._parent = null;
#| newChild._parent = this;
#| if (isConnectedToDocument(this)) {
#| const doc = getOwnerDocument(this);
#| if (doc) {
#| unindexSubtree(oldChild, doc);
#| indexSubtree(newChild, doc);
#| }
#| notifyDisconnectedSubtree(oldChild);
#| notifyConnectedSubtree(newChild);
#| }
#| domOps.push({ op: 'replaceChild', parentId: this._mockId, childId: newChild._mockId, refId: oldChild._mockId });
#| return oldChild;
#| },
#| append(...nodes) {
#| parentNodeAppend(this, getOwnerDocument(this) || document, nodes);
#| },
#| prepend(...nodes) {
#| parentNodePrepend(this, getOwnerDocument(this) || document, nodes);
#| },
#| replaceChildren(...nodes) {
#| parentNodeReplaceChildren(this, getOwnerDocument(this) || document, nodes);
#| },
#| querySelector(selector) {
#| const sel = String(selector);
#| const hostMatches = getHostQueryMatches(this, sel);
#| if (hostMatches !== null) return hostMatches[0] || null;
#| const hostChildMatches = getHostChildQueryMatches(this, sel);
#| if (hostChildMatches !== null) return hostChildMatches[0] || null;
#| const classTokens = parseSimpleClassSelector(sel);
#| if (classTokens) {
#| const list = getCandidatesByFilter(this, false, { kind: 'class', tokens: classTokens });
#| if (list !== null) return list[0] || null;
#| let found = null;
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| if (matchesClassTokens(node, classTokens)) { found = node; return false; }
#| });
#| return found;
#| }
#| const tagName = parseSimpleTagSelector(sel);
#| if (tagName) {
#| const list = getCandidatesByFilter(this, false, { kind: 'tag', name: tagName });
#| if (list !== null) return list[0] || null;
#| let found = null;
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| if (matchesTagName(node, tagName)) { found = node; return false; }
#| });
#| return found;
#| }
#| const compiled = compileSelector(sel);
#| const groups = compiled.groups || [];
#| if (groups.length === 0) return null;
#| let found = null;
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, this, true)) { found = node; return false; }
#| }
#| });
#| return found;
#| },
#| querySelectorAll(selector) {
#| const sel = String(selector);
#| const hostMatches = getHostQueryMatches(this, sel);
#| if (hostMatches !== null) return makeNodeList(hostMatches);
#| const hostChildMatches = getHostChildQueryMatches(this, sel);
#| if (hostChildMatches !== null) return makeNodeList(hostChildMatches);
#| const classTokens = parseSimpleClassSelector(sel);
#| if (classTokens) {
#| const list = getCandidatesByFilter(this, false, { kind: 'class', tokens: classTokens });
#| if (list !== null) return makeNodeList(list);
#| return makeNodeList(collectElements(this, false, (el) => matchesClassTokens(el, classTokens)));
#| }
#| const tagName = parseSimpleTagSelector(sel);
#| if (tagName) {
#| const list = getCandidatesByFilter(this, false, { kind: 'tag', name: tagName });
#| if (list !== null) return makeNodeList(list);
#| return makeNodeList(collectElements(this, false, (el) => matchesTagName(el, tagName)));
#| }
#| const compiled = compileSelector(sel);
#| const groups = compiled.groups || [];
#| if (groups.length === 0) return makeNodeList([]);
#| const allFilterable = groups.every(
#| g => g.filter && !(g.filter.kind === 'tag' && String(g.filter.name) === '*')
#| );
#| if (!allFilterable || !isConnectedToDocument(this)) {
#| const results = [];
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, this, true)) {
#| results.push(node);
#| break;
#| }
#| }
#| });
#| return makeNodeList(results);
#| }
#| const fallbackTraversal = () => {
#| const results = [];
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, this, true)) {
#| results.push(node);
#| break;
#| }
#| }
#| });
#| return makeNodeList(results);
#| };
#| if (groups.length === 1) {
#| const group = groups[0];
#| const candidates = getCandidatesByFilter(this, false, group.filter, true);
#| if (candidates === null) return fallbackTraversal();
#| const results = [];
#| for (const node of candidates) {
#| if (!matchesSelectorGroupCompiled(node, group, this, true)) continue;
#| results.push(node);
#| }
#| return makeNodeList(results);
#| }
#| const results = [];
#| const seen = new Set();
#| let useIndex = true;
#| for (const group of groups) {
#| const candidates = getCandidatesByFilter(this, false, group.filter, true);
#| if (candidates === null) { useIndex = false; break; }
#| for (const node of candidates) {
#| if (!matchesSelectorGroupCompiled(node, group, this, true)) continue;
#| if (!seen.has(node)) { seen.add(node); results.push(node); }
#| }
#| }
#| if (!useIndex) return fallbackTraversal();
#| if (results.length > 1) {
#| results.sort((a, b) => {
#| if (a === b) return 0;
#| const pos = compareDocumentPositionImpl(a, b);
#| return (pos & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1;
#| });
#| }
#| return makeNodeList(results);
#| },
#| getElementById(id) {
#| const target = String(id);
#| if (target === '') return null;
#| let found = null;
#| traverseTree(this, (node) => {
#| if (node._nodeType !== 1) return;
#| if (node.id === target) { found = node; return false; }
#| });
#| return found;
#| },
#| cloneNode(deep) {
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createDocumentFragment', id });
#| const clone = createMockDocumentFragment(id);
#| if (deep) {
#| for (const child of this._children) {
#| const clonedChild = child.cloneNode(true);
#| clone._children.push(clonedChild);
#| clonedChild._parent = clone;
#| }
#| }
#| return clone;
#| },
#| isEqualNode(other) {
#| if (!other || other._nodeType !== 11) return false;
#| if (this._children.length !== (other._children || []).length) return false;
#| for (let i = 0; i < this._children.length; i++) {
#| if (!this._children[i].isEqualNode || !this._children[i].isEqualNode(other._children[i])) return false;
#| }
#| return true;
#| },
#| isSameNode(other) { return this === other; },
#| addEventListener(type, listener, options) { addEventListenerImpl(this, type, listener, options); },
#| removeEventListener(type, listener, options) { removeEventListenerImpl(this, type, listener, options); },
#| dispatchEvent(event) { return dispatchEventImpl(this, event); }
#| };
#| mockElements.set(mockId, frag);
#| return frag;
#| }
#|
#| const htmlEl = createMockElement('html', 1);
#| const headEl = createMockElement('head', 3);
#| const bodyEl = createMockElement('body', 2);
#| Object.setPrototypeOf(htmlEl, HTMLHtmlElement.prototype);
#| Object.setPrototypeOf(headEl, HTMLHeadElement.prototype);
#| Object.setPrototypeOf(bodyEl, HTMLBodyElement.prototype);
#| htmlEl.appendChild(headEl);
#| htmlEl.appendChild(bodyEl);
#| let _title = '';
#| let _doctype = null;
#| let _implementation = null;
#|
#| const document = {
#| _mockElements: mockElements,
#| _preNodes: [],
#| _postNodes: [],
#| _nodeType: 9,
#| _parent: null,
#| get nodeType() { return 9; },
#| get nodeName() { return '#document'; },
#| get nodeValue() { return null; },
#| get textContent() { return null; },
#| set textContent(v) { /* Document textContent is null, ignore setter */ },
#| get ownerDocument() { return null; },
#| get parentNode() { return null; },
#| get parentElement() { return null; },
#| get nextSibling() { return null; },
#| get previousSibling() { return null; },
#| get URL() {
#| if (typeof location !== 'undefined') {
#| return String(location);
#| }
#| return 'about:blank';
#| },
#| get documentURI() {
#| if (typeof location !== 'undefined') {
#| return String(location);
#| }
#| return 'about:blank';
#| },
#| get baseURI() {
#| if (typeof location !== 'undefined') {
#| return String(location);
#| }
#| return 'about:blank';
#| },
#| get compatMode() { return 'CSS1Compat'; },
#| get characterSet() { return 'UTF-8'; },
#| get charset() { return 'UTF-8'; },
#| get inputEncoding() { return 'UTF-8'; },
#| get contentType() { return 'text/html'; },
#| get doctype() { return _doctype; },
#| _setDoctype(dt) { _doctype = dt; },
#| get implementation() {
#| if (_implementation) return _implementation;
#| // Helper to create implementation bound to a specific document
#| const createImplForDoc = function(ownerDoc) {
#| return {
#| _ownerDocument: ownerDoc,
#| createDocument(namespace, qualifiedName, doctype) {
#| if (arguments.length < 2) {
#| throw new TypeError("Failed to execute 'createDocument': 2 arguments required");
#| }
#| const validateQualifiedName = (ns, qname) => {
#| if (qname === null || qname === undefined) return null;
#| const name = String(qname);
#| if (name === '') return null;
#| return validateElementQualifiedName(ns, name);
#| };
#| validateQualifiedName(namespace, qualifiedName);
#| if (doctype !== undefined && doctype !== null && (!doctype._nodeType || doctype._nodeType !== 10)) {
#| throw new TypeError("Failed to execute 'createDocument': parameter 3 is not of type DocumentType");
#| }
#| // Determine content type based on namespace
#| let contentType = 'application/xml';
#| if (namespace === 'http://www.w3.org/1999/xhtml') {
#| contentType = 'application/xhtml+xml';
#| } else if (namespace === 'http://www.w3.org/2000/svg') {
#| contentType = 'image/svg+xml';
#| }
#| let doc = null;
#| const createElementForDoc = function(ns, qname, options) {
#| const normalizedNs = ns === undefined || ns === '' ? null : ns;
#| const name = String(qname);
#| const parsed = normalizedNs === null
#| ? (function() {
#| if (!isValidElementName(name)) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| return { prefix: null, localName: name };
#| })()
#| : validateElementQualifiedName(normalizedNs, name);
#| const isHtmlNamespace = normalizedNs === 'http://www.w3.org/1999/xhtml';
#| const localName = parsed.localName;
#| const prefix = parsed.prefix;
#| const tagName = prefix === null ? localName : prefix + ':' + localName;
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createElement', id, tagName });
#| const el = createMockElement(tagName, id);
#| el._tagName = tagName;
#| el._localName = localName;
#| el._namespaceURI = normalizedNs;
#| el._prefix = prefix;
#| el._ownerDocument = doc;
#| const isValue = normalizedNs === 'http://www.w3.org/1999/xhtml'
#| ? getCustomElementIsValue(options)
#| : null;
#| if (isValue) {
#| el._attrList.push(createAttrNode(doc, null, 'is', isValue, el, false));
#| }
#| const lowerName = asciiLowercase(localName);
#| const Ctor = isHtmlNamespace
#| ? (localName === lowerName ? (tagToConstructor[lowerName] || HTMLElement) : HTMLUnknownElement)
#| : Element;
#| Object.setPrototypeOf(el, Ctor.prototype);
#| return isHtmlNamespace ? maybeUpgradeCustomElement(el) : el;
#| };
#| const createAttributeForDoc = function(name, lowercase) {
#| return createAttrNode(doc, null, name, '', null, lowercase);
#| };
#| doc = {
#| _nodeType: 9,
#| nodeType: 9,
#| nodeName: '#document',
#| ownerDocument: null,
#| get nodeValue() { return null; },
#| set nodeValue(v) { /* ignore */ },
#| get textContent() { return null; },
#| set textContent(v) { /* ignore */ },
#| documentElement: null,
#| doctype: doctype !== undefined ? doctype : null,
#| _children: [],
#| _impl: null,
#| URL: 'about:blank',
#| documentURI: 'about:blank',
#| compatMode: 'CSS1Compat',
#| characterSet: 'UTF-8',
#| charset: 'UTF-8',
#| inputEncoding: 'UTF-8',
#| contentType: contentType,
#| location: null,
#| get implementation() {
#| if (!this._impl) this._impl = createImplForDoc(this);
#| return this._impl;
#| },
#| createElement(name, options) {
#| const defaultNs = (this.contentType === 'text/html' || this.contentType === 'application/xhtml+xml')
#| ? 'http://www.w3.org/1999/xhtml'
#| : null;
#| return createElementForDoc(defaultNs, name, options);
#| },
#| createElementNS(ns, name, options) { return createElementForDoc(ns, name, options); },
#| createTextNode(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createTextNode', id, text: str });
#| const node = createMockTextNode(str, id);
#| node._ownerDocument = doc;
#| Object.setPrototypeOf(node, Text.prototype);
#| return node;
#| },
#| createCDATASection(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createCDATASection', id, text: str });
#| const node = createMockCDATASection(str, id);
#| node._ownerDocument = doc;
#| Object.setPrototypeOf(node, Text.prototype);
#| return node;
#| },
#| createComment(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createComment', id, text: str });
#| const node = createMockComment(str, id);
#| node._ownerDocument = doc;
#| Object.setPrototypeOf(node, Comment.prototype);
#| return node;
#| },
#| createProcessingInstruction(target, data) {
#| const node = document.createProcessingInstruction(target, data);
#| node._ownerDocument = doc;
#| Object.setPrototypeOf(node, ProcessingInstruction.prototype);
#| return node;
#| },
#| createDocumentFragment() {
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createDocumentFragment', id });
#| const frag = createMockDocumentFragment(id);
#| frag._ownerDocument = doc;
#| Object.setPrototypeOf(frag, DocumentFragment.prototype);
#| return frag;
#| },
#| createAttribute(name) { return createAttributeForDoc(name, false); },
#| createAttributeNS(ns, name) {
#| const normalizedNs = ns === undefined || ns === '' ? null : ns;
#| return createAttrNode(doc, normalizedNs, name, '', null, false);
#| },
#| insertBefore(newChild, refChild) {
#| if (arguments.length < 2) {
#| throw new TypeError('Failed to execute insertBefore: 2 arguments required');
#| }
#| if (!isNodeLike(newChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| }
#| if (refChild !== null && refChild !== undefined && !isNodeLike(refChild)) {
#| throw new TypeError('Failed to execute insertBefore: parameter 2 is not of type Node');
#| }
#| if (newChild === this || (newChild.contains && newChild.contains(this))) {
#| throw new DOMException('The new child is an ancestor of the parent', 'HierarchyRequestError');
#| }
#| if (refChild !== null && refChild !== undefined && refChild._parent !== this) {
#| throw new DOMException('The node before which the new node is to be inserted is not a child of this node', 'NotFoundError');
#| }
#| const exclude = arguments.length > 2 ? arguments[2] : null;
#| let actualRef = refChild === undefined ? null : refChild;
#| if (actualRef === newChild) {
#| actualRef = newChild.nextSibling;
#| }
#| validateDocumentInsert(this, newChild, actualRef, exclude);
#| const newType = __craterGetNodeType(newChild);
#| if (newType === 11) {
#| const nodes = newChild._children ? newChild._children.slice() : [];
#| for (const node of nodes) {
#| this.insertBefore(node, actualRef, exclude);
#| }
#| if (newChild._children) newChild._children = [];
#| return newChild;
#| }
#| detachNode(newChild);
#| adoptSubtree(newChild, this);
#| if (actualRef === null || actualRef === undefined) {
#| this._children.push(newChild);
#| } else {
#| const idx = this._children.indexOf(actualRef);
#| if (idx < 0) {
#| throw new DOMException('The node before which the new node is to be inserted is not a child of this node', 'NotFoundError');
#| }
#| this._children.splice(idx, 0, newChild);
#| }
#| newChild._parent = this;
#| newChild.parentNode = this;
#| if (newType === 1) this.documentElement = newChild;
#| if (newType === 10) this.doctype = newChild;
#| indexSubtree(newChild, this);
#| return newChild;
#| },
#| appendChild(child) { return this.insertBefore(child, null); },
#| replaceChild(newChild, oldChild) {
#| if (!isNodeLike(newChild) || !isNodeLike(oldChild)) {
#| throw new TypeError('Failed to execute replaceChild: parameters are not of type Node');
#| }
#| const idx = this._children.indexOf(oldChild);
#| if (idx < 0) {
#| throw new DOMException('The node to be replaced is not a child of this node', 'NotFoundError');
#| }
#| if (newChild === oldChild) return oldChild;
#| this.insertBefore(newChild, oldChild, oldChild);
#| this.removeChild(oldChild);
#| return oldChild;
#| },
#| removeChild(child) {
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute removeChild: parameter 1 is not of type Node');
#| }
#| const idx = this._children.indexOf(child);
#| if (idx < 0) {
#| throw new DOMException('The node to be removed is not a child of this node', 'NotFoundError');
#| }
#| this._children.splice(idx, 1);
#| child._parent = null;
#| child.parentNode = null;
#| if (child._nodeType === 1) this.documentElement = null;
#| if (child._nodeType === 10) this.doctype = null;
#| unindexSubtree(child, this);
#| return child;
#| },
#| append(...nodes) {
#| parentNodeAppend(this, this, nodes);
#| },
#| prepend(...nodes) {
#| parentNodePrepend(this, this, nodes);
#| },
#| replaceChildren(...nodes) {
#| parentNodeReplaceChildren(this, this, nodes);
#| },
#| get childNodes() {
#| if (!this._childNodesList) {
#| this._childNodesList = makeNodeList(() => this._children.slice());
#| }
#| return this._childNodesList;
#| },
#| get firstChild() { return this._children[0] || null; },
#| get lastChild() { return this._children[this._children.length - 1] || null; },
#| getRootNode() { return this; },
#| isSameNode(other) { return this === other; },
#| isEqualNode(other) {
#| if (!other || other._nodeType !== 9) return false;
#| const kids1 = this._children || [];
#| const kids2 = other._children || [];
#| if (kids1.length !== kids2.length) return false;
#| for (let i = 0; i < kids1.length; i++) {
#| if (!kids1[i].isEqualNode || !kids1[i].isEqualNode(kids2[i])) return false;
#| }
#| return true;
#| },
#| cloneNode(deep) {
#| const impl = this.implementation || document.implementation;
#| const isHtml = this.contentType === 'text/html' || this.contentType === 'application/xhtml+xml'
#| || (this.documentElement && this.documentElement._tagName === 'HTML');
#| if (isHtml) {
#| const cloned = impl && impl.createHTMLDocument ? impl.createHTMLDocument('') : document.implementation.createHTMLDocument('');
#| return cloned;
#| }
#| const ns = this.documentElement ? this.documentElement.namespaceURI : null;
#| const cloned = impl && impl.createDocument ? impl.createDocument(ns, null, null) : document.implementation.createDocument(ns, null, null);
#| if (this.contentType) cloned.contentType = this.contentType;
#| if (this.URL) cloned.URL = this.URL;
#| if (this.compatMode) cloned.compatMode = this.compatMode;
#| if (this.charset) cloned.charset = this.charset;
#| if (this.characterSet) cloned.characterSet = this.characterSet;
#| if (this.inputEncoding) cloned.inputEncoding = this.inputEncoding;
#| if (deep && this._children) {
#| for (const child of this._children) {
#| cloned.appendChild(child.cloneNode(true));
#| }
#| }
#| return cloned;
#| },
#| adoptNode(node) {
#| if (!node) return null;
#| if (node._nodeType === 9) throw new DOMException('Cannot adopt a document node', 'NotSupportedError');
#| const detach = (n) => {
#| if (!n._parent) return;
#| if (typeof n._parent.removeChild === 'function') {
#| n._parent.removeChild(n);
#| } else if (Array.isArray(n._parent._children)) {
#| const idx = n._parent._children.indexOf(n);
#| if (idx >= 0) n._parent._children.splice(idx, 1);
#| }
#| n._parent = null;
#| if ('parentNode' in n) n.parentNode = null;
#| };
#| const updateOwner = (n) => {
#| n.ownerDocument = this;
#| if (n._children) {
#| for (const c of n._children) updateOwner(c);
#| }
#| };
#| detach(node);
#| updateOwner(node);
#| return node;
#| },
#| addEventListener(type, listener, options) {
#| addEventListenerImpl(this, type, listener, options);
#| },
#| removeEventListener(type, listener, options) {
#| removeEventListenerImpl(this, type, listener, options);
#| },
#| dispatchEvent(event) {
#| return dispatchEventImpl(this, event);
#| }
#| };
#| ensureDocumentIndexes(doc);
#| doc.cloneNode = function(deep) {
#| const impl = this.implementation || document.implementation;
#| const ns = this.documentElement ? this.documentElement.namespaceURI : null;
#| const cloned = impl && impl.createDocument ? impl.createDocument(ns, null, null) : document.implementation.createDocument(ns, null, null);
#| cloned.contentType = this.contentType;
#| cloned.URL = this.URL;
#| cloned.compatMode = this.compatMode;
#| cloned.charset = this.charset;
#| cloned.characterSet = this.characterSet;
#| cloned.inputEncoding = this.inputEncoding;
#| if (deep && this._children) {
#| for (const child of this._children) {
#| cloned.appendChild(child.cloneNode(true));
#| }
#| }
#| return cloned;
#| };
#| Object.setPrototypeOf(doc, XMLDocument.prototype);
#| if (doctype !== undefined && doctype !== null) {
#| doctype.ownerDocument = doc;
#| doctype._parent = doc;
#| doctype.parentNode = doc;
#| doc._children.push(doctype);
#| doc.doctype = doctype;
#| }
#| const qname = qualifiedName === null ? null : String(qualifiedName);
#| if (qname !== null && qname !== '') {
#| const el = createElementForDoc(namespace, qname);
#| doc.appendChild(el);
#| }
#| return doc;
#| },
#| createDocumentType(qualifiedName, publicId, systemId) {
#| const ownerDoc = this._ownerDocument || document;
#| const qname = String(qualifiedName);
#| validateDoctypeQualifiedName(qname);
#| const doctype = {
#| _nodeType: 10,
#| nodeType: 10,
#| name: qname,
#| publicId: publicId || '',
#| systemId: systemId || '',
#| nodeName: qname,
#| get nodeValue() { return null; },
#| set nodeValue(v) { /* ignore */ },
#| get textContent() { return null; },
#| set textContent(v) { /* ignore */ },
#| ownerDocument: ownerDoc,
#| parentNode: null,
#| _parent: null,
#| get firstChild() { return null; },
#| get lastChild() { return null; },
#| get previousSibling() {
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx > 0 ? siblings[idx - 1] : null;
#| },
#| get nextSibling() {
#| const siblings = getSiblingArray(this);
#| const idx = siblings.indexOf(this);
#| return idx >= 0 ? (siblings[idx + 1] || null) : null;
#| },
#| get childNodes() { return emptyNodeList; },
#| hasChildNodes() { return false; },
#| appendChild(child) {
#| if (!isNodeLike(child)) throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot appendChild to a DocumentType node', 'HierarchyRequestError');
#| },
#| insertBefore(child, ref) {
#| if (!isNodeLike(child)) throw new TypeError('Failed to execute insertBefore: parameter 1 is not of type Node');
#| throw new DOMException('Cannot insertBefore on a DocumentType node', 'HierarchyRequestError');
#| },
#| removeChild(child) {
#| if (!isNodeLike(child)) throw new TypeError('Failed to execute removeChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot removeChild from a DocumentType node', 'NotFoundError');
#| },
#| replaceChild(newChild, oldChild) {
#| if (!isNodeLike(newChild)) throw new TypeError('Failed to execute replaceChild: parameter 1 is not of type Node');
#| throw new DOMException('Cannot replaceChild on a DocumentType node', 'HierarchyRequestError');
#| },
#| isSameNode(other) { return this === other; },
#| isEqualNode(other) { return other && other._nodeType === 10 && other.name === this.name && other.publicId === this.publicId && other.systemId === this.systemId; },
#| cloneNode() {
#| return ownerDoc.implementation.createDocumentType(this.name, this.publicId, this.systemId);
#| },
#| remove() {
#| if (this._parent && typeof this._parent.removeChild === 'function') {
#| this._parent.removeChild(this);
#| } else if (this._parent && Array.isArray(this._parent._children)) {
#| const idx = this._parent._children.indexOf(this);
#| if (idx >= 0) this._parent._children.splice(idx, 1);
#| this._parent = null;
#| this.parentNode = null;
#| }
#| },
#| getRootNode() {
#| let node = this;
#| while (node._parent) node = node._parent;
#| return node;
#| }
#| };
#| Object.setPrototypeOf(doctype, DocumentType.prototype);
#| return doctype;
#| },
#| createHTMLDocument(title) {
#| const doctype = this.createDocumentType('html', '', '');
#| const doc = this.createDocument(null, null, doctype);
#| doc.cloneNode = function(deep) {
#| const impl = this.implementation || document.implementation;
#| const cloned = impl && impl.createHTMLDocument ? impl.createHTMLDocument('') : document.implementation.createHTMLDocument('');
#| return cloned;
#| };
#| Object.setPrototypeOf(doc, HTMLDocument.prototype);
#| doc._children = [doctype];
#| doctype._parent = doc;
#| doctype.parentNode = doc;
#| doctype.ownerDocument = doc;
#| doc.doctype = doctype;
#| doc.contentType = 'text/html';
#| doc.createElement = function(name) {
#| const el = document.createElement(name);
#| el._ownerDocument = doc;
#| return el;
#| };
#| doc.createElementNS = function(ns, name) {
#| const el = document.createElementNS(ns, name);
#| el._ownerDocument = doc;
#| return el;
#| };
#| doc.createAttribute = function(name) {
#| const attr = document.createAttribute(name);
#| attr.ownerDocument = doc;
#| return attr;
#| };
#| doc.createAttributeNS = function(ns, name) {
#| const attr = document.createAttributeNS(ns, name);
#| attr.ownerDocument = doc;
#| return attr;
#| };
#| doc.createTextNode = function(text) {
#| const node = document.createTextNode(text);
#| node._ownerDocument = doc;
#| return node;
#| };
#| doc.createComment = function(text) {
#| const node = document.createComment(text);
#| node._ownerDocument = doc;
#| return node;
#| };
#| doc.createDocumentFragment = function() {
#| const frag = document.createDocumentFragment();
#| frag._ownerDocument = doc;
#| return frag;
#| };
#| const html = doc.createElement('html');
#| const head = doc.createElement('head');
#| const body = doc.createElement('body');
#| if (title !== undefined) {
#| const titleEl = doc.createElement('title');
#| const titleText = title === null ? 'null' : String(title);
#| const textNode = doc.createTextNode(titleText);
#| titleEl.appendChild(textNode);
#| head.appendChild(titleEl);
#| }
#| html.appendChild(head);
#| html.appendChild(body);
#| doc.appendChild(html);
#| doc.documentElement = html;
#| doc.head = head;
#| doc.body = body;
#| doc.title = title === null ? 'null' : (title === undefined ? '' : String(title));
#| return doc;
#| },
#| hasFeature() { return true; }
#| };
#| };
#| const impl = createImplForDoc(document);
#| Object.setPrototypeOf(impl, DOMImplementation.prototype);
#| _implementation = impl;
#| return impl;
#| },
#| _activeElement: bodyEl,
#| get activeElement() { return this._activeElement || this.body || bodyEl || null; },
#| set activeElement(value) { this._activeElement = value || this.body || bodyEl || null; },
#| get forms() {
#| if (!this._formsCollection) {
#| this._formsCollection = makeHTMLCollection(() =>
#| collectElements(htmlEl, true, (el) => isFormElementNode(el))
#| );
#| }
#| return this._formsCollection;
#| },
#| get images() { return []; },
#| get links() { return []; },
#| get scripts() { return []; },
#| get embeds() { return []; },
#| get plugins() { return []; },
#| hasFocus() { return !!(this._activeElement || this.body || bodyEl); },
#| createElement(tagName, options) {
#| const rawName = String(tagName);
#| if (!isValidElementName(rawName)) {
#| throw new DOMException('Invalid character in qualifiedName', 'InvalidCharacterError');
#| }
#| const normalizedName = asciiLowercase(rawName);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createElement', id, tagName: normalizedName });
#| const el = createMockElement(normalizedName, id);
#| el._tagName = normalizedName;
#| el._localName = normalizedName;
#| el._prefix = null;
#| const isValue = getCustomElementIsValue(options);
#| if (isValue) {
#| el._attrList.push(createAttrNode(document, null, 'is', isValue, el, false));
#| }
#| const Ctor = tagToConstructor[normalizedName] || HTMLUnknownElement;
#| Object.setPrototypeOf(el, Ctor.prototype);
#| return maybeUpgradeCustomElement(el);
#| },
#| createTextNode(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createTextNode', id, text: str });
#| const node = createMockTextNode(str, id);
#| Object.setPrototypeOf(node, Text.prototype);
#| return node;
#| },
#| createCDATASection(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createCDATASection', id, text: str });
#| const node = createMockCDATASection(str, id);
#| Object.setPrototypeOf(node, Text.prototype);
#| return node;
#| },
#| createComment(text) {
#| const str = String(text);
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createComment', id, text: str });
#| const node = createMockComment(str, id);
#| Object.setPrototypeOf(node, Comment.prototype);
#| return node;
#| },
#| createAttribute(name) {
#| return createAttrNode(getGlobalDocument(), null, name, '', null, true);
#| },
#| createAttributeNS(ns, name) {
#| const normalizedNs = ns === undefined || ns === '' ? null : ns;
#| return createAttrNode(getGlobalDocument(), normalizedNs, name, '', null, false);
#| },
#| createDocumentFragment() {
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createDocumentFragment', id });
#| return createMockDocumentFragment(id);
#| },
#| cloneNode(deep) {
#| const impl = this.implementation || document.implementation;
#| const cloned = impl && impl.createHTMLDocument ? impl.createHTMLDocument('') : document.implementation.createHTMLDocument('');
#| if (deep) {
#| const kids = getChildNodesArray(this);
#| for (const child of kids) {
#| cloned.appendChild(child.cloneNode(true));
#| }
#| }
#| return cloned;
#| },
#| appendChild(child) {
#| if (!isNodeLike(child)) {
#| throw new TypeError('Failed to execute appendChild: parameter 1 is not of type Node');
#| }
#| const type = __craterGetNodeType(child);
#| if (type === 9 || type === 2) {
#| throw new DOMException('Cannot insert this node type', 'HierarchyRequestError');
#| }
#| if (type === 3) {
#| throw new DOMException('Cannot insert a text node into document', 'HierarchyRequestError');
#| }
#| if (type === 1 || type === 10) {
#| throw new DOMException('Document already has an element', 'HierarchyRequestError');
#| }
#| if (type === 11) {
#| const nodes = child._children ? child._children.slice() : [];
#| for (const node of nodes) {
#| this.appendChild(node);
#| }
#| if (child._children) child._children = [];
#| return child;
#| }
#| detachNode(child);
#| adoptSubtree(child, this);
#| this._postNodes.push(child);
#| child._parent = this;
#| child.parentNode = this;
#| indexSubtree(child, this);
#| return child;
#| },
#| get body() { return bodyEl; },
#| get head() { return headEl; },
#| get documentElement() { return htmlEl; },
#| get title() { return _title; },
#| set title(v) { _title = String(v); },
#| get childNodes() {
#| if (!this._childNodesList) {
#| this._childNodesList = makeNodeList(() => {
#| const nodes = [];
#| if (this._preNodes && this._preNodes.length > 0) nodes.push(...this._preNodes);
#| if (_doctype) nodes.push(_doctype);
#| nodes.push(htmlEl);
#| if (this._postNodes && this._postNodes.length > 0) nodes.push(...this._postNodes);
#| return nodes;
#| });
#| }
#| return this._childNodesList;
#| },
#| hasChildNodes() { return this.childNodes.length > 0; },
#| get children() {
#| if (!this._childrenCollection) {
#| this._childrenCollection = makeHTMLCollection(() => [htmlEl]);
#| }
#| return this._childrenCollection;
#| },
#| get firstChild() {
#| const nodes = this.childNodes;
#| return nodes[0] || null;
#| },
#| get lastChild() {
#| const nodes = this.childNodes;
#| return nodes[nodes.length - 1] || null;
#| },
#| getElementById(id) {
#| const target = String(id);
#| if (target === '') return null;
#| let found = null;
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| if (node.id === target) { found = node; return false; }
#| });
#| return found;
#| },
#| getElementsByTagName(tag) {
#| const name = String(tag);
#| if (name !== '*') {
#| return makeHTMLCollection(() => {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'tag', name });
#| if (list !== null) return list;
#| return collectElements(htmlEl, true, (el) => matchesTagName(el, name));
#| });
#| }
#| return makeHTMLCollection(() => collectElements(htmlEl, true, (el) => matchesTagName(el, name)));
#| },
#| getElementsByClassName(cls) {
#| const tokens = parseClassTokens(cls);
#| if (tokens.length === 0) return makeHTMLCollection(() => []);
#| return makeHTMLCollection(() => {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'class', tokens });
#| if (list !== null) return list;
#| return collectElements(htmlEl, true, (el) => matchesClassTokens(el, tokens));
#| });
#| },
#| getElementsByName(name) {
#| const target = String(name);
#| return makeNodeList(() => collectElements(htmlEl, true, (el) => el._attrs && el._attrs.name === target));
#| },
#| querySelector(selector) {
#| const sel = String(selector);
#| const classTokens = parseSimpleClassSelector(sel);
#| if (classTokens) {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'class', tokens: classTokens });
#| if (list !== null) return list[0] || null;
#| let found = null;
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| if (matchesClassTokens(node, classTokens)) { found = node; return false; }
#| });
#| return found;
#| }
#| const tagName = parseSimpleTagSelector(sel);
#| if (tagName) {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'tag', name: tagName });
#| if (list !== null) return list[0] || null;
#| let found = null;
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| if (matchesTagName(node, tagName)) { found = node; return false; }
#| });
#| return found;
#| }
#| const compiled = compileSelector(sel);
#| const groups = compiled.groups || [];
#| if (groups.length === 0) return null;
#| let found = null;
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, htmlEl, true)) { found = node; return false; }
#| }
#| });
#| return found;
#| },
#| querySelectorAll(selector) {
#| const sel = String(selector);
#| const classTokens = parseSimpleClassSelector(sel);
#| if (classTokens) {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'class', tokens: classTokens });
#| if (list !== null) return makeNodeList(list);
#| return makeNodeList(collectElements(htmlEl, true, (el) => matchesClassTokens(el, classTokens)));
#| }
#| const tagName = parseSimpleTagSelector(sel);
#| if (tagName) {
#| const list = getCandidatesByFilter(htmlEl, true, { kind: 'tag', name: tagName });
#| if (list !== null) return makeNodeList(list);
#| return makeNodeList(collectElements(htmlEl, true, (el) => matchesTagName(el, tagName)));
#| }
#| const compiled = compileSelector(sel);
#| const groups = compiled.groups || [];
#| if (groups.length === 0) return makeNodeList([]);
#| const allFilterable = groups.every(
#| g => g.filter && !(g.filter.kind === 'tag' && String(g.filter.name) === '*')
#| );
#| if (!allFilterable || !isConnectedToDocument(htmlEl)) {
#| const results = [];
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, htmlEl, true)) {
#| results.push(node);
#| break;
#| }
#| }
#| });
#| return makeNodeList(results);
#| }
#| const fallbackTraversal = () => {
#| const results = [];
#| traverseTree(htmlEl, (node) => {
#| if (node._nodeType !== 1) return;
#| for (const group of groups) {
#| if (group.filter && !applySimpleFilter(node, group.filter)) continue;
#| if (matchesSelectorGroupCompiled(node, group, htmlEl, true)) {
#| results.push(node);
#| break;
#| }
#| }
#| });
#| return makeNodeList(results);
#| };
#| if (groups.length === 1) {
#| const group = groups[0];
#| const candidates = getCandidatesByFilter(htmlEl, true, group.filter, true);
#| if (candidates === null) return fallbackTraversal();
#| const results = [];
#| for (const node of candidates) {
#| if (!matchesSelectorGroupCompiled(node, group, htmlEl, true)) continue;
#| results.push(node);
#| }
#| return makeNodeList(results);
#| }
#| const results = [];
#| const seen = new Set();
#| let useIndex = true;
#| for (const group of groups) {
#| const candidates = getCandidatesByFilter(htmlEl, true, group.filter, true);
#| if (candidates === null) { useIndex = false; break; }
#| for (const node of candidates) {
#| if (!matchesSelectorGroupCompiled(node, group, htmlEl, true)) continue;
#| if (!seen.has(node)) { seen.add(node); results.push(node); }
#| }
#| }
#| if (!useIndex) return fallbackTraversal();
#| if (results.length > 1) {
#| results.sort((a, b) => {
#| if (a === b) return 0;
#| const pos = compareDocumentPositionImpl(a, b);
#| return (pos & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1;
#| });
#| }
#| return makeNodeList(results);
#| },
#| createEvent(type) {
#| const name = String(type);
#| const lower = asciiLowercase(name);
#| const eventMap = {
#| 'beforeunloadevent': BeforeUnloadEvent,
#| 'compositionevent': CompositionEvent,
#| 'clipboardevent': ClipboardEvent,
#| 'customevent': CustomEvent,
#| 'devicemotionevent': DeviceMotionEvent,
#| 'deviceorientationevent': DeviceOrientationEvent,
#| 'dragevent': DragEvent,
#| 'event': Event,
#| 'events': Event,
#| 'focusevent': FocusEvent,
#| 'hashchangeevent': HashChangeEvent,
#| 'htmlevents': Event,
#| 'inputevent': InputEvent,
#| 'keyboardevent': KeyboardEvent,
#| 'messageevent': MessageEvent,
#| 'mouseevent': MouseEvent,
#| 'mouseevents': MouseEvent,
#| 'pointerevent': PointerEvent,
#| 'storageevent': StorageEvent,
#| 'svgevents': Event,
#| 'textevent': TextEvent,
#| 'uievent': UIEvent,
#| 'uievents': UIEvent,
#| 'touchevent': TouchEvent
#| };
#| const ctor = eventMap[lower];
#| if (!ctor) {
#| throw new DOMException('Not supported', 'NotSupportedError');
#| }
#| if (lower === 'touchevent' && !('ontouchstart' in document)) {
#| throw new DOMException('Not supported', 'NotSupportedError');
#| }
#| const ev = new ctor('');
#| ev._type = '';
#| ev._target = null;
#| ev._currentTarget = null;
#| ev._eventPhase = 0;
#| ev._bubbles = false;
#| ev._cancelable = false;
#| ev._defaultPrevented = false;
#| ev._isTrusted = false;
#| return ev;
#| },
#| contains(node) { return nodeContains(this, node); },
#| createElementNS(ns, qualifiedName) {
#| const normalizedNs = ns === undefined || ns === '' ? null : ns;
#| const name = String(qualifiedName);
#| const parsed = validateElementQualifiedName(normalizedNs, name);
#| const isHtmlNamespace = normalizedNs === 'http://www.w3.org/1999/xhtml';
#| const localName = parsed.localName;
#| const prefix = parsed.prefix;
#| const tagName = prefix === null ? localName : prefix + ':' + localName;
#| const id = nodeIdCounter++;
#| domOps.push({ op: 'createElement', id, tagName });
#| const el = createMockElement(tagName, id);
#| el._localName = localName;
#| el._namespaceURI = normalizedNs;
#| el._prefix = prefix;
#| el._tagName = tagName;
#| el._ownerDocument = document;
#| if (normalizedNs === 'http://www.w3.org/1999/xhtml') {
#| const lowerName = asciiLowercase(localName);
#| const Ctor = localName === lowerName
#| ? (tagToConstructor[lowerName] || HTMLElement)
#| : HTMLUnknownElement;
#| Object.setPrototypeOf(el, Ctor.prototype);
#| return maybeUpgradeCustomElement(el);
#| } else {
#| Object.setPrototypeOf(el, Element.prototype);
#| }
#| return el;
#| },
#| getElementsByTagNameNS(ns, tag) {
#| const name = String(tag);
#| const namespace = ns;
#| return makeHTMLCollection(() =>
#| collectElements(htmlEl, true, (el) => matchesNamespace(el, namespace) && matchesTagNameNS(el, name))
#| );
#| },
#| importNode(node, deep) {
#| if (!node) return null;
#| if (node._nodeType === 9 || node.nodeType === 9) {
#| throw new DOMException('Cannot import a document node', 'NotSupportedError');
#| }
#| const cloned = node.cloneNode ? node.cloneNode(deep) : node;
#| const updateOwner = (n) => {
#| n._ownerDocument = this;
#| if ('ownerDocument' in n) n.ownerDocument = this;
#| if (n._attrList) {
#| for (const attr of n._attrList) {
#| attr.ownerDocument = this;
#| }
#| }
#| if (n._children) {
#| for (const c of n._children) updateOwner(c);
#| }
#| };
#| updateOwner(cloned);
#| return cloned;
#| },
#| adoptNode(node) {
#| if (!node) return null;
#| if (node._nodeType === 9 || node.nodeType === 9) {
#| throw new DOMException('Cannot adopt a document node', 'NotSupportedError');
#| }
#| const detach = (n) => {
#| if (!n._parent) return;
#| // Special handling for DocumentType nodes
#| if (n._nodeType === 10 || n.nodeType === 10) {
#| // DocumentType is not in _children but has _parent set
#| const parentDoc = n._parent;
#| if (parentDoc.doctype === n) {
#| // Don't clear doctype reference - just detach from tree
#| }
#| n._parent = null;
#| if ('parentNode' in n) n.parentNode = null;
#| return;
#| }
#| if (typeof n._parent.removeChild === 'function') {
#| try {
#| n._parent.removeChild(n);
#| } catch (e) {
#| // Fallback: manually detach from _children
#| if (Array.isArray(n._parent._children)) {
#| const idx = n._parent._children.indexOf(n);
#| if (idx >= 0) n._parent._children.splice(idx, 1);
#| }
#| n._parent = null;
#| if ('parentNode' in n) n.parentNode = null;
#| }
#| } else if (Array.isArray(n._parent._children)) {
#| const idx = n._parent._children.indexOf(n);
#| if (idx >= 0) n._parent._children.splice(idx, 1);
#| n._parent = null;
#| if ('parentNode' in n) n.parentNode = null;
#| }
#| };
#| const updateOwner = (n) => {
#| n.ownerDocument = this;
#| if ('_ownerDocument' in n) n._ownerDocument = this;
#| if (n._attrList) {
#| for (const attr of n._attrList) {
#| attr.ownerDocument = this;
#| }
#| }
#| if (n._children) {
#| for (const c of n._children) updateOwner(c);
#| }
#| };
#| detach(node);
#| updateOwner(node);
#| return node;
#| },
#| createRange() {
#| const getNodeIndex = (node) => {
#| if (!node._parent && !node.parentNode) return 0;
#| const parent = node._parent || node.parentNode;
#| const children = parent._children || parent.childNodes || [];
#| for (let i = 0; i < children.length; i++) {
#| if (children[i] === node) return i;
#| }
#| return 0;
#| };
#| return {
#| startContainer: null, startOffset: 0, endContainer: null, endOffset: 0, collapsed: true,
#| setStart(node, offset) { this.startContainer = node; this.startOffset = offset; this._updateCollapsed(); },
#| setEnd(node, offset) { this.endContainer = node; this.endOffset = offset; this._updateCollapsed(); },
#| setStartBefore(node) {
#| const parent = node._parent || node.parentNode;
#| if (!parent) throw new DOMException('Node has no parent', 'InvalidNodeTypeError');
#| this.startContainer = parent;
#| this.startOffset = getNodeIndex(node);
#| this._updateCollapsed();
#| },
#| setStartAfter(node) {
#| const parent = node._parent || node.parentNode;
#| if (!parent) throw new DOMException('Node has no parent', 'InvalidNodeTypeError');
#| this.startContainer = parent;
#| this.startOffset = getNodeIndex(node) + 1;
#| this._updateCollapsed();
#| },
#| setEndBefore(node) {
#| const parent = node._parent || node.parentNode;
#| if (!parent) throw new DOMException('Node has no parent', 'InvalidNodeTypeError');
#| this.endContainer = parent;
#| this.endOffset = getNodeIndex(node);
#| this._updateCollapsed();
#| },
#| setEndAfter(node) {
#| const parent = node._parent || node.parentNode;
#| if (!parent) throw new DOMException('Node has no parent', 'InvalidNodeTypeError');
#| this.endContainer = parent;
#| this.endOffset = getNodeIndex(node) + 1;
#| this._updateCollapsed();
#| },
#| _updateCollapsed() {
#| this.collapsed = this.startContainer === this.endContainer && this.startOffset === this.endOffset;
#| },
#| selectNode(node) {
#| const parent = node._parent || node.parentNode;
#| if (parent) {
#| const idx = getNodeIndex(node);
#| this.startContainer = parent; this.startOffset = idx;
#| this.endContainer = parent; this.endOffset = idx + 1;
#| } else {
#| this.startContainer = this.endContainer = node;
#| this.startOffset = 0;
#| this.endOffset = (node._children || node.childNodes || []).length;
#| }
#| this._updateCollapsed();
#| },
#| selectNodeContents(node) {
#| this.startContainer = this.endContainer = node;
#| this.startOffset = 0;
#| this.endOffset = (node._children || node.childNodes || []).length;
#| this._updateCollapsed();
#| },
#| collapse(toStart) { if (toStart) { this.endContainer = this.startContainer; this.endOffset = this.startOffset; } else { this.startContainer = this.endContainer; this.startOffset = this.endOffset; } this.collapsed = true; },
#| cloneContents() { return document.createDocumentFragment(); },
#| deleteContents() {},
#| extractContents() { return document.createDocumentFragment(); },
#| insertNode(node) {},
#| surroundContents(node) {},
#| cloneRange() {
#| const newRange = document.createRange();
#| newRange.startContainer = this.startContainer;
#| newRange.startOffset = this.startOffset;
#| newRange.endContainer = this.endContainer;
#| newRange.endOffset = this.endOffset;
#| newRange.collapsed = this.collapsed;
#| return newRange;
#| },
#| detach() {},
#| toString() { return ''; },
#| compareBoundaryPoints(how, sourceRange) { return 0; },
#| comparePoint(node, offset) { return 0; },
#| isPointInRange(node, offset) { return false; },
#| intersectsNode(node) { return false; },
#| getClientRects() { return []; },
#| getBoundingClientRect() { return { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }; }
#| };
#| },
#| createNodeIterator(root, whatToShow, filter) {
#| if (root === undefined) {
#| throw new TypeError("Failed to execute 'createNodeIterator': 1 argument required, but only 0 present.");
#| }
#| const show = whatToShow === undefined ? 0xFFFFFFFF : (whatToShow >>> 0);
#| const f = filter === undefined ? null : filter;
#| return { root, whatToShow: show, filter: f, nextNode() { return null; }, previousNode() { return null; } };
#| },
#| createTreeWalker(root, whatToShow, filter) {
#| if (root === undefined) {
#| throw new TypeError("Failed to execute 'createTreeWalker': 1 argument required, but only 0 present.");
#| }
#| const show = whatToShow === undefined ? 0xFFFFFFFF : (whatToShow >>> 0);
#| const f = filter === undefined ? null : filter;
#| return {
#| root,
#| currentNode: root,
#| whatToShow: show,
#| filter: f,
#| firstChild() {
#| const child = this.currentNode.firstChild || (this.currentNode._children && this.currentNode._children[0]) || null;
#| if (child) this.currentNode = child;
#| return child;
#| },
#| lastChild() {
#| const children = this.currentNode._children || this.currentNode.childNodes || [];
#| const child = children.length > 0 ? children[children.length - 1] : null;
#| if (child) this.currentNode = child;
#| return child;
#| },
#| nextSibling() {
#| const sibling = this.currentNode.nextSibling;
#| if (sibling) this.currentNode = sibling;
#| return sibling;
#| },
#| previousSibling() {
#| const sibling = this.currentNode.previousSibling;
#| if (sibling) this.currentNode = sibling;
#| return sibling;
#| },
#| parentNode() {
#| const parent = this.currentNode._parent || this.currentNode.parentNode;
#| if (parent && parent !== this.root) {
#| this.currentNode = parent;
#| return parent;
#| }
#| return null;
#| },
#| nextNode() { return null; },
#| previousNode() { return null; }
#| };
#| },
#| createCDATASection(data) {
#| throw new DOMException('CDATASection not supported in HTML documents', 'NotSupportedError');
#| },
#| createProcessingInstruction(target, data) {
#| const t = String(target);
#| const d = String(data);
#| if (d.indexOf('?>') >= 0) {
#| throw new DOMException('Invalid character in data', 'InvalidCharacterError');
#| }
#| if (!t || !/[A-Za-z_]/.test(t[0])) {
#| throw new DOMException('Invalid character in target', 'InvalidCharacterError');
#| }
#| for (let i = 0; i < t.length; i++) {
#| const ch = t[i];
#| if (ch === '\\u00D7' || ch === '\\\\' || ch === '\\f') {
#| throw new DOMException('Invalid character in target', 'InvalidCharacterError');
#| }
#| if (i > 0 && ch === '\\u00B7') continue;
#| if (!/[A-Za-z0-9._:-]/.test(ch)) {
#| throw new DOMException('Invalid character in target', 'InvalidCharacterError');
#| }
#| }
#| const id = nodeIdCounter++;
#| return createMockProcessingInstruction(target, data, id);
#| },
#| get defaultView() { return typeof window !== 'undefined' ? window : null; },
#| getRootNode() { return this; },
#| get readyState() { return 'complete'; },
#| get hidden() { return false; },
#| get visibilityState() { return 'visible'; },
#| ontouchstart: null,
#| get dir() { return ''; },
#| set dir(v) {},
#| get firstElementChild() { return htmlEl; },
#| get lastElementChild() { return htmlEl; },
#| get childElementCount() { return 1; },
#| addEventListener(type, listener, options) { addEventListenerImpl(this, type, listener, options); },
#| removeEventListener(type, listener, options) { removeEventListenerImpl(this, type, listener, options); },
#| dispatchEvent(event) { return dispatchEventImpl(this, event); },
#| prepend(...nodes) {
#| for (const n of nodes.reverse()) {
#| const node = (n && n._mockId !== undefined) ? n : this.createTextNode(String(n));
#| htmlEl.insertBefore(node, htmlEl.firstChild);
#| }
#| },
#| append(...nodes) {
#| for (const n of nodes) {
#| const node = (n && n._mockId !== undefined) ? n : this.createTextNode(String(n));
#| htmlEl.appendChild(node);
#| }
#| },
#| replaceChildren(...nodes) {
#| while (htmlEl._children.length > 0) htmlEl.removeChild(htmlEl._children[0]);
#| this.append(...nodes);
#| }
#| };
#| document.normalize = function() {
#| const nodes = document.childNodes;
#| for (let i = 0; i < nodes.length; i++) {
#| const child = nodes[i];
#| if (child && typeof child.normalize === 'function') child.normalize();
#| }
#| };
#| htmlEl._parent = document;
#| htmlEl.parentNode = document;
#| ensureDocumentIndexes(document);
#| indexSubtree(htmlEl, document);
#| if (typeof globalThis !== 'undefined') {
#| globalThis.document = document;
#| }
#|
#| const console = {
#| log(...args) { logs.push(args.map(String).join(' ')); },
#| warn(...args) { logs.push('[WARN] ' + args.map(String).join(' ')); },
#| error(...args) { logs.push('[ERROR] ' + args.map(String).join(' ')); },
#| info(...args) { logs.push('[INFO] ' + args.map(String).join(' ')); }
#| };
#|
#| // Event class
#| class Event {
#| constructor(type, options) {
#| options = options || {};
#| this._type = type === undefined ? '' : String(type);
#| this._bubbles = !!options.bubbles;
#| this._cancelable = !!options.cancelable;
#| this._composed = !!options.composed;
#| this._defaultPrevented = false;
#| this._propagationStopped = false;
#| this._immediatePropagationStopped = false;
#| this._target = null;
#| this._currentTarget = null;
#| this._eventPhase = 0;
#| this._timeStamp = Date.now();
#| this._isTrusted = false;
#| }
#| get type() { return this._type; }
#| get target() { return this._target; }
#| get srcElement() { return this._target; }
#| get currentTarget() { return this._currentTarget; }
#| get bubbles() { return this._bubbles; }
#| get cancelable() { return this._cancelable; }
#| get defaultPrevented() { return this._defaultPrevented; }
#| get composed() { return this._composed; }
#| get isTrusted() { return this._isTrusted; }
#| get timeStamp() { return this._timeStamp; }
#| get eventPhase() { return this._eventPhase; }
#| composedPath() { return this._path ? this._path.slice() : []; }
#| stopPropagation() { this._propagationStopped = true; }
#| stopImmediatePropagation() { this._immediatePropagationStopped = true; this._propagationStopped = true; }
#| preventDefault() { if (this._cancelable) this._defaultPrevented = true; }
#| initEvent(type, bubbles, cancelable) {
#| this._type = type;
#| this._bubbles = !!bubbles;
#| this._cancelable = !!cancelable;
#| }
#| }
#| Event.NONE = 0;
#| Event.CAPTURING_PHASE = 1;
#| Event.AT_TARGET = 2;
#| Event.BUBBLING_PHASE = 3;
#|
#| class SubmitEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this._submitter = Object.prototype.hasOwnProperty.call(options, 'submitter')
#| ? options.submitter
#| : null;
#| }
#| get submitter() { return this._submitter; }
#| }
#|
#| class UIEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this._view = options.view || null;
#| this._detail = options.detail || 0;
#| }
#| get view() { return this._view; }
#| get detail() { return this._detail; }
#| initUIEvent(type, bubbles, cancelable, view, detail) {
#| this.initEvent(type, bubbles, cancelable);
#| this._view = view || null;
#| this._detail = detail || 0;
#| }
#| }
#| class MouseEvent extends UIEvent {
#| constructor(type, options) {
#| super(type, options);
#| options = options || {};
#| this._screenX = options.screenX || 0;
#| this._screenY = options.screenY || 0;
#| this._clientX = options.clientX || 0;
#| this._clientY = options.clientY || 0;
#| this._relatedTarget = options.relatedTarget || null;
#| }
#| get screenX() { return this._screenX; }
#| get screenY() { return this._screenY; }
#| get clientX() { return this._clientX; }
#| get clientY() { return this._clientY; }
#| get relatedTarget() { return this._relatedTarget; }
#| }
#| class FocusEvent extends UIEvent {
#| constructor(type, options) {
#| super(type, options);
#| options = options || {};
#| this._relatedTarget = options.relatedTarget || null;
#| }
#| get relatedTarget() { return this._relatedTarget; }
#| }
#| class KeyboardEvent extends UIEvent {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.key = options.key || '';
#| this.code = options.code || '';
#| this.shiftKey = !!options.shiftKey;
#| this.ctrlKey = !!options.ctrlKey;
#| this.altKey = !!options.altKey;
#| this.metaKey = !!options.metaKey;
#| }
#| }
#| class PointerEvent extends MouseEvent {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.pointerId = options.pointerId || 0;
#| this.width = options.width || 1;
#| this.height = options.height || 1;
#| this.pressure = options.pressure || 0;
#| this.tiltX = options.tiltX || 0;
#| this.tiltY = options.tiltY || 0;
#| this.pointerType = options.pointerType || '';
#| this.isPrimary = options.isPrimary !== undefined ? !!options.isPrimary : true;
#| }
#| }
#| class InputEvent extends UIEvent {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.data = options.data !== undefined ? options.data : null;
#| this.inputType = options.inputType || '';
#| this.isComposing = !!options.isComposing;
#| }
#| }
#| class CompositionEvent extends UIEvent {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.data = options.data || '';
#| }
#| }
#| class DataTransfer {
#| constructor() {
#| this._items = {};
#| this.dropEffect = 'none';
#| this.effectAllowed = 'all';
#| this.files = [];
#| }
#| setData(type, data) {
#| this._items[String(type)] = String(data);
#| }
#| getData(type) {
#| const key = String(type);
#| return Object.prototype.hasOwnProperty.call(this._items, key) ? this._items[key] : '';
#| }
#| clearData(type) {
#| if (type === undefined) {
#| this._items = {};
#| return;
#| }
#| delete this._items[String(type)];
#| }
#| get types() { return Object.keys(this._items); }
#| setDragImage() {}
#| }
#| class CustomEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this._detail = options.detail !== undefined ? options.detail : null;
#| }
#| get detail() { return this._detail; }
#| initCustomEvent(type, bubbles, cancelable, detail) {
#| this.initEvent(type, bubbles, cancelable);
#| this._detail = detail;
#| }
#| }
#| class HashChangeEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this._oldURL = options.oldURL || '';
#| this._newURL = options.newURL || '';
#| }
#| get oldURL() { return this._oldURL; }
#| get newURL() { return this._newURL; }
#| }
#| class MessageEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.data = options.data;
#| this.origin = options.origin || '';
#| this.lastEventId = options.lastEventId || '';
#| this.source = options.source || null;
#| this.ports = options.ports || [];
#| }
#| }
#| class StorageEvent extends Event {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.key = options.key || null;
#| this.oldValue = options.oldValue || null;
#| this.newValue = options.newValue || null;
#| this.url = options.url || '';
#| this.storageArea = options.storageArea || null;
#| }
#| }
#| class DragEvent extends MouseEvent {
#| constructor(type, options = {}) {
#| super(type, options);
#| this._dataTransfer = options.dataTransfer || null;
#| }
#| get dataTransfer() { return this._dataTransfer; }
#| }
#| class ClipboardEvent extends Event {
#| constructor(type, options = {}) {
#| super(type, options);
#| this._clipboardData = options.clipboardData || null;
#| }
#| get clipboardData() { return this._clipboardData; }
#| }
#| class DeviceMotionEvent extends Event {}
#| class DeviceOrientationEvent extends Event {}
#| class TextEvent extends UIEvent {
#| constructor(type, options) {
#| options = options || {};
#| super(type, options);
#| this.data = options.data || '';
#| }
#| }
#| class BeforeUnloadEvent extends Event {}
#| class TouchEvent extends UIEvent {}
#|
#| // Window object
#| const _timers = { nextId: 1, timeouts: {}, intervals: {} };
#| const _animationFrames = { nextId: 1, callbacks: {} };
#|
#| const windowTarget = {
#| get window() { return this; },
#| get self() { return this; },
#| get document() { return document; },
#| Event: Event,
#| SubmitEvent: SubmitEvent,
#| UIEvent: UIEvent,
#| MouseEvent: MouseEvent,
#| PointerEvent: PointerEvent,
#| FocusEvent: FocusEvent,
#| KeyboardEvent: KeyboardEvent,
#| InputEvent: InputEvent,
#| CompositionEvent: CompositionEvent,
#| CustomEvent: CustomEvent,
#| HashChangeEvent: HashChangeEvent,
#| MessageEvent: MessageEvent,
#| StorageEvent: StorageEvent,
#| DragEvent: DragEvent,
#| ClipboardEvent: ClipboardEvent,
#| DataTransfer: DataTransfer,
#| DeviceMotionEvent: DeviceMotionEvent,
#| DeviceOrientationEvent: DeviceOrientationEvent,
#| TextEvent: TextEvent,
#| BeforeUnloadEvent: BeforeUnloadEvent,
#| TouchEvent: TouchEvent,
#| get name() { return ''; },
#| get location() {
#| return {
#| href: 'about:blank',
#| protocol: 'about:',
#| host: '',
#| hostname: '',
#| port: '',
#| pathname: 'blank',
#| search: '',
#| hash: '',
#| origin: 'null',
#| toString() { return this.href; },
#| };
#| },
#| get history() { return { length: 1, state: null, back() {}, forward() {}, go() {}, pushState() {}, replaceState() {} }; },
#| get navigator() { return { userAgent: 'Crater/1.0', language: 'en', languages: ['en'], platform: 'Unknown', cookieEnabled: false, onLine: true }; },
#| devicePixelRatio: 1,
#| innerWidth: 1024,
#| innerHeight: 768,
#| outerWidth: 1024,
#| outerHeight: 768,
#| scrollX: 0,
#| scrollY: 0,
#| get pageXOffset() { return this.scrollX; },
#| get pageYOffset() { return this.scrollY; },
#| screenX: 0,
#| screenY: 0,
#| scroll(options) { if (options) { this.scrollX = options.left || 0; this.scrollY = options.top || 0; } },
#| scrollTo(options) { this.scroll(options); },
#| scrollBy(options) { if (options) { this.scrollX += options.left || 0; this.scrollY += options.top || 0; } },
#| alert(msg) { logs.push('[ALERT] ' + (msg || '')); },
#| close() {},
#| focus() {},
#| blur() {},
#| open(url, target, features) {
#| const popupDocument = document.implementation.createHTMLDocument('');
#| const popupWindow = {
#| document: popupDocument,
#| opener: this,
#| parent: null,
#| top: null,
#| window: null,
#| self: null,
#| close() {},
#| postMessage(message, origin) {},
#| };
#| popupWindow.parent = popupWindow;
#| popupWindow.top = popupWindow;
#| popupWindow.window = popupWindow;
#| popupWindow.self = popupWindow;
#| popupDocument.defaultView = popupWindow;
#| return popupWindow;
#| },
#| print() {},
#| stop() {},
#| setTimeout(handler, timeout) {
#| const id = _timers.nextId++;
#| _timers.timeouts[id] = { handler, timeout: timeout || 0 };
#| return id;
#| },
#| clearTimeout(id) { delete _timers.timeouts[id]; },
#| setInterval(handler, timeout) {
#| const id = _timers.nextId++;
#| _timers.intervals[id] = { handler, timeout: timeout || 0 };
#| return id;
#| },
#| clearInterval(id) { delete _timers.intervals[id]; },
#| requestAnimationFrame(callback) {
#| const id = _animationFrames.nextId++;
#| _animationFrames.callbacks[id] = callback;
#| return id;
#| },
#| cancelAnimationFrame(id) { delete _animationFrames.callbacks[id]; },
#| getComputedStyle(elt, pseudoElt) {
#| return new Proxy({}, {
#| get(_, prop) { return ''; },
#| getPropertyValue(prop) { return ''; }
#| });
#| },
#| matchMedia(query) {
#| return {
#| matches: false,
#| media: query,
#| onchange: null,
#| addListener(cb) {},
#| removeListener(cb) {},
#| addEventListener(type, cb) {},
#| removeEventListener(type, cb) {},
#| dispatchEvent(ev) { return true; }
#| };
#| },
#| addEventListener(type, listener, options) { addEventListenerImpl(this, type, listener, options); },
#| removeEventListener(type, listener, options) { removeEventListenerImpl(this, type, listener, options); },
#| dispatchEvent(event) { return dispatchEventImpl(this, event); },
#| Event: Event,
#| SubmitEvent: SubmitEvent,
#| Node: Node,
#| Attr: Attr,
#| CharacterData: CharacterData,
#| Element: Element,
#| Document: Document,
#| XMLDocument: XMLDocument,
#| HTMLDocument: HTMLDocument,
#| DocumentType: DocumentType,
#| DocumentFragment: DocumentFragment,
#| Text: Text,
#| Comment: Comment,
#| DOMParser: DOMParser,
#| DOMException: DOMException,
#| DOMImplementation: DOMImplementation,
#| ElementInternals: ElementInternals,
#| CustomStateSet: CustomStateSet,
#| CustomElementRegistry: CustomElementRegistry,
#| customElements: customElements,
#| HTMLElement: HTMLElement,
#| HTMLHtmlElement: HTMLHtmlElement,
#| HTMLHeadElement: HTMLHeadElement,
#| HTMLBodyElement: HTMLBodyElement,
#| HTMLDivElement: HTMLDivElement,
#| HTMLSpanElement: HTMLSpanElement,
#| HTMLTitleElement: HTMLTitleElement,
#| HTMLAnchorElement: HTMLAnchorElement,
#| HTMLAreaElement: HTMLAreaElement,
#| HTMLAudioElement: HTMLAudioElement,
#| HTMLBaseElement: HTMLBaseElement,
#| HTMLBRElement: HTMLBRElement,
#| HTMLButtonElement: HTMLButtonElement,
#| HTMLCanvasElement: HTMLCanvasElement,
#| HTMLDataElement: HTMLDataElement,
#| HTMLDataListElement: HTMLDataListElement,
#| HTMLDetailsElement: HTMLDetailsElement,
#| HTMLDialogElement: HTMLDialogElement,
#| HTMLDListElement: HTMLDListElement,
#| HTMLEmbedElement: HTMLEmbedElement,
#| HTMLFieldSetElement: HTMLFieldSetElement,
#| HTMLFormElement: HTMLFormElement,
#| HTMLHeadingElement: HTMLHeadingElement,
#| HTMLHRElement: HTMLHRElement,
#| HTMLIFrameElement: HTMLIFrameElement,
#| HTMLImageElement: HTMLImageElement,
#| HTMLInputElement: HTMLInputElement,
#| HTMLLabelElement: HTMLLabelElement,
#| HTMLLegendElement: HTMLLegendElement,
#| HTMLLIElement: HTMLLIElement,
#| HTMLLinkElement: HTMLLinkElement,
#| HTMLMapElement: HTMLMapElement,
#| HTMLMenuElement: HTMLMenuElement,
#| HTMLMetaElement: HTMLMetaElement,
#| HTMLMeterElement: HTMLMeterElement,
#| HTMLModElement: HTMLModElement,
#| HTMLObjectElement: HTMLObjectElement,
#| HTMLOListElement: HTMLOListElement,
#| HTMLOptGroupElement: HTMLOptGroupElement,
#| HTMLOptionElement: HTMLOptionElement,
#| HTMLOutputElement: HTMLOutputElement,
#| HTMLParagraphElement: HTMLParagraphElement,
#| HTMLPictureElement: HTMLPictureElement,
#| HTMLPreElement: HTMLPreElement,
#| HTMLProgressElement: HTMLProgressElement,
#| HTMLQuoteElement: HTMLQuoteElement,
#| HTMLScriptElement: HTMLScriptElement,
#| HTMLSelectElement: HTMLSelectElement,
#| HTMLSlotElement: HTMLSlotElement,
#| HTMLSourceElement: HTMLSourceElement,
#| HTMLStyleElement: HTMLStyleElement,
#| HTMLTableElement: HTMLTableElement,
#| HTMLTableCellElement: HTMLTableCellElement,
#| HTMLTableColElement: HTMLTableColElement,
#| HTMLTableRowElement: HTMLTableRowElement,
#| HTMLTableSectionElement: HTMLTableSectionElement,
#| HTMLTemplateElement: HTMLTemplateElement,
#| HTMLTextAreaElement: HTMLTextAreaElement,
#| HTMLTimeElement: HTMLTimeElement,
#| HTMLTrackElement: HTMLTrackElement,
#| HTMLUListElement: HTMLUListElement,
#| HTMLVideoElement: HTMLVideoElement,
#| HTMLUnknownElement: HTMLUnknownElement,
#| HTMLTableCaptionElement: HTMLTableCaptionElement,
#| HTMLDirectoryElement: HTMLDirectoryElement,
#| HTMLFontElement: HTMLFontElement,
#| HTMLMarqueeElement: HTMLMarqueeElement,
#| HTMLFrameElement: HTMLFrameElement,
#| HTMLFrameSetElement: HTMLFrameSetElement,
#| HTMLParamElement: HTMLParamElement
#| };
#| const window = new Proxy(windowTarget, {
#| get(target, prop, receiver) {
#| if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
#| if (typeof globalThis !== 'undefined') return globalThis[prop];
#| return undefined;
#| },
#| set(target, prop, value, receiver) {
#| const ok = Reflect.set(target, prop, value, receiver);
#| if (typeof globalThis !== 'undefined' && prop !== 'window' && prop !== 'self') {
#| globalThis[prop] = value;
#| }
#| return ok;
#| },
#| has(target, prop) {
#| return Reflect.has(target, prop) || (typeof globalThis !== 'undefined' && prop in globalThis);
#| }
#| });
#| if (typeof globalThis !== 'undefined') {
#| globalThis.window = window;
#| globalThis.self = window;
#| globalThis.parent = window;
#| globalThis.top = window;
#| globalThis.location = window.location;
#| globalThis.navigator = window.navigator;
#| globalThis.addEventListener = window.addEventListener.bind(window);
#| globalThis.removeEventListener = window.removeEventListener.bind(window);
#| globalThis.dispatchEvent = window.dispatchEvent.bind(window);
#| globalThis.customElements = customElements;
#| globalThis.CustomElementRegistry = CustomElementRegistry;
#| globalThis.ElementInternals = ElementInternals;
#| globalThis.CustomStateSet = CustomStateSet;
#| globalThis.queueMicrotask = queueMicrotask;
#| globalThis.fetch = fetch;
#| globalThis.Response = Response;
#| globalThis.Request = Request;
#| globalThis.Headers = Headers;
#| globalThis.Blob = Blob;
#| }
#| window.queueMicrotask = queueMicrotask;
#| window.fetch = fetch;
#| window.Response = Response;
#| window.Request = Request;
#| window.Headers = Headers;
#| window.Blob = Blob;
#| window.ElementInternals = ElementInternals;
#| window.CustomStateSet = CustomStateSet;
#| window.customElements = customElements;
#| window.CustomElementRegistry = CustomElementRegistry;
#| window.parent = window;
#| window.top = window;
#| const NativeFunction = Function;
#| function createFrameRealm() {
#| const realmDocument = document.implementation.createHTMLDocument('');
#| const realm = {
#| document: realmDocument,
#| onerror: null,
#| parent: window,
#| top: window,
#| frames: null,
#| MutationObserver: null,
#| Error: Error,
#| window: null,
#| self: null,
#| };
#| realm.Function = function() {
#| const fn = NativeFunction.apply(null, arguments);
#| fn.__craterRealm = realm;
#| return fn;
#| };
#| realm.window = realm;
#| realm.self = realm;
#| if (realmDocument) {
#| realmDocument.defaultView = realm;
#| realmDocument.parentWindow = realm;
#| }
#| return realm;
#| }
#| const frames = [createFrameRealm(), createFrameRealm(), createFrameRealm()];
#| for (const frame of frames) {
#| frame.frames = frames;
#| frame.parent = window;
#| frame.top = window;
#| }
#| window.frames = frames;
#| if (typeof globalThis !== 'undefined') {
#| globalThis.frames = frames;
#| }
#|
#| // Make window globals accessible
#| const setTimeout = window.setTimeout.bind(window);
#| const clearTimeout = window.clearTimeout.bind(window);
#| const setInterval = window.setInterval.bind(window);
#| const clearInterval = window.clearInterval.bind(window);
#| const requestAnimationFrame = window.requestAnimationFrame.bind(window);
#| const cancelAnimationFrame = window.cancelAnimationFrame.bind(window);
#| const addEventListener = window.addEventListener.bind(window);
#| const removeEventListener = window.removeEventListener.bind(window);
#| const dispatchEvent = window.dispatchEvent.bind(window);
#| const alert = window.alert.bind(window);
#| const navigator = window.navigator;
#|
#| // DOMTokenList class
#| function DOMTokenList(getter, setter) { this._getter = getter; this._setter = setter; }
#| DOMTokenList.prototype._getAttr = function() { return this._getter(); };
#| DOMTokenList.prototype._tokenize = function() {
#| var value = this._getter();
#| var str = value === null || value === undefined ? '' : String(value);
#| var parts = splitAsciiWhitespace(str);
#| var seen = new Set();
#| var tokens = [];
#| for (var i = 0; i < parts.length; i++) {
#| var part = parts[i];
#| if (!seen.has(part)) { seen.add(part); tokens.push(part); }
#| }
#| return tokens;
#| };
#| DOMTokenList.prototype._setTokens = function(tokens, hadAttr) {
#| if (!tokens || tokens.length === 0) {
#| if (hadAttr) this._setter('');
#| else this._setter(null);
#| return;
#| }
#| this._setter(tokens.join(' '));
#| };
#| DOMTokenList.prototype._validateToken = function(token) {
#| var str = String(token);
#| if (str.length === 0) throw new DOMException('The token provided must not be empty.', 'SyntaxError');
#| if (containsAsciiWhitespace(str)) {
#| throw new DOMException('The token provided contains HTML space characters, which are not valid in tokens.', 'InvalidCharacterError');
#| }
#| return str;
#| };
#| Object.defineProperties(DOMTokenList.prototype, {
#| length: { get: function() { return this._tokenize().length; } },
#| value: { get: function() { var v = this._getter(); return v === null || v === undefined ? '' : String(v); }, set: function(v) { this._setter(String(v)); } }
#| });
#| DOMTokenList.prototype.item = function(index) {
#| var n = Number(index);
#| if (!Number.isFinite(n) || n < 0) return null;
#| var tokens = this._tokenize();
#| return tokens[n] || null;
#| };
#| DOMTokenList.prototype.contains = function(token) {
#| var str = String(token);
#| if (str.length === 0 || containsAsciiWhitespace(str)) return false;
#| return this._tokenize().indexOf(str) >= 0;
#| };
#| DOMTokenList.prototype.add = function() {
#| var hadAttr = this._getter() !== null && this._getter() !== undefined;
#| var list = this._tokenize();
#| var set = new Set(list);
#| var args = Array.prototype.slice.call(arguments);
#| for (var i = 0; i < args.length; i++) {
#| var tok = this._validateToken(args[i]);
#| if (!set.has(tok)) { set.add(tok); list.push(tok); }
#| }
#| this._setTokens(list, hadAttr);
#| };
#| DOMTokenList.prototype.remove = function() {
#| var hadAttr = this._getter() !== null && this._getter() !== undefined;
#| var list = this._tokenize();
#| var removeSet = new Set();
#| var args = Array.prototype.slice.call(arguments);
#| for (var i = 0; i < args.length; i++) {
#| var tok = this._validateToken(args[i]);
#| removeSet.add(tok);
#| }
#| var filtered = list.filter(function(t) { return !removeSet.has(t); });
#| this._setTokens(filtered, hadAttr);
#| };
#| DOMTokenList.prototype.toggle = function(token, force) {
#| var tok = this._validateToken(token);
#| var hadAttr = this._getter() !== null && this._getter() !== undefined;
#| var list = this._tokenize();
#| var idx = list.indexOf(tok);
#| var has = idx >= 0;
#| if (force === undefined) {
#| if (has) {
#| list.splice(idx, 1);
#| this._setTokens(list, hadAttr);
#| return false;
#| } else {
#| list.push(tok);
#| this._setTokens(list, hadAttr);
#| return true;
#| }
#| }
#| if (force) {
#| if (!has) {
#| list.push(tok);
#| this._setTokens(list, hadAttr);
#| }
#| return true;
#| } else {
#| if (has) {
#| list.splice(idx, 1);
#| this._setTokens(list, hadAttr);
#| }
#| return false;
#| }
#| };
#| DOMTokenList.prototype.replace = function(token, newToken) {
#| var tokStr = String(token);
#| var newStr = String(newToken);
#| if (tokStr.length === 0 || newStr.length === 0) {
#| throw new DOMException('The token provided must not be empty.', 'SyntaxError');
#| }
#| if (containsAsciiWhitespace(tokStr) || containsAsciiWhitespace(newStr)) {
#| throw new DOMException('The token provided contains HTML space characters, which are not valid in tokens.', 'InvalidCharacterError');
#| }
#| var hadAttr = this._getter() !== null && this._getter() !== undefined;
#| var list = this._tokenize();
#| var idx = list.indexOf(tokStr);
#| if (idx < 0) return false;
#| list[idx] = newStr;
#| var seen = new Set();
#| var deduped = [];
#| for (var i = 0; i < list.length; i++) {
#| var t = list[i];
#| if (!seen.has(t)) { seen.add(t); deduped.push(t); }
#| }
#| this._setTokens(deduped, hadAttr);
#| return true;
#| };
#| DOMTokenList.prototype.supports = function() { throw new TypeError('Not supported'); };
#| DOMTokenList.prototype.toString = function() {
#| var v = this._getter();
#| return v === null || v === undefined ? '' : String(v);
#| };
#| DOMTokenList.prototype.forEach = function(cb, thisArg) {
#| var tokens = this._tokenize();
#| for (var i = 0; i < tokens.length; i++) cb.call(thisArg, tokens[i], i, this);
#| };
#| DOMTokenList.prototype.keys = function() {
#| var tokens = this._tokenize();
#| return tokens.map(function(_, i) { return i; })[Symbol.iterator]();
#| };
#| DOMTokenList.prototype.values = function() {
#| return this._tokenize()[Symbol.iterator]();
#| };
#| DOMTokenList.prototype.entries = function() {
#| var tokens = this._tokenize();
#| return tokens.map(function(v, i) { return [i, v]; })[Symbol.iterator]();
#| };
#| DOMTokenList.prototype[Symbol.iterator] = function() { return this.values(); };
#|
#| // DOMRect class
#| class DOMRect {
#| constructor(x, y, width, height) {
#| this.x = x || 0;
#| this.y = y || 0;
#| this.width = width || 0;
#| this.height = height || 0;
#| }
#| get top() { return this.y; }
#| get right() { return this.x + this.width; }
#| get bottom() { return this.y + this.height; }
#| get left() { return this.x; }
#| static fromRect(rect) { return new DOMRect(rect.x, rect.y, rect.width, rect.height); }
#| toJSON() { return { x: this.x, y: this.y, width: this.width, height: this.height, top: this.top, right: this.right, bottom: this.bottom, left: this.left }; }
#| }
#|
#| // Storage class
#| class Storage {
#| constructor() { this._data = {}; }
#| get length() { return Object.keys(this._data).length; }
#| key(index) { return Object.keys(this._data)[index] || null; }
#| getItem(key) { return this._data.hasOwnProperty(key) ? this._data[key] : null; }
#| setItem(key, value) { this._data[key] = String(value); }
#| removeItem(key) { delete this._data[key]; }
#| clear() { this._data = {}; }
#| }
#| const localStorage = new Storage();
#| const sessionStorage = new Storage();
#|
#| // MutationObserver class
#| class MutationObserver {
#| constructor(callback) { this._callback = callback; this._records = []; this._targets = []; this._scheduled = false; }
#| observe(target, options) {
#| const normalized = options ? Object.assign({}, options) : {};
#| if (normalized.attributeOldValue || normalized.attributeFilter !== undefined) {
#| if (normalized.attributes === false) throw new TypeError('attributes must be true when attributeOldValue or attributeFilter is set');
#| if (normalized.attributes === undefined) normalized.attributes = true;
#| }
#| if (normalized.characterDataOldValue) {
#| if (normalized.characterData === false) throw new TypeError('characterData must be true when characterDataOldValue is set');
#| if (normalized.characterData === undefined) normalized.characterData = true;
#| }
#| if (!normalized.childList && !normalized.attributes && !normalized.characterData) {
#| throw new TypeError('At least one of childList, attributes, or characterData must be true');
#| }
#| const idx = this._targets.findIndex(function(entry) { return entry.target === target; });
#| if (idx >= 0) this._targets[idx] = { target, options: normalized };
#| else this._targets.push({ target, options: normalized });
#| if (!__craterMutationObservers.includes(this)) {
#| __craterMutationObservers.push(this);
#| }
#| }
#| disconnect() { this._targets = []; this._records = []; this._scheduled = false; }
#| takeRecords() { const records = this._records; this._records = []; return records; }
#| }
#| window.MutationObserver = MutationObserver;
#| for (const frame of frames) {
#| frame.MutationObserver = MutationObserver;
#| }
#|
#| // IntersectionObserver class
#| class IntersectionObserver {
#| constructor(callback, options) {
#| this._callback = callback;
#| this._options = options || {};
#| this._targets = [];
#| }
#| get root() { return this._options.root || null; }
#| get rootMargin() { return this._options.rootMargin || '0px'; }
#| get thresholds() { return this._options.threshold ? [].concat(this._options.threshold) : [0]; }
#| observe(target) { this._targets.push(target); }
#| unobserve(target) { this._targets = this._targets.filter(function(t) { return t !== target; }); }
#| disconnect() { this._targets = []; }
#| takeRecords() { return []; }
#| }
#|
#| // ResizeObserver class
#| class ResizeObserver {
#| constructor(callback) { this._callback = callback; this._targets = []; }
#| observe(target, options) { this._targets.push({ target: target, options: options }); }
#| unobserve(target) { this._targets = this._targets.filter(function(t) { return t.target !== target; }); }
#| disconnect() { this._targets = []; }
#| }
#|
#| // Automation helpers for CDP/BiDi compatibility
#| // waitForSelector - polls until an element matching selector appears
#| window.__waitForSelector = function(selector, options) {
#| options = options || {};
#| var timeout = options.timeout || 30000;
#| var interval = options.interval || 100;
#| var visible = options.visible || false;
#| var hidden = options.hidden || false;
#| var startTime = Date.now();
#| return new Promise(function(resolve, reject) {
#| function check() {
#| var element = document.querySelector(selector);
#| if (element) {
#| if (visible) {
#| // Check if element is visible (has size and not hidden)
#| var rect = element.getBoundingClientRect ? element.getBoundingClientRect() : { width: 1, height: 1 };
#| var isVisible = rect.width > 0 && rect.height > 0 && !element.hidden;
#| if (isVisible) { resolve(element); return; }
#| } else if (hidden) {
#| // Wait for element to be hidden (not found or hidden)
#| } else {
#| resolve(element);
#| return;
#| }
#| } else if (hidden) {
#| resolve(null);
#| return;
#| }
#| if (Date.now() - startTime >= timeout) {
#| reject(new Error('Timeout waiting for selector: ' + selector));
#| return;
#| }
#| setTimeout(check, interval);
#| }
#| check();
#| });
#| };
#|
#| // waitForFunction - polls until a function returns truthy value
#| window.__waitForFunction = function(fn, options) {
#| options = options || {};
#| var timeout = options.timeout || 30000;
#| var interval = options.interval || 100;
#| var args = options.args || [];
#| var startTime = Date.now();
#| return new Promise(function(resolve, reject) {
#| function check() {
#| try {
#| var result = typeof fn === 'function' ? fn.apply(null, args) : eval('(' + fn + ')').apply(null, args);
#| if (result) { resolve(result); return; }
#| } catch (e) {
#| // Function threw, continue polling
#| }
#| if (Date.now() - startTime >= timeout) {
#| reject(new Error('Timeout waiting for function'));
#| return;
#| }
#| setTimeout(check, interval);
#| }
#| check();
#| });
#| };
#|
#| // waitFor - generic wait with condition
#| window.__waitFor = function(condition, options) {
#| if (typeof condition === 'string') {
#| return window.__waitForSelector(condition, options);
#| }
#| return window.__waitForFunction(condition, options);
#| };
#|
#| function appendFormDataValueEntries(formData, name, value) {
#| if (value === null || value === undefined) return;
#| if (value instanceof FormData) {
#| for (const entry of value._data) {
#| formData.append(entry[0], entry[1]);
#| }
#| return;
#| }
#| formData.append(name, value);
#| }
#| function appendAssociatedCustomElementEntries(formData, form) {
#| const controls = collectAssociatedCustomElementsForForm(form);
#| for (const control of controls) {
#| const name = control.getAttribute && control.getAttribute('name');
#| if (name === null || name === undefined || String(name) === '') continue;
#| const internals = control.__elementInternals || null;
#| if (!internals) continue;
#| appendFormDataValueEntries(formData, String(name), internals._formValue);
#| }
#| }
#|
#| // FormData class (using bracket notation for reserved words)
#| function FormData(form) {
#| this._data = [];
#| if (form !== undefined && form !== null && isFormElementNode(form)) {
#| appendAssociatedCustomElementEntries(this, form);
#| }
#| }
#| FormData.prototype.append = function(name, value) { this._data.push([name, String(value)]); };
#| FormData.prototype['delete'] = function(name) { this._data = this._data.filter(function(e) { return e[0] !== name; }); };
#| FormData.prototype['get'] = function(name) { var entry = this._data.find(function(e) { return e[0] === name; }); return entry ? entry[1] : null; };
#| FormData.prototype.getAll = function(name) { return this._data.filter(function(e) { return e[0] === name; }).map(function(e) { return e[1]; }); };
#| FormData.prototype.has = function(name) { return this._data.some(function(e) { return e[0] === name; }); };
#| FormData.prototype['set'] = function(name, value) { this['delete'](name); this.append(name, value); };
#| FormData.prototype.keys = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++][0], done: false } : { done: true }; } }; };
#| FormData.prototype.values = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++][1], done: false } : { done: true }; } }; };
#| FormData.prototype.entries = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++], done: false } : { done: true }; } }; };
#| FormData.prototype.forEach = function(cb, thisArg) { var self = this; this._data.forEach(function(e) { cb.call(thisArg, e[1], e[0], self); }); };
#|
#| // URLSearchParams class (using bracket notation for reserved words)
#| function URLSearchParams(init) {
#| this._data = [];
#| if (typeof init === 'string') {
#| var str = init.charAt(0) === '?' ? init.slice(1) : init;
#| if (str) {
#| var pairs = str.split('&');
#| for (var i = 0; i < pairs.length; i++) {
#| var parts = pairs[i].split('=');
#| this._data.push([decodeURIComponent(parts[0]), decodeURIComponent(parts[1] || '')]);
#| }
#| }
#| } else if (Array.isArray(init)) {
#| for (var j = 0; j < init.length; j++) {
#| this._data.push([String(init[j][0]), String(init[j][1])]);
#| }
#| } else if (init && typeof init === 'object') {
#| var keys = Object.keys(init);
#| for (var k = 0; k < keys.length; k++) {
#| this._data.push([keys[k], String(init[keys[k]])]);
#| }
#| }
#| }
#| URLSearchParams.prototype.append = function(name, value) { this._data.push([String(name), String(value)]); };
#| URLSearchParams.prototype['delete'] = function(name) { this._data = this._data.filter(function(e) { return e[0] !== name; }); };
#| URLSearchParams.prototype['get'] = function(name) { var entry = this._data.find(function(e) { return e[0] === name; }); return entry ? entry[1] : null; };
#| URLSearchParams.prototype.getAll = function(name) { return this._data.filter(function(e) { return e[0] === name; }).map(function(e) { return e[1]; }); };
#| URLSearchParams.prototype.has = function(name) { return this._data.some(function(e) { return e[0] === name; }); };
#| URLSearchParams.prototype['set'] = function(name, value) { this['delete'](name); this.append(name, value); };
#| URLSearchParams.prototype.sort = function() { this._data.sort(function(a, b) { return a[0].localeCompare(b[0]); }); };
#| URLSearchParams.prototype.toString = function() { return this._data.map(function(e) { return encodeURIComponent(e[0]) + '=' + encodeURIComponent(e[1]); }).join('&'); };
#| URLSearchParams.prototype.keys = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++][0], done: false } : { done: true }; } }; };
#| URLSearchParams.prototype.values = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++][1], done: false } : { done: true }; } }; };
#| URLSearchParams.prototype.entries = function() { var self = this; var i = 0; return { next: function() { return i < self._data.length ? { value: self._data[i++], done: false } : { done: true }; } }; };
#| URLSearchParams.prototype.forEach = function(cb, thisArg) { var self = this; this._data.forEach(function(e) { cb.call(thisArg, e[1], e[0], self); }); };
#|
#| // URL class (simplified without complex regex)
#| function URL(url, base) {
#| this._protocol = 'https:';
#| this._hostname = '';
#| this._port = '';
#| this._pathname = '/';
#| this._search = '';
#| this._hash = '';
#| this._username = '';
#| this._password = '';
#| var fullUrl = encodeURI(String(url));
#| if (base && url.indexOf('://') === -1) {
#| var baseSlash = base.lastIndexOf('/');
#| if (baseSlash >= 0) fullUrl = base.substring(0, baseSlash + 1) + url;
#| }
#| var protoEnd = fullUrl.indexOf('://');
#| if (protoEnd >= 0) {
#| this._protocol = fullUrl.substring(0, protoEnd) + ':';
#| fullUrl = fullUrl.substring(protoEnd + 3);
#| }
#| var hashIdx = fullUrl.indexOf('#');
#| if (hashIdx >= 0) { this._hash = fullUrl.substring(hashIdx); fullUrl = fullUrl.substring(0, hashIdx); }
#| var searchIdx = fullUrl.indexOf('?');
#| if (searchIdx >= 0) { this._search = fullUrl.substring(searchIdx); fullUrl = fullUrl.substring(0, searchIdx); }
#| var pathIdx = fullUrl.indexOf('/');
#| if (pathIdx >= 0) { this._pathname = fullUrl.substring(pathIdx); fullUrl = fullUrl.substring(0, pathIdx); }
#| var portIdx = fullUrl.indexOf(':');
#| if (portIdx >= 0) { this._port = fullUrl.substring(portIdx + 1); this._hostname = fullUrl.substring(0, portIdx); }
#| else { this._hostname = fullUrl; }
#| this._searchParams = new URLSearchParams(this._search);
#| }
#| URL.prototype = {
#| get href() { return this._protocol + '//' + this.host + this._pathname + this._search + this._hash; },
#| set href(v) { var u = new URL(v); this._protocol = u._protocol; this._hostname = u._hostname; this._port = u._port; this._pathname = u._pathname; this._search = u._search; this._hash = u._hash; },
#| get origin() { return this._protocol + '//' + this.host; },
#| get protocol() { return this._protocol; },
#| set protocol(v) { this._protocol = v.charAt(v.length - 1) === ':' ? v : v + ':'; },
#| get username() { return this._username; },
#| set username(v) { this._username = v; },
#| get password() { return this._password; },
#| set password(v) { this._password = v; },
#| get host() { return this._port ? this._hostname + ':' + this._port : this._hostname; },
#| set host(v) { var parts = v.split(':'); this._hostname = parts[0]; this._port = parts[1] || ''; },
#| get hostname() { return this._hostname; },
#| set hostname(v) { this._hostname = v; },
#| get port() { return this._port; },
#| set port(v) { this._port = v; },
#| get pathname() { return this._pathname; },
#| set pathname(v) { this._pathname = v.charAt(0) === '/' ? v : '/' + v; },
#| get search() { return this._search; },
#| set search(v) { this._search = v.charAt(0) === '?' ? v : (v ? '?' + v : ''); this._searchParams = new URLSearchParams(this._search); },
#| get searchParams() { return this._searchParams; },
#| get hash() { return this._hash; },
#| set hash(v) { this._hash = v.charAt(0) === '#' ? v : (v ? '#' + v : ''); },
#| toString: function() { return this.href; },
#| toJSON: function() { return this.href; }
#| };
#|
#| // DOMParser (minimal implementation for WPT DOM namespace tests)
#| function DOMParser() {}
#| DOMParser.prototype.parseFromString = function(str, mime) {
#| const type = String(mime || 'application/xml');
#| const text = str === undefined || str === null ? '' : String(str);
#| const tagMatch = text.match(/<\\s*([A-Za-z_][A-Za-z0-9:._-]*)/);
#| let doc;
#| if (type === 'text/html') {
#| doc = document.implementation.createHTMLDocument('');
#| doc.contentType = 'text/html';
#| } else {
#| // Try to extract xmlns attribute from the root element
#| let ns = type === 'application/xhtml+xml' ? 'http://www.w3.org/1999/xhtml' : null;
#| const xmlnsMatch = text.match(/xmlns\\s*=\\s*["']([^"']+)["']/);
#| if (xmlnsMatch) {
#| ns = xmlnsMatch[1];
#| }
#| const qname = tagMatch ? tagMatch[1] : null;
#| doc = document.implementation.createDocument(ns, qname, null);
#| doc.contentType = type;
#| // Also set the namespace on the documentElement if created
#| if (doc.documentElement && ns) {
#| doc.documentElement._namespaceURI = ns;
#| }
#| }
#| return doc;
#| };
#|
#| // Initialize document doctype (simulating parser-created doctype)
#| _doctype = document.implementation.createDocumentType('html', '', '');
#| _doctype._parent = document;
#| _doctype.parentNode = document;
#| `;
#|
#| const sanitizeErrorText = (value) => String(value).replace(/"/g, "'");
#| const buildErrorMessage = (err) => {
#| const msg = err && err.message ? err.message : String(err);
#| const stack = err && err.stack ? err.stack : '';
#| const head = String(code).slice(0, 400).replace(/"/g, "'");
#| const tail = String(code).slice(-200).replace(/"/g, "'");
#| return sanitizeErrorText(msg) + (stack ? ("\n" + sanitizeErrorText(stack)) : '') +
#| "\n[code head]\n" + head + "\n[code tail]\n" + tail;
#| };
#|
#| // Use QuickJS if initialized, otherwise use Node.js vm
#| if (globalThis.__quickjs_initialized && globalThis.__quickjs && !globalThis.__use_nodejs_vm) {
#| const QuickJS = globalThis.__quickjs;
#| let entry = persistentContexts.get(contextId);
#| if (!entry || entry.kind !== 'quickjs') {
#| const vm = QuickJS.newContext();
#| try {
#| const initResult = vm.evalCode(setupCode + '\n' + initCode + '\n_restorePersistedListenersTree(document);');
#| if (initResult.error) {
#| const errorStr = vm.dump(initResult.error);
#| initResult.error.dispose();
#| try { vm.dispose(); } catch {}
#| return JSON.stringify({
#| success: false, value: '', logs: [], domOps: [],
#| error: sanitizeErrorText(errorStr)
#| });
#| }
#| if (initResult.value) initResult.value.dispose();
#| entry = { kind: 'quickjs', vm };
#| persistentContexts.set(contextId, entry);
#| } catch (e) {
#| try { vm.dispose(); } catch {}
#| return JSON.stringify({
#| success: false, value: '', logs: [], domOps: [],
#| error: buildErrorMessage(e)
#| });
#| }
#| } else {
#| try {
#| const resetResult = entry.vm.evalCode('logs.length = 0; domOps.length = 0; "ok"');
#| if (resetResult.error) {
#| resetResult.error.dispose();
#| } else if (resetResult.value) {
#| resetResult.value.dispose();
#| }
#| } catch {}
#| }
#| const vm = entry.vm;
#| try {
#| const userCodeResult = vm.evalCode(code);
#| if (userCodeResult.error) {
#| const errorStr = vm.dump(userCodeResult.error);
#| userCodeResult.error.dispose();
#| return JSON.stringify({
#| success: false, value: '', logs: [], domOps: [],
#| error: sanitizeErrorText(errorStr)
#| });
#| }
#| let userValue = 'undefined';
#| if (userCodeResult.value) {
#| userValue = vm.dump(userCodeResult.value);
#| userCodeResult.value.dispose();
#| }
#|
#| let maxIterations = 1000;
#| const flushAllMicrotasks = () => {
#| let totalWork = 0;
#| for (let i = 0; i < 100; i++) {
#| let jobsExecuted = 0;
#| try {
#| const pendingResult = vm.runtime.executePendingJobs();
#| if (pendingResult.error) {
#| const errHandle = pendingResult.error;
#| const errorStr = vm.dump(errHandle);
#| errHandle.dispose();
#| vm.evalCode('logs.push("[ERROR] Promise: " + ' + JSON.stringify(errorStr) + ')');
#| } else {
#| jobsExecuted = pendingResult.value || 0;
#| }
#| } catch (e) {}
#|
#| const flushResult = vm.evalCode('_flushMicrotasks(); _microtaskQueue.length');
#| let queueLength = 0;
#| if (!flushResult.error && flushResult.value) {
#| queueLength = vm.getNumber(flushResult.value);
#| flushResult.value.dispose();
#| } else if (flushResult.error) {
#| flushResult.error.dispose();
#| }
#|
#| totalWork += jobsExecuted + (queueLength > 0 ? 1 : 0);
#| if (jobsExecuted === 0 && queueLength === 0) break;
#| }
#| return totalWork;
#| };
#|
#| flushAllMicrotasks();
#| if (flushAsync) {
#| while (maxIterations-- > 0) {
#| const timerResult = vm.evalCode('_runOneTimeout()');
#| let ranTimer = false;
#| if (!timerResult.error && timerResult.value) {
#| ranTimer = vm.dump(timerResult.value) === true;
#| timerResult.value.dispose();
#| } else if (timerResult.error) {
#| timerResult.error.dispose();
#| }
#| if (ranTimer) {
#| flushAllMicrotasks();
#| continue;
#| }
#|
#| const rafResult = vm.evalCode('_runOneAnimationFrame()');
#| let ranAnimationFrame = false;
#| if (!rafResult.error && rafResult.value) {
#| ranAnimationFrame = vm.dump(rafResult.value) === true;
#| rafResult.value.dispose();
#| } else if (rafResult.error) {
#| rafResult.error.dispose();
#| }
#| if (!ranAnimationFrame) break;
#| flushAllMicrotasks();
#| }
#| }
#|
#| const collectResult = vm.evalCode('JSON.stringify({ logs, domOps })');
#| if (collectResult.error) {
#| const errorStr = vm.dump(collectResult.error);
#| collectResult.error.dispose();
#| return JSON.stringify({
#| success: false, value: '', logs: [], domOps: [],
#| error: sanitizeErrorText(errorStr)
#| });
#| }
#| const resultStr = vm.dump(collectResult.value);
#| collectResult.value.dispose();
#| const parsed = JSON.parse(resultStr);
#| return JSON.stringify({
#| success: true, value: userValue,
#| logs: parsed.logs || [], domOps: parsed.domOps || []
#| });
#| } catch (e) {
#| let logs = [], domOps = [];
#| try {
#| const collectResult = vm.evalCode('JSON.stringify({ logs, domOps })');
#| if (!collectResult.error && collectResult.value) {
#| const resultStr = vm.dump(collectResult.value);
#| collectResult.value.dispose();
#| const parsed = JSON.parse(resultStr);
#| logs = parsed.logs || [];
#| domOps = parsed.domOps || [];
#| } else if (collectResult.error) {
#| collectResult.error.dispose();
#| }
#| } catch {}
#| return JSON.stringify({
#| success: false, value: '', logs, domOps,
#| error: buildErrorMessage(e)
#| });
#| }
#| } else {
#| const vm = require('vm');
#| let entry = persistentContexts.get(contextId);
#| if (!entry || entry.kind !== 'node') {
#| const sandbox = {};
#| try {
#| vm.createContext(sandbox);
#| vm.runInContext(setupCode + '\n' + initCode + '\n_restorePersistedListenersTree(document);', sandbox, { timeout: 5000 });
#| entry = { kind: 'node', vm, sandbox };
#| persistentContexts.set(contextId, entry);
#| } catch (e) {
#| return JSON.stringify({
#| success: false, value: '', logs: [], domOps: [],
#| error: buildErrorMessage(e)
#| });
#| }
#| } else {
#| try {
#| entry.vm.runInContext('logs.length = 0; domOps.length = 0;', entry.sandbox, { timeout: 1000 });
#| } catch {}
#| }
#| try {
#| const userResult = entry.vm.runInContext(code, entry.sandbox, { timeout: 5000 });
#| entry.vm.runInContext('_flushMicrotasks()', entry.sandbox, { timeout: 1000 });
#| if (flushAsync) {
#| for (let i = 0; i < 100; i++) {
#| const ranTimer = entry.vm.runInContext('_runOneTimeout()', entry.sandbox, { timeout: 1000 });
#| if (ranTimer) {
#| entry.vm.runInContext('_flushMicrotasks()', entry.sandbox, { timeout: 1000 });
#| continue;
#| }
#| const ranAnimationFrame = entry.vm.runInContext('_runOneAnimationFrame()', entry.sandbox, { timeout: 1000 });
#| if (!ranAnimationFrame) break;
#| entry.vm.runInContext('_flushMicrotasks()', entry.sandbox, { timeout: 1000 });
#| }
#| }
#| const collected = entry.vm.runInContext('({ logs, domOps })', entry.sandbox, { timeout: 1000 });
#| return JSON.stringify({
#| success: true,
#| value: userResult === undefined ? 'undefined' : String(userResult),
#| logs: collected.logs || [],
#| domOps: collected.domOps || []
#| });
#| } catch (e) {
#| let logs = [], domOps = [];
#| try {
#| const collected = entry.vm.runInContext('({ logs: logs || [], domOps: domOps || [] })', entry.sandbox, { timeout: 100 });
#| logs = collected.logs || [];
#| domOps = collected.domOps || [];
#| } catch {}
#| return JSON.stringify({
#| success: false, value: '',
#| logs, domOps,
#| error: buildErrorMessage(e)
#| });
#| }
#| }
#| }
///|
extern "js" fn quickjs_tick_with_mock_dom(context_id : Int) -> String =
#| (contextId) => {
#| const persistentContexts = globalThis.__craterPersistentJsContexts || (globalThis.__craterPersistentJsContexts = new Map());
#| const entry = persistentContexts.get(contextId);
#| if (!entry) {
#| return JSON.stringify({ success: true, value: 'false', logs: [], domOps: [] });
#| }
#| const sanitizeErrorText = (value) => String(value).replace(/"/g, "'");
#| if (entry.kind === 'quickjs') {
#| const vm = entry.vm;
#| try {
#| const resetResult = vm.evalCode('logs.length = 0; domOps.length = 0;');
#| if (resetResult.error) {
#| const errorStr = vm.dump(resetResult.error);
#| resetResult.error.dispose();
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(errorStr) });
#| }
#| if (resetResult.value) resetResult.value.dispose();
#| let hadWork = false;
#| const timerResult = vm.evalCode('_runOneTimeout()');
#| if (!timerResult.error && timerResult.value) {
#| hadWork = vm.dump(timerResult.value) === true;
#| timerResult.value.dispose();
#| } else if (timerResult.error) {
#| const errorStr = vm.dump(timerResult.error);
#| timerResult.error.dispose();
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(errorStr) });
#| }
#| if (!hadWork) {
#| const rafResult = vm.evalCode('_runOneAnimationFrame()');
#| if (!rafResult.error && rafResult.value) {
#| hadWork = vm.dump(rafResult.value) === true;
#| rafResult.value.dispose();
#| } else if (rafResult.error) {
#| const errorStr = vm.dump(rafResult.error);
#| rafResult.error.dispose();
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(errorStr) });
#| }
#| }
#| if (hadWork) {
#| const flushResult = vm.evalCode('_flushMicrotasks()');
#| if (flushResult.error) {
#| const errorStr = vm.dump(flushResult.error);
#| flushResult.error.dispose();
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(errorStr) });
#| }
#| if (flushResult.value) flushResult.value.dispose();
#| }
#| const collectResult = vm.evalCode('JSON.stringify({ logs, domOps })');
#| if (collectResult.error) {
#| const errorStr = vm.dump(collectResult.error);
#| collectResult.error.dispose();
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(errorStr) });
#| }
#| const resultStr = vm.dump(collectResult.value);
#| collectResult.value.dispose();
#| const parsed = JSON.parse(resultStr);
#| return JSON.stringify({
#| success: true,
#| value: hadWork ? 'true' : 'false',
#| logs: parsed.logs || [],
#| domOps: parsed.domOps || []
#| });
#| } catch (e) {
#| return JSON.stringify({ success: false, value: '', logs: [], domOps: [], error: sanitizeErrorText(e && e.message ? e.message : String(e)) });
#| }
#| }
#| try {
#| entry.vm.runInContext('logs.length = 0; domOps.length = 0;', entry.sandbox, { timeout: 1000 });
#| let hadWork = entry.vm.runInContext('_runOneTimeout()', entry.sandbox, { timeout: 1000 });
#| if (!hadWork) {
#| hadWork = entry.vm.runInContext('_runOneAnimationFrame()', entry.sandbox, { timeout: 1000 });
#| }
#| if (hadWork) {
#| entry.vm.runInContext('_flushMicrotasks()', entry.sandbox, { timeout: 1000 });
#| }
#| const collected = entry.vm.runInContext('({ logs, domOps })', entry.sandbox, { timeout: 1000 });
#| return JSON.stringify({
#| success: true,
#| value: hadWork ? 'true' : 'false',
#| logs: collected.logs || [],
#| domOps: collected.domOps || []
#| });
#| } catch (e) {
#| return JSON.stringify({
#| success: false,
#| value: '',
#| logs: [],
#| domOps: [],
#| error: sanitizeErrorText(e && e.message ? e.message : String(e))
#| });
#| }
#| }