text: /*!
  ISC License
  
  Copyright (c) 2014-2018, Andrea Giammarchi, @WebReflection
  
  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.
  
  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  PERFORMANCE OF THIS SOFTWARE.
  
  */
  (function(window, polyfill){'use strict';
  
    // DO NOT USE THIS FILE DIRECTLY, IT WON'T WORK
    // THIS IS A PROJECT BASED ON A BUILD SYSTEM
    // THIS FILE IS JUST WRAPPED UP RESULTING IN
    // build/document-register-element.js
    // and its .max.js counter part
  
    var
      document = window.document,
      Object = window.Object
    ;
  
    var htmlClass = (function (info) {
      // (C) Andrea Giammarchi - @WebReflection - MIT Style
      var
        catchClass = /^[A-Z]+[a-z]/,
        filterBy = function (re) {
          var arr = [], tag;
          for (tag in register) {
            if (re.test(tag)) arr.push(tag);
          }
          return arr;
        },
        add = function (Class, tag) {
          tag = tag.toLowerCase();
          if (!(tag in register)) {
            register[Class] = (register[Class] || []).concat(tag);
            register[tag] = (register[tag.toUpperCase()] = Class);
          }
        },
        register = (Object.create || Object)(null),
        htmlClass = {},
        i, section, tags, Class
      ;
      for (section in info) {
        for (Class in info[section]) {
          tags = info[section][Class];
          register[Class] = tags;
          for (i = 0; i < tags.length; i++) {
            register[tags[i].toLowerCase()] =
            register[tags[i].toUpperCase()] = Class;
          }
        }
      }
      htmlClass.get = function get(tagOrClass) {
        return typeof tagOrClass === 'string' ?
          (register[tagOrClass] || (catchClass.test(tagOrClass) ? [] : '')) :
          filterBy(tagOrClass);
      };
      htmlClass.set = function set(tag, Class) {
        return (catchClass.test(tag) ?
          add(tag, Class) :
          add(Class, tag)
        ), htmlClass;
      };
      return htmlClass;
    }({
      "collections": {
        "HTMLAllCollection": [
          "all"
        ],
        "HTMLCollection": [
          "forms"
        ],
        "HTMLFormControlsCollection": [
          "elements"
        ],
        "HTMLOptionsCollection": [
          "options"
        ]
      },
      "elements": {
        "Element": [
          "element"
        ],
        "HTMLAnchorElement": [
          "a"
        ],
        "HTMLAppletElement": [
          "applet"
        ],
        "HTMLAreaElement": [
          "area"
        ],
        "HTMLAttachmentElement": [
          "attachment"
        ],
        "HTMLAudioElement": [
          "audio"
        ],
        "HTMLBRElement": [
          "br"
        ],
        "HTMLBaseElement": [
          "base"
        ],
        "HTMLBodyElement": [
          "body"
        ],
        "HTMLButtonElement": [
          "button"
        ],
        "HTMLCanvasElement": [
          "canvas"
        ],
        "HTMLContentElement": [
          "content"
        ],
        "HTMLDListElement": [
          "dl"
        ],
        "HTMLDataElement": [
          "data"
        ],
        "HTMLDataListElement": [
          "datalist"
        ],
        "HTMLDetailsElement": [
          "details"
        ],
        "HTMLDialogElement": [
          "dialog"
        ],
        "HTMLDirectoryElement": [
          "dir"
        ],
        "HTMLDivElement": [
          "div"
        ],
        "HTMLDocument": [
          "document"
        ],
        "HTMLElement": [
          "element",
          "abbr",
          "address",
          "article",
          "aside",
          "b",
          "bdi",
          "bdo",
          "cite",
          "code",
          "command",
          "dd",
          "dfn",
          "dt",
          "em",
          "figcaption",
          "figure",
          "footer",
          "header",
          "i",
          "kbd",
          "mark",
          "nav",
          "noscript",
          "rp",
          "rt",
          "ruby",
          "s",
          "samp",
          "section",
          "small",
          "strong",
          "sub",
          "summary",
          "sup",
          "u",
          "var",
          "wbr"
        ],
        "HTMLEmbedElement": [
          "embed"
        ],
        "HTMLFieldSetElement": [
          "fieldset"
        ],
        "HTMLFontElement": [
          "font"
        ],
        "HTMLFormElement": [
          "form"
        ],
        "HTMLFrameElement": [
          "frame"
        ],
        "HTMLFrameSetElement": [
          "frameset"
        ],
        "HTMLHRElement": [
          "hr"
        ],
        "HTMLHeadElement": [
          "head"
        ],
        "HTMLHeadingElement": [
          "h1",
          "h2",
          "h3",
          "h4",
          "h5",
          "h6"
        ],
        "HTMLHtmlElement": [
          "html"
        ],
        "HTMLIFrameElement": [
          "iframe"
        ],
        "HTMLImageElement": [
          "img"
        ],
        "HTMLInputElement": [
          "input"
        ],
        "HTMLKeygenElement": [
          "keygen"
        ],
        "HTMLLIElement": [
          "li"
        ],
        "HTMLLabelElement": [
          "label"
        ],
        "HTMLLegendElement": [
          "legend"
        ],
        "HTMLLinkElement": [
          "link"
        ],
        "HTMLMapElement": [
          "map"
        ],
        "HTMLMarqueeElement": [
          "marquee"
        ],
        "HTMLMediaElement": [
          "media"
        ],
        "HTMLMenuElement": [
          "menu"
        ],
        "HTMLMenuItemElement": [
          "menuitem"
        ],
        "HTMLMetaElement": [
          "meta"
        ],
        "HTMLMeterElement": [
          "meter"
        ],
        "HTMLModElement": [
          "del",
          "ins"
        ],
        "HTMLOListElement": [
          "ol"
        ],
        "HTMLObjectElement": [
          "object"
        ],
        "HTMLOptGroupElement": [
          "optgroup"
        ],
        "HTMLOptionElement": [
          "option"
        ],
        "HTMLOutputElement": [
          "output"
        ],
        "HTMLParagraphElement": [
          "p"
        ],
        "HTMLParamElement": [
          "param"
        ],
        "HTMLPictureElement": [
          "picture"
        ],
        "HTMLPreElement": [
          "pre"
        ],
        "HTMLProgressElement": [
          "progress"
        ],
        "HTMLQuoteElement": [
          "blockquote",
          "q",
          "quote"
        ],
        "HTMLScriptElement": [
          "script"
        ],
        "HTMLSelectElement": [
          "select"
        ],
        "HTMLShadowElement": [
          "shadow"
        ],
        "HTMLSlotElement": [
          "slot"
        ],
        "HTMLSourceElement": [
          "source"
        ],
        "HTMLSpanElement": [
          "span"
        ],
        "HTMLStyleElement": [
          "style"
        ],
        "HTMLTableCaptionElement": [
          "caption"
        ],
        "HTMLTableCellElement": [
          "td",
          "th"
        ],
        "HTMLTableColElement": [
          "col",
          "colgroup"
        ],
        "HTMLTableElement": [
          "table"
        ],
        "HTMLTableRowElement": [
          "tr"
        ],
        "HTMLTableSectionElement": [
          "thead",
          "tbody",
          "tfoot"
        ],
        "HTMLTemplateElement": [
          "template"
        ],
        "HTMLTextAreaElement": [
          "textarea"
        ],
        "HTMLTimeElement": [
          "time"
        ],
        "HTMLTitleElement": [
          "title"
        ],
        "HTMLTrackElement": [
          "track"
        ],
        "HTMLUListElement": [
          "ul"
        ],
        "HTMLUnknownElement": [
          "unknown",
          "vhgroupv",
          "vkeygen"
        ],
        "HTMLVideoElement": [
          "video"
        ]
      },
      "nodes": {
        "Attr": [
          "node"
        ],
        "Audio": [
          "audio"
        ],
        "CDATASection": [
          "node"
        ],
        "CharacterData": [
          "node"
        ],
        "Comment": [
          "#comment"
        ],
        "Document": [
          "#document"
        ],
        "DocumentFragment": [
          "#document-fragment"
        ],
        "DocumentType": [
          "node"
        ],
        "HTMLDocument": [
          "#document"
        ],
        "Image": [
          "img"
        ],
        "Option": [
          "option"
        ],
        "ProcessingInstruction": [
          "node"
        ],
        "ShadowRoot": [
          "#shadow-root"
        ],
        "Text": [
          "#text"
        ],
        "XMLDocument": [
          "xml"
        ]
      }
    }));
    
    
      
    // passed at runtime, configurable via nodejs module
    if (typeof polyfill !== 'object') polyfill = {type: polyfill || 'auto'};
    
    var
      // V0 polyfill entry
      REGISTER_ELEMENT = 'registerElement',
    
      // IE < 11 only + old WebKit for attributes + feature detection
      EXPANDO_UID = '__' + REGISTER_ELEMENT + (window.Math.random() * 10e4 >> 0),
    
      // shortcuts and costants
      ADD_EVENT_LISTENER = 'addEventListener',
      ATTACHED = 'attached',
      CALLBACK = 'Callback',
      DETACHED = 'detached',
      EXTENDS = 'extends',
    
      ATTRIBUTE_CHANGED_CALLBACK = 'attributeChanged' + CALLBACK,
      ATTACHED_CALLBACK = ATTACHED + CALLBACK,
      CONNECTED_CALLBACK = 'connected' + CALLBACK,
      DISCONNECTED_CALLBACK = 'disconnected' + CALLBACK,
      CREATED_CALLBACK = 'created' + CALLBACK,
      DETACHED_CALLBACK = DETACHED + CALLBACK,
    
      ADDITION = 'ADDITION',
      MODIFICATION = 'MODIFICATION',
      REMOVAL = 'REMOVAL',
    
      DOM_ATTR_MODIFIED = 'DOMAttrModified',
      DOM_CONTENT_LOADED = 'DOMContentLoaded',
      DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified',
    
      PREFIX_TAG = '<',
      PREFIX_IS = '=',
    
      // valid and invalid node names
      validName = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,
      invalidNames = [
        'ANNOTATION-XML',
        'COLOR-PROFILE',
        'FONT-FACE',
        'FONT-FACE-SRC',
        'FONT-FACE-URI',
        'FONT-FACE-FORMAT',
        'FONT-FACE-NAME',
        'MISSING-GLYPH'
      ],
    
      // registered types and their prototypes
      types = [],
      protos = [],
    
      // to query subnodes
      query = '',
    
      // html shortcut used to feature detect
      documentElement = document.documentElement,
    
      // ES5 inline helpers || basic patches
      indexOf = types.indexOf || function (v) {
        for(var i = this.length; i-- && this[i] !== v;){}
        return i;
      },
    
      // other helpers / shortcuts
      OP = Object.prototype,
      hOP = OP.hasOwnProperty,
      iPO = OP.isPrototypeOf,
    
      defineProperty = Object.defineProperty,
      empty = [],
      gOPD = Object.getOwnPropertyDescriptor,
      gOPN = Object.getOwnPropertyNames,
      gPO = Object.getPrototypeOf,
      sPO = Object.setPrototypeOf,
    
      // jshint proto: true
      hasProto = !!Object.__proto__,
    
      // V1 helpers
      fixGetClass = false,
      DRECEV1 = '__dreCEv1',
      customElements = window.customElements,
      usableCustomElements = !/^force/.test(polyfill.type) && !!(
        customElements &&
        customElements.define &&
        customElements.get &&
        customElements.whenDefined
      ),
      Dict = Object.create || Object,
      Map = window.Map || function Map() {
        var K = [], V = [], i;
        return {
          get: function (k) {
            return V[indexOf.call(K, k)];
          },
          set: function (k, v) {
            i = indexOf.call(K, k);
            if (i < 0) V[K.push(k) - 1] = v;
            else V[i] = v;
          }
        };
      },
      Promise = window.Promise || function (fn) {
        var
          notify = [],
          done = false,
          p = {
            'catch': function () {
              return p;
            },
            'then': function (cb) {
              notify.push(cb);
              if (done) setTimeout(resolve, 1);
              return p;
            }
          }
        ;
        function resolve(value) {
          done = true;
          while (notify.length) notify.shift()(value);
        }
        fn(resolve);
        return p;
      },
      justCreated = false,
      constructors = Dict(null),
      waitingList = Dict(null),
      nodeNames = new Map(),
      secondArgument = function (is) {
        return is.toLowerCase();
      },
    
      // used to create unique instances
      create = Object.create || function Bridge(proto) {
        // silly broken polyfill probably ever used but short enough to work
        return proto ? ((Bridge.prototype = proto), new Bridge()) : this;
      },
    
      // will set the prototype if possible
      // or copy over all properties
      setPrototype = sPO || (
        hasProto ?
          function (o, p) {
            o.__proto__ = p;
            return o;
          } : (
        (gOPN && gOPD) ?
          (function(){
            function setProperties(o, p) {
              for (var
                key,
                names = gOPN(p),
                i = 0, length = names.length;
                i < length; i++
              ) {
                key = names[i];
                if (!hOP.call(o, key)) {
                  defineProperty(o, key, gOPD(p, key));
                }
              }
            }
            return function (o, p) {
              do {
                setProperties(o, p);
              } while ((p = gPO(p)) && !iPO.call(p, o));
              return o;
            };
          }()) :
          function (o, p) {
            for (var key in p) {
              o[key] = p[key];
            }
            return o;
          }
      )),
    
      // DOM shortcuts and helpers, if any
    
      MutationObserver = window.MutationObserver ||
                         window.WebKitMutationObserver,
    
      HTMLElementPrototype = (
        window.HTMLElement ||
        window.Element ||
        window.Node
      ).prototype,
    
      IE8 = !iPO.call(HTMLElementPrototype, documentElement),
    
      safeProperty = IE8 ? function (o, k, d) {
        o[k] = d.value;
        return o;
      } : defineProperty,
    
      isValidNode = IE8 ?
        function (node) {
          return node.nodeType === 1;
        } :
        function (node) {
          return iPO.call(HTMLElementPrototype, node);
        },
    
      targets = IE8 && [],
    
      attachShadow = HTMLElementPrototype.attachShadow,
      cloneNode = HTMLElementPrototype.cloneNode,
      dispatchEvent = HTMLElementPrototype.dispatchEvent,
      getAttribute = HTMLElementPrototype.getAttribute,
      hasAttribute = HTMLElementPrototype.hasAttribute,
      removeAttribute = HTMLElementPrototype.removeAttribute,
      setAttribute = HTMLElementPrototype.setAttribute,
    
      // replaced later on
      createElement = document.createElement,
      importNode = document.importNode,
      patchedCreateElement = createElement,
    
      // shared observer for all attributes
      attributesObserver = MutationObserver && {
        attributes: true,
        characterData: true,
        attributeOldValue: true
      },
    
      // useful to detect only if there's no MutationObserver
      DOMAttrModified = MutationObserver || function(e) {
        doesNotSupportDOMAttrModified = false;
        documentElement.removeEventListener(
          DOM_ATTR_MODIFIED,
          DOMAttrModified
        );
      },
    
      // will both be used to make DOMNodeInserted asynchronous
      asapQueue,
      asapTimer = 0,
    
      // internal flags
      V0 = REGISTER_ELEMENT in document &&
           !/^force-all/.test(polyfill.type),
      setListener = true,
      justSetup = false,
      doesNotSupportDOMAttrModified = true,
      dropDomContentLoaded = true,
    
      // needed for the innerHTML helper
      notFromInnerHTMLHelper = true,
    
      // optionally defined later on
      onSubtreeModified,
      callDOMAttrModified,
      getAttributesMirror,
      observer,
      observe,
    
      // based on setting prototype capability
      // will check proto or the expando attribute
      // in order to setup the node once
      patchIfNotAlready,
      patch,
    
      // used for tests
      tmp
    ;
    
    // IE11 disconnectedCallback issue #
    // to be tested before any createElement patch
    if (MutationObserver) {
      // original fix:
      // https://github.com/javan/mutation-observer-inner-html-shim
      tmp = document.createElement('div');
      tmp.innerHTML = '<div><div></div></div>';
      new MutationObserver(function (mutations, observer) {
        if (
          mutations[0] &&
          mutations[0].type == 'childList' &&
          !mutations[0].removedNodes[0].childNodes.length
        ) {
          tmp = gOPD(HTMLElementPrototype, 'innerHTML');
          var set = tmp && tmp.set;
          if (set)
            defineProperty(HTMLElementPrototype, 'innerHTML', {
              set: function (value) {
                while (this.lastChild)
                  this.removeChild(this.lastChild);
                set.call(this, value);
              }
            });
        }
        observer.disconnect();
        tmp = null;
      }).observe(tmp, {childList: true, subtree: true});
      tmp.innerHTML = "";
    }
    
    // only if needed
    if (!V0) {
    
      if (sPO || hasProto) {
          patchIfNotAlready = function (node, proto) {
            if (!iPO.call(proto, node)) {
              setupNode(node, proto);
            }
          };
          patch = setupNode;
      } else {
          patchIfNotAlready = function (node, proto) {
            if (!node[EXPANDO_UID]) {
              node[EXPANDO_UID] = Object(true);
              setupNode(node, proto);
            }
          };
          patch = patchIfNotAlready;
      }
    
      if (IE8) {
        doesNotSupportDOMAttrModified = false;
        (function (){
          var
            descriptor = gOPD(HTMLElementPrototype, ADD_EVENT_LISTENER),
            addEventListener = descriptor.value,
            patchedRemoveAttribute = function (name) {
              var e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true});
              e.attrName = name;
              e.prevValue = getAttribute.call(this, name);
              e.newValue = null;
              e[REMOVAL] = e.attrChange = 2;
              removeAttribute.call(this, name);
              dispatchEvent.call(this, e);
            },
            patchedSetAttribute = function (name, value) {
              var
                had = hasAttribute.call(this, name),
                old = had && getAttribute.call(this, name),
                e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true})
              ;
              setAttribute.call(this, name, value);
              e.attrName = name;
              e.prevValue = had ? old : null;
              e.newValue = value;
              if (had) {
                e[MODIFICATION] = e.attrChange = 1;
              } else {
                e[ADDITION] = e.attrChange = 0;
              }
              dispatchEvent.call(this, e);
            },
            onPropertyChange = function (e) {
              // jshint eqnull:true
              var
                node = e.currentTarget,
                superSecret = node[EXPANDO_UID],
                propertyName = e.propertyName,
                event
              ;
              if (superSecret.hasOwnProperty(propertyName)) {
                superSecret = superSecret[propertyName];
                event = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true});
                event.attrName = superSecret.name;
                event.prevValue = superSecret.value || null;
                event.newValue = (superSecret.value = node[propertyName] || null);
                if (event.prevValue == null) {
                  event[ADDITION] = event.attrChange = 0;
                } else {
                  event[MODIFICATION] = event.attrChange = 1;
                }
                dispatchEvent.call(node, event);
              }
            }
          ;
          descriptor.value = function (type, handler, capture) {
            if (
              type === DOM_ATTR_MODIFIED &&
              this[ATTRIBUTE_CHANGED_CALLBACK] &&
              this.setAttribute !== patchedSetAttribute
            ) {
              this[EXPANDO_UID] = {
                className: {
                  name: 'class',
                  value: this.className
                }
              };
              this.setAttribute = patchedSetAttribute;
              this.removeAttribute = patchedRemoveAttribute;
              addEventListener.call(this, 'propertychange', onPropertyChange);
            }
            addEventListener.call(this, type, handler, capture);
          };
          defineProperty(HTMLElementPrototype, ADD_EVENT_LISTENER, descriptor);
        }());
      } else if (!MutationObserver) {
        documentElement[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, DOMAttrModified);
        documentElement.setAttribute(EXPANDO_UID, 1);
        documentElement.removeAttribute(EXPANDO_UID);
        if (doesNotSupportDOMAttrModified) {
          onSubtreeModified = function (e) {
            var
              node = this,
              oldAttributes,
              newAttributes,
              key
            ;
            if (node === e.target) {
              oldAttributes = node[EXPANDO_UID];
              node[EXPANDO_UID] = (newAttributes = getAttributesMirror(node));
              for (key in newAttributes) {
                if (!(key in oldAttributes)) {
                  // attribute was added
                  return callDOMAttrModified(
                    0,
                    node,
                    key,
                    oldAttributes[key],
                    newAttributes[key],
                    ADDITION
                  );
                } else if (newAttributes[key] !== oldAttributes[key]) {
                  // attribute was changed
                  return callDOMAttrModified(
                    1,
                    node,
                    key,
                    oldAttributes[key],
                    newAttributes[key],
                    MODIFICATION
                  );
                }
              }
              // checking if it has been removed
              for (key in oldAttributes) {
                if (!(key in newAttributes)) {
                  // attribute removed
                  return callDOMAttrModified(
                    2,
                    node,
                    key,
                    oldAttributes[key],
                    newAttributes[key],
                    REMOVAL
                  );
                }
              }
            }
          };
          callDOMAttrModified = function (
            attrChange,
            currentTarget,
            attrName,
            prevValue,
            newValue,
            action
          ) {
            var e = {
              attrChange: attrChange,
              currentTarget: currentTarget,
              attrName: attrName,
              prevValue: prevValue,
              newValue: newValue
            };
            e[action] = attrChange;
            onDOMAttrModified(e);
          };
          getAttributesMirror = function (node) {
            for (var
              attr, name,
              result = {},
              attributes = node.attributes,
              i = 0, length = attributes.length;
              i < length; i++
            ) {
              attr = attributes[i];
              name = attr.name;
              if (name !== 'setAttribute') {
                result[name] = attr.value;
              }
            }
            return result;
          };
        }
      }
    
      // set as enumerable, writable and configurable
      document[REGISTER_ELEMENT] = function registerElement(type, options) {
        upperType = type.toUpperCase();
        if (setListener) {
          // only first time document.registerElement is used
          // we need to set this listener
          // setting it by default might slow down for no reason
          setListener = false;
          if (MutationObserver) {
            observer = (function(attached, detached){
              function checkEmAll(list, callback) {
                for (var i = 0, length = list.length; i < length; callback(list[i++])){}
              }
              return new MutationObserver(function (records) {
                for (var
                  current, node, newValue,
                  i = 0, length = records.length; i < length; i++
                ) {
                  current = records[i];
                  if (current.type === 'childList') {
                    checkEmAll(current.addedNodes, attached);
                    checkEmAll(current.removedNodes, detached);
                  } else {
                    node = current.target;
                    if (notFromInnerHTMLHelper &&
                        node[ATTRIBUTE_CHANGED_CALLBACK] &&
                        current.attributeName !== 'style') {
                      newValue = getAttribute.call(node, current.attributeName);
                      if (newValue !== current.oldValue) {
                        node[ATTRIBUTE_CHANGED_CALLBACK](
                          current.attributeName,
                          current.oldValue,
                          newValue
                        );
                      }
                    }
                  }
                }
              });
            }(executeAction(ATTACHED), executeAction(DETACHED)));
            observe = function (node) {
              observer.observe(
                node,
                {
                  childList: true,
                  subtree: true
                }
              );
              return node;
            };
            observe(document);
            if (attachShadow) {
              HTMLElementPrototype.attachShadow = function () {
                return observe(attachShadow.apply(this, arguments));
              };
            }
          } else {
            asapQueue = [];
            document[ADD_EVENT_LISTENER]('DOMNodeInserted', onDOMNode(ATTACHED));
            document[ADD_EVENT_LISTENER]('DOMNodeRemoved', onDOMNode(DETACHED));
          }
    
          document[ADD_EVENT_LISTENER](DOM_CONTENT_LOADED, onReadyStateChange);
          document[ADD_EVENT_LISTENER]('readystatechange', onReadyStateChange);
    
          document.importNode = function (node, deep) {
            switch (node.nodeType) {
              case 1:
                return setupAll(document, importNode, [node, !!deep]);
              case 11:
                for (var
                  fragment = document.createDocumentFragment(),
                  childNodes = node.childNodes,
                  length = childNodes.length,
                  i = 0; i < length; i++
                )
                  fragment.appendChild(document.importNode(childNodes[i], !!deep));
                return fragment;
              default:
                return cloneNode.call(node, !!deep);
            }
          };
    
          HTMLElementPrototype.cloneNode = function (deep) {
            return setupAll(this, cloneNode, [!!deep]);
          };
        }
    
        if (justSetup) return (justSetup = false);
    
        if (-2 < (
          indexOf.call(types, PREFIX_IS + upperType) +
          indexOf.call(types, PREFIX_TAG + upperType)
        )) {
          throwTypeError(type);
        }
    
        if (!validName.test(upperType) || -1 < indexOf.call(invalidNames, upperType)) {
          throw new Error('The type ' + type + ' is invalid');
        }
    
        var
          constructor = function () {
            return extending ?
              document.createElement(nodeName, upperType) :
              document.createElement(nodeName);
          },
          opt = options || OP,
          extending = hOP.call(opt, EXTENDS),
          nodeName = extending ? options[EXTENDS].toUpperCase() : upperType,
          upperType,
          i
        ;
    
        if (extending && -1 < (
          indexOf.call(types, PREFIX_TAG + nodeName)
        )) {
          throwTypeError(nodeName);
        }
    
        i = types.push((extending ? PREFIX_IS : PREFIX_TAG) + upperType) - 1;
    
        query = query.concat(
          query.length ? ',' : '',
          extending ? nodeName + '[is="' + type.toLowerCase() + '"]' : nodeName
        );
    
        constructor.prototype = (
          protos[i] = hOP.call(opt, 'prototype') ?
            opt.prototype :
            create(HTMLElementPrototype)
        );
    
        if (query.length) loopAndVerify(
          document.querySelectorAll(query),
          ATTACHED
        );
    
        return constructor;
      };
    
      document.createElement = (patchedCreateElement = function (localName, typeExtension) {
        var
          is = getIs(typeExtension),
          node = is ?
            createElement.call(document, localName, secondArgument(is)) :
            createElement.call(document, localName),
          name = '' + localName,
          i = indexOf.call(
            types,
            (is ? PREFIX_IS : PREFIX_TAG) +
            (is || name).toUpperCase()
          ),
          setup = -1 < i
        ;
        if (is) {
          node.setAttribute('is', is = is.toLowerCase());
          if (setup) {
            setup = isInQSA(name.toUpperCase(), is);
          }
        }
        notFromInnerHTMLHelper = !document.createElement.innerHTMLHelper;
        if (setup) patch(node, protos[i]);
        return node;
      });
    
    }
    
    function ASAP() {
      var queue = asapQueue.splice(0, asapQueue.length);
      asapTimer = 0;
      while (queue.length) {
        queue.shift().call(
          null, queue.shift()
        );
      }
    }
    
    function loopAndVerify(list, action) {
      for (var i = 0, length = list.length; i < length; i++) {
        verifyAndSetupAndAction(list[i], action);
      }
    }
    
    function loopAndSetup(list) {
      for (var i = 0, length = list.length, node; i < length; i++) {
        node = list[i];
        patch(node, protos[getTypeIndex(node)]);
      }
    }
    
    function executeAction(action) {
      return function (node) {
        if (isValidNode(node)) {
          verifyAndSetupAndAction(node, action);
          if (query.length) loopAndVerify(
            node.querySelectorAll(query),
            action
          );
        }
      };
    }
    
    function getTypeIndex(target) {
      var
        is = getAttribute.call(target, 'is'),
        nodeName = target.nodeName.toUpperCase(),
        i = indexOf.call(
          types,
          is ?
              PREFIX_IS + is.toUpperCase() :
              PREFIX_TAG + nodeName
        )
      ;
      return is && -1 < i && !isInQSA(nodeName, is) ? -1 : i;
    }
    
    function isInQSA(name, type) {
      return -1 < query.indexOf(name + '[is="' + type + '"]');
    }
    
    function onDOMAttrModified(e) {
      var
        node = e.currentTarget,
        attrChange = e.attrChange,
        attrName = e.attrName,
        target = e.target,
        addition = e[ADDITION] || 2,
        removal = e[REMOVAL] || 3
      ;
      if (notFromInnerHTMLHelper &&
          (!target || target === node) &&
          node[ATTRIBUTE_CHANGED_CALLBACK] &&
          attrName !== 'style' && (
            e.prevValue !== e.newValue ||
            // IE9, IE10, and Opera 12 gotcha
            e.newValue === '' && (
              attrChange === addition ||
              attrChange === removal
            )
      )) {
        node[ATTRIBUTE_CHANGED_CALLBACK](
          attrName,
          attrChange === addition ? null : e.prevValue,
          attrChange === removal ? null : e.newValue
        );
      }
    }
    
    function onDOMNode(action) {
      var executor = executeAction(action);
      return function (e) {
        asapQueue.push(executor, e.target);
        if (asapTimer) clearTimeout(asapTimer);
        asapTimer = setTimeout(ASAP, 1);
      };
    }
    
    function onReadyStateChange(e) {
      if (dropDomContentLoaded) {
        dropDomContentLoaded = false;
        e.currentTarget.removeEventListener(DOM_CONTENT_LOADED, onReadyStateChange);
      }
      if (query.length) loopAndVerify(
        (e.target || document).querySelectorAll(query),
        e.detail === DETACHED ? DETACHED : ATTACHED
      );
      if (IE8) purge();
    }
    
    function patchedSetAttribute(name, value) {
      // jshint validthis:true
      var self = this;
      setAttribute.call(self, name, value);
      onSubtreeModified.call(self, {target: self});
    }
    
    function setupAll(context, callback, args) {
      var
        node = callback.apply(context, args),
        i = getTypeIndex(node)
      ;
      if (-1 < i) patch(node, protos[i]);
      if (args.pop() && query.length)
        loopAndSetup(node.querySelectorAll(query));
      return node;
    }
    
    function setupNode(node, proto) {
      setPrototype(node, proto);
      if (observer) {
        observer.observe(node, attributesObserver);
      } else {
        if (doesNotSupportDOMAttrModified) {
          node.setAttribute = patchedSetAttribute;
          node[EXPANDO_UID] = getAttributesMirror(node);
          node[ADD_EVENT_LISTENER](DOM_SUBTREE_MODIFIED, onSubtreeModified);
        }
        node[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, onDOMAttrModified);
      }
      if (node[CREATED_CALLBACK] && notFromInnerHTMLHelper) {
        node.created = true;
        node[CREATED_CALLBACK]();
        node.created = false;
      }
    }
    
    function purge() {
      for (var
        node,
        i = 0,
        length = targets.length;
        i < length; i++
      ) {
        node = targets[i];
        if (!documentElement.contains(node)) {
          length--;
          targets.splice(i--, 1);
          verifyAndSetupAndAction(node, DETACHED);
        }
      }
    }
    
    function throwTypeError(type) {
      throw new Error('A ' + type + ' type is already registered');
    }
    
    function verifyAndSetupAndAction(node, action) {
      var
        fn,
        i = getTypeIndex(node),
        counterAction
      ;
      if (-1 < i) {
        patchIfNotAlready(node, protos[i]);
        i = 0;
        if (action === ATTACHED && !node[ATTACHED]) {
          node[DETACHED] = false;
          node[ATTACHED] = true;
          counterAction = 'connected';
          i = 1;
          if (IE8 && indexOf.call(targets, node) < 0) {
            targets.push(node);
          }
        } else if (action === DETACHED && !node[DETACHED]) {
          node[ATTACHED] = false;
          node[DETACHED] = true;
          counterAction = 'disconnected';
          i = 1;
        }
        if (i && (fn = (
          node[action + CALLBACK] ||
          node[counterAction + CALLBACK]
        ))) fn.call(node);
      }
    }
    
    
    
    // V1 in da House!
    function CustomElementRegistry() {}
    
    CustomElementRegistry.prototype = {
      constructor: CustomElementRegistry,
      // a workaround for the stubborn WebKit
      define: usableCustomElements ?
        function (name, Class, options) {
          if (options) {
            CERDefine(name, Class, options);
          } else {
            var NAME = name.toUpperCase();
            constructors[NAME] = {
              constructor: Class,
              create: [NAME]
            };
            nodeNames.set(Class, NAME);
            customElements.define(name, Class);
          }
        } :
        CERDefine,
      get: usableCustomElements ?
        function (name) {
          return customElements.get(name) || get(name);
        } :
        get,
      whenDefined: usableCustomElements ?
        function (name) {
          return Promise.race([
            customElements.whenDefined(name),
            whenDefined(name)
          ]);
        } :
        whenDefined
    };
    
    function CERDefine(name, Class, options) {
      var
        is = options && options[EXTENDS] || '',
        CProto = Class.prototype,
        proto = create(CProto),
        attributes = Class.observedAttributes || empty,
        definition = {prototype: proto}
      ;
      // TODO: is this needed at all since it's inherited?
      // defineProperty(proto, 'constructor', {value: Class});
      safeProperty(proto, CREATED_CALLBACK, {
          value: function () {
            if (justCreated) justCreated = false;
            else if (!this[DRECEV1]) {
              this[DRECEV1] = true;
              new Class(this);
              if (CProto[CREATED_CALLBACK])
                CProto[CREATED_CALLBACK].call(this);
              var info = constructors[nodeNames.get(Class)];
              if (!usableCustomElements || info.create.length > 1) {
                notifyAttributes(this);
              }
            }
        }
      });
      safeProperty(proto, ATTRIBUTE_CHANGED_CALLBACK, {
        value: function (name) {
          if (-1 < indexOf.call(attributes, name)) {
            if (CProto[ATTRIBUTE_CHANGED_CALLBACK])
              CProto[ATTRIBUTE_CHANGED_CALLBACK].apply(this, arguments);
          }
        }
      });
      if (CProto[CONNECTED_CALLBACK]) {
        safeProperty(proto, ATTACHED_CALLBACK, {
          value: CProto[CONNECTED_CALLBACK]
        });
      }
      if (CProto[DISCONNECTED_CALLBACK]) {
        safeProperty(proto, DETACHED_CALLBACK, {
          value: CProto[DISCONNECTED_CALLBACK]
        });
      }
      if (is) definition[EXTENDS] = is;
      name = name.toUpperCase();
      constructors[name] = {
        constructor: Class,
        create: is ? [is, secondArgument(name)] : [name]
      };
      nodeNames.set(Class, name);
      document[REGISTER_ELEMENT](name.toLowerCase(), definition);
      whenDefined(name);
      waitingList[name].r();
    }
    
    function get(name) {
      var info = constructors[name.toUpperCase()];
      return info && info.constructor;
    }
    
    function getIs(options) {
      return typeof options === 'string' ?
          options : (options && options.is || '');
    }
    
    function notifyAttributes(self) {
      var
        callback = self[ATTRIBUTE_CHANGED_CALLBACK],
        attributes = callback ? self.attributes : empty,
        i = attributes.length,
        attribute
      ;
      while (i--) {
        attribute =  attributes[i]; // || attributes.item(i);
        callback.call(
          self,
          attribute.name || attribute.nodeName,
          null,
          attribute.value || attribute.nodeValue
        );
      }
    }
    
    function whenDefined(name) {
      name = name.toUpperCase();
      if (!(name in waitingList)) {
        waitingList[name] = {};
        waitingList[name].p = new Promise(function (resolve) {
          waitingList[name].r = resolve;
        });
      }
      return waitingList[name].p;
    }
    
    function polyfillV1() {
      if (customElements) delete window.customElements;
      defineProperty(window, 'customElements', {
        configurable: true,
        value: new CustomElementRegistry()
      });
      defineProperty(window, 'CustomElementRegistry', {
        configurable: true,
        value: CustomElementRegistry
      });
      for (var
        patchClass = function (name) {
          var Class = window[name];
          if (Class) {
            window[name] = function CustomElementsV1(self) {
              var info, isNative;
              if (!self) self = this;
              if (!self[DRECEV1]) {
                justCreated = true;
                info = constructors[nodeNames.get(self.constructor)];
                isNative = usableCustomElements && info.create.length === 1;
                self = isNative ?
                  Reflect.construct(Class, empty, info.constructor) :
                  document.createElement.apply(document, info.create);
                self[DRECEV1] = true;
                justCreated = false;
                if (!isNative) notifyAttributes(self);
              }
              return self;
            };
            window[name].prototype = Class.prototype;
            try {
              Class.prototype.constructor = window[name];
            } catch(WebKit) {
              fixGetClass = true;
              defineProperty(Class, DRECEV1, {value: window[name]});
            }
          }
        },
        Classes = htmlClass.get(/^HTML[A-Z]*[a-z]/),
        i = Classes.length;
        i--;
        patchClass(Classes[i])
      ) {}
      (document.createElement = function (name, options) {
        var is = getIs(options);
        return is ?
          patchedCreateElement.call(this, name, secondArgument(is)) :
          patchedCreateElement.call(this, name);
      });
      if (!V0) {
        justSetup = true;
        document[REGISTER_ELEMENT]('');
      }
    }
    
    // if customElements is not there at all
    if (!customElements || /^force/.test(polyfill.type)) polyfillV1();
    else if(!polyfill.noBuiltIn) {
      // if available test extends work as expected
      try {
        (function (DRE, options, name) {
          var re = new RegExp('^<a\\s+is=(\'|")' + name + '\\1></a>$');
          options[EXTENDS] = 'a';
          DRE.prototype = create(HTMLAnchorElement.prototype);
          DRE.prototype.constructor = DRE;
          window.customElements.define(name, DRE, options);
          if (
            !re.test(document.createElement('a', {is: name}).outerHTML) ||
            !re.test((new DRE()).outerHTML)
          ) {
            throw options;
          }
        }(
          function DRE() {
            return Reflect.construct(HTMLAnchorElement, [], DRE);
          },
          {},
          'document-register-element-a'
        ));
      } catch(o_O) {
        // or force the polyfill if not
        // and keep internal original reference
        polyfillV1();
      }
    }
    
    // FireFox only issue
    if(!polyfill.noBuiltIn) {
      try {
        createElement.call(document, 'a', 'a');
      } catch(FireFox) {
        secondArgument = function (is) {
          return {is: is.toLowerCase()};
        };
      }
    }
    
  }(window));
  