[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "content": ".sublime-project\n.sublime-workspace\n.vscode/\n.txt\n.styles/.sass-cache/\n.styles/*.css.map\ntesting.html\ntest-webc.html\nbeta.html\n"
  },
  {
    "path": "README.md",
    "content": "# Quotebacks\nQuote the web — [install Chrome extension](https://chrome.google.com/webstore/detail/quotebacks-quote-the-web/makakhdegdcmmbbhepafcghpdkbemach)\n\n---\n\nGrab quotes from any page using cmd+shift+s (on Windows: ctrl+shift+S). Then grab the embed link to produce a live HTML citation like this:\n\n![quoteback-preview](https://github.com/Blogger-Peer-Review/quotebacks/blob/master/quoteback-preview.png?raw=true)\n\nYou can paste the embed code into any HTML page. It looks just like this.\n\n```\n<blockquote class=\"quoteback\" data-title=\"Open Transclude for Networked Writing\" data-author=\"Toby Shorin\" cite=\"http://subpixel.space/entries/open-transclude/\">\nThe web is still a very young medium, and it has been influenced more than anything else by print media design. <strong>There is so much more that can be done with text on a screen than is being done today.</strong> Citations, drawing, chat, speech-to-text. There are opportunities everywhere, and the bar is low! If we are serious about unlocking the value of knowledge we should consider how to improve every part of the knowledge production stack, and that includes reading. As <a href=\"http://beautiful-company.com/i/printed-matter-website\" target=\"_blank\" rel=\"noopener\">Laurel Schwulst says</a>: “Imaginative functionality is important, even if it’s only a trace of what was, as it’s still a sketch for a more ideal world.”\n<footer>Toby Shorin<cite><a href=\"http://subpixel.space/entries/open-transclude/\">http://subpixel.space/entries/open-transclude/</a></cite></footer>\n</blockquote><script note=\"\" src=\"https://cdn.jsdelivr.net/gh/Blogger-Peer-Review/quotebacks@1/quoteback.js\"></script>\n```\n\nQuotes are saved locally in your Chrome storage.\n\nDownload our chrome extension here: https://chrome.google.com/webstore/detail/quotebacks-quote-the-web/makakhdegdcmmbbhepafcghpdkbemach\n\nMade by [Tom Critchlow](https://twitter.com/tomcritchlow) and [Toby Shorin](https://twitter.com/tobyshorin). DM us on Twitter or email us at tjcritchlow@gmail.com or tobyshorin@gmail.com with any questions or bug reports!\n\n\n---\n\nCopyright 2020 Tom Critchlow & Toby Shorin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "background.js",
    "content": "// let gettingAllCommands = browser.commands.getAll();\n// gettingAllCommands.then((commands) => {\n//   for (let command of commands) {\n//     // Note that this logs to the Add-on Debugger's console: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Debugging\n//     // not the regular Web console.\n//     console.log(command);\n//   }\n// });\n\n\n//chrome.storage.local.get(null, function(items) {\n//  allKeys = Object.keys(items);\n//});\n\nchrome.commands.onCommand.addListener(function(command) { \n  copyquote();\n});\n\nchrome.browserAction.setPopup({popup:''});  //disable browserAction's popup\n\nchrome.browserAction.onClicked.addListener(()=>{\n  chrome.tabs.create({url:'options.html'});\n});\n\n// Check whether new version is installed\nchrome.runtime.onInstalled.addListener(function(details){\n  if(details.reason == \"install\"){\n    chrome.tabs.create({url:'https://quotebacks.net/welcome.html'});\n  }else if(details.reason == \"update\"){\n      var thisVersion = chrome.runtime.getManifest().version;\n      console.log(\"Updated from \" + details.previousVersion + \" to \" + thisVersion + \"!\");\n  }\n});\n\nchrome.runtime.onInstalled.addListener(function() {\n  // Create a parent item and two children.\n  chrome.contextMenus.create({\"title\": \"Quoteback: Copy Quote\", \"id\": \"quoteback\",\"contexts\":[\"selection\"]});\n  chrome.contextMenus.onClicked.addListener(onClickHandler);\n});\n\n\nfunction onClickHandler(info, tab) {\n  if (info.menuItemId == \"quoteback\") {\n   copyquote();\n  }\n};\n\nfunction copyquote(){\n  // console.log(\"invoke the quotebacks!\")\n  //send ping. If no response then load scripts.\n\n\nchrome.tabs.query({active: true, currentWindow: true}, function(tabs) {\n  chrome.tabs.sendMessage(tabs[0].id, {message: \"ping\"}, function(response) {\n    if(response){\n      // Send copyquote command\n      console.log(\"we heard a response and we are sending a message to newcontent.js\");\n      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {\n        chrome.tabs.sendMessage(tabs[0].id, {message: \"copyquote\"}, function(response) {\n          \n        });\n      });\n      \n    }\n    else{\n      console.log(\"we didn't hear a response and now we're waiting to load some scripts...\");\n      chrome.tabs.executeScript({\n        file: 'webcomponents-sd-ce.js'\n      },function(){\n        chrome.tabs.executeScript({\n          file: 'quotestyle.js'\n        },function(){\n          chrome.tabs.executeScript({\n            file: 'rangy-core.js'\n          },function(){\n            chrome.tabs.executeScript({\n              file: 'turndown.js'\n            },function(){\n              chrome.tabs.executeScript({\n                file: 'newcontent.js',\n              },function(){\n                chrome.tabs.executeScript({\n                  file: 'quoteback-internal.js'\n                },function(){\n                  chrome.tabs.executeScript({\n                    file: 'readability.js'\n                  },function(){\n\n                    // console.log(\"...and now that those scripts are loaded we are sending a message to newcontent.js\");\n                    // Send copyquote command\n                    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {\n                      chrome.tabs.sendMessage(tabs[0].id, {message: \"copyquote\"}, function(response) {\n                      });                \n                    });\n                  });\n                });\n              });\n            });\n          });\n        });\n      });\n    };\n    \n    \n  });\n});\n}\n\n"
  },
  {
    "path": "fastsearch.js",
    "content": "var fuse; // holds our search engine\nvar searchVisible = false; \nvar firstRun = true; // allow us to delay loading json data unless search activated\nvar list = document.getElementById('searchResults'); // targets the <ul>\nvar first = list.firstElementChild; // first child of search list\nvar last = list.lastElementChild; // last child of search list\nvar maininput = document.getElementById('searchInput'); // input box for search\nvar resultsAvailable = false; // Did we get any search results?\n\n// on click on input\ndocument.getElementById(\"searchInput\").onclick = function(){\n  if(firstRun) {\n    loadSearch(); // loads our json data and builds fuse.js search index\n    firstRun = false; // let's never do this again\n  }\n\n  // Toggle visibility of search box\n  if (!searchVisible) {\n    document.getElementById(\"fastSearch\").style.visibility = \"visible\"; // show search box\n    document.getElementById(\"searchResults\").style.visibility = \"visible\";\n    document.getElementById(\"searchInput\").focus(); // put focus in input box so you can just start typing\n    document.getElementById(\"searchInput\").classList.add(\"unround\")\n    searchVisible = true; // search visible\n  }\n  else {\n\n  }\n};\n\n// if search loses focus hide search bar\ndocument.getElementById(\"fastSearch\").addEventListener('focusout', (event) => {\n  if (document.getElementById(\"fastSearch\").contains(event.relatedTarget)) {\n    // don't react to this\n    return;\n}\n  console.log(\"focusing out\");\n  document.getElementById(\"searchInput\").value = \"\";\n  document.getElementById(\"searchResults\").style.visibility = \"hidden\";\n  searchVisible = false; // search not visible\n\n});\n\n// if hash changes hide search\nwindow.addEventListener('hashchange', function() {\n  document.getElementById(\"searchInput\").value = \"\";\n  document.getElementById(\"searchResults\").style.visibility = \"hidden\";\n  searchVisible = false; // search not visible\n}, false);\n\n\n\n\n\n\n// ==========================================\n// The main keyboard event listener running the show\n//\ndocument.addEventListener('keydown', function(event) {\n\n  // CMD-/ to show / hide Search\n  if ((event.metaKey && event.which === 191) || (event.metaKey && event.which === 75)) {\n      event.preventDefault();\n      // Load json search index if first time invoking search\n      // Means we don't load json unless searches are going to happen; keep user payload small unless needed\n      if(firstRun) {\n        loadSearch(); // loads our json data and builds fuse.js search index\n        firstRun = false; // let's never do this again\n      }\n\n      // Toggle visibility of search box\n      if (!searchVisible) {\n        document.getElementById(\"fastSearch\").style.visibility = \"visible\"; // show search box\n        document.getElementById(\"searchResults\").style.visibility = \"visible\";\n        document.getElementById(\"searchInput\").focus(); // put focus in input box so you can just start typing\n        searchVisible = true; // search visible\n      }\n      else {\n        \n        document.activeElement.blur(); // remove focus from search box \n        searchVisible = false; // search not visible\n      }\n  }\n\n  // Allow ESC (27) to close search box\n  if (event.keyCode == 27) {\n    if (searchVisible) {\n      document.getElementById(\"searchInput\").value = \"\";\n      document.getElementById(\"searchResults\").style.visibility = \"hidden\";\n      document.activeElement.blur();\n      searchVisible = false;\n    }\n  }\n\n  // DOWN (40) arrow\n  if (event.keyCode == 40) {\n    if (searchVisible && resultsAvailable) {\n      console.log(\"down\");\n      event.preventDefault(); // stop window from scrolling\n      if ( document.activeElement == maininput) { first.focus(); } // if the currently focused element is the main input --> focus the first <li>\n      else if ( document.activeElement == last ) { last.focus(); } // if we're at the bottom, stay there\n      else { \n        console.log(document.activeElement.parentElement);\n        document.activeElement.parentElement.nextElementSibling.firstElementChild.focus(); } // otherwise select the next search result\n      }\n    }\n\n\n  // UP (38) arrow\n  if (event.keyCode == 38) {\n    if (searchVisible && resultsAvailable) {\n      event.preventDefault(); // stop window from scrolling\n      if ( document.activeElement == maininput) { maininput.focus(); } // If we're in the input box, do nothing\n      else if ( document.activeElement == first) { maininput.focus(); } // If we're at the first item, go to input box\n      else { document.activeElement.parentElement.previousElementSibling.firstElementChild.focus(); } // Otherwise, select the search result above the current active one\n    }\n  }\n});\n\n\n// ==========================================\n// execute search as each character is typed\n//\ndocument.getElementById(\"searchInput\").onkeyup = function(e) { \n  executeSearch(this.value);\n}\n\n\n\n\n\n// ==========================================\n// load our search index, only executed once\n// on first call of search box (CMD-/)\n//\nfunction loadSearch() { \n  \n\n  var options = {\n    isCaseSensitive: false,\n    findAllMatches: false,\n    includeMatches: false,\n    includeScore: false,\n    useExtendedSearch: false,\n    minMatchCharLength: 2,\n    shouldSort: true,\n    threshold: 0.6,\n    location: 0,\n    distance: 100,\n    keys: [\n      \"url\",\n      \"title\",\n      \"author\",\n      \"quotes.comment\",\n      \"quotes.text\",\n    ]\n  };\n    \n  console.log(alljson);\n\n  fuse = new Fuse(alljson, options); // build the index from the json file\n  \n};\n\nfunction strip(html){\n  var doc = new DOMParser().parseFromString(html, 'text/html');\n  return doc.body.textContent || \"\";\n}\n\n// ==========================================\n// using the index we loaded on CMD-/, run \n// a search query (for \"term\") every time a letter is typed\n// in the search box\n//\nfunction executeSearch(term) {\n  let results = fuse.search(term); // the actual query being run using fuse.js\n  console.log(results);\n  let searchitems = ''; // our results bucket\n\n  if (results.length === 0) { // no results based on what was typed into the input box\n    resultsAvailable = false;\n    searchitems = '';\n  } else { // build our html \n   \n    for (var i in results.slice(0,5)){\n\n      for(var j in results[i].item.quotes){\n        var htmlstripped = strip(results[i].item.quotes[j].text);\n        var searchresult = `\n        <li>\n          <a href='/options.html#${results[i].item.url}'><img src='https://s2.googleusercontent.com/s2/favicons?domain_url=${extractHostname(results[i].item.url)}'/>${results[i].item.title}\n            <div>\n              <div class=\"search-url\">${extractHostname(results[i].item.url)}</div>\n            </div>\n            <span class=\"search-content\">${htmlstripped.substring(0,120)}...</span>\n          </a>\n        </li>`;\n\n        searchitems = searchitems + searchresult;\n        \n      }\n      \n    }\n   \n    resultsAvailable = true;\n  }\n\n  document.getElementById(\"searchResults\").innerHTML = searchitems;\n  if (results.length > 0) {\n    document.getElementById(\"searchResults\").style.display = \"inline-block\";\n    first = list.firstElementChild.firstElementChild; // first result container — used for checking against keyboard up/down location\n    last = list.lastElementChild.firstElementChild; // last result container — used for checking against keyboard up/down location\n  }\n\n}"
  },
  {
    "path": "fuse.js",
    "content": "/**\n * Fuse.js v5.1.0 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2020 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    (global = global || self, global.Fuse = factory());\n  }(this, (function () { 'use strict';\n  \n    function _classCallCheck(instance, Constructor) {\n      if (!(instance instanceof Constructor)) {\n        throw new TypeError(\"Cannot call a class as a function\");\n      }\n    }\n  \n    function _defineProperties(target, props) {\n      for (var i = 0; i < props.length; i++) {\n        var descriptor = props[i];\n        descriptor.enumerable = descriptor.enumerable || false;\n        descriptor.configurable = true;\n        if (\"value\" in descriptor) descriptor.writable = true;\n        Object.defineProperty(target, descriptor.key, descriptor);\n      }\n    }\n  \n    function _createClass(Constructor, protoProps, staticProps) {\n      if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n      if (staticProps) _defineProperties(Constructor, staticProps);\n      return Constructor;\n    }\n  \n    function _defineProperty(obj, key, value) {\n      if (key in obj) {\n        Object.defineProperty(obj, key, {\n          value: value,\n          enumerable: true,\n          configurable: true,\n          writable: true\n        });\n      } else {\n        obj[key] = value;\n      }\n  \n      return obj;\n    }\n  \n    function ownKeys(object, enumerableOnly) {\n      var keys = Object.keys(object);\n  \n      if (Object.getOwnPropertySymbols) {\n        var symbols = Object.getOwnPropertySymbols(object);\n        if (enumerableOnly) symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n        keys.push.apply(keys, symbols);\n      }\n  \n      return keys;\n    }\n  \n    function _objectSpread2(target) {\n      for (var i = 1; i < arguments.length; i++) {\n        var source = arguments[i] != null ? arguments[i] : {};\n  \n        if (i % 2) {\n          ownKeys(Object(source), true).forEach(function (key) {\n            _defineProperty(target, key, source[key]);\n          });\n        } else if (Object.getOwnPropertyDescriptors) {\n          Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n        } else {\n          ownKeys(Object(source)).forEach(function (key) {\n            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n          });\n        }\n      }\n  \n      return target;\n    }\n  \n    function bitapScore(pattern, _ref) {\n      var _ref$errors = _ref.errors,\n          errors = _ref$errors === void 0 ? 0 : _ref$errors,\n          _ref$currentLocation = _ref.currentLocation,\n          currentLocation = _ref$currentLocation === void 0 ? 0 : _ref$currentLocation,\n          _ref$expectedLocation = _ref.expectedLocation,\n          expectedLocation = _ref$expectedLocation === void 0 ? 0 : _ref$expectedLocation,\n          _ref$distance = _ref.distance,\n          distance = _ref$distance === void 0 ? 100 : _ref$distance;\n      var accuracy = errors / pattern.length;\n      var proximity = Math.abs(expectedLocation - currentLocation);\n  \n      if (!distance) {\n        // Dodge divide by zero error.\n        return proximity ? 1.0 : accuracy;\n      }\n  \n      return accuracy + proximity / distance;\n    }\n  \n    function matchedIndiced() {\n      var matchmask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n      var minMatchCharLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n      var matchedIndices = [];\n      var start = -1;\n      var end = -1;\n      var i = 0;\n  \n      for (var len = matchmask.length; i < len; i += 1) {\n        var match = matchmask[i];\n  \n        if (match && start === -1) {\n          start = i;\n        } else if (!match && start !== -1) {\n          end = i - 1;\n  \n          if (end - start + 1 >= minMatchCharLength) {\n            matchedIndices.push([start, end]);\n          }\n  \n          start = -1;\n        }\n      } // (i-1 - start) + 1 => i - start\n  \n  \n      if (matchmask[i - 1] && i - start >= minMatchCharLength) {\n        matchedIndices.push([start, i - 1]);\n      }\n  \n      return matchedIndices;\n    }\n  \n    function bitapSearch(text, pattern, patternAlphabet, _ref) {\n      var _ref$location = _ref.location,\n          location = _ref$location === void 0 ? 0 : _ref$location,\n          _ref$distance = _ref.distance,\n          distance = _ref$distance === void 0 ? 100 : _ref$distance,\n          _ref$threshold = _ref.threshold,\n          threshold = _ref$threshold === void 0 ? 0.6 : _ref$threshold,\n          _ref$findAllMatches = _ref.findAllMatches,\n          findAllMatches = _ref$findAllMatches === void 0 ? false : _ref$findAllMatches,\n          _ref$minMatchCharLeng = _ref.minMatchCharLength,\n          minMatchCharLength = _ref$minMatchCharLeng === void 0 ? 1 : _ref$minMatchCharLeng,\n          _ref$includeMatches = _ref.includeMatches,\n          includeMatches = _ref$includeMatches === void 0 ? false : _ref$includeMatches;\n      var patternLen = pattern.length; // Set starting location at beginning text and initialize the alphabet.\n  \n      var textLen = text.length; // Handle the case when location > text.length\n  \n      var expectedLocation = Math.max(0, Math.min(location, textLen)); // Highest score beyond which we give up.\n  \n      var currentThreshold = threshold; // Is there a nearby exact match? (speedup)\n  \n      var bestLocation = text.indexOf(pattern, expectedLocation); // a mask of the matches\n  \n      var matchMask = [];\n  \n      for (var i = 0; i < textLen; i += 1) {\n        matchMask[i] = 0;\n      }\n  \n      if (bestLocation !== -1) {\n        var score = bitapScore(pattern, {\n          errors: 0,\n          currentLocation: bestLocation,\n          expectedLocation: expectedLocation,\n          distance: distance\n        });\n        currentThreshold = Math.min(score, currentThreshold); // What about in the other direction? (speed up)\n  \n        bestLocation = text.lastIndexOf(pattern, expectedLocation + patternLen);\n  \n        if (bestLocation !== -1) {\n          var _score = bitapScore(pattern, {\n            errors: 0,\n            currentLocation: bestLocation,\n            expectedLocation: expectedLocation,\n            distance: distance\n          });\n  \n          currentThreshold = Math.min(_score, currentThreshold);\n        }\n      } // Reset the best location\n  \n  \n      bestLocation = -1;\n      var lastBitArr = [];\n      var finalScore = 1;\n      var binMax = patternLen + textLen;\n      var mask = 1 << (patternLen <= 31 ? patternLen - 1 : 30);\n  \n      for (var _i = 0; _i < patternLen; _i += 1) {\n        // Scan for the best match; each iteration allows for one more error.\n        // Run a binary search to determine how far from the match location we can stray\n        // at this error level.\n        var binMin = 0;\n        var binMid = binMax;\n  \n        while (binMin < binMid) {\n          var _score3 = bitapScore(pattern, {\n            errors: _i,\n            currentLocation: expectedLocation + binMid,\n            expectedLocation: expectedLocation,\n            distance: distance\n          });\n  \n          if (_score3 <= currentThreshold) {\n            binMin = binMid;\n          } else {\n            binMax = binMid;\n          }\n  \n          binMid = Math.floor((binMax - binMin) / 2 + binMin);\n        } // Use the result from this iteration as the maximum for the next.\n  \n  \n        binMax = binMid;\n        var start = Math.max(1, expectedLocation - binMid + 1);\n        var finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen; // Initialize the bit array\n  \n        var bitArr = Array(finish + 2);\n        bitArr[finish + 1] = (1 << _i) - 1;\n  \n        for (var j = finish; j >= start; j -= 1) {\n          var currentLocation = j - 1;\n          var charMatch = patternAlphabet[text.charAt(currentLocation)];\n  \n          if (charMatch) {\n            matchMask[currentLocation] = 1;\n          } // First pass: exact match\n  \n  \n          bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch; // Subsequent passes: fuzzy match\n  \n          if (_i !== 0) {\n            bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];\n          }\n  \n          if (bitArr[j] & mask) {\n            finalScore = bitapScore(pattern, {\n              errors: _i,\n              currentLocation: currentLocation,\n              expectedLocation: expectedLocation,\n              distance: distance\n            }); // This match will almost certainly be better than any existing match.\n            // But check anyway.\n  \n            if (finalScore <= currentThreshold) {\n              // Indeed it is\n              currentThreshold = finalScore;\n              bestLocation = currentLocation; // Already passed `loc`, downhill from here on in.\n  \n              if (bestLocation <= expectedLocation) {\n                break;\n              } // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.\n  \n  \n              start = Math.max(1, 2 * expectedLocation - bestLocation);\n            }\n          }\n        } // No hope for a (better) match at greater error levels.\n  \n  \n        var _score2 = bitapScore(pattern, {\n          errors: _i + 1,\n          currentLocation: expectedLocation,\n          expectedLocation: expectedLocation,\n          distance: distance\n        });\n  \n        if (_score2 > currentThreshold) {\n          break;\n        }\n  \n        lastBitArr = bitArr;\n      }\n  \n      var result = {\n        isMatch: bestLocation >= 0,\n        // Count exact matches (those with a score of 0) to be \"almost\" exact\n        score: !finalScore ? 0.001 : finalScore\n      };\n  \n      if (includeMatches) {\n        result.matchedIndices = matchedIndiced(matchMask, minMatchCharLength);\n      }\n  \n      return result;\n    }\n  \n    function patternAlphabet(pattern) {\n      var mask = {};\n      var len = pattern.length;\n  \n      for (var i = 0; i < len; i += 1) {\n        mask[pattern.charAt(i)] = 0;\n      }\n  \n      for (var _i = 0; _i < len; _i += 1) {\n        mask[pattern.charAt(_i)] |= 1 << len - _i - 1;\n      }\n  \n      return mask;\n    }\n  \n    // Machine word size\n    var MAX_BITS = 32;\n  \n    var BitapSearch = /*#__PURE__*/function () {\n      function BitapSearch(pattern, _ref) {\n        var _ref$location = _ref.location,\n            location = _ref$location === void 0 ? 0 : _ref$location,\n            _ref$distance = _ref.distance,\n            distance = _ref$distance === void 0 ? 100 : _ref$distance,\n            _ref$threshold = _ref.threshold,\n            threshold = _ref$threshold === void 0 ? 0.6 : _ref$threshold,\n            _ref$isCaseSensitive = _ref.isCaseSensitive,\n            isCaseSensitive = _ref$isCaseSensitive === void 0 ? false : _ref$isCaseSensitive,\n            _ref$findAllMatches = _ref.findAllMatches,\n            findAllMatches = _ref$findAllMatches === void 0 ? false : _ref$findAllMatches,\n            _ref$minMatchCharLeng = _ref.minMatchCharLength,\n            minMatchCharLength = _ref$minMatchCharLeng === void 0 ? 1 : _ref$minMatchCharLeng,\n            _ref$includeMatches = _ref.includeMatches,\n            includeMatches = _ref$includeMatches === void 0 ? false : _ref$includeMatches;\n  \n        _classCallCheck(this, BitapSearch);\n  \n        this.options = {\n          location: location,\n          distance: distance,\n          threshold: threshold,\n          isCaseSensitive: isCaseSensitive,\n          findAllMatches: findAllMatches,\n          includeMatches: includeMatches,\n          minMatchCharLength: minMatchCharLength\n        };\n  \n        if (pattern.length > MAX_BITS) {\n          throw new Error(\"Pattern length exceeds max of \".concat(MAX_BITS, \".\"));\n        }\n  \n        this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n        this.patternAlphabet = patternAlphabet(this.pattern);\n      }\n  \n      _createClass(BitapSearch, [{\n        key: \"searchIn\",\n        value: function searchIn(value) {\n          var text = value.$;\n          return this.searchInString(text);\n        }\n      }, {\n        key: \"searchInString\",\n        value: function searchInString(text) {\n          var _this$options = this.options,\n              isCaseSensitive = _this$options.isCaseSensitive,\n              includeMatches = _this$options.includeMatches;\n  \n          if (!isCaseSensitive) {\n            text = text.toLowerCase();\n          } // Exact match\n  \n  \n          if (this.pattern === text) {\n            var result = {\n              isMatch: true,\n              score: 0\n            };\n  \n            if (includeMatches) {\n              result.matchedIndices = [[0, text.length - 1]];\n            }\n  \n            return result;\n          } // Otherwise, use Bitap algorithm\n  \n  \n          var _this$options2 = this.options,\n              location = _this$options2.location,\n              distance = _this$options2.distance,\n              threshold = _this$options2.threshold,\n              findAllMatches = _this$options2.findAllMatches,\n              minMatchCharLength = _this$options2.minMatchCharLength;\n          return bitapSearch(text, this.pattern, this.patternAlphabet, {\n            location: location,\n            distance: distance,\n            threshold: threshold,\n            findAllMatches: findAllMatches,\n            minMatchCharLength: minMatchCharLength,\n            includeMatches: includeMatches\n          });\n        }\n      }]);\n  \n      return BitapSearch;\n    }();\n  \n    // Token: 'file\n    // Match type: exact-match\n    // Description: Items that include `file`\n    var isForPattern = function isForPattern(pattern) {\n      return pattern.charAt(0) == \"'\";\n    };\n  \n    var sanitize = function sanitize(pattern) {\n      return pattern.substr(1);\n    };\n  \n    var match = function match(pattern, text) {\n      var sanitizedPattern = sanitize(pattern);\n      var index = text.indexOf(sanitizedPattern);\n      var isMatch = index > -1;\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var exactMatch = {\n      isForPattern: isForPattern,\n      sanitize: sanitize,\n      match: match\n    };\n  \n    // Token: !fire\n    // Match type: inverse-exact-match\n    // Description: Items that do not include `fire`\n    var isForPattern$1 = function isForPattern(pattern) {\n      return pattern.charAt(0) == '!';\n    };\n  \n    var sanitize$1 = function sanitize(pattern) {\n      return pattern.substr(1);\n    };\n  \n    var match$1 = function match(pattern, text) {\n      var sanitizedPattern = sanitize$1(pattern);\n      var isMatch = text.indexOf(sanitizedPattern) === -1;\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var inverseExactMatch = {\n      isForPattern: isForPattern$1,\n      sanitize: sanitize$1,\n      match: match$1\n    };\n  \n    // Token: ^file\n    // Match type: prefix-exact-match\n    // Description: Items that start with `file`\n    var isForPattern$2 = function isForPattern(pattern) {\n      return pattern.charAt(0) == '^';\n    };\n  \n    var sanitize$2 = function sanitize(pattern) {\n      return pattern.substr(1);\n    };\n  \n    var match$2 = function match(pattern, text) {\n      var sanitizedPattern = sanitize$2(pattern);\n      var isMatch = text.startsWith(sanitizedPattern);\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var prefixExactMatch = {\n      isForPattern: isForPattern$2,\n      sanitize: sanitize$2,\n      match: match$2\n    };\n  \n    // Token: !^fire\n    // Match type: inverse-prefix-exact-match\n    // Description: Items that do not start with `fire`\n    var isForPattern$3 = function isForPattern(pattern) {\n      return pattern.charAt(0) == '!' && pattern.charAt(1) == '^';\n    };\n  \n    var sanitize$3 = function sanitize(pattern) {\n      return pattern.substr(2);\n    };\n  \n    var match$3 = function match(pattern, text) {\n      var sanitizedPattern = sanitize$3(pattern);\n      var isMatch = !text.startsWith(sanitizedPattern);\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var inversePrefixExactMatch = {\n      isForPattern: isForPattern$3,\n      sanitize: sanitize$3,\n      match: match$3\n    };\n  \n    // Token: .file$\n    // Match type: suffix-exact-match\n    // Description: Items that end with `.file`\n    var isForPattern$4 = function isForPattern(pattern) {\n      return pattern.charAt(pattern.length - 1) == '$';\n    };\n  \n    var sanitize$4 = function sanitize(pattern) {\n      return pattern.substr(0, pattern.length - 1);\n    };\n  \n    var match$4 = function match(pattern, text) {\n      var sanitizedPattern = sanitize$4(pattern);\n      var isMatch = text.endsWith(sanitizedPattern);\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var suffixExactMatch = {\n      isForPattern: isForPattern$4,\n      sanitize: sanitize$4,\n      match: match$4\n    };\n  \n    // Token: !.file$\n    // Match type: inverse-suffix-exact-match\n    // Description: Items that do not end with `.file`\n    var isForPattern$5 = function isForPattern(pattern) {\n      return pattern.charAt(0) == '!' && pattern.charAt(pattern.length - 1) == '$';\n    };\n  \n    var sanitize$5 = function sanitize(pattern) {\n      return pattern.substring(1, pattern.length - 1);\n    };\n  \n    var match$5 = function match(pattern, text) {\n      var sanitizedPattern = sanitize$5(pattern);\n      var isMatch = !text.endsWith(sanitizedPattern);\n      return {\n        isMatch: isMatch,\n        score: 0\n      };\n    };\n  \n    var inverseSuffixExactMatch = {\n      isForPattern: isForPattern$5,\n      sanitize: sanitize$5,\n      match: match$5\n    };\n  \n    var INFINITY = 1 / 0;\n    var isArray = function isArray(value) {\n      return !Array.isArray ? Object.prototype.toString.call(value) === '[object Array]' : Array.isArray(value);\n    }; // Adapted from:\n    // https://github.com/lodash/lodash/blob/f4ca396a796435422bd4fd41fadbd225edddf175/.internal/baseToString.js\n  \n    var baseToString = function baseToString(value) {\n      // Exit early for strings to avoid a performance hit in some environments.\n      if (typeof value == 'string') {\n        return value;\n      }\n  \n      var result = value + '';\n      return result == '0' && 1 / value == -INFINITY ? '-0' : result;\n    };\n    var toString = function toString(value) {\n      return value == null ? '' : baseToString(value);\n    };\n    var isString = function isString(value) {\n      return typeof value === 'string';\n    };\n    var isNumber = function isNumber(value) {\n      return typeof value === 'number';\n    };\n    var isDefined = function isDefined(value) {\n      return value !== undefined && value !== null;\n    };\n  \n    // Example:\n    // \"^core go$ | rb$ | py$ xy$\" => [[\"^core\", \"go$\"], [\"rb$\"], [\"py$\", \"xy$\"]]\n  \n    var queryfy = function queryfy(pattern) {\n      return pattern.split('|').map(function (item) {\n        return item.trim().split(/ +/g);\n      });\n    };\n    /**\n     * Command-like searching\n     * ======================\n     *\n     * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,\n     * search in a given text.\n     *\n     * Search syntax:\n     *\n     * | Token       | Match type                 | Description                            |\n     * | ----------- | -------------------------- | -------------------------------------- |\n     * | `jscript`   | fuzzy-match                | Items that match `jscript`             |\n     * | `'python`   | exact-match                | Items that include `python`            |\n     * | `!ruby`     | inverse-exact-match        | Items that do not include `ruby`       |\n     * | `^java`     | prefix-exact-match         | Items that start with `java`           |\n     * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |\n     * | `.js$`      | suffix-exact-match         | Items that end with `.js`              |\n     * | `!.go$`     | inverse-suffix-exact-match | Items that do not end with `.go`       |\n     *\n     * A single pipe character acts as an OR operator. For example, the following\n     * query matches entries that start with `core` and end with either`go`, `rb`,\n     * or`py`.\n     *\n     * ```\n     * ^core go$ | rb$ | py$\n     * ```\n     */\n  \n  \n    var ExtendedSearch = /*#__PURE__*/function () {\n      function ExtendedSearch(pattern, options) {\n        _classCallCheck(this, ExtendedSearch);\n  \n        var isCaseSensitive = options.isCaseSensitive;\n        this.query = null;\n        this.options = options; // A <pattern>:<BitapSearch> key-value pair for optimizing searching\n  \n        this._fuzzyCache = {};\n  \n        if (isString(pattern) && pattern.trim().length > 0) {\n          this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n          this.query = queryfy(this.pattern);\n        }\n      }\n  \n      _createClass(ExtendedSearch, [{\n        key: \"searchIn\",\n        value: function searchIn(value) {\n          var query = this.query;\n  \n          if (!this.query) {\n            return {\n              isMatch: false,\n              score: 1\n            };\n          }\n  \n          var text = value.$;\n          text = this.options.isCaseSensitive ? text : text.toLowerCase();\n          var matchFound = false;\n  \n          for (var i = 0, qLen = query.length; i < qLen; i += 1) {\n            var parts = query[i];\n            var result = null;\n            matchFound = true;\n  \n            for (var j = 0, pLen = parts.length; j < pLen; j += 1) {\n              var token = parts[j];\n              result = this._search(token, text);\n  \n              if (!result.isMatch) {\n                // AND condition, short-circuit and move on to next part\n                matchFound = false;\n                break;\n              }\n            } // OR condition, so if TRUE, return\n  \n  \n            if (matchFound) {\n              return result;\n            }\n          } // Nothing was matched\n  \n  \n          return {\n            isMatch: false,\n            score: 1\n          };\n        }\n      }, {\n        key: \"_search\",\n        value: function _search(pattern, text) {\n          if (exactMatch.isForPattern(pattern)) {\n            return exactMatch.match(pattern, text);\n          } else if (prefixExactMatch.isForPattern(pattern)) {\n            return prefixExactMatch.match(pattern, text);\n          } else if (inversePrefixExactMatch.isForPattern(pattern)) {\n            return inversePrefixExactMatch.match(pattern, text);\n          } else if (inverseSuffixExactMatch.isForPattern(pattern)) {\n            return inverseSuffixExactMatch.match(pattern, text);\n          } else if (suffixExactMatch.isForPattern(pattern)) {\n            return suffixExactMatch.match(pattern, text);\n          } else if (inverseExactMatch.isForPattern(pattern)) {\n            return inverseExactMatch.match(pattern, text);\n          } else {\n            var searcher = this._fuzzyCache[pattern];\n  \n            if (!searcher) {\n              searcher = new BitapSearch(pattern, this.options);\n              this._fuzzyCache[pattern] = searcher;\n            }\n  \n            return searcher.searchInString(text);\n          }\n        }\n      }]);\n  \n      return ExtendedSearch;\n    }();\n  \n    var NGRAM_LEN = 3;\n    function ngram(text, _ref) {\n      var _ref$n = _ref.n,\n          n = _ref$n === void 0 ? NGRAM_LEN : _ref$n,\n          _ref$pad = _ref.pad,\n          pad = _ref$pad === void 0 ? true : _ref$pad,\n          _ref$sort = _ref.sort,\n          sort = _ref$sort === void 0 ? false : _ref$sort;\n      var nGrams = [];\n  \n      if (text === null || text === undefined) {\n        return nGrams;\n      }\n  \n      text = text.toLowerCase();\n  \n      if (pad) {\n        text = \" \".concat(text, \" \");\n      }\n  \n      var index = text.length - n + 1;\n  \n      if (index < 1) {\n        return nGrams;\n      }\n  \n      while (index--) {\n        nGrams[index] = text.substr(index, n);\n      }\n  \n      if (sort) {\n        nGrams.sort(function (a, b) {\n          return a == b ? 0 : a < b ? -1 : 1;\n        });\n      }\n  \n      return nGrams;\n    }\n  \n    // Assumes arrays are sorted\n    function union (arr1, arr2) {\n      var result = [];\n      var i = 0;\n      var j = 0;\n  \n      while (i < arr1.length && j < arr2.length) {\n        var item1 = arr1[i];\n        var item2 = arr2[j];\n  \n        if (item1 < item2) {\n          result.push(item1);\n          i += 1;\n        } else if (item2 < item1) {\n          result.push(item2);\n          j += 1;\n        } else {\n          result.push(item2);\n          i += 1;\n          j += 1;\n        }\n      }\n  \n      while (i < arr1.length) {\n        result.push(arr1[i]);\n        i += 1;\n      }\n  \n      while (j < arr2.length) {\n        result.push(arr2[j]);\n        j += 1;\n      }\n  \n      return result;\n    }\n  \n    // Assumes arrays are sorted\n    function intersection(arr1, arr2) {\n      var result = [];\n      var i = 0;\n      var j = 0;\n  \n      while (i < arr1.length && j < arr2.length) {\n        var item1 = arr1[i];\n        var item2 = arr2[j];\n  \n        if (item1 == item2) {\n          result.push(item1);\n          i += 1;\n          j += 1;\n        } else if (item1 < item2) {\n          i += 1;\n        } else if (item1 > item2) {\n          j += 1;\n        } else {\n          i += 1;\n          j += 1;\n        }\n      }\n  \n      return result;\n    }\n  \n    function jaccardDistance(nGram1, nGram2) {\n      var nGramUnion = union(nGram1, nGram2);\n      var nGramIntersection = intersection(nGram1, nGram2);\n      return 1 - nGramIntersection.length / nGramUnion.length;\n    }\n  \n    var NGramSearch = /*#__PURE__*/function () {\n      function NGramSearch(pattern) {\n        var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n          threshold: 0.6\n        };\n  \n        _classCallCheck(this, NGramSearch);\n  \n        // Create the ngram, and sort it\n        this.options = options;\n        this.patternNgram = ngram(pattern, {\n          sort: true\n        });\n      }\n  \n      _createClass(NGramSearch, [{\n        key: \"searchIn\",\n        value: function searchIn(value) {\n          var textNgram = value.ng;\n  \n          if (!textNgram) {\n            textNgram = ngram(value.$, {\n              sort: true\n            });\n            value.ng = textNgram;\n          }\n  \n          var jacardResult = jaccardDistance(this.patternNgram, textNgram);\n          var isMatch = jacardResult < this.options.threshold;\n          return {\n            score: isMatch ? jacardResult : 1,\n            isMatch: isMatch\n          };\n        }\n      }]);\n  \n      return NGramSearch;\n    }();\n  \n    function get(obj, path) {\n      var list = [];\n      var arr = false;\n  \n      var _get = function _get(obj, path) {\n        if (!path) {\n          // If there's no path left, we've gotten to the object we care about.\n          list.push(obj);\n        } else {\n          var dotIndex = path.indexOf('.');\n          var key = path;\n          var remaining = null;\n  \n          if (dotIndex !== -1) {\n            key = path.slice(0, dotIndex);\n            remaining = path.slice(dotIndex + 1);\n          }\n  \n          var value = obj[key];\n  \n          if (isDefined(value)) {\n            if (!remaining && (isString(value) || isNumber(value))) {\n              list.push(toString(value));\n            } else if (isArray(value)) {\n              arr = true; // Search each item in the array.\n  \n              for (var i = 0, len = value.length; i < len; i += 1) {\n                _get(value[i], remaining);\n              }\n            } else if (remaining) {\n              // An object. Recurse further.\n              _get(value, remaining);\n            }\n          }\n        }\n      };\n  \n      _get(obj, path);\n  \n      if (arr) {\n        return list;\n      }\n  \n      return list[0];\n    }\n  \n    function createIndex(keys, list) {\n      var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},\n          _ref$getFn = _ref.getFn,\n          getFn = _ref$getFn === void 0 ? get : _ref$getFn,\n          _ref$ngrams = _ref.ngrams,\n          ngrams = _ref$ngrams === void 0 ? false : _ref$ngrams;\n  \n      var indexedList = []; // List is Array<String>\n  \n      if (isString(list[0])) {\n        // Iterate over every string in the list\n        for (var i = 0, len = list.length; i < len; i += 1) {\n          var value = list[i];\n  \n          if (isDefined(value)) {\n            // if (!isCaseSensitive) {\n            //   value = value.toLowerCase()\n            // }\n            var record = {\n              $: value,\n              idx: i\n            };\n  \n            if (ngrams) {\n              record.ng = ngram(value, {\n                sort: true\n              });\n            }\n  \n            indexedList.push(record);\n          }\n        }\n      } else {\n        // List is Array<Object>\n        var keysLen = keys.length;\n  \n        for (var _i = 0, _len = list.length; _i < _len; _i += 1) {\n          var item = list[_i];\n          var _record = {\n            idx: _i,\n            $: {}\n          }; // Iterate over every key (i.e, path), and fetch the value at that key\n  \n          for (var j = 0; j < keysLen; j += 1) {\n            var key = keys[j];\n  \n            var _value = getFn(item, key);\n  \n            if (!isDefined(_value)) {\n              continue;\n            }\n  \n            if (isArray(_value)) {\n              var subRecords = [];\n              var stack = [{\n                arrayIndex: -1,\n                value: _value\n              }];\n  \n              while (stack.length) {\n                var _stack$pop = stack.pop(),\n                    arrayIndex = _stack$pop.arrayIndex,\n                    _value2 = _stack$pop.value;\n  \n                if (!isDefined(_value2)) {\n                  continue;\n                }\n  \n                if (isString(_value2)) {\n                  // if (!isCaseSensitive) {\n                  //   v = v.toLowerCase()\n                  // }\n                  var subRecord = {\n                    $: _value2,\n                    idx: arrayIndex\n                  };\n  \n                  if (ngrams) {\n                    subRecord.ng = ngram(_value2, {\n                      sort: true\n                    });\n                  }\n  \n                  subRecords.push(subRecord);\n                } else if (isArray(_value2)) {\n                  for (var k = 0, arrLen = _value2.length; k < arrLen; k += 1) {\n                    stack.push({\n                      arrayIndex: k,\n                      value: _value2[k]\n                    });\n                  }\n                }\n              }\n  \n              _record.$[key] = subRecords;\n            } else {\n              // if (!isCaseSensitive) {\n              //   value = value.toLowerCase()\n              // }\n              var _subRecord = {\n                $: _value\n              };\n  \n              if (ngrams) {\n                _subRecord.ng = ngram(_value, {\n                  sort: true\n                });\n              }\n  \n              _record.$[key] = _subRecord;\n            }\n          }\n  \n          indexedList.push(_record);\n        }\n      }\n  \n      return indexedList;\n    }\n  \n    var KeyStore = /*#__PURE__*/function () {\n      function KeyStore(keys) {\n        _classCallCheck(this, KeyStore);\n  \n        this._keys = {};\n        this._keyNames = [];\n        this._length = keys.length; // Iterate over every key\n  \n        if (keys.length && isString(keys[0])) {\n          for (var i = 0; i < this._length; i += 1) {\n            var key = keys[i];\n            this._keys[key] = {\n              weight: 1\n            };\n  \n            this._keyNames.push(key);\n          }\n        } else {\n          var totalWeight = 0;\n  \n          for (var _i = 0; _i < this._length; _i += 1) {\n            var _key = keys[_i];\n  \n            if (!Object.prototype.hasOwnProperty.call(_key, 'name')) {\n              throw new Error('Missing \"name\" property in key object');\n            }\n  \n            var keyName = _key.name;\n  \n            this._keyNames.push(keyName);\n  \n            if (!Object.prototype.hasOwnProperty.call(_key, 'weight')) {\n              throw new Error('Missing \"weight\" property in key object');\n            }\n  \n            var weight = _key.weight;\n  \n            if (weight <= 0 || weight >= 1) {\n              throw new Error('\"weight\" property in key must be in the range of (0, 1)');\n            }\n  \n            this._keys[keyName] = {\n              weight: weight\n            };\n            totalWeight += weight;\n          } // Normalize weights so that their sum is equal to 1\n  \n  \n          for (var _i2 = 0; _i2 < this._length; _i2 += 1) {\n            var _keyName = this._keyNames[_i2];\n            var keyWeight = this._keys[_keyName].weight;\n            this._keys[_keyName].weight = keyWeight / totalWeight;\n          }\n        }\n      }\n  \n      _createClass(KeyStore, [{\n        key: \"get\",\n        value: function get(key, name) {\n          return this._keys[key] ? this._keys[key][name] : -1;\n        }\n      }, {\n        key: \"keys\",\n        value: function keys() {\n          return this._keyNames;\n        }\n      }, {\n        key: \"count\",\n        value: function count() {\n          return this._length;\n        }\n      }, {\n        key: \"toJSON\",\n        value: function toJSON() {\n          return JSON.stringify(this._keys);\n        }\n      }]);\n  \n      return KeyStore;\n    }();\n  \n    function transformMatches(result, data) {\n      var matches = result.matches;\n      data.matches = [];\n  \n      if (!isDefined(matches)) {\n        return;\n      }\n  \n      for (var i = 0, len = matches.length; i < len; i += 1) {\n        var match = matches[i];\n  \n        if (!isDefined(match.indices) || match.indices.length === 0) {\n          continue;\n        }\n  \n        var obj = {\n          indices: match.indices,\n          value: match.value\n        };\n  \n        if (match.key) {\n          obj.key = match.key;\n        }\n  \n        if (match.idx > -1) {\n          obj.refIndex = match.idx;\n        }\n  \n        data.matches.push(obj);\n      }\n    }\n  \n    function transformScore(result, data) {\n      data.score = result.score;\n    }\n  \n    var BasicOptions = {\n      // When true, the algorithm continues searching to the end of the input even if a perfect\n      // match is found before the end of the same input.\n      isCaseSensitive: false,\n      // Minimum number of characters that must be matched before a result is considered a match\n      findAllMatches: false,\n      includeMatches: false,\n      includeScore: false,\n      // List of properties that will be searched. This also supports nested properties.\n      keys: [],\n      // Minimum number of characters that must be matched before a result is considered a match\n      minMatchCharLength: 1,\n      // Whether to sort the result list, by score\n      shouldSort: true,\n      // Default sort function\n      sortFn: function sortFn(a, b) {\n        return a.score - b.score;\n      }\n    };\n    var FuzzyOptions = {\n      // Approximately where in the text is the pattern expected to be found?\n      location: 0,\n      // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n      // (of both letters and location), a threshold of '1.0' would match anything.\n      threshold: 0.6,\n      // Determines how close the match must be to the fuzzy location (specified above).\n      // An exact letter match which is 'distance' characters away from the fuzzy location\n      // would score as a complete mismatch. A distance of '0' requires the match be at\n      // the exact location specified, a threshold of '1000' would require a perfect match\n      // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n      distance: 100\n    };\n    var AdvancedOptions = {\n      // Enabled extended-searching\n      useExtendedSearch: false,\n      // The get function to use when fetching an object's properties.\n      // The default will search nested paths *ie foo.bar.baz*\n      getFn: get\n    };\n  \n    var defaultOptions = _objectSpread2({}, BasicOptions, {}, FuzzyOptions, {}, AdvancedOptions);\n  \n    var Fuse = /*#__PURE__*/function () {\n      function Fuse(list) {\n        var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultOptions;\n        var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n  \n        _classCallCheck(this, Fuse);\n  \n        this.options = _objectSpread2({}, defaultOptions, {}, options); // `caseSensitive` is deprecated, use `isCaseSensitive` instead\n  \n        this.options.isCaseSensitive = options.caseSensitive;\n        delete this.options.caseSensitive;\n  \n        this._processKeys(this.options.keys);\n  \n        this.setCollection(list, index);\n      }\n  \n      _createClass(Fuse, [{\n        key: \"setCollection\",\n        value: function setCollection(list) {\n          var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n          this.list = list;\n          this.listIsStringArray = isString(list[0]);\n  \n          if (index) {\n            this.setIndex(index);\n          } else {\n            this.setIndex(this._createIndex());\n          }\n        }\n      }, {\n        key: \"setIndex\",\n        value: function setIndex(listIndex) {\n          this._indexedList = listIndex;\n        }\n      }, {\n        key: \"_processKeys\",\n        value: function _processKeys(keys) {\n          this._keyStore = new KeyStore(keys);\n        }\n      }, {\n        key: \"_createIndex\",\n        value: function _createIndex() {\n          return createIndex(this._keyStore.keys(), this.list, {\n            getFn: this.options.getFn\n          });\n        }\n      }, {\n        key: \"search\",\n        value: function search(pattern) {\n          var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n            limit: false\n          };\n          var _this$options = this.options,\n              useExtendedSearch = _this$options.useExtendedSearch,\n              shouldSort = _this$options.shouldSort;\n          var searcher = null;\n  \n          if (useExtendedSearch) {\n            searcher = new ExtendedSearch(pattern, this.options);\n          } else if (pattern.length > MAX_BITS) {\n            searcher = new NGramSearch(pattern, this.options);\n          } else {\n            searcher = new BitapSearch(pattern, this.options);\n          }\n  \n          var results = this._searchUsing(searcher);\n  \n          this._computeScore(results);\n  \n          if (shouldSort) {\n            this._sort(results);\n          }\n  \n          if (opts.limit && isNumber(opts.limit)) {\n            results = results.slice(0, opts.limit);\n          }\n  \n          return this._format(results);\n        }\n      }, {\n        key: \"_searchUsing\",\n        value: function _searchUsing(searcher) {\n          var list = this._indexedList;\n          var results = [];\n          var includeMatches = this.options.includeMatches; // List is Array<String>\n  \n          if (this.listIsStringArray) {\n            // Iterate over every string in the list\n            for (var i = 0, len = list.length; i < len; i += 1) {\n              var value = list[i];\n              var text = value.$,\n                  idx = value.idx;\n  \n              if (!isDefined(text)) {\n                continue;\n              }\n  \n              var searchResult = searcher.searchIn(value);\n              var isMatch = searchResult.isMatch,\n                  score = searchResult.score;\n  \n              if (!isMatch) {\n                continue;\n              }\n  \n              var match = {\n                score: score,\n                value: text\n              };\n  \n              if (includeMatches) {\n                match.indices = searchResult.matchedIndices;\n              }\n  \n              results.push({\n                item: text,\n                idx: idx,\n                matches: [match]\n              });\n            }\n          } else {\n            // List is Array<Object>\n            var keyNames = this._keyStore.keys();\n  \n            var keysLen = this._keyStore.count();\n  \n            for (var _i = 0, _len = list.length; _i < _len; _i += 1) {\n              var _list$_i = list[_i],\n                  item = _list$_i.$,\n                  _idx = _list$_i.idx;\n  \n              if (!isDefined(item)) {\n                continue;\n              }\n  \n              var matches = []; // Iterate over every key (i.e, path), and fetch the value at that key\n  \n              for (var j = 0; j < keysLen; j += 1) {\n                var key = keyNames[j];\n                var _value = item[key];\n  \n                if (!isDefined(_value)) {\n                  continue;\n                }\n  \n                if (isArray(_value)) {\n                  for (var k = 0, _len2 = _value.length; k < _len2; k += 1) {\n                    var arrItem = _value[k];\n                    var _text = arrItem.$;\n                    var _idx2 = arrItem.idx;\n  \n                    if (!isDefined(_text)) {\n                      continue;\n                    }\n  \n                    var _searchResult = searcher.searchIn(arrItem);\n  \n                    var _isMatch = _searchResult.isMatch,\n                        _score = _searchResult.score;\n  \n                    if (!_isMatch) {\n                      continue;\n                    }\n  \n                    var _match = {\n                      score: _score,\n                      key: key,\n                      value: _text,\n                      idx: _idx2\n                    };\n  \n                    if (includeMatches) {\n                      _match.indices = _searchResult.matchedIndices;\n                    }\n  \n                    matches.push(_match);\n                  }\n                } else {\n                  var _text2 = _value.$;\n  \n                  var _searchResult2 = searcher.searchIn(_value);\n  \n                  var _isMatch2 = _searchResult2.isMatch,\n                      _score2 = _searchResult2.score;\n  \n                  if (!_isMatch2) {\n                    continue;\n                  }\n  \n                  var _match2 = {\n                    score: _score2,\n                    key: key,\n                    value: _text2\n                  };\n  \n                  if (includeMatches) {\n                    _match2.indices = _searchResult2.matchedIndices;\n                  }\n  \n                  matches.push(_match2);\n                }\n              }\n  \n              if (matches.length) {\n                results.push({\n                  idx: _idx,\n                  item: item,\n                  matches: matches\n                });\n              }\n            }\n          }\n  \n          return results;\n        }\n      }, {\n        key: \"_computeScore\",\n        value: function _computeScore(results) {\n          for (var i = 0, len = results.length; i < len; i += 1) {\n            var result = results[i];\n            var matches = result.matches;\n            var scoreLen = matches.length;\n            var totalWeightedScore = 1;\n  \n            for (var j = 0; j < scoreLen; j += 1) {\n              var item = matches[j];\n              var key = item.key;\n  \n              var keyWeight = this._keyStore.get(key, 'weight');\n  \n              var weight = keyWeight > -1 ? keyWeight : 1;\n              var score = item.score === 0 && keyWeight > -1 ? Number.EPSILON : item.score;\n              totalWeightedScore *= Math.pow(score, weight);\n            }\n  \n            result.score = totalWeightedScore;\n          }\n        }\n      }, {\n        key: \"_sort\",\n        value: function _sort(results) {\n          results.sort(this.options.sortFn);\n        }\n      }, {\n        key: \"_format\",\n        value: function _format(results) {\n          var finalOutput = [];\n          var _this$options2 = this.options,\n              includeMatches = _this$options2.includeMatches,\n              includeScore = _this$options2.includeScore;\n          var transformers = [];\n          if (includeMatches) { transformers.push(transformMatches); }\n          if (includeScore) { transformers.push(transformScore); }\n  \n          for (var i = 0, len = results.length; i < len; i += 1) {\n            var result = results[i];\n            var idx = result.idx;\n            var data = {\n              item: this.list[idx],\n              refIndex: idx\n            };\n  \n            if (transformers.length) {\n              for (var j = 0, _len3 = transformers.length; j < _len3; j += 1) {\n                transformers[j](result, data);\n              }\n            }\n  \n            finalOutput.push(data);\n          }\n  \n          return finalOutput;\n        }\n      }]);\n  \n      return Fuse;\n    }();\n  \n    Fuse.version = '5.1.0';\n    Fuse.createIndex = createIndex;\n    Fuse.defaultOptions = defaultOptions;\n  \n    return Fuse;\n  \n  })));"
  },
  {
    "path": "html2screenshot.js",
    "content": "/*!\n * html2canvas 1.0.0-rc.5 <https://html2canvas.hertzen.com>\n * Copyright (c) 2020 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\n!function(A,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(A=A||self).html2canvas=e()}(this,function(){\"use strict\";\n/*! *****************************************************************************\n    Copyright (c) Microsoft Corporation. All rights reserved.\n    Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n    this file except in compliance with the License. You may obtain a copy of the\n    License at http://www.apache.org/licenses/LICENSE-2.0\n\n    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\n    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\n    MERCHANTABLITY OR NON-INFRINGEMENT.\n\n    See the Apache Version 2.0 License for specific language governing permissions\n    and limitations under the License.\n    ***************************************************************************** */var r=function(A,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(A,e){A.__proto__=e}||function(A,e){for(var t in e)e.hasOwnProperty(t)&&(A[t]=e[t])})(A,e)};function A(A,e){function t(){this.constructor=A}r(A,e),A.prototype=null===e?Object.create(e):(t.prototype=e.prototype,new t)}var K=function(){return(K=Object.assign||function(A){for(var e,t=1,r=arguments.length;t<r;t++)for(var n in e=arguments[t])Object.prototype.hasOwnProperty.call(e,n)&&(A[n]=e[n]);return A}).apply(this,arguments)};function a(B,s,o,i){return new(o||(o=Promise))(function(A,e){function t(A){try{n(i.next(A))}catch(A){e(A)}}function r(A){try{n(i.throw(A))}catch(A){e(A)}}function n(e){e.done?A(e.value):new o(function(A){A(e.value)}).then(t,r)}n((i=i.apply(B,s||[])).next())})}function S(t,r){var n,B,s,A,o={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return A={next:e(0),throw:e(1),return:e(2)},\"function\"==typeof Symbol&&(A[Symbol.iterator]=function(){return this}),A;function e(e){return function(A){return function(e){if(n)throw new TypeError(\"Generator is already executing.\");for(;o;)try{if(n=1,B&&(s=2&e[0]?B.return:e[0]?B.throw||((s=B.return)&&s.call(B),0):B.next)&&!(s=s.call(B,e[1])).done)return s;switch(B=0,s&&(e=[2&e[0],s.value]),e[0]){case 0:case 1:s=e;break;case 4:return o.label++,{value:e[1],done:!1};case 5:o.label++,B=e[1],e=[0];continue;case 7:e=o.ops.pop(),o.trys.pop();continue;default:if(!(s=0<(s=o.trys).length&&s[s.length-1])&&(6===e[0]||2===e[0])){o=0;continue}if(3===e[0]&&(!s||e[1]>s[0]&&e[1]<s[3])){o.label=e[1];break}if(6===e[0]&&o.label<s[1]){o.label=s[1],s=e;break}if(s&&o.label<s[2]){o.label=s[2],o.ops.push(e);break}s[2]&&o.ops.pop(),o.trys.pop();continue}e=r.call(t,o)}catch(A){e=[6,A],B=0}finally{n=s=0}if(5&e[0])throw e[1];return{value:e[0]?e[1]:void 0,done:!0}}([e,A])}}}var I=(n.prototype.add=function(A,e,t,r){return new n(this.left+A,this.top+e,this.width+t,this.height+r)},n.fromClientRect=function(A){return new n(A.left,A.top,A.width,A.height)},n);function n(A,e,t,r){this.left=A,this.top=e,this.width=t,this.height=r}for(var T=function(A){return I.fromClientRect(A.getBoundingClientRect())},c=function(A){for(var e=[],t=0,r=A.length;t<r;){var n=A.charCodeAt(t++);if(55296<=n&&n<=56319&&t<r){var B=A.charCodeAt(t++);56320==(64512&B)?e.push(((1023&n)<<10)+(1023&B)+65536):(e.push(n),t--)}else e.push(n)}return e},l=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];if(String.fromCodePoint)return String.fromCodePoint.apply(String,A);var t=A.length;if(!t)return\"\";for(var r=[],n=-1,B=\"\";++n<t;){var s=A[n];s<=65535?r.push(s):(s-=65536,r.push(55296+(s>>10),s%1024+56320)),(n+1===t||16384<r.length)&&(B+=String.fromCharCode.apply(String,r),r.length=0)}return B},e=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",Q=\"undefined\"==typeof Uint8Array?[]:new Uint8Array(256),t=0;t<e.length;t++)Q[e.charCodeAt(t)]=t;function B(A,e,t){return A.slice?A.slice(e,t):new Uint16Array(Array.prototype.slice.call(A,e,t))}var s=(o.prototype.get=function(A){var e;if(0<=A){if(A<55296||56319<A&&A<=65535)return e=((e=this.index[A>>5])<<2)+(31&A),this.data[e];if(A<=65535)return e=((e=this.index[2048+(A-55296>>5)])<<2)+(31&A),this.data[e];if(A<this.highStart)return e=2080+(A>>11),e=this.index[e],e+=A>>5&63,e=((e=this.index[e])<<2)+(31&A),this.data[e];if(A<=1114111)return this.data[this.highValueIndex]}return this.errorValue},o);function o(A,e,t,r,n,B){this.initialValue=A,this.errorValue=e,this.highStart=t,this.highValueIndex=r,this.index=n,this.data=B}function C(A,e,t,r){var n=r[t];if(Array.isArray(A)?-1!==A.indexOf(n):A===n)for(var B=t;B<=r.length;){if((i=r[++B])===e)return!0;if(i!==H)break}if(n===H)for(B=t;0<B;){var s=r[--B];if(Array.isArray(A)?-1!==A.indexOf(s):A===s)for(var o=t;o<=r.length;){var i;if((i=r[++o])===e)return!0;if(i!==H)break}if(s!==H)break}return!1}function g(A,e){for(var t=A;0<=t;){var r=e[t];if(r!==H)return r;t--}return 0}function w(A,e,t,r,n){if(0===t[r])return Y;var B=r-1;if(Array.isArray(n)&&!0===n[B])return Y;var s=B-1,o=1+B,i=e[B],a=0<=s?e[s]:0,c=e[o];if(2===i&&3===c)return Y;if(-1!==j.indexOf(i))return\"!\";if(-1!==j.indexOf(c))return Y;if(-1!==$.indexOf(c))return Y;if(8===g(B,e))return\"÷\";if(11===q.get(A[B])&&(c===X||c===P||c===x))return Y;if(7===i||7===c)return Y;if(9===i)return Y;if(-1===[H,d,f].indexOf(i)&&9===c)return Y;if(-1!==[p,N,m,O,y].indexOf(c))return Y;if(g(B,e)===v)return Y;if(C(23,v,B,e))return Y;if(C([p,N],L,B,e))return Y;if(C(12,12,B,e))return Y;if(i===H)return\"÷\";if(23===i||23===c)return Y;if(16===c||16===i)return\"÷\";if(-1!==[d,f,L].indexOf(c)||14===i)return Y;if(36===a&&-1!==rA.indexOf(i))return Y;if(i===y&&36===c)return Y;if(c===R&&-1!==Z.concat(R,m,D,X,P,x).indexOf(i))return Y;if(-1!==Z.indexOf(c)&&i===D||-1!==Z.indexOf(i)&&c===D)return Y;if(i===M&&-1!==[X,P,x].indexOf(c)||-1!==[X,P,x].indexOf(i)&&c===b)return Y;if(-1!==Z.indexOf(i)&&-1!==AA.indexOf(c)||-1!==AA.indexOf(i)&&-1!==Z.indexOf(c))return Y;if(-1!==[M,b].indexOf(i)&&(c===D||-1!==[v,f].indexOf(c)&&e[1+o]===D)||-1!==[v,f].indexOf(i)&&c===D||i===D&&-1!==[D,y,O].indexOf(c))return Y;if(-1!==[D,y,O,p,N].indexOf(c))for(var Q=B;0<=Q;){if((w=e[Q])===D)return Y;if(-1===[y,O].indexOf(w))break;Q--}if(-1!==[M,b].indexOf(c))for(Q=-1!==[p,N].indexOf(i)?s:B;0<=Q;){var w;if((w=e[Q])===D)return Y;if(-1===[y,O].indexOf(w))break;Q--}if(J===i&&-1!==[J,G,V,z].indexOf(c)||-1!==[G,V].indexOf(i)&&-1!==[G,k].indexOf(c)||-1!==[k,z].indexOf(i)&&c===k)return Y;if(-1!==tA.indexOf(i)&&-1!==[R,b].indexOf(c)||-1!==tA.indexOf(c)&&i===M)return Y;if(-1!==Z.indexOf(i)&&-1!==Z.indexOf(c))return Y;if(i===O&&-1!==Z.indexOf(c))return Y;if(-1!==Z.concat(D).indexOf(i)&&c===v||-1!==Z.concat(D).indexOf(c)&&i===N)return Y;if(41===i&&41===c){for(var u=t[B],U=1;0<u&&41===e[--u];)U++;if(U%2!=0)return Y}return i===P&&c===x?Y:\"÷\"}function u(t,A){A||(A={lineBreak:\"normal\",wordBreak:\"normal\"});var e=function(A,n){void 0===n&&(n=\"strict\");var B=[],s=[],o=[];return A.forEach(function(A,e){var t=q.get(A);if(50<t?(o.push(!0),t-=50):o.push(!1),-1!==[\"normal\",\"auto\",\"loose\"].indexOf(n)&&-1!==[8208,8211,12316,12448].indexOf(A))return s.push(e),B.push(16);if(4!==t&&11!==t)return s.push(e),31===t?B.push(\"strict\"===n?L:X):t===W?B.push(_):29===t?B.push(_):43===t?131072<=A&&A<=196605||196608<=A&&A<=262141?B.push(X):B.push(_):void B.push(t);if(0===e)return s.push(e),B.push(_);var r=B[e-1];return-1===eA.indexOf(r)?(s.push(s[e-1]),B.push(r)):(s.push(e),B.push(_))}),[s,B,o]}(t,A.lineBreak),r=e[0],n=e[1],B=e[2];return\"break-all\"!==A.wordBreak&&\"break-word\"!==A.wordBreak||(n=n.map(function(A){return-1!==[D,_,W].indexOf(A)?X:A})),[r,n,\"keep-all\"===A.wordBreak?B.map(function(A,e){return A&&19968<=t[e]&&t[e]<=40959}):void 0]}var i,U,E,F,h,H=10,d=13,f=15,p=17,N=18,m=19,R=20,L=21,v=22,O=24,D=25,b=26,M=27,y=28,_=30,P=32,x=33,V=34,z=35,X=37,J=38,G=39,k=40,W=42,Y=\"×\",q=(i=function(A){var e,t,r,n,B,s=.75*A.length,o=A.length,i=0;\"=\"===A[A.length-1]&&(s--,\"=\"===A[A.length-2]&&s--);var a=\"undefined\"!=typeof ArrayBuffer&&\"undefined\"!=typeof Uint8Array&&void 0!==Uint8Array.prototype.slice?new ArrayBuffer(s):new Array(s),c=Array.isArray(a)?a:new Uint8Array(a);for(e=0;e<o;e+=4)t=Q[A.charCodeAt(e)],r=Q[A.charCodeAt(e+1)],n=Q[A.charCodeAt(e+2)],B=Q[A.charCodeAt(e+3)],c[i++]=t<<2|r>>4,c[i++]=(15&r)<<4|n>>2,c[i++]=(3&n)<<6|63&B;return a}(\"KwAAAAAAAAAACA4AIDoAAPAfAAACAAAAAAAIABAAGABAAEgAUABYAF4AZgBeAGYAYABoAHAAeABeAGYAfACEAIAAiACQAJgAoACoAK0AtQC9AMUAXgBmAF4AZgBeAGYAzQDVAF4AZgDRANkA3gDmAOwA9AD8AAQBDAEUARoBIgGAAIgAJwEvATcBPwFFAU0BTAFUAVwBZAFsAXMBewGDATAAiwGTAZsBogGkAawBtAG8AcIBygHSAdoB4AHoAfAB+AH+AQYCDgIWAv4BHgImAi4CNgI+AkUCTQJTAlsCYwJrAnECeQKBAk0CiQKRApkCoQKoArACuALAAsQCzAIwANQC3ALkAjAA7AL0AvwCAQMJAxADGAMwACADJgMuAzYDPgOAAEYDSgNSA1IDUgNaA1oDYANiA2IDgACAAGoDgAByA3YDfgOAAIQDgACKA5IDmgOAAIAAogOqA4AAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAK8DtwOAAIAAvwPHA88D1wPfAyAD5wPsA/QD/AOAAIAABAQMBBIEgAAWBB4EJgQuBDMEIAM7BEEEXgBJBCADUQRZBGEEaQQwADAAcQQ+AXkEgQSJBJEEgACYBIAAoASoBK8EtwQwAL8ExQSAAIAAgACAAIAAgACgAM0EXgBeAF4AXgBeAF4AXgBeANUEXgDZBOEEXgDpBPEE+QQBBQkFEQUZBSEFKQUxBTUFPQVFBUwFVAVcBV4AYwVeAGsFcwV7BYMFiwWSBV4AmgWgBacFXgBeAF4AXgBeAKsFXgCyBbEFugW7BcIFwgXIBcIFwgXQBdQF3AXkBesF8wX7BQMGCwYTBhsGIwYrBjMGOwZeAD8GRwZNBl4AVAZbBl4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAGMGXgBqBnEGXgBeAF4AXgBeAF4AXgBeAF4AXgB5BoAG4wSGBo4GkwaAAIADHgR5AF4AXgBeAJsGgABGA4AAowarBrMGswagALsGwwbLBjAA0wbaBtoG3QbaBtoG2gbaBtoG2gblBusG8wb7BgMHCwcTBxsHCwcjBysHMAc1BzUHOgdCB9oGSgdSB1oHYAfaBloHaAfaBlIH2gbaBtoG2gbaBtoG2gbaBjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHbQdeAF4ANQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQd1B30HNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B4MH2gaKB68EgACAAIAAgACAAIAAgACAAI8HlwdeAJ8HpweAAIAArwe3B14AXgC/B8UHygcwANAH2AfgB4AA6AfwBz4B+AcACFwBCAgPCBcIogEYAR8IJwiAAC8INwg/CCADRwhPCFcIXwhnCEoDGgSAAIAAgABvCHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIfQh3CHgIeQh6CHsIfAh9CHcIeAh5CHoIewh8CH0Idwh4CHkIegh7CHwIhAiLCI4IMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAANQc1BzUHNQc1BzUHNQc1BzUHNQc1B54INQc1B6II2gaqCLIIugiAAIAAvgjGCIAAgACAAIAAgACAAIAAgACAAIAAywiHAYAA0wiAANkI3QjlCO0I9Aj8CIAAgACAAAIJCgkSCRoJIgknCTYHLwk3CZYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiWCJYIlgiAAIAAAAFAAXgBeAGAAcABeAHwAQACQAKAArQC9AJ4AXgBeAE0A3gBRAN4A7AD8AMwBGgEAAKcBNwEFAUwBXAF4QkhCmEKnArcCgAHHAsABz4LAAcABwAHAAd+C6ABoAG+C/4LAAcABwAHAAc+DF4MAAcAB54M3gweDV4Nng3eDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEeDqABVg6WDqABoQ6gAaABoAHXDvcONw/3DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DvcO9w73DncPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB7cPPwlGCU4JMACAAIAAgABWCV4JYQmAAGkJcAl4CXwJgAkwADAAMAAwAIgJgACLCZMJgACZCZ8JowmrCYAAswkwAF4AXgB8AIAAuwkABMMJyQmAAM4JgADVCTAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAqwYWBNkIMAAwADAAMADdCeAJ6AnuCR4E9gkwAP4JBQoNCjAAMACAABUK0wiAAB0KJAosCjQKgAAwADwKQwqAAEsKvQmdCVMKWwowADAAgACAALcEMACAAGMKgABrCjAAMAAwADAAMAAwADAAMAAwADAAMAAeBDAAMAAwADAAMAAwADAAMAAwADAAMAAwAIkEPQFzCnoKiQSCCooKkAqJBJgKoAqkCokEGAGsCrQKvArBCjAAMADJCtEKFQHZCuEK/gHpCvEKMAAwADAAMACAAIwE+QowAIAAPwEBCzAAMAAwADAAMACAAAkLEQswAIAAPwEZCyELgAAOCCkLMAAxCzkLMAAwADAAMAAwADAAXgBeAEELMAAwADAAMAAwADAAMAAwAEkLTQtVC4AAXAtkC4AAiQkwADAAMAAwADAAMAAwADAAbAtxC3kLgAuFC4sLMAAwAJMLlwufCzAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAApwswADAAMACAAIAAgACvC4AAgACAAIAAgACAALcLMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAvwuAAMcLgACAAIAAgACAAIAAyguAAIAAgACAAIAA0QswADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAANkLgACAAIAA4AswADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACJCR4E6AswADAAhwHwC4AA+AsADAgMEAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMACAAIAAGAwdDCUMMAAwAC0MNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQw1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHPQwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADUHNQc1BzUHNQc1BzUHNQc2BzAAMAA5DDUHNQc1BzUHNQc1BzUHNQc1BzUHNQdFDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAgACAAIAATQxSDFoMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAF4AXgBeAF4AXgBeAF4AYgxeAGoMXgBxDHkMfwxeAIUMXgBeAI0MMAAwADAAMAAwAF4AXgCVDJ0MMAAwADAAMABeAF4ApQxeAKsMswy7DF4Awgy9DMoMXgBeAF4AXgBeAF4AXgBeAF4AXgDRDNkMeQBqCeAM3Ax8AOYM7Az0DPgMXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgBeAF4AXgCgAAANoAAHDQ4NFg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAeDSYNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIAAgACAAIAAgACAAC4NMABeAF4ANg0wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAD4NRg1ODVYNXg1mDTAAbQ0wADAAMAAwADAAMAAwADAA2gbaBtoG2gbaBtoG2gbaBnUNeg3CBYANwgWFDdoGjA3aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gaUDZwNpA2oDdoG2gawDbcNvw3HDdoG2gbPDdYN3A3fDeYN2gbsDfMN2gbaBvoN/g3aBgYODg7aBl4AXgBeABYOXgBeACUG2gYeDl4AJA5eACwO2w3aBtoGMQ45DtoG2gbaBtoGQQ7aBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDjUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B1EO2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQdZDjUHNQc1BzUHNQc1B2EONQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHaA41BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B3AO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gY1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1BzUHNQc1B2EO2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gZJDtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBtoG2gbaBkkOeA6gAKAAoAAwADAAMAAwAKAAoACgAKAAoACgAKAAgA4wADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAD//wQABAAEAAQABAAEAAQABAAEAA0AAwABAAEAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAKABMAFwAeABsAGgAeABcAFgASAB4AGwAYAA8AGAAcAEsASwBLAEsASwBLAEsASwBLAEsAGAAYAB4AHgAeABMAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAFgAbABIAHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYADQARAB4ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkAFgAaABsAGwAbAB4AHQAdAB4ATwAXAB4ADQAeAB4AGgAbAE8ATwAOAFAAHQAdAB0ATwBPABcATwBPAE8AFgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwArAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAAQABAANAA0ASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAUAArACsAKwArACsAKwArACsABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAGgAaAFAAUABQAFAAUABMAB4AGwBQAB4AKwArACsABAAEAAQAKwBQAFAAUABQAFAAUAArACsAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUAArAFAAUAArACsABAArAAQABAAEAAQABAArACsAKwArAAQABAArACsABAAEAAQAKwArACsABAArACsAKwArACsAKwArAFAAUABQAFAAKwBQACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwAEAAQAUABQAFAABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUAArACsABABQAAQABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQAKwArAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeABsAKwArACsAKwArACsAKwBQAAQABAAEAAQABAAEACsABAAEAAQAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArAAQABAArACsABAAEAAQAKwArACsAKwArACsAKwArAAQABAArACsAKwArAFAAUAArAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwAeAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwAEAFAAKwBQAFAAUABQAFAAUAArACsAKwBQAFAAUAArAFAAUABQAFAAKwArACsAUABQACsAUAArAFAAUAArACsAKwBQAFAAKwArACsAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQAKwArACsABAAEAAQAKwAEAAQABAAEACsAKwBQACsAKwArACsAKwArAAQAKwArACsAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAB4AHgAeAB4AHgAeABsAHgArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArAFAAUABQACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAB4AUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABAArACsAKwArACsAKwArAAQABAArACsAKwArACsAKwArAFAAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwArAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAKwBcAFwAKwBcACsAKwBcACsAKwArACsAKwArAFwAXABcAFwAKwBcAFwAXABcAFwAXABcACsAXABcAFwAKwBcACsAXAArACsAXABcACsAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgArACoAKgBcACsAKwBcAFwAXABcAFwAKwBcACsAKgAqACoAKgAqACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAFwAXABcAFwAUAAOAA4ADgAOAB4ADgAOAAkADgAOAA0ACQATABMAEwATABMACQAeABMAHgAeAB4ABAAEAB4AHgAeAB4AHgAeAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUAANAAQAHgAEAB4ABAAWABEAFgARAAQABABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAAQABAAEAAQABAANAAQABABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsADQANAB4AHgAeAB4AHgAeAAQAHgAeAB4AHgAeAB4AKwAeAB4ADgAOAA0ADgAeAB4AHgAeAB4ACQAJACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgAeAB4AHgBcAFwAXABcAFwAXAAqACoAKgAqAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAKgAqACoAKgAqACoAKgBcAFwAXAAqACoAKgAqAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAXAAqAEsASwBLAEsASwBLAEsASwBLAEsAKgAqACoAKgAqACoAUABQAFAAUABQAFAAKwBQACsAKwArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQACsAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwAEAAQABAAeAA0AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAEQArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAADQANAA0AUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAA0ADQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQACsABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoADQANABUAXAANAB4ADQAbAFwAKgArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAB4AHgATABMADQANAA4AHgATABMAHgAEAAQABAAJACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAUABQAFAAUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwAeACsAKwArABMAEwBLAEsASwBLAEsASwBLAEsASwBLAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwBcAFwAXABcAFwAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcACsAKwArACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwAeAB4AXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsABABLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKgAqACoAKgAqACoAKgBcACoAKgAqACoAKgAqACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAUABQAFAAUABQAFAAUAArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4ADQANAA0ADQAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAHgAeAB4AHgBQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwANAA0ADQANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwBQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsABAAEAAQAHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAABABQAFAAUABQAAQABAAEAFAAUAAEAAQABAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAKwBQACsAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAKwArAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAKwAeAB4AHgAeAB4AHgAeAA4AHgArAA0ADQANAA0ADQANAA0ACQANAA0ADQAIAAQACwAEAAQADQAJAA0ADQAMAB0AHQAeABcAFwAWABcAFwAXABYAFwAdAB0AHgAeABQAFAAUAA0AAQABAAQABAAEAAQABAAJABoAGgAaABoAGgAaABoAGgAeABcAFwAdABUAFQAeAB4AHgAeAB4AHgAYABYAEQAVABUAFQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgANAB4ADQANAA0ADQAeAA0ADQANAAcAHgAeAB4AHgArAAQABAAEAAQABAAEAAQABAAEAAQAUABQACsAKwBPAFAAUABQAFAAUAAeAB4AHgAWABEATwBQAE8ATwBPAE8AUABQAFAAUABQAB4AHgAeABYAEQArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAaABsAGwAbABsAGgAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgBQABoAHgAdAB4AUAAeABoAHgAeAB4AHgAeAB4AHgAeAB4ATwAeAFAAGwAeAB4AUABQAFAAUABQAB4AHgAeAB0AHQAeAFAAHgBQAB4AUAAeAFAATwBQAFAAHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AUABQAFAAUABPAE8AUABQAFAAUABQAE8AUABQAE8AUABPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAE8ATwBPAE8ATwBPAE8ATwBPAE8AUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAATwAeAB4AKwArACsAKwAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB0AHQAeAB4AHgAdAB0AHgAeAB0AHgAeAB4AHQAeAB0AGwAbAB4AHQAeAB4AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB0AHgAdAB4AHQAdAB0AHQAdAB0AHgAdAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAdAB0AHQAdAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAlACUAHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBQAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAeAB4AHgAeAB0AHQAeAB4AHgAeAB0AHQAdAB4AHgAdAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB0AHQAeAB4AHQAeAB4AHgAeAB0AHQAeAB4AHgAeACUAJQAdAB0AJQAeACUAJQAlACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAHgAeAB4AHgAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHQAdAB0AHgAdACUAHQAdAB4AHQAdAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHQAdAB0AHQAlAB4AJQAlACUAHQAlACUAHQAdAB0AJQAlAB0AHQAlAB0AHQAlACUAJQAeAB0AHgAeAB4AHgAdAB0AJQAdAB0AHQAdAB0AHQAlACUAJQAlACUAHQAlACUAIAAlAB0AHQAlACUAJQAlACUAJQAlACUAHgAeAB4AJQAlACAAIAAgACAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeABcAFwAXABcAFwAXAB4AEwATACUAHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACUAJQBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwArACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAE8ATwBPAE8ATwBPAE8ATwAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeACsAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUAArACsAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQBQAFAAUABQACsAKwArACsAUABQAFAAUABQAFAAUABQAA0AUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAABAAEAAQAKwAEAAQAKwArACsAKwArAAQABAAEAAQAUABQAFAAUAArAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsABAAEAAQAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsADQANAA0ADQANAA0ADQANAB4AKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAUABQAFAAUABQAA0ADQANAA0ADQANABQAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwANAA0ADQANAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAeAAQABAAEAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLACsADQArAB4AKwArAAQABAAEAAQAUABQAB4AUAArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwAEAAQABAAEAAQABAAEAAQABAAOAA0ADQATABMAHgAeAB4ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0AUABQAFAAUAAEAAQAKwArAAQADQANAB4AUAArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXABcAA0ADQANACoASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUAArACsAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANACsADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEcARwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQACsAKwAeAAQABAANAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAEAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUAArACsAUAArACsAUABQACsAKwBQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AKwArAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAeAB4ADQANAA0ADQAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAArAAQABAArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAEAAQABAAEAAQABAAEACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAFgAWAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAKwBQACsAKwArACsAKwArAFAAKwArACsAKwBQACsAUAArAFAAKwBQAFAAUAArAFAAUAArAFAAKwArAFAAKwBQACsAUAArAFAAKwBQACsAUABQACsAUAArACsAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAUABQAFAAUAArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUAArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAlACUAJQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeACUAJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeACUAJQAlACUAJQAeACUAJQAlACUAJQAgACAAIAAlACUAIAAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIQAhACEAIQAhACUAJQAgACAAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAIAAlACUAJQAlACAAJQAgACAAIAAgACAAIAAgACAAIAAlACUAJQAgACUAJQAlACUAIAAgACAAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeACUAHgAlAB4AJQAlACUAJQAlACAAJQAlACUAJQAeACUAHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAIAAgACAAIAAgAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFwAXABcAFQAVABUAHgAeAB4AHgAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAIAAgACAAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAlACAAIAAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsA\"),U=Array.isArray(i)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=4)t.push(A[r+3]<<24|A[r+2]<<16|A[r+1]<<8|A[r]);return t}(i):new Uint32Array(i),E=Array.isArray(i)?function(A){for(var e=A.length,t=[],r=0;r<e;r+=2)t.push(A[r+1]<<8|A[r]);return t}(i):new Uint16Array(i),F=B(E,12,U[4]/2),h=2===U[5]?B(E,(24+U[4])/2):function(A,e,t){return A.slice?A.slice(e,t):new Uint32Array(Array.prototype.slice.call(A,e,t))}(U,Math.ceil((24+U[4])/4)),new s(U[0],U[1],U[2],U[3],F,h)),Z=[_,36],j=[1,2,3,5],$=[H,8],AA=[M,b],eA=j.concat($),tA=[J,G,k,V,z],rA=[f,d],nA=(BA.prototype.slice=function(){return l.apply(void 0,this.codePoints.slice(this.start,this.end))},BA);function BA(A,e,t,r){this.codePoints=A,this.required=\"!\"===e,this.start=t,this.end=r}var sA,oA;(oA=sA||(sA={}))[oA.STRING_TOKEN=0]=\"STRING_TOKEN\",oA[oA.BAD_STRING_TOKEN=1]=\"BAD_STRING_TOKEN\",oA[oA.LEFT_PARENTHESIS_TOKEN=2]=\"LEFT_PARENTHESIS_TOKEN\",oA[oA.RIGHT_PARENTHESIS_TOKEN=3]=\"RIGHT_PARENTHESIS_TOKEN\",oA[oA.COMMA_TOKEN=4]=\"COMMA_TOKEN\",oA[oA.HASH_TOKEN=5]=\"HASH_TOKEN\",oA[oA.DELIM_TOKEN=6]=\"DELIM_TOKEN\",oA[oA.AT_KEYWORD_TOKEN=7]=\"AT_KEYWORD_TOKEN\",oA[oA.PREFIX_MATCH_TOKEN=8]=\"PREFIX_MATCH_TOKEN\",oA[oA.DASH_MATCH_TOKEN=9]=\"DASH_MATCH_TOKEN\",oA[oA.INCLUDE_MATCH_TOKEN=10]=\"INCLUDE_MATCH_TOKEN\",oA[oA.LEFT_CURLY_BRACKET_TOKEN=11]=\"LEFT_CURLY_BRACKET_TOKEN\",oA[oA.RIGHT_CURLY_BRACKET_TOKEN=12]=\"RIGHT_CURLY_BRACKET_TOKEN\",oA[oA.SUFFIX_MATCH_TOKEN=13]=\"SUFFIX_MATCH_TOKEN\",oA[oA.SUBSTRING_MATCH_TOKEN=14]=\"SUBSTRING_MATCH_TOKEN\",oA[oA.DIMENSION_TOKEN=15]=\"DIMENSION_TOKEN\",oA[oA.PERCENTAGE_TOKEN=16]=\"PERCENTAGE_TOKEN\",oA[oA.NUMBER_TOKEN=17]=\"NUMBER_TOKEN\",oA[oA.FUNCTION=18]=\"FUNCTION\",oA[oA.FUNCTION_TOKEN=19]=\"FUNCTION_TOKEN\",oA[oA.IDENT_TOKEN=20]=\"IDENT_TOKEN\",oA[oA.COLUMN_TOKEN=21]=\"COLUMN_TOKEN\",oA[oA.URL_TOKEN=22]=\"URL_TOKEN\",oA[oA.BAD_URL_TOKEN=23]=\"BAD_URL_TOKEN\",oA[oA.CDC_TOKEN=24]=\"CDC_TOKEN\",oA[oA.CDO_TOKEN=25]=\"CDO_TOKEN\",oA[oA.COLON_TOKEN=26]=\"COLON_TOKEN\",oA[oA.SEMICOLON_TOKEN=27]=\"SEMICOLON_TOKEN\",oA[oA.LEFT_SQUARE_BRACKET_TOKEN=28]=\"LEFT_SQUARE_BRACKET_TOKEN\",oA[oA.RIGHT_SQUARE_BRACKET_TOKEN=29]=\"RIGHT_SQUARE_BRACKET_TOKEN\",oA[oA.UNICODE_RANGE_TOKEN=30]=\"UNICODE_RANGE_TOKEN\",oA[oA.WHITESPACE_TOKEN=31]=\"WHITESPACE_TOKEN\",oA[oA.EOF_TOKEN=32]=\"EOF_TOKEN\";function iA(A){return 48<=A&&A<=57}function aA(A){return iA(A)||65<=A&&A<=70||97<=A&&A<=102}function cA(A){return 10===A||9===A||32===A}function QA(A){return function(A){return function(A){return 97<=A&&A<=122}(A)||function(A){return 65<=A&&A<=90}(A)}(A)||function(A){return 128<=A}(A)||95===A}function wA(A){return QA(A)||iA(A)||45===A}function uA(A,e){return 92===A&&10!==e}function UA(A,e,t){return 45===A?QA(e)||uA(e,t):!!QA(A)||!(92!==A||!uA(A,e))}function lA(A,e,t){return 43===A||45===A?!!iA(e)||46===e&&iA(t):iA(46===A?e:A)}var CA={type:sA.LEFT_PARENTHESIS_TOKEN},gA={type:sA.RIGHT_PARENTHESIS_TOKEN},EA={type:sA.COMMA_TOKEN},FA={type:sA.SUFFIX_MATCH_TOKEN},hA={type:sA.PREFIX_MATCH_TOKEN},HA={type:sA.COLUMN_TOKEN},dA={type:sA.DASH_MATCH_TOKEN},fA={type:sA.INCLUDE_MATCH_TOKEN},pA={type:sA.LEFT_CURLY_BRACKET_TOKEN},NA={type:sA.RIGHT_CURLY_BRACKET_TOKEN},KA={type:sA.SUBSTRING_MATCH_TOKEN},IA={type:sA.BAD_URL_TOKEN},TA={type:sA.BAD_STRING_TOKEN},mA={type:sA.CDO_TOKEN},RA={type:sA.CDC_TOKEN},LA={type:sA.COLON_TOKEN},vA={type:sA.SEMICOLON_TOKEN},OA={type:sA.LEFT_SQUARE_BRACKET_TOKEN},DA={type:sA.RIGHT_SQUARE_BRACKET_TOKEN},bA={type:sA.WHITESPACE_TOKEN},SA={type:sA.EOF_TOKEN},MA=(yA.prototype.write=function(A){this._value=this._value.concat(c(A))},yA.prototype.read=function(){for(var A=[],e=this.consumeToken();e!==SA;)A.push(e),e=this.consumeToken();return A},yA.prototype.consumeToken=function(){var A=this.consumeCodePoint();switch(A){case 34:return this.consumeStringToken(34);case 35:var e=this.peekCodePoint(0),t=this.peekCodePoint(1),r=this.peekCodePoint(2);if(wA(e)||uA(t,r)){var n=UA(e,t,r)?2:1,B=this.consumeName();return{type:sA.HASH_TOKEN,value:B,flags:n}}break;case 36:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),FA;break;case 39:return this.consumeStringToken(39);case 40:return CA;case 41:return gA;case 42:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),KA;break;case 43:if(lA(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case 44:return EA;case 45:var s=A,o=this.peekCodePoint(0),i=this.peekCodePoint(1);if(lA(s,o,i))return this.reconsumeCodePoint(A),this.consumeNumericToken();if(UA(s,o,i))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();if(45===o&&62===i)return this.consumeCodePoint(),this.consumeCodePoint(),RA;break;case 46:if(lA(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case 47:if(42===this.peekCodePoint(0))for(this.consumeCodePoint();;){var a=this.consumeCodePoint();if(42===a&&47===(a=this.consumeCodePoint()))return this.consumeToken();if(-1===a)return this.consumeToken()}break;case 58:return LA;case 59:return vA;case 60:if(33===this.peekCodePoint(0)&&45===this.peekCodePoint(1)&&45===this.peekCodePoint(2))return this.consumeCodePoint(),this.consumeCodePoint(),mA;break;case 64:var c=this.peekCodePoint(0),Q=this.peekCodePoint(1),w=this.peekCodePoint(2);if(UA(c,Q,w))return B=this.consumeName(),{type:sA.AT_KEYWORD_TOKEN,value:B};break;case 91:return OA;case 92:if(uA(A,this.peekCodePoint(0)))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();break;case 93:return DA;case 61:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),hA;break;case 123:return pA;case 125:return NA;case 117:case 85:var u=this.peekCodePoint(0),U=this.peekCodePoint(1);return 43!==u||!aA(U)&&63!==U||(this.consumeCodePoint(),this.consumeUnicodeRangeToken()),this.reconsumeCodePoint(A),this.consumeIdentLikeToken();case 124:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),dA;if(124===this.peekCodePoint(0))return this.consumeCodePoint(),HA;break;case 126:if(61===this.peekCodePoint(0))return this.consumeCodePoint(),fA;break;case-1:return SA}return cA(A)?(this.consumeWhiteSpace(),bA):iA(A)?(this.reconsumeCodePoint(A),this.consumeNumericToken()):QA(A)?(this.reconsumeCodePoint(A),this.consumeIdentLikeToken()):{type:sA.DELIM_TOKEN,value:l(A)}},yA.prototype.consumeCodePoint=function(){var A=this._value.shift();return void 0===A?-1:A},yA.prototype.reconsumeCodePoint=function(A){this._value.unshift(A)},yA.prototype.peekCodePoint=function(A){return A>=this._value.length?-1:this._value[A]},yA.prototype.consumeUnicodeRangeToken=function(){for(var A=[],e=this.consumeCodePoint();aA(e)&&A.length<6;)A.push(e),e=this.consumeCodePoint();for(var t=!1;63===e&&A.length<6;)A.push(e),e=this.consumeCodePoint(),t=!0;if(t){var r=parseInt(l.apply(void 0,A.map(function(A){return 63===A?48:A})),16),n=parseInt(l.apply(void 0,A.map(function(A){return 63===A?70:A})),16);return{type:sA.UNICODE_RANGE_TOKEN,start:r,end:n}}var B=parseInt(l.apply(void 0,A),16);if(45===this.peekCodePoint(0)&&aA(this.peekCodePoint(1))){this.consumeCodePoint(),e=this.consumeCodePoint();for(var s=[];aA(e)&&s.length<6;)s.push(e),e=this.consumeCodePoint();return n=parseInt(l.apply(void 0,s),16),{type:sA.UNICODE_RANGE_TOKEN,start:B,end:n}}return{type:sA.UNICODE_RANGE_TOKEN,start:B,end:B}},yA.prototype.consumeIdentLikeToken=function(){var A=this.consumeName();return\"url\"===A.toLowerCase()&&40===this.peekCodePoint(0)?(this.consumeCodePoint(),this.consumeUrlToken()):40===this.peekCodePoint(0)?(this.consumeCodePoint(),{type:sA.FUNCTION_TOKEN,value:A}):{type:sA.IDENT_TOKEN,value:A}},yA.prototype.consumeUrlToken=function(){var A=[];if(this.consumeWhiteSpace(),-1===this.peekCodePoint(0))return{type:sA.URL_TOKEN,value:\"\"};var e,t=this.peekCodePoint(0);if(39===t||34===t){var r=this.consumeStringToken(this.consumeCodePoint());return r.type===sA.STRING_TOKEN&&(this.consumeWhiteSpace(),-1===this.peekCodePoint(0)||41===this.peekCodePoint(0))?(this.consumeCodePoint(),{type:sA.URL_TOKEN,value:r.value}):(this.consumeBadUrlRemnants(),IA)}for(;;){var n=this.consumeCodePoint();if(-1===n||41===n)return{type:sA.URL_TOKEN,value:l.apply(void 0,A)};if(cA(n))return this.consumeWhiteSpace(),-1===this.peekCodePoint(0)||41===this.peekCodePoint(0)?(this.consumeCodePoint(),{type:sA.URL_TOKEN,value:l.apply(void 0,A)}):(this.consumeBadUrlRemnants(),IA);if(34===n||39===n||40===n||0<=(e=n)&&e<=8||11===e||14<=e&&e<=31||127===e)return this.consumeBadUrlRemnants(),IA;if(92===n){if(!uA(n,this.peekCodePoint(0)))return this.consumeBadUrlRemnants(),IA;A.push(this.consumeEscapedCodePoint())}else A.push(n)}},yA.prototype.consumeWhiteSpace=function(){for(;cA(this.peekCodePoint(0));)this.consumeCodePoint()},yA.prototype.consumeBadUrlRemnants=function(){for(;;){var A=this.consumeCodePoint();if(41===A||-1===A)return;uA(A,this.peekCodePoint(0))&&this.consumeEscapedCodePoint()}},yA.prototype.consumeStringSlice=function(A){for(var e=\"\";0<A;){var t=Math.min(6e4,A);e+=l.apply(void 0,this._value.splice(0,t)),A-=t}return this._value.shift(),e},yA.prototype.consumeStringToken=function(A){for(var e=\"\",t=0;;){var r=this._value[t];if(-1===r||void 0===r||r===A)return e+=this.consumeStringSlice(t),{type:sA.STRING_TOKEN,value:e};if(10===r)return this._value.splice(0,t),TA;if(92===r){var n=this._value[t+1];-1!==n&&void 0!==n&&(10===n?(e+=this.consumeStringSlice(t),t=-1,this._value.shift()):uA(r,n)&&(e+=this.consumeStringSlice(t),e+=l(this.consumeEscapedCodePoint()),t=-1))}t++}},yA.prototype.consumeNumber=function(){var A=[],e=4,t=this.peekCodePoint(0);for(43!==t&&45!==t||A.push(this.consumeCodePoint());iA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());t=this.peekCodePoint(0);var r=this.peekCodePoint(1);if(46===t&&iA(r))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),e=8;iA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());t=this.peekCodePoint(0),r=this.peekCodePoint(1);var n=this.peekCodePoint(2);if((69===t||101===t)&&((43===r||45===r)&&iA(n)||iA(r)))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),e=8;iA(this.peekCodePoint(0));)A.push(this.consumeCodePoint());return[function(A){var e=0,t=1;43!==A[e]&&45!==A[e]||(45===A[e]&&(t=-1),e++);for(var r=[];iA(A[e]);)r.push(A[e++]);var n=r.length?parseInt(l.apply(void 0,r),10):0;46===A[e]&&e++;for(var B=[];iA(A[e]);)B.push(A[e++]);var s=B.length,o=s?parseInt(l.apply(void 0,B),10):0;69!==A[e]&&101!==A[e]||e++;var i=1;43!==A[e]&&45!==A[e]||(45===A[e]&&(i=-1),e++);for(var a=[];iA(A[e]);)a.push(A[e++]);var c=a.length?parseInt(l.apply(void 0,a),10):0;return t*(n+o*Math.pow(10,-s))*Math.pow(10,i*c)}(A),e]},yA.prototype.consumeNumericToken=function(){var A=this.consumeNumber(),e=A[0],t=A[1],r=this.peekCodePoint(0),n=this.peekCodePoint(1),B=this.peekCodePoint(2);if(UA(r,n,B)){var s=this.consumeName();return{type:sA.DIMENSION_TOKEN,number:e,flags:t,unit:s}}return 37===r?(this.consumeCodePoint(),{type:sA.PERCENTAGE_TOKEN,number:e,flags:t}):{type:sA.NUMBER_TOKEN,number:e,flags:t}},yA.prototype.consumeEscapedCodePoint=function(){var A=this.consumeCodePoint();if(aA(A)){for(var e=l(A);aA(this.peekCodePoint(0))&&e.length<6;)e+=l(this.consumeCodePoint());cA(this.peekCodePoint(0))&&this.consumeCodePoint();var t=parseInt(e,16);return 0===t||function(A){return 55296<=A&&A<=57343}(t)||1114111<t?65533:t}return-1===A?65533:A},yA.prototype.consumeName=function(){for(var A=\"\";;){var e=this.consumeCodePoint();if(wA(e))A+=l(e);else{if(!uA(e,this.peekCodePoint(0)))return this.reconsumeCodePoint(e),A;A+=l(this.consumeEscapedCodePoint())}}},yA);function yA(){this._value=[]}var _A=(PA.create=function(A){var e=new MA;return e.write(A),new PA(e.read())},PA.parseValue=function(A){return PA.create(A).parseComponentValue()},PA.parseValues=function(A){return PA.create(A).parseComponentValues()},PA.prototype.parseComponentValue=function(){for(var A=this.consumeToken();A.type===sA.WHITESPACE_TOKEN;)A=this.consumeToken();if(A.type===sA.EOF_TOKEN)throw new SyntaxError(\"Error parsing CSS component value, unexpected EOF\");this.reconsumeToken(A);for(var e=this.consumeComponentValue();(A=this.consumeToken()).type===sA.WHITESPACE_TOKEN;);if(A.type===sA.EOF_TOKEN)return e;throw new SyntaxError(\"Error parsing CSS component value, multiple values found when expecting only one\")},PA.prototype.parseComponentValues=function(){for(var A=[];;){var e=this.consumeComponentValue();if(e.type===sA.EOF_TOKEN)return A;A.push(e),A.push()}},PA.prototype.consumeComponentValue=function(){var A=this.consumeToken();switch(A.type){case sA.LEFT_CURLY_BRACKET_TOKEN:case sA.LEFT_SQUARE_BRACKET_TOKEN:case sA.LEFT_PARENTHESIS_TOKEN:return this.consumeSimpleBlock(A.type);case sA.FUNCTION_TOKEN:return this.consumeFunction(A)}return A},PA.prototype.consumeSimpleBlock=function(A){for(var e={type:A,values:[]},t=this.consumeToken();;){if(t.type===sA.EOF_TOKEN||Be(t,A))return e;this.reconsumeToken(t),e.values.push(this.consumeComponentValue()),t=this.consumeToken()}},PA.prototype.consumeFunction=function(A){for(var e={name:A.value,values:[],type:sA.FUNCTION};;){var t=this.consumeToken();if(t.type===sA.EOF_TOKEN||t.type===sA.RIGHT_PARENTHESIS_TOKEN)return e;this.reconsumeToken(t),e.values.push(this.consumeComponentValue())}},PA.prototype.consumeToken=function(){var A=this._tokens.shift();return void 0===A?SA:A},PA.prototype.reconsumeToken=function(A){this._tokens.unshift(A)},PA);function PA(A){this._tokens=A}function xA(A){return A.type===sA.DIMENSION_TOKEN}function VA(A){return A.type===sA.NUMBER_TOKEN}function zA(A){return A.type===sA.IDENT_TOKEN}function XA(A){return A.type===sA.STRING_TOKEN}function JA(A,e){return zA(A)&&A.value===e}function GA(A){return A.type!==sA.WHITESPACE_TOKEN}function kA(A){return A.type!==sA.WHITESPACE_TOKEN&&A.type!==sA.COMMA_TOKEN}function WA(A){var e=[],t=[];return A.forEach(function(A){if(A.type===sA.COMMA_TOKEN){if(0===t.length)throw new Error(\"Error parsing function args, zero tokens for arg\");return e.push(t),void(t=[])}A.type!==sA.WHITESPACE_TOKEN&&t.push(A)}),t.length&&e.push(t),e}function YA(A){return A.type===sA.NUMBER_TOKEN||A.type===sA.DIMENSION_TOKEN}function qA(A){return A.type===sA.PERCENTAGE_TOKEN||YA(A)}function ZA(A){return 1<A.length?[A[0],A[1]]:[A[0]]}function jA(A,e,t){var r=A[0],n=A[1];return[ae(r,e),ae(void 0!==n?n:r,t)]}function $A(A){return A.type===sA.DIMENSION_TOKEN&&(\"deg\"===A.unit||\"grad\"===A.unit||\"rad\"===A.unit||\"turn\"===A.unit)}function Ae(A){switch(A.filter(zA).map(function(A){return A.value}).join(\" \")){case\"to bottom right\":case\"to right bottom\":case\"left top\":case\"top left\":return[se,se];case\"to top\":case\"bottom\":return Qe(0);case\"to bottom left\":case\"to left bottom\":case\"right top\":case\"top right\":return[se,ie];case\"to right\":case\"left\":return Qe(90);case\"to top left\":case\"to left top\":case\"right bottom\":case\"bottom right\":return[ie,ie];case\"to bottom\":case\"top\":return Qe(180);case\"to top right\":case\"to right top\":case\"left bottom\":case\"bottom left\":return[ie,se];case\"to left\":case\"right\":return Qe(270)}return 0}function ee(A){return 0==(255&A)}function te(A){var e=255&A,t=255&A>>8,r=255&A>>16,n=255&A>>24;return e<255?\"rgba(\"+n+\",\"+r+\",\"+t+\",\"+e/255+\")\":\"rgb(\"+n+\",\"+r+\",\"+t+\")\"}function re(A,e){if(A.type===sA.NUMBER_TOKEN)return A.number;if(A.type!==sA.PERCENTAGE_TOKEN)return 0;var t=3===e?1:255;return 3===e?A.number/100*t:Math.round(A.number/100*t)}function ne(A){var e=A.filter(kA);if(3===e.length){var t=e.map(re),r=t[0],n=t[1],B=t[2];return ue(r,n,B,1)}if(4!==e.length)return 0;var s=e.map(re),o=(r=s[0],n=s[1],B=s[2],s[3]);return ue(r,n,B,o)}var Be=function(A,e){return e===sA.LEFT_CURLY_BRACKET_TOKEN&&A.type===sA.RIGHT_CURLY_BRACKET_TOKEN||(e===sA.LEFT_SQUARE_BRACKET_TOKEN&&A.type===sA.RIGHT_SQUARE_BRACKET_TOKEN||e===sA.LEFT_PARENTHESIS_TOKEN&&A.type===sA.RIGHT_PARENTHESIS_TOKEN)},se={type:sA.NUMBER_TOKEN,number:0,flags:4},oe={type:sA.PERCENTAGE_TOKEN,number:50,flags:4},ie={type:sA.PERCENTAGE_TOKEN,number:100,flags:4},ae=function(A,e){if(A.type===sA.PERCENTAGE_TOKEN)return A.number/100*e;if(xA(A))switch(A.unit){case\"rem\":case\"em\":return 16*A.number;case\"px\":default:return A.number}return A.number},ce=function(A){if(A.type===sA.DIMENSION_TOKEN)switch(A.unit){case\"deg\":return Math.PI*A.number/180;case\"grad\":return Math.PI/200*A.number;case\"rad\":return A.number;case\"turn\":return 2*Math.PI*A.number}throw new Error(\"Unsupported angle type\")},Qe=function(A){return Math.PI*A/180},we=function(A){if(A.type===sA.FUNCTION){var e=he[A.name];if(void 0===e)throw new Error('Attempting to parse an unsupported color function \"'+A.name+'\"');return e(A.values)}if(A.type===sA.HASH_TOKEN){if(3===A.value.length){var t=A.value.substring(0,1),r=A.value.substring(1,2),n=A.value.substring(2,3);return ue(parseInt(t+t,16),parseInt(r+r,16),parseInt(n+n,16),1)}if(4===A.value.length){t=A.value.substring(0,1),r=A.value.substring(1,2),n=A.value.substring(2,3);var B=A.value.substring(3,4);return ue(parseInt(t+t,16),parseInt(r+r,16),parseInt(n+n,16),parseInt(B+B,16)/255)}if(6===A.value.length){t=A.value.substring(0,2),r=A.value.substring(2,4),n=A.value.substring(4,6);return ue(parseInt(t,16),parseInt(r,16),parseInt(n,16),1)}if(8===A.value.length){t=A.value.substring(0,2),r=A.value.substring(2,4),n=A.value.substring(4,6),B=A.value.substring(6,8);return ue(parseInt(t,16),parseInt(r,16),parseInt(n,16),parseInt(B,16)/255)}}if(A.type===sA.IDENT_TOKEN){var s=He[A.value.toUpperCase()];if(void 0!==s)return s}return He.TRANSPARENT},ue=function(A,e,t,r){return(A<<24|e<<16|t<<8|Math.round(255*r)<<0)>>>0};function Ue(A,e,t){return t<0&&(t+=1),1<=t&&(t-=1),t<1/6?(e-A)*t*6+A:t<.5?e:t<2/3?6*(e-A)*(2/3-t)+A:A}function le(A){var e=A.filter(kA),t=e[0],r=e[1],n=e[2],B=e[3],s=(t.type===sA.NUMBER_TOKEN?Qe(t.number):ce(t))/(2*Math.PI),o=qA(r)?r.number/100:0,i=qA(n)?n.number/100:0,a=void 0!==B&&qA(B)?ae(B,1):1;if(0==o)return ue(255*i,255*i,255*i,1);var c=i<=.5?i*(1+o):i+o-i*o,Q=2*i-c,w=Ue(Q,c,s+1/3),u=Ue(Q,c,s),U=Ue(Q,c,s-1/3);return ue(255*w,255*u,255*U,a)}var Ce,ge,Ee,Fe,he={hsl:le,hsla:le,rgb:ne,rgba:ne},He={ALICEBLUE:4042850303,ANTIQUEWHITE:4209760255,AQUA:16777215,AQUAMARINE:2147472639,AZURE:4043309055,BEIGE:4126530815,BISQUE:4293182719,BLACK:255,BLANCHEDALMOND:4293643775,BLUE:65535,BLUEVIOLET:2318131967,BROWN:2771004159,BURLYWOOD:3736635391,CADETBLUE:1604231423,CHARTREUSE:2147418367,CHOCOLATE:3530104575,CORAL:4286533887,CORNFLOWERBLUE:1687547391,CORNSILK:4294499583,CRIMSON:3692313855,CYAN:16777215,DARKBLUE:35839,DARKCYAN:9145343,DARKGOLDENROD:3095837695,DARKGRAY:2846468607,DARKGREEN:6553855,DARKGREY:2846468607,DARKKHAKI:3182914559,DARKMAGENTA:2332068863,DARKOLIVEGREEN:1433087999,DARKORANGE:4287365375,DARKORCHID:2570243327,DARKRED:2332033279,DARKSALMON:3918953215,DARKSEAGREEN:2411499519,DARKSLATEBLUE:1211993087,DARKSLATEGRAY:793726975,DARKSLATEGREY:793726975,DARKTURQUOISE:13554175,DARKVIOLET:2483082239,DEEPPINK:4279538687,DEEPSKYBLUE:12582911,DIMGRAY:1768516095,DIMGREY:1768516095,DODGERBLUE:512819199,FIREBRICK:2988581631,FLORALWHITE:4294635775,FORESTGREEN:579543807,FUCHSIA:4278255615,GAINSBORO:3705462015,GHOSTWHITE:4177068031,GOLD:4292280575,GOLDENROD:3668254975,GRAY:2155905279,GREEN:8388863,GREENYELLOW:2919182335,GREY:2155905279,HONEYDEW:4043305215,HOTPINK:4285117695,INDIANRED:3445382399,INDIGO:1258324735,IVORY:4294963455,KHAKI:4041641215,LAVENDER:3873897215,LAVENDERBLUSH:4293981695,LAWNGREEN:2096890111,LEMONCHIFFON:4294626815,LIGHTBLUE:2916673279,LIGHTCORAL:4034953471,LIGHTCYAN:3774873599,LIGHTGOLDENRODYELLOW:4210742015,LIGHTGRAY:3553874943,LIGHTGREEN:2431553791,LIGHTGREY:3553874943,LIGHTPINK:4290167295,LIGHTSALMON:4288707327,LIGHTSEAGREEN:548580095,LIGHTSKYBLUE:2278488831,LIGHTSLATEGRAY:2005441023,LIGHTSLATEGREY:2005441023,LIGHTSTEELBLUE:2965692159,LIGHTYELLOW:4294959359,LIME:16711935,LIMEGREEN:852308735,LINEN:4210091775,MAGENTA:4278255615,MAROON:2147483903,MEDIUMAQUAMARINE:1724754687,MEDIUMBLUE:52735,MEDIUMORCHID:3126187007,MEDIUMPURPLE:2473647103,MEDIUMSEAGREEN:1018393087,MEDIUMSLATEBLUE:2070474495,MEDIUMSPRINGGREEN:16423679,MEDIUMTURQUOISE:1221709055,MEDIUMVIOLETRED:3340076543,MIDNIGHTBLUE:421097727,MINTCREAM:4127193855,MISTYROSE:4293190143,MOCCASIN:4293178879,NAVAJOWHITE:4292783615,NAVY:33023,OLDLACE:4260751103,OLIVE:2155872511,OLIVEDRAB:1804477439,ORANGE:4289003775,ORANGERED:4282712319,ORCHID:3664828159,PALEGOLDENROD:4008225535,PALEGREEN:2566625535,PALETURQUOISE:2951671551,PALEVIOLETRED:3681588223,PAPAYAWHIP:4293907967,PEACHPUFF:4292524543,PERU:3448061951,PINK:4290825215,PLUM:3718307327,POWDERBLUE:2967529215,PURPLE:2147516671,REBECCAPURPLE:1714657791,RED:4278190335,ROSYBROWN:3163525119,ROYALBLUE:1097458175,SADDLEBROWN:2336560127,SALMON:4202722047,SANDYBROWN:4104413439,SEAGREEN:780883967,SEASHELL:4294307583,SIENNA:2689740287,SILVER:3233857791,SKYBLUE:2278484991,SLATEBLUE:1784335871,SLATEGRAY:1887473919,SLATEGREY:1887473919,SNOW:4294638335,SPRINGGREEN:16744447,STEELBLUE:1182971135,TAN:3535047935,TEAL:8421631,THISTLE:3636451583,TOMATO:4284696575,TRANSPARENT:0,TURQUOISE:1088475391,VIOLET:4001558271,WHEAT:4125012991,WHITE:4294967295,WHITESMOKE:4126537215,YELLOW:4294902015,YELLOWGREEN:2597139199};(ge=Ce||(Ce={}))[ge.VALUE=0]=\"VALUE\",ge[ge.LIST=1]=\"LIST\",ge[ge.IDENT_VALUE=2]=\"IDENT_VALUE\",ge[ge.TYPE_VALUE=3]=\"TYPE_VALUE\",ge[ge.TOKEN_VALUE=4]=\"TOKEN_VALUE\",(Fe=Ee||(Ee={}))[Fe.BORDER_BOX=0]=\"BORDER_BOX\",Fe[Fe.PADDING_BOX=1]=\"PADDING_BOX\";function de(A){var e=we(A[0]),t=A[1];return t&&qA(t)?{color:e,stop:t}:{color:e,stop:null}}function fe(A,t){var e=A[0],r=A[A.length-1];null===e.stop&&(e.stop=se),null===r.stop&&(r.stop=ie);for(var n=[],B=0,s=0;s<A.length;s++){var o=A[s].stop;if(null!==o){var i=ae(o,t);B<i?n.push(i):n.push(B),B=i}else n.push(null)}var a=null;for(s=0;s<n.length;s++){var c=n[s];if(null===c)null===a&&(a=s);else if(null!==a){for(var Q=s-a,w=(c-n[a-1])/(1+Q),u=1;u<=Q;u++)n[a+u-1]=w*u;a=null}}return A.map(function(A,e){return{color:A.color,stop:Math.max(Math.min(1,n[e]/t),0)}})}function pe(A,e,t){var r=\"number\"==typeof A?A:function(A,e,t){var r=e/2,n=t/2,B=ae(A[0],e)-r,s=n-ae(A[1],t);return(Math.atan2(s,B)+2*Math.PI)%(2*Math.PI)}(A,e,t),n=Math.abs(e*Math.sin(r))+Math.abs(t*Math.cos(r)),B=e/2,s=t/2,o=n/2,i=Math.sin(r-Math.PI/2)*o,a=Math.cos(r-Math.PI/2)*o;return[n,B-a,B+a,s-i,s+i]}function Ne(A,e){return Math.sqrt(A*A+e*e)}function Ke(A,e,B,s,o){return[[0,0],[0,e],[A,0],[A,e]].reduce(function(A,e){var t=e[0],r=e[1],n=Ne(B-t,s-r);return(o?n<A.optimumDistance:n>A.optimumDistance)?{optimumCorner:e,optimumDistance:n}:A},{optimumDistance:o?1/0:-1/0,optimumCorner:null}).optimumCorner}function Ie(A){var n=Qe(180),B=[];return WA(A).forEach(function(A,e){if(0===e){var t=A[0];if(t.type===sA.IDENT_TOKEN&&-1!==[\"top\",\"left\",\"right\",\"bottom\"].indexOf(t.value))return void(n=Ae(A));if($A(t))return void(n=(ce(t)+Qe(270))%Qe(360))}var r=de(A);B.push(r)}),{angle:n,stops:B,type:xe.LINEAR_GRADIENT}}function Te(A){return 0===A[0]&&255===A[1]&&0===A[2]&&255===A[3]}var me={name:\"background-clip\",initialValue:\"border-box\",prefix:!(Fe[Fe.CONTENT_BOX=2]=\"CONTENT_BOX\"),type:Ce.LIST,parse:function(A){return A.map(function(A){if(zA(A))switch(A.value){case\"padding-box\":return Ee.PADDING_BOX;case\"content-box\":return Ee.CONTENT_BOX}return Ee.BORDER_BOX})}},Re={name:\"background-color\",initialValue:\"transparent\",prefix:!1,type:Ce.TYPE_VALUE,format:\"color\"},Le=function(A,e,t,r,n){var B=\"http://www.w3.org/2000/svg\",s=document.createElementNS(B,\"svg\"),o=document.createElementNS(B,\"foreignObject\");return s.setAttributeNS(null,\"width\",A.toString()),s.setAttributeNS(null,\"height\",e.toString()),o.setAttributeNS(null,\"width\",\"100%\"),o.setAttributeNS(null,\"height\",\"100%\"),o.setAttributeNS(null,\"x\",t.toString()),o.setAttributeNS(null,\"y\",r.toString()),o.setAttributeNS(null,\"externalResourcesRequired\",\"true\"),s.appendChild(o),o.appendChild(n),s},ve=function(r){return new Promise(function(A,e){var t=new Image;t.onload=function(){return A(t)},t.onerror=e,t.src=\"data:image/svg+xml;charset=utf-8,\"+encodeURIComponent((new XMLSerializer).serializeToString(r))})},Oe={get SUPPORT_RANGE_BOUNDS(){var A=function(A){if(A.createRange){var e=A.createRange();if(e.getBoundingClientRect){var t=A.createElement(\"boundtest\");t.style.height=\"123px\",t.style.display=\"block\",A.body.appendChild(t),e.selectNode(t);var r=e.getBoundingClientRect(),n=Math.round(r.height);if(A.body.removeChild(t),123===n)return!0}}return!1}(document);return Object.defineProperty(Oe,\"SUPPORT_RANGE_BOUNDS\",{value:A}),A},get SUPPORT_SVG_DRAWING(){var A=function(A){var e=new Image,t=A.createElement(\"canvas\"),r=t.getContext(\"2d\");if(!r)return!1;e.src=\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>\";try{r.drawImage(e,0,0),t.toDataURL()}catch(A){return!1}return!0}(document);return Object.defineProperty(Oe,\"SUPPORT_SVG_DRAWING\",{value:A}),A},get SUPPORT_FOREIGNOBJECT_DRAWING(){var A=\"function\"==typeof Array.from&&\"function\"==typeof window.fetch?function(r){var A=r.createElement(\"canvas\"),n=100;A.width=n,A.height=n;var B=A.getContext(\"2d\");if(!B)return Promise.reject(!1);B.fillStyle=\"rgb(0, 255, 0)\",B.fillRect(0,0,n,n);var e=new Image,s=A.toDataURL();e.src=s;var t=Le(n,n,0,0,e);return B.fillStyle=\"red\",B.fillRect(0,0,n,n),ve(t).then(function(A){B.drawImage(A,0,0);var e=B.getImageData(0,0,n,n).data;B.fillStyle=\"red\",B.fillRect(0,0,n,n);var t=r.createElement(\"div\");return t.style.backgroundImage=\"url(\"+s+\")\",t.style.height=\"100px\",Te(e)?ve(Le(n,n,0,0,t)):Promise.reject(!1)}).then(function(A){return B.drawImage(A,0,0),Te(B.getImageData(0,0,n,n).data)}).catch(function(){return!1})}(document):Promise.resolve(!1);return Object.defineProperty(Oe,\"SUPPORT_FOREIGNOBJECT_DRAWING\",{value:A}),A},get SUPPORT_CORS_IMAGES(){var A=void 0!==(new Image).crossOrigin;return Object.defineProperty(Oe,\"SUPPORT_CORS_IMAGES\",{value:A}),A},get SUPPORT_RESPONSE_TYPE(){var A=\"string\"==typeof(new XMLHttpRequest).responseType;return Object.defineProperty(Oe,\"SUPPORT_RESPONSE_TYPE\",{value:A}),A},get SUPPORT_CORS_XHR(){var A=\"withCredentials\"in new XMLHttpRequest;return Object.defineProperty(Oe,\"SUPPORT_CORS_XHR\",{value:A}),A}},De=(be.prototype.debug=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&(\"undefined\"!=typeof window&&window.console&&\"function\"==typeof console.debug?console.debug.apply(console,[this.id,this.getTime()+\"ms\"].concat(A)):this.info.apply(this,A))},be.prototype.getTime=function(){return Date.now()-this.start},be.create=function(A){be.instances[A.id]=new be(A)},be.destroy=function(A){delete be.instances[A]},be.getInstance=function(A){var e=be.instances[A];if(void 0===e)throw new Error(\"No logger instance found with id \"+A);return e},be.prototype.info=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&\"undefined\"!=typeof window&&window.console&&\"function\"==typeof console.info&&console.info.apply(console,[this.id,this.getTime()+\"ms\"].concat(A))},be.prototype.error=function(){for(var A=[],e=0;e<arguments.length;e++)A[e]=arguments[e];this.enabled&&(\"undefined\"!=typeof window&&window.console&&\"function\"==typeof console.error?console.error.apply(console,[this.id,this.getTime()+\"ms\"].concat(A)):this.info.apply(this,A))},be.instances={},be);function be(A){var e=A.id,t=A.enabled;this.id=e,this.enabled=t,this.start=Date.now()}var Se=(Me.create=function(A,e){return Me._caches[A]=new ye(A,e)},Me.destroy=function(A){delete Me._caches[A]},Me.open=function(A){var e=Me._caches[A];if(void 0!==e)return e;throw new Error('Cache with key \"'+A+'\" not found')},Me.getOrigin=function(A){var e=Me._link;return e?(e.href=A,e.href=e.href,e.protocol+e.hostname+e.port):\"about:blank\"},Me.isSameOrigin=function(A){return Me.getOrigin(A)===Me._origin},Me.setContext=function(A){Me._link=A.document.createElement(\"a\"),Me._origin=Me.getOrigin(A.location.href)},Me.getInstance=function(){var A=Me._current;if(null===A)throw new Error(\"No cache instance attached\");return A},Me.attachInstance=function(A){Me._current=A},Me.detachInstance=function(){Me._current=null},Me._caches={},Me._origin=\"about:blank\",Me._current=null,Me);function Me(){}var ye=(_e.prototype.addImage=function(A){var e=Promise.resolve();return this.has(A)||(Ye(A)||Ge(A))&&(this._cache[A]=this.loadImage(A)),e},_e.prototype.match=function(A){return this._cache[A]},_e.prototype.loadImage=function(s){return a(this,void 0,void 0,function(){var e,r,t,n,B=this;return S(this,function(A){switch(A.label){case 0:return e=Se.isSameOrigin(s),r=!ke(s)&&!0===this._options.useCORS&&Oe.SUPPORT_CORS_IMAGES&&!e,t=!ke(s)&&!e&&\"string\"==typeof this._options.proxy&&Oe.SUPPORT_CORS_XHR&&!r,e||!1!==this._options.allowTaint||ke(s)||t||r?(n=s,t?[4,this.proxy(n)]:[3,2]):[2];case 1:n=A.sent(),A.label=2;case 2:return De.getInstance(this.id).debug(\"Added image \"+s.substring(0,256)),[4,new Promise(function(A,e){var t=new Image;t.onload=function(){return A(t)},t.onerror=e,(We(n)||r)&&(t.crossOrigin=\"anonymous\"),t.src=n,!0===t.complete&&setTimeout(function(){return A(t)},500),0<B._options.imageTimeout&&setTimeout(function(){return e(\"Timed out (\"+B._options.imageTimeout+\"ms) loading image\")},B._options.imageTimeout)})];case 3:return[2,A.sent()]}})})},_e.prototype.has=function(A){return void 0!==this._cache[A]},_e.prototype.keys=function(){return Promise.resolve(Object.keys(this._cache))},_e.prototype.proxy=function(B){var s=this,o=this._options.proxy;if(!o)throw new Error(\"No proxy defined\");var i=B.substring(0,256);return new Promise(function(e,t){var r=Oe.SUPPORT_RESPONSE_TYPE?\"blob\":\"text\",n=new XMLHttpRequest;if(n.onload=function(){if(200===n.status)if(\"text\"==r)e(n.response);else{var A=new FileReader;A.addEventListener(\"load\",function(){return e(A.result)},!1),A.addEventListener(\"error\",function(A){return t(A)},!1),A.readAsDataURL(n.response)}else t(\"Failed to proxy resource \"+i+\" with status code \"+n.status)},n.onerror=t,n.open(\"GET\",o+\"?url=\"+encodeURIComponent(B)+\"&responseType=\"+r),\"text\"!=r&&n instanceof XMLHttpRequest&&(n.responseType=r),s._options.imageTimeout){var A=s._options.imageTimeout;n.timeout=A,n.ontimeout=function(){return t(\"Timed out (\"+A+\"ms) proxying \"+i)}}n.send()})},_e);function _e(A,e){this.id=A,this._options=e,this._cache={}}function Pe(A){var n=rt.CIRCLE,B=Bt.FARTHEST_CORNER,s=[],o=[];return WA(A).forEach(function(A,e){var t=!0;if(0===e?t=A.reduce(function(A,e){if(zA(e))switch(e.value){case\"center\":return o.push(oe),!1;case\"top\":case\"left\":return o.push(se),!1;case\"right\":case\"bottom\":return o.push(ie),!1}else if(qA(e)||YA(e))return o.push(e),!1;return A},t):1===e&&(t=A.reduce(function(A,e){if(zA(e))switch(e.value){case\"circle\":return n=rt.CIRCLE,!1;case et:return n=rt.ELLIPSE,!1;case tt:case Ze:return B=Bt.CLOSEST_SIDE,!1;case je:return B=Bt.FARTHEST_SIDE,!1;case $e:return B=Bt.CLOSEST_CORNER,!1;case\"cover\":case At:return B=Bt.FARTHEST_CORNER,!1}else if(YA(e)||qA(e))return Array.isArray(B)||(B=[]),B.push(e),!1;return A},t)),t){var r=de(A);s.push(r)}}),{size:B,shape:n,stops:s,position:o,type:xe.RADIAL_GRADIENT}}var xe,Ve,ze=/^data:image\\/svg\\+xml/i,Xe=/^data:image\\/.*;base64,/i,Je=/^data:image\\/.*/i,Ge=function(A){return Oe.SUPPORT_SVG_DRAWING||!qe(A)},ke=function(A){return Je.test(A)},We=function(A){return Xe.test(A)},Ye=function(A){return\"blob\"===A.substr(0,4)},qe=function(A){return\"svg\"===A.substr(-3).toLowerCase()||ze.test(A)},Ze=\"closest-side\",je=\"farthest-side\",$e=\"closest-corner\",At=\"farthest-corner\",et=\"ellipse\",tt=\"contain\";(Ve=xe||(xe={}))[Ve.URL=0]=\"URL\",Ve[Ve.LINEAR_GRADIENT=1]=\"LINEAR_GRADIENT\",Ve[Ve.RADIAL_GRADIENT=2]=\"RADIAL_GRADIENT\";var rt,nt,Bt,st;(nt=rt||(rt={}))[nt.CIRCLE=0]=\"CIRCLE\",nt[nt.ELLIPSE=1]=\"ELLIPSE\",(st=Bt||(Bt={}))[st.CLOSEST_SIDE=0]=\"CLOSEST_SIDE\",st[st.FARTHEST_SIDE=1]=\"FARTHEST_SIDE\",st[st.CLOSEST_CORNER=2]=\"CLOSEST_CORNER\",st[st.FARTHEST_CORNER=3]=\"FARTHEST_CORNER\";var ot=function(A){if(A.type===sA.URL_TOKEN){var e={url:A.value,type:xe.URL};return Se.getInstance().addImage(A.value),e}if(A.type!==sA.FUNCTION)throw new Error(\"Unsupported image type\");var t=ct[A.name];if(void 0===t)throw new Error('Attempting to parse an unsupported image function \"'+A.name+'\"');return t(A.values)};var it,at,ct={\"linear-gradient\":function(A){var n=Qe(180),B=[];return WA(A).forEach(function(A,e){if(0===e){var t=A[0];if(t.type===sA.IDENT_TOKEN&&\"to\"===t.value)return void(n=Ae(A));if($A(t))return void(n=ce(t))}var r=de(A);B.push(r)}),{angle:n,stops:B,type:xe.LINEAR_GRADIENT}},\"-moz-linear-gradient\":Ie,\"-ms-linear-gradient\":Ie,\"-o-linear-gradient\":Ie,\"-webkit-linear-gradient\":Ie,\"radial-gradient\":function(A){var B=rt.CIRCLE,s=Bt.FARTHEST_CORNER,o=[],i=[];return WA(A).forEach(function(A,e){var t=!0;if(0===e){var r=!1;t=A.reduce(function(A,e){if(r)if(zA(e))switch(e.value){case\"center\":return i.push(oe),A;case\"top\":case\"left\":return i.push(se),A;case\"right\":case\"bottom\":return i.push(ie),A}else(qA(e)||YA(e))&&i.push(e);else if(zA(e))switch(e.value){case\"circle\":return B=rt.CIRCLE,!1;case et:return B=rt.ELLIPSE,!1;case\"at\":return!(r=!0);case Ze:return s=Bt.CLOSEST_SIDE,!1;case\"cover\":case je:return s=Bt.FARTHEST_SIDE,!1;case tt:case $e:return s=Bt.CLOSEST_CORNER,!1;case At:return s=Bt.FARTHEST_CORNER,!1}else if(YA(e)||qA(e))return Array.isArray(s)||(s=[]),s.push(e),!1;return A},t)}if(t){var n=de(A);o.push(n)}}),{size:s,shape:B,stops:o,position:i,type:xe.RADIAL_GRADIENT}},\"-moz-radial-gradient\":Pe,\"-ms-radial-gradient\":Pe,\"-o-radial-gradient\":Pe,\"-webkit-radial-gradient\":Pe,\"-webkit-gradient\":function(A){var e=Qe(180),s=[],o=xe.LINEAR_GRADIENT,t=rt.CIRCLE,r=Bt.FARTHEST_CORNER;return WA(A).forEach(function(A,e){var t=A[0];if(0===e){if(zA(t)&&\"linear\"===t.value)return void(o=xe.LINEAR_GRADIENT);if(zA(t)&&\"radial\"===t.value)return void(o=xe.RADIAL_GRADIENT)}if(t.type===sA.FUNCTION)if(\"from\"===t.name){var r=we(t.values[0]);s.push({stop:se,color:r})}else if(\"to\"===t.name)r=we(t.values[0]),s.push({stop:ie,color:r});else if(\"color-stop\"===t.name){var n=t.values.filter(kA);if(2===n.length){r=we(n[1]);var B=n[0];VA(B)&&s.push({stop:{type:sA.PERCENTAGE_TOKEN,number:100*B.number,flags:B.flags},color:r})}}}),o===xe.LINEAR_GRADIENT?{angle:(e+Qe(180))%Qe(360),stops:s,type:o}:{size:r,shape:t,stops:s,position:[],type:o}}},Qt={name:\"background-image\",initialValue:\"none\",type:Ce.LIST,prefix:!1,parse:function(A){if(0===A.length)return[];var e=A[0];return e.type===sA.IDENT_TOKEN&&\"none\"===e.value?[]:A.filter(function(A){return kA(A)&&function(A){return A.type!==sA.FUNCTION||ct[A.name]}(A)}).map(ot)}},wt={name:\"background-origin\",initialValue:\"border-box\",prefix:!1,type:Ce.LIST,parse:function(A){return A.map(function(A){if(zA(A))switch(A.value){case\"padding-box\":return 1;case\"content-box\":return 2}return 0})}},ut={name:\"background-position\",initialValue:\"0% 0%\",type:Ce.LIST,prefix:!1,parse:function(A){return WA(A).map(function(A){return A.filter(qA)}).map(ZA)}};(at=it||(it={}))[at.REPEAT=0]=\"REPEAT\",at[at.NO_REPEAT=1]=\"NO_REPEAT\",at[at.REPEAT_X=2]=\"REPEAT_X\";var Ut,lt,Ct={name:\"background-repeat\",initialValue:\"repeat\",prefix:!(at[at.REPEAT_Y=3]=\"REPEAT_Y\"),type:Ce.LIST,parse:function(A){return WA(A).map(function(A){return A.filter(zA).map(function(A){return A.value}).join(\" \")}).map(gt)}},gt=function(A){switch(A){case\"no-repeat\":return it.NO_REPEAT;case\"repeat-x\":case\"repeat no-repeat\":return it.REPEAT_X;case\"repeat-y\":case\"no-repeat repeat\":return it.REPEAT_Y;case\"repeat\":default:return it.REPEAT}};(lt=Ut||(Ut={})).AUTO=\"auto\",lt.CONTAIN=\"contain\";function Et(A){return{name:\"border-\"+A+\"-color\",initialValue:\"transparent\",prefix:!1,type:Ce.TYPE_VALUE,format:\"color\"}}function Ft(A){return{name:\"border-radius-\"+A,initialValue:\"0 0\",prefix:!1,type:Ce.LIST,parse:function(A){return ZA(A.filter(qA))}}}var ht,Ht,dt={name:\"background-size\",initialValue:\"0\",prefix:!(lt.COVER=\"cover\"),type:Ce.LIST,parse:function(A){return WA(A).map(function(A){return A.filter(ft)})}},ft=function(A){return zA(A)||qA(A)},pt=Et(\"top\"),Nt=Et(\"right\"),Kt=Et(\"bottom\"),It=Et(\"left\"),Tt=Ft(\"top-left\"),mt=Ft(\"top-right\"),Rt=Ft(\"bottom-right\"),Lt=Ft(\"bottom-left\");(Ht=ht||(ht={}))[Ht.NONE=0]=\"NONE\",Ht[Ht.SOLID=1]=\"SOLID\";function vt(A){return{name:\"border-\"+A+\"-style\",initialValue:\"solid\",prefix:!1,type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"none\":return ht.NONE}return ht.SOLID}}}function Ot(A){return{name:\"border-\"+A+\"-width\",initialValue:\"0\",type:Ce.VALUE,prefix:!1,parse:function(A){return xA(A)?A.number:0}}}var Dt,bt,St=vt(\"top\"),Mt=vt(\"right\"),yt=vt(\"bottom\"),_t=vt(\"left\"),Pt=Ot(\"top\"),xt=Ot(\"right\"),Vt=Ot(\"bottom\"),zt=Ot(\"left\"),Xt={name:\"color\",initialValue:\"transparent\",prefix:!1,type:Ce.TYPE_VALUE,format:\"color\"},Jt={name:\"display\",initialValue:\"inline-block\",prefix:!1,type:Ce.LIST,parse:function(A){return A.filter(zA).reduce(function(A,e){return A|Gt(e.value)},0)}},Gt=function(A){switch(A){case\"block\":return 2;case\"inline\":return 4;case\"run-in\":return 8;case\"flow\":return 16;case\"flow-root\":return 32;case\"table\":return 64;case\"flex\":case\"-webkit-flex\":return 128;case\"grid\":case\"-ms-grid\":return 256;case\"ruby\":return 512;case\"subgrid\":return 1024;case\"list-item\":return 2048;case\"table-row-group\":return 4096;case\"table-header-group\":return 8192;case\"table-footer-group\":return 16384;case\"table-row\":return 32768;case\"table-cell\":return 65536;case\"table-column-group\":return 131072;case\"table-column\":return 262144;case\"table-caption\":return 524288;case\"ruby-base\":return 1048576;case\"ruby-text\":return 2097152;case\"ruby-base-container\":return 4194304;case\"ruby-text-container\":return 8388608;case\"contents\":return 16777216;case\"inline-block\":return 33554432;case\"inline-list-item\":return 67108864;case\"inline-table\":return 134217728;case\"inline-flex\":return 268435456;case\"inline-grid\":return 536870912}return 0};(bt=Dt||(Dt={}))[bt.NONE=0]=\"NONE\",bt[bt.LEFT=1]=\"LEFT\",bt[bt.RIGHT=2]=\"RIGHT\",bt[bt.INLINE_START=3]=\"INLINE_START\";var kt,Wt,Yt,qt,Zt={name:\"float\",initialValue:\"none\",prefix:!(bt[bt.INLINE_END=4]=\"INLINE_END\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"left\":return Dt.LEFT;case\"right\":return Dt.RIGHT;case\"inline-start\":return Dt.INLINE_START;case\"inline-end\":return Dt.INLINE_END}return Dt.NONE}},jt={name:\"letter-spacing\",initialValue:\"0\",prefix:!1,type:Ce.VALUE,parse:function(A){return A.type===sA.IDENT_TOKEN&&\"normal\"===A.value?0:A.type===sA.NUMBER_TOKEN?A.number:A.type===sA.DIMENSION_TOKEN?A.number:0}},$t={name:\"line-break\",initialValue:(Wt=kt||(kt={})).NORMAL=\"normal\",prefix:!(Wt.STRICT=\"strict\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"strict\":return kt.STRICT;case\"normal\":default:return kt.NORMAL}}},Ar={name:\"line-height\",initialValue:\"normal\",prefix:!1,type:Ce.TOKEN_VALUE},er={name:\"list-style-image\",initialValue:\"none\",type:Ce.VALUE,prefix:!1,parse:function(A){return A.type===sA.IDENT_TOKEN&&\"none\"===A.value?null:ot(A)}};(qt=Yt||(Yt={}))[qt.INSIDE=0]=\"INSIDE\";var tr,rr,nr={name:\"list-style-position\",initialValue:\"outside\",prefix:!(qt[qt.OUTSIDE=1]=\"OUTSIDE\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"inside\":return Yt.INSIDE;case\"outside\":default:return Yt.OUTSIDE}}};(rr=tr||(tr={}))[rr.NONE=-1]=\"NONE\",rr[rr.DISC=0]=\"DISC\",rr[rr.CIRCLE=1]=\"CIRCLE\",rr[rr.SQUARE=2]=\"SQUARE\",rr[rr.DECIMAL=3]=\"DECIMAL\",rr[rr.CJK_DECIMAL=4]=\"CJK_DECIMAL\",rr[rr.DECIMAL_LEADING_ZERO=5]=\"DECIMAL_LEADING_ZERO\",rr[rr.LOWER_ROMAN=6]=\"LOWER_ROMAN\",rr[rr.UPPER_ROMAN=7]=\"UPPER_ROMAN\",rr[rr.LOWER_GREEK=8]=\"LOWER_GREEK\",rr[rr.LOWER_ALPHA=9]=\"LOWER_ALPHA\",rr[rr.UPPER_ALPHA=10]=\"UPPER_ALPHA\",rr[rr.ARABIC_INDIC=11]=\"ARABIC_INDIC\",rr[rr.ARMENIAN=12]=\"ARMENIAN\",rr[rr.BENGALI=13]=\"BENGALI\",rr[rr.CAMBODIAN=14]=\"CAMBODIAN\",rr[rr.CJK_EARTHLY_BRANCH=15]=\"CJK_EARTHLY_BRANCH\",rr[rr.CJK_HEAVENLY_STEM=16]=\"CJK_HEAVENLY_STEM\",rr[rr.CJK_IDEOGRAPHIC=17]=\"CJK_IDEOGRAPHIC\",rr[rr.DEVANAGARI=18]=\"DEVANAGARI\",rr[rr.ETHIOPIC_NUMERIC=19]=\"ETHIOPIC_NUMERIC\",rr[rr.GEORGIAN=20]=\"GEORGIAN\",rr[rr.GUJARATI=21]=\"GUJARATI\",rr[rr.GURMUKHI=22]=\"GURMUKHI\",rr[rr.HEBREW=22]=\"HEBREW\",rr[rr.HIRAGANA=23]=\"HIRAGANA\",rr[rr.HIRAGANA_IROHA=24]=\"HIRAGANA_IROHA\",rr[rr.JAPANESE_FORMAL=25]=\"JAPANESE_FORMAL\",rr[rr.JAPANESE_INFORMAL=26]=\"JAPANESE_INFORMAL\",rr[rr.KANNADA=27]=\"KANNADA\",rr[rr.KATAKANA=28]=\"KATAKANA\",rr[rr.KATAKANA_IROHA=29]=\"KATAKANA_IROHA\",rr[rr.KHMER=30]=\"KHMER\",rr[rr.KOREAN_HANGUL_FORMAL=31]=\"KOREAN_HANGUL_FORMAL\",rr[rr.KOREAN_HANJA_FORMAL=32]=\"KOREAN_HANJA_FORMAL\",rr[rr.KOREAN_HANJA_INFORMAL=33]=\"KOREAN_HANJA_INFORMAL\",rr[rr.LAO=34]=\"LAO\",rr[rr.LOWER_ARMENIAN=35]=\"LOWER_ARMENIAN\",rr[rr.MALAYALAM=36]=\"MALAYALAM\",rr[rr.MONGOLIAN=37]=\"MONGOLIAN\",rr[rr.MYANMAR=38]=\"MYANMAR\",rr[rr.ORIYA=39]=\"ORIYA\",rr[rr.PERSIAN=40]=\"PERSIAN\",rr[rr.SIMP_CHINESE_FORMAL=41]=\"SIMP_CHINESE_FORMAL\",rr[rr.SIMP_CHINESE_INFORMAL=42]=\"SIMP_CHINESE_INFORMAL\",rr[rr.TAMIL=43]=\"TAMIL\",rr[rr.TELUGU=44]=\"TELUGU\",rr[rr.THAI=45]=\"THAI\",rr[rr.TIBETAN=46]=\"TIBETAN\",rr[rr.TRAD_CHINESE_FORMAL=47]=\"TRAD_CHINESE_FORMAL\",rr[rr.TRAD_CHINESE_INFORMAL=48]=\"TRAD_CHINESE_INFORMAL\",rr[rr.UPPER_ARMENIAN=49]=\"UPPER_ARMENIAN\",rr[rr.DISCLOSURE_OPEN=50]=\"DISCLOSURE_OPEN\";function Br(A){return{name:\"margin-\"+A,initialValue:\"0\",prefix:!1,type:Ce.TOKEN_VALUE}}var sr,or,ir={name:\"list-style-type\",initialValue:\"none\",prefix:!(rr[rr.DISCLOSURE_CLOSED=51]=\"DISCLOSURE_CLOSED\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"disc\":return tr.DISC;case\"circle\":return tr.CIRCLE;case\"square\":return tr.SQUARE;case\"decimal\":return tr.DECIMAL;case\"cjk-decimal\":return tr.CJK_DECIMAL;case\"decimal-leading-zero\":return tr.DECIMAL_LEADING_ZERO;case\"lower-roman\":return tr.LOWER_ROMAN;case\"upper-roman\":return tr.UPPER_ROMAN;case\"lower-greek\":return tr.LOWER_GREEK;case\"lower-alpha\":return tr.LOWER_ALPHA;case\"upper-alpha\":return tr.UPPER_ALPHA;case\"arabic-indic\":return tr.ARABIC_INDIC;case\"armenian\":return tr.ARMENIAN;case\"bengali\":return tr.BENGALI;case\"cambodian\":return tr.CAMBODIAN;case\"cjk-earthly-branch\":return tr.CJK_EARTHLY_BRANCH;case\"cjk-heavenly-stem\":return tr.CJK_HEAVENLY_STEM;case\"cjk-ideographic\":return tr.CJK_IDEOGRAPHIC;case\"devanagari\":return tr.DEVANAGARI;case\"ethiopic-numeric\":return tr.ETHIOPIC_NUMERIC;case\"georgian\":return tr.GEORGIAN;case\"gujarati\":return tr.GUJARATI;case\"gurmukhi\":return tr.GURMUKHI;case\"hebrew\":return tr.HEBREW;case\"hiragana\":return tr.HIRAGANA;case\"hiragana-iroha\":return tr.HIRAGANA_IROHA;case\"japanese-formal\":return tr.JAPANESE_FORMAL;case\"japanese-informal\":return tr.JAPANESE_INFORMAL;case\"kannada\":return tr.KANNADA;case\"katakana\":return tr.KATAKANA;case\"katakana-iroha\":return tr.KATAKANA_IROHA;case\"khmer\":return tr.KHMER;case\"korean-hangul-formal\":return tr.KOREAN_HANGUL_FORMAL;case\"korean-hanja-formal\":return tr.KOREAN_HANJA_FORMAL;case\"korean-hanja-informal\":return tr.KOREAN_HANJA_INFORMAL;case\"lao\":return tr.LAO;case\"lower-armenian\":return tr.LOWER_ARMENIAN;case\"malayalam\":return tr.MALAYALAM;case\"mongolian\":return tr.MONGOLIAN;case\"myanmar\":return tr.MYANMAR;case\"oriya\":return tr.ORIYA;case\"persian\":return tr.PERSIAN;case\"simp-chinese-formal\":return tr.SIMP_CHINESE_FORMAL;case\"simp-chinese-informal\":return tr.SIMP_CHINESE_INFORMAL;case\"tamil\":return tr.TAMIL;case\"telugu\":return tr.TELUGU;case\"thai\":return tr.THAI;case\"tibetan\":return tr.TIBETAN;case\"trad-chinese-formal\":return tr.TRAD_CHINESE_FORMAL;case\"trad-chinese-informal\":return tr.TRAD_CHINESE_INFORMAL;case\"upper-armenian\":return tr.UPPER_ARMENIAN;case\"disclosure-open\":return tr.DISCLOSURE_OPEN;case\"disclosure-closed\":return tr.DISCLOSURE_CLOSED;case\"none\":default:return tr.NONE}}},ar=Br(\"top\"),cr=Br(\"right\"),Qr=Br(\"bottom\"),wr=Br(\"left\");(or=sr||(sr={}))[or.VISIBLE=0]=\"VISIBLE\",or[or.HIDDEN=1]=\"HIDDEN\",or[or.SCROLL=2]=\"SCROLL\";function ur(A){return{name:\"padding-\"+A,initialValue:\"0\",prefix:!1,type:Ce.TYPE_VALUE,format:\"length-percentage\"}}var Ur,lr,Cr,gr,Er={name:\"overflow\",initialValue:\"visible\",prefix:!(or[or.AUTO=3]=\"AUTO\"),type:Ce.LIST,parse:function(A){return A.filter(zA).map(function(A){switch(A.value){case\"hidden\":return sr.HIDDEN;case\"scroll\":return sr.SCROLL;case\"auto\":return sr.AUTO;case\"visible\":default:return sr.VISIBLE}})}},Fr={name:\"overflow-wrap\",initialValue:(lr=Ur||(Ur={})).NORMAL=\"normal\",prefix:!(lr.BREAK_WORD=\"break-word\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"break-word\":return Ur.BREAK_WORD;case\"normal\":default:return Ur.NORMAL}}},hr=ur(\"top\"),Hr=ur(\"right\"),dr=ur(\"bottom\"),fr=ur(\"left\");(gr=Cr||(Cr={}))[gr.LEFT=0]=\"LEFT\",gr[gr.CENTER=1]=\"CENTER\";var pr,Nr,Kr={name:\"text-align\",initialValue:\"left\",prefix:!(gr[gr.RIGHT=2]=\"RIGHT\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"right\":return Cr.RIGHT;case\"center\":case\"justify\":return Cr.CENTER;case\"left\":default:return Cr.LEFT}}};(Nr=pr||(pr={}))[Nr.STATIC=0]=\"STATIC\",Nr[Nr.RELATIVE=1]=\"RELATIVE\",Nr[Nr.ABSOLUTE=2]=\"ABSOLUTE\",Nr[Nr.FIXED=3]=\"FIXED\";var Ir,Tr,mr={name:\"position\",initialValue:\"static\",prefix:!(Nr[Nr.STICKY=4]=\"STICKY\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"relative\":return pr.RELATIVE;case\"absolute\":return pr.ABSOLUTE;case\"fixed\":return pr.FIXED;case\"sticky\":return pr.STICKY}return pr.STATIC}},Rr={name:\"text-shadow\",initialValue:\"none\",type:Ce.LIST,prefix:!1,parse:function(A){return 1===A.length&&JA(A[0],\"none\")?[]:WA(A).map(function(A){for(var e={color:He.TRANSPARENT,offsetX:se,offsetY:se,blur:se},t=0,r=0;r<A.length;r++){var n=A[r];YA(n)?(0===t?e.offsetX=n:1===t?e.offsetY=n:e.blur=n,t++):e.color=we(n)}return e})}};(Tr=Ir||(Ir={}))[Tr.NONE=0]=\"NONE\",Tr[Tr.LOWERCASE=1]=\"LOWERCASE\",Tr[Tr.UPPERCASE=2]=\"UPPERCASE\";var Lr,vr,Or={name:\"text-transform\",initialValue:\"none\",prefix:!(Tr[Tr.CAPITALIZE=3]=\"CAPITALIZE\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"uppercase\":return Ir.UPPERCASE;case\"lowercase\":return Ir.LOWERCASE;case\"capitalize\":return Ir.CAPITALIZE}return Ir.NONE}},Dr={name:\"transform\",initialValue:\"none\",prefix:!0,type:Ce.VALUE,parse:function(A){if(A.type===sA.IDENT_TOKEN&&\"none\"===A.value)return null;if(A.type!==sA.FUNCTION)return null;var e=br[A.name];if(void 0===e)throw new Error('Attempting to parse an unsupported transform function \"'+A.name+'\"');return e(A.values)}},br={matrix:function(A){var e=A.filter(function(A){return A.type===sA.NUMBER_TOKEN}).map(function(A){return A.number});return 6===e.length?e:null},matrix3d:function(A){var e=A.filter(function(A){return A.type===sA.NUMBER_TOKEN}).map(function(A){return A.number}),t=e[0],r=e[1],n=(e[2],e[3],e[4]),B=e[5],s=(e[6],e[7],e[8],e[9],e[10],e[11],e[12]),o=e[13];e[14],e[15];return 16===e.length?[t,r,n,B,s,o]:null}},Sr={type:sA.PERCENTAGE_TOKEN,number:50,flags:4},Mr=[Sr,Sr],yr={name:\"transform-origin\",initialValue:\"50% 50%\",prefix:!0,type:Ce.LIST,parse:function(A){var e=A.filter(qA);return 2!==e.length?Mr:[e[0],e[1]]}};(vr=Lr||(Lr={}))[vr.VISIBLE=0]=\"VISIBLE\",vr[vr.HIDDEN=1]=\"HIDDEN\";var _r,Pr,xr={name:\"visible\",initialValue:\"none\",prefix:!(vr[vr.COLLAPSE=2]=\"COLLAPSE\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"hidden\":return Lr.HIDDEN;case\"collapse\":return Lr.COLLAPSE;case\"visible\":default:return Lr.VISIBLE}}};(Pr=_r||(_r={})).NORMAL=\"normal\",Pr.BREAK_ALL=\"break-all\";var Vr,zr,Xr={name:\"word-break\",initialValue:\"normal\",prefix:!(Pr.KEEP_ALL=\"keep-all\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"break-all\":return _r.BREAK_ALL;case\"keep-all\":return _r.KEEP_ALL;case\"normal\":default:return _r.NORMAL}}},Jr={name:\"z-index\",initialValue:\"auto\",prefix:!1,type:Ce.VALUE,parse:function(A){if(A.type===sA.IDENT_TOKEN)return{auto:!0,order:0};if(VA(A))return{auto:!1,order:A.number};throw new Error(\"Invalid z-index number parsed\")}},Gr={name:\"opacity\",initialValue:\"1\",type:Ce.VALUE,prefix:!1,parse:function(A){return VA(A)?A.number:1}},kr={name:\"text-decoration-color\",initialValue:\"transparent\",prefix:!1,type:Ce.TYPE_VALUE,format:\"color\"},Wr={name:\"text-decoration-line\",initialValue:\"none\",prefix:!1,type:Ce.LIST,parse:function(A){return A.filter(zA).map(function(A){switch(A.value){case\"underline\":return 1;case\"overline\":return 2;case\"line-through\":return 3;case\"none\":return 4}return 0}).filter(function(A){return 0!==A})}},Yr={name:\"font-family\",initialValue:\"\",prefix:!1,type:Ce.LIST,parse:function(A){return A.filter(qr).map(function(A){return A.value})}},qr=function(A){return A.type===sA.STRING_TOKEN||A.type===sA.IDENT_TOKEN},Zr={name:\"font-size\",initialValue:\"0\",prefix:!1,type:Ce.TYPE_VALUE,format:\"length\"},jr={name:\"font-weight\",initialValue:\"normal\",type:Ce.VALUE,prefix:!1,parse:function(A){if(VA(A))return A.number;if(zA(A))switch(A.value){case\"bold\":return 700;case\"normal\":default:return 400}return 400}},$r={name:\"font-variant\",initialValue:\"none\",type:Ce.LIST,prefix:!1,parse:function(A){return A.filter(zA).map(function(A){return A.value})}};(zr=Vr||(Vr={})).NORMAL=\"normal\",zr.ITALIC=\"italic\";function An(A,e){return 0!=(A&e)}function en(A,e,t){if(!A)return\"\";var r=A[Math.min(e,A.length-1)];return r?t?r.open:r.close:\"\"}var tn={name:\"font-style\",initialValue:\"normal\",prefix:!(zr.OBLIQUE=\"oblique\"),type:Ce.IDENT_VALUE,parse:function(A){switch(A){case\"oblique\":return Vr.OBLIQUE;case\"italic\":return Vr.ITALIC;case\"normal\":default:return Vr.NORMAL}}},rn={name:\"content\",initialValue:\"none\",type:Ce.LIST,prefix:!1,parse:function(A){if(0===A.length)return[];var e=A[0];return e.type===sA.IDENT_TOKEN&&\"none\"===e.value?[]:A}},nn={name:\"counter-increment\",initialValue:\"none\",prefix:!0,type:Ce.LIST,parse:function(A){if(0===A.length)return null;var e=A[0];if(e.type===sA.IDENT_TOKEN&&\"none\"===e.value)return null;for(var t=[],r=A.filter(GA),n=0;n<r.length;n++){var B=r[n],s=r[n+1];if(B.type===sA.IDENT_TOKEN){var o=s&&VA(s)?s.number:1;t.push({counter:B.value,increment:o})}}return t}},Bn={name:\"counter-reset\",initialValue:\"none\",prefix:!0,type:Ce.LIST,parse:function(A){if(0===A.length)return[];for(var e=[],t=A.filter(GA),r=0;r<t.length;r++){var n=t[r],B=t[r+1];if(zA(n)&&\"none\"!==n.value){var s=B&&VA(B)?B.number:0;e.push({counter:n.value,reset:s})}}return e}},sn={name:\"quotes\",initialValue:\"none\",prefix:!0,type:Ce.LIST,parse:function(A){if(0===A.length)return null;var e=A[0];if(e.type===sA.IDENT_TOKEN&&\"none\"===e.value)return null;var t=[],r=A.filter(XA);if(r.length%2!=0)return null;for(var n=0;n<r.length;n+=2){var B=r[n].value,s=r[n+1].value;t.push({open:B,close:s})}return t}},on={name:\"box-shadow\",initialValue:\"none\",type:Ce.LIST,prefix:!1,parse:function(A){return 1===A.length&&JA(A[0],\"none\")?[]:WA(A).map(function(A){for(var e={color:255,offsetX:se,offsetY:se,blur:se,spread:se,inset:!1},t=0,r=0;r<A.length;r++){var n=A[r];JA(n,\"inset\")?e.inset=!0:YA(n)?(0===t?e.offsetX=n:1===t?e.offsetY=n:2===t?e.blur=n:e.spread=n,t++):e.color=we(n)}return e})}},an=(cn.prototype.isVisible=function(){return 0<this.display&&0<this.opacity&&this.visibility===Lr.VISIBLE},cn.prototype.isTransparent=function(){return ee(this.backgroundColor)},cn.prototype.isTransformed=function(){return null!==this.transform},cn.prototype.isPositioned=function(){return this.position!==pr.STATIC},cn.prototype.isPositionedWithZIndex=function(){return this.isPositioned()&&!this.zIndex.auto},cn.prototype.isFloating=function(){return this.float!==Dt.NONE},cn.prototype.isInlineLevel=function(){return An(this.display,4)||An(this.display,33554432)||An(this.display,268435456)||An(this.display,536870912)||An(this.display,67108864)||An(this.display,134217728)},cn);function cn(A){this.backgroundClip=Un(me,A.backgroundClip),this.backgroundColor=Un(Re,A.backgroundColor),this.backgroundImage=Un(Qt,A.backgroundImage),this.backgroundOrigin=Un(wt,A.backgroundOrigin),this.backgroundPosition=Un(ut,A.backgroundPosition),this.backgroundRepeat=Un(Ct,A.backgroundRepeat),this.backgroundSize=Un(dt,A.backgroundSize),this.borderTopColor=Un(pt,A.borderTopColor),this.borderRightColor=Un(Nt,A.borderRightColor),this.borderBottomColor=Un(Kt,A.borderBottomColor),this.borderLeftColor=Un(It,A.borderLeftColor),this.borderTopLeftRadius=Un(Tt,A.borderTopLeftRadius),this.borderTopRightRadius=Un(mt,A.borderTopRightRadius),this.borderBottomRightRadius=Un(Rt,A.borderBottomRightRadius),this.borderBottomLeftRadius=Un(Lt,A.borderBottomLeftRadius),this.borderTopStyle=Un(St,A.borderTopStyle),this.borderRightStyle=Un(Mt,A.borderRightStyle),this.borderBottomStyle=Un(yt,A.borderBottomStyle),this.borderLeftStyle=Un(_t,A.borderLeftStyle),this.borderTopWidth=Un(Pt,A.borderTopWidth),this.borderRightWidth=Un(xt,A.borderRightWidth),this.borderBottomWidth=Un(Vt,A.borderBottomWidth),this.borderLeftWidth=Un(zt,A.borderLeftWidth),this.boxShadow=Un(on,A.boxShadow),this.color=Un(Xt,A.color),this.display=Un(Jt,A.display),this.float=Un(Zt,A.cssFloat),this.fontFamily=Un(Yr,A.fontFamily),this.fontSize=Un(Zr,A.fontSize),this.fontStyle=Un(tn,A.fontStyle),this.fontVariant=Un($r,A.fontVariant),this.fontWeight=Un(jr,A.fontWeight),this.letterSpacing=Un(jt,A.letterSpacing),this.lineBreak=Un($t,A.lineBreak),this.lineHeight=Un(Ar,A.lineHeight),this.listStyleImage=Un(er,A.listStyleImage),this.listStylePosition=Un(nr,A.listStylePosition),this.listStyleType=Un(ir,A.listStyleType),this.marginTop=Un(ar,A.marginTop),this.marginRight=Un(cr,A.marginRight),this.marginBottom=Un(Qr,A.marginBottom),this.marginLeft=Un(wr,A.marginLeft),this.opacity=Un(Gr,A.opacity);var e=Un(Er,A.overflow);this.overflowX=e[0],this.overflowY=e[1<e.length?1:0],this.overflowWrap=Un(Fr,A.overflowWrap),this.paddingTop=Un(hr,A.paddingTop),this.paddingRight=Un(Hr,A.paddingRight),this.paddingBottom=Un(dr,A.paddingBottom),this.paddingLeft=Un(fr,A.paddingLeft),this.position=Un(mr,A.position),this.textAlign=Un(Kr,A.textAlign),this.textDecorationColor=Un(kr,A.textDecorationColor||A.color),this.textDecorationLine=Un(Wr,A.textDecorationLine),this.textShadow=Un(Rr,A.textShadow),this.textTransform=Un(Or,A.textTransform),this.transform=Un(Dr,A.transform),this.transformOrigin=Un(yr,A.transformOrigin),this.visibility=Un(xr,A.visibility),this.wordBreak=Un(Xr,A.wordBreak),this.zIndex=Un(Jr,A.zIndex)}var Qn,wn=function(A){this.content=Un(rn,A.content),this.quotes=Un(sn,A.quotes)},un=function(A){this.counterIncrement=Un(nn,A.counterIncrement),this.counterReset=Un(Bn,A.counterReset)},Un=function(A,e){var t=new MA,r=null!=e?e.toString():A.initialValue;t.write(r);var n=new _A(t.read());switch(A.type){case Ce.IDENT_VALUE:var B=n.parseComponentValue();return A.parse(zA(B)?B.value:A.initialValue);case Ce.VALUE:return A.parse(n.parseComponentValue());case Ce.LIST:return A.parse(n.parseComponentValues());case Ce.TOKEN_VALUE:return n.parseComponentValue();case Ce.TYPE_VALUE:switch(A.format){case\"angle\":return ce(n.parseComponentValue());case\"color\":return we(n.parseComponentValue());case\"image\":return ot(n.parseComponentValue());case\"length\":var s=n.parseComponentValue();return YA(s)?s:se;case\"length-percentage\":var o=n.parseComponentValue();return qA(o)?o:se}}throw new Error(\"Attempting to parse unsupported css format type \"+A.format)},ln=function(A){this.styles=new an(window.getComputedStyle(A,null)),this.textNodes=[],this.elements=[],null!==this.styles.transform&&uB(A)&&(A.style.transform=\"none\"),this.bounds=T(A),this.flags=0},Cn=function(A,e){this.text=A,this.bounds=e},gn=function(A){var e=A.ownerDocument;if(e){var t=e.createElement(\"html2canvaswrapper\");t.appendChild(A.cloneNode(!0));var r=A.parentNode;if(r){r.replaceChild(t,A);var n=T(t);return t.firstChild&&r.replaceChild(t.firstChild,t),n}}return new I(0,0,0,0)},En=function(A,e,t){var r=A.ownerDocument;if(!r)throw new Error(\"Node has no owner document\");var n=r.createRange();return n.setStart(A,e),n.setEnd(A,e+t),I.fromClientRect(n.getBoundingClientRect())},Fn=function(A,e){return 0!==e.letterSpacing?c(A).map(function(A){return l(A)}):hn(A,e)},hn=function(A,e){for(var t,r=function(A,e){var t=c(A),r=u(t,e),n=r[0],B=r[1],s=r[2],o=t.length,i=0,a=0;return{next:function(){if(o<=a)return{done:!0,value:null};for(var A=Y;a<o&&(A=w(t,B,n,++a,s))===Y;);if(A===Y&&a!==o)return{done:!0,value:null};var e=new nA(t,A,i,a);return i=a,{value:e,done:!1}}}}(A,{lineBreak:e.lineBreak,wordBreak:e.overflowWrap===Ur.BREAK_WORD?\"break-word\":e.wordBreak}),n=[];!(t=r.next()).done;)t.value&&n.push(t.value.slice());return n},Hn=function(A,e){this.text=dn(A.data,e.textTransform),this.textBounds=function(A,t,r){var e=Fn(A,t),n=[],B=0;return e.forEach(function(A){if(t.textDecorationLine.length||0<A.trim().length)if(Oe.SUPPORT_RANGE_BOUNDS)n.push(new Cn(A,En(r,B,A.length)));else{var e=r.splitText(A.length);n.push(new Cn(A,gn(r))),r=e}else Oe.SUPPORT_RANGE_BOUNDS||(r=r.splitText(A.length));B+=A.length}),n}(this.text,e,A)},dn=function(A,e){switch(e){case Ir.LOWERCASE:return A.toLowerCase();case Ir.CAPITALIZE:return A.replace(fn,pn);case Ir.UPPERCASE:return A.toUpperCase();default:return A}},fn=/(^|\\s|:|-|\\(|\\))([a-z])/g,pn=function(A,e,t){return 0<A.length?e+t.toUpperCase():A},Nn=(A(Kn,Qn=ln),Kn);function Kn(A){var e=Qn.call(this,A)||this;return e.src=A.currentSrc||A.src,e.intrinsicWidth=A.naturalWidth,e.intrinsicHeight=A.naturalHeight,Se.getInstance().addImage(e.src),e}var In,Tn=(A(mn,In=ln),mn);function mn(A){var e=In.call(this,A)||this;return e.canvas=A,e.intrinsicWidth=A.width,e.intrinsicHeight=A.height,e}var Rn,Ln=(A(vn,Rn=ln),vn);function vn(A){var e=Rn.call(this,A)||this,t=new XMLSerializer;return e.svg=\"data:image/svg+xml,\"+encodeURIComponent(t.serializeToString(A)),e.intrinsicWidth=A.width.baseVal.value,e.intrinsicHeight=A.height.baseVal.value,Se.getInstance().addImage(e.svg),e}var On,Dn=(A(bn,On=ln),bn);function bn(A){var e=On.call(this,A)||this;return e.value=A.value,e}var Sn,Mn=(A(yn,Sn=ln),yn);function yn(A){var e=Sn.call(this,A)||this;return e.start=A.start,e.reversed=\"boolean\"==typeof A.reversed&&!0===A.reversed,e}var _n,Pn=[{type:sA.DIMENSION_TOKEN,flags:0,unit:\"px\",number:3}],xn=[{type:sA.PERCENTAGE_TOKEN,flags:0,number:50}],Vn=\"checkbox\",zn=\"radio\",Xn=\"password\",Jn=707406591,Gn=(A(kn,_n=ln),kn);function kn(A){var e=_n.call(this,A)||this;switch(e.type=A.type.toLowerCase(),e.checked=A.checked,e.value=function(A){var e=A.type===Xn?new Array(A.value.length+1).join(\"•\"):A.value;return 0===e.length?A.placeholder||\"\":e}(A),e.type!==Vn&&e.type!==zn||(e.styles.backgroundColor=3739148031,e.styles.borderTopColor=e.styles.borderRightColor=e.styles.borderBottomColor=e.styles.borderLeftColor=2779096575,e.styles.borderTopWidth=e.styles.borderRightWidth=e.styles.borderBottomWidth=e.styles.borderLeftWidth=1,e.styles.borderTopStyle=e.styles.borderRightStyle=e.styles.borderBottomStyle=e.styles.borderLeftStyle=ht.SOLID,e.styles.backgroundClip=[Ee.BORDER_BOX],e.styles.backgroundOrigin=[0],e.bounds=function(A){return A.width>A.height?new I(A.left+(A.width-A.height)/2,A.top,A.height,A.height):A.width<A.height?new I(A.left,A.top+(A.height-A.width)/2,A.width,A.width):A}(e.bounds)),e.type){case Vn:e.styles.borderTopRightRadius=e.styles.borderTopLeftRadius=e.styles.borderBottomRightRadius=e.styles.borderBottomLeftRadius=Pn;break;case zn:e.styles.borderTopRightRadius=e.styles.borderTopLeftRadius=e.styles.borderBottomRightRadius=e.styles.borderBottomLeftRadius=xn}return e}var Wn,Yn=(A(qn,Wn=ln),qn);function qn(A){var e=Wn.call(this,A)||this,t=A.options[A.selectedIndex||0];return e.value=t&&t.text||\"\",e}var Zn,jn=(A($n,Zn=ln),$n);function $n(A){var e=Zn.call(this,A)||this;return e.value=A.value,e}function AB(A){return we(_A.create(A).parseComponentValue())}var eB,tB=(A(rB,eB=ln),rB);function rB(A){var e=eB.call(this,A)||this;e.src=A.src,e.width=parseInt(A.width,10)||0,e.height=parseInt(A.height,10)||0,e.backgroundColor=e.styles.backgroundColor;try{if(A.contentWindow&&A.contentWindow.document&&A.contentWindow.document.documentElement){e.tree=iB(A.contentWindow.document.documentElement);var t=A.contentWindow.document.documentElement?AB(getComputedStyle(A.contentWindow.document.documentElement).backgroundColor):He.TRANSPARENT,r=A.contentWindow.document.body?AB(getComputedStyle(A.contentWindow.document.body).backgroundColor):He.TRANSPARENT;e.backgroundColor=ee(t)?ee(r)?e.styles.backgroundColor:r:t}}catch(A){}return e}function nB(A){return\"STYLE\"===A.tagName}var BB=[\"OL\",\"UL\",\"MENU\"],sB=function(A,e,t){for(var r=A.firstChild,n=void 0;r;r=n)if(n=r.nextSibling,QB(r)&&0<r.data.trim().length)e.textNodes.push(new Hn(r,e.styles));else if(wB(r)){var B=oB(r);B.styles.isVisible()&&(aB(r,B,t)?B.flags|=4:cB(B.styles)&&(B.flags|=2),-1!==BB.indexOf(r.tagName)&&(B.flags|=8),e.elements.push(B),dB(r)||gB(r)||fB(r)||sB(r,B,t))}},oB=function(A){return hB(A)?new Nn(A):FB(A)?new Tn(A):gB(A)?new Ln(A):UB(A)?new Dn(A):lB(A)?new Mn(A):CB(A)?new Gn(A):fB(A)?new Yn(A):dB(A)?new jn(A):HB(A)?new tB(A):new ln(A)},iB=function(A){var e=oB(A);return e.flags|=4,sB(A,e,e),e},aB=function(A,e,t){return e.styles.isPositionedWithZIndex()||e.styles.opacity<1||e.styles.isTransformed()||EB(A)&&t.styles.isTransparent()},cB=function(A){return A.isPositioned()||A.isFloating()},QB=function(A){return A.nodeType===Node.TEXT_NODE},wB=function(A){return A.nodeType===Node.ELEMENT_NODE},uB=function(A){return void 0!==A.style},UB=function(A){return\"LI\"===A.tagName},lB=function(A){return\"OL\"===A.tagName},CB=function(A){return\"INPUT\"===A.tagName},gB=function(A){return\"svg\"===A.tagName},EB=function(A){return\"BODY\"===A.tagName},FB=function(A){return\"CANVAS\"===A.tagName},hB=function(A){return\"IMG\"===A.tagName},HB=function(A){return\"IFRAME\"===A.tagName},dB=function(A){return\"TEXTAREA\"===A.tagName},fB=function(A){return\"SELECT\"===A.tagName},pB=(NB.prototype.getCounterValue=function(A){var e=this.counters[A];return e&&e.length?e[e.length-1]:1},NB.prototype.getCounterValues=function(A){var e=this.counters[A];return e||[]},NB.prototype.pop=function(A){var e=this;A.forEach(function(A){return e.counters[A].pop()})},NB.prototype.parse=function(A){var t=this,e=A.counterIncrement,r=A.counterReset,n=!0;null!==e&&e.forEach(function(A){var e=t.counters[A.counter];e&&0!==A.increment&&(n=!1,e[Math.max(0,e.length-1)]+=A.increment)});var B=[];return n&&r.forEach(function(A){var e=t.counters[A.counter];B.push(A.counter),e||(e=t.counters[A.counter]=[]),e.push(A.reset)}),B},NB);function NB(){this.counters={}}function KB(r,A,e,n,t,B){return r<A||e<r?yB(r,t,0<B.length):n.integers.reduce(function(A,e,t){for(;e<=r;)r-=e,A+=n.values[t];return A},\"\")+B}function IB(A,e,t,r){for(var n=\"\";t||A--,n=r(A)+n,e<=(A/=e)*e;);return n}function TB(A,e,t,r,n){var B=t-e+1;return(A<0?\"-\":\"\")+(IB(Math.abs(A),B,r,function(A){return l(Math.floor(A%B)+e)})+n)}function mB(A,e,t){void 0===t&&(t=\". \");var r=e.length;return IB(Math.abs(A),r,!1,function(A){return e[Math.floor(A%r)]})+t}function RB(A,e,t,r,n,B){if(A<-9999||9999<A)return yB(A,tr.CJK_DECIMAL,0<n.length);var s=Math.abs(A),o=n;if(0===s)return e[0]+o;for(var i=0;0<s&&i<=4;i++){var a=s%10;0==a&&An(B,1)&&\"\"!==o?o=e[a]+o:1<a||1==a&&0===i||1==a&&1===i&&An(B,2)||1==a&&1===i&&An(B,4)&&100<A||1==a&&1<i&&An(B,8)?o=e[a]+(0<i?t[i-1]:\"\")+o:1==a&&0<i&&(o=t[i-1]+o),s=Math.floor(s/10)}return(A<0?r:\"\")+o}var LB,vB,OB={integers:[1e3,900,500,400,100,90,50,40,10,9,5,4,1],values:[\"M\",\"CM\",\"D\",\"CD\",\"C\",\"XC\",\"L\",\"XL\",\"X\",\"IX\",\"V\",\"IV\",\"I\"]},DB={integers:[9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:[\"Ք\",\"Փ\",\"Ւ\",\"Ց\",\"Ր\",\"Տ\",\"Վ\",\"Ս\",\"Ռ\",\"Ջ\",\"Պ\",\"Չ\",\"Ո\",\"Շ\",\"Ն\",\"Յ\",\"Մ\",\"Ճ\",\"Ղ\",\"Ձ\",\"Հ\",\"Կ\",\"Ծ\",\"Խ\",\"Լ\",\"Ի\",\"Ժ\",\"Թ\",\"Ը\",\"Է\",\"Զ\",\"Ե\",\"Դ\",\"Գ\",\"Բ\",\"Ա\"]},bB={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,400,300,200,100,90,80,70,60,50,40,30,20,19,18,17,16,15,10,9,8,7,6,5,4,3,2,1],values:[\"י׳\",\"ט׳\",\"ח׳\",\"ז׳\",\"ו׳\",\"ה׳\",\"ד׳\",\"ג׳\",\"ב׳\",\"א׳\",\"ת\",\"ש\",\"ר\",\"ק\",\"צ\",\"פ\",\"ע\",\"ס\",\"נ\",\"מ\",\"ל\",\"כ\",\"יט\",\"יח\",\"יז\",\"טז\",\"טו\",\"י\",\"ט\",\"ח\",\"ז\",\"ו\",\"ה\",\"ד\",\"ג\",\"ב\",\"א\"]},SB={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:[\"ჵ\",\"ჰ\",\"ჯ\",\"ჴ\",\"ხ\",\"ჭ\",\"წ\",\"ძ\",\"ც\",\"ჩ\",\"შ\",\"ყ\",\"ღ\",\"ქ\",\"ფ\",\"ჳ\",\"ტ\",\"ს\",\"რ\",\"ჟ\",\"პ\",\"ო\",\"ჲ\",\"ნ\",\"მ\",\"ლ\",\"კ\",\"ი\",\"თ\",\"ჱ\",\"ზ\",\"ვ\",\"ე\",\"დ\",\"გ\",\"ბ\",\"ა\"]},MB=\"마이너스\",yB=function(A,e,t){var r=t?\". \":\"\",n=t?\"、\":\"\",B=t?\", \":\"\",s=t?\" \":\"\";switch(e){case tr.DISC:return\"•\"+s;case tr.CIRCLE:return\"◦\"+s;case tr.SQUARE:return\"◾\"+s;case tr.DECIMAL_LEADING_ZERO:var o=TB(A,48,57,!0,r);return o.length<4?\"0\"+o:o;case tr.CJK_DECIMAL:return mB(A,\"〇一二三四五六七八九\",n);case tr.LOWER_ROMAN:return KB(A,1,3999,OB,tr.DECIMAL,r).toLowerCase();case tr.UPPER_ROMAN:return KB(A,1,3999,OB,tr.DECIMAL,r);case tr.LOWER_GREEK:return TB(A,945,969,!1,r);case tr.LOWER_ALPHA:return TB(A,97,122,!1,r);case tr.UPPER_ALPHA:return TB(A,65,90,!1,r);case tr.ARABIC_INDIC:return TB(A,1632,1641,!0,r);case tr.ARMENIAN:case tr.UPPER_ARMENIAN:return KB(A,1,9999,DB,tr.DECIMAL,r);case tr.LOWER_ARMENIAN:return KB(A,1,9999,DB,tr.DECIMAL,r).toLowerCase();case tr.BENGALI:return TB(A,2534,2543,!0,r);case tr.CAMBODIAN:case tr.KHMER:return TB(A,6112,6121,!0,r);case tr.CJK_EARTHLY_BRANCH:return mB(A,\"子丑寅卯辰巳午未申酉戌亥\",n);case tr.CJK_HEAVENLY_STEM:return mB(A,\"甲乙丙丁戊己庚辛壬癸\",n);case tr.CJK_IDEOGRAPHIC:case tr.TRAD_CHINESE_INFORMAL:return RB(A,\"零一二三四五六七八九\",\"十百千萬\",\"負\",n,14);case tr.TRAD_CHINESE_FORMAL:return RB(A,\"零壹貳參肆伍陸柒捌玖\",\"拾佰仟萬\",\"負\",n,15);case tr.SIMP_CHINESE_INFORMAL:return RB(A,\"零一二三四五六七八九\",\"十百千萬\",\"负\",n,14);case tr.SIMP_CHINESE_FORMAL:return RB(A,\"零壹贰叁肆伍陆柒捌玖\",\"拾佰仟萬\",\"负\",n,15);case tr.JAPANESE_INFORMAL:return RB(A,\"〇一二三四五六七八九\",\"十百千万\",\"マイナス\",n,0);case tr.JAPANESE_FORMAL:return RB(A,\"零壱弐参四伍六七八九\",\"拾百千万\",\"マイナス\",n,7);case tr.KOREAN_HANGUL_FORMAL:return RB(A,\"영일이삼사오육칠팔구\",\"십백천만\",MB,B,7);case tr.KOREAN_HANJA_INFORMAL:return RB(A,\"零一二三四五六七八九\",\"十百千萬\",MB,B,0);case tr.KOREAN_HANJA_FORMAL:return RB(A,\"零壹貳參四五六七八九\",\"拾百千\",MB,B,7);case tr.DEVANAGARI:return TB(A,2406,2415,!0,r);case tr.GEORGIAN:return KB(A,1,19999,SB,tr.DECIMAL,r);case tr.GUJARATI:return TB(A,2790,2799,!0,r);case tr.GURMUKHI:return TB(A,2662,2671,!0,r);case tr.HEBREW:return KB(A,1,10999,bB,tr.DECIMAL,r);case tr.HIRAGANA:return mB(A,\"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん\");case tr.HIRAGANA_IROHA:return mB(A,\"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす\");case tr.KANNADA:return TB(A,3302,3311,!0,r);case tr.KATAKANA:return mB(A,\"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン\",n);case tr.KATAKANA_IROHA:return mB(A,\"イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス\",n);case tr.LAO:return TB(A,3792,3801,!0,r);case tr.MONGOLIAN:return TB(A,6160,6169,!0,r);case tr.MYANMAR:return TB(A,4160,4169,!0,r);case tr.ORIYA:return TB(A,2918,2927,!0,r);case tr.PERSIAN:return TB(A,1776,1785,!0,r);case tr.TAMIL:return TB(A,3046,3055,!0,r);case tr.TELUGU:return TB(A,3174,3183,!0,r);case tr.THAI:return TB(A,3664,3673,!0,r);case tr.TIBETAN:return TB(A,3872,3881,!0,r);case tr.DECIMAL:default:return TB(A,48,57,!0,r)}},_B=\"data-html2canvas-ignore\",PB=(xB.prototype.toIFrame=function(A,t){var e=this,r=XB(A,t);if(!r.contentWindow)return Promise.reject(\"Unable to find iframe window\");var n=A.defaultView.pageXOffset,B=A.defaultView.pageYOffset,s=r.contentWindow,o=s.document,i=JB(r).then(function(){return a(e,void 0,void 0,function(){var e;return S(this,function(A){switch(A.label){case 0:return this.scrolledElements.forEach(YB),s&&(s.scrollTo(t.left,t.top),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||s.scrollY===t.top&&s.scrollX===t.left||(o.documentElement.style.top=-t.top+\"px\",o.documentElement.style.left=-t.left+\"px\",o.documentElement.style.position=\"absolute\")),e=this.options.onclone,void 0===this.clonedReferenceElement?[2,Promise.reject(\"Error finding the \"+this.referenceElement.nodeName+\" in the cloned document\")]:o.fonts&&o.fonts.ready?[4,o.fonts.ready]:[3,2];case 1:A.sent(),A.label=2;case 2:return\"function\"==typeof e?[2,Promise.resolve().then(function(){return e(o)}).then(function(){return r})]:[2,r]}})})});return o.open(),o.write(kB(document.doctype)+\"<html></html>\"),WB(this.referenceElement.ownerDocument,n,B),o.replaceChild(o.adoptNode(this.documentElement),o.documentElement),o.close(),i},xB.prototype.createElementClone=function(A){return FB(A)?this.createCanvasClone(A):nB(A)?this.createStyleClone(A):A.cloneNode(!1)},xB.prototype.createStyleClone=function(A){try{var e=A.sheet;if(e&&e.cssRules){var t=[].slice.call(e.cssRules,0).reduce(function(A,e){return e&&\"string\"==typeof e.cssText?A+e.cssText:A},\"\"),r=A.cloneNode(!1);return r.textContent=t,r}}catch(A){if(De.getInstance(this.options.id).error(\"Unable to access cssRules property\",A),\"SecurityError\"!==A.name)throw A}return A.cloneNode(!1)},xB.prototype.createCanvasClone=function(A){if(this.options.inlineImages&&A.ownerDocument){var e=A.ownerDocument.createElement(\"img\");try{return e.src=A.toDataURL(),e}catch(A){De.getInstance(this.options.id).info(\"Unable to clone canvas contents, canvas is tainted\")}}var t=A.cloneNode(!1);try{t.width=A.width,t.height=A.height;var r=A.getContext(\"2d\"),n=t.getContext(\"2d\");return n&&(r?n.putImageData(r.getImageData(0,0,A.width,A.height),0,0):n.drawImage(A,0,0)),t}catch(A){}return t},xB.prototype.cloneNode=function(A){if(QB(A))return document.createTextNode(A.data);if(!A.ownerDocument)return A.cloneNode(!1);var e=A.ownerDocument.defaultView;if(uB(A)&&e){var t=this.createElementClone(A),r=e.getComputedStyle(A),n=e.getComputedStyle(A,\":before\"),B=e.getComputedStyle(A,\":after\");this.referenceElement===A&&(this.clonedReferenceElement=t),EB(t)&&$B(t);for(var s=this.counters.parse(new un(r)),o=this.resolvePseudoContent(A,t,n,LB.BEFORE),i=A.firstChild;i;i=i.nextSibling)wB(i)&&(\"SCRIPT\"===i.tagName||i.hasAttribute(_B)||\"function\"==typeof this.options.ignoreElements&&this.options.ignoreElements(i))||this.options.copyStyles&&wB(i)&&nB(i)||t.appendChild(this.cloneNode(i));o&&t.insertBefore(o,t.firstChild);var a=this.resolvePseudoContent(A,t,B,LB.AFTER);return a&&t.appendChild(a),this.counters.pop(s),r&&this.options.copyStyles&&!HB(A)&&GB(r,t),0===A.scrollTop&&0===A.scrollLeft||this.scrolledElements.push([t,A.scrollLeft,A.scrollTop]),(dB(A)||fB(A))&&(dB(t)||fB(t))&&(t.value=A.value),t}return A.cloneNode(!1)},xB.prototype.resolvePseudoContent=function(U,A,e,t){var l=this;if(e){var r=e.content,C=A.ownerDocument;if(C&&r&&\"none\"!==r&&\"-moz-alt-content\"!==r&&\"none\"!==e.display){this.counters.parse(new un(e));var g=new wn(e),E=C.createElement(\"html2canvaspseudoelement\");GB(e,E),g.content.forEach(function(A){if(A.type===sA.STRING_TOKEN)E.appendChild(C.createTextNode(A.value));else if(A.type===sA.URL_TOKEN){var e=C.createElement(\"img\");e.src=A.value,e.style.opacity=\"1\",E.appendChild(e)}else if(A.type===sA.FUNCTION){if(\"attr\"===A.name){var t=A.values.filter(zA);t.length&&E.appendChild(C.createTextNode(U.getAttribute(t[0].value)||\"\"))}else if(\"counter\"===A.name){var r=A.values.filter(kA),n=r[0],B=r[1];if(n&&zA(n)){var s=l.counters.getCounterValue(n.value),o=B&&zA(B)?ir.parse(B.value):tr.DECIMAL;E.appendChild(C.createTextNode(yB(s,o,!1)))}}else if(\"counters\"===A.name){var i=A.values.filter(kA),a=(n=i[0],i[1]);if(B=i[2],n&&zA(n)){var c=l.counters.getCounterValues(n.value),Q=B&&zA(B)?ir.parse(B.value):tr.DECIMAL,w=a&&a.type===sA.STRING_TOKEN?a.value:\"\",u=c.map(function(A){return yB(A,Q,!1)}).join(w);E.appendChild(C.createTextNode(u))}}}else if(A.type===sA.IDENT_TOKEN)switch(A.value){case\"open-quote\":E.appendChild(C.createTextNode(en(g.quotes,l.quoteDepth++,!0)));break;case\"close-quote\":E.appendChild(C.createTextNode(en(g.quotes,--l.quoteDepth,!1)));break;default:E.appendChild(C.createTextNode(A.value))}}),E.className=qB+\" \"+ZB;var n=t===LB.BEFORE?\" \"+qB:\" \"+ZB;return function(A){return\"object\"==typeof A.className}(A)?A.className.baseValue+=n:A.className+=n,E}}},xB.destroy=function(A){return!!A.parentNode&&(A.parentNode.removeChild(A),!0)},xB);function xB(A,e){if(this.options=e,this.scrolledElements=[],this.referenceElement=A,this.counters=new pB,this.quoteDepth=0,!A.ownerDocument)throw new Error(\"Cloned element does not have an owner document\");this.documentElement=this.cloneNode(A.ownerDocument.documentElement)}(vB=LB||(LB={}))[vB.BEFORE=0]=\"BEFORE\",vB[vB.AFTER=1]=\"AFTER\";var VB,zB,XB=function(A,e){var t=A.createElement(\"iframe\");return t.className=\"html2canvas-container\",t.style.visibility=\"hidden\",t.style.position=\"fixed\",t.style.left=\"-10000px\",t.style.top=\"0px\",t.style.border=\"0\",t.width=e.width.toString(),t.height=e.height.toString(),t.scrolling=\"no\",t.setAttribute(_B,\"true\"),A.body.appendChild(t),t},JB=function(n){return new Promise(function(e,A){var t=n.contentWindow;if(!t)return A(\"No window assigned for iframe\");var r=t.document;t.onload=n.onload=r.onreadystatechange=function(){t.onload=n.onload=r.onreadystatechange=null;var A=setInterval(function(){0<r.body.childNodes.length&&\"complete\"===r.readyState&&(clearInterval(A),e(n))},50)}})},GB=function(A,e){for(var t=A.length-1;0<=t;t--){var r=A.item(t);\"content\"!==r&&e.style.setProperty(r,A.getPropertyValue(r))}return e},kB=function(A){var e=\"\";return A&&(e+=\"<!DOCTYPE \",A.name&&(e+=A.name),A.internalSubset&&(e+=A.internalSubset),A.publicId&&(e+='\"'+A.publicId+'\"'),A.systemId&&(e+='\"'+A.systemId+'\"'),e+=\">\"),e},WB=function(A,e,t){A&&A.defaultView&&(e!==A.defaultView.pageXOffset||t!==A.defaultView.pageYOffset)&&A.defaultView.scrollTo(e,t)},YB=function(A){var e=A[0],t=A[1],r=A[2];e.scrollLeft=t,e.scrollTop=r},qB=\"___html2canvas___pseudoelement_before\",ZB=\"___html2canvas___pseudoelement_after\",jB='{\\n    content: \"\" !important;\\n    display: none !important;\\n}',$B=function(A){As(A,\".\"+qB+\":before\"+jB+\"\\n         .\"+ZB+\":after\"+jB)},As=function(A,e){var t=A.ownerDocument;if(t){var r=t.createElement(\"style\");r.textContent=e,A.appendChild(r)}};(zB=VB||(VB={}))[zB.VECTOR=0]=\"VECTOR\",zB[zB.BEZIER_CURVE=1]=\"BEZIER_CURVE\";function es(A,t){return A.length===t.length&&A.some(function(A,e){return A===t[e]})}var ts=(rs.prototype.add=function(A,e){return new rs(this.x+A,this.y+e)},rs);function rs(A,e){this.type=VB.VECTOR,this.x=A,this.y=e}function ns(A,e,t){return new ts(A.x+(e.x-A.x)*t,A.y+(e.y-A.y)*t)}var Bs=(ss.prototype.subdivide=function(A,e){var t=ns(this.start,this.startControl,A),r=ns(this.startControl,this.endControl,A),n=ns(this.endControl,this.end,A),B=ns(t,r,A),s=ns(r,n,A),o=ns(B,s,A);return e?new ss(this.start,t,B,o):new ss(o,s,n,this.end)},ss.prototype.add=function(A,e){return new ss(this.start.add(A,e),this.startControl.add(A,e),this.endControl.add(A,e),this.end.add(A,e))},ss.prototype.reverse=function(){return new ss(this.end,this.endControl,this.startControl,this.start)},ss);function ss(A,e,t,r){this.type=VB.BEZIER_CURVE,this.start=A,this.startControl=e,this.endControl=t,this.end=r}function os(A){return A.type===VB.BEZIER_CURVE}var is,as,cs=function(A){var e=A.styles,t=A.bounds,r=jA(e.borderTopLeftRadius,t.width,t.height),n=r[0],B=r[1],s=jA(e.borderTopRightRadius,t.width,t.height),o=s[0],i=s[1],a=jA(e.borderBottomRightRadius,t.width,t.height),c=a[0],Q=a[1],w=jA(e.borderBottomLeftRadius,t.width,t.height),u=w[0],U=w[1],l=[];l.push((n+o)/t.width),l.push((u+c)/t.width),l.push((B+U)/t.height),l.push((i+Q)/t.height);var C=Math.max.apply(Math,l);1<C&&(n/=C,B/=C,o/=C,i/=C,c/=C,Q/=C,u/=C,U/=C);var g=t.width-o,E=t.height-Q,F=t.width-c,h=t.height-U,H=e.borderTopWidth,d=e.borderRightWidth,f=e.borderBottomWidth,p=e.borderLeftWidth,N=ae(e.paddingTop,A.bounds.width),K=ae(e.paddingRight,A.bounds.width),I=ae(e.paddingBottom,A.bounds.width),T=ae(e.paddingLeft,A.bounds.width);this.topLeftBorderBox=0<n||0<B?us(t.left,t.top,n,B,is.TOP_LEFT):new ts(t.left,t.top),this.topRightBorderBox=0<o||0<i?us(t.left+g,t.top,o,i,is.TOP_RIGHT):new ts(t.left+t.width,t.top),this.bottomRightBorderBox=0<c||0<Q?us(t.left+F,t.top+E,c,Q,is.BOTTOM_RIGHT):new ts(t.left+t.width,t.top+t.height),this.bottomLeftBorderBox=0<u||0<U?us(t.left,t.top+h,u,U,is.BOTTOM_LEFT):new ts(t.left,t.top+t.height),this.topLeftPaddingBox=0<n||0<B?us(t.left+p,t.top+H,Math.max(0,n-p),Math.max(0,B-H),is.TOP_LEFT):new ts(t.left+p,t.top+H),this.topRightPaddingBox=0<o||0<i?us(t.left+Math.min(g,t.width+p),t.top+H,g>t.width+p?0:o-p,i-H,is.TOP_RIGHT):new ts(t.left+t.width-d,t.top+H),this.bottomRightPaddingBox=0<c||0<Q?us(t.left+Math.min(F,t.width-p),t.top+Math.min(E,t.height+H),Math.max(0,c-d),Q-f,is.BOTTOM_RIGHT):new ts(t.left+t.width-d,t.top+t.height-f),this.bottomLeftPaddingBox=0<u||0<U?us(t.left+p,t.top+h,Math.max(0,u-p),U-f,is.BOTTOM_LEFT):new ts(t.left+p,t.top+t.height-f),this.topLeftContentBox=0<n||0<B?us(t.left+p+T,t.top+H+N,Math.max(0,n-(p+T)),Math.max(0,B-(H+N)),is.TOP_LEFT):new ts(t.left+p+T,t.top+H+N),this.topRightContentBox=0<o||0<i?us(t.left+Math.min(g,t.width+p+T),t.top+H+N,g>t.width+p+T?0:o-p+T,i-(H+N),is.TOP_RIGHT):new ts(t.left+t.width-(d+K),t.top+H+N),this.bottomRightContentBox=0<c||0<Q?us(t.left+Math.min(F,t.width-(p+T)),t.top+Math.min(E,t.height+H+N),Math.max(0,c-(d+K)),Q-(f+I),is.BOTTOM_RIGHT):new ts(t.left+t.width-(d+K),t.top+t.height-(f+I)),this.bottomLeftContentBox=0<u||0<U?us(t.left+p+T,t.top+h,Math.max(0,u-(p+T)),U-(f+I),is.BOTTOM_LEFT):new ts(t.left+p+T,t.top+t.height-(f+I))};(as=is||(is={}))[as.TOP_LEFT=0]=\"TOP_LEFT\",as[as.TOP_RIGHT=1]=\"TOP_RIGHT\",as[as.BOTTOM_RIGHT=2]=\"BOTTOM_RIGHT\",as[as.BOTTOM_LEFT=3]=\"BOTTOM_LEFT\";function Qs(A){return[A.topLeftBorderBox,A.topRightBorderBox,A.bottomRightBorderBox,A.bottomLeftBorderBox]}function ws(A){return[A.topLeftPaddingBox,A.topRightPaddingBox,A.bottomRightPaddingBox,A.bottomLeftPaddingBox]}var us=function(A,e,t,r,n){var B=(Math.sqrt(2)-1)/3*4,s=t*B,o=r*B,i=A+t,a=e+r;switch(n){case is.TOP_LEFT:return new Bs(new ts(A,a),new ts(A,a-o),new ts(i-s,e),new ts(i,e));case is.TOP_RIGHT:return new Bs(new ts(A,e),new ts(A+s,e),new ts(i,a-o),new ts(i,a));case is.BOTTOM_RIGHT:return new Bs(new ts(i,e),new ts(i,e+o),new ts(A+s,a),new ts(A,a));case is.BOTTOM_LEFT:default:return new Bs(new ts(i,a),new ts(i-s,a),new ts(A,e+o),new ts(A,e))}},Us=function(A,e,t){this.type=0,this.offsetX=A,this.offsetY=e,this.matrix=t,this.target=6},ls=function(A,e){this.type=1,this.target=e,this.path=A},Cs=function(A){this.element=A,this.inlineLevel=[],this.nonInlineLevel=[],this.negativeZIndex=[],this.zeroOrAutoZIndexOrTransformedOrOpacity=[],this.positiveZIndex=[],this.nonPositionedFloats=[],this.nonPositionedInlineLevel=[]},gs=(Es.prototype.getParentEffects=function(){var A=this.effects.slice(0);if(this.container.styles.overflowX!==sr.VISIBLE){var e=Qs(this.curves),t=ws(this.curves);es(e,t)||A.push(new ls(t,6))}return A},Es);function Es(A,e){if(this.container=A,this.effects=e.slice(0),this.curves=new cs(A),null!==A.styles.transform){var t=A.bounds.left+A.styles.transformOrigin[0].number,r=A.bounds.top+A.styles.transformOrigin[1].number,n=A.styles.transform;this.effects.push(new Us(t,r,n))}if(A.styles.overflowX!==sr.VISIBLE){var B=Qs(this.curves),s=ws(this.curves);es(B,s)?this.effects.push(new ls(B,6)):(this.effects.push(new ls(B,2)),this.effects.push(new ls(s,4)))}}function Fs(A){var e=A.bounds,t=A.styles;return e.add(t.borderLeftWidth,t.borderTopWidth,-(t.borderRightWidth+t.borderLeftWidth),-(t.borderTopWidth+t.borderBottomWidth))}function hs(A){var e=A.styles,t=A.bounds,r=ae(e.paddingLeft,t.width),n=ae(e.paddingRight,t.width),B=ae(e.paddingTop,t.width),s=ae(e.paddingBottom,t.width);return t.add(r+e.borderLeftWidth,B+e.borderTopWidth,-(e.borderRightWidth+e.borderLeftWidth+r+n),-(e.borderTopWidth+e.borderBottomWidth+B+s))}function Hs(A,e,t){var r=function(A,e){return 0===A?e.bounds:2===A?hs(e):Fs(e)}(Ts(A.styles.backgroundOrigin,e),A),n=function(A,e){return A===Ee.BORDER_BOX?e.bounds:A===Ee.CONTENT_BOX?hs(e):Fs(e)}(Ts(A.styles.backgroundClip,e),A),B=Is(Ts(A.styles.backgroundSize,e),t,r),s=B[0],o=B[1],i=jA(Ts(A.styles.backgroundPosition,e),r.width-s,r.height-o);return[ms(Ts(A.styles.backgroundRepeat,e),i,B,r,n),Math.round(r.left+i[0]),Math.round(r.top+i[1]),s,o]}function ds(A){return zA(A)&&A.value===Ut.AUTO}function fs(A){return\"number\"==typeof A}var ps=function(c,Q,w,u){c.container.elements.forEach(function(A){var e=An(A.flags,4),t=An(A.flags,2),r=new gs(A,c.getParentEffects());An(A.styles.display,2048)&&u.push(r);var n=An(A.flags,8)?[]:u;if(e||t){var B=e||A.styles.isPositioned()?w:Q,s=new Cs(r);if(A.styles.isPositioned()||A.styles.opacity<1||A.styles.isTransformed()){var o=A.styles.zIndex.order;if(o<0){var i=0;B.negativeZIndex.some(function(A,e){return o>A.element.container.styles.zIndex.order?(i=e,!1):0<i}),B.negativeZIndex.splice(i,0,s)}else if(0<o){var a=0;B.positiveZIndex.some(function(A,e){return o>A.element.container.styles.zIndex.order?(a=e+1,!1):0<a}),B.positiveZIndex.splice(a,0,s)}else B.zeroOrAutoZIndexOrTransformedOrOpacity.push(s)}else A.styles.isFloating()?B.nonPositionedFloats.push(s):B.nonPositionedInlineLevel.push(s);ps(r,s,e?s:w,n)}else A.styles.isInlineLevel()?Q.inlineLevel.push(r):Q.nonInlineLevel.push(r),ps(r,Q,w,n);An(A.flags,8)&&Ns(A,n)})},Ns=function(A,e){for(var t=A instanceof Mn?A.start:1,r=A instanceof Mn&&A.reversed,n=0;n<e.length;n++){var B=e[n];B.container instanceof Dn&&\"number\"==typeof B.container.value&&0!==B.container.value&&(t=B.container.value),B.listValue=yB(t,B.container.styles.listStyleType,!0),t+=r?-1:1}},Ks=function(A,e,t,r){var n=[];return os(A)?n.push(A.subdivide(.5,!1)):n.push(A),os(t)?n.push(t.subdivide(.5,!0)):n.push(t),os(r)?n.push(r.subdivide(.5,!0).reverse()):n.push(r),os(e)?n.push(e.subdivide(.5,!1).reverse()):n.push(e),n},Is=function(A,e,t){var r=e[0],n=e[1],B=e[2],s=A[0],o=A[1];if(qA(s)&&o&&qA(o))return[ae(s,t.width),ae(o,t.height)];var i=fs(B);if(zA(s)&&(s.value===Ut.CONTAIN||s.value===Ut.COVER))return fs(B)?t.width/t.height<B!=(s.value===Ut.COVER)?[t.width,t.width/B]:[t.height*B,t.height]:[t.width,t.height];var a=fs(r),c=fs(n),Q=a||c;if(ds(s)&&(!o||ds(o)))return a&&c?[r,n]:i||Q?Q&&i?[a?r:n*B,c?n:r/B]:[a?r:t.width,c?n:t.height]:[t.width,t.height];if(i){var w=0,u=0;return qA(s)?w=ae(s,t.width):qA(o)&&(u=ae(o,t.height)),ds(s)?w=u*B:o&&!ds(o)||(u=w/B),[w,u]}var U=null,l=null;if(qA(s)?U=ae(s,t.width):o&&qA(o)&&(l=ae(o,t.height)),null===U||o&&!ds(o)||(l=a&&c?U/r*n:t.height),null!==l&&ds(s)&&(U=a&&c?l/n*r:t.width),null!==U&&null!==l)return[U,l];throw new Error(\"Unable to calculate background-size for element\")},Ts=function(A,e){var t=A[e];return void 0===t?A[0]:t},ms=function(A,e,t,r,n){var B=e[0],s=e[1],o=t[0],i=t[1];switch(A){case it.REPEAT_X:return[new ts(Math.round(r.left),Math.round(r.top+s)),new ts(Math.round(r.left+r.width),Math.round(r.top+s)),new ts(Math.round(r.left+r.width),Math.round(i+r.top+s)),new ts(Math.round(r.left),Math.round(i+r.top+s))];case it.REPEAT_Y:return[new ts(Math.round(r.left+B),Math.round(r.top)),new ts(Math.round(r.left+B+o),Math.round(r.top)),new ts(Math.round(r.left+B+o),Math.round(r.height+r.top)),new ts(Math.round(r.left+B),Math.round(r.height+r.top))];case it.NO_REPEAT:return[new ts(Math.round(r.left+B),Math.round(r.top+s)),new ts(Math.round(r.left+B+o),Math.round(r.top+s)),new ts(Math.round(r.left+B+o),Math.round(r.top+s+i)),new ts(Math.round(r.left+B),Math.round(r.top+s+i))];default:return[new ts(Math.round(n.left),Math.round(n.top)),new ts(Math.round(n.left+n.width),Math.round(n.top)),new ts(Math.round(n.left+n.width),Math.round(n.height+n.top)),new ts(Math.round(n.left),Math.round(n.height+n.top))]}},Rs=\"Hidden Text\",Ls=(vs.prototype.parseMetrics=function(A,e){var t=this._document.createElement(\"div\"),r=this._document.createElement(\"img\"),n=this._document.createElement(\"span\"),B=this._document.body;t.style.visibility=\"hidden\",t.style.fontFamily=A,t.style.fontSize=e,t.style.margin=\"0\",t.style.padding=\"0\",B.appendChild(t),r.src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",r.width=1,r.height=1,r.style.margin=\"0\",r.style.padding=\"0\",r.style.verticalAlign=\"baseline\",n.style.fontFamily=A,n.style.fontSize=e,n.style.margin=\"0\",n.style.padding=\"0\",n.appendChild(this._document.createTextNode(Rs)),t.appendChild(n),t.appendChild(r);var s=r.offsetTop-n.offsetTop+2;t.removeChild(n),t.appendChild(this._document.createTextNode(Rs)),t.style.lineHeight=\"normal\",r.style.verticalAlign=\"super\";var o=r.offsetTop-t.offsetTop+2;return B.removeChild(t),{baseline:s,middle:o}},vs.prototype.getMetrics=function(A,e){var t=A+\" \"+e;return void 0===this._data[t]&&(this._data[t]=this.parseMetrics(A,e)),this._data[t]},vs);function vs(A){this._data={},this._document=A}var Os=(Ds.prototype.applyEffects=function(A,e){for(var t=this;this._activeEffects.length;)this.popEffect();A.filter(function(A){return An(A.target,e)}).forEach(function(A){return t.applyEffect(A)})},Ds.prototype.applyEffect=function(A){this.ctx.save(),function(A){return 0===A.type}(A)&&(this.ctx.translate(A.offsetX,A.offsetY),this.ctx.transform(A.matrix[0],A.matrix[1],A.matrix[2],A.matrix[3],A.matrix[4],A.matrix[5]),this.ctx.translate(-A.offsetX,-A.offsetY)),function(A){return 1===A.type}(A)&&(this.path(A.path),this.ctx.clip()),this._activeEffects.push(A)},Ds.prototype.popEffect=function(){this._activeEffects.pop(),this.ctx.restore()},Ds.prototype.renderStack=function(t){return a(this,void 0,void 0,function(){var e;return S(this,function(A){switch(A.label){case 0:return(e=t.element.container.styles).isVisible()?(this.ctx.globalAlpha=e.opacity,[4,this.renderStackContent(t)]):[3,2];case 1:A.sent(),A.label=2;case 2:return[2]}})})},Ds.prototype.renderNode=function(e){return a(this,void 0,void 0,function(){return S(this,function(A){switch(A.label){case 0:return e.container.styles.isVisible()?[4,this.renderNodeBackgroundAndBorders(e)]:[3,3];case 1:return A.sent(),[4,this.renderNodeContent(e)];case 2:A.sent(),A.label=3;case 3:return[2]}})})},Ds.prototype.renderTextWithLetterSpacing=function(t,A){var r=this;0===A?this.ctx.fillText(t.text,t.bounds.left,t.bounds.top+t.bounds.height):c(t.text).map(function(A){return l(A)}).reduce(function(A,e){return r.ctx.fillText(e,A,t.bounds.top+t.bounds.height),A+r.ctx.measureText(e).width},t.bounds.left)},Ds.prototype.createFontStyle=function(A){var e=A.fontVariant.filter(function(A){return\"normal\"===A||\"small-caps\"===A}).join(\"\"),t=A.fontFamily.join(\", \"),r=xA(A.fontSize)?\"\"+A.fontSize.number+A.fontSize.unit:A.fontSize.number+\"px\";return[[A.fontStyle,e,A.fontWeight,r,t].join(\" \"),t,r]},Ds.prototype.renderTextNode=function(r,o){return a(this,void 0,void 0,function(){var e,t,n,B,s=this;return S(this,function(A){return e=this.createFontStyle(o),t=e[0],n=e[1],B=e[2],this.ctx.font=t,r.textBounds.forEach(function(r){s.ctx.fillStyle=te(o.color),s.renderTextWithLetterSpacing(r,o.letterSpacing);var A=o.textShadow;A.length&&r.text.trim().length&&(A.slice(0).reverse().forEach(function(A){s.ctx.shadowColor=te(A.color),s.ctx.shadowOffsetX=A.offsetX.number*s.options.scale,s.ctx.shadowOffsetY=A.offsetY.number*s.options.scale,s.ctx.shadowBlur=A.blur.number,s.ctx.fillText(r.text,r.bounds.left,r.bounds.top+r.bounds.height)}),s.ctx.shadowColor=\"\",s.ctx.shadowOffsetX=0,s.ctx.shadowOffsetY=0,s.ctx.shadowBlur=0),o.textDecorationLine.length&&(s.ctx.fillStyle=te(o.textDecorationColor||o.color),o.textDecorationLine.forEach(function(A){switch(A){case 1:var e=s.fontMetrics.getMetrics(n,B).baseline;s.ctx.fillRect(r.bounds.left,Math.round(r.bounds.top+e),r.bounds.width,1);break;case 2:s.ctx.fillRect(r.bounds.left,Math.round(r.bounds.top),r.bounds.width,1);break;case 3:var t=s.fontMetrics.getMetrics(n,B).middle;s.ctx.fillRect(r.bounds.left,Math.ceil(r.bounds.top+t),r.bounds.width,1)}}))}),[2]})})},Ds.prototype.renderReplacedElement=function(A,e,t){if(t&&0<A.intrinsicWidth&&0<A.intrinsicHeight){var r=hs(A),n=ws(e);this.path(n),this.ctx.save(),this.ctx.clip(),this.ctx.drawImage(t,0,0,A.intrinsicWidth,A.intrinsicHeight,r.left,r.top,r.width,r.height),this.ctx.restore()}},Ds.prototype.renderNodeContent=function(l){return a(this,void 0,void 0,function(){var e,t,r,n,B,s,o,i,a,c,Q,w,u,U;return S(this,function(A){switch(A.label){case 0:this.applyEffects(l.effects,4),e=l.container,t=l.curves,r=e.styles,n=0,B=e.textNodes,A.label=1;case 1:return n<B.length?(s=B[n],[4,this.renderTextNode(s,r)]):[3,4];case 2:A.sent(),A.label=3;case 3:return n++,[3,1];case 4:if(!(e instanceof Nn))return[3,8];A.label=5;case 5:return A.trys.push([5,7,,8]),[4,this.options.cache.match(e.src)];case 6:return w=A.sent(),this.renderReplacedElement(e,t,w),[3,8];case 7:return A.sent(),De.getInstance(this.options.id).error(\"Error loading image \"+e.src),[3,8];case 8:if(e instanceof Tn&&this.renderReplacedElement(e,t,e.canvas),!(e instanceof Ln))return[3,12];A.label=9;case 9:return A.trys.push([9,11,,12]),[4,this.options.cache.match(e.svg)];case 10:return w=A.sent(),this.renderReplacedElement(e,t,w),[3,12];case 11:return A.sent(),De.getInstance(this.options.id).error(\"Error loading svg \"+e.svg.substring(0,255)),[3,12];case 12:return e instanceof tB&&e.tree?[4,new Ds({id:this.options.id,scale:this.options.scale,backgroundColor:e.backgroundColor,x:0,y:0,scrollX:0,scrollY:0,width:e.width,height:e.height,cache:this.options.cache,windowWidth:e.width,windowHeight:e.height}).render(e.tree)]:[3,14];case 13:o=A.sent(),e.width&&e.height&&this.ctx.drawImage(o,0,0,e.width,e.height,e.bounds.left,e.bounds.top,e.bounds.width,e.bounds.height),A.label=14;case 14:if(e instanceof Gn&&(i=Math.min(e.bounds.width,e.bounds.height),e.type===Vn?e.checked&&(this.ctx.save(),this.path([new ts(e.bounds.left+.39363*i,e.bounds.top+.79*i),new ts(e.bounds.left+.16*i,e.bounds.top+.5549*i),new ts(e.bounds.left+.27347*i,e.bounds.top+.44071*i),new ts(e.bounds.left+.39694*i,e.bounds.top+.5649*i),new ts(e.bounds.left+.72983*i,e.bounds.top+.23*i),new ts(e.bounds.left+.84*i,e.bounds.top+.34085*i),new ts(e.bounds.left+.39363*i,e.bounds.top+.79*i)]),this.ctx.fillStyle=te(Jn),this.ctx.fill(),this.ctx.restore()):e.type===zn&&e.checked&&(this.ctx.save(),this.ctx.beginPath(),this.ctx.arc(e.bounds.left+i/2,e.bounds.top+i/2,i/4,0,2*Math.PI,!0),this.ctx.fillStyle=te(Jn),this.ctx.fill(),this.ctx.restore())),bs(e)&&e.value.length){switch(this.ctx.font=this.createFontStyle(r)[0],this.ctx.fillStyle=te(r.color),this.ctx.textBaseline=\"middle\",this.ctx.textAlign=Ms(e.styles.textAlign),U=hs(e),a=0,e.styles.textAlign){case Cr.CENTER:a+=U.width/2;break;case Cr.RIGHT:a+=U.width}c=U.add(a,0,0,-U.height/2+1),this.ctx.save(),this.path([new ts(U.left,U.top),new ts(U.left+U.width,U.top),new ts(U.left+U.width,U.top+U.height),new ts(U.left,U.top+U.height)]),this.ctx.clip(),this.renderTextWithLetterSpacing(new Cn(e.value,c),r.letterSpacing),this.ctx.restore(),this.ctx.textBaseline=\"bottom\",this.ctx.textAlign=\"left\"}if(!An(e.styles.display,2048))return[3,20];if(null===e.styles.listStyleImage)return[3,19];if((Q=e.styles.listStyleImage).type!==xe.URL)return[3,18];w=void 0,u=Q.url,A.label=15;case 15:return A.trys.push([15,17,,18]),[4,this.options.cache.match(u)];case 16:return w=A.sent(),this.ctx.drawImage(w,e.bounds.left-(w.width+10),e.bounds.top),[3,18];case 17:return A.sent(),De.getInstance(this.options.id).error(\"Error loading list-style-image \"+u),[3,18];case 18:return[3,20];case 19:l.listValue&&e.styles.listStyleType!==tr.NONE&&(this.ctx.font=this.createFontStyle(r)[0],this.ctx.fillStyle=te(r.color),this.ctx.textBaseline=\"middle\",this.ctx.textAlign=\"right\",U=new I(e.bounds.left,e.bounds.top+ae(e.styles.paddingTop,e.bounds.width),e.bounds.width,function(A,e){return zA(A)&&\"normal\"===A.value?1.2*e:A.type===sA.NUMBER_TOKEN?e*A.number:qA(A)?ae(A,e):e}(r.lineHeight,r.fontSize.number)/2+1),this.renderTextWithLetterSpacing(new Cn(l.listValue,U),r.letterSpacing),this.ctx.textBaseline=\"bottom\",this.ctx.textAlign=\"left\"),A.label=20;case 20:return[2]}})})},Ds.prototype.renderStackContent=function(C){return a(this,void 0,void 0,function(){var e,t,r,n,B,s,o,i,a,c,Q,w,u,U,l;return S(this,function(A){switch(A.label){case 0:return[4,this.renderNodeBackgroundAndBorders(C.element)];case 1:A.sent(),e=0,t=C.negativeZIndex,A.label=2;case 2:return e<t.length?(l=t[e],[4,this.renderStack(l)]):[3,5];case 3:A.sent(),A.label=4;case 4:return e++,[3,2];case 5:return[4,this.renderNodeContent(C.element)];case 6:A.sent(),r=0,n=C.nonInlineLevel,A.label=7;case 7:return r<n.length?(l=n[r],[4,this.renderNode(l)]):[3,10];case 8:A.sent(),A.label=9;case 9:return r++,[3,7];case 10:B=0,s=C.nonPositionedFloats,A.label=11;case 11:return B<s.length?(l=s[B],[4,this.renderStack(l)]):[3,14];case 12:A.sent(),A.label=13;case 13:return B++,[3,11];case 14:o=0,i=C.nonPositionedInlineLevel,A.label=15;case 15:return o<i.length?(l=i[o],[4,this.renderStack(l)]):[3,18];case 16:A.sent(),A.label=17;case 17:return o++,[3,15];case 18:a=0,c=C.inlineLevel,A.label=19;case 19:return a<c.length?(l=c[a],[4,this.renderNode(l)]):[3,22];case 20:A.sent(),A.label=21;case 21:return a++,[3,19];case 22:Q=0,w=C.zeroOrAutoZIndexOrTransformedOrOpacity,A.label=23;case 23:return Q<w.length?(l=w[Q],[4,this.renderStack(l)]):[3,26];case 24:A.sent(),A.label=25;case 25:return Q++,[3,23];case 26:u=0,U=C.positiveZIndex,A.label=27;case 27:return u<U.length?(l=U[u],[4,this.renderStack(l)]):[3,30];case 28:A.sent(),A.label=29;case 29:return u++,[3,27];case 30:return[2]}})})},Ds.prototype.mask=function(A){this.ctx.beginPath(),this.ctx.moveTo(0,0),this.ctx.lineTo(this.canvas.width,0),this.ctx.lineTo(this.canvas.width,this.canvas.height),this.ctx.lineTo(0,this.canvas.height),this.ctx.lineTo(0,0),this.formatPath(A.slice(0).reverse()),this.ctx.closePath()},Ds.prototype.path=function(A){this.ctx.beginPath(),this.formatPath(A),this.ctx.closePath()},Ds.prototype.formatPath=function(A){var r=this;A.forEach(function(A,e){var t=os(A)?A.start:A;0===e?r.ctx.moveTo(t.x,t.y):r.ctx.lineTo(t.x,t.y),os(A)&&r.ctx.bezierCurveTo(A.startControl.x,A.startControl.y,A.endControl.x,A.endControl.y,A.end.x,A.end.y)})},Ds.prototype.renderRepeat=function(A,e,t,r){this.path(A),this.ctx.fillStyle=e,this.ctx.translate(t,r),this.ctx.fill(),this.ctx.translate(-t,-r)},Ds.prototype.resizeImage=function(A,e,t){if(A.width===e&&A.height===t)return A;var r=this.canvas.ownerDocument.createElement(\"canvas\");return r.width=e,r.height=t,r.getContext(\"2d\").drawImage(A,0,0,A.width,A.height,0,0,e,t),r},Ds.prototype.renderBackgroundImage=function(b){return a(this,void 0,void 0,function(){var O,e,D,t,r,n;return S(this,function(A){switch(A.label){case 0:O=b.styles.backgroundImage.length-1,e=function(e){var t,r,n,B,s,o,i,a,c,Q,w,u,U,l,C,g,E,F,h,H,d,f,p,N,K,I,T,m,R,L,v;return S(this,function(A){switch(A.label){case 0:if(e.type!==xe.URL)return[3,5];t=void 0,r=e.url,A.label=1;case 1:return A.trys.push([1,3,,4]),[4,D.options.cache.match(r)];case 2:return t=A.sent(),[3,4];case 3:return A.sent(),De.getInstance(D.options.id).error(\"Error loading background-image \"+r),[3,4];case 4:return t&&(n=Hs(b,O,[t.width,t.height,t.width/t.height]),g=n[0],f=n[1],p=n[2],h=n[3],H=n[4],l=D.ctx.createPattern(D.resizeImage(t,h,H),\"repeat\"),D.renderRepeat(g,l,f,p)),[3,6];case 5:!function(A){return A.type===xe.LINEAR_GRADIENT}(e)?function(A){return A.type===xe.RADIAL_GRADIENT}(e)&&(C=Hs(b,O,[null,null,null]),g=C[0],E=C[1],F=C[2],h=C[3],H=C[4],d=0===e.position.length?[oe]:e.position,f=ae(d[0],h),p=ae(d[d.length-1],H),N=function(A,e,t,r,n){var B=0,s=0;switch(A.size){case Bt.CLOSEST_SIDE:A.shape===rt.CIRCLE?B=s=Math.min(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-n)):A.shape===rt.ELLIPSE&&(B=Math.min(Math.abs(e),Math.abs(e-r)),s=Math.min(Math.abs(t),Math.abs(t-n)));break;case Bt.CLOSEST_CORNER:if(A.shape===rt.CIRCLE)B=s=Math.min(Ne(e,t),Ne(e,t-n),Ne(e-r,t),Ne(e-r,t-n));else if(A.shape===rt.ELLIPSE){var o=Math.min(Math.abs(t),Math.abs(t-n))/Math.min(Math.abs(e),Math.abs(e-r)),i=Ke(r,n,e,t,!0),a=i[0],c=i[1];s=o*(B=Ne(a-e,(c-t)/o))}break;case Bt.FARTHEST_SIDE:A.shape===rt.CIRCLE?B=s=Math.max(Math.abs(e),Math.abs(e-r),Math.abs(t),Math.abs(t-n)):A.shape===rt.ELLIPSE&&(B=Math.max(Math.abs(e),Math.abs(e-r)),s=Math.max(Math.abs(t),Math.abs(t-n)));break;case Bt.FARTHEST_CORNER:if(A.shape===rt.CIRCLE)B=s=Math.max(Ne(e,t),Ne(e,t-n),Ne(e-r,t),Ne(e-r,t-n));else if(A.shape===rt.ELLIPSE){o=Math.max(Math.abs(t),Math.abs(t-n))/Math.max(Math.abs(e),Math.abs(e-r));var Q=Ke(r,n,e,t,!1);a=Q[0],c=Q[1],s=o*(B=Ne(a-e,(c-t)/o))}}return Array.isArray(A.size)&&(B=ae(A.size[0],r),s=2===A.size.length?ae(A.size[1],n):B),[B,s]}(e,f,p,h,H),K=N[0],I=N[1],0<K&&0<K&&(T=D.ctx.createRadialGradient(E+f,F+p,0,E+f,F+p,K),fe(e.stops,2*K).forEach(function(A){return T.addColorStop(A.stop,te(A.color))}),D.path(g),D.ctx.fillStyle=T,K!==I?(m=b.bounds.left+.5*b.bounds.width,R=b.bounds.top+.5*b.bounds.height,v=1/(L=I/K),D.ctx.save(),D.ctx.translate(m,R),D.ctx.transform(1,0,0,L,0,0),D.ctx.translate(-m,-R),D.ctx.fillRect(E,v*(F-R)+R,h,H*v),D.ctx.restore()):D.ctx.fill())):(B=Hs(b,O,[null,null,null]),g=B[0],f=B[1],p=B[2],h=B[3],H=B[4],s=pe(e.angle,h,H),o=s[0],i=s[1],a=s[2],c=s[3],Q=s[4],(w=document.createElement(\"canvas\")).width=h,w.height=H,u=w.getContext(\"2d\"),U=u.createLinearGradient(i,c,a,Q),fe(e.stops,o).forEach(function(A){return U.addColorStop(A.stop,te(A.color))}),u.fillStyle=U,u.fillRect(0,0,h,H),0<h&&0<H&&(l=D.ctx.createPattern(w,\"repeat\"),D.renderRepeat(g,l,f,p))),A.label=6;case 6:return O--,[2]}})},D=this,t=0,r=b.styles.backgroundImage.slice(0).reverse(),A.label=1;case 1:return t<r.length?(n=r[t],[5,e(n)]):[3,4];case 2:A.sent(),A.label=3;case 3:return t++,[3,1];case 4:return[2]}})})},Ds.prototype.renderBorder=function(e,t,r){return a(this,void 0,void 0,function(){return S(this,function(A){return this.path(function(A,e){switch(e){case 0:return Ks(A.topLeftBorderBox,A.topLeftPaddingBox,A.topRightBorderBox,A.topRightPaddingBox);case 1:return Ks(A.topRightBorderBox,A.topRightPaddingBox,A.bottomRightBorderBox,A.bottomRightPaddingBox);case 2:return Ks(A.bottomRightBorderBox,A.bottomRightPaddingBox,A.bottomLeftBorderBox,A.bottomLeftPaddingBox);case 3:default:return Ks(A.bottomLeftBorderBox,A.bottomLeftPaddingBox,A.topLeftBorderBox,A.topLeftPaddingBox)}}(r,t)),this.ctx.fillStyle=te(e),this.ctx.fill(),[2]})})},Ds.prototype.renderNodeBackgroundAndBorders=function(c){return a(this,void 0,void 0,function(){var e,t,r,n,B,s,o,i,a=this;return S(this,function(A){switch(A.label){case 0:return this.applyEffects(c.effects,2),e=c.container.styles,t=!ee(e.backgroundColor)||e.backgroundImage.length,r=[{style:e.borderTopStyle,color:e.borderTopColor},{style:e.borderRightStyle,color:e.borderRightColor},{style:e.borderBottomStyle,color:e.borderBottomColor},{style:e.borderLeftStyle,color:e.borderLeftColor}],n=Ss(Ts(e.backgroundClip,0),c.curves),t||e.boxShadow.length?(this.ctx.save(),this.path(n),this.ctx.clip(),ee(e.backgroundColor)||(this.ctx.fillStyle=te(e.backgroundColor),this.ctx.fill()),[4,this.renderBackgroundImage(c.container)]):[3,2];case 1:A.sent(),this.ctx.restore(),e.boxShadow.slice(0).reverse().forEach(function(A){a.ctx.save();var e=Qs(c.curves),t=A.inset?0:1e4,r=function(A,t,r,n,B){return A.map(function(A,e){switch(e){case 0:return A.add(t,r);case 1:return A.add(t+n,r);case 2:return A.add(t+n,r+B);case 3:return A.add(t,r+B)}return A})}(e,-t+(A.inset?1:-1)*A.spread.number,(A.inset?1:-1)*A.spread.number,A.spread.number*(A.inset?-2:2),A.spread.number*(A.inset?-2:2));A.inset?(a.path(e),a.ctx.clip(),a.mask(r)):(a.mask(e),a.ctx.clip(),a.path(r)),a.ctx.shadowOffsetX=A.offsetX.number+t,a.ctx.shadowOffsetY=A.offsetY.number,a.ctx.shadowColor=te(A.color),a.ctx.shadowBlur=A.blur.number,a.ctx.fillStyle=A.inset?te(A.color):\"rgba(0,0,0,1)\",a.ctx.fill(),a.ctx.restore()}),A.label=2;case 2:s=B=0,o=r,A.label=3;case 3:return s<o.length?(i=o[s]).style===ht.NONE||ee(i.color)?[3,5]:[4,this.renderBorder(i.color,B,c.curves)]:[3,7];case 4:A.sent(),A.label=5;case 5:B++,A.label=6;case 6:return s++,[3,3];case 7:return[2]}})})},Ds.prototype.render=function(t){return a(this,void 0,void 0,function(){var e;return S(this,function(A){switch(A.label){case 0:return this.options.backgroundColor&&(this.ctx.fillStyle=te(this.options.backgroundColor),this.ctx.fillRect(this.options.x-this.options.scrollX,this.options.y-this.options.scrollY,this.options.width,this.options.height)),e=function(A){var e=new gs(A,[]),t=new Cs(e),r=[];return ps(e,t,t,r),Ns(e.container,r),t}(t),[4,this.renderStack(e)];case 1:return A.sent(),this.applyEffects([],2),[2,this.canvas]}})})},Ds);function Ds(A){this._activeEffects=[],this.canvas=A.canvas?A.canvas:document.createElement(\"canvas\"),this.ctx=this.canvas.getContext(\"2d\"),(this.options=A).canvas||(this.canvas.width=Math.floor(A.width*A.scale),this.canvas.height=Math.floor(A.height*A.scale),this.canvas.style.width=A.width+\"px\",this.canvas.style.height=A.height+\"px\"),this.fontMetrics=new Ls(document),this.ctx.scale(this.options.scale,this.options.scale),this.ctx.translate(-A.x+A.scrollX,-A.y+A.scrollY),this.ctx.textBaseline=\"bottom\",this._activeEffects=[],De.getInstance(A.id).debug(\"Canvas renderer initialized (\"+A.width+\"x\"+A.height+\" at \"+A.x+\",\"+A.y+\") with scale \"+A.scale)}var bs=function(A){return A instanceof jn||(A instanceof Yn||A instanceof Gn&&A.type!==zn&&A.type!==Vn)},Ss=function(A,e){switch(A){case Ee.BORDER_BOX:return Qs(e);case Ee.CONTENT_BOX:return function(A){return[A.topLeftContentBox,A.topRightContentBox,A.bottomRightContentBox,A.bottomLeftContentBox]}(e);case Ee.PADDING_BOX:default:return ws(e)}},Ms=function(A){switch(A){case Cr.CENTER:return\"center\";case Cr.RIGHT:return\"right\";case Cr.LEFT:default:return\"left\"}},ys=(_s.prototype.render=function(r){return a(this,void 0,void 0,function(){var e,t;return S(this,function(A){switch(A.label){case 0:return e=Le(Math.max(this.options.windowWidth,this.options.width)*this.options.scale,Math.max(this.options.windowHeight,this.options.height)*this.options.scale,this.options.scrollX*this.options.scale,this.options.scrollY*this.options.scale,r),[4,xs(e)];case 1:return t=A.sent(),this.options.backgroundColor&&(this.ctx.fillStyle=te(this.options.backgroundColor),this.ctx.fillRect(0,0,this.options.width*this.options.scale,this.options.height*this.options.scale)),this.ctx.drawImage(t,-this.options.x*this.options.scale,-this.options.y*this.options.scale),[2,this.canvas]}})})},_s);function _s(A){this.canvas=A.canvas?A.canvas:document.createElement(\"canvas\"),this.ctx=this.canvas.getContext(\"2d\"),this.options=A,this.canvas.width=Math.floor(A.width*A.scale),this.canvas.height=Math.floor(A.height*A.scale),this.canvas.style.width=A.width+\"px\",this.canvas.style.height=A.height+\"px\",this.ctx.scale(this.options.scale,this.options.scale),this.ctx.translate(-A.x+A.scrollX,-A.y+A.scrollY),De.getInstance(A.id).debug(\"EXPERIMENTAL ForeignObject renderer initialized (\"+A.width+\"x\"+A.height+\" at \"+A.x+\",\"+A.y+\") with scale \"+A.scale)}function Ps(A){return we(_A.create(A).parseComponentValue())}var xs=function(r){return new Promise(function(A,e){var t=new Image;t.onload=function(){A(t)},t.onerror=e,t.src=\"data:image/svg+xml;charset=utf-8,\"+encodeURIComponent((new XMLSerializer).serializeToString(r))})};\"undefined\"!=typeof window&&Se.setContext(window);var Vs=function(p,N){return a(void 0,void 0,void 0,function(){var e,t,r,n,B,s,o,i,a,c,Q,w,u,U,l,C,g,E,F,h,H,d,f;return S(this,function(A){switch(A.label){case 0:if(!(e=p.ownerDocument))throw new Error(\"Element is not attached to a Document\");if(!(t=e.defaultView))throw new Error(\"Document is not attached to a Window\");return r=(Math.round(1e3*Math.random())+Date.now()).toString(16),n=EB(p)||function(A){return\"HTML\"===A.tagName}(p)?function(A){var e=A.body,t=A.documentElement;if(!e||!t)throw new Error(\"Unable to get document size\");var r=Math.max(Math.max(e.scrollWidth,t.scrollWidth),Math.max(e.offsetWidth,t.offsetWidth),Math.max(e.clientWidth,t.clientWidth)),n=Math.max(Math.max(e.scrollHeight,t.scrollHeight),Math.max(e.offsetHeight,t.offsetHeight),Math.max(e.clientHeight,t.clientHeight));return new I(0,0,r,n)}(e):T(p),B=n.width,s=n.height,o=n.left,i=n.top,a=K({},{allowTaint:!1,imageTimeout:15e3,proxy:void 0,useCORS:!1},N),c={backgroundColor:\"#ffffff\",cache:N.cache?N.cache:Se.create(r,a),logging:!0,removeContainer:!0,foreignObjectRendering:!1,scale:t.devicePixelRatio||1,windowWidth:t.innerWidth,windowHeight:t.innerHeight,scrollX:t.pageXOffset,scrollY:t.pageYOffset,x:o,y:i,width:Math.ceil(B),height:Math.ceil(s),id:r},Q=K({},c,a,N),w=new I(Q.scrollX,Q.scrollY,Q.windowWidth,Q.windowHeight),De.create({id:r,enabled:Q.logging}),De.getInstance(r).debug(\"Starting document clone\"),u=new PB(p,{id:r,onclone:Q.onclone,ignoreElements:Q.ignoreElements,inlineImages:Q.foreignObjectRendering,copyStyles:Q.foreignObjectRendering}),(U=u.clonedReferenceElement)?[4,u.toIFrame(e,w)]:[2,Promise.reject(\"Unable to find element in cloned iframe\")];case 1:return l=A.sent(),C=e.documentElement?Ps(getComputedStyle(e.documentElement).backgroundColor):He.TRANSPARENT,g=e.body?Ps(getComputedStyle(e.body).backgroundColor):He.TRANSPARENT,E=N.backgroundColor,F=\"string\"==typeof E?Ps(E):null===E?He.TRANSPARENT:4294967295,h=p===e.documentElement?ee(C)?ee(g)?F:g:C:F,H={id:r,cache:Q.cache,canvas:Q.canvas,backgroundColor:h,scale:Q.scale,x:Q.x,y:Q.y,scrollX:Q.scrollX,scrollY:Q.scrollY,width:Q.width,height:Q.height,windowWidth:Q.windowWidth,windowHeight:Q.windowHeight},Q.foreignObjectRendering?(De.getInstance(r).debug(\"Document cloned, using foreign object rendering\"),[4,new ys(H).render(U)]):[3,3];case 2:return d=A.sent(),[3,5];case 3:return De.getInstance(r).debug(\"Document cloned, using computed rendering\"),Se.attachInstance(Q.cache),De.getInstance(r).debug(\"Starting DOM parsing\"),f=iB(U),Se.detachInstance(),h===f.styles.backgroundColor&&(f.styles.backgroundColor=He.TRANSPARENT),De.getInstance(r).debug(\"Starting renderer\"),[4,new Os(H).render(f)];case 4:d=A.sent(),A.label=5;case 5:return!0===Q.removeContainer&&(PB.destroy(l)||De.getInstance(r).error(\"Cannot detach cloned iframe as it is not in the DOM anymore\")),De.getInstance(r).debug(\"Finished rendering\"),De.destroy(r),Se.destroy(r),[2,d]}})})};return function(A,e){return void 0===e&&(e={}),Vs(A,e)}});"
  },
  {
    "path": "images/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"/mstile-150x150.png\"/>\n            <TileColor>#da532c</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "images/site.webmanifest",
    "content": "{\n    \"name\": \"\",\n    \"short_name\": \"\",\n    \"icons\": [\n        {\n            \"src\": \"/android-chrome-192x192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/android-chrome-512x512.png\",\n            \"sizes\": \"512x512\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "manifest.json",
    "content": "{\n  \"name\": \"Quotebacks - quote the web\",\n  \"description\": \"Quote the web and manage your snippets.\",\n  \"version\": \"1.1.3\",\n  \"manifest_version\": 2,\n  \"permissions\": [\n    \"storage\",\n    \"activeTab\",\n    \"unlimitedStorage\",\n    \"contextMenus\"\n  ],\n  \"icons\": {\n    \"16\": \"images/icon-16x16.png\",\n    \"32\": \"images/icon-32x32.png\",\n    \"48\": \"images/icon-48x48.png\",\n    \"128\": \"images/icon-128x128.png\"\n  },\n  \"browser_action\": {\n    \"default_title\": \"Options\"\n  },\n  \"options_page\": \"options.html\",\n  \"background\": {\n    \"scripts\": [\"background.js\"],\n    \"persistent\": false\n  },\n  \"web_accessible_resources\": [\"options.html\",\"styles/styles.css\",\"images/allquotes.png\", \"images/editicon.svg\",\"quoteback-internal.js\",\"readability.js\"],\n  \"commands\": {\n    \"open-popup\": {\n      \"description\": \"Capture a quote from the web\",\n      \"suggested_key\": {\n        \"default\": \"Ctrl+Shift+S\",\n        \"windows\": \"Ctrl+Shift+S\",\n        \"chromeos\": \"Ctrl+Shift+S\"\n      }\n    },\n    \"alt-open\":{\n      \"description\": \"Alternative quote capture for Firefox\",\n      \"suggested_key\": {\n        \"mac\": \"Alt+S\",\n        \"windows\": \"Alt+S\",\n        \"chromeos\": \"Alt+S\"\n      }      \n    }\n  }\n}\n\n\n"
  },
  {
    "path": "newcontent.js",
    "content": "var debug = localStorage.getItem(\"quotebackdebug\");\nif(debug){console.log(\"Debug set to true\")};\n//var debug = false; // enable logging, prevent blur, make countdown 500\n\nchrome.runtime.onMessage.addListener(\n  function(request, sender, sendResponse) {\n    \n    // tell background.js that we're loaded and alive\n    if (request.message == \"ping\"){\n      sendResponse({alive: \"loaded\"});\n      return Promise.resolve({alive: \"loaded\"});\n    }\n\n    var selectionChecker = (window.getSelection().toString());\n    // run the popup on message from background.js if there is no selection text\n    \n    if (request.message == \"copyquote\" && selectionChecker == \"\"){\n      return null;\n    } else if (request.message == \"copyquote\" && selectionChecker != \"\"){\n      \n      closePopup();\n      \n      var object = {};\n      var highlighter;\n\n      rangy.init();\n    \n      var text = getSelectionText(); \n    \n      var links = document.getElementsByTagName(\"link\");\n      if (getCanonical()){\n          var page = getCanonical();    \n      }else{\n          var page = document.location.href;      \n      };\n\n      // NEW! Readability function parses the text and pushes to the quote on line 87.\n      //var documentClone = document.cloneNode(true); - this doesn't work\n      var documentClone = document.implementation.createHTMLDocument('');\n      var pagehtml = document.body.innerHTML;\n      documentClone.body.innerHTML = pagehtml;\n      var articleText = new Readability(documentClone).parse();\n      //console.log(articleText.textContent);\n      \n\n      chrome.storage.local.get([page], function(result) {\n        var page_object = {};        \n        page_object[\"last_update\"] = getDate();\n        page_object[\"url\"] = page;\n    \n        if(result[page] == null){\n            if(getMeta(\"twitter:title\")){\n            page_object[\"title\"] = getMeta(\"twitter:title\");\n            } else if(getMeta(\"og:title\")){\n            page_object[\"title\"] = getMeta(\"og:title\");\n            }else{\n            page_object[\"title\"] = document.title;\n            }\n            if(getMeta(\"author\")){\n            page_object[\"author\"] = getMeta(\"author\");  \n            }else{\n            page_object[\"author\"] = getMeta(\"twitter:site\");\n            }\n          }\n        else{\n          page_object[\"title\"] = result[page][\"title\"];\n          page_object[\"author\"] = result[page][\"author\"];\n\n        }\n    \n        var quotes = [];\n        var quote = {};\n    \n        quote[\"text\"] = text;\n        quote[\"date\"] = getDate();\n        quote[\"articleText\"] = articleText;\n    \n        quotes.push(quote);\n    \n        if(result[page] == null){\n        var combined = quotes;\n        }\n        else{\n        var combined = quotes.concat(result[page][\"quotes\"])\n        }\n    \n        page_object[\"quotes\"] = combined;\n        page_object[\"favicon\"] = favicon=`https://s2.googleusercontent.com/s2/favicons?domain_url=${page_object[\"url\"]}&sz=64`\n    \n        object[page] = page_object; \n    \n    \n        chrome.storage.local.set(object, function() {            \n          console.log(object[page][\"quotes\"][0]);\n        });\n    \n\n        // Web Component Stuff Start Here //\n        var component = `\n        <quoteback-popup text=\"${encodeURIComponent(text)}\" author=\"${page_object[\"author\"]}\" title=\"${encodeURIComponent(page_object[\"title\"])}\">\n        <quoteback-component slot=\"quoteback-component\" url=\"${page_object[\"url\"]}\" text=\"${encodeURIComponent(text)}\" author=\"${page_object[\"author\"]}\" title=\"${encodeURIComponent(page_object[\"title\"])}\" favicon=\"${page_object[\"favicon\"]}\" editable=\"true\">\n        </quoteback-component> \n        </quoteback-popup>    \n        `;   \n\n  \n        var popup = document.createElement('div');\n        document.documentElement.appendChild(popup);\n        popup.innerHTML = component;\n        popup.style.cssText = \"background-color:white; width:670px; height:auto; position:fixed; border:none; top:0px; right:0px; z-index:2147483647;\"\n    \n        var template = document.createElement('template');\n        template.innerHTML=`\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"${chrome.runtime.getURL(\"styles/styles.css\")}\">\n        <div class=\"citation-capture\" id=\"citation-capture\">\n    \n        <slot name=\"quoteback-component\"></slot>\n    \n        <div class=\"citation-tools\">\n        <div class=\"comment-field\">\n        <input class=\"citation-input\" placeholder=\"Add comment\"></input>    \n          <div class=\"save-indicator\">Saved</div>\n        </div>\n        <div class=\"tools-buttons\">\n          <button id=\"getlink\" class=\"control-button\"><> Embed</button>\n          <button id=\"getMarkdown\" class=\"control-button\">Copy Markdown</button>\n          <a target=\"_blank\" rel=\"noopener\" id=\"quoteslink\" class=\"control-button\" href=\"${chrome.runtime.getURL(\"options.html\")}#${page}\">All Quotes<img src=\"${chrome.runtime.getURL(\"images/allquotes.png\")}\"></a>\n          <button id=\"close-button\" class=\"control-button\">Close</button>\n        </div>\n        </div>\n    \n        </div>\n        `;\n    \n        class QuotebackPopup extends HTMLElement {\n          constructor(){\n           \n            super();\n            this.attachShadow({mode: 'open'});\n            this.shadowRoot.appendChild(template.content.cloneNode(true));\n        \n            this.author = this.getAttribute('author');\n            this.title = this.getAttribute('title'); \n            this.url = this.getAttribute('url')\n            this.favicon = this.getAttribute('favicon');\n          };\n        }\n\n        if (customElements.get('quoteback-popup')){\n        null;\n        }else{\n        window.customElements.define('quoteback-popup', QuotebackPopup)  \n        }\n\n        embedquoteback();\n\n        //\n        //\n        // COPY EMBED //\n        var p = document.querySelector(\"quoteback-popup\").shadowRoot;\n        p.querySelector(\"#getlink\").addEventListener(\"click\", function(event) {\n          var embed = `<blockquote class=\"quoteback\" darkmode=\"\" data-title=\"${encodeURIComponent(page_object[\"title\"])}\" data-author=\"${page_object[\"author\"]}\" cite=\"${page_object[\"url\"]}\">\n                      ${text}\n                      <footer>${page_object[\"author\"]} <cite><a href=\"${page_object[\"url\"]}\">${page_object[\"url\"]}</a></cite></footer>\n                      </blockquote>\n                      <script note=\"\" src=\"https://cdn.jsdelivr.net/gh/Blogger-Peer-Review/quotebacks@1/quoteback.js\"></script>`;\n      \n          copyToClipboard(embed);\n          p.querySelector(\"#getlink\").innerHTML = \"Copied!\";\n          setTimeout(function() {\n              p.querySelector(\"#getlink\").innerHTML = \"<> Embed\";\n          }, 1000);\n        });\n\n        // COPY MARKDOWN //\n        var p = document.querySelector(\"quoteback-popup\").shadowRoot;\n        p.querySelector(\"#getMarkdown\").addEventListener(\"click\", function(event) {\n\n          var htmlembed = `<blockquote>${text}</blockquote>\n          Source: <a href=\"${page_object[\"url\"]}\">${page_object[\"title\"]}</a> by ${page_object[\"author\"]}`;\n      \n          const turndownService = new TurndownService();\n\n          const markdown = turndownService.turndown(htmlembed);\n    \n          copyToClipboard(markdown);\n          \n          p.querySelector(\"#getMarkdown\").innerHTML = \"Copied!\";\n          setTimeout(function() {\n              p.querySelector(\"#getMarkdown\").innerHTML = \"Copy Markdown\";\n          }, 1000);\n        });        \n    \n    \n        appendIcon();\n        function appendIcon(){\n          var popup = document.querySelector(\"quoteback-popup\");\n          var quote = popup.querySelector(\"quoteback-component\").shadowRoot;\n          quote.querySelector(\".quoteback-title\").classList.add(\"editable\");\n          quote.querySelector(\".quoteback-author\").classList.add(\"editable\");\n        };\n\n        // SAVE & CLOSE //\n        p.querySelector(\"#close-button\").addEventListener(\"click\", function(event) {\n          closePopup()           \n          clearInterval(t); // stop timer\n        });\n    \n        // Close popup on \"all quotes\" button\n        p.querySelector(\"#quoteslink\").addEventListener(\"click\", function(event) {\n          closePopup()           \n          clearInterval(t); // stop timer\n        });      \n    \n        // Close popup on tab focus out\n        if(!debug){window.onblur = onBlur};\n        function onBlur() {\n         closePopup()           \n         clearInterval(t); // stop timer\n        };\n        \n        // rangy highlight selection code\n        // remember to uncomment background.js files too\n        /*\n        highlighter = rangy.createHighlighter();\n\n        highlighter.addClassApplier(\n          rangy.createClassApplier(\"quotebackhighlight\", {\n            ignoreWhiteSpace: true,\n            tagNames: [\"span\", \"a\"]\n          })\n        );\n\n        highlighter.highlightSelection(\"quotebackhighlight\");\n\n        */\n\n        var time = 0;\n        var textfocus = false;\n        var ishover = false;\n        var isPaused = false;\n        txtAreaListenFocus();\n        txtAreaListenBlur();\n\n        p.addEventListener(\"mouseover\", function( event ) {   \n            ishover = true;\n        });\n    \n        p.addEventListener(\"mouseout\", function( event ) {   \n            ishover = false;\n        });\n    \n        AutoSave.start(object);\n    \n        var t = window.setInterval(function() {\n            // timeout to remove popups\n            if(!ishover && !textfocus) {\n            time++;\n            var timer = 5;\n            if(debug){var timer = 500};\n            if(time > timer){\n                if (popup){\n                popup.parentNode.removeChild(popup);\n                };\n    \n                AutoSave.stop();              \n                clearInterval(t); // stop timer\n            };\n            if(debug){console.log(time + \"is hover: \"+ishover + \"is textfocus:\"+textfocus);};\n            }\n    \n        }, 1000);\n    \n        function txtAreaListenFocus(){\n            var popup = document.querySelector(\"quoteback-popup\");\n            var quote = popup.querySelector(\"quoteback-component\").shadowRoot;   \n            var authorArea = quote.querySelector('.quoteback-author'); // changed\n            var titleArea = quote.querySelector('.quoteback-title'); // changed\n            \n            authorArea.addEventListener('keydown', function(event){\n              if (event.keyCode === 13) {\n                event.preventDefault();\n                return null;\n                authorArea.blur()\n              };\n            });\n\n            titleArea.addEventListener('keydown', function(event){\n              if (event.keyCode === 13) {\n                event.preventDefault();\n                return null;\n                titleArea.blur()\n              };\n            });\n\n            authorArea.addEventListener('focus', function(event) {\n              textfocus = true;\n            }.bind(this));\n            titleArea.addEventListener('focus', function(event) {\n              textfocus = true;\n            }.bind(this));                               \n        };\n    \n        function txtAreaListenBlur(){\n          if(debug){console.log(\"txtarealistenblur starting\")};\n          var popup = document.querySelector(\"quoteback-popup\");\n          var quote = popup.querySelector(\"quoteback-component\").shadowRoot;   \n          var authorArea = quote.querySelector('.quoteback-author'); // changed\n          var titleArea = quote.querySelector('.quoteback-title'); // changed\n          \n          authorArea.addEventListener('blur', function(event) {\n            if(debug){console.log(\"author area blurred: setting textfocus = false\")};\n            textfocus = false;\n          }.bind(this));\n          titleArea.addEventListener('blur', function(event) {\n            if(debug){console.log(\"title area blurred: setting textfocus = false\")};\n          textfocus = false;\n          }.bind(this));\n          \n        };                          \n    \n      });\n\n    }\n\n  });\n      \n    \n    function getSelectionText() {\n\n      var text = \"\";\n      if (window.getSelection) {\n        //get rangehtml using rangy, strip un-allowed tags (e.g. script tags, button tags)\n        // regex here: https://stackoverflow.com/questions/44009089/javascript-replace-regex-all-html-tags-except-p-a-and-img\n        // NOTE: this removes tags but not contents. e.g. \"<script>some script</script>\"\" will return \"some script\"\n        var selectionhtml =  rangy.getSelection().toHtml();\n        var cleaned = selectionhtml.replace(/(<\\/?(?:a|b|p|img|h1|h2|h3|h4|h5|em|strong|ul|ol|li|blockquote)[^>]*>)|<[^>]+>/ig, '$1');\n        if(debug){console.log(\"cleaned selection: \"+cleaned)};\n\n        //create a document fragment to make manipulations like absolute links\n        var htmlfragment = document.createRange().createContextualFragment(cleaned);\n        if(debug){console.log(\"htmlfragment = \"+htmlfragment.innerHTML)};\n\n        // remove inline styles from elements\n        var descendents = htmlfragment.querySelectorAll(\"*\");\n        for (var i = 0; i < descendents.length; i++) {\n          e = descendents[i];\n          e.removeAttribute(\"style\");\n        }\n\n        //make all link & image references absolute not relative\n        var links = htmlfragment.querySelectorAll(\"a\");\n        links.forEach(e => {\n          e.href = convertAbsolute(e.href);\n          e.setAttribute(\"target\",\"_blank\"); //ensure links open inside quoteback in new window\n          e.setAttribute(\"rel\",\"noopener\");\n        });\n  \n        var images = htmlfragment.querySelectorAll(\"img\");\n        if(debug){console.log(images)};\n        images.forEach(e => {e.src = convertAbsolute(e.src)});\n  \n        var div = document.createElement('div');\n        div.appendChild( htmlfragment.cloneNode(true) );\n        if(debug){console.log(\"getselectiontext div: \"+div.innerHTML)};\n        removeEmpty(div); // remove empty html elements - rangy is adding them\n        var html = div.innerHTML;\n        if(debug){console.log(\"getselectiontext html: \"+html)};\n        return(html);\n  \n      } else if (document.selection && document.selection.type != \"Control\") { // think this is for IE?\n        text = document.selection.createRange().text;\n      }\n    };\n\n    function removeEmpty(elem){\n      var children = elem.children;\n    \n      // Remove the emptys elements\n      for (var i = 0; i < children.length; i++) {\n          if( children[i].textContent.trim() === '' && children[i].innerHTML.trim().length === 0)\n              children[i].parentNode.removeChild(children[i]);\n      }\n\n      return elem;\n    }\n\n   \n        \n    function convertAbsolute(url){\n      if(debug){console.log(\"About to convert: \"+url+\" to absolute\")};\n      let absolute = new URL(url, document.baseURI).href;\n      if(debug){console.log(\"Absolute: \"+absolute)};\n      return absolute;\n    }    \n    \n    function getMeta(metaName) {\n      const metas = document.getElementsByTagName('meta');\n  \n      for (let i = 0; i < metas.length; i++) {\n        if (metas[i].getAttribute('name') === metaName) {\n          return metas[i].getAttribute('content');\n        } else if(metas[i].getAttribute('property') === metaName){ //for facebook meta property tags\n          return metas[i].getAttribute('content');\n        }\n      }\n    \n      return '';\n    };\n    \n    function getCanonical() {\n      var canonical = \"\";\n      var links = document.getElementsByTagName(\"link\");\n      for (var i = 0; i < links.length; i ++) {\n        if (links[i].getAttribute(\"rel\") === \"canonical\") {\n          if(links[i].getAttribute(\"href\").includes(\"http\")){  // ignore relative canonical links\n            canonical = links[i].getAttribute(\"href\")\n          }\n        }\n      }\n    return canonical;\n    };  \n    \n    function getDate(){\n      var today = Number(new Date());\n      return today;\n    };\n    \n    \n    \n    var AutoSave = (function(){\n      var timer = null;\n        function save(object){\n          var popup = document.querySelector(\"quoteback-popup\");                 \n          var quote = popup.querySelector(\"quoteback-component\").shadowRoot;\n          var commentbox = popup.shadowRoot.querySelector(\".citation-input\");\n          var title = quote.querySelector('.quoteback-title');\n          var author = quote.querySelector('.quoteback-author'); \n      \n          var page = document.location.href;\n      \n          object[page][\"quotes\"][0][\"comment\"] = commentbox.value;\n          object[page][\"title\"] = title.textContent;\n          object[page][\"author\"] = author.textContent;\n      \n          chrome.storage.local.set(object, function() { \n              if(debug){console.log(\"autosaved\")};\n              if(popup.shadowRoot.querySelector(\".save-indicator\").innerText == \"Saving...\"){\n                popup.shadowRoot.querySelector(\".save-indicator\").innerHTML = \"Saved\"; // changed\n            };\n          });          \n      };\n      return {\n        start: function(object){\n        var popup = document.querySelector(\"quoteback-popup\").shadowRoot;                 \n        popup.addEventListener(\"keydown\", function( event ) {\n          popup.querySelector(\".save-indicator\").innerText = \"Saving...\"; // changed\n        });            \n\n        if (timer != null){\n          clearInterval(timer);\n          timer = null;\n        }\n        timer = setInterval(function(){\n          save(object)\n        }, 500);\n        },\n        stop: function(){\n          if (timer){ \n              clearInterval(timer);\n              timer = null;\n          }\n        }\n      }\n    }());\n\nfunction copyToClipboard(str){   \n  const el = document.createElement('textarea');\n  el.value = str;\n  document.body.appendChild(el);\n  el.select();\n  document.execCommand('copy');\n  document.body.removeChild(el);\n};\n\nfunction closePopup(){\n  var paras = document.querySelector(\"quoteback-popup\");\n  if (paras){\n      paras.parentNode.removeChild(paras);\n  };         \n  AutoSave.stop();              \n}\n\n\n\n"
  },
  {
    "path": "options.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <script src=\"jquery-3.5.1.min.js\" type=\"text/javascript\"></script>\n  <script src=\"html2screenshot.js\" type=\"text/javascript\"></script>\n  <script src=\"turndown.js\"></script>\n  <link rel=\"stylesheet\" href=\"styles/styles.css\" type=\"text/css\">\n  <script src=\"quotestyle.js\"></script>\n  <script src=\"quoteback-internal.js\"></script>\n  <script src=\"options.js\"></script>\n  <title>QuoteBack Library</title>\n\n</head>\n\n<body>\n\n<div id=\"nav\">\n  <div id=\"pagetitle\">QuoteBack Library</div>\n  <div id=\"searchbar\">\n      <div id=\"fastSearch\">\n          <input id=\"searchInput\" tabindex=\"0\" placeholder=\"Search (&#8984;+K)\" autocomplete=\"off\">\n          <ul id=\"searchResults\">\n          </ul>\n      </div>\n  </div>\n   <div id=\"global-options-button\">\n    <svg id=\"options-svg\" fill=\"#B1B2B4\" ;xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\"><path d=\"M24 13.616v-3.232c-1.651-.587-2.694-.752-3.219-2.019v-.001c-.527-1.271.1-2.134.847-3.707l-2.285-2.285c-1.561.742-2.433 1.375-3.707.847h-.001c-1.269-.526-1.435-1.576-2.019-3.219h-3.232c-.582 1.635-.749 2.692-2.019 3.219h-.001c-1.271.528-2.132-.098-3.707-.847l-2.285 2.285c.745 1.568 1.375 2.434.847 3.707-.527 1.271-1.584 1.438-3.219 2.02v3.232c1.632.58 2.692.749 3.219 2.019.53 1.282-.114 2.166-.847 3.707l2.285 2.286c1.562-.743 2.434-1.375 3.707-.847h.001c1.27.526 1.436 1.579 2.019 3.219h3.232c.582-1.636.75-2.69 2.027-3.222h.001c1.262-.524 2.12.101 3.698.851l2.285-2.286c-.744-1.563-1.375-2.433-.848-3.706.527-1.271 1.588-1.44 3.221-2.021zm-12 2.384c-2.209 0-4-1.791-4-4s1.791-4 4-4 4 1.791 4 4-1.791 4-4 4z\"/></svg>\n    <div class=\"dropdown\" id=\"global-options\">\n      <button id=\"clearStorage\">Clear Storage</button>\n      <button id=\"exportQuotes\">Export data</button>\n      <button id=\"importQuotes\" type=\"file\">Import data</button>\n      <input id='fileid' type='file' hidden/>\n    </div>\n  </div>  \n</div>\n\n<div id=\"appcontainer\">\n  <div id=\"leftnav\">\n    <div id=\"articleSort\">Sorted by Most Recent</div>\n    <div id=\"article-scrollContainer\"></div>\n    <span id=\"capture-helper\">&#8984;+Shift+S to save a quote on any site</span>\n  </div>\n  <div id=\"rightpanel\">\n    <div id=\"titlebar\">\n      <div id=\"titlebar-innercontainer\">\n        <div id=\"titlebar-author\" placeholder=\"No Author Found\" contenteditable=\"true\">Author</div>\n        <div id=\"titlebar-title\" placeholder=\"No Title Found\" contenteditable=\"true\">Title</div>        \n      </div>\n      <button id=\"article-view\">click me for article view</button>\n      <div id=\"titlebar-options\">\n        <div class=\"dropdown\" id=\"titlebar-dropdown\">\n            <button id=\"titlebar-delete\">Delete Article</button>  \n        </div>        \n      </div>\n    </div>\n    <div id=\"panel-scrollContainer\"></div>\n  </div>  \n</div>\n\n\n<template id=\"articleItem\">\n  <div class=\"article\">\n    <img class=\"mini-favicon\"/>\n    <div class=\"title\"></div>\n    <div class=\"url\"></div>\n  </div>\n</template>\n\n\n<template id=\"quote\">\n  <quoteback-component url=\"\" text=\"\" author=\"\" title=\"\" favicon=\"\"> \n  </quoteback-component>   \n</template>\n\n<template id=\"searchitem\">\n    <div class=\"searchitem\">\n    <div class=\"title\"></div>\n    </div>\n</template>\n\n<script src=\"fuse.js\"></script> <!-- download and copy over fuse.js file from fusejs.io -->\n<script src=\"fastsearch.js\"></script>\n<script src=\"jquery-resizable.js\"></script>\n<script src=\"readability.js\"></script>\n\n\n</body>\n\n</html>"
  },
  {
    "path": "options.js",
    "content": "var debug = localStorage.getItem(\"quotebackdebug\");\nif(debug){console.log(\"Debug set to true\")};\n\nvar alldata;\nvar allKeys;\nvar alljson = [];\nvar sorted = [];\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n  chrome.storage.local.get(null, function(items) {\n    allKeys = Object.keys(items);\n    \n\n    //only run all the code if there are items in the DB\n    if(allKeys.length != 0){\n      \n    alldata = items;\n\n    if(debug){console.log(alldata)};\n    embedquoteback();\n\n    //create sorted array by last_updated \n    for (var item in items) {\n      //for quotes with no last_mod\n      //i.e. beta users\n      if(!items[item].last_update){\n        items[item].last_update = \"1546347661\"\n      }\n      sorted.push([item, items[item].last_update]);\n    }\n    sorted.sort(function(a,b){\n      return a[1] - b[1]\n    })    \n    sorted.reverse();\n\n    for( var i in sorted){\n\n      alljson.push(items[sorted[i][0]]);\n\n      const article_fragment = document.getElementById('articleItem');\n      const article_instance = document.importNode(article_fragment.content, true);\n      // Add relevant content to the template\n\n      var domain = extractHostname(items[sorted[i][0]].url);\n      article_instance.querySelector('.title').innerHTML = items[sorted[i][0]].title;\n      article_instance.querySelector('.mini-favicon').src = \"https://s2.googleusercontent.com/s2/favicons?domain_url=\"+domain+\"&size=64\";\n      article_instance.querySelector('.url').innerHTML = domain;\n      article_instance.querySelector('.article').setAttribute(\"data-id\",items[sorted[i][0]].url);\n\n      \n\n      // Append the instance ot the DOM\n      document.getElementById('article-scrollContainer').appendChild(article_instance);\n    }\n\n    alljson = JSON.stringify(alljson);\n    alljson = JSON.parse(alljson);\n\n    var pagehash = $(location).attr('hash').replace(\"#\",\"\");\n\n    if($(location).attr('hash')){\n      if(allKeys.includes(pagehash)){ // error handling for some mishandled hash value\n        displayquotes(pagehash)\n    }else{\n      displayquotes(sorted[0][0]);\n    };\n    }else{\n      displayquotes(sorted[0][0]);\n    }\n\n    window.addEventListener('hashchange', function() {\n      var hashval = $(location).attr('hash').replace(\"#\",\"\");\n      if(allKeys.includes(hashval)){ // check hash is a valid entry in data\n        displayquotes(hashval)\n      };\n    }, false);\n      \n    $( \".article\" ).click(function() {\n      var url = $(this).attr('data-id');\n      displayquotes(url);\n\n    });\n    \n    $('#rightpanel').on('click',\"#copy\", function() {\n\n      var quote = $(this).closest(\".quote-container\").find(\"#quoteback-component\");\n      var text = decodeURIComponent(quote.attr(\"text\"));\n\n      var htmlfragment = document.createRange().createContextualFragment(text);\n      var cleaned = htmlfragment.textContent;\n\n      copyToClipboard(cleaned);\n      var el = $(this);\n      el.html(\"Copied!\");\n      setTimeout(function() {\n        el.html(\"Copy Text\");\n      }, 1000);\n    });\n\n\n    $('#rightpanel').on('click',\"#article-view\", function(){\n      var url = $(\".selected\").attr(\"data-id\");\n      displayArticle(url);\n    });\n\n    $('#rightpanel').on('click',\"#embedLink\", function() {\n\n      var quote = $(this).closest(\".quote-container\").find(\"#quoteback-component\");\n\n      var title = $(\".selected\").find(\".title\").text();\n      var url = $(\".selected\").attr(\"data-id\");\n      var text = quote.attr(\"text\");\n\n      // if we want to use text instead of html inside the blockquote we should use this:\n      // https://ourcodeworld.com/articles/read/376/how-to-strip-html-from-a-string-extract-only-text-content-in-javascript\n      // however we'd then need to move to storing the html string in an attribute in the web component\n      //var stripedHtml = decodeURIComponent(text).replace(/<[^>]+>/g, '');\n      \n      \n      var author = quote.attr(\"author\");\n\n      var embed = `\n<blockquote class=\"quoteback\" darkmode=\"\" data-title=\"${encodeURIComponent(title)}\" data-author=\"${author}\" cite=\"${url}\">\n${decodeURIComponent(text)}\n<footer>${author}<cite> <a href=\"${url}\">${url}</a></cite></footer>\n</blockquote><script note=\"\" src=\"https://cdn.jsdelivr.net/gh/Blogger-Peer-Review/quotebacks@1/quoteback.js\"></script>`;\n\n        copyToClipboard(embed);\n        let el = $(this);\n        el.html(\"Copied!\");\n        setTimeout(function() {\n          el.html(\"<> Embed\");\n        }, 1000);\n      });\n\n    // use html2screenshot to generate canvas, copy img to clipboard\n    $('#rightpanel').on('click',\"#copyimg\", function() {\n      var el = $(this);\n\n      quote = el.closest(\".quoteblock\");\n      quote = quote[0].querySelector(\"quoteback-component\");\n      if(debug){console.log(quote)};\n\n      var newDiv = document.createElement(\"div\"); \n      newDiv.id = \"copyimage\";\n      newDiv.innerHTML = quote.shadowRoot.innerHTML;\n      \n      //position div offscreen to prevent flicker\n      document.getElementById(\"panel-scrollContainer\").style.height = \"3000px\";\n      newDiv.style.bottom = \"-999px\";\n      newDiv.style.position = \"absolute\";\n      newDiv.style.width = \"500px\";\n      newDiv.style.padding = \"7px 7px 7px 7px\";\n      \n      var content = newDiv.querySelector(\".quoteback-content\");\n      newDiv.querySelector(\".quoteback-container\").setAttribute(\"style\", \"margin: 0px 0px 0px 0px\");\n      if(navigator.userAgent.indexOf(\"Firefox\") != -1 ){ \n        console.log(\"firefox only\");\n        newDiv.querySelector(\".quoteback-container\").setAttribute(\"style\", \"margin: 0px 0px 0px 0px; font-family: 'Inter';\");\n        newDiv.querySelector(\".quoteback-content\").setAttribute(\"style\", \"font-family:'Inter' !important; font-weight:400;\");\n      };\n      var ems = content.querySelectorAll(\"div.quoteback-content > em\");\n      if(content.querySelector(\"em\")){\n        content.querySelector(\"em\").setAttribute(\"style\", \"font-family:'Inter' !important; font-style: italic;\");\n      }\n      \n\n      ems.forEach(function(emItem) {\n        emItem.setAttribute(\"style\", \"font-family:'Inter' !important; font-style: italic;\");\n      });      \n\n      document.getElementById(\"panel-scrollContainer\").appendChild(newDiv);\n\n\n      //stop the \"go to text\" element rendering in the image\n      document.getElementById(\"copyimage\").querySelector(\".quoteback-backlink\").setAttribute(\"data-html2canvas-ignore\", \"true\");\n\n      // use faviconkit for screenshots for CORS\n      var url = document.getElementById(\"copyimage\").querySelector(\".quoteback-arrow\").href;\n      var hostname = (new URL(url)).hostname;\n      document.getElementById(\"copyimage\").querySelector(\".mini-favicon\").src = \"https://api.faviconkit.com/\"+hostname;\n\n      var title = document.getElementById(\"copyimage\").querySelector(\".quoteback-title\");\n      if(title.innerHTML.length > 65){ // html2canvas doesn't support text-overflow:ellipses\n        title.innerHTML = title.innerHTML.substring(0,60);\n        title.innerHTML = title.innerHTML + \"...\";\n      }\n    \n\n      html2canvas(document.getElementById(\"copyimage\"), {\n        useCORS: true,\n        onclone: function(document) {\n        }\n      }).then((canvas) => {\n        canvas.toBlob(function(blob) {\n          saveAs(canvas.toDataURL(), url+'.png');\n          var item = new ClipboardItem({ \"image/png\": blob });\n          navigator.clipboard.write([item]).then(\n            function() {\n              console.log(\"Copied to clipboard successfully!\");\n              \n              var element = document.getElementById(\"copyimage\");\n              if(debug){}else{\n                element.parentNode.removeChild(element);\n              }\n\n              document.getElementById(\"panel-scrollContainer\").style.height = \"initial\";\n\n              el.html(\"Copied!\");\n              setTimeout(function() {\n                el.html(\"Copy Image\");\n              }, 1000);\n            },\n            function(error) {\n              console.error(\"unable to write to clipboard. Error:\");\n              console.log(error);\n            }\n          );\n        });\n      }).catch(function (error) {\n          console.log('oops, something went wrong!', error);\n      });\n    \n      \n    \n\n    });\n  \n\n// used in html2canvas\nfunction saveAs(uri, filename) {\n\n      var link = document.createElement('a');\n  \n      if (typeof link.download === 'string') {\n  \n          link.href = uri;\n          link.download = filename;\n  \n          //Firefox requires the link to be in the body\n          document.body.appendChild(link);\n  \n          //simulate click\n          link.click();\n  \n          //remove the link when done\n          document.body.removeChild(link);\n  \n      } else {\n  \n          window.open(uri);\n  \n      }\n  }\n\n    // convert quote to markdown using turndown.js\n    $('#rightpanel').on('click',\"#copymd\", function() {\n      var el = $(this);\n\n      quote = el.closest(\".quoteblock\");\n      quote = quote[0].querySelector(\"quoteback-component\");\n\n      var html = `<blockquote>${quote.text}</blockquote>\n      Source: <a href=\"${quote.url}\">${quote.title}</a> by ${quote.author}`;\n\n      const turndownService = new TurndownService();\n\n      const markdown = turndownService.turndown(html);\n\n      copyToClipboard(markdown);\n\n      el.html(\"Copied!\");\n      setTimeout(function() {\n        el.html(\"Copy Markdown\");\n      }, 1000);\n\n    });\n\n    // Delete QUOTE\n    $('#rightpanel').on('click',\"#delete\", function() {\n      \n      var r = confirm(\"Are you sure you want to delete this quote?\");\n      if (r == true) {\n        \n        var url = $(\".selected\").attr(\"data-id\");\n        var quoteblock = $(this).closest('.quoteblock');\n        var index = $(\".quoteblock\").index(quoteblock);\n        var quotes = alldata[url][\"quotes\"];\n        var removed = quotes.splice(index,1);\n        alldata[url][\"quotes\"] = quotes;\n        if(quotes.length == 0){ //if no quotes left then delete whole item from alldata\n          chrome.storage.local.remove(url, function (){\n            console.log(\"deleted \"+url);\n            location.reload();\n          });\n        }else{\n        chrome.storage.local.set(alldata, function(){ \n          console.log(\"saving data\");\n          displayquotes(url);\n        }); \n      }\n      \n      } else {\n      } \n    });    \n\n    // DELETE ARTICLE\n    $('#titlebar').on('click',\"#titlebar-delete\", function(){\n      var r = confirm(\"Are you sure you want to delete this entire article?\")\n      if (r == true) {\n        var url = $(\".selected\").attr(\"data-id\");\n        chrome.storage.local.remove(url, function(){ // delete entire item from alldata\n          location.reload();\n          \n        });\n      }else{\n      }\n    });\n\n\n\n\n\n\n    // on title/author -> trigger autosave\n    $( \"#rightpanel\" ).on(\"focus\" , \"#titlebar-author\", function() {\n      var el = $(this);\n      var url = $(\".selected\").attr(\"data-id\");\n      var object = alldata[url];\n      AutoSaveTitle.start(object, el ,url);\n      $(\"#titlebar-author\").keypress(function(e){ // prevent return in title\n        if(e.which == 13){\n          $(\"#titlebar-author\").blur();\n        }\n        return e.which != 13;\n        \n       });\n    });\n\n    $( \"#rightpanel\" ).on(\"focusout\" , \"#titlebar-author\", function() {\n      AutoSaveTitle.stop();\n    });\n\n    $( \"#rightpanel\" ).on(\"focus\" , \"#titlebar-title\", function() {\n      var el = $(this);\n      var url = $(\".selected\").attr(\"data-id\");\n      var object = alldata[url];\n      AutoSaveTitle.start(object, el ,url);\n      $(\"#titlebar-title\").keypress(function(e){ // prevent return in title\n        if(e.which == 13){\n          $(\"#titlebar-title\").blur();\n        }\n        return e.which != 13;\n        \n       });\n    });\n\n    $( \"#rightpanel\" ).on(\"focusout\" , \"#titlebar-title\", function() {\n      AutoSaveTitle.stop();\n    });\n    \n    \n    \n    // on focus comment box -> trigger autosave\n    $( \"#rightpanel\" ).on(\"focus\" , \".comment\", function() {\n      \n      var url = $(\".selected\").attr(\"data-id\");\n      var object = alldata[url];\n      if($(this).text() == \"Add comment\"){\n        $(this).text(\"\");\n      };\n      $(this).css(\"color\",\"#464A4D\")\n      var el = $(this);\n      AutoSave.start(object, el , $(this).index(\".comment\"),url);\n    });\n\n    // on focusout comment box -> stop autosave\n    $( \"#rightpanel\" ).on(\"focusout\" , \".comment\", function() {\n      AutoSave.stop();\n    });    \n  };\n  });\n});\n\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n\n// Import function\ndocument.getElementById(\"importQuotes\").onclick = function(){\n  document.getElementById('fileid').click();\n};\n\ndocument.getElementById('fileid').onchange = function(evt) {\n  try {\n      let files = evt.target.files;\n      if (!files.length) {\n          alert('No file selected!');\n          return;\n      }\n      let file = files[0];\n      let reader = new FileReader();\n      const self = this;\n      var importobject = {};\n      reader.onload = (event) => {\n          var importitems = JSON.parse(event.target.result);\n          //console.log('FILE CONTENT', event.target.result);\n\n          chrome.storage.local.set(importitems, function() {            \n            console.log(\"import done!\");\n            location.reload();\n    \n          });\n\n          //console.log(importitems);\n      };\n      reader.readAsText(file);\n  } catch (err) {\n      console.error(err);\n  }\n}\n      \n// CLEAR STORAGE\ndocument.getElementById(\"clearStorage\").onclick = function(){\n  var r = confirm(\"Are you sure you want to delete all citations?!\");\n  if (r == true) {\n    chrome.storage.local.clear();\n    location.reload();\n  } else {\n  } \n};\n\n// Export function\ndocument.getElementById(\"exportQuotes\").onclick = function(){\n  var dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(alldata, null, 2));\n  var d = new Date();\n  var curr_date = d.getDate();\n  var curr_month = d.getMonth() + 1; //Months are zero based\n  var curr_year = d.getFullYear();\n  var a = document.createElement(\"a\");\n  a.setAttribute(\"href\",     dataStr     );\n  a.setAttribute(\"download\", curr_date + \"-\" + curr_month + \"-\" + curr_year +\"-quoteback.json\");\n  a.click();\n};\n});\n\n\n\nfunction displayArticle(url){\n  if(alldata[url]){\n    document.getElementById('panel-scrollContainer').innerHTML = \"\";\n\n    var content = alldata[url].quotes[0].articleText.content;\n    console.log(content);\n\n    var articleTemplate = `\n    <div class=\"article-container\">\n      ${content}\n    </div>\n    `\n    document.getElementById('panel-scrollContainer').insertAdjacentHTML(\"beforeend\", articleTemplate);\n  }\n}\n\n\n\nfunction displayquotes(url){\n\n  if(alldata[url]){\n\n    document.getElementById('panel-scrollContainer').innerHTML = \"\";\n\n    window.location.hash = url;\n\n    const fragment = document.getElementById('quote');\n\n    var offset = $(\".article[data-id='\"+url+\"']\").offset();\n    if(offset){\n      $(\"#article-scrollContainer\").scrollTop(offset.top);\n    }\n      \n    alldata[url].quotes.forEach(item => {\n\n      var date = new Date(item.date);\n      var dd = String(date.getDate()).padStart(2, '0');\n      var mm = String(date.getMonth() + 1).padStart(2, '0'); //January is 0!\n      var yyyy = date.getFullYear();\n      \n      date = mm + '/' + dd + '/' + yyyy;\n      var datefield = date;\n\n      var quotetext = document.createElement(\"div\");\n      quotetext.innerHTML = item.text;\n      if(debug){console.log(quotetext.textContent)};\n\n      var quotetemplate = `\n      <div class=\"quoteblock\">\n        <div class=\"meta\">\n        <div class=\"date\">Created ${datefield}</div>\n        <div class=\"linkback\"><a target=\"_blank\" rel=\"noopener\" href=\"${url}#:~:text=${encodeURIComponent(quotetext.textContent)}\">View Original</a></div>\n        </div>\n        <div class=\"quote-container\">\n          <quoteback-component id=\"quoteback-component\" url=\"${url}\" text=\"${encodeURIComponent(item.text)}\" author=\"${alldata[url].author}\" title=\"${encodeURIComponent(alldata[url].title)}\" favicon=\"https://s2.googleusercontent.com/s2/favicons?domain_url=${url}&size=64\"> \n          </quoteback-component> \n          <div class=\"quote-controls\">\n            <button id=\"embedLink\" class=\"options-control-button\"><> Embed</button>        \n            <button id=\"copyimg\" class=\"options-control-button\">Copy Image</button>        \n            <button id=\"copy\" class=\"options-control-button\">Copy Text</button>\n            <button id=\"copymd\" class=\"options-control-button\">Copy Markdown</button>\n            <button id=\"delete\" class=\"options-control-button\">Delete</button>        \n          </div>\n        </div>\n      <div class=\"comment\" contenteditable=\"true\" ${item.comment ? \"style='color:#464A4D'\" : \"\"}>${item.comment ? item.comment : \"Add Comment\"}</div>\n      </div>\n      `;\n      \n      embedquoteback();\n      // Append the instance ot the DOM\n      document.getElementById('panel-scrollContainer').insertAdjacentHTML(\"beforeend\", quotetemplate);\n\n      \n\n      $( \".article\" ).each(function() {\n        $( this ).removeClass( \"selected\" );\n      });\n\n      $(\".article[data-id='\"+url+\"']\").addClass( \"selected\" );\n\n      // Update the Title Bar\n      var titlebar = document.getElementById('titlebar');\n      titlebar.querySelector(\"#titlebar-author\").innerHTML = alldata[url].author;\n      titlebar.querySelector(\"#titlebar-title\").innerHTML = alldata[url].title;\n\n    });\n  }\n};\n\n// COPY TO CLIPBOARD\n\nconst copyToClipboard = str => {\n  const el = document.createElement('textarea');\n  el.value = str;\n  document.body.appendChild(el);\n  el.select();\n  document.execCommand('copy');\n  document.body.removeChild(el);\n};\n\nfunction extractHostname(url) {\n  var hostname;\n  //find & remove protocol (http, ftp, etc.) and get hostname\n\n  if (url.indexOf(\"//\") > -1) {\n      hostname = url.split('/')[2];\n  }\n  else {\n      hostname = url.split('/')[0];\n  }\n  return hostname \n};\n\n\n\n// HOVER TO SHOW CONTROLS\n\n$(document).on('mouseenter mouseleave', '.quoteblock', function(e) {\n    if (e.type == \"mouseenter\"){\n\n      $(this).find('.quote-controls').addClass('showcontrols');\n    }else{\n      $(this).find('.quote-controls').removeClass('showcontrols');\n    }\n});\n\n\n// AUTOSAVE FUNCTION\nvar AutoSave = (function(){\n  var timer = null;\n\n  function save(object, el, index, url){\n    console.log(\"running save\");\n    console.log(el);\n    alldata[url][\"quotes\"][index][\"comment\"] = el.text();\n    chrome.storage.local.set(alldata, function(){ \n      console.log(\"autosaved\");\n    });          \n  };\n\n  function restore(){ //don't think I actually need this restore function...?\n    var page = document.location.href;\n    var saved = \"\";\n    chrome.storage.local.get([page], function(result) {\n        saved = result[page][\"quotes\"][0][\"comment\"];\n    });\n\n    var editor = getEditor();\n    if (saved && editor){\n      editor.value = saved; \n    }\n  }\n\n  return { \n\n    start: function(object, el, index, url){\n\n      if (timer != null){\n        clearInterval(timer);\n        timer = null;\n      }\n      timer = setInterval(function(){\n                save(object, el, index, url)\n            }, 500);\n    },\n\n    stop: function(){\n\n      if (timer){ \n        clearInterval(timer);\n        timer = null;\n      }\n\n    }\n  }\n}());\n\n// AUTOSAVE Meta Title / Author FUNCTION\nvar AutoSaveTitle = (function(){\n  var timer = null;\n\n  function save(object, el, url){\n    console.log(\"running autosavetitle\");\n    console.log(el);\n    var author = document.getElementById(\"titlebar-author\").textContent;\n    var title = document.getElementById(\"titlebar-title\").textContent;\n    alldata[url][\"author\"] = author;\n    alldata[url][\"title\"] = title;\n    chrome.storage.local.set(alldata, function(){ \n      var quoteelems = document.getElementsByTagName(\"quoteback-component\");\n      for(var i = 0; i < quoteelems.length; i++){\n        quoteelems[i].author = author;\n        quoteelems[i].title = title;\n      }\n      \n      console.log(\"autosaved\");\n    });          \n  };\n\n  return { \n\n    start: function(object, el, url){\n\n      if (timer != null){\n        clearInterval(timer);\n        timer = null;\n      }\n      timer = setInterval(function(){\n                save(object, el, url)\n            }, 500);\n    },\n\n    stop: function(){\n\n      if (timer){ \n        clearInterval(timer);\n        timer = null;\n      }\n\n    }\n  }\n}());\n\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n  $(\".comment\").resizable();\n});\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n    var articleOptions = document.getElementById(\"titlebar-options\");\n    var dropdown = document.getElementById(\"titlebar-dropdown\");\n\n    var addMenu = function addDropDownMenu() {\n      dropdown.classList.add(\"on\");\n    };\n    var removeMenu = function removeDropDownMenu() {\n      dropdown.classList.remove(\"on\");\n    };\n    articleOptions.addEventListener(\"mouseover\", addMenu);\n    articleOptions.addEventListener(\"mouseout\", removeMenu);\n});\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n    var globalOptions = document.getElementById(\"global-options-button\");\n    var dropdown = document.getElementById(\"global-options\");\n\n    var addMenu = function addDropDownMenu() {\n      dropdown.classList.add(\"on\");\n    };\n    var removeMenu = function removeDropDownMenu() {\n      dropdown.classList.remove(\"on\");\n    };\n    // Add mouse over event to show menu\n    globalOptions.addEventListener(\"mouseover\", addMenu);\n    // Add mouse out event to remove menu\n    globalOptions.addEventListener(\"mouseout\", removeMenu);\n});\n\n\n\n\n// $(\"#leftnav\").resizable({\n//     // only use the eastern handle\n//     handles: 'e',\n//     // restrict the width range\n//     minWidth: 120,\n//     maxWidth: 450,\n//     // resize handler updates the content panel width\n//     resize: function(event, ui){\n//         var currentWidth = ui.size.width;\n\n//         // this accounts for padding in the panels + \n//         // borders, you could calculate this using jQuery\n//         var padding = 12; \n\n//         // this accounts for some lag in the ui.size value, if you take this away \n//         // you'll get some instable behaviour\n//         $(this).width(currentWidth);\n\n//         // set the content panel width\n//         $(\"#rightpanel\").width(containerWidth - currentWidth - padding);            \n//     }\n// });"
  },
  {
    "path": "quoteback-internal.js",
    "content": "console.log(\"quoteback-internal loaded\");\n\n  var qbtemplate = document.createElement('template');\n\tqbtemplate.innerHTML=`\n      <style>${quoteStyle}</style>\n      <div class=\"quoteback-container\" role=\"quotation\" aria-labelledby=\"quoteback-author\" >\n          <div id=\"quoteback-parent\" class=\"quoteback-parent\">\n              <div class=\"quoteback-content\"></div>       \n          </div>\n\n          <div class=\"quoteback-head\">       \n              <div class=\"quoteback-avatar\"><img class=\"mini-favicon\" src=\"\"/></div>     \n              <div class=\"quoteback-metadata\">\n\t\t\t\t\t\t\t\t\t<div class=\"metadata-inner\">\n\t\t\t\t\t\t\t\t\t\t<div aria-label=\"\" id=\"quoteback-author\" class=\"quoteback-author\"></div>\n\t\t\t\t\t\t\t\t\t\t<div aria-label=\"\" class=\"quoteback-title\"></div>\n                  </div>  \n              </div>\n\n          <div class=\"quoteback-backlink\"><a target=\"_blank\" aria-label=\"go to the full text of this quotation\" rel=\"noopener\" href=\"\" class=\"quoteback-arrow\">Go to text <span class=\"right-arrow\">&#8594;</span></a></div>\n          </div>  \n      </div>\n\t\t`;\n\t\n\t\tclass QuoteBack extends HTMLElement {\n\t\t\tconstructor(){\n\t\t\t\t\n\t\t\t\tsuper();\n\t\t\t\t\n\t\t\t\t// if the page has embeds already then we don't define element\n\t\t\t\t// this is because for some reason this file can't do customElements.get('quoteback-component')\n\t\t\t\tif(this.shadowRoot){\n\n\t\t\t\t}else{\n\t\t\n\t\t\t\t\tthis.attachShadow({mode: 'open'});\n\t\t\t\t\tthis.shadowRoot.appendChild(qbtemplate.content.cloneNode(true));\n\t\t\t\t\t\t\n\t\t\t\t\tthis.text = decodeURIComponent(this.getAttribute('text'));\n\t\t\t\t\tthis.author = this.getAttribute('author');\n\t\t\t\t\tthis.title = this.getAttribute('title'); \n\t\t\t\t\tthis.url = this.getAttribute('url');\n\t\t\t\t\tthis.favicon = this.getAttribute('favicon');\n\t\t\t\t\tthis.editable = this.getAttribute('editable');\n\t\t\t\t\tthis.darkmode = this.getAttribute('darkmode')\n\n\t\t\t\t\tif(this.darkmode == \"true\"){\n\t\t\t\t\t\tthis.shadowRoot.querySelector('.quoteback-container').classList += \" dark-theme\";\n\t\t\t\t\t}\t\t\t\t\t\t\n\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t\t\tconnectedCallback() {\n          console.info( 'connected' );\n\n          if(this.darkmode == \"true\"){\n            this.shadowRoot.querySelector('.quoteback-container').classList += \" dark-theme\";\n\t\t\t\t\t}\n\t\t\t\t\tthis.shadowRoot.querySelector('.quoteback-content').innerHTML = decodeURIComponent(this.getAttribute('text'));\n\t\t\t\t\tthis.shadowRoot.querySelector('.mini-favicon').src = this.getAttribute('favicon');\n          this.shadowRoot.querySelector('.quoteback-author').innerHTML = this.getAttribute('author');\n          this.shadowRoot.querySelector('.quoteback-author').setAttribute(\"aria-label\", \"quote by \" + this.getAttribute('author'));\n\t\t\t\t\tthis.shadowRoot.querySelector('.quoteback-title').innerHTML = decodeURIComponent(this.getAttribute('title'));\n          this.shadowRoot.querySelector('.quoteback-title').setAttribute(\"aria-label\", \"title: \" + decodeURIComponent(this.getAttribute('title')));\n          this.shadowRoot.querySelector('.quoteback-arrow').href = this.getAttribute('url');\t\t\t\t\t\n\n\t\t\t\t\t// Manually focus and blur clicked targets\n\t\t\t\t\t// This solves firefox bug where clicking between contenteditable fields doesn't work\t\t\t\t\t\n\t\t\t\t\tif(this.editable == \"true\"){\n\t\t\t\t\t\tlet titlediv = this.shadowRoot.querySelector('.quoteback-title');\n\t\t\t\t\t\tlet authordiv = this.shadowRoot.querySelector('.quoteback-author');\n\t\t\t\t\t\t\n\t\t\t\t\t\ttitlediv.addEventListener(\"click\", evt => {\n\t\t\t\t\t\t\tevt.target.contentEditable = true;\n\t\t\t\t\t\t\tevt.target.focus();\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttitlediv.addEventListener(\"blur\", evt => {\n\t\t\t\t\t\t\tevt.target.contentEditable = false;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tauthordiv.addEventListener(\"click\", evt => {\n\t\t\t\t\t\t\tevt.target.contentEditable = true;\n\t\t\t\t\t\t\tevt.target.focus();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tauthordiv.addEventListener(\"blur\", evt => {\n\t\t\t\t\t\t\tevt.target.contentEditable = false;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// end this fix\n\n\t\t\t\t};\n\n\t\t};\n\t\n\t\tfunction embedquoteback(){\n\t\n\t\n\t\t\t// THIS DOESN'T WORK. customElements.get('quoteback-component')\n\t\t\t// returns undefined even if page has embeds on and has customelement defined\n\t\t\tif (customElements.get('quoteback-component')){\n\t\t\t\tconsole.log(\"quoteback-component already defined\");\n\t\t\t\tnull;\n\t\t\t}else{\n\t\t\t\t\tconsole.log(\"about to define quoteback-component\");\n\t\t\t\t\twindow.customElements.define('quoteback-component', QuoteBack)  \n\t\t\t}\n\t\t}\t"
  },
  {
    "path": "quoteback.js",
    "content": "var editSVG = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M3.42852 8.1826L3.83008 6.04181C3.84249 5.9758 3.87452 5.91507 3.92201 5.86756L9.55515 0.234417C9.97431 -0.184732 10.7881 -0.0275712 11.408 0.592253C12.0277 1.21199 12.1848 2.02581 11.7657 2.44496L6.13255 8.0781C6.08504 8.12559 6.02431 8.15763 5.9583 8.17004L3.81761 8.5717C3.76434 8.58168 3.70943 8.57853 3.65765 8.56251C3.60587 8.54649 3.55878 8.51809 3.52045 8.47976C3.48212 8.44143 3.45372 8.39434 3.4377 8.34256C3.42168 8.29078 3.41853 8.23588 3.42852 8.1826ZM10.0266 0.705828L4.46633 6.26605L4.17359 7.82661L5.73407 7.53378L11.2943 1.97355C11.4042 1.86366 11.3175 1.44465 10.9365 1.06366C10.5555 0.682577 10.1364 0.59594 10.0266 0.705828ZM10.2326 12H0.333333C0.289558 12 0.246212 11.9914 0.205768 11.9746C0.165325 11.9579 0.128577 11.9333 0.0976236 11.9024C0.0666701 11.8714 0.0421171 11.8347 0.0253667 11.7942C0.00861633 11.7538 -3.32535e-06 11.7104 9.62344e-10 11.6667V1.76752C-3.32535e-06 1.72374 0.00861633 1.68039 0.0253667 1.63995C0.0421171 1.59951 0.0666701 1.56276 0.0976236 1.53181C0.128577 1.50085 0.165325 1.4763 0.205768 1.45955C0.246212 1.4428 0.289558 1.43418 0.333333 1.43418H5.7154L5.04872 2.10085H0.666667V11.3333H9.89922V6.95119L10.5659 6.28453V11.6667C10.5659 11.7104 10.5573 11.7538 10.5405 11.7942C10.5238 11.8347 10.4992 11.8714 10.4683 11.9024C10.4373 11.9333 10.4006 11.9579 10.3601 11.9746C10.3197 11.9914 10.2763 12 10.2326 12Z\" fill=\"#9DB8BF\"/></svg>`\nvar quoteStyle  = `.quoteback-container {\n    --background-color: white;\n    --border-color-normal: #C2DFE3;\n    --border-color-hover: #9DB8BF;\n    --author-color: black;\n    --title-color: #5C6D73;\n    --gototext-color: #9DB8BF;\n    --content-color: #464A4D;\n    --internal-blockquote-color: #5C6D73;\n}\n@media (prefers-color-scheme: dark) {\n    .quoteback-container {\n    --background-color: #161717;\n    --border-color-normal: #253237;\n    --border-color-hover: #5C6D73;\n    --author-color: #E0FBFC;\n    --title-color: #9DB8BF;\n    --gototext-color: #5C6D73;\n    --content-color: #9DB8BF;\n    --internal-blockquote-color: #5C6D73;\n}\n}\n.quoteback-container{font-family:-apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";text-rendering:optimizeLegibility;border:1px solid var(--border-color-normal);border-radius:8px;margin-bottom:25px;max-width:800px;background-color:var(--background-color);text-align:left;-webkit-transition:all 0.2s ease;-moz-transition:all 0.2s ease;-ms-transition:all 0.2s ease;-o-transition:all 0.2s ease;transition:all 0.2s ease}.quoteback-container:hover{transform:translateY(-3px);box-shadow:0px 6px 20px 0px rgba(0,0,0,0.15);border:1px solid var(--border-color-hover)}.quoteback-container .quoteback-parent{overflow:hidden;position:relative;width:100%;box-sizing:border-box}.quoteback-container .quoteback-parent .quoteback-content{font-family:-apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";font-size:16px;font-weight:400;padding:15px;color:var(--content-color);line-height:150%}.quoteback-container .quoteback-head{border-top:1px solid var(--border-color-normal);display:flex;flex-flow:row nowrap;justify-content:start;align-items:stretch;padding-left:15px;-webkit-transition:all 0.2s ease;-moz-transition:all 0.2s ease;-ms-transition:all 0.2s ease;-o-transition:all 0.2s ease;transition:all 0.2s ease}.quoteback-container .quoteback-head .quoteback-avatar{border-radius:100%;border:1px solid var(--border-color-normal);width:42px;height:42px;min-width:42px !important;margin:12px 0px;position:relative}.quoteback-container .quoteback-head .quoteback-avatar .mini-favicon{width:22px;height:22px;position:absolute;margin:auto;top:0;left:0;right:0;bottom:0}.quoteback-container .quoteback-head .quoteback-metadata{min-width:0px;display:flex;flex-shrink:1;align-items:center;margin-left:10px}.quoteback-container .quoteback-head .metadata-inner{font-size:14px;line-height:1.2;width:100%;max-width:525px}@media (max-width: 414px){.quoteback-container .quoteback-head .metadata-inner{max-width:200px}}.quoteback-container .quoteback-head .metadata-inner .quoteback-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600;padding-right:20px;color:var(--title-color)}.quoteback-container .quoteback-head .metadata-inner .quoteback-author{font-size:14px;line-height:1.2;color:var(--author-color);font-weight:600;margin-bottom:2px}.quoteback-container .quoteback-head .quoteback-backlink{margin-left:auto;display:flex;flex-shrink:1;align-items:center;width:81px;min-width:81px !important;padding:0px 15px !important;border-left:1px solid var(--border-color-normal)}.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow{border:none !important;font-family:inherit !important;font-size:14px !important;color:var(--gototext-color) !important;text-decoration:none !important;-webkit-transition:opacity 0.1s ease;-moz-transition:opacity 0.1s ease;-ms-transition:opacity 0.1s ease;-o-transition:opacity 0.1s ease;transition:opacity 0.1s ease}.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:hover{opacity:.5 !important}.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:visited{text-decoration:none !important}.editable:focus{outline:none}.editable:before{margin-right:8px;content: url(data:image/svg+xml,${encodeURIComponent(editSVG)}) ;}.quoteback-content a{color:var(--content-color);-webkit-transition:opacity 0.2s ease;-moz-transition:opacity 0.2s ease;-ms-transition:opacity 0.2s ease;-o-transition:opacity 0.2s ease;transition:opacity 0.2s ease}.quoteback-content a:hover{opacity:.5}.quoteback-content p{margin-block-start:0px;margin-block-end:.5em}.quoteback-content p:last-of-type{margin-block-end:0px}.quoteback-content img{width:100%;height:auto;margin:.5em 0em}.quoteback-content blockquote{border-left:2px solid var(--border-color-normal);padding-left:.75em;margin-inline-start:1em;color:var(--internal-blockquote-color)}.quoteback-content ol,.quoteback-content ul{margin-block-start:.5em;margin-block-end:.5em}.quoteback-content h1,.quoteback-content h2,.quoteback-content h3{margin-block-start:.5em;margin-block-end:.5em}`\n\ndocument.addEventListener(\"DOMContentLoaded\", function(){\n    \n    // get all our classed blockquote components\n    var index = document.querySelectorAll(\".quoteback\");\n\n\n    for(var item=0; item < index.length; item++ ){   \n      // remove the footer element\n      console.log(index[item]);\n      index[item].removeChild(index[item].querySelector(\"footer\"));\n      \n      var text = index[item].innerHTML;\n\n      var url = index[item].cite;\n      var author = index[item].getAttribute(\"data-author\");\n      var title = index[item].getAttribute(\"data-title\");\n      var favicon = `https://s2.googleusercontent.com/s2/favicons?domain_url=${url}&sz=64`\n      var darkmode = index[item].getAttribute(\"darkmode\");\n\n      // create a new component with that data\n      var component = `\n      <quoteback-component darkmode=\"${darkmode}\" url=\"${url}\" text=\"${encodeURIComponent(text)}\" author=\"${author}\" title=\"${title}\" favicon=\"${favicon}\"> \n      </quoteback-component>    \n      `;\n      var newEl = document.createElement('div');\n      newEl.innerHTML = component;\n      \n\n      // replace the original blockquote with our quoteback seed component\n      index[item].parentNode.replaceChild(newEl, index[item]);\n\n      var template = document.createElement('template');\n      template.innerHTML=`\n      <style>${quoteStyle}</style>\n      <div class=\"quoteback-container\" role=\"quotation\" aria-labelledby=\"quoteback-author\" tabindex=\"0\">\n          <div id=\"quoteback-parent\" class=\"quoteback-parent\">\n              <div class=\"quoteback-content\"></div>       \n          </div>\n\n          <div class=\"quoteback-head\">       \n              <div class=\"quoteback-avatar\"><img class=\"mini-favicon\" src=\"\"/></div>     \n              <div class=\"quoteback-metadata\">\n                  <div class=\"metadata-inner\">\n                      <div aria-label=\"\" id=\"quoteback-author\" class=\"quoteback-author\"></div>\n                      <div aria-label=\"\" class=\"quoteback-title\"></div>\n                  </div>  \n              </div>\n\n          <div class=\"quoteback-backlink\"><a target=\"_blank\" aria-label=\"go to the full text of this quotation\" rel=\"noopener\" href=\"\" class=\"quoteback-arrow\">Go to text <span class=\"right-arrow\">&#8594;</span></a></div>\n          </div>  \n      </div>`;\n\n      class QuoteBack extends HTMLElement {\n        constructor(){  \n          super();\n          this.attachShadow({mode: 'open'});\n          this.shadowRoot.appendChild(template.content.cloneNode(true));\n  \t\t\t  \n  \t\t\t  this.text = decodeURIComponent(this.getAttribute('text'));\n  \t\t\t  this.author = this.getAttribute('author');\n  \t\t\t  this.title = this.getAttribute('title'); \n  \t\t\t  this.url = this.getAttribute('url')\n          this.favicon = this.getAttribute('favicon');\n          this.editable = this.getAttribute('editable');\n          this.darkmode = this.getAttribute('darkmode')\n\n        };\n        \n        connectedCallback() {\n          console.info( 'connected' );\n\n          if(this.darkmode == \"true\"){\n            this.shadowRoot.querySelector('.quoteback-container').classList += \" dark-theme\";\n          }\n          this.shadowRoot.querySelector('.quoteback-content').innerHTML = decodeURIComponent(this.getAttribute('text'));\n          this.shadowRoot.querySelector('.mini-favicon').src = this.getAttribute('favicon');\n          this.shadowRoot.querySelector('.quoteback-author').innerHTML = this.getAttribute('author');\n          this.shadowRoot.querySelector('.quoteback-author').setAttribute(\"aria-label\", \"quote by \" + this.getAttribute('author'));\n          this.shadowRoot.querySelector('.quoteback-title').innerHTML = decodeURIComponent(this.getAttribute('title'));\n          this.shadowRoot.querySelector('.quoteback-title').setAttribute(\"aria-label\", \"title: \" + decodeURIComponent(this.getAttribute('title')));\n          this.shadowRoot.querySelector('.quoteback-arrow').href = this.getAttribute('url');          \n\n          // Manually focus and blur clicked targets\n          // This solves firefox bug where clicking between contenteditable fields doesn't work         \n          if(this.editable == \"true\"){\n            let titlediv = this.shadowRoot.querySelector('.quoteback-title');\n            let authordiv = this.shadowRoot.querySelector('.quoteback-author');\n            \n            titlediv.addEventListener(\"click\", evt => {\n              evt.target.contentEditable = true;\n              evt.target.focus();\n            });\n            titlediv.addEventListener(\"blur\", evt => {\n              evt.target.contentEditable = false;\n            });\n\n            authordiv.addEventListener(\"click\", evt => {\n              evt.target.contentEditable = true;\n              evt.target.focus();\n            });\n            authordiv.addEventListener(\"blur\", evt => {\n              evt.target.contentEditable = false;\n            });\n          }\n          // end this fix\n\n        };                                  \n\n      }\n\n      // if quoteback-component is already defined\n      if (customElements.get('quoteback-component')){\n          null;\n      }else{\n          window.customElements.define('quoteback-component', QuoteBack)  \n      }\n    }\n});\n\n// here's some nonsens\n"
  },
  {
    "path": "quoteback.sublime-workspace",
    "content": "{\n\t\"auto_complete\":\n\t{\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"backgound\",\n\t\t\t\t\"background-color\\tproperty\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bacgk\",\n\t\t\t\t\"background-color\\tproperty\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"shift\",\n\t\t\t\t\"shift-away\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"knowledge\",\n\t\t\t\t\"knowledgeGraph\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"content\",\n\t\t\t\t\"contentDocument\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"end\",\n\t\t\t\t\"endhighlight\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"link\",\n\t\t\t\t\"linkFunction\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"itxt\",\n\t\t\t\t\"itxt-body\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"getElem\",\n\t\t\t\t\"getElementById\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"flex\",\n\t\t\t\t\"flexdir\\tFlexbox - flex-direction: row;\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"contribut\",\n\t\t\t\t\"contributor-avatar\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"contrib\",\n\t\t\t\t\"contributor-avatar\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blue\",\n\t\t\t\t\"bluegray-text-med\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"slidesh\",\n\t\t\t\t\"slideshowStopper\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"slid\",\n\t\t\t\t\"slideshow\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel\",\n\t\t\t\t\"channelButton\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"title\",\n\t\t\t\t\"titleString\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"slides\",\n\t\t\t\t\"slideshowButton\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"get\",\n\t\t\t\t\"getElementById\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"slideshow\",\n\t\t\t\t\"slideshow\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chan\",\n\t\t\t\t\"channelTitle\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"display\",\n\t\t\t\t\"displayTitle\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"arena\",\n\t\t\t\t\"arenaChannel\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"backgroun\",\n\t\t\t\t\"background-color\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"background\",\n\t\t\t\t\"background-position\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"text-\",\n\t\t\t\t\"text-align\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"font-\",\n\t\t\t\t\"font-style\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"margin-\",\n\t\t\t\t\"margin-right\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bluegra\",\n\t\t\t\t\"bluegray-text-dark\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"list-\",\n\t\t\t\t\"list-style-type\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bluegr\",\n\t\t\t\t\"bluegray-text-light\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blueg\",\n\t\t\t\t\"bluegray-bg-med\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chane\",\n\t\t\t\t\"changelog-container\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"changelog\",\n\t\t\t\t\"changelog-list\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bluegray-\",\n\t\t\t\t\"bluegray-text-dark\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"iline\",\n\t\t\t\t\"inline-block\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"base\",\n\t\t\t\t\"base-line-height\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ba\",\n\t\t\t\t\"base-line-height\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"menu-\",\n\t\t\t\t\"menu-container-bot\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"elemen\",\n\t\t\t\t\"element_height\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"offset-\",\n\t\t\t\t\"offset-by-one\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"font\",\n\t\t\t\t\"font-size\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"min-\",\n\t\t\t\t\"min-width\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"backgrou\",\n\t\t\t\t\"background-origin\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Moskau\",\n\t\t\t\t\"MoskauGrotesk-ExtraBold\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"rb\",\n\t\t\t\t\"rgba(r,g,b,a)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"fon\",\n\t\t\t\t\"font-family\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"padd\",\n\t\t\t\t\"padding-top\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"backg\",\n\t\t\t\t\"backgroundColor\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"post\",\n\t\t\t\t\"postdate\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"cone\",\n\t\t\t\t\"content-container\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"head\",\n\t\t\t\t\"head-container\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"current\",\n\t\t\t\t\"currentMinutes\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inline\",\n\t\t\t\t\"inline-block\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"block\",\n\t\t\t\t\"inline-block\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"carouse\",\n\t\t\t\t\"carousel-inner\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"margin\",\n\t\t\t\t\"margin-right\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"supported-\",\n\t\t\t\t\"supported-list-2\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"supporte\",\n\t\t\t\t\"supported-services\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"backgr\",\n\t\t\t\t\"background-color\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"amber\",\n\t\t\t\t\"ambergraphic\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"padding\",\n\t\t\t\t\"padding-left\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"carousel\",\n\t\t\t\t\"carousel-inner\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"back\",\n\t\t\t\t\"background-color\"\n\t\t\t]\n\t\t]\n\t},\n\t\"buffers\":\n\t[\n\t],\n\t\"build_system\": \"\",\n\t\"build_system_choices\":\n\t[\n\t\t[\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t\"Packages/SASS Build/SASS - Compressed.sublime-build\",\n\t\t\t\t\t\"\"\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t\"Packages/SASS Build/SASS.sublime-build\",\n\t\t\t\t\t\"\"\n\t\t\t\t]\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Packages/SASS Build/SASS - Compressed.sublime-build\",\n\t\t\t\t\"\"\n\t\t\t]\n\t\t]\n\t],\n\t\"build_varint\": \"\",\n\t\"command_palette\":\n\t{\n\t\t\"height\": 400.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"package control \",\n\t\t\t\t\"Package Control: List Packages\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"packagecontrol\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package control\",\n\t\t\t\t\"Package Control: List Packages\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package setting\",\n\t\t\t\t\"Preferences: Package Control Settings – User\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sass\",\n\t\t\t\t\"Build With: SASS - Compressed\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sublimerge\",\n\t\t\t\t\"Sublimerge: Compare to Clipboard\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"install package\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"install p\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package \",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"packageresour\",\n\t\t\t\t\"PackageResourceViewer: Open Resource\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"install\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package insta\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package inst\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"remove packa\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package control rem\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package control remove\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package contro\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"packate inst\",\n\t\t\t\t\"Package Control: Advanced Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package: install\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package co\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package: instal\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"packagecontrol remov\",\n\t\t\t\t\"Package Control: Remove Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package control: install\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"monito\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"monit\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"moni\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"monitor\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"upload\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"uplod\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mont\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"monio\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mon\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sftp: monitor\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sftp: moni\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"SFTP: monio\",\n\t\t\t\t\"SFTP: Monitor File (Upload on External Save)\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"package contro: install package\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"insta\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Package COntrol: Install\",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"Package \",\n\t\t\t\t\"Package Control: Install Package\"\n\t\t\t]\n\t\t],\n\t\t\"width\": 583.0\n\t},\n\t\"console\":\n\t{\n\t\t\"height\": 202.0,\n\t\t\"history\":\n\t\t[\n\t\t\t\"import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)\"\n\t\t]\n\t},\n\t\"distraction_free\":\n\t{\n\t\t\"menu_visible\": true,\n\t\t\"show_minimap\": false,\n\t\t\"show_open_files\": false,\n\t\t\"show_tabs\": false,\n\t\t\"side_bar_visible\": false,\n\t\t\"status_bar_visible\": false\n\t},\n\t\"file_history\":\n\t[\n\t\t\"/Users/tobyshorin/Documents/Work/Other Internet/otherinternet-research/content/web3/headless-brands.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Other Internet/otherinternet-research/squad-culture.md\",\n\t\t\"/Users/tobyshorin/Library/Application Support/Sublime Text 3/Packages/User/SublimeOnSaveBuild.sublime-settings\",\n\t\t\"/Users/tobyshorin/Documents/Work/Other Internet/otherinternet-research/templates/base.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/configurator/config.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/configurator/index.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/index_archived.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/styles/configurator.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks/quoteback.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/index.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/styles/styles.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/styles/styles.css\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/quoteback.net.sublime-project\",\n\t\t\"/Users/tobyshorin/Documents/urbit2/urbit/README.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/welcome/index.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks/test-webc.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks/quoteback-internal.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/welcome.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/quotebacks-site\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks/newcontent.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/2020/quotebacks.net/site.webmanifest\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_colors.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/head.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/blogchain-test-2.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_fonts.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/blogchain.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_post.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/blogchain-nav.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/post.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_global.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/post-titleblock.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/blogchain-test-1.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/after-authenticity.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/distributed-ecommerce.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/the-disbelievers-guide-to-authenticity.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/after-authenticity.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/portal.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/about.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_entries.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/gemfile\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_config.yml\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/entries.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/topnav.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/right-menu.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/about.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/entries.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Notes/obsidian.css\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/main.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/.gitignore\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/css/main.scss\",\n\t\t\"/Users/tobyshorin/Downloads/subpixel-space-master 2/_sass/_entries.scss\",\n\t\t\"/Users/tobyshorin/Downloads/subpixel-space-master 2/_layouts/entries.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_portal.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/portal.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/components.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/open-transclude.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_mixins.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_highlight.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/building-for-the-culture.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/notes-on-comparative-psychology.markdown\",\n\t\t\"/Users/tobyshorin/Desktop/Open Transclude.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/css/main.css\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/define-concepts-from-the-behavior-up.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/jobs-to-be-done.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/diminishing-marginal-aesthetic-value.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/components.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/haute-baroque-capitalism.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_intertext.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/channel.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/universal-menu.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/clock.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/channel-menu.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/timechecker.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/itxt.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/bftc-player.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_building-for-the-culture.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/itxt.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/universal-menu.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/intertext.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/custom-posts/architecture-at-scale.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/channel-head.html\",\n\t\t\"/Users/tobyshorin/Desktop/Export-19c9d7cd-5ea0-404e-bdc1-ad7e18e0ca5d/Define Concepts From the Behavior Up.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/consulting-promo.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_channel.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/layout-selector.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_about.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/index.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/default-post.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/mapping-the-self-in-the-desert-of-the-real.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/.ruby-version\",\n\t\t\"/Users/tobyshorin/Desktop/jtbd.md\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/our-jobs-to-be-done.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/the-desire-for-full-automation.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/frame-speaking-info.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_topnav.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_grid.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_workshops/lifestyle-brand.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_universal-menu.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_newera.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/full-automation.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_issue-cover.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/the-new-era-of-trust.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/the-desire-for-full-autonomy.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/workshop-material.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/newera.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/frame-speaking-info.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/custom-posts/mapping-the-self.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_ministorage.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/ministorage.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_entries/nyc-mini-storage.markdown\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/issue-cover-2.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/entries/nyc-mini-storage.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/trust.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_includes/contribution.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_layouts/latest-post.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_js/trust-res.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/universal-menu.js\",\n\t\t\"/Users/tobyshorin/Downloads/gyre.png\",\n\t\t\"/Users/tobyshorin/Downloads/gyre.jpg\",\n\t\t\"/Users/tobyshorin/Library/Application Support/Sublime Text 3/Packages/User/Package Control.sublime-settings\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/entries/the-disbelievers-guide-to-authenticity.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_mapping-the-self.scss\",\n\t\t\"/Users/tobyshorin/Downloads/Takeout/Search Contributions/Thumbs.json\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/main.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_site/index.html\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/arena-channeler.js\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_seeking-new-arrangements.scss\",\n\t\t\"/Users/tobyshorin/Documents/Work/Subpixel Space/subpixel-space/_sass/_after-authenticity.scss\"\n\t],\n\t\"find\":\n\t{\n\t\t\"height\": 24.0\n\t},\n\t\"find_in_files\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"where_history\":\n\t\t[\n\t\t]\n\t},\n\t\"find_state\":\n\t{\n\t\t\"case_sensitive\": false,\n\t\t\"find_history\":\n\t\t[\n\t\t],\n\t\t\"highlight\": true,\n\t\t\"in_selection\": false,\n\t\t\"preserve_case\": false,\n\t\t\"regex\": false,\n\t\t\"replace_history\":\n\t\t[\n\t\t],\n\t\t\"reverse\": false,\n\t\t\"show_context\": true,\n\t\t\"use_buffer2\": true,\n\t\t\"whole_word\": false,\n\t\t\"wrap\": true\n\t},\n\t\"groups\":\n\t[\n\t\t{\n\t\t\t\"sheets\":\n\t\t\t[\n\t\t\t]\n\t\t}\n\t],\n\t\"incremental_find\":\n\t{\n\t\t\"height\": 24.0\n\t},\n\t\"input\":\n\t{\n\t\t\"height\": 34.0\n\t},\n\t\"layout\":\n\t{\n\t\t\"cells\":\n\t\t[\n\t\t\t[\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t\t1\n\t\t\t]\n\t\t],\n\t\t\"cols\":\n\t\t[\n\t\t\t0.0,\n\t\t\t1.0\n\t\t],\n\t\t\"rows\":\n\t\t[\n\t\t\t0.0,\n\t\t\t1.0\n\t\t]\n\t},\n\t\"menu_visible\": true,\n\t\"output.exec\":\n\t{\n\t\t\"height\": 170.0\n\t},\n\t\"output.find_results\":\n\t{\n\t\t\"height\": 0.0\n\t},\n\t\"output.sftp\":\n\t{\n\t\t\"height\": 146.0\n\t},\n\t\"pinned_build_system\": \"\",\n\t\"project\": \"quoteback.sublime-project\",\n\t\"replace\":\n\t{\n\t\t\"height\": 44.0\n\t},\n\t\"save_all_on_build\": true,\n\t\"select_file\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t\t[\n\t\t\t\t\"col\",\n\t\t\t\t\"_sass/_colors.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"post-b\",\n\t\t\t\t\"templates/post-base.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"squd\",\n\t\t\t\t\"templates/squad.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"headle\",\n\t\t\t\t\"content/web3/headless-brands.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"welc\",\n\t\t\t\t\"welcome.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inde\",\n\t\t\t\t\"configurator/index.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"con\",\n\t\t\t\t\"configurator/config.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"confi\",\n\t\t\t\t\"configurator/config.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"js\",\n\t\t\t\t\"configurator/config.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"sty\",\n\t\t\t\t\"styles/styles.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"config\",\n\t\t\t\t\"styles/configurator.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"styles\",\n\t\t\t\t\"styles/styles.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"index\",\n\t\t\t\t\"index.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"test\",\n\t\t\t\t\"~/Documents/Work/2020/quotebacks/test-webc.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"quot\",\n\t\t\t\t\"~/Documents/Work/2020/quotebacks/quoteback.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"newcon\",\n\t\t\t\t\"newcontent.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"backg\",\n\t\t\t\t\"background.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mani\",\n\t\t\t\t\"site.webmanifest\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"hea\",\n\t\t\t\t\"_includes/head.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"colo\",\n\t\t\t\t\"_sass/_colors.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blogchain\",\n\t\t\t\t\"_entries/blogchain-test-2.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"glob\",\n\t\t\t\t\"_sass/_global.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"font\",\n\t\t\t\t\"_sass/_fonts.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"head\",\n\t\t\t\t\"_includes/head.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"logchaint\",\n\t\t\t\t\"_entries/blogchain-test-2.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blogch\",\n\t\t\t\t\"_entries/blogchain-test-1.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"po\",\n\t\t\t\t\"_includes/post-titleblock.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"after-\",\n\t\t\t\t\"_layouts/after-authenticity.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"af\",\n\t\t\t\t\"_entries/after-authenticity.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"after\",\n\t\t\t\t\"_entries/after-authenticity.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"gm\",\n\t\t\t\t\"_entries/the-disbelievers-guide-to-authenticity.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"por\",\n\t\t\t\t\"_includes/portal.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blog\",\n\t\t\t\t\"_layouts/blogchain.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"post\",\n\t\t\t\t\"_sass/_post.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"porta\",\n\t\t\t\t\"_includes/portal.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"right-menu\",\n\t\t\t\t\"_includes/right-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"abou\",\n\t\t\t\t\"_layouts/about.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"top\",\n\t\t\t\t\"_includes/topnav.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"entr\",\n\t\t\t\t\"entries.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"blo\",\n\t\t\t\t\"_entries/blogchain-test-2.md\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"en\",\n\t\t\t\t\"_layouts/entries.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"gemfile\",\n\t\t\t\t\"gemfile\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"\",\n\t\t\t\t\"_sass/_entries.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ent\",\n\t\t\t\t\"_layouts/entries.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"entri\",\n\t\t\t\t\"_sass/_entries.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"giti\",\n\t\t\t\t\".gitignore\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"conf\",\n\t\t\t\t\"_config.yml\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"main\",\n\t\t\t\t\"main.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"gem\",\n\t\t\t\t\"gemfile\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"entries\",\n\t\t\t\t\"_layouts/entries.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"open \",\n\t\t\t\t\"_entries/open-transclude.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"compon\",\n\t\t\t\t\"_layouts/components.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"highligh\",\n\t\t\t\t\"_sass/_highlight.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"building\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"high\",\n\t\t\t\t\"_sass/_highlight.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"scss\",\n\t\t\t\t\"css/main.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"gemf\",\n\t\t\t\t\"gemfile\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"psychol\",\n\t\t\t\t\"_entries/notes-on-comparative-psychology.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mixin\",\n\t\t\t\t\"_sass/_mixins.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"css\",\n\t\t\t\t\"_site/css/main.css\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"portal\",\n\t\t\t\t\"_includes/portal.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"define\",\n\t\t\t\t\"_entries/define-concepts-from-the-behavior-up.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"compone\",\n\t\t\t\t\"_layouts/components.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"psych\",\n\t\t\t\t\"_entries/notes-on-comparative-psychology.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jobs\",\n\t\t\t\t\"_entries/jobs-to-be-done.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"building for\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"interte\",\n\t\t\t\t\"_sass/_intertext.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"baroque\",\n\t\t\t\t\"_entries/haute-baroque-capitalism.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"dimini\",\n\t\t\t\t\"_entries/diminishing-marginal-aesthetic-value.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"INTERTE\",\n\t\t\t\t\"_sass/_intertext.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"componen\",\n\t\t\t\t\"components.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel.\",\n\t\t\t\t\"_layouts/channel.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel-menu\",\n\t\t\t\t\"_includes/channel-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"universa\",\n\t\t\t\t\"universal-menu.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel-m\",\n\t\t\t\t\"_includes/channel-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"univer\",\n\t\t\t\t\"universal-menu.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"intert\",\n\t\t\t\t\"_sass/_intertext.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"buildin\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"it\",\n\t\t\t\t\"itxt.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components.\",\n\t\t\t\t\"_layouts/components.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"compo\",\n\t\t\t\t\"_layouts/components.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"components\",\n\t\t\t\t\"components.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"itx\",\n\t\t\t\t\"itxt.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"bui\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"build\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inteer\",\n\t\t\t\t\"_includes/intertext.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"itxt\",\n\t\t\t\t\"_site/itxt.js\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"haute\",\n\t\t\t\t\"_entries/haute-baroque-capitalism.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chan\",\n\t\t\t\t\"_includes/channel-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel\",\n\t\t\t\t\"_includes/channel-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"univ\",\n\t\t\t\t\"_includes/universal-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"buil\",\n\t\t\t\t\"_entries/building-for-the-culture.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"diminish\",\n\t\t\t\t\"_entries/diminishing-marginal-aesthetic-value.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"jobs-\",\n\t\t\t\t\"_entries/jobs-to-be-done.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"component\",\n\t\t\t\t\"components.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"inter\",\n\t\t\t\t\"_sass/_intertext.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"intertext\",\n\t\t\t\t\"_includes/intertext.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"after auth\",\n\t\t\t\t\"_entries/after-authenticity.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"define \",\n\t\t\t\t\"_entries/define-concepts-from-the-behavior-up.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"head.HTML\",\n\t\t\t\t\"_includes/head.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"channel-he\",\n\t\t\t\t\"_includes/channel-head.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"intertex\",\n\t\t\t\t\"_includes/intertext.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"about\",\n\t\t\t\t\"about.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"about.sc\",\n\t\t\t\t\"_sass/_about.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"abo\",\n\t\t\t\t\"_sass/_about.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"chann\",\n\t\t\t\t\"_layouts/channel.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"de\",\n\t\t\t\t\"_includes/default-post.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"consu\",\n\t\t\t\t\"_layouts/consulting-promo.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"ruby\",\n\t\t\t\t\".ruby-version\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"la\",\n\t\t\t\t\"_includes/layout-selector.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"pos\",\n\t\t\t\t\"_layouts/post.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"uni\",\n\t\t\t\t\"_includes/universal-menu.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defa\",\n\t\t\t\t\"_includes/default-post.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"lay\",\n\t\t\t\t\"_includes/layout-selector.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"speaki\",\n\t\t\t\t\"_includes/frame-speaking-info.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"desi\",\n\t\t\t\t\"_entries/the-desire-for-full-automation.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"our jobs\",\n\t\t\t\t\"_entries/our-jobs-to-be-done.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"fon\",\n\t\t\t\t\"_sass/_fonts.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"topn\",\n\t\t\t\t\"_sass/_topnav.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"global\",\n\t\t\t\t\"_sass/_global.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"gri\",\n\t\t\t\t\"_sass/_grid.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"mix\",\n\t\t\t\t\"_sass/_mixins.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"main.scss\",\n\t\t\t\t\"css/main.scss\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"topna\",\n\t\t\t\t\"_includes/topnav.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"speaking-in\",\n\t\t\t\t\"_includes/frame-speaking-info.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"desire\",\n\t\t\t\t\"_entries/the-desire-for-full-automation.markdown\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"defau\",\n\t\t\t\t\"_includes/default-post.html\"\n\t\t\t],\n\t\t\t[\n\t\t\t\t\"new e\",\n\t\t\t\t\"_entries/the-new-era-of-trust.markdown\"\n\t\t\t]\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"select_project\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"select_symbol\":\n\t{\n\t\t\"height\": 0.0,\n\t\t\"last_filter\": \"\",\n\t\t\"selected_items\":\n\t\t[\n\t\t],\n\t\t\"width\": 0.0\n\t},\n\t\"selected_group\": 0,\n\t\"settings\":\n\t{\n\t},\n\t\"show_minimap\": true,\n\t\"show_open_files\": true,\n\t\"show_tabs\": true,\n\t\"side_bar_visible\": true,\n\t\"side_bar_width\": 267.0,\n\t\"status_bar_visible\": true,\n\t\"template_settings\":\n\t{\n\t}\n}\n"
  },
  {
    "path": "quotestyle.js",
    "content": "var quoteStyle  = `@import url(\"https://rsms.me/inter/inter.css\");\n    .quoteback-container {\n    --background-color: white;\n    --border-color-normal: #C2DFE3;\n    --border-color-hover: #9DB8BF;\n    --author-color: black;\n    --title-color: #5C6D73;\n    --gototext-color: #9DB8BF;\n    --content-color: #464A4D;\n    --internal-blockquote-color: #5C6D73;\n}\n@media (prefers-color-scheme: dark) {\n    .quoteback-container {\n    --background-color: #161717;\n    --border-color-normal: #253237;\n    --border-color-hover: #5C6D73;\n    --author-color: #E0FBFC;\n    --title-color: #9DB8BF;\n    --gototext-color: #5C6D73;\n    --content-color: #9DB8BF;\n    --internal-blockquote-color: #5C6D73;\n}\n}\n.quoteback-container {\n    font-family: \"SF Pro Text\", -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    text-rendering: optimizeLegibility;\n    border: 1px solid var(--border-color-normal);\n    border-radius: 8px;\n    margin-bottom: 25px;\n    max-width: 800px;\n    background-color: var(--background-color);\n    text-align: left;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease;\n}\n.quoteback-container:hover {\n    transform: translateY(-3px);\n    box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n    border: 1px solid var(--border-color-hover);\n}\n.quoteback-container .quoteback-parent {\n    overflow: hidden;\n    position: relative;\n    width: 100%;\n    box-sizing: border-box;\n}\n.quoteback-container .quoteback-parent .quoteback-content {\n    font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    font-size: 16px;\n    font-weight: 400;\n    padding: 15px;\n    color: var(--content-color);\n    line-height: 150%}\n.quoteback-container .quoteback-parent .quoteback-content em {\n    font-family: inherit;\n}\n.quoteback-container .quoteback-head {\n    border-top: 1px solid var(--border-color-normal);\n    display: flex;\n    flex-flow: row nowrap;\n    justify-content: start;\n    align-items: stretch;\n    padding-left: 15px;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease;\n}\n.quoteback-container .quoteback-head .quoteback-avatar {\n    border-radius: 100%;\n    border: 1px solid var(--border-color-normal);\n    width: 42px;\n    height: 42px;\n    min-width: 42px !important;\n    margin: 12px 0px;\n    position: relative;\n}\n.quoteback-container .quoteback-head .quoteback-avatar .mini-favicon {\n    width: 22px;\n    height: 22px;\n    position: absolute;\n    margin: auto;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n}\n.quoteback-container .quoteback-head .quoteback-metadata {\n    min-width: 0px;\n    display: flex;\n    flex-shrink: 1;\n    align-items: center;\n    margin-left: 10px;\n}\n.quoteback-container .quoteback-head .metadata-inner {\n    font-size: 14px;\n    line-height: 1.2;\n    width: 100%;\n    max-width: 525px;\n}\n@media (max-width: 414px) {\n    .quoteback-container .quoteback-head .metadata-inner {\n    max-width: 200px;\n}\n}\n.quoteback-container .quoteback-head .metadata-inner .quoteback-title {\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    font-weight: 600;\n    padding-right: 20px;\n    color: var(--title-color);\n}\n.quoteback-container .quoteback-head .metadata-inner .quoteback-author {\n    font-size: 14px;\n    line-height: 1.2;\n    color: var(--author-color);\n    font-weight: 600;\n    margin-bottom: 2px;\n}\n.quoteback-container .quoteback-head .quoteback-backlink {\n    margin-left: auto;\n    display: flex;\n    flex-shrink: 1;\n    align-items: center;\n    width: 81px;\n    min-width: 81px !important;\n    padding: 0px 15px !important;\n    border-left: 1px solid var(--border-color-normal);\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow {\n    border: none !important;\n    font-family: inherit !important;\n    font-size: 14px !important;\n    color: var(--gototext-color) !important;\n    text-decoration: none !important;\n    -webkit-transition: opacity 0.15s ease;\n    -moz-transition: opacity 0.15s ease;\n    -ms-transition: opacity 0.15s ease;\n    -o-transition: opacity 0.15s ease;\n    transition: opacity 0.15s ease;\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:hover {\n    opacity: .5 !important;\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:visited {\n    text-decoration: none !important;\n}\n.editable:focus {\n    outline: none;\n}\n.editable:before {\n    margin-right: 8px;\n    content: url($ {\n    chrome.runtime.getURL(\"images/editicon.svg\");\n}\n);\n}\n.quoteback-content a {\n    color: var(--content-color);\n    -webkit-transition: opacity 0.2s ease;\n    -moz-transition: opacity 0.2s ease;\n    -ms-transition: opacity 0.2s ease;\n    -o-transition: opacity 0.2s ease;\n    transition: opacity 0.2s ease;\n}\n.quoteback-content a:hover {\n    opacity: .5;\n}\n.quoteback-content p {\n    margin-block-start: 0px;\n    margin-block-end: .5em;\n}\n.quoteback-content p:last-of-type {\n    margin-block-end: 0px;\n}\n.quoteback-content img {\n    width: 100%;\n    height: auto;\n    margin: .5em 0em;\n}\n.quoteback-content blockquote {\n    border-left: 2px solid var(--border-color-normal);\n    padding-left: .75em;\n    margin-inline-start: 1em;\n    color: var(--internal-blockquote-color);\n}\n.quoteback-content ol, .quoteback-content ul {\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n}\n.quoteback-content h1, .quoteback-content h2, .quoteback-content h3 {\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n}\n`"
  },
  {
    "path": "rangy-classapplier.js",
    "content": "/**\n * Class Applier module for Rangy.\n * Adds, removes and toggles classes on Ranges and Selections\n *\n * Part of Rangy, a cross-browser JavaScript range and selection library\n * https://github.com/timdown/rangy\n *\n * Depends on Rangy core.\n *\n * Copyright 2015, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.1-dev\n * Build date: 20 May 2015\n */\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module with a dependency on Rangy.\n        define([\"./rangy-core\"], factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory( require(\"rangy\") );\n    } else {\n        // No AMD or CommonJS support so we use the rangy property of root (probably the global variable)\n        factory(root.rangy);\n    }\n})(function(rangy) {\n    rangy.createModule(\"ClassApplier\", [\"WrappedSelection\"], function(api, module) {\n        var dom = api.dom;\n        var DomPosition = dom.DomPosition;\n        var contains = dom.arrayContains;\n        var util = api.util;\n        var forEach = util.forEach;\n\n\n        var defaultTagName = \"span\";\n        var createElementNSSupported = util.isHostMethod(document, \"createElementNS\");\n\n        function each(obj, func) {\n            for (var i in obj) {\n                if (obj.hasOwnProperty(i)) {\n                    if (func(i, obj[i]) === false) {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        }\n\n        function trim(str) {\n            return str.replace(/^\\s\\s*/, \"\").replace(/\\s\\s*$/, \"\");\n        }\n\n        function classNameContainsClass(fullClassName, className) {\n            return !!fullClassName && new RegExp(\"(?:^|\\\\s)\" + className + \"(?:\\\\s|$)\").test(fullClassName);\n        }\n\n        // Inefficient, inelegant nonsense for IE's svg element, which has no classList and non-HTML className implementation\n        function hasClass(el, className) {\n            if (typeof el.classList == \"object\") {\n                return el.classList.contains(className);\n            } else {\n                var classNameSupported = (typeof el.className == \"string\");\n                var elClass = classNameSupported ? el.className : el.getAttribute(\"class\");\n                return classNameContainsClass(elClass, className);\n            }\n        }\n\n        function addClass(el, className) {\n            if (typeof el.classList == \"object\") {\n                el.classList.add(className);\n            } else {\n                var classNameSupported = (typeof el.className == \"string\");\n                var elClass = classNameSupported ? el.className : el.getAttribute(\"class\");\n                if (elClass) {\n                    if (!classNameContainsClass(elClass, className)) {\n                        elClass += \" \" + className;\n                    }\n                } else {\n                    elClass = className;\n                }\n                if (classNameSupported) {\n                    el.className = elClass;\n                } else {\n                    el.setAttribute(\"class\", elClass);\n                }\n            }\n        }\n\n        var removeClass = (function() {\n            function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {\n                return (whiteSpaceBefore && whiteSpaceAfter) ? \" \" : \"\";\n            }\n\n            return function(el, className) {\n                if (typeof el.classList == \"object\") {\n                    el.classList.remove(className);\n                } else {\n                    var classNameSupported = (typeof el.className == \"string\");\n                    var elClass = classNameSupported ? el.className : el.getAttribute(\"class\");\n                    elClass = elClass.replace(new RegExp(\"(^|\\\\s)\" + className + \"(\\\\s|$)\"), replacer);\n                    if (classNameSupported) {\n                        el.className = elClass;\n                    } else {\n                        el.setAttribute(\"class\", elClass);\n                    }\n                }\n            };\n        })();\n\n        function getClass(el) {\n            var classNameSupported = (typeof el.className == \"string\");\n            return classNameSupported ? el.className : el.getAttribute(\"class\");\n        }\n\n        function sortClassName(className) {\n            return className && className.split(/\\s+/).sort().join(\" \");\n        }\n\n        function getSortedClassName(el) {\n            return sortClassName( getClass(el) );\n        }\n\n        function haveSameClasses(el1, el2) {\n            return getSortedClassName(el1) == getSortedClassName(el2);\n        }\n\n        function hasAllClasses(el, className) {\n            var classes = className.split(/\\s+/);\n            for (var i = 0, len = classes.length; i < len; ++i) {\n                if (!hasClass(el, trim(classes[i]))) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function canTextBeStyled(textNode) {\n            var parent = textNode.parentNode;\n            return (parent && parent.nodeType == 1 && !/^(textarea|style|script|select|iframe)$/i.test(parent.nodeName));\n        }\n\n        function movePosition(position, oldParent, oldIndex, newParent, newIndex) {\n            var posNode = position.node, posOffset = position.offset;\n            var newNode = posNode, newOffset = posOffset;\n\n            if (posNode == newParent && posOffset > newIndex) {\n                ++newOffset;\n            }\n\n            if (posNode == oldParent && (posOffset == oldIndex  || posOffset == oldIndex + 1)) {\n                newNode = newParent;\n                newOffset += newIndex - oldIndex;\n            }\n\n            if (posNode == oldParent && posOffset > oldIndex + 1) {\n                --newOffset;\n            }\n\n            position.node = newNode;\n            position.offset = newOffset;\n        }\n\n        function movePositionWhenRemovingNode(position, parentNode, index) {\n            if (position.node == parentNode && position.offset > index) {\n                --position.offset;\n            }\n        }\n\n        function movePreservingPositions(node, newParent, newIndex, positionsToPreserve) {\n            // For convenience, allow newIndex to be -1 to mean \"insert at the end\".\n            if (newIndex == -1) {\n                newIndex = newParent.childNodes.length;\n            }\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            forEach(positionsToPreserve, function(position) {\n                movePosition(position, oldParent, oldIndex, newParent, newIndex);\n            });\n\n            // Now actually move the node.\n            if (newParent.childNodes.length == newIndex) {\n                newParent.appendChild(node);\n            } else {\n                newParent.insertBefore(node, newParent.childNodes[newIndex]);\n            }\n        }\n\n        function removePreservingPositions(node, positionsToPreserve) {\n\n            var oldParent = node.parentNode;\n            var oldIndex = dom.getNodeIndex(node);\n\n            forEach(positionsToPreserve, function(position) {\n                movePositionWhenRemovingNode(position, oldParent, oldIndex);\n            });\n\n            dom.removeNode(node);\n        }\n\n        function moveChildrenPreservingPositions(node, newParent, newIndex, removeNode, positionsToPreserve) {\n            var child, children = [];\n            while ( (child = node.firstChild) ) {\n                movePreservingPositions(child, newParent, newIndex++, positionsToPreserve);\n                children.push(child);\n            }\n            if (removeNode) {\n                removePreservingPositions(node, positionsToPreserve);\n            }\n            return children;\n        }\n\n        function replaceWithOwnChildrenPreservingPositions(element, positionsToPreserve) {\n            return moveChildrenPreservingPositions(element, element.parentNode, dom.getNodeIndex(element), true, positionsToPreserve);\n        }\n\n        function rangeSelectsAnyText(range, textNode) {\n            var textNodeRange = range.cloneRange();\n            textNodeRange.selectNodeContents(textNode);\n\n            var intersectionRange = textNodeRange.intersection(range);\n            var text = intersectionRange ? intersectionRange.toString() : \"\";\n\n            return text != \"\";\n        }\n\n        function getEffectiveTextNodes(range) {\n            var nodes = range.getNodes([3]);\n\n            // Optimization as per issue 145\n\n            // Remove non-intersecting text nodes from the start of the range\n            var start = 0, node;\n            while ( (node = nodes[start]) && !rangeSelectsAnyText(range, node) ) {\n                ++start;\n            }\n\n            // Remove non-intersecting text nodes from the start of the range\n            var end = nodes.length - 1;\n            while ( (node = nodes[end]) && !rangeSelectsAnyText(range, node) ) {\n                --end;\n            }\n\n            return nodes.slice(start, end + 1);\n        }\n\n        function elementsHaveSameNonClassAttributes(el1, el2) {\n            if (el1.attributes.length != el2.attributes.length) return false;\n            for (var i = 0, len = el1.attributes.length, attr1, attr2, name; i < len; ++i) {\n                attr1 = el1.attributes[i];\n                name = attr1.name;\n                if (name != \"class\") {\n                    attr2 = el2.attributes.getNamedItem(name);\n                    if ( (attr1 === null) != (attr2 === null) ) return false;\n                    if (attr1.specified != attr2.specified) return false;\n                    if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) return false;\n                }\n            }\n            return true;\n        }\n\n        function elementHasNonClassAttributes(el, exceptions) {\n            for (var i = 0, len = el.attributes.length, attrName; i < len; ++i) {\n                attrName = el.attributes[i].name;\n                if ( !(exceptions && contains(exceptions, attrName)) && el.attributes[i].specified && attrName != \"class\") {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        var getComputedStyleProperty = dom.getComputedStyleProperty;\n        var isEditableElement = (function() {\n            var testEl = document.createElement(\"div\");\n            return typeof testEl.isContentEditable == \"boolean\" ?\n                function (node) {\n                    return node && node.nodeType == 1 && node.isContentEditable;\n                } :\n                function (node) {\n                    if (!node || node.nodeType != 1 || node.contentEditable == \"false\") {\n                        return false;\n                    }\n                    return node.contentEditable == \"true\" || isEditableElement(node.parentNode);\n                };\n        })();\n\n        function isEditingHost(node) {\n            var parent;\n            return node && node.nodeType == 1 &&\n                (( (parent = node.parentNode) && parent.nodeType == 9 && parent.designMode == \"on\") ||\n                (isEditableElement(node) && !isEditableElement(node.parentNode)));\n        }\n\n        function isEditable(node) {\n            return (isEditableElement(node) || (node.nodeType != 1 && isEditableElement(node.parentNode))) && !isEditingHost(node);\n        }\n\n        var inlineDisplayRegex = /^inline(-block|-table)?$/i;\n\n        function isNonInlineElement(node) {\n            return node && node.nodeType == 1 && !inlineDisplayRegex.test(getComputedStyleProperty(node, \"display\"));\n        }\n\n        // White space characters as defined by HTML 4 (http://www.w3.org/TR/html401/struct/text.html)\n        var htmlNonWhiteSpaceRegex = /[^\\r\\n\\t\\f \\u200B]/;\n\n        function isUnrenderedWhiteSpaceNode(node) {\n            if (node.data.length == 0) {\n                return true;\n            }\n            if (htmlNonWhiteSpaceRegex.test(node.data)) {\n                return false;\n            }\n            var cssWhiteSpace = getComputedStyleProperty(node.parentNode, \"whiteSpace\");\n            switch (cssWhiteSpace) {\n                case \"pre\":\n                case \"pre-wrap\":\n                case \"-moz-pre-wrap\":\n                    return false;\n                case \"pre-line\":\n                    if (/[\\r\\n]/.test(node.data)) {\n                        return false;\n                    }\n            }\n\n            // We now have a whitespace-only text node that may be rendered depending on its context. If it is adjacent to a\n            // non-inline element, it will not be rendered. This seems to be a good enough definition.\n            return isNonInlineElement(node.previousSibling) || isNonInlineElement(node.nextSibling);\n        }\n\n        function getRangeBoundaries(ranges) {\n            var positions = [], i, range;\n            for (i = 0; range = ranges[i++]; ) {\n                positions.push(\n                    new DomPosition(range.startContainer, range.startOffset),\n                    new DomPosition(range.endContainer, range.endOffset)\n                );\n            }\n            return positions;\n        }\n\n        function updateRangesFromBoundaries(ranges, positions) {\n            for (var i = 0, range, start, end, len = ranges.length; i < len; ++i) {\n                range = ranges[i];\n                start = positions[i * 2];\n                end = positions[i * 2 + 1];\n                range.setStartAndEnd(start.node, start.offset, end.node, end.offset);\n            }\n        }\n\n        function isSplitPoint(node, offset) {\n            if (dom.isCharacterDataNode(node)) {\n                if (offset == 0) {\n                    return !!node.previousSibling;\n                } else if (offset == node.length) {\n                    return !!node.nextSibling;\n                } else {\n                    return true;\n                }\n            }\n\n            return offset > 0 && offset < node.childNodes.length;\n        }\n\n        function splitNodeAt(node, descendantNode, descendantOffset, positionsToPreserve) {\n            var newNode, parentNode;\n            var splitAtStart = (descendantOffset == 0);\n\n            if (dom.isAncestorOf(descendantNode, node)) {\n                return node;\n            }\n\n            if (dom.isCharacterDataNode(descendantNode)) {\n                var descendantIndex = dom.getNodeIndex(descendantNode);\n                if (descendantOffset == 0) {\n                    descendantOffset = descendantIndex;\n                } else if (descendantOffset == descendantNode.length) {\n                    descendantOffset = descendantIndex + 1;\n                } else {\n                    throw module.createError(\"splitNodeAt() should not be called with offset in the middle of a data node (\" +\n                        descendantOffset + \" in \" + descendantNode.data);\n                }\n                descendantNode = descendantNode.parentNode;\n            }\n\n            if (isSplitPoint(descendantNode, descendantOffset)) {\n                // descendantNode is now guaranteed not to be a text or other character node\n                newNode = descendantNode.cloneNode(false);\n                parentNode = descendantNode.parentNode;\n                if (newNode.id) {\n                    newNode.removeAttribute(\"id\");\n                }\n                var child, newChildIndex = 0;\n\n                while ( (child = descendantNode.childNodes[descendantOffset]) ) {\n                    movePreservingPositions(child, newNode, newChildIndex++, positionsToPreserve);\n                }\n                movePreservingPositions(newNode, parentNode, dom.getNodeIndex(descendantNode) + 1, positionsToPreserve);\n                return (descendantNode == node) ? newNode : splitNodeAt(node, parentNode, dom.getNodeIndex(newNode), positionsToPreserve);\n            } else if (node != descendantNode) {\n                newNode = descendantNode.parentNode;\n\n                // Work out a new split point in the parent node\n                var newNodeIndex = dom.getNodeIndex(descendantNode);\n\n                if (!splitAtStart) {\n                    newNodeIndex++;\n                }\n                return splitNodeAt(node, newNode, newNodeIndex, positionsToPreserve);\n            }\n            return node;\n        }\n\n        function areElementsMergeable(el1, el2) {\n            return el1.namespaceURI == el2.namespaceURI &&\n                el1.tagName.toLowerCase() == el2.tagName.toLowerCase() &&\n                haveSameClasses(el1, el2) &&\n                elementsHaveSameNonClassAttributes(el1, el2) &&\n                getComputedStyleProperty(el1, \"display\") == \"inline\" &&\n                getComputedStyleProperty(el2, \"display\") == \"inline\";\n        }\n\n        function createAdjacentMergeableTextNodeGetter(forward) {\n            var siblingPropName = forward ? \"nextSibling\" : \"previousSibling\";\n\n            return function(textNode, checkParentElement) {\n                var el = textNode.parentNode;\n                var adjacentNode = textNode[siblingPropName];\n                if (adjacentNode) {\n                    // Can merge if the node's previous/next sibling is a text node\n                    if (adjacentNode && adjacentNode.nodeType == 3) {\n                        return adjacentNode;\n                    }\n                } else if (checkParentElement) {\n                    // Compare text node parent element with its sibling\n                    adjacentNode = el[siblingPropName];\n                    if (adjacentNode && adjacentNode.nodeType == 1 && areElementsMergeable(el, adjacentNode)) {\n                        var adjacentNodeChild = adjacentNode[forward ? \"firstChild\" : \"lastChild\"];\n                        if (adjacentNodeChild && adjacentNodeChild.nodeType == 3) {\n                            return adjacentNodeChild;\n                        }\n                    }\n                }\n                return null;\n            };\n        }\n\n        var getPreviousMergeableTextNode = createAdjacentMergeableTextNodeGetter(false),\n            getNextMergeableTextNode = createAdjacentMergeableTextNodeGetter(true);\n\n    \n        function Merge(firstNode) {\n            this.isElementMerge = (firstNode.nodeType == 1);\n            this.textNodes = [];\n            var firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;\n            if (firstTextNode) {\n                this.textNodes[0] = firstTextNode;\n            }\n        }\n\n        Merge.prototype = {\n            doMerge: function(positionsToPreserve) {\n                var textNodes = this.textNodes;\n                var firstTextNode = textNodes[0];\n                if (textNodes.length > 1) {\n                    var firstTextNodeIndex = dom.getNodeIndex(firstTextNode);\n                    var textParts = [], combinedTextLength = 0, textNode, parent;\n                    forEach(textNodes, function(textNode, i) {\n                        parent = textNode.parentNode;\n                        if (i > 0) {\n                            parent.removeChild(textNode);\n                            if (!parent.hasChildNodes()) {\n                                dom.removeNode(parent);\n                            }\n                            if (positionsToPreserve) {\n                                forEach(positionsToPreserve, function(position) {\n                                    // Handle case where position is inside the text node being merged into a preceding node\n                                    if (position.node == textNode) {\n                                        position.node = firstTextNode;\n                                        position.offset += combinedTextLength;\n                                    }\n                                    // Handle case where both text nodes precede the position within the same parent node\n                                    if (position.node == parent && position.offset > firstTextNodeIndex) {\n                                        --position.offset;\n                                        if (position.offset == firstTextNodeIndex + 1 && i < len - 1) {\n                                            position.node = firstTextNode;\n                                            position.offset = combinedTextLength;\n                                        }\n                                    }\n                                });\n                            }\n                        }\n                        textParts[i] = textNode.data;\n                        combinedTextLength += textNode.data.length;\n                    });\n                    firstTextNode.data = textParts.join(\"\");\n                }\n                return firstTextNode.data;\n            },\n\n            getLength: function() {\n                var i = this.textNodes.length, len = 0;\n                while (i--) {\n                    len += this.textNodes[i].length;\n                }\n                return len;\n            },\n\n            toString: function() {\n                var textParts = [];\n                forEach(this.textNodes, function(textNode, i) {\n                    textParts[i] = \"'\" + textNode.data + \"'\";\n                });\n                return \"[Merge(\" + textParts.join(\",\") + \")]\";\n            }\n        };\n\n        var optionProperties = [\"elementTagName\", \"ignoreWhiteSpace\", \"applyToEditableOnly\", \"useExistingElements\",\n            \"removeEmptyElements\", \"onElementCreate\"];\n\n        // TODO: Populate this with every attribute name that corresponds to a property with a different name. Really??\n        var attrNamesForProperties = {};\n\n        function ClassApplier(className, options, tagNames) {\n            var normalize, i, len, propName, applier = this;\n            applier.cssClass = applier.className = className; // cssClass property is for backward compatibility\n\n            var elementPropertiesFromOptions = null, elementAttributes = {};\n\n            // Initialize from options object\n            if (typeof options == \"object\" && options !== null) {\n                if (typeof options.elementTagName !== \"undefined\") {\n                    options.elementTagName = options.elementTagName.toLowerCase();\n                }\n                tagNames = options.tagNames;\n                elementPropertiesFromOptions = options.elementProperties;\n                elementAttributes = options.elementAttributes;\n\n                for (i = 0; propName = optionProperties[i++]; ) {\n                    if (options.hasOwnProperty(propName)) {\n                        applier[propName] = options[propName];\n                    }\n                }\n                normalize = options.normalize;\n            } else {\n                normalize = options;\n            }\n\n            // Backward compatibility: the second parameter can also be a Boolean indicating to normalize after unapplying\n            applier.normalize = (typeof normalize == \"undefined\") ? true : normalize;\n\n            // Initialize element properties and attribute exceptions\n            applier.attrExceptions = [];\n            var el = document.createElement(applier.elementTagName);\n            applier.elementProperties = applier.copyPropertiesToElement(elementPropertiesFromOptions, el, true);\n            each(elementAttributes, function(attrName, attrValue) {\n                applier.attrExceptions.push(attrName);\n                // Ensure each attribute value is a string\n                elementAttributes[attrName] = \"\" + attrValue;\n            });\n            applier.elementAttributes = elementAttributes;\n\n            applier.elementSortedClassName = applier.elementProperties.hasOwnProperty(\"className\") ?\n                sortClassName(applier.elementProperties.className + \" \" + className) : className;\n\n            // Initialize tag names\n            applier.applyToAnyTagName = false;\n            var type = typeof tagNames;\n            if (type == \"string\") {\n                if (tagNames == \"*\") {\n                    applier.applyToAnyTagName = true;\n                } else {\n                    applier.tagNames = trim(tagNames.toLowerCase()).split(/\\s*,\\s*/);\n                }\n            } else if (type == \"object\" && typeof tagNames.length == \"number\") {\n                applier.tagNames = [];\n                for (i = 0, len = tagNames.length; i < len; ++i) {\n                    if (tagNames[i] == \"*\") {\n                        applier.applyToAnyTagName = true;\n                    } else {\n                        applier.tagNames.push(tagNames[i].toLowerCase());\n                    }\n                }\n            } else {\n                applier.tagNames = [applier.elementTagName];\n            }\n        }\n\n        ClassApplier.prototype = {\n            elementTagName: defaultTagName,\n            elementProperties: {},\n            elementAttributes: {},\n            ignoreWhiteSpace: true,\n            applyToEditableOnly: false,\n            useExistingElements: true,\n            removeEmptyElements: true,\n            onElementCreate: null,\n\n            copyPropertiesToElement: function(props, el, createCopy) {\n                var s, elStyle, elProps = {}, elPropsStyle, propValue, elPropValue, attrName;\n\n                for (var p in props) {\n                    if (props.hasOwnProperty(p)) {\n                        propValue = props[p];\n                        elPropValue = el[p];\n\n                        // Special case for class. The copied properties object has the applier's class as well as its own\n                        // to simplify checks when removing styling elements\n                        if (p == \"className\") {\n                            addClass(el, propValue);\n                            addClass(el, this.className);\n                            el[p] = sortClassName(el[p]);\n                            if (createCopy) {\n                                elProps[p] = propValue;\n                            }\n                        }\n\n                        // Special case for style\n                        else if (p == \"style\") {\n                            elStyle = elPropValue;\n                            if (createCopy) {\n                                elProps[p] = elPropsStyle = {};\n                            }\n                            for (s in props[p]) {\n                                if (props[p].hasOwnProperty(s)) {\n                                    elStyle[s] = propValue[s];\n                                    if (createCopy) {\n                                        elPropsStyle[s] = elStyle[s];\n                                    }\n                                }\n                            }\n                            this.attrExceptions.push(p);\n                        } else {\n                            el[p] = propValue;\n                            // Copy the property back from the dummy element so that later comparisons to check whether\n                            // elements may be removed are checking against the right value. For example, the href property\n                            // of an element returns a fully qualified URL even if it was previously assigned a relative\n                            // URL.\n                            if (createCopy) {\n                                elProps[p] = el[p];\n\n                                // Not all properties map to identically-named attributes\n                                attrName = attrNamesForProperties.hasOwnProperty(p) ? attrNamesForProperties[p] : p;\n                                this.attrExceptions.push(attrName);\n                            }\n                        }\n                    }\n                }\n\n                return createCopy ? elProps : \"\";\n            },\n\n            copyAttributesToElement: function(attrs, el) {\n                for (var attrName in attrs) {\n                    if (attrs.hasOwnProperty(attrName) && !/^class(?:Name)?$/i.test(attrName)) {\n                        el.setAttribute(attrName, attrs[attrName]);\n                    }\n                }\n            },\n\n            appliesToElement: function(el) {\n                return contains(this.tagNames, el.tagName.toLowerCase());\n            },\n\n            getEmptyElements: function(range) {\n                var applier = this;\n                return range.getNodes([1], function(el) {\n                    return applier.appliesToElement(el) && !el.hasChildNodes();\n                });\n            },\n\n            hasClass: function(node) {\n                return node.nodeType == 1 &&\n                    (this.applyToAnyTagName || this.appliesToElement(node)) &&\n                    hasClass(node, this.className);\n            },\n\n            getSelfOrAncestorWithClass: function(node) {\n                while (node) {\n                    if (this.hasClass(node)) {\n                        return node;\n                    }\n                    node = node.parentNode;\n                }\n                return null;\n            },\n\n            isModifiable: function(node) {\n                return !this.applyToEditableOnly || isEditable(node);\n            },\n\n            // White space adjacent to an unwrappable node can be ignored for wrapping\n            isIgnorableWhiteSpaceNode: function(node) {\n                return this.ignoreWhiteSpace && node && node.nodeType == 3 && isUnrenderedWhiteSpaceNode(node);\n            },\n\n            // Normalizes nodes after applying a class to a Range.\n            postApply: function(textNodes, range, positionsToPreserve, isUndo) {\n                var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];\n\n                var merges = [], currentMerge;\n\n                var rangeStartNode = firstNode, rangeEndNode = lastNode;\n                var rangeStartOffset = 0, rangeEndOffset = lastNode.length;\n\n                var textNode, precedingTextNode;\n\n                // Check for every required merge and create a Merge object for each\n                forEach(textNodes, function(textNode) {\n                    precedingTextNode = getPreviousMergeableTextNode(textNode, !isUndo);\n                    if (precedingTextNode) {\n                        if (!currentMerge) {\n                            currentMerge = new Merge(precedingTextNode);\n                            merges.push(currentMerge);\n                        }\n                        currentMerge.textNodes.push(textNode);\n                        if (textNode === firstNode) {\n                            rangeStartNode = currentMerge.textNodes[0];\n                            rangeStartOffset = rangeStartNode.length;\n                        }\n                        if (textNode === lastNode) {\n                            rangeEndNode = currentMerge.textNodes[0];\n                            rangeEndOffset = currentMerge.getLength();\n                        }\n                    } else {\n                        currentMerge = null;\n                    }\n                });\n\n                // Test whether the first node after the range needs merging\n                var nextTextNode = getNextMergeableTextNode(lastNode, !isUndo);\n\n                if (nextTextNode) {\n                    if (!currentMerge) {\n                        currentMerge = new Merge(lastNode);\n                        merges.push(currentMerge);\n                    }\n                    currentMerge.textNodes.push(nextTextNode);\n                }\n\n                // Apply the merges\n                if (merges.length) {\n                    for (i = 0, len = merges.length; i < len; ++i) {\n                        merges[i].doMerge(positionsToPreserve);\n                    }\n\n                    // Set the range boundaries\n                    range.setStartAndEnd(rangeStartNode, rangeStartOffset, rangeEndNode, rangeEndOffset);\n                }\n            },\n\n            createContainer: function(parentNode) {\n                var doc = dom.getDocument(parentNode);\n                var namespace;\n                var el = createElementNSSupported && !dom.isHtmlNamespace(parentNode) && (namespace = parentNode.namespaceURI) ?\n                    doc.createElementNS(parentNode.namespaceURI, this.elementTagName) :\n                    doc.createElement(this.elementTagName);\n\n                this.copyPropertiesToElement(this.elementProperties, el, false);\n                this.copyAttributesToElement(this.elementAttributes, el);\n                addClass(el, this.className);\n                if (this.onElementCreate) {\n                    this.onElementCreate(el, this);\n                }\n                return el;\n            },\n\n            elementHasProperties: function(el, props) {\n                var applier = this;\n                return each(props, function(p, propValue) {\n                    if (p == \"className\") {\n                        // For checking whether we should reuse an existing element, we just want to check that the element\n                        // has all the classes specified in the className property. When deciding whether the element is\n                        // removable when unapplying a class, there is separate special handling to check whether the\n                        // element has extra classes so the same simple check will do.\n                        return hasAllClasses(el, propValue);\n                    } else if (typeof propValue == \"object\") {\n                        if (!applier.elementHasProperties(el[p], propValue)) {\n                            return false;\n                        }\n                    } else if (el[p] !== propValue) {\n                        return false;\n                    }\n                });\n            },\n\n            elementHasAttributes: function(el, attrs) {\n                return each(attrs, function(name, value) {\n                    if (el.getAttribute(name) !== value) {\n                        return false;\n                    }\n                });\n            },\n\n            applyToTextNode: function(textNode, positionsToPreserve) {\n\n                // Check whether the text node can be styled. Text within a <style> or <script> element, for example,\n                // should not be styled. See issue 283.\n                if (canTextBeStyled(textNode)) {\n                    var parent = textNode.parentNode;\n                    if (parent.childNodes.length == 1 &&\n                        this.useExistingElements &&\n                        this.appliesToElement(parent) &&\n                        this.elementHasProperties(parent, this.elementProperties) &&\n                        this.elementHasAttributes(parent, this.elementAttributes)) {\n\n                        addClass(parent, this.className);\n                    } else {\n                        var textNodeParent = textNode.parentNode;\n                        var el = this.createContainer(textNodeParent);\n                        textNodeParent.insertBefore(el, textNode);\n                        el.appendChild(textNode);\n                    }\n                }\n\n            },\n\n            isRemovable: function(el) {\n                return el.tagName.toLowerCase() == this.elementTagName &&\n                    getSortedClassName(el) == this.elementSortedClassName &&\n                    this.elementHasProperties(el, this.elementProperties) &&\n                    !elementHasNonClassAttributes(el, this.attrExceptions) &&\n                    this.elementHasAttributes(el, this.elementAttributes) &&\n                    this.isModifiable(el);\n            },\n\n            isEmptyContainer: function(el) {\n                var childNodeCount = el.childNodes.length;\n                return el.nodeType == 1 &&\n                    this.isRemovable(el) &&\n                    (childNodeCount == 0 || (childNodeCount == 1 && this.isEmptyContainer(el.firstChild)));\n            },\n\n            removeEmptyContainers: function(range) {\n                var applier = this;\n                var nodesToRemove = range.getNodes([1], function(el) {\n                    return applier.isEmptyContainer(el);\n                });\n\n                var rangesToPreserve = [range];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n\n                forEach(nodesToRemove, function(node) {\n                    removePreservingPositions(node, positionsToPreserve);\n                });\n\n                // Update the range from the preserved boundary positions\n                updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n            },\n\n            undoToTextNode: function(textNode, range, ancestorWithClass, positionsToPreserve) {\n                if (!range.containsNode(ancestorWithClass)) {\n                    // Split out the portion of the ancestor from which we can remove the class\n                    //var parent = ancestorWithClass.parentNode, index = dom.getNodeIndex(ancestorWithClass);\n                    var ancestorRange = range.cloneRange();\n                    ancestorRange.selectNode(ancestorWithClass);\n                    if (ancestorRange.isPointInRange(range.endContainer, range.endOffset)) {\n                        splitNodeAt(ancestorWithClass, range.endContainer, range.endOffset, positionsToPreserve);\n                        range.setEndAfter(ancestorWithClass);\n                    }\n                    if (ancestorRange.isPointInRange(range.startContainer, range.startOffset)) {\n                        ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset, positionsToPreserve);\n                    }\n                }\n\n                if (this.isRemovable(ancestorWithClass)) {\n                    replaceWithOwnChildrenPreservingPositions(ancestorWithClass, positionsToPreserve);\n                } else {\n                    removeClass(ancestorWithClass, this.className);\n                }\n            },\n\n            splitAncestorWithClass: function(container, offset, positionsToPreserve) {\n                var ancestorWithClass = this.getSelfOrAncestorWithClass(container);\n                if (ancestorWithClass) {\n                    splitNodeAt(ancestorWithClass, container, offset, positionsToPreserve);\n                }\n            },\n\n            undoToAncestor: function(ancestorWithClass, positionsToPreserve) {\n                if (this.isRemovable(ancestorWithClass)) {\n                    replaceWithOwnChildrenPreservingPositions(ancestorWithClass, positionsToPreserve);\n                } else {\n                    removeClass(ancestorWithClass, this.className);\n                }\n            },\n\n            applyToRange: function(range, rangesToPreserve) {\n                var applier = this;\n                rangesToPreserve = rangesToPreserve || [];\n\n                // Create an array of range boundaries to preserve\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve || []);\n\n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers\n                if (applier.removeEmptyElements) {\n                    applier.removeEmptyContainers(range);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n\n                if (textNodes.length) {\n                    forEach(textNodes, function(textNode) {\n                        if (!applier.isIgnorableWhiteSpaceNode(textNode) && !applier.getSelfOrAncestorWithClass(textNode) &&\n                                applier.isModifiable(textNode)) {\n                            applier.applyToTextNode(textNode, positionsToPreserve);\n                        }\n                    });\n                    var lastTextNode = textNodes[textNodes.length - 1];\n                    range.setStartAndEnd(textNodes[0], 0, lastTextNode, lastTextNode.length);\n                    if (applier.normalize) {\n                        applier.postApply(textNodes, range, positionsToPreserve, false);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n\n                // Apply classes to any appropriate empty elements\n                var emptyElements = applier.getEmptyElements(range);\n\n                forEach(emptyElements, function(el) {\n                    addClass(el, applier.className);\n                });\n            },\n\n            applyToRanges: function(ranges) {\n\n                var i = ranges.length;\n                while (i--) {\n                    this.applyToRange(ranges[i], ranges);\n                }\n\n\n                return ranges;\n            },\n\n            applyToSelection: function(win) {\n                var sel = api.getSelection(win);\n                sel.setRanges( this.applyToRanges(sel.getAllRanges()) );\n            },\n\n            undoToRange: function(range, rangesToPreserve) {\n                var applier = this;\n                // Create an array of range boundaries to preserve\n                rangesToPreserve = rangesToPreserve || [];\n                var positionsToPreserve = getRangeBoundaries(rangesToPreserve);\n\n\n                range.splitBoundariesPreservingPositions(positionsToPreserve);\n\n                // Tidy up the DOM by removing empty containers\n                if (applier.removeEmptyElements) {\n                    applier.removeEmptyContainers(range, positionsToPreserve);\n                }\n\n                var textNodes = getEffectiveTextNodes(range);\n                var textNode, ancestorWithClass;\n                var lastTextNode = textNodes[textNodes.length - 1];\n\n                if (textNodes.length) {\n                    applier.splitAncestorWithClass(range.endContainer, range.endOffset, positionsToPreserve);\n                    applier.splitAncestorWithClass(range.startContainer, range.startOffset, positionsToPreserve);\n                    for (var i = 0, len = textNodes.length; i < len; ++i) {\n                        textNode = textNodes[i];\n                        ancestorWithClass = applier.getSelfOrAncestorWithClass(textNode);\n                        if (ancestorWithClass && applier.isModifiable(textNode)) {\n                            applier.undoToAncestor(ancestorWithClass, positionsToPreserve);\n                        }\n                    }\n                    // Ensure the range is still valid\n                    range.setStartAndEnd(textNodes[0], 0, lastTextNode, lastTextNode.length);\n\n\n                    if (applier.normalize) {\n                        applier.postApply(textNodes, range, positionsToPreserve, true);\n                    }\n\n                    // Update the ranges from the preserved boundary positions\n                    updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);\n                }\n\n                // Remove class from any appropriate empty elements\n                var emptyElements = applier.getEmptyElements(range);\n\n                forEach(emptyElements, function(el) {\n                    removeClass(el, applier.className);\n                });\n            },\n\n            undoToRanges: function(ranges) {\n                // Get ranges returned in document order\n                var i = ranges.length;\n\n                while (i--) {\n                    this.undoToRange(ranges[i], ranges);\n                }\n\n                return ranges;\n            },\n\n            undoToSelection: function(win) {\n                var sel = api.getSelection(win);\n                var ranges = api.getSelection(win).getAllRanges();\n                this.undoToRanges(ranges);\n                sel.setRanges(ranges);\n            },\n\n            isAppliedToRange: function(range) {\n                if (range.collapsed || range.toString() == \"\") {\n                    return !!this.getSelfOrAncestorWithClass(range.commonAncestorContainer);\n                } else {\n                    var textNodes = range.getNodes( [3] );\n                    if (textNodes.length)\n                    for (var i = 0, textNode; textNode = textNodes[i++]; ) {\n                        if (!this.isIgnorableWhiteSpaceNode(textNode) && rangeSelectsAnyText(range, textNode) &&\n                                this.isModifiable(textNode) && !this.getSelfOrAncestorWithClass(textNode)) {\n                            return false;\n                        }\n                    }\n                    return true;\n                }\n            },\n\n            isAppliedToRanges: function(ranges) {\n                var i = ranges.length;\n                if (i == 0) {\n                    return false;\n                }\n                while (i--) {\n                    if (!this.isAppliedToRange(ranges[i])) {\n                        return false;\n                    }\n                }\n                return true;\n            },\n\n            isAppliedToSelection: function(win) {\n                var sel = api.getSelection(win);\n                return this.isAppliedToRanges(sel.getAllRanges());\n            },\n\n            toggleRange: function(range) {\n                if (this.isAppliedToRange(range)) {\n                    this.undoToRange(range);\n                } else {\n                    this.applyToRange(range);\n                }\n            },\n\n            toggleSelection: function(win) {\n                if (this.isAppliedToSelection(win)) {\n                    this.undoToSelection(win);\n                } else {\n                    this.applyToSelection(win);\n                }\n            },\n\n            getElementsWithClassIntersectingRange: function(range) {\n                var elements = [];\n                var applier = this;\n                range.getNodes([3], function(textNode) {\n                    var el = applier.getSelfOrAncestorWithClass(textNode);\n                    if (el && !contains(elements, el)) {\n                        elements.push(el);\n                    }\n                });\n                return elements;\n            },\n\n            detach: function() {}\n        };\n\n        function createClassApplier(className, options, tagNames) {\n            return new ClassApplier(className, options, tagNames);\n        }\n\n        ClassApplier.util = {\n            hasClass: hasClass,\n            addClass: addClass,\n            removeClass: removeClass,\n            getClass: getClass,\n            hasSameClasses: haveSameClasses,\n            hasAllClasses: hasAllClasses,\n            replaceWithOwnChildren: replaceWithOwnChildrenPreservingPositions,\n            elementsHaveSameNonClassAttributes: elementsHaveSameNonClassAttributes,\n            elementHasNonClassAttributes: elementHasNonClassAttributes,\n            splitNodeAt: splitNodeAt,\n            isEditableElement: isEditableElement,\n            isEditingHost: isEditingHost,\n            isEditable: isEditable\n        };\n\n        api.CssClassApplier = api.ClassApplier = ClassApplier;\n        api.createClassApplier = createClassApplier;\n        util.createAliasForDeprecatedMethod(api, \"createCssClassApplier\", \"createClassApplier\", module);\n    });\n    \n    return rangy;\n}, this);\n"
  },
  {
    "path": "rangy-core.js",
    "content": "/**\n * Rangy, a cross-browser JavaScript range and selection library\n * https://github.com/timdown/rangy\n *\n * Copyright 2015, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3.1-dev\n * Build date: 20 May 2015\n */\n\n(function(factory, root) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n    } else if (typeof module != \"undefined\" && typeof exports == \"object\") {\n        // Node/CommonJS style\n        module.exports = factory();\n    } else {\n        // No AMD or CommonJS support so we place Rangy in (probably) the global variable\n        root.rangy = factory();\n    }\n})(function() {\n\n    var OBJECT = \"object\", FUNCTION = \"function\", UNDEFINED = \"undefined\";\n\n    // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START\n    // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.\n    var domRangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n        \"commonAncestorContainer\"];\n\n    // Minimal set of methods required for DOM Level 2 Range compliance\n    var domRangeMethods = [\"setStart\", \"setStartBefore\", \"setStartAfter\", \"setEnd\", \"setEndBefore\",\n        \"setEndAfter\", \"collapse\", \"selectNode\", \"selectNodeContents\", \"compareBoundaryPoints\", \"deleteContents\",\n        \"extractContents\", \"cloneContents\", \"insertNode\", \"surroundContents\", \"cloneRange\", \"toString\", \"detach\"];\n\n    var textRangeProperties = [\"boundingHeight\", \"boundingLeft\", \"boundingTop\", \"boundingWidth\", \"htmlText\", \"text\"];\n\n    // Subset of TextRange's full set of methods that we're interested in\n    var textRangeMethods = [\"collapse\", \"compareEndPoints\", \"duplicate\", \"moveToElementText\", \"parentElement\", \"select\",\n        \"setEndPoint\", \"getBoundingClientRect\"];\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Trio of functions taken from Peter Michaux's article:\n    // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting\n    function isHostMethod(o, p) {\n        var t = typeof o[p];\n        return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == \"unknown\";\n    }\n\n    function isHostObject(o, p) {\n        return !!(typeof o[p] == OBJECT && o[p]);\n    }\n\n    function isHostProperty(o, p) {\n        return typeof o[p] != UNDEFINED;\n    }\n\n    // Creates a convenience function to save verbose repeated calls to tests functions\n    function createMultiplePropertyTest(testFunc) {\n        return function(o, props) {\n            var i = props.length;\n            while (i--) {\n                if (!testFunc(o, props[i])) {\n                    return false;\n                }\n            }\n            return true;\n        };\n    }\n\n    // Next trio of functions are a convenience to save verbose repeated calls to previous two functions\n    var areHostMethods = createMultiplePropertyTest(isHostMethod);\n    var areHostObjects = createMultiplePropertyTest(isHostObject);\n    var areHostProperties = createMultiplePropertyTest(isHostProperty);\n\n    function isTextRange(range) {\n        return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);\n    }\n\n    function getBody(doc) {\n        return isHostObject(doc, \"body\") ? doc.body : doc.getElementsByTagName(\"body\")[0];\n    }\n\n    var forEach = [].forEach ?\n        function(arr, func) {\n            arr.forEach(func);\n        } :\n        function(arr, func) {\n            for (var i = 0, len = arr.length; i < len; ++i) {\n                func(arr[i], i);\n            }\n        };\n\n    var modules = {};\n\n    var isBrowser = (typeof window != UNDEFINED && typeof document != UNDEFINED);\n\n    var util = {\n        isHostMethod: isHostMethod,\n        isHostObject: isHostObject,\n        isHostProperty: isHostProperty,\n        areHostMethods: areHostMethods,\n        areHostObjects: areHostObjects,\n        areHostProperties: areHostProperties,\n        isTextRange: isTextRange,\n        getBody: getBody,\n        forEach: forEach\n    };\n\n    var api = {\n        version: \"1.3.1-dev\",\n        initialized: false,\n        isBrowser: isBrowser,\n        supported: true,\n        util: util,\n        features: {},\n        modules: modules,\n        config: {\n            alertOnFail: false,\n            alertOnWarn: false,\n            preferTextRange: false,\n            autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize\n        }\n    };\n\n    function consoleLog(msg) {\n        if (typeof console != UNDEFINED && isHostMethod(console, \"log\")) {\n            console.log(msg);\n        }\n    }\n\n    function alertOrLog(msg, shouldAlert) {\n        if (isBrowser && shouldAlert) {\n            alert(msg);\n        } else  {\n            consoleLog(msg);\n        }\n    }\n\n    function fail(reason) {\n        api.initialized = true;\n        api.supported = false;\n        alertOrLog(\"Rangy is not supported in this environment. Reason: \" + reason, api.config.alertOnFail);\n    }\n\n    api.fail = fail;\n\n    function warn(msg) {\n        alertOrLog(\"Rangy warning: \" + msg, api.config.alertOnWarn);\n    }\n\n    api.warn = warn;\n\n    // Add utility extend() method\n    var extend;\n    if ({}.hasOwnProperty) {\n        util.extend = extend = function(obj, props, deep) {\n            var o, p;\n            for (var i in props) {\n                if (props.hasOwnProperty(i)) {\n                    o = obj[i];\n                    p = props[i];\n                    if (deep && o !== null && typeof o == \"object\" && p !== null && typeof p == \"object\") {\n                        extend(o, p, true);\n                    }\n                    obj[i] = p;\n                }\n            }\n            // Special case for toString, which does not show up in for...in loops in IE <= 8\n            if (props.hasOwnProperty(\"toString\")) {\n                obj.toString = props.toString;\n            }\n            return obj;\n        };\n\n        util.createOptions = function(optionsParam, defaults) {\n            var options = {};\n            extend(options, defaults);\n            if (optionsParam) {\n                extend(options, optionsParam);\n            }\n            return options;\n        };\n    } else {\n        fail(\"hasOwnProperty not supported\");\n    }\n\n    // Test whether we're in a browser and bail out if not\n    if (!isBrowser) {\n        fail(\"Rangy can only run in a browser\");\n    }\n\n    // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not\n    (function() {\n        var toArray;\n\n        if (isBrowser) {\n            var el = document.createElement(\"div\");\n            el.appendChild(document.createElement(\"span\"));\n            var slice = [].slice;\n            try {\n                if (slice.call(el.childNodes, 0)[0].nodeType == 1) {\n                    toArray = function(arrayLike) {\n                        return slice.call(arrayLike, 0);\n                    };\n                }\n            } catch (e) {}\n        }\n\n        if (!toArray) {\n            toArray = function(arrayLike) {\n                var arr = [];\n                for (var i = 0, len = arrayLike.length; i < len; ++i) {\n                    arr[i] = arrayLike[i];\n                }\n                return arr;\n            };\n        }\n\n        util.toArray = toArray;\n    })();\n\n    // Very simple event handler wrapper function that doesn't attempt to solve issues such as \"this\" handling or\n    // normalization of event properties\n    var addListener;\n    if (isBrowser) {\n        if (isHostMethod(document, \"addEventListener\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.addEventListener(eventType, listener, false);\n            };\n        } else if (isHostMethod(document, \"attachEvent\")) {\n            addListener = function(obj, eventType, listener) {\n                obj.attachEvent(\"on\" + eventType, listener);\n            };\n        } else {\n            fail(\"Document does not have required addEventListener or attachEvent method\");\n        }\n\n        util.addListener = addListener;\n    }\n\n    var initListeners = [];\n\n    function getErrorDesc(ex) {\n        return ex.message || ex.description || String(ex);\n    }\n\n    // Initialization\n    function init() {\n        if (!isBrowser || api.initialized) {\n            return;\n        }\n        var testRange;\n        var implementsDomRange = false, implementsTextRange = false;\n\n        // First, perform basic feature tests\n\n        if (isHostMethod(document, \"createRange\")) {\n            testRange = document.createRange();\n            if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {\n                implementsDomRange = true;\n            }\n        }\n\n        var body = getBody(document);\n        if (!body || body.nodeName.toLowerCase() != \"body\") {\n            fail(\"No body element found\");\n            return;\n        }\n\n        if (body && isHostMethod(body, \"createTextRange\")) {\n            testRange = body.createTextRange();\n            if (isTextRange(testRange)) {\n                implementsTextRange = true;\n            }\n        }\n\n        if (!implementsDomRange && !implementsTextRange) {\n            fail(\"Neither Range nor TextRange are available\");\n            return;\n        }\n\n        api.initialized = true;\n        api.features = {\n            implementsDomRange: implementsDomRange,\n            implementsTextRange: implementsTextRange\n        };\n\n        // Initialize modules\n        var module, errorMessage;\n        for (var moduleName in modules) {\n            if ( (module = modules[moduleName]) instanceof Module ) {\n                module.init(module, api);\n            }\n        }\n\n        // Call init listeners\n        for (var i = 0, len = initListeners.length; i < len; ++i) {\n            try {\n                initListeners[i](api);\n            } catch (ex) {\n                errorMessage = \"Rangy init listener threw an exception. Continuing. Detail: \" + getErrorDesc(ex);\n                consoleLog(errorMessage);\n            }\n        }\n    }\n\n    function deprecationNotice(deprecated, replacement, module) {\n        if (module) {\n            deprecated += \" in module \" + module.name;\n        }\n        api.warn(\"DEPRECATED: \" + deprecated + \" is deprecated. Please use \" +\n        replacement + \" instead.\");\n    }\n\n    function createAliasForDeprecatedMethod(owner, deprecated, replacement, module) {\n        owner[deprecated] = function() {\n            deprecationNotice(deprecated, replacement, module);\n            return owner[replacement].apply(owner, util.toArray(arguments));\n        };\n    }\n\n    util.deprecationNotice = deprecationNotice;\n    util.createAliasForDeprecatedMethod = createAliasForDeprecatedMethod;\n\n    // Allow external scripts to initialize this library in case it's loaded after the document has loaded\n    api.init = init;\n\n    // Execute listener immediately if already initialized\n    api.addInitListener = function(listener) {\n        if (api.initialized) {\n            listener(api);\n        } else {\n            initListeners.push(listener);\n        }\n    };\n\n    var shimListeners = [];\n\n    api.addShimListener = function(listener) {\n        shimListeners.push(listener);\n    };\n\n    function shim(win) {\n        win = win || window;\n        init();\n\n        // Notify listeners\n        for (var i = 0, len = shimListeners.length; i < len; ++i) {\n            shimListeners[i](win);\n        }\n    }\n\n    if (isBrowser) {\n        api.shim = api.createMissingNativeApi = shim;\n        createAliasForDeprecatedMethod(api, \"createMissingNativeApi\", \"shim\");\n    }\n\n    function Module(name, dependencies, initializer) {\n        this.name = name;\n        this.dependencies = dependencies;\n        this.initialized = false;\n        this.supported = false;\n        this.initializer = initializer;\n    }\n\n    Module.prototype = {\n        init: function() {\n            var requiredModuleNames = this.dependencies || [];\n            for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {\n                moduleName = requiredModuleNames[i];\n\n                requiredModule = modules[moduleName];\n                if (!requiredModule || !(requiredModule instanceof Module)) {\n                    throw new Error(\"required module '\" + moduleName + \"' not found\");\n                }\n\n                requiredModule.init();\n\n                if (!requiredModule.supported) {\n                    throw new Error(\"required module '\" + moduleName + \"' not supported\");\n                }\n            }\n\n            // Now run initializer\n            this.initializer(this);\n        },\n\n        fail: function(reason) {\n            this.initialized = true;\n            this.supported = false;\n            throw new Error(reason);\n        },\n\n        warn: function(msg) {\n            api.warn(\"Module \" + this.name + \": \" + msg);\n        },\n\n        deprecationNotice: function(deprecated, replacement) {\n            api.warn(\"DEPRECATED: \" + deprecated + \" in module \" + this.name + \" is deprecated. Please use \" +\n                replacement + \" instead\");\n        },\n\n        createError: function(msg) {\n            return new Error(\"Error in Rangy \" + this.name + \" module: \" + msg);\n        }\n    };\n\n    function createModule(name, dependencies, initFunc) {\n        var newModule = new Module(name, dependencies, function(module) {\n            if (!module.initialized) {\n                module.initialized = true;\n                try {\n                    initFunc(api, module);\n                    module.supported = true;\n                } catch (ex) {\n                    var errorMessage = \"Module '\" + name + \"' failed to load: \" + getErrorDesc(ex);\n                    consoleLog(errorMessage);\n                    if (ex.stack) {\n                        consoleLog(ex.stack);\n                    }\n                }\n            }\n        });\n        modules[name] = newModule;\n        return newModule;\n    }\n\n    api.createModule = function(name) {\n        // Allow 2 or 3 arguments (second argument is an optional array of dependencies)\n        var initFunc, dependencies;\n        if (arguments.length == 2) {\n            initFunc = arguments[1];\n            dependencies = [];\n        } else {\n            initFunc = arguments[2];\n            dependencies = arguments[1];\n        }\n\n        var module = createModule(name, dependencies, initFunc);\n\n        // Initialize the module immediately if the core is already initialized\n        if (api.initialized && api.supported) {\n            module.init();\n        }\n    };\n\n    api.createCoreModule = function(name, dependencies, initFunc) {\n        createModule(name, dependencies, initFunc);\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately\n\n    function RangePrototype() {}\n    api.RangePrototype = RangePrototype;\n    api.rangePrototype = new RangePrototype();\n\n    function SelectionPrototype() {}\n    api.selectionPrototype = new SelectionPrototype();\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // DOM utility methods used by Rangy\n    api.createCoreModule(\"DomUtil\", [], function(api, module) {\n        var UNDEF = \"undefined\";\n        var util = api.util;\n        var getBody = util.getBody;\n\n        // Perform feature tests\n        if (!util.areHostMethods(document, [\"createDocumentFragment\", \"createElement\", \"createTextNode\"])) {\n            module.fail(\"document missing a Node creation method\");\n        }\n\n        if (!util.isHostMethod(document, \"getElementsByTagName\")) {\n            module.fail(\"document missing getElementsByTagName method\");\n        }\n\n        var el = document.createElement(\"div\");\n        if (!util.areHostMethods(el, [\"insertBefore\", \"appendChild\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]))) {\n            module.fail(\"Incomplete Element implementation\");\n        }\n\n        // innerHTML is required for Range's createContextualFragment method\n        if (!util.isHostProperty(el, \"innerHTML\")) {\n            module.fail(\"Element is missing innerHTML property\");\n        }\n\n        var textNode = document.createTextNode(\"test\");\n        if (!util.areHostMethods(textNode, [\"splitText\", \"deleteData\", \"insertData\", \"appendData\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]) ||\n                !util.areHostProperties(textNode, [\"data\"]))) {\n            module.fail(\"Incomplete Text Node implementation\");\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been\n        // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that\n        // contains just the document as a single element and the value searched for is the document.\n        var arrayContains = /*Array.prototype.indexOf ?\n            function(arr, val) {\n                return arr.indexOf(val) > -1;\n            }:*/\n\n            function(arr, val) {\n                var i = arr.length;\n                while (i--) {\n                    if (arr[i] === val) {\n                        return true;\n                    }\n                }\n                return false;\n            };\n\n        // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI\n        function isHtmlNamespace(node) {\n            var ns;\n            return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == \"http://www.w3.org/1999/xhtml\");\n        }\n\n        function parentElement(node) {\n            var parent = node.parentNode;\n            return (parent.nodeType == 1) ? parent : null;\n        }\n\n        function getNodeIndex(node) {\n            var i = 0;\n            while( (node = node.previousSibling) ) {\n                ++i;\n            }\n            return i;\n        }\n\n        function getNodeLength(node) {\n            switch (node.nodeType) {\n                case 7:\n                case 10:\n                    return 0;\n                case 3:\n                case 8:\n                    return node.length;\n                default:\n                    return node.childNodes.length;\n            }\n        }\n\n        function getCommonAncestor(node1, node2) {\n            var ancestors = [], n;\n            for (n = node1; n; n = n.parentNode) {\n                ancestors.push(n);\n            }\n\n            for (n = node2; n; n = n.parentNode) {\n                if (arrayContains(ancestors, n)) {\n                    return n;\n                }\n            }\n\n            return null;\n        }\n\n        function isAncestorOf(ancestor, descendant, selfIsAncestor) {\n            var n = selfIsAncestor ? descendant : descendant.parentNode;\n            while (n) {\n                if (n === ancestor) {\n                    return true;\n                } else {\n                    n = n.parentNode;\n                }\n            }\n            return false;\n        }\n\n        function isOrIsAncestorOf(ancestor, descendant) {\n            return isAncestorOf(ancestor, descendant, true);\n        }\n\n        function getClosestAncestorIn(node, ancestor, selfIsAncestor) {\n            var p, n = selfIsAncestor ? node : node.parentNode;\n            while (n) {\n                p = n.parentNode;\n                if (p === ancestor) {\n                    return n;\n                }\n                n = p;\n            }\n            return null;\n        }\n\n        function isCharacterDataNode(node) {\n            var t = node.nodeType;\n            return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment\n        }\n\n        function isTextOrCommentNode(node) {\n            if (!node) {\n                return false;\n            }\n            var t = node.nodeType;\n            return t == 3 || t == 8 ; // Text or Comment\n        }\n\n        function insertAfter(node, precedingNode) {\n            var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode;\n            if (nextNode) {\n                parent.insertBefore(node, nextNode);\n            } else {\n                parent.appendChild(node);\n            }\n            return node;\n        }\n\n        // Note that we cannot use splitText() because it is bugridden in IE 9.\n        function splitDataNode(node, index, positionsToPreserve) {\n            var newNode = node.cloneNode(false);\n            newNode.deleteData(0, index);\n            node.deleteData(index, node.length - index);\n            insertAfter(newNode, node);\n\n            // Preserve positions\n            if (positionsToPreserve) {\n                for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                    // Handle case where position was inside the portion of node after the split point\n                    if (position.node == node && position.offset > index) {\n                        position.node = newNode;\n                        position.offset -= index;\n                    }\n                    // Handle the case where the position is a node offset within node's parent\n                    else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {\n                        ++position.offset;\n                    }\n                }\n            }\n            return newNode;\n        }\n\n        function getDocument(node) {\n            if (node.nodeType == 9) {\n                return node;\n            } else if (typeof node.ownerDocument != UNDEF) {\n                return node.ownerDocument;\n            } else if (typeof node.document != UNDEF) {\n                return node.document;\n            } else if (node.parentNode) {\n                return getDocument(node.parentNode);\n            } else {\n                throw module.createError(\"getDocument: no document found for node\");\n            }\n        }\n\n        function getWindow(node) {\n            var doc = getDocument(node);\n            if (typeof doc.defaultView != UNDEF) {\n                return doc.defaultView;\n            } else if (typeof doc.parentWindow != UNDEF) {\n                return doc.parentWindow;\n            } else {\n                throw module.createError(\"Cannot get a window object for node\");\n            }\n        }\n\n        function getIframeDocument(iframeEl) {\n            if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument;\n            } else if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow.document;\n            } else {\n                throw module.createError(\"getIframeDocument: No Document object found for iframe element\");\n            }\n        }\n\n        function getIframeWindow(iframeEl) {\n            if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow;\n            } else if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument.defaultView;\n            } else {\n                throw module.createError(\"getIframeWindow: No Window object found for iframe element\");\n            }\n        }\n\n        // This looks bad. Is it worth it?\n        function isWindow(obj) {\n            return obj && util.isHostMethod(obj, \"setTimeout\") && util.isHostObject(obj, \"document\");\n        }\n\n        function getContentDocument(obj, module, methodName) {\n            var doc;\n\n            if (!obj) {\n                doc = document;\n            }\n\n            // Test if a DOM node has been passed and obtain a document object for it if so\n            else if (util.isHostProperty(obj, \"nodeType\")) {\n                doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == \"iframe\") ?\n                    getIframeDocument(obj) : getDocument(obj);\n            }\n\n            // Test if the doc parameter appears to be a Window object\n            else if (isWindow(obj)) {\n                doc = obj.document;\n            }\n\n            if (!doc) {\n                throw module.createError(methodName + \"(): Parameter must be a Window object or DOM node\");\n            }\n\n            return doc;\n        }\n\n        function getRootContainer(node) {\n            var parent;\n            while ( (parent = node.parentNode) ) {\n                node = parent;\n            }\n            return node;\n        }\n\n        function comparePoints(nodeA, offsetA, nodeB, offsetB) {\n            // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing\n            var nodeC, root, childA, childB, n;\n            if (nodeA == nodeB) {\n                // Case 1: nodes are the same\n                return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) {\n                // Case 2: node C (container B or an ancestor) is a child node of A\n                return offsetA <= getNodeIndex(nodeC) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) {\n                // Case 3: node C (container A or an ancestor) is a child node of B\n                return getNodeIndex(nodeC) < offsetB  ? -1 : 1;\n            } else {\n                root = getCommonAncestor(nodeA, nodeB);\n                if (!root) {\n                    throw new Error(\"comparePoints error: nodes have no common ancestor\");\n                }\n\n                // Case 4: containers are siblings or descendants of siblings\n                childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true);\n                childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true);\n\n                if (childA === childB) {\n                    // This shouldn't be possible\n                    throw module.createError(\"comparePoints got to case 4 and childA and childB are the same!\");\n                } else {\n                    n = root.firstChild;\n                    while (n) {\n                        if (n === childA) {\n                            return -1;\n                        } else if (n === childB) {\n                            return 1;\n                        }\n                        n = n.nextSibling;\n                    }\n                }\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried\n        var crashyTextNodes = false;\n\n        function isBrokenNode(node) {\n            var n;\n            try {\n                n = node.parentNode;\n                return false;\n            } catch (e) {\n                return true;\n            }\n        }\n\n        (function() {\n            var el = document.createElement(\"b\");\n            el.innerHTML = \"1\";\n            var textNode = el.firstChild;\n            el.innerHTML = \"<br />\";\n            crashyTextNodes = isBrokenNode(textNode);\n\n            api.features.crashyTextNodes = crashyTextNodes;\n        })();\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        function inspectNode(node) {\n            if (!node) {\n                return \"[No node]\";\n            }\n            if (crashyTextNodes && isBrokenNode(node)) {\n                return \"[Broken node]\";\n            }\n            if (isCharacterDataNode(node)) {\n                return '\"' + node.data + '\"';\n            }\n            if (node.nodeType == 1) {\n                var idAttr = node.id ? ' id=\"' + node.id + '\"' : \"\";\n                return \"<\" + node.nodeName + idAttr + \">[index:\" + getNodeIndex(node) + \",length:\" + node.childNodes.length + \"][\" + (node.innerHTML || \"[innerHTML not supported]\").slice(0, 25) + \"]\";\n            }\n            return node.nodeName;\n        }\n\n        function fragmentFromNodeChildren(node) {\n            var fragment = getDocument(node).createDocumentFragment(), child;\n            while ( (child = node.firstChild) ) {\n                fragment.appendChild(child);\n            }\n            return fragment;\n        }\n\n        var getComputedStyleProperty;\n        if (typeof window.getComputedStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return getWindow(el).getComputedStyle(el, null)[propName];\n            };\n        } else if (typeof document.documentElement.currentStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return el.currentStyle ? el.currentStyle[propName] : \"\";\n            };\n        } else {\n            module.fail(\"No means of obtaining computed style properties found\");\n        }\n\n        function createTestElement(doc, html, contentEditable) {\n            var body = getBody(doc);\n            var el = doc.createElement(\"div\");\n            el.contentEditable = \"\" + !!contentEditable;\n            if (html) {\n                el.innerHTML = html;\n            }\n\n            // Insert the test element at the start of the body to prevent scrolling to the bottom in iOS (issue #292)\n            var bodyFirstChild = body.firstChild;\n            if (bodyFirstChild) {\n                body.insertBefore(el, bodyFirstChild);\n            } else {\n                body.appendChild(el);\n            }\n\n            return el;\n        }\n\n        function removeNode(node) {\n            return node.parentNode.removeChild(node);\n        }\n\n        function NodeIterator(root) {\n            this.root = root;\n            this._next = root;\n        }\n\n        NodeIterator.prototype = {\n            _current: null,\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                var n = this._current = this._next;\n                var child, next;\n                if (this._current) {\n                    child = n.firstChild;\n                    if (child) {\n                        this._next = child;\n                    } else {\n                        next = null;\n                        while ((n !== this.root) && !(next = n.nextSibling)) {\n                            n = n.parentNode;\n                        }\n                        this._next = next;\n                    }\n                }\n                return this._current;\n            },\n\n            detach: function() {\n                this._current = this._next = this.root = null;\n            }\n        };\n\n        function createIterator(root) {\n            return new NodeIterator(root);\n        }\n\n        function DomPosition(node, offset) {\n            this.node = node;\n            this.offset = offset;\n        }\n\n        DomPosition.prototype = {\n            equals: function(pos) {\n                return !!pos && this.node === pos.node && this.offset == pos.offset;\n            },\n\n            inspect: function() {\n                return \"[DomPosition(\" + inspectNode(this.node) + \":\" + this.offset + \")]\";\n            },\n\n            toString: function() {\n                return this.inspect();\n            }\n        };\n\n        function DOMException(codeName) {\n            this.code = this[codeName];\n            this.codeName = codeName;\n            this.message = \"DOMException: \" + this.codeName;\n        }\n\n        DOMException.prototype = {\n            INDEX_SIZE_ERR: 1,\n            HIERARCHY_REQUEST_ERR: 3,\n            WRONG_DOCUMENT_ERR: 4,\n            NO_MODIFICATION_ALLOWED_ERR: 7,\n            NOT_FOUND_ERR: 8,\n            NOT_SUPPORTED_ERR: 9,\n            INVALID_STATE_ERR: 11,\n            INVALID_NODE_TYPE_ERR: 24\n        };\n\n        DOMException.prototype.toString = function() {\n            return this.message;\n        };\n\n        api.dom = {\n            arrayContains: arrayContains,\n            isHtmlNamespace: isHtmlNamespace,\n            parentElement: parentElement,\n            getNodeIndex: getNodeIndex,\n            getNodeLength: getNodeLength,\n            getCommonAncestor: getCommonAncestor,\n            isAncestorOf: isAncestorOf,\n            isOrIsAncestorOf: isOrIsAncestorOf,\n            getClosestAncestorIn: getClosestAncestorIn,\n            isCharacterDataNode: isCharacterDataNode,\n            isTextOrCommentNode: isTextOrCommentNode,\n            insertAfter: insertAfter,\n            splitDataNode: splitDataNode,\n            getDocument: getDocument,\n            getWindow: getWindow,\n            getIframeWindow: getIframeWindow,\n            getIframeDocument: getIframeDocument,\n            getBody: getBody,\n            isWindow: isWindow,\n            getContentDocument: getContentDocument,\n            getRootContainer: getRootContainer,\n            comparePoints: comparePoints,\n            isBrokenNode: isBrokenNode,\n            inspectNode: inspectNode,\n            getComputedStyleProperty: getComputedStyleProperty,\n            createTestElement: createTestElement,\n            removeNode: removeNode,\n            fragmentFromNodeChildren: fragmentFromNodeChildren,\n            createIterator: createIterator,\n            DomPosition: DomPosition\n        };\n\n        api.DOMException = DOMException;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Pure JavaScript implementation of DOM Range\n    api.createCoreModule(\"DomRange\", [\"DomUtil\"], function(api, module) {\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DOMException = api.DOMException;\n\n        var isCharacterDataNode = dom.isCharacterDataNode;\n        var getNodeIndex = dom.getNodeIndex;\n        var isOrIsAncestorOf = dom.isOrIsAncestorOf;\n        var getDocument = dom.getDocument;\n        var comparePoints = dom.comparePoints;\n        var splitDataNode = dom.splitDataNode;\n        var getClosestAncestorIn = dom.getClosestAncestorIn;\n        var getNodeLength = dom.getNodeLength;\n        var arrayContains = dom.arrayContains;\n        var getRootContainer = dom.getRootContainer;\n        var crashyTextNodes = api.features.crashyTextNodes;\n\n        var removeNode = dom.removeNode;\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Utility functions\n\n        function isNonTextPartiallySelected(node, range) {\n            return (node.nodeType != 3) &&\n                   (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer));\n        }\n\n        function getRangeDocument(range) {\n            return range.document || getDocument(range.startContainer);\n        }\n\n        function getRangeRoot(range) {\n            return getRootContainer(range.startContainer);\n        }\n\n        function getBoundaryBeforeNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node));\n        }\n\n        function getBoundaryAfterNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node) + 1);\n        }\n\n        function insertNodeAtPosition(node, n, o) {\n            var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node;\n            if (isCharacterDataNode(n)) {\n                if (o == n.length) {\n                    dom.insertAfter(node, n);\n                } else {\n                    n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o));\n                }\n            } else if (o >= n.childNodes.length) {\n                n.appendChild(node);\n            } else {\n                n.insertBefore(node, n.childNodes[o]);\n            }\n            return firstNodeInserted;\n        }\n\n        function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) {\n            assertRangeValid(rangeA);\n            assertRangeValid(rangeB);\n\n            if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n\n            var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset),\n                endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset);\n\n            return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n        }\n\n        function cloneSubtree(iterator) {\n            var partiallySelected;\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n                partiallySelected = iterator.isPartiallySelectedSubtree();\n                node = node.cloneNode(!partiallySelected);\n                if (partiallySelected) {\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(cloneSubtree(subIterator));\n                    subIterator.detach();\n                }\n\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function iterateSubtree(rangeIterator, func, iteratorState) {\n            var it, n;\n            iteratorState = iteratorState || { stop: false };\n            for (var node, subRangeIterator; node = rangeIterator.next(); ) {\n                if (rangeIterator.isPartiallySelectedSubtree()) {\n                    if (func(node) === false) {\n                        iteratorState.stop = true;\n                        return;\n                    } else {\n                        // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of\n                        // the node selected by the Range.\n                        subRangeIterator = rangeIterator.getSubtreeIterator();\n                        iterateSubtree(subRangeIterator, func, iteratorState);\n                        subRangeIterator.detach();\n                        if (iteratorState.stop) {\n                            return;\n                        }\n                    }\n                } else {\n                    // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its\n                    // descendants\n                    it = dom.createIterator(node);\n                    while ( (n = it.next()) ) {\n                        if (func(n) === false) {\n                            iteratorState.stop = true;\n                            return;\n                        }\n                    }\n                }\n            }\n        }\n\n        function deleteSubtree(iterator) {\n            var subIterator;\n            while (iterator.next()) {\n                if (iterator.isPartiallySelectedSubtree()) {\n                    subIterator = iterator.getSubtreeIterator();\n                    deleteSubtree(subIterator);\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n            }\n        }\n\n        function extractSubtree(iterator) {\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n\n                if (iterator.isPartiallySelectedSubtree()) {\n                    node = node.cloneNode(false);\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(extractSubtree(subIterator));\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function getNodesInRange(range, nodeTypes, filter) {\n            var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex;\n            var filterExists = !!filter;\n            if (filterNodeTypes) {\n                regex = new RegExp(\"^(\" + nodeTypes.join(\"|\") + \")$\");\n            }\n\n            var nodes = [];\n            iterateSubtree(new RangeIterator(range, false), function(node) {\n                if (filterNodeTypes && !regex.test(node.nodeType)) {\n                    return;\n                }\n                if (filterExists && !filter(node)) {\n                    return;\n                }\n                // Don't include a boundary container if it is a character data node and the range does not contain any\n                // of its character data. See issue 190.\n                var sc = range.startContainer;\n                if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) {\n                    return;\n                }\n\n                var ec = range.endContainer;\n                if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) {\n                    return;\n                }\n\n                nodes.push(node);\n            });\n            return nodes;\n        }\n\n        function inspect(range) {\n            var name = (typeof range.getName == \"undefined\") ? \"Range\" : range.getName();\n            return \"[\" + name + \"(\" + dom.inspectNode(range.startContainer) + \":\" + range.startOffset + \", \" +\n                    dom.inspectNode(range.endContainer) + \":\" + range.endOffset + \")]\";\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)\n\n        function RangeIterator(range, clonePartiallySelectedTextNodes) {\n            this.range = range;\n            this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes;\n\n\n            if (!range.collapsed) {\n                this.sc = range.startContainer;\n                this.so = range.startOffset;\n                this.ec = range.endContainer;\n                this.eo = range.endOffset;\n                var root = range.commonAncestorContainer;\n\n                if (this.sc === this.ec && isCharacterDataNode(this.sc)) {\n                    this.isSingleCharacterDataNode = true;\n                    this._first = this._last = this._next = this.sc;\n                } else {\n                    this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ?\n                        this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true);\n                    this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ?\n                        this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true);\n                }\n            }\n        }\n\n        RangeIterator.prototype = {\n            _current: null,\n            _next: null,\n            _first: null,\n            _last: null,\n            isSingleCharacterDataNode: false,\n\n            reset: function() {\n                this._current = null;\n                this._next = this._first;\n            },\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                // Move to next node\n                var current = this._current = this._next;\n                if (current) {\n                    this._next = (current !== this._last) ? current.nextSibling : null;\n\n                    // Check for partially selected text nodes\n                    if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) {\n                        if (current === this.ec) {\n                            (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo);\n                        }\n                        if (this._current === this.sc) {\n                            (current = current.cloneNode(true)).deleteData(0, this.so);\n                        }\n                    }\n                }\n\n                return current;\n            },\n\n            remove: function() {\n                var current = this._current, start, end;\n\n                if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) {\n                    start = (current === this.sc) ? this.so : 0;\n                    end = (current === this.ec) ? this.eo : current.length;\n                    if (start != end) {\n                        current.deleteData(start, end - start);\n                    }\n                } else {\n                    if (current.parentNode) {\n                        removeNode(current);\n                    } else {\n                    }\n                }\n            },\n\n            // Checks if the current node is partially selected\n            isPartiallySelectedSubtree: function() {\n                var current = this._current;\n                return isNonTextPartiallySelected(current, this.range);\n            },\n\n            getSubtreeIterator: function() {\n                var subRange;\n                if (this.isSingleCharacterDataNode) {\n                    subRange = this.range.cloneRange();\n                    subRange.collapse(false);\n                } else {\n                    subRange = new Range(getRangeDocument(this.range));\n                    var current = this._current;\n                    var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current);\n\n                    if (isOrIsAncestorOf(current, this.sc)) {\n                        startContainer = this.sc;\n                        startOffset = this.so;\n                    }\n                    if (isOrIsAncestorOf(current, this.ec)) {\n                        endContainer = this.ec;\n                        endOffset = this.eo;\n                    }\n\n                    updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset);\n                }\n                return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes);\n            },\n\n            detach: function() {\n                this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null;\n            }\n        };\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10];\n        var rootContainerNodeTypes = [2, 9, 11];\n        var readonlyNodeTypes = [5, 6, 10, 12];\n        var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11];\n        var surroundNodeTypes = [1, 3, 4, 5, 7, 8];\n\n        function createAncestorFinder(nodeTypes) {\n            return function(node, selfIsAncestor) {\n                var t, n = selfIsAncestor ? node : node.parentNode;\n                while (n) {\n                    t = n.nodeType;\n                    if (arrayContains(nodeTypes, t)) {\n                        return n;\n                    }\n                    n = n.parentNode;\n                }\n                return null;\n            };\n        }\n\n        var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] );\n        var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes);\n        var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] );\n\n        function assertNoDocTypeNotationEntityAncestor(node, allowSelf) {\n            if (getDocTypeNotationEntityAncestor(node, allowSelf)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidNodeType(node, invalidTypes) {\n            if (!arrayContains(invalidTypes, node.nodeType)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidOffset(node, offset) {\n            if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            }\n        }\n\n        function assertSameDocumentOrFragment(node1, node2) {\n            if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        function assertNodeNotReadOnly(node) {\n            if (getReadonlyAncestor(node, true)) {\n                throw new DOMException(\"NO_MODIFICATION_ALLOWED_ERR\");\n            }\n        }\n\n        function assertNode(node, codeName) {\n            if (!node) {\n                throw new DOMException(codeName);\n            }\n        }\n\n        function isValidOffset(node, offset) {\n            return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length);\n        }\n\n        function isRangeValid(range) {\n            return (!!range.startContainer && !!range.endContainer &&\n                    !(crashyTextNodes && (dom.isBrokenNode(range.startContainer) || dom.isBrokenNode(range.endContainer))) &&\n                    getRootContainer(range.startContainer) == getRootContainer(range.endContainer) &&\n                    isValidOffset(range.startContainer, range.startOffset) &&\n                    isValidOffset(range.endContainer, range.endOffset));\n        }\n\n        function assertRangeValid(range) {\n            if (!isRangeValid(range)) {\n                throw new Error(\"Range error: Range is not valid. This usually happens after DOM mutation. Range: (\" + range.inspect() + \")\");\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test the browser's innerHTML support to decide how to implement createContextualFragment\n        var styleEl = document.createElement(\"style\");\n        var htmlParsingConforms = false;\n        try {\n            styleEl.innerHTML = \"<b>x</b>\";\n            htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node\n        } catch (e) {\n            // IE 6 and 7 throw\n        }\n\n        api.features.htmlParsingConforms = htmlParsingConforms;\n\n        var createContextualFragment = htmlParsingConforms ?\n\n            // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See\n            // discussion and base code for this implementation at issue 67.\n            // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface\n            // Thanks to Aleks Williams.\n            function(fragmentStr) {\n                // \"Let node the context object's start's node.\"\n                var node = this.startContainer;\n                var doc = getDocument(node);\n\n                // \"If the context object's start's node is null, raise an INVALID_STATE_ERR\n                // exception and abort these steps.\"\n                if (!node) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // \"Let element be as follows, depending on node's interface:\"\n                // Document, Document Fragment: null\n                var el = null;\n\n                // \"Element: node\"\n                if (node.nodeType == 1) {\n                    el = node;\n\n                // \"Text, Comment: node's parentElement\"\n                } else if (isCharacterDataNode(node)) {\n                    el = dom.parentElement(node);\n                }\n\n                // \"If either element is null or element's ownerDocument is an HTML document\n                // and element's local name is \"html\" and element's namespace is the HTML\n                // namespace\"\n                if (el === null || (\n                    el.nodeName == \"HTML\" &&\n                    dom.isHtmlNamespace(getDocument(el).documentElement) &&\n                    dom.isHtmlNamespace(el)\n                )) {\n\n                // \"let element be a new Element with \"body\" as its local name and the HTML\n                // namespace as its namespace.\"\"\n                    el = doc.createElement(\"body\");\n                } else {\n                    el = el.cloneNode(false);\n                }\n\n                // \"If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm.\"\n                // \"If the node's document is an XML document: Invoke the XML fragment parsing algorithm.\"\n                // \"In either case, the algorithm must be invoked with fragment as the input\n                // and element as the context element.\"\n                el.innerHTML = fragmentStr;\n\n                // \"If this raises an exception, then abort these steps. Otherwise, let new\n                // children be the nodes returned.\"\n\n                // \"Let fragment be a new DocumentFragment.\"\n                // \"Append all new children to fragment.\"\n                // \"Return fragment.\"\n                return dom.fragmentFromNodeChildren(el);\n            } :\n\n            // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that\n            // previous versions of Rangy used (with the exception of using a body element rather than a div)\n            function(fragmentStr) {\n                var doc = getRangeDocument(this);\n                var el = doc.createElement(\"body\");\n                el.innerHTML = fragmentStr;\n\n                return dom.fragmentFromNodeChildren(el);\n            };\n\n        function splitRangeBoundaries(range, positionsToPreserve) {\n            assertRangeValid(range);\n\n            var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset;\n            var startEndSame = (sc === ec);\n\n            if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) {\n                splitDataNode(ec, eo, positionsToPreserve);\n            }\n\n            if (isCharacterDataNode(sc) && so > 0 && so < sc.length) {\n                sc = splitDataNode(sc, so, positionsToPreserve);\n                if (startEndSame) {\n                    eo -= so;\n                    ec = sc;\n                } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) {\n                    eo++;\n                }\n                so = 0;\n            }\n            range.setStartAndEnd(sc, so, ec, eo);\n        }\n\n        function rangeToHtml(range) {\n            assertRangeValid(range);\n            var container = range.commonAncestorContainer.parentNode.cloneNode(false);\n            container.appendChild( range.cloneContents() );\n            return container.innerHTML;\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var rangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n            \"commonAncestorContainer\"];\n\n        var s2s = 0, s2e = 1, e2e = 2, e2s = 3;\n        var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3;\n\n        util.extend(api.rangePrototype, {\n            compareBoundaryPoints: function(how, range) {\n                assertRangeValid(this);\n                assertSameDocumentOrFragment(this.startContainer, range.startContainer);\n\n                var nodeA, offsetA, nodeB, offsetB;\n                var prefixA = (how == e2s || how == s2s) ? \"start\" : \"end\";\n                var prefixB = (how == s2e || how == s2s) ? \"start\" : \"end\";\n                nodeA = this[prefixA + \"Container\"];\n                offsetA = this[prefixA + \"Offset\"];\n                nodeB = range[prefixB + \"Container\"];\n                offsetB = range[prefixB + \"Offset\"];\n                return comparePoints(nodeA, offsetA, nodeB, offsetB);\n            },\n\n            insertNode: function(node) {\n                assertRangeValid(this);\n                assertValidNodeType(node, insertableNodeTypes);\n                assertNodeNotReadOnly(this.startContainer);\n\n                if (isOrIsAncestorOf(node, this.startContainer)) {\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n\n                // No check for whether the container of the start of the Range is of a type that does not allow\n                // children of the type of node: the browser's DOM implementation should do this for us when we attempt\n                // to add the node\n\n                var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                this.setStartBefore(firstNodeInserted);\n            },\n\n            cloneContents: function() {\n                assertRangeValid(this);\n\n                var clone, frag;\n                if (this.collapsed) {\n                    return getRangeDocument(this).createDocumentFragment();\n                } else {\n                    if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) {\n                        clone = this.startContainer.cloneNode(true);\n                        clone.data = clone.data.slice(this.startOffset, this.endOffset);\n                        frag = getRangeDocument(this).createDocumentFragment();\n                        frag.appendChild(clone);\n                        return frag;\n                    } else {\n                        var iterator = new RangeIterator(this, true);\n                        clone = cloneSubtree(iterator);\n                        iterator.detach();\n                    }\n                    return clone;\n                }\n            },\n\n            canSurroundContents: function() {\n                assertRangeValid(this);\n                assertNodeNotReadOnly(this.startContainer);\n                assertNodeNotReadOnly(this.endContainer);\n\n                // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                // no non-text nodes.\n                var iterator = new RangeIterator(this, true);\n                var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) ||\n                        (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                iterator.detach();\n                return !boundariesInvalid;\n            },\n\n            surroundContents: function(node) {\n                assertValidNodeType(node, surroundNodeTypes);\n\n                if (!this.canSurroundContents()) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // Extract the contents\n                var content = this.extractContents();\n\n                // Clear the children of the node\n                if (node.hasChildNodes()) {\n                    while (node.lastChild) {\n                        node.removeChild(node.lastChild);\n                    }\n                }\n\n                // Insert the new node and add the extracted contents\n                insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                node.appendChild(content);\n\n                this.selectNode(node);\n            },\n\n            cloneRange: function() {\n                assertRangeValid(this);\n                var range = new Range(getRangeDocument(this));\n                var i = rangeProperties.length, prop;\n                while (i--) {\n                    prop = rangeProperties[i];\n                    range[prop] = this[prop];\n                }\n                return range;\n            },\n\n            toString: function() {\n                assertRangeValid(this);\n                var sc = this.startContainer;\n                if (sc === this.endContainer && isCharacterDataNode(sc)) {\n                    return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : \"\";\n                } else {\n                    var textParts = [], iterator = new RangeIterator(this, true);\n                    iterateSubtree(iterator, function(node) {\n                        // Accept only text or CDATA nodes, not comments\n                        if (node.nodeType == 3 || node.nodeType == 4) {\n                            textParts.push(node.data);\n                        }\n                    });\n                    iterator.detach();\n                    return textParts.join(\"\");\n                }\n            },\n\n            // The methods below are all non-standard. The following batch were introduced by Mozilla but have since\n            // been removed from Mozilla.\n\n            compareNode: function(node) {\n                assertRangeValid(this);\n\n                var parent = node.parentNode;\n                var nodeIndex = getNodeIndex(node);\n\n                if (!parent) {\n                    throw new DOMException(\"NOT_FOUND_ERR\");\n                }\n\n                var startComparison = this.comparePoint(parent, nodeIndex),\n                    endComparison = this.comparePoint(parent, nodeIndex + 1);\n\n                if (startComparison < 0) { // Node starts before\n                    return (endComparison > 0) ? n_b_a : n_b;\n                } else {\n                    return (endComparison > 0) ? n_a : n_i;\n                }\n            },\n\n            comparePoint: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) {\n                    return -1;\n                } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) {\n                    return 1;\n                }\n                return 0;\n            },\n\n            createContextualFragment: createContextualFragment,\n\n            toHtml: function() {\n                return rangeToHtml(this);\n            },\n\n            // touchingIsIntersecting determines whether this method considers a node that borders a range intersects\n            // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default)\n            intersectsNode: function(node, touchingIsIntersecting) {\n                assertRangeValid(this);\n                if (getRootContainer(node) != getRangeRoot(this)) {\n                    return false;\n                }\n\n                var parent = node.parentNode, offset = getNodeIndex(node);\n                if (!parent) {\n                    return true;\n                }\n\n                var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset),\n                    endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset);\n\n                return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n            },\n\n            isPointInRange: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) &&\n                       (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0);\n            },\n\n            // The methods below are non-standard and invented by me.\n\n            // Sharing a boundary start-to-end or end-to-start does not count as intersection.\n            intersectsRange: function(range) {\n                return rangesIntersect(this, range, false);\n            },\n\n            // Sharing a boundary start-to-end or end-to-start does count as intersection.\n            intersectsOrTouchesRange: function(range) {\n                return rangesIntersect(this, range, true);\n            },\n\n            intersection: function(range) {\n                if (this.intersectsRange(range)) {\n                    var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset),\n                        endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset);\n\n                    var intersectionRange = this.cloneRange();\n                    if (startComparison == -1) {\n                        intersectionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (endComparison == 1) {\n                        intersectionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return intersectionRange;\n                }\n                return null;\n            },\n\n            union: function(range) {\n                if (this.intersectsOrTouchesRange(range)) {\n                    var unionRange = this.cloneRange();\n                    if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) {\n                        unionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) {\n                        unionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return unionRange;\n                } else {\n                    throw new DOMException(\"Ranges do not intersect\");\n                }\n            },\n\n            containsNode: function(node, allowPartial) {\n                if (allowPartial) {\n                    return this.intersectsNode(node, false);\n                } else {\n                    return this.compareNode(node) == n_i;\n                }\n            },\n\n            containsNodeContents: function(node) {\n                return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0;\n            },\n\n            containsRange: function(range) {\n                var intersection = this.intersection(range);\n                return intersection !== null && range.equals(intersection);\n            },\n\n            containsNodeText: function(node) {\n                var nodeRange = this.cloneRange();\n                nodeRange.selectNode(node);\n                var textNodes = nodeRange.getNodes([3]);\n                if (textNodes.length > 0) {\n                    nodeRange.setStart(textNodes[0], 0);\n                    var lastTextNode = textNodes.pop();\n                    nodeRange.setEnd(lastTextNode, lastTextNode.length);\n                    return this.containsRange(nodeRange);\n                } else {\n                    return this.containsNodeContents(node);\n                }\n            },\n\n            getNodes: function(nodeTypes, filter) {\n                assertRangeValid(this);\n                return getNodesInRange(this, nodeTypes, filter);\n            },\n\n            getDocument: function() {\n                return getRangeDocument(this);\n            },\n\n            collapseBefore: function(node) {\n                this.setEndBefore(node);\n                this.collapse(false);\n            },\n\n            collapseAfter: function(node) {\n                this.setStartAfter(node);\n                this.collapse(true);\n            },\n\n            getBookmark: function(containerNode) {\n                var doc = getRangeDocument(this);\n                var preSelectionRange = api.createRange(doc);\n                containerNode = containerNode || dom.getBody(doc);\n                preSelectionRange.selectNodeContents(containerNode);\n                var range = this.intersection(preSelectionRange);\n                var start = 0, end = 0;\n                if (range) {\n                    preSelectionRange.setEnd(range.startContainer, range.startOffset);\n                    start = preSelectionRange.toString().length;\n                    end = start + range.toString().length;\n                }\n\n                return {\n                    start: start,\n                    end: end,\n                    containerNode: containerNode\n                };\n            },\n\n            moveToBookmark: function(bookmark) {\n                var containerNode = bookmark.containerNode;\n                var charIndex = 0;\n                this.setStart(containerNode, 0);\n                this.collapse(true);\n                var nodeStack = [containerNode], node, foundStart = false, stop = false;\n                var nextCharIndex, i, childNodes;\n\n                while (!stop && (node = nodeStack.pop())) {\n                    if (node.nodeType == 3) {\n                        nextCharIndex = charIndex + node.length;\n                        if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) {\n                            this.setStart(node, bookmark.start - charIndex);\n                            foundStart = true;\n                        }\n                        if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) {\n                            this.setEnd(node, bookmark.end - charIndex);\n                            stop = true;\n                        }\n                        charIndex = nextCharIndex;\n                    } else {\n                        childNodes = node.childNodes;\n                        i = childNodes.length;\n                        while (i--) {\n                            nodeStack.push(childNodes[i]);\n                        }\n                    }\n                }\n            },\n\n            getName: function() {\n                return \"DomRange\";\n            },\n\n            equals: function(range) {\n                return Range.rangesEqual(this, range);\n            },\n\n            isValid: function() {\n                return isRangeValid(this);\n            },\n\n            inspect: function() {\n                return inspect(this);\n            },\n\n            detach: function() {\n                // In DOM4, detach() is now a no-op.\n            }\n        });\n\n        function copyComparisonConstantsToObject(obj) {\n            obj.START_TO_START = s2s;\n            obj.START_TO_END = s2e;\n            obj.END_TO_END = e2e;\n            obj.END_TO_START = e2s;\n\n            obj.NODE_BEFORE = n_b;\n            obj.NODE_AFTER = n_a;\n            obj.NODE_BEFORE_AND_AFTER = n_b_a;\n            obj.NODE_INSIDE = n_i;\n        }\n\n        function copyComparisonConstants(constructor) {\n            copyComparisonConstantsToObject(constructor);\n            copyComparisonConstantsToObject(constructor.prototype);\n        }\n\n        function createRangeContentRemover(remover, boundaryUpdater) {\n            return function() {\n                assertRangeValid(this);\n\n                var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer;\n\n                var iterator = new RangeIterator(this, true);\n\n                // Work out where to position the range after content removal\n                var node, boundary;\n                if (sc !== root) {\n                    node = getClosestAncestorIn(sc, root, true);\n                    boundary = getBoundaryAfterNode(node);\n                    sc = boundary.node;\n                    so = boundary.offset;\n                }\n\n                // Check none of the range is read-only\n                iterateSubtree(iterator, assertNodeNotReadOnly);\n\n                iterator.reset();\n\n                // Remove the content\n                var returnValue = remover(iterator);\n                iterator.detach();\n\n                // Move to the new position\n                boundaryUpdater(this, sc, so, sc, so);\n\n                return returnValue;\n            };\n        }\n\n        function createPrototypeRange(constructor, boundaryUpdater) {\n            function createBeforeAfterNodeSetter(isBefore, isStart) {\n                return function(node) {\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n                    assertValidNodeType(getRootContainer(node), rootContainerNodeTypes);\n\n                    var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node);\n                    (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset);\n                };\n            }\n\n            function setRangeStart(range, node, offset) {\n                var ec = range.endContainer, eo = range.endOffset;\n                if (node !== range.startContainer || offset !== range.startOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) {\n                        ec = node;\n                        eo = offset;\n                    }\n                    boundaryUpdater(range, node, offset, ec, eo);\n                }\n            }\n\n            function setRangeEnd(range, node, offset) {\n                var sc = range.startContainer, so = range.startOffset;\n                if (node !== range.endContainer || offset !== range.endOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) {\n                        sc = node;\n                        so = offset;\n                    }\n                    boundaryUpdater(range, sc, so, node, offset);\n                }\n            }\n\n            // Set up inheritance\n            var F = function() {};\n            F.prototype = api.rangePrototype;\n            constructor.prototype = new F();\n\n            util.extend(constructor.prototype, {\n                setStart: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeStart(this, node, offset);\n                },\n\n                setEnd: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeEnd(this, node, offset);\n                },\n\n                /**\n                 * Convenience method to set a range's start and end boundaries. Overloaded as follows:\n                 * - Two parameters (node, offset) creates a collapsed range at that position\n                 * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at\n                 *   startOffset and ending at endOffset\n                 * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in\n                 *   startNode and ending at endOffset in endNode\n                 */\n                setStartAndEnd: function() {\n                    var args = arguments;\n                    var sc = args[0], so = args[1], ec = sc, eo = so;\n\n                    switch (args.length) {\n                        case 3:\n                            eo = args[2];\n                            break;\n                        case 4:\n                            ec = args[2];\n                            eo = args[3];\n                            break;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n\n                setBoundary: function(node, offset, isStart) {\n                    this[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                },\n\n                setStartBefore: createBeforeAfterNodeSetter(true, true),\n                setStartAfter: createBeforeAfterNodeSetter(false, true),\n                setEndBefore: createBeforeAfterNodeSetter(true, false),\n                setEndAfter: createBeforeAfterNodeSetter(false, false),\n\n                collapse: function(isStart) {\n                    assertRangeValid(this);\n                    if (isStart) {\n                        boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset);\n                    } else {\n                        boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset);\n                    }\n                },\n\n                selectNodeContents: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n\n                    boundaryUpdater(this, node, 0, node, getNodeLength(node));\n                },\n\n                selectNode: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, false);\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n\n                    var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node);\n                    boundaryUpdater(this, start.node, start.offset, end.node, end.offset);\n                },\n\n                extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater),\n\n                deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater),\n\n                canSurroundContents: function() {\n                    assertRangeValid(this);\n                    assertNodeNotReadOnly(this.startContainer);\n                    assertNodeNotReadOnly(this.endContainer);\n\n                    // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                    // no non-text nodes.\n                    var iterator = new RangeIterator(this, true);\n                    var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) ||\n                            (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                    iterator.detach();\n                    return !boundariesInvalid;\n                },\n\n                splitBoundaries: function() {\n                    splitRangeBoundaries(this);\n                },\n\n                splitBoundariesPreservingPositions: function(positionsToPreserve) {\n                    splitRangeBoundaries(this, positionsToPreserve);\n                },\n\n                normalizeBoundaries: function() {\n                    assertRangeValid(this);\n\n                    var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset;\n\n                    var mergeForward = function(node) {\n                        var sibling = node.nextSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            ec = node;\n                            eo = node.length;\n                            node.appendData(sibling.data);\n                            removeNode(sibling);\n                        }\n                    };\n\n                    var mergeBackward = function(node) {\n                        var sibling = node.previousSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            sc = node;\n                            var nodeLength = node.length;\n                            so = sibling.length;\n                            node.insertData(0, sibling.data);\n                            removeNode(sibling);\n                            if (sc == ec) {\n                                eo += so;\n                                ec = sc;\n                            } else if (ec == node.parentNode) {\n                                var nodeIndex = getNodeIndex(node);\n                                if (eo == nodeIndex) {\n                                    ec = node;\n                                    eo = nodeLength;\n                                } else if (eo > nodeIndex) {\n                                    eo--;\n                                }\n                            }\n                        }\n                    };\n\n                    var normalizeStart = true;\n                    var sibling;\n\n                    if (isCharacterDataNode(ec)) {\n                        if (eo == ec.length) {\n                            mergeForward(ec);\n                        } else if (eo == 0) {\n                            sibling = ec.previousSibling;\n                            if (sibling && sibling.nodeType == ec.nodeType) {\n                                eo = sibling.length;\n                                if (sc == ec) {\n                                    normalizeStart = false;\n                                }\n                                sibling.appendData(ec.data);\n                                removeNode(ec);\n                                ec = sibling;\n                            }\n                        }\n                    } else {\n                        if (eo > 0) {\n                            var endNode = ec.childNodes[eo - 1];\n                            if (endNode && isCharacterDataNode(endNode)) {\n                                mergeForward(endNode);\n                            }\n                        }\n                        normalizeStart = !this.collapsed;\n                    }\n\n                    if (normalizeStart) {\n                        if (isCharacterDataNode(sc)) {\n                            if (so == 0) {\n                                mergeBackward(sc);\n                            } else if (so == sc.length) {\n                                sibling = sc.nextSibling;\n                                if (sibling && sibling.nodeType == sc.nodeType) {\n                                    if (ec == sibling) {\n                                        ec = sc;\n                                        eo += sc.length;\n                                    }\n                                    sc.appendData(sibling.data);\n                                    removeNode(sibling);\n                                }\n                            }\n                        } else {\n                            if (so < sc.childNodes.length) {\n                                var startNode = sc.childNodes[so];\n                                if (startNode && isCharacterDataNode(startNode)) {\n                                    mergeBackward(startNode);\n                                }\n                            }\n                        }\n                    } else {\n                        sc = ec;\n                        so = eo;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n\n                collapseToPoint: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n                    this.setStartAndEnd(node, offset);\n                }\n            });\n\n            copyComparisonConstants(constructor);\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Updates commonAncestorContainer and collapsed after boundary change\n        function updateCollapsedAndCommonAncestor(range) {\n            range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n            range.commonAncestorContainer = range.collapsed ?\n                range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer);\n        }\n\n        function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) {\n            range.startContainer = startContainer;\n            range.startOffset = startOffset;\n            range.endContainer = endContainer;\n            range.endOffset = endOffset;\n            range.document = dom.getDocument(startContainer);\n\n            updateCollapsedAndCommonAncestor(range);\n        }\n\n        function Range(doc) {\n            this.startContainer = doc;\n            this.startOffset = 0;\n            this.endContainer = doc;\n            this.endOffset = 0;\n            this.document = doc;\n            updateCollapsedAndCommonAncestor(this);\n        }\n\n        createPrototypeRange(Range, updateBoundaries);\n\n        util.extend(Range, {\n            rangeProperties: rangeProperties,\n            RangeIterator: RangeIterator,\n            copyComparisonConstants: copyComparisonConstants,\n            createPrototypeRange: createPrototypeRange,\n            inspect: inspect,\n            toHtml: rangeToHtml,\n            getRangeDocument: getRangeDocument,\n            rangesEqual: function(r1, r2) {\n                return r1.startContainer === r2.startContainer &&\n                    r1.startOffset === r2.startOffset &&\n                    r1.endContainer === r2.endContainer &&\n                    r1.endOffset === r2.endOffset;\n            }\n        });\n\n        api.DomRange = Range;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wrappers for the browser's native DOM Range and/or TextRange implementation\n    api.createCoreModule(\"WrappedRange\", [\"DomRange\"], function(api, module) {\n        var WrappedRange, WrappedTextRange;\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DomRange = api.DomRange;\n        var getBody = dom.getBody;\n        var getContentDocument = dom.getContentDocument;\n        var isCharacterDataNode = dom.isCharacterDataNode;\n\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        if (api.features.implementsDomRange) {\n            // This is a wrapper around the browser's native DOM Range. It has two aims:\n            // - Provide workarounds for specific browser bugs\n            // - provide convenient extensions, which are inherited from Rangy's DomRange\n\n            (function() {\n                var rangeProto;\n                var rangeProperties = DomRange.rangeProperties;\n\n                function updateRangeProperties(range) {\n                    var i = rangeProperties.length, prop;\n                    while (i--) {\n                        prop = rangeProperties[i];\n                        range[prop] = range.nativeRange[prop];\n                    }\n                    // Fix for broken collapsed property in IE 9.\n                    range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n                }\n\n                function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) {\n                    var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);\n                    var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);\n                    var nativeRangeDifferent = !range.equals(range.nativeRange);\n\n                    // Always set both boundaries for the benefit of IE9 (see issue 35)\n                    if (startMoved || endMoved || nativeRangeDifferent) {\n                        range.setEnd(endContainer, endOffset);\n                        range.setStart(startContainer, startOffset);\n                    }\n                }\n\n                var createBeforeAfterNodeSetter;\n\n                WrappedRange = function(range) {\n                    if (!range) {\n                        throw module.createError(\"WrappedRange: Range must be specified\");\n                    }\n                    this.nativeRange = range;\n                    updateRangeProperties(this);\n                };\n\n                DomRange.createPrototypeRange(WrappedRange, updateNativeRange);\n\n                rangeProto = WrappedRange.prototype;\n\n                rangeProto.selectNode = function(node) {\n                    this.nativeRange.selectNode(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneContents = function() {\n                    return this.nativeRange.cloneContents();\n                };\n\n                // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,\n                // insertNode() is never delegated to the native range.\n\n                rangeProto.surroundContents = function(node) {\n                    this.nativeRange.surroundContents(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.collapse = function(isStart) {\n                    this.nativeRange.collapse(isStart);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneRange = function() {\n                    return new WrappedRange(this.nativeRange.cloneRange());\n                };\n\n                rangeProto.refresh = function() {\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.toString = function() {\n                    return this.nativeRange.toString();\n                };\n\n                // Create test range and node for feature detection\n\n                var testTextNode = document.createTextNode(\"test\");\n                getBody(document).appendChild(testTextNode);\n                var range = document.createRange();\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and\n                // correct for it\n\n                range.setStart(testTextNode, 0);\n                range.setEnd(testTextNode, 0);\n\n                try {\n                    range.setStart(testTextNode, 1);\n\n                    rangeProto.setStart = function(node, offset) {\n                        this.nativeRange.setStart(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        this.nativeRange.setEnd(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name) {\n                        return function(node) {\n                            this.nativeRange[name](node);\n                            updateRangeProperties(this);\n                        };\n                    };\n\n                } catch(ex) {\n\n                    rangeProto.setStart = function(node, offset) {\n                        try {\n                            this.nativeRange.setStart(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setEnd(node, offset);\n                            this.nativeRange.setStart(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        try {\n                            this.nativeRange.setEnd(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setStart(node, offset);\n                            this.nativeRange.setEnd(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name, oppositeName) {\n                        return function(node) {\n                            try {\n                                this.nativeRange[name](node);\n                            } catch (ex) {\n                                this.nativeRange[oppositeName](node);\n                                this.nativeRange[name](node);\n                            }\n                            updateRangeProperties(this);\n                        };\n                    };\n                }\n\n                rangeProto.setStartBefore = createBeforeAfterNodeSetter(\"setStartBefore\", \"setEndBefore\");\n                rangeProto.setStartAfter = createBeforeAfterNodeSetter(\"setStartAfter\", \"setEndAfter\");\n                rangeProto.setEndBefore = createBeforeAfterNodeSetter(\"setEndBefore\", \"setStartBefore\");\n                rangeProto.setEndAfter = createBeforeAfterNodeSetter(\"setEndAfter\", \"setStartAfter\");\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing\n                // whether the native implementation can be trusted\n                rangeProto.selectNodeContents = function(node) {\n                    this.setStartAndEnd(node, 0, dom.getNodeLength(node));\n                };\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for\n                // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738\n\n                range.selectNodeContents(testTextNode);\n                range.setEnd(testTextNode, 3);\n\n                var range2 = document.createRange();\n                range2.selectNodeContents(testTextNode);\n                range2.setEnd(testTextNode, 4);\n                range2.setStart(testTextNode, 2);\n\n                if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &&\n                        range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {\n                    // This is the wrong way round, so correct for it\n\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        range = range.nativeRange || range;\n                        if (type == range.START_TO_END) {\n                            type = range.END_TO_START;\n                        } else if (type == range.END_TO_START) {\n                            type = range.START_TO_END;\n                        }\n                        return this.nativeRange.compareBoundaryPoints(type, range);\n                    };\n                } else {\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for IE deleteContents() and extractContents() bug and correct it. See issue 107.\n\n                var el = document.createElement(\"div\");\n                el.innerHTML = \"123\";\n                var textNode = el.firstChild;\n                var body = getBody(document);\n                body.appendChild(el);\n\n                range.setStart(textNode, 1);\n                range.setEnd(textNode, 2);\n                range.deleteContents();\n\n                if (textNode.data == \"13\") {\n                    // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and\n                    // extractContents()\n                    rangeProto.deleteContents = function() {\n                        this.nativeRange.deleteContents();\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.extractContents = function() {\n                        var frag = this.nativeRange.extractContents();\n                        updateRangeProperties(this);\n                        return frag;\n                    };\n                } else {\n                }\n\n                body.removeChild(el);\n                body = null;\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for existence of createContextualFragment and delegate to it if it exists\n                if (util.isHostMethod(range, \"createContextualFragment\")) {\n                    rangeProto.createContextualFragment = function(fragmentStr) {\n                        return this.nativeRange.createContextualFragment(fragmentStr);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Clean up\n                getBody(document).removeChild(testTextNode);\n\n                rangeProto.getName = function() {\n                    return \"WrappedRange\";\n                };\n\n                api.WrappedRange = WrappedRange;\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return doc.createRange();\n                };\n            })();\n        }\n\n        if (api.features.implementsTextRange) {\n            /*\n            This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement()\n            method. For example, in the following (where pipes denote the selection boundaries):\n\n            <ul id=\"ul\"><li id=\"a\">| a </li><li id=\"b\"> b |</li></ul>\n\n            var range = document.selection.createRange();\n            alert(range.parentElement().id); // Should alert \"ul\" but alerts \"b\"\n\n            This method returns the common ancestor node of the following:\n            - the parentElement() of the textRange\n            - the parentElement() of the textRange after calling collapse(true)\n            - the parentElement() of the textRange after calling collapse(false)\n            */\n            var getTextRangeContainerElement = function(textRange) {\n                var parentEl = textRange.parentElement();\n                var range = textRange.duplicate();\n                range.collapse(true);\n                var startEl = range.parentElement();\n                range = textRange.duplicate();\n                range.collapse(false);\n                var endEl = range.parentElement();\n                var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl);\n\n                return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);\n            };\n\n            var textRangeIsCollapsed = function(textRange) {\n                return textRange.compareEndPoints(\"StartToEnd\", textRange) == 0;\n            };\n\n            // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started\n            // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/)\n            // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange\n            // bugs, handling for inputs and images, plus optimizations.\n            var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) {\n                var workingRange = textRange.duplicate();\n                workingRange.collapse(isStart);\n                var containerElement = workingRange.parentElement();\n\n                // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so\n                // check for that\n                if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) {\n                    containerElement = wholeRangeContainerElement;\n                }\n\n\n                // Deal with nodes that cannot \"contain rich HTML markup\". In practice, this means form inputs, images and\n                // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx\n                if (!containerElement.canHaveHTML) {\n                    var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement));\n                    return {\n                        boundaryPosition: pos,\n                        nodeInfo: {\n                            nodeIndex: pos.offset,\n                            containerElement: pos.node\n                        }\n                    };\n                }\n\n                var workingNode = dom.getDocument(containerElement).createElement(\"span\");\n\n                // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5\n                // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64\n                if (workingNode.parentNode) {\n                    dom.removeNode(workingNode);\n                }\n\n                var comparison, workingComparisonType = isStart ? \"StartToStart\" : \"StartToEnd\";\n                var previousNode, nextNode, boundaryPosition, boundaryNode;\n                var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0;\n                var childNodeCount = containerElement.childNodes.length;\n                var end = childNodeCount;\n\n                // Check end first. Code within the loop assumes that the endth child node of the container is definitely\n                // after the range boundary.\n                var nodeIndex = end;\n\n                while (true) {\n                    if (nodeIndex == childNodeCount) {\n                        containerElement.appendChild(workingNode);\n                    } else {\n                        containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]);\n                    }\n                    workingRange.moveToElementText(workingNode);\n                    comparison = workingRange.compareEndPoints(workingComparisonType, textRange);\n                    if (comparison == 0 || start == end) {\n                        break;\n                    } else if (comparison == -1) {\n                        if (end == start + 1) {\n                            // We know the endth child node is after the range boundary, so we must be done.\n                            break;\n                        } else {\n                            start = nodeIndex;\n                        }\n                    } else {\n                        end = (end == start + 1) ? start : nodeIndex;\n                    }\n                    nodeIndex = Math.floor((start + end) / 2);\n                    containerElement.removeChild(workingNode);\n                }\n\n\n                // We've now reached or gone past the boundary of the text range we're interested in\n                // so have identified the node we want\n                boundaryNode = workingNode.nextSibling;\n\n                if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) {\n                    // This is a character data node (text, comment, cdata). The working range is collapsed at the start of\n                    // the node containing the text range's boundary, so we move the end of the working range to the\n                    // boundary point and measure the length of its text to get the boundary's offset within the node.\n                    workingRange.setEndPoint(isStart ? \"EndToStart\" : \"EndToEnd\", textRange);\n\n                    var offset;\n\n                    if (/[\\r\\n]/.test(boundaryNode.data)) {\n                        /*\n                        For the particular case of a boundary within a text node containing rendered line breaks (within a\n                        <pre> element, for example), we need a slightly complicated approach to get the boundary's offset in\n                        IE. The facts:\n\n                        - Each line break is represented as \\r in the text node's data/nodeValue properties\n                        - Each line break is represented as \\r\\n in the TextRange's 'text' property\n                        - The 'text' property of the TextRange does not contain trailing line breaks\n\n                        To get round the problem presented by the final fact above, we can use the fact that TextRange's\n                        moveStart() and moveEnd() methods return the actual number of characters moved, which is not\n                        necessarily the same as the number of characters it was instructed to move. The simplest approach is\n                        to use this to store the characters moved when moving both the start and end of the range to the\n                        start of the document body and subtracting the start offset from the end offset (the\n                        \"move-negative-gazillion\" method). However, this is extremely slow when the document is large and\n                        the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to\n                        the end of the document) has the same problem.\n\n                        Another approach that works is to use moveStart() to move the start boundary of the range up to the\n                        end boundary one character at a time and incrementing a counter with the value returned by the\n                        moveStart() call. However, the check for whether the start boundary has reached the end boundary is\n                        expensive, so this method is slow (although unlike \"move-negative-gazillion\" is largely unaffected\n                        by the location of the range within the document).\n\n                        The approach used below is a hybrid of the two methods above. It uses the fact that a string\n                        containing the TextRange's 'text' property with each \\r\\n converted to a single \\r character cannot\n                        be longer than the text of the TextRange, so the start of the range is moved that length initially\n                        and then a character at a time to make up for any trailing line breaks not contained in the 'text'\n                        property. This has good performance in most situations compared to the previous two methods.\n                        */\n                        var tempRange = workingRange.duplicate();\n                        var rangeLength = tempRange.text.replace(/\\r\\n/g, \"\\r\").length;\n\n                        offset = tempRange.moveStart(\"character\", rangeLength);\n                        while ( (comparison = tempRange.compareEndPoints(\"StartToEnd\", tempRange)) == -1) {\n                            offset++;\n                            tempRange.moveStart(\"character\", 1);\n                        }\n                    } else {\n                        offset = workingRange.text.length;\n                    }\n                    boundaryPosition = new DomPosition(boundaryNode, offset);\n                } else {\n\n                    // If the boundary immediately follows a character data node and this is the end boundary, we should favour\n                    // a position within that, and likewise for a start boundary preceding a character data node\n                    previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;\n                    nextNode = (isCollapsed || isStart) && workingNode.nextSibling;\n                    if (nextNode && isCharacterDataNode(nextNode)) {\n                        boundaryPosition = new DomPosition(nextNode, 0);\n                    } else if (previousNode && isCharacterDataNode(previousNode)) {\n                        boundaryPosition = new DomPosition(previousNode, previousNode.data.length);\n                    } else {\n                        boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));\n                    }\n                }\n\n                // Clean up\n                dom.removeNode(workingNode);\n\n                return {\n                    boundaryPosition: boundaryPosition,\n                    nodeInfo: {\n                        nodeIndex: nodeIndex,\n                        containerElement: containerElement\n                    }\n                };\n            };\n\n            // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that\n            // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange\n            // (http://code.google.com/p/ierange/)\n            var createBoundaryTextRange = function(boundaryPosition, isStart) {\n                var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;\n                var doc = dom.getDocument(boundaryPosition.node);\n                var workingNode, childNodes, workingRange = getBody(doc).createTextRange();\n                var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);\n\n                if (nodeIsDataNode) {\n                    boundaryNode = boundaryPosition.node;\n                    boundaryParent = boundaryNode.parentNode;\n                } else {\n                    childNodes = boundaryPosition.node.childNodes;\n                    boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;\n                    boundaryParent = boundaryPosition.node;\n                }\n\n                // Position the range immediately before the node containing the boundary\n                workingNode = doc.createElement(\"span\");\n\n                // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within\n                // the element rather than immediately before or after it\n                workingNode.innerHTML = \"&#feff;\";\n\n                // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report\n                // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12\n                if (boundaryNode) {\n                    boundaryParent.insertBefore(workingNode, boundaryNode);\n                } else {\n                    boundaryParent.appendChild(workingNode);\n                }\n\n                workingRange.moveToElementText(workingNode);\n                workingRange.collapse(!isStart);\n\n                // Clean up\n                boundaryParent.removeChild(workingNode);\n\n                // Move the working range to the text offset, if required\n                if (nodeIsDataNode) {\n                    workingRange[isStart ? \"moveStart\" : \"moveEnd\"](\"character\", boundaryOffset);\n                }\n\n                return workingRange;\n            };\n\n            /*------------------------------------------------------------------------------------------------------------*/\n\n            // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a\n            // prototype\n\n            WrappedTextRange = function(textRange) {\n                this.textRange = textRange;\n                this.refresh();\n            };\n\n            WrappedTextRange.prototype = new DomRange(document);\n\n            WrappedTextRange.prototype.refresh = function() {\n                var start, end, startBoundary;\n\n                // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.\n                var rangeContainerElement = getTextRangeContainerElement(this.textRange);\n\n                if (textRangeIsCollapsed(this.textRange)) {\n                    end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,\n                        true).boundaryPosition;\n                } else {\n                    startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);\n                    start = startBoundary.boundaryPosition;\n\n                    // An optimization used here is that if the start and end boundaries have the same parent element, the\n                    // search scope for the end boundary can be limited to exclude the portion of the element that precedes\n                    // the start boundary\n                    end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,\n                        startBoundary.nodeInfo).boundaryPosition;\n                }\n\n                this.setStart(start.node, start.offset);\n                this.setEnd(end.node, end.offset);\n            };\n\n            WrappedTextRange.prototype.getName = function() {\n                return \"WrappedTextRange\";\n            };\n\n            DomRange.copyComparisonConstants(WrappedTextRange);\n\n            var rangeToTextRange = function(range) {\n                if (range.collapsed) {\n                    return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                } else {\n                    var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                    var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);\n                    var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();\n                    textRange.setEndPoint(\"StartToStart\", startRange);\n                    textRange.setEndPoint(\"EndToEnd\", endRange);\n                    return textRange;\n                }\n            };\n\n            WrappedTextRange.rangeToTextRange = rangeToTextRange;\n\n            WrappedTextRange.prototype.toTextRange = function() {\n                return rangeToTextRange(this);\n            };\n\n            api.WrappedTextRange = WrappedTextRange;\n\n            // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which\n            // implementation to use by default.\n            if (!api.features.implementsDomRange || api.config.preferTextRange) {\n                // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work\n                var globalObj = (function(f) { return f(\"return this;\")(); })(Function);\n                if (typeof globalObj.Range == \"undefined\") {\n                    globalObj.Range = WrappedTextRange;\n                }\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return getBody(doc).createTextRange();\n                };\n\n                api.WrappedRange = WrappedTextRange;\n            }\n        }\n\n        api.createRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRange\");\n            return new api.WrappedRange(api.createNativeRange(doc));\n        };\n\n        api.createRangyRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRangyRange\");\n            return new DomRange(doc);\n        };\n\n        util.createAliasForDeprecatedMethod(api, \"createIframeRange\", \"createRange\");\n        util.createAliasForDeprecatedMethod(api, \"createIframeRangyRange\", \"createRangyRange\");\n\n        api.addShimListener(function(win) {\n            var doc = win.document;\n            if (typeof doc.createRange == \"undefined\") {\n                doc.createRange = function() {\n                    return api.createRange(doc);\n                };\n            }\n            doc = win = null;\n        });\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification\n    // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)\n    api.createCoreModule(\"WrappedSelection\", [\"DomRange\", \"WrappedRange\"], function(api, module) {\n        api.config.checkSelectionRanges = true;\n\n        var BOOLEAN = \"boolean\";\n        var NUMBER = \"number\";\n        var dom = api.dom;\n        var util = api.util;\n        var isHostMethod = util.isHostMethod;\n        var DomRange = api.DomRange;\n        var WrappedRange = api.WrappedRange;\n        var DOMException = api.DOMException;\n        var DomPosition = dom.DomPosition;\n        var getNativeSelection;\n        var selectionIsCollapsed;\n        var features = api.features;\n        var CONTROL = \"Control\";\n        var getDocument = dom.getDocument;\n        var getBody = dom.getBody;\n        var rangesEqual = DomRange.rangesEqual;\n\n\n        // Utility function to support direction parameters in the API that may be a string (\"backward\", \"backwards\",\n        // \"forward\" or \"forwards\") or a Boolean (true for backwards).\n        function isDirectionBackward(dir) {\n            return (typeof dir == \"string\") ? /^backward(s)?$/i.test(dir) : !!dir;\n        }\n\n        function getWindow(win, methodName) {\n            if (!win) {\n                return window;\n            } else if (dom.isWindow(win)) {\n                return win;\n            } else if (win instanceof WrappedSelection) {\n                return win.win;\n            } else {\n                var doc = dom.getContentDocument(win, module, methodName);\n                return dom.getWindow(doc);\n            }\n        }\n\n        function getWinSelection(winParam) {\n            return getWindow(winParam, \"getWinSelection\").getSelection();\n        }\n\n        function getDocSelection(winParam) {\n            return getWindow(winParam, \"getDocSelection\").document.selection;\n        }\n\n        function winSelectionIsBackward(sel) {\n            var backward = false;\n            if (sel.anchorNode) {\n                backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);\n            }\n            return backward;\n        }\n\n        // Test for the Range/TextRange and Selection features required\n        // Test for ability to retrieve selection\n        var implementsWinGetSelection = isHostMethod(window, \"getSelection\"),\n            implementsDocSelection = util.isHostObject(document, \"selection\");\n\n        features.implementsWinGetSelection = implementsWinGetSelection;\n        features.implementsDocSelection = implementsDocSelection;\n\n        var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);\n\n        if (useDocumentSelection) {\n            getNativeSelection = getDocSelection;\n            api.isSelectionValid = function(winParam) {\n                var doc = getWindow(winParam, \"isSelectionValid\").document, nativeSel = doc.selection;\n\n                // Check whether the selection TextRange is actually contained within the correct document\n                return (nativeSel.type != \"None\" || getDocument(nativeSel.createRange().parentElement()) == doc);\n            };\n        } else if (implementsWinGetSelection) {\n            getNativeSelection = getWinSelection;\n            api.isSelectionValid = function() {\n                return true;\n            };\n        } else {\n            module.fail(\"Neither document.selection or window.getSelection() detected.\");\n            return false;\n        }\n\n        api.getNativeSelection = getNativeSelection;\n\n        var testSelection = getNativeSelection();\n\n        // In Firefox, the selection is null in an iframe with display: none. See issue #138.\n        if (!testSelection) {\n            module.fail(\"Native selection was null (possibly issue 138?)\");\n            return false;\n        }\n\n        var testRange = api.createNativeRange(document);\n        var body = getBody(document);\n\n        // Obtaining a range from a selection\n        var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,\n            [\"anchorNode\", \"focusNode\", \"anchorOffset\", \"focusOffset\"]);\n\n        features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;\n\n        // Test for existence of native selection extend() method\n        var selectionHasExtend = isHostMethod(testSelection, \"extend\");\n        features.selectionHasExtend = selectionHasExtend;\n\n        // Test if rangeCount exists\n        var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);\n        features.selectionHasRangeCount = selectionHasRangeCount;\n\n        var selectionSupportsMultipleRanges = false;\n        var collapsedNonEditableSelectionsSupported = true;\n\n        var addRangeBackwardToNative = selectionHasExtend ?\n            function(nativeSelection, range) {\n                var doc = DomRange.getRangeDocument(range);\n                var endRange = api.createRange(doc);\n                endRange.collapseToPoint(range.endContainer, range.endOffset);\n                nativeSelection.addRange(getNativeRange(endRange));\n                nativeSelection.extend(range.startContainer, range.startOffset);\n            } : null;\n\n        if (util.areHostMethods(testSelection, [\"addRange\", \"getRangeAt\", \"removeAllRanges\"]) &&\n                typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {\n\n            (function() {\n                // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are\n                // performed on the current document's selection. See issue 109.\n\n                // Note also that if a selection previously existed, it is wiped and later restored by these tests. This\n                // will result in the selection direction begin reversed if the original selection was backwards and the\n                // browser does not support setting backwards selections (Internet Explorer, I'm looking at you).\n                var sel = window.getSelection();\n                if (sel) {\n                    // Store the current selection\n                    var originalSelectionRangeCount = sel.rangeCount;\n                    var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);\n                    var originalSelectionRanges = [];\n                    var originalSelectionBackward = winSelectionIsBackward(sel);\n                    for (var i = 0; i < originalSelectionRangeCount; ++i) {\n                        originalSelectionRanges[i] = sel.getRangeAt(i);\n                    }\n\n                    // Create some test elements\n                    var testEl = dom.createTestElement(document, \"\", false);\n                    var textNode = testEl.appendChild( document.createTextNode(\"\\u00a0\\u00a0\\u00a0\") );\n\n                    // Test whether the native selection will allow a collapsed selection within a non-editable element\n                    var r1 = document.createRange();\n\n                    r1.setStart(textNode, 1);\n                    r1.collapse(true);\n                    sel.removeAllRanges();\n                    sel.addRange(r1);\n                    collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);\n                    sel.removeAllRanges();\n\n                    // Test whether the native selection is capable of supporting multiple ranges.\n                    if (!selectionHasMultipleRanges) {\n                        // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a\n                        // console error of \"Discontiguous selection is not supported.\" that cannot be suppressed. There's\n                        // nothing we can do about this while retaining the feature test so we have to resort to a browser\n                        // sniff. I'm not happy about it. See\n                        // https://code.google.com/p/chromium/issues/detail?id=399791\n                        var chromeMatch = window.navigator.appVersion.match(/Chrome\\/(.*?) /);\n                        if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {\n                            selectionSupportsMultipleRanges = false;\n                        } else {\n                            var r2 = r1.cloneRange();\n                            r1.setStart(textNode, 0);\n                            r2.setEnd(textNode, 3);\n                            r2.setStart(textNode, 2);\n                            sel.addRange(r1);\n                            sel.addRange(r2);\n                            selectionSupportsMultipleRanges = (sel.rangeCount == 2);\n                        }\n                    }\n\n                    // Clean up\n                    dom.removeNode(testEl);\n                    sel.removeAllRanges();\n\n                    for (i = 0; i < originalSelectionRangeCount; ++i) {\n                        if (i == 0 && originalSelectionBackward) {\n                            if (addRangeBackwardToNative) {\n                                addRangeBackwardToNative(sel, originalSelectionRanges[i]);\n                            } else {\n                                api.warn(\"Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend\");\n                                sel.addRange(originalSelectionRanges[i]);\n                            }\n                        } else {\n                            sel.addRange(originalSelectionRanges[i]);\n                        }\n                    }\n                }\n            })();\n        }\n\n        features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;\n        features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;\n\n        // ControlRanges\n        var implementsControlRange = false, testControlRange;\n\n        if (body && isHostMethod(body, \"createControlRange\")) {\n            testControlRange = body.createControlRange();\n            if (util.areHostProperties(testControlRange, [\"item\", \"add\"])) {\n                implementsControlRange = true;\n            }\n        }\n        features.implementsControlRange = implementsControlRange;\n\n        // Selection collapsedness\n        if (selectionHasAnchorAndFocus) {\n            selectionIsCollapsed = function(sel) {\n                return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;\n            };\n        } else {\n            selectionIsCollapsed = function(sel) {\n                return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;\n            };\n        }\n\n        function updateAnchorAndFocusFromRange(sel, range, backward) {\n            var anchorPrefix = backward ? \"end\" : \"start\", focusPrefix = backward ? \"start\" : \"end\";\n            sel.anchorNode = range[anchorPrefix + \"Container\"];\n            sel.anchorOffset = range[anchorPrefix + \"Offset\"];\n            sel.focusNode = range[focusPrefix + \"Container\"];\n            sel.focusOffset = range[focusPrefix + \"Offset\"];\n        }\n\n        function updateAnchorAndFocusFromNativeSelection(sel) {\n            var nativeSel = sel.nativeSelection;\n            sel.anchorNode = nativeSel.anchorNode;\n            sel.anchorOffset = nativeSel.anchorOffset;\n            sel.focusNode = nativeSel.focusNode;\n            sel.focusOffset = nativeSel.focusOffset;\n        }\n\n        function updateEmptySelection(sel) {\n            sel.anchorNode = sel.focusNode = null;\n            sel.anchorOffset = sel.focusOffset = 0;\n            sel.rangeCount = 0;\n            sel.isCollapsed = true;\n            sel._ranges.length = 0;\n        }\n\n        function getNativeRange(range) {\n            var nativeRange;\n            if (range instanceof DomRange) {\n                nativeRange = api.createNativeRange(range.getDocument());\n                nativeRange.setEnd(range.endContainer, range.endOffset);\n                nativeRange.setStart(range.startContainer, range.startOffset);\n            } else if (range instanceof WrappedRange) {\n                nativeRange = range.nativeRange;\n            } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {\n                nativeRange = range;\n            }\n            return nativeRange;\n        }\n\n        function rangeContainsSingleElement(rangeNodes) {\n            if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {\n                return false;\n            }\n            for (var i = 1, len = rangeNodes.length; i < len; ++i) {\n                if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function getSingleElementFromRange(range) {\n            var nodes = range.getNodes();\n            if (!rangeContainsSingleElement(nodes)) {\n                throw module.createError(\"getSingleElementFromRange: range \" + range.inspect() + \" did not consist of a single element\");\n            }\n            return nodes[0];\n        }\n\n        // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange\n        function isTextRange(range) {\n            return !!range && typeof range.text != \"undefined\";\n        }\n\n        function updateFromTextRange(sel, range) {\n            // Create a Range from the selected TextRange\n            var wrappedRange = new WrappedRange(range);\n            sel._ranges = [wrappedRange];\n\n            updateAnchorAndFocusFromRange(sel, wrappedRange, false);\n            sel.rangeCount = 1;\n            sel.isCollapsed = wrappedRange.collapsed;\n        }\n\n        function updateControlSelection(sel) {\n            // Update the wrapped selection based on what's now in the native selection\n            sel._ranges.length = 0;\n            if (sel.docSelection.type == \"None\") {\n                updateEmptySelection(sel);\n            } else {\n                var controlRange = sel.docSelection.createRange();\n                if (isTextRange(controlRange)) {\n                    // This case (where the selection type is \"Control\" and calling createRange() on the selection returns\n                    // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected\n                    // ControlRange have been removed from the ControlRange and removed from the document.\n                    updateFromTextRange(sel, controlRange);\n                } else {\n                    sel.rangeCount = controlRange.length;\n                    var range, doc = getDocument(controlRange.item(0));\n                    for (var i = 0; i < sel.rangeCount; ++i) {\n                        range = api.createRange(doc);\n                        range.selectNode(controlRange.item(i));\n                        sel._ranges.push(range);\n                    }\n                    sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);\n                }\n            }\n        }\n\n        function addRangeToControlSelection(sel, range) {\n            var controlRange = sel.docSelection.createRange();\n            var rangeElement = getSingleElementFromRange(range);\n\n            // Create a new ControlRange containing all the elements in the selected ControlRange plus the element\n            // contained by the supplied range\n            var doc = getDocument(controlRange.item(0));\n            var newControlRange = getBody(doc).createControlRange();\n            for (var i = 0, len = controlRange.length; i < len; ++i) {\n                newControlRange.add(controlRange.item(i));\n            }\n            try {\n                newControlRange.add(rangeElement);\n            } catch (ex) {\n                throw module.createError(\"addRange(): Element within the specified Range could not be added to control selection (does it have layout?)\");\n            }\n            newControlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        var getSelectionRangeAt;\n\n        if (isHostMethod(testSelection, \"getRangeAt\")) {\n            // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.\n            // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a\n            // lesson to us all, especially me.\n            getSelectionRangeAt = function(sel, index) {\n                try {\n                    return sel.getRangeAt(index);\n                } catch (ex) {\n                    return null;\n                }\n            };\n        } else if (selectionHasAnchorAndFocus) {\n            getSelectionRangeAt = function(sel) {\n                var doc = getDocument(sel.anchorNode);\n                var range = api.createRange(doc);\n                range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n\n                // Handle the case when the selection was selected backwards (from the end to the start in the\n                // document)\n                if (range.collapsed !== this.isCollapsed) {\n                    range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);\n                }\n\n                return range;\n            };\n        }\n\n        function WrappedSelection(selection, docSelection, win) {\n            this.nativeSelection = selection;\n            this.docSelection = docSelection;\n            this._ranges = [];\n            this.win = win;\n            this.refresh();\n        }\n\n        WrappedSelection.prototype = api.selectionPrototype;\n\n        function deleteProperties(sel) {\n            sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;\n            sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;\n            sel.detached = true;\n        }\n\n        var cachedRangySelections = [];\n\n        function actOnCachedSelection(win, action) {\n            var i = cachedRangySelections.length, cached, sel;\n            while (i--) {\n                cached = cachedRangySelections[i];\n                sel = cached.selection;\n                if (action == \"deleteAll\") {\n                    deleteProperties(sel);\n                } else if (cached.win == win) {\n                    if (action == \"delete\") {\n                        cachedRangySelections.splice(i, 1);\n                        return true;\n                    } else {\n                        return sel;\n                    }\n                }\n            }\n            if (action == \"deleteAll\") {\n                cachedRangySelections.length = 0;\n            }\n            return null;\n        }\n\n        var getSelection = function(win) {\n            // Check if the parameter is a Rangy Selection object\n            if (win && win instanceof WrappedSelection) {\n                win.refresh();\n                return win;\n            }\n\n            win = getWindow(win, \"getNativeSelection\");\n\n            var sel = actOnCachedSelection(win);\n            var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;\n            if (sel) {\n                sel.nativeSelection = nativeSel;\n                sel.docSelection = docSel;\n                sel.refresh();\n            } else {\n                sel = new WrappedSelection(nativeSel, docSel, win);\n                cachedRangySelections.push( { win: win, selection: sel } );\n            }\n            return sel;\n        };\n\n        api.getSelection = getSelection;\n\n        util.createAliasForDeprecatedMethod(api, \"getIframeSelection\", \"getSelection\");\n\n        var selProto = WrappedSelection.prototype;\n\n        function createControlSelection(sel, ranges) {\n            // Ensure that the selection becomes of type \"Control\"\n            var doc = getDocument(ranges[0].startContainer);\n            var controlRange = getBody(doc).createControlRange();\n            for (var i = 0, el, len = ranges.length; i < len; ++i) {\n                el = getSingleElementFromRange(ranges[i]);\n                try {\n                    controlRange.add(el);\n                } catch (ex) {\n                    throw module.createError(\"setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)\");\n                }\n            }\n            controlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        // Selecting a range\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, [\"removeAllRanges\", \"addRange\"])) {\n            selProto.removeAllRanges = function() {\n                this.nativeSelection.removeAllRanges();\n                updateEmptySelection(this);\n            };\n\n            var addRangeBackward = function(sel, range) {\n                addRangeBackwardToNative(sel.nativeSelection, range);\n                sel.refresh();\n            };\n\n            if (selectionHasRangeCount) {\n                selProto.addRange = function(range, direction) {\n                    if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                        addRangeToControlSelection(this, range);\n                    } else {\n                        if (isDirectionBackward(direction) && selectionHasExtend) {\n                            addRangeBackward(this, range);\n                        } else {\n                            var previousRangeCount;\n                            if (selectionSupportsMultipleRanges) {\n                                previousRangeCount = this.rangeCount;\n                            } else {\n                                this.removeAllRanges();\n                                previousRangeCount = 0;\n                            }\n                            // Clone the native range so that changing the selected range does not affect the selection.\n                            // This is contrary to the spec but is the only way to achieve consistency between browsers. See\n                            // issue 80.\n                            var clonedNativeRange = getNativeRange(range).cloneRange();\n                            try {\n                                this.nativeSelection.addRange(clonedNativeRange);\n                            } catch (ex) {\n                            }\n\n                            // Check whether adding the range was successful\n                            this.rangeCount = this.nativeSelection.rangeCount;\n\n                            if (this.rangeCount == previousRangeCount + 1) {\n                                // The range was added successfully\n\n                                // Check whether the range that we added to the selection is reflected in the last range extracted from\n                                // the selection\n                                if (api.config.checkSelectionRanges) {\n                                    var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);\n                                    if (nativeRange && !rangesEqual(nativeRange, range)) {\n                                        // Happens in WebKit with, for example, a selection placed at the start of a text node\n                                        range = new WrappedRange(nativeRange);\n                                    }\n                                }\n                                this._ranges[this.rangeCount - 1] = range;\n                                updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));\n                                this.isCollapsed = selectionIsCollapsed(this);\n                            } else {\n                                // The range was not added successfully. The simplest thing is to refresh\n                                this.refresh();\n                            }\n                        }\n                    }\n                };\n            } else {\n                selProto.addRange = function(range, direction) {\n                    if (isDirectionBackward(direction) && selectionHasExtend) {\n                        addRangeBackward(this, range);\n                    } else {\n                        this.nativeSelection.addRange(getNativeRange(range));\n                        this.refresh();\n                    }\n                };\n            }\n\n            selProto.setRanges = function(ranges) {\n                if (implementsControlRange && implementsDocSelection && ranges.length > 1) {\n                    createControlSelection(this, ranges);\n                } else {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        this.addRange(ranges[i]);\n                    }\n                }\n            };\n        } else if (isHostMethod(testSelection, \"empty\") && isHostMethod(testRange, \"select\") &&\n                   implementsControlRange && useDocumentSelection) {\n\n            selProto.removeAllRanges = function() {\n                // Added try/catch as fix for issue #21\n                try {\n                    this.docSelection.empty();\n\n                    // Check for empty() not working (issue #24)\n                    if (this.docSelection.type != \"None\") {\n                        // Work around failure to empty a control selection by instead selecting a TextRange and then\n                        // calling empty()\n                        var doc;\n                        if (this.anchorNode) {\n                            doc = getDocument(this.anchorNode);\n                        } else if (this.docSelection.type == CONTROL) {\n                            var controlRange = this.docSelection.createRange();\n                            if (controlRange.length) {\n                                doc = getDocument( controlRange.item(0) );\n                            }\n                        }\n                        if (doc) {\n                            var textRange = getBody(doc).createTextRange();\n                            textRange.select();\n                            this.docSelection.empty();\n                        }\n                    }\n                } catch(ex) {}\n                updateEmptySelection(this);\n            };\n\n            selProto.addRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    addRangeToControlSelection(this, range);\n                } else {\n                    api.WrappedTextRange.rangeToTextRange(range).select();\n                    this._ranges[0] = range;\n                    this.rangeCount = 1;\n                    this.isCollapsed = this._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(this, range, false);\n                }\n            };\n\n            selProto.setRanges = function(ranges) {\n                this.removeAllRanges();\n                var rangeCount = ranges.length;\n                if (rangeCount > 1) {\n                    createControlSelection(this, ranges);\n                } else if (rangeCount) {\n                    this.addRange(ranges[0]);\n                }\n            };\n        } else {\n            module.fail(\"No means of selecting a Range or TextRange was found\");\n            return false;\n        }\n\n        selProto.getRangeAt = function(index) {\n            if (index < 0 || index >= this.rangeCount) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            } else {\n                // Clone the range to preserve selection-range independence. See issue 80.\n                return this._ranges[index].cloneRange();\n            }\n        };\n\n        var refreshSelection;\n\n        if (useDocumentSelection) {\n            refreshSelection = function(sel) {\n                var range;\n                if (api.isSelectionValid(sel.win)) {\n                    range = sel.docSelection.createRange();\n                } else {\n                    range = getBody(sel.win.document).createTextRange();\n                    range.collapse(true);\n                }\n\n                if (sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else if (isTextRange(range)) {\n                    updateFromTextRange(sel, range);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else if (isHostMethod(testSelection, \"getRangeAt\") && typeof testSelection.rangeCount == NUMBER) {\n            refreshSelection = function(sel) {\n                if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else {\n                    sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;\n                    if (sel.rangeCount) {\n                        for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                            sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));\n                        }\n                        updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));\n                        sel.isCollapsed = selectionIsCollapsed(sel);\n                    } else {\n                        updateEmptySelection(sel);\n                    }\n                }\n            };\n        } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {\n            refreshSelection = function(sel) {\n                var range, nativeSel = sel.nativeSelection;\n                if (nativeSel.anchorNode) {\n                    range = getSelectionRangeAt(nativeSel, 0);\n                    sel._ranges = [range];\n                    sel.rangeCount = 1;\n                    updateAnchorAndFocusFromNativeSelection(sel);\n                    sel.isCollapsed = selectionIsCollapsed(sel);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else {\n            module.fail(\"No means of obtaining a Range or TextRange from the user's selection was found\");\n            return false;\n        }\n\n        selProto.refresh = function(checkForChanges) {\n            var oldRanges = checkForChanges ? this._ranges.slice(0) : null;\n            var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;\n\n            refreshSelection(this);\n            if (checkForChanges) {\n                // Check the range count first\n                var i = oldRanges.length;\n                if (i != this._ranges.length) {\n                    return true;\n                }\n\n                // Now check the direction. Checking the anchor position is the same is enough since we're checking all the\n                // ranges after this\n                if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {\n                    return true;\n                }\n\n                // Finally, compare each range in turn\n                while (i--) {\n                    if (!rangesEqual(oldRanges[i], this._ranges[i])) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n        };\n\n        // Removal of a single range\n        var removeRangeManually = function(sel, range) {\n            var ranges = sel.getAllRanges();\n            sel.removeAllRanges();\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                if (!rangesEqual(range, ranges[i])) {\n                    sel.addRange(ranges[i]);\n                }\n            }\n            if (!sel.rangeCount) {\n                updateEmptySelection(sel);\n            }\n        };\n\n        if (implementsControlRange && implementsDocSelection) {\n            selProto.removeRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    var controlRange = this.docSelection.createRange();\n                    var rangeElement = getSingleElementFromRange(range);\n\n                    // Create a new ControlRange containing all the elements in the selected ControlRange minus the\n                    // element contained by the supplied range\n                    var doc = getDocument(controlRange.item(0));\n                    var newControlRange = getBody(doc).createControlRange();\n                    var el, removed = false;\n                    for (var i = 0, len = controlRange.length; i < len; ++i) {\n                        el = controlRange.item(i);\n                        if (el !== rangeElement || removed) {\n                            newControlRange.add(controlRange.item(i));\n                        } else {\n                            removed = true;\n                        }\n                    }\n                    newControlRange.select();\n\n                    // Update the wrapped selection based on what's now in the native selection\n                    updateControlSelection(this);\n                } else {\n                    removeRangeManually(this, range);\n                }\n            };\n        } else {\n            selProto.removeRange = function(range) {\n                removeRangeManually(this, range);\n            };\n        }\n\n        // Detecting if a selection is backward\n        var selectionIsBackward;\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {\n            selectionIsBackward = winSelectionIsBackward;\n\n            selProto.isBackward = function() {\n                return selectionIsBackward(this);\n            };\n        } else {\n            selectionIsBackward = selProto.isBackward = function() {\n                return false;\n            };\n        }\n\n        // Create an alias for backwards compatibility. From 1.3, everything is \"backward\" rather than \"backwards\"\n        selProto.isBackwards = selProto.isBackward;\n\n        // Selection stringifier\n        // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.\n        // The current spec does not yet define this method.\n        selProto.toString = function() {\n            var rangeTexts = [];\n            for (var i = 0, len = this.rangeCount; i < len; ++i) {\n                rangeTexts[i] = \"\" + this._ranges[i];\n            }\n            return rangeTexts.join(\"\");\n        };\n\n        function assertNodeInSameDocument(sel, node) {\n            if (sel.win.document != getDocument(node)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        // No current browser conforms fully to the spec for this method, so Rangy's own method is always used\n        selProto.collapse = function(node, offset) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.collapseToPoint(node, offset);\n            this.setSingleRange(range);\n            this.isCollapsed = true;\n        };\n\n        selProto.collapseToStart = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[0];\n                this.collapse(range.startContainer, range.startOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        selProto.collapseToEnd = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[this.rangeCount - 1];\n                this.collapse(range.endContainer, range.endOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        // The spec is very specific on how selectAllChildren should be implemented and not all browsers implement it as\n        // specified so the native implementation is never used by Rangy.\n        selProto.selectAllChildren = function(node) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.selectNodeContents(node);\n            this.setSingleRange(range);\n        };\n\n        selProto.deleteFromDocument = function() {\n            // Sepcial behaviour required for IE's control selections\n            if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                var controlRange = this.docSelection.createRange();\n                var element;\n                while (controlRange.length) {\n                    element = controlRange.item(0);\n                    controlRange.remove(element);\n                    dom.removeNode(element);\n                }\n                this.refresh();\n            } else if (this.rangeCount) {\n                var ranges = this.getAllRanges();\n                if (ranges.length) {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        ranges[i].deleteContents();\n                    }\n                    // The spec says nothing about what the selection should contain after calling deleteContents on each\n                    // range. Firefox moves the selection to where the final selected range was, so we emulate that\n                    this.addRange(ranges[len - 1]);\n                }\n            }\n        };\n\n        // The following are non-standard extensions\n        selProto.eachRange = function(func, returnValue) {\n            for (var i = 0, len = this._ranges.length; i < len; ++i) {\n                if ( func( this.getRangeAt(i) ) ) {\n                    return returnValue;\n                }\n            }\n        };\n\n        selProto.getAllRanges = function() {\n            var ranges = [];\n            this.eachRange(function(range) {\n                ranges.push(range);\n            });\n            return ranges;\n        };\n\n        selProto.setSingleRange = function(range, direction) {\n            this.removeAllRanges();\n            this.addRange(range, direction);\n        };\n\n        selProto.callMethodOnEachRange = function(methodName, params) {\n            var results = [];\n            this.eachRange( function(range) {\n                results.push( range[methodName].apply(range, params || []) );\n            } );\n            return results;\n        };\n\n        function createStartOrEndSetter(isStart) {\n            return function(node, offset) {\n                var range;\n                if (this.rangeCount) {\n                    range = this.getRangeAt(0);\n                    range[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                } else {\n                    range = api.createRange(this.win.document);\n                    range.setStartAndEnd(node, offset);\n                }\n                this.setSingleRange(range, this.isBackward());\n            };\n        }\n\n        selProto.setStart = createStartOrEndSetter(true);\n        selProto.setEnd = createStartOrEndSetter(false);\n\n        // Add select() method to Range prototype. Any existing selection will be removed.\n        api.rangePrototype.select = function(direction) {\n            getSelection( this.getDocument() ).setSingleRange(this, direction);\n        };\n\n        selProto.changeEachRange = function(func) {\n            var ranges = [];\n            var backward = this.isBackward();\n\n            this.eachRange(function(range) {\n                func(range);\n                ranges.push(range);\n            });\n\n            this.removeAllRanges();\n            if (backward && ranges.length == 1) {\n                this.addRange(ranges[0], \"backward\");\n            } else {\n                this.setRanges(ranges);\n            }\n        };\n\n        selProto.containsNode = function(node, allowPartial) {\n            return this.eachRange( function(range) {\n                return range.containsNode(node, allowPartial);\n            }, true ) || false;\n        };\n\n        selProto.getBookmark = function(containerNode) {\n            return {\n                backward: this.isBackward(),\n                rangeBookmarks: this.callMethodOnEachRange(\"getBookmark\", [containerNode])\n            };\n        };\n\n        selProto.moveToBookmark = function(bookmark) {\n            var selRanges = [];\n            for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {\n                range = api.createRange(this.win);\n                range.moveToBookmark(rangeBookmark);\n                selRanges.push(range);\n            }\n            if (bookmark.backward) {\n                this.setSingleRange(selRanges[0], \"backward\");\n            } else {\n                this.setRanges(selRanges);\n            }\n        };\n\n        selProto.saveRanges = function() {\n            return {\n                backward: this.isBackward(),\n                ranges: this.callMethodOnEachRange(\"cloneRange\")\n            };\n        };\n\n        selProto.restoreRanges = function(selRanges) {\n            this.removeAllRanges();\n            for (var i = 0, range; range = selRanges.ranges[i]; ++i) {\n                this.addRange(range, (selRanges.backward && i == 0));\n            }\n        };\n\n        selProto.toHtml = function() {\n            var rangeHtmls = [];\n            this.eachRange(function(range) {\n                rangeHtmls.push( DomRange.toHtml(range) );\n            });\n            return rangeHtmls.join(\"\");\n        };\n\n        if (features.implementsTextRange) {\n            selProto.getNativeTextRange = function() {\n                var sel, textRange;\n                if ( (sel = this.docSelection) ) {\n                    var range = sel.createRange();\n                    if (isTextRange(range)) {\n                        return range;\n                    } else {\n                        throw module.createError(\"getNativeTextRange: selection is a control selection\");\n                    }\n                } else if (this.rangeCount > 0) {\n                    return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );\n                } else {\n                    throw module.createError(\"getNativeTextRange: selection contains no range\");\n                }\n            };\n        }\n\n        function inspect(sel) {\n            var rangeInspects = [];\n            var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);\n            var focus = new DomPosition(sel.focusNode, sel.focusOffset);\n            var name = (typeof sel.getName == \"function\") ? sel.getName() : \"Selection\";\n\n            if (typeof sel.rangeCount != \"undefined\") {\n                for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                    rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));\n                }\n            }\n            return \"[\" + name + \"(Ranges: \" + rangeInspects.join(\", \") +\n                    \")(anchor: \" + anchor.inspect() + \", focus: \" + focus.inspect() + \"]\";\n        }\n\n        selProto.getName = function() {\n            return \"WrappedSelection\";\n        };\n\n        selProto.inspect = function() {\n            return inspect(this);\n        };\n\n        selProto.detach = function() {\n            actOnCachedSelection(this.win, \"delete\");\n            deleteProperties(this);\n        };\n\n        WrappedSelection.detachAll = function() {\n            actOnCachedSelection(null, \"deleteAll\");\n        };\n\n        WrappedSelection.inspect = inspect;\n        WrappedSelection.isDirectionBackward = isDirectionBackward;\n\n        api.Selection = WrappedSelection;\n\n        api.selectionPrototype = selProto;\n\n        api.addShimListener(function(win) {\n            if (typeof win.getSelection == \"undefined\") {\n                win.getSelection = function() {\n                    return getSelection(win);\n                };\n            }\n            win = null;\n        });\n    });\n    \n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wait for document to load before initializing\n    var docReady = false;\n\n    var loadHandler = function(e) {\n        if (!docReady) {\n            docReady = true;\n            if (!api.initialized && api.config.autoInitialize) {\n                init();\n            }\n        }\n    };\n\n    if (isBrowser) {\n        // Test whether the document has already been loaded and initialize immediately if so\n        if (document.readyState == \"complete\") {\n            loadHandler();\n        } else {\n            if (isHostMethod(document, \"addEventListener\")) {\n                document.addEventListener(\"DOMContentLoaded\", loadHandler, false);\n            }\n\n            // Add a fallback in case the DOMContentLoaded event isn't supported\n            addListener(window, \"load\", loadHandler);\n        }\n    }\n\n    return api;\n}, this);"
  },
  {
    "path": "rangy-highlighter.js",
    "content": "/**\n * Highlighter module for Rangy, a cross-browser JavaScript range and selection library\n * https://github.com/timdown/rangy\n *\n * Depends on Rangy core, ClassApplier and optionally TextRange modules.\n *\n * Copyright %%build:year%%, Tim Down\n * Licensed under the MIT license.\n * Version: %%build:version%%\n * Build date: %%build:date%%\n */\n/* build:modularizeWithRangyDependency */\nrangy.createModule(\"Highlighter\", [\"ClassApplier\"], function(api, module) {\n    var dom = api.dom;\n    var contains = dom.arrayContains;\n    var getBody = dom.getBody;\n    var createOptions = api.util.createOptions;\n    var forEach = api.util.forEach;\n    var nextHighlightId = 1;\n\n    // Puts highlights in order, last in document first.\n    function compareHighlights(h1, h2) {\n        return h1.characterRange.start - h2.characterRange.start;\n    }\n\n    function getContainerElement(doc, id) {\n        return id ? doc.getElementById(id) : getBody(doc);\n    }\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    var highlighterTypes = {};\n\n    function HighlighterType(type, converterCreator) {\n        this.type = type;\n        this.converterCreator = converterCreator;\n    }\n\n    HighlighterType.prototype.create = function() {\n        var converter = this.converterCreator();\n        converter.type = this.type;\n        return converter;\n    };\n\n    function registerHighlighterType(type, converterCreator) {\n        highlighterTypes[type] = new HighlighterType(type, converterCreator);\n    }\n\n    function getConverter(type) {\n        var highlighterType = highlighterTypes[type];\n        if (highlighterType instanceof HighlighterType) {\n            return highlighterType.create();\n        } else {\n            throw new Error(\"Highlighter type '\" + type + \"' is not valid\");\n        }\n    }\n\n    api.registerHighlighterType = registerHighlighterType;\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    function CharacterRange(start, end) {\n        this.start = start;\n        this.end = end;\n    }\n\n    CharacterRange.prototype = {\n        intersects: function(charRange) {\n            return this.start < charRange.end && this.end > charRange.start;\n        },\n\n        isContiguousWith: function(charRange) {\n            return this.start == charRange.end || this.end == charRange.start;\n        },\n\n        union: function(charRange) {\n            return new CharacterRange(Math.min(this.start, charRange.start), Math.max(this.end, charRange.end));\n        },\n\n        intersection: function(charRange) {\n            return new CharacterRange(Math.max(this.start, charRange.start), Math.min(this.end, charRange.end));\n        },\n\n        getComplements: function(charRange) {\n            var ranges = [];\n            if (this.start >= charRange.start) {\n                if (this.end <= charRange.end) {\n                    return [];\n                }\n                ranges.push(new CharacterRange(charRange.end, this.end));\n            } else {\n                ranges.push(new CharacterRange(this.start, Math.min(this.end, charRange.start)));\n                if (this.end > charRange.end) {\n                    ranges.push(new CharacterRange(charRange.end, this.end));\n                }\n            }\n            return ranges;\n        },\n\n        toString: function() {\n            return \"[CharacterRange(\" + this.start + \", \" + this.end + \")]\";\n        }\n    };\n\n    CharacterRange.fromCharacterRange = function(charRange) {\n        return new CharacterRange(charRange.start, charRange.end);\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    var textContentConverter = {\n        rangeToCharacterRange: function(range, containerNode) {\n            var bookmark = range.getBookmark(containerNode);\n            return new CharacterRange(bookmark.start, bookmark.end);\n        },\n\n        characterRangeToRange: function(doc, characterRange, containerNode) {\n            var range = api.createRange(doc);\n            range.moveToBookmark({\n                start: characterRange.start,\n                end: characterRange.end,\n                containerNode: containerNode\n            });\n\n            return range;\n        },\n\n        serializeSelection: function(selection, containerNode) {\n            var ranges = selection.getAllRanges(), rangeCount = ranges.length;\n            var rangeInfos = [];\n\n            var backward = rangeCount == 1 && selection.isBackward();\n\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                rangeInfos[i] = {\n                    characterRange: this.rangeToCharacterRange(ranges[i], containerNode),\n                    backward: backward\n                };\n            }\n\n            return rangeInfos;\n        },\n\n        restoreSelection: function(selection, savedSelection, containerNode) {\n            selection.removeAllRanges();\n            var doc = selection.win.document;\n            for (var i = 0, len = savedSelection.length, range, rangeInfo, characterRange; i < len; ++i) {\n                rangeInfo = savedSelection[i];\n                characterRange = rangeInfo.characterRange;\n                range = this.characterRangeToRange(doc, rangeInfo.characterRange, containerNode);\n                selection.addRange(range, rangeInfo.backward);\n            }\n        }\n    };\n\n    registerHighlighterType(\"textContent\", function() {\n        return textContentConverter;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Lazily load the TextRange-based converter so that the dependency is only checked when required.\n    registerHighlighterType(\"TextRange\", (function() {\n        var converter;\n\n        return function() {\n            if (!converter) {\n                // Test that textRangeModule exists and is supported\n                var textRangeModule = api.modules.TextRange;\n                if (!textRangeModule) {\n                    throw new Error(\"TextRange module is missing.\");\n                } else if (!textRangeModule.supported) {\n                    throw new Error(\"TextRange module is present but not supported.\");\n                }\n\n                converter = {\n                    rangeToCharacterRange: function(range, containerNode) {\n                        return CharacterRange.fromCharacterRange( range.toCharacterRange(containerNode) );\n                    },\n\n                    characterRangeToRange: function(doc, characterRange, containerNode) {\n                        var range = api.createRange(doc);\n                        range.selectCharacters(containerNode, characterRange.start, characterRange.end);\n                        return range;\n                    },\n\n                    serializeSelection: function(selection, containerNode) {\n                        return selection.saveCharacterRanges(containerNode);\n                    },\n\n                    restoreSelection: function(selection, savedSelection, containerNode) {\n                        selection.restoreCharacterRanges(containerNode, savedSelection);\n                    }\n                };\n            }\n\n            return converter;\n        };\n    })());\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    function Highlight(doc, characterRange, classApplier, converter, id, containerElementId) {\n        if (id) {\n            this.id = id;\n            nextHighlightId = Math.max(nextHighlightId, id + 1);\n        } else {\n            this.id = nextHighlightId++;\n        }\n        this.characterRange = characterRange;\n        this.doc = doc;\n        this.classApplier = classApplier;\n        this.converter = converter;\n        this.containerElementId = containerElementId || null;\n        this.applied = false;\n    }\n\n    Highlight.prototype = {\n        getContainerElement: function() {\n            return getContainerElement(this.doc, this.containerElementId);\n        },\n\n        getRange: function() {\n            return this.converter.characterRangeToRange(this.doc, this.characterRange, this.getContainerElement());\n        },\n\n        fromRange: function(range) {\n            this.characterRange = this.converter.rangeToCharacterRange(range, this.getContainerElement());\n        },\n\n        getText: function() {\n            return this.getRange().toString();\n        },\n\n        containsElement: function(el) {\n            return this.getRange().containsNodeContents(el.firstChild);\n        },\n\n        unapply: function() {\n            this.classApplier.undoToRange(this.getRange());\n            this.applied = false;\n        },\n\n        apply: function() {\n            this.classApplier.applyToRange(this.getRange());\n            this.applied = true;\n        },\n\n        getHighlightElements: function() {\n            return this.classApplier.getElementsWithClassIntersectingRange(this.getRange());\n        },\n\n        toString: function() {\n            return \"[Highlight(ID: \" + this.id + \", class: \" + this.classApplier.className + \", character range: \" +\n                this.characterRange.start + \" - \" + this.characterRange.end + \")]\";\n        }\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    function Highlighter(doc, type) {\n        type = type || \"textContent\";\n        this.doc = doc || document;\n        this.classAppliers = {};\n        this.highlights = [];\n        this.converter = getConverter(type);\n    }\n\n    Highlighter.prototype = {\n        addClassApplier: function(classApplier) {\n            this.classAppliers[classApplier.className] = classApplier;\n        },\n\n        getHighlightForElement: function(el) {\n            var highlights = this.highlights;\n            for (var i = 0, len = highlights.length; i < len; ++i) {\n                if (highlights[i].containsElement(el)) {\n                    return highlights[i];\n                }\n            }\n            return null;\n        },\n\n        removeHighlights: function(highlights) {\n            for (var i = 0, len = this.highlights.length, highlight; i < len; ++i) {\n                highlight = this.highlights[i];\n                if (contains(highlights, highlight)) {\n                    highlight.unapply();\n                    this.highlights.splice(i--, 1);\n                }\n            }\n        },\n\n        removeAllHighlights: function() {\n            this.removeHighlights(this.highlights);\n        },\n\n        getIntersectingHighlights: function(ranges) {\n            // Test each range against each of the highlighted ranges to see whether they overlap\n            var intersectingHighlights = [], highlights = this.highlights;\n            forEach(ranges, function(range) {\n                //var selCharRange = converter.rangeToCharacterRange(range);\n                forEach(highlights, function(highlight) {\n                    if (range.intersectsRange( highlight.getRange() ) && !contains(intersectingHighlights, highlight)) {\n                        intersectingHighlights.push(highlight);\n                    }\n                });\n            });\n\n            return intersectingHighlights;\n        },\n\n        highlightCharacterRanges: function(className, charRanges, options) {\n            var i, len, j;\n            var highlights = this.highlights;\n            var converter = this.converter;\n            var doc = this.doc;\n            var highlightsToRemove = [];\n            var classApplier = className ? this.classAppliers[className] : null;\n\n            options = createOptions(options, {\n                containerElementId: null,\n                exclusive: true\n            });\n\n            var containerElementId = options.containerElementId;\n            var exclusive = options.exclusive;\n\n            var containerElement, containerElementRange, containerElementCharRange;\n            if (containerElementId) {\n                containerElement = this.doc.getElementById(containerElementId);\n                if (containerElement) {\n                    containerElementRange = api.createRange(this.doc);\n                    containerElementRange.selectNodeContents(containerElement);\n                    containerElementCharRange = new CharacterRange(0, containerElementRange.toString().length);\n                }\n            }\n\n            var charRange, highlightCharRange, removeHighlight, isSameClassApplier, highlightsToKeep, splitHighlight;\n\n            for (i = 0, len = charRanges.length; i < len; ++i) {\n                charRange = charRanges[i];\n                highlightsToKeep = [];\n\n                // Restrict character range to container element, if it exists\n                if (containerElementCharRange) {\n                    charRange = charRange.intersection(containerElementCharRange);\n                }\n\n                // Ignore empty ranges\n                if (charRange.start == charRange.end) {\n                    continue;\n                }\n\n                // Check for intersection with existing highlights. For each intersection, create a new highlight\n                // which is the union of the highlight range and the selected range\n                for (j = 0; j < highlights.length; ++j) {\n                    removeHighlight = false;\n\n                    if (containerElementId == highlights[j].containerElementId) {\n                        highlightCharRange = highlights[j].characterRange;\n                        isSameClassApplier = (classApplier == highlights[j].classApplier);\n                        splitHighlight = !isSameClassApplier && exclusive;\n\n                        // Replace the existing highlight if it needs to be:\n                        //  1. merged (isSameClassApplier)\n                        //  2. partially or entirely erased (className === null)\n                        //  3. partially or entirely replaced (isSameClassApplier == false && exclusive == true)\n                        if (    (highlightCharRange.intersects(charRange) || highlightCharRange.isContiguousWith(charRange)) &&\n                                (isSameClassApplier || splitHighlight) ) {\n\n                            // Remove existing highlights, keeping the unselected parts\n                            if (splitHighlight) {\n                                forEach(highlightCharRange.getComplements(charRange), function(rangeToAdd) {\n                                    highlightsToKeep.push( new Highlight(doc, rangeToAdd, highlights[j].classApplier, converter, null, containerElementId) );\n                                });\n                            }\n\n                            removeHighlight = true;\n                            if (isSameClassApplier) {\n                                charRange = highlightCharRange.union(charRange);\n                            }\n                        }\n                    }\n\n                    if (removeHighlight) {\n                        highlightsToRemove.push(highlights[j]);\n                        highlights[j] = new Highlight(doc, highlightCharRange.union(charRange), classApplier, converter, null, containerElementId);\n                    } else {\n                        highlightsToKeep.push(highlights[j]);\n                    }\n                }\n\n                // Add new range\n                if (classApplier) {\n                    highlightsToKeep.push(new Highlight(doc, charRange, classApplier, converter, null, containerElementId));\n                }\n                this.highlights = highlights = highlightsToKeep;\n            }\n\n            // Remove the old highlights\n            forEach(highlightsToRemove, function(highlightToRemove) {\n                highlightToRemove.unapply();\n            });\n\n            // Apply new highlights\n            var newHighlights = [];\n            forEach(highlights, function(highlight) {\n                if (!highlight.applied) {\n                    highlight.apply();\n                    newHighlights.push(highlight);\n                }\n            });\n\n            return newHighlights;\n        },\n\n        highlightRanges: function(className, ranges, options) {\n            var selCharRanges = [];\n            var converter = this.converter;\n\n            options = createOptions(options, {\n                containerElement: null,\n                exclusive: true\n            });\n\n            var containerElement = options.containerElement;\n            var containerElementId = containerElement ? containerElement.id : null;\n            var containerElementRange;\n            if (containerElement) {\n                containerElementRange = api.createRange(containerElement);\n                containerElementRange.selectNodeContents(containerElement);\n            }\n\n            forEach(ranges, function(range) {\n                var scopedRange = containerElement ? containerElementRange.intersection(range) : range;\n                selCharRanges.push( converter.rangeToCharacterRange(scopedRange, containerElement || getBody(range.getDocument())) );\n            });\n\n            return this.highlightCharacterRanges(className, selCharRanges, {\n                containerElementId: containerElementId,\n                exclusive: options.exclusive\n            });\n        },\n\n        highlightSelection: function(className, options) {\n            var converter = this.converter;\n            var classApplier = className ? this.classAppliers[className] : false;\n\n            options = createOptions(options, {\n                containerElementId: null,\n                exclusive: true\n            });\n\n            var containerElementId = options.containerElementId;\n            var exclusive = options.exclusive;\n            var selection = options.selection || api.getSelection(this.doc);\n            var doc = selection.win.document;\n            var containerElement = getContainerElement(doc, containerElementId);\n\n            if (!classApplier && className !== false) {\n                throw new Error(\"No class applier found for class '\" + className + \"'\");\n            }\n\n            // Store the existing selection as character ranges\n            var serializedSelection = converter.serializeSelection(selection, containerElement);\n\n            // Create an array of selected character ranges\n            var selCharRanges = [];\n            forEach(serializedSelection, function(rangeInfo) {\n                selCharRanges.push( CharacterRange.fromCharacterRange(rangeInfo.characterRange) );\n            });\n\n            var newHighlights = this.highlightCharacterRanges(className, selCharRanges, {\n                containerElementId: containerElementId,\n                exclusive: exclusive\n            });\n\n            // Restore selection\n            converter.restoreSelection(selection, serializedSelection, containerElement);\n\n            return newHighlights;\n        },\n\n        unhighlightSelection: function(selection) {\n            selection = selection || api.getSelection(this.doc);\n            var intersectingHighlights = this.getIntersectingHighlights( selection.getAllRanges() );\n            this.removeHighlights(intersectingHighlights);\n            selection.removeAllRanges();\n            return intersectingHighlights;\n        },\n\n        getHighlightsInSelection: function(selection) {\n            selection = selection || api.getSelection(this.doc);\n            return this.getIntersectingHighlights(selection.getAllRanges());\n        },\n\n        selectionOverlapsHighlight: function(selection) {\n            return this.getHighlightsInSelection(selection).length > 0;\n        },\n\n        serialize: function(options) {\n            var highlighter = this;\n            var highlights = highlighter.highlights;\n            var serializedType, serializedHighlights, convertType, serializationConverter;\n\n            highlights.sort(compareHighlights);\n            options = createOptions(options, {\n                serializeHighlightText: false,\n                type: highlighter.converter.type\n            });\n\n            serializedType = options.type;\n            convertType = (serializedType != highlighter.converter.type);\n\n            if (convertType) {\n                serializationConverter = getConverter(serializedType);\n            }\n\n            serializedHighlights = [\"type:\" + serializedType];\n\n            forEach(highlights, function(highlight) {\n                var characterRange = highlight.characterRange;\n                var containerElement;\n\n                // Convert to the current Highlighter's type, if different from the serialization type\n                if (convertType) {\n                    containerElement = highlight.getContainerElement();\n                    characterRange = serializationConverter.rangeToCharacterRange(\n                        highlighter.converter.characterRangeToRange(highlighter.doc, characterRange, containerElement),\n                        containerElement\n                    );\n                }\n\n                var parts = [\n                    characterRange.start,\n                    characterRange.end,\n                    highlight.id,\n                    highlight.classApplier.className,\n                    highlight.containerElementId\n                ];\n\n                if (options.serializeHighlightText) {\n                    parts.push(highlight.getText());\n                }\n                serializedHighlights.push( parts.join(\"$\") );\n            });\n\n            return serializedHighlights.join(\"|\");\n        },\n\n        deserialize: function(serialized) {\n            var serializedHighlights = serialized.split(\"|\");\n            var highlights = [];\n\n            var firstHighlight = serializedHighlights[0];\n            var regexResult;\n            var serializationType, serializationConverter, convertType = false;\n            if ( firstHighlight && (regexResult = /^type:(\\w+)$/.exec(firstHighlight)) ) {\n                serializationType = regexResult[1];\n                if (serializationType != this.converter.type) {\n                    serializationConverter = getConverter(serializationType);\n                    convertType = true;\n                }\n                serializedHighlights.shift();\n            } else {\n                throw new Error(\"Serialized highlights are invalid.\");\n            }\n\n            var classApplier, highlight, characterRange, containerElementId, containerElement;\n\n            for (var i = serializedHighlights.length, parts; i-- > 0; ) {\n                parts = serializedHighlights[i].split(\"$\");\n                characterRange = new CharacterRange(+parts[0], +parts[1]);\n                containerElementId = parts[4] || null;\n\n                // Convert to the current Highlighter's type, if different from the serialization type\n                if (convertType) {\n                    containerElement = getContainerElement(this.doc, containerElementId);\n                    characterRange = this.converter.rangeToCharacterRange(\n                        serializationConverter.characterRangeToRange(this.doc, characterRange, containerElement),\n                        containerElement\n                    );\n                }\n\n                classApplier = this.classAppliers[ parts[3] ];\n\n                if (!classApplier) {\n                    throw new Error(\"No class applier found for class '\" + parts[3] + \"'\");\n                }\n\n                highlight = new Highlight(this.doc, characterRange, classApplier, this.converter, parseInt(parts[2]), containerElementId);\n                highlight.apply();\n                highlights.push(highlight);\n            }\n            this.highlights = highlights;\n        }\n    };\n\n    api.Highlighter = Highlighter;\n\n    api.createHighlighter = function(doc, rangeCharacterOffsetConverterType) {\n        return new Highlighter(doc, rangeCharacterOffsetConverterType);\n    };\n});\n/* build:modularizeEnd */\n"
  },
  {
    "path": "readability.js",
    "content": "/*eslint-env es6:false*/\n/*\n * Copyright (c) 2010 Arc90 Inc\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * This code is heavily based on Arc90's readability.js (1.7.1) script\n * available at: http://code.google.com/p/arc90labs-readability\n */\n\n/**\n * Public constructor.\n * @param {HTMLDocument} doc     The document to parse.\n * @param {Object}       options The options object.\n */\nfunction Readability(doc, options) {\n  // In some older versions, people passed a URI as the first argument. Cope:\n  if (options && options.documentElement) {\n    doc = options;\n    options = arguments[2];\n  } else if (!doc || !doc.documentElement) {\n    throw new Error(\"First argument to Readability constructor should be a document object.\");\n  }\n  options = options || {};\n\n  this._doc = doc;\n  this._docJSDOMParser = this._doc.firstChild.__JSDOMParser__;\n  this._articleTitle = null;\n  this._articleByline = null;\n  this._articleDir = null;\n  this._articleSiteName = null;\n  this._attempts = [];\n\n  // Configurable options\n  this._debug = !!options.debug;\n  this._maxElemsToParse = options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE;\n  this._nbTopCandidates = options.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES;\n  this._charThreshold = options.charThreshold || this.DEFAULT_CHAR_THRESHOLD;\n  this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(options.classesToPreserve || []);\n  this._keepClasses = !!options.keepClasses;\n\n  // Start with all flags set\n  this._flags = this.FLAG_STRIP_UNLIKELYS |\n                this.FLAG_WEIGHT_CLASSES |\n                this.FLAG_CLEAN_CONDITIONALLY;\n\n  var logEl;\n\n  // Control whether log messages are sent to the console\n  if (this._debug) {\n    logEl = function(e) {\n      var rv = e.nodeName + \" \";\n      if (e.nodeType == e.TEXT_NODE) {\n        return rv + '(\"' + e.textContent + '\")';\n      }\n      var classDesc = e.className && (\".\" + e.className.replace(/ /g, \".\"));\n      var elDesc = \"\";\n      if (e.id)\n        elDesc = \"(#\" + e.id + classDesc + \")\";\n      else if (classDesc)\n        elDesc = \"(\" + classDesc + \")\";\n      return rv + elDesc;\n    };\n    this.log = function () {\n      if (typeof dump !== \"undefined\") {\n        var msg = Array.prototype.map.call(arguments, function(x) {\n          return (x && x.nodeName) ? logEl(x) : x;\n        }).join(\" \");\n        dump(\"Reader: (Readability) \" + msg + \"\\n\");\n      } else if (typeof console !== \"undefined\") {\n        var args = [\"Reader: (Readability) \"].concat(arguments);\n        console.log.apply(console, args);\n      }\n    };\n  } else {\n    this.log = function () {};\n  }\n}\n\nReadability.prototype = {\n  FLAG_STRIP_UNLIKELYS: 0x1,\n  FLAG_WEIGHT_CLASSES: 0x2,\n  FLAG_CLEAN_CONDITIONALLY: 0x4,\n\n  // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\n  ELEMENT_NODE: 1,\n  TEXT_NODE: 3,\n\n  // Max number of nodes supported by this parser. Default: 0 (no limit)\n  DEFAULT_MAX_ELEMS_TO_PARSE: 0,\n\n  // The number of top candidates to consider when analysing how\n  // tight the competition is among candidates.\n  DEFAULT_N_TOP_CANDIDATES: 5,\n\n  // Element tags to score by default.\n  DEFAULT_TAGS_TO_SCORE: \"section,h2,h3,h4,h5,h6,p,td,pre\".toUpperCase().split(\",\"),\n\n  // The default number of chars an article must have in order to return a result\n  DEFAULT_CHAR_THRESHOLD: 500,\n\n  // All of the regular expressions in use within readability.\n  // Defined up here so we don't instantiate them repeatedly in loops.\n  REGEXPS: {\n    // NOTE: These two regular expressions are duplicated in\n    // Readability-readerable.js. Please keep both copies in sync.\n    unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,\n    okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i,\n\n    positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,\n    negative: /hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,\n    extraneous: /print|archive|comment|discuss|e[\\-]?mail|share|reply|all|login|sign|single|utility/i,\n    byline: /byline|author|dateline|writtenby|p-author/i,\n    replaceFonts: /<(\\/?)font[^>]*>/gi,\n    normalize: /\\s{2,}/g,\n    videos: /\\/\\/(www\\.)?((dailymotion|youtube|youtube-nocookie|player\\.vimeo|v\\.qq)\\.com|(archive|upload\\.wikimedia)\\.org|player\\.twitch\\.tv)/i,\n    shareElements: /(\\b|_)(share|sharedaddy)(\\b|_)/i,\n    nextLink: /(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))/i,\n    prevLink: /(prev|earl|old|new|<|«)/i,\n    whitespace: /^\\s*$/,\n    hasContent: /\\S$/,\n  },\n\n  DIV_TO_P_ELEMS: [ \"A\", \"BLOCKQUOTE\", \"DL\", \"DIV\", \"IMG\", \"OL\", \"P\", \"PRE\", \"TABLE\", \"UL\", \"SELECT\" ],\n\n  ALTER_TO_DIV_EXCEPTIONS: [\"DIV\", \"ARTICLE\", \"SECTION\", \"P\"],\n\n  PRESENTATIONAL_ATTRIBUTES: [ \"align\", \"background\", \"bgcolor\", \"border\", \"cellpadding\", \"cellspacing\", \"frame\", \"hspace\", \"rules\", \"style\", \"valign\", \"vspace\" ],\n\n  DEPRECATED_SIZE_ATTRIBUTE_ELEMS: [ \"TABLE\", \"TH\", \"TD\", \"HR\", \"PRE\" ],\n\n  // The commented out elements qualify as phrasing content but tend to be\n  // removed by readability when put into paragraphs, so we ignore them here.\n  PHRASING_ELEMS: [\n    // \"CANVAS\", \"IFRAME\", \"SVG\", \"VIDEO\",\n    \"ABBR\", \"AUDIO\", \"B\", \"BDO\", \"BR\", \"BUTTON\", \"CITE\", \"CODE\", \"DATA\",\n    \"DATALIST\", \"DFN\", \"EM\", \"EMBED\", \"I\", \"IMG\", \"INPUT\", \"KBD\", \"LABEL\",\n    \"MARK\", \"MATH\", \"METER\", \"NOSCRIPT\", \"OBJECT\", \"OUTPUT\", \"PROGRESS\", \"Q\",\n    \"RUBY\", \"SAMP\", \"SCRIPT\", \"SELECT\", \"SMALL\", \"SPAN\", \"STRONG\", \"SUB\",\n    \"SUP\", \"TEXTAREA\", \"TIME\", \"VAR\", \"WBR\"\n  ],\n\n  // These are the classes that readability sets itself.\n  CLASSES_TO_PRESERVE: [ \"page\" ],\n\n  /**\n   * Run any post-process modifications to article content as necessary.\n   *\n   * @param Element\n   * @return void\n  **/\n  _postProcessContent: function(articleContent) {\n    // Readability cannot open relative uris so we convert them to absolute uris.\n    this._fixRelativeUris(articleContent);\n\n    if (!this._keepClasses) {\n      // Remove classes.\n      this._cleanClasses(articleContent);\n    }\n  },\n\n  /**\n   * Iterates over a NodeList, calls `filterFn` for each node and removes node\n   * if function returned `true`.\n   *\n   * If function is not passed, removes all the nodes in node list.\n   *\n   * @param NodeList nodeList The nodes to operate on\n   * @param Function filterFn the function to use as a filter\n   * @return void\n   */\n  _removeNodes: function(nodeList, filterFn) {\n    // Avoid ever operating on live node lists.\n    if (this._docJSDOMParser && nodeList._isLiveNodeList) {\n      throw new Error(\"Do not pass live node lists to _removeNodes\");\n    }\n    for (var i = nodeList.length - 1; i >= 0; i--) {\n      var node = nodeList[i];\n      var parentNode = node.parentNode;\n      if (parentNode) {\n        if (!filterFn || filterFn.call(this, node, i, nodeList)) {\n          parentNode.removeChild(node);\n        }\n      }\n    }\n  },\n\n  /**\n   * Iterates over a NodeList, and calls _setNodeTag for each node.\n   *\n   * @param NodeList nodeList The nodes to operate on\n   * @param String newTagName the new tag name to use\n   * @return void\n   */\n  _replaceNodeTags: function(nodeList, newTagName) {\n    // Avoid ever operating on live node lists.\n    if (this._docJSDOMParser && nodeList._isLiveNodeList) {\n      throw new Error(\"Do not pass live node lists to _replaceNodeTags\");\n    }\n    for (var i = nodeList.length - 1; i >= 0; i--) {\n      var node = nodeList[i];\n      this._setNodeTag(node, newTagName);\n    }\n  },\n\n  /**\n   * Iterate over a NodeList, which doesn't natively fully implement the Array\n   * interface.\n   *\n   * For convenience, the current object context is applied to the provided\n   * iterate function.\n   *\n   * @param  NodeList nodeList The NodeList.\n   * @param  Function fn       The iterate function.\n   * @return void\n   */\n  _forEachNode: function(nodeList, fn) {\n    Array.prototype.forEach.call(nodeList, fn, this);\n  },\n\n  /**\n   * Iterate over a NodeList, return true if any of the provided iterate\n   * function calls returns true, false otherwise.\n   *\n   * For convenience, the current object context is applied to the\n   * provided iterate function.\n   *\n   * @param  NodeList nodeList The NodeList.\n   * @param  Function fn       The iterate function.\n   * @return Boolean\n   */\n  _someNode: function(nodeList, fn) {\n    return Array.prototype.some.call(nodeList, fn, this);\n  },\n\n  /**\n   * Iterate over a NodeList, return true if all of the provided iterate\n   * function calls return true, false otherwise.\n   *\n   * For convenience, the current object context is applied to the\n   * provided iterate function.\n   *\n   * @param  NodeList nodeList The NodeList.\n   * @param  Function fn       The iterate function.\n   * @return Boolean\n   */\n  _everyNode: function(nodeList, fn) {\n    return Array.prototype.every.call(nodeList, fn, this);\n  },\n\n  /**\n   * Concat all nodelists passed as arguments.\n   *\n   * @return ...NodeList\n   * @return Array\n   */\n  _concatNodeLists: function() {\n    var slice = Array.prototype.slice;\n    var args = slice.call(arguments);\n    var nodeLists = args.map(function(list) {\n      return slice.call(list);\n    });\n    return Array.prototype.concat.apply([], nodeLists);\n  },\n\n  _getAllNodesWithTag: function(node, tagNames) {\n    if (node.querySelectorAll) {\n      return node.querySelectorAll(tagNames.join(\",\"));\n    }\n    return [].concat.apply([], tagNames.map(function(tag) {\n      var collection = node.getElementsByTagName(tag);\n      return Array.isArray(collection) ? collection : Array.from(collection);\n    }));\n  },\n\n  /**\n   * Removes the class=\"\" attribute from every element in the given\n   * subtree, except those that match CLASSES_TO_PRESERVE and\n   * the classesToPreserve array from the options object.\n   *\n   * @param Element\n   * @return void\n   */\n  _cleanClasses: function(node) {\n    var classesToPreserve = this._classesToPreserve;\n    var className = (node.getAttribute(\"class\") || \"\")\n      .split(/\\s+/)\n      .filter(function(cls) {\n        return classesToPreserve.indexOf(cls) != -1;\n      })\n      .join(\" \");\n\n    if (className) {\n      node.setAttribute(\"class\", className);\n    } else {\n      node.removeAttribute(\"class\");\n    }\n\n    for (node = node.firstElementChild; node; node = node.nextElementSibling) {\n      this._cleanClasses(node);\n    }\n  },\n\n  /**\n   * Converts each <a> and <img> uri in the given element to an absolute URI,\n   * ignoring #ref URIs.\n   *\n   * @param Element\n   * @return void\n   */\n  _fixRelativeUris: function(articleContent) {\n    var baseURI = this._doc.baseURI;\n    var documentURI = this._doc.documentURI;\n    function toAbsoluteURI(uri) {\n      // Leave hash links alone if the base URI matches the document URI:\n      if (baseURI == documentURI && uri.charAt(0) == \"#\") {\n        return uri;\n      }\n      // Otherwise, resolve against base URI:\n      try {\n        return new URL(uri, baseURI).href;\n      } catch (ex) {\n        // Something went wrong, just return the original:\n      }\n      return uri;\n    }\n\n    var links = this._getAllNodesWithTag(articleContent, [\"a\"]);\n    this._forEachNode(links, function(link) {\n      var href = link.getAttribute(\"href\");\n      if (href) {\n        // Remove links with javascript: URIs, since\n        // they won't work after scripts have been removed from the page.\n        if (href.indexOf(\"javascript:\") === 0) {\n          // if the link only contains simple text content, it can be converted to a text node\n          if (link.childNodes.length === 1 && link.childNodes[0].nodeType === this.TEXT_NODE) {\n            var text = this._doc.createTextNode(link.textContent);\n            link.parentNode.replaceChild(text, link);\n          } else {\n            // if the link has multiple children, they should all be preserved\n            var container = this._doc.createElement(\"span\");\n            while (link.childNodes.length > 0) {\n              container.appendChild(link.childNodes[0]);\n            }\n            link.parentNode.replaceChild(container, link);\n          }\n        } else {\n          link.setAttribute(\"href\", toAbsoluteURI(href));\n        }\n      }\n    });\n\n    var imgs = this._getAllNodesWithTag(articleContent, [\"img\"]);\n    this._forEachNode(imgs, function(img) {\n      var src = img.getAttribute(\"src\");\n      if (src) {\n        img.setAttribute(\"src\", toAbsoluteURI(src));\n      }\n    });\n  },\n\n  /**\n   * Get the article title as an H1.\n   *\n   * @return void\n   **/\n  _getArticleTitle: function() {\n    var doc = this._doc;\n    var curTitle = \"\";\n    var origTitle = \"\";\n\n    try {\n      curTitle = origTitle = doc.title.trim();\n\n      // If they had an element with id \"title\" in their HTML\n      if (typeof curTitle !== \"string\")\n        curTitle = origTitle = this._getInnerText(doc.getElementsByTagName(\"title\")[0]);\n    } catch (e) {/* ignore exceptions setting the title. */}\n\n    var titleHadHierarchicalSeparators = false;\n    function wordCount(str) {\n      return str.split(/\\s+/).length;\n    }\n\n    // If there's a separator in the title, first remove the final part\n    if ((/ [\\|\\-\\\\\\/>»] /).test(curTitle)) {\n      titleHadHierarchicalSeparators = / [\\\\\\/>»] /.test(curTitle);\n      curTitle = origTitle.replace(/(.*)[\\|\\-\\\\\\/>»] .*/gi, \"$1\");\n\n      // If the resulting title is too short (3 words or fewer), remove\n      // the first part instead:\n      if (wordCount(curTitle) < 3)\n        curTitle = origTitle.replace(/[^\\|\\-\\\\\\/>»]*[\\|\\-\\\\\\/>»](.*)/gi, \"$1\");\n    } else if (curTitle.indexOf(\": \") !== -1) {\n      // Check if we have an heading containing this exact string, so we\n      // could assume it's the full title.\n      var headings = this._concatNodeLists(\n        doc.getElementsByTagName(\"h1\"),\n        doc.getElementsByTagName(\"h2\")\n      );\n      var trimmedTitle = curTitle.trim();\n      var match = this._someNode(headings, function(heading) {\n        return heading.textContent.trim() === trimmedTitle;\n      });\n\n      // If we don't, let's extract the title out of the original title string.\n      if (!match) {\n        curTitle = origTitle.substring(origTitle.lastIndexOf(\":\") + 1);\n\n        // If the title is now too short, try the first colon instead:\n        if (wordCount(curTitle) < 3) {\n          curTitle = origTitle.substring(origTitle.indexOf(\":\") + 1);\n          // But if we have too many words before the colon there's something weird\n          // with the titles and the H tags so let's just use the original title instead\n        } else if (wordCount(origTitle.substr(0, origTitle.indexOf(\":\"))) > 5) {\n          curTitle = origTitle;\n        }\n      }\n    } else if (curTitle.length > 150 || curTitle.length < 15) {\n      var hOnes = doc.getElementsByTagName(\"h1\");\n\n      if (hOnes.length === 1)\n        curTitle = this._getInnerText(hOnes[0]);\n    }\n\n    curTitle = curTitle.trim().replace(this.REGEXPS.normalize, \" \");\n    // If we now have 4 words or fewer as our title, and either no\n    // 'hierarchical' separators (\\, /, > or ») were found in the original\n    // title or we decreased the number of words by more than 1 word, use\n    // the original title.\n    var curTitleWordCount = wordCount(curTitle);\n    if (curTitleWordCount <= 4 &&\n        (!titleHadHierarchicalSeparators ||\n         curTitleWordCount != wordCount(origTitle.replace(/[\\|\\-\\\\\\/>»]+/g, \"\")) - 1)) {\n      curTitle = origTitle;\n    }\n\n    return curTitle;\n  },\n\n  /**\n   * Prepare the HTML document for readability to scrape it.\n   * This includes things like stripping javascript, CSS, and handling terrible markup.\n   *\n   * @return void\n   **/\n  _prepDocument: function() {\n    var doc = this._doc;\n\n    // Remove all style tags in head\n    this._removeNodes(this._getAllNodesWithTag(doc, [\"style\"]));\n\n    if (doc.body) {\n      this._replaceBrs(doc.body);\n    }\n\n    this._replaceNodeTags(this._getAllNodesWithTag(doc, [\"font\"]), \"SPAN\");\n  },\n\n  /**\n   * Finds the next element, starting from the given node, and ignoring\n   * whitespace in between. If the given node is an element, the same node is\n   * returned.\n   */\n  _nextElement: function (node) {\n    var next = node;\n    while (next\n        && (next.nodeType != this.ELEMENT_NODE)\n        && this.REGEXPS.whitespace.test(next.textContent)) {\n      next = next.nextSibling;\n    }\n    return next;\n  },\n\n  /**\n   * Replaces 2 or more successive <br> elements with a single <p>.\n   * Whitespace between <br> elements are ignored. For example:\n   *   <div>foo<br>bar<br> <br><br>abc</div>\n   * will become:\n   *   <div>foo<br>bar<p>abc</p></div>\n   */\n  _replaceBrs: function (elem) {\n    this._forEachNode(this._getAllNodesWithTag(elem, [\"br\"]), function(br) {\n      var next = br.nextSibling;\n\n      // Whether 2 or more <br> elements have been found and replaced with a\n      // <p> block.\n      var replaced = false;\n\n      // If we find a <br> chain, remove the <br>s until we hit another element\n      // or non-whitespace. This leaves behind the first <br> in the chain\n      // (which will be replaced with a <p> later).\n      while ((next = this._nextElement(next)) && (next.tagName == \"BR\")) {\n        replaced = true;\n        var brSibling = next.nextSibling;\n        next.parentNode.removeChild(next);\n        next = brSibling;\n      }\n\n      // If we removed a <br> chain, replace the remaining <br> with a <p>. Add\n      // all sibling nodes as children of the <p> until we hit another <br>\n      // chain.\n      if (replaced) {\n        var p = this._doc.createElement(\"p\");\n        br.parentNode.replaceChild(p, br);\n\n        next = p.nextSibling;\n        while (next) {\n          // If we've hit another <br><br>, we're done adding children to this <p>.\n          if (next.tagName == \"BR\") {\n            var nextElem = this._nextElement(next.nextSibling);\n            if (nextElem && nextElem.tagName == \"BR\")\n              break;\n          }\n\n          if (!this._isPhrasingContent(next))\n            break;\n\n          // Otherwise, make this node a child of the new <p>.\n          var sibling = next.nextSibling;\n          p.appendChild(next);\n          next = sibling;\n        }\n\n        while (p.lastChild && this._isWhitespace(p.lastChild)) {\n          p.removeChild(p.lastChild);\n        }\n\n        if (p.parentNode.tagName === \"P\")\n          this._setNodeTag(p.parentNode, \"DIV\");\n      }\n    });\n  },\n\n  _setNodeTag: function (node, tag) {\n    this.log(\"_setNodeTag\", node, tag);\n    if (this._docJSDOMParser) {\n      node.localName = tag.toLowerCase();\n      node.tagName = tag.toUpperCase();\n      return node;\n    }\n\n    var replacement = node.ownerDocument.createElement(tag);\n    while (node.firstChild) {\n      replacement.appendChild(node.firstChild);\n    }\n    node.parentNode.replaceChild(replacement, node);\n    if (node.readability)\n      replacement.readability = node.readability;\n\n    for (var i = 0; i < node.attributes.length; i++) {\n      try {\n        replacement.setAttribute(node.attributes[i].name, node.attributes[i].value);\n      } catch (ex) {\n        /* it's possible for setAttribute() to throw if the attribute name\n         * isn't a valid XML Name. Such attributes can however be parsed from\n         * source in HTML docs, see https://github.com/whatwg/html/issues/4275,\n         * so we can hit them here and then throw. We don't care about such\n         * attributes so we ignore them.\n         */\n      }\n    }\n    return replacement;\n  },\n\n  /**\n   * Prepare the article node for display. Clean out any inline styles,\n   * iframes, forms, strip extraneous <p> tags, etc.\n   *\n   * @param Element\n   * @return void\n   **/\n  _prepArticle: function(articleContent) {\n    this._cleanStyles(articleContent);\n\n    // Check for data tables before we continue, to avoid removing items in\n    // those tables, which will often be isolated even though they're\n    // visually linked to other content-ful elements (text, images, etc.).\n    this._markDataTables(articleContent);\n\n    this._fixLazyImages(articleContent);\n\n    // Clean out junk from the article content\n    this._cleanConditionally(articleContent, \"form\");\n    this._cleanConditionally(articleContent, \"fieldset\");\n    this._clean(articleContent, \"object\");\n    this._clean(articleContent, \"embed\");\n    this._clean(articleContent, \"h1\");\n    this._clean(articleContent, \"footer\");\n    this._clean(articleContent, \"link\");\n    this._clean(articleContent, \"aside\");\n\n    // Clean out elements with little content that have \"share\" in their id/class combinations from final top candidates,\n    // which means we don't remove the top candidates even they have \"share\".\n\n    var shareElementThreshold = this.DEFAULT_CHAR_THRESHOLD;\n\n    this._forEachNode(articleContent.children, function (topCandidate) {\n      this._cleanMatchedNodes(topCandidate, function (node, matchString) {\n        return this.REGEXPS.shareElements.test(matchString) && node.textContent.length < shareElementThreshold;\n      });\n    });\n\n    // If there is only one h2 and its text content substantially equals article title,\n    // they are probably using it as a header and not a subheader,\n    // so remove it since we already extract the title separately.\n    var h2 = articleContent.getElementsByTagName(\"h2\");\n    if (h2.length === 1) {\n      var lengthSimilarRate = (h2[0].textContent.length - this._articleTitle.length) / this._articleTitle.length;\n      if (Math.abs(lengthSimilarRate) < 0.5) {\n        var titlesMatch = false;\n        if (lengthSimilarRate > 0) {\n          titlesMatch = h2[0].textContent.includes(this._articleTitle);\n        } else {\n          titlesMatch = this._articleTitle.includes(h2[0].textContent);\n        }\n        if (titlesMatch) {\n          this._clean(articleContent, \"h2\");\n        }\n      }\n    }\n\n    this._clean(articleContent, \"iframe\");\n    this._clean(articleContent, \"input\");\n    this._clean(articleContent, \"textarea\");\n    this._clean(articleContent, \"select\");\n    this._clean(articleContent, \"button\");\n    this._cleanHeaders(articleContent);\n\n    // Do these last as the previous stuff may have removed junk\n    // that will affect these\n    this._cleanConditionally(articleContent, \"table\");\n    this._cleanConditionally(articleContent, \"ul\");\n    this._cleanConditionally(articleContent, \"div\");\n\n    // Remove extra paragraphs\n    this._removeNodes(this._getAllNodesWithTag(articleContent, [\"p\"]), function (paragraph) {\n      var imgCount = paragraph.getElementsByTagName(\"img\").length;\n      var embedCount = paragraph.getElementsByTagName(\"embed\").length;\n      var objectCount = paragraph.getElementsByTagName(\"object\").length;\n      // At this point, nasty iframes have been removed, only remain embedded video ones.\n      var iframeCount = paragraph.getElementsByTagName(\"iframe\").length;\n      var totalCount = imgCount + embedCount + objectCount + iframeCount;\n\n      return totalCount === 0 && !this._getInnerText(paragraph, false);\n    });\n\n    this._forEachNode(this._getAllNodesWithTag(articleContent, [\"br\"]), function(br) {\n      var next = this._nextElement(br.nextSibling);\n      if (next && next.tagName == \"P\")\n        br.parentNode.removeChild(br);\n    });\n\n    // Remove single-cell tables\n    this._forEachNode(this._getAllNodesWithTag(articleContent, [\"table\"]), function(table) {\n      var tbody = this._hasSingleTagInsideElement(table, \"TBODY\") ? table.firstElementChild : table;\n      if (this._hasSingleTagInsideElement(tbody, \"TR\")) {\n        var row = tbody.firstElementChild;\n        if (this._hasSingleTagInsideElement(row, \"TD\")) {\n          var cell = row.firstElementChild;\n          cell = this._setNodeTag(cell, this._everyNode(cell.childNodes, this._isPhrasingContent) ? \"P\" : \"DIV\");\n          table.parentNode.replaceChild(cell, table);\n        }\n      }\n    });\n  },\n\n  /**\n   * Initialize a node with the readability object. Also checks the\n   * className/id for special names to add to its score.\n   *\n   * @param Element\n   * @return void\n  **/\n  _initializeNode: function(node) {\n    node.readability = {\"contentScore\": 0};\n\n    switch (node.tagName) {\n      case \"DIV\":\n        node.readability.contentScore += 5;\n        break;\n\n      case \"PRE\":\n      case \"TD\":\n      case \"BLOCKQUOTE\":\n        node.readability.contentScore += 3;\n        break;\n\n      case \"ADDRESS\":\n      case \"OL\":\n      case \"UL\":\n      case \"DL\":\n      case \"DD\":\n      case \"DT\":\n      case \"LI\":\n      case \"FORM\":\n        node.readability.contentScore -= 3;\n        break;\n\n      case \"H1\":\n      case \"H2\":\n      case \"H3\":\n      case \"H4\":\n      case \"H5\":\n      case \"H6\":\n      case \"TH\":\n        node.readability.contentScore -= 5;\n        break;\n    }\n\n    node.readability.contentScore += this._getClassWeight(node);\n  },\n\n  _removeAndGetNext: function(node) {\n    var nextNode = this._getNextNode(node, true);\n    node.parentNode.removeChild(node);\n    return nextNode;\n  },\n\n  /**\n   * Traverse the DOM from node to node, starting at the node passed in.\n   * Pass true for the second parameter to indicate this node itself\n   * (and its kids) are going away, and we want the next node over.\n   *\n   * Calling this in a loop will traverse the DOM depth-first.\n   */\n  _getNextNode: function(node, ignoreSelfAndKids) {\n    // First check for kids if those aren't being ignored\n    if (!ignoreSelfAndKids && node.firstElementChild) {\n      return node.firstElementChild;\n    }\n    // Then for siblings...\n    if (node.nextElementSibling) {\n      return node.nextElementSibling;\n    }\n    // And finally, move up the parent chain *and* find a sibling\n    // (because this is depth-first traversal, we will have already\n    // seen the parent nodes themselves).\n    do {\n      node = node.parentNode;\n    } while (node && !node.nextElementSibling);\n    return node && node.nextElementSibling;\n  },\n\n  _checkByline: function(node, matchString) {\n    if (this._articleByline) {\n      return false;\n    }\n\n    if (node.getAttribute !== undefined) {\n      var rel = node.getAttribute(\"rel\");\n      var itemprop = node.getAttribute(\"itemprop\");\n    }\n\n    if ((rel === \"author\" || (itemprop && itemprop.indexOf(\"author\") !== -1) || this.REGEXPS.byline.test(matchString)) && this._isValidByline(node.textContent)) {\n      this._articleByline = node.textContent.trim();\n      return true;\n    }\n\n    return false;\n  },\n\n  _getNodeAncestors: function(node, maxDepth) {\n    maxDepth = maxDepth || 0;\n    var i = 0, ancestors = [];\n    while (node.parentNode) {\n      ancestors.push(node.parentNode);\n      if (maxDepth && ++i === maxDepth)\n        break;\n      node = node.parentNode;\n    }\n    return ancestors;\n  },\n\n  /***\n   * grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is\n   *         most likely to be the stuff a user wants to read. Then return it wrapped up in a div.\n   *\n   * @param page a document to run upon. Needs to be a full document, complete with body.\n   * @return Element\n  **/\n  _grabArticle: function (page) {\n    this.log(\"**** grabArticle ****\");\n    var doc = this._doc;\n    var isPaging = (page !== null ? true: false);\n    page = page ? page : this._doc.body;\n\n    // We can't grab an article if we don't have a page!\n    if (!page) {\n      this.log(\"No body found in document. Abort.\");\n      return null;\n    }\n\n    var pageCacheHtml = page.innerHTML;\n\n    while (true) {\n      var stripUnlikelyCandidates = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS);\n\n      // First, node prepping. Trash nodes that look cruddy (like ones with the\n      // class name \"comment\", etc), and turn divs into P tags where they have been\n      // used inappropriately (as in, where they contain no other block level elements.)\n      var elementsToScore = [];\n      var node = this._doc.documentElement;\n\n      while (node) {\n        var matchString = node.className + \" \" + node.id;\n\n        if (!this._isProbablyVisible(node)) {\n          this.log(\"Removing hidden node - \" + matchString);\n          node = this._removeAndGetNext(node);\n          continue;\n        }\n\n        // Check to see if this node is a byline, and remove it if it is.\n        if (this._checkByline(node, matchString)) {\n          node = this._removeAndGetNext(node);\n          continue;\n        }\n\n        // Remove unlikely candidates\n        if (stripUnlikelyCandidates) {\n          if (this.REGEXPS.unlikelyCandidates.test(matchString) &&\n              !this.REGEXPS.okMaybeItsACandidate.test(matchString) &&\n              !this._hasAncestorTag(node, \"table\") &&\n              node.tagName !== \"BODY\" &&\n              node.tagName !== \"A\") {\n            this.log(\"Removing unlikely candidate - \" + matchString);\n            node = this._removeAndGetNext(node);\n            continue;\n          }\n        }\n\n        // Remove DIV, SECTION, and HEADER nodes without any content(e.g. text, image, video, or iframe).\n        if ((node.tagName === \"DIV\" || node.tagName === \"SECTION\" || node.tagName === \"HEADER\" ||\n             node.tagName === \"H1\" || node.tagName === \"H2\" || node.tagName === \"H3\" ||\n             node.tagName === \"H4\" || node.tagName === \"H5\" || node.tagName === \"H6\") &&\n            this._isElementWithoutContent(node)) {\n          node = this._removeAndGetNext(node);\n          continue;\n        }\n\n        if (this.DEFAULT_TAGS_TO_SCORE.indexOf(node.tagName) !== -1) {\n          elementsToScore.push(node);\n        }\n\n        // Turn all divs that don't have children block level elements into p's\n        if (node.tagName === \"DIV\") {\n          // Put phrasing content into paragraphs.\n          var p = null;\n          var childNode = node.firstChild;\n          while (childNode) {\n            var nextSibling = childNode.nextSibling;\n            if (this._isPhrasingContent(childNode)) {\n              if (p !== null) {\n                p.appendChild(childNode);\n              } else if (!this._isWhitespace(childNode)) {\n                p = doc.createElement(\"p\");\n                node.replaceChild(p, childNode);\n                p.appendChild(childNode);\n              }\n            } else if (p !== null) {\n              while (p.lastChild && this._isWhitespace(p.lastChild)) {\n                p.removeChild(p.lastChild);\n              }\n              p = null;\n            }\n            childNode = nextSibling;\n          }\n\n          // Sites like http://mobile.slate.com encloses each paragraph with a DIV\n          // element. DIVs with only a P element inside and no text content can be\n          // safely converted into plain P elements to avoid confusing the scoring\n          // algorithm with DIVs with are, in practice, paragraphs.\n          if (this._hasSingleTagInsideElement(node, \"P\") && this._getLinkDensity(node) < 0.25) {\n            var newNode = node.children[0];\n            node.parentNode.replaceChild(newNode, node);\n            node = newNode;\n            elementsToScore.push(node);\n          } else if (!this._hasChildBlockElement(node)) {\n            node = this._setNodeTag(node, \"P\");\n            elementsToScore.push(node);\n          }\n        }\n        node = this._getNextNode(node);\n      }\n\n      /**\n       * Loop through all paragraphs, and assign a score to them based on how content-y they look.\n       * Then add their score to their parent node.\n       *\n       * A score is determined by things like number of commas, class names, etc. Maybe eventually link density.\n      **/\n      var candidates = [];\n      this._forEachNode(elementsToScore, function(elementToScore) {\n        if (!elementToScore.parentNode || typeof(elementToScore.parentNode.tagName) === \"undefined\")\n          return;\n\n        // If this paragraph is less than 25 characters, don't even count it.\n        var innerText = this._getInnerText(elementToScore);\n        if (innerText.length < 25)\n          return;\n\n        // Exclude nodes with no ancestor.\n        var ancestors = this._getNodeAncestors(elementToScore, 3);\n        if (ancestors.length === 0)\n          return;\n\n        var contentScore = 0;\n\n        // Add a point for the paragraph itself as a base.\n        contentScore += 1;\n\n        // Add points for any commas within this paragraph.\n        contentScore += innerText.split(\",\").length;\n\n        // For every 100 characters in this paragraph, add another point. Up to 3 points.\n        contentScore += Math.min(Math.floor(innerText.length / 100), 3);\n\n        // Initialize and score ancestors.\n        this._forEachNode(ancestors, function(ancestor, level) {\n          if (!ancestor.tagName || !ancestor.parentNode || typeof(ancestor.parentNode.tagName) === \"undefined\")\n            return;\n\n          if (typeof(ancestor.readability) === \"undefined\") {\n            this._initializeNode(ancestor);\n            candidates.push(ancestor);\n          }\n\n          // Node score divider:\n          // - parent:             1 (no division)\n          // - grandparent:        2\n          // - great grandparent+: ancestor level * 3\n          if (level === 0)\n            var scoreDivider = 1;\n          else if (level === 1)\n            scoreDivider = 2;\n          else\n            scoreDivider = level * 3;\n          ancestor.readability.contentScore += contentScore / scoreDivider;\n        });\n      });\n\n      // After we've calculated scores, loop through all of the possible\n      // candidate nodes we found and find the one with the highest score.\n      var topCandidates = [];\n      for (var c = 0, cl = candidates.length; c < cl; c += 1) {\n        var candidate = candidates[c];\n\n        // Scale the final candidates score based on link density. Good content\n        // should have a relatively small link density (5% or less) and be mostly\n        // unaffected by this operation.\n        var candidateScore = candidate.readability.contentScore * (1 - this._getLinkDensity(candidate));\n        candidate.readability.contentScore = candidateScore;\n\n        this.log(\"Candidate:\", candidate, \"with score \" + candidateScore);\n\n        for (var t = 0; t < this._nbTopCandidates; t++) {\n          var aTopCandidate = topCandidates[t];\n\n          if (!aTopCandidate || candidateScore > aTopCandidate.readability.contentScore) {\n            topCandidates.splice(t, 0, candidate);\n            if (topCandidates.length > this._nbTopCandidates)\n              topCandidates.pop();\n            break;\n          }\n        }\n      }\n\n      var topCandidate = topCandidates[0] || null;\n      var neededToCreateTopCandidate = false;\n      var parentOfTopCandidate;\n\n      // If we still have no top candidate, just use the body as a last resort.\n      // We also have to copy the body node so it is something we can modify.\n      if (topCandidate === null || topCandidate.tagName === \"BODY\") {\n        // Move all of the page's children into topCandidate\n        topCandidate = doc.createElement(\"DIV\");\n        neededToCreateTopCandidate = true;\n        // Move everything (not just elements, also text nodes etc.) into the container\n        // so we even include text directly in the body:\n        var kids = page.childNodes;\n        while (kids.length) {\n          this.log(\"Moving child out:\", kids[0]);\n          topCandidate.appendChild(kids[0]);\n        }\n\n        page.appendChild(topCandidate);\n\n        this._initializeNode(topCandidate);\n      } else if (topCandidate) {\n        // Find a better top candidate node if it contains (at least three) nodes which belong to `topCandidates` array\n        // and whose scores are quite closed with current `topCandidate` node.\n        var alternativeCandidateAncestors = [];\n        for (var i = 1; i < topCandidates.length; i++) {\n          if (topCandidates[i].readability.contentScore / topCandidate.readability.contentScore >= 0.75) {\n            alternativeCandidateAncestors.push(this._getNodeAncestors(topCandidates[i]));\n          }\n        }\n        var MINIMUM_TOPCANDIDATES = 3;\n        if (alternativeCandidateAncestors.length >= MINIMUM_TOPCANDIDATES) {\n          parentOfTopCandidate = topCandidate.parentNode;\n          while (parentOfTopCandidate.tagName !== \"BODY\") {\n            var listsContainingThisAncestor = 0;\n            for (var ancestorIndex = 0; ancestorIndex < alternativeCandidateAncestors.length && listsContainingThisAncestor < MINIMUM_TOPCANDIDATES; ancestorIndex++) {\n              listsContainingThisAncestor += Number(alternativeCandidateAncestors[ancestorIndex].includes(parentOfTopCandidate));\n            }\n            if (listsContainingThisAncestor >= MINIMUM_TOPCANDIDATES) {\n              topCandidate = parentOfTopCandidate;\n              break;\n            }\n            parentOfTopCandidate = parentOfTopCandidate.parentNode;\n          }\n        }\n        if (!topCandidate.readability) {\n          this._initializeNode(topCandidate);\n        }\n\n        // Because of our bonus system, parents of candidates might have scores\n        // themselves. They get half of the node. There won't be nodes with higher\n        // scores than our topCandidate, but if we see the score going *up* in the first\n        // few steps up the tree, that's a decent sign that there might be more content\n        // lurking in other places that we want to unify in. The sibling stuff\n        // below does some of that - but only if we've looked high enough up the DOM\n        // tree.\n        parentOfTopCandidate = topCandidate.parentNode;\n        var lastScore = topCandidate.readability.contentScore;\n        // The scores shouldn't get too low.\n        var scoreThreshold = lastScore / 3;\n        while (parentOfTopCandidate.tagName !== \"BODY\") {\n          if (!parentOfTopCandidate.readability) {\n            parentOfTopCandidate = parentOfTopCandidate.parentNode;\n            continue;\n          }\n          var parentScore = parentOfTopCandidate.readability.contentScore;\n          if (parentScore < scoreThreshold)\n            break;\n          if (parentScore > lastScore) {\n            // Alright! We found a better parent to use.\n            topCandidate = parentOfTopCandidate;\n            break;\n          }\n          lastScore = parentOfTopCandidate.readability.contentScore;\n          parentOfTopCandidate = parentOfTopCandidate.parentNode;\n        }\n\n        // If the top candidate is the only child, use parent instead. This will help sibling\n        // joining logic when adjacent content is actually located in parent's sibling node.\n        parentOfTopCandidate = topCandidate.parentNode;\n        while (parentOfTopCandidate.tagName != \"BODY\" && parentOfTopCandidate.children.length == 1) {\n          topCandidate = parentOfTopCandidate;\n          parentOfTopCandidate = topCandidate.parentNode;\n        }\n        if (!topCandidate.readability) {\n          this._initializeNode(topCandidate);\n        }\n      }\n\n      // Now that we have the top candidate, look through its siblings for content\n      // that might also be related. Things like preambles, content split by ads\n      // that we removed, etc.\n      var articleContent = doc.createElement(\"DIV\");\n      if (isPaging)\n        articleContent.id = \"readability-content\";\n\n      var siblingScoreThreshold = Math.max(10, topCandidate.readability.contentScore * 0.2);\n      // Keep potential top candidate's parent node to try to get text direction of it later.\n      parentOfTopCandidate = topCandidate.parentNode;\n      var siblings = parentOfTopCandidate.children;\n\n      for (var s = 0, sl = siblings.length; s < sl; s++) {\n        var sibling = siblings[s];\n        var append = false;\n\n        this.log(\"Looking at sibling node:\", sibling, sibling.readability ? (\"with score \" + sibling.readability.contentScore) : \"\");\n        this.log(\"Sibling has score\", sibling.readability ? sibling.readability.contentScore : \"Unknown\");\n\n        if (sibling === topCandidate) {\n          append = true;\n        } else {\n          var contentBonus = 0;\n\n          // Give a bonus if sibling nodes and top candidates have the example same classname\n          if (sibling.className === topCandidate.className && topCandidate.className !== \"\")\n            contentBonus += topCandidate.readability.contentScore * 0.2;\n\n          if (sibling.readability &&\n              ((sibling.readability.contentScore + contentBonus) >= siblingScoreThreshold)) {\n            append = true;\n          } else if (sibling.nodeName === \"P\") {\n            var linkDensity = this._getLinkDensity(sibling);\n            var nodeContent = this._getInnerText(sibling);\n            var nodeLength = nodeContent.length;\n\n            if (nodeLength > 80 && linkDensity < 0.25) {\n              append = true;\n            } else if (nodeLength < 80 && nodeLength > 0 && linkDensity === 0 &&\n                       nodeContent.search(/\\.( |$)/) !== -1) {\n              append = true;\n            }\n          }\n        }\n\n        if (append) {\n          this.log(\"Appending node:\", sibling);\n\n          if (this.ALTER_TO_DIV_EXCEPTIONS.indexOf(sibling.nodeName) === -1) {\n            // We have a node that isn't a common block level element, like a form or td tag.\n            // Turn it into a div so it doesn't get filtered out later by accident.\n            this.log(\"Altering sibling:\", sibling, \"to div.\");\n\n            sibling = this._setNodeTag(sibling, \"DIV\");\n          }\n\n          articleContent.appendChild(sibling);\n          // siblings is a reference to the children array, and\n          // sibling is removed from the array when we call appendChild().\n          // As a result, we must revisit this index since the nodes\n          // have been shifted.\n          s -= 1;\n          sl -= 1;\n        }\n      }\n\n      if (this._debug)\n        this.log(\"Article content pre-prep: \" + articleContent.innerHTML);\n      // So we have all of the content that we need. Now we clean it up for presentation.\n      this._prepArticle(articleContent);\n      if (this._debug)\n        this.log(\"Article content post-prep: \" + articleContent.innerHTML);\n\n      if (neededToCreateTopCandidate) {\n        // We already created a fake div thing, and there wouldn't have been any siblings left\n        // for the previous loop, so there's no point trying to create a new div, and then\n        // move all the children over. Just assign IDs and class names here. No need to append\n        // because that already happened anyway.\n        topCandidate.id = \"readability-page-1\";\n        topCandidate.className = \"page\";\n      } else {\n        var div = doc.createElement(\"DIV\");\n        div.id = \"readability-page-1\";\n        div.className = \"page\";\n        var children = articleContent.childNodes;\n        while (children.length) {\n          div.appendChild(children[0]);\n        }\n        articleContent.appendChild(div);\n      }\n\n      if (this._debug)\n        this.log(\"Article content after paging: \" + articleContent.innerHTML);\n\n      var parseSuccessful = true;\n\n      // Now that we've gone through the full algorithm, check to see if\n      // we got any meaningful content. If we didn't, we may need to re-run\n      // grabArticle with different flags set. This gives us a higher likelihood of\n      // finding the content, and the sieve approach gives us a higher likelihood of\n      // finding the -right- content.\n      var textLength = this._getInnerText(articleContent, true).length;\n      if (textLength < this._charThreshold) {\n        parseSuccessful = false;\n        page.innerHTML = pageCacheHtml;\n\n        if (this._flagIsActive(this.FLAG_STRIP_UNLIKELYS)) {\n          this._removeFlag(this.FLAG_STRIP_UNLIKELYS);\n          this._attempts.push({articleContent: articleContent, textLength: textLength});\n        } else if (this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) {\n          this._removeFlag(this.FLAG_WEIGHT_CLASSES);\n          this._attempts.push({articleContent: articleContent, textLength: textLength});\n        } else if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) {\n          this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY);\n          this._attempts.push({articleContent: articleContent, textLength: textLength});\n        } else {\n          this._attempts.push({articleContent: articleContent, textLength: textLength});\n          // No luck after removing flags, just return the longest text we found during the different loops\n          this._attempts.sort(function (a, b) {\n            return b.textLength - a.textLength;\n          });\n\n          // But first check if we actually have something\n          if (!this._attempts[0].textLength) {\n            return null;\n          }\n\n          articleContent = this._attempts[0].articleContent;\n          parseSuccessful = true;\n        }\n      }\n\n      if (parseSuccessful) {\n        // Find out text direction from ancestors of final top candidate.\n        var ancestors = [parentOfTopCandidate, topCandidate].concat(this._getNodeAncestors(parentOfTopCandidate));\n        this._someNode(ancestors, function(ancestor) {\n          if (!ancestor.tagName)\n            return false;\n          var articleDir = ancestor.getAttribute(\"dir\");\n          if (articleDir) {\n            this._articleDir = articleDir;\n            return true;\n          }\n          return false;\n        });\n        return articleContent;\n      }\n    }\n  },\n\n  /**\n   * Check whether the input string could be a byline.\n   * This verifies that the input is a string, and that the length\n   * is less than 100 chars.\n   *\n   * @param possibleByline {string} - a string to check whether its a byline.\n   * @return Boolean - whether the input string is a byline.\n   */\n  _isValidByline: function(byline) {\n    if (typeof byline == \"string\" || byline instanceof String) {\n      byline = byline.trim();\n      return (byline.length > 0) && (byline.length < 100);\n    }\n    return false;\n  },\n\n  /**\n   * Attempts to get excerpt and byline metadata for the article.\n   *\n   * @return Object with optional \"excerpt\" and \"byline\" properties\n   */\n  _getArticleMetadata: function() {\n    var metadata = {};\n    var values = {};\n    var metaElements = this._doc.getElementsByTagName(\"meta\");\n\n    // property is a space-separated list of values\n    var propertyPattern = /\\s*(dc|dcterm|og|twitter)\\s*:\\s*(author|creator|description|title|site_name)\\s*/gi;\n\n    // name is a single value\n    var namePattern = /^\\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\\s*[\\.:]\\s*)?(author|creator|description|title|site_name)\\s*$/i;\n\n    // Find description tags.\n    this._forEachNode(metaElements, function(element) {\n      var elementName = element.getAttribute(\"name\");\n      var elementProperty = element.getAttribute(\"property\");\n      var content = element.getAttribute(\"content\");\n      if (!content) {\n        return;\n      }\n      var matches = null;\n      var name = null;\n\n      if (elementProperty) {\n        matches = elementProperty.match(propertyPattern);\n        if (matches) {\n          for (var i = matches.length - 1; i >= 0; i--) {\n            // Convert to lowercase, and remove any whitespace\n            // so we can match below.\n            name = matches[i].toLowerCase().replace(/\\s/g, \"\");\n            // multiple authors\n            values[name] = content.trim();\n          }\n        }\n      }\n      if (!matches && elementName && namePattern.test(elementName)) {\n        name = elementName;\n        if (content) {\n          // Convert to lowercase, remove any whitespace, and convert dots\n          // to colons so we can match below.\n          name = name.toLowerCase().replace(/\\s/g, \"\").replace(/\\./g, \":\");\n          values[name] = content.trim();\n        }\n      }\n    });\n\n    // get title\n    metadata.title = values[\"dc:title\"] ||\n                     values[\"dcterm:title\"] ||\n                     values[\"og:title\"] ||\n                     values[\"weibo:article:title\"] ||\n                     values[\"weibo:webpage:title\"] ||\n                     values[\"title\"] ||\n                     values[\"twitter:title\"];\n\n    if (!metadata.title) {\n      metadata.title = this._getArticleTitle();\n    }\n\n    // get author\n    metadata.byline = values[\"dc:creator\"] ||\n                      values[\"dcterm:creator\"] ||\n                      values[\"author\"];\n\n    // get description\n    metadata.excerpt = values[\"dc:description\"] ||\n                       values[\"dcterm:description\"] ||\n                       values[\"og:description\"] ||\n                       values[\"weibo:article:description\"] ||\n                       values[\"weibo:webpage:description\"] ||\n                       values[\"description\"] ||\n                       values[\"twitter:description\"];\n\n    // get site name\n    metadata.siteName = values[\"og:site_name\"];\n\n    return metadata;\n  },\n\n  /**\n   * Check if node is image, or if node contains exactly only one image\n   * whether as a direct child or as its descendants.\n   *\n   * @param Element\n  **/\n  _isSingleImage: function(node) {\n    if (node.tagName === \"IMG\") {\n      return true;\n    }\n\n    if (node.children.length !== 1 || node.textContent.trim() !== \"\") {\n      return false;\n    }\n\n    return this._isSingleImage(node.children[0]);\n  },\n\n  /**\n   * Find all <noscript> that are located after <img> nodes, and which contain only one\n   * <img> element. Replace the first image with the image from inside the <noscript> tag,\n   * and remove the <noscript> tag. This improves the quality of the images we use on\n   * some sites (e.g. Medium).\n   *\n   * @param Element\n  **/\n  _unwrapNoscriptImages: function(doc) {\n    // Find img without source or attributes that might contains image, and remove it.\n    // This is done to prevent a placeholder img is replaced by img from noscript in next step.\n    var imgs = Array.from(doc.getElementsByTagName(\"img\"));\n    this._forEachNode(imgs, function(img) {\n      for (var i = 0; i < img.attributes.length; i++) {\n        var attr = img.attributes[i];\n        switch (attr.name) {\n          case \"src\":\n          case \"srcset\":\n          case \"data-src\":\n          case \"data-srcset\":\n            return;\n        }\n\n        if (/\\.(jpg|jpeg|png|webp)/i.test(attr.value)) {\n          return;\n        }\n      }\n\n      img.parentNode.removeChild(img);\n    });\n\n    // Next find noscript and try to extract its image\n    var noscripts = Array.from(doc.getElementsByTagName(\"noscript\"));\n    this._forEachNode(noscripts, function(noscript) {\n      // Parse content of noscript and make sure it only contains image\n      var tmp = doc.createElement(\"div\");\n      tmp.innerHTML = noscript.innerHTML;\n      if (!this._isSingleImage(tmp)) {\n        return;\n      }\n\n      // If noscript has previous sibling and it only contains image,\n      // replace it with noscript content. However we also keep old\n      // attributes that might contains image.\n      var prevElement = noscript.previousElementSibling;\n      if (prevElement && this._isSingleImage(prevElement)) {\n        var prevImg = prevElement;\n        if (prevImg.tagName !== \"IMG\") {\n          prevImg = prevElement.getElementsByTagName(\"img\")[0];\n        }\n\n        var newImg = tmp.getElementsByTagName(\"img\")[0];\n        for (var i = 0; i < prevImg.attributes.length; i++) {\n          var attr = prevImg.attributes[i];\n          if (attr.value === \"\") {\n            continue;\n          }\n\n          if (attr.name === \"src\" || attr.name === \"srcset\" || /\\.(jpg|jpeg|png|webp)/i.test(attr.value)) {\n            if (newImg.getAttribute(attr.name) === attr.value) {\n              continue;\n            }\n\n            var attrName = attr.name;\n            if (newImg.hasAttribute(attrName)) {\n              attrName = \"data-old-\" + attrName;\n            }\n\n            newImg.setAttribute(attrName, attr.value);\n          }\n        }\n\n        noscript.parentNode.replaceChild(tmp.firstElementChild, prevElement);\n      }\n    });\n  },\n\n  /**\n   * Removes script tags from the document.\n   *\n   * @param Element\n  **/\n  _removeScripts: function(doc) {\n    this._removeNodes(this._getAllNodesWithTag(doc, [\"script\"]), function(scriptNode) {\n      scriptNode.nodeValue = \"\";\n      scriptNode.removeAttribute(\"src\");\n      return true;\n    });\n    this._removeNodes(this._getAllNodesWithTag(doc, [\"noscript\"]));\n  },\n\n  /**\n   * Check if this node has only whitespace and a single element with given tag\n   * Returns false if the DIV node contains non-empty text nodes\n   * or if it contains no element with given tag or more than 1 element.\n   *\n   * @param Element\n   * @param string tag of child element\n  **/\n  _hasSingleTagInsideElement: function(element, tag) {\n    // There should be exactly 1 element child with given tag\n    if (element.children.length != 1 || element.children[0].tagName !== tag) {\n      return false;\n    }\n\n    // And there should be no text nodes with real content\n    return !this._someNode(element.childNodes, function(node) {\n      return node.nodeType === this.TEXT_NODE &&\n             this.REGEXPS.hasContent.test(node.textContent);\n    });\n  },\n\n  _isElementWithoutContent: function(node) {\n    return node.nodeType === this.ELEMENT_NODE &&\n      node.textContent.trim().length == 0 &&\n      (node.children.length == 0 ||\n       node.children.length == node.getElementsByTagName(\"br\").length + node.getElementsByTagName(\"hr\").length);\n  },\n\n  /**\n   * Determine whether element has any children block level elements.\n   *\n   * @param Element\n   */\n  _hasChildBlockElement: function (element) {\n    return this._someNode(element.childNodes, function(node) {\n      return this.DIV_TO_P_ELEMS.indexOf(node.tagName) !== -1 ||\n             this._hasChildBlockElement(node);\n    });\n  },\n\n  /***\n   * Determine if a node qualifies as phrasing content.\n   * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content\n  **/\n  _isPhrasingContent: function(node) {\n    return node.nodeType === this.TEXT_NODE || this.PHRASING_ELEMS.indexOf(node.tagName) !== -1 ||\n      ((node.tagName === \"A\" || node.tagName === \"DEL\" || node.tagName === \"INS\") &&\n        this._everyNode(node.childNodes, this._isPhrasingContent));\n  },\n\n  _isWhitespace: function(node) {\n    return (node.nodeType === this.TEXT_NODE && node.textContent.trim().length === 0) ||\n           (node.nodeType === this.ELEMENT_NODE && node.tagName === \"BR\");\n  },\n\n  /**\n   * Get the inner text of a node - cross browser compatibly.\n   * This also strips out any excess whitespace to be found.\n   *\n   * @param Element\n   * @param Boolean normalizeSpaces (default: true)\n   * @return string\n  **/\n  _getInnerText: function(e, normalizeSpaces) {\n    normalizeSpaces = (typeof normalizeSpaces === \"undefined\") ? true : normalizeSpaces;\n    var textContent = e.textContent.trim();\n\n    if (normalizeSpaces) {\n      return textContent.replace(this.REGEXPS.normalize, \" \");\n    }\n    return textContent;\n  },\n\n  /**\n   * Get the number of times a string s appears in the node e.\n   *\n   * @param Element\n   * @param string - what to split on. Default is \",\"\n   * @return number (integer)\n  **/\n  _getCharCount: function(e, s) {\n    s = s || \",\";\n    return this._getInnerText(e).split(s).length - 1;\n  },\n\n  /**\n   * Remove the style attribute on every e and under.\n   * TODO: Test if getElementsByTagName(*) is faster.\n   *\n   * @param Element\n   * @return void\n  **/\n  _cleanStyles: function(e) {\n    if (!e || e.tagName.toLowerCase() === \"svg\")\n      return;\n\n    // Remove `style` and deprecated presentational attributes\n    for (var i = 0; i < this.PRESENTATIONAL_ATTRIBUTES.length; i++) {\n      e.removeAttribute(this.PRESENTATIONAL_ATTRIBUTES[i]);\n    }\n\n    if (this.DEPRECATED_SIZE_ATTRIBUTE_ELEMS.indexOf(e.tagName) !== -1) {\n      e.removeAttribute(\"width\");\n      e.removeAttribute(\"height\");\n    }\n\n    var cur = e.firstElementChild;\n    while (cur !== null) {\n      this._cleanStyles(cur);\n      cur = cur.nextElementSibling;\n    }\n  },\n\n  /**\n   * Get the density of links as a percentage of the content\n   * This is the amount of text that is inside a link divided by the total text in the node.\n   *\n   * @param Element\n   * @return number (float)\n  **/\n  _getLinkDensity: function(element) {\n    var textLength = this._getInnerText(element).length;\n    if (textLength === 0)\n      return 0;\n\n    var linkLength = 0;\n\n    // XXX implement _reduceNodeList?\n    this._forEachNode(element.getElementsByTagName(\"a\"), function(linkNode) {\n      linkLength += this._getInnerText(linkNode).length;\n    });\n\n    return linkLength / textLength;\n  },\n\n  /**\n   * Get an elements class/id weight. Uses regular expressions to tell if this\n   * element looks good or bad.\n   *\n   * @param Element\n   * @return number (Integer)\n  **/\n  _getClassWeight: function(e) {\n    if (!this._flagIsActive(this.FLAG_WEIGHT_CLASSES))\n      return 0;\n\n    var weight = 0;\n\n    // Look for a special classname\n    if (typeof(e.className) === \"string\" && e.className !== \"\") {\n      if (this.REGEXPS.negative.test(e.className))\n        weight -= 25;\n\n      if (this.REGEXPS.positive.test(e.className))\n        weight += 25;\n    }\n\n    // Look for a special ID\n    if (typeof(e.id) === \"string\" && e.id !== \"\") {\n      if (this.REGEXPS.negative.test(e.id))\n        weight -= 25;\n\n      if (this.REGEXPS.positive.test(e.id))\n        weight += 25;\n    }\n\n    return weight;\n  },\n\n  /**\n   * Clean a node of all elements of type \"tag\".\n   * (Unless it's a youtube/vimeo video. People love movies.)\n   *\n   * @param Element\n   * @param string tag to clean\n   * @return void\n   **/\n  _clean: function(e, tag) {\n    var isEmbed = [\"object\", \"embed\", \"iframe\"].indexOf(tag) !== -1;\n\n    this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(element) {\n      // Allow youtube and vimeo videos through as people usually want to see those.\n      if (isEmbed) {\n        // First, check the elements attributes to see if any of them contain youtube or vimeo\n        for (var i = 0; i < element.attributes.length; i++) {\n          if (this.REGEXPS.videos.test(element.attributes[i].value)) {\n            return false;\n          }\n        }\n\n        // For embed with <object> tag, check inner HTML as well.\n        if (element.tagName === \"object\" && this.REGEXPS.videos.test(element.innerHTML)) {\n          return false;\n        }\n      }\n\n      return true;\n    });\n  },\n\n  /**\n   * Check if a given node has one of its ancestor tag name matching the\n   * provided one.\n   * @param  HTMLElement node\n   * @param  String      tagName\n   * @param  Number      maxDepth\n   * @param  Function    filterFn a filter to invoke to determine whether this node 'counts'\n   * @return Boolean\n   */\n  _hasAncestorTag: function(node, tagName, maxDepth, filterFn) {\n    maxDepth = maxDepth || 3;\n    tagName = tagName.toUpperCase();\n    var depth = 0;\n    while (node.parentNode) {\n      if (maxDepth > 0 && depth > maxDepth)\n        return false;\n      if (node.parentNode.tagName === tagName && (!filterFn || filterFn(node.parentNode)))\n        return true;\n      node = node.parentNode;\n      depth++;\n    }\n    return false;\n  },\n\n  /**\n   * Return an object indicating how many rows and columns this table has.\n   */\n  _getRowAndColumnCount: function(table) {\n    var rows = 0;\n    var columns = 0;\n    var trs = table.getElementsByTagName(\"tr\");\n    for (var i = 0; i < trs.length; i++) {\n      var rowspan = trs[i].getAttribute(\"rowspan\") || 0;\n      if (rowspan) {\n        rowspan = parseInt(rowspan, 10);\n      }\n      rows += (rowspan || 1);\n\n      // Now look for column-related info\n      var columnsInThisRow = 0;\n      var cells = trs[i].getElementsByTagName(\"td\");\n      for (var j = 0; j < cells.length; j++) {\n        var colspan = cells[j].getAttribute(\"colspan\") || 0;\n        if (colspan) {\n          colspan = parseInt(colspan, 10);\n        }\n        columnsInThisRow += (colspan || 1);\n      }\n      columns = Math.max(columns, columnsInThisRow);\n    }\n    return {rows: rows, columns: columns};\n  },\n\n  /**\n   * Look for 'data' (as opposed to 'layout') tables, for which we use\n   * similar checks as\n   * https://dxr.mozilla.org/mozilla-central/rev/71224049c0b52ab190564d3ea0eab089a159a4cf/accessible/html/HTMLTableAccessible.cpp#920\n   */\n  _markDataTables: function(root) {\n    var tables = root.getElementsByTagName(\"table\");\n    for (var i = 0; i < tables.length; i++) {\n      var table = tables[i];\n      var role = table.getAttribute(\"role\");\n      if (role == \"presentation\") {\n        table._readabilityDataTable = false;\n        continue;\n      }\n      var datatable = table.getAttribute(\"datatable\");\n      if (datatable == \"0\") {\n        table._readabilityDataTable = false;\n        continue;\n      }\n      var summary = table.getAttribute(\"summary\");\n      if (summary) {\n        table._readabilityDataTable = true;\n        continue;\n      }\n\n      var caption = table.getElementsByTagName(\"caption\")[0];\n      if (caption && caption.childNodes.length > 0) {\n        table._readabilityDataTable = true;\n        continue;\n      }\n\n      // If the table has a descendant with any of these tags, consider a data table:\n      var dataTableDescendants = [\"col\", \"colgroup\", \"tfoot\", \"thead\", \"th\"];\n      var descendantExists = function(tag) {\n        return !!table.getElementsByTagName(tag)[0];\n      };\n      if (dataTableDescendants.some(descendantExists)) {\n        this.log(\"Data table because found data-y descendant\");\n        table._readabilityDataTable = true;\n        continue;\n      }\n\n      // Nested tables indicate a layout table:\n      if (table.getElementsByTagName(\"table\")[0]) {\n        table._readabilityDataTable = false;\n        continue;\n      }\n\n      var sizeInfo = this._getRowAndColumnCount(table);\n      if (sizeInfo.rows >= 10 || sizeInfo.columns > 4) {\n        table._readabilityDataTable = true;\n        continue;\n      }\n      // Now just go by size entirely:\n      table._readabilityDataTable = sizeInfo.rows * sizeInfo.columns > 10;\n    }\n  },\n\n  /* convert images and figures that have properties like data-src into images that can be loaded without JS */\n  _fixLazyImages: function (root) {\n    this._forEachNode(this._getAllNodesWithTag(root, [\"img\", \"picture\", \"figure\"]), function (elem) {\n      // also check for \"null\" to work around https://github.com/jsdom/jsdom/issues/2580\n      if ((!elem.src && (!elem.srcset || elem.srcset == \"null\")) || elem.className.toLowerCase().indexOf(\"lazy\") !== -1) {\n        for (var i = 0; i < elem.attributes.length; i++) {\n          var attr = elem.attributes[i];\n          if (attr.name === \"src\" || attr.name === \"srcset\") {\n            continue;\n          }\n          var copyTo = null;\n          if (/\\.(jpg|jpeg|png|webp)\\s+\\d/.test(attr.value)) {\n            copyTo = \"srcset\";\n          } else if (/^\\s*\\S+\\.(jpg|jpeg|png|webp)\\S*\\s*$/.test(attr.value)) {\n            copyTo = \"src\";\n          }\n          if (copyTo) {\n            //if this is an img or picture, set the attribute directly\n            if (elem.tagName === \"IMG\" || elem.tagName === \"PICTURE\") {\n              elem.setAttribute(copyTo, attr.value);\n            } else if (elem.tagName === \"FIGURE\" && !this._getAllNodesWithTag(elem, [\"img\", \"picture\"]).length) {\n              //if the item is a <figure> that does not contain an image or picture, create one and place it inside the figure\n              //see the nytimes-3 testcase for an example\n              var img = this._doc.createElement(\"img\");\n              img.setAttribute(copyTo, attr.value);\n              elem.appendChild(img);\n            }\n          }\n        }\n      }\n    });\n  },\n\n  /**\n   * Clean an element of all tags of type \"tag\" if they look fishy.\n   * \"Fishy\" is an algorithm based on content length, classnames, link density, number of images & embeds, etc.\n   *\n   * @return void\n   **/\n  _cleanConditionally: function(e, tag) {\n    if (!this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY))\n      return;\n\n    var isList = tag === \"ul\" || tag === \"ol\";\n\n    // Gather counts for other typical elements embedded within.\n    // Traverse backwards so we can remove nodes at the same time\n    // without effecting the traversal.\n    //\n    // TODO: Consider taking into account original contentScore here.\n    this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(node) {\n      // First check if this node IS data table, in which case don't remove it.\n      var isDataTable = function(t) {\n        return t._readabilityDataTable;\n      };\n\n      if (tag === \"table\" && isDataTable(node)) {\n        return false;\n      }\n\n      // Next check if we're inside a data table, in which case don't remove it as well.\n      if (this._hasAncestorTag(node, \"table\", -1, isDataTable)) {\n        return false;\n      }\n\n      var weight = this._getClassWeight(node);\n      var contentScore = 0;\n\n      this.log(\"Cleaning Conditionally\", node);\n\n      if (weight + contentScore < 0) {\n        return true;\n      }\n\n      if (this._getCharCount(node, \",\") < 10) {\n        // If there are not very many commas, and the number of\n        // non-paragraph elements is more than paragraphs or other\n        // ominous signs, remove the element.\n        var p = node.getElementsByTagName(\"p\").length;\n        var img = node.getElementsByTagName(\"img\").length;\n        var li = node.getElementsByTagName(\"li\").length - 100;\n        var input = node.getElementsByTagName(\"input\").length;\n\n        var embedCount = 0;\n        var embeds = this._getAllNodesWithTag(node, [\"object\", \"embed\", \"iframe\"]);\n\n        for (var i = 0; i < embeds.length; i++) {\n          // If this embed has attribute that matches video regex, don't delete it.\n          for (var j = 0; j < embeds[i].attributes.length; j++) {\n            if (this.REGEXPS.videos.test(embeds[i].attributes[j].value)) {\n              return false;\n            }\n          }\n\n          // For embed with <object> tag, check inner HTML as well.\n          if (embeds[i].tagName === \"object\" && this.REGEXPS.videos.test(embeds[i].innerHTML)) {\n            return false;\n          }\n\n          embedCount++;\n        }\n\n        var linkDensity = this._getLinkDensity(node);\n        var contentLength = this._getInnerText(node).length;\n\n        var haveToRemove =\n          (img > 1 && p / img < 0.5 && !this._hasAncestorTag(node, \"figure\")) ||\n          (!isList && li > p) ||\n          (input > Math.floor(p/3)) ||\n          (!isList && contentLength < 25 && (img === 0 || img > 2) && !this._hasAncestorTag(node, \"figure\")) ||\n          (!isList && weight < 25 && linkDensity > 0.2) ||\n          (weight >= 25 && linkDensity > 0.5) ||\n          ((embedCount === 1 && contentLength < 75) || embedCount > 1);\n        return haveToRemove;\n      }\n      return false;\n    });\n  },\n\n  /**\n   * Clean out elements that match the specified conditions\n   *\n   * @param Element\n   * @param Function determines whether a node should be removed\n   * @return void\n   **/\n  _cleanMatchedNodes: function(e, filter) {\n    var endOfSearchMarkerNode = this._getNextNode(e, true);\n    var next = this._getNextNode(e);\n    while (next && next != endOfSearchMarkerNode) {\n      if (filter.call(this, next, next.className + \" \" + next.id)) {\n        next = this._removeAndGetNext(next);\n      } else {\n        next = this._getNextNode(next);\n      }\n    }\n  },\n\n  /**\n   * Clean out spurious headers from an Element. Checks things like classnames and link density.\n   *\n   * @param Element\n   * @return void\n  **/\n  _cleanHeaders: function(e) {\n    this._removeNodes(this._getAllNodesWithTag(e, [\"h1\", \"h2\"]), function (header) {\n      return this._getClassWeight(header) < 0;\n    });\n  },\n\n  _flagIsActive: function(flag) {\n    return (this._flags & flag) > 0;\n  },\n\n  _removeFlag: function(flag) {\n    this._flags = this._flags & ~flag;\n  },\n\n  _isProbablyVisible: function(node) {\n    // Have to null-check node.style and node.className.indexOf to deal with SVG and MathML nodes.\n    return (!node.style || node.style.display != \"none\")\n      && !node.hasAttribute(\"hidden\")\n      //check for \"fallback-image\" so that wikimedia math images are displayed\n      && (!node.hasAttribute(\"aria-hidden\") || node.getAttribute(\"aria-hidden\") != \"true\" || (node.className && node.className.indexOf && node.className.indexOf(\"fallback-image\") !== -1));\n  },\n\n  /**\n   * Runs readability.\n   *\n   * Workflow:\n   *  1. Prep the document by removing script tags, css, etc.\n   *  2. Build readability's DOM tree.\n   *  3. Grab the article content from the current dom tree.\n   *  4. Replace the current DOM tree with the new one.\n   *  5. Read peacefully.\n   *\n   * @return void\n   **/\n  parse: function () {\n    // Avoid parsing too large documents, as per configuration option\n    if (this._maxElemsToParse > 0) {\n      var numTags = this._doc.getElementsByTagName(\"*\").length;\n      if (numTags > this._maxElemsToParse) {\n        throw new Error(\"Aborting parsing document; \" + numTags + \" elements found\");\n      }\n    }\n\n    // Unwrap image from noscript\n    this._unwrapNoscriptImages(this._doc);\n\n    // Remove script tags from the document.\n    this._removeScripts(this._doc);\n\n    this._prepDocument();\n\n    var metadata = this._getArticleMetadata();\n    this._articleTitle = metadata.title;\n\n    var articleContent = this._grabArticle();\n    if (!articleContent)\n      return null;\n\n    this.log(\"Grabbed: \" + articleContent.innerHTML);\n\n    this._postProcessContent(articleContent);\n\n    // If we haven't found an excerpt in the article's metadata, use the article's\n    // first paragraph as the excerpt. This is used for displaying a preview of\n    // the article's content.\n    if (!metadata.excerpt) {\n      var paragraphs = articleContent.getElementsByTagName(\"p\");\n      if (paragraphs.length > 0) {\n        metadata.excerpt = paragraphs[0].textContent.trim();\n      }\n    }\n\n    var textContent = articleContent.textContent;\n    return {\n      title: this._articleTitle,\n      byline: metadata.byline || this._articleByline,\n      dir: this._articleDir,\n      content: articleContent.innerHTML,\n      textContent: textContent,\n      length: textContent.length,\n      excerpt: metadata.excerpt,\n      siteName: metadata.siteName || this._articleSiteName\n    };\n  }\n};\n\nif (typeof module === \"object\") {\n  module.exports = Readability;\n}"
  },
  {
    "path": "styles/_options.scss",
    "content": "body{\n  --background:#EBEEF0;\n  --light-background:#F7F9FA;\n  --graydiv:#d5d5d5;\n  --selection:#2162AF;\n  --rightpanel: white;\n  --article-title: #253237;\n\n  @media(prefers-color-scheme: dark){\n    --background:#323333;\n    --light-background:#4B4D4D;\n    --graydiv:#656565;\n    --selection: white;   \n    --rightpanel: #4B4D4D;\n    --article-title: rgba(255,255,255,.65);\n  }\n}\n\nbody{\n  font-size: 14px;\n  font-family: -apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  margin: 0px;\n  padding: 0px;\n  background-color: var(--background);\n}\n\n#pagetitle{\n  float: left;\n  color: #253237;\n  opacity: .5; \n  line-height: 33px; \n  margin-left: 12px;\n}\n\n#nav{\n  border: 1px solid var(--graydiv);\n  box-sizing: border-box;\n  width: 100%;\n  height: 36px;\n  position: absolute;\n  top: 0px;  \n  left: 0px;\n  background-color: var(--background);\n  #searchbar{\n    position: relative;  \n    width: 516px;\n    height: 40px;\n    margin: auto;\n    margin-top: 2px;\n  }\n  #global-options-button{\n    position:absolute;\n    top:1px;\n    right:4px;\n    padding:7px;\n  }\n}\n\n#global-options{\n  position: absolute;\n  z-index: 100;\n  right: -5px;\n  top: 33px;\n  display:none;\n  background-color: #fff;\n  padding: 10px;\n  width: 100px;\n}\n\n\n#global-options.on {\n  position: absolute;\n  display:block;\n  background-color: #fff; \n  padding: 10px;\n  color: #333;\n}\n\n#global-options button {\n  padding:5px;\n  color: #A8A9AB;\n  font-size:14px;\n  text-align:left;\n  &:hover{\n    cursor:pointer;\n    text-decoration:underline;\n  }  \n}\n\n\n\n#appcontainer{\n  position:fixed;\n  top:36px;\n  display:flex;\n  flex-direction:row;\n  width:100%;\n\n  #leftnav{\n    position:relative;\n    border-right: 1px solid var(--graydiv);\n    background-color: var(--background);\n    height:100vh;\n    flex-grow:1;\n    min-width:350px;\n    max-width:500px;\n    overflow-y:scroll;\n    overscroll-behavior: contain;\n  }\n\n  #rightpanel{\n    position: relative;\n    min-width: 800px;\n    flex-grow: 2;\n    background: var(--rightpanel);\n    height: 100vh;\n    overflow: scroll;\n  }\n\n}\n\n#articleSort{\n  position:relative;\n  display:flex;\n  z-index:105;\n  width:100%;\n  background-color: var(--background);\n  height:25px;\n  font-size:14px;\n  border-bottom:1px solid var(--graydiv);\n  color: #333;\n  font-weight:600;\n  padding:5px 0px 0px 12px;\n  text-overflow: ellipsis;     \n}\n\n\n#article-scrollContainer, #panel-scrollContainer{\n  padding-bottom:70px;\n}\n\n#leftnav::-webkit-scrollbar {\n      display: none;\n};\n#rightpanel::-webkit-scrollbar {\n      // display: none;\n};\n\n#panel-scrollContainer{\n  margin-top:40px ;\n  padding: 25px 75px 50px 3vw;\n}\n\n#titlebar{\n  position:absolute;\n  width:100%;\n  display:flex;\n  flex-flow: row nowrap;\n  align-items:center;\n  justify-content: space-between;\n  height:40px;\n  z-index: 10;\n  background-color: var(--light-background);\n  font-size:14px;\n  border-bottom:1px solid var(--graydiv);\n  #titlebar-innercontainer{\n    display:flex;\n    flex-flow: row nowrap;\n    white-space: nowrap !important;\n    overflow: hidden !important;\n    text-overflow: ellipsis;    \n  }\n  #titlebar-author{\n    margin-left:10px;\n    padding:5px 5px 5px 5px;\n    display:block;\n    float:left\n  }\n  #titlebar-title{\n    display:block;\n    float:left;\n    color: var(--selection);\n    font-weight:600;\n    padding:5px;\n    white-space: nowrap; \n    overflow: hidden; \n    text-overflow: ellipsis;    \n  }\n  #titlebar-options{\n    right:40px;\n    display:flex;\n    align-items:center;    \n    width:40px;\n    height:100%;\n    border-left: 1px solid var(--graydiv);\n    &:hover{\n      background-color: #fafafa;\n    };\n    &::after {\n      content: '\\2807';\n      font-size: 24px;\n      padding:12px 10px 10px 14px;\n      color: #B1B2B4;\n    }    \n  }\n}\n\n#titlebar-author, #titlebar-title{\n &:hover{\n  opacity:.65;\n  background-color: var(--background);\n }\n}\n\n#titlebar-author, #titlebar-title{\n  &:focus{\n   opacity:.65;\n   background-color: var(--background);\n   outline:none;\n  }\n }\n\n[contenteditable=true]:empty:before{\n  content: attr(placeholder);\n}\n\n.dropdown{\n  position:absolute;\n  color: #333;\n  border: 1px solid #9DB8BF;\n  box-shadow: 1px 3px 8px rgba(0,0,0,.15);  \n}\n\n\n#titlebar-dropdown{\n  position: absolute;\n  right: 0px;\n  top: 40px;\n  display:none;\n  background-color: #fff;\n  padding: 10px;\n  #titlebar-delete{\n    font-size:14px;\n    &:hover{\n      cursor:pointer;\n      color:red;\n    };\n  }\n}\n\n#titlebar-dropdown.on {\n  position: absolute;\n  display:block;\n  background-color: #fff; \n  padding: 10px;\n  color: #333;\n}\n\n#capture-helper{\n  position:absolute;\n  left:50%;\n  width:300px;\n  margin-top:-40px;\n  transform:translateX(-50%);\n  text-align:center;\n  z-index:100;\n  color: #A8A9AB;\n  font-size:14px;\n}\n\n.quoteblock{\n  margin-bottom: 25px;  \n  z-index:9999;\n}\n\n.quote-container{\n  display:flex;\n  flex-direction:row;\n  #quoteback-component{\n    max-width:700px;\n  }\n\n  .quote-controls{\n    flex-direction:column;\n    margin-left:5px;\n    position:relative;\n    width:130px;\n    opacity:0;  \n    @include transition(all .20s ease);\n    .control-button{\n      margin-bottom:6px;\n      word-wrap: no-wrap;\n    }\n    #delete{\n      color:red;\n      &:hover{\n        color:black;\n      }      \n    }\n    #embedLink{\n      color: #395FE5;\n      &:hover{\n        color:black;\n      }\n    }\n  }\n}\n\n\n.options-control-button{\n  border:none;\n  padding:10px;\n  text-align: left;\n  font-size:14px;\n  font-weight:500;\n  font-family:inherit;\n  display:inline-block;\n  border-radius:2px;\n  @include transition(background-color .20s ease);\n  &:hover{\n    cursor: pointer;\n    color: black;\n    background-color:rgba(194,223,227,.25);\n  }\n  #options-svg{\n\n  }\n}\n\n.showcontrols{\n  transform: translateX(10px);\n  opacity:1 !important;\n}\n\n.comment{\n  max-width:600px;\n  line-height:20px;\n  padding:11px;\n  color:#b6b6b6;\n  background: #ECEEEF;\n  box-sizing: border-box;\n  border-radius: 10px;\n  margin-top:-15px;\n  @include transition(all .10s ease);\n}\n\n.comment:focus{\n  outline:none;\n  box-shadow: inset 0px 0px 0px 1px #9DB8BF;\n}\n\n.meta{\n  height:25px;\n  width:100%;\n}\n\n.date{\n  color:#B8B8B8;\n  float:left;\n}\n\n.linkback{\n  a{\n    color:#B8B8B8;\n    float:left;\n    text-decoration:underline;\n    margin-left:15px;\n    &:visited{\n      color:#B8B8B8;\n    }\n  }\n}\n\n\n.article{\n  @include transition(all .1s ease);\n  border-bottom: .5px solid var(--graydiv);\n  padding: 15px 11px 10px 15px;\n  background-color: var(--background);\n  cursor: pointer;\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: start;\n  align-items: stretch;\n  &:hover{\n    background-color: var(--rightpanel);\n  }\n  .title{\n    color: var(--article-title);\n    font-weight:600;\n    margin-bottom:8px;\n    white-space: nowrap; \n    overflow: hidden; \n    text-overflow: ellipsis;\n    padding-right:5px;    \n  } \n  .url{\n    font-weight: 300;\n    margin-left: auto;\n    white-space: nowrap;\n    color: var(--article-title);\n    opacity: .5;\n\n    img{\n      padding-right:5px;\n      vertical-align:bottom;\n    }\n\n  }  \n}\n\n.selected{\n  border-left: 4px solid var(--selection);\n  background-color: var(--rightpanel);\n  .title{\n    color: var(--selection);\n  }\n  .url{\n    color: var(--selection);\n    opacity: 1;\n  }  \n}\n\n.mini-favicon{\n  margin-right: 6px;\n  width:16px;\n  height:16px;\n  margin: 1px 12px 0px 0px;\n}\n\n\n\n\n\n#fastSearch { \n  position: absolute;\n  left:0px;\n  display: inline-block;\n  width: 100%;\n  z-index:5;\n  &:focus-within{\n    #searchInput{\n      box-shadow:0 1px 1px 0 rgba(65,69,73,0.3), 0 1px 3px 1px rgba(65,69,73,0.15);\n      background: var(--light-background);\n      border:none;\n      border-radius: 4px 4px 0px 0px;  \n    }\n  }\n}      \n#fastSearch input { \n  @include transition(all .20s ease);\n  padding-left: 10px;\n  width: 100%;\n  height: 26px;\n  font-size: 14px;\n  background: var(--light-background);\n  outline: none;\n  text-align: left;\n  display: inline-block;\n  background: var(--light-background);\n  border: 0.5px solid var(--graydiv);\n  border-radius: 4px;\n  &::placeholder{\n    color: #767778;\n    opacity: .5;\n  };\n}\n\n#searchResults{\n  display:none;\n  position:absolute;\n  margin:0px;\n  padding:0px;\n  width:528px;\n  background:white;\n  border-radius:0px 0px 4px 4px;\n  box-shadow:0 1px 1px 0 rgba(65,69,73,0.3), 0 1px 3px 1px rgba(65,69,73,0.15);\n}\n\n#searchResults li { \n  list-style: none; \n  width:100%;\n  margin-left: 0em;\n  background:white; \n  border-bottom: 1px solid var(--graydiv);\n  position:relative;\n}\n#searchResults li .title { font-size: 1.1em; margin-bottom: 10px; display: inline-block;}\n\n#searchResults .search-url { font-weight: 300;\n  margin: 2px 0px 2px auto;\n  white-space: nowrap;\n  color: #253237;\n  opacity: .5;\n}\n\n.search-content{\n  color: #464A4D;\n}\n\n#searchResults a { \n  color:black;\n  text-decoration: none !important; \n  padding: 10px; \n  display: inline-block;\n  img{  \n    margin-right:5px;\n  }\n}\n#searchResults a:hover, a:focus { outline: 0; background-color: #ECEEEF; }\n#searchResults li:focus-within, #searchResults li:hover {outline: 0; background-color: #ECEEEF;  }\n\n"
  },
  {
    "path": "styles/article-style.scss",
    "content": ".article-container{\n\tmax-width:700px;\n\n\tfigure{\n\t\tmargin:0px;\n\t}\n\timg{\n\t\twidth:100%;\n\t\theight:auto;\n\t}\n}\n\t"
  },
  {
    "path": "styles/options.css",
    "content": "body{font-size:14px;font-family:-apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";margin:0px;padding:0px}#clearStorage{margin:10px;position:fixed;right:10px}#nav{border:1px solid #BDBCBC;box-sizing:border-box;width:100%;height:50px;position:absolute;top:0px;left:0px;background-color:white}#nav #searchbar{position:relative;width:516px;height:40px;margin:auto;margin-top:5px;background:#ECEEEF;border-radius:4px}#appcontainer{position:fixed;top:50px;display:flex;flex-direction:row;width:100%}#appcontainer #leftnav{border-right:1px solid #BDBCBC;height:100vh;width:450px;overflow-y:scroll}#appcontainer #rightpanel{padding:25px 75px 50px 50px;background:white;width:100%;height:100vh;overflow:scroll}.quoteblock{margin-bottom:25px}.quote-container{display:flex;flex-direction:row}.quote-container .quote{background:#ECEEEF;border-radius:8px;padding:12px;font-size:16px;color:#464A4D;line-height:150%;font-weight:400;width:600px;min-height:128px}.quote-container .quote-controls{margin-left:10px;position:relative}.quote-container .quote-controls #delete{color:red;position:absolute;bottom:0px;left:0px}.quote-container .quote-controls #getlink{color:#395FE5;margin-bottom:6px}.control-button{background:linear-gradient(180deg, #fff 0%, #FCFCFC 14.58%, #FCFCFC 82.29%, #F6F6F6 100%);border:0.5px solid #D5D5D5;box-sizing:border-box;border-radius:4px;width:130px;height:36px;font-size:14px;font-weight:500;font-family:inherit;display:block}.control-button:hover{cursor:pointer;background:linear-gradient(180deg, #FCFCFC 0%, #F2F7FA 14.58%, #F2F7FA 82.29%, #EBF0F2 100%);border:0.5px solid #C2DFE3}.comment{max-width:600px;line-height:20px;padding:11px;color:#b6b6b6;background:#FFFFFF;border:1px solid #C2DFE3;box-sizing:border-box;border-radius:10px;margin-top:10px}.comment:focus{outline:none;border:1px solid #9DB8BF}.meta{height:25px;width:100%}.date{color:#B8B8B8;float:left}.linkback{color:#B8B8B8;float:left;text-decoration:underline;margin-left:15px}.article{border-bottom:1px solid #979797;padding:20px 20px 20px 25px;cursor:pointer}.article:hover{background-color:#F1F3F4}.article .title{font-weight:600;margin-bottom:8px}.article .author{font-weight:600;color:#808080;margin-bottom:8px}.article .url{font-weight:300}.article .url img{padding-right:5px;vertical-align:bottom}.selected{border-left:4px solid black;background-color:#ECEEEF}\n/*# sourceMappingURL=options.css.map */\n"
  },
  {
    "path": "styles/popup.css",
    "content": "input,button{border:none;background-image:none;background-color:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;color:#9DB8BF;text-decoration:none}#citation-capture{font-family:-apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";overflow:hidden !important;width:600px;height:auto;position:fixed !important;top:-5px !important;right:-5px !important;overflow-x:hidden;overflow-y:auto;max-height:calc(100% - 50px);z-index:2147483;padding:20px}.blockquote-wrapper{box-shadow:0px 6px 20px 0px rgba(0,0,0,0.15);border-radius:8px}.citation-tools{margin-top:-15px;background-color:white;border:1px solid #C2DFE3;border-radius:8px;box-shadow:0px 6px 20px 0px rgba(0,0,0,0.15)}.comment-field{padding:12px;border-bottom:1px solid #C2DFE3}.citation-input{width:500px;box-shadow:none;-webkit-appearance:none;color:#464A4D;box-sizing:border-box;border-radius:4px;font-size:14px;word-wrap:break-word;word-break:break-all;-webkit-transition:all 0.1s ease;-moz-transition:all 0.1s ease;-ms-transition:all 0.1s ease;-o-transition:all 0.1s ease;transition:all 0.1s ease}.citation-input::placeholder{font-size:14px;line-height:150%;color:#000000;opacity:0.25}.citation-input:focus{outline:none}.tools-buttons{display:flex;flex-direction:row;justify-content:space-between;align-items:center;height:44px}.control-button{border:none;height:44px;width:100%;text-align:center;font-size:14px;font-weight:500;font-family:inherit;display:inline-block;-webkit-transition:background-color 0.2s ease;-moz-transition:background-color 0.2s ease;-ms-transition:background-color 0.2s ease;-o-transition:background-color 0.2s ease;transition:background-color 0.2s ease}.control-button:hover{cursor:pointer;opacity:1;background-color:rgba(194,223,227,0.25)}.control-button:focus{outline:none}#getlink{padding:0px;color:#395FE5;border-right:1px solid #C2DFE3}#getMarkdown{padding:0px;text-align:center;border-right:1px solid #C2DFE3}#close-button{width:50%}.save-indicator{font-size:14px;float:right;display:inline-block;text-align:center;box-sizing:border-box;color:rgba(23,154,12,0.5);align-self:start}#quoteslink{height:44px;line-height:45px;display:flex;align-items:center;justify-content:center;color:#9DB8BF;text-decoration:none;text-align:center;border-right:1px solid #C2DFE3}#quoteslink img{width:24px;height:auto;margin-left:11px}\n/*# sourceMappingURL=popup.css.map */\n"
  },
  {
    "path": "styles/popup.scss",
    "content": "@charset \"UTF-8\";\n\n@mixin transition($args...) {\n  -webkit-transition: $args;\n  -moz-transition: $args;\n  -ms-transition: $args;\n  -o-transition: $args;\n  transition: $args;\n}\n\ninput,button{\n  border:none;\n  background-image:none;\n  background-color:transparent;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;color:#9DB8BF;\n  text-decoration:none;\n}\n\n#citation-capture{\n    font-family: -apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    overflow: hidden !important;\n    width: 600px;\n    height: auto;\n    position: fixed !important;\n    top: -5px !important;\n    right: -5px !important;\n    overflow-x: hidden;\n    overflow-y: auto;\n    max-height: calc(100% - 50px);\n    z-index:2147483;\n    padding:20px;\n}\n\n.blockquote-wrapper{\n  box-shadow: 0px 6px 20px 0px rgba(0,0,0,.15);\n  border-radius:8px;\n}\n\n.citation-tools{\n  margin-top:-15px;\n  background-color:white;\n  border: 1px solid #C2DFE3;\n  border-radius: 8px;\n  box-shadow: 0px 6px 20px 0px rgba(0,0,0,.15);   \n}\n\n\n.comment-field{\n  padding: 12px;\n  border-bottom: 1px solid #C2DFE3;\n}\n\n.citation-input{\n  width: 500px;\n  box-shadow:none;\n  -webkit-appearance: none;\n  color:#464A4D;\n  box-sizing: border-box;\n  border-radius: 4px;\n  font-size:14px;\n  word-wrap: break-word;\n  word-break: break-all;   \n  @include transition(all .10s ease);\n  &::placeholder{\n    font-size: 14px;\n    line-height: 150%;\n    color: #000000;\n    opacity: 0.25;\n  };\n}\n.citation-input:focus{\n  outline:none;\n}\n\n.tools-buttons{\n  display:flex;\n  flex-direction:row;\n  justify-content: space-between;\n  align-items: center;\n  height:44px;\n}\n\n.control-button{\n  border:none;\n  height:44px;\n  width:100%;\n  text-align: center;\n  font-size:14px;\n  font-weight:500;\n  font-family:inherit;\n  display:inline-block;\n  @include transition(background-color .20s ease);\n  &:hover{\n    cursor: pointer;\n    opacity: 1;\n    background-color:rgba(194,223,227,.25);\n  }\n  &:focus{\n    outline:none;\n  }\n}\n\n#getlink{\n  padding:0px;\n  color: #395FE5;\n  border-right: 1px solid #C2DFE3;\n}  \n\n#getMarkdown{\n  padding:0px;\n  text-align:center;\n  border-right: 1px solid #C2DFE3;\n}  \n\n#close-button{\n  width:50%;\n}\n\n\n.save-indicator{\n  font-size:14px;\n  float:right;\n  display:inline-block;\n  text-align:center;\n  box-sizing: border-box;\n  color: rgba(23,154,12,.5);\n  align-self:start;\n}\n\n\n#quoteslink{\n  height:44px;\n  line-height:45px;\n  display:flex;\n  align-items:center;\n  justify-content:center;\n  color:#9DB8BF;\n  text-decoration:none;\n  text-align: center;\n  border-right: 1px solid #C2DFE3;\n  img{\n    width:24px;\n    height:auto;\n    margin-left:11px;\n  }\n}"
  },
  {
    "path": "styles/quote.css",
    "content": ".portal-container-519256 {\n  font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  text-rendering: optimizeLegibility;\n  border: 1px solid #C2DFE3;\n  border-radius: 8px;\n  margin-bottom: 25px;\n  max-width: 800px;\n  background-color: white;\n  -webkit-transition: all 0.2s ease;\n  transition: all 0.2s ease;\n}\n\n.portal-container-519256:hover {\n  -webkit-transform: translateY(-3px);\n          transform: translateY(-3px);\n  -webkit-box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n          box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n  border: 1px solid #9DB8BF;\n}\n\n.portal-container-519256 .portal-parent-519256 {\n  overflow: hidden;\n  position: relative;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\n.portal-container-519256 .portal-parent-519256 .portal-parent-text-519256 {\n  padding: 15px;\n  color: #5C6D73;\n  z-index: 40;\n}\n\n.portal-container-519256 .portal-parent-519256 .portal-content-519256 {\n  font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  font-size: 16px;\n  font-weight: 400;\n  padding: 15px;\n  color: #464A4D;\n  line-height: 150%;\n}\n\n.portal-container-519256 .portal-head-519256 {\n  border-top: 1px solid #C2DFE3;\n  display: -webkit-box;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-orient: horizontal;\n  -webkit-box-direction: normal;\n      -ms-flex-flow: row nowrap;\n          flex-flow: row nowrap;\n  -webkit-box-pack: start;\n      -ms-flex-pack: start;\n          justify-content: start;\n  -webkit-box-align: stretch;\n      -ms-flex-align: stretch;\n          align-items: stretch;\n  padding-left: 15px;\n  -webkit-transition: all 0.2s ease;\n  transition: all 0.2s ease;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-avatar-519256 {\n  border-radius: 100%;\n  border: 1px solid #C2DFE3;\n  width: 42px;\n  height: 42px;\n  min-width: 42px !important;\n  margin: 12px 0px;\n  position: relative;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-avatar-519256 .mini-favicon-519256 {\n  width: 22px;\n  height: 22px;\n  position: absolute;\n  margin: auto;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-metadata-519256 {\n  min-width: 0px;\n  display: -webkit-box;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-negative: 1;\n      flex-shrink: 1;\n  -webkit-box-align: center;\n      -ms-flex-align: center;\n          align-items: center;\n  margin-left: 10px;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-author-519256 {\n  font-size: 14px;\n  line-height: 1.2;\n  color: black;\n  font-weight: 600;\n  margin-bottom: 2px;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-title-519256 {\n  font-size: 14px;\n  line-height: 1.2;\n  color: #9DB8BF;\n  max-width: 100%;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-title-519256 .title-wrapper-519256 {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  font-weight: 600;\n  padding-right: 20px;\n  color: #5C6D73;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-backlink-519256 {\n  margin-left: auto;\n  display: -webkit-box;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-negative: 1;\n      flex-shrink: 1;\n  -webkit-box-align: center;\n      -ms-flex-align: center;\n          align-items: center;\n  width: 81px;\n  min-width: 81px !important;\n  padding: 0px 15px !important;\n  border-left: 1px solid #C2DFE3;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256 {\n  border: none !important;\n  font-family: inherit !important;\n  font-size: 14px !important;\n  color: #9DB8BF !important;\n  text-decoration: none !important;\n  -webkit-transition: opacity 0.1s ease;\n  transition: opacity 0.1s ease;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256:hover {\n  opacity: .5 !important;\n}\n\n.portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256:visited {\n  text-decoration: none !important;\n}\n\n.portal-content-519256 a {\n  color: #464A4D;\n  -webkit-transition: opacity 0.2s ease;\n  transition: opacity 0.2s ease;\n}\n\n.portal-content-519256 a:hover {\n  opacity: .5;\n}\n\n.portal-content-519256 p {\n  margin: 0px;\n}\n\n.portal-content-519256 img {\n  width: 100%;\n  height: auto;\n  margin: .5em 0em;\n}\n\n.portal-content-519256 blockquote {\n  border-left: 2px solid #C2DFE3;\n  padding-left: .75em;\n  -webkit-margin-start: 1em;\n          margin-inline-start: 1em;\n  color: #5C6D73;\n}\n\n.portal-content-519256 ol, .portal-content-519256 ul {\n  -webkit-margin-before: .5em;\n          margin-block-start: .5em;\n  -webkit-margin-after: .5em;\n          margin-block-end: .5em;\n}\n\n.portal-content-519256 h1, .portal-content-519256 h2, .portal-content-519256 h3 {\n  -webkit-margin-before: .5em;\n          margin-block-start: .5em;\n  -webkit-margin-after: .5em;\n          margin-block-end: .5em;\n}\n/*# sourceMappingURL=quote.css.map */"
  },
  {
    "path": "styles/quote.scss",
    "content": "// @charset \"UTF-8\";\n@mixin transition($args...) {\n  -webkit-transition: $args;\n  -moz-transition: $args;\n  -ms-transition: $args;\n  -o-transition: $args;\n  transition: $args;\n}\n\n$bluegray-bg-med: #C2DFE3;\n\n$bluegray-text-light: #9DB8BF;\n\n$bluegray-text-med: #5C6D73;\n\n$bluegray-text-dark: #253237;\n\n\n.portal-container-519256{\n  font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  text-rendering: optimizeLegibility;\n  border: 1px solid #C2DFE3;\n  border-radius: 8px;\n  margin-bottom: 25px;\n  max-width:800px;\n  background-color:white;\n\n  @include transition(all .20s ease);\n  &:hover{\n    transform: translateY(-3px);\n    box-shadow: 0px 6px 20px 0px rgba(0,0,0,.15);\n    border: 1px solid $bluegray-text-light;\n  }\n  \n  .portal-parent-519256{\n    overflow:hidden;\n    position: relative;\n    width:100%;\n    box-sizing: border-box;\n      \n    .portal-parent-text-519256{\n      padding: 15px;\n      color: $bluegray-text-med;          \n      z-index: 40;\n    }\n    .portal-content-519256{\n      font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n      font-size:16px;\n      font-weight:400;\n      padding: 15px; \n      color: #464A4D;\n      line-height:150%; \n    }\n  }\n\n  .portal-head-519256{\n    border-top: 1px solid $bluegray-bg-med;\n    display:flex;\n    flex-flow:row nowrap;\n    justify-content: start;\n    align-items: stretch;\n    padding-left:15px;\n    @include transition(all .20s ease); \n\n    .portal-avatar-519256{\n      border-radius:100%;\n      border: 1px solid #C2DFE3;\n      width:42px;\n      height:42px;\n      min-width:42px !important;\n      margin: 12px 0px;\n      position:relative;\n      .mini-favicon-519256{\n        width:22px;\n        height:22px;\n        position: absolute;\n        margin: auto;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n      }\n    }\n\n    .portal-metadata-519256{\n      min-width:0px;\n      display:flex;\n      flex-shrink:1;\n      align-items:center;         \n      margin-left:10px;\n    }\n\n    .portal-author-519256{\n      font-size:14px;\n      line-height:1.2;\n      color: black;\n      font-weight:600;\n      margin-bottom:2px;\n    }       \n    .portal-title-519256{\n      font-size: 14px;\n      line-height:1.2;\n      color: $bluegray-text-light;\n      max-width: 100%;\n\n      .title-wrapper-519256{\n        white-space: nowrap; \n        overflow: hidden; \n        text-overflow: ellipsis;\n        font-weight:600;\n        padding-right:20px;\n        color: $bluegray-text-med;                  \n      }                   \n    }\n    .portal-backlink-519256{\n      margin-left: auto;\n      display:flex;\n      flex-shrink:1;\n      align-items:center;\n      width:81px;\n      min-width:81px !important;\n      padding: 0px 15px !important;\n      border-left: 1px solid $bluegray-bg-med;\n      .portal-arrow-519256{\n        border: none !important;\n        font-family:inherit !important;\n        font-size: 14px !important;\n        color: $bluegray-text-light !important;\n        text-decoration:none !important;\n        @include transition(opacity .10s ease);\n        &:hover{\n          opacity:.5 !important;\n        }\n        &:visited{\n          text-decoration: none !important;\n        };\n      }\n    }\n  }   \n}\n\n\n.portal-content-519256{\n  a{\n    color:#464A4D;\n    @include transition(opacity .2s ease);\n    &:hover{\n      opacity:.5;\n    }\n  }\n  p{\n    margin:0px;\n  }\n  img {\n    width:100%;\n    height: auto;\n    margin: .5em 0em;\n  }\n  blockquote{\n    border-left: 2px solid $bluegray-bg-med;\n    padding-left: .75em;\n    margin-inline-start: 1em;\n    color: $bluegray-text-med;\n  }\n  ol, ul{\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n  }\n  h1, h2, h3{\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n  }\n}\n"
  },
  {
    "path": "styles/quoteback-highlighter.css",
    "content": ".quotebackhighlight {\n  background-color: #CFE2F3;\n}\n/*# sourceMappingURL=quoteback-highlighter.css.map */"
  },
  {
    "path": "styles/quoteback-highlighter.scss",
    "content": ".quotebackhighlight{\n    background-color: #CFE2F3;\n}"
  },
  {
    "path": "styles/quoteback.css",
    "content": "@import url(\"https://rsms.me/inter/inter.css\");\n    .quoteback-container {\n    --background-color: white;\n    --border-color-normal: #C2DFE3;\n    --border-color-hover: #9DB8BF;\n    --author-color: black;\n    --title-color: #5C6D73;\n    --gototext-color: #9DB8BF;\n    --content-color: #464A4D;\n    --internal-blockquote-color: #5C6D73;\n}\n@media (prefers-color-scheme: dark) {\n    .quoteback-container {\n    --background-color: #161717;\n    --border-color-normal: #253237;\n    --border-color-hover: #5C6D73;\n    --author-color: #E0FBFC;\n    --title-color: #9DB8BF;\n    --gototext-color: #5C6D73;\n    --content-color: #9DB8BF;\n    --internal-blockquote-color: #5C6D73;\n}\n}\n.quoteback-container {\n    font-family: \"SF Pro Text\", -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    text-rendering: optimizeLegibility;\n    border: 1px solid var(--border-color-normal);\n    border-radius: 8px;\n    margin-bottom: 25px;\n    max-width: 800px;\n    background-color: var(--background-color);\n    text-align: left;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease;\n}\n.quoteback-container:hover {\n    transform: translateY(-3px);\n    box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n    border: 1px solid var(--border-color-hover);\n}\n.quoteback-container .quoteback-parent {\n    overflow: hidden;\n    position: relative;\n    width: 100%;\n    box-sizing: border-box;\n}\n.quoteback-container .quoteback-parent .quoteback-content {\n    font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n    font-size: 16px;\n    font-weight: 400;\n    padding: 15px;\n    color: var(--content-color);\n    line-height: 150%}\n.quoteback-container .quoteback-parent .quoteback-content em {\n    font-family: inherit;\n}\n.quoteback-container .quoteback-head {\n    border-top: 1px solid var(--border-color-normal);\n    display: flex;\n    flex-flow: row nowrap;\n    justify-content: start;\n    align-items: stretch;\n    padding-left: 15px;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease;\n}\n.quoteback-container .quoteback-head .quoteback-avatar {\n    border-radius: 100%;\n    border: 1px solid var(--border-color-normal);\n    width: 42px;\n    height: 42px;\n    min-width: 42px !important;\n    margin: 12px 0px;\n    position: relative;\n}\n.quoteback-container .quoteback-head .quoteback-avatar .mini-favicon {\n    width: 22px;\n    height: 22px;\n    position: absolute;\n    margin: auto;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n}\n.quoteback-container .quoteback-head .quoteback-metadata {\n    min-width: 0px;\n    display: flex;\n    flex-shrink: 1;\n    align-items: center;\n    margin-left: 10px;\n}\n.quoteback-container .quoteback-head .metadata-inner {\n    font-size: 14px;\n    line-height: 1.2;\n    width: 100%;\n    max-width: 525px;\n}\n@media (max-width: 414px) {\n    .quoteback-container .quoteback-head .metadata-inner {\n    max-width: 200px;\n}\n}\n.quoteback-container .quoteback-head .metadata-inner .quoteback-title {\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    font-weight: 600;\n    padding-right: 20px;\n    color: var(--title-color);\n}\n.quoteback-container .quoteback-head .metadata-inner .quoteback-author {\n    font-size: 14px;\n    line-height: 1.2;\n    color: var(--author-color);\n    font-weight: 600;\n    margin-bottom: 2px;\n}\n.quoteback-container .quoteback-head .quoteback-backlink {\n    margin-left: auto;\n    display: flex;\n    flex-shrink: 1;\n    align-items: center;\n    width: 81px;\n    min-width: 81px !important;\n    padding: 0px 15px !important;\n    border-left: 1px solid var(--border-color-normal);\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow {\n    border: none !important;\n    font-family: inherit !important;\n    font-size: 14px !important;\n    color: var(--gototext-color) !important;\n    text-decoration: none !important;\n    -webkit-transition: opacity 0.15s ease;\n    -moz-transition: opacity 0.15s ease;\n    -ms-transition: opacity 0.15s ease;\n    -o-transition: opacity 0.15s ease;\n    transition: opacity 0.15s ease;\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:hover {\n    opacity: .5 !important;\n}\n.quoteback-container .quoteback-head .quoteback-backlink .quoteback-arrow:visited {\n    text-decoration: none !important;\n}\n.editable:focus {\n    outline: none;\n}\n.editable:before {\n    margin-right: 8px;\n    content: 'url($ {\n    chrome.runtime.getURL(\"images/editicon.svg\");\n}\n)'}\n.quoteback-content a {\n    color: var(--content-color);\n    -webkit-transition: opacity 0.2s ease;\n    -moz-transition: opacity 0.2s ease;\n    -ms-transition: opacity 0.2s ease;\n    -o-transition: opacity 0.2s ease;\n    transition: opacity 0.2s ease;\n}\n.quoteback-content a:hover {\n    opacity: .5;\n}\n.quoteback-content p {\n    margin-block-start: 0px;\n    margin-block-end: .5em;\n}\n.quoteback-content p:last-of-type {\n    margin-block-end: 0px;\n}\n.quoteback-content img {\n    width: 100%;\n    height: auto;\n    margin: .5em 0em;\n}\n.quoteback-content blockquote {\n    border-left: 2px solid var(--border-color-normal);\n    padding-left: .75em;\n    margin-inline-start: 1em;\n    color: var(--internal-blockquote-color);\n}\n.quoteback-content ol, .quoteback-content ul {\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n}\n.quoteback-content h1, .quoteback-content h2, .quoteback-content h3 {\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n}\n/*# sourceMappingURL=quoteback.css.map */\n"
  },
  {
    "path": "styles/quoteback.scss",
    "content": "@charset \"UTF-8\";\n\n@mixin transition($args...) {\n  -webkit-transition: $args;\n  -moz-transition: $args;\n  -ms-transition: $args;\n  -o-transition: $args;\n  transition: $args;\n}\n\n@import url('https://rsms.me/inter/inter.css');\n\n$editIcon: 'url(${chrome.runtime.getURL(\"images/editicon.svg\")})';\n\n// Edit to change color scheme\n\n.quoteback-container{\n  --background-color: white;\n  --border-color-normal: #C2DFE3;\n  --border-color-hover: #9DB8BF;\n\n  --author-color: black;\n  --title-color: #5C6D73;\n  --gototext-color:#9DB8BF;\n\n  --content-color:#464A4D;\n  --internal-blockquote-color:#5C6D73;\n  \n  @media (prefers-color-scheme: dark) {\n    --background-color: #161717;\n    --border-color-normal: #253237;\n    --border-color-hover: #5C6D73;\n\n    --author-color: #E0FBFC;\n    --title-color: #9DB8BF;\n    --gototext-color:#5C6D73;\n\n    --content-color:#9DB8BF;\n    --internal-blockquote-color:#5C6D73;\n  }  \n}\n\n.quoteback-container{\n  font-family: \"SF Pro Text\", -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  text-rendering: optimizeLegibility;\n  border: 1px solid var(--border-color-normal);\n  border-radius: 8px;\n  margin-bottom: 25px;\n  max-width:800px;\n  background-color:var(--background-color);\n  text-align:left;\n\n  @include transition(all .20s ease);\n  &:hover{\n    transform: translateY(-3px);\n    box-shadow: 0px 6px 20px 0px rgba(0,0,0,.15);\n    border: 1px solid var(--border-color-hover);\n  }\n  \n  .quoteback-parent{\n    overflow:hidden;\n    position: relative;\n    width:100%;\n    box-sizing: border-box;\n    .quoteback-content{\n      font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n      font-size:16px;\n      font-weight:400;\n      padding: 15px; \n      color: var(--content-color);\n      line-height:150%;\n      em{\n        font-family:inherit;\n      }\n    }\n  }\n\n  .quoteback-head{\n    border-top: 1px solid var(--border-color-normal);\n    display:flex;\n    flex-flow:row nowrap;\n    justify-content: start;\n    align-items: stretch;\n    padding-left:15px;\n    @include transition(all .20s ease); \n\n    .quoteback-avatar{\n      border-radius:100%;\n      border: 1px solid var(--border-color-normal);\n      width:42px;\n      height:42px;\n      min-width:42px !important;\n      margin: 12px 0px;\n      position:relative;\n      .mini-favicon{\n        width:22px;\n        height:22px;\n        position: absolute;\n        margin: auto;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n      }\n    }\n\n    .quoteback-metadata{\n      min-width:0px;\n      display:flex;\n      flex-shrink:1;\n      align-items:center;         \n      margin-left:10px;\n    }       \n    .metadata-inner{\n      font-size: 14px;\n      line-height:1.2;\n      width: 100%;\n      max-width:525px;\n      @media(max-width:414px){\n        max-width: 200px;\n      }\n\n      .quoteback-title{\n        white-space: nowrap; \n        overflow: hidden; \n        text-overflow: ellipsis;\n        font-weight:600;\n        padding-right:20px;\n        color: var(--title-color);                  \n      }\n      .quoteback-author{\n        font-size:14px;\n        line-height:1.2;\n        color: var(--author-color);\n        font-weight:600;\n        margin-bottom:2px;\n      }                         \n    }\n    .quoteback-backlink{\n      margin-left: auto;\n      display:flex;\n      flex-shrink:1;\n      align-items:center;\n      width:81px;\n      min-width:81px !important;\n      padding: 0px 15px !important;\n      border-left: 1px solid var(--border-color-normal);\n      .quoteback-arrow{\n        border: none !important;\n        font-family:inherit !important;\n        font-size: 14px !important;\n        color: var(--gototext-color) !important;\n        text-decoration:none !important;\n        @include transition(opacity .15s ease);\n        &:hover{\n          opacity:.5 !important;\n        }\n        &:visited{\n          text-decoration: none !important;\n        };\n      }\n    }\n  }   \n}\n\n.editable{\n  &:focus{\n    outline:none;\n  }\n  &:before{\n    margin-right:8px;\n    content: $editIcon; \n  }\n}\n\n.quoteback-content{\n  a{\n    color: var(--content-color);\n    @include transition(opacity .2s ease);\n    &:hover{\n      opacity:.5;\n    }\n  }\n  p{\n    margin-block-start:0px;\n    margin-block-end:.5em;\n    &:last-of-type{\n      margin-block-end:0px;\n    }\n  }\n  img {\n    width:100%;\n    height: auto;\n    margin: .5em 0em;\n  }\n  blockquote{\n    border-left: 2px solid var(--border-color-normal);\n    padding-left: .75em;\n    margin-inline-start: 1em;\n    color: var(--internal-blockquote-color);\n  }\n  ol, ul{\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n  }\n  h1, h2, h3{\n    margin-block-start: .5em;\n    margin-block-end: .5em;\n  }\n}\n"
  },
  {
    "path": "styles/styles.css",
    "content": ".portal-container-519256 {\n  font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  text-rendering: optimizeLegibility;\n  border: 1px solid #C2DFE3;\n  border-radius: 8px;\n  margin-bottom: 25px;\n  max-width: 800px;\n  background-color: white;\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n  transition: all 0.2s ease; }\n  .portal-container-519256:hover {\n    transform: translateY(-3px);\n    box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n    border: 1px solid #9DB8BF; }\n  .portal-container-519256 .portal-parent-519256 {\n    overflow: hidden;\n    position: relative;\n    width: 100%;\n    box-sizing: border-box; }\n    .portal-container-519256 .portal-parent-519256 .portal-parent-text-519256 {\n      padding: 15px;\n      color: #5C6D73;\n      z-index: 40; }\n    .portal-container-519256 .portal-parent-519256 .portal-content-519256 {\n      font-family: -apple-system, system-ui, \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n      font-size: 16px;\n      font-weight: 400;\n      padding: 15px;\n      color: #464A4D;\n      line-height: 150%; }\n  .portal-container-519256 .portal-head-519256 {\n    border-top: 1px solid #C2DFE3;\n    display: flex;\n    flex-flow: row nowrap;\n    justify-content: start;\n    align-items: stretch;\n    padding-left: 15px;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease; }\n    .portal-container-519256 .portal-head-519256 .portal-avatar-519256 {\n      border-radius: 100%;\n      border: 1px solid #C2DFE3;\n      width: 42px;\n      height: 42px;\n      min-width: 42px !important;\n      margin: 12px 0px;\n      position: relative; }\n      .portal-container-519256 .portal-head-519256 .portal-avatar-519256 .mini-favicon-519256 {\n        width: 22px;\n        height: 22px;\n        position: absolute;\n        margin: auto;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0; }\n    .portal-container-519256 .portal-head-519256 .portal-metadata-519256 {\n      min-width: 0px;\n      display: flex;\n      flex-shrink: 1;\n      align-items: center;\n      margin-left: 10px; }\n    .portal-container-519256 .portal-head-519256 .portal-author-519256 {\n      font-size: 14px;\n      line-height: 1.2;\n      color: black;\n      font-weight: 600;\n      margin-bottom: 2px; }\n    .portal-container-519256 .portal-head-519256 .portal-title-519256 {\n      font-size: 14px;\n      line-height: 1.2;\n      color: #9DB8BF;\n      max-width: 100%; }\n      .portal-container-519256 .portal-head-519256 .portal-title-519256 .title-wrapper-519256 {\n        white-space: nowrap;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        font-weight: 600;\n        padding-right: 20px;\n        color: #5C6D73; }\n    .portal-container-519256 .portal-head-519256 .portal-backlink-519256 {\n      margin-left: auto;\n      display: flex;\n      flex-shrink: 1;\n      align-items: center;\n      width: 81px;\n      min-width: 81px !important;\n      padding: 0px 15px !important;\n      border-left: 1px solid #C2DFE3; }\n      .portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256 {\n        border: none !important;\n        font-family: inherit !important;\n        font-size: 14px !important;\n        color: #9DB8BF !important;\n        text-decoration: none !important;\n        -webkit-transition: opacity 0.1s ease;\n        -moz-transition: opacity 0.1s ease;\n        -ms-transition: opacity 0.1s ease;\n        -o-transition: opacity 0.1s ease;\n        transition: opacity 0.1s ease; }\n        .portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256:hover {\n          opacity: .5 !important; }\n        .portal-container-519256 .portal-head-519256 .portal-backlink-519256 .portal-arrow-519256:visited {\n          text-decoration: none !important; }\n\n.portal-content-519256 a {\n  color: #464A4D;\n  -webkit-transition: opacity 0.2s ease;\n  -moz-transition: opacity 0.2s ease;\n  -ms-transition: opacity 0.2s ease;\n  -o-transition: opacity 0.2s ease;\n  transition: opacity 0.2s ease; }\n  .portal-content-519256 a:hover {\n    opacity: .5; }\n.portal-content-519256 p {\n  margin: 0px; }\n.portal-content-519256 img {\n  width: 100%;\n  height: auto;\n  margin: .5em 0em; }\n.portal-content-519256 blockquote {\n  border-left: 2px solid #C2DFE3;\n  padding-left: .75em;\n  margin-inline-start: 1em;\n  color: #5C6D73; }\n.portal-content-519256 ol, .portal-content-519256 ul {\n  margin-block-start: .5em;\n  margin-block-end: .5em; }\n.portal-content-519256 h1, .portal-content-519256 h2, .portal-content-519256 h3 {\n  margin-block-start: .5em;\n  margin-block-end: .5em; }\n\nbody {\n  --background:#EBEEF0;\n  --light-background:#F7F9FA;\n  --graydiv:#d5d5d5;\n  --selection:#2162AF;\n  --rightpanel: white;\n  --article-title: #253237; }\n  @media (prefers-color-scheme: dark) {\n    body {\n      --background:#323333;\n      --light-background:#4B4D4D;\n      --graydiv:#656565;\n      --selection: white;\n      --rightpanel: #4B4D4D;\n      --article-title: rgba(255,255,255,.65); } }\n\nbody {\n  font-size: 14px;\n  font-family: -apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  margin: 0px;\n  padding: 0px;\n  background-color: var(--background); }\n\n#pagetitle {\n  float: left;\n  color: #253237;\n  opacity: .5;\n  line-height: 33px;\n  margin-left: 12px; }\n\n#nav {\n  border: 1px solid var(--graydiv);\n  box-sizing: border-box;\n  width: 100%;\n  height: 36px;\n  position: absolute;\n  top: 0px;\n  left: 0px;\n  background-color: var(--background); }\n  #nav #searchbar {\n    position: relative;\n    width: 516px;\n    height: 40px;\n    margin: auto;\n    margin-top: 2px; }\n  #nav #global-options-button {\n    position: absolute;\n    top: 1px;\n    right: 4px;\n    padding: 7px; }\n\n#global-options {\n  position: absolute;\n  z-index: 100;\n  right: -5px;\n  top: 33px;\n  display: none;\n  background-color: #fff;\n  padding: 10px;\n  width: 100px; }\n\n#global-options.on {\n  position: absolute;\n  display: block;\n  background-color: #fff;\n  padding: 10px;\n  color: #333; }\n\n#global-options button {\n  padding: 5px;\n  color: #A8A9AB;\n  font-size: 14px;\n  text-align: left; }\n  #global-options button:hover {\n    cursor: pointer;\n    text-decoration: underline; }\n\n#appcontainer {\n  position: fixed;\n  top: 36px;\n  display: flex;\n  flex-direction: row;\n  width: 100%; }\n  #appcontainer #leftnav {\n    position: relative;\n    border-right: 1px solid var(--graydiv);\n    background-color: var(--background);\n    height: 100vh;\n    flex-grow: 1;\n    min-width: 350px;\n    max-width: 500px;\n    overflow-y: scroll;\n    overscroll-behavior: contain; }\n  #appcontainer #rightpanel {\n    position: relative;\n    min-width: 800px;\n    flex-grow: 2;\n    background: var(--rightpanel);\n    height: 100vh;\n    overflow: scroll; }\n\n#articleSort {\n  position: relative;\n  display: flex;\n  z-index: 105;\n  width: 100%;\n  background-color: var(--background);\n  height: 25px;\n  font-size: 14px;\n  border-bottom: 1px solid var(--graydiv);\n  color: #333;\n  font-weight: 600;\n  padding: 5px 0px 0px 12px;\n  text-overflow: ellipsis; }\n\n#article-scrollContainer, #panel-scrollContainer {\n  padding-bottom: 70px; }\n\n#leftnav::-webkit-scrollbar {\n  display: none; }\n\n#panel-scrollContainer {\n  margin-top: 40px;\n  padding: 25px 75px 50px 3vw; }\n\n#titlebar {\n  position: absolute;\n  width: 100%;\n  display: flex;\n  flex-flow: row nowrap;\n  align-items: center;\n  justify-content: space-between;\n  height: 40px;\n  z-index: 10;\n  background-color: var(--light-background);\n  font-size: 14px;\n  border-bottom: 1px solid var(--graydiv); }\n  #titlebar #titlebar-innercontainer {\n    display: flex;\n    flex-flow: row nowrap;\n    white-space: nowrap !important;\n    overflow: hidden !important;\n    text-overflow: ellipsis; }\n  #titlebar #titlebar-author {\n    margin-left: 10px;\n    padding: 5px 5px 5px 5px;\n    display: block;\n    float: left; }\n  #titlebar #titlebar-title {\n    display: block;\n    float: left;\n    color: var(--selection);\n    font-weight: 600;\n    padding: 5px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis; }\n  #titlebar #titlebar-options {\n    right: 40px;\n    display: flex;\n    align-items: center;\n    width: 40px;\n    height: 100%;\n    border-left: 1px solid var(--graydiv); }\n    #titlebar #titlebar-options:hover {\n      background-color: #fafafa; }\n    #titlebar #titlebar-options::after {\n      content: '\\2807';\n      font-size: 24px;\n      padding: 12px 10px 10px 14px;\n      color: #B1B2B4; }\n\n#titlebar-author:hover, #titlebar-title:hover {\n  opacity: .65;\n  background-color: var(--background); }\n\n#titlebar-author:focus, #titlebar-title:focus {\n  opacity: .65;\n  background-color: var(--background);\n  outline: none; }\n\n[contenteditable=true]:empty:before {\n  content: attr(placeholder); }\n\n.dropdown {\n  position: absolute;\n  color: #333;\n  border: 1px solid #9DB8BF;\n  box-shadow: 1px 3px 8px rgba(0, 0, 0, 0.15); }\n\n#titlebar-dropdown {\n  position: absolute;\n  right: 0px;\n  top: 40px;\n  display: none;\n  background-color: #fff;\n  padding: 10px; }\n  #titlebar-dropdown #titlebar-delete {\n    font-size: 14px; }\n    #titlebar-dropdown #titlebar-delete:hover {\n      cursor: pointer;\n      color: red; }\n\n#titlebar-dropdown.on {\n  position: absolute;\n  display: block;\n  background-color: #fff;\n  padding: 10px;\n  color: #333; }\n\n#capture-helper {\n  position: absolute;\n  left: 50%;\n  width: 300px;\n  margin-top: -40px;\n  transform: translateX(-50%);\n  text-align: center;\n  z-index: 100;\n  color: #A8A9AB;\n  font-size: 14px; }\n\n.quoteblock {\n  margin-bottom: 25px;\n  z-index: 9999; }\n\n.quote-container {\n  display: flex;\n  flex-direction: row; }\n  .quote-container #quoteback-component {\n    max-width: 700px; }\n  .quote-container .quote-controls {\n    flex-direction: column;\n    margin-left: 5px;\n    position: relative;\n    width: 130px;\n    opacity: 0;\n    -webkit-transition: all 0.2s ease;\n    -moz-transition: all 0.2s ease;\n    -ms-transition: all 0.2s ease;\n    -o-transition: all 0.2s ease;\n    transition: all 0.2s ease; }\n    .quote-container .quote-controls .control-button {\n      margin-bottom: 6px;\n      word-wrap: no-wrap; }\n    .quote-container .quote-controls #delete {\n      color: red; }\n      .quote-container .quote-controls #delete:hover {\n        color: black; }\n    .quote-container .quote-controls #embedLink {\n      color: #395FE5; }\n      .quote-container .quote-controls #embedLink:hover {\n        color: black; }\n\n.options-control-button {\n  border: none;\n  padding: 10px;\n  text-align: left;\n  font-size: 14px;\n  font-weight: 500;\n  font-family: inherit;\n  display: inline-block;\n  border-radius: 2px;\n  -webkit-transition: background-color 0.2s ease;\n  -moz-transition: background-color 0.2s ease;\n  -ms-transition: background-color 0.2s ease;\n  -o-transition: background-color 0.2s ease;\n  transition: background-color 0.2s ease; }\n  .options-control-button:hover {\n    cursor: pointer;\n    color: black;\n    background-color: rgba(194, 223, 227, 0.25); }\n\n.showcontrols {\n  transform: translateX(10px);\n  opacity: 1 !important; }\n\n.comment {\n  max-width: 600px;\n  line-height: 20px;\n  padding: 11px;\n  color: #b6b6b6;\n  background: #ECEEEF;\n  box-sizing: border-box;\n  border-radius: 10px;\n  margin-top: -15px;\n  -webkit-transition: all 0.1s ease;\n  -moz-transition: all 0.1s ease;\n  -ms-transition: all 0.1s ease;\n  -o-transition: all 0.1s ease;\n  transition: all 0.1s ease; }\n\n.comment:focus {\n  outline: none;\n  box-shadow: inset 0px 0px 0px 1px #9DB8BF; }\n\n.meta {\n  height: 25px;\n  width: 100%; }\n\n.date {\n  color: #B8B8B8;\n  float: left; }\n\n.linkback a {\n  color: #B8B8B8;\n  float: left;\n  text-decoration: underline;\n  margin-left: 15px; }\n  .linkback a:visited {\n    color: #B8B8B8; }\n\n.article {\n  -webkit-transition: all 0.1s ease;\n  -moz-transition: all 0.1s ease;\n  -ms-transition: all 0.1s ease;\n  -o-transition: all 0.1s ease;\n  transition: all 0.1s ease;\n  border-bottom: 0.5px solid var(--graydiv);\n  padding: 15px 11px 10px 15px;\n  background-color: var(--background);\n  cursor: pointer;\n  display: flex;\n  flex-flow: row nowrap;\n  justify-content: start;\n  align-items: stretch; }\n  .article:hover {\n    background-color: var(--rightpanel); }\n  .article .title {\n    color: var(--article-title);\n    font-weight: 600;\n    margin-bottom: 8px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    padding-right: 5px; }\n  .article .url {\n    font-weight: 300;\n    margin-left: auto;\n    white-space: nowrap;\n    color: var(--article-title);\n    opacity: .5; }\n    .article .url img {\n      padding-right: 5px;\n      vertical-align: bottom; }\n\n.selected {\n  border-left: 4px solid var(--selection);\n  background-color: var(--rightpanel); }\n  .selected .title {\n    color: var(--selection); }\n  .selected .url {\n    color: var(--selection);\n    opacity: 1; }\n\n.mini-favicon {\n  margin-right: 6px;\n  width: 16px;\n  height: 16px;\n  margin: 1px 12px 0px 0px; }\n\n#fastSearch {\n  position: absolute;\n  left: 0px;\n  display: inline-block;\n  width: 100%;\n  z-index: 5; }\n  #fastSearch:focus-within #searchInput {\n    box-shadow: 0 1px 1px 0 rgba(65, 69, 73, 0.3), 0 1px 3px 1px rgba(65, 69, 73, 0.15);\n    background: var(--light-background);\n    border: none;\n    border-radius: 4px 4px 0px 0px; }\n\n#fastSearch input {\n  -webkit-transition: all 0.2s ease;\n  -moz-transition: all 0.2s ease;\n  -ms-transition: all 0.2s ease;\n  -o-transition: all 0.2s ease;\n  transition: all 0.2s ease;\n  padding-left: 10px;\n  width: 100%;\n  height: 26px;\n  font-size: 14px;\n  background: var(--light-background);\n  outline: none;\n  text-align: left;\n  display: inline-block;\n  background: var(--light-background);\n  border: 0.5px solid var(--graydiv);\n  border-radius: 4px; }\n  #fastSearch input::placeholder {\n    color: #767778;\n    opacity: .5; }\n\n#searchResults {\n  display: none;\n  position: absolute;\n  margin: 0px;\n  padding: 0px;\n  width: 528px;\n  background: white;\n  border-radius: 0px 0px 4px 4px;\n  box-shadow: 0 1px 1px 0 rgba(65, 69, 73, 0.3), 0 1px 3px 1px rgba(65, 69, 73, 0.15); }\n\n#searchResults li {\n  list-style: none;\n  width: 100%;\n  margin-left: 0em;\n  background: white;\n  border-bottom: 1px solid var(--graydiv);\n  position: relative; }\n\n#searchResults li .title {\n  font-size: 1.1em;\n  margin-bottom: 10px;\n  display: inline-block; }\n\n#searchResults .search-url {\n  font-weight: 300;\n  margin: 2px 0px 2px auto;\n  white-space: nowrap;\n  color: #253237;\n  opacity: .5; }\n\n.search-content {\n  color: #464A4D; }\n\n#searchResults a {\n  color: black;\n  text-decoration: none !important;\n  padding: 10px;\n  display: inline-block; }\n  #searchResults a img {\n    margin-right: 5px; }\n\n#searchResults a:hover, a:focus {\n  outline: 0;\n  background-color: #ECEEEF; }\n\n#searchResults li:focus-within, #searchResults li:hover {\n  outline: 0;\n  background-color: #ECEEEF; }\n\ninput, button {\n  border: none;\n  background-image: none;\n  background-color: transparent;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  color: #9DB8BF;\n  text-decoration: none; }\n\n#citation-capture {\n  font-family: -apple-system, system-ui, \"Open Sans\", \"Segoe UI\", Helvetica, \"Apple Color Emoji\", Arial, sans-serif, \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  overflow: hidden !important;\n  width: 600px;\n  height: auto;\n  position: fixed !important;\n  top: -5px !important;\n  right: -5px !important;\n  overflow-x: hidden;\n  overflow-y: auto;\n  max-height: calc(100% - 50px);\n  z-index: 2147483;\n  padding: 20px; }\n\n.blockquote-wrapper {\n  box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15);\n  border-radius: 8px; }\n\n.citation-tools {\n  margin-top: -15px;\n  background-color: white;\n  border: 1px solid #C2DFE3;\n  border-radius: 8px;\n  box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.15); }\n\n.comment-field {\n  padding: 12px;\n  border-bottom: 1px solid #C2DFE3; }\n\n.citation-input {\n  width: 500px;\n  box-shadow: none;\n  -webkit-appearance: none;\n  color: #464A4D;\n  box-sizing: border-box;\n  border-radius: 4px;\n  font-size: 14px;\n  word-wrap: break-word;\n  word-break: break-all;\n  -webkit-transition: all 0.1s ease;\n  -moz-transition: all 0.1s ease;\n  -ms-transition: all 0.1s ease;\n  -o-transition: all 0.1s ease;\n  transition: all 0.1s ease; }\n  .citation-input::placeholder {\n    font-size: 14px;\n    line-height: 150%;\n    color: #000000;\n    opacity: 0.25; }\n\n.citation-input:focus {\n  outline: none; }\n\n.tools-buttons {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n  height: 44px; }\n\n.control-button {\n  border: none;\n  height: 44px;\n  width: 100%;\n  text-align: center;\n  font-size: 14px;\n  font-weight: 500;\n  font-family: inherit;\n  display: inline-block;\n  -webkit-transition: background-color 0.2s ease;\n  -moz-transition: background-color 0.2s ease;\n  -ms-transition: background-color 0.2s ease;\n  -o-transition: background-color 0.2s ease;\n  transition: background-color 0.2s ease; }\n  .control-button:hover {\n    cursor: pointer;\n    opacity: 1;\n    background-color: rgba(194, 223, 227, 0.25); }\n  .control-button:focus {\n    outline: none; }\n\n#getlink {\n  padding: 0px;\n  color: #395FE5;\n  border-right: 1px solid #C2DFE3; }\n\n#getMarkdown {\n  padding: 0px;\n  text-align: center;\n  border-right: 1px solid #C2DFE3; }\n\n#close-button {\n  width: 50%; }\n\n.save-indicator {\n  font-size: 14px;\n  float: right;\n  display: inline-block;\n  text-align: center;\n  box-sizing: border-box;\n  color: rgba(23, 154, 12, 0.5);\n  align-self: start; }\n\n#quoteslink {\n  height: 44px;\n  line-height: 45px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: #9DB8BF;\n  text-decoration: none;\n  text-align: center;\n  border-right: 1px solid #C2DFE3; }\n  #quoteslink img {\n    width: 24px;\n    height: auto;\n    margin-left: 11px; }\n\nbody.welcome {\n  margin: 0px auto;\n  padding-top: 15rem;\n  padding-bottom: 3rem;\n  line-height: 130%;\n  width: 500px; }\n  body.welcome ol li {\n    margin-bottom: .5rem; }\n\n.article-container {\n  max-width: 700px; }\n  .article-container figure {\n    margin: 0px; }\n  .article-container img {\n    width: 100%;\n    height: auto; }\n\n/*# sourceMappingURL=styles.css.map */\n"
  },
  {
    "path": "styles/styles.scss",
    "content": "@charset \"UTF-8\";\n@import 'quote';\n@import 'options';\n@import 'popup';\n@import 'welcome';\n@import 'article-style';"
  },
  {
    "path": "styles/welcome.css",
    "content": "body.welcome {\n  margin: 0px auto;\n  padding-top: 15rem;\n  padding-bottom: 3rem;\n  line-height: 130%;\n  width: 500px;\n}\n\nbody.welcome ol li {\n  margin-bottom: .5rem;\n}\n/*# sourceMappingURL=welcome.css.map */"
  },
  {
    "path": "styles/welcome.scss",
    "content": "body{\n  &.welcome{\n\t\tmargin: 0px auto;\n\t\tpadding-top:15rem;\n\t\tpadding-bottom:3rem;\n\t\tline-height:130%;\n\t\twidth: 500px;  \t\n\t  ol{\n\t  \tli{\n\t  \t\tmargin-bottom:.5rem;\n\t  \t}\n\t  }\t\t\n  }\n}\n\n"
  },
  {
    "path": "turndown.js",
    "content": "var TurndownService = (function () {\n  'use strict';\n\n  function extend (destination) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i];\n      for (var key in source) {\n        if (source.hasOwnProperty(key)) destination[key] = source[key];\n      }\n    }\n    return destination\n  }\n\n  function repeat (character, count) {\n    return Array(count + 1).join(character)\n  }\n\n  var blockElements = [\n    'address', 'article', 'aside', 'audio', 'blockquote', 'body', 'canvas',\n    'center', 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption',\n    'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n    'header', 'hgroup', 'hr', 'html', 'isindex', 'li', 'main', 'menu', 'nav',\n    'noframes', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table',\n    'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul'\n  ];\n\n  function isBlock (node) {\n    return blockElements.indexOf(node.nodeName.toLowerCase()) !== -1\n  }\n\n  var voidElements = [\n    'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',\n    'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'\n  ];\n\n  function isVoid (node) {\n    return voidElements.indexOf(node.nodeName.toLowerCase()) !== -1\n  }\n\n  var voidSelector = voidElements.join();\n  function hasVoid (node) {\n    return node.querySelector && node.querySelector(voidSelector)\n  }\n\n  var rules = {};\n\n  rules.paragraph = {\n    filter: 'p',\n\n    replacement: function (content) {\n      return '\\n\\n' + content + '\\n\\n'\n    }\n  };\n\n  rules.lineBreak = {\n    filter: 'br',\n\n    replacement: function (content, node, options) {\n      return options.br + '\\n'\n    }\n  };\n\n  rules.heading = {\n    filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n    replacement: function (content, node, options) {\n      var hLevel = Number(node.nodeName.charAt(1));\n\n      if (options.headingStyle === 'setext' && hLevel < 3) {\n        var underline = repeat((hLevel === 1 ? '=' : '-'), content.length);\n        return (\n          '\\n\\n' + content + '\\n' + underline + '\\n\\n'\n        )\n      } else {\n        return '\\n\\n' + repeat('#', hLevel) + ' ' + content + '\\n\\n'\n      }\n    }\n  };\n\n  rules.blockquote = {\n    filter: 'blockquote',\n\n    replacement: function (content) {\n      content = content.replace(/^\\n+|\\n+$/g, '');\n      content = content.replace(/^/gm, '> ');\n      return '\\n\\n' + content + '\\n\\n'\n    }\n  };\n\n  rules.list = {\n    filter: ['ul', 'ol'],\n\n    replacement: function (content, node) {\n      var parent = node.parentNode;\n      if (parent.nodeName === 'LI' && parent.lastElementChild === node) {\n        return '\\n' + content\n      } else {\n        return '\\n\\n' + content + '\\n\\n'\n      }\n    }\n  };\n\n  rules.listItem = {\n    filter: 'li',\n\n    replacement: function (content, node, options) {\n      content = content\n        .replace(/^\\n+/, '') // remove leading newlines\n        .replace(/\\n+$/, '\\n') // replace trailing newlines with just a single one\n        .replace(/\\n/gm, '\\n    '); // indent\n      var prefix = options.bulletListMarker + '   ';\n      var parent = node.parentNode;\n      if (parent.nodeName === 'OL') {\n        var start = parent.getAttribute('start');\n        var index = Array.prototype.indexOf.call(parent.children, node);\n        prefix = (start ? Number(start) + index : index + 1) + '.  ';\n      }\n      return (\n        prefix + content + (node.nextSibling && !/\\n$/.test(content) ? '\\n' : '')\n      )\n    }\n  };\n\n  rules.indentedCodeBlock = {\n    filter: function (node, options) {\n      return (\n        options.codeBlockStyle === 'indented' &&\n        node.nodeName === 'PRE' &&\n        node.firstChild &&\n        node.firstChild.nodeName === 'CODE'\n      )\n    },\n\n    replacement: function (content, node, options) {\n      return (\n        '\\n\\n    ' +\n        node.firstChild.textContent.replace(/\\n/g, '\\n    ') +\n        '\\n\\n'\n      )\n    }\n  };\n\n  rules.fencedCodeBlock = {\n    filter: function (node, options) {\n      return (\n        options.codeBlockStyle === 'fenced' &&\n        node.nodeName === 'PRE' &&\n        node.firstChild &&\n        node.firstChild.nodeName === 'CODE'\n      )\n    },\n\n    replacement: function (content, node, options) {\n      var className = node.firstChild.className || '';\n      var language = (className.match(/language-(\\S+)/) || [null, ''])[1];\n      var code = node.firstChild.textContent;\n\n      var fenceChar = options.fence.charAt(0);\n      var fenceSize = 3;\n      var fenceInCodeRegex = new RegExp('^' + fenceChar + '{3,}', 'gm');\n\n      var match;\n      while ((match = fenceInCodeRegex.exec(code))) {\n        if (match[0].length >= fenceSize) {\n          fenceSize = match[0].length + 1;\n        }\n      }\n\n      var fence = repeat(fenceChar, fenceSize);\n\n      return (\n        '\\n\\n' + fence + language + '\\n' +\n        code.replace(/\\n$/, '') +\n        '\\n' + fence + '\\n\\n'\n      )\n    }\n  };\n\n  rules.horizontalRule = {\n    filter: 'hr',\n\n    replacement: function (content, node, options) {\n      return '\\n\\n' + options.hr + '\\n\\n'\n    }\n  };\n\n  rules.inlineLink = {\n    filter: function (node, options) {\n      return (\n        options.linkStyle === 'inlined' &&\n        node.nodeName === 'A' &&\n        node.getAttribute('href')\n      )\n    },\n\n    replacement: function (content, node) {\n      var href = node.getAttribute('href');\n      var title = node.title ? ' \"' + node.title + '\"' : '';\n      return '[' + content + '](' + href + title + ')'\n    }\n  };\n\n  rules.referenceLink = {\n    filter: function (node, options) {\n      return (\n        options.linkStyle === 'referenced' &&\n        node.nodeName === 'A' &&\n        node.getAttribute('href')\n      )\n    },\n\n    replacement: function (content, node, options) {\n      var href = node.getAttribute('href');\n      var title = node.title ? ' \"' + node.title + '\"' : '';\n      var replacement;\n      var reference;\n\n      switch (options.linkReferenceStyle) {\n        case 'collapsed':\n          replacement = '[' + content + '][]';\n          reference = '[' + content + ']: ' + href + title;\n          break\n        case 'shortcut':\n          replacement = '[' + content + ']';\n          reference = '[' + content + ']: ' + href + title;\n          break\n        default:\n          var id = this.references.length + 1;\n          replacement = '[' + content + '][' + id + ']';\n          reference = '[' + id + ']: ' + href + title;\n      }\n\n      this.references.push(reference);\n      return replacement\n    },\n\n    references: [],\n\n    append: function (options) {\n      var references = '';\n      if (this.references.length) {\n        references = '\\n\\n' + this.references.join('\\n') + '\\n\\n';\n        this.references = []; // Reset references\n      }\n      return references\n    }\n  };\n\n  rules.emphasis = {\n    filter: ['em', 'i'],\n\n    replacement: function (content, node, options) {\n      if (!content.trim()) return ''\n      return options.emDelimiter + content + options.emDelimiter\n    }\n  };\n\n  rules.strong = {\n    filter: ['strong', 'b'],\n\n    replacement: function (content, node, options) {\n      if (!content.trim()) return ''\n      return options.strongDelimiter + content + options.strongDelimiter\n    }\n  };\n\n  rules.code = {\n    filter: function (node) {\n      var hasSiblings = node.previousSibling || node.nextSibling;\n      var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings;\n\n      return node.nodeName === 'CODE' && !isCodeBlock\n    },\n\n    replacement: function (content) {\n      if (!content.trim()) return ''\n\n      var delimiter = '`';\n      var leadingSpace = '';\n      var trailingSpace = '';\n      var matches = content.match(/`+/gm);\n      if (matches) {\n        if (/^`/.test(content)) leadingSpace = ' ';\n        if (/`$/.test(content)) trailingSpace = ' ';\n        while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`';\n      }\n\n      return delimiter + leadingSpace + content + trailingSpace + delimiter\n    }\n  };\n\n  rules.image = {\n    filter: 'img',\n\n    replacement: function (content, node) {\n      var alt = node.alt || '';\n      var src = node.getAttribute('src') || '';\n      var title = node.title || '';\n      var titlePart = title ? ' \"' + title + '\"' : '';\n      return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''\n    }\n  };\n\n  /**\n   * Manages a collection of rules used to convert HTML to Markdown\n   */\n\n  function Rules (options) {\n    this.options = options;\n    this._keep = [];\n    this._remove = [];\n\n    this.blankRule = {\n      replacement: options.blankReplacement\n    };\n\n    this.keepReplacement = options.keepReplacement;\n\n    this.defaultRule = {\n      replacement: options.defaultReplacement\n    };\n\n    this.array = [];\n    for (var key in options.rules) this.array.push(options.rules[key]);\n  }\n\n  Rules.prototype = {\n    add: function (key, rule) {\n      this.array.unshift(rule);\n    },\n\n    keep: function (filter) {\n      this._keep.unshift({\n        filter: filter,\n        replacement: this.keepReplacement\n      });\n    },\n\n    remove: function (filter) {\n      this._remove.unshift({\n        filter: filter,\n        replacement: function () {\n          return ''\n        }\n      });\n    },\n\n    forNode: function (node) {\n      if (node.isBlank) return this.blankRule\n      var rule;\n\n      if ((rule = findRule(this.array, node, this.options))) return rule\n      if ((rule = findRule(this._keep, node, this.options))) return rule\n      if ((rule = findRule(this._remove, node, this.options))) return rule\n\n      return this.defaultRule\n    },\n\n    forEach: function (fn) {\n      for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);\n    }\n  };\n\n  function findRule (rules, node, options) {\n    for (var i = 0; i < rules.length; i++) {\n      var rule = rules[i];\n      if (filterValue(rule, node, options)) return rule\n    }\n    return void 0\n  }\n\n  function filterValue (rule, node, options) {\n    var filter = rule.filter;\n    if (typeof filter === 'string') {\n      if (filter === node.nodeName.toLowerCase()) return true\n    } else if (Array.isArray(filter)) {\n      if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true\n    } else if (typeof filter === 'function') {\n      if (filter.call(rule, node, options)) return true\n    } else {\n      throw new TypeError('`filter` needs to be a string, array, or function')\n    }\n  }\n\n  /**\n   * The collapseWhitespace function is adapted from collapse-whitespace\n   * by Luc Thevenard.\n   *\n   * The MIT License (MIT)\n   *\n   * Copyright (c) 2014 Luc Thevenard <lucthevenard@gmail.com>\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining a copy\n   * of this software and associated documentation files (the \"Software\"), to deal\n   * in the Software without restriction, including without limitation the rights\n   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   * copies of the Software, and to permit persons to whom the Software is\n   * furnished to do so, subject to the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be included in\n   * all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n   * THE SOFTWARE.\n   */\n\n  /**\n   * collapseWhitespace(options) removes extraneous whitespace from an the given element.\n   *\n   * @param {Object} options\n   */\n  function collapseWhitespace (options) {\n    var element = options.element;\n    var isBlock = options.isBlock;\n    var isVoid = options.isVoid;\n    var isPre = options.isPre || function (node) {\n      return node.nodeName === 'PRE'\n    };\n\n    if (!element.firstChild || isPre(element)) return\n\n    var prevText = null;\n    var prevVoid = false;\n\n    var prev = null;\n    var node = next(prev, element, isPre);\n\n    while (node !== element) {\n      if (node.nodeType === 3 || node.nodeType === 4) { // Node.TEXT_NODE or Node.CDATA_SECTION_NODE\n        var text = node.data.replace(/[ \\r\\n\\t]+/g, ' ');\n\n        if ((!prevText || / $/.test(prevText.data)) &&\n            !prevVoid && text[0] === ' ') {\n          text = text.substr(1);\n        }\n\n        // `text` might be empty at this point.\n        if (!text) {\n          node = remove(node);\n          continue\n        }\n\n        node.data = text;\n\n        prevText = node;\n      } else if (node.nodeType === 1) { // Node.ELEMENT_NODE\n        if (isBlock(node) || node.nodeName === 'BR') {\n          if (prevText) {\n            prevText.data = prevText.data.replace(/ $/, '');\n          }\n\n          prevText = null;\n          prevVoid = false;\n        } else if (isVoid(node)) {\n          // Avoid trimming space around non-block, non-BR void elements.\n          prevText = null;\n          prevVoid = true;\n        }\n      } else {\n        node = remove(node);\n        continue\n      }\n\n      var nextNode = next(prev, node, isPre);\n      prev = node;\n      node = nextNode;\n    }\n\n    if (prevText) {\n      prevText.data = prevText.data.replace(/ $/, '');\n      if (!prevText.data) {\n        remove(prevText);\n      }\n    }\n  }\n\n  /**\n   * remove(node) removes the given node from the DOM and returns the\n   * next node in the sequence.\n   *\n   * @param {Node} node\n   * @return {Node} node\n   */\n  function remove (node) {\n    var next = node.nextSibling || node.parentNode;\n\n    node.parentNode.removeChild(node);\n\n    return next\n  }\n\n  /**\n   * next(prev, current, isPre) returns the next node in the sequence, given the\n   * current and previous nodes.\n   *\n   * @param {Node} prev\n   * @param {Node} current\n   * @param {Function} isPre\n   * @return {Node}\n   */\n  function next (prev, current, isPre) {\n    if ((prev && prev.parentNode === current) || isPre(current)) {\n      return current.nextSibling || current.parentNode\n    }\n\n    return current.firstChild || current.nextSibling || current.parentNode\n  }\n\n  /*\n   * Set up window for Node.js\n   */\n\n  var root = (typeof window !== 'undefined' ? window : {});\n\n  /*\n   * Parsing HTML strings\n   */\n\n  function canParseHTMLNatively () {\n    var Parser = root.DOMParser;\n    var canParse = false;\n\n    // Adapted from https://gist.github.com/1129031\n    // Firefox/Opera/IE throw errors on unsupported types\n    try {\n      // WebKit returns null on unsupported types\n      if (new Parser().parseFromString('', 'text/html')) {\n        canParse = true;\n      }\n    } catch (e) {}\n\n    return canParse\n  }\n\n  function createHTMLParser () {\n    var Parser = function () {};\n\n    {\n      if (shouldUseActiveX()) {\n        Parser.prototype.parseFromString = function (string) {\n          var doc = new window.ActiveXObject('htmlfile');\n          doc.designMode = 'on'; // disable on-page scripts\n          doc.open();\n          doc.write(string);\n          doc.close();\n          return doc\n        };\n      } else {\n        Parser.prototype.parseFromString = function (string) {\n          var doc = document.implementation.createHTMLDocument('');\n          doc.open();\n          doc.write(string);\n          doc.close();\n          return doc\n        };\n      }\n    }\n    return Parser\n  }\n\n  function shouldUseActiveX () {\n    var useActiveX = false;\n    try {\n      document.implementation.createHTMLDocument('').open();\n    } catch (e) {\n      if (window.ActiveXObject) useActiveX = true;\n    }\n    return useActiveX\n  }\n\n  var HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();\n\n  function RootNode (input) {\n    var root;\n    if (typeof input === 'string') {\n      var doc = htmlParser().parseFromString(\n        // DOM parsers arrange elements in the <head> and <body>.\n        // Wrapping in a custom element ensures elements are reliably arranged in\n        // a single element.\n        '<x-turndown id=\"turndown-root\">' + input + '</x-turndown>',\n        'text/html'\n      );\n      root = doc.getElementById('turndown-root');\n    } else {\n      root = input.cloneNode(true);\n    }\n    collapseWhitespace({\n      element: root,\n      isBlock: isBlock,\n      isVoid: isVoid\n    });\n\n    return root\n  }\n\n  var _htmlParser;\n  function htmlParser () {\n    _htmlParser = _htmlParser || new HTMLParser();\n    return _htmlParser\n  }\n\n  function Node (node) {\n    node.isBlock = isBlock(node);\n    node.isCode = node.nodeName.toLowerCase() === 'code' || node.parentNode.isCode;\n    node.isBlank = isBlank(node);\n    node.flankingWhitespace = flankingWhitespace(node);\n    return node\n  }\n\n  function isBlank (node) {\n    return (\n      ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&\n      /^\\s*$/i.test(node.textContent) &&\n      !isVoid(node) &&\n      !hasVoid(node)\n    )\n  }\n\n  function flankingWhitespace (node) {\n    var leading = '';\n    var trailing = '';\n\n    if (!node.isBlock) {\n      var hasLeading = /^\\s/.test(node.textContent);\n      var hasTrailing = /\\s$/.test(node.textContent);\n      var blankWithSpaces = node.isBlank && hasLeading && hasTrailing;\n\n      if (hasLeading && !isFlankedByWhitespace('left', node)) {\n        leading = ' ';\n      }\n\n      if (!blankWithSpaces && hasTrailing && !isFlankedByWhitespace('right', node)) {\n        trailing = ' ';\n      }\n    }\n\n    return { leading: leading, trailing: trailing }\n  }\n\n  function isFlankedByWhitespace (side, node) {\n    var sibling;\n    var regExp;\n    var isFlanked;\n\n    if (side === 'left') {\n      sibling = node.previousSibling;\n      regExp = / $/;\n    } else {\n      sibling = node.nextSibling;\n      regExp = /^ /;\n    }\n\n    if (sibling) {\n      if (sibling.nodeType === 3) {\n        isFlanked = regExp.test(sibling.nodeValue);\n      } else if (sibling.nodeType === 1 && !isBlock(sibling)) {\n        isFlanked = regExp.test(sibling.textContent);\n      }\n    }\n    return isFlanked\n  }\n\n  var reduce = Array.prototype.reduce;\n  var leadingNewLinesRegExp = /^\\n*/;\n  var trailingNewLinesRegExp = /\\n*$/;\n  var escapes = [\n    [/\\\\/g, '\\\\\\\\'],\n    [/\\*/g, '\\\\*'],\n    [/^-/g, '\\\\-'],\n    [/^\\+ /g, '\\\\+ '],\n    [/^(=+)/g, '\\\\$1'],\n    [/^(#{1,6}) /g, '\\\\$1 '],\n    [/`/g, '\\\\`'],\n    [/^~~~/g, '\\\\~~~'],\n    [/\\[/g, '\\\\['],\n    [/\\]/g, '\\\\]'],\n    [/^>/g, '\\\\>'],\n    [/_/g, '\\\\_'],\n    [/^(\\d+)\\. /g, '$1\\\\. ']\n  ];\n\n  function TurndownService (options) {\n    if (!(this instanceof TurndownService)) return new TurndownService(options)\n\n    var defaults = {\n      rules: rules,\n      headingStyle: 'setext',\n      hr: '* * *',\n      bulletListMarker: '*',\n      codeBlockStyle: 'indented',\n      fence: '```',\n      emDelimiter: '_',\n      strongDelimiter: '**',\n      linkStyle: 'inlined',\n      linkReferenceStyle: 'full',\n      br: '  ',\n      blankReplacement: function (content, node) {\n        return node.isBlock ? '\\n\\n' : ''\n      },\n      keepReplacement: function (content, node) {\n        return node.isBlock ? '\\n\\n' + node.outerHTML + '\\n\\n' : node.outerHTML\n      },\n      defaultReplacement: function (content, node) {\n        return node.isBlock ? '\\n\\n' + content + '\\n\\n' : content\n      }\n    };\n    this.options = extend({}, defaults, options);\n    this.rules = new Rules(this.options);\n  }\n\n  TurndownService.prototype = {\n    /**\n     * The entry point for converting a string or DOM node to Markdown\n     * @public\n     * @param {String|HTMLElement} input The string or DOM node to convert\n     * @returns A Markdown representation of the input\n     * @type String\n     */\n\n    turndown: function (input) {\n      if (!canConvert(input)) {\n        throw new TypeError(\n          input + ' is not a string, or an element/document/fragment node.'\n        )\n      }\n\n      if (input === '') return ''\n\n      var output = process.call(this, new RootNode(input));\n      return postProcess.call(this, output)\n    },\n\n    /**\n     * Add one or more plugins\n     * @public\n     * @param {Function|Array} plugin The plugin or array of plugins to add\n     * @returns The Turndown instance for chaining\n     * @type Object\n     */\n\n    use: function (plugin) {\n      if (Array.isArray(plugin)) {\n        for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);\n      } else if (typeof plugin === 'function') {\n        plugin(this);\n      } else {\n        throw new TypeError('plugin must be a Function or an Array of Functions')\n      }\n      return this\n    },\n\n    /**\n     * Adds a rule\n     * @public\n     * @param {String} key The unique key of the rule\n     * @param {Object} rule The rule\n     * @returns The Turndown instance for chaining\n     * @type Object\n     */\n\n    addRule: function (key, rule) {\n      this.rules.add(key, rule);\n      return this\n    },\n\n    /**\n     * Keep a node (as HTML) that matches the filter\n     * @public\n     * @param {String|Array|Function} filter The unique key of the rule\n     * @returns The Turndown instance for chaining\n     * @type Object\n     */\n\n    keep: function (filter) {\n      this.rules.keep(filter);\n      return this\n    },\n\n    /**\n     * Remove a node that matches the filter\n     * @public\n     * @param {String|Array|Function} filter The unique key of the rule\n     * @returns The Turndown instance for chaining\n     * @type Object\n     */\n\n    remove: function (filter) {\n      this.rules.remove(filter);\n      return this\n    },\n\n    /**\n     * Escapes Markdown syntax\n     * @public\n     * @param {String} string The string to escape\n     * @returns A string with Markdown syntax escaped\n     * @type String\n     */\n\n    escape: function (string) {\n      return escapes.reduce(function (accumulator, escape) {\n        return accumulator.replace(escape[0], escape[1])\n      }, string)\n    }\n  };\n\n  /**\n   * Reduces a DOM node down to its Markdown string equivalent\n   * @private\n   * @param {HTMLElement} parentNode The node to convert\n   * @returns A Markdown representation of the node\n   * @type String\n   */\n\n  function process (parentNode) {\n    var self = this;\n    return reduce.call(parentNode.childNodes, function (output, node) {\n      node = new Node(node);\n\n      var replacement = '';\n      if (node.nodeType === 3) {\n        replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue);\n      } else if (node.nodeType === 1) {\n        replacement = replacementForNode.call(self, node);\n      }\n\n      return join(output, replacement)\n    }, '')\n  }\n\n  /**\n   * Appends strings as each rule requires and trims the output\n   * @private\n   * @param {String} output The conversion output\n   * @returns A trimmed version of the ouput\n   * @type String\n   */\n\n  function postProcess (output) {\n    var self = this;\n    this.rules.forEach(function (rule) {\n      if (typeof rule.append === 'function') {\n        output = join(output, rule.append(self.options));\n      }\n    });\n\n    return output.replace(/^[\\t\\r\\n]+/, '').replace(/[\\t\\r\\n\\s]+$/, '')\n  }\n\n  /**\n   * Converts an element node to its Markdown equivalent\n   * @private\n   * @param {HTMLElement} node The node to convert\n   * @returns A Markdown representation of the node\n   * @type String\n   */\n\n  function replacementForNode (node) {\n    var rule = this.rules.forNode(node);\n    var content = process.call(this, node);\n    var whitespace = node.flankingWhitespace;\n    if (whitespace.leading || whitespace.trailing) content = content.trim();\n    return (\n      whitespace.leading +\n      rule.replacement(content, node, this.options) +\n      whitespace.trailing\n    )\n  }\n\n  /**\n   * Determines the new lines between the current output and the replacement\n   * @private\n   * @param {String} output The current conversion output\n   * @param {String} replacement The string to append to the output\n   * @returns The whitespace to separate the current output and the replacement\n   * @type String\n   */\n\n  function separatingNewlines (output, replacement) {\n    var newlines = [\n      output.match(trailingNewLinesRegExp)[0],\n      replacement.match(leadingNewLinesRegExp)[0]\n    ].sort();\n    var maxNewlines = newlines[newlines.length - 1];\n    return maxNewlines.length < 2 ? maxNewlines : '\\n\\n'\n  }\n\n  function join (string1, string2) {\n    var separator = separatingNewlines(string1, string2);\n\n    // Remove trailing/leading newlines and replace with separator\n    string1 = string1.replace(trailingNewLinesRegExp, '');\n    string2 = string2.replace(leadingNewLinesRegExp, '');\n\n    return string1 + separator + string2\n  }\n\n  /**\n   * Determines whether an input can be converted\n   * @private\n   * @param {String|HTMLElement} input Describe this parameter\n   * @returns Describe what it returns\n   * @type String|Object|Array|Boolean|Number\n   */\n\n  function canConvert (input) {\n    return (\n      input != null && (\n        typeof input === 'string' ||\n        (input.nodeType && (\n          input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11\n        ))\n      )\n    )\n  }\n\n  return TurndownService;\n\n}());\n"
  },
  {
    "path": "webcomponents-sd-ce.js",
    "content": "/**\n@license @nocompile\nCopyright (c) 2018 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n(function(){/*\n\nCopyright (c) 2016 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n'use strict';var n;function aa(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}function ba(a){var b=\"undefined\"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}}function ca(a){for(var b,c=[];!(b=a.next()).done;)c.push(b.value);return c}var da=\"undefined\"!=typeof window&&window===this?this:\"undefined\"!=typeof global&&null!=global?global:this;function ea(){}ea.prototype.toJSON=function(){return{}};\nfunction p(a){a.__shady||(a.__shady=new ea);return a.__shady}function r(a){return a&&a.__shady};var t=window.ShadyDOM||{};t.Aa=!(!Element.prototype.attachShadow||!Node.prototype.getRootNode);var fa=Object.getOwnPropertyDescriptor(Node.prototype,\"firstChild\");t.h=!!(fa&&fa.configurable&&fa.get);t.ca=t.force||!t.Aa;t.j=t.noPatch||!1;t.W=t.preferPerformance;t.ea=\"on-demand\"===t.j;t.qa=navigator.userAgent.match(\"Trident\");function u(a){return(a=r(a))&&void 0!==a.firstChild}function v(a){return a instanceof ShadowRoot}function ha(a){return(a=(a=r(a))&&a.root)&&ia(a)}\nvar w=Element.prototype,ja=w.matches||w.matchesSelector||w.mozMatchesSelector||w.msMatchesSelector||w.oMatchesSelector||w.webkitMatchesSelector,ka=document.createTextNode(\"\"),ma=0,na=[];(new MutationObserver(function(){for(;na.length;)try{na.shift()()}catch(a){throw ka.textContent=ma++,a;}})).observe(ka,{characterData:!0});function oa(a){na.push(a);ka.textContent=ma++}var pa=!!document.contains;function qa(a,b){for(;b;){if(b==a)return!0;b=b.__shady_parentNode}return!1}\nfunction ra(a){for(var b=a.length-1;0<=b;b--){var c=a[b],d=c.getAttribute(\"id\")||c.getAttribute(\"name\");d&&\"length\"!==d&&isNaN(d)&&(a[d]=c)}a.item=function(e){return a[e]};a.namedItem=function(e){if(\"length\"!==e&&isNaN(e)&&a[e])return a[e];for(var f=ba(a),g=f.next();!g.done;g=f.next())if(g=g.value,(g.getAttribute(\"id\")||g.getAttribute(\"name\"))==e)return g;return null};return a}function sa(a){var b=[];for(a=a.__shady_native_firstChild;a;a=a.__shady_native_nextSibling)b.push(a);return b}\nfunction ta(a){var b=[];for(a=a.__shady_firstChild;a;a=a.__shady_nextSibling)b.push(a);return b}function ua(a,b,c){c.configurable=!0;if(c.value)a[b]=c.value;else try{Object.defineProperty(a,b,c)}catch(d){}}function y(a,b,c,d){c=void 0===c?\"\":c;for(var e in b)d&&0<=d.indexOf(e)||ua(a,c+e,b[e])}function va(a,b){for(var c in b)c in a&&ua(a,c,b[c])}function z(a){var b={};Object.getOwnPropertyNames(a).forEach(function(c){b[c]=Object.getOwnPropertyDescriptor(a,c)});return b}\nfunction wa(a,b){for(var c=Object.getOwnPropertyNames(b),d=0,e;d<c.length;d++)e=c[d],a[e]=b[e]};var xa=[],ya;function za(a){ya||(ya=!0,oa(Aa));xa.push(a)}function Aa(){ya=!1;for(var a=!!xa.length;xa.length;)xa.shift()();return a}Aa.list=xa;function Ba(){this.a=!1;this.addedNodes=[];this.removedNodes=[];this.S=new Set}function Ca(a){a.a||(a.a=!0,oa(function(){a.flush()}))}Ba.prototype.flush=function(){if(this.a){this.a=!1;var a=this.takeRecords();a.length&&this.S.forEach(function(b){b(a)})}};Ba.prototype.takeRecords=function(){if(this.addedNodes.length||this.removedNodes.length){var a=[{addedNodes:this.addedNodes,removedNodes:this.removedNodes}];this.addedNodes=[];this.removedNodes=[];return a}return[]};\nfunction Da(a,b){var c=p(a);c.I||(c.I=new Ba);c.I.S.add(b);var d=c.I;return{ua:b,D:d,va:a,takeRecords:function(){return d.takeRecords()}}}function Ea(a){var b=a&&a.D;b&&(b.S.delete(a.ua),b.S.size||(p(a.va).I=null))}\nfunction Fa(a,b){var c=b.getRootNode();return a.map(function(d){var e=c===d.target.getRootNode();if(e&&d.addedNodes){if(e=[].slice.call(d.addedNodes).filter(function(f){return c===f.getRootNode()}),e.length)return d=Object.create(d),Object.defineProperty(d,\"addedNodes\",{value:e,configurable:!0}),d}else if(e)return d}).filter(function(d){return d})};var Ga=/[&\\u00A0\"]/g,Ha=/[&\\u00A0<>]/g;function Ia(a){switch(a){case \"&\":return\"&amp;\";case \"<\":return\"&lt;\";case \">\":return\"&gt;\";case '\"':return\"&quot;\";case \"\\u00a0\":return\"&nbsp;\"}}function Ja(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}var Ka=Ja(\"area base br col command embed hr img input keygen link meta param source track wbr\".split(\" \")),La=Ja(\"style script xmp iframe noembed noframes plaintext noscript\".split(\" \"));\nfunction Ma(a,b){\"template\"===a.localName&&(a=a.content);for(var c=\"\",d=b?b(a):a.childNodes,e=0,f=d.length,g=void 0;e<f&&(g=d[e]);e++){a:{var h=g;var k=a,l=b;switch(h.nodeType){case Node.ELEMENT_NODE:k=h.localName;for(var m=\"<\"+k,q=h.attributes,x=0,la;la=q[x];x++)m+=\" \"+la.name+'=\"'+la.value.replace(Ga,Ia)+'\"';m+=\">\";h=Ka[k]?m:m+Ma(h,l)+\"</\"+k+\">\";break a;case Node.TEXT_NODE:h=h.data;h=k&&La[k.localName]?h:h.replace(Ha,Ia);break a;case Node.COMMENT_NODE:h=\"\\x3c!--\"+h.data+\"--\\x3e\";break a;default:throw window.console.error(h),\nError(\"not implemented\");}}c+=h}return c};var Na=t.h,Oa={querySelector:function(a){return this.__shady_native_querySelector(a)},querySelectorAll:function(a){return this.__shady_native_querySelectorAll(a)}},Pa={};function Qa(a){Pa[a]=function(b){return b[\"__shady_native_\"+a]}}function Ra(a,b){y(a,b,\"__shady_native_\");for(var c in b)Qa(c)}function A(a,b){b=void 0===b?[]:b;for(var c=0;c<b.length;c++){var d=b[c],e=Object.getOwnPropertyDescriptor(a,d);e&&(Object.defineProperty(a,\"__shady_native_\"+d,e),e.value?Oa[d]||(Oa[d]=e.value):Qa(d))}}\nvar B=document.createTreeWalker(document,NodeFilter.SHOW_ALL,null,!1),C=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT,null,!1),Sa=document.implementation.createHTMLDocument(\"inert\");function Ta(a){for(var b;b=a.__shady_native_firstChild;)a.__shady_native_removeChild(b)}var Ua=[\"firstElementChild\",\"lastElementChild\",\"children\",\"childElementCount\"],Va=[\"querySelector\",\"querySelectorAll\"];\nfunction Wa(){var a=[\"dispatchEvent\",\"addEventListener\",\"removeEventListener\"];window.EventTarget?A(window.EventTarget.prototype,a):(A(Node.prototype,a),A(Window.prototype,a));Na?A(Node.prototype,\"parentNode firstChild lastChild previousSibling nextSibling childNodes parentElement textContent\".split(\" \")):Ra(Node.prototype,{parentNode:{get:function(){B.currentNode=this;return B.parentNode()}},firstChild:{get:function(){B.currentNode=this;return B.firstChild()}},lastChild:{get:function(){B.currentNode=\nthis;return B.lastChild()}},previousSibling:{get:function(){B.currentNode=this;return B.previousSibling()}},nextSibling:{get:function(){B.currentNode=this;return B.nextSibling()}},childNodes:{get:function(){var b=[];B.currentNode=this;for(var c=B.firstChild();c;)b.push(c),c=B.nextSibling();return b}},parentElement:{get:function(){C.currentNode=this;return C.parentNode()}},textContent:{get:function(){switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:for(var b=document.createTreeWalker(this,\nNodeFilter.SHOW_TEXT,null,!1),c=\"\",d;d=b.nextNode();)c+=d.nodeValue;return c;default:return this.nodeValue}},set:function(b){if(\"undefined\"===typeof b||null===b)b=\"\";switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:Ta(this);(0<b.length||this.nodeType===Node.ELEMENT_NODE)&&this.__shady_native_insertBefore(document.createTextNode(b),void 0);break;default:this.nodeValue=b}}}});A(Node.prototype,\"appendChild insertBefore removeChild replaceChild cloneNode contains\".split(\" \"));\nA(HTMLElement.prototype,[\"parentElement\",\"contains\"]);a={firstElementChild:{get:function(){C.currentNode=this;return C.firstChild()}},lastElementChild:{get:function(){C.currentNode=this;return C.lastChild()}},children:{get:function(){var b=[];C.currentNode=this;for(var c=C.firstChild();c;)b.push(c),c=C.nextSibling();return ra(b)}},childElementCount:{get:function(){return this.children?this.children.length:0}}};Na?(A(Element.prototype,Ua),A(Element.prototype,[\"previousElementSibling\",\"nextElementSibling\",\n\"innerHTML\",\"className\"]),A(HTMLElement.prototype,[\"children\",\"innerHTML\",\"className\"])):(Ra(Element.prototype,a),Ra(Element.prototype,{previousElementSibling:{get:function(){C.currentNode=this;return C.previousSibling()}},nextElementSibling:{get:function(){C.currentNode=this;return C.nextSibling()}},innerHTML:{get:function(){return Ma(this,sa)},set:function(b){var c=\"template\"===this.localName?this.content:this;Ta(c);var d=this.localName||\"div\";d=this.namespaceURI&&this.namespaceURI!==Sa.namespaceURI?\nSa.createElementNS(this.namespaceURI,d):Sa.createElement(d);d.innerHTML=b;for(b=\"template\"===this.localName?d.content:d;d=b.__shady_native_firstChild;)c.__shady_native_insertBefore(d,void 0)}},className:{get:function(){return this.getAttribute(\"class\")||\"\"},set:function(b){this.setAttribute(\"class\",b)}}}));A(Element.prototype,\"setAttribute getAttribute hasAttribute removeAttribute focus blur\".split(\" \"));A(Element.prototype,Va);A(HTMLElement.prototype,[\"focus\",\"blur\"]);window.HTMLTemplateElement&&\nA(window.HTMLTemplateElement.prototype,[\"innerHTML\"]);Na?A(DocumentFragment.prototype,Ua):Ra(DocumentFragment.prototype,a);A(DocumentFragment.prototype,Va);Na?(A(Document.prototype,Ua),A(Document.prototype,[\"activeElement\"])):Ra(Document.prototype,a);A(Document.prototype,[\"importNode\",\"getElementById\"]);A(Document.prototype,Va)};var Ya=z({get childNodes(){return this.__shady_childNodes},get firstChild(){return this.__shady_firstChild},get lastChild(){return this.__shady_lastChild},get childElementCount(){return this.__shady_childElementCount},get children(){return this.__shady_children},get firstElementChild(){return this.__shady_firstElementChild},get lastElementChild(){return this.__shady_lastElementChild},get shadowRoot(){return this.__shady_shadowRoot}}),Za=z({get textContent(){return this.__shady_textContent},set textContent(a){this.__shady_textContent=\na},get innerHTML(){return this.__shady_innerHTML},set innerHTML(a){return this.__shady_innerHTML=a}}),$a=z({get parentElement(){return this.__shady_parentElement},get parentNode(){return this.__shady_parentNode},get nextSibling(){return this.__shady_nextSibling},get previousSibling(){return this.__shady_previousSibling},get nextElementSibling(){return this.__shady_nextElementSibling},get previousElementSibling(){return this.__shady_previousElementSibling},get className(){return this.__shady_className},\nset className(a){return this.__shady_className=a}});function ab(a){for(var b in a){var c=a[b];c&&(c.enumerable=!1)}}ab(Ya);ab(Za);ab($a);var bb=t.h||!0===t.j,cb=bb?function(){}:function(a){var b=p(a);b.sa||(b.sa=!0,va(a,$a))},db=bb?function(){}:function(a){var b=p(a);b.ra||(b.ra=!0,va(a,Ya),window.customElements&&window.customElements.polyfillWrapFlushCallback&&!t.j||va(a,Za))};var eb=\"__eventWrappers\"+Date.now(),fb=function(){var a=Object.getOwnPropertyDescriptor(Event.prototype,\"composed\");return a?function(b){return a.get.call(b)}:null}(),gb=function(){function a(){}var b=!1,c={get capture(){b=!0;return!1}};window.addEventListener(\"test\",a,c);window.removeEventListener(\"test\",a,c);return b}();function hb(a){if(a&&\"object\"===typeof a){var b=!!a.capture;var c=!!a.once;var d=!!a.passive;var e=a.A}else b=!!a,d=c=!1;return{oa:e,capture:b,once:c,passive:d,na:gb?a:b}}\nvar ib={blur:!0,focus:!0,focusin:!0,focusout:!0,click:!0,dblclick:!0,mousedown:!0,mouseenter:!0,mouseleave:!0,mousemove:!0,mouseout:!0,mouseover:!0,mouseup:!0,wheel:!0,beforeinput:!0,input:!0,keydown:!0,keyup:!0,compositionstart:!0,compositionupdate:!0,compositionend:!0,touchstart:!0,touchend:!0,touchmove:!0,touchcancel:!0,pointerover:!0,pointerenter:!0,pointerdown:!0,pointermove:!0,pointerup:!0,pointercancel:!0,pointerout:!0,pointerleave:!0,gotpointercapture:!0,lostpointercapture:!0,dragstart:!0,\ndrag:!0,dragenter:!0,dragleave:!0,dragover:!0,drop:!0,dragend:!0,DOMActivate:!0,DOMFocusIn:!0,DOMFocusOut:!0,keypress:!0},jb={DOMAttrModified:!0,DOMAttributeNameChanged:!0,DOMCharacterDataModified:!0,DOMElementNameChanged:!0,DOMNodeInserted:!0,DOMNodeInsertedIntoDocument:!0,DOMNodeRemoved:!0,DOMNodeRemovedFromDocument:!0,DOMSubtreeModified:!0};function kb(a){return a instanceof Node?a.__shady_getRootNode():a}\nfunction lb(a,b){var c=[],d=a;for(a=kb(a);d;)c.push(d),d.__shady_assignedSlot?d=d.__shady_assignedSlot:d.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&d.host&&(b||d!==a)?d=d.host:d=d.__shady_parentNode;c[c.length-1]===document&&c.push(window);return c}function mb(a){a.__composedPath||(a.__composedPath=lb(a.target,!0));return a.__composedPath}function nb(a,b){if(!v)return a;a=lb(a,!0);for(var c=0,d,e=void 0,f,g=void 0;c<b.length;c++)if(d=b[c],f=kb(d),f!==e&&(g=a.indexOf(f),e=f),!v(f)||-1<g)return d}\nfunction ob(a){function b(c,d){c=new a(c,d);c.__composed=d&&!!d.composed;return c}b.__proto__=a;b.prototype=a.prototype;return b}var pb={focus:!0,blur:!0};function qb(a){return a.__target!==a.target||a.__relatedTarget!==a.relatedTarget}function rb(a,b,c){if(c=b.__handlers&&b.__handlers[a.type]&&b.__handlers[a.type][c])for(var d=0,e;(e=c[d])&&(!qb(a)||a.target!==a.relatedTarget)&&(e.call(b,a),!a.__immediatePropagationStopped);d++);}\nfunction sb(a){var b=a.composedPath();Object.defineProperty(a,\"currentTarget\",{get:function(){return d},configurable:!0});for(var c=b.length-1;0<=c;c--){var d=b[c];rb(a,d,\"capture\");if(a.X)return}Object.defineProperty(a,\"eventPhase\",{get:function(){return Event.AT_TARGET}});var e;for(c=0;c<b.length;c++){d=b[c];var f=r(d);f=f&&f.root;if(0===c||f&&f===e)if(rb(a,d,\"bubble\"),d!==window&&(e=d.__shady_getRootNode()),a.X)break}}\nfunction tb(a,b,c,d,e,f){for(var g=0;g<a.length;g++){var h=a[g],k=h.type,l=h.capture,m=h.once,q=h.passive;if(b===h.node&&c===k&&d===l&&e===m&&f===q)return g}return-1}function ub(a){Aa();return this.__shady_native_dispatchEvent(a)}\nfunction vb(a,b,c){var d=hb(c),e=d.capture,f=d.once,g=d.passive,h=d.oa;d=d.na;if(b){var k=typeof b;if(\"function\"===k||\"object\"===k)if(\"object\"!==k||b.handleEvent&&\"function\"===typeof b.handleEvent){if(jb[a])return this.__shady_native_addEventListener(a,b,d);var l=h||this;if(h=b[eb]){if(-1<tb(h,l,a,e,f,g))return}else b[eb]=[];h=function(m){f&&this.__shady_removeEventListener(a,b,c);m.__target||wb(m);if(l!==this){var q=Object.getOwnPropertyDescriptor(m,\"currentTarget\");Object.defineProperty(m,\"currentTarget\",\n{get:function(){return l},configurable:!0})}m.__previousCurrentTarget=m.currentTarget;if(!v(l)&&\"slot\"!==l.localName||-1!=m.composedPath().indexOf(l))if(m.composed||-1<m.composedPath().indexOf(l))if(qb(m)&&m.target===m.relatedTarget)m.eventPhase===Event.BUBBLING_PHASE&&m.stopImmediatePropagation();else if(m.eventPhase===Event.CAPTURING_PHASE||m.bubbles||m.target===l||l instanceof Window){var x=\"function\"===k?b.call(l,m):b.handleEvent&&b.handleEvent(m);l!==this&&(q?(Object.defineProperty(m,\"currentTarget\",\nq),q=null):delete m.currentTarget);return x}};b[eb].push({node:l,type:a,capture:e,once:f,passive:g,Oa:h});pb[a]?(this.__handlers=this.__handlers||{},this.__handlers[a]=this.__handlers[a]||{capture:[],bubble:[]},this.__handlers[a][e?\"capture\":\"bubble\"].push(h)):this.__shady_native_addEventListener(a,h,d)}}}\nfunction xb(a,b,c){if(b){var d=hb(c);c=d.capture;var e=d.once,f=d.passive,g=d.oa;d=d.na;if(jb[a])return this.__shady_native_removeEventListener(a,b,d);var h=g||this;g=void 0;var k=null;try{k=b[eb]}catch(l){}k&&(e=tb(k,h,a,c,e,f),-1<e&&(g=k.splice(e,1)[0].Oa,k.length||(b[eb]=void 0)));this.__shady_native_removeEventListener(a,g||b,d);g&&pb[a]&&this.__handlers&&this.__handlers[a]&&(a=this.__handlers[a][c?\"capture\":\"bubble\"],b=a.indexOf(g),-1<b&&a.splice(b,1))}}\nfunction yb(){for(var a in pb)window.__shady_native_addEventListener(a,function(b){b.__target||(wb(b),sb(b))},!0)}\nvar zb=z({get composed(){void 0===this.__composed&&(fb?this.__composed=\"focusin\"===this.type||\"focusout\"===this.type||fb(this):!1!==this.isTrusted&&(this.__composed=ib[this.type]));return this.__composed||!1},composedPath:function(){this.__composedPath||(this.__composedPath=lb(this.__target,this.composed));return this.__composedPath},get target(){return nb(this.currentTarget||this.__previousCurrentTarget,this.composedPath())},get relatedTarget(){if(!this.__relatedTarget)return null;this.__relatedTargetComposedPath||\n(this.__relatedTargetComposedPath=lb(this.__relatedTarget,!0));return nb(this.currentTarget||this.__previousCurrentTarget,this.__relatedTargetComposedPath)},stopPropagation:function(){Event.prototype.stopPropagation.call(this);this.X=!0},stopImmediatePropagation:function(){Event.prototype.stopImmediatePropagation.call(this);this.X=this.__immediatePropagationStopped=!0}});\nfunction wb(a){a.__target=a.target;a.__relatedTarget=a.relatedTarget;if(t.h){var b=Object.getPrototypeOf(a);if(!b.hasOwnProperty(\"__shady_patchedProto\")){var c=Object.create(b);c.__shady_sourceProto=b;y(c,zb);b.__shady_patchedProto=c}a.__proto__=b.__shady_patchedProto}else y(a,zb)}var Ab=ob(Event),Bb=ob(CustomEvent),Cb=ob(MouseEvent);\nfunction Db(){if(!fb&&Object.getOwnPropertyDescriptor(Event.prototype,\"isTrusted\")){var a=function(){var b=new MouseEvent(\"click\",{bubbles:!0,cancelable:!0,composed:!0});this.__shady_dispatchEvent(b)};Element.prototype.click?Element.prototype.click=a:HTMLElement.prototype.click&&(HTMLElement.prototype.click=a)}}\nvar Eb=Object.getOwnPropertyNames(Element.prototype).filter(function(a){return\"on\"===a.substring(0,2)}),Fb=Object.getOwnPropertyNames(HTMLElement.prototype).filter(function(a){return\"on\"===a.substring(0,2)});function Gb(a){return{set:function(b){var c=p(this),d=a.substring(2);c.w||(c.w={});c.w[a]&&this.removeEventListener(d,c.w[a]);this.__shady_addEventListener(d,b);c.w[a]=b},get:function(){var b=r(this);return b&&b.w&&b.w[a]},configurable:!0}};function Hb(a,b){return{index:a,J:[],R:b}}\nfunction Ib(a,b,c,d){var e=0,f=0,g=0,h=0,k=Math.min(b-e,d-f);if(0==e&&0==f)a:{for(g=0;g<k;g++)if(a[g]!==c[g])break a;g=k}if(b==a.length&&d==c.length){h=a.length;for(var l=c.length,m=0;m<k-g&&Jb(a[--h],c[--l]);)m++;h=m}e+=g;f+=g;b-=h;d-=h;if(0==b-e&&0==d-f)return[];if(e==b){for(b=Hb(e,0);f<d;)b.J.push(c[f++]);return[b]}if(f==d)return[Hb(e,b-e)];k=e;g=f;d=d-g+1;h=b-k+1;b=Array(d);for(l=0;l<d;l++)b[l]=Array(h),b[l][0]=l;for(l=0;l<h;l++)b[0][l]=l;for(l=1;l<d;l++)for(m=1;m<h;m++)if(a[k+m-1]===c[g+l-1])b[l][m]=\nb[l-1][m-1];else{var q=b[l-1][m]+1,x=b[l][m-1]+1;b[l][m]=q<x?q:x}k=b.length-1;g=b[0].length-1;d=b[k][g];for(a=[];0<k||0<g;)0==k?(a.push(2),g--):0==g?(a.push(3),k--):(h=b[k-1][g-1],l=b[k-1][g],m=b[k][g-1],q=l<m?l<h?l:h:m<h?m:h,q==h?(h==d?a.push(0):(a.push(1),d=h),k--,g--):q==l?(a.push(3),k--,d=l):(a.push(2),g--,d=m));a.reverse();b=void 0;k=[];for(g=0;g<a.length;g++)switch(a[g]){case 0:b&&(k.push(b),b=void 0);e++;f++;break;case 1:b||(b=Hb(e,0));b.R++;e++;b.J.push(c[f]);f++;break;case 2:b||(b=Hb(e,0));\nb.R++;e++;break;case 3:b||(b=Hb(e,0)),b.J.push(c[f]),f++}b&&k.push(b);return k}function Jb(a,b){return a===b};var Kb=z({dispatchEvent:ub,addEventListener:vb,removeEventListener:xb});var Lb=null;function D(){Lb||(Lb=window.ShadyCSS&&window.ShadyCSS.ScopingShim);return Lb||null}function Mb(a,b,c){var d=D();return d&&\"class\"===b?(d.setElementClass(a,c),!0):!1}function Nb(a,b){var c=D();c&&c.unscopeNode(a,b)}function Ob(a,b){var c=D();if(!c)return!0;if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE){c=!0;for(a=a.__shady_firstChild;a;a=a.__shady_nextSibling)c=c&&Ob(a,b);return c}return a.nodeType!==Node.ELEMENT_NODE?!0:c.currentScopeForNode(a)===b}\nfunction Pb(a){if(a.nodeType!==Node.ELEMENT_NODE)return\"\";var b=D();return b?b.currentScopeForNode(a):\"\"}function Qb(a,b){if(a)for(a.nodeType===Node.ELEMENT_NODE&&b(a),a=a.__shady_firstChild;a;a=a.__shady_nextSibling)a.nodeType===Node.ELEMENT_NODE&&Qb(a,b)};var Rb=window.document,Sb=t.W,Tb=Object.getOwnPropertyDescriptor(Node.prototype,\"isConnected\"),Ub=Tb&&Tb.get;function Vb(a){for(var b;b=a.__shady_firstChild;)a.__shady_removeChild(b)}function Wb(a){var b=r(a);if(b&&void 0!==b.V)for(b=a.__shady_firstChild;b;b=b.__shady_nextSibling)Wb(b);if(a=r(a))a.V=void 0}function Xb(a){var b=a;if(a&&\"slot\"===a.localName){var c=r(a);(c=c&&c.G)&&(b=c.length?c[0]:Xb(a.__shady_nextSibling))}return b}\nfunction Yb(a,b,c){if(a=(a=r(a))&&a.I){if(b)if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(var d=0,e=b.childNodes.length;d<e;d++)a.addedNodes.push(b.childNodes[d]);else a.addedNodes.push(b);c&&a.removedNodes.push(c);Ca(a)}}\nvar cc=z({get parentNode(){var a=r(this);a=a&&a.parentNode;return void 0!==a?a:this.__shady_native_parentNode},get firstChild(){var a=r(this);a=a&&a.firstChild;return void 0!==a?a:this.__shady_native_firstChild},get lastChild(){var a=r(this);a=a&&a.lastChild;return void 0!==a?a:this.__shady_native_lastChild},get nextSibling(){var a=r(this);a=a&&a.nextSibling;return void 0!==a?a:this.__shady_native_nextSibling},get previousSibling(){var a=r(this);a=a&&a.previousSibling;return void 0!==a?a:this.__shady_native_previousSibling},\nget childNodes(){if(u(this)){var a=r(this);if(!a.childNodes){a.childNodes=[];for(var b=this.__shady_firstChild;b;b=b.__shady_nextSibling)a.childNodes.push(b)}var c=a.childNodes}else c=this.__shady_native_childNodes;c.item=function(d){return c[d]};return c},get parentElement(){var a=r(this);(a=a&&a.parentNode)&&a.nodeType!==Node.ELEMENT_NODE&&(a=null);return void 0!==a?a:this.__shady_native_parentElement},get isConnected(){if(Ub&&Ub.call(this))return!0;if(this.nodeType==Node.DOCUMENT_FRAGMENT_NODE)return!1;\nvar a=this.ownerDocument;if(pa){if(a.__shady_native_contains(this))return!0}else if(a.documentElement&&a.documentElement.__shady_native_contains(this))return!0;for(a=this;a&&!(a instanceof Document);)a=a.__shady_parentNode||(v(a)?a.host:void 0);return!!(a&&a instanceof Document)},get textContent(){if(u(this)){for(var a=[],b=this.__shady_firstChild;b;b=b.__shady_nextSibling)b.nodeType!==Node.COMMENT_NODE&&a.push(b.__shady_textContent);return a.join(\"\")}return this.__shady_native_textContent},set textContent(a){if(\"undefined\"===\ntypeof a||null===a)a=\"\";switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:if(!u(this)&&t.h){var b=this.__shady_firstChild;(b!=this.__shady_lastChild||b&&b.nodeType!=Node.TEXT_NODE)&&Vb(this);this.__shady_native_textContent=a}else Vb(this),(0<a.length||this.nodeType===Node.ELEMENT_NODE)&&this.__shady_insertBefore(document.createTextNode(a));break;default:this.nodeValue=a}},insertBefore:function(a,b){if(this.ownerDocument!==Rb&&a.ownerDocument!==Rb)return this.__shady_native_insertBefore(a,\nb),a;if(a===this)throw Error(\"Failed to execute 'appendChild' on 'Node': The new child element contains the parent.\");if(b){var c=r(b);c=c&&c.parentNode;if(void 0!==c&&c!==this||void 0===c&&b.__shady_native_parentNode!==this)throw Error(\"Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.\");}if(b===a)return a;Yb(this,a);var d=[],e=(c=E(this))?c.host.localName:Pb(this),f=a.__shady_parentNode;if(f){var g=Pb(a);var h=!!c||!E(a)||\nSb&&void 0!==this.__noInsertionPoint;f.__shady_removeChild(a,h)}f=!0;var k=(!Sb||void 0===a.__noInsertionPoint&&void 0===this.__noInsertionPoint)&&!Ob(a,e),l=c&&!a.__noInsertionPoint&&(!Sb||a.nodeType===Node.DOCUMENT_FRAGMENT_NODE);if(l||k)k&&(g=g||Pb(a)),Qb(a,function(m){l&&\"slot\"===m.localName&&d.push(m);if(k){var q=g;D()&&(q&&Nb(m,q),(q=D())&&q.scopeNode(m,e))}});d.length&&(Zb(c),c.c.push.apply(c.c,d instanceof Array?d:ca(ba(d))),F(c));u(this)&&($b(a,this,b),h=r(this),h.root?(f=!1,ha(this)&&F(h.root)):\nc&&\"slot\"===this.localName&&(f=!1,F(c)));f?(c=v(this)?this.host:this,b?(b=Xb(b),c.__shady_native_insertBefore(a,b)):c.__shady_native_appendChild(a)):a.ownerDocument!==this.ownerDocument&&this.ownerDocument.adoptNode(a);return a},appendChild:function(a){if(this!=a||!v(a))return this.__shady_insertBefore(a)},removeChild:function(a,b){b=void 0===b?!1:b;if(this.ownerDocument!==Rb)return this.__shady_native_removeChild(a);if(a.__shady_parentNode!==this)throw Error(\"The node to be removed is not a child of this node: \"+\na);Yb(this,null,a);var c=E(a),d=c&&ac(c,a),e=r(this);if(u(this)&&(bc(a,this),ha(this))){F(e.root);var f=!0}if(D()&&!b&&c&&a.nodeType!==Node.TEXT_NODE){var g=Pb(a);Qb(a,function(h){Nb(h,g)})}Wb(a);c&&((b=\"slot\"===this.localName)&&(f=!0),(d||b)&&F(c));f||(f=v(this)?this.host:this,(!e.root&&\"slot\"!==a.localName||f===a.__shady_native_parentNode)&&f.__shady_native_removeChild(a));return a},replaceChild:function(a,b){this.__shady_insertBefore(a,b);this.__shady_removeChild(b);return a},cloneNode:function(a){if(\"template\"==\nthis.localName)return this.__shady_native_cloneNode(a);var b=this.__shady_native_cloneNode(!1);if(a&&b.nodeType!==Node.ATTRIBUTE_NODE){a=this.__shady_firstChild;for(var c;a;a=a.__shady_nextSibling)c=a.__shady_cloneNode(!0),b.__shady_appendChild(c)}return b},getRootNode:function(a){if(this&&this.nodeType){var b=p(this),c=b.V;void 0===c&&(v(this)?(c=this,b.V=c):(c=(c=this.__shady_parentNode)?c.__shady_getRootNode(a):this,document.documentElement.__shady_native_contains(this)&&(b.V=c)));return c}},contains:function(a){return qa(this,\na)}});var ec=z({get assignedSlot(){var a=this.__shady_parentNode;(a=a&&a.__shady_shadowRoot)&&dc(a);return(a=r(this))&&a.assignedSlot||null}});function fc(a,b,c){var d=[];gc(a,b,c,d);return d}function gc(a,b,c,d){for(a=a.__shady_firstChild;a;a=a.__shady_nextSibling){var e;if(e=a.nodeType===Node.ELEMENT_NODE){e=a;var f=b,g=c,h=d,k=f(e);k&&h.push(e);g&&g(k)?e=k:(gc(e,f,g,h),e=void 0)}if(e)break}}\nvar G=z({get firstElementChild(){var a=r(this);if(a&&void 0!==a.firstChild){for(a=this.__shady_firstChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__shady_nextSibling;return a}return this.__shady_native_firstElementChild},get lastElementChild(){var a=r(this);if(a&&void 0!==a.lastChild){for(a=this.__shady_lastChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__shady_previousSibling;return a}return this.__shady_native_lastElementChild},get children(){return u(this)?ra(Array.prototype.filter.call(ta(this),\nfunction(a){return a.nodeType===Node.ELEMENT_NODE})):this.__shady_native_children},get childElementCount(){var a=this.__shady_children;return a?a.length:0}}),hc=z({querySelector:function(a){return fc(this,function(b){return ja.call(b,a)},function(b){return!!b})[0]||null},querySelectorAll:function(a,b){if(b){b=Array.prototype.slice.call(this.__shady_native_querySelectorAll(a));var c=this.__shady_getRootNode();return ra(b.filter(function(d){return d.__shady_getRootNode()==c}))}return ra(fc(this,function(d){return ja.call(d,\na)}))}}),ic=t.W&&!t.j?wa({},G):G;wa(G,hc);var jc=window.document;function kc(a,b){if(\"slot\"===b)a=a.__shady_parentNode,ha(a)&&F(r(a).root);else if(\"slot\"===a.localName&&\"name\"===b&&(b=E(a))){if(b.a){lc(b);var c=a.ta,d=mc(a);if(d!==c){c=b.b[c];var e=c.indexOf(a);0<=e&&c.splice(e,1);c=b.b[d]||(b.b[d]=[]);c.push(a);1<c.length&&(b.b[d]=nc(c))}}F(b)}}\nvar oc=z({get previousElementSibling(){var a=r(this);if(a&&void 0!==a.previousSibling){for(a=this.__shady_previousSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__shady_previousSibling;return a}return this.__shady_native_previousElementSibling},get nextElementSibling(){var a=r(this);if(a&&void 0!==a.nextSibling){for(a=this.__shady_nextSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.__shady_nextSibling;return a}return this.__shady_native_nextElementSibling},get slot(){return this.getAttribute(\"slot\")},\nset slot(a){this.__shady_setAttribute(\"slot\",a)},get className(){return this.getAttribute(\"class\")||\"\"},set className(a){this.__shady_setAttribute(\"class\",a)},setAttribute:function(a,b){this.ownerDocument!==jc?this.__shady_native_setAttribute(a,b):Mb(this,a,b)||(this.__shady_native_setAttribute(a,b),kc(this,a))},removeAttribute:function(a){this.ownerDocument!==jc?this.__shady_native_removeAttribute(a):Mb(this,a,\"\")?\"\"===this.getAttribute(a)&&this.__shady_native_removeAttribute(a):(this.__shady_native_removeAttribute(a),\nkc(this,a))}});t.W||Eb.forEach(function(a){oc[a]=Gb(a)});\nvar tc=z({attachShadow:function(a){if(!this)throw Error(\"Must provide a host.\");if(!a)throw Error(\"Not enough arguments.\");if(a.shadyUpgradeFragment&&!t.qa){var b=a.shadyUpgradeFragment;b.__proto__=ShadowRoot.prototype;pc(b,this,a);qc(b,b);a=b.__noInsertionPoint?null:b.querySelectorAll(\"slot\");b.__noInsertionPoint=void 0;if(a&&a.length){var c=b;Zb(c);c.c.push.apply(c.c,a instanceof Array?a:ca(ba(a)));F(b)}b.host.__shady_native_appendChild(b)}else b=new rc(sc,this,a);return this.__CE_shadowRoot=b},\nget shadowRoot(){var a=r(this);return a&&a.Fa||null}});wa(oc,tc);var uc=document.implementation.createHTMLDocument(\"inert\"),vc=z({get innerHTML(){return u(this)?Ma(\"template\"===this.localName?this.content:this,ta):this.__shady_native_innerHTML},set innerHTML(a){if(\"template\"===this.localName)this.__shady_native_innerHTML=a;else{Vb(this);var b=this.localName||\"div\";b=this.namespaceURI&&this.namespaceURI!==uc.namespaceURI?uc.createElementNS(this.namespaceURI,b):uc.createElement(b);for(t.h?b.__shady_native_innerHTML=a:b.innerHTML=a;a=b.__shady_firstChild;)this.__shady_insertBefore(a)}}});var wc=z({blur:function(){var a=r(this);(a=(a=a&&a.root)&&a.activeElement)?a.__shady_blur():this.__shady_native_blur()}});t.W||Fb.forEach(function(a){wc[a]=Gb(a)});var xc=z({assignedNodes:function(a){if(\"slot\"===this.localName){var b=this.__shady_getRootNode();b&&v(b)&&dc(b);return(b=r(this))?(a&&a.flatten?b.G:b.assignedNodes)||[]:[]}},addEventListener:function(a,b,c){if(\"slot\"!==this.localName||\"slotchange\"===a)vb.call(this,a,b,c);else{\"object\"!==typeof c&&(c={capture:!!c});var d=this.__shady_parentNode;if(!d)throw Error(\"ShadyDOM cannot attach event to slot unless it has a `parentNode`\");c.A=this;d.__shady_addEventListener(a,b,c)}},removeEventListener:function(a,\nb,c){if(\"slot\"!==this.localName||\"slotchange\"===a)xb.call(this,a,b,c);else{\"object\"!==typeof c&&(c={capture:!!c});var d=this.__shady_parentNode;if(!d)throw Error(\"ShadyDOM cannot attach event to slot unless it has a `parentNode`\");c.A=this;d.__shady_removeEventListener(a,b,c)}}});var yc=z({getElementById:function(a){return\"\"===a?null:fc(this,function(b){return b.id==a},function(b){return!!b})[0]||null}});var zc=z({get activeElement(){var a=t.h?document.__shady_native_activeElement:document.activeElement;if(!a||!a.nodeType)return null;var b=!!v(this);if(!(this===document||b&&this.host!==a&&this.host.__shady_native_contains(a)))return null;for(b=E(a);b&&b!==this;)a=b.host,b=E(a);return this===document?b?null:a:b===this?a:null}});var Ac=window.document,Bc=z({importNode:function(a,b){if(a.ownerDocument!==Ac||\"template\"===a.localName)return this.__shady_native_importNode(a,b);var c=this.__shady_native_importNode(a,!1);if(b)for(a=a.__shady_firstChild;a;a=a.__shady_nextSibling)b=this.__shady_importNode(a,!0),c.__shady_appendChild(b);return c}});var Cc=z({dispatchEvent:ub,addEventListener:vb.bind(window),removeEventListener:xb.bind(window)});var H={};Object.getOwnPropertyDescriptor(HTMLElement.prototype,\"parentElement\")&&(H.parentElement=cc.parentElement);Object.getOwnPropertyDescriptor(HTMLElement.prototype,\"contains\")&&(H.contains=cc.contains);Object.getOwnPropertyDescriptor(HTMLElement.prototype,\"children\")&&(H.children=G.children);Object.getOwnPropertyDescriptor(HTMLElement.prototype,\"innerHTML\")&&(H.innerHTML=vc.innerHTML);Object.getOwnPropertyDescriptor(HTMLElement.prototype,\"className\")&&(H.className=oc.className);\nvar I={EventTarget:[Kb],Node:[cc,window.EventTarget?null:Kb],Text:[ec],Comment:[ec],CDATASection:[ec],ProcessingInstruction:[ec],Element:[oc,G,ec,!t.h||\"innerHTML\"in Element.prototype?vc:null,window.HTMLSlotElement?null:xc],HTMLElement:[wc,H],HTMLSlotElement:[xc],DocumentFragment:[ic,yc],Document:[Bc,ic,yc,zc],Window:[Cc]},Dc=t.h?null:[\"innerHTML\",\"textContent\"];function J(a,b,c,d){b.forEach(function(e){return a&&e&&y(a,e,c,d)})}\nfunction Ec(a){var b=a?null:Dc,c;for(c in I)J(window[c]&&window[c].prototype,I[c],a,b)}[\"Text\",\"Comment\",\"CDATASection\",\"ProcessingInstruction\"].forEach(function(a){var b=window[a],c=Object.create(b.prototype);c.__shady_protoIsPatched=!0;J(c,I.EventTarget);J(c,I.Node);I[a]&&J(c,I[a]);b.prototype.__shady_patchedProto=c});function Fc(a){a.__shady_protoIsPatched=!0;J(a,I.EventTarget);J(a,I.Node);J(a,I.Element);J(a,I.HTMLElement);J(a,I.HTMLSlotElement);return a};var Gc=t.ea,Hc=t.h;function Ic(a,b){if(Gc&&!a.__shady_protoIsPatched&&!v(a)){var c=Object.getPrototypeOf(a),d=c.hasOwnProperty(\"__shady_patchedProto\")&&c.__shady_patchedProto;d||(d=Object.create(c),Fc(d),c.__shady_patchedProto=d);Object.setPrototypeOf(a,d)}Hc||(1===b?cb(a):2===b&&db(a))}\nfunction Jc(a,b,c,d){Ic(a,1);d=d||null;var e=p(a),f=d?p(d):null;e.previousSibling=d?f.previousSibling:b.__shady_lastChild;if(f=r(e.previousSibling))f.nextSibling=a;if(f=r(e.nextSibling=d))f.previousSibling=a;e.parentNode=b;d?d===c.firstChild&&(c.firstChild=a):(c.lastChild=a,c.firstChild||(c.firstChild=a));c.childNodes=null}\nfunction $b(a,b,c){Ic(b,2);var d=p(b);void 0!==d.firstChild&&(d.childNodes=null);if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE)for(a=a.__shady_native_firstChild;a;a=a.__shady_native_nextSibling)Jc(a,b,d,c);else Jc(a,b,d,c)}\nfunction bc(a,b){var c=p(a);b=p(b);a===b.firstChild&&(b.firstChild=c.nextSibling);a===b.lastChild&&(b.lastChild=c.previousSibling);a=c.previousSibling;var d=c.nextSibling;a&&(p(a).nextSibling=d);d&&(p(d).previousSibling=a);c.parentNode=c.previousSibling=c.nextSibling=void 0;void 0!==b.childNodes&&(b.childNodes=null)}\nfunction qc(a,b){var c=p(a);if(b||void 0===c.firstChild){c.childNodes=null;var d=c.firstChild=a.__shady_native_firstChild;c.lastChild=a.__shady_native_lastChild;Ic(a,2);c=d;for(d=void 0;c;c=c.__shady_native_nextSibling){var e=p(c);e.parentNode=b||a;e.nextSibling=c.__shady_native_nextSibling;e.previousSibling=d||null;d=c;Ic(c,1)}}};var Kc=z({addEventListener:function(a,b,c){\"object\"!==typeof c&&(c={capture:!!c});c.A=c.A||this;this.host.__shady_addEventListener(a,b,c)},removeEventListener:function(a,b,c){\"object\"!==typeof c&&(c={capture:!!c});c.A=c.A||this;this.host.__shady_removeEventListener(a,b,c)}});function Lc(a,b){y(a,Kc,b);y(a,zc,b);y(a,vc,b);y(a,G,b);t.j&&!b?(y(a,cc,b),y(a,yc,b)):t.h||(y(a,$a),y(a,Ya),y(a,Za))};var sc={},K=t.deferConnectionCallbacks&&\"loading\"===document.readyState,Mc;function Nc(a){var b=[];do b.unshift(a);while(a=a.__shady_parentNode);return b}function rc(a,b,c){if(a!==sc)throw new TypeError(\"Illegal constructor\");this.a=null;pc(this,b,c)}\nfunction pc(a,b,c){a.host=b;a.mode=c&&c.mode;qc(a.host);b=p(a.host);b.root=a;b.Fa=\"closed\"!==a.mode?a:null;b=p(a);b.firstChild=b.lastChild=b.parentNode=b.nextSibling=b.previousSibling=null;if(t.preferPerformance)for(;b=a.host.__shady_native_firstChild;)a.host.__shady_native_removeChild(b);else F(a)}function F(a){a.F||(a.F=!0,za(function(){return dc(a)}))}\nfunction dc(a){var b;if(b=a.F){for(var c;a;)a:{a.F&&(c=a),b=a;a=b.host.__shady_getRootNode();if(v(a)&&(b=r(b.host))&&0<b.L)break a;a=void 0}b=c}(c=b)&&c._renderSelf()}\nrc.prototype._renderSelf=function(){var a=K;K=!0;this.F=!1;if(this.a){lc(this);for(var b=0,c;b<this.a.length;b++){c=this.a[b];var d=r(c),e=d.assignedNodes;d.assignedNodes=[];d.G=[];if(d.ja=e)for(d=0;d<e.length;d++){var f=r(e[d]);f.Z=f.assignedSlot;f.assignedSlot===c&&(f.assignedSlot=null)}}for(b=this.host.__shady_firstChild;b;b=b.__shady_nextSibling)Oc(this,b);for(b=0;b<this.a.length;b++){c=this.a[b];e=r(c);if(!e.assignedNodes.length)for(d=c.__shady_firstChild;d;d=d.__shady_nextSibling)Oc(this,d,\nc);(d=(d=r(c.__shady_parentNode))&&d.root)&&(ia(d)||d.F)&&d._renderSelf();Pc(this,e.G,e.assignedNodes);if(d=e.ja){for(f=0;f<d.length;f++)r(d[f]).Z=null;e.ja=null;d.length>e.assignedNodes.length&&(e.ba=!0)}e.ba&&(e.ba=!1,Qc(this,c))}c=this.a;b=[];for(e=0;e<c.length;e++)d=c[e].__shady_parentNode,(f=r(d))&&f.root||!(0>b.indexOf(d))||b.push(d);for(c=0;c<b.length;c++){f=b[c];e=f===this?this.host:f;d=[];for(f=f.__shady_firstChild;f;f=f.__shady_nextSibling)if(\"slot\"==f.localName)for(var g=r(f).G,h=0;h<g.length;h++)d.push(g[h]);\nelse d.push(f);f=sa(e);g=Ib(d,d.length,f,f.length);for(var k=h=0,l=void 0;h<g.length&&(l=g[h]);h++){for(var m=0,q=void 0;m<l.J.length&&(q=l.J[m]);m++)q.__shady_native_parentNode===e&&e.__shady_native_removeChild(q),f.splice(l.index+k,1);k-=l.R}k=0;for(l=void 0;k<g.length&&(l=g[k]);k++)for(h=f[l.index],m=l.index;m<l.index+l.R;m++)q=d[m],e.__shady_native_insertBefore(q,h),f.splice(m,0,q)}}if(!t.preferPerformance&&!this.ia)for(b=this.host.__shady_firstChild;b;b=b.__shady_nextSibling)c=r(b),b.__shady_native_parentNode!==\nthis.host||\"slot\"!==b.localName&&c.assignedSlot||this.host.__shady_native_removeChild(b);this.ia=!0;K=a;Mc&&Mc()};function Oc(a,b,c){var d=p(b),e=d.Z;d.Z=null;c||(c=(a=a.b[b.__shady_slot||\"__catchall\"])&&a[0]);c?(p(c).assignedNodes.push(b),d.assignedSlot=c):d.assignedSlot=void 0;e!==d.assignedSlot&&d.assignedSlot&&(p(d.assignedSlot).ba=!0)}function Pc(a,b,c){for(var d=0,e=void 0;d<c.length&&(e=c[d]);d++)if(\"slot\"==e.localName){var f=r(e).assignedNodes;f&&f.length&&Pc(a,b,f)}else b.push(c[d])}\nfunction Qc(a,b){b.__shady_native_dispatchEvent(new Event(\"slotchange\"));b=r(b);b.assignedSlot&&Qc(a,b.assignedSlot)}function Zb(a){a.c=a.c||[];a.a=a.a||[];a.b=a.b||{}}function lc(a){if(a.c&&a.c.length){for(var b=a.c,c,d=0;d<b.length;d++){var e=b[d];qc(e);var f=e.__shady_parentNode;qc(f);f=r(f);f.L=(f.L||0)+1;f=mc(e);a.b[f]?(c=c||{},c[f]=!0,a.b[f].push(e)):a.b[f]=[e];a.a.push(e)}if(c)for(var g in c)a.b[g]=nc(a.b[g]);a.c=[]}}\nfunction mc(a){var b=a.name||a.getAttribute(\"name\")||\"__catchall\";return a.ta=b}function nc(a){return a.sort(function(b,c){b=Nc(b);for(var d=Nc(c),e=0;e<b.length;e++){c=b[e];var f=d[e];if(c!==f)return b=ta(c.__shady_parentNode),b.indexOf(c)-b.indexOf(f)}})}\nfunction ac(a,b){if(a.a){lc(a);var c=a.b,d;for(d in c)for(var e=c[d],f=0;f<e.length;f++){var g=e[f];if(qa(b,g)){e.splice(f,1);var h=a.a.indexOf(g);0<=h&&(a.a.splice(h,1),(h=r(g.__shady_parentNode))&&h.L&&h.L--);f--;g=r(g);if(h=g.G)for(var k=0;k<h.length;k++){var l=h[k],m=l.__shady_native_parentNode;m&&m.__shady_native_removeChild(l)}g.G=[];g.assignedNodes=[];h=!0}}return h}}function ia(a){lc(a);return!(!a.a||!a.a.length)}\n(function(a){a.__proto__=DocumentFragment.prototype;Lc(a,\"__shady_\");Lc(a);Object.defineProperties(a,{nodeType:{value:Node.DOCUMENT_FRAGMENT_NODE,configurable:!0},nodeName:{value:\"#document-fragment\",configurable:!0},nodeValue:{value:null,configurable:!0}});[\"localName\",\"namespaceURI\",\"prefix\"].forEach(function(b){Object.defineProperty(a,b,{value:void 0,configurable:!0})});[\"ownerDocument\",\"baseURI\",\"isConnected\"].forEach(function(b){Object.defineProperty(a,b,{get:function(){return this.host[b]},\nconfigurable:!0})})})(rc.prototype);\nif(window.customElements&&window.customElements.define&&t.ca&&!t.preferPerformance){var Rc=new Map;Mc=function(){var a=[];Rc.forEach(function(d,e){a.push([e,d])});Rc.clear();for(var b=0;b<a.length;b++){var c=a[b][0];a[b][1]?c.__shadydom_connectedCallback():c.__shadydom_disconnectedCallback()}};K&&document.addEventListener(\"readystatechange\",function(){K=!1;Mc()},{once:!0});var Sc=function(a,b,c){var d=0,e=\"__isConnected\"+d++;if(b||c)a.prototype.connectedCallback=a.prototype.__shadydom_connectedCallback=\nfunction(){K?Rc.set(this,!0):this[e]||(this[e]=!0,b&&b.call(this))},a.prototype.disconnectedCallback=a.prototype.__shadydom_disconnectedCallback=function(){K?this.isConnected||Rc.set(this,!1):this[e]&&(this[e]=!1,c&&c.call(this))};return a},Tc=window.customElements.define,Uc=function(a,b){var c=b.prototype.connectedCallback,d=b.prototype.disconnectedCallback;Tc.call(window.customElements,a,Sc(b,c,d));b.prototype.connectedCallback=c;b.prototype.disconnectedCallback=d};window.customElements.define=\nUc;Object.defineProperty(window.CustomElementRegistry.prototype,\"define\",{value:Uc,configurable:!0})}function E(a){a=a.__shady_getRootNode();if(v(a))return a};function Vc(a){this.node=a}n=Vc.prototype;n.addEventListener=function(a,b,c){return this.node.__shady_addEventListener(a,b,c)};n.removeEventListener=function(a,b,c){return this.node.__shady_removeEventListener(a,b,c)};n.appendChild=function(a){return this.node.__shady_appendChild(a)};n.insertBefore=function(a,b){return this.node.__shady_insertBefore(a,b)};n.removeChild=function(a){return this.node.__shady_removeChild(a)};n.replaceChild=function(a,b){return this.node.__shady_replaceChild(a,b)};\nn.cloneNode=function(a){return this.node.__shady_cloneNode(a)};n.getRootNode=function(a){return this.node.__shady_getRootNode(a)};n.contains=function(a){return this.node.__shady_contains(a)};n.dispatchEvent=function(a){return this.node.__shady_dispatchEvent(a)};n.setAttribute=function(a,b){this.node.__shady_setAttribute(a,b)};n.getAttribute=function(a){return this.node.__shady_native_getAttribute(a)};n.removeAttribute=function(a){this.node.__shady_removeAttribute(a)};n.attachShadow=function(a){return this.node.__shady_attachShadow(a)};\nn.focus=function(){this.node.__shady_native_focus()};n.blur=function(){this.node.__shady_blur()};n.importNode=function(a,b){if(this.node.nodeType===Node.DOCUMENT_NODE)return this.node.__shady_importNode(a,b)};n.getElementById=function(a){if(this.node.nodeType===Node.DOCUMENT_NODE)return this.node.__shady_getElementById(a)};n.querySelector=function(a){return this.node.__shady_querySelector(a)};n.querySelectorAll=function(a,b){return this.node.__shady_querySelectorAll(a,b)};\nn.assignedNodes=function(a){if(\"slot\"===this.node.localName)return this.node.__shady_assignedNodes(a)};\nda.Object.defineProperties(Vc.prototype,{activeElement:{configurable:!0,enumerable:!0,get:function(){if(v(this.node)||this.node.nodeType===Node.DOCUMENT_NODE)return this.node.__shady_activeElement}},_activeElement:{configurable:!0,enumerable:!0,get:function(){return this.activeElement}},host:{configurable:!0,enumerable:!0,get:function(){if(v(this.node))return this.node.host}},parentNode:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_parentNode}},firstChild:{configurable:!0,\nenumerable:!0,get:function(){return this.node.__shady_firstChild}},lastChild:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_lastChild}},nextSibling:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_nextSibling}},previousSibling:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_previousSibling}},childNodes:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_childNodes}},parentElement:{configurable:!0,enumerable:!0,\nget:function(){return this.node.__shady_parentElement}},firstElementChild:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_firstElementChild}},lastElementChild:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_lastElementChild}},nextElementSibling:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_nextElementSibling}},previousElementSibling:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_previousElementSibling}},\nchildren:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_children}},childElementCount:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_childElementCount}},shadowRoot:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_shadowRoot}},assignedSlot:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_assignedSlot}},isConnected:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_isConnected}},innerHTML:{configurable:!0,\nenumerable:!0,get:function(){return this.node.__shady_innerHTML},set:function(a){this.node.__shady_innerHTML=a}},textContent:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_textContent},set:function(a){this.node.__shady_textContent=a}},slot:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_slot},set:function(a){this.node.__shady_slot=a}},className:{configurable:!0,enumerable:!0,get:function(){return this.node.__shady_className},set:function(a){return this.node.__shady_className=\na}}});function Wc(a){Object.defineProperty(Vc.prototype,a,{get:function(){return this.node[\"__shady_\"+a]},set:function(b){this.node[\"__shady_\"+a]=b},configurable:!0})}Eb.forEach(function(a){return Wc(a)});Fb.forEach(function(a){return Wc(a)});var Xc=new WeakMap;function Yc(a){if(v(a)||a instanceof Vc)return a;var b=Xc.get(a);b||(b=new Vc(a),Xc.set(a,b));return b};if(t.ca){var Zc=t.h?function(a){return a}:function(a){db(a);cb(a);return a},ShadyDOM={inUse:t.ca,patch:Zc,isShadyRoot:v,enqueue:za,flush:Aa,flushInitial:function(a){!a.ia&&a.F&&dc(a)},settings:t,filterMutations:Fa,observeChildren:Da,unobserveChildren:Ea,deferConnectionCallbacks:t.deferConnectionCallbacks,preferPerformance:t.preferPerformance,handlesDynamicScoping:!0,wrap:t.j?Yc:Zc,wrapIfNeeded:!0===t.j?Yc:function(a){return a},Wrapper:Vc,composedPath:mb,noPatch:t.j,patchOnDemand:t.ea,nativeMethods:Oa,\nnativeTree:Pa,patchElementProto:Fc};window.ShadyDOM=ShadyDOM;Wa();Ec(\"__shady_\");Object.defineProperty(document,\"_activeElement\",zc.activeElement);y(Window.prototype,Cc,\"__shady_\");t.j?t.ea&&y(Element.prototype,tc):(Ec(),Db());yb();window.Event=Ab;window.CustomEvent=Bb;window.MouseEvent=Cb;window.ShadowRoot=rc};/*\n\n Copyright (c) 2020 The Polymer Project Authors. All rights reserved.\n This code may only be used under the BSD style license found at\n http://polymer.github.io/LICENSE.txt The complete set of authors may be found\n at http://polymer.github.io/AUTHORS.txt The complete set of contributors may\n be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by\n Google as part of the polymer project is also subject to an additional IP\n rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n/*\n\n Copyright (c) 2016 The Polymer Project Authors. All rights reserved.\n This code may only be used under the BSD style license found at\n http://polymer.github.io/LICENSE.txt The complete set of authors may be found\n at http://polymer.github.io/AUTHORS.txt The complete set of contributors may\n be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by\n Google as part of the polymer project is also subject to an additional IP\n rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nvar $c=window.Document.prototype.createElement,ad=window.Document.prototype.createElementNS,bd=window.Document.prototype.importNode,cd=window.Document.prototype.prepend,dd=window.Document.prototype.append,ed=window.DocumentFragment.prototype.prepend,fd=window.DocumentFragment.prototype.append,gd=window.Node.prototype.cloneNode,hd=window.Node.prototype.appendChild,id=window.Node.prototype.insertBefore,jd=window.Node.prototype.removeChild,kd=window.Node.prototype.replaceChild,ld=Object.getOwnPropertyDescriptor(window.Node.prototype,\n\"textContent\"),md=window.Element.prototype.attachShadow,nd=Object.getOwnPropertyDescriptor(window.Element.prototype,\"innerHTML\"),od=window.Element.prototype.getAttribute,pd=window.Element.prototype.setAttribute,qd=window.Element.prototype.removeAttribute,rd=window.Element.prototype.getAttributeNS,sd=window.Element.prototype.setAttributeNS,td=window.Element.prototype.removeAttributeNS,ud=window.Element.prototype.insertAdjacentElement,vd=window.Element.prototype.insertAdjacentHTML,wd=window.Element.prototype.prepend,\nxd=window.Element.prototype.append,yd=window.Element.prototype.before,zd=window.Element.prototype.after,Ad=window.Element.prototype.replaceWith,Bd=window.Element.prototype.remove,Cd=window.HTMLElement,Dd=Object.getOwnPropertyDescriptor(window.HTMLElement.prototype,\"innerHTML\"),Ed=window.HTMLElement.prototype.insertAdjacentElement,Fd=window.HTMLElement.prototype.insertAdjacentHTML;var Gd=new Set;\"annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-name missing-glyph\".split(\" \").forEach(function(a){return Gd.add(a)});function Hd(a){var b=Gd.has(a);a=/^[a-z][.0-9_a-z]*-[-.0-9_a-z]*$/.test(a);return!b&&a}var Id=document.contains?document.contains.bind(document):document.documentElement.contains.bind(document.documentElement);\nfunction L(a){var b=a.isConnected;if(void 0!==b)return b;if(Id(a))return!0;for(;a&&!(a.__CE_isImportDocument||a instanceof Document);)a=a.parentNode||(window.ShadowRoot&&a instanceof ShadowRoot?a.host:void 0);return!(!a||!(a.__CE_isImportDocument||a instanceof Document))}function Jd(a){var b=a.children;if(b)return Array.prototype.slice.call(b);b=[];for(a=a.firstChild;a;a=a.nextSibling)a.nodeType===Node.ELEMENT_NODE&&b.push(a);return b}\nfunction Kd(a,b){for(;b&&b!==a&&!b.nextSibling;)b=b.parentNode;return b&&b!==a?b.nextSibling:null}\nfunction Ld(a,b,c){for(var d=a;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d;b(e);var f=e.localName;if(\"link\"===f&&\"import\"===e.getAttribute(\"rel\")){d=e.import;void 0===c&&(c=new Set);if(d instanceof Node&&!c.has(d))for(c.add(d),d=d.firstChild;d;d=d.nextSibling)Ld(d,b,c);d=Kd(a,e);continue}else if(\"template\"===f){d=Kd(a,e);continue}if(e=e.__CE_shadowRoot)for(e=e.firstChild;e;e=e.nextSibling)Ld(e,b,c)}d=d.firstChild?d.firstChild:Kd(a,d)}};function Md(){var a=!(null===M||void 0===M||!M.noDocumentConstructionObserver),b=!(null===M||void 0===M||!M.shadyDomFastWalk);this.H=[];this.a=[];this.C=!1;this.shadyDomFastWalk=b;this.Ma=!a}function Nd(a,b,c,d){var e=window.ShadyDom;if(a.shadyDomFastWalk&&e&&e.inUse){if(b.nodeType===Node.ELEMENT_NODE&&c(b),b.querySelectorAll)for(a=e.nativeMethods.querySelectorAll.call(b,\"*\"),b=0;b<a.length;b++)c(a[b])}else Ld(b,c,d)}function Od(a,b){a.C=!0;a.H.push(b)}function Pd(a,b){a.C=!0;a.a.push(b)}\nfunction Qd(a,b){a.C&&Nd(a,b,function(c){return Rd(a,c)})}function Rd(a,b){if(a.C&&!b.__CE_patched){b.__CE_patched=!0;for(var c=0;c<a.H.length;c++)a.H[c](b);for(c=0;c<a.a.length;c++)a.a[c](b)}}function N(a,b){var c=[];Nd(a,b,function(e){return c.push(e)});for(b=0;b<c.length;b++){var d=c[b];1===d.__CE_state?a.connectedCallback(d):Sd(a,d)}}function O(a,b){var c=[];Nd(a,b,function(e){return c.push(e)});for(b=0;b<c.length;b++){var d=c[b];1===d.__CE_state&&a.disconnectedCallback(d)}}\nfunction P(a,b,c){c=void 0===c?{}:c;var d=c.Na,e=c.upgrade||function(g){return Sd(a,g)},f=[];Nd(a,b,function(g){a.C&&Rd(a,g);if(\"link\"===g.localName&&\"import\"===g.getAttribute(\"rel\")){var h=g.import;h instanceof Node&&(h.__CE_isImportDocument=!0,h.__CE_registry=document.__CE_registry);h&&\"complete\"===h.readyState?h.__CE_documentLoadHandled=!0:g.addEventListener(\"load\",function(){var k=g.import;if(!k.__CE_documentLoadHandled){k.__CE_documentLoadHandled=!0;var l=new Set;d&&(d.forEach(function(m){return l.add(m)}),\nl.delete(k));P(a,k,{Na:l,upgrade:e})}})}else f.push(g)},d);for(b=0;b<f.length;b++)e(f[b])}\nfunction Sd(a,b){try{var c=b.ownerDocument,d=c.__CE_registry;var e=d&&(c.defaultView||c.__CE_isImportDocument)?Td(d,b.localName):void 0;if(e&&void 0===b.__CE_state){e.constructionStack.push(b);try{try{if(new e.constructorFunction!==b)throw Error(\"The custom element constructor did not produce the element being upgraded.\");}finally{e.constructionStack.pop()}}catch(k){throw b.__CE_state=2,k;}b.__CE_state=1;b.__CE_definition=e;if(e.attributeChangedCallback&&b.hasAttributes()){var f=e.observedAttributes;\nfor(e=0;e<f.length;e++){var g=f[e],h=b.getAttribute(g);null!==h&&a.attributeChangedCallback(b,g,null,h,null)}}L(b)&&a.connectedCallback(b)}}catch(k){Ud(k)}}Md.prototype.connectedCallback=function(a){var b=a.__CE_definition;if(b.connectedCallback)try{b.connectedCallback.call(a)}catch(c){Ud(c)}};Md.prototype.disconnectedCallback=function(a){var b=a.__CE_definition;if(b.disconnectedCallback)try{b.disconnectedCallback.call(a)}catch(c){Ud(c)}};\nMd.prototype.attributeChangedCallback=function(a,b,c,d,e){var f=a.__CE_definition;if(f.attributeChangedCallback&&-1<f.observedAttributes.indexOf(b))try{f.attributeChangedCallback.call(a,b,c,d,e)}catch(g){Ud(g)}};\nfunction Vd(a,b,c,d){var e=b.__CE_registry;if(e&&(null===d||\"http://www.w3.org/1999/xhtml\"===d)&&(e=Td(e,c)))try{var f=new e.constructorFunction;if(void 0===f.__CE_state||void 0===f.__CE_definition)throw Error(\"Failed to construct '\"+c+\"': The returned value was not constructed with the HTMLElement constructor.\");if(\"http://www.w3.org/1999/xhtml\"!==f.namespaceURI)throw Error(\"Failed to construct '\"+c+\"': The constructed element's namespace must be the HTML namespace.\");if(f.hasAttributes())throw Error(\"Failed to construct '\"+\nc+\"': The constructed element must not have any attributes.\");if(null!==f.firstChild)throw Error(\"Failed to construct '\"+c+\"': The constructed element must not have any children.\");if(null!==f.parentNode)throw Error(\"Failed to construct '\"+c+\"': The constructed element must not have a parent node.\");if(f.ownerDocument!==b)throw Error(\"Failed to construct '\"+c+\"': The constructed element's owner document is incorrect.\");if(f.localName!==c)throw Error(\"Failed to construct '\"+c+\"': The constructed element's local name is incorrect.\");\nreturn f}catch(g){return Ud(g),b=null===d?$c.call(b,c):ad.call(b,d,c),Object.setPrototypeOf(b,HTMLUnknownElement.prototype),b.__CE_state=2,b.__CE_definition=void 0,Rd(a,b),b}b=null===d?$c.call(b,c):ad.call(b,d,c);Rd(a,b);return b}\nfunction Ud(a){var b=a.message,c=a.sourceURL||a.fileName||\"\",d=a.line||a.lineNumber||0,e=a.column||a.columnNumber||0,f=void 0;void 0===ErrorEvent.prototype.initErrorEvent?f=new ErrorEvent(\"error\",{cancelable:!0,message:b,filename:c,lineno:d,colno:e,error:a}):(f=document.createEvent(\"ErrorEvent\"),f.initErrorEvent(\"error\",!1,!0,b,c,d),f.preventDefault=function(){Object.defineProperty(this,\"defaultPrevented\",{configurable:!0,get:function(){return!0}})});void 0===f.error&&Object.defineProperty(f,\"error\",\n{configurable:!0,enumerable:!0,get:function(){return a}});window.dispatchEvent(f);f.defaultPrevented||console.error(a)};function Wd(){var a=this;this.a=void 0;this.ka=new Promise(function(b){a.b=b})}Wd.prototype.resolve=function(a){if(this.a)throw Error(\"Already resolved.\");this.a=a;this.b(a)};function Xd(a){var b=document;this.D=void 0;this.v=a;this.a=b;P(this.v,this.a);\"loading\"===this.a.readyState&&(this.D=new MutationObserver(this.b.bind(this)),this.D.observe(this.a,{childList:!0,subtree:!0}))}function Yd(a){a.D&&a.D.disconnect()}Xd.prototype.b=function(a){var b=this.a.readyState;\"interactive\"!==b&&\"complete\"!==b||Yd(this);for(b=0;b<a.length;b++)for(var c=a[b].addedNodes,d=0;d<c.length;d++)P(this.v,c[d])};function Q(a){this.N=new Map;this.O=new Map;this.ga=new Map;this.Y=!1;this.aa=new Map;this.M=function(b){return b()};this.B=!1;this.P=[];this.v=a;this.ha=a.Ma?new Xd(a):void 0}n=Q.prototype;n.Da=function(a,b){var c=this;if(!(b instanceof Function))throw new TypeError(\"Custom element constructor getters must be functions.\");Zd(this,a);this.N.set(a,b);this.P.push(a);this.B||(this.B=!0,this.M(function(){return $d(c)}))};\nn.define=function(a,b){var c=this;if(!(b instanceof Function))throw new TypeError(\"Custom element constructors must be functions.\");Zd(this,a);ae(this,a,b);this.P.push(a);this.B||(this.B=!0,this.M(function(){return $d(c)}))};function Zd(a,b){if(!Hd(b))throw new SyntaxError(\"The element name '\"+b+\"' is not valid.\");if(Td(a,b))throw Error(\"A custom element with name '\"+(b+\"' has already been defined.\"));if(a.Y)throw Error(\"A custom element is already being defined.\");}\nfunction ae(a,b,c){a.Y=!0;var d;try{var e=c.prototype;if(!(e instanceof Object))throw new TypeError(\"The custom element constructor's prototype is not an object.\");var f=function(m){var q=e[m];if(void 0!==q&&!(q instanceof Function))throw Error(\"The '\"+m+\"' callback must be a function.\");return q};var g=f(\"connectedCallback\");var h=f(\"disconnectedCallback\");var k=f(\"adoptedCallback\");var l=(d=f(\"attributeChangedCallback\"))&&c.observedAttributes||[]}catch(m){throw m;}finally{a.Y=!1}c={localName:b,\nconstructorFunction:c,connectedCallback:g,disconnectedCallback:h,adoptedCallback:k,attributeChangedCallback:d,observedAttributes:l,constructionStack:[]};a.O.set(b,c);a.ga.set(c.constructorFunction,c);return c}n.upgrade=function(a){P(this.v,a)};\nfunction $d(a){if(!1!==a.B){a.B=!1;for(var b=[],c=a.P,d=new Map,e=0;e<c.length;e++)d.set(c[e],[]);P(a.v,document,{upgrade:function(k){if(void 0===k.__CE_state){var l=k.localName,m=d.get(l);m?m.push(k):a.O.has(l)&&b.push(k)}}});for(e=0;e<b.length;e++)Sd(a.v,b[e]);for(e=0;e<c.length;e++){for(var f=c[e],g=d.get(f),h=0;h<g.length;h++)Sd(a.v,g[h]);(f=a.aa.get(f))&&f.resolve(void 0)}c.length=0}}n.get=function(a){if(a=Td(this,a))return a.constructorFunction};\nn.whenDefined=function(a){if(!Hd(a))return Promise.reject(new SyntaxError(\"'\"+a+\"' is not a valid custom element name.\"));var b=this.aa.get(a);if(b)return b.ka;b=new Wd;this.aa.set(a,b);var c=this.O.has(a)||this.N.has(a);a=-1===this.P.indexOf(a);c&&a&&b.resolve(void 0);return b.ka};n.polyfillWrapFlushCallback=function(a){this.ha&&Yd(this.ha);var b=this.M;this.M=function(c){return a(function(){return b(c)})}};\nfunction Td(a,b){var c=a.O.get(b);if(c)return c;if(c=a.N.get(b)){a.N.delete(b);try{return ae(a,b,c())}catch(d){Ud(d)}}}window.CustomElementRegistry=Q;Q.prototype.define=Q.prototype.define;Q.prototype.upgrade=Q.prototype.upgrade;Q.prototype.get=Q.prototype.get;Q.prototype.whenDefined=Q.prototype.whenDefined;Q.prototype.polyfillDefineLazy=Q.prototype.Da;Q.prototype.polyfillWrapFlushCallback=Q.prototype.polyfillWrapFlushCallback;function be(a,b,c){function d(e){return function(f){for(var g=[],h=0;h<arguments.length;++h)g[h]=arguments[h];h=[];for(var k=[],l=0;l<g.length;l++){var m=g[l];m instanceof Element&&L(m)&&k.push(m);if(m instanceof DocumentFragment)for(m=m.firstChild;m;m=m.nextSibling)h.push(m);else h.push(m)}e.apply(this,g);for(g=0;g<k.length;g++)O(a,k[g]);if(L(this))for(g=0;g<h.length;g++)k=h[g],k instanceof Element&&N(a,k)}}void 0!==c.prepend&&(b.prepend=d(c.prepend));void 0!==c.append&&(b.append=d(c.append))};function ce(a){Document.prototype.createElement=function(b){return Vd(a,this,b,null)};Document.prototype.importNode=function(b,c){b=bd.call(this,b,!!c);this.__CE_registry?P(a,b):Qd(a,b);return b};Document.prototype.createElementNS=function(b,c){return Vd(a,this,c,b)};be(a,Document.prototype,{prepend:cd,append:dd})};function de(a){function b(d){return function(e){for(var f=[],g=0;g<arguments.length;++g)f[g]=arguments[g];g=[];for(var h=[],k=0;k<f.length;k++){var l=f[k];l instanceof Element&&L(l)&&h.push(l);if(l instanceof DocumentFragment)for(l=l.firstChild;l;l=l.nextSibling)g.push(l);else g.push(l)}d.apply(this,f);for(f=0;f<h.length;f++)O(a,h[f]);if(L(this))for(f=0;f<g.length;f++)h=g[f],h instanceof Element&&N(a,h)}}var c=Element.prototype;void 0!==yd&&(c.before=b(yd));void 0!==zd&&(c.after=b(zd));void 0!==Ad&&\n(c.replaceWith=function(d){for(var e=[],f=0;f<arguments.length;++f)e[f]=arguments[f];f=[];for(var g=[],h=0;h<e.length;h++){var k=e[h];k instanceof Element&&L(k)&&g.push(k);if(k instanceof DocumentFragment)for(k=k.firstChild;k;k=k.nextSibling)f.push(k);else f.push(k)}h=L(this);Ad.apply(this,e);for(e=0;e<g.length;e++)O(a,g[e]);if(h)for(O(a,this),e=0;e<f.length;e++)g=f[e],g instanceof Element&&N(a,g)});void 0!==Bd&&(c.remove=function(){var d=L(this);Bd.call(this);d&&O(a,this)})};function ee(a){function b(e,f){Object.defineProperty(e,\"innerHTML\",{enumerable:f.enumerable,configurable:!0,get:f.get,set:function(g){var h=this,k=void 0;L(this)&&(k=[],Nd(a,this,function(q){q!==h&&k.push(q)}));f.set.call(this,g);if(k)for(var l=0;l<k.length;l++){var m=k[l];1===m.__CE_state&&a.disconnectedCallback(m)}this.ownerDocument.__CE_registry?P(a,this):Qd(a,this);return g}})}function c(e,f){e.insertAdjacentElement=function(g,h){var k=L(h);g=f.call(this,g,h);k&&O(a,h);L(g)&&N(a,h);return g}}\nfunction d(e,f){function g(h,k){for(var l=[];h!==k;h=h.nextSibling)l.push(h);for(k=0;k<l.length;k++)P(a,l[k])}e.insertAdjacentHTML=function(h,k){h=h.toLowerCase();if(\"beforebegin\"===h){var l=this.previousSibling;f.call(this,h,k);g(l||this.parentNode.firstChild,this)}else if(\"afterbegin\"===h)l=this.firstChild,f.call(this,h,k),g(this.firstChild,l);else if(\"beforeend\"===h)l=this.lastChild,f.call(this,h,k),g(l||this.firstChild,null);else if(\"afterend\"===h)l=this.nextSibling,f.call(this,h,k),g(this.nextSibling,\nl);else throw new SyntaxError(\"The value provided (\"+String(h)+\") is not one of 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'.\");}}md&&(Element.prototype.attachShadow=function(e){e=md.call(this,e);if(a.C&&!e.__CE_patched){e.__CE_patched=!0;for(var f=0;f<a.H.length;f++)a.H[f](e)}return this.__CE_shadowRoot=e});nd&&nd.get?b(Element.prototype,nd):Dd&&Dd.get?b(HTMLElement.prototype,Dd):Pd(a,function(e){b(e,{enumerable:!0,configurable:!0,get:function(){return gd.call(this,!0).innerHTML},set:function(f){var g=\n\"template\"===this.localName,h=g?this.content:this,k=ad.call(document,this.namespaceURI,this.localName);for(k.innerHTML=f;0<h.childNodes.length;)jd.call(h,h.childNodes[0]);for(f=g?k.content:k;0<f.childNodes.length;)hd.call(h,f.childNodes[0])}})});Element.prototype.setAttribute=function(e,f){if(1!==this.__CE_state)return pd.call(this,e,f);var g=od.call(this,e);pd.call(this,e,f);f=od.call(this,e);a.attributeChangedCallback(this,e,g,f,null)};Element.prototype.setAttributeNS=function(e,f,g){if(1!==this.__CE_state)return sd.call(this,\ne,f,g);var h=rd.call(this,e,f);sd.call(this,e,f,g);g=rd.call(this,e,f);a.attributeChangedCallback(this,f,h,g,e)};Element.prototype.removeAttribute=function(e){if(1!==this.__CE_state)return qd.call(this,e);var f=od.call(this,e);qd.call(this,e);null!==f&&a.attributeChangedCallback(this,e,f,null,null)};Element.prototype.removeAttributeNS=function(e,f){if(1!==this.__CE_state)return td.call(this,e,f);var g=rd.call(this,e,f);td.call(this,e,f);var h=rd.call(this,e,f);g!==h&&a.attributeChangedCallback(this,\nf,g,h,e)};Ed?c(HTMLElement.prototype,Ed):ud&&c(Element.prototype,ud);Fd?d(HTMLElement.prototype,Fd):vd&&d(Element.prototype,vd);be(a,Element.prototype,{prepend:wd,append:xd});de(a)};var fe={};function ge(a){function b(){var c=this.constructor;var d=document.__CE_registry.ga.get(c);if(!d)throw Error(\"Failed to construct a custom element: The constructor was not registered with `customElements`.\");var e=d.constructionStack;if(0===e.length)return e=$c.call(document,d.localName),Object.setPrototypeOf(e,c.prototype),e.__CE_state=1,e.__CE_definition=d,Rd(a,e),e;var f=e.length-1,g=e[f];if(g===fe)throw Error(\"Failed to construct '\"+d.localName+\"': This element was already constructed.\");e[f]=\nfe;Object.setPrototypeOf(g,c.prototype);Rd(a,g);return g}b.prototype=Cd.prototype;Object.defineProperty(HTMLElement.prototype,\"constructor\",{writable:!0,configurable:!0,enumerable:!1,value:b});window.HTMLElement=b};function he(a){function b(c,d){Object.defineProperty(c,\"textContent\",{enumerable:d.enumerable,configurable:!0,get:d.get,set:function(e){if(this.nodeType===Node.TEXT_NODE)d.set.call(this,e);else{var f=void 0;if(this.firstChild){var g=this.childNodes,h=g.length;if(0<h&&L(this)){f=Array(h);for(var k=0;k<h;k++)f[k]=g[k]}}d.set.call(this,e);if(f)for(e=0;e<f.length;e++)O(a,f[e])}}})}Node.prototype.insertBefore=function(c,d){if(c instanceof DocumentFragment){var e=Jd(c);c=id.call(this,c,d);if(L(this))for(d=\n0;d<e.length;d++)N(a,e[d]);return c}e=c instanceof Element&&L(c);d=id.call(this,c,d);e&&O(a,c);L(this)&&N(a,c);return d};Node.prototype.appendChild=function(c){if(c instanceof DocumentFragment){var d=Jd(c);c=hd.call(this,c);if(L(this))for(var e=0;e<d.length;e++)N(a,d[e]);return c}d=c instanceof Element&&L(c);e=hd.call(this,c);d&&O(a,c);L(this)&&N(a,c);return e};Node.prototype.cloneNode=function(c){c=gd.call(this,!!c);this.ownerDocument.__CE_registry?P(a,c):Qd(a,c);return c};Node.prototype.removeChild=\nfunction(c){var d=c instanceof Element&&L(c),e=jd.call(this,c);d&&O(a,c);return e};Node.prototype.replaceChild=function(c,d){if(c instanceof DocumentFragment){var e=Jd(c);c=kd.call(this,c,d);if(L(this))for(O(a,d),d=0;d<e.length;d++)N(a,e[d]);return c}e=c instanceof Element&&L(c);var f=kd.call(this,c,d),g=L(this);g&&O(a,d);e&&O(a,c);g&&N(a,c);return f};ld&&ld.get?b(Node.prototype,ld):Od(a,function(c){b(c,{enumerable:!0,configurable:!0,get:function(){for(var d=[],e=this.firstChild;e;e=e.nextSibling)e.nodeType!==\nNode.COMMENT_NODE&&d.push(e.textContent);return d.join(\"\")},set:function(d){for(;this.firstChild;)jd.call(this,this.firstChild);null!=d&&\"\"!==d&&hd.call(this,document.createTextNode(d))}})})};var M=window.customElements;function ie(){var a=new Md;ge(a);ce(a);be(a,DocumentFragment.prototype,{prepend:ed,append:fd});he(a);ee(a);a=new Q(a);document.__CE_registry=a;Object.defineProperty(window,\"customElements\",{configurable:!0,enumerable:!0,value:a})}M&&!M.forcePolyfill&&\"function\"==typeof M.define&&\"function\"==typeof M.get||ie();window.__CE_installPolyfill=ie;/*\n\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nfunction je(){this.end=this.start=0;this.rules=this.parent=this.previous=null;this.cssText=this.parsedCssText=\"\";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=\"\"}\nfunction ke(a){var b=a=a.replace(le,\"\").replace(me,\"\"),c=new je;c.start=0;c.end=b.length;for(var d=c,e=0,f=b.length;e<f;e++)if(\"{\"===b[e]){d.rules||(d.rules=[]);var g=d,h=g.rules[g.rules.length-1]||null;d=new je;d.start=e+1;d.parent=g;d.previous=h;g.rules.push(d)}else\"}\"===b[e]&&(d.end=e+1,d=d.parent||c);return ne(c,a)}\nfunction ne(a,b){var c=b.substring(a.start,a.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&(c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=oe(c),c=c.replace(pe,\" \"),c=c.substring(c.lastIndexOf(\";\")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=0===c.indexOf(\"@\"),a.atRule?0===c.indexOf(\"@media\")?a.type=qe:c.match(re)&&(a.type=se,a.keyframesName=a.selector.split(pe).pop()):a.type=0===c.indexOf(\"--\")?te:ue);if(c=a.rules)for(var d=0,e=c.length,f=void 0;d<e&&(f=c[d]);d++)ne(f,\nb);return a}function oe(a){return a.replace(/\\\\([0-9a-f]{1,6})\\s/gi,function(b,c){b=c;for(c=6-b.length;c--;)b=\"0\"+b;return\"\\\\\"+b})}\nfunction ve(a,b,c){c=void 0===c?\"\":c;var d=\"\";if(a.cssText||a.rules){var e=a.rules,f;if(f=e)f=e[0],f=!(f&&f.selector&&0===f.selector.indexOf(\"--\"));if(f){f=0;for(var g=e.length,h=void 0;f<g&&(h=e[f]);f++)d=ve(h,b,d)}else b?b=a.cssText:(b=a.cssText,b=b.replace(we,\"\").replace(xe,\"\"),b=b.replace(ye,\"\").replace(ze,\"\")),(d=b.trim())&&(d=\"  \"+d+\"\\n\")}d&&(a.selector&&(c+=a.selector+\" {\\n\"),c+=d,a.selector&&(c+=\"}\\n\\n\"));return c}\nvar ue=1,se=7,qe=4,te=1E3,le=/\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//gim,me=/@import[^;]*;/gim,we=/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\\n]|$)/gim,xe=/(?:^[^;\\-\\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\\n]|$)?/gim,ye=/@apply\\s*\\(?[^);]*\\)?\\s*(?:[;\\n]|$)?/gim,ze=/[^;:]*?:[^;]*?var\\([^;]*\\)(?:[;\\n]|$)?/gim,re=/^@[^\\s]*keyframes/,pe=/\\s+/g;var R=!(window.ShadyDOM&&window.ShadyDOM.inUse),Ae;function Be(a){Ae=a&&a.shimcssproperties?!1:R||!(navigator.userAgent.match(/AppleWebKit\\/601|Edge\\/15/)||!window.CSS||!CSS.supports||!CSS.supports(\"box-shadow\",\"0 0 0 var(--foo)\"))}var Ce;window.ShadyCSS&&void 0!==window.ShadyCSS.cssBuild&&(Ce=window.ShadyCSS.cssBuild);var De=!(!window.ShadyCSS||!window.ShadyCSS.disableRuntime);\nwindow.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss?Ae=window.ShadyCSS.nativeCss:window.ShadyCSS?(Be(window.ShadyCSS),window.ShadyCSS=void 0):Be(window.WebComponents&&window.WebComponents.flags);var S=Ae;var Ee=/(?:^|[;\\s{]\\s*)(--[\\w-]*?)\\s*:\\s*(?:((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^)]*?\\)|[^};{])+)|\\{([^}]*)\\}(?:(?=[;\\s}])|$))/gi,Fe=/(?:^|\\W+)@apply\\s*\\(?([^);\\n]*)\\)?/gi,Ge=/(--[\\w-]+)\\s*([:,;)]|$)/gi,He=/(animation\\s*:)|(animation-name\\s*:)/,Ie=/@media\\s(.*)/,Je=/\\{[^}]*\\}/g;var Ke=new Set;function Le(a,b){if(!a)return\"\";\"string\"===typeof a&&(a=ke(a));b&&Me(a,b);return ve(a,S)}function Ne(a){!a.__cssRules&&a.textContent&&(a.__cssRules=ke(a.textContent));return a.__cssRules||null}function Oe(a){return!!a.parent&&a.parent.type===se}function Me(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===qe){var g=a.selector.match(Ie);g&&(window.matchMedia(g[1]).matches||(e=!0))}f===ue?b(a):c&&f===se?c(a):f===te&&(e=!0);if((a=a.rules)&&!e)for(e=0,f=a.length,g=void 0;e<f&&(g=a[e]);e++)Me(g,b,c,d)}}\nfunction Pe(a,b,c,d){var e=document.createElement(\"style\");b&&e.setAttribute(\"scope\",b);e.textContent=a;Qe(e,c,d);return e}var T=null;function Re(a){a=document.createComment(\" Shady DOM styles for \"+a+\" \");var b=document.head;b.insertBefore(a,(T?T.nextSibling:null)||b.firstChild);return T=a}function Qe(a,b,c){b=b||document.head;b.insertBefore(a,c&&c.nextSibling||b.firstChild);T?a.compareDocumentPosition(T)===Node.DOCUMENT_POSITION_PRECEDING&&(T=a):T=a}\nfunction Se(a,b){for(var c=0,d=a.length;b<d;b++)if(\"(\"===a[b])c++;else if(\")\"===a[b]&&0===--c)return b;return-1}function Te(a,b){var c=a.indexOf(\"var(\");if(-1===c)return b(a,\"\",\"\",\"\");var d=Se(a,c+3),e=a.substring(c+4,d);c=a.substring(0,c);a=Te(a.substring(d+1),b);d=e.indexOf(\",\");return-1===d?b(c,e.trim(),\"\",a):b(c,e.substring(0,d).trim(),e.substring(d+1).trim(),a)}function Ue(a,b){R?a.setAttribute(\"class\",b):window.ShadyDOM.nativeMethods.setAttribute.call(a,\"class\",b)}\nvar Ve=window.ShadyDOM&&window.ShadyDOM.wrap||function(a){return a};function U(a){var b=a.localName,c=\"\";b?-1<b.indexOf(\"-\")||(c=b,b=a.getAttribute&&a.getAttribute(\"is\")||\"\"):(b=a.is,c=a.extends);return{is:b,K:c}}function We(a){for(var b=[],c=\"\",d=0;0<=d&&d<a.length;d++)if(\"(\"===a[d]){var e=Se(a,d);c+=a.slice(d,e+1);d=e}else\",\"===a[d]?(b.push(c),c=\"\"):c+=a[d];c&&b.push(c);return b}\nfunction Xe(a){if(void 0!==Ce)return Ce;if(void 0===a.__cssBuild){var b=a.getAttribute(\"css-build\");if(b)a.__cssBuild=b;else{a:{b=\"template\"===a.localName?a.content.firstChild:a.firstChild;if(b instanceof Comment&&(b=b.textContent.trim().split(\":\"),\"css-build\"===b[0])){b=b[1];break a}b=\"\"}if(\"\"!==b){var c=\"template\"===a.localName?a.content.firstChild:a.firstChild;c.parentNode.removeChild(c)}a.__cssBuild=b}}return a.__cssBuild||\"\"}\nfunction Ye(a){a=void 0===a?\"\":a;return\"\"!==a&&S?R?\"shadow\"===a:\"shady\"===a:!1};function Ze(){}function $e(a,b){af(V,a,function(c){W(c,b||\"\")})}function af(a,b,c){b.nodeType===Node.ELEMENT_NODE&&c(b);var d;\"template\"===b.localName?d=(b.content||b._content||b).childNodes:d=b.children||b.childNodes;if(d)for(b=0;b<d.length;b++)af(a,d[b],c)}\nfunction W(a,b,c){if(b)if(a.classList)c?(a.classList.remove(\"style-scope\"),a.classList.remove(b)):(a.classList.add(\"style-scope\"),a.classList.add(b));else if(a.getAttribute){var d=a.getAttribute(\"class\");c?d&&(b=d.replace(\"style-scope\",\"\").replace(b,\"\"),Ue(a,b)):Ue(a,(d?d+\" \":\"\")+\"style-scope \"+b)}}function bf(a,b,c){af(V,a,function(d){W(d,b,!0);W(d,c)})}function cf(a,b){af(V,a,function(c){W(c,b||\"\",!0)})}\nfunction df(a,b,c,d,e){var f=V;e=void 0===e?\"\":e;\"\"===e&&(R||\"shady\"===(void 0===d?\"\":d)?e=Le(b,c):(a=U(a),e=ef(f,b,a.is,a.K,c)+\"\\n\\n\"));return e.trim()}function ef(a,b,c,d,e){var f=ff(c,d);c=c?\".\"+c:\"\";return Le(b,function(g){g.c||(g.selector=g.g=gf(a,g,a.b,c,f),g.c=!0);e&&e(g,c,f)})}function ff(a,b){return b?\"[is=\"+a+\"]\":a}\nfunction gf(a,b,c,d,e){var f=We(b.selector);if(!Oe(b)){b=0;for(var g=f.length,h=void 0;b<g&&(h=f[b]);b++)f[b]=c.call(a,h,d,e)}return f.filter(function(k){return!!k}).join(\",\")}function hf(a){return a.replace(jf,function(b,c,d){-1<d.indexOf(\"+\")?d=d.replace(/\\+/g,\"___\"):-1<d.indexOf(\"___\")&&(d=d.replace(/___/g,\"+\"));return\":\"+c+\"(\"+d+\")\"})}\nfunction kf(a){for(var b=[],c;c=a.match(lf);){var d=c.index,e=Se(a,d);if(-1===e)throw Error(c.input+\" selector missing ')'\");c=a.slice(d,e+1);a=a.replace(c,\"\\ue000\");b.push(c)}return{fa:a,matches:b}}function mf(a,b){var c=a.split(\"\\ue000\");return b.reduce(function(d,e,f){return d+e+c[f+1]},c[0])}\nZe.prototype.b=function(a,b,c){var d=!1;a=a.trim();var e=jf.test(a);e&&(a=a.replace(jf,function(h,k,l){return\":\"+k+\"(\"+l.replace(/\\s/g,\"\")+\")\"}),a=hf(a));var f=lf.test(a);if(f){var g=kf(a);a=g.fa;g=g.matches}a=a.replace(nf,\":host $1\");a=a.replace(of,function(h,k,l){d||(h=pf(l,k,b,c),d=d||h.stop,k=h.xa,l=h.value);return k+l});f&&(a=mf(a,g));e&&(a=hf(a));return a=a.replace(qf,function(h,k,l,m){return'[dir=\"'+l+'\"] '+k+m+\", \"+k+'[dir=\"'+l+'\"]'+m})};\nfunction pf(a,b,c,d){var e=a.indexOf(\"::slotted\");0<=a.indexOf(\":host\")?a=rf(a,d):0!==e&&(a=c?sf(a,c):a);c=!1;0<=e&&(b=\"\",c=!0);if(c){var f=!0;c&&(a=a.replace(tf,function(g,h){return\" > \"+h}))}return{value:a,xa:b,stop:f}}function sf(a,b){a=a.split(/(\\[.+?\\])/);for(var c=[],d=0;d<a.length;d++)if(1===d%2)c.push(a[d]);else{var e=a[d];if(\"\"!==e||d!==a.length-1)e=e.split(\":\"),e[0]+=b,c.push(e.join(\":\"))}return c.join(\"\")}\nfunction rf(a,b){var c=a.match(uf);return(c=c&&c[2].trim()||\"\")?c[0].match(vf)?a.replace(uf,function(d,e,f){return b+f}):c.split(vf)[0]===b?c:\"should_not_match\":a.replace(\":host\",b)}function wf(a){\":root\"===a.selector&&(a.selector=\"html\")}Ze.prototype.c=function(a){return a.match(\":host\")?\"\":a.match(\"::slotted\")?this.b(a,\":not(.style-scope)\"):sf(a.trim(),\":not(.style-scope)\")};da.Object.defineProperties(Ze.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return\"style-scope\"}}});\nvar jf=/:(nth[-\\w]+)\\(([^)]+)\\)/,of=/(^|[\\s>+~]+)((?:\\[.+?\\]|[^\\s>+~=[])+)/g,vf=/[[.:#*]/,nf=/^(::slotted)/,uf=/(:host)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/,tf=/(?:::slotted)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))/,qf=/(.*):dir\\((?:(ltr|rtl))\\)(.*)/,lf=/:(?:matches|any|-(?:webkit|moz)-any)/,V=new Ze;function xf(a,b,c,d,e){this.o=a||null;this.b=b||null;this.da=c||[];this.l=null;this.cssBuild=e||\"\";this.K=d||\"\";this.a=this.m=this.u=null}function X(a){return a?a.__styleInfo:null}function yf(a,b){return a.__styleInfo=b}xf.prototype.c=function(){return this.o};xf.prototype._getStyleRules=xf.prototype.c;function zf(a){var b=this.matches||this.matchesSelector||this.mozMatchesSelector||this.msMatchesSelector||this.oMatchesSelector||this.webkitMatchesSelector;return b&&b.call(this,a)}var Af=/:host\\s*>\\s*/,Bf=navigator.userAgent.match(\"Trident\");function Cf(){}function Df(a){var b={},c=[],d=0;Me(a,function(f){Ef(f);f.index=d++;f=f.f.cssText;for(var g;g=Ge.exec(f);){var h=g[1];\":\"!==g[2]&&(b[h]=!0)}},function(f){c.push(f)});a.b=c;a=[];for(var e in b)a.push(e);return a}\nfunction Ef(a){if(!a.f){var b={},c={};Ff(a,c)&&(b.s=c,a.rules=null);b.cssText=a.parsedCssText.replace(Je,\"\").replace(Ee,\"\");a.f=b}}function Ff(a,b){var c=a.f;if(c){if(c.s)return Object.assign(b,c.s),!0}else{c=a.parsedCssText;for(var d;a=Ee.exec(c);){d=(a[2]||a[3]).trim();if(\"inherit\"!==d||\"unset\"!==d)b[a[1].trim()]=d;d=!0}return d}}\nfunction Gf(a,b,c){b&&(b=0<=b.indexOf(\";\")?Hf(a,b,c):Te(b,function(d,e,f,g){if(!e)return d+g;(e=Gf(a,c[e],c))&&\"initial\"!==e?\"apply-shim-inherit\"===e&&(e=\"inherit\"):e=Gf(a,c[f]||f,c)||f;return d+(e||\"\")+g}));return b&&b.trim()||\"\"}\nfunction Hf(a,b,c){b=b.split(\";\");for(var d=0,e,f;d<b.length;d++)if(e=b[d]){Fe.lastIndex=0;if(f=Fe.exec(e))e=Gf(a,c[f[1]],c);else if(f=e.indexOf(\":\"),-1!==f){var g=e.substring(f);g=g.trim();g=Gf(a,g,c)||g;e=e.substring(0,f)+g}b[d]=e&&e.lastIndexOf(\";\")===e.length-1?e.slice(0,-1):e||\"\"}return b.join(\";\")}\nfunction If(a,b){var c={},d=[];Me(a,function(e){e.f||Ef(e);var f=e.g||e.parsedSelector;b&&e.f.s&&f&&zf.call(b,f)&&(Ff(e,c),e=e.index,f=parseInt(e/32,10),d[f]=(d[f]||0)|1<<e%32)},null,!0);return{s:c,key:d}}\nfunction Jf(a,b,c,d){b.f||Ef(b);if(b.f.s){var e=U(a);a=e.is;e=e.K;e=a?ff(a,e):\"html\";var f=b.parsedSelector;var g=!!f.match(Af)||\"html\"===e&&-1<f.indexOf(\"html\");var h=0===f.indexOf(\":host\")&&!g;\"shady\"===c&&(g=f===e+\" > *.\"+e||-1!==f.indexOf(\"html\"),h=!g&&0===f.indexOf(e));if(g||h)c=e,h&&(b.g||(b.g=gf(V,b,V.b,a?\".\"+a:\"\",e)),c=b.g||e),g&&\"html\"===e&&(c=b.g||b.T),d({fa:c,Ca:h,Pa:g})}}\nfunction Kf(a,b,c){var d={},e={};Me(b,function(f){Jf(a,f,c,function(g){zf.call(a._element||a,g.fa)&&(g.Ca?Ff(f,d):Ff(f,e))})},null,!0);return{Ga:e,Ba:d}}\nfunction Lf(a,b,c,d){var e=U(b),f=ff(e.is,e.K),g=new RegExp(\"(?:^|[^.#[:])\"+(b.extends?\"\\\\\"+f.slice(0,-1)+\"\\\\]\":f)+\"($|[.:[\\\\s>+~])\"),h=X(b);e=h.o;h=h.cssBuild;var k=Mf(e,d);return df(b,e,function(l){var m=\"\";l.f||Ef(l);l.f.cssText&&(m=Hf(a,l.f.cssText,c));l.cssText=m;if(!R&&!Oe(l)&&l.cssText){var q=m=l.cssText;null==l.ma&&(l.ma=He.test(m));if(l.ma)if(null==l.U){l.U=[];for(var x in k)q=k[x],q=q(m),m!==q&&(m=q,l.U.push(x))}else{for(x=0;x<l.U.length;++x)q=k[l.U[x]],m=q(m);q=m}l.cssText=q;l.g=l.g||l.selector;\nm=\".\"+d;x=We(l.g);q=0;for(var la=x.length,Xa=void 0;q<la&&(Xa=x[q]);q++)x[q]=Xa.match(g)?Xa.replace(f,m):m+\" \"+Xa;l.selector=x.join(\",\")}},h)}function Mf(a,b){a=a.b;var c={};if(!R&&a)for(var d=0,e=a[d];d<a.length;e=a[++d]){var f=e,g=b;f.i=new RegExp(\"\\\\b\"+f.keyframesName+\"(?!\\\\B|-)\",\"g\");f.a=f.keyframesName+\"-\"+g;f.g=f.g||f.selector;f.selector=f.g.replace(f.keyframesName,f.a);c[e.keyframesName]=Nf(e)}return c}function Nf(a){return function(b){return b.replace(a.i,a.a)}}\nfunction Of(a,b){var c=Pf,d=Ne(a);a.textContent=Le(d,function(e){var f=e.cssText=e.parsedCssText;e.f&&e.f.cssText&&(f=f.replace(we,\"\").replace(xe,\"\"),e.cssText=Hf(c,f,b))})}da.Object.defineProperties(Cf.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return\"x-scope\"}}});var Pf=new Cf;var Qf={},Rf=window.customElements;if(Rf&&!R&&!De){var Sf=Rf.define;Rf.define=function(a,b,c){Qf[a]||(Qf[a]=Re(a));Sf.call(Rf,a,b,c)}};function Tf(){this.cache={}}Tf.prototype.store=function(a,b,c,d){var e=this.cache[a]||[];e.push({s:b,styleElement:c,m:d});100<e.length&&e.shift();this.cache[a]=e};function Uf(){}var Vf=new RegExp(V.a+\"\\\\s*([^\\\\s]*)\");function Wf(a){return(a=(a.classList&&a.classList.value?a.classList.value:a.getAttribute(\"class\")||\"\").match(Vf))?a[1]:\"\"}function Xf(a){var b=Ve(a).getRootNode();return b===a||b===a.ownerDocument?\"\":(a=b.host)?U(a).is:\"\"}\nfunction Yf(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.target!==document.documentElement&&c.target!==document.head)for(var d=0;d<c.addedNodes.length;d++){var e=c.addedNodes[d];if(e.nodeType===Node.ELEMENT_NODE){var f=e.getRootNode(),g=Wf(e);if(g&&f===e.ownerDocument&&(\"style\"!==e.localName&&\"template\"!==e.localName||\"\"===Xe(e)))cf(e,g);else if(f instanceof ShadowRoot)for(f=Xf(e),f!==g&&bf(e,g,f),e=window.ShadyDOM.nativeMethods.querySelectorAll.call(e,\":not(.\"+V.a+\")\"),g=0;g<e.length;g++){f=e[g];\nvar h=Xf(f);h&&W(f,h)}}}}}\nif(!(R||window.ShadyDOM&&window.ShadyDOM.handlesDynamicScoping)){var Zf=new MutationObserver(Yf),$f=function(a){Zf.observe(a,{childList:!0,subtree:!0})};if(window.customElements&&!window.customElements.polyfillWrapFlushCallback)$f(document);else{var ag=function(){$f(document.body)};window.HTMLImports?window.HTMLImports.whenReady(ag):requestAnimationFrame(function(){if(\"loading\"===document.readyState){var a=function(){ag();document.removeEventListener(\"readystatechange\",a)};document.addEventListener(\"readystatechange\",\na)}else ag()})}Uf=function(){Yf(Zf.takeRecords())}};var bg={};var cg=Promise.resolve();function dg(a){if(a=bg[a])a._applyShimCurrentVersion=a._applyShimCurrentVersion||0,a._applyShimValidatingVersion=a._applyShimValidatingVersion||0,a._applyShimNextVersion=(a._applyShimNextVersion||0)+1}function eg(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}function fg(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a._validating||(a._validating=!0,cg.then(function(){a._applyShimCurrentVersion=a._applyShimNextVersion;a._validating=!1}))};var gg={},hg=new Tf;function Y(){this.la={};this.c=document.documentElement;var a=new je;a.rules=[];this.i=yf(this.c,new xf(a));this.T=!1;this.a=this.b=null}n=Y.prototype;n.flush=function(){Uf()};n.za=function(a){return Ne(a)};n.Ka=function(a){return Le(a)};n.prepareTemplate=function(a,b,c){this.prepareTemplateDom(a,b);this.prepareTemplateStyles(a,b,c)};\nn.prepareTemplateStyles=function(a,b,c){if(!a._prepared&&!De){R||Qf[b]||(Qf[b]=Re(b));a._prepared=!0;a.name=b;a.extends=c;bg[b]=a;var d=Xe(a),e=Ye(d);c={is:b,extends:c};for(var f=[],g=a.content.querySelectorAll(\"style\"),h=0;h<g.length;h++){var k=g[h];if(k.hasAttribute(\"shady-unscoped\")){if(!R){var l=k.textContent;if(!Ke.has(l)){Ke.add(l);var m=document.createElement(\"style\");m.setAttribute(\"shady-unscoped\",\"\");m.textContent=l;document.head.appendChild(m)}k.parentNode.removeChild(k)}}else f.push(k.textContent),\nk.parentNode.removeChild(k)}f=f.join(\"\").trim()+(gg[b]||\"\");ig(this);if(!e){if(g=!d)g=Fe.test(f)||Ee.test(f),Fe.lastIndex=0,Ee.lastIndex=0;h=ke(f);g&&S&&this.b&&this.b.transformRules(h,b);a._styleAst=h}g=[];S||(g=Df(a._styleAst));if(!g.length||S)h=R?a.content:null,b=Qf[b]||null,d=df(c,a._styleAst,null,d,e?f:\"\"),d=d.length?Pe(d,c.is,h,b):null,a._style=d;a.a=g}};n.Ea=function(a,b){gg[b]=a.join(\" \")};\nn.prepareTemplateDom=function(a,b){if(!De){var c=Xe(a);R||\"shady\"===c||a._domPrepared||(a._domPrepared=!0,$e(a.content,b))}};function jg(a){var b=U(a),c=b.is;b=b.K;var d=Qf[c]||null,e=bg[c];if(e){c=e._styleAst;var f=e.a;e=Xe(e);b=new xf(c,d,f,b,e);yf(a,b);return b}}\nfunction kg(a){!a.a&&window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface&&(a.a=window.ShadyCSS.CustomStyleInterface,a.a.transformCallback=function(b){a.pa(b)},a.a.validateCallback=function(){requestAnimationFrame(function(){(a.a.enqueued||a.T)&&a.flushCustomStyles()})})}function ig(a){if(!a.b&&window.ShadyCSS&&window.ShadyCSS.ApplyShim){a.b=window.ShadyCSS.ApplyShim;a.b.invalidCallback=dg;var b=!0}else b=!1;kg(a);return b}\nn.flushCustomStyles=function(){if(!De){var a=ig(this);if(this.a){var b=this.a.processStyles();if((a||this.a.enqueued)&&!Ye(this.i.cssBuild)){if(S){if(!this.i.cssBuild)for(a=0;a<b.length;a++){var c=this.a.getStyleForCustomStyle(b[a]);if(c&&S&&this.b){var d=Ne(c);ig(this);this.b.transformRules(d);c.textContent=Le(d)}}}else{lg(this,b);mg(this,this.c,this.i);for(a=0;a<b.length;a++)(c=this.a.getStyleForCustomStyle(b[a]))&&Of(c,this.i.u);this.T&&this.styleDocument()}this.a.enqueued=!1}}}};\nfunction lg(a,b){b=b.map(function(c){return a.a.getStyleForCustomStyle(c)}).filter(function(c){return!!c});b.sort(function(c,d){c=d.compareDocumentPosition(c);return c&Node.DOCUMENT_POSITION_FOLLOWING?1:c&Node.DOCUMENT_POSITION_PRECEDING?-1:0});a.i.o.rules=b.map(function(c){return Ne(c)})}\nn.styleElement=function(a,b){if(De){if(b){X(a)||yf(a,new xf(null));var c=X(a);c.l=c.l||{};Object.assign(c.l,b);ng(this,a,c)}}else if(c=X(a)||jg(a))if(a!==this.c&&(this.T=!0),b&&(c.l=c.l||{},Object.assign(c.l,b)),S)ng(this,a,c);else if(this.flush(),mg(this,a,c),c.da&&c.da.length){b=U(a).is;var d;a:{if(d=hg.cache[b])for(var e=d.length-1;0<=e;e--){var f=d[e];b:{var g=c.da;for(var h=0;h<g.length;h++){var k=g[h];if(f.s[k]!==c.u[k]){g=!1;break b}}g=!0}if(g){d=f;break a}}d=void 0}g=d?d.styleElement:null;\ne=c.m;(f=d&&d.m)||(f=this.la[b]=(this.la[b]||0)+1,f=b+\"-\"+f);c.m=f;f=c.m;h=Pf;h=g?g.textContent||\"\":Lf(h,a,c.u,f);k=X(a);var l=k.a;l&&!R&&l!==g&&(l._useCount--,0>=l._useCount&&l.parentNode&&l.parentNode.removeChild(l));R?k.a?(k.a.textContent=h,g=k.a):h&&(g=Pe(h,f,a.shadowRoot,k.b)):g?g.parentNode||(Bf&&-1<h.indexOf(\"@media\")&&(g.textContent=h),Qe(g,null,k.b)):h&&(g=Pe(h,f,null,k.b));g&&(g._useCount=g._useCount||0,k.a!=g&&g._useCount++,k.a=g);f=g;R||(g=c.m,k=h=a.getAttribute(\"class\")||\"\",e&&(k=h.replace(new RegExp(\"\\\\s*x-scope\\\\s*\"+\ne+\"\\\\s*\",\"g\"),\" \")),k+=(k?\" \":\"\")+\"x-scope \"+g,h!==k&&Ue(a,k));d||hg.store(b,c.u,f,c.m)}};\nfunction ng(a,b,c){var d=U(b).is;if(c.l){var e=c.l,f;for(f in e)null===f?b.style.removeProperty(f):b.style.setProperty(f,e[f])}e=bg[d];if(!(!e&&b!==a.c||e&&\"\"!==Xe(e))&&e&&e._style&&!eg(e)){if(eg(e)||e._applyShimValidatingVersion!==e._applyShimNextVersion)ig(a),a.b&&a.b.transformRules(e._styleAst,d),e._style.textContent=df(b,c.o),fg(e);R&&(a=b.shadowRoot)&&(a=a.querySelector(\"style\"))&&(a.textContent=df(b,c.o));c.o=e._styleAst}}\nfunction og(a,b){return(b=Ve(b).getRootNode().host)?X(b)||jg(b)?b:og(a,b):a.c}function mg(a,b,c){var d=og(a,b),e=X(d),f=e.u;d===a.c||f||(mg(a,d,e),f=e.u);a=Object.create(f||null);d=Kf(b,c.o,c.cssBuild);b=If(e.o,b).s;Object.assign(a,d.Ba,b,d.Ga);b=c.l;for(var g in b)if((e=b[g])||0===e)a[g]=e;g=Pf;b=Object.getOwnPropertyNames(a);for(e=0;e<b.length;e++)d=b[e],a[d]=Gf(g,a[d],a);c.u=a}n.styleDocument=function(a){this.styleSubtree(this.c,a)};\nn.styleSubtree=function(a,b){var c=Ve(a),d=c.shadowRoot,e=a===this.c;(d||e)&&this.styleElement(a,b);if(a=e?c:d)for(a=Array.from(a.querySelectorAll(\"*\")).filter(function(f){return Ve(f).shadowRoot}),b=0;b<a.length;b++)this.styleSubtree(a[b])};\nn.pa=function(a){var b=this,c=Xe(a);c!==this.i.cssBuild&&(this.i.cssBuild=c);if(!Ye(c)){var d=Ne(a);Me(d,function(e){if(R)wf(e);else{var f=V;e.selector=e.parsedSelector;wf(e);e.selector=e.g=gf(f,e,f.c,void 0,void 0)}S&&\"\"===c&&(ig(b),b.b&&b.b.transformRule(e))});S?a.textContent=Le(d):this.i.o.rules.push(d)}};n.getComputedStyleValue=function(a,b){var c;S||(c=(X(a)||X(og(this,a))).u[b]);return(c=c||window.getComputedStyle(a).getPropertyValue(b))?c.trim():\"\"};\nn.Ja=function(a,b){var c=Ve(a).getRootNode(),d;b?d=(\"string\"===typeof b?b:String(b)).split(/\\s/):d=[];b=c.host&&c.host.localName;if(!b&&(c=a.getAttribute(\"class\"))){c=c.split(/\\s/);for(var e=0;e<c.length;e++)if(c[e]===V.a){b=c[e+1];break}}b&&d.push(V.a,b);S||(b=X(a))&&b.m&&d.push(Pf.a,b.m);Ue(a,d.join(\" \"))};n.wa=function(a){return X(a)};n.Ia=function(a,b){W(a,b)};n.La=function(a,b){W(a,b,!0)};n.Ha=function(a){return Xf(a)};n.ya=function(a){return Wf(a)};Y.prototype.flush=Y.prototype.flush;\nY.prototype.prepareTemplate=Y.prototype.prepareTemplate;Y.prototype.styleElement=Y.prototype.styleElement;Y.prototype.styleDocument=Y.prototype.styleDocument;Y.prototype.styleSubtree=Y.prototype.styleSubtree;Y.prototype.getComputedStyleValue=Y.prototype.getComputedStyleValue;Y.prototype.setElementClass=Y.prototype.Ja;Y.prototype._styleInfoForNode=Y.prototype.wa;Y.prototype.transformCustomStyleForDocument=Y.prototype.pa;Y.prototype.getStyleAst=Y.prototype.za;Y.prototype.styleAstToString=Y.prototype.Ka;\nY.prototype.flushCustomStyles=Y.prototype.flushCustomStyles;Y.prototype.scopeNode=Y.prototype.Ia;Y.prototype.unscopeNode=Y.prototype.La;Y.prototype.scopeForNode=Y.prototype.Ha;Y.prototype.currentScopeForNode=Y.prototype.ya;Y.prototype.prepareAdoptedCssText=Y.prototype.Ea;Object.defineProperties(Y.prototype,{nativeShadow:{get:function(){return R}},nativeCss:{get:function(){return S}}});var Z=new Y,pg,qg;window.ShadyCSS&&(pg=window.ShadyCSS.ApplyShim,qg=window.ShadyCSS.CustomStyleInterface);\nwindow.ShadyCSS={ScopingShim:Z,prepareTemplate:function(a,b,c){Z.flushCustomStyles();Z.prepareTemplate(a,b,c)},prepareTemplateDom:function(a,b){Z.prepareTemplateDom(a,b)},prepareTemplateStyles:function(a,b,c){Z.flushCustomStyles();Z.prepareTemplateStyles(a,b,c)},styleSubtree:function(a,b){Z.flushCustomStyles();Z.styleSubtree(a,b)},styleElement:function(a){Z.flushCustomStyles();Z.styleElement(a)},styleDocument:function(a){Z.flushCustomStyles();Z.styleDocument(a)},flushCustomStyles:function(){Z.flushCustomStyles()},\ngetComputedStyleValue:function(a,b){return Z.getComputedStyleValue(a,b)},nativeCss:S,nativeShadow:R,cssBuild:Ce,disableRuntime:De};pg&&(window.ShadyCSS.ApplyShim=pg);qg&&(window.ShadyCSS.CustomStyleInterface=qg);}).call(this);\n\n//# sourceMappingURL=webcomponents-sd-ce.js.map\n"
  }
]