{"version":3,"file":"platform-server.mjs","sources":["../../../../../../external/npm/node_modules/domino/lib/Event.js","../../../../../../external/npm/node_modules/domino/lib/UIEvent.js","../../../../../../external/npm/node_modules/domino/lib/MouseEvent.js","../../../../../../external/npm/node_modules/domino/lib/DOMException.js","../../../../../../external/npm/node_modules/domino/lib/config.js","../../../../../../external/npm/node_modules/domino/lib/utils.js","../../../../../../external/npm/node_modules/domino/lib/EventTarget.js","../../../../../../external/npm/node_modules/domino/lib/LinkedList.js","../../../../../../external/npm/node_modules/domino/lib/NodeUtils.js","../../../../../../external/npm/node_modules/domino/lib/Node.js","../../../../../../external/npm/node_modules/domino/lib/NodeList.es6.js","../../../../../../external/npm/node_modules/domino/lib/NodeList.es5.js","../../../../../../external/npm/node_modules/domino/lib/NodeList.js","../../../../../../external/npm/node_modules/domino/lib/ContainerNode.js","../../../../../../external/npm/node_modules/domino/lib/xmlnames.js","../../../../../../external/npm/node_modules/domino/lib/attributes.js","../../../../../../external/npm/node_modules/domino/lib/FilteredElementList.js","../../../../../../external/npm/node_modules/domino/lib/DOMTokenList.js","../../../../../../external/npm/node_modules/domino/lib/select.js","../../../../../../external/npm/node_modules/domino/lib/ChildNode.js","../../../../../../external/npm/node_modules/domino/lib/NonDocumentTypeChildNode.js","../../../../../../external/npm/node_modules/domino/lib/NamedNodeMap.js","../../../../../../external/npm/node_modules/domino/lib/Element.js","../../../../../../external/npm/node_modules/domino/lib/Leaf.js","../../../../../../external/npm/node_modules/domino/lib/CharacterData.js","../../../../../../external/npm/node_modules/domino/lib/Text.js","../../../../../../external/npm/node_modules/domino/lib/Comment.js","../../../../../../external/npm/node_modules/domino/lib/DocumentFragment.js","../../../../../../external/npm/node_modules/domino/lib/ProcessingInstruction.js","../../../../../../external/npm/node_modules/domino/lib/NodeFilter.js","../../../../../../external/npm/node_modules/domino/lib/NodeTraversal.js","../../../../../../external/npm/node_modules/domino/lib/TreeWalker.js","../../../../../../external/npm/node_modules/domino/lib/NodeIterator.js","../../../../../../external/npm/node_modules/domino/lib/URL.js","../../../../../../external/npm/node_modules/domino/lib/CustomEvent.js","../../../../../../external/npm/node_modules/domino/lib/events.js","../../../../../../external/npm/node_modules/domino/lib/style_parser.js","../../../../../../external/npm/node_modules/domino/lib/CSSStyleDeclaration.js","../../../../../../external/npm/node_modules/domino/lib/URLUtils.js","../../../../../../external/npm/node_modules/domino/lib/defineElement.js","../../../../../../external/npm/node_modules/domino/lib/htmlelts.js","../../../../../../external/npm/node_modules/domino/lib/svg.js","../../../../../../external/npm/node_modules/domino/lib/MutationConstants.js","../../../../../../external/npm/node_modules/domino/lib/Document.js","../../../../../../external/npm/node_modules/domino/lib/DocumentType.js","../../../../../../external/npm/node_modules/domino/lib/HTMLParser.js","../../../../../../external/npm/node_modules/domino/lib/DOMImplementation.js","../../../../../../external/npm/node_modules/domino/lib/Location.js","../../../../../../external/npm/node_modules/domino/lib/NavigatorID.js","../../../../../../external/npm/node_modules/domino/lib/WindowTimers.js","../../../../../../external/npm/node_modules/domino/lib/impl.js","../../../../../../external/npm/node_modules/domino/lib/Window.js","../../../../../../external/npm/node_modules/domino/lib/index.js","../../../../../../packages/platform-server/src/domino_adapter.ts","../../../../../../packages/platform-server/src/platform_state.ts","../../../../../../packages/platform-server/src/http.ts","../../../../../../packages/platform-server/src/tokens.ts","../../../../../../packages/platform-server/src/location.ts","../../../../../../packages/platform-server/src/server_events.ts","../../../../../../packages/platform-server/src/transfer_state.ts","../../../../../../packages/platform-server/src/server.ts","../../../../../../packages/platform-server/src/provide_server.ts","../../../../../../packages/platform-server/src/utils.ts","../../../../../../packages/platform-server/src/version.ts","../../../../../../packages/platform-server/public_api.ts","../../../../../../packages/platform-server/index.ts","../../../../../../packages/platform-server/platform-server.ts"],"sourcesContent":["\"use strict\";\nmodule.exports = Event;\n\nEvent.CAPTURING_PHASE = 1;\nEvent.AT_TARGET = 2;\nEvent.BUBBLING_PHASE = 3;\n\nfunction Event(type, dictionary) {\n // Initialize basic event properties\n this.type = '';\n this.target = null;\n this.currentTarget = null;\n this.eventPhase = Event.AT_TARGET;\n this.bubbles = false;\n this.cancelable = false;\n this.isTrusted = false;\n this.defaultPrevented = false;\n this.timeStamp = Date.now();\n\n // Initialize internal flags\n // XXX: Would it be better to inherit these defaults from the prototype?\n this._propagationStopped = false;\n this._immediatePropagationStopped = false;\n this._initialized = true;\n this._dispatching = false;\n\n // Now initialize based on the constructor arguments (if any)\n if (type) this.type = type;\n if (dictionary) {\n for(var p in dictionary) {\n this[p] = dictionary[p];\n }\n }\n}\n\nEvent.prototype = Object.create(Object.prototype, {\n constructor: { value: Event },\n stopPropagation: { value: function stopPropagation() {\n this._propagationStopped = true;\n }},\n\n stopImmediatePropagation: { value: function stopImmediatePropagation() {\n this._propagationStopped = true;\n this._immediatePropagationStopped = true;\n }},\n\n preventDefault: { value: function preventDefault() {\n if (this.cancelable) this.defaultPrevented = true;\n }},\n\n initEvent: { value: function initEvent(type, bubbles, cancelable) {\n this._initialized = true;\n if (this._dispatching) return;\n\n this._propagationStopped = false;\n this._immediatePropagationStopped = false;\n this.defaultPrevented = false;\n this.isTrusted = false;\n\n this.target = null;\n this.type = type;\n this.bubbles = bubbles;\n this.cancelable = cancelable;\n }},\n\n});\n","\"use strict\";\nvar Event = require('./Event');\n\nmodule.exports = UIEvent;\n\nfunction UIEvent() {\n // Just use the superclass constructor to initialize\n Event.call(this);\n this.view = null; // FF uses the current window\n this.detail = 0;\n}\nUIEvent.prototype = Object.create(Event.prototype, {\n constructor: { value: UIEvent },\n initUIEvent: { value: function(type, bubbles, cancelable, view, detail) {\n this.initEvent(type, bubbles, cancelable);\n this.view = view;\n this.detail = detail;\n }}\n});\n","\"use strict\";\nvar UIEvent = require('./UIEvent');\n\nmodule.exports = MouseEvent;\n\nfunction MouseEvent() {\n // Just use the superclass constructor to initialize\n UIEvent.call(this);\n\n this.screenX = this.screenY = this.clientX = this.clientY = 0;\n this.ctrlKey = this.altKey = this.shiftKey = this.metaKey = false;\n this.button = 0;\n this.buttons = 1;\n this.relatedTarget = null;\n}\nMouseEvent.prototype = Object.create(UIEvent.prototype, {\n constructor: { value: MouseEvent },\n initMouseEvent: { value: function(type, bubbles, cancelable,\n view, detail,\n screenX, screenY, clientX, clientY,\n ctrlKey, altKey, shiftKey, metaKey,\n button, relatedTarget) {\n\n this.initEvent(type, bubbles, cancelable, view, detail);\n this.screenX = screenX;\n this.screenY = screenY;\n this.clientX = clientX;\n this.clientY = clientY;\n this.ctrlKey = ctrlKey;\n this.altKey = altKey;\n this.shiftKey = shiftKey;\n this.metaKey = metaKey;\n this.button = button;\n switch(button) {\n case 0: this.buttons = 1; break;\n case 1: this.buttons = 4; break;\n case 2: this.buttons = 2; break;\n default: this.buttons = 0; break;\n }\n this.relatedTarget = relatedTarget;\n }},\n\n getModifierState: { value: function(key) {\n switch(key) {\n case \"Alt\": return this.altKey;\n case \"Control\": return this.ctrlKey;\n case \"Shift\": return this.shiftKey;\n case \"Meta\": return this.metaKey;\n default: return false;\n }\n }}\n});\n","\"use strict\";\nmodule.exports = DOMException;\n\nvar INDEX_SIZE_ERR = 1;\nvar HIERARCHY_REQUEST_ERR = 3;\nvar WRONG_DOCUMENT_ERR = 4;\nvar INVALID_CHARACTER_ERR = 5;\nvar NO_MODIFICATION_ALLOWED_ERR = 7;\nvar NOT_FOUND_ERR = 8;\nvar NOT_SUPPORTED_ERR = 9;\nvar INVALID_STATE_ERR = 11;\nvar SYNTAX_ERR = 12;\nvar INVALID_MODIFICATION_ERR = 13;\nvar NAMESPACE_ERR = 14;\nvar INVALID_ACCESS_ERR = 15;\nvar TYPE_MISMATCH_ERR = 17;\nvar SECURITY_ERR = 18;\nvar NETWORK_ERR = 19;\nvar ABORT_ERR = 20;\nvar URL_MISMATCH_ERR = 21;\nvar QUOTA_EXCEEDED_ERR = 22;\nvar TIMEOUT_ERR = 23;\nvar INVALID_NODE_TYPE_ERR = 24;\nvar DATA_CLONE_ERR = 25;\n\n// Code to name\nvar names = [\n null, // No error with code 0\n 'INDEX_SIZE_ERR',\n null, // historical\n 'HIERARCHY_REQUEST_ERR',\n 'WRONG_DOCUMENT_ERR',\n 'INVALID_CHARACTER_ERR',\n null, // historical\n 'NO_MODIFICATION_ALLOWED_ERR',\n 'NOT_FOUND_ERR',\n 'NOT_SUPPORTED_ERR',\n 'INUSE_ATTRIBUTE_ERR', // historical\n 'INVALID_STATE_ERR',\n 'SYNTAX_ERR',\n 'INVALID_MODIFICATION_ERR',\n 'NAMESPACE_ERR',\n 'INVALID_ACCESS_ERR',\n null, // historical\n 'TYPE_MISMATCH_ERR',\n 'SECURITY_ERR',\n 'NETWORK_ERR',\n 'ABORT_ERR',\n 'URL_MISMATCH_ERR',\n 'QUOTA_EXCEEDED_ERR',\n 'TIMEOUT_ERR',\n 'INVALID_NODE_TYPE_ERR',\n 'DATA_CLONE_ERR',\n];\n\n// Code to message\n// These strings are from the 13 May 2011 Editor's Draft of DOM Core.\n// http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html\n// Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved.\n// Used under the terms of the W3C Document License:\n// http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231\nvar messages = [\n null, // No error with code 0\n 'INDEX_SIZE_ERR (1): the index is not in the allowed range',\n null,\n 'HIERARCHY_REQUEST_ERR (3): the operation would yield an incorrect nodes model',\n 'WRONG_DOCUMENT_ERR (4): the object is in the wrong Document, a call to importNode is required',\n 'INVALID_CHARACTER_ERR (5): the string contains invalid characters',\n null,\n 'NO_MODIFICATION_ALLOWED_ERR (7): the object can not be modified',\n 'NOT_FOUND_ERR (8): the object can not be found here',\n 'NOT_SUPPORTED_ERR (9): this operation is not supported',\n 'INUSE_ATTRIBUTE_ERR (10): setAttributeNode called on owned Attribute',\n 'INVALID_STATE_ERR (11): the object is in an invalid state',\n 'SYNTAX_ERR (12): the string did not match the expected pattern',\n 'INVALID_MODIFICATION_ERR (13): the object can not be modified in this way',\n 'NAMESPACE_ERR (14): the operation is not allowed by Namespaces in XML',\n 'INVALID_ACCESS_ERR (15): the object does not support the operation or argument',\n null,\n 'TYPE_MISMATCH_ERR (17): the type of the object does not match the expected type',\n 'SECURITY_ERR (18): the operation is insecure',\n 'NETWORK_ERR (19): a network error occurred',\n 'ABORT_ERR (20): the user aborted an operation',\n 'URL_MISMATCH_ERR (21): the given URL does not match another URL',\n 'QUOTA_EXCEEDED_ERR (22): the quota has been exceeded',\n 'TIMEOUT_ERR (23): a timeout occurred',\n 'INVALID_NODE_TYPE_ERR (24): the supplied node is invalid or has an invalid ancestor for this operation',\n 'DATA_CLONE_ERR (25): the object can not be cloned.'\n];\n\n// Name to code\nvar constants = {\n INDEX_SIZE_ERR: INDEX_SIZE_ERR,\n DOMSTRING_SIZE_ERR: 2, // historical\n HIERARCHY_REQUEST_ERR: HIERARCHY_REQUEST_ERR,\n WRONG_DOCUMENT_ERR: WRONG_DOCUMENT_ERR,\n INVALID_CHARACTER_ERR: INVALID_CHARACTER_ERR,\n NO_DATA_ALLOWED_ERR: 6, // historical\n NO_MODIFICATION_ALLOWED_ERR: NO_MODIFICATION_ALLOWED_ERR,\n NOT_FOUND_ERR: NOT_FOUND_ERR,\n NOT_SUPPORTED_ERR: NOT_SUPPORTED_ERR,\n INUSE_ATTRIBUTE_ERR: 10, // historical\n INVALID_STATE_ERR: INVALID_STATE_ERR,\n SYNTAX_ERR: SYNTAX_ERR,\n INVALID_MODIFICATION_ERR: INVALID_MODIFICATION_ERR,\n NAMESPACE_ERR: NAMESPACE_ERR,\n INVALID_ACCESS_ERR: INVALID_ACCESS_ERR,\n VALIDATION_ERR: 16, // historical\n TYPE_MISMATCH_ERR: TYPE_MISMATCH_ERR,\n SECURITY_ERR: SECURITY_ERR,\n NETWORK_ERR: NETWORK_ERR,\n ABORT_ERR: ABORT_ERR,\n URL_MISMATCH_ERR: URL_MISMATCH_ERR,\n QUOTA_EXCEEDED_ERR: QUOTA_EXCEEDED_ERR,\n TIMEOUT_ERR: TIMEOUT_ERR,\n INVALID_NODE_TYPE_ERR: INVALID_NODE_TYPE_ERR,\n DATA_CLONE_ERR: DATA_CLONE_ERR\n};\n\nfunction DOMException(code) {\n Error.call(this);\n Error.captureStackTrace(this, this.constructor);\n this.code = code;\n this.message = messages[code];\n this.name = names[code];\n}\nDOMException.prototype.__proto__ = Error.prototype;\n\n// Initialize the constants on DOMException and DOMException.prototype\nfor(var c in constants) {\n var v = { value: constants[c] };\n Object.defineProperty(DOMException, c, v);\n Object.defineProperty(DOMException.prototype, c, v);\n}\n","/*\n * This file defines Domino behaviour that can be externally configured.\n * To change these settings, set the relevant global property *before*\n * you call `require(\"domino\")`.\n */\n\nexports.isApiWritable = !globalThis.__domino_frozen__;\n","\"use strict\";\nvar DOMException = require('./DOMException');\nvar ERR = DOMException;\nvar isApiWritable = require(\"./config\").isApiWritable;\n\nexports.NAMESPACE = {\n HTML: 'http://www.w3.org/1999/xhtml',\n XML: 'http://www.w3.org/XML/1998/namespace',\n XMLNS: 'http://www.w3.org/2000/xmlns/',\n MATHML: 'http://www.w3.org/1998/Math/MathML',\n SVG: 'http://www.w3.org/2000/svg',\n XLINK: 'http://www.w3.org/1999/xlink'\n};\n\n//\n// Shortcut functions for throwing errors of various types.\n//\nexports.IndexSizeError = function() { throw new DOMException(ERR.INDEX_SIZE_ERR); };\nexports.HierarchyRequestError = function() { throw new DOMException(ERR.HIERARCHY_REQUEST_ERR); };\nexports.WrongDocumentError = function() { throw new DOMException(ERR.WRONG_DOCUMENT_ERR); };\nexports.InvalidCharacterError = function() { throw new DOMException(ERR.INVALID_CHARACTER_ERR); };\nexports.NoModificationAllowedError = function() { throw new DOMException(ERR.NO_MODIFICATION_ALLOWED_ERR); };\nexports.NotFoundError = function() { throw new DOMException(ERR.NOT_FOUND_ERR); };\nexports.NotSupportedError = function() { throw new DOMException(ERR.NOT_SUPPORTED_ERR); };\nexports.InvalidStateError = function() { throw new DOMException(ERR.INVALID_STATE_ERR); };\nexports.SyntaxError = function() { throw new DOMException(ERR.SYNTAX_ERR); };\nexports.InvalidModificationError = function() { throw new DOMException(ERR.INVALID_MODIFICATION_ERR); };\nexports.NamespaceError = function() { throw new DOMException(ERR.NAMESPACE_ERR); };\nexports.InvalidAccessError = function() { throw new DOMException(ERR.INVALID_ACCESS_ERR); };\nexports.TypeMismatchError = function() { throw new DOMException(ERR.TYPE_MISMATCH_ERR); };\nexports.SecurityError = function() { throw new DOMException(ERR.SECURITY_ERR); };\nexports.NetworkError = function() { throw new DOMException(ERR.NETWORK_ERR); };\nexports.AbortError = function() { throw new DOMException(ERR.ABORT_ERR); };\nexports.UrlMismatchError = function() { throw new DOMException(ERR.URL_MISMATCH_ERR); };\nexports.QuotaExceededError = function() { throw new DOMException(ERR.QUOTA_EXCEEDED_ERR); };\nexports.TimeoutError = function() { throw new DOMException(ERR.TIMEOUT_ERR); };\nexports.InvalidNodeTypeError = function() { throw new DOMException(ERR.INVALID_NODE_TYPE_ERR); };\nexports.DataCloneError = function() { throw new DOMException(ERR.DATA_CLONE_ERR); };\n\nexports.nyi = function() {\n throw new Error(\"NotYetImplemented\");\n};\n\nexports.shouldOverride = function() {\n throw new Error(\"Abstract function; should be overriding in subclass.\");\n};\n\nexports.assert = function(expr, msg) {\n if (!expr) {\n throw new Error(\"Assertion failed: \" + (msg || \"\") + \"\\n\" + new Error().stack);\n }\n};\n\nexports.expose = function(src, c) {\n for (var n in src) {\n Object.defineProperty(c.prototype, n, { value: src[n], writable: isApiWritable });\n }\n};\n\nexports.merge = function(a, b) {\n for (var n in b) {\n a[n] = b[n];\n }\n};\n\n// Compare two nodes based on their document order. This function is intended\n// to be passed to sort(). Assumes that the array being sorted does not\n// contain duplicates. And that all nodes are connected and comparable.\n// Clever code by ppk via jeresig.\nexports.documentOrder = function(n,m) {\n /* jshint bitwise: false */\n return 3 - (n.compareDocumentPosition(m) & 6);\n};\n\nexports.toASCIILowerCase = function(s) {\n return s.replace(/[A-Z]+/g, function(c) {\n return c.toLowerCase();\n });\n};\n\nexports.toASCIIUpperCase = function(s) {\n return s.replace(/[a-z]+/g, function(c) {\n return c.toUpperCase();\n });\n};\n","\"use strict\";\nvar Event = require('./Event');\nvar MouseEvent = require('./MouseEvent');\nvar utils = require('./utils');\n\nmodule.exports = EventTarget;\n\nfunction EventTarget() {}\n\nEventTarget.prototype = {\n // XXX\n // See WebIDL §4.8 for details on object event handlers\n // and how they should behave. We actually have to accept\n // any object to addEventListener... Can't type check it.\n // on registration.\n\n // XXX:\n // Capturing event listeners are sort of rare. I think I can optimize\n // them so that dispatchEvent can skip the capturing phase (or much of\n // it). Each time a capturing listener is added, increment a flag on\n // the target node and each of its ancestors. Decrement when removed.\n // And update the counter when nodes are added and removed from the\n // tree as well. Then, in dispatch event, the capturing phase can\n // abort if it sees any node with a zero count.\n addEventListener: function addEventListener(type, listener, capture) {\n if (!listener) return;\n if (capture === undefined) capture = false;\n if (!this._listeners) this._listeners = Object.create(null);\n if (!this._listeners[type]) this._listeners[type] = [];\n var list = this._listeners[type];\n\n // If this listener has already been registered, just return\n for(var i = 0, n = list.length; i < n; i++) {\n var l = list[i];\n if (l.listener === listener && l.capture === capture)\n return;\n }\n\n // Add an object to the list of listeners\n var obj = { listener: listener, capture: capture };\n if (typeof listener === 'function') obj.f = listener;\n list.push(obj);\n },\n\n removeEventListener: function removeEventListener(type,\n listener,\n capture) {\n if (capture === undefined) capture = false;\n if (this._listeners) {\n var list = this._listeners[type];\n if (list) {\n // Find the listener in the list and remove it\n for(var i = 0, n = list.length; i < n; i++) {\n var l = list[i];\n if (l.listener === listener && l.capture === capture) {\n if (list.length === 1) {\n this._listeners[type] = undefined;\n }\n else {\n list.splice(i, 1);\n }\n return;\n }\n }\n }\n }\n },\n\n // This is the public API for dispatching untrusted public events.\n // See _dispatchEvent for the implementation\n dispatchEvent: function dispatchEvent(event) {\n // Dispatch an untrusted event\n return this._dispatchEvent(event, false);\n },\n\n //\n // See DOMCore §4.4\n // XXX: I'll probably need another version of this method for\n // internal use, one that does not set isTrusted to false.\n // XXX: see Document._dispatchEvent: perhaps that and this could\n // call a common internal function with different settings of\n // a trusted boolean argument\n //\n // XXX:\n // The spec has changed in how to deal with handlers registered\n // on idl or content attributes rather than with addEventListener.\n // Used to say that they always ran first. That's how webkit does it\n // Spec now says that they run in a position determined by\n // when they were first set. FF does it that way. See:\n // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handlers\n //\n _dispatchEvent: function _dispatchEvent(event, trusted) {\n if (typeof trusted !== 'boolean') trusted = false;\n function invoke(target, event) {\n var type = event.type, phase = event.eventPhase;\n event.currentTarget = target;\n\n // If there was an individual handler defined, invoke it first\n // XXX: see comment above: this shouldn't always be first.\n if (phase !== Event.CAPTURING_PHASE &&\n target._handlers && target._handlers[type])\n {\n var handler = target._handlers[type];\n var rv;\n if (typeof handler === 'function') {\n rv=handler.call(event.currentTarget, event);\n }\n else {\n var f = handler.handleEvent;\n if (typeof f !== 'function')\n throw new TypeError('handleEvent property of ' +\n 'event handler object is' +\n 'not a function.');\n rv=f.call(handler, event);\n }\n\n switch(event.type) {\n case 'mouseover':\n if (rv === true) // Historical baggage\n event.preventDefault();\n break;\n case 'beforeunload':\n // XXX: eventually we need a special case here\n /* falls through */\n default:\n if (rv === false)\n event.preventDefault();\n break;\n }\n }\n\n // Now invoke list list of listeners for this target and type\n var list = target._listeners && target._listeners[type];\n if (!list) return;\n list = list.slice();\n for(var i = 0, n = list.length; i < n; i++) {\n if (event._immediatePropagationStopped) return;\n var l = list[i];\n if ((phase === Event.CAPTURING_PHASE && !l.capture) ||\n (phase === Event.BUBBLING_PHASE && l.capture))\n continue;\n if (l.f) {\n l.f.call(event.currentTarget, event);\n }\n else {\n var fn = l.listener.handleEvent;\n if (typeof fn !== 'function')\n throw new TypeError('handleEvent property of event listener object is not a function.');\n fn.call(l.listener, event);\n }\n }\n }\n\n if (!event._initialized || event._dispatching) utils.InvalidStateError();\n event.isTrusted = trusted;\n\n // Begin dispatching the event now\n event._dispatching = true;\n event.target = this;\n\n // Build the list of targets for the capturing and bubbling phases\n // XXX: we'll eventually have to add Window to this list.\n var ancestors = [];\n for(var n = this.parentNode; n; n = n.parentNode)\n ancestors.push(n);\n\n // Capturing phase\n event.eventPhase = Event.CAPTURING_PHASE;\n for(var i = ancestors.length-1; i >= 0; i--) {\n invoke(ancestors[i], event);\n if (event._propagationStopped) break;\n }\n\n // At target phase\n if (!event._propagationStopped) {\n event.eventPhase = Event.AT_TARGET;\n invoke(this, event);\n }\n\n // Bubbling phase\n if (event.bubbles && !event._propagationStopped) {\n event.eventPhase = Event.BUBBLING_PHASE;\n for(var ii = 0, nn = ancestors.length; ii < nn; ii++) {\n invoke(ancestors[ii], event);\n if (event._propagationStopped) break;\n }\n }\n\n event._dispatching = false;\n event.eventPhase = Event.AT_TARGET;\n event.currentTarget = null;\n\n // Deal with mouse events and figure out when\n // a click has happened\n if (trusted && !event.defaultPrevented && event instanceof MouseEvent) {\n switch(event.type) {\n case 'mousedown':\n this._armed = {\n x: event.clientX,\n y: event.clientY,\n t: event.timeStamp\n };\n break;\n case 'mouseout':\n case 'mouseover':\n this._armed = null;\n break;\n case 'mouseup':\n if (this._isClick(event)) this._doClick(event);\n this._armed = null;\n break;\n }\n }\n\n\n\n return !event.defaultPrevented;\n },\n\n // Determine whether a click occurred\n // XXX We don't support double clicks for now\n _isClick: function(event) {\n return (this._armed !== null &&\n event.type === 'mouseup' &&\n event.isTrusted &&\n event.button === 0 &&\n event.timeStamp - this._armed.t < 1000 &&\n Math.abs(event.clientX - this._armed.x) < 10 &&\n Math.abs(event.clientY - this._armed.Y) < 10);\n },\n\n // Clicks are handled like this:\n // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#interactive-content-0\n //\n // Note that this method is similar to the HTMLElement.click() method\n // The event argument must be the trusted mouseup event\n _doClick: function(event) {\n if (this._click_in_progress) return;\n this._click_in_progress = true;\n\n // Find the nearest enclosing element that is activatable\n // An element is activatable if it has a\n // _post_click_activation_steps hook\n var activated = this;\n while(activated && !activated._post_click_activation_steps)\n activated = activated.parentNode;\n\n if (activated && activated._pre_click_activation_steps) {\n activated._pre_click_activation_steps();\n }\n\n var click = this.ownerDocument.createEvent('MouseEvent');\n click.initMouseEvent('click', true, true,\n this.ownerDocument.defaultView, 1,\n event.screenX, event.screenY,\n event.clientX, event.clientY,\n event.ctrlKey, event.altKey,\n event.shiftKey, event.metaKey,\n event.button, null);\n\n var result = this._dispatchEvent(click, true);\n\n if (activated) {\n if (result) {\n // This is where hyperlinks get followed, for example.\n if (activated._post_click_activation_steps)\n activated._post_click_activation_steps(click);\n }\n else {\n if (activated._cancelled_activation_steps)\n activated._cancelled_activation_steps();\n }\n }\n },\n\n //\n // An event handler is like an event listener, but it registered\n // by setting an IDL or content attribute like onload or onclick.\n // There can only be one of these at a time for any event type.\n // This is an internal method for the attribute accessors and\n // content attribute handlers that need to register events handlers.\n // The type argument is the same as in addEventListener().\n // The handler argument is the same as listeners in addEventListener:\n // it can be a function or an object. Pass null to remove any existing\n // handler. Handlers are always invoked before any listeners of\n // the same type. They are not invoked during the capturing phase\n // of event dispatch.\n //\n _setEventHandler: function _setEventHandler(type, handler) {\n if (!this._handlers) this._handlers = Object.create(null);\n this._handlers[type] = handler;\n },\n\n _getEventHandler: function _getEventHandler(type) {\n return (this._handlers && this._handlers[type]) || null;\n }\n\n};\n","\"use strict\";\nvar utils = require('./utils');\n\nvar LinkedList = module.exports = {\n // basic validity tests on a circular linked list a\n valid: function(a) {\n utils.assert(a, \"list falsy\");\n utils.assert(a._previousSibling, \"previous falsy\");\n utils.assert(a._nextSibling, \"next falsy\");\n // xxx check that list is actually circular\n return true;\n },\n // insert a before b\n insertBefore: function(a, b) {\n utils.assert(LinkedList.valid(a) && LinkedList.valid(b));\n var a_first = a, a_last = a._previousSibling;\n var b_first = b, b_last = b._previousSibling;\n a_first._previousSibling = b_last;\n a_last._nextSibling = b_first;\n b_last._nextSibling = a_first;\n b_first._previousSibling = a_last;\n utils.assert(LinkedList.valid(a) && LinkedList.valid(b));\n },\n // replace a single node a with a list b (which could be null)\n replace: function(a, b) {\n utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));\n if (b!==null) {\n LinkedList.insertBefore(b, a);\n }\n LinkedList.remove(a);\n utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));\n },\n // remove single node a from its list\n remove: function(a) {\n utils.assert(LinkedList.valid(a));\n var prev = a._previousSibling;\n if (prev === a) { return; }\n var next = a._nextSibling;\n prev._nextSibling = next;\n next._previousSibling = prev;\n a._previousSibling = a._nextSibling = a;\n utils.assert(LinkedList.valid(a));\n }\n};\n","\"use strict\";\nmodule.exports = {\n // NOTE: The `serializeOne()` function used to live on the `Node.prototype`\n // as a private method `Node#_serializeOne(child)`, however that requires\n // a megamorphic property access `this._serializeOne` just to get to the\n // method, and this is being done on lots of different `Node` subclasses,\n // which puts a lot of pressure on V8's megamorphic stub cache. So by\n // moving the helper off of the `Node.prototype` and into a separate\n // function in this helper module, we get a monomorphic property access\n // `NodeUtils.serializeOne` to get to the function and reduce pressure\n // on the megamorphic stub cache.\n // See https://github.com/fgnass/domino/pull/142 for more information.\n serializeOne: serializeOne,\n\n // Export util functions so that we can run extra test for them.\n // Note: we prefix function names with `ɵ`, similar to what we do\n // with internal functions in Angular packages.\n ɵescapeMatchingClosingTag: escapeMatchingClosingTag,\n ɵescapeClosingCommentTag: escapeClosingCommentTag,\n ɵescapeProcessingInstructionContent: escapeProcessingInstructionContent\n};\n\nvar utils = require('./utils');\nvar NAMESPACE = utils.NAMESPACE;\n\nvar hasRawContent = {\n STYLE: true,\n SCRIPT: true,\n XMP: true,\n IFRAME: true,\n NOEMBED: true,\n NOFRAMES: true,\n PLAINTEXT: true\n};\n\nvar emptyElements = {\n area: true,\n base: true,\n basefont: true,\n bgsound: true,\n br: true,\n col: true,\n embed: true,\n frame: true,\n hr: true,\n img: true,\n input: true,\n keygen: true,\n link: true,\n meta: true,\n param: true,\n source: true,\n track: true,\n wbr: true\n};\n\nvar extraNewLine = {\n /* Removed in https://github.com/whatwg/html/issues/944\n pre: true,\n textarea: true,\n listing: true\n */\n};\n\nconst ESCAPE_REGEXP = /[&<>\\u00A0]/g;\nconst ESCAPE_ATTR_REGEXP = /[&\"<>\\u00A0]/g;\n\nfunction escape(s) {\n if (!ESCAPE_REGEXP.test(s)) {\n // nothing to do, fast path\n return s;\n }\n\n return s.replace(ESCAPE_REGEXP, (c) => {\n switch (c) {\n case \"&\":\n return \"&\";\n case \"<\":\n return \"<\";\n case \">\":\n return \">\";\n case \"\\u00A0\":\n return \" \";\n }\n });\n}\n\nfunction escapeAttr(s) {\n if (!ESCAPE_ATTR_REGEXP.test(s)) {\n // nothing to do, fast path\n return s;\n }\n\n return s.replace(ESCAPE_ATTR_REGEXP, (c) => {\n switch (c) {\n case \"<\":\n return \"<\";\n case \">\":\n return \">\";\n case \"&\":\n return \"&\";\n case '\"':\n return \""\";\n case \"\\u00A0\":\n return \" \";\n }\n });\n}\n\nfunction attrname(a) {\n var ns = a.namespaceURI;\n if (!ns)\n return a.localName;\n if (ns === NAMESPACE.XML)\n return 'xml:' + a.localName;\n if (ns === NAMESPACE.XLINK)\n return 'xlink:' + a.localName;\n\n if (ns === NAMESPACE.XMLNS) {\n if (a.localName === 'xmlns') return 'xmlns';\n else return 'xmlns:' + a.localName;\n }\n return a.name;\n}\n\n/**\n * Escapes matching closing tag in a raw text.\n *\n * For example, given `)`,\n * the parent tag would by \"style\" and the raw text is\n * \"\". If we come across a matching closing tag\n * (in out case ``) - replace `<` with `<` to avoid unexpected\n * and unsafe behavior after de-serialization.\n */\nfunction escapeMatchingClosingTag(rawText, parentTag) {\n const parentClosingTag = '/;\n\n/**\n * Escapes closing comment tag in a comment content.\n *\n * For example, given `#comment('-->')`, the content of a comment would be\n * updated to `-->` to avoid unexpected and unsafe behavior after\n * de-serialization.\n */\nfunction escapeClosingCommentTag(rawContent) {\n if (!CLOSING_COMMENT_REGEXP.test(rawContent)) {\n return rawContent; // fast path\n }\n return rawContent.replace(/(--\\!?)>/g, '$1>');\n}\n\n/**\n * Escapes processing instruction content by replacing `>` with `>`.\n */\nfunction escapeProcessingInstructionContent(rawContent) {\n return rawContent.includes('>')\n ? rawContent.replaceAll('>', '>')\n : rawContent;\n}\n\nfunction serializeOne(kid, parent) {\n var s = '';\n switch(kid.nodeType) {\n case 1: //ELEMENT_NODE\n var ns = kid.namespaceURI;\n var html = ns === NAMESPACE.HTML;\n var tagname = (html || ns === NAMESPACE.SVG || ns === NAMESPACE.MATHML) ? kid.localName : kid.tagName;\n\n s += '<' + tagname;\n\n for(var j = 0, k = kid._numattrs; j < k; j++) {\n var a = kid._attr(j);\n s += ' ' + attrname(a);\n if (a.value !== undefined) s += '=\"' + escapeAttr(a.value) + '\"';\n }\n s += '>';\n\n if (!(html && emptyElements[tagname])) {\n var ss = kid.serialize();\n // If an element can have raw content, this content may\n // potentially require escaping to avoid XSS.\n if (hasRawContent[tagname.toUpperCase()]) {\n ss = escapeMatchingClosingTag(ss, tagname);\n }\n if (html && extraNewLine[tagname] && ss.charAt(0)==='\\n') s += '\\n';\n // Serialize children and add end tag for all others\n s += ss;\n s += '';\n }\n break;\n case 3: //TEXT_NODE\n case 4: //CDATA_SECTION_NODE\n var parenttag;\n if (parent.nodeType === 1 /*ELEMENT_NODE*/ &&\n parent.namespaceURI === NAMESPACE.HTML)\n parenttag = parent.tagName;\n else\n parenttag = '';\n\n if (hasRawContent[parenttag] ||\n (parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {\n s += kid.data;\n } else {\n s += escape(kid.data);\n }\n break;\n case 8: //COMMENT_NODE\n s += '';\n break;\n case 7: //PROCESSING_INSTRUCTION_NODE\n const content = escapeProcessingInstructionContent(kid.data);\n s += '';\n break;\n case 10: //DOCUMENT_TYPE_NODE\n s += '';\n break;\n default:\n utils.InvalidStateError();\n }\n return s;\n}\n","\"use strict\";\nmodule.exports = Node;\n\nvar EventTarget = require('./EventTarget');\nvar LinkedList = require('./LinkedList');\nvar NodeUtils = require('./NodeUtils');\nvar utils = require('./utils');\n\n// All nodes have a nodeType and an ownerDocument.\n// Once inserted, they also have a parentNode.\n// This is an abstract class; all nodes in a document are instances\n// of a subtype, so all the properties are defined by more specific\n// constructors.\nfunction Node() {\n EventTarget.call(this);\n this.parentNode = null;\n this._nextSibling = this._previousSibling = this;\n this._index = undefined;\n}\n\nvar ELEMENT_NODE = Node.ELEMENT_NODE = 1;\nvar ATTRIBUTE_NODE = Node.ATTRIBUTE_NODE = 2;\nvar TEXT_NODE = Node.TEXT_NODE = 3;\nvar CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE = 4;\nvar ENTITY_REFERENCE_NODE = Node.ENTITY_REFERENCE_NODE = 5;\nvar ENTITY_NODE = Node.ENTITY_NODE = 6;\nvar PROCESSING_INSTRUCTION_NODE = Node.PROCESSING_INSTRUCTION_NODE = 7;\nvar COMMENT_NODE = Node.COMMENT_NODE = 8;\nvar DOCUMENT_NODE = Node.DOCUMENT_NODE = 9;\nvar DOCUMENT_TYPE_NODE = Node.DOCUMENT_TYPE_NODE = 10;\nvar DOCUMENT_FRAGMENT_NODE = Node.DOCUMENT_FRAGMENT_NODE = 11;\nvar NOTATION_NODE = Node.NOTATION_NODE = 12;\n\nvar DOCUMENT_POSITION_DISCONNECTED = Node.DOCUMENT_POSITION_DISCONNECTED = 0x01;\nvar DOCUMENT_POSITION_PRECEDING = Node.DOCUMENT_POSITION_PRECEDING = 0x02;\nvar DOCUMENT_POSITION_FOLLOWING = Node.DOCUMENT_POSITION_FOLLOWING = 0x04;\nvar DOCUMENT_POSITION_CONTAINS = Node.DOCUMENT_POSITION_CONTAINS = 0x08;\nvar DOCUMENT_POSITION_CONTAINED_BY = Node.DOCUMENT_POSITION_CONTAINED_BY = 0x10;\nvar DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;\n\nNode.prototype = Object.create(EventTarget.prototype, {\n\n // Node that are not inserted into the tree inherit a null parent\n\n // XXX: the baseURI attribute is defined by dom core, but\n // a correct implementation of it requires HTML features, so\n // we'll come back to this later.\n baseURI: { get: utils.nyi },\n\n parentElement: { get: function() {\n return (this.parentNode && this.parentNode.nodeType===ELEMENT_NODE) ? this.parentNode : null;\n }},\n\n hasChildNodes: { value: utils.shouldOverride },\n\n firstChild: { get: utils.shouldOverride },\n\n lastChild: { get: utils.shouldOverride },\n\n isConnected: {\n get: function () {\n let node = this;\n while (node != null) {\n if (node.nodeType === Node.DOCUMENT_NODE) {\n return true;\n }\n\n node = node.parentNode;\n if (node != null && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n node = node.host;\n }\n }\n return false;\n },\n },\n\n previousSibling: { get: function() {\n var parent = this.parentNode;\n if (!parent) return null;\n if (this === parent.firstChild) return null;\n return this._previousSibling;\n }},\n\n nextSibling: { get: function() {\n var parent = this.parentNode, next = this._nextSibling;\n if (!parent) return null;\n if (next === parent.firstChild) return null;\n return next;\n }},\n\n textContent: {\n // Should override for DocumentFragment/Element/Attr/Text/PI/Comment\n get: function() { return null; },\n set: function(v) { /* do nothing */ },\n },\n\n innerText: {\n // Should override for DocumentFragment/Element/Attr/Text/PI/Comment\n get: function() { return null; },\n set: function(v) { /* do nothing */ },\n },\n\n _countChildrenOfType: { value: function(type) {\n var sum = 0;\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === type) sum++;\n }\n return sum;\n }},\n\n _ensureInsertValid: { value: function _ensureInsertValid(node, child, isPreinsert) {\n var parent = this, i, kid;\n if (!node.nodeType) throw new TypeError('not a node');\n // 1. If parent is not a Document, DocumentFragment, or Element\n // node, throw a HierarchyRequestError.\n switch (parent.nodeType) {\n case DOCUMENT_NODE:\n case DOCUMENT_FRAGMENT_NODE:\n case ELEMENT_NODE:\n break;\n default: utils.HierarchyRequestError();\n }\n // 2. If node is a host-including inclusive ancestor of parent,\n // throw a HierarchyRequestError.\n if (node.isAncestor(parent)) utils.HierarchyRequestError();\n // 3. If child is not null and its parent is not parent, then\n // throw a NotFoundError. (replaceChild omits the 'child is not null'\n // and throws a TypeError here if child is null.)\n if (child !== null || !isPreinsert) {\n if (child.parentNode !== parent) utils.NotFoundError();\n }\n // 4. If node is not a DocumentFragment, DocumentType, Element,\n // Text, ProcessingInstruction, or Comment node, throw a\n // HierarchyRequestError.\n switch (node.nodeType) {\n case DOCUMENT_FRAGMENT_NODE:\n case DOCUMENT_TYPE_NODE:\n case ELEMENT_NODE:\n case TEXT_NODE:\n case PROCESSING_INSTRUCTION_NODE:\n case COMMENT_NODE:\n break;\n default: utils.HierarchyRequestError();\n }\n // 5. If either node is a Text node and parent is a document, or\n // node is a doctype and parent is not a document, throw a\n // HierarchyRequestError.\n // 6. If parent is a document, and any of the statements below, switched\n // on node, are true, throw a HierarchyRequestError.\n if (parent.nodeType === DOCUMENT_NODE) {\n switch (node.nodeType) {\n case TEXT_NODE:\n utils.HierarchyRequestError();\n break;\n case DOCUMENT_FRAGMENT_NODE:\n // 6a1. If node has more than one element child or has a Text\n // node child.\n if (node._countChildrenOfType(TEXT_NODE) > 0)\n utils.HierarchyRequestError();\n switch (node._countChildrenOfType(ELEMENT_NODE)) {\n case 0:\n break;\n case 1:\n // 6a2. Otherwise, if node has one element child and either\n // parent has an element child, child is a doctype, or child\n // is not null and a doctype is following child. [preinsert]\n // 6a2. Otherwise, if node has one element child and either\n // parent has an element child that is not child or a\n // doctype is following child. [replaceWith]\n if (child !== null /* always true here for replaceWith */) {\n if (isPreinsert && child.nodeType === DOCUMENT_TYPE_NODE)\n utils.HierarchyRequestError();\n for (kid = child.nextSibling; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === DOCUMENT_TYPE_NODE)\n utils.HierarchyRequestError();\n }\n }\n i = parent._countChildrenOfType(ELEMENT_NODE);\n if (isPreinsert) {\n // \"parent has an element child\"\n if (i > 0)\n utils.HierarchyRequestError();\n } else {\n // \"parent has an element child that is not child\"\n if (i > 1 || (i === 1 && child.nodeType !== ELEMENT_NODE))\n utils.HierarchyRequestError();\n }\n break;\n default: // 6a1, continued. (more than one Element child)\n utils.HierarchyRequestError();\n }\n break;\n case ELEMENT_NODE:\n // 6b. parent has an element child, child is a doctype, or\n // child is not null and a doctype is following child. [preinsert]\n // 6b. parent has an element child that is not child or a\n // doctype is following child. [replaceWith]\n if (child !== null /* always true here for replaceWith */) {\n if (isPreinsert && child.nodeType === DOCUMENT_TYPE_NODE)\n utils.HierarchyRequestError();\n for (kid = child.nextSibling; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === DOCUMENT_TYPE_NODE)\n utils.HierarchyRequestError();\n }\n }\n i = parent._countChildrenOfType(ELEMENT_NODE);\n if (isPreinsert) {\n // \"parent has an element child\"\n if (i > 0)\n utils.HierarchyRequestError();\n } else {\n // \"parent has an element child that is not child\"\n if (i > 1 || (i === 1 && child.nodeType !== ELEMENT_NODE))\n utils.HierarchyRequestError();\n }\n break;\n case DOCUMENT_TYPE_NODE:\n // 6c. parent has a doctype child, child is non-null and an\n // element is preceding child, or child is null and parent has\n // an element child. [preinsert]\n // 6c. parent has a doctype child that is not child, or an\n // element is preceding child. [replaceWith]\n if (child === null) {\n if (parent._countChildrenOfType(ELEMENT_NODE))\n utils.HierarchyRequestError();\n } else {\n // child is always non-null for [replaceWith] case\n for (kid = parent.firstChild; kid !== null; kid = kid.nextSibling) {\n if (kid === child) break;\n if (kid.nodeType === ELEMENT_NODE)\n utils.HierarchyRequestError();\n }\n }\n i = parent._countChildrenOfType(DOCUMENT_TYPE_NODE);\n if (isPreinsert) {\n // \"parent has an doctype child\"\n if (i > 0)\n utils.HierarchyRequestError();\n } else {\n // \"parent has an doctype child that is not child\"\n if (i > 1 || (i === 1 && child.nodeType !== DOCUMENT_TYPE_NODE))\n utils.HierarchyRequestError();\n }\n break;\n }\n } else {\n // 5, continued: (parent is not a document)\n if (node.nodeType === DOCUMENT_TYPE_NODE) utils.HierarchyRequestError();\n }\n }},\n\n insertBefore: { value: function insertBefore(node, child) {\n var parent = this;\n // 1. Ensure pre-insertion validity\n parent._ensureInsertValid(node, child, true);\n // 2. Let reference child be child.\n var refChild = child;\n // 3. If reference child is node, set it to node's next sibling\n if (refChild === node) { refChild = node.nextSibling; }\n // 4. Adopt node into parent's node document.\n parent.doc.adoptNode(node);\n // 5. Insert node into parent before reference child.\n node._insertOrReplace(parent, refChild, false);\n // 6. Return node\n return node;\n }},\n\n\n appendChild: { value: function(child) {\n // This invokes _appendChild after doing validity checks.\n return this.insertBefore(child, null);\n }},\n\n _appendChild: { value: function(child) {\n child._insertOrReplace(this, null, false);\n }},\n\n removeChild: { value: function removeChild(child) {\n var parent = this;\n if (!child.nodeType) throw new TypeError('not a node');\n if (child.parentNode !== parent) utils.NotFoundError();\n child.remove();\n return child;\n }},\n\n // To replace a `child` with `node` within a `parent` (this)\n replaceChild: { value: function replaceChild(node, child) {\n var parent = this;\n // Ensure validity (slight differences from pre-insertion check)\n parent._ensureInsertValid(node, child, false);\n // Adopt node into parent's node document.\n if (node.doc !== parent.doc) {\n // XXX adoptNode has side-effect of removing node from its parent\n // and generating a mutation event, thus causing the _insertOrReplace\n // to generate two deletes and an insert instead of a 'move'\n // event. It looks like the new MutationObserver stuff avoids\n // this problem, but for now let's only adopt (ie, remove `node`\n // from its parent) here if we need to.\n parent.doc.adoptNode(node);\n }\n // Do the replace.\n node._insertOrReplace(parent, child, true);\n return child;\n }},\n\n // See: http://ejohn.org/blog/comparing-document-position/\n contains: { value: function contains(node) {\n if (node === null) { return false; }\n if (this === node) { return true; /* inclusive descendant */ }\n /* jshint bitwise: false */\n return (this.compareDocumentPosition(node) &\n DOCUMENT_POSITION_CONTAINED_BY) !== 0;\n }},\n\n compareDocumentPosition: { value: function compareDocumentPosition(that){\n // Basic algorithm for finding the relative position of two nodes.\n // Make a list the ancestors of each node, starting with the\n // document element and proceeding down to the nodes themselves.\n // Then, loop through the lists, looking for the first element\n // that differs. The order of those two elements give the\n // order of their descendant nodes. Or, if one list is a prefix\n // of the other one, then that node contains the other.\n\n if (this === that) return 0;\n\n // If they're not owned by the same document or if one is rooted\n // and one is not, then they're disconnected.\n if (this.doc !== that.doc ||\n this.rooted !== that.rooted)\n return (DOCUMENT_POSITION_DISCONNECTED +\n DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);\n\n // Get arrays of ancestors for this and that\n var these = [], those = [];\n for(var n = this; n !== null; n = n.parentNode) these.push(n);\n for(n = that; n !== null; n = n.parentNode) those.push(n);\n these.reverse(); // So we start with the outermost\n those.reverse();\n\n if (these[0] !== those[0]) // No common ancestor\n return (DOCUMENT_POSITION_DISCONNECTED +\n DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);\n\n n = Math.min(these.length, those.length);\n for(var i = 1; i < n; i++) {\n if (these[i] !== those[i]) {\n // We found two different ancestors, so compare\n // their positions\n if (these[i].index < those[i].index)\n return DOCUMENT_POSITION_FOLLOWING;\n else\n return DOCUMENT_POSITION_PRECEDING;\n }\n }\n\n // If we get to here, then one of the nodes (the one with the\n // shorter list of ancestors) contains the other one.\n if (these.length < those.length)\n return (DOCUMENT_POSITION_FOLLOWING +\n DOCUMENT_POSITION_CONTAINED_BY);\n else\n return (DOCUMENT_POSITION_PRECEDING +\n DOCUMENT_POSITION_CONTAINS);\n }},\n\n isSameNode: {value : function isSameNode(node) {\n return this === node;\n }},\n\n\n // This method implements the generic parts of node equality testing\n // and defers to the (non-recursive) type-specific isEqual() method\n // defined by subclasses\n isEqualNode: { value: function isEqualNode(node) {\n if (!node) return false;\n if (node.nodeType !== this.nodeType) return false;\n\n // Check type-specific properties for equality\n if (!this.isEqual(node)) return false;\n\n // Now check children for number and equality\n for (var c1 = this.firstChild, c2 = node.firstChild;\n c1 && c2;\n c1 = c1.nextSibling, c2 = c2.nextSibling) {\n if (!c1.isEqualNode(c2)) return false;\n }\n return c1 === null && c2 === null;\n }},\n\n // This method delegates shallow cloning to a clone() method\n // that each concrete subclass must implement\n cloneNode: { value: function(deep) {\n // Clone this node\n var clone = this.clone();\n\n // Handle the recursive case if necessary\n if (deep) {\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n clone._appendChild(kid.cloneNode(true));\n }\n }\n\n return clone;\n }},\n\n lookupPrefix: { value: function lookupPrefix(ns) {\n var e;\n if (ns === '' || ns === null || ns === undefined) return null;\n switch(this.nodeType) {\n case ELEMENT_NODE:\n return this._lookupNamespacePrefix(ns, this);\n case DOCUMENT_NODE:\n e = this.documentElement;\n return e ? e.lookupPrefix(ns) : null;\n case ENTITY_NODE:\n case NOTATION_NODE:\n case DOCUMENT_FRAGMENT_NODE:\n case DOCUMENT_TYPE_NODE:\n return null;\n case ATTRIBUTE_NODE:\n e = this.ownerElement;\n return e ? e.lookupPrefix(ns) : null;\n default:\n e = this.parentElement;\n return e ? e.lookupPrefix(ns) : null;\n }\n }},\n\n\n lookupNamespaceURI: {value: function lookupNamespaceURI(prefix) {\n if (prefix === '' || prefix === undefined) { prefix = null; }\n var e;\n switch(this.nodeType) {\n case ELEMENT_NODE:\n return utils.shouldOverride();\n case DOCUMENT_NODE:\n e = this.documentElement;\n return e ? e.lookupNamespaceURI(prefix) : null;\n case ENTITY_NODE:\n case NOTATION_NODE:\n case DOCUMENT_TYPE_NODE:\n case DOCUMENT_FRAGMENT_NODE:\n return null;\n case ATTRIBUTE_NODE:\n e = this.ownerElement;\n return e ? e.lookupNamespaceURI(prefix) : null;\n default:\n e = this.parentElement;\n return e ? e.lookupNamespaceURI(prefix) : null;\n }\n }},\n\n isDefaultNamespace: { value: function isDefaultNamespace(ns) {\n if (ns === '' || ns === undefined) { ns = null; }\n var defaultNamespace = this.lookupNamespaceURI(null);\n return (defaultNamespace === ns);\n }},\n\n // Utility methods for nodes. Not part of the DOM\n\n // Return the index of this node in its parent.\n // Throw if no parent, or if this node is not a child of its parent\n index: { get: function() {\n var parent = this.parentNode;\n if (this === parent.firstChild) return 0; // fast case\n var kids = parent.childNodes;\n if (this._index === undefined || kids[this._index] !== this) {\n // Ensure that we don't have an O(N^2) blowup if none of the\n // kids have defined indices yet and we're traversing via\n // nextSibling or previousSibling\n for (var i=0; i 2 ? spliceArgs[2] : null);\n } else if (len > 2 && n !== null) {\n LinkedList.insertBefore(spliceArgs[2], n);\n }\n if (parent._childNodes) {\n spliceArgs[0] = (before === null) ?\n parent._childNodes.length : before._index;\n parent._childNodes.splice.apply(parent._childNodes, spliceArgs);\n for (i=2; i 2) {\n parent._firstChild = spliceArgs[2];\n } else if (isReplace) {\n parent._firstChild = null;\n }\n }\n // Remove all nodes from the document fragment\n if (child._childNodes) {\n child._childNodes.length = 0;\n } else {\n child._firstChild = null;\n }\n // Call the mutation handlers\n // Use spliceArgs since the original array has been destroyed. The\n // liveness guarantee requires us to clone the array so that\n // references to the childNodes of the DocumentFragment will be empty\n // when the insertion handlers are called.\n if (parent.rooted) {\n parent.modify();\n for (i = 2; i < len; i++) {\n parent.doc.mutateInsert(spliceArgs[i]);\n }\n }\n } else {\n if (before === child) { return; }\n if (bothRooted) {\n // Remove the child from its current position in the tree\n // without calling remove(), since we don't want to uproot it.\n child._remove();\n } else if (child.parentNode) {\n child.remove();\n }\n\n // Insert it as a child of its new parent\n child.parentNode = parent;\n if (isReplace) {\n LinkedList.replace(n, child);\n if (parent._childNodes) {\n child._index = before_index;\n parent._childNodes[before_index] = child;\n } else if (parent._firstChild === before) {\n parent._firstChild = child;\n }\n } else {\n if (n !== null) {\n LinkedList.insertBefore(child, n);\n }\n if (parent._childNodes) {\n child._index = before_index;\n parent._childNodes.splice(before_index, 0, child);\n } else if (parent._firstChild === before) {\n parent._firstChild = child;\n }\n }\n if (bothRooted) {\n parent.modify();\n // Generate a move mutation event\n parent.doc.mutateMove(child);\n } else if (parent.rooted) {\n parent.modify();\n parent.doc.mutateInsert(child);\n }\n }\n }},\n\n\n // Return the lastModTime value for this node. (For use as a\n // cache invalidation mechanism. If the node does not already\n // have one, initialize it from the owner document's modclock\n // property. (Note that modclock does not return the actual\n // time; it is simply a counter incremented on each document\n // modification)\n lastModTime: { get: function() {\n if (!this._lastModTime) {\n this._lastModTime = this.doc.modclock;\n }\n return this._lastModTime;\n }},\n\n // Increment the owner document's modclock and use the new\n // value to update the lastModTime value for this node and\n // all of its ancestors. Nodes that have never had their\n // lastModTime value queried do not need to have a\n // lastModTime property set on them since there is no\n // previously queried value to ever compare the new value\n // against, so only update nodes that already have a\n // _lastModTime property.\n modify: { value: function() {\n if (this.doc.modclock) { // Skip while doc.modclock == 0\n var time = ++this.doc.modclock;\n for(var n = this; n; n = n.parentElement) {\n if (n._lastModTime) {\n n._lastModTime = time;\n }\n }\n }\n }},\n\n // This attribute is not part of the DOM but is quite helpful.\n // It returns the document with which a node is associated. Usually\n // this is the ownerDocument. But ownerDocument is null for the\n // document object itself, so this is a handy way to get the document\n // regardless of the node type\n doc: { get: function() {\n return this.ownerDocument || this;\n }},\n\n\n // If the node has a nid (node id), then it is rooted in a document\n rooted: { get: function() {\n return !!this._nid;\n }},\n\n normalize: { value: function() {\n var next;\n for (var child=this.firstChild; child !== null; child=next) {\n next = child.nextSibling;\n\n if (child.normalize) {\n child.normalize();\n }\n\n if (child.nodeType !== Node.TEXT_NODE) {\n continue;\n }\n\n if (child.nodeValue === \"\") {\n this.removeChild(child);\n continue;\n }\n\n var prevChild = child.previousSibling;\n if (prevChild === null) {\n continue;\n } else if (prevChild.nodeType === Node.TEXT_NODE) {\n // merge this with previous and remove the child\n prevChild.appendData(child.nodeValue);\n this.removeChild(child);\n }\n }\n }},\n\n // Convert the children of a node to an HTML string.\n // This is used by the innerHTML getter\n // The serialization spec is at:\n // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments\n //\n // The serialization logic is intentionally implemented in a separate\n // `NodeUtils` helper instead of the more obvious choice of a private\n // `_serializeOne()` method on the `Node.prototype` in order to avoid\n // the megamorphic `this._serializeOne` property access, which reduces\n // performance unnecessarily. If you need specialized behavior for a\n // certain subclass, you'll need to implement that in `NodeUtils`.\n // See https://github.com/fgnass/domino/pull/142 for more information.\n serialize: { value: function() {\n if (this._innerHTML) {\n return this._innerHTML;\n }\n var s = '';\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n s += NodeUtils.serializeOne(kid, this);\n }\n return s;\n }},\n\n // Non-standard, but often useful for debugging.\n outerHTML: {\n get: function() {\n return NodeUtils.serializeOne(this, { nodeType: 0 });\n },\n set: utils.nyi,\n },\n\n // mirror node type properties in the prototype, so they are present\n // in instances of Node (and subclasses)\n ELEMENT_NODE: { value: ELEMENT_NODE },\n ATTRIBUTE_NODE: { value: ATTRIBUTE_NODE },\n TEXT_NODE: { value: TEXT_NODE },\n CDATA_SECTION_NODE: { value: CDATA_SECTION_NODE },\n ENTITY_REFERENCE_NODE: { value: ENTITY_REFERENCE_NODE },\n ENTITY_NODE: { value: ENTITY_NODE },\n PROCESSING_INSTRUCTION_NODE: { value: PROCESSING_INSTRUCTION_NODE },\n COMMENT_NODE: { value: COMMENT_NODE },\n DOCUMENT_NODE: { value: DOCUMENT_NODE },\n DOCUMENT_TYPE_NODE: { value: DOCUMENT_TYPE_NODE },\n DOCUMENT_FRAGMENT_NODE: { value: DOCUMENT_FRAGMENT_NODE },\n NOTATION_NODE: { value: NOTATION_NODE },\n\n DOCUMENT_POSITION_DISCONNECTED: { value: DOCUMENT_POSITION_DISCONNECTED },\n DOCUMENT_POSITION_PRECEDING: { value: DOCUMENT_POSITION_PRECEDING },\n DOCUMENT_POSITION_FOLLOWING: { value: DOCUMENT_POSITION_FOLLOWING },\n DOCUMENT_POSITION_CONTAINS: { value: DOCUMENT_POSITION_CONTAINS },\n DOCUMENT_POSITION_CONTAINED_BY: { value: DOCUMENT_POSITION_CONTAINED_BY },\n DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: { value: DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC },\n});\n","/* jshint esversion: 6 */\n\"use strict\";\n\nmodule.exports = class NodeList extends Array {\n constructor(a) {\n super((a && a.length) || 0);\n if (a) {\n for (var idx in a) { this[idx] = a[idx]; }\n }\n }\n item(i) { return this[i] || null; }\n};\n","\"use strict\";\n\n// No support for subclassing array, return an actual Array object.\nfunction item(i) {\n /* jshint validthis: true */\n return this[i] || null;\n}\n\nfunction NodeList(a) {\n if (!a) a = [];\n a.item = item;\n return a;\n}\n\nmodule.exports = NodeList;\n","\"use strict\";\n\nvar NodeList;\n\ntry {\n // Attempt to use ES6-style Array subclass if possible.\n NodeList = require('./NodeList.es6.js');\n} catch (e) {\n // No support for subclassing array, return an actual Array object.\n NodeList = require('./NodeList.es5.js');\n}\n\nmodule.exports = NodeList;\n","\"use strict\";\nmodule.exports = ContainerNode;\n\nvar Node = require('./Node');\nvar NodeList = require('./NodeList');\n\n// This class defines common functionality for node subtypes that\n// can have children\n\nfunction ContainerNode() {\n Node.call(this);\n this._firstChild = this._childNodes = null;\n}\n\n// Primary representation is a circular linked list of siblings\nContainerNode.prototype = Object.create(Node.prototype, {\n\n hasChildNodes: { value: function() {\n if (this._childNodes) {\n return this._childNodes.length > 0;\n }\n return this._firstChild !== null;\n }},\n\n childNodes: { get: function() {\n this._ensureChildNodes();\n return this._childNodes;\n }},\n\n firstChild: { get: function() {\n if (this._childNodes) {\n return this._childNodes.length === 0 ? null : this._childNodes[0];\n }\n return this._firstChild;\n }},\n\n lastChild: { get: function() {\n var kids = this._childNodes, first;\n if (kids) {\n return kids.length === 0 ? null: kids[kids.length-1];\n }\n first = this._firstChild;\n if (first === null) { return null; }\n return first._previousSibling; // circular linked list\n }},\n\n _ensureChildNodes: { value: function() {\n if (this._childNodes) { return; }\n var first = this._firstChild,\n kid = first,\n childNodes = this._childNodes = new NodeList();\n if (first) do {\n childNodes.push(kid);\n kid = kid._nextSibling;\n } while (kid !== first); // circular linked list\n this._firstChild = null; // free memory\n }},\n\n // Remove all of this node's children. This is a minor\n // optimization that only calls modify() once.\n removeChildren: { value: function removeChildren() {\n var root = this.rooted ? this.ownerDocument : null,\n next = this.firstChild,\n kid;\n while (next !== null) {\n kid = next;\n next = kid.nextSibling;\n\n if (root) root.mutateRemove(kid);\n kid.parentNode = null;\n }\n if (this._childNodes) {\n this._childNodes.length = 0;\n } else {\n this._firstChild = null;\n }\n this.modify(); // Update last modified type once only\n }},\n\n});\n","\"use strict\";\n// This grammar is from the XML and XML Namespace specs. It specifies whether\n// a string (such as an element or attribute name) is a valid Name or QName.\n//\n// Name ::= NameStartChar (NameChar)*\n// NameStartChar ::= \":\" | [A-Z] | \"_\" | [a-z] |\n// [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] |\n// [#x370-#x37D] | [#x37F-#x1FFF] |\n// [#x200C-#x200D] | [#x2070-#x218F] |\n// [#x2C00-#x2FEF] | [#x3001-#xD7FF] |\n// [#xF900-#xFDCF] | [#xFDF0-#xFFFD] |\n// [#x10000-#xEFFFF]\n//\n// NameChar ::= NameStartChar | \"-\" | \".\" | [0-9] |\n// #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n//\n// QName ::= PrefixedName| UnprefixedName\n// PrefixedName ::= Prefix ':' LocalPart\n// UnprefixedName ::= LocalPart\n// Prefix ::= NCName\n// LocalPart ::= NCName\n// NCName ::= Name - (Char* ':' Char*)\n// # An XML Name, minus the \":\"\n//\n\nexports.isValidName = isValidName;\nexports.isValidQName = isValidQName;\n\n// Most names will be ASCII only. Try matching against simple regexps first\nvar simplename = /^[_:A-Za-z][-.:\\w]+$/;\nvar simpleqname = /^([_A-Za-z][-.\\w]+|[_A-Za-z][-.\\w]+:[_A-Za-z][-.\\w]+)$/;\n\n// If the regular expressions above fail, try more complex ones that work\n// for any identifiers using codepoints from the Unicode BMP\nvar ncnamestartchars = \"_A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\";\nvar ncnamechars = \"-._A-Za-z0-9\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0300-\\u037D\\u037F-\\u1FFF\\u200C\\u200D\\u203f\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\";\n\nvar ncname = \"[\" + ncnamestartchars + \"][\" + ncnamechars + \"]*\";\nvar namestartchars = ncnamestartchars + \":\";\nvar namechars = ncnamechars + \":\";\nvar name = new RegExp(\"^[\" + namestartchars + \"]\" + \"[\" + namechars + \"]*$\");\nvar qname = new RegExp(\"^(\" + ncname + \"|\" + ncname + \":\" + ncname + \")$\");\n\n// XML says that these characters are also legal:\n// [#x10000-#xEFFFF]. So if the patterns above fail, and the\n// target string includes surrogates, then try the following\n// patterns that allow surrogates and then run an extra validation\n// step to make sure that the surrogates are in valid pairs and in\n// the right range. Note that since the characters \\uf0000 to \\u1f0000\n// are not allowed, it means that the high surrogate can only go up to\n// \\uDB7f instead of \\uDBFF.\nvar hassurrogates = /[\\uD800-\\uDB7F\\uDC00-\\uDFFF]/;\nvar surrogatechars = /[\\uD800-\\uDB7F\\uDC00-\\uDFFF]/g;\nvar surrogatepairs = /[\\uD800-\\uDB7F][\\uDC00-\\uDFFF]/g;\n\n// Modify the variables above to allow surrogates\nncnamestartchars += \"\\uD800-\\uDB7F\\uDC00-\\uDFFF\";\nncnamechars += \"\\uD800-\\uDB7F\\uDC00-\\uDFFF\";\nncname = \"[\" + ncnamestartchars + \"][\" + ncnamechars + \"]*\";\nnamestartchars = ncnamestartchars + \":\";\nnamechars = ncnamechars + \":\";\n\n// Build another set of regexps that include surrogates\nvar surrogatename = new RegExp(\"^[\" + namestartchars + \"]\" + \"[\" + namechars + \"]*$\");\nvar surrogateqname = new RegExp(\"^(\" + ncname + \"|\" + ncname + \":\" + ncname + \")$\");\n\nfunction isValidName(s) {\n if (simplename.test(s)) return true; // Plain ASCII\n if (name.test(s)) return true; // Unicode BMP\n\n // Maybe the tests above failed because s includes surrogate pairs\n // Most likely, though, they failed for some more basic syntax problem\n if (!hassurrogates.test(s)) return false;\n\n // Is the string a valid name if we allow surrogates?\n if (!surrogatename.test(s)) return false;\n\n // Finally, are the surrogates all correctly paired up?\n var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs);\n return pairs !== null && 2*pairs.length === chars.length;\n}\n\nfunction isValidQName(s) {\n if (simpleqname.test(s)) return true; // Plain ASCII\n if (qname.test(s)) return true; // Unicode BMP\n\n if (!hassurrogates.test(s)) return false;\n if (!surrogateqname.test(s)) return false;\n var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs);\n return pairs !== null && 2*pairs.length === chars.length;\n}\n","\"use strict\";\nvar utils = require('./utils');\n\nexports.property = function(attr) {\n if (Array.isArray(attr.type)) {\n var valid = Object.create(null);\n attr.type.forEach(function(val) {\n valid[val.value || val] = val.alias || val;\n });\n var missingValueDefault = attr.missing;\n if (missingValueDefault===undefined) { missingValueDefault = null; }\n var invalidValueDefault = attr.invalid;\n if (invalidValueDefault===undefined) { invalidValueDefault = missingValueDefault; }\n return {\n get: function() {\n var v = this._getattr(attr.name);\n if (v === null) return missingValueDefault;\n\n v = valid[v.toLowerCase()];\n if (v !== undefined) return v;\n if (invalidValueDefault !== null) return invalidValueDefault;\n return v;\n },\n set: function(v) {\n this._setattr(attr.name, v);\n }\n };\n }\n else if (attr.type === Boolean) {\n return {\n get: function() {\n return this.hasAttribute(attr.name);\n },\n set: function(v) {\n if (v) {\n this._setattr(attr.name, '');\n }\n else {\n this.removeAttribute(attr.name);\n }\n }\n };\n }\n else if (attr.type === Number ||\n attr.type === \"long\" ||\n attr.type === \"unsigned long\" ||\n attr.type === \"limited unsigned long with fallback\") {\n return numberPropDesc(attr);\n }\n else if (!attr.type || attr.type === String) {\n return {\n get: function() { return this._getattr(attr.name) || ''; },\n set: function(v) {\n if (attr.treatNullAsEmptyString && v === null) { v = ''; }\n this._setattr(attr.name, v);\n }\n };\n }\n else if (typeof attr.type === 'function') {\n return attr.type(attr.name, attr);\n }\n throw new Error('Invalid attribute definition');\n};\n\n// See http://www.whatwg.org/specs/web-apps/current-work/#reflect\n//\n// defval is the default value. If it is a function, then that function\n// will be invoked as a method of the element to obtain the default.\n// If no default is specified for a given attribute, then the default\n// depends on the type of the attribute, but since this function handles\n// 4 integer cases, you must specify the default value in each call\n//\n// min and max define a valid range for getting the attribute.\n//\n// setmin defines a minimum value when setting. If the value is less\n// than that, then throw INDEX_SIZE_ERR.\n//\n// Conveniently, JavaScript's parseInt function appears to be\n// compatible with HTML's 'rules for parsing integers'\nfunction numberPropDesc(a) {\n var def;\n if(typeof a.default === 'function') {\n def = a.default;\n }\n else if(typeof a.default === 'number') {\n def = function() { return a.default; };\n }\n else {\n def = function() { utils.assert(false, typeof a.default); };\n }\n var unsigned_long = (a.type === 'unsigned long');\n var signed_long = (a.type === 'long');\n var unsigned_fallback = (a.type === 'limited unsigned long with fallback');\n var min = a.min, max = a.max, setmin = a.setmin;\n if (min === undefined) {\n if (unsigned_long) min = 0;\n if (signed_long) min = -0x80000000;\n if (unsigned_fallback) min = 1;\n }\n if (max === undefined) {\n if (unsigned_long || signed_long || unsigned_fallback) max = 0x7FFFFFFF;\n }\n\n return {\n get: function() {\n var v = this._getattr(a.name);\n var n = a.float ? parseFloat(v) : parseInt(v, 10);\n if (v === null || !isFinite(n) || (min !== undefined && n < min) || (max !== undefined && n > max)) {\n return def.call(this);\n }\n if (unsigned_long || signed_long || unsigned_fallback) {\n if (!/^[ \\t\\n\\f\\r]*[-+]?[0-9]/.test(v)) { return def.call(this); }\n n = n|0; // jshint ignore:line\n }\n return n;\n },\n set: function(v) {\n if (!a.float) { v = Math.floor(v); }\n if (setmin !== undefined && v < setmin) {\n utils.IndexSizeError(a.name + ' set to ' + v);\n }\n if (unsigned_long) {\n v = (v < 0 || v > 0x7FFFFFFF) ? def.call(this) :\n (v|0); // jshint ignore:line\n } else if (unsigned_fallback) {\n v = (v < 1 || v > 0x7FFFFFFF) ? def.call(this) :\n (v|0); // jshint ignore:line\n } else if (signed_long) {\n v = (v < -0x80000000 || v > 0x7FFFFFFF) ? def.call(this) :\n (v|0); // jshint ignore:line\n }\n this._setattr(a.name, String(v));\n }\n };\n}\n\n// This is a utility function for setting up change handler functions\n// for attributes like 'id' that require special handling when they change.\nexports.registerChangeHandler = function(c, name, handler) {\n var p = c.prototype;\n\n // If p does not already have its own _attributeChangeHandlers\n // then create one for it, inheriting from the inherited\n // _attributeChangeHandlers. At the top (for the Element class) the\n // _attributeChangeHandlers object will be created with a null prototype.\n if (!Object.prototype.hasOwnProperty.call(p, '_attributeChangeHandlers')) {\n p._attributeChangeHandlers =\n Object.create(p._attributeChangeHandlers || null);\n }\n\n p._attributeChangeHandlers[name] = handler;\n};\n","\"use strict\";\nmodule.exports = FilteredElementList;\n\nvar Node = require('./Node');\n\n//\n// This file defines node list implementation that lazily traverses\n// the document tree (or a subtree rooted at any element) and includes\n// only those elements for which a specified filter function returns true.\n// It is used to implement the\n// {Document,Element}.getElementsBy{TagName,ClassName}{,NS} methods.\n//\n// XXX this should inherit from NodeList\n\nfunction FilteredElementList(root, filter) {\n this.root = root;\n this.filter = filter;\n this.lastModTime = root.lastModTime;\n this.done = false;\n this.cache = [];\n this.traverse();\n}\n\nFilteredElementList.prototype = Object.create(Object.prototype, {\n length: { get: function() {\n this.checkcache();\n if (!this.done) this.traverse();\n return this.cache.length;\n } },\n\n item: { value: function(n) {\n this.checkcache();\n if (!this.done && n >= this.cache.length) {\n // This can lead to O(N^2) behavior if we stop when we get to n\n // and the caller is iterating through the items in order; so\n // be sure to do the full traverse here.\n this.traverse(/*n*/);\n }\n return this.cache[n];\n } },\n\n checkcache: { value: function() {\n if (this.lastModTime !== this.root.lastModTime) {\n // subtree has changed, so invalidate cache\n for (var i = this.cache.length-1; i>=0; i--) {\n this[i] = undefined;\n }\n this.cache.length = 0;\n this.done = false;\n this.lastModTime = this.root.lastModTime;\n }\n } },\n\n // If n is specified, then traverse the tree until we've found the nth\n // item (or until we've found all items). If n is not specified,\n // traverse until we've found all items.\n traverse: { value: function(n) {\n // increment n so we can compare to length, and so it is never falsy\n if (n !== undefined) n++;\n\n var elt;\n while ((elt = this.next()) !== null) {\n this[this.cache.length] = elt; //XXX Use proxy instead\n this.cache.push(elt);\n if (n && this.cache.length === n) return;\n }\n\n // no next element, so we've found everything\n this.done = true;\n } },\n\n // Return the next element under root that matches filter\n next: { value: function() {\n var start = (this.cache.length === 0) ? this.root // Start at the root or at\n : this.cache[this.cache.length-1]; // the last element we found\n\n var elt;\n if (start.nodeType === Node.DOCUMENT_NODE)\n elt = start.documentElement;\n else\n elt = start.nextElement(this.root);\n\n while(elt) {\n if (this.filter(elt)) {\n return elt;\n }\n\n elt = elt.nextElement(this.root);\n }\n return null;\n } },\n});\n","\"use strict\";\n// DOMTokenList implementation based on https://github.com/Raynos/DOM-shim\nvar utils = require('./utils');\n\nmodule.exports = DOMTokenList;\n\nfunction DOMTokenList(getter, setter) {\n this._getString = getter;\n this._setString = setter;\n this._length = 0;\n this._lastStringValue = '';\n this._update();\n}\n\nObject.defineProperties(DOMTokenList.prototype, {\n length: { get: function() { return this._length; } },\n item: { value: function(index) {\n var list = getList(this);\n if (index < 0 || index >= list.length) {\n return null;\n }\n return list[index];\n }},\n\n contains: { value: function(token) {\n token = String(token); // no error checking for contains()\n var list = getList(this);\n return list.indexOf(token) > -1;\n }},\n\n add: { value: function() {\n var list = getList(this);\n for (var i = 0, len = arguments.length; i < len; i++) {\n var token = handleErrors(arguments[i]);\n if (list.indexOf(token) < 0) {\n list.push(token);\n }\n }\n // Note: as per spec, if handleErrors() throws any errors, we never\n // make it here and none of the changes take effect.\n // Also per spec: we run the \"update steps\" even if no change was\n // made (ie, if the token already existed)\n this._update(list);\n }},\n\n remove: { value: function() {\n var list = getList(this);\n for (var i = 0, len = arguments.length; i < len; i++) {\n var token = handleErrors(arguments[i]);\n var index = list.indexOf(token);\n if (index > -1) {\n list.splice(index, 1);\n }\n }\n // Note: as per spec, if handleErrors() throws any errors, we never\n // make it here and none of the changes take effect.\n // Also per spec: we run the \"update steps\" even if no change was\n // made (ie, if the token wasn't previously present)\n this._update(list);\n }},\n\n toggle: { value: function toggle(token, force) {\n token = handleErrors(token);\n if (this.contains(token)) {\n if (force === undefined || force === false) {\n this.remove(token);\n return false;\n }\n return true;\n } else {\n if (force === undefined || force === true) {\n this.add(token);\n return true;\n }\n return false;\n }\n }},\n\n replace: { value: function replace(token, newToken) {\n // weird corner case of spec: if `token` contains whitespace, but\n // `newToken` is the empty string, we must throw SyntaxError not\n // InvalidCharacterError (sigh)\n if (String(newToken)==='') { utils.SyntaxError(); }\n token = handleErrors(token);\n newToken = handleErrors(newToken);\n var list = getList(this);\n var idx = list.indexOf(token);\n if (idx < 0) {\n // Note that, per spec, we do not run the update steps on this path.\n return false;\n }\n var idx2 = list.indexOf(newToken);\n if (idx2 < 0) {\n list[idx] = newToken;\n } else {\n // \"replace the first instance of either `token` or `newToken` with\n // `newToken` and remove all other instances\"\n if (idx < idx2) {\n list[idx] = newToken;\n list.splice(idx2, 1);\n } else {\n // idx2 is already `newToken`\n list.splice(idx, 1);\n }\n }\n this._update(list);\n return true;\n }},\n\n toString: { value: function() {\n return this._getString();\n }},\n\n value: {\n get: function() {\n return this._getString();\n },\n set: function(v) {\n this._setString(v);\n this._update();\n }\n },\n\n // Called when the setter is called from outside this interface.\n _update: { value: function(list) {\n if (list) {\n fixIndex(this, list);\n this._setString(list.join(\" \").trim());\n } else {\n fixIndex(this, getList(this));\n }\n this._lastStringValue = this._getString();\n } },\n});\n\nfunction fixIndex(clist, list) {\n var oldLength = clist._length;\n var i;\n clist._length = list.length;\n for (i = 0; i < list.length; i++) {\n clist[i] = list[i];\n }\n // Clear/free old entries.\n for (; i < oldLength; i++) {\n clist[i] = undefined;\n }\n}\n\nfunction handleErrors(token) {\n token = String(token);\n if (token === \"\") {\n utils.SyntaxError();\n }\n if (/[ \\t\\r\\n\\f]/.test(token)) {\n utils.InvalidCharacterError();\n }\n return token;\n}\n\nfunction toArray(clist) {\n var length = clist._length;\n var arr = Array(length);\n for (var i = 0; i < length; i++) {\n arr[i] = clist[i];\n }\n return arr;\n}\n\nfunction getList(clist) {\n var strProp = clist._getString();\n if (strProp === clist._lastStringValue) {\n return toArray(clist);\n }\n var str = strProp.replace(/(^[ \\t\\r\\n\\f]+)|([ \\t\\r\\n\\f]+$)/g, '');\n if (str === \"\") {\n return [];\n } else {\n var seen = Object.create(null);\n return str.split(/[ \\t\\r\\n\\f]+/g).filter(function(n) {\n var key = '$' + n;\n if (seen[key]) { return false; }\n seen[key] = true;\n return true;\n });\n }\n}\n","\"use strict\";\n/* jshint eqnull: true */\n/**\n * Zest (https://github.com/chjj/zest)\n * A css selector engine.\n * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed)\n * Domino version based on Zest v0.1.3 with bugfixes applied.\n */\n\n/**\n * Helpers\n */\n\nvar window = Object.create(null, {\n location: { get: function() {\n throw new Error('window.location is not supported.');\n } }\n});\n\nvar compareDocumentPosition = function(a, b) {\n return a.compareDocumentPosition(b);\n};\n\nvar order = function(a, b) {\n /* jshint bitwise: false */\n return compareDocumentPosition(a, b) & 2 ? 1 : -1;\n};\n\nvar next = function(el) {\n while ((el = el.nextSibling)\n && el.nodeType !== 1);\n return el;\n};\n\nvar prev = function(el) {\n while ((el = el.previousSibling)\n && el.nodeType !== 1);\n return el;\n};\n\nvar child = function(el) {\n /*jshint -W084 */\n if (el = el.firstChild) {\n while (el.nodeType !== 1\n && (el = el.nextSibling));\n }\n return el;\n};\n\nvar lastChild = function(el) {\n /*jshint -W084 */\n if (el = el.lastChild) {\n while (el.nodeType !== 1\n && (el = el.previousSibling));\n }\n return el;\n};\n\nvar parentIsElement = function(n) {\n if (!n.parentNode) { return false; }\n var nodeType = n.parentNode.nodeType;\n // The root `html` element can be a first- or last-child, too.\n return nodeType === 1 || nodeType === 9;\n};\n\nvar unquote = function(str) {\n if (!str) return str;\n var ch = str[0];\n if (ch === '\"' || ch === '\\'') {\n if (str[str.length-1] === ch) {\n str = str.slice(1, -1);\n } else {\n // bad string.\n str = str.slice(1);\n }\n return str.replace(rules.str_escape, function(s) {\n var m = /^\\\\(?:([0-9A-Fa-f]+)|([\\r\\n\\f]+))/.exec(s);\n if (!m) { return s.slice(1); }\n if (m[2]) { return ''; /* escaped newlines are ignored in strings. */ }\n var cp = parseInt(m[1], 16);\n return String.fromCodePoint ? String.fromCodePoint(cp) :\n // Not all JavaScript implementations have String.fromCodePoint yet.\n String.fromCharCode(cp);\n });\n } else if (rules.ident.test(str)) {\n return decodeid(str);\n } else {\n // NUMBER, PERCENTAGE, DIMENSION, etc\n return str;\n }\n};\n\nvar decodeid = function(str) {\n return str.replace(rules.escape, function(s) {\n var m = /^\\\\([0-9A-Fa-f]+)/.exec(s);\n if (!m) { return s[1]; }\n var cp = parseInt(m[1], 16);\n return String.fromCodePoint ? String.fromCodePoint(cp) :\n // Not all JavaScript implementations have String.fromCodePoint yet.\n String.fromCharCode(cp);\n });\n};\n\nvar indexOf = (function() {\n if (Array.prototype.indexOf) {\n return Array.prototype.indexOf;\n }\n return function(obj, item) {\n var i = this.length;\n while (i--) {\n if (this[i] === item) return i;\n }\n return -1;\n };\n})();\n\nvar makeInside = function(start, end) {\n var regex = rules.inside.source\n .replace(//g, end);\n\n return new RegExp(regex);\n};\n\nvar replace = function(regex, name, val) {\n regex = regex.source;\n regex = regex.replace(name, val.source || val);\n return new RegExp(regex);\n};\n\nvar truncateUrl = function(url, num) {\n return url\n .replace(/^(?:\\w+:\\/\\/|\\/+)/, '')\n .replace(/(?:\\/+|\\/*#.*?)$/, '')\n .split('/', num)\n .join('/');\n};\n\n/**\n * Handle `nth` Selectors\n */\n\nvar parseNth = function(param_, test) {\n var param = param_.replace(/\\s+/g, '')\n , cap;\n\n if (param === 'even') {\n param = '2n+0';\n } else if (param === 'odd') {\n param = '2n+1';\n } else if (param.indexOf('n') === -1) {\n param = '0n' + param;\n }\n\n cap = /^([+-])?(\\d+)?n([+-])?(\\d+)?$/.exec(param);\n\n return {\n group: cap[1] === '-'\n ? -(cap[2] || 1)\n : +(cap[2] || 1),\n offset: cap[4]\n ? (cap[3] === '-' ? -cap[4] : +cap[4])\n : 0\n };\n};\n\nvar nth = function(param_, test, last) {\n var param = parseNth(param_)\n , group = param.group\n , offset = param.offset\n , find = !last ? child : lastChild\n , advance = !last ? next : prev;\n\n return function(el) {\n if (!parentIsElement(el)) return;\n\n var rel = find(el.parentNode)\n , pos = 0;\n\n while (rel) {\n if (test(rel, el)) pos++;\n if (rel === el) {\n pos -= offset;\n return group && pos\n ? (pos % group) === 0 && (pos < 0 === group < 0)\n : !pos;\n }\n rel = advance(rel);\n }\n };\n};\n\n/**\n * Simple Selectors\n */\n\nvar selectors = {\n '*': (function() {\n if (false/*function() {\n var el = document.createElement('div');\n el.appendChild(document.createComment(''));\n return !!el.getElementsByTagName('*')[0];\n }()*/) {\n return function(el) {\n if (el.nodeType === 1) return true;\n };\n }\n return function() {\n return true;\n };\n })(),\n 'type': function(type) {\n type = type.toLowerCase();\n return function(el) {\n return el.nodeName.toLowerCase() === type;\n };\n },\n 'attr': function(key, op, val, i) {\n op = operators[op];\n return function(el) {\n var attr;\n switch (key) {\n case 'for':\n attr = el.htmlFor;\n break;\n case 'class':\n // className is '' when non-existent\n // getAttribute('class') is null\n attr = el.className;\n if (attr === '' && el.getAttribute('class') == null) {\n attr = null;\n }\n break;\n case 'href':\n case 'src':\n attr = el.getAttribute(key, 2);\n break;\n case 'title':\n // getAttribute('title') can be '' when non-existent sometimes?\n attr = el.getAttribute('title') || null;\n break;\n // careful with attributes with special getter functions\n case 'id':\n case 'lang':\n case 'dir':\n case 'accessKey':\n case 'hidden':\n case 'tabIndex':\n case 'style':\n if (el.getAttribute) {\n attr = el.getAttribute(key);\n break;\n }\n /* falls through */\n default:\n if (el.hasAttribute && !el.hasAttribute(key)) {\n break;\n }\n attr = el[key] != null\n ? el[key]\n : el.getAttribute && el.getAttribute(key);\n break;\n }\n if (attr == null) return;\n attr = attr + '';\n if (i) {\n attr = attr.toLowerCase();\n val = val.toLowerCase();\n }\n return op(attr, val);\n };\n },\n ':first-child': function(el) {\n return !prev(el) && parentIsElement(el);\n },\n ':last-child': function(el) {\n return !next(el) && parentIsElement(el);\n },\n ':only-child': function(el) {\n return !prev(el) && !next(el) && parentIsElement(el);\n },\n ':nth-child': function(param, last) {\n return nth(param, function() {\n return true;\n }, last);\n },\n ':nth-last-child': function(param) {\n return selectors[':nth-child'](param, true);\n },\n ':root': function(el) {\n return el.ownerDocument.documentElement === el;\n },\n ':empty': function(el) {\n return !el.firstChild;\n },\n ':not': function(sel) {\n var test = compileGroup(sel);\n return function(el) {\n return !test(el);\n };\n },\n ':first-of-type': function(el) {\n if (!parentIsElement(el)) return;\n var type = el.nodeName;\n /*jshint -W084 */\n while (el = prev(el)) {\n if (el.nodeName === type) return;\n }\n return true;\n },\n ':last-of-type': function(el) {\n if (!parentIsElement(el)) return;\n var type = el.nodeName;\n /*jshint -W084 */\n while (el = next(el)) {\n if (el.nodeName === type) return;\n }\n return true;\n },\n ':only-of-type': function(el) {\n return selectors[':first-of-type'](el)\n && selectors[':last-of-type'](el);\n },\n ':nth-of-type': function(param, last) {\n return nth(param, function(rel, el) {\n return rel.nodeName === el.nodeName;\n }, last);\n },\n ':nth-last-of-type': function(param) {\n return selectors[':nth-of-type'](param, true);\n },\n ':checked': function(el) {\n return !!(el.checked || el.selected);\n },\n ':indeterminate': function(el) {\n return !selectors[':checked'](el);\n },\n ':enabled': function(el) {\n return !el.disabled && el.type !== 'hidden';\n },\n ':disabled': function(el) {\n return !!el.disabled;\n },\n ':target': function(el) {\n return el.id === window.location.hash.substring(1);\n },\n ':focus': function(el) {\n return el === el.ownerDocument.activeElement;\n },\n ':is': function(sel) {\n return compileGroup(sel);\n },\n // :matches is an older name for :is; see\n // https://github.com/w3c/csswg-drafts/issues/3258\n ':matches': function(sel) {\n return selectors[':is'](sel);\n },\n ':nth-match': function(param, last) {\n var args = param.split(/\\s*,\\s*/)\n , arg = args.shift()\n , test = compileGroup(args.join(','));\n\n return nth(arg, test, last);\n },\n ':nth-last-match': function(param) {\n return selectors[':nth-match'](param, true);\n },\n ':links-here': function(el) {\n return el + '' === window.location + '';\n },\n ':lang': function(param) {\n return function(el) {\n while (el) {\n if (el.lang) return el.lang.indexOf(param) === 0;\n el = el.parentNode;\n }\n };\n },\n ':dir': function(param) {\n return function(el) {\n while (el) {\n if (el.dir) return el.dir === param;\n el = el.parentNode;\n }\n };\n },\n ':scope': function(el, con) {\n var context = con || el.ownerDocument;\n if (context.nodeType === 9) {\n return el === context.documentElement;\n }\n return el === context;\n },\n ':any-link': function(el) {\n return typeof el.href === 'string';\n },\n ':local-link': function(el) {\n if (el.nodeName) {\n return el.href && el.host === window.location.host;\n }\n var param = +el + 1;\n return function(el) {\n if (!el.href) return;\n\n var url = window.location + ''\n , href = el + '';\n\n return truncateUrl(url, param) === truncateUrl(href, param);\n };\n },\n ':default': function(el) {\n return !!el.defaultSelected;\n },\n ':valid': function(el) {\n return el.willValidate || (el.validity && el.validity.valid);\n },\n ':invalid': function(el) {\n return !selectors[':valid'](el);\n },\n ':in-range': function(el) {\n return el.value > el.min && el.value <= el.max;\n },\n ':out-of-range': function(el) {\n return !selectors[':in-range'](el);\n },\n ':required': function(el) {\n return !!el.required;\n },\n ':optional': function(el) {\n return !el.required;\n },\n ':read-only': function(el) {\n if (el.readOnly) return true;\n\n var attr = el.getAttribute('contenteditable')\n , prop = el.contentEditable\n , name = el.nodeName.toLowerCase();\n\n name = name !== 'input' && name !== 'textarea';\n\n return (name || el.disabled) && attr == null && prop !== 'true';\n },\n ':read-write': function(el) {\n return !selectors[':read-only'](el);\n },\n ':hover': function() {\n throw new Error(':hover is not supported.');\n },\n ':active': function() {\n throw new Error(':active is not supported.');\n },\n ':link': function() {\n throw new Error(':link is not supported.');\n },\n ':visited': function() {\n throw new Error(':visited is not supported.');\n },\n ':column': function() {\n throw new Error(':column is not supported.');\n },\n ':nth-column': function() {\n throw new Error(':nth-column is not supported.');\n },\n ':nth-last-column': function() {\n throw new Error(':nth-last-column is not supported.');\n },\n ':current': function() {\n throw new Error(':current is not supported.');\n },\n ':past': function() {\n throw new Error(':past is not supported.');\n },\n ':future': function() {\n throw new Error(':future is not supported.');\n },\n // Non-standard, for compatibility purposes.\n ':contains': function(param) {\n return function(el) {\n var text = el.innerText || el.textContent || el.value || '';\n return text.indexOf(param) !== -1;\n };\n },\n ':has': function(param) {\n return function(el) {\n return find(param, el).length > 0;\n };\n }\n // Potentially add more pseudo selectors for\n // compatibility with sizzle and most other\n // selector engines (?).\n};\n\n/**\n * Attribute Operators\n */\n\nvar operators = {\n '-': function() {\n return true;\n },\n '=': function(attr, val) {\n return attr === val;\n },\n '*=': function(attr, val) {\n return attr.indexOf(val) !== -1;\n },\n '~=': function(attr, val) {\n var i\n , s\n , f\n , l;\n\n for (s = 0; true; s = i + 1) {\n i = attr.indexOf(val, s);\n if (i === -1) return false;\n f = attr[i - 1];\n l = attr[i + val.length];\n if ((!f || f === ' ') && (!l || l === ' ')) return true;\n }\n },\n '|=': function(attr, val) {\n var i = attr.indexOf(val)\n , l;\n\n if (i !== 0) return;\n l = attr[i + val.length];\n\n return l === '-' || !l;\n },\n '^=': function(attr, val) {\n return attr.indexOf(val) === 0;\n },\n '$=': function(attr, val) {\n var i = attr.lastIndexOf(val);\n return i !== -1 && i + val.length === attr.length;\n },\n // non-standard\n '!=': function(attr, val) {\n return attr !== val;\n }\n};\n\n/**\n * Combinator Logic\n */\n\nvar combinators = {\n ' ': function(test) {\n return function(el) {\n /*jshint -W084 */\n while (el = el.parentNode) {\n if (test(el)) return el;\n }\n };\n },\n '>': function(test) {\n return function(el) {\n /*jshint -W084 */\n if (el = el.parentNode) {\n return test(el) && el;\n }\n };\n },\n '+': function(test) {\n return function(el) {\n /*jshint -W084 */\n if (el = prev(el)) {\n return test(el) && el;\n }\n };\n },\n '~': function(test) {\n return function(el) {\n /*jshint -W084 */\n while (el = prev(el)) {\n if (test(el)) return el;\n }\n };\n },\n 'noop': function(test) {\n return function(el) {\n return test(el) && el;\n };\n },\n 'ref': function(test, name) {\n var node;\n\n function ref(el) {\n var doc = el.ownerDocument\n , nodes = doc.getElementsByTagName('*')\n , i = nodes.length;\n\n while (i--) {\n node = nodes[i];\n if (ref.test(el)) {\n node = null;\n return true;\n }\n }\n\n node = null;\n }\n\n ref.combinator = function(el) {\n if (!node || !node.getAttribute) return;\n\n var attr = node.getAttribute(name) || '';\n if (attr[0] === '#') attr = attr.substring(1);\n\n if (attr === el.id && test(node)) {\n return node;\n }\n };\n\n return ref;\n }\n};\n\n/**\n * Grammar\n */\n\nvar rules = {\n escape: /\\\\(?:[^0-9A-Fa-f\\r\\n]|[0-9A-Fa-f]{1,6}[\\r\\n\\t ]?)/g,\n str_escape: /(escape)|\\\\(\\n|\\r\\n?|\\f)/g,\n nonascii: /[\\u00A0-\\uFFFF]/,\n cssid: /(?:(?!-?[0-9])(?:escape|nonascii|[-_a-zA-Z0-9])+)/,\n qname: /^ *(cssid|\\*)/,\n simple: /^(?:([.#]cssid)|pseudo|attr)/,\n ref: /^ *\\/(cssid)\\/ */,\n combinator: /^(?: +([^ \\w*.#\\\\]) +|( )+|([^ \\w*.#\\\\]))(?! *$)/,\n attr: /^\\[(cssid)(?:([^\\w]?=)(inside))?\\]/,\n pseudo: /^(:cssid)(?:\\((inside)\\))?/,\n inside: /(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'|<[^\"'>]*>|\\\\[\"'>]|[^\"'>])*/,\n ident: /^(cssid)$/\n};\n\nrules.cssid = replace(rules.cssid, 'nonascii', rules.nonascii);\nrules.cssid = replace(rules.cssid, 'escape', rules.escape);\nrules.qname = replace(rules.qname, 'cssid', rules.cssid);\nrules.simple = replace(rules.simple, 'cssid', rules.cssid);\nrules.ref = replace(rules.ref, 'cssid', rules.cssid);\nrules.attr = replace(rules.attr, 'cssid', rules.cssid);\nrules.pseudo = replace(rules.pseudo, 'cssid', rules.cssid);\nrules.inside = replace(rules.inside, '[^\"\\'>]*', rules.inside);\nrules.attr = replace(rules.attr, 'inside', makeInside('\\\\[', '\\\\]'));\nrules.pseudo = replace(rules.pseudo, 'inside', makeInside('\\\\(', '\\\\)'));\nrules.simple = replace(rules.simple, 'pseudo', rules.pseudo);\nrules.simple = replace(rules.simple, 'attr', rules.attr);\nrules.ident = replace(rules.ident, 'cssid', rules.cssid);\nrules.str_escape = replace(rules.str_escape, 'escape', rules.escape);\n\n/**\n * Compiling\n */\n\nvar compile = function(sel_) {\n var sel = sel_.replace(/^\\s+|\\s+$/g, '')\n , test\n , filter = []\n , buff = []\n , subject\n , qname\n , cap\n , op\n , ref;\n\n /*jshint -W084 */\n while (sel) {\n if (cap = rules.qname.exec(sel)) {\n sel = sel.substring(cap[0].length);\n qname = decodeid(cap[1]);\n buff.push(tok(qname, true));\n } else if (cap = rules.simple.exec(sel)) {\n sel = sel.substring(cap[0].length);\n qname = '*';\n buff.push(tok(qname, true));\n buff.push(tok(cap));\n } else {\n throw new SyntaxError('Invalid selector.');\n }\n\n while (cap = rules.simple.exec(sel)) {\n sel = sel.substring(cap[0].length);\n buff.push(tok(cap));\n }\n\n if (sel[0] === '!') {\n sel = sel.substring(1);\n subject = makeSubject();\n subject.qname = qname;\n buff.push(subject.simple);\n }\n\n if (cap = rules.ref.exec(sel)) {\n sel = sel.substring(cap[0].length);\n ref = combinators.ref(makeSimple(buff), decodeid(cap[1]));\n filter.push(ref.combinator);\n buff = [];\n continue;\n }\n\n if (cap = rules.combinator.exec(sel)) {\n sel = sel.substring(cap[0].length);\n op = cap[1] || cap[2] || cap[3];\n if (op === ',') {\n filter.push(combinators.noop(makeSimple(buff)));\n break;\n }\n } else {\n op = 'noop';\n }\n\n if (!combinators[op]) { throw new SyntaxError('Bad combinator.'); }\n filter.push(combinators[op](makeSimple(buff)));\n buff = [];\n }\n\n test = makeTest(filter);\n test.qname = qname;\n test.sel = sel;\n\n if (subject) {\n subject.lname = test.qname;\n\n subject.test = test;\n subject.qname = subject.qname;\n subject.sel = test.sel;\n test = subject;\n }\n\n if (ref) {\n ref.test = test;\n ref.qname = test.qname;\n ref.sel = test.sel;\n test = ref;\n }\n\n return test;\n};\n\nvar tok = function(cap, qname) {\n // qname\n if (qname) {\n return cap === '*'\n ? selectors['*']\n : selectors.type(cap);\n }\n\n // class/id\n if (cap[1]) {\n return cap[1][0] === '.'\n\t // XXX unescape here? or in attr?\n ? selectors.attr('class', '~=', decodeid(cap[1].substring(1)), false)\n : selectors.attr('id', '=', decodeid(cap[1].substring(1)), false);\n }\n\n // pseudo-name\n // inside-pseudo\n if (cap[2]) {\n return cap[3]\n ? selectors[decodeid(cap[2])](unquote(cap[3]))\n : selectors[decodeid(cap[2])];\n }\n\n // attr name\n // attr op\n // attr value\n if (cap[4]) {\n var value = cap[6];\n var i = /[\"'\\s]\\s*I$/i.test(value);\n if (i) {\n value = value.replace(/\\s*I$/i, '');\n }\n return selectors.attr(decodeid(cap[4]), cap[5] || '-', unquote(value), i);\n }\n\n throw new SyntaxError('Unknown Selector.');\n};\n\nvar makeSimple = function(func) {\n var l = func.length\n , i;\n\n // Potentially make sure\n // `el` is truthy.\n if (l < 2) return func[0];\n\n return function(el) {\n if (!el) return;\n for (i = 0; i < l; i++) {\n if (!func[i](el)) return;\n }\n return true;\n };\n};\n\nvar makeTest = function(func) {\n if (func.length < 2) {\n return function(el) {\n return !!func[0](el);\n };\n }\n return function(el) {\n var i = func.length;\n while (i--) {\n if (!(el = func[i](el))) return;\n }\n return true;\n };\n};\n\nvar makeSubject = function() {\n var target;\n\n function subject(el) {\n var node = el.ownerDocument\n , scope = node.getElementsByTagName(subject.lname)\n , i = scope.length;\n\n while (i--) {\n if (subject.test(scope[i]) && target === el) {\n target = null;\n return true;\n }\n }\n\n target = null;\n }\n\n subject.simple = function(el) {\n target = el;\n return true;\n };\n\n return subject;\n};\n\nvar compileGroup = function(sel) {\n var test = compile(sel)\n , tests = [ test ];\n\n while (test.sel) {\n test = compile(test.sel);\n tests.push(test);\n }\n\n if (tests.length < 2) return test;\n\n return function(el) {\n var l = tests.length\n , i = 0;\n\n for (; i < l; i++) {\n if (tests[i](el)) return true;\n }\n };\n};\n\n/**\n * Selection\n */\n\nvar find = function(sel, node) {\n var results = []\n , test = compile(sel)\n , scope = node.getElementsByTagName(test.qname)\n , i = 0\n , el;\n\n /*jshint -W084 */\n while (el = scope[i++]) {\n if (test(el)) results.push(el);\n }\n\n if (test.sel) {\n while (test.sel) {\n test = compile(test.sel);\n scope = node.getElementsByTagName(test.qname);\n i = 0;\n /*jshint -W084 */\n while (el = scope[i++]) {\n if (test(el) && indexOf.call(results, el) === -1) {\n results.push(el);\n }\n }\n }\n results.sort(order);\n }\n\n return results;\n};\n\n/**\n * Expose\n */\n\nmodule.exports = exports = function(sel, context) {\n /* when context isn't a DocumentFragment and the selector is simple: */\n var id, r;\n if (context.nodeType !== 11 && sel.indexOf(' ') === -1) {\n if (sel[0] === '#' && context.rooted && /^#[A-Z_][-A-Z0-9_]*$/i.test(sel)) {\n if (context.doc._hasMultipleElementsWithId) {\n id = sel.substring(1);\n if (!context.doc._hasMultipleElementsWithId(id)) {\n r = context.doc.getElementById(id);\n return r ? [r] : [];\n }\n }\n }\n if (sel[0] === '.' && /^\\.\\w+$/.test(sel)) {\n return context.getElementsByClassName(sel.substring(1));\n }\n if (/^\\w+$/.test(sel)) {\n return context.getElementsByTagName(sel);\n }\n }\n /* do things the hard/slow way */\n return find(sel, context);\n};\n\nexports.selectors = selectors;\nexports.operators = operators;\nexports.combinators = combinators;\n\nexports.matches = function(el, sel) {\n var test = { sel: sel };\n do {\n test = compile(test.sel);\n if (test(el)) { return true; }\n } while (test.sel);\n return false;\n};\n","\"use strict\";\n\nvar Node = require('./Node');\nvar LinkedList = require('./LinkedList');\n\nvar createDocumentFragmentFromArguments = function(document, args) {\n var docFrag = document.createDocumentFragment();\n\n for (var i=0; iAttr map\n this._attrsByLName = Object.create(null); // The ns|lname->Attr map\n this._attrKeys = []; // attr index -> ns|lname\n}\n\nfunction recursiveGetText(node, a) {\n if (node.nodeType === Node.TEXT_NODE) {\n a.push(node._data);\n }\n else {\n for(var i = 0, n = node.childNodes.length; i < n; i++)\n recursiveGetText(node.childNodes[i], a);\n }\n}\n\nElement.prototype = Object.create(ContainerNode.prototype, {\n isHTML: { get: function isHTML() {\n return this.namespaceURI === NAMESPACE.HTML && this.ownerDocument.isHTML;\n }},\n tagName: { get: function tagName() {\n if (this._tagName === undefined) {\n var tn;\n if (this.prefix === null) {\n tn = this.localName;\n } else {\n tn = this.prefix + ':' + this.localName;\n }\n if (this.isHTML) {\n var up = uppercaseCache[tn];\n if (!up) {\n // Converting to uppercase can be slow, so cache the conversion.\n uppercaseCache[tn] = up = utils.toASCIIUpperCase(tn);\n }\n tn = up;\n }\n this._tagName = tn;\n }\n return this._tagName;\n }},\n nodeName: { get: function() { return this.tagName; }},\n nodeValue: {\n get: function() {\n return null;\n },\n set: function() {}\n },\n textContent: {\n get: function() {\n var strings = [];\n recursiveGetText(this, strings);\n return strings.join('');\n },\n set: function(newtext) {\n this.removeChildren();\n if (newtext !== null && newtext !== undefined && newtext !== '') {\n this._appendChild(this.ownerDocument.createTextNode(newtext));\n }\n }\n },\n innerText: {\n get: function() {\n var strings = [];\n recursiveGetText(this, strings);\n // Strip and collapse whitespace\n // This doesn't 100% match the browser behavior,\n // but should cover most of the cases. This is also similar to\n // how Angular's renderer used to work: the `textContent` and `innerText`\n // were almost equivalent from the renderer perspective.\n // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext\n return strings.join('').replace(/[ \\t\\n\\f\\r]+/g, ' ').trim();\n },\n set: function(newtext) {\n this.removeChildren();\n if (newtext !== null && newtext !== undefined && newtext !== '') {\n this._appendChild(this.ownerDocument.createTextNode(newtext));\n }\n }\n },\n innerHTML: {\n get: function() {\n return this.serialize();\n },\n set: utils.nyi\n },\n outerHTML: {\n get: function() {\n // \"the attribute must return the result of running the HTML fragment\n // serialization algorithm on a fictional node whose only child is\n // the context object\"\n //\n // The serialization logic is intentionally implemented in a separate\n // `NodeUtils` helper instead of the more obvious choice of a private\n // `_serializeOne()` method on the `Node.prototype` in order to avoid\n // the megamorphic `this._serializeOne` property access, which reduces\n // performance unnecessarily. If you need specialized behavior for a\n // certain subclass, you'll need to implement that in `NodeUtils`.\n // See https://github.com/fgnass/domino/pull/142 for more information.\n return NodeUtils.serializeOne(this, { nodeType: 0 });\n },\n set: function(v) {\n var document = this.ownerDocument;\n var parent = this.parentNode;\n if (parent === null) { return; }\n if (parent.nodeType === Node.DOCUMENT_NODE) {\n utils.NoModificationAllowedError();\n }\n if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n parent = parent.ownerDocument.createElement(\"body\");\n }\n var parser = document.implementation.mozHTMLParser(\n document._address,\n parent\n );\n parser.parse(v===null?'':String(v), true);\n this.replaceWith(parser._asDocumentFragment());\n },\n },\n\n _insertAdjacent: { value: function _insertAdjacent(position, node) {\n var first = false;\n switch(position) {\n case 'beforebegin':\n first = true;\n /* falls through */\n case 'afterend':\n var parent = this.parentNode;\n if (parent === null) { return null; }\n return parent.insertBefore(node, first ? this : this.nextSibling);\n case 'afterbegin':\n first = true;\n /* falls through */\n case 'beforeend':\n return this.insertBefore(node, first ? this.firstChild : null);\n default:\n return utils.SyntaxError();\n }\n }},\n\n insertAdjacentElement: { value: function insertAdjacentElement(position, element) {\n if (element.nodeType !== Node.ELEMENT_NODE) {\n throw new TypeError('not an element');\n }\n position = utils.toASCIILowerCase(String(position));\n return this._insertAdjacent(position, element);\n }},\n\n insertAdjacentText: { value: function insertAdjacentText(position, data) {\n var textNode = this.ownerDocument.createTextNode(data);\n position = utils.toASCIILowerCase(String(position));\n this._insertAdjacent(position, textNode);\n // \"This method returns nothing because it existed before we had a chance\n // to design it.\"\n }},\n\n insertAdjacentHTML: { value: function insertAdjacentHTML(position, text) {\n position = utils.toASCIILowerCase(String(position));\n text = String(text);\n var context;\n switch(position) {\n case 'beforebegin':\n case 'afterend':\n context = this.parentNode;\n if (context === null || context.nodeType === Node.DOCUMENT_NODE) {\n utils.NoModificationAllowedError();\n }\n break;\n case 'afterbegin':\n case 'beforeend':\n context = this;\n break;\n default:\n utils.SyntaxError();\n }\n if ( (!(context instanceof Element)) || (\n context.ownerDocument.isHTML &&\n context.localName === 'html' &&\n context.namespaceURI === NAMESPACE.HTML\n ) ) {\n context = context.ownerDocument.createElementNS(NAMESPACE.HTML, 'body');\n }\n var parser = this.ownerDocument.implementation.mozHTMLParser(\n this.ownerDocument._address, context\n );\n parser.parse(text, true);\n this._insertAdjacent(position, parser._asDocumentFragment());\n }},\n\n children: { get: function() {\n if (!this._children) {\n this._children = new ChildrenCollection(this);\n }\n return this._children;\n }},\n\n attributes: { get: function() {\n if (!this._attributes) {\n this._attributes = new AttributesArray(this);\n }\n return this._attributes;\n }},\n\n\n firstElementChild: { get: function() {\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === Node.ELEMENT_NODE) return kid;\n }\n return null;\n }},\n\n lastElementChild: { get: function() {\n for (var kid = this.lastChild; kid !== null; kid = kid.previousSibling) {\n if (kid.nodeType === Node.ELEMENT_NODE) return kid;\n }\n return null;\n }},\n\n childElementCount: { get: function() {\n return this.children.length;\n }},\n\n\n // Return the next element, in source order, after this one or\n // null if there are no more. If root element is specified,\n // then don't traverse beyond its subtree.\n //\n // This is not a DOM method, but is convenient for\n // lazy traversals of the tree.\n nextElement: { value: function(root) {\n if (!root) root = this.ownerDocument.documentElement;\n var next = this.firstElementChild;\n if (!next) {\n // don't use sibling if we're at root\n if (this===root) return null;\n next = this.nextElementSibling;\n }\n if (next) return next;\n\n // If we can't go down or across, then we have to go up\n // and across to the parent sibling or another ancestor's\n // sibling. Be careful, though: if we reach the root\n // element, or if we reach the documentElement, then\n // the traversal ends.\n for(var parent = this.parentElement;\n parent && parent !== root;\n parent = parent.parentElement) {\n\n next = parent.nextElementSibling;\n if (next) return next;\n }\n\n return null;\n }},\n\n // XXX:\n // Tests are currently failing for this function.\n // Awaiting resolution of:\n // http://lists.w3.org/Archives/Public/www-dom/2011JulSep/0016.html\n getElementsByTagName: { value: function getElementsByTagName(lname) {\n var filter;\n if (!lname) return new NodeList();\n if (lname === '*')\n filter = function() { return true; };\n else if (this.isHTML)\n filter = htmlLocalNameElementFilter(lname);\n else\n filter = localNameElementFilter(lname);\n\n return new FilteredElementList(this, filter);\n }},\n\n getElementsByTagNameNS: { value: function getElementsByTagNameNS(ns, lname){\n var filter;\n if (ns === '*' && lname === '*')\n filter = function() { return true; };\n else if (ns === '*')\n filter = localNameElementFilter(lname);\n else if (lname === '*')\n filter = namespaceElementFilter(ns);\n else\n filter = namespaceLocalNameElementFilter(ns, lname);\n\n return new FilteredElementList(this, filter);\n }},\n\n getElementsByClassName: { value: function getElementsByClassName(names){\n names = String(names).trim();\n if (names === '') {\n var result = new NodeList(); // Empty node list\n return result;\n }\n names = names.split(/[ \\t\\r\\n\\f]+/); // Split on ASCII whitespace\n return new FilteredElementList(this, classNamesElementFilter(names));\n }},\n\n getElementsByName: { value: function getElementsByName(name) {\n return new FilteredElementList(this, elementNameFilter(String(name)));\n }},\n\n // Utility methods used by the public API methods above\n clone: { value: function clone() {\n var e;\n\n // XXX:\n // Modify this to use the constructor directly or\n // avoid error checking in some other way. In case we try\n // to clone an invalid node that the parser inserted.\n //\n if (this.namespaceURI !== NAMESPACE.HTML || this.prefix || !this.ownerDocument.isHTML) {\n e = this.ownerDocument.createElementNS(\n this.namespaceURI, (this.prefix !== null) ?\n (this.prefix + ':' + this.localName) : this.localName\n );\n } else {\n e = this.ownerDocument.createElement(this.localName);\n }\n\n for(var i = 0, n = this._attrKeys.length; i < n; i++) {\n var lname = this._attrKeys[i];\n var a = this._attrsByLName[lname];\n var b = a.cloneNode();\n b._setOwnerElement(e);\n e._attrsByLName[lname] = b;\n e._addQName(b);\n }\n e._attrKeys = this._attrKeys.concat();\n\n return e;\n }},\n\n isEqual: { value: function isEqual(that) {\n if (this.localName !== that.localName ||\n this.namespaceURI !== that.namespaceURI ||\n this.prefix !== that.prefix ||\n this._numattrs !== that._numattrs)\n return false;\n\n // Compare the sets of attributes, ignoring order\n // and ignoring attribute prefixes.\n for(var i = 0, n = this._numattrs; i < n; i++) {\n var a = this._attr(i);\n if (!that.hasAttributeNS(a.namespaceURI, a.localName))\n return false;\n if (that.getAttributeNS(a.namespaceURI,a.localName) !== a.value)\n return false;\n }\n\n return true;\n }},\n\n // This is the 'locate a namespace prefix' algorithm from the\n // DOM specification. It is used by Node.lookupPrefix()\n // (Be sure to compare DOM3 and DOM4 versions of spec.)\n _lookupNamespacePrefix: { value: function _lookupNamespacePrefix(ns, originalElement) {\n if (\n this.namespaceURI &&\n this.namespaceURI === ns &&\n this.prefix !== null &&\n originalElement.lookupNamespaceURI(this.prefix) === ns\n ) {\n return this.prefix;\n }\n\n for(var i = 0, n = this._numattrs; i < n; i++) {\n var a = this._attr(i);\n if (\n a.prefix === 'xmlns' &&\n a.value === ns &&\n originalElement.lookupNamespaceURI(a.localName) === ns\n ) {\n return a.localName;\n }\n }\n\n var parent = this.parentElement;\n return parent ? parent._lookupNamespacePrefix(ns, originalElement) : null;\n }},\n\n // This is the 'locate a namespace' algorithm for Element nodes\n // from the DOM Core spec. It is used by Node#lookupNamespaceURI()\n lookupNamespaceURI: { value: function lookupNamespaceURI(prefix) {\n if (prefix === '' || prefix === undefined) { prefix = null; }\n if (this.namespaceURI !== null && this.prefix === prefix)\n return this.namespaceURI;\n\n for(var i = 0, n = this._numattrs; i < n; i++) {\n var a = this._attr(i);\n if (a.namespaceURI === NAMESPACE.XMLNS) {\n if (\n (a.prefix === 'xmlns' && a.localName === prefix) ||\n (prefix === null && a.prefix === null && a.localName === 'xmlns')\n ) {\n return a.value || null;\n }\n }\n }\n\n var parent = this.parentElement;\n return parent ? parent.lookupNamespaceURI(prefix) : null;\n }},\n\n //\n // Attribute handling methods and utilities\n //\n\n /*\n * Attributes in the DOM are tricky:\n *\n * - there are the 8 basic get/set/has/removeAttribute{NS} methods\n *\n * - but many HTML attributes are also 'reflected' through IDL\n * attributes which means that they can be queried and set through\n * regular properties of the element. There is just one attribute\n * value, but two ways to get and set it.\n *\n * - Different HTML element types have different sets of reflected\n attributes.\n *\n * - attributes can also be queried and set through the .attributes\n * property of an element. This property behaves like an array of\n * Attr objects. The value property of each Attr is writeable, so\n * this is a third way to read and write attributes.\n *\n * - for efficiency, we really want to store attributes in some kind\n * of name->attr map. But the attributes[] array is an array, not a\n * map, which is kind of unnatural.\n *\n * - When using namespaces and prefixes, and mixing the NS methods\n * with the non-NS methods, it is apparently actually possible for\n * an attributes[] array to have more than one attribute with the\n * same qualified name. And certain methods must operate on only\n * the first attribute with such a name. So for these methods, an\n * inefficient array-like data structure would be easier to\n * implement.\n *\n * - The attributes[] array is live, not a snapshot, so changes to the\n * attributes must be immediately visible through existing arrays.\n *\n * - When attributes are queried and set through IDL properties\n * (instead of the get/setAttributes() method or the attributes[]\n * array) they may be subject to type conversions, URL\n * normalization, etc., so some extra processing is required in that\n * case.\n *\n * - But access through IDL properties is probably the most common\n * case, so we'd like that to be as fast as possible.\n *\n * - We can't just store attribute values in their parsed idl form,\n * because setAttribute() has to return whatever string is passed to\n * getAttribute even if it is not a legal, parseable value. So\n * attribute values must be stored in unparsed string form.\n *\n * - We need to be able to send change notifications or mutation\n * events of some sort to the renderer whenever an attribute value\n * changes, regardless of the way in which it changes.\n *\n * - Some attributes, such as id and class affect other parts of the\n * DOM API, like getElementById and getElementsByClassName and so\n * for efficiency, we need to specially track changes to these\n * special attributes.\n *\n * - Some attributes like class have different names (className) when\n * reflected.\n *\n * - Attributes whose names begin with the string 'data-' are treated\n specially.\n *\n * - Reflected attributes that have a boolean type in IDL have special\n * behavior: setting them to false (in IDL) is the same as removing\n * them with removeAttribute()\n *\n * - numeric attributes (like HTMLElement.tabIndex) can have default\n * values that must be returned by the idl getter even if the\n * content attribute does not exist. (The default tabIndex value\n * actually varies based on the type of the element, so that is a\n * tricky one).\n *\n * See\n * http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#reflect\n * for rules on how attributes are reflected.\n *\n */\n\n getAttribute: { value: function getAttribute(qname) {\n var attr = this.getAttributeNode(qname);\n return attr ? attr.value : null;\n }},\n\n getAttributeNS: { value: function getAttributeNS(ns, lname) {\n var attr = this.getAttributeNodeNS(ns, lname);\n return attr ? attr.value : null;\n }},\n\n getAttributeNode: { value: function getAttributeNode(qname) {\n qname = String(qname);\n if (/[A-Z]/.test(qname) && this.isHTML)\n qname = utils.toASCIILowerCase(qname);\n var attr = this._attrsByQName[qname];\n if (!attr) return null;\n\n if (Array.isArray(attr)) // If there is more than one\n attr = attr[0]; // use the first\n\n return attr;\n }},\n\n getAttributeNodeNS: { value: function getAttributeNodeNS(ns, lname) {\n ns = (ns === undefined || ns === null) ? '' : String(ns);\n lname = String(lname);\n var attr = this._attrsByLName[ns + '|' + lname];\n return attr ? attr : null;\n }},\n\n hasAttribute: { value: function hasAttribute(qname) {\n qname = String(qname);\n if (/[A-Z]/.test(qname) && this.isHTML)\n qname = utils.toASCIILowerCase(qname);\n return this._attrsByQName[qname] !== undefined;\n }},\n\n hasAttributeNS: { value: function hasAttributeNS(ns, lname) {\n ns = (ns === undefined || ns === null) ? '' : String(ns);\n lname = String(lname);\n var key = ns + '|' + lname;\n return this._attrsByLName[key] !== undefined;\n }},\n\n hasAttributes: { value: function hasAttributes() {\n return this._numattrs > 0;\n }},\n\n toggleAttribute: { value: function toggleAttribute(qname, force) {\n qname = String(qname);\n if (!xml.isValidName(qname)) utils.InvalidCharacterError();\n if (/[A-Z]/.test(qname) && this.isHTML)\n qname = utils.toASCIILowerCase(qname);\n var a = this._attrsByQName[qname];\n if (a === undefined) {\n if (force === undefined || force === true) {\n this._setAttribute(qname, '');\n return true;\n }\n return false;\n } else {\n if (force === undefined || force === false) {\n this.removeAttribute(qname);\n return false;\n }\n return true;\n }\n }},\n\n // Set the attribute without error checking. The parser uses this.\n _setAttribute: { value: function _setAttribute(qname, value) {\n // XXX: the spec says that this next search should be done\n // on the local name, but I think that is an error.\n // email pending on www-dom about it.\n var attr = this._attrsByQName[qname];\n var isnew;\n if (!attr) {\n attr = this._newattr(qname);\n isnew = true;\n }\n else {\n if (Array.isArray(attr)) attr = attr[0];\n }\n\n // Now set the attribute value on the new or existing Attr object.\n // The Attr.value setter method handles mutation events, etc.\n attr.value = value;\n if (this._attributes) this._attributes[qname] = attr;\n if (isnew && this._newattrhook) this._newattrhook(qname, value);\n }},\n\n // Check for errors, and then set the attribute\n setAttribute: { value: function setAttribute(qname, value) {\n qname = String(qname);\n if (!xml.isValidName(qname)) utils.InvalidCharacterError();\n if (/[A-Z]/.test(qname) && this.isHTML)\n qname = utils.toASCIILowerCase(qname);\n this._setAttribute(qname, String(value));\n }},\n\n\n // The version with no error checking used by the parser\n _setAttributeNS: { value: function _setAttributeNS(ns, qname, value) {\n var pos = qname.indexOf(':'), prefix, lname;\n if (pos < 0) {\n prefix = null;\n lname = qname;\n }\n else {\n prefix = qname.substring(0, pos);\n lname = qname.substring(pos+1);\n }\n\n if (ns === '' || ns === undefined) ns = null;\n var key = (ns === null ? '' : ns) + '|' + lname;\n\n var attr = this._attrsByLName[key];\n var isnew;\n if (!attr) {\n attr = new Attr(this, lname, prefix, ns);\n isnew = true;\n this._attrsByLName[key] = attr;\n if (this._attributes) {\n this._attributes[this._attrKeys.length] = attr;\n }\n this._attrKeys.push(key);\n\n // We also have to make the attr searchable by qname.\n // But we have to be careful because there may already\n // be an attr with this qname.\n this._addQName(attr);\n }\n else if (false /* changed in DOM 4 */) {\n // Calling setAttributeNS() can change the prefix of an\n // existing attribute in DOM 2/3.\n if (attr.prefix !== prefix) {\n // Unbind the old qname\n this._removeQName(attr);\n // Update the prefix\n attr.prefix = prefix;\n // Bind the new qname\n this._addQName(attr);\n }\n\n }\n attr.value = value; // Automatically sends mutation event\n if (isnew && this._newattrhook) this._newattrhook(qname, value);\n }},\n\n // Do error checking then call _setAttributeNS\n setAttributeNS: { value: function setAttributeNS(ns, qname, value) {\n // Convert parameter types according to WebIDL\n ns = (ns === null || ns === undefined || ns === '') ? null : String(ns);\n qname = String(qname);\n if (!xml.isValidQName(qname)) utils.InvalidCharacterError();\n\n var pos = qname.indexOf(':');\n var prefix = (pos < 0) ? null : qname.substring(0, pos);\n\n if ((prefix !== null && ns === null) ||\n (prefix === 'xml' && ns !== NAMESPACE.XML) ||\n ((qname === 'xmlns' || prefix === 'xmlns') &&\n (ns !== NAMESPACE.XMLNS)) ||\n (ns === NAMESPACE.XMLNS &&\n !(qname === 'xmlns' || prefix === 'xmlns')))\n utils.NamespaceError();\n\n this._setAttributeNS(ns, qname, String(value));\n }},\n\n setAttributeNode: { value: function setAttributeNode(attr) {\n if (attr.ownerElement !== null && attr.ownerElement !== this) {\n throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);\n }\n var result = null;\n var oldAttrs = this._attrsByQName[attr.name];\n if (oldAttrs) {\n if (!Array.isArray(oldAttrs)) { oldAttrs = [ oldAttrs ]; }\n if (oldAttrs.some(function(a) { return a===attr; })) {\n return attr;\n } else if (attr.ownerElement !== null) {\n throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);\n }\n oldAttrs.forEach(function(a) { this.removeAttributeNode(a); }, this);\n result = oldAttrs[0];\n }\n this.setAttributeNodeNS(attr);\n return result;\n }},\n\n setAttributeNodeNS: { value: function setAttributeNodeNS(attr) {\n if (attr.ownerElement !== null) {\n throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);\n }\n var ns = attr.namespaceURI;\n var key = (ns === null ? '' : ns) + '|' + attr.localName;\n var oldAttr = this._attrsByLName[key];\n if (oldAttr) { this.removeAttributeNode(oldAttr); }\n attr._setOwnerElement(this);\n this._attrsByLName[key] = attr;\n if (this._attributes) {\n this._attributes[this._attrKeys.length] = attr;\n }\n this._attrKeys.push(key);\n this._addQName(attr);\n if (this._newattrhook) this._newattrhook(attr.name, attr.value);\n return oldAttr || null;\n }},\n\n removeAttribute: { value: function removeAttribute(qname) {\n qname = String(qname);\n if (/[A-Z]/.test(qname) && this.isHTML)\n qname = utils.toASCIILowerCase(qname);\n\n var attr = this._attrsByQName[qname];\n if (!attr) return;\n\n // If there is more than one match for this qname\n // so don't delete the qname mapping, just remove the first\n // element from it.\n if (Array.isArray(attr)) {\n if (attr.length > 2) {\n attr = attr.shift(); // remove it from the array\n }\n else {\n this._attrsByQName[qname] = attr[1];\n attr = attr[0];\n }\n }\n else {\n // only a single match, so remove the qname mapping\n this._attrsByQName[qname] = undefined;\n }\n\n var ns = attr.namespaceURI;\n // Now attr is the removed attribute. Figure out its\n // ns+lname key and remove it from the other mapping as well.\n var key = (ns === null ? '' : ns) + '|' + attr.localName;\n this._attrsByLName[key] = undefined;\n\n var i = this._attrKeys.indexOf(key);\n if (this._attributes) {\n Array.prototype.splice.call(this._attributes, i, 1);\n this._attributes[qname] = undefined;\n }\n this._attrKeys.splice(i, 1);\n\n // Onchange handler for the attribute\n var onchange = attr.onchange;\n attr._setOwnerElement(null);\n if (onchange) {\n onchange.call(attr, this, attr.localName, attr.value, null);\n }\n // Mutation event\n if (this.rooted) this.ownerDocument.mutateRemoveAttr(attr);\n }},\n\n removeAttributeNS: { value: function removeAttributeNS(ns, lname) {\n ns = (ns === undefined || ns === null) ? '' : String(ns);\n lname = String(lname);\n var key = ns + '|' + lname;\n var attr = this._attrsByLName[key];\n if (!attr) return;\n\n this._attrsByLName[key] = undefined;\n\n var i = this._attrKeys.indexOf(key);\n if (this._attributes) {\n Array.prototype.splice.call(this._attributes, i, 1);\n }\n this._attrKeys.splice(i, 1);\n\n // Now find the same Attr object in the qname mapping and remove it\n // But be careful because there may be more than one match.\n this._removeQName(attr);\n\n // Onchange handler for the attribute\n var onchange = attr.onchange;\n attr._setOwnerElement(null);\n if (onchange) {\n onchange.call(attr, this, attr.localName, attr.value, null);\n }\n // Mutation event\n if (this.rooted) this.ownerDocument.mutateRemoveAttr(attr);\n }},\n\n removeAttributeNode: { value: function removeAttributeNode(attr) {\n var ns = attr.namespaceURI;\n var key = (ns === null ? '' : ns) + '|' + attr.localName;\n if (this._attrsByLName[key] !== attr) {\n utils.NotFoundError();\n }\n this.removeAttributeNS(ns, attr.localName);\n return attr;\n }},\n\n getAttributeNames: { value: function getAttributeNames() {\n var elt = this;\n return this._attrKeys.map(function(key) {\n return elt._attrsByLName[key].name;\n });\n }},\n\n // This 'raw' version of getAttribute is used by the getter functions\n // of reflected attributes. It skips some error checking and\n // namespace steps\n _getattr: { value: function _getattr(qname) {\n // Assume that qname is already lowercased, so don't do it here.\n // Also don't check whether attr is an array: a qname with no\n // prefix will never have two matching Attr objects (because\n // setAttributeNS doesn't allow a non-null namespace with a\n // null prefix.\n var attr = this._attrsByQName[qname];\n return attr ? attr.value : null;\n }},\n\n // The raw version of setAttribute for reflected idl attributes.\n _setattr: { value: function _setattr(qname, value) {\n var attr = this._attrsByQName[qname];\n var isnew;\n if (!attr) {\n attr = this._newattr(qname);\n isnew = true;\n }\n attr.value = String(value);\n if (this._attributes) this._attributes[qname] = attr;\n if (isnew && this._newattrhook) this._newattrhook(qname, value);\n }},\n\n // Create a new Attr object, insert it, and return it.\n // Used by setAttribute() and by set()\n _newattr: { value: function _newattr(qname) {\n var attr = new Attr(this, qname, null, null);\n var key = '|' + qname;\n this._attrsByQName[qname] = attr;\n this._attrsByLName[key] = attr;\n if (this._attributes) {\n this._attributes[this._attrKeys.length] = attr;\n }\n this._attrKeys.push(key);\n return attr;\n }},\n\n // Add a qname->Attr mapping to the _attrsByQName object, taking into\n // account that there may be more than one attr object with the\n // same qname\n _addQName: { value: function(attr) {\n var qname = attr.name;\n var existing = this._attrsByQName[qname];\n if (!existing) {\n this._attrsByQName[qname] = attr;\n }\n else if (Array.isArray(existing)) {\n existing.push(attr);\n }\n else {\n this._attrsByQName[qname] = [existing, attr];\n }\n if (this._attributes) this._attributes[qname] = attr;\n }},\n\n // Remove a qname->Attr mapping to the _attrsByQName object, taking into\n // account that there may be more than one attr object with the\n // same qname\n _removeQName: { value: function(attr) {\n var qname = attr.name;\n var target = this._attrsByQName[qname];\n\n if (Array.isArray(target)) {\n var idx = target.indexOf(attr);\n utils.assert(idx !== -1); // It must be here somewhere\n if (target.length === 2) {\n this._attrsByQName[qname] = target[1-idx];\n if (this._attributes) {\n this._attributes[qname] = this._attrsByQName[qname];\n }\n } else {\n target.splice(idx, 1);\n if (this._attributes && this._attributes[qname] === attr) {\n this._attributes[qname] = target[0];\n }\n }\n }\n else {\n utils.assert(target === attr); // If only one, it must match\n this._attrsByQName[qname] = undefined;\n if (this._attributes) {\n this._attributes[qname] = undefined;\n }\n }\n }},\n\n // Return the number of attributes\n _numattrs: { get: function() { return this._attrKeys.length; }},\n // Return the nth Attr object\n _attr: { value: function(n) {\n return this._attrsByLName[this._attrKeys[n]];\n }},\n\n // Define getters and setters for an 'id' property that reflects\n // the content attribute 'id'.\n id: attributes.property({name: 'id'}),\n\n // Define getters and setters for a 'className' property that reflects\n // the content attribute 'class'.\n className: attributes.property({name: 'class'}),\n\n classList: { get: function() {\n var self = this;\n if (this._classList) {\n return this._classList;\n }\n var dtlist = new DOMTokenList(\n function() {\n return self.className || \"\";\n },\n function(v) {\n self.className = v;\n }\n );\n this._classList = dtlist;\n return dtlist;\n }, set: function(v) { this.className = v; }},\n\n matches: { value: function(selector) {\n return select.matches(this, selector);\n }},\n\n closest: { value: function(selector) {\n var el = this;\n\tdo {\n\t if (el.matches && el.matches(selector)) { return el; }\n\t el = el.parentElement || el.parentNode;\n\t} while (el !== null && el.nodeType === Node.ELEMENT_NODE);\n\treturn null;\n }},\n\n querySelector: { value: function(selector) {\n return select(selector, this)[0];\n }},\n\n querySelectorAll: { value: function(selector) {\n var nodes = select(selector, this);\n return nodes.item ? nodes : new NodeList(nodes);\n }}\n\n});\n\nObject.defineProperties(Element.prototype, ChildNode);\nObject.defineProperties(Element.prototype, NonDocumentTypeChildNode);\n\n// Register special handling for the id attribute\nattributes.registerChangeHandler(Element, 'id',\n function(element, lname, oldval, newval) {\n if (element.rooted) {\n if (oldval) {\n element.ownerDocument.delId(oldval, element);\n }\n if (newval) {\n element.ownerDocument.addId(newval, element);\n }\n }\n }\n);\nattributes.registerChangeHandler(Element, 'class',\n function(element, lname, oldval, newval) {\n if (element._classList) { element._classList._update(); }\n }\n);\n\n// The Attr class represents a single attribute. The values in\n// _attrsByQName and _attrsByLName are instances of this class.\nfunction Attr(elt, lname, prefix, namespace, value) {\n // localName and namespace are constant for any attr object.\n // But value may change. And so can prefix, and so, therefore can name.\n this.localName = lname;\n this.prefix = (prefix===null || prefix==='') ? null : ('' + prefix);\n this.namespaceURI = (namespace===null || namespace==='') ? null : ('' + namespace);\n this.data = value;\n // Set ownerElement last to ensure it is hooked up to onchange handler\n this._setOwnerElement(elt);\n}\n\n// In DOM 3 Attr was supposed to extend Node; in DOM 4 that was abandoned.\nAttr.prototype = Object.create(Object.prototype, {\n ownerElement: {\n get: function() { return this._ownerElement; },\n },\n _setOwnerElement: { value: function _setOwnerElement(elt) {\n this._ownerElement = elt;\n if (this.prefix === null && this.namespaceURI === null && elt) {\n this.onchange = elt._attributeChangeHandlers[this.localName];\n } else {\n this.onchange = null;\n }\n }},\n\n name: { get: function() {\n return this.prefix ? this.prefix + ':' + this.localName : this.localName;\n }},\n\n specified: { get: function() {\n // Deprecated\n return true;\n }},\n\n value: {\n get: function() {\n return this.data;\n },\n set: function(value) {\n var oldval = this.data;\n value = (value === undefined) ? '' : value + '';\n if (value === oldval) return;\n\n this.data = value;\n\n // Run the onchange hook for the attribute\n // if there is one.\n if (this.ownerElement) {\n if (this.onchange)\n this.onchange(this.ownerElement,this.localName, oldval, value);\n\n // Generate a mutation event if the element is rooted\n if (this.ownerElement.rooted)\n this.ownerElement.ownerDocument.mutateAttr(this, oldval);\n }\n },\n },\n\n cloneNode: { value: function cloneNode(deep) {\n // Both this method and Document#createAttribute*() create unowned Attrs\n return new Attr(\n null, this.localName, this.prefix, this.namespaceURI, this.data\n );\n }},\n\n // Legacy aliases (see gh#70 and https://dom.spec.whatwg.org/#interface-attr)\n nodeType: { get: function() { return Node.ATTRIBUTE_NODE; } },\n nodeName: { get: function() { return this.name; } },\n nodeValue: {\n get: function() { return this.value; },\n set: function(v) { this.value = v; },\n },\n textContent: {\n get: function() { return this.value; },\n set: function(v) {\n if (v === null || v === undefined) { v = ''; }\n this.value = v;\n },\n },\n innerText: {\n get: function() { return this.value; },\n set: function(v) {\n if (v === null || v === undefined) { v = ''; }\n this.value = v;\n },\n },\n});\n// Sneakily export this class for use by Document.createAttribute()\nElement._Attr = Attr;\n\n// The attributes property of an Element will be an instance of this class.\n// This class is really just a dummy, though. It only defines a length\n// property and an item() method. The AttrArrayProxy that\n// defines the public API just uses the Element object itself.\nfunction AttributesArray(elt) {\n NamedNodeMap.call(this, elt);\n for (var name in elt._attrsByQName) {\n this[name] = elt._attrsByQName[name];\n }\n for (var i = 0; i < elt._attrKeys.length; i++) {\n this[i] = elt._attrsByLName[elt._attrKeys[i]];\n }\n}\nAttributesArray.prototype = Object.create(NamedNodeMap.prototype, {\n length: { get: function() {\n return this.element._attrKeys.length;\n }, set: function() { /* ignore */ } },\n item: { value: function(n) {\n /* jshint bitwise: false */\n n = n >>> 0;\n if (n >= this.length) { return null; }\n return this.element._attrsByLName[this.element._attrKeys[n]];\n /* jshint bitwise: true */\n } },\n});\n\n// We can't make direct array access work (without Proxies, node >=6)\n// but we can make `Array.from(node.attributes)` and for-of loops work.\nif (globalThis.Symbol?.iterator) {\n AttributesArray.prototype[globalThis.Symbol.iterator] = function() {\n var i=0, n=this.length, self=this;\n return {\n next: function() {\n if (ielement map.\n // It is not part of the HTMLCollection API, but we need it in\n // src/HTMLCollectionProxy\n namedItems: { get: function() {\n this.updateCache();\n return this.childrenByName;\n } },\n\n updateCache: { value: function updateCache() {\n var namedElts = /^(a|applet|area|embed|form|frame|frameset|iframe|img|object)$/;\n if (this.lastModTime !== this.element.lastModTime) {\n this.lastModTime = this.element.lastModTime;\n\n var n = this.childrenByNumber && this.childrenByNumber.length || 0;\n for(var i = 0; i < n; i++) {\n this[i] = undefined;\n }\n\n this.childrenByNumber = [];\n this.childrenByName = Object.create(null);\n\n for (var c = this.element.firstChild; c !== null; c = c.nextSibling) {\n if (c.nodeType === Node.ELEMENT_NODE) {\n\n this[this.childrenByNumber.length] = c;\n this.childrenByNumber.push(c);\n\n // XXX Are there any requirements about the namespace\n // of the id property?\n var id = c.getAttribute('id');\n\n // If there is an id that is not already in use...\n if (id && !this.childrenByName[id])\n this.childrenByName[id] = c;\n\n // For certain HTML elements we check the name attribute\n var name = c.getAttribute('name');\n if (name &&\n this.element.namespaceURI === NAMESPACE.HTML &&\n namedElts.test(this.element.localName) &&\n !this.childrenByName[name])\n this.childrenByName[id] = c;\n }\n }\n }\n } },\n});\n\n// These functions return predicates for filtering elements.\n// They're used by the Document and Element classes for methods like\n// getElementsByTagName and getElementsByClassName\n\nfunction localNameElementFilter(lname) {\n return function(e) { return e.localName === lname; };\n}\n\nfunction htmlLocalNameElementFilter(lname) {\n var lclname = utils.toASCIILowerCase(lname);\n if (lclname === lname)\n return localNameElementFilter(lname);\n\n return function(e) {\n return e.isHTML ? e.localName === lclname : e.localName === lname;\n };\n}\n\nfunction namespaceElementFilter(ns) {\n return function(e) { return e.namespaceURI === ns; };\n}\n\nfunction namespaceLocalNameElementFilter(ns, lname) {\n return function(e) {\n return e.namespaceURI === ns && e.localName === lname;\n };\n}\n\nfunction classNamesElementFilter(names) {\n return function(e) {\n return names.every(function(n) { return e.classList.contains(n); });\n };\n}\n\nfunction elementNameFilter(name) {\n return function(e) {\n // All the *HTML elements* in the document with the given name attribute\n if (e.namespaceURI !== NAMESPACE.HTML) { return false; }\n return e.getAttribute('name') === name;\n };\n}\n","\"use strict\";\nmodule.exports = Leaf;\n\nvar Node = require('./Node');\nvar NodeList = require('./NodeList');\nvar utils = require('./utils');\nvar HierarchyRequestError = utils.HierarchyRequestError;\nvar NotFoundError = utils.NotFoundError;\n\n// This class defines common functionality for node subtypes that\n// can never have children\nfunction Leaf() {\n Node.call(this);\n}\n\nLeaf.prototype = Object.create(Node.prototype, {\n hasChildNodes: { value: function() { return false; }},\n firstChild: { value: null },\n lastChild: { value: null },\n insertBefore: { value: function(node, child) {\n if (!node.nodeType) throw new TypeError('not a node');\n HierarchyRequestError();\n }},\n replaceChild: { value: function(node, child) {\n if (!node.nodeType) throw new TypeError('not a node');\n HierarchyRequestError();\n }},\n removeChild: { value: function(node) {\n if (!node.nodeType) throw new TypeError('not a node');\n NotFoundError();\n }},\n removeChildren: { value: function() { /* no op */ }},\n childNodes: { get: function() {\n if (!this._childNodes) this._childNodes = new NodeList();\n return this._childNodes;\n }}\n});\n","/* jshint bitwise: false */\n\"use strict\";\nmodule.exports = CharacterData;\n\nvar Leaf = require('./Leaf');\nvar utils = require('./utils');\nvar ChildNode = require('./ChildNode');\nvar NonDocumentTypeChildNode = require('./NonDocumentTypeChildNode');\n\nfunction CharacterData() {\n Leaf.call(this);\n}\n\nCharacterData.prototype = Object.create(Leaf.prototype, {\n // DOMString substringData(unsigned long offset,\n // unsigned long count);\n // The substringData(offset, count) method must run these steps:\n //\n // If offset is greater than the context object's\n // length, throw an INDEX_SIZE_ERR exception and\n // terminate these steps.\n //\n // If offset+count is greater than the context\n // object's length, return a DOMString whose value is\n // the UTF-16 code units from the offsetth UTF-16 code\n // unit to the end of data.\n //\n // Return a DOMString whose value is the UTF-16 code\n // units from the offsetth UTF-16 code unit to the\n // offset+countth UTF-16 code unit in data.\n substringData: { value: function substringData(offset, count) {\n if (arguments.length < 2) { throw new TypeError(\"Not enough arguments\"); }\n // Convert arguments to WebIDL \"unsigned long\"\n offset = offset >>> 0;\n count = count >>> 0;\n if (offset > this.data.length || offset < 0 || count < 0) {\n utils.IndexSizeError();\n }\n return this.data.substring(offset, offset+count);\n }},\n\n // void appendData(DOMString data);\n // The appendData(data) method must append data to the context\n // object's data.\n appendData: { value: function appendData(data) {\n if (arguments.length < 1) { throw new TypeError(\"Not enough arguments\"); }\n this.data += String(data);\n }},\n\n // void insertData(unsigned long offset, DOMString data);\n // The insertData(offset, data) method must run these steps:\n //\n // If offset is greater than the context object's\n // length, throw an INDEX_SIZE_ERR exception and\n // terminate these steps.\n //\n // Insert data into the context object's data after\n // offset UTF-16 code units.\n //\n insertData: { value: function insertData(offset, data) {\n return this.replaceData(offset, 0, data);\n }},\n\n\n // void deleteData(unsigned long offset, unsigned long count);\n // The deleteData(offset, count) method must run these steps:\n //\n // If offset is greater than the context object's\n // length, throw an INDEX_SIZE_ERR exception and\n // terminate these steps.\n //\n // If offset+count is greater than the context\n // object's length var count be length-offset.\n //\n // Starting from offset UTF-16 code units remove count\n // UTF-16 code units from the context object's data.\n deleteData: { value: function deleteData(offset, count) {\n return this.replaceData(offset, count, '');\n }},\n\n\n // void replaceData(unsigned long offset, unsigned long count,\n // DOMString data);\n //\n // The replaceData(offset, count, data) method must act as\n // if the deleteData() method is invoked with offset and\n // count as arguments followed by the insertData() method\n // with offset and data as arguments and re-throw any\n // exceptions these methods might have thrown.\n replaceData: { value: function replaceData(offset, count, data) {\n var curtext = this.data, len = curtext.length;\n // Convert arguments to correct WebIDL type\n offset = offset >>> 0;\n count = count >>> 0;\n data = String(data);\n\n if (offset > len || offset < 0) utils.IndexSizeError();\n\n if (offset+count > len)\n count = len - offset;\n\n var prefix = curtext.substring(0, offset),\n suffix = curtext.substring(offset+count);\n\n this.data = prefix + data + suffix;\n }},\n\n // Utility method that Node.isEqualNode() calls to test Text and\n // Comment nodes for equality. It is okay to put it here, since\n // Node will have already verified that nodeType is equal\n isEqual: { value: function isEqual(n) {\n return this._data === n._data;\n }},\n\n length: { get: function() { return this.data.length; }}\n\n});\n\nObject.defineProperties(CharacterData.prototype, ChildNode);\nObject.defineProperties(CharacterData.prototype, NonDocumentTypeChildNode);\n","\"use strict\";\nmodule.exports = Text;\n\nvar utils = require('./utils');\nvar Node = require('./Node');\nvar CharacterData = require('./CharacterData');\n\nfunction Text(doc, data) {\n CharacterData.call(this);\n this.nodeType = Node.TEXT_NODE;\n this.ownerDocument = doc;\n this._data = data;\n this._index = undefined;\n}\n\nvar nodeValue = {\n get: function() { return this._data; },\n set: function(v) {\n if (v === null || v === undefined) { v = ''; } else { v = String(v); }\n if (v === this._data) return;\n this._data = v;\n if (this.rooted)\n this.ownerDocument.mutateValue(this);\n if (this.parentNode &&\n this.parentNode._textchangehook)\n this.parentNode._textchangehook(this);\n }\n};\n\nText.prototype = Object.create(CharacterData.prototype, {\n nodeName: { value: \"#text\" },\n // These three attributes are all the same.\n // The data attribute has a [TreatNullAs=EmptyString] but we'll\n // implement that at the interface level\n nodeValue: nodeValue,\n textContent: nodeValue,\n innerText: nodeValue,\n data: {\n get: nodeValue.get,\n set: function(v) {\n nodeValue.set.call(this, v===null ? '' : String(v));\n },\n },\n\n splitText: { value: function splitText(offset) {\n if (offset > this._data.length || offset < 0) utils.IndexSizeError();\n\n var newdata = this._data.substring(offset),\n newnode = this.ownerDocument.createTextNode(newdata);\n this.data = this.data.substring(0, offset);\n\n var parent = this.parentNode;\n if (parent !== null)\n parent.insertBefore(newnode, this.nextSibling);\n\n return newnode;\n }},\n\n wholeText: { get: function wholeText() {\n var result = this.textContent;\n for (var next = this.nextSibling; next; next = next.nextSibling) {\n if (next.nodeType !== Node.TEXT_NODE) { break; }\n result += next.textContent;\n }\n return result;\n }},\n // Obsolete, removed from spec.\n replaceWholeText: { value: utils.nyi },\n\n // Utility methods\n clone: { value: function clone() {\n return new Text(this.ownerDocument, this._data);\n }},\n\n});\n","\"use strict\";\nmodule.exports = Comment;\n\nvar Node = require('./Node');\nvar CharacterData = require('./CharacterData');\n\nfunction Comment(doc, data) {\n CharacterData.call(this);\n this.nodeType = Node.COMMENT_NODE;\n this.ownerDocument = doc;\n this._data = data;\n}\n\nvar nodeValue = {\n get: function() { return this._data; },\n set: function(v) {\n if (v === null || v === undefined) { v = ''; } else { v = String(v); }\n this._data = v;\n if (this.rooted)\n this.ownerDocument.mutateValue(this);\n }\n};\n\nComment.prototype = Object.create(CharacterData.prototype, {\n nodeName: { value: '#comment' },\n nodeValue: nodeValue,\n textContent: nodeValue,\n innerText: nodeValue,\n data: {\n get: nodeValue.get,\n set: function(v) {\n nodeValue.set.call(this, v===null ? '' : String(v));\n },\n },\n\n // Utility methods\n clone: { value: function clone() {\n return new Comment(this.ownerDocument, this._data);\n }},\n});\n","\"use strict\";\nmodule.exports = DocumentFragment;\n\nvar Node = require('./Node');\nvar NodeList = require('./NodeList');\nvar ContainerNode = require('./ContainerNode');\nvar Element = require('./Element');\nvar select = require('./select');\nvar utils = require('./utils');\n\nfunction DocumentFragment(doc) {\n ContainerNode.call(this);\n this.nodeType = Node.DOCUMENT_FRAGMENT_NODE;\n this.ownerDocument = doc;\n}\n\nDocumentFragment.prototype = Object.create(ContainerNode.prototype, {\n nodeName: { value: '#document-fragment' },\n nodeValue: {\n get: function() {\n return null;\n },\n set: function() {}\n },\n // Copy the text content getter/setter from Element\n textContent: Object.getOwnPropertyDescriptor(Element.prototype, 'textContent'),\n\n // Copy the text content getter/setter from Element\n innerText: Object.getOwnPropertyDescriptor(Element.prototype, 'innerText'),\n\n querySelector: { value: function(selector) {\n // implement in terms of querySelectorAll\n var nodes = this.querySelectorAll(selector);\n return nodes.length ? nodes[0] : null;\n }},\n querySelectorAll: { value: function(selector) {\n // create a context\n var context = Object.create(this);\n // add some methods to the context for zest implementation, without\n // adding them to the public DocumentFragment API\n context.isHTML = true; // in HTML namespace (case-insensitive match)\n context.getElementsByTagName = Element.prototype.getElementsByTagName;\n context.nextElement =\n Object.getOwnPropertyDescriptor(Element.prototype, 'firstElementChild').\n get;\n // invoke zest\n var nodes = select(selector, context);\n return nodes.item ? nodes : new NodeList(nodes);\n }},\n\n // Utility methods\n clone: { value: function clone() {\n return new DocumentFragment(this.ownerDocument);\n }},\n isEqual: { value: function isEqual(n) {\n // Any two document fragments are shallowly equal.\n // Node.isEqualNode() will test their children for equality\n return true;\n }},\n\n // Non-standard, but useful (github issue #73)\n innerHTML: {\n get: function() { return this.serialize(); },\n set: utils.nyi\n },\n outerHTML: {\n get: function() { return this.serialize(); },\n set: utils.nyi\n },\n\n});\n","\"use strict\";\nmodule.exports = ProcessingInstruction;\n\nvar Node = require('./Node');\nvar CharacterData = require('./CharacterData');\n\nfunction ProcessingInstruction(doc, target, data) {\n CharacterData.call(this);\n this.nodeType = Node.PROCESSING_INSTRUCTION_NODE;\n this.ownerDocument = doc;\n this.target = target;\n this._data = data;\n}\n\nvar nodeValue = {\n get: function() { return this._data; },\n set: function(v) {\n if (v === null || v === undefined) { v = ''; } else { v = String(v); }\n this._data = v;\n if (this.rooted) this.ownerDocument.mutateValue(this);\n }\n};\n\nProcessingInstruction.prototype = Object.create(CharacterData.prototype, {\n nodeName: { get: function() { return this.target; }},\n nodeValue: nodeValue,\n textContent: nodeValue,\n innerText: nodeValue,\n data: {\n get: nodeValue.get,\n set: function(v) {\n nodeValue.set.call(this, v===null ? '' : String(v));\n },\n },\n\n // Utility methods\n clone: { value: function clone() {\n return new ProcessingInstruction(this.ownerDocument, this.target, this._data);\n }},\n isEqual: { value: function isEqual(n) {\n return this.target === n.target && this._data === n._data;\n }}\n\n});\n","\"use strict\";\nvar NodeFilter = {\n // Constants for acceptNode()\n FILTER_ACCEPT: 1,\n FILTER_REJECT: 2,\n FILTER_SKIP: 3,\n\n // Constants for whatToShow\n SHOW_ALL: 0xFFFFFFFF,\n SHOW_ELEMENT: 0x1,\n SHOW_ATTRIBUTE: 0x2, // historical\n SHOW_TEXT: 0x4,\n SHOW_CDATA_SECTION: 0x8, // historical\n SHOW_ENTITY_REFERENCE: 0x10, // historical\n SHOW_ENTITY: 0x20, // historical\n SHOW_PROCESSING_INSTRUCTION: 0x40,\n SHOW_COMMENT: 0x80,\n SHOW_DOCUMENT: 0x100,\n SHOW_DOCUMENT_TYPE: 0x200,\n SHOW_DOCUMENT_FRAGMENT: 0x400,\n SHOW_NOTATION: 0x800 // historical\n};\n\nmodule.exports = (NodeFilter.constructor = NodeFilter.prototype = NodeFilter);\n","\"use strict\";\n/* exported NodeTraversal */\nvar NodeTraversal = module.exports = {\n nextSkippingChildren: nextSkippingChildren,\n nextAncestorSibling: nextAncestorSibling,\n next: next,\n previous: previous,\n deepLastChild: deepLastChild\n};\n\n/**\n * @based on WebKit's NodeTraversal::nextSkippingChildren\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L109\n */\nfunction nextSkippingChildren(node, stayWithin) {\n if (node === stayWithin) {\n return null;\n }\n if (node.nextSibling !== null) {\n return node.nextSibling;\n }\n return nextAncestorSibling(node, stayWithin);\n}\n\n/**\n * @based on WebKit's NodeTraversal::nextAncestorSibling\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.cpp?rev=179143#L93\n */\nfunction nextAncestorSibling(node, stayWithin) {\n for (node = node.parentNode; node !== null; node = node.parentNode) {\n if (node === stayWithin) {\n return null;\n }\n if (node.nextSibling !== null) {\n return node.nextSibling;\n }\n }\n return null;\n}\n\n/**\n * @based on WebKit's NodeTraversal::next\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L99\n */\nfunction next(node, stayWithin) {\n var n;\n n = node.firstChild;\n if (n !== null) {\n return n;\n }\n if (node === stayWithin) {\n return null;\n }\n n = node.nextSibling;\n if (n !== null) {\n return n;\n }\n return nextAncestorSibling(node, stayWithin);\n}\n\n/**\n * @based on WebKit's NodeTraversal::deepLastChild\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.cpp?rev=179143#L116\n */\nfunction deepLastChild(node) {\n while (node.lastChild) {\n node = node.lastChild;\n }\n return node;\n}\n\n/**\n * @based on WebKit's NodeTraversal::previous\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L121\n */\nfunction previous(node, stayWithin) {\n var p;\n p = node.previousSibling;\n if (p !== null) {\n return deepLastChild(p);\n }\n p = node.parentNode;\n if (p === stayWithin) {\n return null;\n }\n return p;\n}\n","\"use strict\";\nmodule.exports = TreeWalker;\n\nvar Node = require('./Node');\nvar NodeFilter = require('./NodeFilter');\nvar NodeTraversal = require('./NodeTraversal');\nvar utils = require('./utils');\n\nvar mapChild = {\n first: 'firstChild',\n last: 'lastChild',\n next: 'firstChild',\n previous: 'lastChild'\n};\n\nvar mapSibling = {\n first: 'nextSibling',\n last: 'previousSibling',\n next: 'nextSibling',\n previous: 'previousSibling'\n};\n\n/* Private methods and helpers */\n\n/**\n * @spec https://dom.spec.whatwg.org/#concept-traverse-children\n * @method\n * @access private\n * @param {TreeWalker} tw\n * @param {string} type One of 'first' or 'last'.\n * @return {Node|null}\n */\nfunction traverseChildren(tw, type) {\n var child, node, parent, result, sibling;\n node = tw._currentNode[mapChild[type]];\n while (node !== null) {\n result = tw._internalFilter(node);\n if (result === NodeFilter.FILTER_ACCEPT) {\n tw._currentNode = node;\n return node;\n }\n if (result === NodeFilter.FILTER_SKIP) {\n child = node[mapChild[type]];\n if (child !== null) {\n node = child;\n continue;\n }\n }\n while (node !== null) {\n sibling = node[mapSibling[type]];\n if (sibling !== null) {\n node = sibling;\n break;\n }\n parent = node.parentNode;\n if (parent === null || parent === tw.root || parent === tw._currentNode) {\n return null;\n } else {\n node = parent;\n }\n }\n }\n return null;\n}\n\n/**\n * @spec https://dom.spec.whatwg.org/#concept-traverse-siblings\n * @method\n * @access private\n * @param {TreeWalker} tw\n * @param {TreeWalker} type One of 'next' or 'previous'.\n * @return {Node|nul}\n */\nfunction traverseSiblings(tw, type) {\n var node, result, sibling;\n node = tw._currentNode;\n if (node === tw.root) {\n return null;\n }\n while (true) {\n sibling = node[mapSibling[type]];\n while (sibling !== null) {\n node = sibling;\n result = tw._internalFilter(node);\n if (result === NodeFilter.FILTER_ACCEPT) {\n tw._currentNode = node;\n return node;\n }\n sibling = node[mapChild[type]];\n if (result === NodeFilter.FILTER_REJECT || sibling === null) {\n sibling = node[mapSibling[type]];\n }\n }\n node = node.parentNode;\n if (node === null || node === tw.root) {\n return null;\n }\n if (tw._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {\n return null;\n }\n }\n}\n\n\n/* Public API */\n\n/**\n * Latest version: https://dom.spec.whatwg.org/#treewalker\n *\n * @constructor\n * @param {Node} root\n * @param {number} whatToShow [optional]\n * @param {Function|NodeFilter} filter [optional]\n * @throws Error\n */\nfunction TreeWalker(root, whatToShow, filter) {\n if (!root || !root.nodeType) {\n utils.NotSupportedError();\n }\n\n // Read-only properties\n this._root = root;\n this._whatToShow = Number(whatToShow) || 0;\n this._filter = filter || null;\n this._active = false;\n // Read-write property\n this._currentNode = root;\n}\n\nObject.defineProperties(TreeWalker.prototype, {\n root: { get: function() { return this._root; } },\n whatToShow: { get: function() { return this._whatToShow; } },\n filter: { get: function() { return this._filter; } },\n\n currentNode: {\n get: function currentNode() {\n return this._currentNode;\n },\n set: function setCurrentNode(v) {\n if (!(v instanceof Node)) {\n throw new TypeError(\"Not a Node\"); // `null` is also not a node\n }\n this._currentNode = v;\n },\n },\n\n /**\n * @method\n * @param {Node} node\n * @return {Number} Constant NodeFilter.FILTER_ACCEPT,\n * NodeFilter.FILTER_REJECT or NodeFilter.FILTER_SKIP.\n */\n _internalFilter: { value: function _internalFilter(node) {\n /* jshint bitwise: false */\n var result, filter;\n if (this._active) {\n utils.InvalidStateError();\n }\n\n // Maps nodeType to whatToShow\n if (!(((1 << (node.nodeType - 1)) & this._whatToShow))) {\n return NodeFilter.FILTER_SKIP;\n }\n\n filter = this._filter;\n if (filter === null) {\n result = NodeFilter.FILTER_ACCEPT;\n } else {\n this._active = true;\n try {\n if (typeof filter === 'function') {\n result = filter(node);\n } else {\n result = filter.acceptNode(node);\n }\n } finally {\n this._active = false;\n }\n }\n\n // Note that coercing to a number means that\n // `true` becomes `1` (which is NodeFilter.FILTER_ACCEPT)\n // `false` becomes `0` (neither accept, reject, or skip)\n return (+result);\n }},\n\n /**\n * @spec https://dom.spec.whatwg.org/#dom-treewalker-parentnode\n * @based on WebKit's TreeWalker::parentNode\n * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L50\n * @method\n * @return {Node|null}\n */\n parentNode: { value: function parentNode() {\n var node = this._currentNode;\n while (node !== this.root) {\n node = node.parentNode;\n if (node === null) {\n return null;\n }\n if (this._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {\n this._currentNode = node;\n return node;\n }\n }\n return null;\n }},\n\n /**\n * @spec https://dom.spec.whatwg.org/#dom-treewalker-firstchild\n * @method\n * @return {Node|null}\n */\n firstChild: { value: function firstChild() {\n return traverseChildren(this, 'first');\n }},\n\n /**\n * @spec https://dom.spec.whatwg.org/#dom-treewalker-lastchild\n * @method\n * @return {Node|null}\n */\n lastChild: { value: function lastChild() {\n return traverseChildren(this, 'last');\n }},\n\n /**\n * @spec http://www.w3.org/TR/dom/#dom-treewalker-previoussibling\n * @method\n * @return {Node|null}\n */\n previousSibling: { value: function previousSibling() {\n return traverseSiblings(this, 'previous');\n }},\n\n /**\n * @spec http://www.w3.org/TR/dom/#dom-treewalker-nextsibling\n * @method\n * @return {Node|null}\n */\n nextSibling: { value: function nextSibling() {\n return traverseSiblings(this, 'next');\n }},\n\n /**\n * @spec https://dom.spec.whatwg.org/#dom-treewalker-previousnode\n * @based on WebKit's TreeWalker::previousNode\n * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L181\n * @method\n * @return {Node|null}\n */\n previousNode: { value: function previousNode() {\n var node, result, previousSibling, lastChild;\n node = this._currentNode;\n while (node !== this._root) {\n for (previousSibling = node.previousSibling;\n previousSibling;\n previousSibling = node.previousSibling) {\n node = previousSibling;\n result = this._internalFilter(node);\n if (result === NodeFilter.FILTER_REJECT) {\n continue;\n }\n for (lastChild = node.lastChild;\n lastChild;\n lastChild = node.lastChild) {\n node = lastChild;\n result = this._internalFilter(node);\n if (result === NodeFilter.FILTER_REJECT) {\n break;\n }\n }\n if (result === NodeFilter.FILTER_ACCEPT) {\n this._currentNode = node;\n return node;\n }\n }\n if (node === this.root || node.parentNode === null) {\n return null;\n }\n node = node.parentNode;\n if (this._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {\n this._currentNode = node;\n return node;\n }\n }\n return null;\n }},\n\n /**\n * @spec https://dom.spec.whatwg.org/#dom-treewalker-nextnode\n * @based on WebKit's TreeWalker::nextNode\n * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L228\n * @method\n * @return {Node|null}\n */\n nextNode: { value: function nextNode() {\n var node, result, firstChild, nextSibling;\n node = this._currentNode;\n result = NodeFilter.FILTER_ACCEPT;\n\n CHILDREN:\n while (true) {\n for (firstChild = node.firstChild;\n firstChild;\n firstChild = node.firstChild) {\n node = firstChild;\n result = this._internalFilter(node);\n if (result === NodeFilter.FILTER_ACCEPT) {\n this._currentNode = node;\n return node;\n } else if (result === NodeFilter.FILTER_REJECT) {\n break;\n }\n }\n for (nextSibling = NodeTraversal.nextSkippingChildren(node, this.root);\n nextSibling;\n nextSibling = NodeTraversal.nextSkippingChildren(node, this.root)) {\n node = nextSibling;\n result = this._internalFilter(node);\n if (result === NodeFilter.FILTER_ACCEPT) {\n this._currentNode = node;\n return node;\n } else if (result === NodeFilter.FILTER_SKIP) {\n continue CHILDREN;\n }\n }\n return null;\n }\n }},\n\n /** For compatibility with web-platform-tests. */\n toString: { value: function toString() {\n return \"[object TreeWalker]\";\n }},\n});\n","\"use strict\";\nmodule.exports = NodeIterator;\n\nvar NodeFilter = require('./NodeFilter');\nvar NodeTraversal = require('./NodeTraversal');\nvar utils = require('./utils');\n\n/* Private methods and helpers */\n\n/**\n * @based on WebKit's NodeIterator::moveToNext and NodeIterator::moveToPrevious\n * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeIterator.cpp?rev=186279#L51\n */\nfunction move(node, stayWithin, directionIsNext) {\n if (directionIsNext) {\n return NodeTraversal.next(node, stayWithin);\n } else {\n if (node === stayWithin) {\n return null;\n }\n return NodeTraversal.previous(node, null);\n }\n}\n\nfunction isInclusiveAncestor(node, possibleChild) {\n for ( ; possibleChild; possibleChild = possibleChild.parentNode) {\n if (node === possibleChild) { return true; }\n }\n return false;\n}\n\n/**\n * @spec http://www.w3.org/TR/dom/#concept-nodeiterator-traverse\n * @method\n * @access private\n * @param {NodeIterator} ni\n * @param {string} direction One of 'next' or 'previous'.\n * @return {Node|null}\n */\nfunction traverse(ni, directionIsNext) {\n var node, beforeNode;\n node = ni._referenceNode;\n beforeNode = ni._pointerBeforeReferenceNode;\n while (true) {\n if (beforeNode === directionIsNext) {\n beforeNode = !beforeNode;\n } else {\n node = move(node, ni._root, directionIsNext);\n if (node === null) {\n return null;\n }\n }\n var result = ni._internalFilter(node);\n if (result === NodeFilter.FILTER_ACCEPT) {\n break;\n }\n }\n ni._referenceNode = node;\n ni._pointerBeforeReferenceNode = beforeNode;\n return node;\n}\n\n/* Public API */\n\n/**\n * Implemented version: http://www.w3.org/TR/2015/WD-dom-20150618/#nodeiterator\n * Latest version: http://www.w3.org/TR/dom/#nodeiterator\n *\n * @constructor\n * @param {Node} root\n * @param {number} whatToShow [optional]\n * @param {Function|NodeFilter} filter [optional]\n * @throws Error\n */\nfunction NodeIterator(root, whatToShow, filter) {\n if (!root || !root.nodeType) {\n utils.NotSupportedError();\n }\n\n // Read-only properties\n this._root = root;\n this._referenceNode = root;\n this._pointerBeforeReferenceNode = true;\n this._whatToShow = Number(whatToShow) || 0;\n this._filter = filter || null;\n this._active = false;\n // Record active node iterators in the document, in order to perform\n // \"node iterator pre-removal steps\".\n root.doc._attachNodeIterator(this);\n}\n\nObject.defineProperties(NodeIterator.prototype, {\n root: { get: function root() {\n return this._root;\n } },\n referenceNode: { get: function referenceNode() {\n return this._referenceNode;\n } },\n pointerBeforeReferenceNode: { get: function pointerBeforeReferenceNode() {\n return this._pointerBeforeReferenceNode;\n } },\n whatToShow: { get: function whatToShow() {\n return this._whatToShow;\n } },\n filter: { get: function filter() {\n return this._filter;\n } },\n\n /**\n * @method\n * @param {Node} node\n * @return {Number} Constant NodeFilter.FILTER_ACCEPT,\n * NodeFilter.FILTER_REJECT or NodeFilter.FILTER_SKIP.\n */\n _internalFilter: { value: function _internalFilter(node) {\n /* jshint bitwise: false */\n var result, filter;\n if (this._active) {\n utils.InvalidStateError();\n }\n\n // Maps nodeType to whatToShow\n if (!(((1 << (node.nodeType - 1)) & this._whatToShow))) {\n return NodeFilter.FILTER_SKIP;\n }\n\n filter = this._filter;\n if (filter === null) {\n result = NodeFilter.FILTER_ACCEPT;\n } else {\n this._active = true;\n try {\n if (typeof filter === 'function') {\n result = filter(node);\n } else {\n result = filter.acceptNode(node);\n }\n } finally {\n this._active = false;\n }\n }\n\n // Note that coercing to a number means that\n // `true` becomes `1` (which is NodeFilter.FILTER_ACCEPT)\n // `false` becomes `0` (neither accept, reject, or skip)\n return (+result);\n } },\n\n /**\n * @spec https://dom.spec.whatwg.org/#nodeiterator-pre-removing-steps\n * @method\n * @return void\n */\n _preremove: { value: function _preremove(toBeRemovedNode) {\n if (isInclusiveAncestor(toBeRemovedNode, this._root)) { return; }\n if (!isInclusiveAncestor(toBeRemovedNode, this._referenceNode)) { return; }\n if (this._pointerBeforeReferenceNode) {\n var next = toBeRemovedNode;\n while (next.lastChild) {\n next = next.lastChild;\n }\n next = NodeTraversal.next(next, this.root);\n if (next) {\n this._referenceNode = next;\n return;\n }\n this._pointerBeforeReferenceNode = false;\n // fall through\n }\n if (toBeRemovedNode.previousSibling === null) {\n this._referenceNode = toBeRemovedNode.parentNode;\n } else {\n this._referenceNode = toBeRemovedNode.previousSibling;\n var lastChild;\n for (lastChild = this._referenceNode.lastChild;\n lastChild;\n lastChild = this._referenceNode.lastChild) {\n this._referenceNode = lastChild;\n }\n }\n } },\n\n /**\n * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-nextnode\n * @method\n * @return {Node|null}\n */\n nextNode: { value: function nextNode() {\n return traverse(this, true);\n } },\n\n /**\n * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-previousnode\n * @method\n * @return {Node|null}\n */\n previousNode: { value: function previousNode() {\n return traverse(this, false);\n } },\n\n /**\n * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-detach\n * @method\n * @return void\n */\n detach: { value: function detach() {\n /* \"The detach() method must do nothing.\n * Its functionality (disabling a NodeIterator object) was removed,\n * but the method itself is preserved for compatibility.\n */\n } },\n\n /** For compatibility with web-platform-tests. */\n toString: { value: function toString() {\n return \"[object NodeIterator]\";\n } },\n});\n","\"use strict\";\nmodule.exports = URL;\n\nfunction URL(url) {\n if (!url) return Object.create(URL.prototype);\n // Can't use String.trim() since it defines whitespace differently than HTML\n this.url = url.replace(/^[ \\t\\n\\r\\f]+|[ \\t\\n\\r\\f]+$/g, \"\");\n\n // See http://tools.ietf.org/html/rfc3986#appendix-B\n // and https://url.spec.whatwg.org/#parsing\n var match = URL.pattern.exec(this.url);\n if (match) {\n if (match[2]) this.scheme = match[2];\n if (match[4]) {\n // parse username/password\n var userinfo = match[4].match(URL.userinfoPattern);\n if (userinfo) {\n this.username = userinfo[1];\n this.password = userinfo[3];\n match[4] = match[4].substring(userinfo[0].length);\n }\n if (match[4].match(URL.portPattern)) {\n var pos = match[4].lastIndexOf(':');\n this.host = match[4].substring(0, pos);\n this.port = match[4].substring(pos+1);\n }\n else {\n this.host = match[4];\n }\n }\n if (match[5]) this.path = match[5];\n if (match[6]) this.query = match[7];\n if (match[8]) this.fragment = match[9];\n }\n}\n\nURL.pattern = /^(([^:\\/?#]+):)?(\\/\\/([^\\/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/;\nURL.userinfoPattern = /^([^@:]*)(:([^@]*))?@/;\nURL.portPattern = /:\\d+$/;\nURL.authorityPattern = /^[^:\\/?#]+:\\/\\//;\nURL.hierarchyPattern = /^[^:\\/?#]+:\\//;\n\n// Return a percentEncoded version of s.\n// S should be a single-character string\n// XXX: needs to do utf-8 encoding?\nURL.percentEncode = function percentEncode(s) {\n var c = s.charCodeAt(0);\n if (c < 256) return \"%\" + c.toString(16);\n else throw Error(\"can't percent-encode codepoints > 255 yet\");\n};\n\nURL.prototype = {\n constructor: URL,\n\n // XXX: not sure if this is the precise definition of absolute\n isAbsolute: function() { return !!this.scheme; },\n isAuthorityBased: function() {\n return URL.authorityPattern.test(this.url);\n },\n isHierarchical: function() {\n return URL.hierarchyPattern.test(this.url);\n },\n\n toString: function() {\n var s = \"\";\n if (this.scheme !== undefined) s += this.scheme + \":\";\n if (this.isAbsolute()) {\n s += '//';\n if (this.username || this.password) {\n s += this.username || '';\n if (this.password) {\n s += ':' + this.password;\n }\n s += '@';\n }\n if (this.host) {\n s += this.host;\n }\n }\n if (this.port !== undefined) s += \":\" + this.port;\n if (this.path !== undefined) s += this.path;\n if (this.query !== undefined) s += \"?\" + this.query;\n if (this.fragment !== undefined) s += \"#\" + this.fragment;\n return s;\n },\n\n // See: http://tools.ietf.org/html/rfc3986#section-5.2\n // and https://url.spec.whatwg.org/#constructors\n resolve: function(relative) {\n var base = this; // The base url we're resolving against\n var r = new URL(relative); // The relative reference url to resolve\n var t = new URL(); // The absolute target url we will return\n\n if (r.scheme !== undefined) {\n t.scheme = r.scheme;\n t.username = r.username;\n t.password = r.password;\n t.host = r.host;\n t.port = r.port;\n t.path = remove_dot_segments(r.path);\n t.query = r.query;\n }\n else {\n t.scheme = base.scheme;\n if (r.host !== undefined) {\n t.username = r.username;\n t.password = r.password;\n t.host = r.host;\n t.port = r.port;\n t.path = remove_dot_segments(r.path);\n t.query = r.query;\n }\n else {\n t.username = base.username;\n t.password = base.password;\n t.host = base.host;\n t.port = base.port;\n if (!r.path) { // undefined or empty\n t.path = base.path;\n if (r.query !== undefined)\n t.query = r.query;\n else\n t.query = base.query;\n }\n else {\n if (r.path.charAt(0) === \"/\") {\n t.path = remove_dot_segments(r.path);\n }\n else {\n t.path = merge(base.path, r.path);\n t.path = remove_dot_segments(t.path);\n }\n t.query = r.query;\n }\n }\n }\n t.fragment = r.fragment;\n\n return t.toString();\n\n\n function merge(basepath, refpath) {\n if (base.host !== undefined && !base.path)\n return \"/\" + refpath;\n\n var lastslash = basepath.lastIndexOf(\"/\");\n if (lastslash === -1)\n return refpath;\n else\n return basepath.substring(0, lastslash+1) + refpath;\n }\n\n function remove_dot_segments(path) {\n if (!path) return path; // For \"\" or undefined\n\n var output = \"\";\n while(path.length > 0) {\n if (path === \".\" || path === \"..\") {\n path = \"\";\n break;\n }\n\n var twochars = path.substring(0,2);\n var threechars = path.substring(0,3);\n var fourchars = path.substring(0,4);\n if (threechars === \"../\") {\n path = path.substring(3);\n }\n else if (twochars === \"./\") {\n path = path.substring(2);\n }\n else if (threechars === \"/./\") {\n path = \"/\" + path.substring(3);\n }\n else if (twochars === \"/.\" && path.length === 2) {\n path = \"/\";\n }\n else if (fourchars === \"/../\" ||\n (threechars === \"/..\" && path.length === 3)) {\n path = \"/\" + path.substring(4);\n\n output = output.replace(/\\/?[^\\/]*$/, \"\");\n }\n else {\n var segment = path.match(/(\\/?([^\\/]*))/)[0];\n output += segment;\n path = path.substring(segment.length);\n }\n }\n\n return output;\n }\n },\n};\n","\"use strict\";\nmodule.exports = CustomEvent;\n\nvar Event = require('./Event');\n\nfunction CustomEvent(type, dictionary) {\n // Just use the superclass constructor to initialize\n Event.call(this, type, dictionary);\n}\nCustomEvent.prototype = Object.create(Event.prototype, {\n constructor: { value: CustomEvent }\n});\n","\"use strict\";\nmodule.exports = {\n Event: require('./Event'),\n UIEvent: require('./UIEvent'),\n MouseEvent: require('./MouseEvent'),\n CustomEvent: require('./CustomEvent')\n};\n","\"use strict\";\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n// The below is a compiled copy of https://github.com/angular/angular/blob/92e41e9cb417223d9888a4c23b4c0e73188f87d0/packages/compiler/src/render3/view/style_parser.ts\n\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.hyphenate = exports.parse = void 0;\n/**\n * Parses string representation of a style and converts it into object literal.\n *\n * @param value string representation of style as used in the `style` attribute in HTML.\n * Example: `color: red; height: auto`.\n * @returns An array of style property name and value pairs, e.g. `['color', 'red', 'height',\n * 'auto']`\n */\nfunction parse(value) {\n // we use a string array here instead of a string map\n // because a string-map is not guaranteed to retain the\n // order of the entries whereas a string array can be\n // constructed in a [key, value, key, value] format.\n const styles = [];\n let i = 0;\n let parenDepth = 0;\n let quote = 0; /* Char.QuoteNone */\n let valueStart = 0;\n let propStart = 0;\n let currentProp = null;\n while (i < value.length) {\n const token = value.charCodeAt(i++);\n switch (token) {\n case 40 /* Char.OpenParen */:\n parenDepth++;\n break;\n case 41 /* Char.CloseParen */:\n parenDepth--;\n break;\n case 39 /* Char.QuoteSingle */:\n // valueStart needs to be there since prop values don't\n // have quotes in CSS\n if (quote === 0 /* Char.QuoteNone */) {\n quote = 39 /* Char.QuoteSingle */;\n } else if (\n quote === 39 /* Char.QuoteSingle */ &&\n value.charCodeAt(i - 1) !== 92 /* Char.BackSlash */\n ) {\n quote = 0 /* Char.QuoteNone */;\n }\n break;\n case 34 /* Char.QuoteDouble */:\n // same logic as above\n if (quote === 0 /* Char.QuoteNone */) {\n quote = 34 /* Char.QuoteDouble */;\n } else if (\n quote === 34 /* Char.QuoteDouble */ &&\n value.charCodeAt(i - 1) !== 92 /* Char.BackSlash */\n ) {\n quote = 0 /* Char.QuoteNone */;\n }\n break;\n case 58 /* Char.Colon */:\n if (\n !currentProp &&\n parenDepth === 0 &&\n quote === 0 /* Char.QuoteNone */\n ) {\n currentProp = hyphenate(value.substring(propStart, i - 1).trim());\n valueStart = i;\n }\n break;\n case 59 /* Char.Semicolon */:\n if (\n currentProp &&\n valueStart > 0 &&\n parenDepth === 0 &&\n quote === 0 /* Char.QuoteNone */\n ) {\n const styleVal = value.substring(valueStart, i - 1).trim();\n styles.push(currentProp, styleVal);\n propStart = i;\n valueStart = 0;\n currentProp = null;\n }\n break;\n }\n }\n if (currentProp && valueStart) {\n const styleVal = value.slice(valueStart).trim();\n styles.push(currentProp, styleVal);\n }\n return styles;\n}\nexports.parse = parse;\nfunction hyphenate(value) {\n return value\n .replace(/[a-z][A-Z]/g, (v) => {\n return v.charAt(0) + \"-\" + v.charAt(1);\n })\n .toLowerCase();\n}\nexports.hyphenate = hyphenate;\n","\"use strict\";\n\nconst { parse } = require('./style_parser');\n\nmodule.exports = function (elt) {\n const style = new CSSStyleDeclaration(elt)\n const handler = {\n get: function(target, property) {\n return property in target ? target[property] : target.getPropertyValue(dasherizeProperty(property));\n },\n has: function(target, key) {\n return true;\n },\n set: function(target, property, value) {\n if (property in target) {\n target[property] = value;\n } else {\n target.setProperty(dasherizeProperty(property), value ?? undefined);\n }\n\n return true;\n }\n };\n\n return new Proxy(style, handler);\n};\n\nfunction dasherizeProperty(property) {\n return property.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\n\nfunction CSSStyleDeclaration(elt) {\n this._element = elt;\n}\n\nconst IMPORTANT_BANG = '!important';\n\n// Utility function for parsing style declarations\n// Pass in a string like \"margin-left: 5px; border-style: solid\"\n// and this function returns an object like\n// {\"margin-left\":\"5px\", \"border-style\":\"solid\"}\nfunction parseStyles(value) {\n const result = {\n property: {},\n priority: {},\n }\n\n if (!value) {\n return result;\n }\n\n const styleValues = parse(value);\n if (styleValues.length < 2) {\n return result;\n }\n\n for (let i = 0; i < styleValues.length; i += 2) {\n const name = styleValues[i];\n let value = styleValues[i+1];\n\n if (value.endsWith(IMPORTANT_BANG)) {\n result.priority[name] = 'important';\n value = value.slice(0, -IMPORTANT_BANG.length).trim();\n }\n\n result.property[name] = value;\n }\n\n return result;\n}\n\nvar NO_CHANGE = {}; // Private marker object\n\nCSSStyleDeclaration.prototype = Object.create(Object.prototype, {\n\n // Return the parsed form of the element's style attribute.\n // If the element's style attribute has never been parsed\n // or if it has changed since the last parse, then reparse it\n // Note that the styles don't get parsed until they're actually needed\n _parsed: { get: function() {\n if (!this._parsedStyles || this.cssText !== this._lastParsedText) {\n var text = this.cssText;\n this._parsedStyles = parseStyles(text);\n this._lastParsedText = text;\n delete this._names;\n }\n return this._parsedStyles;\n }},\n\n // Call this method any time the parsed representation of the\n // style changes. It converts the style properties to a string and\n // sets cssText and the element's style attribute\n _serialize: { value: function() {\n var styles = this._parsed;\n var s = \"\";\n\n for(var name in styles.property) {\n if (s) s += \" \";\n s += name + \": \" + styles.property[name];\n if (styles.priority[name]) {\n s += \" !\" + styles.priority[name];\n }\n s += \";\";\n }\n\n this.cssText = s; // also sets the style attribute\n this._lastParsedText = s; // so we don't reparse\n delete this._names;\n }},\n\n cssText: {\n get: function() {\n // XXX: this is a CSSStyleDeclaration for an element.\n // A different impl might be necessary for a set of styles\n // associated returned by getComputedStyle(), e.g.\n return this._element.getAttribute(\"style\");\n },\n set: function(value) {\n // XXX: I should parse and serialize the value to\n // normalize it and remove errors. FF and chrome do that.\n this._element.setAttribute(\"style\", value);\n }\n },\n\n length: { get: function() {\n if (!this._names)\n this._names = Object.getOwnPropertyNames(this._parsed.property);\n return this._names.length;\n }},\n\n item: { value: function(n) {\n if (!this._names)\n this._names = Object.getOwnPropertyNames(this._parsed.property);\n return this._names[n];\n }},\n\n getPropertyValue: { value: function(property) {\n property = property.toLowerCase();\n return this._parsed.property[property] || \"\";\n }},\n\n getPropertyPriority: { value: function(property) {\n property = property.toLowerCase();\n return this._parsed.priority[property] || \"\";\n }},\n\n setProperty: { value: function(property, value, priority) {\n property = property.toLowerCase();\n if (value === null || value === undefined) {\n value = \"\";\n }\n if (priority === null || priority === undefined) {\n priority = \"\";\n }\n\n // String coercion\n if (value !== NO_CHANGE) {\n value = \"\" + value;\n }\n\n value = value.trim();\n if (value === \"\") {\n this.removeProperty(property);\n return;\n }\n\n if (priority !== \"\" && priority !== NO_CHANGE &&\n !/^important$/i.test(priority)) {\n return;\n }\n\n var styles = this._parsed;\n if (value === NO_CHANGE) {\n if (!styles.property[property]) {\n return; // Not a valid property name.\n }\n if (priority !== \"\") {\n styles.priority[property] = \"important\";\n } else {\n delete styles.priority[property];\n }\n } else {\n // We don't just accept the property value. Instead\n // we parse it to ensure that it is something valid.\n // If it contains a semicolon it is invalid\n if (value.indexOf(\";\") !== -1) return;\n\n var newprops = parseStyles(property + \":\" + value);\n if (Object.getOwnPropertyNames(newprops.property).length === 0) {\n return; // no valid property found\n }\n if (Object.getOwnPropertyNames(newprops.priority).length !== 0) {\n return; // if the value included '!important' it wasn't valid.\n }\n\n // XXX handle shorthand properties\n\n for (var p in newprops.property) {\n styles.property[p] = newprops.property[p];\n if (priority === NO_CHANGE) {\n continue;\n } else if (priority !== \"\") {\n styles.priority[p] = \"important\";\n } else if (styles.priority[p]) {\n delete styles.priority[p];\n }\n }\n }\n\n // Serialize and update cssText and element.style!\n this._serialize();\n }},\n\n setPropertyValue: { value: function(property, value) {\n return this.setProperty(property, value, NO_CHANGE);\n }},\n\n setPropertyPriority: { value: function(property, priority) {\n return this.setProperty(property, NO_CHANGE, priority);\n }},\n\n removeProperty: { value: function(property) {\n property = property.toLowerCase();\n var styles = this._parsed;\n if (property in styles.property) {\n delete styles.property[property];\n delete styles.priority[property];\n\n // Serialize and update cssText and element.style!\n this._serialize();\n }\n }},\n});\n","\"use strict\";\nvar URL = require('./URL');\n\nmodule.exports = URLUtils;\n\n// Allow the `x == null` pattern. This is eslint's \"null: 'ignore'\" option,\n// but jshint doesn't support this.\n/* jshint eqeqeq: false */\n\n// This is an abstract superclass for Location, HTMLAnchorElement and\n// other types that have the standard complement of \"URL decomposition\n// IDL attributes\". This is now standardized as URLUtils, see:\n// https://url.spec.whatwg.org/#urlutils\n// Subclasses must define a getter/setter on href.\n// The getter and setter methods parse and rebuild the URL on each\n// invocation; there is no attempt to cache the value and be more efficient\nfunction URLUtils() {}\nURLUtils.prototype = Object.create(Object.prototype, {\n\n _url: { get: function() {\n // XXX: this should do the \"Reinitialize url\" steps, and \"null\" should\n // be a valid return value.\n return new URL(this.href);\n } },\n\n protocol: {\n get: function() {\n var url = this._url;\n if (url && url.scheme) return url.scheme + \":\";\n else return \":\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute()) {\n v = v.replace(/:+$/, \"\");\n v = v.replace(/[^-+\\.a-zA-Z0-9]/g, URL.percentEncode);\n if (v.length > 0) {\n url.scheme = v;\n output = url.toString();\n }\n }\n this.href = output;\n },\n },\n\n host: {\n get: function() {\n var url = this._url;\n if (url.isAbsolute() && url.isAuthorityBased())\n return url.host + (url.port ? (\":\" + url.port) : \"\");\n else\n return \"\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute() && url.isAuthorityBased()) {\n v = v.replace(/[^-+\\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);\n if (v.length > 0) {\n url.host = v;\n delete url.port;\n output = url.toString();\n }\n }\n this.href = output;\n },\n },\n\n hostname: {\n get: function() {\n var url = this._url;\n if (url.isAbsolute() && url.isAuthorityBased())\n return url.host;\n else\n return \"\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute() && url.isAuthorityBased()) {\n v = v.replace(/^\\/+/, \"\");\n v = v.replace(/[^-+\\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);\n if (v.length > 0) {\n url.host = v;\n output = url.toString();\n }\n }\n this.href = output;\n },\n },\n\n port: {\n get: function() {\n var url = this._url;\n if (url.isAbsolute() && url.isAuthorityBased() && url.port!==undefined)\n return url.port;\n else\n return \"\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute() && url.isAuthorityBased()) {\n v = '' + v;\n v = v.replace(/[^0-9].*$/, \"\");\n v = v.replace(/^0+/, \"\");\n if (v.length === 0) v = \"0\";\n if (parseInt(v, 10) <= 65535) {\n url.port = v;\n output = url.toString();\n }\n }\n this.href = output;\n },\n },\n\n pathname: {\n get: function() {\n var url = this._url;\n if (url.isAbsolute() && url.isHierarchical())\n return url.path;\n else\n return \"\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute() && url.isHierarchical()) {\n if (v.charAt(0) !== \"/\")\n v = \"/\" + v;\n v = v.replace(/[^-+\\._~!$&'()*,;:=@\\/a-zA-Z0-9]/g, URL.percentEncode);\n url.path = v;\n output = url.toString();\n }\n this.href = output;\n },\n },\n\n search: {\n get: function() {\n var url = this._url;\n if (url.isAbsolute() && url.isHierarchical() && url.query!==undefined)\n return \"?\" + url.query;\n else\n return \"\";\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute() && url.isHierarchical()) {\n if (v.charAt(0) === \"?\") v = v.substring(1);\n v = v.replace(/[^-+\\._~!$&'()*,;:=@\\/?a-zA-Z0-9]/g, URL.percentEncode);\n url.query = v;\n output = url.toString();\n }\n this.href = output;\n },\n },\n\n hash: {\n get: function() {\n var url = this._url;\n if (url == null || url.fragment == null || url.fragment === '') {\n return \"\";\n } else {\n return \"#\" + url.fragment;\n }\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n\n if (v.charAt(0) === \"#\") v = v.substring(1);\n v = v.replace(/[^-+\\._~!$&'()*,;:=@\\/?a-zA-Z0-9]/g, URL.percentEncode);\n url.fragment = v;\n output = url.toString();\n\n this.href = output;\n },\n },\n\n username: {\n get: function() {\n var url = this._url;\n return url.username || '';\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute()) {\n v = v.replace(/[\\x00-\\x1F\\x7F-\\uFFFF \"#<>?`\\/@\\\\:]/g, URL.percentEncode);\n url.username = v;\n output = url.toString();\n }\n this.href = output;\n },\n },\n\n password: {\n get: function() {\n var url = this._url;\n return url.password || '';\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n if (url.isAbsolute()) {\n if (v==='') {\n url.password = null;\n } else {\n v = v.replace(/[\\x00-\\x1F\\x7F-\\uFFFF \"#<>?`\\/@\\\\]/g, URL.percentEncode);\n url.password = v;\n }\n output = url.toString();\n }\n this.href = output;\n },\n },\n\n origin: { get: function() {\n var url = this._url;\n if (url == null) { return ''; }\n var originForPort = function(defaultPort) {\n var origin = [url.scheme, url.host, +url.port || defaultPort];\n // XXX should be \"unicode serialization\"\n return origin[0] + '://' + origin[1] +\n (origin[2] === defaultPort ? '' : (':' + origin[2]));\n };\n switch (url.scheme) {\n case 'ftp':\n return originForPort(21);\n case 'gopher':\n return originForPort(70);\n case 'http':\n case 'ws':\n return originForPort(80);\n case 'https':\n case 'wss':\n return originForPort(443);\n default:\n // this is what chrome does\n return url.scheme + '://';\n }\n } },\n\n /*\n searchParams: {\n get: function() {\n var url = this._url;\n // XXX\n },\n set: function(v) {\n var output = this.href;\n var url = new URL(output);\n // XXX\n this.href = output;\n },\n },\n */\n});\n\nURLUtils._inherit = function(proto) {\n // copy getters/setters from URLUtils to o.\n Object.getOwnPropertyNames(URLUtils.prototype).forEach(function(p) {\n if (p==='constructor' || p==='href') { return; }\n var desc = Object.getOwnPropertyDescriptor(URLUtils.prototype, p);\n Object.defineProperty(proto, p, desc);\n });\n};\n","\"use strict\";\n\nvar attributes = require('./attributes');\nvar isApiWritable = require(\"./config\").isApiWritable;\n\nmodule.exports = function(spec, defaultConstructor, tagList, tagNameToImpl) {\n var c = spec.ctor;\n if (c) {\n var props = spec.props || {};\n\n if (spec.attributes) {\n for (var n in spec.attributes) {\n var attr = spec.attributes[n];\n if (typeof attr !== 'object' || Array.isArray(attr)) attr = {type: attr};\n if (!attr.name) attr.name = n.toLowerCase();\n props[n] = attributes.property(attr);\n }\n }\n\n props.constructor = { value : c, writable: isApiWritable };\n c.prototype = Object.create((spec.superclass || defaultConstructor).prototype, props);\n if (spec.events) {\n addEventHandlers(c, spec.events);\n }\n tagList[spec.name] = c;\n }\n else {\n c = defaultConstructor;\n }\n\n (spec.tags || spec.tag && [spec.tag] || []).forEach(function(tag) {\n tagNameToImpl[tag] = c;\n });\n\n return c;\n};\n\nfunction EventHandlerBuilder(body, document, form, element) {\n this.body = body;\n this.document = document;\n this.form = form;\n this.element = element;\n}\n\nEventHandlerBuilder.prototype.build = function () {\n return () => {};\n};\n\nfunction EventHandlerChangeHandler(elt, name, oldval, newval) {\n var doc = elt.ownerDocument || Object.create(null);\n var form = elt.form || Object.create(null);\n elt[name] = new EventHandlerBuilder(newval, doc, form, elt).build();\n}\n\nfunction addEventHandlers(c, eventHandlerTypes) {\n var p = c.prototype;\n eventHandlerTypes.forEach(function(type) {\n // Define the event handler registration IDL attribute for this type\n Object.defineProperty(p, \"on\" + type, {\n get: function() {\n return this._getEventHandler(type);\n },\n set: function(v) {\n this._setEventHandler(type, v);\n },\n });\n\n // Define special behavior for the content attribute as well\n attributes.registerChangeHandler(c, \"on\" + type, EventHandlerChangeHandler);\n });\n}\n","\"use strict\";\nvar Node = require('./Node');\nvar Element = require('./Element');\nvar CSSStyleDeclaration = require('./CSSStyleDeclaration');\nvar utils = require('./utils');\nvar URLUtils = require('./URLUtils');\nvar defineElement = require('./defineElement');\n\nvar htmlElements = exports.elements = {};\nvar htmlNameToImpl = Object.create(null);\n\nexports.createElement = function(doc, localName, prefix) {\n var impl = htmlNameToImpl[localName] || HTMLUnknownElement;\n return new impl(doc, localName, prefix);\n};\n\nfunction define(spec) {\n return defineElement(spec, HTMLElement, htmlElements, htmlNameToImpl);\n}\n\nfunction URL(attr) {\n return {\n get: function() {\n var v = this._getattr(attr);\n if (v === null) { return ''; }\n var url = this.doc._resolve(v);\n return (url === null) ? v : url;\n },\n set: function(value) {\n this._setattr(attr, value);\n }\n };\n}\n\nfunction CORS(attr) {\n return {\n get: function() {\n var v = this._getattr(attr);\n if (v === null) { return null; }\n if (v.toLowerCase() === 'use-credentials') { return 'use-credentials'; }\n return 'anonymous';\n },\n set: function(value) {\n if (value===null || value===undefined) {\n this.removeAttribute(attr);\n } else {\n this._setattr(attr, value);\n }\n }\n };\n}\n\nconst REFERRER = {\n type: [\"\", \"no-referrer\", \"no-referrer-when-downgrade\", \"same-origin\", \"origin\", \"strict-origin\", \"origin-when-cross-origin\", \"strict-origin-when-cross-origin\", \"unsafe-url\"],\n missing: '',\n};\n\n\n// XXX: the default value for tabIndex should be 0 if the element is\n// focusable and -1 if it is not. But the full definition of focusable\n// is actually hard to compute, so for now, I'll follow Firefox and\n// just base the default value on the type of the element.\nvar focusableElements = {\n \"A\":true, \"LINK\":true, \"BUTTON\":true, \"INPUT\":true,\n \"SELECT\":true, \"TEXTAREA\":true, \"COMMAND\":true\n};\n\nvar HTMLFormElement = function(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n this._form = null; // Prevent later deoptimization\n};\n\nvar HTMLElement = exports.HTMLElement = define({\n superclass: Element,\n name: 'HTMLElement',\n ctor: function HTMLElement(doc, localName, prefix) {\n Element.call(this, doc, localName, utils.NAMESPACE.HTML, prefix);\n },\n props: {\n dangerouslySetInnerHTML: {\n set: function (v) {\n this._innerHTML = v;\n },\n },\n innerHTML: {\n get: function() {\n return this.serialize();\n },\n set: function(v) {\n var parser = this.ownerDocument.implementation.mozHTMLParser(\n this.ownerDocument._address,\n this);\n parser.parse(v===null ? '' : String(v), true);\n\n // Remove any existing children of this node\n var target = (this instanceof htmlNameToImpl.template) ?\n this.content : this;\n while(target.hasChildNodes())\n target.removeChild(target.firstChild);\n\n // Now copy newly parsed children to this node\n target.appendChild(parser._asDocumentFragment());\n }\n },\n style: { get: function() {\n if (!this._style)\n this._style = new CSSStyleDeclaration(this);\n return this._style;\n }, set: function(v) {\n if (v===null||v===undefined) { v = ''; }\n this._setattr('style', String(v));\n }},\n\n // These can't really be implemented server-side in a reasonable way.\n blur: { value: function() {}},\n focus: { value: function() {}},\n forceSpellCheck: { value: function() {}},\n\n click: { value: function() {\n if (this._click_in_progress) return;\n this._click_in_progress = true;\n try {\n if (this._pre_click_activation_steps)\n this._pre_click_activation_steps();\n\n var event = this.ownerDocument.createEvent(\"MouseEvent\");\n event.initMouseEvent(\"click\", true, true,\n this.ownerDocument.defaultView, 1,\n 0, 0, 0, 0,\n // These 4 should be initialized with\n // the actually current keyboard state\n // somehow...\n false, false, false, false,\n 0, null\n );\n\n // Dispatch this as an untrusted event since it is synthetic\n var success = this.dispatchEvent(event);\n\n if (success) {\n if (this._post_click_activation_steps)\n this._post_click_activation_steps(event);\n }\n else {\n if (this._cancelled_activation_steps)\n this._cancelled_activation_steps();\n }\n }\n finally {\n this._click_in_progress = false;\n }\n }},\n submit: { value: utils.nyi },\n },\n attributes: {\n title: String,\n lang: String,\n dir: {type: [\"ltr\", \"rtl\", \"auto\"], missing: ''},\n draggable: {type: [\"true\", \"false\"], treatNullAsEmptyString: true },\n spellcheck: {type: [\"true\", \"false\"], missing: ''},\n enterKeyHint: {type: [\"enter\", \"done\", \"go\", \"next\", \"previous\", \"search\", \"send\"], missing: ''},\n autoCapitalize: {type: [\"off\", \"on\", \"none\", \"sentences\", \"words\", \"characters\"], missing: '' },\n autoFocus: Boolean,\n accessKey: String,\n nonce: String,\n hidden: Boolean,\n translate: {type: [\"no\", \"yes\"], missing: '' },\n tabIndex: {type: \"long\", default: function() {\n if (this.tagName in focusableElements ||\n this.contentEditable)\n return 0;\n else\n return -1;\n }}\n },\n events: [\n \"abort\", \"canplay\", \"canplaythrough\", \"change\", \"click\", \"contextmenu\",\n \"cuechange\", \"dblclick\", \"drag\", \"dragend\", \"dragenter\", \"dragleave\",\n \"dragover\", \"dragstart\", \"drop\", \"durationchange\", \"emptied\", \"ended\",\n \"input\", \"invalid\", \"keydown\", \"keypress\", \"keyup\", \"loadeddata\",\n \"loadedmetadata\", \"loadstart\", \"mousedown\", \"mousemove\", \"mouseout\",\n \"mouseover\", \"mouseup\", \"mousewheel\", \"pause\", \"play\", \"playing\",\n \"progress\", \"ratechange\", \"readystatechange\", \"reset\", \"seeked\",\n \"seeking\", \"select\", \"show\", \"stalled\", \"submit\", \"suspend\",\n \"timeupdate\", \"volumechange\", \"waiting\",\n\n // These last 5 event types will be overriden by HTMLBodyElement\n \"blur\", \"error\", \"focus\", \"load\", \"scroll\"\n ]\n});\n\n\n// XXX: reflect contextmenu as contextMenu, with element type\n\n\n// style: the spec doesn't call this a reflected attribute.\n// may want to handle it manually.\n\n// contentEditable: enumerated, not clear if it is actually\n// reflected or requires custom getter/setter. Not listed as\n// \"limited to known values\". Raises syntax_err on bad setting,\n// so I think this is custom.\n\n// contextmenu: content is element id, idl type is an element\n// draggable: boolean, but not a reflected attribute\n// dropzone: reflected SettableTokenList, experimental, so don't\n// implement it right away.\n\n// data-* attributes: need special handling in setAttribute?\n// Or maybe that isn't necessary. Can I just scan the attribute list\n// when building the dataset? Liveness and caching issues?\n\n// microdata attributes: many are simple reflected attributes, but\n// I'm not going to implement this now.\n\n\nvar HTMLUnknownElement = define({\n name: 'HTMLUnknownElement',\n ctor: function HTMLUnknownElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\n\nvar formAssociatedProps = {\n // See http://www.w3.org/TR/html5/association-of-controls-and-forms.html#form-owner\n form: { get: function() {\n return this._form;\n }}\n};\n\ndefine({\n tag: 'a',\n name: 'HTMLAnchorElement',\n ctor: function HTMLAnchorElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n _post_click_activation_steps: { value: function(e) {\n if (this.href) {\n // Follow the link\n // XXX: this is just a quick hack\n // XXX: the HTML spec probably requires more than this\n this.ownerDocument.defaultView.location = this.href;\n }\n }},\n },\n attributes: {\n href: URL,\n ping: String,\n download: String,\n target: String,\n rel: String,\n media: String,\n hreflang: String,\n type: String,\n referrerPolicy: REFERRER,\n // Obsolete\n coords: String,\n charset: String,\n name: String,\n rev: String,\n shape: String,\n }\n});\n// Latest WhatWG spec says these methods come via HTMLHyperlinkElementUtils\nURLUtils._inherit(htmlNameToImpl.a.prototype);\n\ndefine({\n tag: 'area',\n name: 'HTMLAreaElement',\n ctor: function HTMLAreaElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n alt: String,\n target: String,\n download: String,\n rel: String,\n media: String,\n href: URL,\n hreflang: String,\n type: String,\n shape: String,\n coords: String,\n ping: String,\n // XXX: also reflect relList\n referrerPolicy: REFERRER,\n // Obsolete\n noHref: Boolean,\n }\n});\n// Latest WhatWG spec says these methods come via HTMLHyperlinkElementUtils\nURLUtils._inherit(htmlNameToImpl.area.prototype);\n\ndefine({\n tag: 'br',\n name: 'HTMLBRElement',\n ctor: function HTMLBRElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n clear: String\n },\n});\n\ndefine({\n tag: 'base',\n name: 'HTMLBaseElement',\n ctor: function HTMLBaseElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n \"target\": String\n }\n});\n\n\ndefine({\n tag: 'body',\n name: 'HTMLBodyElement',\n ctor: function HTMLBodyElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n // Certain event handler attributes on a tag actually set\n // handlers for the window rather than just that element. Define\n // getters and setters for those here. Note that some of these override\n // properties on HTMLElement.prototype.\n // XXX: If I add support for , these have to go there, too\n // XXX\n // When the Window object is implemented, these attribute will have\n // to work with the same-named attributes on the Window.\n events: [\n \"afterprint\", \"beforeprint\", \"beforeunload\", \"blur\", \"error\",\n \"focus\",\"hashchange\", \"load\", \"message\", \"offline\", \"online\",\n \"pagehide\", \"pageshow\",\"popstate\",\"resize\",\"scroll\",\"storage\",\"unload\",\n ],\n attributes: {\n // Obsolete\n text: { type: String, treatNullAsEmptyString: true },\n link: { type: String, treatNullAsEmptyString: true },\n vLink: { type: String, treatNullAsEmptyString: true },\n aLink: { type: String, treatNullAsEmptyString: true },\n bgColor: { type: String, treatNullAsEmptyString: true },\n background: String,\n }\n});\n\ndefine({\n tag: 'button',\n name: 'HTMLButtonElement',\n ctor: function HTMLButtonElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n name: String,\n value: String,\n disabled: Boolean,\n autofocus: Boolean,\n type: { type:[\"submit\", \"reset\", \"button\", \"menu\"], missing: 'submit' },\n formTarget: String,\n formAction: URL,\n formNoValidate: Boolean,\n formMethod: { type: [\"get\", \"post\", \"dialog\"], invalid: 'get', missing: '' },\n formEnctype: { type: [\"application/x-www-form-urlencoded\", \"multipart/form-data\", \"text/plain\"], invalid: \"application/x-www-form-urlencoded\", missing: '' },\n }\n});\n\ndefine({\n tag: 'dl',\n name: 'HTMLDListElement',\n ctor: function HTMLDListElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n compact: Boolean,\n }\n});\n\ndefine({\n tag: 'data',\n name: 'HTMLDataElement',\n ctor: function HTMLDataElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n value: String,\n }\n});\n\ndefine({\n tag: 'datalist',\n name: 'HTMLDataListElement',\n ctor: function HTMLDataListElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tag: 'details',\n name: 'HTMLDetailsElement',\n ctor: function HTMLDetailsElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n \"open\": Boolean\n }\n});\n\ndefine({\n tag: 'div',\n name: 'HTMLDivElement',\n ctor: function HTMLDivElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String\n }\n});\n\ndefine({\n tag: 'embed',\n name: 'HTMLEmbedElement',\n ctor: function HTMLEmbedElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n src: URL,\n type: String,\n width: String,\n height: String,\n // Obsolete\n align: String,\n name: String,\n }\n});\n\ndefine({\n tag: 'fieldset',\n name: 'HTMLFieldSetElement',\n ctor: function HTMLFieldSetElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n disabled: Boolean,\n name: String\n }\n});\n\ndefine({\n tag: 'form',\n name: 'HTMLFormElement',\n ctor: function HTMLFormElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n action: String,\n autocomplete: {type:['on', 'off'], missing: 'on'},\n name: String,\n acceptCharset: {name: \"accept-charset\"},\n target: String,\n noValidate: Boolean,\n method: { type: [\"get\", \"post\", \"dialog\"], invalid: 'get', missing: 'get' },\n // Both enctype and encoding reflect the enctype content attribute\n enctype: { type: [\"application/x-www-form-urlencoded\", \"multipart/form-data\", \"text/plain\"], invalid: \"application/x-www-form-urlencoded\", missing: \"application/x-www-form-urlencoded\" },\n encoding: {name: 'enctype', type: [\"application/x-www-form-urlencoded\", \"multipart/form-data\", \"text/plain\"], invalid: \"application/x-www-form-urlencoded\", missing: \"application/x-www-form-urlencoded\" },\n }\n});\n\ndefine({\n tag: 'hr',\n name: 'HTMLHRElement',\n ctor: function HTMLHRElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String,\n color: String,\n noShade: Boolean,\n size: String,\n width: String,\n },\n});\n\ndefine({\n tag: 'head',\n name: 'HTMLHeadElement',\n ctor: function HTMLHeadElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tags: ['h1','h2','h3','h4','h5','h6'],\n name: 'HTMLHeadingElement',\n ctor: function HTMLHeadingElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String,\n },\n});\n\ndefine({\n tag: 'html',\n name: 'HTMLHtmlElement',\n ctor: function HTMLHtmlElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n xmlns: URL,\n // Obsolete\n version: String\n }\n});\n\ndefine({\n tag: 'iframe',\n name: 'HTMLIFrameElement',\n ctor: function HTMLIFrameElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n src: URL,\n srcdoc: String,\n name: String,\n width: String,\n height: String,\n // XXX: sandbox is a reflected settable token list\n seamless: Boolean,\n allow: Boolean,\n allowFullscreen: Boolean,\n allowUserMedia: Boolean,\n allowPaymentRequest: Boolean,\n referrerPolicy: REFERRER,\n loading: { type:['eager','lazy'], treatNullAsEmptyString: true },\n // Obsolete\n align: String,\n scrolling: String,\n frameBorder: String,\n longDesc: URL,\n marginHeight: { type: String, treatNullAsEmptyString: true },\n marginWidth: { type: String, treatNullAsEmptyString: true },\n }\n});\n\ndefine({\n tag: 'img',\n name: 'HTMLImageElement',\n ctor: function HTMLImageElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n alt: String,\n src: URL,\n srcset: String,\n crossOrigin: CORS,\n useMap: String,\n isMap: Boolean,\n sizes: String,\n height: { type: \"unsigned long\", default: 0 },\n width: { type: \"unsigned long\", default: 0 },\n referrerPolicy: REFERRER,\n loading: { type:['eager','lazy'], missing: '' },\n // Obsolete:\n name: String,\n lowsrc: URL,\n align: String,\n hspace: { type: \"unsigned long\", default: 0 },\n vspace: { type: \"unsigned long\", default: 0 },\n longDesc: URL,\n border: { type: String, treatNullAsEmptyString: true },\n }\n});\n\ndefine({\n tag: 'input',\n name: 'HTMLInputElement',\n ctor: function HTMLInputElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: {\n form: formAssociatedProps.form,\n _post_click_activation_steps: { value: function(e) {\n if (this.type === 'checkbox') {\n this.checked = !this.checked;\n }\n else if (this.type === 'radio') {\n var group = this.form.getElementsByName(this.name);\n for (var i=group.length-1; i >= 0; i--) {\n var el = group[i];\n el.checked = (el === this);\n }\n }\n }},\n },\n attributes: {\n name: String,\n disabled: Boolean,\n autofocus: Boolean,\n accept: String,\n alt: String,\n max: String,\n min: String,\n pattern: String,\n placeholder: String,\n step: String,\n dirName: String,\n defaultValue: {name: 'value'},\n multiple: Boolean,\n required: Boolean,\n readOnly: Boolean,\n checked: Boolean,\n value: String,\n src: URL,\n defaultChecked: {name: 'checked', type: Boolean},\n size: {type: 'unsigned long', default: 20, min: 1, setmin: 1},\n width: {type: 'unsigned long', min: 0, setmin: 0, default: 0},\n height: {type: 'unsigned long', min: 0, setmin: 0, default: 0},\n minLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},\n maxLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},\n autocomplete: String, // It's complicated\n type: { type:\n [\"text\", \"hidden\", \"search\", \"tel\", \"url\", \"email\", \"password\",\n \"datetime\", \"date\", \"month\", \"week\", \"time\", \"datetime-local\",\n \"number\", \"range\", \"color\", \"checkbox\", \"radio\", \"file\", \"submit\",\n \"image\", \"reset\", \"button\"],\n missing: 'text' },\n formTarget: String,\n formNoValidate: Boolean,\n formMethod: { type: [\"get\", \"post\"], invalid: 'get', missing: '' },\n formEnctype: { type: [\"application/x-www-form-urlencoded\", \"multipart/form-data\", \"text/plain\"], invalid: \"application/x-www-form-urlencoded\", missing: '' },\n inputMode: { type: [ \"verbatim\", \"latin\", \"latin-name\", \"latin-prose\", \"full-width-latin\", \"kana\", \"kana-name\", \"katakana\", \"numeric\", \"tel\", \"email\", \"url\" ], missing: '' },\n // Obsolete\n align: String,\n useMap: String,\n }\n});\n\ndefine({\n tag: 'keygen',\n name: 'HTMLKeygenElement',\n ctor: function HTMLKeygenElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n name: String,\n disabled: Boolean,\n autofocus: Boolean,\n challenge: String,\n keytype: { type:[\"rsa\"], missing: '' },\n }\n});\n\ndefine({\n tag: 'li',\n name: 'HTMLLIElement',\n ctor: function HTMLLIElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n value: {type: \"long\", default: 0},\n // Obsolete\n type: String,\n }\n});\n\ndefine({\n tag: 'label',\n name: 'HTMLLabelElement',\n ctor: function HTMLLabelElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n htmlFor: {name: 'for', type: String}\n }\n});\n\ndefine({\n tag: 'legend',\n name: 'HTMLLegendElement',\n ctor: function HTMLLegendElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String\n },\n});\n\ndefine({\n tag: 'link',\n name: 'HTMLLinkElement',\n ctor: function HTMLLinkElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // XXX Reflect DOMSettableTokenList sizes also DOMTokenList relList\n href: URL,\n rel: String,\n media: String,\n hreflang: String,\n type: String,\n crossOrigin: CORS,\n nonce: String,\n integrity: String,\n referrerPolicy: REFERRER,\n imageSizes: String,\n imageSrcset: String,\n // Obsolete\n charset: String,\n rev: String,\n target: String,\n }\n});\n\ndefine({\n tag: 'map',\n name: 'HTMLMapElement',\n ctor: function HTMLMapElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n name: String\n }\n});\n\ndefine({\n tag: 'menu',\n name: 'HTMLMenuElement',\n ctor: function HTMLMenuElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // XXX: not quite right, default should be popup if parent element is\n // popup.\n type: { type: [ 'context', 'popup', 'toolbar' ], missing: 'toolbar' },\n label: String,\n // Obsolete\n compact: Boolean,\n }\n});\n\ndefine({\n tag: 'meta',\n name: 'HTMLMetaElement',\n ctor: function HTMLMetaElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n name: String,\n content: String,\n httpEquiv: {name: 'http-equiv', type: String},\n // Obsolete\n scheme: String,\n }\n});\n\ndefine({\n tag: 'meter',\n name: 'HTMLMeterElement',\n ctor: function HTMLMeterElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps\n});\n\ndefine({\n tags: ['ins', 'del'],\n name: 'HTMLModElement',\n ctor: function HTMLModElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n cite: URL,\n dateTime: String\n }\n});\n\ndefine({\n tag: 'ol',\n name: 'HTMLOListElement',\n ctor: function HTMLOListElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n // Utility function (see the start attribute default value). Returns\n // the number of
  • children of this element\n _numitems: { get: function() {\n var items = 0;\n this.childNodes.forEach(function(n) {\n if (n.nodeType === Node.ELEMENT_NODE && n.tagName === \"LI\")\n items++;\n });\n return items;\n }}\n },\n attributes: {\n type: String,\n reversed: Boolean,\n start: {\n type: \"long\",\n default: function() {\n // The default value of the start attribute is 1 unless the list is\n // reversed. Then it is the # of li children\n if (this.reversed)\n return this._numitems;\n else\n return 1;\n }\n },\n // Obsolete\n compact: Boolean,\n }\n});\n\ndefine({\n tag: 'object',\n name: 'HTMLObjectElement',\n ctor: function HTMLObjectElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n data: URL,\n type: String,\n name: String,\n useMap: String,\n typeMustMatch: Boolean,\n width: String,\n height: String,\n // Obsolete\n align: String,\n archive: String,\n code: String,\n declare: Boolean,\n hspace: { type: \"unsigned long\", default: 0 },\n standby: String,\n vspace: { type: \"unsigned long\", default: 0 },\n codeBase: URL,\n codeType: String,\n border: { type: String, treatNullAsEmptyString: true },\n }\n});\n\ndefine({\n tag: 'optgroup',\n name: 'HTMLOptGroupElement',\n ctor: function HTMLOptGroupElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n disabled: Boolean,\n label: String\n }\n});\n\ndefine({\n tag: 'option',\n name: 'HTMLOptionElement',\n ctor: function HTMLOptionElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n form: { get: function() {\n var p = this.parentNode;\n while (p && p.nodeType === Node.ELEMENT_NODE) {\n if (p.localName === 'select') return p.form;\n p = p.parentNode;\n }\n }},\n value: {\n get: function() { return this._getattr('value') || this.text; },\n set: function(v) { this._setattr('value', v); },\n },\n text: {\n get: function() {\n // Strip and collapse whitespace\n return this.textContent.replace(/[ \\t\\n\\f\\r]+/g, ' ').trim();\n },\n set: function(v) { this.textContent = v; },\n },\n // missing: index\n },\n attributes: {\n disabled: Boolean,\n defaultSelected: {name: 'selected', type: Boolean},\n label: String,\n }\n});\n\ndefine({\n tag: 'output',\n name: 'HTMLOutputElement',\n ctor: function HTMLOutputElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n // XXX Reflect for/htmlFor as a settable token list\n name: String\n }\n});\n\ndefine({\n tag: 'p',\n name: 'HTMLParagraphElement',\n ctor: function HTMLParagraphElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String\n }\n});\n\ndefine({\n tag: 'param',\n name: 'HTMLParamElement',\n ctor: function HTMLParamElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n name: String,\n value: String,\n // Obsolete\n type: String,\n valueType: String,\n }\n});\n\ndefine({\n tags: ['pre',/*legacy elements:*/'listing','xmp'],\n name: 'HTMLPreElement',\n ctor: function HTMLPreElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n width: { type: \"long\", default: 0 },\n }\n});\n\ndefine({\n tag: 'progress',\n name: 'HTMLProgressElement',\n ctor: function HTMLProgressElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: formAssociatedProps,\n attributes: {\n max: {type: Number, float: true, default: 1.0, min: 0}\n }\n});\n\ndefine({\n tags: ['q', 'blockquote'],\n name: 'HTMLQuoteElement',\n ctor: function HTMLQuoteElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n cite: URL\n }\n});\n\ndefine({\n tag: 'script',\n name: 'HTMLScriptElement',\n ctor: function HTMLScriptElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n text: {\n get: function() {\n var s = \"\";\n for(var i = 0, n = this.childNodes.length; i < n; i++) {\n var child = this.childNodes[i];\n if (child.nodeType === Node.TEXT_NODE)\n s += child._data;\n }\n return s;\n },\n set: function(value) {\n this.removeChildren();\n if (value !== null && value !== \"\") {\n this.appendChild(this.ownerDocument.createTextNode(value));\n }\n }\n }\n },\n attributes: {\n src: URL,\n type: String,\n charset: String,\n referrerPolicy: REFERRER,\n defer: Boolean,\n async: Boolean,\n nomodule: Boolean,\n crossOrigin: CORS,\n nonce: String,\n integrity: String,\n }\n});\n\ndefine({\n tag: 'select',\n name: 'HTMLSelectElement',\n ctor: function HTMLSelectElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: {\n form: formAssociatedProps.form,\n options: { get: function() {\n return this.getElementsByTagName('option');\n }}\n },\n attributes: {\n autocomplete: String, // It's complicated\n name: String,\n disabled: Boolean,\n autofocus: Boolean,\n multiple: Boolean,\n required: Boolean,\n size: {type: \"unsigned long\", default: 0}\n }\n});\n\ndefine({\n tag: 'span',\n name: 'HTMLSpanElement',\n ctor: function HTMLSpanElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tag: 'style',\n name: 'HTMLStyleElement',\n ctor: function HTMLStyleElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n media: String,\n type: String,\n scoped: Boolean\n }\n});\n\ndefine({\n tag: 'caption',\n name: 'HTMLTableCaptionElement',\n ctor: function HTMLTableCaptionElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n // Obsolete\n align: String,\n }\n});\n\n\ndefine({\n name: 'HTMLTableCellElement',\n ctor: function HTMLTableCellElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n colSpan: {type: \"unsigned long\", default: 1},\n rowSpan: {type: \"unsigned long\", default: 1},\n //XXX Also reflect settable token list headers\n scope: { type: ['row','col','rowgroup','colgroup'], missing: '' },\n abbr: String,\n // Obsolete\n align: String,\n axis: String,\n height: String,\n width: String,\n ch: { name: 'char', type: String },\n chOff: { name: 'charoff', type: String },\n noWrap: Boolean,\n vAlign: String,\n bgColor: { type: String, treatNullAsEmptyString: true },\n }\n});\n\ndefine({\n tags: ['col', 'colgroup'],\n name: 'HTMLTableColElement',\n ctor: function HTMLTableColElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n span: {type: 'limited unsigned long with fallback', default: 1, min: 1},\n // Obsolete\n align: String,\n ch: { name: 'char', type: String },\n chOff: { name: 'charoff', type: String },\n vAlign: String,\n width: String,\n }\n});\n\ndefine({\n tag: 'table',\n name: 'HTMLTableElement',\n ctor: function HTMLTableElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n rows: { get: function() {\n return this.getElementsByTagName('tr');\n }}\n },\n attributes: {\n // Obsolete\n align: String,\n border: String,\n frame: String,\n rules: String,\n summary: String,\n width: String,\n bgColor: { type: String, treatNullAsEmptyString: true },\n cellPadding: { type: String, treatNullAsEmptyString: true },\n cellSpacing: { type: String, treatNullAsEmptyString: true },\n }\n});\n\ndefine({\n tag: 'template',\n name: 'HTMLTemplateElement',\n ctor: function HTMLTemplateElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n this._contentFragment = doc._templateDoc.createDocumentFragment();\n },\n props: {\n content: { get: function() { return this._contentFragment; } },\n serialize: { value: function() { return this.content.serialize(); } }\n }\n});\n\ndefine({\n tag: 'tr',\n name: 'HTMLTableRowElement',\n ctor: function HTMLTableRowElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n cells: { get: function() {\n return this.querySelectorAll('td,th');\n }}\n },\n attributes: {\n // Obsolete\n align: String,\n ch: { name: 'char', type: String },\n chOff: { name: 'charoff', type: String },\n vAlign: String,\n bgColor: { type: String, treatNullAsEmptyString: true },\n },\n});\n\ndefine({\n tags: ['thead', 'tfoot', 'tbody'],\n name: 'HTMLTableSectionElement',\n ctor: function HTMLTableSectionElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n rows: { get: function() {\n return this.getElementsByTagName('tr');\n }}\n },\n attributes: {\n // Obsolete\n align: String,\n ch: { name: 'char', type: String },\n chOff: { name: 'charoff', type: String },\n vAlign: String,\n }\n});\n\ndefine({\n tag: 'textarea',\n name: 'HTMLTextAreaElement',\n ctor: function HTMLTextAreaElement(doc, localName, prefix) {\n HTMLFormElement.call(this, doc, localName, prefix);\n },\n props: {\n form: formAssociatedProps.form,\n type: { get: function() { return 'textarea'; } },\n defaultValue: {\n get: function() { return this.textContent; },\n set: function(v) { this.textContent = v; },\n },\n value: {\n get: function() { return this.defaultValue; /* never dirty */ },\n set: function(v) {\n // This isn't completely correct: according to the spec, this\n // should \"dirty\" the API value, and result in\n // `this.value !== this.defaultValue`. But for most of what\n // folks want to do, this implementation should be fine:\n this.defaultValue = v;\n },\n },\n textLength: { get: function() { return this.value.length; } },\n },\n attributes: {\n autocomplete: String, // It's complicated\n name: String,\n disabled: Boolean,\n autofocus: Boolean,\n placeholder: String,\n wrap: String,\n dirName: String,\n required: Boolean,\n readOnly: Boolean,\n rows: {type: 'limited unsigned long with fallback', default: 2 },\n cols: {type: 'limited unsigned long with fallback', default: 20 },\n maxLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},\n minLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},\n inputMode: { type: [ \"verbatim\", \"latin\", \"latin-name\", \"latin-prose\", \"full-width-latin\", \"kana\", \"kana-name\", \"katakana\", \"numeric\", \"tel\", \"email\", \"url\" ], missing: '' },\n }\n});\n\ndefine({\n tag: 'time',\n name: 'HTMLTimeElement',\n ctor: function HTMLTimeElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n dateTime: String,\n pubDate: Boolean\n }\n});\n\ndefine({\n tag: 'title',\n name: 'HTMLTitleElement',\n ctor: function HTMLTitleElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n text: { get: function() {\n return this.textContent;\n }}\n }\n});\n\ndefine({\n tag: 'ul',\n name: 'HTMLUListElement',\n ctor: function HTMLUListElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n type: String,\n // Obsolete\n compact: Boolean,\n }\n});\n\ndefine({\n name: 'HTMLMediaElement',\n ctor: function HTMLMediaElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n src: URL,\n crossOrigin: CORS,\n preload: { type:[\"metadata\", \"none\", \"auto\", {value: \"\", alias: \"auto\"}], missing: 'auto' },\n loop: Boolean,\n autoplay: Boolean,\n mediaGroup: String,\n controls: Boolean,\n defaultMuted: {name: \"muted\", type: Boolean}\n }\n});\n\ndefine({\n name: 'HTMLAudioElement',\n tag: 'audio',\n superclass: htmlElements.HTMLMediaElement,\n ctor: function HTMLAudioElement(doc, localName, prefix) {\n htmlElements.HTMLMediaElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n name: 'HTMLVideoElement',\n tag: 'video',\n superclass: htmlElements.HTMLMediaElement,\n ctor: function HTMLVideoElement(doc, localName, prefix) {\n htmlElements.HTMLMediaElement.call(this, doc, localName, prefix);\n },\n attributes: {\n poster: URL,\n width: {type: \"unsigned long\", min: 0, default: 0 },\n height: {type: \"unsigned long\", min: 0, default: 0 }\n }\n});\n\ndefine({\n tag: 'td',\n name: 'HTMLTableDataCellElement',\n superclass: htmlElements.HTMLTableCellElement,\n ctor: function HTMLTableDataCellElement(doc, localName, prefix) {\n htmlElements.HTMLTableCellElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tag: 'th',\n name: 'HTMLTableHeaderCellElement',\n superclass: htmlElements.HTMLTableCellElement,\n ctor: function HTMLTableHeaderCellElement(doc, localName, prefix) {\n htmlElements.HTMLTableCellElement.call(this, doc, localName, prefix);\n },\n});\n\ndefine({\n tag: 'frameset',\n name: 'HTMLFrameSetElement',\n ctor: function HTMLFrameSetElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tag: 'frame',\n name: 'HTMLFrameElement',\n ctor: function HTMLFrameElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n }\n});\n\ndefine({\n tag: 'canvas',\n name: 'HTMLCanvasElement',\n ctor: function HTMLCanvasElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n getContext: { value: utils.nyi },\n probablySupportsContext: { value: utils.nyi },\n setContext: { value: utils.nyi },\n transferControlToProxy: { value: utils.nyi },\n toDataURL: { value: utils.nyi },\n toBlob: { value: utils.nyi }\n },\n attributes: {\n width: { type: \"unsigned long\", default: 300},\n height: { type: \"unsigned long\", default: 150}\n }\n});\n\ndefine({\n tag: 'dialog',\n name: 'HTMLDialogElement',\n ctor: function HTMLDialogElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n show: { value: utils.nyi },\n showModal: { value: utils.nyi },\n close: { value: utils.nyi }\n },\n attributes: {\n open: Boolean,\n returnValue: String\n }\n});\n\ndefine({\n tag: 'menuitem',\n name: 'HTMLMenuItemElement',\n ctor: function HTMLMenuItemElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n props: {\n // The menuitem's label\n _label: {\n get: function() {\n var val = this._getattr('label');\n if (val !== null && val !== '') { return val; }\n val = this.textContent;\n // Strip and collapse whitespace\n return val.replace(/[ \\t\\n\\f\\r]+/g, ' ').trim();\n }\n },\n // The menuitem label IDL attribute\n label: {\n get: function() {\n var val = this._getattr('label');\n if (val !== null) { return val; }\n return this._label;\n },\n set: function(v) {\n this._setattr('label', v);\n },\n }\n },\n attributes: {\n type: { type: [\"command\",\"checkbox\",\"radio\"], missing: 'command' },\n icon: URL,\n disabled: Boolean,\n checked: Boolean,\n radiogroup: String,\n default: Boolean\n }\n});\n\ndefine({\n tag: 'source',\n name: 'HTMLSourceElement',\n ctor: function HTMLSourceElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n srcset: String,\n sizes: String,\n media: String,\n src: URL,\n type: String,\n width: String,\n height: String,\n }\n});\n\ndefine({\n tag: 'track',\n name: 'HTMLTrackElement',\n ctor: function HTMLTrackElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n src: URL,\n srclang: String,\n label: String,\n default: Boolean,\n kind: { type: [\"subtitles\", \"captions\", \"descriptions\", \"chapters\", \"metadata\"], missing: 'subtitles', invalid: 'metadata' },\n },\n props: {\n NONE: { get: function() { return 0; } },\n LOADING: { get: function() { return 1; } },\n LOADED: { get: function() { return 2; } },\n ERROR: { get: function() { return 3; } },\n readyState: { get: utils.nyi },\n track: { get: utils.nyi }\n }\n});\n\ndefine({\n // obsolete\n tag: 'font',\n name: 'HTMLFontElement',\n ctor: function HTMLFontElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n color: { type: String, treatNullAsEmptyString: true },\n face: { type: String },\n size: { type: String },\n },\n});\n\ndefine({\n // obsolete\n tag: 'dir',\n name: 'HTMLDirectoryElement',\n ctor: function HTMLDirectoryElement(doc, localName, prefix) {\n HTMLElement.call(this, doc, localName, prefix);\n },\n attributes: {\n compact: Boolean,\n },\n});\n\ndefine({\n tags: [\n \"abbr\", \"address\", \"article\", \"aside\", \"b\", \"bdi\", \"bdo\", \"cite\", \"content\", \"code\",\n \"dd\", \"dfn\", \"dt\", \"em\", \"figcaption\", \"figure\", \"footer\", \"header\", \"hgroup\", \"i\", \"kbd\",\n \"main\", \"mark\", \"nav\", \"noscript\", \"rb\", \"rp\", \"rt\", \"rtc\",\n \"ruby\", \"s\", \"samp\", \"section\", \"small\", \"strong\", \"sub\", \"summary\", \"sup\", \"u\", \"var\", \"wbr\",\n // Legacy elements\n \"acronym\", \"basefont\", \"big\", \"center\", \"nobr\", \"noembed\", \"noframes\",\n \"plaintext\", \"strike\", \"tt\"\n ]\n});\n","\"use strict\";\nvar Element = require('./Element');\nvar defineElement = require('./defineElement');\nvar utils = require('./utils');\nvar CSSStyleDeclaration = require('./CSSStyleDeclaration');\n\nvar svgElements = exports.elements = {};\nvar svgNameToImpl = Object.create(null);\n\nexports.createElement = function(doc, localName, prefix) {\n var impl = svgNameToImpl[localName] || SVGElement;\n return new impl(doc, localName, prefix);\n};\n\nfunction define(spec) {\n return defineElement(spec, SVGElement, svgElements, svgNameToImpl);\n}\n\nvar SVGElement = define({\n superclass: Element,\n name: 'SVGElement',\n ctor: function SVGElement(doc, localName, prefix) {\n Element.call(this, doc, localName, utils.NAMESPACE.SVG, prefix);\n },\n props: {\n style: { get: function() {\n if (!this._style)\n this._style = new CSSStyleDeclaration(this);\n return this._style;\n }}\n }\n});\n\ndefine({\n name: 'SVGSVGElement',\n ctor: function SVGSVGElement(doc, localName, prefix) {\n SVGElement.call(this, doc, localName, prefix);\n },\n tag: 'svg',\n props: {\n createSVGRect: { value: function () {\n return exports.createElement(this.ownerDocument, 'rect', null);\n } }\n }\n});\n\ndefine({\n tags: [\n 'a', 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'animate', 'animateColor', 'animateMotion', 'animateTransform',\n 'circle', 'clipPath', 'color-profile', 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix',\n 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight',\n 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode',\n 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'filter',\n 'font', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignObject', 'g',\n 'glyph', 'glyphRef', 'hkern', 'image', 'line', 'linearGradient', 'marker', 'mask', 'metadata', 'missing-glyph',\n 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'script', 'set', 'stop', 'style',\n 'switch', 'symbol', 'text', 'textPath', 'title', 'tref', 'tspan', 'use', 'view', 'vkern'\n ]\n});\n","\"use strict\";\nmodule.exports = {\n VALUE: 1, // The value of a Text, Comment or PI node changed\n ATTR: 2, // A new attribute was added or an attribute value and/or prefix changed\n REMOVE_ATTR: 3, // An attribute was removed\n REMOVE: 4, // A node was removed\n MOVE: 5, // A node was moved\n INSERT: 6 // A node (or a subtree of nodes) was inserted\n};","\"use strict\";\nmodule.exports = Document;\n\nvar Node = require('./Node');\nvar NodeList = require('./NodeList');\nvar ContainerNode = require('./ContainerNode');\nvar Element = require('./Element');\nvar Text = require('./Text');\nvar Comment = require('./Comment');\nvar Event = require('./Event');\nvar DocumentFragment = require('./DocumentFragment');\nvar ProcessingInstruction = require('./ProcessingInstruction');\nvar DOMImplementation = require('./DOMImplementation');\nvar TreeWalker = require('./TreeWalker');\nvar NodeIterator = require('./NodeIterator');\nvar NodeFilter = require('./NodeFilter');\nvar URL = require('./URL');\nvar select = require('./select');\nvar events = require('./events');\nvar xml = require('./xmlnames');\nvar html = require('./htmlelts');\nvar svg = require('./svg');\nvar utils = require('./utils');\nvar MUTATE = require('./MutationConstants');\nvar NAMESPACE = utils.NAMESPACE;\nvar isApiWritable = require(\"./config\").isApiWritable;\n\nfunction Document(isHTML, address) {\n ContainerNode.call(this);\n this.nodeType = Node.DOCUMENT_NODE;\n this.isHTML = isHTML;\n this._address = address || 'about:blank';\n this.readyState = 'loading';\n this.implementation = new DOMImplementation(this);\n\n // DOMCore says that documents are always associated with themselves\n this.ownerDocument = null; // ... but W3C tests expect null\n this._contentType = isHTML ? 'text/html' : 'application/xml';\n\n // These will be initialized by our custom versions of\n // appendChild and insertBefore that override the inherited\n // Node methods.\n // XXX: override those methods!\n this.doctype = null;\n this.documentElement = null;\n\n // \"Associated inert template document\"\n this._templateDocCache = null;\n // List of active NodeIterators, see NodeIterator#_preremove()\n this._nodeIterators = null;\n\n // Documents are always rooted, by definition\n this._nid = 1;\n this._nextnid = 2; // For numbering children of the document\n this._nodes = [null, this]; // nid to node map\n\n // This maintains the mapping from element ids to element nodes.\n // We may need to update this mapping every time a node is rooted\n // or uprooted, and any time an attribute is added, removed or changed\n // on a rooted element.\n this.byId = Object.create(null);\n\n // This property holds a monotonically increasing value akin to\n // a timestamp used to record the last modification time of nodes\n // and their subtrees. See the lastModTime attribute and modify()\n // method of the Node class. And see FilteredElementList for an example\n // of the use of lastModTime\n this.modclock = 0;\n}\n\n// Map from lowercase event category names (used as arguments to\n// createEvent()) to the property name in the impl object of the\n// event constructor.\nvar supportedEvents = {\n event: 'Event',\n customevent: 'CustomEvent',\n uievent: 'UIEvent',\n mouseevent: 'MouseEvent'\n};\n\n// Certain arguments to document.createEvent() must be treated specially\nvar replacementEvent = {\n events: 'event',\n htmlevents: 'event',\n mouseevents: 'mouseevent',\n mutationevents: 'mutationevent',\n uievents: 'uievent'\n};\n\nvar mirrorAttr = function(f, name, defaultValue) {\n return {\n get: function() {\n var o = f.call(this);\n if (o) { return o[name]; }\n return defaultValue;\n },\n set: function(value) {\n var o = f.call(this);\n if (o) { o[name] = value; }\n },\n };\n};\n\n/** @spec https://dom.spec.whatwg.org/#validate-and-extract */\nfunction validateAndExtract(namespace, qualifiedName) {\n var prefix, localName, pos;\n if (namespace==='') { namespace = null; }\n // See https://github.com/whatwg/dom/issues/671\n // and https://github.com/whatwg/dom/issues/319\n if (!xml.isValidQName(qualifiedName)) {\n utils.InvalidCharacterError();\n }\n prefix = null;\n localName = qualifiedName;\n\n pos = qualifiedName.indexOf(':');\n if (pos >= 0) {\n prefix = qualifiedName.substring(0, pos);\n localName = qualifiedName.substring(pos+1);\n }\n if (prefix !== null && namespace === null) {\n utils.NamespaceError();\n }\n if (prefix === 'xml' && namespace !== NAMESPACE.XML) {\n utils.NamespaceError();\n }\n if ((prefix === 'xmlns' || qualifiedName === 'xmlns') &&\n namespace !== NAMESPACE.XMLNS) {\n utils.NamespaceError();\n }\n if (namespace === NAMESPACE.XMLNS && !(prefix==='xmlns' || qualifiedName==='xmlns')) {\n utils.NamespaceError();\n }\n return { namespace: namespace, prefix: prefix, localName: localName };\n}\n\nDocument.prototype = Object.create(ContainerNode.prototype, {\n // This method allows dom.js to communicate with a renderer\n // that displays the document in some way\n // XXX: I should probably move this to the window object\n _setMutationHandler: { value: function(handler) {\n this.mutationHandler = handler;\n }},\n\n // This method allows dom.js to receive event notifications\n // from the renderer.\n // XXX: I should probably move this to the window object\n _dispatchRendererEvent: { value: function(targetNid, type, details) {\n var target = this._nodes[targetNid];\n if (!target) return;\n target._dispatchEvent(new Event(type, details), true);\n }},\n\n nodeName: { value: '#document'},\n nodeValue: {\n get: function() {\n return null;\n },\n set: function() {}\n },\n\n // XXX: DOMCore may remove documentURI, so it is NYI for now\n documentURI: { get: function() { return this._address; }, set: utils.nyi },\n compatMode: { get: function() {\n // The _quirks property is set by the HTML parser\n return this._quirks ? 'BackCompat' : 'CSS1Compat';\n }},\n\n createTextNode: { value: function(data) {\n return new Text(this, String(data));\n }},\n createComment: { value: function(data) {\n return new Comment(this, data);\n }},\n createDocumentFragment: { value: function() {\n return new DocumentFragment(this);\n }},\n createProcessingInstruction: { value: function(target, data) {\n if (!xml.isValidName(target) || data.indexOf('?>') !== -1)\n utils.InvalidCharacterError();\n return new ProcessingInstruction(this, target, data);\n }},\n\n createAttribute: { value: function(localName) {\n localName = String(localName);\n if (!xml.isValidName(localName)) utils.InvalidCharacterError();\n if (this.isHTML) {\n localName = utils.toASCIILowerCase(localName);\n }\n return new Element._Attr(null, localName, null, null, '');\n }},\n createAttributeNS: { value: function(namespace, qualifiedName) {\n // Convert parameter types according to WebIDL\n namespace =\n (namespace === null || namespace === undefined || namespace === '') ? null :\n String(namespace);\n qualifiedName = String(qualifiedName);\n var ve = validateAndExtract(namespace, qualifiedName);\n return new Element._Attr(null, ve.localName, ve.prefix, ve.namespace, '');\n }},\n\n createElement: { value: function(localName) {\n localName = String(localName);\n if (!xml.isValidName(localName)) utils.InvalidCharacterError();\n // Per spec, namespace should be HTML namespace if \"context object is\n // an HTML document or context object's content type is\n // \"application/xhtml+xml\", and null otherwise.\n if (this.isHTML) {\n if (/[A-Z]/.test(localName))\n localName = utils.toASCIILowerCase(localName);\n return html.createElement(this, localName, null);\n } else if (this.contentType === 'application/xhtml+xml') {\n return html.createElement(this, localName, null);\n } else {\n return new Element(this, localName, null, null);\n }\n }, writable: isApiWritable },\n\n createElementNS: { value: function(namespace, qualifiedName) {\n // Convert parameter types according to WebIDL\n namespace =\n (namespace === null || namespace === undefined || namespace === '') ? null :\n String(namespace);\n qualifiedName = String(qualifiedName);\n var ve = validateAndExtract(namespace, qualifiedName);\n return this._createElementNS(ve.localName, ve.namespace, ve.prefix);\n }, writable: isApiWritable },\n\n // This is used directly by HTML parser, which allows it to create\n // elements with localNames containing ':' and non-default namespaces\n _createElementNS: { value: function(localName, namespace, prefix) {\n if (namespace === NAMESPACE.HTML) {\n return html.createElement(this, localName, prefix);\n }\n else if (namespace === NAMESPACE.SVG) {\n return svg.createElement(this, localName, prefix);\n }\n\n return new Element(this, localName, namespace, prefix);\n }},\n\n createEvent: { value: function createEvent(interfaceName) {\n interfaceName = interfaceName.toLowerCase();\n var name = replacementEvent[interfaceName] || interfaceName;\n var constructor = events[supportedEvents[name]];\n\n if (constructor) {\n var e = new constructor();\n e._initialized = false;\n return e;\n }\n else {\n utils.NotSupportedError();\n }\n }},\n\n // See: http://www.w3.org/TR/dom/#dom-document-createtreewalker\n createTreeWalker: {value: function (root, whatToShow, filter) {\n if (!root) { throw new TypeError(\"root argument is required\"); }\n if (!(root instanceof Node)) { throw new TypeError(\"root not a node\"); }\n whatToShow = whatToShow === undefined ? NodeFilter.SHOW_ALL : (+whatToShow);\n filter = filter === undefined ? null : filter;\n\n return new TreeWalker(root, whatToShow, filter);\n }},\n\n // See: http://www.w3.org/TR/dom/#dom-document-createnodeiterator\n createNodeIterator: {value: function (root, whatToShow, filter) {\n if (!root) { throw new TypeError(\"root argument is required\"); }\n if (!(root instanceof Node)) { throw new TypeError(\"root not a node\"); }\n whatToShow = whatToShow === undefined ? NodeFilter.SHOW_ALL : (+whatToShow);\n filter = filter === undefined ? null : filter;\n\n return new NodeIterator(root, whatToShow, filter);\n }},\n\n _attachNodeIterator: { value: function(ni) {\n // XXX ideally this should be a weak reference from Document to NodeIterator\n if (!this._nodeIterators) { this._nodeIterators = []; }\n this._nodeIterators.push(ni);\n }},\n\n _detachNodeIterator: { value: function(ni) {\n // ni should always be in list of node iterators\n var idx = this._nodeIterators.indexOf(ni);\n this._nodeIterators.splice(idx, 1);\n }},\n\n _preremoveNodeIterators: { value: function(toBeRemoved) {\n if (this._nodeIterators) {\n this._nodeIterators.forEach(function(ni) { ni._preremove(toBeRemoved); });\n }\n }},\n\n // Maintain the documentElement and\n // doctype properties of the document. Each of the following\n // methods chains to the Node implementation of the method\n // to do the actual inserting, removal or replacement.\n\n _updateDocTypeElement: { value: function _updateDocTypeElement() {\n this.doctype = this.documentElement = null;\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === Node.DOCUMENT_TYPE_NODE)\n this.doctype = kid;\n else if (kid.nodeType === Node.ELEMENT_NODE)\n this.documentElement = kid;\n }\n }},\n\n insertBefore: { value: function insertBefore(child, refChild) {\n Node.prototype.insertBefore.call(this, child, refChild);\n this._updateDocTypeElement();\n return child;\n }},\n\n replaceChild: { value: function replaceChild(node, child) {\n Node.prototype.replaceChild.call(this, node, child);\n this._updateDocTypeElement();\n return child;\n }},\n\n removeChild: { value: function removeChild(child) {\n Node.prototype.removeChild.call(this, child);\n this._updateDocTypeElement();\n return child;\n }},\n\n getElementById: { value: function(id) {\n var n = this.byId[id];\n if (!n) return null;\n if (n instanceof MultiId) { // there was more than one element with this id\n return n.getFirst();\n }\n return n;\n }},\n\n _hasMultipleElementsWithId: { value: function(id) {\n // Used internally by querySelectorAll optimization\n return (this.byId[id] instanceof MultiId);\n }},\n\n // Just copy this method from the Element prototype\n getElementsByName: { value: Element.prototype.getElementsByName },\n getElementsByTagName: { value: Element.prototype.getElementsByTagName },\n getElementsByTagNameNS: { value: Element.prototype.getElementsByTagNameNS },\n getElementsByClassName: { value: Element.prototype.getElementsByClassName },\n\n adoptNode: { value: function adoptNode(node) {\n if (node.nodeType === Node.DOCUMENT_NODE) utils.NotSupportedError();\n if (node.nodeType === Node.ATTRIBUTE_NODE) { return node; }\n\n if (node.parentNode) node.parentNode.removeChild(node);\n\n if (node.ownerDocument !== this)\n recursivelySetOwner(node, this);\n\n return node;\n }},\n\n importNode: { value: function importNode(node, deep) {\n return this.adoptNode(node.cloneNode(deep));\n }, writable: isApiWritable },\n\n // The following attributes and methods are from the HTML spec\n origin: { get: function origin() { return null; } },\n characterSet: { get: function characterSet() { return \"UTF-8\"; } },\n contentType: { get: function contentType() { return this._contentType; } },\n URL: { get: function URL() { return this._address; } },\n domain: { get: utils.nyi, set: utils.nyi },\n referrer: { get: utils.nyi },\n cookie: { get: utils.nyi, set: utils.nyi },\n lastModified: { get: utils.nyi },\n location: {\n\tget: function() {\n\t return this.defaultView ? this.defaultView.location : null; // gh #75\n\t},\n\tset: utils.nyi\n },\n _titleElement: {\n get: function() {\n // The title element of a document is the first title element in the\n // document in tree order, if there is one, or null otherwise.\n return this.getElementsByTagName('title').item(0) || null;\n }\n },\n title: {\n get: function() {\n var elt = this._titleElement;\n // The child text content of the title element, or '' if null.\n var value = elt ? elt.textContent : '';\n // Strip and collapse whitespace in value\n return value.replace(/[ \\t\\n\\r\\f]+/g, ' ').replace(/(^ )|( $)/g, '');\n },\n set: function(value) {\n var elt = this._titleElement;\n var head = this.head;\n if (!elt && !head) { return; /* according to spec */ }\n if (!elt) {\n elt = this.createElement('title');\n head.appendChild(elt);\n }\n elt.textContent = value;\n }\n },\n dir: mirrorAttr(function() {\n var htmlElement = this.documentElement;\n if (htmlElement && htmlElement.tagName === 'HTML') { return htmlElement; }\n }, 'dir', ''),\n fgColor: mirrorAttr(function() { return this.body; }, 'text', ''),\n linkColor: mirrorAttr(function() { return this.body; }, 'link', ''),\n vlinkColor: mirrorAttr(function() { return this.body; }, 'vLink', ''),\n alinkColor: mirrorAttr(function() { return this.body; }, 'aLink', ''),\n bgColor: mirrorAttr(function() { return this.body; }, 'bgColor', ''),\n\n // Historical aliases of Document#characterSet\n charset: { get: function() { return this.characterSet; } },\n inputEncoding: { get: function() { return this.characterSet; } },\n\n scrollingElement: {\n get: function() {\n return this._quirks ? this.body : this.documentElement;\n }\n },\n\n // Return the first child of the document element.\n // XXX For now, setting this attribute is not implemented.\n body: {\n get: function() {\n return namedHTMLChild(this.documentElement, 'body');\n },\n set: utils.nyi\n },\n // Return the first child of the document element.\n head: { get: function() {\n return namedHTMLChild(this.documentElement, 'head');\n }},\n images: { get: utils.nyi },\n embeds: { get: utils.nyi },\n plugins: { get: utils.nyi },\n links: { get: utils.nyi },\n forms: { get: utils.nyi },\n scripts: { get: utils.nyi },\n applets: { get: function() { return []; } },\n activeElement: { get: function() { return null; } },\n innerHTML: {\n get: function() { return this.serialize(); },\n set: utils.nyi\n },\n outerHTML: {\n get: function() { return this.serialize(); },\n set: utils.nyi\n },\n\n write: { value: function(args) {\n if (!this.isHTML) utils.InvalidStateError();\n\n // XXX: still have to implement the ignore part\n if (!this._parser /* && this._ignore_destructive_writes > 0 */ )\n return;\n\n if (!this._parser) {\n // XXX call document.open, etc.\n }\n\n var s = arguments.join('');\n\n // If the Document object's reload override flag is set, then\n // append the string consisting of the concatenation of all the\n // arguments to the method to the Document's reload override\n // buffer.\n // XXX: don't know what this is about. Still have to do it\n\n // If there is no pending parsing-blocking script, have the\n // tokenizer process the characters that were inserted, one at a\n // time, processing resulting tokens as they are emitted, and\n // stopping when the tokenizer reaches the insertion point or when\n // the processing of the tokenizer is aborted by the tree\n // construction stage (this can happen if a script end tag token is\n // emitted by the tokenizer).\n\n // XXX: still have to do the above. Sounds as if we don't\n // always call parse() here. If we're blocked, then we just\n // insert the text into the stream but don't parse it reentrantly...\n\n // Invoke the parser reentrantly\n this._parser.parse(s);\n }},\n\n writeln: { value: function writeln(args) {\n this.write(Array.prototype.join.call(arguments, '') + '\\n');\n }},\n\n open: { value: function() {\n this.documentElement = null;\n }},\n\n close: { value: function() {\n this.readyState = 'interactive';\n this._dispatchEvent(new Event('readystatechange'), true);\n this._dispatchEvent(new Event('DOMContentLoaded'), true);\n this.readyState = 'complete';\n this._dispatchEvent(new Event('readystatechange'), true);\n if (this.defaultView) {\n this.defaultView._dispatchEvent(new Event('load'), true);\n }\n }},\n\n // Utility methods\n clone: { value: function clone() {\n var d = new Document(this.isHTML, this._address);\n d._quirks = this._quirks;\n d._contentType = this._contentType;\n return d;\n }},\n\n // We need to adopt the nodes if we do a deep clone\n cloneNode: { value: function cloneNode(deep) {\n var clone = Node.prototype.cloneNode.call(this, false);\n if (deep) {\n for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {\n clone._appendChild(clone.importNode(kid, true));\n }\n }\n clone._updateDocTypeElement();\n return clone;\n }},\n\n isEqual: { value: function isEqual(n) {\n // Any two documents are shallowly equal.\n // Node.isEqualNode will also test the children\n return true;\n }},\n\n // Implementation-specific function. Called when a text, comment,\n // or pi value changes.\n mutateValue: { value: function(node) {\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.VALUE,\n target: node,\n data: node.data\n });\n }\n }},\n\n // Invoked when an attribute's value changes. Attr holds the new\n // value. oldval is the old value. Attribute mutations can also\n // involve changes to the prefix (and therefore the qualified name)\n mutateAttr: { value: function(attr, oldval) {\n // Manage id->element mapping for getElementsById()\n // XXX: this special case id handling should not go here,\n // but in the attribute declaration for the id attribute\n /*\n if (attr.localName === 'id' && attr.namespaceURI === null) {\n if (oldval) delId(oldval, attr.ownerElement);\n addId(attr.value, attr.ownerElement);\n }\n */\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.ATTR,\n target: attr.ownerElement,\n attr: attr\n });\n }\n }},\n\n // Used by removeAttribute and removeAttributeNS for attributes.\n mutateRemoveAttr: { value: function(attr) {\n/*\n* This is now handled in Attributes.js\n // Manage id to element mapping\n if (attr.localName === 'id' && attr.namespaceURI === null) {\n this.delId(attr.value, attr.ownerElement);\n }\n*/\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.REMOVE_ATTR,\n target: attr.ownerElement,\n attr: attr\n });\n }\n }},\n\n // Called by Node.removeChild, etc. to remove a rooted element from\n // the tree. Only needs to generate a single mutation event when a\n // node is removed, but must recursively mark all descendants as not\n // rooted.\n mutateRemove: { value: function(node) {\n // Send a single mutation event\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.REMOVE,\n target: node.parentNode,\n node: node\n });\n }\n\n // Mark this and all descendants as not rooted\n recursivelyUproot(node);\n }},\n\n // Called when a new element becomes rooted. It must recursively\n // generate mutation events for each of the children, and mark them all\n // as rooted.\n mutateInsert: { value: function(node) {\n // Mark node and its descendants as rooted\n recursivelyRoot(node);\n\n // Send a single mutation event\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.INSERT,\n target: node.parentNode,\n node: node\n });\n }\n }},\n\n // Called when a rooted element is moved within the document\n mutateMove: { value: function(node) {\n if (this.mutationHandler) {\n this.mutationHandler({\n type: MUTATE.MOVE,\n target: node\n });\n }\n }},\n\n\n // Add a mapping from id to n for n.ownerDocument\n addId: { value: function addId(id, n) {\n var val = this.byId[id];\n if (!val) {\n this.byId[id] = n;\n }\n else {\n // TODO: Add a way to opt-out console warnings\n //console.warn('Duplicate element id ' + id);\n if (!(val instanceof MultiId)) {\n val = new MultiId(val);\n this.byId[id] = val;\n }\n val.add(n);\n }\n }},\n\n // Delete the mapping from id to n for n.ownerDocument\n delId: { value: function delId(id, n) {\n var val = this.byId[id];\n utils.assert(val);\n\n if (val instanceof MultiId) {\n val.del(n);\n if (val.length === 1) { // convert back to a single node\n this.byId[id] = val.downgrade();\n }\n }\n else {\n this.byId[id] = undefined;\n }\n }},\n\n _resolve: { value: function(href) {\n //XXX: Cache the URL\n return new URL(this._documentBaseURL).resolve(href);\n }},\n\n _documentBaseURL: { get: function() {\n // XXX: This is not implemented correctly yet\n var url = this._address;\n if (url === 'about:blank') url = '/';\n\n var base = this.querySelector('base[href]');\n if (base) {\n return new URL(url).resolve(base.getAttribute('href'));\n }\n return url;\n\n // The document base URL of a Document object is the\n // absolute URL obtained by running these substeps:\n\n // Let fallback base url be the document's address.\n\n // If fallback base url is about:blank, and the\n // Document's browsing context has a creator browsing\n // context, then let fallback base url be the document\n // base URL of the creator Document instead.\n\n // If the Document is an iframe srcdoc document, then\n // let fallback base url be the document base URL of\n // the Document's browsing context's browsing context\n // container's Document instead.\n\n // If there is no base element that has an href\n // attribute, then the document base URL is fallback\n // base url; abort these steps. Otherwise, let url be\n // the value of the href attribute of the first such\n // element.\n\n // Resolve url relative to fallback base url (thus,\n // the base href attribute isn't affected by xml:base\n // attributes).\n\n // The document base URL is the result of the previous\n // step if it was successful; otherwise it is fallback\n // base url.\n }},\n\n _templateDoc: { get: function() {\n if (!this._templateDocCache) {\n // \"associated inert template document\"\n var newDoc = new Document(this.isHTML, this._address);\n this._templateDocCache = newDoc._templateDocCache = newDoc;\n }\n return this._templateDocCache;\n }},\n\n querySelector: { value: function(selector) {\n return select(selector, this)[0];\n }},\n\n querySelectorAll: { value: function(selector) {\n var nodes = select(selector, this);\n return nodes.item ? nodes : new NodeList(nodes);\n }}\n\n});\n\n\nvar eventHandlerTypes = [\n 'abort', 'canplay', 'canplaythrough', 'change', 'click', 'contextmenu',\n 'cuechange', 'dblclick', 'drag', 'dragend', 'dragenter', 'dragleave',\n 'dragover', 'dragstart', 'drop', 'durationchange', 'emptied', 'ended',\n 'input', 'invalid', 'keydown', 'keypress', 'keyup', 'loadeddata',\n 'loadedmetadata', 'loadstart', 'mousedown', 'mousemove', 'mouseout',\n 'mouseover', 'mouseup', 'mousewheel', 'pause', 'play', 'playing',\n 'progress', 'ratechange', 'readystatechange', 'reset', 'seeked',\n 'seeking', 'select', 'show', 'stalled', 'submit', 'suspend',\n 'timeupdate', 'volumechange', 'waiting',\n\n 'blur', 'error', 'focus', 'load', 'scroll'\n];\n\n// Add event handler idl attribute getters and setters to Document\neventHandlerTypes.forEach(function(type) {\n // Define the event handler registration IDL attribute for this type\n Object.defineProperty(Document.prototype, 'on' + type, {\n get: function() {\n return this._getEventHandler(type);\n },\n set: function(v) {\n this._setEventHandler(type, v);\n }\n });\n});\n\nfunction namedHTMLChild(parent, name) {\n if (parent && parent.isHTML) {\n for (var kid = parent.firstChild; kid !== null; kid = kid.nextSibling) {\n if (kid.nodeType === Node.ELEMENT_NODE &&\n kid.localName === name &&\n kid.namespaceURI === NAMESPACE.HTML) {\n return kid;\n }\n }\n }\n return null;\n}\n\nfunction root(n) {\n n._nid = n.ownerDocument._nextnid++;\n n.ownerDocument._nodes[n._nid] = n;\n // Manage id to element mapping\n if (n.nodeType === Node.ELEMENT_NODE) {\n var id = n.getAttribute('id');\n if (id) n.ownerDocument.addId(id, n);\n\n // Script elements need to know when they're inserted\n // into the document\n if (n._roothook) n._roothook();\n }\n}\n\nfunction uproot(n) {\n // Manage id to element mapping\n if (n.nodeType === Node.ELEMENT_NODE) {\n var id = n.getAttribute('id');\n if (id) n.ownerDocument.delId(id, n);\n }\n n.ownerDocument._nodes[n._nid] = undefined;\n n._nid = undefined;\n}\n\nfunction recursivelyRoot(node) {\n root(node);\n // XXX:\n // accessing childNodes on a leaf node creates a new array the\n // first time, so be careful to write this loop so that it\n // doesn't do that. node is polymorphic, so maybe this is hard to\n // optimize? Try switching on nodeType?\n/*\n if (node.hasChildNodes()) {\n var kids = node.childNodes;\n for(var i = 0, n = kids.length; i < n; i++)\n recursivelyRoot(kids[i]);\n }\n*/\n if (node.nodeType === Node.ELEMENT_NODE) {\n for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)\n recursivelyRoot(kid);\n }\n}\n\nfunction recursivelyUproot(node) {\n uproot(node);\n for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)\n recursivelyUproot(kid);\n}\n\nfunction recursivelySetOwner(node, owner) {\n node.ownerDocument = owner;\n node._lastModTime = undefined; // mod times are document-based\n if (Object.prototype.hasOwnProperty.call(node, '_tagName')) {\n node._tagName = undefined; // Element subclasses might need to change case\n }\n for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)\n recursivelySetOwner(kid, owner);\n}\n\n// A class for storing multiple nodes with the same ID\nfunction MultiId(node) {\n this.nodes = Object.create(null);\n this.nodes[node._nid] = node;\n this.length = 1;\n this.firstNode = undefined;\n}\n\n// Add a node to the list, with O(1) time\nMultiId.prototype.add = function(node) {\n if (!this.nodes[node._nid]) {\n this.nodes[node._nid] = node;\n this.length++;\n this.firstNode = undefined;\n }\n};\n\n// Remove a node from the list, with O(1) time\nMultiId.prototype.del = function(node) {\n if (this.nodes[node._nid]) {\n delete this.nodes[node._nid];\n this.length--;\n this.firstNode = undefined;\n }\n};\n\n// Get the first node from the list, in the document order\n// Takes O(N) time in the size of the list, with a cache that is invalidated\n// when the list is modified.\nMultiId.prototype.getFirst = function() {\n /* jshint bitwise: false */\n if (!this.firstNode) {\n var nid;\n for (nid in this.nodes) {\n if (this.firstNode === undefined ||\n this.firstNode.compareDocumentPosition(this.nodes[nid]) & Node.DOCUMENT_POSITION_PRECEDING) {\n this.firstNode = this.nodes[nid];\n }\n }\n }\n return this.firstNode;\n};\n\n// If there is only one node left, return it. Otherwise return \"this\".\nMultiId.prototype.downgrade = function() {\n if (this.length === 1) {\n var nid;\n for (nid in this.nodes) {\n return this.nodes[nid];\n }\n }\n return this;\n};\n","\"use strict\";\nmodule.exports = DocumentType;\n\nvar Node = require('./Node');\nvar Leaf = require('./Leaf');\nvar ChildNode = require('./ChildNode');\n\nfunction DocumentType(ownerDocument, name, publicId, systemId) {\n Leaf.call(this);\n this.nodeType = Node.DOCUMENT_TYPE_NODE;\n this.ownerDocument = ownerDocument || null;\n this.name = name;\n this.publicId = publicId || \"\";\n this.systemId = systemId || \"\";\n}\n\nDocumentType.prototype = Object.create(Leaf.prototype, {\n nodeName: { get: function() { return this.name; }},\n nodeValue: {\n get: function() { return null; },\n set: function() {}\n },\n\n // Utility methods\n clone: { value: function clone() {\n return new DocumentType(this.ownerDocument, this.name, this.publicId, this.systemId);\n }},\n\n isEqual: { value: function isEqual(n) {\n return this.name === n.name &&\n this.publicId === n.publicId &&\n this.systemId === n.systemId;\n }}\n});\n\nObject.defineProperties(DocumentType.prototype, ChildNode);\n","\"use strict\";\nmodule.exports = HTMLParser;\n\nvar Document = require('./Document');\nvar DocumentType = require('./DocumentType');\nvar Node = require('./Node');\nvar NAMESPACE = require('./utils').NAMESPACE;\nvar html = require('./htmlelts');\nvar impl = html.elements;\n\nvar pushAll = Function.prototype.apply.bind(Array.prototype.push);\n\n/*\n * This file contains an implementation of the HTML parsing algorithm.\n * The algorithm and the implementation are complex because HTML\n * explicitly defines how the parser should behave for all possible\n * valid and invalid inputs.\n *\n * Usage:\n *\n * The file defines a single HTMLParser() function, which dom.js exposes\n * publicly as document.implementation.mozHTMLParser(). This is a\n * factory function, not a constructor.\n *\n * When you call document.implementation.mozHTMLParser(), it returns\n * an object that has parse() and document() methods. To parse HTML text,\n * pass the text (in one or more chunks) to the parse() method. When\n * you've passed all the text (on the last chunk, or afterward) pass\n * true as the second argument to parse() to tell the parser that there\n * is no more coming. Call document() to get the document object that\n * the parser is parsing into. You can call this at any time, before\n * or after calling parse().\n *\n * The first argument to mozHTMLParser is the absolute URL of the document.\n *\n * The second argument is optional and is for internal use only. Pass an\n * element as the fragmentContext to do innerHTML parsing for the\n * element. To do innerHTML parsing on a document, pass null. Otherwise,\n * omit the 2nd argument. See HTMLElement.innerHTML for an example. Note\n * that if you pass a context element, the end() method will return an\n * unwrapped document instead of a wrapped one.\n *\n * Implementation details:\n *\n * This is a long file of almost 7000 lines. It is structured as one\n * big function nested within another big function. The outer\n * function defines a bunch of constant data, utility functions\n * that use that data, and a couple of classes used by the parser.\n * The outer function also defines and returns the\n * inner function. This inner function is the HTMLParser factory\n * function that implements the parser and holds all the parser state\n * as local variables. The HTMLParser function is quite big because\n * it defines many nested functions that use those local variables.\n *\n * There are three tightly coupled parser stages: a scanner, a\n * tokenizer and a tree builder. In a (possibly misguided) attempt at\n * efficiency, the stages are not implemented as separate classes:\n * everything shares state and is (mostly) implemented in imperative\n * (rather than OO) style.\n *\n * The stages of the parser work like this: When the client code calls\n * the parser's parse() method, the specified string is passed to\n * scanChars(). The scanner loops through that string and passes characters\n * (sometimes one at a time, sometimes in chunks) to the tokenizer stage.\n * The tokenizer groups the characters into tokens: tags, endtags, runs\n * of text, comments, doctype declarations, and the end-of-file (EOF)\n * token. These tokens are then passed to the tree building stage via\n * the insertToken() function. The tree building stage builds up the\n * document tree.\n *\n * The tokenizer stage is a finite state machine. Each state is\n * implemented as a function with a name that ends in \"_state\". The\n * initial state is data_state(). The current tokenizer state is stored\n * in the variable 'tokenizer'. Most state functions expect a single\n * integer argument which represents a single UTF-16 codepoint. Some\n * states want more characters and set a lookahead property on\n * themselves. The scanChars() function in the scanner checks for this\n * lookahead property. If it doesn't exist, then scanChars() just passes\n * the next input character to the current tokenizer state function.\n * Otherwise, scanChars() looks ahead (a given # of characters, or for a\n * matching string, or for a matching regexp) and passes a string of\n * characters to the current tokenizer state function.\n *\n * As a shortcut, certain states of the tokenizer use regular expressions\n * to look ahead in the scanner's input buffer for runs of text, simple\n * tags and attributes. For well-formed input, these shortcuts skip a\n * lot of state transitions and speed things up a bit.\n *\n * When a tokenizer state function has consumed a complete token, it\n * emits that token, by calling insertToken(), or by calling a utility\n * function that itself calls insertToken(). These tokens are passed to\n * the tree building stage, which is also a state machine. Like the\n * tokenizer, the tree building states are implemented as functions, and\n * these functions have names that end with _mode (because the HTML spec\n * refers to them as insertion modes). The current insertion mode is held\n * by the 'parser' variable. Each insertion mode function takes up to 4\n * arguments. The first is a token type, represented by the constants\n * TAG, ENDTAG, TEXT, COMMENT, DOCTYPE and EOF. The second argument is\n * the value of the token: the text or comment data, or tagname or\n * doctype. For tags, the 3rd argument is an array of attributes. For\n * DOCTYPES it is the optional public id. For tags, the 4th argument is\n * true if the tag is self-closing. For doctypes, the 4th argument is the\n * optional system id.\n *\n * Search for \"***\" to find the major sub-divisions in the code.\n */\n\n\n/***\n * Data prolog. Lots of constants declared here, including some\n * very large objects. They're used throughout the code that follows\n */\n// Token types for the tree builder.\nvar EOF = -1;\nvar TEXT = 1;\nvar TAG = 2;\nvar ENDTAG = 3;\nvar COMMENT = 4;\nvar DOCTYPE = 5;\n\n// A re-usable empty array\nvar NOATTRS = [];\n\n// These DTD public ids put the browser in quirks mode\nvar quirkyPublicIds = /^HTML$|^-\\/\\/W3O\\/\\/DTD W3 HTML Strict 3\\.0\\/\\/EN\\/\\/$|^-\\/W3C\\/DTD HTML 4\\.0 Transitional\\/EN$|^\\+\\/\\/Silmaril\\/\\/dtd html Pro v0r11 19970101\\/\\/|^-\\/\\/AdvaSoft Ltd\\/\\/DTD HTML 3\\.0 asWedit \\+ extensions\\/\\/|^-\\/\\/AS\\/\\/DTD HTML 3\\.0 asWedit \\+ extensions\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0 Level 1\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0 Level 2\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0 Strict Level 1\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0 Strict Level 2\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0 Strict\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.0\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 2\\.1E\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 3\\.0\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 3\\.2 Final\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 3\\.2\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML 3\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Level 0\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Level 1\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Level 2\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Level 3\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Strict Level 0\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Strict Level 1\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Strict Level 2\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Strict Level 3\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML Strict\\/\\/|^-\\/\\/IETF\\/\\/DTD HTML\\/\\/|^-\\/\\/Metrius\\/\\/DTD Metrius Presentational\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 2\\.0 HTML Strict\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 2\\.0 HTML\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 2\\.0 Tables\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 3\\.0 HTML Strict\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 3\\.0 HTML\\/\\/|^-\\/\\/Microsoft\\/\\/DTD Internet Explorer 3\\.0 Tables\\/\\/|^-\\/\\/Netscape Comm\\. Corp\\.\\/\\/DTD HTML\\/\\/|^-\\/\\/Netscape Comm\\. Corp\\.\\/\\/DTD Strict HTML\\/\\/|^-\\/\\/O'Reilly and Associates\\/\\/DTD HTML 2\\.0\\/\\/|^-\\/\\/O'Reilly and Associates\\/\\/DTD HTML Extended 1\\.0\\/\\/|^-\\/\\/O'Reilly and Associates\\/\\/DTD HTML Extended Relaxed 1\\.0\\/\\/|^-\\/\\/SoftQuad Software\\/\\/DTD HoTMetaL PRO 6\\.0::19990601::extensions to HTML 4\\.0\\/\\/|^-\\/\\/SoftQuad\\/\\/DTD HoTMetaL PRO 4\\.0::19971010::extensions to HTML 4\\.0\\/\\/|^-\\/\\/Spyglass\\/\\/DTD HTML 2\\.0 Extended\\/\\/|^-\\/\\/SQ\\/\\/DTD HTML 2\\.0 HoTMetaL \\+ extensions\\/\\/|^-\\/\\/Sun Microsystems Corp\\.\\/\\/DTD HotJava HTML\\/\\/|^-\\/\\/Sun Microsystems Corp\\.\\/\\/DTD HotJava Strict HTML\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 3 1995-03-24\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 3\\.2 Draft\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 3\\.2 Final\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 3\\.2\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 3\\.2S Draft\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 4\\.0 Frameset\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 4\\.0 Transitional\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML Experimental 19960712\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML Experimental 970421\\/\\/|^-\\/\\/W3C\\/\\/DTD W3 HTML\\/\\/|^-\\/\\/W3O\\/\\/DTD W3 HTML 3\\.0\\/\\/|^-\\/\\/WebTechs\\/\\/DTD Mozilla HTML 2\\.0\\/\\/|^-\\/\\/WebTechs\\/\\/DTD Mozilla HTML\\/\\//i;\n\nvar quirkySystemId = \"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd\";\n\nvar conditionallyQuirkyPublicIds = /^-\\/\\/W3C\\/\\/DTD HTML 4\\.01 Frameset\\/\\/|^-\\/\\/W3C\\/\\/DTD HTML 4\\.01 Transitional\\/\\//i;\n\n// These DTD public ids put the browser in limited quirks mode\nvar limitedQuirkyPublicIds = /^-\\/\\/W3C\\/\\/DTD XHTML 1\\.0 Frameset\\/\\/|^-\\/\\/W3C\\/\\/DTD XHTML 1\\.0 Transitional\\/\\//i;\n\n\n// Element sets below. See the isA() function for a way to test\n// whether an element is a member of a set\nvar specialSet = Object.create(null);\nspecialSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"address\":true, \"applet\":true, \"area\":true, \"article\":true,\n \"aside\":true, \"base\":true, \"basefont\":true, \"bgsound\":true,\n \"blockquote\":true, \"body\":true, \"br\":true, \"button\":true,\n \"caption\":true, \"center\":true, \"col\":true, \"colgroup\":true,\n \"dd\":true, \"details\":true, \"dir\":true,\n \"div\":true, \"dl\":true, \"dt\":true, \"embed\":true,\n \"fieldset\":true, \"figcaption\":true, \"figure\":true, \"footer\":true,\n \"form\":true, \"frame\":true, \"frameset\":true, \"h1\":true,\n \"h2\":true, \"h3\":true, \"h4\":true, \"h5\":true,\n \"h6\":true, \"head\":true, \"header\":true, \"hgroup\":true,\n \"hr\":true, \"html\":true, \"iframe\":true, \"img\":true,\n \"input\":true, \"li\":true, \"link\":true,\n \"listing\":true, \"main\":true, \"marquee\":true, \"menu\":true, \"meta\":true,\n \"nav\":true, \"noembed\":true, \"noframes\":true, \"noscript\":true,\n \"object\":true, \"ol\":true, \"p\":true, \"param\":true,\n \"plaintext\":true, \"pre\":true, \"script\":true, \"section\":true,\n \"select\":true, \"source\":true, \"style\":true, \"summary\":true, \"table\":true,\n \"tbody\":true, \"td\":true, \"template\":true, \"textarea\":true, \"tfoot\":true,\n \"th\":true, \"thead\":true, \"title\":true, \"tr\":true, \"track\":true,\n // Note that \"xmp\" was removed from the \"special\" set in the latest\n // spec, apparently by accident; see\n // https://github.com/whatwg/html/pull/1919\n \"ul\":true, \"wbr\":true, \"xmp\":true\n};\nspecialSet[NAMESPACE.SVG] = {\n __proto__: null,\n \"foreignObject\": true, \"desc\": true, \"title\": true\n};\nspecialSet[NAMESPACE.MATHML] = {\n __proto__: null,\n \"mi\":true, \"mo\":true, \"mn\":true, \"ms\":true,\n \"mtext\":true, \"annotation-xml\":true\n};\n\n// The set of address, div, and p HTML tags\nvar addressdivpSet = Object.create(null);\naddressdivpSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"address\":true, \"div\":true, \"p\":true\n};\n\nvar dddtSet = Object.create(null);\ndddtSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"dd\":true, \"dt\":true\n};\n\nvar tablesectionrowSet = Object.create(null);\ntablesectionrowSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"table\":true, \"thead\":true, \"tbody\":true, \"tfoot\":true, \"tr\":true\n};\n\nvar impliedEndTagsSet = Object.create(null);\nimpliedEndTagsSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"dd\": true, \"dt\": true, \"li\": true, \"menuitem\": true, \"optgroup\": true,\n \"option\": true, \"p\": true, \"rb\": true, \"rp\": true, \"rt\": true, \"rtc\": true\n};\n\nvar thoroughImpliedEndTagsSet = Object.create(null);\nthoroughImpliedEndTagsSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"caption\": true, \"colgroup\": true, \"dd\": true, \"dt\": true, \"li\": true,\n \"optgroup\": true, \"option\": true, \"p\": true, \"rb\": true, \"rp\": true,\n \"rt\": true, \"rtc\": true, \"tbody\": true, \"td\": true, \"tfoot\": true,\n \"th\": true, \"thead\": true, \"tr\": true\n};\n\nvar tableContextSet = Object.create(null);\ntableContextSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"table\": true, \"template\": true, \"html\": true\n};\n\nvar tableBodyContextSet = Object.create(null);\ntableBodyContextSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"tbody\": true, \"tfoot\": true, \"thead\": true, \"template\": true, \"html\": true\n};\n\nvar tableRowContextSet = Object.create(null);\ntableRowContextSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"tr\": true, \"template\": true, \"html\": true\n};\n\n// See http://www.w3.org/TR/html5/forms.html#form-associated-element\nvar formassociatedSet = Object.create(null);\nformassociatedSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"button\": true, \"fieldset\": true, \"input\": true, \"keygen\": true,\n \"object\": true, \"output\": true, \"select\": true, \"textarea\": true,\n \"img\": true\n};\n\nvar inScopeSet = Object.create(null);\ninScopeSet[NAMESPACE.HTML]= {\n __proto__: null,\n \"applet\":true, \"caption\":true, \"html\":true, \"table\":true,\n \"td\":true, \"th\":true, \"marquee\":true, \"object\":true,\n \"template\":true\n};\ninScopeSet[NAMESPACE.MATHML] = {\n __proto__: null,\n \"mi\":true, \"mo\":true, \"mn\":true, \"ms\":true,\n \"mtext\":true, \"annotation-xml\":true\n};\ninScopeSet[NAMESPACE.SVG] = {\n __proto__: null,\n \"foreignObject\":true, \"desc\":true, \"title\":true\n};\n\nvar inListItemScopeSet = Object.create(inScopeSet);\ninListItemScopeSet[NAMESPACE.HTML] =\n Object.create(inScopeSet[NAMESPACE.HTML]);\ninListItemScopeSet[NAMESPACE.HTML].ol = true;\ninListItemScopeSet[NAMESPACE.HTML].ul = true;\n\nvar inButtonScopeSet = Object.create(inScopeSet);\ninButtonScopeSet[NAMESPACE.HTML] =\n Object.create(inScopeSet[NAMESPACE.HTML]);\ninButtonScopeSet[NAMESPACE.HTML].button = true;\n\nvar inTableScopeSet = Object.create(null);\ninTableScopeSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"html\":true, \"table\":true, \"template\":true\n};\n\n// The set of elements for select scope is the everything *except* these\nvar invertedSelectScopeSet = Object.create(null);\ninvertedSelectScopeSet[NAMESPACE.HTML] = {\n __proto__: null,\n \"optgroup\":true, \"option\":true\n};\n\nvar mathmlTextIntegrationPointSet = Object.create(null);\nmathmlTextIntegrationPointSet[NAMESPACE.MATHML] = {\n __proto__: null,\n mi: true,\n mo: true,\n mn: true,\n ms: true,\n mtext: true\n};\n\nvar htmlIntegrationPointSet = Object.create(null);\nhtmlIntegrationPointSet[NAMESPACE.SVG] = {\n __proto__: null,\n foreignObject: true,\n desc: true,\n title: true\n};\n\nvar foreignAttributes = {\n __proto__: null,\n \"xlink:actuate\": NAMESPACE.XLINK, \"xlink:arcrole\": NAMESPACE.XLINK,\n \"xlink:href\": NAMESPACE.XLINK, \"xlink:role\": NAMESPACE.XLINK,\n \"xlink:show\": NAMESPACE.XLINK, \"xlink:title\": NAMESPACE.XLINK,\n \"xlink:type\": NAMESPACE.XLINK, \"xml:base\": NAMESPACE.XML,\n \"xml:lang\": NAMESPACE.XML, \"xml:space\": NAMESPACE.XML,\n \"xmlns\": NAMESPACE.XMLNS, \"xmlns:xlink\": NAMESPACE.XMLNS\n};\n\n\n// Lowercase to mixed case mapping for SVG attributes and tagnames\nvar svgAttrAdjustments = {\n __proto__: null,\n attributename: \"attributeName\", attributetype: \"attributeType\",\n basefrequency: \"baseFrequency\", baseprofile: \"baseProfile\",\n calcmode: \"calcMode\", clippathunits: \"clipPathUnits\",\n diffuseconstant: \"diffuseConstant\",\n edgemode: \"edgeMode\",\n filterunits: \"filterUnits\",\n glyphref: \"glyphRef\", gradienttransform: \"gradientTransform\",\n gradientunits: \"gradientUnits\", kernelmatrix: \"kernelMatrix\",\n kernelunitlength: \"kernelUnitLength\", keypoints: \"keyPoints\",\n keysplines: \"keySplines\", keytimes: \"keyTimes\",\n lengthadjust: \"lengthAdjust\", limitingconeangle: \"limitingConeAngle\",\n markerheight: \"markerHeight\", markerunits: \"markerUnits\",\n markerwidth: \"markerWidth\", maskcontentunits: \"maskContentUnits\",\n maskunits: \"maskUnits\", numoctaves: \"numOctaves\",\n pathlength: \"pathLength\", patterncontentunits: \"patternContentUnits\",\n patterntransform: \"patternTransform\", patternunits: \"patternUnits\",\n pointsatx: \"pointsAtX\", pointsaty: \"pointsAtY\",\n pointsatz: \"pointsAtZ\", preservealpha: \"preserveAlpha\",\n preserveaspectratio: \"preserveAspectRatio\",\n primitiveunits: \"primitiveUnits\", refx: \"refX\",\n refy: \"refY\", repeatcount: \"repeatCount\",\n repeatdur: \"repeatDur\", requiredextensions: \"requiredExtensions\",\n requiredfeatures: \"requiredFeatures\",\n specularconstant: \"specularConstant\",\n specularexponent: \"specularExponent\", spreadmethod: \"spreadMethod\",\n startoffset: \"startOffset\", stddeviation: \"stdDeviation\",\n stitchtiles: \"stitchTiles\", surfacescale: \"surfaceScale\",\n systemlanguage: \"systemLanguage\", tablevalues: \"tableValues\",\n targetx: \"targetX\", targety: \"targetY\",\n textlength: \"textLength\", viewbox: \"viewBox\",\n viewtarget: \"viewTarget\", xchannelselector: \"xChannelSelector\",\n ychannelselector: \"yChannelSelector\", zoomandpan: \"zoomAndPan\"\n};\n\nvar svgTagNameAdjustments = {\n __proto__: null,\n altglyph: \"altGlyph\", altglyphdef: \"altGlyphDef\",\n altglyphitem: \"altGlyphItem\", animatecolor: \"animateColor\",\n animatemotion: \"animateMotion\", animatetransform: \"animateTransform\",\n clippath: \"clipPath\", feblend: \"feBlend\",\n fecolormatrix: \"feColorMatrix\",\n fecomponenttransfer: \"feComponentTransfer\", fecomposite: \"feComposite\",\n feconvolvematrix: \"feConvolveMatrix\",\n fediffuselighting: \"feDiffuseLighting\",\n fedisplacementmap: \"feDisplacementMap\",\n fedistantlight: \"feDistantLight\", feflood: \"feFlood\",\n fefunca: \"feFuncA\", fefuncb: \"feFuncB\",\n fefuncg: \"feFuncG\", fefuncr: \"feFuncR\",\n fegaussianblur: \"feGaussianBlur\", feimage: \"feImage\",\n femerge: \"feMerge\", femergenode: \"feMergeNode\",\n femorphology: \"feMorphology\", feoffset: \"feOffset\",\n fepointlight: \"fePointLight\", fespecularlighting: \"feSpecularLighting\",\n fespotlight: \"feSpotLight\", fetile: \"feTile\",\n feturbulence: \"feTurbulence\", foreignobject: \"foreignObject\",\n glyphref: \"glyphRef\", lineargradient: \"linearGradient\",\n radialgradient: \"radialGradient\", textpath: \"textPath\"\n};\n\n\n// Data for parsing numeric and named character references\n// These next 3 objects are direct translations of tables\n// in the HTML spec into JavaScript object format\nvar numericCharRefReplacements = {\n __proto__: null,\n 0x00:0xFFFD, 0x80:0x20AC, 0x82:0x201A, 0x83:0x0192, 0x84:0x201E,\n 0x85:0x2026, 0x86:0x2020, 0x87:0x2021, 0x88:0x02C6, 0x89:0x2030,\n 0x8A:0x0160, 0x8B:0x2039, 0x8C:0x0152, 0x8E:0x017D, 0x91:0x2018,\n 0x92:0x2019, 0x93:0x201C, 0x94:0x201D, 0x95:0x2022, 0x96:0x2013,\n 0x97:0x2014, 0x98:0x02DC, 0x99:0x2122, 0x9A:0x0161, 0x9B:0x203A,\n 0x9C:0x0153, 0x9E:0x017E, 0x9F:0x0178\n};\n\n/*\n * This table is generated with test/tools/update-entities.js\n */\nvar namedCharRefs = {\n __proto__: null,\n \"AElig\":0xc6, \"AElig;\":0xc6,\n \"AMP\":0x26, \"AMP;\":0x26,\n \"Aacute\":0xc1, \"Aacute;\":0xc1,\n \"Abreve;\":0x102, \"Acirc\":0xc2,\n \"Acirc;\":0xc2, \"Acy;\":0x410,\n \"Afr;\":[0xd835,0xdd04], \"Agrave\":0xc0,\n \"Agrave;\":0xc0, \"Alpha;\":0x391,\n \"Amacr;\":0x100, \"And;\":0x2a53,\n \"Aogon;\":0x104, \"Aopf;\":[0xd835,0xdd38],\n \"ApplyFunction;\":0x2061, \"Aring\":0xc5,\n \"Aring;\":0xc5, \"Ascr;\":[0xd835,0xdc9c],\n \"Assign;\":0x2254, \"Atilde\":0xc3,\n \"Atilde;\":0xc3, \"Auml\":0xc4,\n \"Auml;\":0xc4, \"Backslash;\":0x2216,\n \"Barv;\":0x2ae7, \"Barwed;\":0x2306,\n \"Bcy;\":0x411, \"Because;\":0x2235,\n \"Bernoullis;\":0x212c, \"Beta;\":0x392,\n \"Bfr;\":[0xd835,0xdd05], \"Bopf;\":[0xd835,0xdd39],\n \"Breve;\":0x2d8, \"Bscr;\":0x212c,\n \"Bumpeq;\":0x224e, \"CHcy;\":0x427,\n \"COPY\":0xa9, \"COPY;\":0xa9,\n \"Cacute;\":0x106, \"Cap;\":0x22d2,\n \"CapitalDifferentialD;\":0x2145, \"Cayleys;\":0x212d,\n \"Ccaron;\":0x10c, \"Ccedil\":0xc7,\n \"Ccedil;\":0xc7, \"Ccirc;\":0x108,\n \"Cconint;\":0x2230, \"Cdot;\":0x10a,\n \"Cedilla;\":0xb8, \"CenterDot;\":0xb7,\n \"Cfr;\":0x212d, \"Chi;\":0x3a7,\n \"CircleDot;\":0x2299, \"CircleMinus;\":0x2296,\n \"CirclePlus;\":0x2295, \"CircleTimes;\":0x2297,\n \"ClockwiseContourIntegral;\":0x2232, \"CloseCurlyDoubleQuote;\":0x201d,\n \"CloseCurlyQuote;\":0x2019, \"Colon;\":0x2237,\n \"Colone;\":0x2a74, \"Congruent;\":0x2261,\n \"Conint;\":0x222f, \"ContourIntegral;\":0x222e,\n \"Copf;\":0x2102, \"Coproduct;\":0x2210,\n \"CounterClockwiseContourIntegral;\":0x2233, \"Cross;\":0x2a2f,\n \"Cscr;\":[0xd835,0xdc9e], \"Cup;\":0x22d3,\n \"CupCap;\":0x224d, \"DD;\":0x2145,\n \"DDotrahd;\":0x2911, \"DJcy;\":0x402,\n \"DScy;\":0x405, \"DZcy;\":0x40f,\n \"Dagger;\":0x2021, \"Darr;\":0x21a1,\n \"Dashv;\":0x2ae4, \"Dcaron;\":0x10e,\n \"Dcy;\":0x414, \"Del;\":0x2207,\n \"Delta;\":0x394, \"Dfr;\":[0xd835,0xdd07],\n \"DiacriticalAcute;\":0xb4, \"DiacriticalDot;\":0x2d9,\n \"DiacriticalDoubleAcute;\":0x2dd, \"DiacriticalGrave;\":0x60,\n \"DiacriticalTilde;\":0x2dc, \"Diamond;\":0x22c4,\n \"DifferentialD;\":0x2146, \"Dopf;\":[0xd835,0xdd3b],\n \"Dot;\":0xa8, \"DotDot;\":0x20dc,\n \"DotEqual;\":0x2250, \"DoubleContourIntegral;\":0x222f,\n \"DoubleDot;\":0xa8, \"DoubleDownArrow;\":0x21d3,\n \"DoubleLeftArrow;\":0x21d0, \"DoubleLeftRightArrow;\":0x21d4,\n \"DoubleLeftTee;\":0x2ae4, \"DoubleLongLeftArrow;\":0x27f8,\n \"DoubleLongLeftRightArrow;\":0x27fa, \"DoubleLongRightArrow;\":0x27f9,\n \"DoubleRightArrow;\":0x21d2, \"DoubleRightTee;\":0x22a8,\n \"DoubleUpArrow;\":0x21d1, \"DoubleUpDownArrow;\":0x21d5,\n \"DoubleVerticalBar;\":0x2225, \"DownArrow;\":0x2193,\n \"DownArrowBar;\":0x2913, \"DownArrowUpArrow;\":0x21f5,\n \"DownBreve;\":0x311, \"DownLeftRightVector;\":0x2950,\n \"DownLeftTeeVector;\":0x295e, \"DownLeftVector;\":0x21bd,\n \"DownLeftVectorBar;\":0x2956, \"DownRightTeeVector;\":0x295f,\n \"DownRightVector;\":0x21c1, \"DownRightVectorBar;\":0x2957,\n \"DownTee;\":0x22a4, \"DownTeeArrow;\":0x21a7,\n \"Downarrow;\":0x21d3, \"Dscr;\":[0xd835,0xdc9f],\n \"Dstrok;\":0x110, \"ENG;\":0x14a,\n \"ETH\":0xd0, \"ETH;\":0xd0,\n \"Eacute\":0xc9, \"Eacute;\":0xc9,\n \"Ecaron;\":0x11a, \"Ecirc\":0xca,\n \"Ecirc;\":0xca, \"Ecy;\":0x42d,\n \"Edot;\":0x116, \"Efr;\":[0xd835,0xdd08],\n \"Egrave\":0xc8, \"Egrave;\":0xc8,\n \"Element;\":0x2208, \"Emacr;\":0x112,\n \"EmptySmallSquare;\":0x25fb, \"EmptyVerySmallSquare;\":0x25ab,\n \"Eogon;\":0x118, \"Eopf;\":[0xd835,0xdd3c],\n \"Epsilon;\":0x395, \"Equal;\":0x2a75,\n \"EqualTilde;\":0x2242, \"Equilibrium;\":0x21cc,\n \"Escr;\":0x2130, \"Esim;\":0x2a73,\n \"Eta;\":0x397, \"Euml\":0xcb,\n \"Euml;\":0xcb, \"Exists;\":0x2203,\n \"ExponentialE;\":0x2147, \"Fcy;\":0x424,\n \"Ffr;\":[0xd835,0xdd09], \"FilledSmallSquare;\":0x25fc,\n \"FilledVerySmallSquare;\":0x25aa, \"Fopf;\":[0xd835,0xdd3d],\n \"ForAll;\":0x2200, \"Fouriertrf;\":0x2131,\n \"Fscr;\":0x2131, \"GJcy;\":0x403,\n \"GT\":0x3e, \"GT;\":0x3e,\n \"Gamma;\":0x393, \"Gammad;\":0x3dc,\n \"Gbreve;\":0x11e, \"Gcedil;\":0x122,\n \"Gcirc;\":0x11c, \"Gcy;\":0x413,\n \"Gdot;\":0x120, \"Gfr;\":[0xd835,0xdd0a],\n \"Gg;\":0x22d9, \"Gopf;\":[0xd835,0xdd3e],\n \"GreaterEqual;\":0x2265, \"GreaterEqualLess;\":0x22db,\n \"GreaterFullEqual;\":0x2267, \"GreaterGreater;\":0x2aa2,\n \"GreaterLess;\":0x2277, \"GreaterSlantEqual;\":0x2a7e,\n \"GreaterTilde;\":0x2273, \"Gscr;\":[0xd835,0xdca2],\n \"Gt;\":0x226b, \"HARDcy;\":0x42a,\n \"Hacek;\":0x2c7, \"Hat;\":0x5e,\n \"Hcirc;\":0x124, \"Hfr;\":0x210c,\n \"HilbertSpace;\":0x210b, \"Hopf;\":0x210d,\n \"HorizontalLine;\":0x2500, \"Hscr;\":0x210b,\n \"Hstrok;\":0x126, \"HumpDownHump;\":0x224e,\n \"HumpEqual;\":0x224f, \"IEcy;\":0x415,\n \"IJlig;\":0x132, \"IOcy;\":0x401,\n \"Iacute\":0xcd, \"Iacute;\":0xcd,\n \"Icirc\":0xce, \"Icirc;\":0xce,\n \"Icy;\":0x418, \"Idot;\":0x130,\n \"Ifr;\":0x2111, \"Igrave\":0xcc,\n \"Igrave;\":0xcc, \"Im;\":0x2111,\n \"Imacr;\":0x12a, \"ImaginaryI;\":0x2148,\n \"Implies;\":0x21d2, \"Int;\":0x222c,\n \"Integral;\":0x222b, \"Intersection;\":0x22c2,\n \"InvisibleComma;\":0x2063, \"InvisibleTimes;\":0x2062,\n \"Iogon;\":0x12e, \"Iopf;\":[0xd835,0xdd40],\n \"Iota;\":0x399, \"Iscr;\":0x2110,\n \"Itilde;\":0x128, \"Iukcy;\":0x406,\n \"Iuml\":0xcf, \"Iuml;\":0xcf,\n \"Jcirc;\":0x134, \"Jcy;\":0x419,\n \"Jfr;\":[0xd835,0xdd0d], \"Jopf;\":[0xd835,0xdd41],\n \"Jscr;\":[0xd835,0xdca5], \"Jsercy;\":0x408,\n \"Jukcy;\":0x404, \"KHcy;\":0x425,\n \"KJcy;\":0x40c, \"Kappa;\":0x39a,\n \"Kcedil;\":0x136, \"Kcy;\":0x41a,\n \"Kfr;\":[0xd835,0xdd0e], \"Kopf;\":[0xd835,0xdd42],\n \"Kscr;\":[0xd835,0xdca6], \"LJcy;\":0x409,\n \"LT\":0x3c, \"LT;\":0x3c,\n \"Lacute;\":0x139, \"Lambda;\":0x39b,\n \"Lang;\":0x27ea, \"Laplacetrf;\":0x2112,\n \"Larr;\":0x219e, \"Lcaron;\":0x13d,\n \"Lcedil;\":0x13b, \"Lcy;\":0x41b,\n \"LeftAngleBracket;\":0x27e8, \"LeftArrow;\":0x2190,\n \"LeftArrowBar;\":0x21e4, \"LeftArrowRightArrow;\":0x21c6,\n \"LeftCeiling;\":0x2308, \"LeftDoubleBracket;\":0x27e6,\n \"LeftDownTeeVector;\":0x2961, \"LeftDownVector;\":0x21c3,\n \"LeftDownVectorBar;\":0x2959, \"LeftFloor;\":0x230a,\n \"LeftRightArrow;\":0x2194, \"LeftRightVector;\":0x294e,\n \"LeftTee;\":0x22a3, \"LeftTeeArrow;\":0x21a4,\n \"LeftTeeVector;\":0x295a, \"LeftTriangle;\":0x22b2,\n \"LeftTriangleBar;\":0x29cf, \"LeftTriangleEqual;\":0x22b4,\n \"LeftUpDownVector;\":0x2951, \"LeftUpTeeVector;\":0x2960,\n \"LeftUpVector;\":0x21bf, \"LeftUpVectorBar;\":0x2958,\n \"LeftVector;\":0x21bc, \"LeftVectorBar;\":0x2952,\n \"Leftarrow;\":0x21d0, \"Leftrightarrow;\":0x21d4,\n \"LessEqualGreater;\":0x22da, \"LessFullEqual;\":0x2266,\n \"LessGreater;\":0x2276, \"LessLess;\":0x2aa1,\n \"LessSlantEqual;\":0x2a7d, \"LessTilde;\":0x2272,\n \"Lfr;\":[0xd835,0xdd0f], \"Ll;\":0x22d8,\n \"Lleftarrow;\":0x21da, \"Lmidot;\":0x13f,\n \"LongLeftArrow;\":0x27f5, \"LongLeftRightArrow;\":0x27f7,\n \"LongRightArrow;\":0x27f6, \"Longleftarrow;\":0x27f8,\n \"Longleftrightarrow;\":0x27fa, \"Longrightarrow;\":0x27f9,\n \"Lopf;\":[0xd835,0xdd43], \"LowerLeftArrow;\":0x2199,\n \"LowerRightArrow;\":0x2198, \"Lscr;\":0x2112,\n \"Lsh;\":0x21b0, \"Lstrok;\":0x141,\n \"Lt;\":0x226a, \"Map;\":0x2905,\n \"Mcy;\":0x41c, \"MediumSpace;\":0x205f,\n \"Mellintrf;\":0x2133, \"Mfr;\":[0xd835,0xdd10],\n \"MinusPlus;\":0x2213, \"Mopf;\":[0xd835,0xdd44],\n \"Mscr;\":0x2133, \"Mu;\":0x39c,\n \"NJcy;\":0x40a, \"Nacute;\":0x143,\n \"Ncaron;\":0x147, \"Ncedil;\":0x145,\n \"Ncy;\":0x41d, \"NegativeMediumSpace;\":0x200b,\n \"NegativeThickSpace;\":0x200b, \"NegativeThinSpace;\":0x200b,\n \"NegativeVeryThinSpace;\":0x200b, \"NestedGreaterGreater;\":0x226b,\n \"NestedLessLess;\":0x226a, \"NewLine;\":0xa,\n \"Nfr;\":[0xd835,0xdd11], \"NoBreak;\":0x2060,\n \"NonBreakingSpace;\":0xa0, \"Nopf;\":0x2115,\n \"Not;\":0x2aec, \"NotCongruent;\":0x2262,\n \"NotCupCap;\":0x226d, \"NotDoubleVerticalBar;\":0x2226,\n \"NotElement;\":0x2209, \"NotEqual;\":0x2260,\n \"NotEqualTilde;\":[0x2242,0x338], \"NotExists;\":0x2204,\n \"NotGreater;\":0x226f, \"NotGreaterEqual;\":0x2271,\n \"NotGreaterFullEqual;\":[0x2267,0x338], \"NotGreaterGreater;\":[0x226b,0x338],\n \"NotGreaterLess;\":0x2279, \"NotGreaterSlantEqual;\":[0x2a7e,0x338],\n \"NotGreaterTilde;\":0x2275, \"NotHumpDownHump;\":[0x224e,0x338],\n \"NotHumpEqual;\":[0x224f,0x338], \"NotLeftTriangle;\":0x22ea,\n \"NotLeftTriangleBar;\":[0x29cf,0x338], \"NotLeftTriangleEqual;\":0x22ec,\n \"NotLess;\":0x226e, \"NotLessEqual;\":0x2270,\n \"NotLessGreater;\":0x2278, \"NotLessLess;\":[0x226a,0x338],\n \"NotLessSlantEqual;\":[0x2a7d,0x338], \"NotLessTilde;\":0x2274,\n \"NotNestedGreaterGreater;\":[0x2aa2,0x338], \"NotNestedLessLess;\":[0x2aa1,0x338],\n \"NotPrecedes;\":0x2280, \"NotPrecedesEqual;\":[0x2aaf,0x338],\n \"NotPrecedesSlantEqual;\":0x22e0, \"NotReverseElement;\":0x220c,\n \"NotRightTriangle;\":0x22eb, \"NotRightTriangleBar;\":[0x29d0,0x338],\n \"NotRightTriangleEqual;\":0x22ed, \"NotSquareSubset;\":[0x228f,0x338],\n \"NotSquareSubsetEqual;\":0x22e2, \"NotSquareSuperset;\":[0x2290,0x338],\n \"NotSquareSupersetEqual;\":0x22e3, \"NotSubset;\":[0x2282,0x20d2],\n \"NotSubsetEqual;\":0x2288, \"NotSucceeds;\":0x2281,\n \"NotSucceedsEqual;\":[0x2ab0,0x338], \"NotSucceedsSlantEqual;\":0x22e1,\n \"NotSucceedsTilde;\":[0x227f,0x338], \"NotSuperset;\":[0x2283,0x20d2],\n \"NotSupersetEqual;\":0x2289, \"NotTilde;\":0x2241,\n \"NotTildeEqual;\":0x2244, \"NotTildeFullEqual;\":0x2247,\n \"NotTildeTilde;\":0x2249, \"NotVerticalBar;\":0x2224,\n \"Nscr;\":[0xd835,0xdca9], \"Ntilde\":0xd1,\n \"Ntilde;\":0xd1, \"Nu;\":0x39d,\n \"OElig;\":0x152, \"Oacute\":0xd3,\n \"Oacute;\":0xd3, \"Ocirc\":0xd4,\n \"Ocirc;\":0xd4, \"Ocy;\":0x41e,\n \"Odblac;\":0x150, \"Ofr;\":[0xd835,0xdd12],\n \"Ograve\":0xd2, \"Ograve;\":0xd2,\n \"Omacr;\":0x14c, \"Omega;\":0x3a9,\n \"Omicron;\":0x39f, \"Oopf;\":[0xd835,0xdd46],\n \"OpenCurlyDoubleQuote;\":0x201c, \"OpenCurlyQuote;\":0x2018,\n \"Or;\":0x2a54, \"Oscr;\":[0xd835,0xdcaa],\n \"Oslash\":0xd8, \"Oslash;\":0xd8,\n \"Otilde\":0xd5, \"Otilde;\":0xd5,\n \"Otimes;\":0x2a37, \"Ouml\":0xd6,\n \"Ouml;\":0xd6, \"OverBar;\":0x203e,\n \"OverBrace;\":0x23de, \"OverBracket;\":0x23b4,\n \"OverParenthesis;\":0x23dc, \"PartialD;\":0x2202,\n \"Pcy;\":0x41f, \"Pfr;\":[0xd835,0xdd13],\n \"Phi;\":0x3a6, \"Pi;\":0x3a0,\n \"PlusMinus;\":0xb1, \"Poincareplane;\":0x210c,\n \"Popf;\":0x2119, \"Pr;\":0x2abb,\n \"Precedes;\":0x227a, \"PrecedesEqual;\":0x2aaf,\n \"PrecedesSlantEqual;\":0x227c, \"PrecedesTilde;\":0x227e,\n \"Prime;\":0x2033, \"Product;\":0x220f,\n \"Proportion;\":0x2237, \"Proportional;\":0x221d,\n \"Pscr;\":[0xd835,0xdcab], \"Psi;\":0x3a8,\n \"QUOT\":0x22, \"QUOT;\":0x22,\n \"Qfr;\":[0xd835,0xdd14], \"Qopf;\":0x211a,\n \"Qscr;\":[0xd835,0xdcac], \"RBarr;\":0x2910,\n \"REG\":0xae, \"REG;\":0xae,\n \"Racute;\":0x154, \"Rang;\":0x27eb,\n \"Rarr;\":0x21a0, \"Rarrtl;\":0x2916,\n \"Rcaron;\":0x158, \"Rcedil;\":0x156,\n \"Rcy;\":0x420, \"Re;\":0x211c,\n \"ReverseElement;\":0x220b, \"ReverseEquilibrium;\":0x21cb,\n \"ReverseUpEquilibrium;\":0x296f, \"Rfr;\":0x211c,\n \"Rho;\":0x3a1, \"RightAngleBracket;\":0x27e9,\n \"RightArrow;\":0x2192, \"RightArrowBar;\":0x21e5,\n \"RightArrowLeftArrow;\":0x21c4, \"RightCeiling;\":0x2309,\n \"RightDoubleBracket;\":0x27e7, \"RightDownTeeVector;\":0x295d,\n \"RightDownVector;\":0x21c2, \"RightDownVectorBar;\":0x2955,\n \"RightFloor;\":0x230b, \"RightTee;\":0x22a2,\n \"RightTeeArrow;\":0x21a6, \"RightTeeVector;\":0x295b,\n \"RightTriangle;\":0x22b3, \"RightTriangleBar;\":0x29d0,\n \"RightTriangleEqual;\":0x22b5, \"RightUpDownVector;\":0x294f,\n \"RightUpTeeVector;\":0x295c, \"RightUpVector;\":0x21be,\n \"RightUpVectorBar;\":0x2954, \"RightVector;\":0x21c0,\n \"RightVectorBar;\":0x2953, \"Rightarrow;\":0x21d2,\n \"Ropf;\":0x211d, \"RoundImplies;\":0x2970,\n \"Rrightarrow;\":0x21db, \"Rscr;\":0x211b,\n \"Rsh;\":0x21b1, \"RuleDelayed;\":0x29f4,\n \"SHCHcy;\":0x429, \"SHcy;\":0x428,\n \"SOFTcy;\":0x42c, \"Sacute;\":0x15a,\n \"Sc;\":0x2abc, \"Scaron;\":0x160,\n \"Scedil;\":0x15e, \"Scirc;\":0x15c,\n \"Scy;\":0x421, \"Sfr;\":[0xd835,0xdd16],\n \"ShortDownArrow;\":0x2193, \"ShortLeftArrow;\":0x2190,\n \"ShortRightArrow;\":0x2192, \"ShortUpArrow;\":0x2191,\n \"Sigma;\":0x3a3, \"SmallCircle;\":0x2218,\n \"Sopf;\":[0xd835,0xdd4a], \"Sqrt;\":0x221a,\n \"Square;\":0x25a1, \"SquareIntersection;\":0x2293,\n \"SquareSubset;\":0x228f, \"SquareSubsetEqual;\":0x2291,\n \"SquareSuperset;\":0x2290, \"SquareSupersetEqual;\":0x2292,\n \"SquareUnion;\":0x2294, \"Sscr;\":[0xd835,0xdcae],\n \"Star;\":0x22c6, \"Sub;\":0x22d0,\n \"Subset;\":0x22d0, \"SubsetEqual;\":0x2286,\n \"Succeeds;\":0x227b, \"SucceedsEqual;\":0x2ab0,\n \"SucceedsSlantEqual;\":0x227d, \"SucceedsTilde;\":0x227f,\n \"SuchThat;\":0x220b, \"Sum;\":0x2211,\n \"Sup;\":0x22d1, \"Superset;\":0x2283,\n \"SupersetEqual;\":0x2287, \"Supset;\":0x22d1,\n \"THORN\":0xde, \"THORN;\":0xde,\n \"TRADE;\":0x2122, \"TSHcy;\":0x40b,\n \"TScy;\":0x426, \"Tab;\":0x9,\n \"Tau;\":0x3a4, \"Tcaron;\":0x164,\n \"Tcedil;\":0x162, \"Tcy;\":0x422,\n \"Tfr;\":[0xd835,0xdd17], \"Therefore;\":0x2234,\n \"Theta;\":0x398, \"ThickSpace;\":[0x205f,0x200a],\n \"ThinSpace;\":0x2009, \"Tilde;\":0x223c,\n \"TildeEqual;\":0x2243, \"TildeFullEqual;\":0x2245,\n \"TildeTilde;\":0x2248, \"Topf;\":[0xd835,0xdd4b],\n \"TripleDot;\":0x20db, \"Tscr;\":[0xd835,0xdcaf],\n \"Tstrok;\":0x166, \"Uacute\":0xda,\n \"Uacute;\":0xda, \"Uarr;\":0x219f,\n \"Uarrocir;\":0x2949, \"Ubrcy;\":0x40e,\n \"Ubreve;\":0x16c, \"Ucirc\":0xdb,\n \"Ucirc;\":0xdb, \"Ucy;\":0x423,\n \"Udblac;\":0x170, \"Ufr;\":[0xd835,0xdd18],\n \"Ugrave\":0xd9, \"Ugrave;\":0xd9,\n \"Umacr;\":0x16a, \"UnderBar;\":0x5f,\n \"UnderBrace;\":0x23df, \"UnderBracket;\":0x23b5,\n \"UnderParenthesis;\":0x23dd, \"Union;\":0x22c3,\n \"UnionPlus;\":0x228e, \"Uogon;\":0x172,\n \"Uopf;\":[0xd835,0xdd4c], \"UpArrow;\":0x2191,\n \"UpArrowBar;\":0x2912, \"UpArrowDownArrow;\":0x21c5,\n \"UpDownArrow;\":0x2195, \"UpEquilibrium;\":0x296e,\n \"UpTee;\":0x22a5, \"UpTeeArrow;\":0x21a5,\n \"Uparrow;\":0x21d1, \"Updownarrow;\":0x21d5,\n \"UpperLeftArrow;\":0x2196, \"UpperRightArrow;\":0x2197,\n \"Upsi;\":0x3d2, \"Upsilon;\":0x3a5,\n \"Uring;\":0x16e, \"Uscr;\":[0xd835,0xdcb0],\n \"Utilde;\":0x168, \"Uuml\":0xdc,\n \"Uuml;\":0xdc, \"VDash;\":0x22ab,\n \"Vbar;\":0x2aeb, \"Vcy;\":0x412,\n \"Vdash;\":0x22a9, \"Vdashl;\":0x2ae6,\n \"Vee;\":0x22c1, \"Verbar;\":0x2016,\n \"Vert;\":0x2016, \"VerticalBar;\":0x2223,\n \"VerticalLine;\":0x7c, \"VerticalSeparator;\":0x2758,\n \"VerticalTilde;\":0x2240, \"VeryThinSpace;\":0x200a,\n \"Vfr;\":[0xd835,0xdd19], \"Vopf;\":[0xd835,0xdd4d],\n \"Vscr;\":[0xd835,0xdcb1], \"Vvdash;\":0x22aa,\n \"Wcirc;\":0x174, \"Wedge;\":0x22c0,\n \"Wfr;\":[0xd835,0xdd1a], \"Wopf;\":[0xd835,0xdd4e],\n \"Wscr;\":[0xd835,0xdcb2], \"Xfr;\":[0xd835,0xdd1b],\n \"Xi;\":0x39e, \"Xopf;\":[0xd835,0xdd4f],\n \"Xscr;\":[0xd835,0xdcb3], \"YAcy;\":0x42f,\n \"YIcy;\":0x407, \"YUcy;\":0x42e,\n \"Yacute\":0xdd, \"Yacute;\":0xdd,\n \"Ycirc;\":0x176, \"Ycy;\":0x42b,\n \"Yfr;\":[0xd835,0xdd1c], \"Yopf;\":[0xd835,0xdd50],\n \"Yscr;\":[0xd835,0xdcb4], \"Yuml;\":0x178,\n \"ZHcy;\":0x416, \"Zacute;\":0x179,\n \"Zcaron;\":0x17d, \"Zcy;\":0x417,\n \"Zdot;\":0x17b, \"ZeroWidthSpace;\":0x200b,\n \"Zeta;\":0x396, \"Zfr;\":0x2128,\n \"Zopf;\":0x2124, \"Zscr;\":[0xd835,0xdcb5],\n \"aacute\":0xe1, \"aacute;\":0xe1,\n \"abreve;\":0x103, \"ac;\":0x223e,\n \"acE;\":[0x223e,0x333], \"acd;\":0x223f,\n \"acirc\":0xe2, \"acirc;\":0xe2,\n \"acute\":0xb4, \"acute;\":0xb4,\n \"acy;\":0x430, \"aelig\":0xe6,\n \"aelig;\":0xe6, \"af;\":0x2061,\n \"afr;\":[0xd835,0xdd1e], \"agrave\":0xe0,\n \"agrave;\":0xe0, \"alefsym;\":0x2135,\n \"aleph;\":0x2135, \"alpha;\":0x3b1,\n \"amacr;\":0x101, \"amalg;\":0x2a3f,\n \"amp\":0x26, \"amp;\":0x26,\n \"and;\":0x2227, \"andand;\":0x2a55,\n \"andd;\":0x2a5c, \"andslope;\":0x2a58,\n \"andv;\":0x2a5a, \"ang;\":0x2220,\n \"ange;\":0x29a4, \"angle;\":0x2220,\n \"angmsd;\":0x2221, \"angmsdaa;\":0x29a8,\n \"angmsdab;\":0x29a9, \"angmsdac;\":0x29aa,\n \"angmsdad;\":0x29ab, \"angmsdae;\":0x29ac,\n \"angmsdaf;\":0x29ad, \"angmsdag;\":0x29ae,\n \"angmsdah;\":0x29af, \"angrt;\":0x221f,\n \"angrtvb;\":0x22be, \"angrtvbd;\":0x299d,\n \"angsph;\":0x2222, \"angst;\":0xc5,\n \"angzarr;\":0x237c, \"aogon;\":0x105,\n \"aopf;\":[0xd835,0xdd52], \"ap;\":0x2248,\n \"apE;\":0x2a70, \"apacir;\":0x2a6f,\n \"ape;\":0x224a, \"apid;\":0x224b,\n \"apos;\":0x27, \"approx;\":0x2248,\n \"approxeq;\":0x224a, \"aring\":0xe5,\n \"aring;\":0xe5, \"ascr;\":[0xd835,0xdcb6],\n \"ast;\":0x2a, \"asymp;\":0x2248,\n \"asympeq;\":0x224d, \"atilde\":0xe3,\n \"atilde;\":0xe3, \"auml\":0xe4,\n \"auml;\":0xe4, \"awconint;\":0x2233,\n \"awint;\":0x2a11, \"bNot;\":0x2aed,\n \"backcong;\":0x224c, \"backepsilon;\":0x3f6,\n \"backprime;\":0x2035, \"backsim;\":0x223d,\n \"backsimeq;\":0x22cd, \"barvee;\":0x22bd,\n \"barwed;\":0x2305, \"barwedge;\":0x2305,\n \"bbrk;\":0x23b5, \"bbrktbrk;\":0x23b6,\n \"bcong;\":0x224c, \"bcy;\":0x431,\n \"bdquo;\":0x201e, \"becaus;\":0x2235,\n \"because;\":0x2235, \"bemptyv;\":0x29b0,\n \"bepsi;\":0x3f6, \"bernou;\":0x212c,\n \"beta;\":0x3b2, \"beth;\":0x2136,\n \"between;\":0x226c, \"bfr;\":[0xd835,0xdd1f],\n \"bigcap;\":0x22c2, \"bigcirc;\":0x25ef,\n \"bigcup;\":0x22c3, \"bigodot;\":0x2a00,\n \"bigoplus;\":0x2a01, \"bigotimes;\":0x2a02,\n \"bigsqcup;\":0x2a06, \"bigstar;\":0x2605,\n \"bigtriangledown;\":0x25bd, \"bigtriangleup;\":0x25b3,\n \"biguplus;\":0x2a04, \"bigvee;\":0x22c1,\n \"bigwedge;\":0x22c0, \"bkarow;\":0x290d,\n \"blacklozenge;\":0x29eb, \"blacksquare;\":0x25aa,\n \"blacktriangle;\":0x25b4, \"blacktriangledown;\":0x25be,\n \"blacktriangleleft;\":0x25c2, \"blacktriangleright;\":0x25b8,\n \"blank;\":0x2423, \"blk12;\":0x2592,\n \"blk14;\":0x2591, \"blk34;\":0x2593,\n \"block;\":0x2588, \"bne;\":[0x3d,0x20e5],\n \"bnequiv;\":[0x2261,0x20e5], \"bnot;\":0x2310,\n \"bopf;\":[0xd835,0xdd53], \"bot;\":0x22a5,\n \"bottom;\":0x22a5, \"bowtie;\":0x22c8,\n \"boxDL;\":0x2557, \"boxDR;\":0x2554,\n \"boxDl;\":0x2556, \"boxDr;\":0x2553,\n \"boxH;\":0x2550, \"boxHD;\":0x2566,\n \"boxHU;\":0x2569, \"boxHd;\":0x2564,\n \"boxHu;\":0x2567, \"boxUL;\":0x255d,\n \"boxUR;\":0x255a, \"boxUl;\":0x255c,\n \"boxUr;\":0x2559, \"boxV;\":0x2551,\n \"boxVH;\":0x256c, \"boxVL;\":0x2563,\n \"boxVR;\":0x2560, \"boxVh;\":0x256b,\n \"boxVl;\":0x2562, \"boxVr;\":0x255f,\n \"boxbox;\":0x29c9, \"boxdL;\":0x2555,\n \"boxdR;\":0x2552, \"boxdl;\":0x2510,\n \"boxdr;\":0x250c, \"boxh;\":0x2500,\n \"boxhD;\":0x2565, \"boxhU;\":0x2568,\n \"boxhd;\":0x252c, \"boxhu;\":0x2534,\n \"boxminus;\":0x229f, \"boxplus;\":0x229e,\n \"boxtimes;\":0x22a0, \"boxuL;\":0x255b,\n \"boxuR;\":0x2558, \"boxul;\":0x2518,\n \"boxur;\":0x2514, \"boxv;\":0x2502,\n \"boxvH;\":0x256a, \"boxvL;\":0x2561,\n \"boxvR;\":0x255e, \"boxvh;\":0x253c,\n \"boxvl;\":0x2524, \"boxvr;\":0x251c,\n \"bprime;\":0x2035, \"breve;\":0x2d8,\n \"brvbar\":0xa6, \"brvbar;\":0xa6,\n \"bscr;\":[0xd835,0xdcb7], \"bsemi;\":0x204f,\n \"bsim;\":0x223d, \"bsime;\":0x22cd,\n \"bsol;\":0x5c, \"bsolb;\":0x29c5,\n \"bsolhsub;\":0x27c8, \"bull;\":0x2022,\n \"bullet;\":0x2022, \"bump;\":0x224e,\n \"bumpE;\":0x2aae, \"bumpe;\":0x224f,\n \"bumpeq;\":0x224f, \"cacute;\":0x107,\n \"cap;\":0x2229, \"capand;\":0x2a44,\n \"capbrcup;\":0x2a49, \"capcap;\":0x2a4b,\n \"capcup;\":0x2a47, \"capdot;\":0x2a40,\n \"caps;\":[0x2229,0xfe00], \"caret;\":0x2041,\n \"caron;\":0x2c7, \"ccaps;\":0x2a4d,\n \"ccaron;\":0x10d, \"ccedil\":0xe7,\n \"ccedil;\":0xe7, \"ccirc;\":0x109,\n \"ccups;\":0x2a4c, \"ccupssm;\":0x2a50,\n \"cdot;\":0x10b, \"cedil\":0xb8,\n \"cedil;\":0xb8, \"cemptyv;\":0x29b2,\n \"cent\":0xa2, \"cent;\":0xa2,\n \"centerdot;\":0xb7, \"cfr;\":[0xd835,0xdd20],\n \"chcy;\":0x447, \"check;\":0x2713,\n \"checkmark;\":0x2713, \"chi;\":0x3c7,\n \"cir;\":0x25cb, \"cirE;\":0x29c3,\n \"circ;\":0x2c6, \"circeq;\":0x2257,\n \"circlearrowleft;\":0x21ba, \"circlearrowright;\":0x21bb,\n \"circledR;\":0xae, \"circledS;\":0x24c8,\n \"circledast;\":0x229b, \"circledcirc;\":0x229a,\n \"circleddash;\":0x229d, \"cire;\":0x2257,\n \"cirfnint;\":0x2a10, \"cirmid;\":0x2aef,\n \"cirscir;\":0x29c2, \"clubs;\":0x2663,\n \"clubsuit;\":0x2663, \"colon;\":0x3a,\n \"colone;\":0x2254, \"coloneq;\":0x2254,\n \"comma;\":0x2c, \"commat;\":0x40,\n \"comp;\":0x2201, \"compfn;\":0x2218,\n \"complement;\":0x2201, \"complexes;\":0x2102,\n \"cong;\":0x2245, \"congdot;\":0x2a6d,\n \"conint;\":0x222e, \"copf;\":[0xd835,0xdd54],\n \"coprod;\":0x2210, \"copy\":0xa9,\n \"copy;\":0xa9, \"copysr;\":0x2117,\n \"crarr;\":0x21b5, \"cross;\":0x2717,\n \"cscr;\":[0xd835,0xdcb8], \"csub;\":0x2acf,\n \"csube;\":0x2ad1, \"csup;\":0x2ad0,\n \"csupe;\":0x2ad2, \"ctdot;\":0x22ef,\n \"cudarrl;\":0x2938, \"cudarrr;\":0x2935,\n \"cuepr;\":0x22de, \"cuesc;\":0x22df,\n \"cularr;\":0x21b6, \"cularrp;\":0x293d,\n \"cup;\":0x222a, \"cupbrcap;\":0x2a48,\n \"cupcap;\":0x2a46, \"cupcup;\":0x2a4a,\n \"cupdot;\":0x228d, \"cupor;\":0x2a45,\n \"cups;\":[0x222a,0xfe00], \"curarr;\":0x21b7,\n \"curarrm;\":0x293c, \"curlyeqprec;\":0x22de,\n \"curlyeqsucc;\":0x22df, \"curlyvee;\":0x22ce,\n \"curlywedge;\":0x22cf, \"curren\":0xa4,\n \"curren;\":0xa4, \"curvearrowleft;\":0x21b6,\n \"curvearrowright;\":0x21b7, \"cuvee;\":0x22ce,\n \"cuwed;\":0x22cf, \"cwconint;\":0x2232,\n \"cwint;\":0x2231, \"cylcty;\":0x232d,\n \"dArr;\":0x21d3, \"dHar;\":0x2965,\n \"dagger;\":0x2020, \"daleth;\":0x2138,\n \"darr;\":0x2193, \"dash;\":0x2010,\n \"dashv;\":0x22a3, \"dbkarow;\":0x290f,\n \"dblac;\":0x2dd, \"dcaron;\":0x10f,\n \"dcy;\":0x434, \"dd;\":0x2146,\n \"ddagger;\":0x2021, \"ddarr;\":0x21ca,\n \"ddotseq;\":0x2a77, \"deg\":0xb0,\n \"deg;\":0xb0, \"delta;\":0x3b4,\n \"demptyv;\":0x29b1, \"dfisht;\":0x297f,\n \"dfr;\":[0xd835,0xdd21], \"dharl;\":0x21c3,\n \"dharr;\":0x21c2, \"diam;\":0x22c4,\n \"diamond;\":0x22c4, \"diamondsuit;\":0x2666,\n \"diams;\":0x2666, \"die;\":0xa8,\n \"digamma;\":0x3dd, \"disin;\":0x22f2,\n \"div;\":0xf7, \"divide\":0xf7,\n \"divide;\":0xf7, \"divideontimes;\":0x22c7,\n \"divonx;\":0x22c7, \"djcy;\":0x452,\n \"dlcorn;\":0x231e, \"dlcrop;\":0x230d,\n \"dollar;\":0x24, \"dopf;\":[0xd835,0xdd55],\n \"dot;\":0x2d9, \"doteq;\":0x2250,\n \"doteqdot;\":0x2251, \"dotminus;\":0x2238,\n \"dotplus;\":0x2214, \"dotsquare;\":0x22a1,\n \"doublebarwedge;\":0x2306, \"downarrow;\":0x2193,\n \"downdownarrows;\":0x21ca, \"downharpoonleft;\":0x21c3,\n \"downharpoonright;\":0x21c2, \"drbkarow;\":0x2910,\n \"drcorn;\":0x231f, \"drcrop;\":0x230c,\n \"dscr;\":[0xd835,0xdcb9], \"dscy;\":0x455,\n \"dsol;\":0x29f6, \"dstrok;\":0x111,\n \"dtdot;\":0x22f1, \"dtri;\":0x25bf,\n \"dtrif;\":0x25be, \"duarr;\":0x21f5,\n \"duhar;\":0x296f, \"dwangle;\":0x29a6,\n \"dzcy;\":0x45f, \"dzigrarr;\":0x27ff,\n \"eDDot;\":0x2a77, \"eDot;\":0x2251,\n \"eacute\":0xe9, \"eacute;\":0xe9,\n \"easter;\":0x2a6e, \"ecaron;\":0x11b,\n \"ecir;\":0x2256, \"ecirc\":0xea,\n \"ecirc;\":0xea, \"ecolon;\":0x2255,\n \"ecy;\":0x44d, \"edot;\":0x117,\n \"ee;\":0x2147, \"efDot;\":0x2252,\n \"efr;\":[0xd835,0xdd22], \"eg;\":0x2a9a,\n \"egrave\":0xe8, \"egrave;\":0xe8,\n \"egs;\":0x2a96, \"egsdot;\":0x2a98,\n \"el;\":0x2a99, \"elinters;\":0x23e7,\n \"ell;\":0x2113, \"els;\":0x2a95,\n \"elsdot;\":0x2a97, \"emacr;\":0x113,\n \"empty;\":0x2205, \"emptyset;\":0x2205,\n \"emptyv;\":0x2205, \"emsp13;\":0x2004,\n \"emsp14;\":0x2005, \"emsp;\":0x2003,\n \"eng;\":0x14b, \"ensp;\":0x2002,\n \"eogon;\":0x119, \"eopf;\":[0xd835,0xdd56],\n \"epar;\":0x22d5, \"eparsl;\":0x29e3,\n \"eplus;\":0x2a71, \"epsi;\":0x3b5,\n \"epsilon;\":0x3b5, \"epsiv;\":0x3f5,\n \"eqcirc;\":0x2256, \"eqcolon;\":0x2255,\n \"eqsim;\":0x2242, \"eqslantgtr;\":0x2a96,\n \"eqslantless;\":0x2a95, \"equals;\":0x3d,\n \"equest;\":0x225f, \"equiv;\":0x2261,\n \"equivDD;\":0x2a78, \"eqvparsl;\":0x29e5,\n \"erDot;\":0x2253, \"erarr;\":0x2971,\n \"escr;\":0x212f, \"esdot;\":0x2250,\n \"esim;\":0x2242, \"eta;\":0x3b7,\n \"eth\":0xf0, \"eth;\":0xf0,\n \"euml\":0xeb, \"euml;\":0xeb,\n \"euro;\":0x20ac, \"excl;\":0x21,\n \"exist;\":0x2203, \"expectation;\":0x2130,\n \"exponentiale;\":0x2147, \"fallingdotseq;\":0x2252,\n \"fcy;\":0x444, \"female;\":0x2640,\n \"ffilig;\":0xfb03, \"fflig;\":0xfb00,\n \"ffllig;\":0xfb04, \"ffr;\":[0xd835,0xdd23],\n \"filig;\":0xfb01, \"fjlig;\":[0x66,0x6a],\n \"flat;\":0x266d, \"fllig;\":0xfb02,\n \"fltns;\":0x25b1, \"fnof;\":0x192,\n \"fopf;\":[0xd835,0xdd57], \"forall;\":0x2200,\n \"fork;\":0x22d4, \"forkv;\":0x2ad9,\n \"fpartint;\":0x2a0d, \"frac12\":0xbd,\n \"frac12;\":0xbd, \"frac13;\":0x2153,\n \"frac14\":0xbc, \"frac14;\":0xbc,\n \"frac15;\":0x2155, \"frac16;\":0x2159,\n \"frac18;\":0x215b, \"frac23;\":0x2154,\n \"frac25;\":0x2156, \"frac34\":0xbe,\n \"frac34;\":0xbe, \"frac35;\":0x2157,\n \"frac38;\":0x215c, \"frac45;\":0x2158,\n \"frac56;\":0x215a, \"frac58;\":0x215d,\n \"frac78;\":0x215e, \"frasl;\":0x2044,\n \"frown;\":0x2322, \"fscr;\":[0xd835,0xdcbb],\n \"gE;\":0x2267, \"gEl;\":0x2a8c,\n \"gacute;\":0x1f5, \"gamma;\":0x3b3,\n \"gammad;\":0x3dd, \"gap;\":0x2a86,\n \"gbreve;\":0x11f, \"gcirc;\":0x11d,\n \"gcy;\":0x433, \"gdot;\":0x121,\n \"ge;\":0x2265, \"gel;\":0x22db,\n \"geq;\":0x2265, \"geqq;\":0x2267,\n \"geqslant;\":0x2a7e, \"ges;\":0x2a7e,\n \"gescc;\":0x2aa9, \"gesdot;\":0x2a80,\n \"gesdoto;\":0x2a82, \"gesdotol;\":0x2a84,\n \"gesl;\":[0x22db,0xfe00], \"gesles;\":0x2a94,\n \"gfr;\":[0xd835,0xdd24], \"gg;\":0x226b,\n \"ggg;\":0x22d9, \"gimel;\":0x2137,\n \"gjcy;\":0x453, \"gl;\":0x2277,\n \"glE;\":0x2a92, \"gla;\":0x2aa5,\n \"glj;\":0x2aa4, \"gnE;\":0x2269,\n \"gnap;\":0x2a8a, \"gnapprox;\":0x2a8a,\n \"gne;\":0x2a88, \"gneq;\":0x2a88,\n \"gneqq;\":0x2269, \"gnsim;\":0x22e7,\n \"gopf;\":[0xd835,0xdd58], \"grave;\":0x60,\n \"gscr;\":0x210a, \"gsim;\":0x2273,\n \"gsime;\":0x2a8e, \"gsiml;\":0x2a90,\n \"gt\":0x3e, \"gt;\":0x3e,\n \"gtcc;\":0x2aa7, \"gtcir;\":0x2a7a,\n \"gtdot;\":0x22d7, \"gtlPar;\":0x2995,\n \"gtquest;\":0x2a7c, \"gtrapprox;\":0x2a86,\n \"gtrarr;\":0x2978, \"gtrdot;\":0x22d7,\n \"gtreqless;\":0x22db, \"gtreqqless;\":0x2a8c,\n \"gtrless;\":0x2277, \"gtrsim;\":0x2273,\n \"gvertneqq;\":[0x2269,0xfe00], \"gvnE;\":[0x2269,0xfe00],\n \"hArr;\":0x21d4, \"hairsp;\":0x200a,\n \"half;\":0xbd, \"hamilt;\":0x210b,\n \"hardcy;\":0x44a, \"harr;\":0x2194,\n \"harrcir;\":0x2948, \"harrw;\":0x21ad,\n \"hbar;\":0x210f, \"hcirc;\":0x125,\n \"hearts;\":0x2665, \"heartsuit;\":0x2665,\n \"hellip;\":0x2026, \"hercon;\":0x22b9,\n \"hfr;\":[0xd835,0xdd25], \"hksearow;\":0x2925,\n \"hkswarow;\":0x2926, \"hoarr;\":0x21ff,\n \"homtht;\":0x223b, \"hookleftarrow;\":0x21a9,\n \"hookrightarrow;\":0x21aa, \"hopf;\":[0xd835,0xdd59],\n \"horbar;\":0x2015, \"hscr;\":[0xd835,0xdcbd],\n \"hslash;\":0x210f, \"hstrok;\":0x127,\n \"hybull;\":0x2043, \"hyphen;\":0x2010,\n \"iacute\":0xed, \"iacute;\":0xed,\n \"ic;\":0x2063, \"icirc\":0xee,\n \"icirc;\":0xee, \"icy;\":0x438,\n \"iecy;\":0x435, \"iexcl\":0xa1,\n \"iexcl;\":0xa1, \"iff;\":0x21d4,\n \"ifr;\":[0xd835,0xdd26], \"igrave\":0xec,\n \"igrave;\":0xec, \"ii;\":0x2148,\n \"iiiint;\":0x2a0c, \"iiint;\":0x222d,\n \"iinfin;\":0x29dc, \"iiota;\":0x2129,\n \"ijlig;\":0x133, \"imacr;\":0x12b,\n \"image;\":0x2111, \"imagline;\":0x2110,\n \"imagpart;\":0x2111, \"imath;\":0x131,\n \"imof;\":0x22b7, \"imped;\":0x1b5,\n \"in;\":0x2208, \"incare;\":0x2105,\n \"infin;\":0x221e, \"infintie;\":0x29dd,\n \"inodot;\":0x131, \"int;\":0x222b,\n \"intcal;\":0x22ba, \"integers;\":0x2124,\n \"intercal;\":0x22ba, \"intlarhk;\":0x2a17,\n \"intprod;\":0x2a3c, \"iocy;\":0x451,\n \"iogon;\":0x12f, \"iopf;\":[0xd835,0xdd5a],\n \"iota;\":0x3b9, \"iprod;\":0x2a3c,\n \"iquest\":0xbf, \"iquest;\":0xbf,\n \"iscr;\":[0xd835,0xdcbe], \"isin;\":0x2208,\n \"isinE;\":0x22f9, \"isindot;\":0x22f5,\n \"isins;\":0x22f4, \"isinsv;\":0x22f3,\n \"isinv;\":0x2208, \"it;\":0x2062,\n \"itilde;\":0x129, \"iukcy;\":0x456,\n \"iuml\":0xef, \"iuml;\":0xef,\n \"jcirc;\":0x135, \"jcy;\":0x439,\n \"jfr;\":[0xd835,0xdd27], \"jmath;\":0x237,\n \"jopf;\":[0xd835,0xdd5b], \"jscr;\":[0xd835,0xdcbf],\n \"jsercy;\":0x458, \"jukcy;\":0x454,\n \"kappa;\":0x3ba, \"kappav;\":0x3f0,\n \"kcedil;\":0x137, \"kcy;\":0x43a,\n \"kfr;\":[0xd835,0xdd28], \"kgreen;\":0x138,\n \"khcy;\":0x445, \"kjcy;\":0x45c,\n \"kopf;\":[0xd835,0xdd5c], \"kscr;\":[0xd835,0xdcc0],\n \"lAarr;\":0x21da, \"lArr;\":0x21d0,\n \"lAtail;\":0x291b, \"lBarr;\":0x290e,\n \"lE;\":0x2266, \"lEg;\":0x2a8b,\n \"lHar;\":0x2962, \"lacute;\":0x13a,\n \"laemptyv;\":0x29b4, \"lagran;\":0x2112,\n \"lambda;\":0x3bb, \"lang;\":0x27e8,\n \"langd;\":0x2991, \"langle;\":0x27e8,\n \"lap;\":0x2a85, \"laquo\":0xab,\n \"laquo;\":0xab, \"larr;\":0x2190,\n \"larrb;\":0x21e4, \"larrbfs;\":0x291f,\n \"larrfs;\":0x291d, \"larrhk;\":0x21a9,\n \"larrlp;\":0x21ab, \"larrpl;\":0x2939,\n \"larrsim;\":0x2973, \"larrtl;\":0x21a2,\n \"lat;\":0x2aab, \"latail;\":0x2919,\n \"late;\":0x2aad, \"lates;\":[0x2aad,0xfe00],\n \"lbarr;\":0x290c, \"lbbrk;\":0x2772,\n \"lbrace;\":0x7b, \"lbrack;\":0x5b,\n \"lbrke;\":0x298b, \"lbrksld;\":0x298f,\n \"lbrkslu;\":0x298d, \"lcaron;\":0x13e,\n \"lcedil;\":0x13c, \"lceil;\":0x2308,\n \"lcub;\":0x7b, \"lcy;\":0x43b,\n \"ldca;\":0x2936, \"ldquo;\":0x201c,\n \"ldquor;\":0x201e, \"ldrdhar;\":0x2967,\n \"ldrushar;\":0x294b, \"ldsh;\":0x21b2,\n \"le;\":0x2264, \"leftarrow;\":0x2190,\n \"leftarrowtail;\":0x21a2, \"leftharpoondown;\":0x21bd,\n \"leftharpoonup;\":0x21bc, \"leftleftarrows;\":0x21c7,\n \"leftrightarrow;\":0x2194, \"leftrightarrows;\":0x21c6,\n \"leftrightharpoons;\":0x21cb, \"leftrightsquigarrow;\":0x21ad,\n \"leftthreetimes;\":0x22cb, \"leg;\":0x22da,\n \"leq;\":0x2264, \"leqq;\":0x2266,\n \"leqslant;\":0x2a7d, \"les;\":0x2a7d,\n \"lescc;\":0x2aa8, \"lesdot;\":0x2a7f,\n \"lesdoto;\":0x2a81, \"lesdotor;\":0x2a83,\n \"lesg;\":[0x22da,0xfe00], \"lesges;\":0x2a93,\n \"lessapprox;\":0x2a85, \"lessdot;\":0x22d6,\n \"lesseqgtr;\":0x22da, \"lesseqqgtr;\":0x2a8b,\n \"lessgtr;\":0x2276, \"lesssim;\":0x2272,\n \"lfisht;\":0x297c, \"lfloor;\":0x230a,\n \"lfr;\":[0xd835,0xdd29], \"lg;\":0x2276,\n \"lgE;\":0x2a91, \"lhard;\":0x21bd,\n \"lharu;\":0x21bc, \"lharul;\":0x296a,\n \"lhblk;\":0x2584, \"ljcy;\":0x459,\n \"ll;\":0x226a, \"llarr;\":0x21c7,\n \"llcorner;\":0x231e, \"llhard;\":0x296b,\n \"lltri;\":0x25fa, \"lmidot;\":0x140,\n \"lmoust;\":0x23b0, \"lmoustache;\":0x23b0,\n \"lnE;\":0x2268, \"lnap;\":0x2a89,\n \"lnapprox;\":0x2a89, \"lne;\":0x2a87,\n \"lneq;\":0x2a87, \"lneqq;\":0x2268,\n \"lnsim;\":0x22e6, \"loang;\":0x27ec,\n \"loarr;\":0x21fd, \"lobrk;\":0x27e6,\n \"longleftarrow;\":0x27f5, \"longleftrightarrow;\":0x27f7,\n \"longmapsto;\":0x27fc, \"longrightarrow;\":0x27f6,\n \"looparrowleft;\":0x21ab, \"looparrowright;\":0x21ac,\n \"lopar;\":0x2985, \"lopf;\":[0xd835,0xdd5d],\n \"loplus;\":0x2a2d, \"lotimes;\":0x2a34,\n \"lowast;\":0x2217, \"lowbar;\":0x5f,\n \"loz;\":0x25ca, \"lozenge;\":0x25ca,\n \"lozf;\":0x29eb, \"lpar;\":0x28,\n \"lparlt;\":0x2993, \"lrarr;\":0x21c6,\n \"lrcorner;\":0x231f, \"lrhar;\":0x21cb,\n \"lrhard;\":0x296d, \"lrm;\":0x200e,\n \"lrtri;\":0x22bf, \"lsaquo;\":0x2039,\n \"lscr;\":[0xd835,0xdcc1], \"lsh;\":0x21b0,\n \"lsim;\":0x2272, \"lsime;\":0x2a8d,\n \"lsimg;\":0x2a8f, \"lsqb;\":0x5b,\n \"lsquo;\":0x2018, \"lsquor;\":0x201a,\n \"lstrok;\":0x142, \"lt\":0x3c,\n \"lt;\":0x3c, \"ltcc;\":0x2aa6,\n \"ltcir;\":0x2a79, \"ltdot;\":0x22d6,\n \"lthree;\":0x22cb, \"ltimes;\":0x22c9,\n \"ltlarr;\":0x2976, \"ltquest;\":0x2a7b,\n \"ltrPar;\":0x2996, \"ltri;\":0x25c3,\n \"ltrie;\":0x22b4, \"ltrif;\":0x25c2,\n \"lurdshar;\":0x294a, \"luruhar;\":0x2966,\n \"lvertneqq;\":[0x2268,0xfe00], \"lvnE;\":[0x2268,0xfe00],\n \"mDDot;\":0x223a, \"macr\":0xaf,\n \"macr;\":0xaf, \"male;\":0x2642,\n \"malt;\":0x2720, \"maltese;\":0x2720,\n \"map;\":0x21a6, \"mapsto;\":0x21a6,\n \"mapstodown;\":0x21a7, \"mapstoleft;\":0x21a4,\n \"mapstoup;\":0x21a5, \"marker;\":0x25ae,\n \"mcomma;\":0x2a29, \"mcy;\":0x43c,\n \"mdash;\":0x2014, \"measuredangle;\":0x2221,\n \"mfr;\":[0xd835,0xdd2a], \"mho;\":0x2127,\n \"micro\":0xb5, \"micro;\":0xb5,\n \"mid;\":0x2223, \"midast;\":0x2a,\n \"midcir;\":0x2af0, \"middot\":0xb7,\n \"middot;\":0xb7, \"minus;\":0x2212,\n \"minusb;\":0x229f, \"minusd;\":0x2238,\n \"minusdu;\":0x2a2a, \"mlcp;\":0x2adb,\n \"mldr;\":0x2026, \"mnplus;\":0x2213,\n \"models;\":0x22a7, \"mopf;\":[0xd835,0xdd5e],\n \"mp;\":0x2213, \"mscr;\":[0xd835,0xdcc2],\n \"mstpos;\":0x223e, \"mu;\":0x3bc,\n \"multimap;\":0x22b8, \"mumap;\":0x22b8,\n \"nGg;\":[0x22d9,0x338], \"nGt;\":[0x226b,0x20d2],\n \"nGtv;\":[0x226b,0x338], \"nLeftarrow;\":0x21cd,\n \"nLeftrightarrow;\":0x21ce, \"nLl;\":[0x22d8,0x338],\n \"nLt;\":[0x226a,0x20d2], \"nLtv;\":[0x226a,0x338],\n \"nRightarrow;\":0x21cf, \"nVDash;\":0x22af,\n \"nVdash;\":0x22ae, \"nabla;\":0x2207,\n \"nacute;\":0x144, \"nang;\":[0x2220,0x20d2],\n \"nap;\":0x2249, \"napE;\":[0x2a70,0x338],\n \"napid;\":[0x224b,0x338], \"napos;\":0x149,\n \"napprox;\":0x2249, \"natur;\":0x266e,\n \"natural;\":0x266e, \"naturals;\":0x2115,\n \"nbsp\":0xa0, \"nbsp;\":0xa0,\n \"nbump;\":[0x224e,0x338], \"nbumpe;\":[0x224f,0x338],\n \"ncap;\":0x2a43, \"ncaron;\":0x148,\n \"ncedil;\":0x146, \"ncong;\":0x2247,\n \"ncongdot;\":[0x2a6d,0x338], \"ncup;\":0x2a42,\n \"ncy;\":0x43d, \"ndash;\":0x2013,\n \"ne;\":0x2260, \"neArr;\":0x21d7,\n \"nearhk;\":0x2924, \"nearr;\":0x2197,\n \"nearrow;\":0x2197, \"nedot;\":[0x2250,0x338],\n \"nequiv;\":0x2262, \"nesear;\":0x2928,\n \"nesim;\":[0x2242,0x338], \"nexist;\":0x2204,\n \"nexists;\":0x2204, \"nfr;\":[0xd835,0xdd2b],\n \"ngE;\":[0x2267,0x338], \"nge;\":0x2271,\n \"ngeq;\":0x2271, \"ngeqq;\":[0x2267,0x338],\n \"ngeqslant;\":[0x2a7e,0x338], \"nges;\":[0x2a7e,0x338],\n \"ngsim;\":0x2275, \"ngt;\":0x226f,\n \"ngtr;\":0x226f, \"nhArr;\":0x21ce,\n \"nharr;\":0x21ae, \"nhpar;\":0x2af2,\n \"ni;\":0x220b, \"nis;\":0x22fc,\n \"nisd;\":0x22fa, \"niv;\":0x220b,\n \"njcy;\":0x45a, \"nlArr;\":0x21cd,\n \"nlE;\":[0x2266,0x338], \"nlarr;\":0x219a,\n \"nldr;\":0x2025, \"nle;\":0x2270,\n \"nleftarrow;\":0x219a, \"nleftrightarrow;\":0x21ae,\n \"nleq;\":0x2270, \"nleqq;\":[0x2266,0x338],\n \"nleqslant;\":[0x2a7d,0x338], \"nles;\":[0x2a7d,0x338],\n \"nless;\":0x226e, \"nlsim;\":0x2274,\n \"nlt;\":0x226e, \"nltri;\":0x22ea,\n \"nltrie;\":0x22ec, \"nmid;\":0x2224,\n \"nopf;\":[0xd835,0xdd5f], \"not\":0xac,\n \"not;\":0xac, \"notin;\":0x2209,\n \"notinE;\":[0x22f9,0x338], \"notindot;\":[0x22f5,0x338],\n \"notinva;\":0x2209, \"notinvb;\":0x22f7,\n \"notinvc;\":0x22f6, \"notni;\":0x220c,\n \"notniva;\":0x220c, \"notnivb;\":0x22fe,\n \"notnivc;\":0x22fd, \"npar;\":0x2226,\n \"nparallel;\":0x2226, \"nparsl;\":[0x2afd,0x20e5],\n \"npart;\":[0x2202,0x338], \"npolint;\":0x2a14,\n \"npr;\":0x2280, \"nprcue;\":0x22e0,\n \"npre;\":[0x2aaf,0x338], \"nprec;\":0x2280,\n \"npreceq;\":[0x2aaf,0x338], \"nrArr;\":0x21cf,\n \"nrarr;\":0x219b, \"nrarrc;\":[0x2933,0x338],\n \"nrarrw;\":[0x219d,0x338], \"nrightarrow;\":0x219b,\n \"nrtri;\":0x22eb, \"nrtrie;\":0x22ed,\n \"nsc;\":0x2281, \"nsccue;\":0x22e1,\n \"nsce;\":[0x2ab0,0x338], \"nscr;\":[0xd835,0xdcc3],\n \"nshortmid;\":0x2224, \"nshortparallel;\":0x2226,\n \"nsim;\":0x2241, \"nsime;\":0x2244,\n \"nsimeq;\":0x2244, \"nsmid;\":0x2224,\n \"nspar;\":0x2226, \"nsqsube;\":0x22e2,\n \"nsqsupe;\":0x22e3, \"nsub;\":0x2284,\n \"nsubE;\":[0x2ac5,0x338], \"nsube;\":0x2288,\n \"nsubset;\":[0x2282,0x20d2], \"nsubseteq;\":0x2288,\n \"nsubseteqq;\":[0x2ac5,0x338], \"nsucc;\":0x2281,\n \"nsucceq;\":[0x2ab0,0x338], \"nsup;\":0x2285,\n \"nsupE;\":[0x2ac6,0x338], \"nsupe;\":0x2289,\n \"nsupset;\":[0x2283,0x20d2], \"nsupseteq;\":0x2289,\n \"nsupseteqq;\":[0x2ac6,0x338], \"ntgl;\":0x2279,\n \"ntilde\":0xf1, \"ntilde;\":0xf1,\n \"ntlg;\":0x2278, \"ntriangleleft;\":0x22ea,\n \"ntrianglelefteq;\":0x22ec, \"ntriangleright;\":0x22eb,\n \"ntrianglerighteq;\":0x22ed, \"nu;\":0x3bd,\n \"num;\":0x23, \"numero;\":0x2116,\n \"numsp;\":0x2007, \"nvDash;\":0x22ad,\n \"nvHarr;\":0x2904, \"nvap;\":[0x224d,0x20d2],\n \"nvdash;\":0x22ac, \"nvge;\":[0x2265,0x20d2],\n \"nvgt;\":[0x3e,0x20d2], \"nvinfin;\":0x29de,\n \"nvlArr;\":0x2902, \"nvle;\":[0x2264,0x20d2],\n \"nvlt;\":[0x3c,0x20d2], \"nvltrie;\":[0x22b4,0x20d2],\n \"nvrArr;\":0x2903, \"nvrtrie;\":[0x22b5,0x20d2],\n \"nvsim;\":[0x223c,0x20d2], \"nwArr;\":0x21d6,\n \"nwarhk;\":0x2923, \"nwarr;\":0x2196,\n \"nwarrow;\":0x2196, \"nwnear;\":0x2927,\n \"oS;\":0x24c8, \"oacute\":0xf3,\n \"oacute;\":0xf3, \"oast;\":0x229b,\n \"ocir;\":0x229a, \"ocirc\":0xf4,\n \"ocirc;\":0xf4, \"ocy;\":0x43e,\n \"odash;\":0x229d, \"odblac;\":0x151,\n \"odiv;\":0x2a38, \"odot;\":0x2299,\n \"odsold;\":0x29bc, \"oelig;\":0x153,\n \"ofcir;\":0x29bf, \"ofr;\":[0xd835,0xdd2c],\n \"ogon;\":0x2db, \"ograve\":0xf2,\n \"ograve;\":0xf2, \"ogt;\":0x29c1,\n \"ohbar;\":0x29b5, \"ohm;\":0x3a9,\n \"oint;\":0x222e, \"olarr;\":0x21ba,\n \"olcir;\":0x29be, \"olcross;\":0x29bb,\n \"oline;\":0x203e, \"olt;\":0x29c0,\n \"omacr;\":0x14d, \"omega;\":0x3c9,\n \"omicron;\":0x3bf, \"omid;\":0x29b6,\n \"ominus;\":0x2296, \"oopf;\":[0xd835,0xdd60],\n \"opar;\":0x29b7, \"operp;\":0x29b9,\n \"oplus;\":0x2295, \"or;\":0x2228,\n \"orarr;\":0x21bb, \"ord;\":0x2a5d,\n \"order;\":0x2134, \"orderof;\":0x2134,\n \"ordf\":0xaa, \"ordf;\":0xaa,\n \"ordm\":0xba, \"ordm;\":0xba,\n \"origof;\":0x22b6, \"oror;\":0x2a56,\n \"orslope;\":0x2a57, \"orv;\":0x2a5b,\n \"oscr;\":0x2134, \"oslash\":0xf8,\n \"oslash;\":0xf8, \"osol;\":0x2298,\n \"otilde\":0xf5, \"otilde;\":0xf5,\n \"otimes;\":0x2297, \"otimesas;\":0x2a36,\n \"ouml\":0xf6, \"ouml;\":0xf6,\n \"ovbar;\":0x233d, \"par;\":0x2225,\n \"para\":0xb6, \"para;\":0xb6,\n \"parallel;\":0x2225, \"parsim;\":0x2af3,\n \"parsl;\":0x2afd, \"part;\":0x2202,\n \"pcy;\":0x43f, \"percnt;\":0x25,\n \"period;\":0x2e, \"permil;\":0x2030,\n \"perp;\":0x22a5, \"pertenk;\":0x2031,\n \"pfr;\":[0xd835,0xdd2d], \"phi;\":0x3c6,\n \"phiv;\":0x3d5, \"phmmat;\":0x2133,\n \"phone;\":0x260e, \"pi;\":0x3c0,\n \"pitchfork;\":0x22d4, \"piv;\":0x3d6,\n \"planck;\":0x210f, \"planckh;\":0x210e,\n \"plankv;\":0x210f, \"plus;\":0x2b,\n \"plusacir;\":0x2a23, \"plusb;\":0x229e,\n \"pluscir;\":0x2a22, \"plusdo;\":0x2214,\n \"plusdu;\":0x2a25, \"pluse;\":0x2a72,\n \"plusmn\":0xb1, \"plusmn;\":0xb1,\n \"plussim;\":0x2a26, \"plustwo;\":0x2a27,\n \"pm;\":0xb1, \"pointint;\":0x2a15,\n \"popf;\":[0xd835,0xdd61], \"pound\":0xa3,\n \"pound;\":0xa3, \"pr;\":0x227a,\n \"prE;\":0x2ab3, \"prap;\":0x2ab7,\n \"prcue;\":0x227c, \"pre;\":0x2aaf,\n \"prec;\":0x227a, \"precapprox;\":0x2ab7,\n \"preccurlyeq;\":0x227c, \"preceq;\":0x2aaf,\n \"precnapprox;\":0x2ab9, \"precneqq;\":0x2ab5,\n \"precnsim;\":0x22e8, \"precsim;\":0x227e,\n \"prime;\":0x2032, \"primes;\":0x2119,\n \"prnE;\":0x2ab5, \"prnap;\":0x2ab9,\n \"prnsim;\":0x22e8, \"prod;\":0x220f,\n \"profalar;\":0x232e, \"profline;\":0x2312,\n \"profsurf;\":0x2313, \"prop;\":0x221d,\n \"propto;\":0x221d, \"prsim;\":0x227e,\n \"prurel;\":0x22b0, \"pscr;\":[0xd835,0xdcc5],\n \"psi;\":0x3c8, \"puncsp;\":0x2008,\n \"qfr;\":[0xd835,0xdd2e], \"qint;\":0x2a0c,\n \"qopf;\":[0xd835,0xdd62], \"qprime;\":0x2057,\n \"qscr;\":[0xd835,0xdcc6], \"quaternions;\":0x210d,\n \"quatint;\":0x2a16, \"quest;\":0x3f,\n \"questeq;\":0x225f, \"quot\":0x22,\n \"quot;\":0x22, \"rAarr;\":0x21db,\n \"rArr;\":0x21d2, \"rAtail;\":0x291c,\n \"rBarr;\":0x290f, \"rHar;\":0x2964,\n \"race;\":[0x223d,0x331], \"racute;\":0x155,\n \"radic;\":0x221a, \"raemptyv;\":0x29b3,\n \"rang;\":0x27e9, \"rangd;\":0x2992,\n \"range;\":0x29a5, \"rangle;\":0x27e9,\n \"raquo\":0xbb, \"raquo;\":0xbb,\n \"rarr;\":0x2192, \"rarrap;\":0x2975,\n \"rarrb;\":0x21e5, \"rarrbfs;\":0x2920,\n \"rarrc;\":0x2933, \"rarrfs;\":0x291e,\n \"rarrhk;\":0x21aa, \"rarrlp;\":0x21ac,\n \"rarrpl;\":0x2945, \"rarrsim;\":0x2974,\n \"rarrtl;\":0x21a3, \"rarrw;\":0x219d,\n \"ratail;\":0x291a, \"ratio;\":0x2236,\n \"rationals;\":0x211a, \"rbarr;\":0x290d,\n \"rbbrk;\":0x2773, \"rbrace;\":0x7d,\n \"rbrack;\":0x5d, \"rbrke;\":0x298c,\n \"rbrksld;\":0x298e, \"rbrkslu;\":0x2990,\n \"rcaron;\":0x159, \"rcedil;\":0x157,\n \"rceil;\":0x2309, \"rcub;\":0x7d,\n \"rcy;\":0x440, \"rdca;\":0x2937,\n \"rdldhar;\":0x2969, \"rdquo;\":0x201d,\n \"rdquor;\":0x201d, \"rdsh;\":0x21b3,\n \"real;\":0x211c, \"realine;\":0x211b,\n \"realpart;\":0x211c, \"reals;\":0x211d,\n \"rect;\":0x25ad, \"reg\":0xae,\n \"reg;\":0xae, \"rfisht;\":0x297d,\n \"rfloor;\":0x230b, \"rfr;\":[0xd835,0xdd2f],\n \"rhard;\":0x21c1, \"rharu;\":0x21c0,\n \"rharul;\":0x296c, \"rho;\":0x3c1,\n \"rhov;\":0x3f1, \"rightarrow;\":0x2192,\n \"rightarrowtail;\":0x21a3, \"rightharpoondown;\":0x21c1,\n \"rightharpoonup;\":0x21c0, \"rightleftarrows;\":0x21c4,\n \"rightleftharpoons;\":0x21cc, \"rightrightarrows;\":0x21c9,\n \"rightsquigarrow;\":0x219d, \"rightthreetimes;\":0x22cc,\n \"ring;\":0x2da, \"risingdotseq;\":0x2253,\n \"rlarr;\":0x21c4, \"rlhar;\":0x21cc,\n \"rlm;\":0x200f, \"rmoust;\":0x23b1,\n \"rmoustache;\":0x23b1, \"rnmid;\":0x2aee,\n \"roang;\":0x27ed, \"roarr;\":0x21fe,\n \"robrk;\":0x27e7, \"ropar;\":0x2986,\n \"ropf;\":[0xd835,0xdd63], \"roplus;\":0x2a2e,\n \"rotimes;\":0x2a35, \"rpar;\":0x29,\n \"rpargt;\":0x2994, \"rppolint;\":0x2a12,\n \"rrarr;\":0x21c9, \"rsaquo;\":0x203a,\n \"rscr;\":[0xd835,0xdcc7], \"rsh;\":0x21b1,\n \"rsqb;\":0x5d, \"rsquo;\":0x2019,\n \"rsquor;\":0x2019, \"rthree;\":0x22cc,\n \"rtimes;\":0x22ca, \"rtri;\":0x25b9,\n \"rtrie;\":0x22b5, \"rtrif;\":0x25b8,\n \"rtriltri;\":0x29ce, \"ruluhar;\":0x2968,\n \"rx;\":0x211e, \"sacute;\":0x15b,\n \"sbquo;\":0x201a, \"sc;\":0x227b,\n \"scE;\":0x2ab4, \"scap;\":0x2ab8,\n \"scaron;\":0x161, \"sccue;\":0x227d,\n \"sce;\":0x2ab0, \"scedil;\":0x15f,\n \"scirc;\":0x15d, \"scnE;\":0x2ab6,\n \"scnap;\":0x2aba, \"scnsim;\":0x22e9,\n \"scpolint;\":0x2a13, \"scsim;\":0x227f,\n \"scy;\":0x441, \"sdot;\":0x22c5,\n \"sdotb;\":0x22a1, \"sdote;\":0x2a66,\n \"seArr;\":0x21d8, \"searhk;\":0x2925,\n \"searr;\":0x2198, \"searrow;\":0x2198,\n \"sect\":0xa7, \"sect;\":0xa7,\n \"semi;\":0x3b, \"seswar;\":0x2929,\n \"setminus;\":0x2216, \"setmn;\":0x2216,\n \"sext;\":0x2736, \"sfr;\":[0xd835,0xdd30],\n \"sfrown;\":0x2322, \"sharp;\":0x266f,\n \"shchcy;\":0x449, \"shcy;\":0x448,\n \"shortmid;\":0x2223, \"shortparallel;\":0x2225,\n \"shy\":0xad, \"shy;\":0xad,\n \"sigma;\":0x3c3, \"sigmaf;\":0x3c2,\n \"sigmav;\":0x3c2, \"sim;\":0x223c,\n \"simdot;\":0x2a6a, \"sime;\":0x2243,\n \"simeq;\":0x2243, \"simg;\":0x2a9e,\n \"simgE;\":0x2aa0, \"siml;\":0x2a9d,\n \"simlE;\":0x2a9f, \"simne;\":0x2246,\n \"simplus;\":0x2a24, \"simrarr;\":0x2972,\n \"slarr;\":0x2190, \"smallsetminus;\":0x2216,\n \"smashp;\":0x2a33, \"smeparsl;\":0x29e4,\n \"smid;\":0x2223, \"smile;\":0x2323,\n \"smt;\":0x2aaa, \"smte;\":0x2aac,\n \"smtes;\":[0x2aac,0xfe00], \"softcy;\":0x44c,\n \"sol;\":0x2f, \"solb;\":0x29c4,\n \"solbar;\":0x233f, \"sopf;\":[0xd835,0xdd64],\n \"spades;\":0x2660, \"spadesuit;\":0x2660,\n \"spar;\":0x2225, \"sqcap;\":0x2293,\n \"sqcaps;\":[0x2293,0xfe00], \"sqcup;\":0x2294,\n \"sqcups;\":[0x2294,0xfe00], \"sqsub;\":0x228f,\n \"sqsube;\":0x2291, \"sqsubset;\":0x228f,\n \"sqsubseteq;\":0x2291, \"sqsup;\":0x2290,\n \"sqsupe;\":0x2292, \"sqsupset;\":0x2290,\n \"sqsupseteq;\":0x2292, \"squ;\":0x25a1,\n \"square;\":0x25a1, \"squarf;\":0x25aa,\n \"squf;\":0x25aa, \"srarr;\":0x2192,\n \"sscr;\":[0xd835,0xdcc8], \"ssetmn;\":0x2216,\n \"ssmile;\":0x2323, \"sstarf;\":0x22c6,\n \"star;\":0x2606, \"starf;\":0x2605,\n \"straightepsilon;\":0x3f5, \"straightphi;\":0x3d5,\n \"strns;\":0xaf, \"sub;\":0x2282,\n \"subE;\":0x2ac5, \"subdot;\":0x2abd,\n \"sube;\":0x2286, \"subedot;\":0x2ac3,\n \"submult;\":0x2ac1, \"subnE;\":0x2acb,\n \"subne;\":0x228a, \"subplus;\":0x2abf,\n \"subrarr;\":0x2979, \"subset;\":0x2282,\n \"subseteq;\":0x2286, \"subseteqq;\":0x2ac5,\n \"subsetneq;\":0x228a, \"subsetneqq;\":0x2acb,\n \"subsim;\":0x2ac7, \"subsub;\":0x2ad5,\n \"subsup;\":0x2ad3, \"succ;\":0x227b,\n \"succapprox;\":0x2ab8, \"succcurlyeq;\":0x227d,\n \"succeq;\":0x2ab0, \"succnapprox;\":0x2aba,\n \"succneqq;\":0x2ab6, \"succnsim;\":0x22e9,\n \"succsim;\":0x227f, \"sum;\":0x2211,\n \"sung;\":0x266a, \"sup1\":0xb9,\n \"sup1;\":0xb9, \"sup2\":0xb2,\n \"sup2;\":0xb2, \"sup3\":0xb3,\n \"sup3;\":0xb3, \"sup;\":0x2283,\n \"supE;\":0x2ac6, \"supdot;\":0x2abe,\n \"supdsub;\":0x2ad8, \"supe;\":0x2287,\n \"supedot;\":0x2ac4, \"suphsol;\":0x27c9,\n \"suphsub;\":0x2ad7, \"suplarr;\":0x297b,\n \"supmult;\":0x2ac2, \"supnE;\":0x2acc,\n \"supne;\":0x228b, \"supplus;\":0x2ac0,\n \"supset;\":0x2283, \"supseteq;\":0x2287,\n \"supseteqq;\":0x2ac6, \"supsetneq;\":0x228b,\n \"supsetneqq;\":0x2acc, \"supsim;\":0x2ac8,\n \"supsub;\":0x2ad4, \"supsup;\":0x2ad6,\n \"swArr;\":0x21d9, \"swarhk;\":0x2926,\n \"swarr;\":0x2199, \"swarrow;\":0x2199,\n \"swnwar;\":0x292a, \"szlig\":0xdf,\n \"szlig;\":0xdf, \"target;\":0x2316,\n \"tau;\":0x3c4, \"tbrk;\":0x23b4,\n \"tcaron;\":0x165, \"tcedil;\":0x163,\n \"tcy;\":0x442, \"tdot;\":0x20db,\n \"telrec;\":0x2315, \"tfr;\":[0xd835,0xdd31],\n \"there4;\":0x2234, \"therefore;\":0x2234,\n \"theta;\":0x3b8, \"thetasym;\":0x3d1,\n \"thetav;\":0x3d1, \"thickapprox;\":0x2248,\n \"thicksim;\":0x223c, \"thinsp;\":0x2009,\n \"thkap;\":0x2248, \"thksim;\":0x223c,\n \"thorn\":0xfe, \"thorn;\":0xfe,\n \"tilde;\":0x2dc, \"times\":0xd7,\n \"times;\":0xd7, \"timesb;\":0x22a0,\n \"timesbar;\":0x2a31, \"timesd;\":0x2a30,\n \"tint;\":0x222d, \"toea;\":0x2928,\n \"top;\":0x22a4, \"topbot;\":0x2336,\n \"topcir;\":0x2af1, \"topf;\":[0xd835,0xdd65],\n \"topfork;\":0x2ada, \"tosa;\":0x2929,\n \"tprime;\":0x2034, \"trade;\":0x2122,\n \"triangle;\":0x25b5, \"triangledown;\":0x25bf,\n \"triangleleft;\":0x25c3, \"trianglelefteq;\":0x22b4,\n \"triangleq;\":0x225c, \"triangleright;\":0x25b9,\n \"trianglerighteq;\":0x22b5, \"tridot;\":0x25ec,\n \"trie;\":0x225c, \"triminus;\":0x2a3a,\n \"triplus;\":0x2a39, \"trisb;\":0x29cd,\n \"tritime;\":0x2a3b, \"trpezium;\":0x23e2,\n \"tscr;\":[0xd835,0xdcc9], \"tscy;\":0x446,\n \"tshcy;\":0x45b, \"tstrok;\":0x167,\n \"twixt;\":0x226c, \"twoheadleftarrow;\":0x219e,\n \"twoheadrightarrow;\":0x21a0, \"uArr;\":0x21d1,\n \"uHar;\":0x2963, \"uacute\":0xfa,\n \"uacute;\":0xfa, \"uarr;\":0x2191,\n \"ubrcy;\":0x45e, \"ubreve;\":0x16d,\n \"ucirc\":0xfb, \"ucirc;\":0xfb,\n \"ucy;\":0x443, \"udarr;\":0x21c5,\n \"udblac;\":0x171, \"udhar;\":0x296e,\n \"ufisht;\":0x297e, \"ufr;\":[0xd835,0xdd32],\n \"ugrave\":0xf9, \"ugrave;\":0xf9,\n \"uharl;\":0x21bf, \"uharr;\":0x21be,\n \"uhblk;\":0x2580, \"ulcorn;\":0x231c,\n \"ulcorner;\":0x231c, \"ulcrop;\":0x230f,\n \"ultri;\":0x25f8, \"umacr;\":0x16b,\n \"uml\":0xa8, \"uml;\":0xa8,\n \"uogon;\":0x173, \"uopf;\":[0xd835,0xdd66],\n \"uparrow;\":0x2191, \"updownarrow;\":0x2195,\n \"upharpoonleft;\":0x21bf, \"upharpoonright;\":0x21be,\n \"uplus;\":0x228e, \"upsi;\":0x3c5,\n \"upsih;\":0x3d2, \"upsilon;\":0x3c5,\n \"upuparrows;\":0x21c8, \"urcorn;\":0x231d,\n \"urcorner;\":0x231d, \"urcrop;\":0x230e,\n \"uring;\":0x16f, \"urtri;\":0x25f9,\n \"uscr;\":[0xd835,0xdcca], \"utdot;\":0x22f0,\n \"utilde;\":0x169, \"utri;\":0x25b5,\n \"utrif;\":0x25b4, \"uuarr;\":0x21c8,\n \"uuml\":0xfc, \"uuml;\":0xfc,\n \"uwangle;\":0x29a7, \"vArr;\":0x21d5,\n \"vBar;\":0x2ae8, \"vBarv;\":0x2ae9,\n \"vDash;\":0x22a8, \"vangrt;\":0x299c,\n \"varepsilon;\":0x3f5, \"varkappa;\":0x3f0,\n \"varnothing;\":0x2205, \"varphi;\":0x3d5,\n \"varpi;\":0x3d6, \"varpropto;\":0x221d,\n \"varr;\":0x2195, \"varrho;\":0x3f1,\n \"varsigma;\":0x3c2, \"varsubsetneq;\":[0x228a,0xfe00],\n \"varsubsetneqq;\":[0x2acb,0xfe00], \"varsupsetneq;\":[0x228b,0xfe00],\n \"varsupsetneqq;\":[0x2acc,0xfe00], \"vartheta;\":0x3d1,\n \"vartriangleleft;\":0x22b2, \"vartriangleright;\":0x22b3,\n \"vcy;\":0x432, \"vdash;\":0x22a2,\n \"vee;\":0x2228, \"veebar;\":0x22bb,\n \"veeeq;\":0x225a, \"vellip;\":0x22ee,\n \"verbar;\":0x7c, \"vert;\":0x7c,\n \"vfr;\":[0xd835,0xdd33], \"vltri;\":0x22b2,\n \"vnsub;\":[0x2282,0x20d2], \"vnsup;\":[0x2283,0x20d2],\n \"vopf;\":[0xd835,0xdd67], \"vprop;\":0x221d,\n \"vrtri;\":0x22b3, \"vscr;\":[0xd835,0xdccb],\n \"vsubnE;\":[0x2acb,0xfe00], \"vsubne;\":[0x228a,0xfe00],\n \"vsupnE;\":[0x2acc,0xfe00], \"vsupne;\":[0x228b,0xfe00],\n \"vzigzag;\":0x299a, \"wcirc;\":0x175,\n \"wedbar;\":0x2a5f, \"wedge;\":0x2227,\n \"wedgeq;\":0x2259, \"weierp;\":0x2118,\n \"wfr;\":[0xd835,0xdd34], \"wopf;\":[0xd835,0xdd68],\n \"wp;\":0x2118, \"wr;\":0x2240,\n \"wreath;\":0x2240, \"wscr;\":[0xd835,0xdccc],\n \"xcap;\":0x22c2, \"xcirc;\":0x25ef,\n \"xcup;\":0x22c3, \"xdtri;\":0x25bd,\n \"xfr;\":[0xd835,0xdd35], \"xhArr;\":0x27fa,\n \"xharr;\":0x27f7, \"xi;\":0x3be,\n \"xlArr;\":0x27f8, \"xlarr;\":0x27f5,\n \"xmap;\":0x27fc, \"xnis;\":0x22fb,\n \"xodot;\":0x2a00, \"xopf;\":[0xd835,0xdd69],\n \"xoplus;\":0x2a01, \"xotime;\":0x2a02,\n \"xrArr;\":0x27f9, \"xrarr;\":0x27f6,\n \"xscr;\":[0xd835,0xdccd], \"xsqcup;\":0x2a06,\n \"xuplus;\":0x2a04, \"xutri;\":0x25b3,\n \"xvee;\":0x22c1, \"xwedge;\":0x22c0,\n \"yacute\":0xfd, \"yacute;\":0xfd,\n \"yacy;\":0x44f, \"ycirc;\":0x177,\n \"ycy;\":0x44b, \"yen\":0xa5,\n \"yen;\":0xa5, \"yfr;\":[0xd835,0xdd36],\n \"yicy;\":0x457, \"yopf;\":[0xd835,0xdd6a],\n \"yscr;\":[0xd835,0xdcce], \"yucy;\":0x44e,\n \"yuml\":0xff, \"yuml;\":0xff,\n \"zacute;\":0x17a, \"zcaron;\":0x17e,\n \"zcy;\":0x437, \"zdot;\":0x17c,\n \"zeetrf;\":0x2128, \"zeta;\":0x3b6,\n \"zfr;\":[0xd835,0xdd37], \"zhcy;\":0x436,\n \"zigrarr;\":0x21dd, \"zopf;\":[0xd835,0xdd6b],\n \"zscr;\":[0xd835,0xdccf], \"zwj;\":0x200d,\n \"zwnj;\":0x200c,\n};\n/*\n * This regexp is generated with test/tools/update-entities.js\n * It will always match at least one character -- but note that there\n * are no entities whose names are a single character long.\n */\nvar NAMEDCHARREF = /(A(?:Elig;?|MP;?|acute;?|breve;|c(?:irc;?|y;)|fr;|grave;?|lpha;|macr;|nd;|o(?:gon;|pf;)|pplyFunction;|ring;?|s(?:cr;|sign;)|tilde;?|uml;?)|B(?:a(?:ckslash;|r(?:v;|wed;))|cy;|e(?:cause;|rnoullis;|ta;)|fr;|opf;|reve;|scr;|umpeq;)|C(?:Hcy;|OPY;?|a(?:cute;|p(?:;|italDifferentialD;)|yleys;)|c(?:aron;|edil;?|irc;|onint;)|dot;|e(?:dilla;|nterDot;)|fr;|hi;|ircle(?:Dot;|Minus;|Plus;|Times;)|lo(?:ckwiseContourIntegral;|seCurly(?:DoubleQuote;|Quote;))|o(?:lon(?:;|e;)|n(?:gruent;|int;|tourIntegral;)|p(?:f;|roduct;)|unterClockwiseContourIntegral;)|ross;|scr;|up(?:;|Cap;))|D(?:D(?:;|otrahd;)|Jcy;|Scy;|Zcy;|a(?:gger;|rr;|shv;)|c(?:aron;|y;)|el(?:;|ta;)|fr;|i(?:a(?:critical(?:Acute;|Do(?:t;|ubleAcute;)|Grave;|Tilde;)|mond;)|fferentialD;)|o(?:pf;|t(?:;|Dot;|Equal;)|uble(?:ContourIntegral;|Do(?:t;|wnArrow;)|L(?:eft(?:Arrow;|RightArrow;|Tee;)|ong(?:Left(?:Arrow;|RightArrow;)|RightArrow;))|Right(?:Arrow;|Tee;)|Up(?:Arrow;|DownArrow;)|VerticalBar;)|wn(?:Arrow(?:;|Bar;|UpArrow;)|Breve;|Left(?:RightVector;|TeeVector;|Vector(?:;|Bar;))|Right(?:TeeVector;|Vector(?:;|Bar;))|Tee(?:;|Arrow;)|arrow;))|s(?:cr;|trok;))|E(?:NG;|TH;?|acute;?|c(?:aron;|irc;?|y;)|dot;|fr;|grave;?|lement;|m(?:acr;|pty(?:SmallSquare;|VerySmallSquare;))|o(?:gon;|pf;)|psilon;|qu(?:al(?:;|Tilde;)|ilibrium;)|s(?:cr;|im;)|ta;|uml;?|x(?:ists;|ponentialE;))|F(?:cy;|fr;|illed(?:SmallSquare;|VerySmallSquare;)|o(?:pf;|rAll;|uriertrf;)|scr;)|G(?:Jcy;|T;?|amma(?:;|d;)|breve;|c(?:edil;|irc;|y;)|dot;|fr;|g;|opf;|reater(?:Equal(?:;|Less;)|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;)|scr;|t;)|H(?:ARDcy;|a(?:cek;|t;)|circ;|fr;|ilbertSpace;|o(?:pf;|rizontalLine;)|s(?:cr;|trok;)|ump(?:DownHump;|Equal;))|I(?:Ecy;|Jlig;|Ocy;|acute;?|c(?:irc;?|y;)|dot;|fr;|grave;?|m(?:;|a(?:cr;|ginaryI;)|plies;)|n(?:t(?:;|e(?:gral;|rsection;))|visible(?:Comma;|Times;))|o(?:gon;|pf;|ta;)|scr;|tilde;|u(?:kcy;|ml;?))|J(?:c(?:irc;|y;)|fr;|opf;|s(?:cr;|ercy;)|ukcy;)|K(?:Hcy;|Jcy;|appa;|c(?:edil;|y;)|fr;|opf;|scr;)|L(?:Jcy;|T;?|a(?:cute;|mbda;|ng;|placetrf;|rr;)|c(?:aron;|edil;|y;)|e(?:ft(?:A(?:ngleBracket;|rrow(?:;|Bar;|RightArrow;))|Ceiling;|Do(?:ubleBracket;|wn(?:TeeVector;|Vector(?:;|Bar;)))|Floor;|Right(?:Arrow;|Vector;)|T(?:ee(?:;|Arrow;|Vector;)|riangle(?:;|Bar;|Equal;))|Up(?:DownVector;|TeeVector;|Vector(?:;|Bar;))|Vector(?:;|Bar;)|arrow;|rightarrow;)|ss(?:EqualGreater;|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;))|fr;|l(?:;|eftarrow;)|midot;|o(?:ng(?:Left(?:Arrow;|RightArrow;)|RightArrow;|left(?:arrow;|rightarrow;)|rightarrow;)|pf;|wer(?:LeftArrow;|RightArrow;))|s(?:cr;|h;|trok;)|t;)|M(?:ap;|cy;|e(?:diumSpace;|llintrf;)|fr;|inusPlus;|opf;|scr;|u;)|N(?:Jcy;|acute;|c(?:aron;|edil;|y;)|e(?:gative(?:MediumSpace;|Thi(?:ckSpace;|nSpace;)|VeryThinSpace;)|sted(?:GreaterGreater;|LessLess;)|wLine;)|fr;|o(?:Break;|nBreakingSpace;|pf;|t(?:;|C(?:ongruent;|upCap;)|DoubleVerticalBar;|E(?:lement;|qual(?:;|Tilde;)|xists;)|Greater(?:;|Equal;|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;)|Hump(?:DownHump;|Equal;)|Le(?:ftTriangle(?:;|Bar;|Equal;)|ss(?:;|Equal;|Greater;|Less;|SlantEqual;|Tilde;))|Nested(?:GreaterGreater;|LessLess;)|Precedes(?:;|Equal;|SlantEqual;)|R(?:everseElement;|ightTriangle(?:;|Bar;|Equal;))|S(?:quareSu(?:bset(?:;|Equal;)|perset(?:;|Equal;))|u(?:bset(?:;|Equal;)|cceeds(?:;|Equal;|SlantEqual;|Tilde;)|perset(?:;|Equal;)))|Tilde(?:;|Equal;|FullEqual;|Tilde;)|VerticalBar;))|scr;|tilde;?|u;)|O(?:Elig;|acute;?|c(?:irc;?|y;)|dblac;|fr;|grave;?|m(?:acr;|ega;|icron;)|opf;|penCurly(?:DoubleQuote;|Quote;)|r;|s(?:cr;|lash;?)|ti(?:lde;?|mes;)|uml;?|ver(?:B(?:ar;|rac(?:e;|ket;))|Parenthesis;))|P(?:artialD;|cy;|fr;|hi;|i;|lusMinus;|o(?:incareplane;|pf;)|r(?:;|ecedes(?:;|Equal;|SlantEqual;|Tilde;)|ime;|o(?:duct;|portion(?:;|al;)))|s(?:cr;|i;))|Q(?:UOT;?|fr;|opf;|scr;)|R(?:Barr;|EG;?|a(?:cute;|ng;|rr(?:;|tl;))|c(?:aron;|edil;|y;)|e(?:;|verse(?:E(?:lement;|quilibrium;)|UpEquilibrium;))|fr;|ho;|ight(?:A(?:ngleBracket;|rrow(?:;|Bar;|LeftArrow;))|Ceiling;|Do(?:ubleBracket;|wn(?:TeeVector;|Vector(?:;|Bar;)))|Floor;|T(?:ee(?:;|Arrow;|Vector;)|riangle(?:;|Bar;|Equal;))|Up(?:DownVector;|TeeVector;|Vector(?:;|Bar;))|Vector(?:;|Bar;)|arrow;)|o(?:pf;|undImplies;)|rightarrow;|s(?:cr;|h;)|uleDelayed;)|S(?:H(?:CHcy;|cy;)|OFTcy;|acute;|c(?:;|aron;|edil;|irc;|y;)|fr;|hort(?:DownArrow;|LeftArrow;|RightArrow;|UpArrow;)|igma;|mallCircle;|opf;|q(?:rt;|uare(?:;|Intersection;|Su(?:bset(?:;|Equal;)|perset(?:;|Equal;))|Union;))|scr;|tar;|u(?:b(?:;|set(?:;|Equal;))|c(?:ceeds(?:;|Equal;|SlantEqual;|Tilde;)|hThat;)|m;|p(?:;|erset(?:;|Equal;)|set;)))|T(?:HORN;?|RADE;|S(?:Hcy;|cy;)|a(?:b;|u;)|c(?:aron;|edil;|y;)|fr;|h(?:e(?:refore;|ta;)|i(?:ckSpace;|nSpace;))|ilde(?:;|Equal;|FullEqual;|Tilde;)|opf;|ripleDot;|s(?:cr;|trok;))|U(?:a(?:cute;?|rr(?:;|ocir;))|br(?:cy;|eve;)|c(?:irc;?|y;)|dblac;|fr;|grave;?|macr;|n(?:der(?:B(?:ar;|rac(?:e;|ket;))|Parenthesis;)|ion(?:;|Plus;))|o(?:gon;|pf;)|p(?:Arrow(?:;|Bar;|DownArrow;)|DownArrow;|Equilibrium;|Tee(?:;|Arrow;)|arrow;|downarrow;|per(?:LeftArrow;|RightArrow;)|si(?:;|lon;))|ring;|scr;|tilde;|uml;?)|V(?:Dash;|bar;|cy;|dash(?:;|l;)|e(?:e;|r(?:bar;|t(?:;|ical(?:Bar;|Line;|Separator;|Tilde;))|yThinSpace;))|fr;|opf;|scr;|vdash;)|W(?:circ;|edge;|fr;|opf;|scr;)|X(?:fr;|i;|opf;|scr;)|Y(?:Acy;|Icy;|Ucy;|acute;?|c(?:irc;|y;)|fr;|opf;|scr;|uml;)|Z(?:Hcy;|acute;|c(?:aron;|y;)|dot;|e(?:roWidthSpace;|ta;)|fr;|opf;|scr;)|a(?:acute;?|breve;|c(?:;|E;|d;|irc;?|ute;?|y;)|elig;?|f(?:;|r;)|grave;?|l(?:e(?:fsym;|ph;)|pha;)|m(?:a(?:cr;|lg;)|p;?)|n(?:d(?:;|and;|d;|slope;|v;)|g(?:;|e;|le;|msd(?:;|a(?:a;|b;|c;|d;|e;|f;|g;|h;))|rt(?:;|vb(?:;|d;))|s(?:ph;|t;)|zarr;))|o(?:gon;|pf;)|p(?:;|E;|acir;|e;|id;|os;|prox(?:;|eq;))|ring;?|s(?:cr;|t;|ymp(?:;|eq;))|tilde;?|uml;?|w(?:conint;|int;))|b(?:Not;|a(?:ck(?:cong;|epsilon;|prime;|sim(?:;|eq;))|r(?:vee;|wed(?:;|ge;)))|brk(?:;|tbrk;)|c(?:ong;|y;)|dquo;|e(?:caus(?:;|e;)|mptyv;|psi;|rnou;|t(?:a;|h;|ween;))|fr;|ig(?:c(?:ap;|irc;|up;)|o(?:dot;|plus;|times;)|s(?:qcup;|tar;)|triangle(?:down;|up;)|uplus;|vee;|wedge;)|karow;|l(?:a(?:ck(?:lozenge;|square;|triangle(?:;|down;|left;|right;))|nk;)|k(?:1(?:2;|4;)|34;)|ock;)|n(?:e(?:;|quiv;)|ot;)|o(?:pf;|t(?:;|tom;)|wtie;|x(?:D(?:L;|R;|l;|r;)|H(?:;|D;|U;|d;|u;)|U(?:L;|R;|l;|r;)|V(?:;|H;|L;|R;|h;|l;|r;)|box;|d(?:L;|R;|l;|r;)|h(?:;|D;|U;|d;|u;)|minus;|plus;|times;|u(?:L;|R;|l;|r;)|v(?:;|H;|L;|R;|h;|l;|r;)))|prime;|r(?:eve;|vbar;?)|s(?:cr;|emi;|im(?:;|e;)|ol(?:;|b;|hsub;))|u(?:ll(?:;|et;)|mp(?:;|E;|e(?:;|q;))))|c(?:a(?:cute;|p(?:;|and;|brcup;|c(?:ap;|up;)|dot;|s;)|r(?:et;|on;))|c(?:a(?:ps;|ron;)|edil;?|irc;|ups(?:;|sm;))|dot;|e(?:dil;?|mptyv;|nt(?:;|erdot;|))|fr;|h(?:cy;|eck(?:;|mark;)|i;)|ir(?:;|E;|c(?:;|eq;|le(?:arrow(?:left;|right;)|d(?:R;|S;|ast;|circ;|dash;)))|e;|fnint;|mid;|scir;)|lubs(?:;|uit;)|o(?:lon(?:;|e(?:;|q;))|m(?:ma(?:;|t;)|p(?:;|fn;|le(?:ment;|xes;)))|n(?:g(?:;|dot;)|int;)|p(?:f;|rod;|y(?:;|sr;|)))|r(?:arr;|oss;)|s(?:cr;|u(?:b(?:;|e;)|p(?:;|e;)))|tdot;|u(?:darr(?:l;|r;)|e(?:pr;|sc;)|larr(?:;|p;)|p(?:;|brcap;|c(?:ap;|up;)|dot;|or;|s;)|r(?:arr(?:;|m;)|ly(?:eq(?:prec;|succ;)|vee;|wedge;)|ren;?|vearrow(?:left;|right;))|vee;|wed;)|w(?:conint;|int;)|ylcty;)|d(?:Arr;|Har;|a(?:gger;|leth;|rr;|sh(?:;|v;))|b(?:karow;|lac;)|c(?:aron;|y;)|d(?:;|a(?:gger;|rr;)|otseq;)|e(?:g;?|lta;|mptyv;)|f(?:isht;|r;)|har(?:l;|r;)|i(?:am(?:;|ond(?:;|suit;)|s;)|e;|gamma;|sin;|v(?:;|ide(?:;|ontimes;|)|onx;))|jcy;|lc(?:orn;|rop;)|o(?:llar;|pf;|t(?:;|eq(?:;|dot;)|minus;|plus;|square;)|ublebarwedge;|wn(?:arrow;|downarrows;|harpoon(?:left;|right;)))|r(?:bkarow;|c(?:orn;|rop;))|s(?:c(?:r;|y;)|ol;|trok;)|t(?:dot;|ri(?:;|f;))|u(?:arr;|har;)|wangle;|z(?:cy;|igrarr;))|e(?:D(?:Dot;|ot;)|a(?:cute;?|ster;)|c(?:aron;|ir(?:;|c;?)|olon;|y;)|dot;|e;|f(?:Dot;|r;)|g(?:;|rave;?|s(?:;|dot;))|l(?:;|inters;|l;|s(?:;|dot;))|m(?:acr;|pty(?:;|set;|v;)|sp(?:1(?:3;|4;)|;))|n(?:g;|sp;)|o(?:gon;|pf;)|p(?:ar(?:;|sl;)|lus;|si(?:;|lon;|v;))|q(?:c(?:irc;|olon;)|s(?:im;|lant(?:gtr;|less;))|u(?:als;|est;|iv(?:;|DD;))|vparsl;)|r(?:Dot;|arr;)|s(?:cr;|dot;|im;)|t(?:a;|h;?)|u(?:ml;?|ro;)|x(?:cl;|ist;|p(?:ectation;|onentiale;)))|f(?:allingdotseq;|cy;|emale;|f(?:ilig;|l(?:ig;|lig;)|r;)|ilig;|jlig;|l(?:at;|lig;|tns;)|nof;|o(?:pf;|r(?:all;|k(?:;|v;)))|partint;|r(?:a(?:c(?:1(?:2;?|3;|4;?|5;|6;|8;)|2(?:3;|5;)|3(?:4;?|5;|8;)|45;|5(?:6;|8;)|78;)|sl;)|own;)|scr;)|g(?:E(?:;|l;)|a(?:cute;|mma(?:;|d;)|p;)|breve;|c(?:irc;|y;)|dot;|e(?:;|l;|q(?:;|q;|slant;)|s(?:;|cc;|dot(?:;|o(?:;|l;))|l(?:;|es;)))|fr;|g(?:;|g;)|imel;|jcy;|l(?:;|E;|a;|j;)|n(?:E;|ap(?:;|prox;)|e(?:;|q(?:;|q;))|sim;)|opf;|rave;|s(?:cr;|im(?:;|e;|l;))|t(?:;|c(?:c;|ir;)|dot;|lPar;|quest;|r(?:a(?:pprox;|rr;)|dot;|eq(?:less;|qless;)|less;|sim;)|)|v(?:ertneqq;|nE;))|h(?:Arr;|a(?:irsp;|lf;|milt;|r(?:dcy;|r(?:;|cir;|w;)))|bar;|circ;|e(?:arts(?:;|uit;)|llip;|rcon;)|fr;|ks(?:earow;|warow;)|o(?:arr;|mtht;|ok(?:leftarrow;|rightarrow;)|pf;|rbar;)|s(?:cr;|lash;|trok;)|y(?:bull;|phen;))|i(?:acute;?|c(?:;|irc;?|y;)|e(?:cy;|xcl;?)|f(?:f;|r;)|grave;?|i(?:;|i(?:int;|nt;)|nfin;|ota;)|jlig;|m(?:a(?:cr;|g(?:e;|line;|part;)|th;)|of;|ped;)|n(?:;|care;|fin(?:;|tie;)|odot;|t(?:;|cal;|e(?:gers;|rcal;)|larhk;|prod;))|o(?:cy;|gon;|pf;|ta;)|prod;|quest;?|s(?:cr;|in(?:;|E;|dot;|s(?:;|v;)|v;))|t(?:;|ilde;)|u(?:kcy;|ml;?))|j(?:c(?:irc;|y;)|fr;|math;|opf;|s(?:cr;|ercy;)|ukcy;)|k(?:appa(?:;|v;)|c(?:edil;|y;)|fr;|green;|hcy;|jcy;|opf;|scr;)|l(?:A(?:arr;|rr;|tail;)|Barr;|E(?:;|g;)|Har;|a(?:cute;|emptyv;|gran;|mbda;|ng(?:;|d;|le;)|p;|quo;?|rr(?:;|b(?:;|fs;)|fs;|hk;|lp;|pl;|sim;|tl;)|t(?:;|ail;|e(?:;|s;)))|b(?:arr;|brk;|r(?:ac(?:e;|k;)|k(?:e;|sl(?:d;|u;))))|c(?:aron;|e(?:dil;|il;)|ub;|y;)|d(?:ca;|quo(?:;|r;)|r(?:dhar;|ushar;)|sh;)|e(?:;|ft(?:arrow(?:;|tail;)|harpoon(?:down;|up;)|leftarrows;|right(?:arrow(?:;|s;)|harpoons;|squigarrow;)|threetimes;)|g;|q(?:;|q;|slant;)|s(?:;|cc;|dot(?:;|o(?:;|r;))|g(?:;|es;)|s(?:approx;|dot;|eq(?:gtr;|qgtr;)|gtr;|sim;)))|f(?:isht;|loor;|r;)|g(?:;|E;)|h(?:ar(?:d;|u(?:;|l;))|blk;)|jcy;|l(?:;|arr;|corner;|hard;|tri;)|m(?:idot;|oust(?:;|ache;))|n(?:E;|ap(?:;|prox;)|e(?:;|q(?:;|q;))|sim;)|o(?:a(?:ng;|rr;)|brk;|ng(?:left(?:arrow;|rightarrow;)|mapsto;|rightarrow;)|oparrow(?:left;|right;)|p(?:ar;|f;|lus;)|times;|w(?:ast;|bar;)|z(?:;|enge;|f;))|par(?:;|lt;)|r(?:arr;|corner;|har(?:;|d;)|m;|tri;)|s(?:aquo;|cr;|h;|im(?:;|e;|g;)|q(?:b;|uo(?:;|r;))|trok;)|t(?:;|c(?:c;|ir;)|dot;|hree;|imes;|larr;|quest;|r(?:Par;|i(?:;|e;|f;))|)|ur(?:dshar;|uhar;)|v(?:ertneqq;|nE;))|m(?:DDot;|a(?:cr;?|l(?:e;|t(?:;|ese;))|p(?:;|sto(?:;|down;|left;|up;))|rker;)|c(?:omma;|y;)|dash;|easuredangle;|fr;|ho;|i(?:cro;?|d(?:;|ast;|cir;|dot;?)|nus(?:;|b;|d(?:;|u;)))|l(?:cp;|dr;)|nplus;|o(?:dels;|pf;)|p;|s(?:cr;|tpos;)|u(?:;|ltimap;|map;))|n(?:G(?:g;|t(?:;|v;))|L(?:eft(?:arrow;|rightarrow;)|l;|t(?:;|v;))|Rightarrow;|V(?:Dash;|dash;)|a(?:bla;|cute;|ng;|p(?:;|E;|id;|os;|prox;)|tur(?:;|al(?:;|s;)))|b(?:sp;?|ump(?:;|e;))|c(?:a(?:p;|ron;)|edil;|ong(?:;|dot;)|up;|y;)|dash;|e(?:;|Arr;|ar(?:hk;|r(?:;|ow;))|dot;|quiv;|s(?:ear;|im;)|xist(?:;|s;))|fr;|g(?:E;|e(?:;|q(?:;|q;|slant;)|s;)|sim;|t(?:;|r;))|h(?:Arr;|arr;|par;)|i(?:;|s(?:;|d;)|v;)|jcy;|l(?:Arr;|E;|arr;|dr;|e(?:;|ft(?:arrow;|rightarrow;)|q(?:;|q;|slant;)|s(?:;|s;))|sim;|t(?:;|ri(?:;|e;)))|mid;|o(?:pf;|t(?:;|in(?:;|E;|dot;|v(?:a;|b;|c;))|ni(?:;|v(?:a;|b;|c;))|))|p(?:ar(?:;|allel;|sl;|t;)|olint;|r(?:;|cue;|e(?:;|c(?:;|eq;))))|r(?:Arr;|arr(?:;|c;|w;)|ightarrow;|tri(?:;|e;))|s(?:c(?:;|cue;|e;|r;)|hort(?:mid;|parallel;)|im(?:;|e(?:;|q;))|mid;|par;|qsu(?:be;|pe;)|u(?:b(?:;|E;|e;|set(?:;|eq(?:;|q;)))|cc(?:;|eq;)|p(?:;|E;|e;|set(?:;|eq(?:;|q;)))))|t(?:gl;|ilde;?|lg;|riangle(?:left(?:;|eq;)|right(?:;|eq;)))|u(?:;|m(?:;|ero;|sp;))|v(?:Dash;|Harr;|ap;|dash;|g(?:e;|t;)|infin;|l(?:Arr;|e;|t(?:;|rie;))|r(?:Arr;|trie;)|sim;)|w(?:Arr;|ar(?:hk;|r(?:;|ow;))|near;))|o(?:S;|a(?:cute;?|st;)|c(?:ir(?:;|c;?)|y;)|d(?:ash;|blac;|iv;|ot;|sold;)|elig;|f(?:cir;|r;)|g(?:on;|rave;?|t;)|h(?:bar;|m;)|int;|l(?:arr;|c(?:ir;|ross;)|ine;|t;)|m(?:acr;|ega;|i(?:cron;|d;|nus;))|opf;|p(?:ar;|erp;|lus;)|r(?:;|arr;|d(?:;|er(?:;|of;)|f;?|m;?)|igof;|or;|slope;|v;)|s(?:cr;|lash;?|ol;)|ti(?:lde;?|mes(?:;|as;))|uml;?|vbar;)|p(?:ar(?:;|a(?:;|llel;|)|s(?:im;|l;)|t;)|cy;|er(?:cnt;|iod;|mil;|p;|tenk;)|fr;|h(?:i(?:;|v;)|mmat;|one;)|i(?:;|tchfork;|v;)|l(?:an(?:ck(?:;|h;)|kv;)|us(?:;|acir;|b;|cir;|d(?:o;|u;)|e;|mn;?|sim;|two;))|m;|o(?:intint;|pf;|und;?)|r(?:;|E;|ap;|cue;|e(?:;|c(?:;|approx;|curlyeq;|eq;|n(?:approx;|eqq;|sim;)|sim;))|ime(?:;|s;)|n(?:E;|ap;|sim;)|o(?:d;|f(?:alar;|line;|surf;)|p(?:;|to;))|sim;|urel;)|s(?:cr;|i;)|uncsp;)|q(?:fr;|int;|opf;|prime;|scr;|u(?:at(?:ernions;|int;)|est(?:;|eq;)|ot;?))|r(?:A(?:arr;|rr;|tail;)|Barr;|Har;|a(?:c(?:e;|ute;)|dic;|emptyv;|ng(?:;|d;|e;|le;)|quo;?|rr(?:;|ap;|b(?:;|fs;)|c;|fs;|hk;|lp;|pl;|sim;|tl;|w;)|t(?:ail;|io(?:;|nals;)))|b(?:arr;|brk;|r(?:ac(?:e;|k;)|k(?:e;|sl(?:d;|u;))))|c(?:aron;|e(?:dil;|il;)|ub;|y;)|d(?:ca;|ldhar;|quo(?:;|r;)|sh;)|e(?:al(?:;|ine;|part;|s;)|ct;|g;?)|f(?:isht;|loor;|r;)|h(?:ar(?:d;|u(?:;|l;))|o(?:;|v;))|i(?:ght(?:arrow(?:;|tail;)|harpoon(?:down;|up;)|left(?:arrows;|harpoons;)|rightarrows;|squigarrow;|threetimes;)|ng;|singdotseq;)|l(?:arr;|har;|m;)|moust(?:;|ache;)|nmid;|o(?:a(?:ng;|rr;)|brk;|p(?:ar;|f;|lus;)|times;)|p(?:ar(?:;|gt;)|polint;)|rarr;|s(?:aquo;|cr;|h;|q(?:b;|uo(?:;|r;)))|t(?:hree;|imes;|ri(?:;|e;|f;|ltri;))|uluhar;|x;)|s(?:acute;|bquo;|c(?:;|E;|a(?:p;|ron;)|cue;|e(?:;|dil;)|irc;|n(?:E;|ap;|sim;)|polint;|sim;|y;)|dot(?:;|b;|e;)|e(?:Arr;|ar(?:hk;|r(?:;|ow;))|ct;?|mi;|swar;|tm(?:inus;|n;)|xt;)|fr(?:;|own;)|h(?:arp;|c(?:hcy;|y;)|ort(?:mid;|parallel;)|y;?)|i(?:gma(?:;|f;|v;)|m(?:;|dot;|e(?:;|q;)|g(?:;|E;)|l(?:;|E;)|ne;|plus;|rarr;))|larr;|m(?:a(?:llsetminus;|shp;)|eparsl;|i(?:d;|le;)|t(?:;|e(?:;|s;)))|o(?:ftcy;|l(?:;|b(?:;|ar;))|pf;)|pa(?:des(?:;|uit;)|r;)|q(?:c(?:ap(?:;|s;)|up(?:;|s;))|su(?:b(?:;|e;|set(?:;|eq;))|p(?:;|e;|set(?:;|eq;)))|u(?:;|ar(?:e;|f;)|f;))|rarr;|s(?:cr;|etmn;|mile;|tarf;)|t(?:ar(?:;|f;)|r(?:aight(?:epsilon;|phi;)|ns;))|u(?:b(?:;|E;|dot;|e(?:;|dot;)|mult;|n(?:E;|e;)|plus;|rarr;|s(?:et(?:;|eq(?:;|q;)|neq(?:;|q;))|im;|u(?:b;|p;)))|cc(?:;|approx;|curlyeq;|eq;|n(?:approx;|eqq;|sim;)|sim;)|m;|ng;|p(?:1;?|2;?|3;?|;|E;|d(?:ot;|sub;)|e(?:;|dot;)|hs(?:ol;|ub;)|larr;|mult;|n(?:E;|e;)|plus;|s(?:et(?:;|eq(?:;|q;)|neq(?:;|q;))|im;|u(?:b;|p;))))|w(?:Arr;|ar(?:hk;|r(?:;|ow;))|nwar;)|zlig;?)|t(?:a(?:rget;|u;)|brk;|c(?:aron;|edil;|y;)|dot;|elrec;|fr;|h(?:e(?:re(?:4;|fore;)|ta(?:;|sym;|v;))|i(?:ck(?:approx;|sim;)|nsp;)|k(?:ap;|sim;)|orn;?)|i(?:lde;|mes(?:;|b(?:;|ar;)|d;|)|nt;)|o(?:ea;|p(?:;|bot;|cir;|f(?:;|ork;))|sa;)|prime;|r(?:ade;|i(?:angle(?:;|down;|left(?:;|eq;)|q;|right(?:;|eq;))|dot;|e;|minus;|plus;|sb;|time;)|pezium;)|s(?:c(?:r;|y;)|hcy;|trok;)|w(?:ixt;|ohead(?:leftarrow;|rightarrow;)))|u(?:Arr;|Har;|a(?:cute;?|rr;)|br(?:cy;|eve;)|c(?:irc;?|y;)|d(?:arr;|blac;|har;)|f(?:isht;|r;)|grave;?|h(?:ar(?:l;|r;)|blk;)|l(?:c(?:orn(?:;|er;)|rop;)|tri;)|m(?:acr;|l;?)|o(?:gon;|pf;)|p(?:arrow;|downarrow;|harpoon(?:left;|right;)|lus;|si(?:;|h;|lon;)|uparrows;)|r(?:c(?:orn(?:;|er;)|rop;)|ing;|tri;)|scr;|t(?:dot;|ilde;|ri(?:;|f;))|u(?:arr;|ml;?)|wangle;)|v(?:Arr;|Bar(?:;|v;)|Dash;|a(?:ngrt;|r(?:epsilon;|kappa;|nothing;|p(?:hi;|i;|ropto;)|r(?:;|ho;)|s(?:igma;|u(?:bsetneq(?:;|q;)|psetneq(?:;|q;)))|t(?:heta;|riangle(?:left;|right;))))|cy;|dash;|e(?:e(?:;|bar;|eq;)|llip;|r(?:bar;|t;))|fr;|ltri;|nsu(?:b;|p;)|opf;|prop;|rtri;|s(?:cr;|u(?:bn(?:E;|e;)|pn(?:E;|e;)))|zigzag;)|w(?:circ;|e(?:d(?:bar;|ge(?:;|q;))|ierp;)|fr;|opf;|p;|r(?:;|eath;)|scr;)|x(?:c(?:ap;|irc;|up;)|dtri;|fr;|h(?:Arr;|arr;)|i;|l(?:Arr;|arr;)|map;|nis;|o(?:dot;|p(?:f;|lus;)|time;)|r(?:Arr;|arr;)|s(?:cr;|qcup;)|u(?:plus;|tri;)|vee;|wedge;)|y(?:ac(?:ute;?|y;)|c(?:irc;|y;)|en;?|fr;|icy;|opf;|scr;|u(?:cy;|ml;?))|z(?:acute;|c(?:aron;|y;)|dot;|e(?:etrf;|ta;)|fr;|hcy;|igrarr;|opf;|scr;|w(?:j;|nj;)))|[\\s\\S]/g;\n\nvar NAMEDCHARREF_MAXLEN = 32;\n\n// Regular expression constants used by the tokenizer and parser\n\n// Note that \\r is included in all of these regexps because it will need\n// to be converted to LF by the scanChars() function.\nvar DBLQUOTEATTRVAL = /[^\\r\"&\\u0000]+/g;\nvar SINGLEQUOTEATTRVAL = /[^\\r'&\\u0000]+/g;\nvar UNQUOTEDATTRVAL = /[^\\r\\t\\n\\f &>\\u0000]+/g;\nvar TAGNAME = /[^\\r\\t\\n\\f \\/>A-Z\\u0000]+/g;\nvar ATTRNAME = /[^\\r\\t\\n\\f \\/=>A-Z\\u0000]+/g;\n\nvar CDATATEXT = /[^\\]\\r\\u0000\\uffff]*/g;\nvar DATATEXT = /[^&<\\r\\u0000\\uffff]*/g;\nvar RAWTEXT = /[^<\\r\\u0000\\uffff]*/g;\nvar PLAINTEXT = /[^\\r\\u0000\\uffff]*/g;\n// Since we don't have the 'sticky tag', add '|.' to the end of SIMPLETAG\n// and SIMPLEATTR so that we are guaranteed to always match. This prevents\n// us from scanning past the lastIndex set. (Note that the desired matches\n// are always greater than 1 char long, so longest-match will ensure that .\n// is not matched unless the desired match fails.)\nvar SIMPLETAG = /(?:(\\/)?([a-z]+)>)|[\\s\\S]/g;\nvar SIMPLEATTR = /(?:([-a-z]+)[ \\t\\n\\f]*=[ \\t\\n\\f]*('[^'&\\r\\u0000]*'|\"[^\"&\\r\\u0000]*\"|[^\\t\\n\\r\\f \"&'\\u0000>][^&> \\t\\n\\r\\f\\u0000]*[ \\t\\n\\f]))|[\\s\\S]/g;\n\nvar NONWS = /[^\\x09\\x0A\\x0C\\x0D\\x20]/;\nvar ALLNONWS = /[^\\x09\\x0A\\x0C\\x0D\\x20]/g; // like above, with g flag\nvar NONWSNONNUL = /[^\\x00\\x09\\x0A\\x0C\\x0D\\x20]/; // don't allow NUL either\nvar LEADINGWS = /^[\\x09\\x0A\\x0C\\x0D\\x20]+/;\nvar NULCHARS = /\\x00/g;\n\n/***\n * These are utility functions that don't use any of the parser's\n * internal state.\n */\nfunction buf2str(buf) {\n var CHUNKSIZE=16384;\n if (buf.length < CHUNKSIZE) {\n return String.fromCharCode.apply(String, buf);\n }\n // special case for large strings, to avoid busting the stack.\n var result = '';\n for (var i = 0; i < buf.length; i += CHUNKSIZE) {\n result += String.fromCharCode.apply(String, buf.slice(i, i+CHUNKSIZE));\n }\n return result;\n}\n\nfunction str2buf(s) {\n var result = [];\n for (var i=0; i 0; i--) {\n var e = this.elements[i];\n if (isA(e, tag)) break;\n }\n this.elements.length = i;\n this.top = this.elements[i-1];\n};\n\n// Pop elements off the stack up to and including the first\n// element that is an instance of the specified type\nHTMLParser.ElementStack.prototype.popElementType = function(type) {\n for(var i = this.elements.length-1; i > 0; i--) {\n if (this.elements[i] instanceof type) break;\n }\n this.elements.length = i;\n this.top = this.elements[i-1];\n};\n\n// Pop elements off the stack up to and including the element e.\n// Note that this is very different from removeElement()\n// This requires that e is on the stack.\nHTMLParser.ElementStack.prototype.popElement = function(e) {\n for(var i = this.elements.length-1; i > 0; i--) {\n if (this.elements[i] === e) break;\n }\n this.elements.length = i;\n this.top = this.elements[i-1];\n};\n\n// Remove a specific element from the stack.\n// Do nothing if the element is not on the stack\nHTMLParser.ElementStack.prototype.removeElement = function(e) {\n if (this.top === e) this.pop();\n else {\n var idx = this.elements.lastIndexOf(e);\n if (idx !== -1)\n this.elements.splice(idx, 1);\n }\n};\n\nHTMLParser.ElementStack.prototype.clearToContext = function(set) {\n // Note that we don't loop to 0. Never pop the elt off.\n for(var i = this.elements.length-1; i > 0; i--) {\n if (isA(this.elements[i], set)) break;\n }\n this.elements.length = i+1;\n this.top = this.elements[i];\n};\n\nHTMLParser.ElementStack.prototype.contains = function(tag) {\n return this.inSpecificScope(tag, Object.create(null));\n};\n\nHTMLParser.ElementStack.prototype.inSpecificScope = function(tag, set) {\n for(var i = this.elements.length-1; i >= 0; i--) {\n var elt = this.elements[i];\n if (isA(elt, tag)) return true;\n if (isA(elt, set)) return false;\n }\n return false;\n};\n\n// Like the above, but for a specific element, not a tagname\nHTMLParser.ElementStack.prototype.elementInSpecificScope = function(target, set) {\n for(var i = this.elements.length-1; i >= 0; i--) {\n var elt = this.elements[i];\n if (elt === target) return true;\n if (isA(elt, set)) return false;\n }\n return false;\n};\n\n// Like the above, but for an element interface, not a tagname\nHTMLParser.ElementStack.prototype.elementTypeInSpecificScope = function(target, set) {\n for(var i = this.elements.length-1; i >= 0; i--) {\n var elt = this.elements[i];\n if (elt instanceof target) return true;\n if (isA(elt, set)) return false;\n }\n return false;\n};\n\nHTMLParser.ElementStack.prototype.inScope = function(tag) {\n return this.inSpecificScope(tag, inScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.elementInScope = function(e) {\n return this.elementInSpecificScope(e, inScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.elementTypeInScope = function(type) {\n return this.elementTypeInSpecificScope(type, inScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.inButtonScope = function(tag) {\n return this.inSpecificScope(tag, inButtonScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.inListItemScope = function(tag) {\n return this.inSpecificScope(tag, inListItemScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.inTableScope = function(tag) {\n return this.inSpecificScope(tag, inTableScopeSet);\n};\n\nHTMLParser.ElementStack.prototype.inSelectScope = function(tag) {\n // Can't implement this one with inSpecificScope, since it involves\n // a set defined by inverting another set. So implement manually.\n for(var i = this.elements.length-1; i >= 0; i--) {\n var elt = this.elements[i];\n if (elt.namespaceURI !== NAMESPACE.HTML) return false;\n var localname = elt.localName;\n if (localname === tag) return true;\n if (localname !== \"optgroup\" && localname !== \"option\")\n return false;\n }\n return false;\n};\n\nHTMLParser.ElementStack.prototype.generateImpliedEndTags = function(butnot, thorough) {\n var endTagSet = thorough ? thoroughImpliedEndTagsSet : impliedEndTagsSet;\n for(var i = this.elements.length-1; i >= 0; i--) {\n var e = this.elements[i];\n if (butnot && isA(e, butnot)) break;\n if (!isA(this.elements[i], endTagSet)) break;\n }\n\n this.elements.length = i+1;\n this.top = this.elements[i];\n};\n\n/***\n * The ActiveFormattingElements class\n */\nHTMLParser.ActiveFormattingElements = function AFE() {\n this.list = []; // elements\n this.attrs = []; // attribute tokens for cloning\n};\n\nHTMLParser.ActiveFormattingElements.prototype.MARKER = { localName: \"|\" };\n\n/*\n// For debugging\nHTMLParser.ActiveFormattingElements.prototype.toString = function() {\n return \"AFE: \" +\n this.list.map(function(e) { return e.localName; }).join(\"-\");\n}\n*/\n\nHTMLParser.ActiveFormattingElements.prototype.insertMarker = function() {\n this.list.push(this.MARKER);\n this.attrs.push(this.MARKER);\n};\n\nHTMLParser.ActiveFormattingElements.prototype.push = function(elt, attrs) {\n // Scan backwards: if there are already 3 copies of this element\n // before we encounter a marker, then drop the last one\n var count = 0;\n for(var i = this.list.length-1; i >= 0; i--) {\n if (this.list[i] === this.MARKER) break;\n // equal() is defined below\n if (equal(elt, this.list[i], this.attrs[i])) {\n count++;\n if (count === 3) {\n this.list.splice(i, 1);\n this.attrs.splice(i, 1);\n break;\n }\n }\n }\n\n\n // Now push the element onto the list\n this.list.push(elt);\n\n // Copy the attributes and push those on, too\n var attrcopy = [];\n for(var ii = 0; ii < attrs.length; ii++) {\n attrcopy[ii] = attrs[ii];\n }\n\n this.attrs.push(attrcopy);\n\n // This function defines equality of two elements for the purposes\n // of the AFE list. Note that it compares the new elements\n // attributes to the saved array of attributes associated with\n // the old element because a script could have changed the\n // old element's set of attributes\n function equal(newelt, oldelt, oldattrs) {\n if (newelt.localName !== oldelt.localName) return false;\n if (newelt._numattrs !== oldattrs.length) return false;\n for(var i = 0, n = oldattrs.length; i < n; i++) {\n var oldname = oldattrs[i][0];\n var oldval = oldattrs[i][1];\n if (!newelt.hasAttribute(oldname)) return false;\n if (newelt.getAttribute(oldname) !== oldval) return false;\n }\n return true;\n }\n};\n\nHTMLParser.ActiveFormattingElements.prototype.clearToMarker = function() {\n for(var i = this.list.length-1; i >= 0; i--) {\n if (this.list[i] === this.MARKER) break;\n }\n if (i < 0) i = 0;\n this.list.length = i;\n this.attrs.length = i;\n};\n\n// Find and return the last element with the specified tag between the\n// end of the list and the last marker on the list.\n// Used when parsing in_body_mode()\nHTMLParser.ActiveFormattingElements.prototype.findElementByTag = function(tag) {\n for(var i = this.list.length-1; i >= 0; i--) {\n var elt = this.list[i];\n if (elt === this.MARKER) break;\n if (elt.localName === tag) return elt;\n }\n return null;\n};\n\nHTMLParser.ActiveFormattingElements.prototype.indexOf = function(e) {\n return this.list.lastIndexOf(e);\n};\n\n// Find the element e in the list and remove it\n// Used when parsing in_body()\nHTMLParser.ActiveFormattingElements.prototype.remove = function(e) {\n var idx = this.list.lastIndexOf(e);\n if (idx !== -1) {\n this.list.splice(idx, 1);\n this.attrs.splice(idx, 1);\n }\n};\n\n// Find element a in the list and replace it with element b\n// XXX: Do I need to handle attributes here?\nHTMLParser.ActiveFormattingElements.prototype.replace = function(a, b, attrs) {\n var idx = this.list.lastIndexOf(a);\n if (idx !== -1) {\n this.list[idx] = b;\n this.attrs[idx] = attrs;\n }\n};\n\n// Find a in the list and insert b after it\n// This is only used for insert a bookmark object, so the\n// attrs array doesn't really matter\nHTMLParser.ActiveFormattingElements.prototype.insertAfter = function(a,b) {\n var idx = this.list.lastIndexOf(a);\n if (idx !== -1) {\n this.list.splice(idx, 0, b);\n this.attrs.splice(idx, 0, b);\n }\n};\n\n\n\n\n/***\n * This is the parser factory function. It is the return value of\n * the outer closure that it is defined within. Most of the parser\n * implementation details are inside this function.\n */\nfunction HTMLParser(address, fragmentContext, options) {\n /***\n * These are the parser's state variables\n */\n // Scanner state\n var chars = null;\n var numchars = 0; // Length of chars\n var nextchar = 0; // Index of next char\n var input_complete = false; // Becomes true when end() called.\n var scanner_skip_newline = false; // If previous char was CR\n var reentrant_invocations = 0;\n var saved_scanner_state = [];\n var leftovers = \"\";\n var first_batch = true;\n var paused = 0; // Becomes non-zero while loading scripts\n\n\n // Tokenizer state\n var tokenizer = data_state; // Current tokenizer state\n var return_state;\n var character_reference_code;\n var tagnamebuf = \"\";\n var lasttagname = \"\"; // holds the target end tag for text states\n var tempbuf = [];\n var attrnamebuf = \"\";\n var attrvaluebuf = \"\";\n var commentbuf = [];\n var doctypenamebuf = [];\n var doctypepublicbuf = [];\n var doctypesystembuf = [];\n var attributes = [];\n var is_end_tag = false;\n\n // Tree builder state\n var parser = initial_mode; // Current insertion mode\n var originalInsertionMode = null; // A saved insertion mode\n var templateInsertionModes = []; // Stack of template insertion modes.\n var stack = new HTMLParser.ElementStack(); // Stack of open elements\n var afe = new HTMLParser.ActiveFormattingElements(); // mis-nested tags\n var fragment = (fragmentContext!==undefined); // For innerHTML, etc.\n var head_element_pointer = null;\n var form_element_pointer = null;\n var scripting_enabled = true;\n if (fragmentContext) {\n\tscripting_enabled = fragmentContext.ownerDocument._scripting_enabled;\n }\n if (options && options.scripting_enabled === false)\n scripting_enabled = false;\n var frameset_ok = true;\n var force_quirks = false;\n var pending_table_text;\n var text_integration_mode; // XXX a spec bug workaround?\n\n // A single run of characters, buffered up to be sent to\n // the parser as a single string.\n var textrun = [];\n var textIncludesNUL = false;\n var ignore_linefeed = false;\n\n /***\n * This is the parser object that will be the return value of this\n * factory function, which is some 5000 lines below.\n * Note that the variable \"parser\" is the current state of the\n * parser's state machine. This variable \"htmlparser\" is the\n * return value and defines the public API of the parser\n */\n var htmlparser = {\n document: function() {\n return doc;\n },\n\n // Convenience function for internal use. Can only be called once,\n // as it removes the nodes from `doc` to add them to fragment.\n _asDocumentFragment: function() {\n var frag = doc.createDocumentFragment();\n var root = doc.firstChild;\n while(root.hasChildNodes()) {\n frag.appendChild(root.firstChild);\n }\n return frag;\n },\n\n // Internal function used from HTMLScriptElement to pause the\n // parser while a script is being loaded from the network\n pause: function() {\n // print(\"pausing parser\");\n paused++;\n },\n\n // Called when a script finishes loading\n resume: function() {\n // print(\"resuming parser\");\n paused--;\n // XXX: added this to force a resumption.\n // Is this the right thing to do?\n this.parse(\"\");\n },\n\n // Parse the HTML text s.\n // The second argument should be true if there is no more\n // text to be parsed, and should be false or omitted otherwise.\n // The second argument must not be set for recursive invocations\n // from document.write()\n parse: function(s, end, shouldPauseFunc) {\n var moreToDo;\n\n // If we're paused, remember the text to parse, but\n // don't parse it now.\n // (Don't invoke shouldPauseFunc because we haven't handled 'end' yet.)\n if (paused > 0) {\n leftovers += s;\n return true; // more to do\n }\n\n\n if (reentrant_invocations === 0) {\n // A normal, top-level invocation\n if (leftovers) {\n s = leftovers + s;\n leftovers = \"\";\n }\n\n // Add a special marker character to the end of\n // the buffer. If the scanner is at the end of\n // the buffer and input_complete is set, then this\n // character will transform into an EOF token.\n // Having an actual character that represents EOF\n // in the character buffer makes lookahead regexp\n // matching work more easily, and this is\n // important for character references.\n if (end) {\n s += \"\\uFFFF\";\n input_complete = true; // Makes scanChars() send EOF\n }\n\n chars = s;\n numchars = s.length;\n nextchar = 0;\n\n if (first_batch) {\n // We skip a leading Byte Order Mark (\\uFEFF)\n // on first batch of text we're given\n first_batch = false;\n if (chars.charCodeAt(0) === 0xFEFF) nextchar = 1;\n }\n\n reentrant_invocations++;\n moreToDo = scanChars(shouldPauseFunc);\n leftovers = chars.substring(nextchar, numchars);\n reentrant_invocations--;\n }\n else {\n // This is the re-entrant case, which we have to\n // handle a little differently.\n reentrant_invocations++;\n\n // Save current scanner state\n saved_scanner_state.push(chars, numchars, nextchar);\n\n // Set new scanner state\n chars = s;\n numchars = s.length;\n nextchar = 0;\n\n // Now scan as many of these new chars as we can\n scanChars();\n moreToDo = false;\n\n leftovers = chars.substring(nextchar, numchars);\n\n // restore old scanner state\n nextchar = saved_scanner_state.pop();\n numchars = saved_scanner_state.pop();\n chars = saved_scanner_state.pop();\n\n // If there were leftover chars from this invocation\n // insert them into the pending invocation's buffer\n // and trim already processed chars at the same time\n if (leftovers) {\n chars = leftovers + chars.substring(nextchar);\n numchars = chars.length;\n nextchar = 0;\n leftovers = \"\";\n }\n\n // Decrement the counter\n reentrant_invocations--;\n }\n return moreToDo;\n }\n };\n\n\n // This is the document we'll be building up\n var doc = new Document(true, address);\n\n // The document needs to know about the parser, for document.write().\n // This _parser property will be deleted when we're done parsing.\n doc._parser = htmlparser;\n\n // XXX I think that any document we use this parser on should support\n // scripts. But I may need to configure that through a parser parameter\n // Only documents with windows (\"browsing contexts\" to be precise)\n // allow scripting.\n doc._scripting_enabled = scripting_enabled;\n\n\n /***\n * The actual code of the HTMLParser() factory function begins here.\n */\n\n if (fragmentContext) { // for innerHTML parsing\n if (fragmentContext.ownerDocument._quirks)\n doc._quirks = true;\n if (fragmentContext.ownerDocument._limitedQuirks)\n doc._limitedQuirks = true;\n\n // Set the initial tokenizer state\n if (fragmentContext.namespaceURI === NAMESPACE.HTML) {\n switch(fragmentContext.localName) {\n case \"title\":\n case \"textarea\":\n tokenizer = rcdata_state;\n break;\n case \"style\":\n case \"xmp\":\n case \"iframe\":\n case \"noembed\":\n case \"noframes\":\n case \"script\":\n case \"plaintext\":\n tokenizer = plaintext_state;\n break;\n }\n }\n\n var root = doc.createElement(\"html\");\n doc._appendChild(root);\n stack.push(root);\n if (fragmentContext instanceof impl.HTMLTemplateElement) {\n templateInsertionModes.push(in_template_mode);\n }\n resetInsertionMode();\n\n for(var e = fragmentContext; e !== null; e = e.parentElement) {\n if (e instanceof impl.HTMLFormElement) {\n form_element_pointer = e;\n break;\n }\n }\n }\n\n /***\n * Scanner functions\n */\n // Loop through the characters in chars, and pass them one at a time\n // to the tokenizer FSM. Return when no more characters can be processed\n // (This may leave 1 or more characters in the buffer: like a CR\n // waiting to see if the next char is LF, or for states that require\n // lookahead...)\n function scanChars(shouldPauseFunc) {\n var codepoint, s, pattern, eof;\n\n while(nextchar < numchars) {\n\n // If we just tokenized a tag, then the paused flag\n // may have been set to tell us to stop tokenizing while\n // the script is loading\n if (paused > 0 || (shouldPauseFunc && shouldPauseFunc())) {\n return true;\n }\n\n\n switch(typeof tokenizer.lookahead) {\n case 'undefined':\n codepoint = chars.charCodeAt(nextchar++);\n if (scanner_skip_newline) {\n scanner_skip_newline = false;\n if (codepoint === 0x000A) {\n nextchar++;\n continue;\n }\n }\n switch(codepoint) {\n case 0x000D:\n // CR always turns into LF, but if the next character\n // is LF, then that second LF is skipped.\n if (nextchar < numchars) {\n if (chars.charCodeAt(nextchar) === 0x000A)\n nextchar++;\n }\n else {\n // We don't know the next char right now, so we\n // can't check if it is a LF. So set a flag\n scanner_skip_newline = true;\n }\n\n // In either case, emit a LF\n tokenizer(0x000A);\n\n break;\n case 0xFFFF:\n if (input_complete && nextchar === numchars) {\n tokenizer(EOF); // codepoint will be 0xFFFF here\n break;\n }\n /* falls through */\n default:\n tokenizer(codepoint);\n break;\n }\n break;\n\n case 'number':\n codepoint = chars.charCodeAt(nextchar);\n\n // The only tokenizer states that require fixed lookahead\n // only consume alphanum characters, so we don't have\n // to worry about CR and LF in this case\n\n // tokenizer wants n chars of lookahead\n var n = tokenizer.lookahead;\n var needsString = true;\n if (n < 0) {\n needsString = false;\n n = -n;\n }\n\n if (n < numchars - nextchar) {\n // If we can look ahead that far\n s = needsString ? chars.substring(nextchar, nextchar+n) : null;\n eof = false;\n }\n else { // if we don't have that many characters\n if (input_complete) { // If no more are coming\n // Just return what we have\n s = needsString ? chars.substring(nextchar, numchars) : null;\n eof = true;\n if (codepoint === 0xFFFF && nextchar === numchars-1)\n codepoint = EOF;\n }\n else {\n // Return now and wait for more chars later\n return true;\n }\n }\n tokenizer(codepoint, s, eof);\n break;\n case 'string':\n codepoint = chars.charCodeAt(nextchar);\n\n // tokenizer wants characters up to a matching string\n pattern = tokenizer.lookahead;\n var pos = chars.indexOf(pattern, nextchar);\n if (pos !== -1) {\n s = chars.substring(nextchar, pos + pattern.length);\n eof = false;\n }\n else { // No match\n // If more characters coming, wait for them\n if (!input_complete) return true;\n\n // Otherwise, we've got to return what we've got\n s = chars.substring(nextchar, numchars);\n if (codepoint === 0xFFFF && nextchar === numchars-1)\n codepoint = EOF;\n eof = true;\n }\n\n // The tokenizer states that require this kind of\n // lookahead have to be careful to handle CR characters\n // correctly\n tokenizer(codepoint, s, eof);\n break;\n }\n }\n return false; // no more characters to scan!\n }\n\n\n /***\n * Tokenizer utility functions\n */\n function addAttribute(name,value) {\n // Make sure there isn't already an attribute with this name\n // If there is, ignore this one.\n for(var i = 0; i < attributes.length; i++) {\n if (attributes[i][0] === name) return;\n }\n\n if (value !== undefined) {\n attributes.push([name, value]);\n }\n else {\n attributes.push([name]);\n }\n }\n\n // Shortcut for simple attributes\n function handleSimpleAttribute() {\n SIMPLEATTR.lastIndex = nextchar-1;\n var matched = SIMPLEATTR.exec(chars);\n if (!matched) throw new Error(\"should never happen\");\n var name = matched[1];\n if (!name) return false;\n var value = matched[2];\n var len = value.length;\n switch(value[0]) {\n case '\"':\n case \"'\":\n value = value.substring(1, len-1);\n nextchar += (matched[0].length-1);\n tokenizer = after_attribute_value_quoted_state;\n break;\n default:\n tokenizer = before_attribute_name_state;\n nextchar += (matched[0].length-1);\n value = value.substring(0, len-1);\n break;\n }\n\n // Make sure there isn't already an attribute with this name\n // If there is, ignore this one.\n for(var i = 0; i < attributes.length; i++) {\n if (attributes[i][0] === name) return true;\n }\n\n attributes.push([name, value]);\n return true;\n }\n\n function beginTagName() {\n is_end_tag = false;\n tagnamebuf = \"\";\n attributes.length = 0;\n }\n function beginEndTagName() {\n is_end_tag = true;\n tagnamebuf = \"\";\n attributes.length = 0;\n }\n\n function beginTempBuf() { tempbuf.length = 0; }\n function beginAttrName() { attrnamebuf = \"\"; }\n function beginAttrValue() { attrvaluebuf = \"\"; }\n function beginComment() { commentbuf.length = 0; }\n function beginDoctype() {\n doctypenamebuf.length = 0;\n doctypepublicbuf = null;\n doctypesystembuf = null;\n }\n function beginDoctypePublicId() { doctypepublicbuf = []; }\n function beginDoctypeSystemId() { doctypesystembuf = []; }\n function forcequirks() { force_quirks = true; }\n function cdataAllowed() {\n return stack.top &&\n stack.top.namespaceURI !== \"http://www.w3.org/1999/xhtml\";\n }\n\n // Return true if the codepoints in the specified buffer match the\n // characters of lasttagname\n function appropriateEndTag(buf) {\n return lasttagname === buf;\n }\n\n function flushText() {\n if (textrun.length > 0) {\n var s = buf2str(textrun);\n textrun.length = 0;\n\n if (ignore_linefeed) {\n ignore_linefeed = false;\n if (s[0] === \"\\n\") s = s.substring(1);\n if (s.length === 0) return;\n }\n\n insertToken(TEXT, s);\n textIncludesNUL = false;\n }\n ignore_linefeed = false;\n }\n\n // Consume chars matched by the pattern and return them as a string. Starts\n // matching at the current position, so users should drop the current char\n // otherwise.\n function getMatchingChars(pattern) {\n pattern.lastIndex = nextchar - 1;\n var match = pattern.exec(chars);\n if (match && match.index === nextchar - 1) {\n match = match[0];\n nextchar += match.length - 1;\n /* Careful! Make sure we haven't matched the EOF character! */\n if (input_complete && nextchar === numchars) {\n // Oops, backup one.\n match = match.slice(0, -1);\n nextchar--;\n }\n return match;\n } else {\n throw new Error(\"should never happen\");\n }\n }\n\n // emit a string of chars that match a regexp\n // Returns false if no chars matched.\n function emitCharsWhile(pattern) {\n pattern.lastIndex = nextchar-1;\n var match = pattern.exec(chars)[0];\n if (!match) return false;\n emitCharString(match);\n nextchar += match.length - 1;\n return true;\n }\n\n // This is used by CDATA sections\n function emitCharString(s) {\n if (textrun.length > 0) flushText();\n\n if (ignore_linefeed) {\n ignore_linefeed = false;\n if (s[0] === \"\\n\") s = s.substring(1);\n if (s.length === 0) return;\n }\n\n insertToken(TEXT, s);\n }\n\n function emitTag() {\n if (is_end_tag) insertToken(ENDTAG, tagnamebuf);\n else {\n // Remember the last open tag we emitted\n var tagname = tagnamebuf;\n tagnamebuf = \"\";\n lasttagname = tagname;\n insertToken(TAG, tagname, attributes);\n }\n }\n\n\n // A shortcut: look ahead and if this is a open or close tag\n // in lowercase with no spaces and no attributes, just emit it now.\n function emitSimpleTag() {\n if (nextchar === numchars) { return false; /* not even 1 char left */ }\n SIMPLETAG.lastIndex = nextchar;\n var matched = SIMPLETAG.exec(chars);\n if (!matched) throw new Error(\"should never happen\");\n var tagname = matched[2];\n if (!tagname) return false;\n var endtag = matched[1];\n if (endtag) {\n nextchar += (tagname.length+2);\n insertToken(ENDTAG, tagname);\n }\n else {\n nextchar += (tagname.length+1);\n lasttagname = tagname;\n insertToken(TAG, tagname, NOATTRS);\n }\n return true;\n }\n\n function emitSelfClosingTag() {\n if (is_end_tag) insertToken(ENDTAG, tagnamebuf, null, true);\n else {\n insertToken(TAG, tagnamebuf, attributes, true);\n }\n }\n\n function emitDoctype() {\n insertToken(DOCTYPE,\n buf2str(doctypenamebuf),\n doctypepublicbuf ? buf2str(doctypepublicbuf) : undefined,\n doctypesystembuf ? buf2str(doctypesystembuf) : undefined);\n }\n\n function emitEOF() {\n flushText();\n parser(EOF); // EOF never goes to insertForeignContent()\n doc.modclock = 1; // Start tracking modifications\n }\n\n // Insert a token, either using the current parser insertion mode\n // (for HTML stuff) or using the insertForeignToken() method.\n var insertToken = htmlparser.insertToken = function insertToken(t, value, arg3, arg4) {\n flushText();\n var current = stack.top;\n\n if (!current || current.namespaceURI === NAMESPACE.HTML) {\n // This is the common case\n parser(t, value, arg3, arg4);\n }\n else {\n // Otherwise we may need to insert this token as foreign content\n if (t !== TAG && t !== TEXT) {\n insertForeignToken(t, value, arg3, arg4);\n }\n else {\n // But in some cases we treat it as regular content\n if ((isMathmlTextIntegrationPoint(current) &&\n (t === TEXT ||\n (t === TAG &&\n value !== \"mglyph\" && value !== \"malignmark\"))) ||\n (t === TAG &&\n value === \"svg\" &&\n current.namespaceURI === NAMESPACE.MATHML &&\n current.localName === \"annotation-xml\") ||\n isHTMLIntegrationPoint(current)) {\n\n // XXX: the text_integration_mode stuff is an\n // attempted bug workaround of mine\n text_integration_mode = true;\n parser(t, value, arg3, arg4);\n text_integration_mode = false;\n }\n // Otherwise it is foreign content\n else {\n insertForeignToken(t, value, arg3, arg4);\n }\n }\n }\n };\n\n\n /***\n * Tree building utility functions\n */\n function insertComment(data) {\n var parent = stack.top;\n if (foster_parent_mode && isA(parent, tablesectionrowSet)) {\n fosterParent(function(doc) { return doc.createComment(data); });\n } else {\n // \"If the adjusted insertion location is inside a template element,\n // let it instead be inside the template element's template contents\"\n if (parent instanceof impl.HTMLTemplateElement) {\n parent = parent.content;\n }\n parent._appendChild(parent.ownerDocument.createComment(data));\n }\n }\n\n function insertText(s) {\n var parent = stack.top;\n if (foster_parent_mode && isA(parent, tablesectionrowSet)) {\n fosterParent(function(doc) { return doc.createTextNode(s); });\n } else {\n // \"If the adjusted insertion location is inside a template element,\n // let it instead be inside the template element's template contents\"\n if (parent instanceof impl.HTMLTemplateElement) {\n parent = parent.content;\n }\n // \"If there is a Text node immediately before the adjusted insertion\n // location, then append data to that Text node's data.\"\n var lastChild = parent.lastChild;\n if (lastChild && lastChild.nodeType === Node.TEXT_NODE) {\n lastChild.appendData(s);\n } else {\n parent._appendChild(parent.ownerDocument.createTextNode(s));\n }\n }\n }\n\n function createHTMLElt(doc, name, attrs) {\n // Create the element this way, rather than with\n // doc.createElement because createElement() does error\n // checking on the element name that we need to avoid here.\n var elt = html.createElement(doc, name, null);\n\n if (attrs) {\n for(var i = 0, n = attrs.length; i < n; i++) {\n // Use the _ version to avoid testing the validity\n // of the attribute name\n elt._setAttribute(attrs[i][0], attrs[i][1]);\n }\n }\n // XXX\n // If the element is a resettable form element,\n // run its reset algorithm now\n // XXX\n // handle case where form-element-pointer is not null\n return elt;\n }\n\n // The in_table insertion mode turns on this flag, and that makes\n // insertHTMLElement use the foster parenting algorithm for elements\n // tags inside a table\n var foster_parent_mode = false;\n\n function insertHTMLElement(name, attrs) {\n var elt = insertElement(function(doc) {\n return createHTMLElt(doc, name, attrs);\n });\n\n // XXX\n // If this is a form element, set its form attribute property here\n if (isA(elt, formassociatedSet)) {\n elt._form = form_element_pointer;\n }\n\n return elt;\n }\n\n // Insert the element into the open element or foster parent it\n function insertElement(eltFunc) {\n var elt;\n if (foster_parent_mode && isA(stack.top, tablesectionrowSet)) {\n elt = fosterParent(eltFunc);\n }\n else if (stack.top instanceof impl.HTMLTemplateElement) {\n // \"If the adjusted insertion location is inside a template element,\n // let it instead be inside the template element's template contents\"\n elt = eltFunc(stack.top.content.ownerDocument);\n stack.top.content._appendChild(elt);\n } else {\n elt = eltFunc(stack.top.ownerDocument);\n stack.top._appendChild(elt);\n }\n\n stack.push(elt);\n return elt;\n }\n\n function insertForeignElement(name, attrs, ns) {\n return insertElement(function(doc) {\n // We need to prevent createElementNS from trying to parse `name` as a\n // `qname`, so use an internal Document#_createElementNS() interface.\n var elt = doc._createElementNS(name, ns, null);\n if (attrs) {\n for(var i = 0, n = attrs.length; i < n; i++) {\n var attr = attrs[i];\n if (attr.length === 2)\n elt._setAttribute(attr[0], attr[1]);\n else {\n elt._setAttributeNS(attr[2], attr[0], attr[1]);\n }\n }\n }\n return elt;\n });\n }\n\n function lastElementOfType(type) {\n for(var i = stack.elements.length-1; i >= 0; i--) {\n if (stack.elements[i] instanceof type) {\n return i;\n }\n }\n return -1;\n }\n\n function fosterParent(eltFunc) {\n var parent, before, lastTable = -1, lastTemplate = -1, elt;\n\n lastTable = lastElementOfType(impl.HTMLTableElement);\n lastTemplate = lastElementOfType(impl.HTMLTemplateElement);\n\n if (lastTemplate >= 0 && (lastTable < 0 || lastTemplate > lastTable)) {\n parent = stack.elements[lastTemplate];\n } else if (lastTable >= 0) {\n parent = stack.elements[lastTable].parentNode;\n if (parent) {\n before = stack.elements[lastTable];\n } else {\n parent = stack.elements[lastTable - 1];\n }\n }\n if (!parent) parent = stack.elements[0]; // the `html` element.\n\n // \"If the adjusted insertion location is inside a template element,\n // let it instead be inside the template element's template contents\"\n if (parent instanceof impl.HTMLTemplateElement) {\n parent = parent.content;\n }\n // Create element in the appropriate document.\n elt = eltFunc(parent.ownerDocument);\n\n if (elt.nodeType === Node.TEXT_NODE) {\n var prev;\n if (before) prev = before.previousSibling;\n else prev = parent.lastChild;\n if (prev && prev.nodeType === Node.TEXT_NODE) {\n prev.appendData(elt.data);\n return elt;\n }\n }\n if (before)\n parent.insertBefore(elt, before);\n else\n parent._appendChild(elt);\n return elt;\n }\n\n\n function resetInsertionMode() {\n var last = false;\n for(var i = stack.elements.length-1; i >= 0; i--) {\n var node = stack.elements[i];\n if (i === 0) {\n last = true;\n if (fragment) {\n node = fragmentContext;\n }\n }\n if (node.namespaceURI === NAMESPACE.HTML) {\n var tag = node.localName;\n switch(tag) {\n case \"select\":\n for(var j = i; j > 0; ) {\n var ancestor = stack.elements[--j];\n if (ancestor instanceof impl.HTMLTemplateElement) {\n break;\n } else if (ancestor instanceof impl.HTMLTableElement) {\n parser = in_select_in_table_mode;\n return;\n }\n }\n parser = in_select_mode;\n return;\n case \"tr\":\n parser = in_row_mode;\n return;\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n parser = in_table_body_mode;\n return;\n case \"caption\":\n parser = in_caption_mode;\n return;\n case \"colgroup\":\n parser = in_column_group_mode;\n return;\n case \"table\":\n parser = in_table_mode;\n return;\n case \"template\":\n parser = templateInsertionModes[templateInsertionModes.length-1];\n return;\n case \"body\":\n parser = in_body_mode;\n return;\n case \"frameset\":\n parser = in_frameset_mode;\n return;\n case \"html\":\n if (head_element_pointer === null) {\n parser = before_head_mode;\n } else {\n parser = after_head_mode;\n }\n return;\n default:\n if (!last) {\n if (tag === \"head\") {\n parser = in_head_mode;\n return;\n }\n if (tag === \"td\" || tag === \"th\") {\n parser = in_cell_mode;\n return;\n }\n }\n }\n }\n if (last) {\n parser = in_body_mode;\n return;\n }\n }\n }\n\n\n function parseRawText(name, attrs) {\n insertHTMLElement(name, attrs);\n tokenizer = rawtext_state;\n originalInsertionMode = parser;\n parser = text_mode;\n }\n\n function parseRCDATA(name, attrs) {\n insertHTMLElement(name, attrs);\n tokenizer = rcdata_state;\n originalInsertionMode = parser;\n parser = text_mode;\n }\n\n // Make a copy of element i on the list of active formatting\n // elements, using its original attributes, not current\n // attributes (which may have been modified by a script)\n function afeclone(doc, i) {\n return {\n elt: createHTMLElt(doc, afe.list[i].localName, afe.attrs[i]),\n attrs: afe.attrs[i],\n };\n }\n\n\n function afereconstruct() {\n if (afe.list.length === 0) return;\n var entry = afe.list[afe.list.length-1];\n // If the last is a marker , do nothing\n if (entry === afe.MARKER) return;\n // Or if it is an open element, do nothing\n if (stack.elements.lastIndexOf(entry) !== -1) return;\n\n // Loop backward through the list until we find a marker or an\n // open element, and then move forward one from there.\n for(var i = afe.list.length-2; i >= 0; i--) {\n entry = afe.list[i];\n if (entry === afe.MARKER) break;\n if (stack.elements.lastIndexOf(entry) !== -1) break;\n }\n\n // Now loop forward, starting from the element after the current\n // one, recreating formatting elements and pushing them back onto\n // the list of open elements\n for(i = i+1; i < afe.list.length; i++) {\n var newelt = insertElement(function(doc) { return afeclone(doc, i).elt; });\n afe.list[i] = newelt;\n }\n }\n\n // Used by the adoptionAgency() function\n var BOOKMARK = {localName:\"BM\"};\n\n function adoptionAgency(tag) {\n // If the current node is an HTML element whose tag name is subject,\n // and the current node is not in the list of active formatting\n // elements, then pop the current node off the stack of open\n // elements and abort these steps.\n if (isA(stack.top, tag) && afe.indexOf(stack.top) === -1) {\n stack.pop();\n return true; // no more handling required\n }\n\n // Let outer loop counter be zero.\n var outer = 0;\n\n // Outer loop: If outer loop counter is greater than or\n // equal to eight, then abort these steps.\n while(outer < 8) {\n // Increment outer loop counter by one.\n outer++;\n\n // Let the formatting element be the last element in the list\n // of active formatting elements that: is between the end of\n // the list and the last scope marker in the list, if any, or\n // the start of the list otherwise, and has the same tag name\n // as the token.\n var fmtelt = afe.findElementByTag(tag);\n\n // If there is no such node, then abort these steps and instead\n // act as described in the \"any other end tag\" entry below.\n if (!fmtelt) {\n return false; // false means handle by the default case\n }\n\n // Otherwise, if there is such a node, but that node is not in\n // the stack of open elements, then this is a parse error;\n // remove the element from the list, and abort these steps.\n var index = stack.elements.lastIndexOf(fmtelt);\n if (index === -1) {\n afe.remove(fmtelt);\n return true; // true means no more handling required\n }\n\n // Otherwise, if there is such a node, and that node is also in\n // the stack of open elements, but the element is not in scope,\n // then this is a parse error; ignore the token, and abort\n // these steps.\n if (!stack.elementInScope(fmtelt)) {\n return true;\n }\n\n // Let the furthest block be the topmost node in the stack of\n // open elements that is lower in the stack than the formatting\n // element, and is an element in the special category. There\n // might not be one.\n var furthestblock = null, furthestblockindex;\n for(var i = index+1; i < stack.elements.length; i++) {\n if (isA(stack.elements[i], specialSet)) {\n furthestblock = stack.elements[i];\n furthestblockindex = i;\n break;\n }\n }\n\n // If there is no furthest block, then the UA must skip the\n // subsequent steps and instead just pop all the nodes from the\n // bottom of the stack of open elements, from the current node\n // up to and including the formatting element, and remove the\n // formatting element from the list of active formatting\n // elements.\n if (!furthestblock) {\n stack.popElement(fmtelt);\n afe.remove(fmtelt);\n return true;\n }\n else {\n // Let the common ancestor be the element immediately above\n // the formatting element in the stack of open elements.\n var ancestor = stack.elements[index-1];\n\n // Let a bookmark note the position of the formatting\n // element in the list of active formatting elements\n // relative to the elements on either side of it in the\n // list.\n afe.insertAfter(fmtelt, BOOKMARK);\n\n // Let node and last node be the furthest block.\n var node = furthestblock;\n var lastnode = furthestblock;\n var nodeindex = furthestblockindex;\n var nodeafeindex;\n\n // Let inner loop counter be zero.\n var inner = 0;\n\n while (true) {\n\n // Increment inner loop counter by one.\n inner++;\n\n // Let node be the element immediately above node in\n // the stack of open elements, or if node is no longer\n // in the stack of open elements (e.g. because it got\n // removed by this algorithm), the element that was\n // immediately above node in the stack of open elements\n // before node was removed.\n node = stack.elements[--nodeindex];\n\n // If node is the formatting element, then go\n // to the next step in the overall algorithm.\n if (node === fmtelt) break;\n\n // If the inner loop counter is greater than three and node\n // is in the list of active formatting elements, then remove\n // node from the list of active formatting elements.\n nodeafeindex = afe.indexOf(node);\n if (inner > 3 && nodeafeindex !== -1) {\n afe.remove(node);\n nodeafeindex = -1;\n }\n\n // If node is not in the list of active formatting\n // elements, then remove node from the stack of open\n // elements and then go back to the step labeled inner\n // loop.\n if (nodeafeindex === -1) {\n stack.removeElement(node);\n continue;\n }\n\n // Create an element for the token for which the\n // element node was created with common ancestor as\n // the intended parent, replace the entry for node\n // in the list of active formatting elements with an\n // entry for the new element, replace the entry for\n // node in the stack of open elements with an entry for\n // the new element, and let node be the new element.\n var newelt = afeclone(ancestor.ownerDocument, nodeafeindex);\n afe.replace(node, newelt.elt, newelt.attrs);\n stack.elements[nodeindex] = newelt.elt;\n node = newelt.elt;\n\n // If last node is the furthest block, then move the\n // aforementioned bookmark to be immediately after the\n // new node in the list of active formatting elements.\n if (lastnode === furthestblock) {\n afe.remove(BOOKMARK);\n afe.insertAfter(newelt.elt, BOOKMARK);\n }\n\n // Insert last node into node, first removing it from\n // its previous parent node if any.\n node._appendChild(lastnode);\n\n // Let last node be node.\n lastnode = node;\n }\n\n // If the common ancestor node is a table, tbody, tfoot,\n // thead, or tr element, then, foster parent whatever last\n // node ended up being in the previous step, first removing\n // it from its previous parent node if any.\n if (foster_parent_mode && isA(ancestor, tablesectionrowSet)) {\n fosterParent(function() { return lastnode; });\n }\n // Otherwise, append whatever last node ended up being in\n // the previous step to the common ancestor node, first\n // removing it from its previous parent node if any.\n else if (ancestor instanceof impl.HTMLTemplateElement) {\n ancestor.content._appendChild(lastnode);\n } else {\n ancestor._appendChild(lastnode);\n }\n\n // Create an element for the token for which the\n // formatting element was created, with furthest block\n // as the intended parent.\n var newelt2 = afeclone(furthestblock.ownerDocument, afe.indexOf(fmtelt));\n\n // Take all of the child nodes of the furthest block and\n // append them to the element created in the last step.\n while(furthestblock.hasChildNodes()) {\n newelt2.elt._appendChild(furthestblock.firstChild);\n }\n\n // Append that new element to the furthest block.\n furthestblock._appendChild(newelt2.elt);\n\n // Remove the formatting element from the list of active\n // formatting elements, and insert the new element into the\n // list of active formatting elements at the position of\n // the aforementioned bookmark.\n afe.remove(fmtelt);\n afe.replace(BOOKMARK, newelt2.elt, newelt2.attrs);\n\n // Remove the formatting element from the stack of open\n // elements, and insert the new element into the stack of\n // open elements immediately below the position of the\n // furthest block in that stack.\n stack.removeElement(fmtelt);\n var pos = stack.elements.lastIndexOf(furthestblock);\n stack.elements.splice(pos+1, 0, newelt2.elt);\n }\n }\n\n return true;\n }\n\n // We do this when we get /script in in_text_mode\n function handleScriptEnd() {\n // XXX:\n // This is just a stub implementation right now and doesn't run scripts.\n // Getting this method right involves the event loop, URL resolution\n // script fetching etc. For now I just want to be able to parse\n // documents and test the parser.\n\n //var script = stack.top;\n stack.pop();\n parser = originalInsertionMode;\n //script._prepare();\n return;\n\n // XXX: here is what this method is supposed to do\n\n // Provide a stable state.\n\n // Let script be the current node (which will be a script\n // element).\n\n // Pop the current node off the stack of open elements.\n\n // Switch the insertion mode to the original insertion mode.\n\n // Let the old insertion point have the same value as the current\n // insertion point. Let the insertion point be just before the\n // next input character.\n\n // Increment the parser's script nesting level by one.\n\n // Prepare the script. This might cause some script to execute,\n // which might cause new characters to be inserted into the\n // tokenizer, and might cause the tokenizer to output more tokens,\n // resulting in a reentrant invocation of the parser.\n\n // Decrement the parser's script nesting level by one. If the\n // parser's script nesting level is zero, then set the parser\n // pause flag to false.\n\n // Let the insertion point have the value of the old insertion\n // point. (In other words, restore the insertion point to its\n // previous value. This value might be the \"undefined\" value.)\n\n // At this stage, if there is a pending parsing-blocking script,\n // then:\n\n // If the script nesting level is not zero:\n\n // Set the parser pause flag to true, and abort the processing\n // of any nested invocations of the tokenizer, yielding\n // control back to the caller. (Tokenization will resume when\n // the caller returns to the \"outer\" tree construction stage.)\n\n // The tree construction stage of this particular parser is\n // being called reentrantly, say from a call to\n // document.write().\n\n // Otherwise:\n\n // Run these steps:\n\n // Let the script be the pending parsing-blocking\n // script. There is no longer a pending\n // parsing-blocking script.\n\n // Block the tokenizer for this instance of the HTML\n // parser, such that the event loop will not run tasks\n // that invoke the tokenizer.\n\n // If the parser's Document has a style sheet that is\n // blocking scripts or the script's \"ready to be\n // parser-executed\" flag is not set: spin the event\n // loop until the parser's Document has no style sheet\n // that is blocking scripts and the script's \"ready to\n // be parser-executed\" flag is set.\n\n // Unblock the tokenizer for this instance of the HTML\n // parser, such that tasks that invoke the tokenizer\n // can again be run.\n\n // Let the insertion point be just before the next\n // input character.\n\n // Increment the parser's script nesting level by one\n // (it should be zero before this step, so this sets\n // it to one).\n\n // Execute the script.\n\n // Decrement the parser's script nesting level by\n // one. If the parser's script nesting level is zero\n // (which it always should be at this point), then set\n // the parser pause flag to false.\n\n // Let the insertion point be undefined again.\n\n // If there is once again a pending parsing-blocking\n // script, then repeat these steps from step 1.\n\n\n }\n\n function stopParsing() {\n // XXX This is just a temporary implementation to get the parser working.\n // A full implementation involves scripts and events and the event loop.\n\n // Remove the link from document to parser.\n // This is instead of \"set the insertion point to undefined\".\n // It means that document.write() can't write into the doc anymore.\n delete doc._parser;\n\n stack.elements.length = 0; // pop everything off\n\n // If there is a window object associated with the document\n // then trigger an load event on it\n if (doc.defaultView) {\n doc.defaultView.dispatchEvent(new impl.Event(\"load\",{}));\n }\n\n }\n\n /****\n * Tokenizer states\n */\n\n /**\n * This file was partially mechanically generated from\n * http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html\n *\n * After mechanical conversion, it was further converted from\n * prose to JS by hand, but the intent is that it is a very\n * faithful rendering of the HTML tokenization spec in\n * JavaScript.\n *\n * It is not a goal of this tokenizer to detect or report\n * parse errors.\n *\n * XXX The tokenizer is supposed to work with straight UTF32\n * codepoints. But I don't think it has any dependencies on\n * any character outside of the BMP so I think it is safe to\n * pass it UTF16 characters. I don't think it will ever change\n * state in the middle of a surrogate pair.\n */\n\n /*\n * Each state is represented by a function. For most states, the\n * scanner simply passes the next character (as an integer\n * codepoint) to the current state function and automatically\n * consumes the character. If the state function can't process\n * the character it can call pushback() to push it back to the\n * scanner.\n *\n * Some states require lookahead, though. If a state function has\n * a lookahead property, then it is invoked differently. In this\n * case, the scanner invokes the function with 3 arguments: 1) the\n * next codepoint 2) a string of lookahead text 3) a boolean that\n * is true if the lookahead goes all the way to the EOF. (XXX\n * actually maybe this third is not necessary... the lookahead\n * could just include \\uFFFF?)\n *\n * If the lookahead property of a state function is an integer, it\n * specifies the number of characters required. If it is a string,\n * then the scanner will scan for that string and return all\n * characters up to and including that sequence, or up to EOF. If\n * the lookahead property is a regexp, then the scanner will match\n * the regexp at the current point and return the matching string.\n *\n * States that require lookahead are responsible for explicitly\n * consuming the characters they process. They do this by\n * incrementing nextchar by the number of processed characters.\n */\n function reconsume(c, new_state) {\n tokenizer = new_state;\n nextchar--; // pushback\n }\n\n function data_state(c) {\n switch(c) {\n case 0x0026: // AMPERSAND\n return_state = data_state;\n tokenizer = character_reference_state;\n break;\n case 0x003C: // LESS-THAN SIGN\n if (emitSimpleTag()) // Shortcut for

    ,

    , etc.\n break;\n tokenizer = tag_open_state;\n break;\n case 0x0000: // NULL\n // Usually null characters emitted by the tokenizer will be\n // ignored by the tree builder, but sometimes they'll be\n // converted to \\uFFFD. I don't want to have the search every\n // string emitted to replace NULs, so I'll set a flag\n // if I've emitted a NUL.\n textrun.push(c);\n textIncludesNUL = true;\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n // Instead of just pushing a single character and then\n // coming back to the very same place, lookahead and\n // emit everything we can at once.\n /*jshint -W030 */\n emitCharsWhile(DATATEXT) || textrun.push(c);\n break;\n }\n }\n\n function rcdata_state(c) {\n // Save the open tag so we can find a matching close tag\n switch(c) {\n case 0x0026: // AMPERSAND\n return_state = rcdata_state;\n tokenizer = character_reference_state;\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = rcdata_less_than_sign_state;\n break;\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n textIncludesNUL = true;\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n textrun.push(c);\n break;\n }\n }\n\n function rawtext_state(c) {\n switch(c) {\n case 0x003C: // LESS-THAN SIGN\n tokenizer = rawtext_less_than_sign_state;\n break;\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n /*jshint -W030 */\n emitCharsWhile(RAWTEXT) || textrun.push(c);\n break;\n }\n }\n\n function script_data_state(c) {\n switch(c) {\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_less_than_sign_state;\n break;\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n /*jshint -W030 */\n emitCharsWhile(RAWTEXT) || textrun.push(c);\n break;\n }\n }\n\n function plaintext_state(c) {\n switch(c) {\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n /*jshint -W030 */\n emitCharsWhile(PLAINTEXT) || textrun.push(c);\n break;\n }\n }\n\n function tag_open_state(c) {\n switch(c) {\n case 0x0021: // EXCLAMATION MARK\n tokenizer = markup_declaration_open_state;\n break;\n case 0x002F: // SOLIDUS\n tokenizer = end_tag_open_state;\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginTagName();\n reconsume(c, tag_name_state);\n break;\n case 0x003F: // QUESTION MARK\n reconsume(c, bogus_comment_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, data_state);\n break;\n }\n }\n\n function end_tag_open_state(c) {\n switch(c) {\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginEndTagName();\n reconsume(c, tag_name_state);\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n break;\n case -1: // EOF\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n emitEOF();\n break;\n default:\n reconsume(c, bogus_comment_state);\n break;\n }\n }\n\n function tag_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = before_attribute_name_state;\n break;\n case 0x002F: // SOLIDUS\n tokenizer = self_closing_start_tag_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitTag();\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n tagnamebuf += String.fromCharCode(c + 0x0020);\n break;\n case 0x0000: // NULL\n tagnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n tagnamebuf += getMatchingChars(TAGNAME);\n break;\n }\n }\n\n function rcdata_less_than_sign_state(c) {\n /* identical to the RAWTEXT less-than sign state, except s/RAWTEXT/RCDATA/g */\n if (c === 0x002F) { // SOLIDUS\n beginTempBuf();\n tokenizer = rcdata_end_tag_open_state;\n }\n else {\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, rcdata_state);\n }\n }\n\n function rcdata_end_tag_open_state(c) {\n /* identical to the RAWTEXT (and Script data) end tag open state, except s/RAWTEXT/RCDATA/g */\n switch(c) {\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginEndTagName();\n reconsume(c, rcdata_end_tag_name_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n reconsume(c, rcdata_state);\n break;\n }\n }\n\n function rcdata_end_tag_name_state(c) {\n /* identical to the RAWTEXT (and Script data) end tag name state, except s/RAWTEXT/RCDATA/g */\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = before_attribute_name_state;\n return;\n }\n break;\n case 0x002F: // SOLIDUS\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = self_closing_start_tag_state;\n return;\n }\n break;\n case 0x003E: // GREATER-THAN SIGN\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = data_state;\n emitTag();\n return;\n }\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n\n tagnamebuf += String.fromCharCode(c + 0x0020);\n tempbuf.push(c);\n return;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n\n tagnamebuf += String.fromCharCode(c);\n tempbuf.push(c);\n return;\n default:\n break;\n }\n\n // If we don't return in one of the cases above, then this was not\n // an appropriately matching close tag, so back out by emitting all\n // the characters as text\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n pushAll(textrun, tempbuf);\n reconsume(c, rcdata_state);\n }\n\n function rawtext_less_than_sign_state(c) {\n /* identical to the RCDATA less-than sign state, except s/RCDATA/RAWTEXT/g\n */\n if (c === 0x002F) { // SOLIDUS\n beginTempBuf();\n tokenizer = rawtext_end_tag_open_state;\n }\n else {\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, rawtext_state);\n }\n }\n\n function rawtext_end_tag_open_state(c) {\n /* identical to the RCDATA (and Script data) end tag open state, except s/RCDATA/RAWTEXT/g */\n switch(c) {\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginEndTagName();\n reconsume(c, rawtext_end_tag_name_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n reconsume(c, rawtext_state);\n break;\n }\n }\n\n function rawtext_end_tag_name_state(c) {\n /* identical to the RCDATA (and Script data) end tag name state, except s/RCDATA/RAWTEXT/g */\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = before_attribute_name_state;\n return;\n }\n break;\n case 0x002F: // SOLIDUS\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = self_closing_start_tag_state;\n return;\n }\n break;\n case 0x003E: // GREATER-THAN SIGN\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = data_state;\n emitTag();\n return;\n }\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n tagnamebuf += String.fromCharCode(c + 0x0020);\n tempbuf.push(c);\n return;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n tagnamebuf += String.fromCharCode(c);\n tempbuf.push(c);\n return;\n default:\n break;\n }\n\n // If we don't return in one of the cases above, then this was not\n // an appropriately matching close tag, so back out by emitting all\n // the characters as text\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n pushAll(textrun,tempbuf);\n reconsume(c, rawtext_state);\n }\n\n function script_data_less_than_sign_state(c) {\n switch(c) {\n case 0x002F: // SOLIDUS\n beginTempBuf();\n tokenizer = script_data_end_tag_open_state;\n break;\n case 0x0021: // EXCLAMATION MARK\n tokenizer = script_data_escape_start_state;\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x0021); // EXCLAMATION MARK\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, script_data_state);\n break;\n }\n }\n\n function script_data_end_tag_open_state(c) {\n /* identical to the RCDATA (and RAWTEXT) end tag open state, except s/RCDATA/Script data/g */\n switch(c) {\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginEndTagName();\n reconsume(c, script_data_end_tag_name_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n reconsume(c, script_data_state);\n break;\n }\n }\n\n function script_data_end_tag_name_state(c) {\n /* identical to the RCDATA (and RAWTEXT) end tag name state, except s/RCDATA/Script data/g */\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = before_attribute_name_state;\n return;\n }\n break;\n case 0x002F: // SOLIDUS\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = self_closing_start_tag_state;\n return;\n }\n break;\n case 0x003E: // GREATER-THAN SIGN\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = data_state;\n emitTag();\n return;\n }\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n\n tagnamebuf += String.fromCharCode(c + 0x0020);\n tempbuf.push(c);\n return;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n\n tagnamebuf += String.fromCharCode(c);\n tempbuf.push(c);\n return;\n default:\n break;\n }\n\n // If we don't return in one of the cases above, then this was not\n // an appropriately matching close tag, so back out by emitting all\n // the characters as text\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n pushAll(textrun,tempbuf);\n reconsume(c, script_data_state);\n }\n\n function script_data_escape_start_state(c) {\n if (c === 0x002D) { // HYPHEN-MINUS\n tokenizer = script_data_escape_start_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n }\n else {\n reconsume(c, script_data_state);\n }\n }\n\n function script_data_escape_start_dash_state(c) {\n if (c === 0x002D) { // HYPHEN-MINUS\n tokenizer = script_data_escaped_dash_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n }\n else {\n reconsume(c, script_data_state);\n }\n }\n\n function script_data_escaped_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = script_data_escaped_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_escaped_less_than_sign_state;\n break;\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n textrun.push(c);\n break;\n }\n }\n\n function script_data_escaped_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = script_data_escaped_dash_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_escaped_less_than_sign_state;\n break;\n case 0x0000: // NULL\n tokenizer = script_data_escaped_state;\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n tokenizer = script_data_escaped_state;\n textrun.push(c);\n break;\n }\n }\n\n function script_data_escaped_dash_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_escaped_less_than_sign_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = script_data_state;\n textrun.push(0x003E); // GREATER-THAN SIGN\n break;\n case 0x0000: // NULL\n tokenizer = script_data_escaped_state;\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n tokenizer = script_data_escaped_state;\n textrun.push(c);\n break;\n }\n }\n\n function script_data_escaped_less_than_sign_state(c) {\n switch(c) {\n case 0x002F: // SOLIDUS\n beginTempBuf();\n tokenizer = script_data_escaped_end_tag_open_state;\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginTempBuf();\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, script_data_double_escape_start_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n reconsume(c, script_data_escaped_state);\n break;\n }\n }\n\n function script_data_escaped_end_tag_open_state(c) {\n switch(c) {\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n beginEndTagName();\n reconsume(c, script_data_escaped_end_tag_name_state);\n break;\n default:\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n reconsume(c, script_data_escaped_state);\n break;\n }\n }\n\n function script_data_escaped_end_tag_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = before_attribute_name_state;\n return;\n }\n break;\n case 0x002F: // SOLIDUS\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = self_closing_start_tag_state;\n return;\n }\n break;\n case 0x003E: // GREATER-THAN SIGN\n if (appropriateEndTag(tagnamebuf)) {\n tokenizer = data_state;\n emitTag();\n return;\n }\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n tagnamebuf += String.fromCharCode(c + 0x0020);\n tempbuf.push(c);\n return;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n tagnamebuf += String.fromCharCode(c);\n tempbuf.push(c);\n return;\n default:\n break;\n }\n\n // We get here in the default case, and if the closing tagname\n // is not an appropriate tagname.\n textrun.push(0x003C); // LESS-THAN SIGN\n textrun.push(0x002F); // SOLIDUS\n pushAll(textrun,tempbuf);\n reconsume(c, script_data_escaped_state);\n }\n\n function script_data_double_escape_start_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n case 0x002F: // SOLIDUS\n case 0x003E: // GREATER-THAN SIGN\n if (buf2str(tempbuf) === \"script\") {\n tokenizer = script_data_double_escaped_state;\n }\n else {\n tokenizer = script_data_escaped_state;\n }\n textrun.push(c);\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n tempbuf.push(c + 0x0020);\n textrun.push(c);\n break;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n tempbuf.push(c);\n textrun.push(c);\n break;\n default:\n reconsume(c, script_data_escaped_state);\n break;\n }\n }\n\n function script_data_double_escaped_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = script_data_double_escaped_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_double_escaped_less_than_sign_state;\n textrun.push(0x003C); // LESS-THAN SIGN\n break;\n case 0x0000: // NULL\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n textrun.push(c);\n break;\n }\n }\n\n function script_data_double_escaped_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = script_data_double_escaped_dash_dash_state;\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_double_escaped_less_than_sign_state;\n textrun.push(0x003C); // LESS-THAN SIGN\n break;\n case 0x0000: // NULL\n tokenizer = script_data_double_escaped_state;\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n tokenizer = script_data_double_escaped_state;\n textrun.push(c);\n break;\n }\n }\n\n function script_data_double_escaped_dash_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n textrun.push(0x002D); // HYPHEN-MINUS\n break;\n case 0x003C: // LESS-THAN SIGN\n tokenizer = script_data_double_escaped_less_than_sign_state;\n textrun.push(0x003C); // LESS-THAN SIGN\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = script_data_state;\n textrun.push(0x003E); // GREATER-THAN SIGN\n break;\n case 0x0000: // NULL\n tokenizer = script_data_double_escaped_state;\n textrun.push(0xFFFD); // REPLACEMENT CHARACTER\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n tokenizer = script_data_double_escaped_state;\n textrun.push(c);\n break;\n }\n }\n\n function script_data_double_escaped_less_than_sign_state(c) {\n if (c === 0x002F) { // SOLIDUS\n beginTempBuf();\n tokenizer = script_data_double_escape_end_state;\n textrun.push(0x002F); // SOLIDUS\n }\n else {\n reconsume(c, script_data_double_escaped_state);\n }\n }\n\n function script_data_double_escape_end_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n case 0x002F: // SOLIDUS\n case 0x003E: // GREATER-THAN SIGN\n if (buf2str(tempbuf) === \"script\") {\n tokenizer = script_data_escaped_state;\n }\n else {\n tokenizer = script_data_double_escaped_state;\n }\n textrun.push(c);\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n tempbuf.push(c + 0x0020);\n textrun.push(c);\n break;\n case 0x0061: // [a-z]\n case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:\n case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:\n case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:\n case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:\n case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:\n tempbuf.push(c);\n textrun.push(c);\n break;\n default:\n reconsume(c, script_data_double_escaped_state);\n break;\n }\n }\n\n function before_attribute_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n // For SOLIDUS, GREATER-THAN SIGN, and EOF, spec says \"reconsume in\n // the after attribute name state\", but in our implementation that\n // state always has an active attribute in attrnamebuf. Just clone\n // the rules here, without the addAttribute business.\n case 0x002F: // SOLIDUS\n tokenizer = self_closing_start_tag_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitTag();\n break;\n case -1: // EOF\n emitEOF();\n break;\n case 0x003D: // EQUALS SIGN\n beginAttrName();\n attrnamebuf += String.fromCharCode(c);\n tokenizer = attribute_name_state;\n break;\n default:\n if (handleSimpleAttribute()) break;\n beginAttrName();\n reconsume(c, attribute_name_state);\n break;\n }\n }\n\n // beginAttrName() must have been called before this point\n // There is an active attribute in attrnamebuf (but not attrvaluebuf)\n function attribute_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n case 0x002F: // SOLIDUS\n case 0x003E: // GREATER-THAN SIGN\n case -1: // EOF\n reconsume(c, after_attribute_name_state);\n break;\n case 0x003D: // EQUALS SIGN\n tokenizer = before_attribute_value_state;\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n attrnamebuf += String.fromCharCode(c + 0x0020);\n break;\n case 0x0000: // NULL\n attrnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case 0x0022: // QUOTATION MARK\n case 0x0027: // APOSTROPHE\n case 0x003C: // LESS-THAN SIGN\n /* falls through */\n default:\n attrnamebuf += getMatchingChars(ATTRNAME);\n break;\n }\n }\n\n // There is an active attribute in attrnamebuf, but not yet in attrvaluebuf.\n function after_attribute_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n case 0x002F: // SOLIDUS\n // Keep in sync with before_attribute_name_state.\n addAttribute(attrnamebuf);\n tokenizer = self_closing_start_tag_state;\n break;\n case 0x003D: // EQUALS SIGN\n tokenizer = before_attribute_value_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n // Keep in sync with before_attribute_name_state.\n tokenizer = data_state;\n addAttribute(attrnamebuf);\n emitTag();\n break;\n case -1: // EOF\n // Keep in sync with before_attribute_name_state.\n addAttribute(attrnamebuf);\n emitEOF();\n break;\n default:\n addAttribute(attrnamebuf);\n beginAttrName();\n reconsume(c, attribute_name_state);\n break;\n }\n }\n\n function before_attribute_value_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n case 0x0022: // QUOTATION MARK\n beginAttrValue();\n tokenizer = attribute_value_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginAttrValue();\n tokenizer = attribute_value_single_quoted_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n /* falls through */\n default:\n beginAttrValue();\n reconsume(c, attribute_value_unquoted_state);\n break;\n }\n }\n\n function attribute_value_double_quoted_state(c) {\n switch(c) {\n case 0x0022: // QUOTATION MARK\n addAttribute(attrnamebuf, attrvaluebuf);\n tokenizer = after_attribute_value_quoted_state;\n break;\n case 0x0026: // AMPERSAND\n return_state = attribute_value_double_quoted_state;\n tokenizer = character_reference_state;\n break;\n case 0x0000: // NULL\n attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n emitEOF();\n break;\n case 0x000A: // LF\n // this could be a converted \\r, so don't use getMatchingChars\n attrvaluebuf += String.fromCharCode(c);\n break;\n default:\n attrvaluebuf += getMatchingChars(DBLQUOTEATTRVAL);\n break;\n }\n }\n\n function attribute_value_single_quoted_state(c) {\n switch(c) {\n case 0x0027: // APOSTROPHE\n addAttribute(attrnamebuf, attrvaluebuf);\n tokenizer = after_attribute_value_quoted_state;\n break;\n case 0x0026: // AMPERSAND\n return_state = attribute_value_single_quoted_state;\n tokenizer = character_reference_state;\n break;\n case 0x0000: // NULL\n attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n emitEOF();\n break;\n case 0x000A: // LF\n // this could be a converted \\r, so don't use getMatchingChars\n attrvaluebuf += String.fromCharCode(c);\n break;\n default:\n attrvaluebuf += getMatchingChars(SINGLEQUOTEATTRVAL);\n break;\n }\n }\n\n function attribute_value_unquoted_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n addAttribute(attrnamebuf, attrvaluebuf);\n tokenizer = before_attribute_name_state;\n break;\n case 0x0026: // AMPERSAND\n return_state = attribute_value_unquoted_state;\n tokenizer = character_reference_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n addAttribute(attrnamebuf, attrvaluebuf);\n tokenizer = data_state;\n emitTag();\n break;\n case 0x0000: // NULL\n attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n nextchar--; // pushback\n tokenizer = data_state;\n break;\n case 0x0022: // QUOTATION MARK\n case 0x0027: // APOSTROPHE\n case 0x003C: // LESS-THAN SIGN\n case 0x003D: // EQUALS SIGN\n case 0x0060: // GRAVE ACCENT\n /* falls through */\n default:\n attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);\n break;\n }\n }\n\n function after_attribute_value_quoted_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = before_attribute_name_state;\n break;\n case 0x002F: // SOLIDUS\n tokenizer = self_closing_start_tag_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitTag();\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n reconsume(c, before_attribute_name_state);\n break;\n }\n }\n\n function self_closing_start_tag_state(c) {\n switch(c) {\n case 0x003E: // GREATER-THAN SIGN\n // Set the self-closing flag of the current tag token.\n tokenizer = data_state;\n emitSelfClosingTag(true);\n break;\n case -1: // EOF\n emitEOF();\n break;\n default:\n reconsume(c, before_attribute_name_state);\n break;\n }\n }\n\n function bogus_comment_state(c, lookahead, eof) {\n var len = lookahead.length;\n\n if (eof) {\n nextchar += len-1; // don't consume the eof\n }\n else {\n nextchar += len;\n }\n\n var comment = lookahead.substring(0, len-1);\n\n comment = comment.replace(/\\u0000/g,\"\\uFFFD\");\n comment = comment.replace(/\\u000D\\u000A/g,\"\\u000A\");\n comment = comment.replace(/\\u000D/g,\"\\u000A\");\n\n insertToken(COMMENT, comment);\n tokenizer = data_state;\n }\n bogus_comment_state.lookahead = \">\";\n\n function markup_declaration_open_state(c, lookahead, eof) {\n if (lookahead[0] === \"-\" && lookahead[1] === \"-\") {\n nextchar += 2;\n beginComment();\n tokenizer = comment_start_state;\n return;\n }\n\n if (lookahead.toUpperCase() === \"DOCTYPE\") {\n nextchar += 7;\n tokenizer = doctype_state;\n }\n else if (lookahead === \"[CDATA[\" && cdataAllowed()) {\n nextchar += 7;\n tokenizer = cdata_section_state;\n }\n else {\n tokenizer = bogus_comment_state;\n }\n }\n markup_declaration_open_state.lookahead = 7;\n\n function comment_start_state(c) {\n beginComment();\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_start_dash_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n insertToken(COMMENT, buf2str(commentbuf));\n break; /* see comment in comment end state */\n default:\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_start_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_end_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n insertToken(COMMENT, buf2str(commentbuf));\n break;\n case -1: // EOF\n insertToken(COMMENT, buf2str(commentbuf));\n emitEOF();\n break; /* see comment in comment end state */\n default:\n commentbuf.push(0x002D /* HYPHEN-MINUS */);\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_state(c) {\n switch(c) {\n case 0x003C: // LESS-THAN SIGN\n commentbuf.push(c);\n tokenizer = comment_less_than_sign_state;\n break;\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_end_dash_state;\n break;\n case 0x0000: // NULL\n commentbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n insertToken(COMMENT, buf2str(commentbuf));\n emitEOF();\n break; /* see comment in comment end state */\n default:\n commentbuf.push(c);\n break;\n }\n }\n\n function comment_less_than_sign_state(c) {\n switch(c) {\n case 0x0021: // EXCLAMATION MARK\n commentbuf.push(c);\n tokenizer = comment_less_than_sign_bang_state;\n break;\n case 0x003C: // LESS-THAN SIGN\n commentbuf.push(c);\n break;\n default:\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_less_than_sign_bang_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_less_than_sign_bang_dash_state;\n break;\n default:\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_less_than_sign_bang_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_less_than_sign_bang_dash_dash_state;\n break;\n default:\n reconsume(c, comment_end_dash_state);\n break;\n }\n }\n\n function comment_less_than_sign_bang_dash_dash_state(c) {\n switch(c) {\n case 0x003E: // GREATER-THAN SIGN\n case -1: // EOF\n reconsume(c, comment_end_state);\n break;\n default:\n // parse error\n reconsume(c, comment_end_state);\n break;\n }\n }\n\n function comment_end_dash_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n tokenizer = comment_end_state;\n break;\n case -1: // EOF\n insertToken(COMMENT, buf2str(commentbuf));\n emitEOF();\n break; /* see comment in comment end state */\n default:\n commentbuf.push(0x002D /* HYPHEN-MINUS */);\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_end_state(c) {\n switch(c) {\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n insertToken(COMMENT, buf2str(commentbuf));\n break;\n case 0x0021: // EXCLAMATION MARK\n tokenizer = comment_end_bang_state;\n break;\n case 0x002D: // HYPHEN-MINUS\n commentbuf.push(0x002D);\n break;\n case -1: // EOF\n insertToken(COMMENT, buf2str(commentbuf));\n emitEOF();\n break; /* For security reasons: otherwise, hostile user could put a script in a comment e.g. in a blog comment and then DOS the server so that the end tag isn't read, and then the commented script tag would be treated as live code */\n default:\n commentbuf.push(0x002D);\n commentbuf.push(0x002D);\n reconsume(c, comment_state);\n break;\n }\n }\n\n function comment_end_bang_state(c) {\n switch(c) {\n case 0x002D: // HYPHEN-MINUS\n commentbuf.push(0x002D);\n commentbuf.push(0x002D);\n commentbuf.push(0x0021);\n tokenizer = comment_end_dash_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n insertToken(COMMENT, buf2str(commentbuf));\n break;\n case -1: // EOF\n insertToken(COMMENT, buf2str(commentbuf));\n emitEOF();\n break; /* see comment in comment end state */\n default:\n commentbuf.push(0x002D);\n commentbuf.push(0x002D);\n commentbuf.push(0x0021);\n reconsume(c, comment_state);\n break;\n }\n }\n\n function doctype_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = before_doctype_name_state;\n break;\n case -1: // EOF\n beginDoctype();\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n reconsume(c, before_doctype_name_state);\n break;\n }\n }\n\n function before_doctype_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n beginDoctype();\n doctypenamebuf.push(c + 0x0020);\n tokenizer = doctype_name_state;\n break;\n case 0x0000: // NULL\n beginDoctype();\n doctypenamebuf.push(0xFFFD);\n tokenizer = doctype_name_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n beginDoctype();\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n beginDoctype();\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n beginDoctype();\n doctypenamebuf.push(c);\n tokenizer = doctype_name_state;\n break;\n }\n }\n\n function doctype_name_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = after_doctype_name_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitDoctype();\n break;\n case 0x0041: // [A-Z]\n case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:\n case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:\n case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:\n case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:\n case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:\n doctypenamebuf.push(c + 0x0020);\n break;\n case 0x0000: // NULL\n doctypenamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n doctypenamebuf.push(c);\n break;\n }\n }\n\n function after_doctype_name_state(c, lookahead, eof) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n nextchar += 1;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n nextchar += 1;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n lookahead = lookahead.toUpperCase();\n if (lookahead === \"PUBLIC\") {\n nextchar += 6;\n tokenizer = after_doctype_public_keyword_state;\n }\n else if (lookahead === \"SYSTEM\") {\n nextchar += 6;\n tokenizer = after_doctype_system_keyword_state;\n }\n else {\n forcequirks();\n tokenizer = bogus_doctype_state;\n }\n break;\n }\n }\n after_doctype_name_state.lookahead = 6;\n\n function after_doctype_public_keyword_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = before_doctype_public_identifier_state;\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypePublicId();\n tokenizer = doctype_public_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypePublicId();\n tokenizer = doctype_public_identifier_single_quoted_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function before_doctype_public_identifier_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypePublicId();\n tokenizer = doctype_public_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypePublicId();\n tokenizer = doctype_public_identifier_single_quoted_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function doctype_public_identifier_double_quoted_state(c) {\n switch(c) {\n case 0x0022: // QUOTATION MARK\n tokenizer = after_doctype_public_identifier_state;\n break;\n case 0x0000: // NULL\n doctypepublicbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n doctypepublicbuf.push(c);\n break;\n }\n }\n\n function doctype_public_identifier_single_quoted_state(c) {\n switch(c) {\n case 0x0027: // APOSTROPHE\n tokenizer = after_doctype_public_identifier_state;\n break;\n case 0x0000: // NULL\n doctypepublicbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n doctypepublicbuf.push(c);\n break;\n }\n }\n\n function after_doctype_public_identifier_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = between_doctype_public_and_system_identifiers_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitDoctype();\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_single_quoted_state;\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function between_doctype_public_and_system_identifiers_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE Ignore the character.\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitDoctype();\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_single_quoted_state;\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function after_doctype_system_keyword_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n tokenizer = before_doctype_system_identifier_state;\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_single_quoted_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function before_doctype_system_identifier_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE Ignore the character.\n break;\n case 0x0022: // QUOTATION MARK\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_double_quoted_state;\n break;\n case 0x0027: // APOSTROPHE\n beginDoctypeSystemId();\n tokenizer = doctype_system_identifier_single_quoted_state;\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n forcequirks();\n tokenizer = bogus_doctype_state;\n break;\n }\n }\n\n function doctype_system_identifier_double_quoted_state(c) {\n switch(c) {\n case 0x0022: // QUOTATION MARK\n tokenizer = after_doctype_system_identifier_state;\n break;\n case 0x0000: // NULL\n doctypesystembuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n doctypesystembuf.push(c);\n break;\n }\n }\n\n function doctype_system_identifier_single_quoted_state(c) {\n switch(c) {\n case 0x0027: // APOSTROPHE\n tokenizer = after_doctype_system_identifier_state;\n break;\n case 0x0000: // NULL\n doctypesystembuf.push(0xFFFD /* REPLACEMENT CHARACTER */);\n break;\n case 0x003E: // GREATER-THAN SIGN\n forcequirks();\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n doctypesystembuf.push(c);\n break;\n }\n }\n\n function after_doctype_system_identifier_state(c) {\n switch(c) {\n case 0x0009: // CHARACTER TABULATION (tab)\n case 0x000A: // LINE FEED (LF)\n case 0x000C: // FORM FEED (FF)\n case 0x0020: // SPACE\n /* Ignore the character. */\n break;\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n forcequirks();\n emitDoctype();\n emitEOF();\n break;\n default:\n tokenizer = bogus_doctype_state;\n /* This does *not* set the DOCTYPE token's force-quirks flag. */\n break;\n }\n }\n\n function bogus_doctype_state(c) {\n switch(c) {\n case 0x003E: // GREATER-THAN SIGN\n tokenizer = data_state;\n emitDoctype();\n break;\n case -1: // EOF\n emitDoctype();\n emitEOF();\n break;\n default:\n /* Ignore the character. */\n break;\n }\n }\n\n function cdata_section_state(c) {\n switch(c) {\n case 0x005D: // RIGHT SQUARE BRACKET\n tokenizer = cdata_section_bracket_state;\n break;\n case -1: // EOF\n emitEOF();\n break;\n case 0x0000: // NULL\n textIncludesNUL = true;\n /* fall through */\n default:\n // Instead of just pushing a single character and then\n // coming back to the very same place, lookahead and\n // emit everything we can at once.\n /*jshint -W030 */\n emitCharsWhile(CDATATEXT) || textrun.push(c);\n break;\n }\n }\n\n function cdata_section_bracket_state(c) {\n switch(c) {\n case 0x005D: // RIGHT SQUARE BRACKET\n tokenizer = cdata_section_end_state;\n break;\n default:\n textrun.push(0x005D);\n reconsume(c, cdata_section_state);\n break;\n }\n }\n\n function cdata_section_end_state(c) {\n switch(c) {\n case 0x005D: // RIGHT SQUARE BRACKET\n textrun.push(0x005D);\n break;\n case 0x003E: // GREATER-THAN SIGN\n flushText();\n tokenizer = data_state;\n break;\n default:\n textrun.push(0x005D);\n textrun.push(0x005D);\n reconsume(c, cdata_section_state);\n break;\n }\n }\n\n function character_reference_state(c) {\n beginTempBuf();\n tempbuf.push(0x0026);\n switch(c) {\n case 0x0009: // TAB\n case 0x000A: // LINE FEED\n case 0x000C: // FORM FEED\n case 0x0020: // SPACE\n case 0x003C: // LESS-THAN SIGN\n case 0x0026: // AMPERSAND\n case -1: // EOF\n reconsume(c, character_reference_end_state);\n break;\n case 0x0023: // NUMBER SIGN\n tempbuf.push(c);\n tokenizer = numeric_character_reference_state;\n break;\n default:\n reconsume(c, named_character_reference_state);\n break;\n }\n }\n\n function named_character_reference_state(c) {\n NAMEDCHARREF.lastIndex = nextchar; // w/ lookahead no char has been consumed\n var matched = NAMEDCHARREF.exec(chars);\n if (!matched) throw new Error(\"should never happen\");\n var name = matched[1];\n if (!name) {\n // If no match can be made, switch to the character reference end state\n tokenizer = character_reference_end_state;\n return;\n }\n\n // Consume the matched characters and append them to temporary buffer\n nextchar += name.length;\n pushAll(tempbuf, str2buf(name));\n\n switch(return_state) {\n case attribute_value_double_quoted_state:\n case attribute_value_single_quoted_state:\n case attribute_value_unquoted_state:\n // If the character reference was consumed as part of an attribute...\n if (name[name.length-1] !== ';') { // ...and the last char is not ;\n if (/[=A-Za-z0-9]/.test(chars[nextchar])) {\n tokenizer = character_reference_end_state;\n return;\n }\n }\n break;\n default:\n break;\n }\n\n beginTempBuf();\n var rv = namedCharRefs[name];\n if (typeof rv === 'number') {\n tempbuf.push(rv);\n } else {\n pushAll(tempbuf, rv);\n }\n tokenizer = character_reference_end_state;\n }\n // We might need to pause tokenization until we have enough characters\n // in the buffer for longest possible character reference.\n named_character_reference_state.lookahead = -NAMEDCHARREF_MAXLEN;\n\n function numeric_character_reference_state(c) {\n character_reference_code = 0;\n switch(c) {\n case 0x0078: // x\n case 0x0058: // X\n tempbuf.push(c);\n tokenizer = hexadecimal_character_reference_start_state;\n break;\n default:\n reconsume(c, decimal_character_reference_start_state);\n break;\n }\n }\n\n function hexadecimal_character_reference_start_state(c) {\n switch(c) {\n case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:\n case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]\n case 0x0041: case 0x0042: case 0x0043: case 0x0044: case 0x0045:\n case 0x0046: // [A-F]\n case 0x0061: case 0x0062: case 0x0063: case 0x0064: case 0x0065:\n case 0x0066: // [a-f]\n reconsume(c, hexadecimal_character_reference_state);\n break;\n default:\n reconsume(c, character_reference_end_state);\n break;\n }\n }\n\n function decimal_character_reference_start_state(c) {\n switch(c) {\n case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:\n case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]\n reconsume(c, decimal_character_reference_state);\n break;\n default:\n reconsume(c, character_reference_end_state);\n break;\n }\n }\n\n function hexadecimal_character_reference_state(c) {\n switch(c) {\n case 0x0041: case 0x0042: case 0x0043: case 0x0044: case 0x0045:\n case 0x0046: // [A-F]\n character_reference_code *= 16;\n character_reference_code += (c - 0x0037);\n break;\n case 0x0061: case 0x0062: case 0x0063: case 0x0064: case 0x0065:\n case 0x0066: // [a-f]\n character_reference_code *= 16;\n character_reference_code += (c - 0x0057);\n break;\n case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:\n case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]\n character_reference_code *= 16;\n character_reference_code += (c - 0x0030);\n break;\n case 0x003B: // SEMICOLON\n tokenizer = numeric_character_reference_end_state;\n break;\n default:\n reconsume(c, numeric_character_reference_end_state);\n break;\n }\n }\n\n function decimal_character_reference_state(c) {\n switch(c) {\n case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:\n case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]\n character_reference_code *= 10;\n character_reference_code += (c - 0x0030);\n break;\n case 0x003B: // SEMICOLON\n tokenizer = numeric_character_reference_end_state;\n break;\n default:\n reconsume(c, numeric_character_reference_end_state);\n break;\n }\n }\n\n function numeric_character_reference_end_state(c) {\n if (character_reference_code in numericCharRefReplacements) {\n character_reference_code = numericCharRefReplacements[character_reference_code];\n } else if (character_reference_code > 0x10FFFF || (character_reference_code >= 0xD800 && character_reference_code < 0xE000)) {\n character_reference_code = 0xFFFD;\n }\n\n beginTempBuf();\n if (character_reference_code <= 0xFFFF) {\n tempbuf.push(character_reference_code);\n } else {\n character_reference_code = character_reference_code - 0x10000;\n /* jshint bitwise: false */\n tempbuf.push(0xD800 + (character_reference_code >> 10));\n tempbuf.push(0xDC00 + (character_reference_code & 0x03FF));\n }\n reconsume(c, character_reference_end_state);\n }\n\n function character_reference_end_state(c) {\n switch(return_state) {\n case attribute_value_double_quoted_state:\n case attribute_value_single_quoted_state:\n case attribute_value_unquoted_state:\n // append each character to the current attribute's value\n attrvaluebuf += buf2str(tempbuf);\n break;\n default:\n pushAll(textrun, tempbuf);\n break;\n }\n reconsume(c, return_state);\n }\n\n /***\n * The tree builder insertion modes\n */\n\n // 11.2.5.4.1 The \"initial\" insertion mode\n function initial_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n value = value.replace(LEADINGWS, \"\"); // Ignore spaces\n if (value.length === 0) return; // Are we done?\n break; // Handle anything non-space text below\n case 4: // COMMENT\n doc._appendChild(doc.createComment(value));\n return;\n case 5: // DOCTYPE\n var name = value;\n var publicid = arg3;\n var systemid = arg4;\n // Use the constructor directly instead of\n // implementation.createDocumentType because the create\n // function throws errors on invalid characters, and\n // we don't want the parser to throw them.\n doc.appendChild(new DocumentType(doc, name, publicid, systemid));\n\n // Note that there is no public API for setting quirks mode We can\n // do this here because we have access to implementation details\n if (force_quirks ||\n name.toLowerCase() !== \"html\" ||\n quirkyPublicIds.test(publicid) ||\n (systemid && systemid.toLowerCase() === quirkySystemId) ||\n (systemid === undefined &&\n conditionallyQuirkyPublicIds.test(publicid)))\n doc._quirks = true;\n else if (limitedQuirkyPublicIds.test(publicid) ||\n (systemid !== undefined &&\n conditionallyQuirkyPublicIds.test(publicid)))\n doc._limitedQuirks = true;\n parser = before_html_mode;\n return;\n }\n\n // tags or non-whitespace text\n doc._quirks = true;\n parser = before_html_mode;\n parser(t,value,arg3,arg4);\n }\n\n // 11.2.5.4.2 The \"before html\" insertion mode\n function before_html_mode(t,value,arg3,arg4) {\n var elt;\n switch(t) {\n case 1: // TEXT\n value = value.replace(LEADINGWS, \"\"); // Ignore spaces\n if (value.length === 0) return; // Are we done?\n break; // Handle anything non-space text below\n case 5: // DOCTYPE\n /* ignore the token */\n return;\n case 4: // COMMENT\n doc._appendChild(doc.createComment(value));\n return;\n case 2: // TAG\n if (value === \"html\") {\n elt = createHTMLElt(doc, value, arg3);\n stack.push(elt);\n doc.appendChild(elt);\n // XXX: handle application cache here\n parser = before_head_mode;\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"html\":\n case \"head\":\n case \"body\":\n case \"br\":\n break; // fall through on these\n default:\n return; // ignore most end tags\n }\n }\n\n // Anything that didn't get handled above is handled like this:\n elt = createHTMLElt(doc, \"html\", null);\n stack.push(elt);\n doc.appendChild(elt);\n // XXX: handle application cache here\n parser = before_head_mode;\n parser(t,value,arg3,arg4);\n }\n\n // 11.2.5.4.3 The \"before head\" insertion mode\n function before_head_mode(t,value,arg3,arg4) {\n switch(t) {\n case 1: // TEXT\n value = value.replace(LEADINGWS, \"\"); // Ignore spaces\n if (value.length === 0) return; // Are we done?\n break; // Handle anything non-space text below\n case 5: // DOCTYPE\n /* ignore the token */\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t,value,arg3,arg4);\n return;\n case \"head\":\n var elt = insertHTMLElement(value, arg3);\n head_element_pointer = elt;\n parser = in_head_mode;\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"html\":\n case \"head\":\n case \"body\":\n case \"br\":\n break;\n default:\n return; // ignore most end tags\n }\n }\n\n // If not handled explicitly above\n before_head_mode(TAG, \"head\", null); // create a head tag\n parser(t, value, arg3, arg4); // then try again with this token\n }\n\n function in_head_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n var ws = value.match(LEADINGWS);\n if (ws) {\n insertText(ws[0]);\n value = value.substring(ws[0].length);\n }\n if (value.length === 0) return;\n break; // Handle non-whitespace below\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"meta\":\n // XXX:\n // May need to change the encoding based on this tag\n /* falls through */\n case \"base\":\n case \"basefont\":\n case \"bgsound\":\n case \"link\":\n insertHTMLElement(value, arg3);\n stack.pop();\n return;\n case \"title\":\n parseRCDATA(value, arg3);\n return;\n case \"noscript\":\n if (!scripting_enabled) {\n insertHTMLElement(value, arg3);\n parser = in_head_noscript_mode;\n return;\n }\n // Otherwise, if scripting is enabled...\n /* falls through */\n case \"noframes\":\n case \"style\":\n parseRawText(value,arg3);\n return;\n case \"script\":\n insertElement(function(doc) {\n var elt = createHTMLElt(doc, value, arg3);\n elt._parser_inserted = true;\n elt._force_async = false;\n if (fragment) elt._already_started = true;\n flushText();\n return elt;\n });\n tokenizer = script_data_state;\n originalInsertionMode = parser;\n parser = text_mode;\n return;\n case \"template\":\n insertHTMLElement(value, arg3);\n afe.insertMarker();\n frameset_ok = false;\n parser = in_template_mode;\n templateInsertionModes.push(parser);\n return;\n case \"head\":\n return; // ignore it\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"head\":\n stack.pop();\n parser = after_head_mode;\n return;\n case \"body\":\n case \"html\":\n case \"br\":\n break; // handle these at the bottom of the function\n case \"template\":\n if (!stack.contains(\"template\")) {\n return;\n }\n stack.generateImpliedEndTags(null, \"thorough\");\n stack.popTag(\"template\");\n afe.clearToMarker();\n templateInsertionModes.pop();\n resetInsertionMode();\n return;\n default:\n // ignore any other end tag\n return;\n }\n break;\n }\n\n // If not handled above\n in_head_mode(ENDTAG, \"head\", null); // synthetic \n parser(t, value, arg3, arg4); // Then redo this one\n }\n\n // 13.2.5.4.5 The \"in head noscript\" insertion mode\n function in_head_noscript_mode(t, value, arg3, arg4) {\n switch(t) {\n case 5: // DOCTYPE\n return;\n case 4: // COMMENT\n in_head_mode(t, value);\n return;\n case 1: // TEXT\n var ws = value.match(LEADINGWS);\n if (ws) {\n in_head_mode(t, ws[0]);\n value = value.substring(ws[0].length);\n }\n if (value.length === 0) return; // no more text\n break; // Handle non-whitespace below\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"basefont\":\n case \"bgsound\":\n case \"link\":\n case \"meta\":\n case \"noframes\":\n case \"style\":\n in_head_mode(t, value, arg3);\n return;\n case \"head\":\n case \"noscript\":\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"noscript\":\n stack.pop();\n parser = in_head_mode;\n return;\n case \"br\":\n break; // goes to the outer default\n default:\n return; // ignore other end tags\n }\n break;\n }\n\n // If not handled above\n in_head_noscript_mode(ENDTAG, \"noscript\", null);\n parser(t, value, arg3, arg4);\n }\n\n function after_head_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n var ws = value.match(LEADINGWS);\n if (ws) {\n insertText(ws[0]);\n value = value.substring(ws[0].length);\n }\n if (value.length === 0) return;\n break; // Handle non-whitespace below\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"body\":\n insertHTMLElement(value, arg3);\n frameset_ok = false;\n parser = in_body_mode;\n return;\n case \"frameset\":\n insertHTMLElement(value, arg3);\n parser = in_frameset_mode;\n return;\n case \"base\":\n case \"basefont\":\n case \"bgsound\":\n case \"link\":\n case \"meta\":\n case \"noframes\":\n case \"script\":\n case \"style\":\n case \"template\":\n case \"title\":\n stack.push(head_element_pointer);\n in_head_mode(TAG, value, arg3);\n stack.removeElement(head_element_pointer);\n return;\n case \"head\":\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"template\":\n return in_head_mode(t, value, arg3, arg4);\n case \"body\":\n case \"html\":\n case \"br\":\n break;\n default:\n return; // ignore any other end tag\n }\n break;\n }\n\n after_head_mode(TAG, \"body\", null);\n frameset_ok = true;\n parser(t, value, arg3, arg4);\n }\n\n // 13.2.5.4.7 The \"in body\" insertion mode\n function in_body_mode(t,value,arg3,arg4) {\n var body, i, node, elt;\n switch(t) {\n case 1: // TEXT\n if (textIncludesNUL) {\n value = value.replace(NULCHARS, \"\");\n if (value.length === 0) return;\n }\n // If any non-space characters\n if (frameset_ok && NONWS.test(value))\n frameset_ok = false;\n afereconstruct();\n insertText(value);\n return;\n case 5: // DOCTYPE\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case -1: // EOF\n if (templateInsertionModes.length) {\n return in_template_mode(t);\n }\n stopParsing();\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n if (stack.contains(\"template\")) {\n return;\n }\n transferAttributes(arg3, stack.elements[0]);\n return;\n case \"base\":\n case \"basefont\":\n case \"bgsound\":\n case \"link\":\n case \"meta\":\n case \"noframes\":\n case \"script\":\n case \"style\":\n case \"template\":\n case \"title\":\n in_head_mode(TAG, value, arg3);\n return;\n case \"body\":\n body = stack.elements[1];\n if (!body || !(body instanceof impl.HTMLBodyElement) ||\n stack.contains(\"template\"))\n return;\n frameset_ok = false;\n transferAttributes(arg3, body);\n return;\n case \"frameset\":\n if (!frameset_ok) return;\n body = stack.elements[1];\n if (!body || !(body instanceof impl.HTMLBodyElement))\n return;\n if (body.parentNode) body.parentNode.removeChild(body);\n while(!(stack.top instanceof impl.HTMLHtmlElement))\n stack.pop();\n insertHTMLElement(value, arg3);\n parser = in_frameset_mode;\n return;\n\n case \"address\":\n case \"article\":\n case \"aside\":\n case \"blockquote\":\n case \"center\":\n case \"details\":\n case \"dialog\":\n case \"dir\":\n case \"div\":\n case \"dl\":\n case \"fieldset\":\n case \"figcaption\":\n case \"figure\":\n case \"footer\":\n case \"header\":\n case \"hgroup\":\n case \"main\":\n case \"nav\":\n case \"ol\":\n case \"p\":\n case \"section\":\n case \"summary\":\n case \"ul\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n insertHTMLElement(value, arg3);\n return;\n\n case \"menu\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n if (isA(stack.top, 'menuitem')) {\n stack.pop();\n }\n insertHTMLElement(value, arg3);\n return;\n\n case \"h1\":\n case \"h2\":\n case \"h3\":\n case \"h4\":\n case \"h5\":\n case \"h6\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n if (stack.top instanceof impl.HTMLHeadingElement)\n stack.pop();\n insertHTMLElement(value, arg3);\n return;\n\n case \"pre\":\n case \"listing\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n insertHTMLElement(value, arg3);\n ignore_linefeed = true;\n frameset_ok = false;\n return;\n\n case \"form\":\n if (form_element_pointer && !stack.contains(\"template\")) return;\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n elt = insertHTMLElement(value, arg3);\n if (!stack.contains(\"template\"))\n form_element_pointer = elt;\n return;\n\n case \"li\":\n frameset_ok = false;\n for(i = stack.elements.length-1; i >= 0; i--) {\n node = stack.elements[i];\n if (node instanceof impl.HTMLLIElement) {\n in_body_mode(ENDTAG, \"li\");\n break;\n }\n if (isA(node, specialSet) && !isA(node, addressdivpSet))\n break;\n }\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n insertHTMLElement(value, arg3);\n return;\n\n case \"dd\":\n case \"dt\":\n frameset_ok = false;\n for(i = stack.elements.length-1; i >= 0; i--) {\n node = stack.elements[i];\n if (isA(node, dddtSet)) {\n in_body_mode(ENDTAG, node.localName);\n break;\n }\n if (isA(node, specialSet) && !isA(node, addressdivpSet))\n break;\n }\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n insertHTMLElement(value, arg3);\n return;\n\n case \"plaintext\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n insertHTMLElement(value, arg3);\n tokenizer = plaintext_state;\n return;\n\n case \"button\":\n if (stack.inScope(\"button\")) {\n in_body_mode(ENDTAG, \"button\");\n parser(t, value, arg3, arg4);\n }\n else {\n afereconstruct();\n insertHTMLElement(value, arg3);\n frameset_ok = false;\n }\n return;\n\n case \"a\":\n var activeElement = afe.findElementByTag(\"a\");\n if (activeElement) {\n in_body_mode(ENDTAG, value);\n afe.remove(activeElement);\n stack.removeElement(activeElement);\n }\n /* falls through */\n case \"b\":\n case \"big\":\n case \"code\":\n case \"em\":\n case \"font\":\n case \"i\":\n case \"s\":\n case \"small\":\n case \"strike\":\n case \"strong\":\n case \"tt\":\n case \"u\":\n afereconstruct();\n afe.push(insertHTMLElement(value,arg3), arg3);\n return;\n\n case \"nobr\":\n afereconstruct();\n\n if (stack.inScope(value)) {\n in_body_mode(ENDTAG, value);\n afereconstruct();\n }\n afe.push(insertHTMLElement(value,arg3), arg3);\n return;\n\n case \"applet\":\n case \"marquee\":\n case \"object\":\n afereconstruct();\n insertHTMLElement(value,arg3);\n afe.insertMarker();\n frameset_ok = false;\n return;\n\n case \"table\":\n if (!doc._quirks && stack.inButtonScope(\"p\")) {\n in_body_mode(ENDTAG, \"p\");\n }\n insertHTMLElement(value,arg3);\n frameset_ok = false;\n parser = in_table_mode;\n return;\n\n case \"area\":\n case \"br\":\n case \"embed\":\n case \"img\":\n case \"keygen\":\n case \"wbr\":\n afereconstruct();\n insertHTMLElement(value,arg3);\n stack.pop();\n frameset_ok = false;\n return;\n\n case \"input\":\n afereconstruct();\n elt = insertHTMLElement(value,arg3);\n stack.pop();\n var type = elt.getAttribute(\"type\");\n if (!type || type.toLowerCase() !== \"hidden\")\n frameset_ok = false;\n return;\n\n case \"param\":\n case \"source\":\n case \"track\":\n insertHTMLElement(value,arg3);\n stack.pop();\n return;\n\n case \"hr\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n if (isA(stack.top, 'menuitem')) {\n stack.pop();\n }\n insertHTMLElement(value,arg3);\n stack.pop();\n frameset_ok = false;\n return;\n\n case \"image\":\n in_body_mode(TAG, \"img\", arg3, arg4);\n return;\n\n case \"textarea\":\n insertHTMLElement(value,arg3);\n ignore_linefeed = true;\n frameset_ok = false;\n tokenizer = rcdata_state;\n originalInsertionMode = parser;\n parser = text_mode;\n return;\n\n case \"xmp\":\n if (stack.inButtonScope(\"p\")) in_body_mode(ENDTAG, \"p\");\n afereconstruct();\n frameset_ok = false;\n parseRawText(value, arg3);\n return;\n\n case \"iframe\":\n frameset_ok = false;\n parseRawText(value, arg3);\n return;\n\n case \"noembed\":\n parseRawText(value,arg3);\n return;\n\n case \"select\":\n afereconstruct();\n insertHTMLElement(value,arg3);\n frameset_ok = false;\n if (parser === in_table_mode ||\n parser === in_caption_mode ||\n parser === in_table_body_mode ||\n parser === in_row_mode ||\n parser === in_cell_mode)\n parser = in_select_in_table_mode;\n else\n parser = in_select_mode;\n return;\n\n case \"optgroup\":\n case \"option\":\n if (stack.top instanceof impl.HTMLOptionElement) {\n in_body_mode(ENDTAG, \"option\");\n }\n afereconstruct();\n insertHTMLElement(value,arg3);\n return;\n\n case \"menuitem\":\n if (isA(stack.top, 'menuitem')) {\n stack.pop();\n }\n afereconstruct();\n insertHTMLElement(value, arg3);\n return;\n\n case \"rb\":\n case \"rtc\":\n if (stack.inScope(\"ruby\")) {\n stack.generateImpliedEndTags();\n }\n insertHTMLElement(value,arg3);\n return;\n\n case \"rp\":\n case \"rt\":\n if (stack.inScope(\"ruby\")) {\n stack.generateImpliedEndTags(\"rtc\");\n }\n insertHTMLElement(value,arg3);\n return;\n\n case \"math\":\n afereconstruct();\n adjustMathMLAttributes(arg3);\n adjustForeignAttributes(arg3);\n insertForeignElement(value, arg3, NAMESPACE.MATHML);\n if (arg4) // self-closing flag\n stack.pop();\n return;\n\n case \"svg\":\n afereconstruct();\n adjustSVGAttributes(arg3);\n adjustForeignAttributes(arg3);\n insertForeignElement(value, arg3, NAMESPACE.SVG);\n if (arg4) // self-closing flag\n stack.pop();\n return;\n\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"frame\":\n case \"head\":\n case \"tbody\":\n case \"td\":\n case \"tfoot\":\n case \"th\":\n case \"thead\":\n case \"tr\":\n // Ignore table tags if we're not in_table mode\n return;\n }\n\n // Handle any other start tag here\n // (and also noscript tags when scripting is disabled)\n afereconstruct();\n insertHTMLElement(value,arg3);\n return;\n\n case 3: // ENDTAG\n switch(value) {\n case \"template\":\n in_head_mode(ENDTAG, value, arg3);\n return;\n case \"body\":\n if (!stack.inScope(\"body\")) return;\n parser = after_body_mode;\n return;\n case \"html\":\n if (!stack.inScope(\"body\")) return;\n parser = after_body_mode;\n parser(t, value, arg3);\n return;\n\n case \"address\":\n case \"article\":\n case \"aside\":\n case \"blockquote\":\n case \"button\":\n case \"center\":\n case \"details\":\n case \"dialog\":\n case \"dir\":\n case \"div\":\n case \"dl\":\n case \"fieldset\":\n case \"figcaption\":\n case \"figure\":\n case \"footer\":\n case \"header\":\n case \"hgroup\":\n case \"listing\":\n case \"main\":\n case \"menu\":\n case \"nav\":\n case \"ol\":\n case \"pre\":\n case \"section\":\n case \"summary\":\n case \"ul\":\n // Ignore if there is not a matching open tag\n if (!stack.inScope(value)) return;\n stack.generateImpliedEndTags();\n stack.popTag(value);\n return;\n\n case \"form\":\n if (!stack.contains(\"template\")) {\n var openform = form_element_pointer;\n form_element_pointer = null;\n if (!openform || !stack.elementInScope(openform)) return;\n stack.generateImpliedEndTags();\n stack.removeElement(openform);\n } else {\n if (!stack.inScope(\"form\")) return;\n stack.generateImpliedEndTags();\n stack.popTag(\"form\");\n }\n return;\n\n case \"p\":\n if (!stack.inButtonScope(value)) {\n in_body_mode(TAG, value, null);\n parser(t, value, arg3, arg4);\n }\n else {\n stack.generateImpliedEndTags(value);\n stack.popTag(value);\n }\n return;\n\n case \"li\":\n if (!stack.inListItemScope(value)) return;\n stack.generateImpliedEndTags(value);\n stack.popTag(value);\n return;\n\n case \"dd\":\n case \"dt\":\n if (!stack.inScope(value)) return;\n stack.generateImpliedEndTags(value);\n stack.popTag(value);\n return;\n\n case \"h1\":\n case \"h2\":\n case \"h3\":\n case \"h4\":\n case \"h5\":\n case \"h6\":\n if (!stack.elementTypeInScope(impl.HTMLHeadingElement)) return;\n stack.generateImpliedEndTags();\n stack.popElementType(impl.HTMLHeadingElement);\n return;\n\n case \"sarcasm\":\n // Take a deep breath, and then:\n break;\n\n case \"a\":\n case \"b\":\n case \"big\":\n case \"code\":\n case \"em\":\n case \"font\":\n case \"i\":\n case \"nobr\":\n case \"s\":\n case \"small\":\n case \"strike\":\n case \"strong\":\n case \"tt\":\n case \"u\":\n var result = adoptionAgency(value);\n if (result) return; // If we did something we're done\n break; // Go to the \"any other end tag\" case\n\n case \"applet\":\n case \"marquee\":\n case \"object\":\n if (!stack.inScope(value)) return;\n stack.generateImpliedEndTags();\n stack.popTag(value);\n afe.clearToMarker();\n return;\n\n case \"br\":\n in_body_mode(TAG, value, null); // Turn
    into
    \n return;\n }\n\n // Any other end tag goes here\n for(i = stack.elements.length-1; i >= 0; i--) {\n node = stack.elements[i];\n if (isA(node, value)) {\n stack.generateImpliedEndTags(value);\n stack.popElement(node);\n break;\n }\n else if (isA(node, specialSet)) {\n return;\n }\n }\n\n return;\n }\n }\n\n function text_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n insertText(value);\n return;\n case -1: // EOF\n if (stack.top instanceof impl.HTMLScriptElement)\n stack.top._already_started = true;\n stack.pop();\n parser = originalInsertionMode;\n parser(t);\n return;\n case 3: // ENDTAG\n if (value === \"script\") {\n handleScriptEnd();\n }\n else {\n stack.pop();\n parser = originalInsertionMode;\n }\n return;\n default:\n // We should never get any other token types\n return;\n }\n }\n\n function in_table_mode(t, value, arg3, arg4) {\n function getTypeAttr(attrs) {\n for(var i = 0, n = attrs.length; i < n; i++) {\n if (attrs[i][0] === \"type\")\n return attrs[i][1].toLowerCase();\n }\n return null;\n }\n\n switch(t) {\n case 1: // TEXT\n // XXX the text_integration_mode stuff is\n // just a hack I made up\n if (text_integration_mode) {\n in_body_mode(t, value, arg3, arg4);\n return;\n }\n else if (isA(stack.top, tablesectionrowSet)) {\n pending_table_text = [];\n originalInsertionMode = parser;\n parser = in_table_text_mode;\n parser(t, value, arg3, arg4);\n return;\n }\n break;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case 2: // TAG\n switch(value) {\n case \"caption\":\n stack.clearToContext(tableContextSet);\n afe.insertMarker();\n insertHTMLElement(value,arg3);\n parser = in_caption_mode;\n return;\n case \"colgroup\":\n stack.clearToContext(tableContextSet);\n insertHTMLElement(value,arg3);\n parser = in_column_group_mode;\n return;\n case \"col\":\n in_table_mode(TAG, \"colgroup\", null);\n parser(t, value, arg3, arg4);\n return;\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n stack.clearToContext(tableContextSet);\n insertHTMLElement(value,arg3);\n parser = in_table_body_mode;\n return;\n case \"td\":\n case \"th\":\n case \"tr\":\n in_table_mode(TAG, \"tbody\", null);\n parser(t, value, arg3, arg4);\n return;\n\n case \"table\":\n if (!stack.inTableScope(value)) {\n return; // Ignore the token\n }\n in_table_mode(ENDTAG, value);\n parser(t, value, arg3, arg4);\n return;\n\n case \"style\":\n case \"script\":\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n\n case \"input\":\n var type = getTypeAttr(arg3);\n if (type !== \"hidden\") break; // to the anything else case\n insertHTMLElement(value,arg3);\n stack.pop();\n return;\n\n case \"form\":\n if (form_element_pointer || stack.contains(\"template\")) return;\n form_element_pointer = insertHTMLElement(value, arg3);\n stack.popElement(form_element_pointer);\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"table\":\n if (!stack.inTableScope(value)) return;\n stack.popTag(value);\n resetInsertionMode();\n return;\n case \"body\":\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"html\":\n case \"tbody\":\n case \"td\":\n case \"tfoot\":\n case \"th\":\n case \"thead\":\n case \"tr\":\n return;\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n\n break;\n case -1: // EOF\n in_body_mode(t, value, arg3, arg4);\n return;\n }\n\n // This is the anything else case\n foster_parent_mode = true;\n in_body_mode(t, value, arg3, arg4);\n foster_parent_mode = false;\n }\n\n function in_table_text_mode(t, value, arg3, arg4) {\n if (t === TEXT) {\n if (textIncludesNUL) {\n value = value.replace(NULCHARS, \"\");\n if (value.length === 0) return;\n }\n pending_table_text.push(value);\n }\n else {\n var s = pending_table_text.join(\"\");\n pending_table_text.length = 0;\n if (NONWS.test(s)) { // If any non-whitespace characters\n // This must be the same code as the \"anything else\"\n // case of the in_table mode above.\n foster_parent_mode = true;\n in_body_mode(TEXT, s);\n foster_parent_mode = false;\n }\n else {\n insertText(s);\n }\n parser = originalInsertionMode;\n parser(t, value, arg3, arg4);\n }\n }\n\n\n function in_caption_mode(t, value, arg3, arg4) {\n function end_caption() {\n if (!stack.inTableScope(\"caption\")) return false;\n stack.generateImpliedEndTags();\n stack.popTag(\"caption\");\n afe.clearToMarker();\n parser = in_table_mode;\n return true;\n }\n\n switch(t) {\n case 2: // TAG\n switch(value) {\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"tbody\":\n case \"td\":\n case \"tfoot\":\n case \"th\":\n case \"thead\":\n case \"tr\":\n if (end_caption()) parser(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"caption\":\n end_caption();\n return;\n case \"table\":\n if (end_caption()) parser(t, value, arg3, arg4);\n return;\n case \"body\":\n case \"col\":\n case \"colgroup\":\n case \"html\":\n case \"tbody\":\n case \"td\":\n case \"tfoot\":\n case \"th\":\n case \"thead\":\n case \"tr\":\n return;\n }\n break;\n }\n\n // The Anything Else case\n in_body_mode(t, value, arg3, arg4);\n }\n\n function in_column_group_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n var ws = value.match(LEADINGWS);\n if (ws) {\n insertText(ws[0]);\n value = value.substring(ws[0].length);\n }\n if (value.length === 0) return;\n break; // Handle non-whitespace below\n\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"col\":\n insertHTMLElement(value, arg3);\n stack.pop();\n return;\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"colgroup\":\n if (!isA(stack.top, 'colgroup')) {\n return; // Ignore the token.\n }\n stack.pop();\n parser = in_table_mode;\n return;\n case \"col\":\n return;\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n case -1: // EOF\n in_body_mode(t, value, arg3, arg4);\n return;\n }\n\n // Anything else\n if (!isA(stack.top, 'colgroup')) {\n return; // Ignore the token.\n }\n in_column_group_mode(ENDTAG, \"colgroup\");\n parser(t, value, arg3, arg4);\n }\n\n function in_table_body_mode(t, value, arg3, arg4) {\n function endsect() {\n if (!stack.inTableScope(\"tbody\") &&\n !stack.inTableScope(\"thead\") &&\n !stack.inTableScope(\"tfoot\"))\n return;\n stack.clearToContext(tableBodyContextSet);\n in_table_body_mode(ENDTAG, stack.top.localName, null);\n parser(t, value, arg3, arg4);\n }\n\n switch(t) {\n case 2: // TAG\n switch(value) {\n case \"tr\":\n stack.clearToContext(tableBodyContextSet);\n insertHTMLElement(value, arg3);\n parser = in_row_mode;\n return;\n case \"th\":\n case \"td\":\n in_table_body_mode(TAG, \"tr\", null);\n parser(t, value, arg3, arg4);\n return;\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n endsect();\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"table\":\n endsect();\n return;\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n if (stack.inTableScope(value)) {\n stack.clearToContext(tableBodyContextSet);\n stack.pop();\n parser = in_table_mode;\n }\n return;\n case \"body\":\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"html\":\n case \"td\":\n case \"th\":\n case \"tr\":\n return;\n }\n break;\n }\n\n // Anything else:\n in_table_mode(t, value, arg3, arg4);\n }\n\n function in_row_mode(t, value, arg3, arg4) {\n function endrow() {\n if (!stack.inTableScope(\"tr\")) return false;\n stack.clearToContext(tableRowContextSet);\n stack.pop();\n parser = in_table_body_mode;\n return true;\n }\n\n switch(t) {\n case 2: // TAG\n switch(value) {\n case \"th\":\n case \"td\":\n stack.clearToContext(tableRowContextSet);\n insertHTMLElement(value, arg3);\n parser = in_cell_mode;\n afe.insertMarker();\n return;\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n case \"tr\":\n if (endrow()) parser(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"tr\":\n endrow();\n return;\n case \"table\":\n if (endrow()) parser(t, value, arg3, arg4);\n return;\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n if (stack.inTableScope(value)) {\n if (endrow()) parser(t, value, arg3, arg4);\n }\n return;\n case \"body\":\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"html\":\n case \"td\":\n case \"th\":\n return;\n }\n break;\n }\n\n // anything else\n in_table_mode(t, value, arg3, arg4);\n }\n\n function in_cell_mode(t, value, arg3, arg4) {\n switch(t) {\n case 2: // TAG\n switch(value) {\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"tbody\":\n case \"td\":\n case \"tfoot\":\n case \"th\":\n case \"thead\":\n case \"tr\":\n if (stack.inTableScope(\"td\")) {\n in_cell_mode(ENDTAG, \"td\");\n parser(t, value, arg3, arg4);\n }\n else if (stack.inTableScope(\"th\")) {\n in_cell_mode(ENDTAG, \"th\");\n parser(t, value, arg3, arg4);\n }\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"td\":\n case \"th\":\n if (!stack.inTableScope(value)) return;\n stack.generateImpliedEndTags();\n stack.popTag(value);\n afe.clearToMarker();\n parser = in_row_mode;\n return;\n\n case \"body\":\n case \"caption\":\n case \"col\":\n case \"colgroup\":\n case \"html\":\n return;\n\n case \"table\":\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n case \"tr\":\n if (!stack.inTableScope(value)) return;\n in_cell_mode(ENDTAG, stack.inTableScope(\"td\") ? \"td\" : \"th\");\n parser(t, value, arg3, arg4);\n return;\n }\n break;\n }\n\n // anything else\n in_body_mode(t, value, arg3, arg4);\n }\n\n function in_select_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n if (textIncludesNUL) {\n value = value.replace(NULCHARS, \"\");\n if (value.length === 0) return;\n }\n insertText(value);\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case -1: // EOF\n in_body_mode(t, value, arg3, arg4);\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"option\":\n if (stack.top instanceof impl.HTMLOptionElement)\n in_select_mode(ENDTAG, value);\n insertHTMLElement(value, arg3);\n return;\n case \"optgroup\":\n if (stack.top instanceof impl.HTMLOptionElement)\n in_select_mode(ENDTAG, \"option\");\n if (stack.top instanceof impl.HTMLOptGroupElement)\n in_select_mode(ENDTAG, value);\n insertHTMLElement(value, arg3);\n return;\n case \"select\":\n in_select_mode(ENDTAG, value); // treat it as a close tag\n return;\n\n case \"input\":\n case \"keygen\":\n case \"textarea\":\n if (!stack.inSelectScope(\"select\")) return;\n in_select_mode(ENDTAG, \"select\");\n parser(t, value, arg3, arg4);\n return;\n\n case \"script\":\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n switch(value) {\n case \"optgroup\":\n if (stack.top instanceof impl.HTMLOptionElement &&\n stack.elements[stack.elements.length-2] instanceof\n impl.HTMLOptGroupElement) {\n in_select_mode(ENDTAG, \"option\");\n }\n if (stack.top instanceof impl.HTMLOptGroupElement)\n stack.pop();\n\n return;\n\n case \"option\":\n if (stack.top instanceof impl.HTMLOptionElement)\n stack.pop();\n return;\n\n case \"select\":\n if (!stack.inSelectScope(value)) return;\n stack.popTag(value);\n resetInsertionMode();\n return;\n\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n\n break;\n }\n\n // anything else: just ignore the token\n }\n\n function in_select_in_table_mode(t, value, arg3, arg4) {\n switch(value) {\n case \"caption\":\n case \"table\":\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n case \"tr\":\n case \"td\":\n case \"th\":\n switch(t) {\n case 2: // TAG\n in_select_in_table_mode(ENDTAG, \"select\");\n parser(t, value, arg3, arg4);\n return;\n case 3: // ENDTAG\n if (stack.inTableScope(value)) {\n in_select_in_table_mode(ENDTAG, \"select\");\n parser(t, value, arg3, arg4);\n }\n return;\n }\n }\n\n // anything else\n in_select_mode(t, value, arg3, arg4);\n }\n\n function in_template_mode(t, value, arg3, arg4) {\n function switchModeAndReprocess(mode) {\n parser = mode;\n templateInsertionModes[templateInsertionModes.length-1] = parser;\n parser(t, value, arg3, arg4);\n }\n switch(t) {\n case 1: // TEXT\n case 4: // COMMENT\n case 5: // DOCTYPE\n in_body_mode(t, value, arg3, arg4);\n return;\n case -1: // EOF\n if (!stack.contains(\"template\")) {\n stopParsing();\n } else {\n stack.popTag(\"template\");\n afe.clearToMarker();\n templateInsertionModes.pop();\n resetInsertionMode();\n parser(t, value, arg3, arg4);\n }\n return;\n case 2: // TAG\n switch(value) {\n case \"base\":\n case \"basefont\":\n case \"bgsound\":\n case \"link\":\n case \"meta\":\n case \"noframes\":\n case \"script\":\n case \"style\":\n case \"template\":\n case \"title\":\n in_head_mode(t, value, arg3, arg4);\n return;\n case \"caption\":\n case \"colgroup\":\n case \"tbody\":\n case \"tfoot\":\n case \"thead\":\n switchModeAndReprocess(in_table_mode);\n return;\n case \"col\":\n switchModeAndReprocess(in_column_group_mode);\n return;\n case \"tr\":\n switchModeAndReprocess(in_table_body_mode);\n return;\n case \"td\":\n case \"th\":\n switchModeAndReprocess(in_row_mode);\n return;\n }\n switchModeAndReprocess(in_body_mode);\n return;\n case 3: // ENDTAG\n switch(value) {\n case \"template\":\n in_head_mode(t, value, arg3, arg4);\n return;\n default:\n return;\n }\n }\n }\n\n function after_body_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n // If any non-space chars, handle below\n if (NONWS.test(value)) break;\n in_body_mode(t, value);\n return;\n case 4: // COMMENT\n // Append it to the element\n stack.elements[0]._appendChild(doc.createComment(value));\n return;\n case 5: // DOCTYPE\n return;\n case -1: // EOF\n stopParsing();\n return;\n case 2: // TAG\n if (value === \"html\") {\n in_body_mode(t, value, arg3, arg4);\n return;\n }\n break; // for any other tags\n case 3: // ENDTAG\n if (value === \"html\") {\n if (fragment) return;\n parser = after_after_body_mode;\n return;\n }\n break; // for any other tags\n }\n\n // anything else\n parser = in_body_mode;\n parser(t, value, arg3, arg4);\n }\n\n function in_frameset_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n // Ignore any non-space characters\n value = value.replace(ALLNONWS, \"\");\n if (value.length > 0) insertText(value);\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case -1: // EOF\n stopParsing();\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"frameset\":\n insertHTMLElement(value, arg3);\n return;\n case \"frame\":\n insertHTMLElement(value, arg3);\n stack.pop();\n return;\n case \"noframes\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n if (value === \"frameset\") {\n if (fragment && stack.top instanceof impl.HTMLHtmlElement)\n return;\n stack.pop();\n if (!fragment &&\n !(stack.top instanceof impl.HTMLFrameSetElement))\n parser = after_frameset_mode;\n return;\n }\n break;\n }\n\n // ignore anything else\n }\n\n function after_frameset_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n // Ignore any non-space characters\n value = value.replace(ALLNONWS, \"\");\n if (value.length > 0) insertText(value);\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n return;\n case -1: // EOF\n stopParsing();\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"noframes\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n case 3: // ENDTAG\n if (value === \"html\") {\n parser = after_after_frameset_mode;\n return;\n }\n break;\n }\n\n // ignore anything else\n }\n\n function after_after_body_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n // If any non-space chars, handle below\n if (NONWS.test(value)) break;\n in_body_mode(t, value, arg3, arg4);\n return;\n case 4: // COMMENT\n doc._appendChild(doc.createComment(value));\n return;\n case 5: // DOCTYPE\n in_body_mode(t, value, arg3, arg4);\n return;\n case -1: // EOF\n stopParsing();\n return;\n case 2: // TAG\n if (value === \"html\") {\n in_body_mode(t, value, arg3, arg4);\n return;\n }\n break;\n }\n\n // anything else\n parser = in_body_mode;\n parser(t, value, arg3, arg4);\n }\n\n function after_after_frameset_mode(t, value, arg3, arg4) {\n switch(t) {\n case 1: // TEXT\n // Ignore any non-space characters\n value = value.replace(ALLNONWS, \"\");\n if (value.length > 0)\n in_body_mode(t, value, arg3, arg4);\n return;\n case 4: // COMMENT\n doc._appendChild(doc.createComment(value));\n return;\n case 5: // DOCTYPE\n in_body_mode(t, value, arg3, arg4);\n return;\n case -1: // EOF\n stopParsing();\n return;\n case 2: // TAG\n switch(value) {\n case \"html\":\n in_body_mode(t, value, arg3, arg4);\n return;\n case \"noframes\":\n in_head_mode(t, value, arg3, arg4);\n return;\n }\n break;\n }\n\n // ignore anything else\n }\n\n\n // 13.2.5.5 The rules for parsing tokens in foreign content\n //\n // This is like one of the insertion modes above, but is\n // invoked somewhat differently when the current token is not HTML.\n // See the insertToken() function.\n function insertForeignToken(t, value, arg3, arg4) {\n // A tag is an HTML font tag if it has a color, font, or size\n // attribute. Otherwise we assume it is foreign content\n function isHTMLFont(attrs) {\n for(var i = 0, n = attrs.length; i < n; i++) {\n switch(attrs[i][0]) {\n case \"color\":\n case \"face\":\n case \"size\":\n return true;\n }\n }\n return false;\n }\n\n var current;\n\n switch(t) {\n case 1: // TEXT\n // If any non-space, non-nul characters\n if (frameset_ok && NONWSNONNUL.test(value))\n frameset_ok = false;\n if (textIncludesNUL) {\n value = value.replace(NULCHARS, \"\\uFFFD\");\n }\n insertText(value);\n return;\n case 4: // COMMENT\n insertComment(value);\n return;\n case 5: // DOCTYPE\n // ignore it\n return;\n case 2: // TAG\n switch(value) {\n case \"font\":\n if (!isHTMLFont(arg3)) break;\n /* falls through */\n case \"b\":\n case \"big\":\n case \"blockquote\":\n case \"body\":\n case \"br\":\n case \"center\":\n case \"code\":\n case \"dd\":\n case \"div\":\n case \"dl\":\n case \"dt\":\n case \"em\":\n case \"embed\":\n case \"h1\":\n case \"h2\":\n case \"h3\":\n case \"h4\":\n case \"h5\":\n case \"h6\":\n case \"head\":\n case \"hr\":\n case \"i\":\n case \"img\":\n case \"li\":\n case \"listing\":\n case \"menu\":\n case \"meta\":\n case \"nobr\":\n case \"ol\":\n case \"p\":\n case \"pre\":\n case \"ruby\":\n case \"s\":\n case \"small\":\n case \"span\":\n case \"strong\":\n case \"strike\":\n case \"sub\":\n case \"sup\":\n case \"table\":\n case \"tt\":\n case \"u\":\n case \"ul\":\n case \"var\":\n if (fragment) {\n break;\n }\n do {\n stack.pop();\n current = stack.top;\n } while(current.namespaceURI !== NAMESPACE.HTML &&\n !isMathmlTextIntegrationPoint(current) &&\n !isHTMLIntegrationPoint(current));\n\n insertToken(t, value, arg3, arg4); // reprocess\n return;\n }\n\n // Any other start tag case goes here\n current = (stack.elements.length===1 && fragment) ? fragmentContext :\n stack.top;\n if (current.namespaceURI === NAMESPACE.MATHML) {\n adjustMathMLAttributes(arg3);\n }\n else if (current.namespaceURI === NAMESPACE.SVG) {\n value = adjustSVGTagName(value);\n adjustSVGAttributes(arg3);\n }\n adjustForeignAttributes(arg3);\n\n insertForeignElement(value, arg3, current.namespaceURI);\n if (arg4) { // the self-closing flag\n if (value === 'script' && current.namespaceURI === NAMESPACE.SVG) {\n // XXX deal with SVG scripts here\n }\n stack.pop();\n }\n return;\n\n case 3: // ENDTAG\n current = stack.top;\n if (value === \"script\" &&\n current.namespaceURI === NAMESPACE.SVG &&\n current.localName === \"script\") {\n\n stack.pop();\n\n // XXX\n // Deal with SVG scripts here\n }\n else {\n // The any other end tag case\n var i = stack.elements.length-1;\n var node = stack.elements[i];\n for(;;) {\n if (node.localName.toLowerCase() === value) {\n stack.popElement(node);\n break;\n }\n node = stack.elements[--i];\n // If non-html, keep looping\n if (node.namespaceURI !== NAMESPACE.HTML)\n continue;\n // Otherwise process the end tag as html\n parser(t, value, arg3, arg4);\n break;\n }\n }\n return;\n }\n }\n\n /***\n * Finally, this is the end of the HTMLParser() factory function.\n * It returns the htmlparser object with the append() and end() methods.\n */\n\n // Sneak another method into the htmlparser object to allow us to run\n // tokenizer tests. This can be commented out in production code.\n // This is a hook for testing the tokenizer. It has to be here\n // because the tokenizer details are all hidden away within the closure.\n // It should return an array of tokens generated while parsing the\n // input string.\n htmlparser.testTokenizer = function(input, initialState, lastStartTag, charbychar) {\n var tokens = [];\n\n switch(initialState) {\n case \"PCDATA state\":\n tokenizer = data_state;\n break;\n case \"RCDATA state\":\n tokenizer = rcdata_state;\n break;\n case \"RAWTEXT state\":\n tokenizer = rawtext_state;\n break;\n case \"PLAINTEXT state\":\n tokenizer = plaintext_state;\n break;\n }\n\n if (lastStartTag) {\n lasttagname = lastStartTag;\n }\n\n insertToken = function(t, value, arg3, arg4) {\n flushText();\n switch(t) {\n case 1: // TEXT\n if (tokens.length > 0 &&\n tokens[tokens.length-1][0] === \"Character\") {\n tokens[tokens.length-1][1] += value;\n }\n else tokens.push([\"Character\", value]);\n break;\n case 4: // COMMENT\n tokens.push([\"Comment\", value]);\n break;\n case 5: // DOCTYPE\n tokens.push([\"DOCTYPE\", value,\n arg3 === undefined ? null : arg3,\n arg4 === undefined ? null : arg4,\n !force_quirks]);\n break;\n case 2: // TAG\n var attrs = Object.create(null);\n for(var i = 0; i < arg3.length; i++) {\n // XXX: does attribute order matter?\n var a = arg3[i];\n if (a.length === 1) {\n attrs[a[0]] = \"\";\n }\n else {\n attrs[a[0]] = a[1];\n }\n }\n var token = [\"StartTag\", value, attrs];\n if (arg4) token.push(true);\n tokens.push(token);\n break;\n case 3: // ENDTAG\n tokens.push([\"EndTag\", value]);\n break;\n case -1: // EOF\n break;\n }\n };\n\n if (!charbychar) {\n this.parse(input, true);\n }\n else {\n for(var i = 0; i < input.length; i++) {\n this.parse(input[i]);\n }\n this.parse(\"\", true);\n }\n return tokens;\n };\n\n // Return the parser object from the HTMLParser() factory function\n return htmlparser;\n}\n","\"use strict\";\nmodule.exports = DOMImplementation;\n\nvar Document = require('./Document');\nvar DocumentType = require('./DocumentType');\nvar HTMLParser = require('./HTMLParser');\nvar utils = require('./utils');\nvar xml = require('./xmlnames');\n\n// Each document must have its own instance of the domimplementation object\nfunction DOMImplementation(contextObject) {\n this.contextObject = contextObject;\n}\n\n\n// Feature/version pairs that DOMImplementation.hasFeature() returns\n// true for. It returns false for anything else.\nvar supportedFeatures = {\n 'xml': { '': true, '1.0': true, '2.0': true }, // DOM Core\n 'core': { '': true, '2.0': true }, // DOM Core\n 'html': { '': true, '1.0': true, '2.0': true} , // HTML\n 'xhtml': { '': true, '1.0': true, '2.0': true} , // HTML\n};\n\nDOMImplementation.prototype = {\n hasFeature: function hasFeature(feature, version) {\n var f = supportedFeatures[(feature || '').toLowerCase()];\n return (f && f[version || '']) || false;\n },\n\n createDocumentType: function createDocumentType(qualifiedName, publicId, systemId) {\n if (!xml.isValidQName(qualifiedName)) utils.InvalidCharacterError();\n\n return new DocumentType(this.contextObject, qualifiedName, publicId, systemId);\n },\n\n createDocument: function createDocument(namespace, qualifiedName, doctype) {\n //\n // Note that the current DOMCore spec makes it impossible to\n // create an HTML document with this function, even if the\n // namespace and doctype are propertly set. See this thread:\n // http://lists.w3.org/Archives/Public/www-dom/2011AprJun/0132.html\n //\n var d = new Document(false, null);\n var e;\n\n if (qualifiedName)\n e = d.createElementNS(namespace, qualifiedName);\n else\n e = null;\n\n if (doctype) {\n d.appendChild(doctype);\n }\n\n if (e) d.appendChild(e);\n if (namespace === utils.NAMESPACE.HTML) {\n d._contentType = 'application/xhtml+xml';\n } else if (namespace === utils.NAMESPACE.SVG) {\n d._contentType = 'image/svg+xml';\n } else {\n d._contentType = 'application/xml';\n }\n\n return d;\n },\n\n createHTMLDocument: function createHTMLDocument(titleText) {\n var d = new Document(true, null);\n d.appendChild(new DocumentType(d, 'html'));\n var html = d.createElement('html');\n d.appendChild(html);\n var head = d.createElement('head');\n html.appendChild(head);\n if (titleText !== undefined) {\n var title = d.createElement('title');\n head.appendChild(title);\n title.appendChild(d.createTextNode(titleText));\n }\n html.appendChild(d.createElement('body'));\n d.modclock = 1; // Start tracking modifications\n return d;\n },\n\n mozSetOutputMutationHandler: function(doc, handler) {\n doc.mutationHandler = handler;\n },\n\n mozGetInputMutationHandler: function(doc) {\n utils.nyi();\n },\n\n mozHTMLParser: HTMLParser,\n};\n","\"use strict\";\nvar URL = require('./URL');\nvar URLUtils = require('./URLUtils');\n\nmodule.exports = Location;\n\nfunction Location(window, href) {\n this._window = window;\n this._href = href;\n}\n\nLocation.prototype = Object.create(URLUtils.prototype, {\n constructor: { value: Location },\n\n // Special behavior when href is set\n href: {\n get: function() { return this._href; },\n set: function(v) { this.assign(v); }\n },\n\n assign: { value: function(url) {\n // Resolve the new url against the current one\n // XXX:\n // This is not actually correct. It should be resolved against\n // the URL of the document of the script. For now, though, I only\n // support a single window and there is only one base url.\n // So this is good enough for now.\n var current = new URL(this._href);\n var newurl = current.resolve(url);\n\n // Save the new url\n this._href = newurl;\n\n // Start loading the new document!\n // XXX\n // This is just something hacked together.\n // The real algorithm is: http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#navigate\n }},\n\n replace: { value: function(url) {\n // XXX\n // Since we aren't tracking history yet, replace is the same as assign\n this.assign(url);\n }},\n\n reload: { value: function() {\n // XXX:\n // Actually, the spec is a lot more complicated than this\n this.assign(this.href);\n }},\n\n toString: { value: function() {\n return this.href;\n }}\n\n});\n","\"use strict\";\n\n// https://html.spec.whatwg.org/multipage/webappapis.html#navigatorid\nvar NavigatorID = Object.create(null, {\n appCodeName: { value: \"Mozilla\" },\n appName: { value: \"Netscape\" },\n appVersion: { value: \"4.0\" },\n platform: { value: \"\" },\n product: { value: \"Gecko\" },\n productSub: { value: \"20100101\" },\n userAgent: { value: \"\" },\n vendor: { value: \"\" },\n vendorSub: { value: \"\" },\n taintEnabled: { value: function() { return false; } }\n});\n\nmodule.exports = NavigatorID;\n","\"use strict\";\n\n// https://html.spec.whatwg.org/multipage/webappapis.html#windowtimers\nvar WindowTimers = {\n setTimeout: setTimeout,\n clearTimeout: clearTimeout,\n setInterval: setInterval,\n clearInterval: clearInterval\n};\n\nmodule.exports = WindowTimers;\n","\"use strict\";\nvar utils = require('./utils');\n\nexports = module.exports = {\n CSSStyleDeclaration: require('./CSSStyleDeclaration'),\n CharacterData: require('./CharacterData'),\n Comment: require('./Comment'),\n DOMException: require('./DOMException'),\n DOMImplementation: require('./DOMImplementation'),\n DOMTokenList: require('./DOMTokenList'),\n Document: require('./Document'),\n DocumentFragment: require('./DocumentFragment'),\n DocumentType: require('./DocumentType'),\n Element: require('./Element'),\n HTMLParser: require('./HTMLParser'),\n NamedNodeMap: require('./NamedNodeMap'),\n Node: require('./Node'),\n NodeList: require('./NodeList'),\n NodeFilter: require('./NodeFilter'),\n ProcessingInstruction: require('./ProcessingInstruction'),\n Text: require('./Text'),\n Window: require('./Window')\n};\n\nutils.merge(exports, require('./events'));\nutils.merge(exports, require('./htmlelts').elements);\nutils.merge(exports, require('./svg').elements);\n","\"use strict\";\nvar DOMImplementation = require('./DOMImplementation');\nvar EventTarget = require('./EventTarget');\nvar Location = require('./Location');\nvar utils = require('./utils');\n\nmodule.exports = Window;\n\nfunction Window(document) {\n this.document = document || new DOMImplementation(null).createHTMLDocument(\"\");\n this.document._scripting_enabled = true;\n this.document.defaultView = this;\n this.location = new Location(this, this.document._address || 'about:blank');\n}\n\nWindow.prototype = Object.create(EventTarget.prototype, {\n console: { value: console },\n history: { value: {\n back: utils.nyi,\n forward: utils.nyi,\n go: utils.nyi\n }},\n navigator: { value: require(\"./NavigatorID\") },\n\n // Self-referential properties\n window: { get: function() { return this; }},\n self: { get: function() { return this; }},\n frames: { get: function() { return this; }},\n\n // Self-referential properties for a top-level window\n parent: { get: function() { return this; }},\n top: { get: function() { return this; }},\n\n // We don't support any other windows for now\n length: { value: 0 }, // no frames\n frameElement: { value: null }, // not part of a frame\n opener: { value: null }, // not opened by another window\n\n // The onload event handler.\n // XXX: need to support a bunch of other event types, too,\n // and have them interoperate with document.body.\n\n onload: {\n get: function() {\n return this._getEventHandler(\"load\");\n },\n set: function(v) {\n this._setEventHandler(\"load\", v);\n }\n },\n\n // XXX This is a completely broken implementation\n getComputedStyle: { value: function getComputedStyle(elt) {\n return elt.style;\n }}\n\n});\n\nutils.expose(require('./WindowTimers'), Window);\nutils.expose(require('./impl'), Window);\n","\"use strict\";\nvar DOMImplementation = require('./DOMImplementation');\nvar HTMLParser = require('./HTMLParser');\nvar Window = require('./Window');\nvar impl = require('./impl');\n\nexports.createDOMImplementation = function() {\n return new DOMImplementation(null);\n};\n\nexports.createDocument = function(html, force) {\n // Previous API couldn't let you pass '' as a document, and that\n // yields a slightly different document than createHTMLDocument('')\n // does. The new `force` parameter lets you pass '' if you want to.\n if (html || force) {\n var parser = new HTMLParser();\n parser.parse(html || '', true);\n return parser.document();\n }\n return new DOMImplementation(null).createHTMLDocument(\"\");\n};\n\nexports.createIncrementalHTMLParser = function() {\n var parser = new HTMLParser();\n /** API for incremental parser. */\n return {\n /** Provide an additional chunk of text to be parsed. */\n write: function(s) {\n if (s.length > 0) {\n parser.parse(s, false, function() { return true; });\n }\n },\n /**\n * Signal that we are done providing input text, optionally\n * providing one last chunk as a parameter.\n */\n end: function(s) {\n parser.parse(s || '', true, function() { return true; });\n },\n /**\n * Performs a chunk of parsing work, returning at the end of\n * the next token as soon as shouldPauseFunc() returns true.\n * Returns true iff there is more work to do.\n *\n * For example:\n * ```\n * var incrParser = domino.createIncrementalHTMLParser();\n * incrParser.end('...long html document...');\n * while (true) {\n * // Pause every 10ms\n * var start = Date.now();\n * var pauseIn10 = function() { return (Date.now() - start) >= 10; };\n * if (!incrParser.process(pauseIn10)) {\n * break;\n * }\n * ...yield to other tasks, do other housekeeping, etc...\n * }\n * ```\n */\n process: function(shouldPauseFunc) {\n return parser.parse('', false, shouldPauseFunc);\n },\n /**\n * Returns the result of the incremental parse. Valid after\n * `this.end()` has been called and `this.process()` has returned\n * false.\n */\n document: function() {\n return parser.document();\n },\n }; \n};\n\nexports.createWindow = function(html, address) {\n var document = exports.createDocument(html);\n if (address !== undefined) { document._address = address; }\n return new impl.Window(document);\n};\n\nexports.impl = impl;","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ɵsetRootDomAdapter as setRootDomAdapter} from '@angular/common';\nimport {ɵBrowserDomAdapter as BrowserDomAdapter} from '@angular/platform-browser';\n\nimport domino from './bundled-domino';\n\nexport function setDomTypes() {\n // Make all Domino types available in the global env.\n // NB: Any changes here should also be done in `packages/platform-server/init/src/shims.ts`.\n Object.assign(globalThis, domino.impl);\n (globalThis as any)['KeyboardEvent'] = domino.impl.Event;\n}\n\n/**\n * Parses a document string to a Document object.\n */\nexport function parseDocument(html: string, url = '/') {\n let window = domino.createWindow(html, url);\n let doc = window.document;\n return doc;\n}\n\n/**\n * Serializes a document to string.\n */\nexport function serializeDocument(doc: Document): string {\n return (doc as any).serialize();\n}\n\n/**\n * DOM Adapter for the server platform based on https://github.com/fgnass/domino.\n */\nexport class DominoAdapter extends BrowserDomAdapter {\n static override makeCurrent() {\n setDomTypes();\n setRootDomAdapter(new DominoAdapter());\n }\n\n override readonly supportsDOMEvents = false;\n private static defaultDoc: Document;\n\n override createHtmlDocument(): Document {\n return parseDocument('fakeTitle');\n }\n\n override getDefaultDocument(): Document {\n if (!DominoAdapter.defaultDoc) {\n DominoAdapter.defaultDoc = domino.createDocument();\n }\n return DominoAdapter.defaultDoc;\n }\n\n override isElementNode(node: any): boolean {\n return node ? node.nodeType === DominoAdapter.defaultDoc.ELEMENT_NODE : false;\n }\n override isShadowRoot(node: any): boolean {\n return node.shadowRoot == node;\n }\n\n /** @deprecated No longer being used in Ivy code. To be removed in version 14. */\n override getGlobalEventTarget(doc: Document, target: string): EventTarget|null {\n if (target === 'window') {\n return doc.defaultView;\n }\n if (target === 'document') {\n return doc;\n }\n if (target === 'body') {\n return doc.body;\n }\n return null;\n }\n\n override getBaseHref(doc: Document): string {\n // TODO(alxhub): Need relative path logic from BrowserDomAdapter here?\n return doc.documentElement!.querySelector('base')?.getAttribute('href') || '';\n }\n\n override dispatchEvent(el: Node, evt: any) {\n el.dispatchEvent(evt);\n\n // Dispatch the event to the window also.\n const doc = el.ownerDocument || el;\n const win = (doc as any).defaultView;\n if (win) {\n win.dispatchEvent(evt);\n }\n }\n\n override getUserAgent(): string {\n return 'Fake user agent';\n }\n\n override getCookie(name: string): string {\n throw new Error('getCookie has not been implemented');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {DOCUMENT} from '@angular/common';\nimport {Inject, Injectable} from '@angular/core';\n\nimport {serializeDocument} from './domino_adapter';\n\n/**\n * Representation of the current platform state.\n *\n * @publicApi\n */\n@Injectable()\nexport class PlatformState {\n constructor(@Inject(DOCUMENT) private _doc: any) {}\n\n /**\n * Renders the current state of the platform to string.\n */\n renderToString(): string {\n return serializeDocument(this._doc);\n }\n\n /**\n * Returns the current DOM state.\n */\n getDocument(): any {\n return this._doc;\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {PlatformLocation, XhrFactory} from '@angular/common';\nimport {HttpEvent, HttpHandlerFn, HttpRequest, ɵHTTP_ROOT_INTERCEPTOR_FNS as HTTP_ROOT_INTERCEPTOR_FNS} from '@angular/common/http';\nimport {inject, Injectable, Provider} from '@angular/core';\nimport {Observable} from 'rxjs';\n\n@Injectable()\nexport class ServerXhr implements XhrFactory {\n private xhrImpl: typeof import('xhr2')|undefined;\n\n // The `xhr2` dependency has a side-effect of accessing and modifying a\n // global scope. Loading `xhr2` dynamically allows us to delay the loading\n // and start the process once the global scope is established by the underlying\n // server platform (via shims, etc).\n private async ɵloadImpl(): Promise {\n if (!this.xhrImpl) {\n const {default: xhr} = await import('xhr2');\n this.xhrImpl = xhr;\n }\n }\n\n build(): XMLHttpRequest {\n const impl = this.xhrImpl;\n if (!impl) {\n throw new Error('Unexpected state in ServerXhr: XHR implementation is not loaded.');\n }\n\n return new impl.XMLHttpRequest();\n }\n}\n\nfunction relativeUrlsTransformerInterceptorFn(\n request: HttpRequest, next: HttpHandlerFn): Observable> {\n const platformLocation = inject(PlatformLocation);\n const {href, protocol, hostname, port} = platformLocation;\n if (!protocol.startsWith('http')) {\n return next(request);\n }\n\n let urlPrefix = `${protocol}//${hostname}`;\n if (port) {\n urlPrefix += `:${port}`;\n }\n\n const baseHref = platformLocation.getBaseHrefFromDOM() || href;\n const baseUrl = new URL(baseHref, urlPrefix);\n const newUrl = new URL(request.url, baseUrl).toString();\n\n return next(request.clone({url: newUrl}));\n}\n\nexport const SERVER_HTTP_PROVIDERS: Provider[] = [\n {provide: XhrFactory, useClass: ServerXhr},\n {\n provide: HTTP_ROOT_INTERCEPTOR_FNS,\n useValue: relativeUrlsTransformerInterceptorFn,\n multi: true,\n },\n];\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken} from '@angular/core';\n\n/**\n * Config object passed to initialize the platform.\n *\n * @publicApi\n */\nexport interface PlatformConfig {\n /**\n * The initial DOM to use to bootstrap the server application.\n * @default create a new DOM using Domino\n */\n document?: string;\n /**\n * The URL for the current application state. This is used for initializing\n * the platform's location. `protocol`, `hostname`, and `port` will be\n * overridden if `baseUrl` is set.\n * @default none\n */\n url?: string;\n /**\n * Note: this option has no effect and can be removed from the config.\n *\n * Whether to append the absolute URL to any relative HTTP requests. If set to\n * true, this logic executes prior to any HTTP interceptors that may run later\n * on in the request. `baseUrl` must be supplied if this flag is enabled.\n *\n * @deprecated This option is a noop.\n * @default false\n */\n useAbsoluteUrl?: boolean;\n /**\n * Note: this option has no effect and can be removed from the config.\n *\n * The base URL for resolving absolute URL for HTTP requests. It must be set\n * if `useAbsoluteUrl` is true, and must consist of protocol, hostname,\n * and optional port. This option has no effect if `useAbsoluteUrl` is not\n * enabled.\n *\n * @deprecated This option is a noop.\n */\n baseUrl?: string;\n}\n\n/**\n * The DI token for setting the initial config for the platform.\n *\n * @publicApi\n */\nexport const INITIAL_CONFIG = new InjectionToken('Server.INITIAL_CONFIG');\n\n/**\n * A function that will be executed when calling `renderApplication` or\n * `renderModule` just before current platform state is rendered to string.\n *\n * @publicApi\n */\nexport const BEFORE_APP_SERIALIZED =\n new InjectionToken void | Promise>>('Server.RENDER_MODULE_HOOK');\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {DOCUMENT, LocationChangeEvent, LocationChangeListener, PlatformLocation, ɵgetDOM as getDOM} from '@angular/common';\nimport {Inject, Injectable, Optional, ɵWritable as Writable} from '@angular/core';\nimport {Subject} from 'rxjs';\n\nimport {INITIAL_CONFIG, PlatformConfig} from './tokens';\n\nconst RESOLVE_PROTOCOL = 'resolve:';\n\nfunction parseUrl(urlStr: string): {\n hostname: string,\n protocol: string,\n port: string,\n pathname: string,\n search: string,\n hash: string,\n} {\n let {hostname, protocol, port, pathname, search, hash} = new URL(urlStr, RESOLVE_PROTOCOL + '//');\n\n /**\n * TODO(alanagius): Remove the below in version 18.\n * The following are done to maintain the same behaviour as `url.parse`.\n * The main differences are;\n * - `pathname` is always suffixed with a `/`.\n * - `port` is empty when `http:` protocol and port in url is `80`\n * - `port` is empty when `https:` protocol and port in url is `443`\n */\n if (protocol !== RESOLVE_PROTOCOL && port === '' && /\\:(80|443)/.test(urlStr)) {\n port = protocol === 'http:' ? '80' : '443';\n }\n\n if (protocol === RESOLVE_PROTOCOL && urlStr.charAt(0) !== '/') {\n pathname = pathname.slice(1); // Remove leading slash.\n }\n // END TODO\n\n return {\n hostname,\n protocol: protocol === RESOLVE_PROTOCOL ? '' : protocol,\n port,\n pathname,\n search,\n hash,\n };\n}\n\n/**\n * Server-side implementation of URL state. Implements `pathname`, `search`, and `hash`\n * but not the state stack.\n */\n@Injectable()\nexport class ServerPlatformLocation implements PlatformLocation {\n public readonly href: string = '/';\n public readonly hostname: string = '/';\n public readonly protocol: string = '/';\n public readonly port: string = '/';\n public readonly pathname: string = '/';\n public readonly search: string = '';\n public readonly hash: string = '';\n private _hashUpdate = new Subject();\n\n constructor(\n @Inject(DOCUMENT) private _doc: any, @Optional() @Inject(INITIAL_CONFIG) _config: any) {\n const config = _config as PlatformConfig | null;\n if (!config) {\n return;\n }\n if (config.url) {\n const url = parseUrl(config.url);\n this.protocol = url.protocol;\n this.hostname = url.hostname;\n this.port = url.port;\n this.pathname = url.pathname;\n this.search = url.search;\n this.hash = url.hash;\n this.href = _doc.location.href;\n }\n if (config.useAbsoluteUrl) {\n if (!config.baseUrl) {\n throw new Error(`\"PlatformConfig.baseUrl\" must be set if \"useAbsoluteUrl\" is true`);\n }\n const url = parseUrl(config.baseUrl);\n this.protocol = url.protocol;\n this.hostname = url.hostname;\n this.port = url.port;\n }\n }\n\n getBaseHrefFromDOM(): string {\n return getDOM().getBaseHref(this._doc)!;\n }\n\n onPopState(fn: LocationChangeListener): VoidFunction {\n // No-op: a state stack is not implemented, so\n // no events will ever come.\n return () => {};\n }\n\n onHashChange(fn: LocationChangeListener): VoidFunction {\n const subscription = this._hashUpdate.subscribe(fn);\n return () => subscription.unsubscribe();\n }\n\n get url(): string {\n return `${this.pathname}${this.search}${this.hash}`;\n }\n\n private setHash(value: string, oldUrl: string) {\n if (this.hash === value) {\n // Don't fire events if the hash has not changed.\n return;\n }\n (this as Writable).hash = value;\n const newUrl = this.url;\n queueMicrotask(\n () => this._hashUpdate.next(\n {type: 'hashchange', state: null, oldUrl, newUrl} as LocationChangeEvent));\n }\n\n replaceState(state: any, title: string, newUrl: string): void {\n const oldUrl = this.url;\n const parsedUrl = parseUrl(newUrl);\n (this as Writable).pathname = parsedUrl.pathname;\n (this as Writable).search = parsedUrl.search;\n this.setHash(parsedUrl.hash, oldUrl);\n }\n\n pushState(state: any, title: string, newUrl: string): void {\n this.replaceState(state, title, newUrl);\n }\n\n forward(): void {\n throw new Error('Not implemented');\n }\n\n back(): void {\n throw new Error('Not implemented');\n }\n\n // History API isn't available on server, therefore return undefined\n getState(): unknown {\n return undefined;\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {DOCUMENT, ɵgetDOM as getDOM} from '@angular/common';\nimport {Inject, Injectable} from '@angular/core';\nimport {EventManagerPlugin} from '@angular/platform-browser';\n\n@Injectable()\nexport class ServerEventManagerPlugin extends EventManagerPlugin {\n constructor(@Inject(DOCUMENT) private doc: any) {\n super(doc);\n }\n\n // Handle all events on the server.\n override supports(eventName: string) {\n return true;\n }\n\n override addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {\n return getDOM().onAndCancel(element, eventName, handler);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {DOCUMENT} from '@angular/common';\nimport {APP_ID, NgModule, Provider, TransferState} from '@angular/core';\n\nimport {BEFORE_APP_SERIALIZED} from './tokens';\n\nexport const TRANSFER_STATE_SERIALIZATION_PROVIDERS: Provider[] = [{\n provide: BEFORE_APP_SERIALIZED,\n useFactory: serializeTransferStateFactory,\n deps: [DOCUMENT, APP_ID, TransferState],\n multi: true,\n}];\n\nfunction serializeTransferStateFactory(doc: Document, appId: string, transferStore: TransferState) {\n return () => {\n // The `.toJSON` here causes the `onSerialize` callbacks to be called.\n // These callbacks can be used to provide the value for a given key.\n const content = transferStore.toJson();\n\n if (transferStore.isEmpty) {\n // The state is empty, nothing to transfer,\n // avoid creating an extra `