{"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 = '' + parentTag;\n if (!rawText.toLowerCase().includes(parentClosingTag)) {\n return rawText; // fast path\n }\n const result = [...rawText];\n const matches = rawText.matchAll(new RegExp(parentClosingTag, 'ig'));\n for (const match of matches) {\n result[match.index] = '<';\n }\n return result.join('');\n}\n\nconst CLOSING_COMMENT_REGEXP = /--!?>/;\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 += '' + tagname + '>';\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 += '' + kid.target + ' ' + content + '?>';\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