var fs = require('node:fs'); var path = require('node:path'); var vm = require('node:vm'); // Execute production socket cases, stream state, bubble construction and replay // batching. Only DOM/layout, Markdown parsing and unrelated UI services are doubles. function create(options) { options = options || {}; function Element() { this.children = []; this.dataset = {}; this.className = ''; this.raw = ''; this.style = {}; } Element.prototype.appendChild = function (child) { if (child.parentNode) child.remove(); this.children.push(child); child.parentNode = this; return child; }; Element.prototype.remove = function () { if (this.parentNode) { this.parentNode.children = this.parentNode.children.filter(function (child) { return child !== this; }, this); this.parentNode = null; } }; Element.prototype.setAttribute = function (name, value) { this[name] = value; }; Element.prototype.addEventListener = function () {}; Element.prototype.removeEventListener = function () {}; Element.prototype.querySelectorAll = function (selector) { var found = []; function visit(node) { node.children.forEach(function (child) { var attr = selector.match(/^\[data-client-message-id="(.*)"\]$/); if (attr ? child.dataset.clientMessageId === attr[1] : child.className.split(' ').indexOf(selector.slice(1)) !== -1) found.push(child); visit(child); }); } visit(this); return found; }; Element.prototype.querySelector = function (selector) { return this.querySelectorAll(selector)[0] || null; }; Object.defineProperty(Element.prototype, 'lastElementChild', { get: function () { return this.children[this.children.length - 1] || null; } }); Object.defineProperty(Element.prototype, 'classList', { get: function () { var self = this; return { contains: function (value) { return self.className.split(' ').indexOf(value) !== -1; }, add: function (value) { if (!this.contains(value)) self.className += ' ' + value; }, remove: function () {} }; } }); Object.defineProperty(Element.prototype, 'textContent', { get: function () { return this.raw + this.children.map(function (child) { return child.textContent; }).join(''); }, set: function (text) { this.children = []; this.raw = String(text); } }); Object.defineProperty(Element.prototype, 'innerHTML', { get: function () { return this.raw; }, set: function (html) { this.children = []; this.raw = html; var self = this; Array.from(html.matchAll(/<(?:span|button)[^>]*class="([^"]+)"[^>]*>/g)).forEach(function (match) { var child = new Element(); child.className = match[1]; self.appendChild(child); }); } }); var messages = new Element(); var calls = {}; var errors = []; var frames = new Map(); var frameId = 0; var context = { console: Object.assign({}, console, { error: function (message) { errors.push(String(message)); } }), window: {}, document: { body: new Element(), hidden: false, createElement: function () { return new Element(); }, addEventListener: function () {}, removeEventListener: function () {}, getElementById: function () { return null; }, querySelectorAll: function () { return []; } }, messagesEl: messages, getMessagesEl: function () { return messages; }, renderMarkdown: function (text) { return text; }, escapeHtml: function (text) { return String(text).replace(/&/g, '&').replace(/"/g, '"').replace(/